pts 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/pts.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pts.js","names":["generator","UIA","this","Typo","Canvas","Create","Form","LinearAlgebra","Num","Op","Pt","Space","Color","Util","Dom","Svg","Typography","Physics","UI","Play","Image","Svg.SVGSpace","Canvas.CanvasSpace"],"sources":["../src/Op.ts","../src/LinearAlgebra.ts","../src/uheprng.ts","../src/Num.ts","../src/Util.ts","../src/Pt.ts","../src/UI.ts","../src/Space.ts","../src/Form.ts","../src/Typography.ts","../src/Image.ts","../src/Canvas.ts","../src/_triangulate.ts","../src/Create.ts","../src/Color.ts","../src/Dom.ts","../src/Svg.ts","../src/Physics.ts","../src/Play.ts","../src/_script.ts"],"sourcesContent":["/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Util } from \"./Util\";\nimport { Geom, Num } from \"./Num\";\nimport { Pt, Group } from \"./Pt\";\nimport { Mat } from \"./LinearAlgebra\";\nimport {\n type PtLike,\n type GroupLike,\n type PtLikeIterable,\n type IntersectContext,\n type PtIterable,\n} from \"./Types\";\n\nlet _errorLength = (obj: any, param: number | string = \"expected\") =>\n Util.warn(\"Group's length is less than \" + param, obj);\nlet _errorOutofBound = (obj: any, param: number | string = \"\") =>\n Util.warn(`Index ${param} is out of bound in Group`, obj);\n\n/**\n * Line class provides static functions to create and operate on lines. A line is usually represented as a Group of 2 Pts.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Line {\n /**\n * Create a line that originates from an anchor point, given an angle and a magnitude.\n * @param anchor an anchor Pt\n * @param angle an angle in radian\n * @param magnitude magnitude of the line\n * @return a Group of 2 Pts representing a line segement\n */\n static fromAngle(anchor: PtLike, angle: number, magnitude: number): Group {\n let g = new Group(new Pt(anchor), new Pt(anchor));\n g[1].toAngle(angle, magnitude, true);\n return g;\n }\n\n /**\n * Calculate the slope of a line.\n * @param p1 line's first end point\n * @param p2 line's second end point\n */\n static slope(p1: PtLike, p2: PtLike): number | undefined {\n return p2[0] - p1[0] === 0 ? undefined : (p2[1] - p1[1]) / (p2[0] - p1[0]);\n }\n\n /**\n * Calculate the slope and xy intercepts of a line.\n * @param p1 line's first end point\n * @param p2 line's second end point\n * @returns an object with `slope`, `xi`, `yi` properties\n */\n static intercept(\n p1: PtLike,\n p2: PtLike,\n ): { slope: number; xi: number | undefined; yi: number } | undefined {\n if (p2[0] - p1[0] === 0) {\n return undefined;\n } else {\n let m = (p2[1] - p1[1]) / (p2[0] - p1[0]);\n let c = p1[1] - m * p1[0];\n return { slope: m, yi: c, xi: m === 0 ? undefined : -c / m };\n }\n }\n\n /**\n * Given a 2D path and a point, find whether the point is on left or right side of the line.\n * @param line a Group or an Iterable<PtLike> representing a line\n * @param pt a Pt or numeric array\n * @returns a negative value if on left and a positive value if on right. If collinear, then the return value is 0.\n */\n static sideOfPt2D(line: PtLikeIterable, pt: PtLike): number {\n let _line = Util.iterToArray(line);\n return (\n (_line[1][0] - _line[0][0]) * (pt[1] - _line[0][1]) -\n (pt[0] - _line[0][0]) * (_line[1][1] - _line[0][1])\n );\n }\n\n /**\n * Check if three Pts are collinear, ie, on the same straight path.\n * @param p1 first Pt\n * @param p2 second Pt\n * @param p3 third Pt\n * @param threshold a threshold where a smaller value means higher precision threshold for the straight line. Default is 0.01.\n */\n static collinear(\n p1: PtLike,\n p2: PtLike,\n p3: PtLike,\n threshold: number = 0.01,\n ): boolean {\n // Compare the cross product normalized by the segment magnitudes (the\n // sine of the angle between them), so the threshold is scale-free.\n const a = new Pt(0, 0, 0).to(p1).$subtract(p2);\n const b = new Pt(0, 0, 0).to(p1).$subtract(p3);\n const magSq = a.magnitudeSq() * b.magnitudeSq();\n if (magSq === 0) return true; // coincident points are collinear\n return a.$cross(b).magnitudeSq() / magSq <= threshold * threshold;\n }\n\n /**\n * Get magnitude of a line segment.\n * @param line a Group or an Iterable<Pt> with at least 2 Pt\n */\n static magnitude(line: PtIterable): number {\n let _line = Util.iterToArray(line);\n return _line.length >= 2 ? _line[1].$subtract(_line[0]).magnitude() : 0;\n }\n\n /**\n * Get squared magnitude of a line segment.\n * @param line a Group or an Iterable<Pt> with at least 2 Pt\n */\n static magnitudeSq(line: PtIterable): number {\n let _line = Util.iterToArray(line);\n return _line.length >= 2 ? _line[1].$subtract(_line[0]).magnitudeSq() : 0;\n }\n\n /**\n * Find a point on a line that is perpendicular (shortest distance) to a target point.\n * @param line a Group or an Iterable<Pt> that defines a line\n * @param pt a target Pt\n * @param asProjection if true, this returns the projection vector instead. Default is false.\n * @returns a Pt on the line that is perpendicular to the target Pt, or a projection vector if `asProjection` is true.\n */\n static perpendicularFromPt(\n line: PtIterable,\n pt: PtLike,\n asProjection: boolean = false,\n ): Pt | undefined {\n let _line = Util.iterToArray(line);\n if (_line[0].equals(_line[1])) return undefined;\n let a = _line[0].$subtract(_line[1]);\n let b = _line[1].$subtract(pt);\n let proj = b.$subtract(a.$project(b));\n\n return asProjection ? proj : proj.$add(pt);\n }\n\n /**\n * Given a line and a point, find the shortest distance from the point to the line.\n * @param line a Group of 2 Pts\n * @param pt a Pt\n * @see `Line.perpendicularFromPt`\n */\n static distanceFromPt(line: GroupLike, pt: PtLike | number[]): number {\n let _line = Util.iterToArray(line);\n let projectionVector = Line.perpendicularFromPt(_line, pt, true);\n if (projectionVector) {\n return projectionVector.magnitude();\n } else {\n // line is made of 2 identical points, return distance between this point and pt\n return _line[0].$subtract(pt).magnitude();\n }\n }\n\n /**\n * Given two lines as rays (infinite lines), find their intersection point if any.\n * @param la a Group or an Iterable<Pt> with 2 Pt representing a ray\n * @param lb a Group or an Iterable<Pt> with 2 Pts representing another ray\n * @returns an intersection Pt or undefined if no intersection\n */\n static intersectRay2D(la: PtIterable, lb: PtIterable): Pt | undefined {\n const _la = Util.iterToArray(la);\n const _lb = Util.iterToArray(lb);\n\n const pa = _la[0];\n const pb = _lb[0];\n\n // parametric form: no slope blow-up near vertical lines and uniform\n // handling of vertical/horizontal cases\n const rx = _la[1][0] - pa[0];\n const ry = _la[1][1] - pa[1];\n const sx = _lb[1][0] - pb[0];\n const sy = _lb[1][1] - pb[1];\n\n // a zero-length input does not define a ray\n if ((rx === 0 && ry === 0) || (sx === 0 && sy === 0)) return undefined;\n\n const det = rx * sy - ry * sx;\n if (det === 0) {\n // parallel; if collinear, keep legacy behavior of returning la's start\n const qpx = pb[0] - pa[0];\n const qpy = pb[1] - pa[1];\n return qpx * ry - qpy * rx === 0 ? new Pt(pa[0], pa[1]) : undefined;\n }\n\n const t = ((pb[0] - pa[0]) * sy - (pb[1] - pa[1]) * sx) / det;\n return new Pt(pa[0] + t * rx, pa[1] + t * ry);\n }\n\n /**\n * Given two line segemnts, find their intersection point if any.\n * @param la a Group or an Iterable<Pt> with 2 Pt representing a line segment\n * @param lb a Group or an Iterable<Pt> with 2 Pt representing a line segment\n * @returns an intersection Pt or undefined if no intersection\n */\n static intersectLine2D(la: PtIterable, lb: PtIterable): Pt | undefined {\n let _la = Util.iterToArray(la);\n let _lb = Util.iterToArray(lb);\n\n let pt = Line.intersectRay2D(_la, _lb);\n return pt &&\n Geom.withinBound(pt, _la[0], _la[1]) &&\n Geom.withinBound(pt, _lb[0], _lb[1])\n ? pt\n : undefined;\n }\n\n /**\n * Given a line segemnt and a ray (infinite line), find their intersection point if any.\n * @param line a Group of 2 Pts representing a line segment\n * @param ray a Group of 2 Pts representing a ray\n * @returns an intersection Pt or undefined if no intersection\n */\n static intersectLineWithRay2D(\n line: PtIterable,\n ray: PtIterable,\n ): Pt | undefined {\n let _line = Util.iterToArray(line);\n let _ray = Util.iterToArray(ray);\n let pt = Line.intersectRay2D(_line, _ray);\n return pt && Geom.withinBound(pt, _line[0], _line[1]) ? pt : undefined;\n }\n\n /**\n * Given a line segemnt or a ray (infinite line), find its intersection point(s) with a polygon.\n * @param lineOrRay a Group or an Iterable<Pt> with 2 Pt representing a line or ray\n * @param poly a Group or an Iterable<Pt> representing a polygon\n * @param sourceIsRay a boolean value to treat the line as a ray (infinite line). Default is `false`.\n */\n static intersectPolygon2D(\n lineOrRay: PtIterable,\n poly: PtIterable,\n sourceIsRay: boolean = false,\n ): Group | undefined {\n let _lineOrRay = Util.iterToArray(lineOrRay);\n let _poly = Util.iterToArray(poly);\n\n let fn = sourceIsRay ? Line.intersectLineWithRay2D : Line.intersectLine2D;\n let pts = new Group();\n for (let i = 0, len = _poly.length; i < len; i++) {\n let next = i === len - 1 ? 0 : i + 1;\n let d = fn([_poly[i], _poly[next]], _lineOrRay);\n if (d) pts.push(d);\n }\n return pts.length > 0 ? pts : undefined;\n }\n\n /**\n * Find intersection points of 2 sets of lines. This checks all line segments in the two lists. Consider using a bounding-box check before calling this. If you are checking convex polygon intersections, using [`Polygon.intersectPolygon2D`](#link) will be more efficient.\n * @param lines1 an Array/Iterable of (Groups or Iterables<Pt>)\n * @param lines2 an Array/Iterable of (Groups or Iterables<Pt>)\n * @param isRay a boolean value to treat the line as a ray (infinite line). Default is `false`.\n */\n static intersectLines2D(\n lines1: Iterable<PtIterable>,\n lines2: Iterable<PtIterable>,\n isRay: boolean = false,\n ): Group {\n let group = new Group();\n let fn = isRay ? Line.intersectLineWithRay2D : Line.intersectLine2D;\n for (let l1 of lines1) {\n for (let l2 of lines2) {\n let _ip = fn(l1, l2);\n if (_ip) group.push(_ip);\n }\n }\n return group;\n }\n\n /**\n * Get two points of a ray that intersects with a point on a 2D grid.\n * @param ray a Group or an Iterable<Pt> representing a ray\n * @param gridPt a Pt on the grid\n * @returns a group of two intersecting Pts. The first one is horizontal intersection and the second one is vertical intersection.\n */\n static intersectGridWithRay2D(ray: PtIterable, gridPt: PtLike): Group {\n let _ray = Util.iterToArray(ray);\n let t = Line.intercept(\n new Pt(_ray[0]).subtract(gridPt),\n new Pt(_ray[1]).subtract(gridPt),\n );\n let g = new Group();\n if (t && t.xi !== undefined) g.push(new Pt(gridPt[0] + t.xi, gridPt[1]));\n if (t && t.yi !== undefined) g.push(new Pt(gridPt[0], gridPt[1] + t.yi));\n return g;\n }\n\n /**\n * Get two intersection Pts of a line segment with a 2D grid point.\n * @param line a ray specified by 2 Pts\n * @param gridPt a Pt on the grid\n * @returns a group of two intersecting Pts. The first one is horizontal intersection and the second one is vertical intersection.\n */\n static intersectGridWithLine2D(\n line: GroupLike,\n gridPt: PtLike | number[],\n ): Group {\n let _line = Util.iterToArray(line);\n let g = Line.intersectGridWithRay2D(_line, gridPt);\n let gg = new Group();\n for (let i = 0, len = g.length; i < len; i++) {\n if (Geom.withinBound(g[i], _line[0], _line[1])) gg.push(g[i]);\n }\n return gg;\n }\n\n /**\n * An easy way to get rectangle-line intersection points. For more optimized implementation, store the rectangle's sides separately (eg, `Rectangle.sides()`) and use `Polygon.intersectPolygon2D()`.\n * @param line a Group representing a line\n * @param rect a Group representing a rectangle\n * @returns a Group of intersecting Pts\n */\n static intersectRect2D(line: GroupLike, rect: GroupLike): Group {\n let _line = Util.iterToArray(line);\n let _rect = Util.iterToArray(rect);\n let box = Geom.boundingBox(Group.fromPtArray(_line));\n if (!Rectangle.hasIntersectRect2D(box, _rect)) return new Group();\n return Line.intersectLines2D([_line], Rectangle.sides(_rect));\n }\n\n /**\n * Get evenly distributed points on a line. Similar to [`Create.distributeLinear`](#link) but excluding end points.\n * @param line a Group or an Iterable<PtLike> representing a line\n * @param num number of points to get\n */\n static subpoints(line: PtLikeIterable, num: number) {\n let _line = Util.iterToArray(line);\n let pts = new Group();\n for (let i = 1; i <= num; i++) {\n pts.push(Geom.interpolate(_line[0], _line[1], i / (num + 1)));\n }\n return pts;\n }\n\n /**\n * Crop this line by a circle or rectangle at end points. This can be useful for creating arrows that connect to an object's edge.\n * @param line a Group or an Iterable<Pt> representing a line to crop\n * @param size size of circle or rectangle as Pt\n * @param index line's end point index, ie, 0 = start and 1 = end.\n * @param cropAsCircle a boolean to specify whether the `size` parameter should be treated as circle. Default is `true`.\n * @return an intersecting point on the line that can be used for cropping.\n */\n static crop(\n line: PtIterable,\n size: PtLike,\n index: number = 0,\n cropAsCircle: boolean = true,\n ): Pt | undefined {\n let _line = Util.iterToArray(line);\n let tdx = index === 0 ? 1 : 0;\n let ls = _line[tdx].$subtract(_line[index]);\n\n if (ls.magnitudeSq() === 0) return _line[index]; // zero-length line\n\n if (cropAsCircle) {\n let d = ls.unit().multiply(size[1]);\n return _line[index].$add(d);\n } else {\n if (size[0] === 0) return _line[index]; // degenerate rectangle\n let rect = Rectangle.fromCenter(_line[index], size);\n let sides = Rectangle.sides(rect);\n let sideIdx = 0;\n\n if (Math.abs(ls[1] / ls[0]) > Math.abs(size[1] / size[0])) {\n sideIdx = ls[1] < 0 ? 0 : 2;\n } else {\n sideIdx = ls[0] < 0 ? 3 : 1;\n }\n return Line.intersectRay2D(sides[sideIdx], _line);\n }\n }\n\n /**\n * Create an marker arrow or line, placed at an end point of this line.\n * @param line a Group or an Iterable<Pt> representing a line to place marker\n * @param size size of the marker as Pt\n * @param graphic either \"arrow\" or \"line\"\n * @param atTail a boolean, if `true`, the marker will be positioned at tail of the line (ie, index = 1). Default is `true`.\n * @returns a Group that defines the marker's shape\n */\n static marker(\n line: PtIterable,\n size: PtLike,\n graphic: string = \"arrow\",\n atTail: boolean = true,\n ): Group {\n let _line = Util.iterToArray(line);\n let h = atTail ? 0 : 1;\n let t = atTail ? 1 : 0;\n let unit = _line[h].$subtract(_line[t]);\n\n if (unit.magnitudeSq() === 0) return new Group();\n unit.unit();\n\n let ps = Geom.perpendicular(unit).multiply(size[0]).add(_line[t]);\n if (graphic == \"arrow\") {\n ps.add(unit.$multiply(size[1]));\n return new Group(_line[t], ps[0], ps[1]);\n } else {\n return new Group(ps[0], ps[1]);\n }\n }\n\n /**\n * Convert this line to a new rectangle representation.\n * @param line a Group representing a line\n */\n static toRect(line: GroupLike) {\n let _line = Util.iterToArray(line);\n return new Group(_line[0].$min(_line[1]), _line[0].$max(_line[1]));\n }\n}\n\n/**\n * Rectangle class provides static functions to create and operate on rectangles. A rectangle is usually represented as a Group of 2 Pts, marking the top-left and bottom-right corners of the rectangle.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Rectangle {\n /**\n * Create a rectangle from top-left anchor point. Same as [`Rectangle.fromTopLeft`](#link).\n * @param topLeft top-left point\n * @param widthOrSize width as a number, or a Pt that defines its size\n * @param height optional height as a number\n * @returns a Group of 2 Pts representing a rectangle\n */\n static from(\n topLeft: PtLike,\n widthOrSize: number | PtLike,\n height?: number,\n ): Group {\n return Rectangle.fromTopLeft(topLeft, widthOrSize, height);\n }\n\n /**\n * Create a rectangle given a top-left position and a size.\n * @param topLeft top-left point\n * @param widthOrSize width as a number, or a Pt that defines its size\n * @param height optional height as a number\n * @returns a Group of 2 Pts representing a rectangle\n */\n static fromTopLeft(\n topLeft: PtLike,\n widthOrSize: number | PtLike,\n height?: number,\n ): Group {\n let size =\n typeof widthOrSize == \"number\"\n ? [widthOrSize, height ?? widthOrSize]\n : widthOrSize;\n return new Group(new Pt(topLeft), new Pt(topLeft).add(size));\n }\n\n /**\n * Create a rectangle given a center position and a size.\n * @param center center point\n * @param widthOrSize width as a number, or a Pt that defines its size\n * @param height optional height as a number\n * @returns a Group of 2 Pts representing a rectangle\n */\n static fromCenter(\n center: PtLike,\n widthOrSize: number | PtLike,\n height?: number,\n ): Group {\n let half =\n typeof widthOrSize == \"number\"\n ? [widthOrSize / 2, (height ?? widthOrSize) / 2]\n : new Pt(widthOrSize).divide(2);\n return new Group(new Pt(center).subtract(half), new Pt(center).add(half));\n }\n\n /**\n * Create a new circle that either fits within or encloses the rectangle. Same as [`Circle.fromRect`](#link).\n * @param pts a Group or an Iterable<Pt> with 2 Pt representing a rectangle\n * @param enclose if `true`, the circle will enclose the rectangle. If `false`, the circle will fit inside the rectangle.\n * @returns a Group that represents a circle\n */\n static toCircle(pts: PtIterable, enclose: boolean = true): Group {\n return Circle.fromRect(pts, enclose);\n }\n\n /**\n * Create a square that either fits within or encloses a rectangle.\n * @param pts a Group or an Iterable<Pt> with 2 Pt representing a rectangle\n * @param enclose if `true`, the square will enclose the rectangle. Default is `false`, which will fit the square inside the rectangle.\n * @returns a Group of 2 Pts representing a rectangle\n */\n static toSquare(pts: PtIterable, enclose = false): Group {\n let _pts = Util.iterToArray(pts);\n let s = Rectangle.size(_pts);\n let m = enclose ? s.maxValue().value : s.minValue().value;\n return Rectangle.fromCenter(Rectangle.center(_pts), m, m);\n }\n\n /**\n * Get the size of this rectangle as a Pt.\n * @param pts a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n */\n static size(pts: PtIterable): Pt {\n let p = Util.iterToArray(pts);\n return p[0].$max(p[1]).subtract(p[0].$min(p[1]));\n }\n\n /**\n * Get the center of this rectangle.\n * @param pts a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n */\n static center(pts: PtIterable): Pt {\n let p = Util.iterToArray(pts);\n let min = p[0].$min(p[1]);\n let max = p[0].$max(p[1]);\n return min.add(max.$subtract(min).divide(2));\n }\n\n /**\n * Get the 4 corners of this rectangle as a Group.\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n */\n static corners(rect: PtIterable): Group {\n let _rect = Util.iterToArray(rect);\n let p0 = _rect[0].$min(_rect[1]);\n let p2 = _rect[0].$max(_rect[1]);\n return new Group(p0, new Pt(p2.x, p0.y), p2, new Pt(p0.x, p2.y));\n }\n\n /**\n * Get the 4 sides of this rectangle as an array of 4 Groups.\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n * @returns an array of 4 Groups, each of which represents a line segment\n */\n static sides(rect: PtIterable): Group[] {\n let [p0, p1, p2, p3] = Rectangle.corners(rect);\n return [\n new Group(p0, p1),\n new Group(p1, p2),\n new Group(p2, p3),\n new Group(p3, p0),\n ];\n }\n\n /**\n * Given an array of rectangles, get a rectangle that bounds all of them.\n * @param rects an array of (Groups or Iterables<PtLike>) that represents a set of rectangles\n * @returns the bounding rectangle as a Group\n */\n static boundingBox(rects: Iterable<PtLikeIterable>): Group {\n let _rects = Util.iterToArray(rects);\n let merged = Util.flatten(_rects, false);\n if (merged.length === 0) return new Group();\n\n // Infinity, not Number.MAX_VALUE/MIN_VALUE. Pt is a Float32Array, in which\n // MAX_VALUE overflows to Infinity and MIN_VALUE flushes to 0, which would\n // leave the running maximum starting above every negative coordinate.\n let min = Pt.make(2, Infinity);\n let max = Pt.make(2, -Infinity);\n\n // calculate min max in a single pass\n for (let i = 0, len = merged.length; i < len; i++) {\n let p = merged[i];\n let dim = Math.min(2, p.length);\n for (let k = 0; k < dim; k++) {\n min[k] = Math.min(min[k], p[k]);\n max[k] = Math.max(max[k], p[k]);\n }\n }\n return new Group(min, max);\n }\n\n /**\n * Convert this rectangle into a Group representing a polygon. An alias for [`Rectangle.corners`](#link)\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n */\n static polygon(rect: PtIterable): Group {\n return Rectangle.corners(rect);\n }\n\n /**\n * Subdivide a rectangle into 4 rectangles, one for each quadrant.\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n * @returns an array of 4 Groups of rectangles\n */\n static quadrants(rect: PtIterable, center?: PtLike): Group[] {\n let _rect = Util.iterToArray(rect);\n let corners = Rectangle.corners(_rect);\n let _center =\n center != undefined ? new Pt(center) : Rectangle.center(_rect);\n return corners.map((c) => new Group(c, _center).boundingBox());\n }\n\n /**\n * Subdivde a rectangle into 2 rectangles, by row or by column.\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n * @param ratio a value between 0 to 1 to indicate the split ratio\n * @param asRows if `true`, split into 2 rows. Default is `false` which splits into 2 columns.\n * @returns an array of 2 Groups of rectangles\n */\n static halves(\n rect: PtIterable,\n ratio: number = 0.5,\n asRows: boolean = false,\n ): Group[] {\n let _rect = Util.iterToArray(rect);\n let min = _rect[0].$min(_rect[1]);\n let max = _rect[0].$max(_rect[1]);\n let mid = asRows\n ? Num.lerp(min[1], max[1], ratio)\n : Num.lerp(min[0], max[0], ratio);\n return asRows\n ? [\n new Group(min, new Pt(max[0], mid)),\n new Group(new Pt(min[0], mid), max),\n ]\n : [\n new Group(min, new Pt(mid, max[1])),\n new Group(new Pt(mid, min[1]), max),\n ];\n }\n\n /**\n * Check if a point is within a rectangle.\n * @param rect a Group of 2 Pts representing a Rectangle\n * @param pt the point to check\n */\n static withinBound(rect: GroupLike, pt: PtLike): boolean {\n let _rect = Util.iterToArray(rect);\n return Geom.withinBound(pt, _rect[0], _rect[1]);\n }\n\n /**\n * Check if a rectangle is within the bounds of another rectangle.\n * @param rect1 a Group of 2 Pts representing a rectangle\n * @param rect2 a Group of 2 Pts representing a rectangle\n * @param resetBoundingBox if `true`, reset the bounding box. Default is `false` which assumes the rect's first Pt at is its top-left corner.\n */\n static hasIntersectRect2D(\n rect1: GroupLike,\n rect2: GroupLike,\n resetBoundingBox: boolean = false,\n ): boolean {\n let _rect1 = Util.iterToArray(rect1);\n let _rect2 = Util.iterToArray(rect2);\n\n if (resetBoundingBox) {\n _rect1 = Geom.boundingBox(_rect1);\n _rect2 = Geom.boundingBox(_rect2);\n }\n\n if (_rect1[0][0] > _rect2[1][0] || _rect2[0][0] > _rect1[1][0])\n return false;\n if (_rect1[0][1] > _rect2[1][1] || _rect2[0][1] > _rect1[1][1])\n return false;\n return true;\n }\n\n /**\n * An easy way to get rectangle-rectangle intersection points. For more optimized implementation, store the rectangle's sides separately (eg, `Rectangle.sides()`) and use `Polygon.intersectPolygon2D()`.\n * @param rect1 a Group of 2 Pts representing a rectangle\n * @param rect2 a Group of 2 Pts representing a rectangle\n */\n static intersectRect2D(rect1: GroupLike, rect2: GroupLike): Group {\n let _rect1 = Util.iterToArray(rect1);\n let _rect2 = Util.iterToArray(rect2);\n if (!Rectangle.hasIntersectRect2D(_rect1, _rect2)) return new Group();\n return Line.intersectLines2D(\n Rectangle.sides(_rect1),\n Rectangle.sides(_rect2),\n );\n }\n}\n\n/**\n * Circle class provides static functions to create and operate on circles. A circle is usually represented as a Group of 2 Pts, where the first Pt specifies the center, and the second Pt specifies the radius.\n * To move a circle without changing its radius, move only its center, eg `circle[0].to(20, 20)`. Group transforms such as `circle.moveTo(20, 20)` affect both Pts, including the radius.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Circle {\n /**\n * Create a circle that either fits within, or encloses, a rectangle.\n * @param pts a Group or an Iterable<PtLike> with 2 Pt representing a rectangle\n * @param enclose if `true`, the circle will enclose the rectangle. Default is `false`, which will fit the circle inside the rectangle.\n * @returns a Group that represents a circle\n */\n static fromRect(pts: PtLikeIterable, enclose = false): Group {\n let _pts = Util.iterToArray(pts);\n let r = 0;\n let min = (r = Rectangle.size(_pts).minValue().value / 2);\n if (enclose) {\n let max = Rectangle.size(_pts).maxValue().value / 2;\n r = Math.sqrt(min * min + max * max);\n } else {\n r = min;\n }\n return new Group(Rectangle.center(_pts), new Pt(r, r));\n }\n\n /**\n * Create a circle that either fits within, or encloses, a triangle. Same as [`Triangle.circumcircle`](#link) or [`Triangle.incircle`](#link).\n * @param pts a Group or an Iterable<Pt> with 3 Pt representing a rectangle\n * @param enclose if `true`, the circle will enclose the triangle. Default is `false`, which will fit the circle inside the triangle.\n * @returns a Group that represents a circle\n */\n static fromTriangle(\n pts: PtIterable,\n enclose: boolean = false,\n ): Group | undefined {\n if (enclose) {\n return Triangle.circumcircle(pts);\n } else {\n return Triangle.incircle(pts);\n }\n }\n\n /**\n * Create a circle based on a center point and a radius.\n * @param pt center point of circle\n * @param radius radius of circle\n * @returns a Group that represents a circle\n */\n static fromCenter(pt: PtLike, radius: number): Group {\n return new Group(new Pt(pt), new Pt(radius, radius));\n }\n\n /**\n * Check if a point is within a circle.\n * @param pts a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param pt the point to checks\n * @param threshold an optional small number to set threshold. Default is 0.\n */\n static withinBound(\n pts: PtIterable,\n pt: PtLike,\n threshold: number = 0,\n ): boolean {\n let _pts = Util.iterToArray(pts);\n let d = _pts[0].$subtract(pt);\n return d.dot(d) + threshold < _pts[1].x * _pts[1].x;\n }\n\n /**\n * Get the intersection points between a circle and a ray (infinite line).\n * @param circle a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param ray a Group or an Iterable<Pt> with 2 Pt representing a ray\n * @returns a Group of intersection points, or an empty Group if no intersection is found\n */\n static intersectRay2D(circle: PtIterable, ray: PtIterable): Group {\n let _pts = Util.iterToArray(circle);\n let _ray = Util.iterToArray(ray);\n\n let d = _ray[0].$subtract(_ray[1]);\n let f = _pts[0].$subtract(_ray[0]);\n\n let a = d.dot(d);\n if (a === 0) return new Group(); // degenerate ray (two identical points)\n let b = f.dot(d);\n let c = f.dot(f) - _pts[1].x * _pts[1].x;\n let p = b / a;\n let q = c / a;\n let disc = p * p - q; // discriminant\n\n if (disc < 0) {\n return new Group();\n } else {\n let discSqrt = Math.sqrt(disc);\n\n let t1 = -p + discSqrt;\n let p1 = _ray[0].$subtract(d.$multiply(t1));\n if (disc === 0) return new Group(p1);\n\n let t2 = -p - discSqrt;\n let p2 = _ray[0].$subtract(d.$multiply(t2));\n return new Group(p1, p2);\n }\n }\n\n /**\n * Get the intersection points between a circle and a line segment.\n * @param circle a Group or an Iterable<Pt> with Pt representing a circle\n * @param line a Group or an Iterable<Pt> with 2 Pt representing a line\n * @returns a Group of intersection points, or an empty Group if no intersection is found\n */\n static intersectLine2D(circle: PtIterable, line: PtIterable): Group {\n let _pts = Util.iterToArray(circle);\n let _line = Util.iterToArray(line);\n\n let ps = Circle.intersectRay2D(_pts, _line);\n let g = new Group();\n if (ps.length > 0) {\n for (let i = 0, len = ps.length; i < len; i++) {\n if (Rectangle.withinBound(_line, ps[i])) g.push(ps[i]);\n }\n }\n return g;\n }\n\n /**\n * Get the intersection points between two circles.\n * @param circle1 a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param circle2 a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @returns a Group of intersection points, or an empty Group if no intersection is found\n */\n static intersectCircle2D(circle1: PtIterable, circle2: PtIterable): Group {\n let _pts = Util.iterToArray(circle1);\n let _circle = Util.iterToArray(circle2);\n\n let dv = _circle[0].$subtract(_pts[0]);\n let dr2 = dv.magnitudeSq();\n let dr = Math.sqrt(dr2);\n\n let ar = _pts[1].x;\n let br = _circle[1].x;\n let ar2 = ar * ar;\n let br2 = br * br;\n\n if (dr > ar + br) {\n // not intersected\n return new Group();\n } else if (dr < Math.abs(ar - br)) {\n // completely enclosed\n return new Group(_pts[0].clone());\n } else if (dr === 0) {\n // coincident circles: no discrete intersection points\n return new Group();\n } else {\n let a = (ar2 - br2 + dr2) / (2 * dr);\n let h = Math.sqrt(ar2 - a * a);\n let p = dv.$multiply(a / dr).add(_pts[0]);\n return new Group(\n new Pt(p.x + (h * dv.y) / dr, p.y - (h * dv.x) / dr),\n new Pt(p.x - (h * dv.y) / dr, p.y + (h * dv.x) / dr),\n );\n }\n }\n\n /**\n * Quick way to check rectangle intersection with a circle.\n * For more optimized implementation, store the rectangle's sides separately (eg, [`Rectangle.sides`](#link)) and use [`Polygon.intersectPolygon2D()`](#link).\n * @param circle a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a rectangle\n * @returns a Group of intersection points, or an empty Group if no intersection is found\n */\n static intersectRect2D(circle: PtIterable, rect: PtIterable): Group {\n let _pts = Util.iterToArray(circle);\n let _rect = Util.iterToArray(rect);\n\n let sides = Rectangle.sides(_rect);\n let g = [];\n for (let i = 0, len = sides.length; i < len; i++) {\n let ps = Circle.intersectLine2D(_pts, sides[i]);\n if (ps.length > 0) g.push(ps);\n }\n return Util.flatten(g);\n }\n\n /**\n * Get a rectangle that either fits within or encloses this circle. See also [`Rectangle.toCircle`](#link)\n * @param circle a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param within if `true`, the rectangle will be within the circle. If `false`, the rectangle will enclose the circle.\n * @returns a Group representing a rectangle\n */\n static toRect(circle: PtIterable, within: boolean = false): Group {\n let _pts = Util.iterToArray(circle);\n let r = _pts[1][0];\n if (within) {\n // half-side of the maximal inscribed square (its corners on the circle)\n let half = r / Math.SQRT2;\n return new Group(_pts[0].$subtract(half), _pts[0].$add(half));\n } else {\n return new Group(_pts[0].$subtract(r), _pts[0].$add(r));\n }\n }\n\n /**\n * Get a triangle that fits within this circle.\n * @param circle a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param within if `true`, the triangle will be within the circle. If `false`, the triangle will enclose the circle.\n */\n static toTriangle(circle: PtIterable, within: boolean = true): Group {\n let _pts = Util.iterToArray(circle);\n if (within) {\n let ang = -Math.PI / 2;\n let inc = (Math.PI * 2) / 3;\n let g = new Group();\n for (let i = 0; i < 3; i++) {\n g.push(_pts[0].clone().toAngle(ang, _pts[1][0], true));\n ang += inc;\n }\n return g;\n } else {\n return Triangle.fromCenter(_pts[0], _pts[1][0]);\n }\n }\n}\n\n/**\n * Triangle class provides static functions to create and operate on trianges. A triange is a polygon represented as a Group of 3 Pts.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Triangle {\n /**\n * Create a triangle from a rectangle. The triangle will be isosceles, with the bottom of the rectangle as its base.\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a rectangle\n */\n static fromRect(rect: PtIterable): Group {\n let _rect = Util.iterToArray(rect);\n let top = _rect[0].$add(_rect[1]).divide(2);\n top.y = _rect[0][1];\n let left = _rect[1].clone();\n left.x = _rect[0][0];\n return new Group(top, _rect[1].clone(), left);\n }\n\n /**\n * Create a triangle that fits within a circle.\n * @param circle a Group or an Iterable<Pt> with 2 Pt representing a circle\n */\n static fromCircle(circle: PtIterable): Group {\n return Circle.toTriangle(circle, true);\n }\n\n /**\n * Create an equilateral triangle based on a center point and a size.\n * @param pt the center point\n * @param size size is the magnitude of lines from center to the triangle's vertices, like a \"radius\".\n */\n static fromCenter(pt: PtLike, size: number): Group {\n return Triangle.fromCircle(Circle.fromCenter(pt, size));\n }\n\n /**\n * Get the medial, which is an inner triangle formed by connecting the midpoints of this triangle's sides.\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @returns a Group representing a medial triangle\n */\n static medial(tri: PtIterable): Group {\n let _pts = Util.iterToArray(tri);\n if (_pts.length < 3) return _errorLength(new Group(), 3);\n return Polygon.midpoints(_pts, true);\n }\n\n /**\n * Given a point of the triangle, the opposite side is the side which the point doesn't touch.\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @param index a Pt on the triangle group\n * @returns a Group that represents a line of the opposite side\n */\n static oppositeSide(tri: PtIterable, index: number): Group {\n let _pts = Util.iterToArray(tri);\n if (_pts.length < 3) return _errorLength(new Group(), 3);\n if (index === 0) {\n return Group.fromPtArray([_pts[1], _pts[2]]);\n } else if (index === 1) {\n return Group.fromPtArray([_pts[0], _pts[2]]);\n } else {\n return Group.fromPtArray([_pts[0], _pts[1]]);\n }\n }\n\n /**\n * Get a triangle's altitude, which is a line from a triangle's point to its opposite side, and perpendicular to its opposite side.\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @param index a Pt on the triangle group\n * @returns a Group that represents the altitude line\n */\n static altitude(tri: PtIterable, index: number): Group {\n let _pts = Util.iterToArray(tri);\n let opp = Triangle.oppositeSide(_pts, index);\n if (opp.length > 1) {\n return new Group(\n _pts[index],\n Line.perpendicularFromPt(opp, _pts[index])!,\n );\n } else {\n return new Group();\n }\n }\n\n /**\n * Get orthocenter, which is the intersection point of a triangle's 3 altitudes (the 3 lines that are perpendicular to its 3 opposite sides).\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @returns the orthocenter as a Pt\n */\n static orthocenter(tri: PtIterable): Pt | undefined {\n let _pts = Util.iterToArray(tri);\n if (_pts.length < 3) return _errorLength(undefined, 3);\n let a = Triangle.altitude(_pts, 0);\n let b = Triangle.altitude(_pts, 1);\n return Line.intersectRay2D(a, b);\n }\n\n /**\n * Get incenter, which is the center point of its inner circle, and also the intersection point of its 3 angle bisector lines (each of which cuts one of the 3 angles in half).\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @returns the incenter as a Pt\n */\n static incenter(tri: PtIterable): Pt | undefined {\n let _pts = Util.iterToArray(tri);\n if (_pts.length < 3) return _errorLength(undefined, 3);\n let a = Polygon.bisector(_pts, 0)!.add(_pts[0]);\n let b = Polygon.bisector(_pts, 1)!.add(_pts[1]);\n return Line.intersectRay2D(new Group(_pts[0], a), new Group(_pts[1], b));\n }\n\n /**\n * Get an interior circle, which is the largest circle completed enclosed by this triangle.\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @param center Optional parameter if the incenter is already known. Otherwise, leave it empty and the incenter will be calculated\n */\n static incircle(tri: PtIterable, center?: Pt): Group | undefined {\n let _pts = Util.iterToArray(tri);\n let c = center ? center : Triangle.incenter(_pts);\n if (!c) return undefined; // degenerate (collinear) triangle\n let area = Polygon.area(_pts);\n let perim = Polygon.perimeter(_pts, true);\n let r = (2 * area) / perim.total;\n // incenter can still resolve for some collinear orderings; a zero-area\n // triangle has no incircle regardless of point order\n if (!(r > 0)) return undefined;\n return Circle.fromCenter(c, r);\n }\n\n /**\n * Get circumcenter, which is the intersection point of its 3 perpendicular bisectors lines ( each of which divides a side in half and is perpendicular to the side).\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @returns the circumcenter as a Pt\n */\n static circumcenter(tri: PtIterable): Pt | undefined {\n let _pts = Util.iterToArray(tri);\n let md = Triangle.medial(_pts);\n let a = [\n md[0],\n Geom.perpendicular(_pts[0].$subtract(md[0])).p1.$add(md[0]),\n ];\n let b = [\n md[1],\n Geom.perpendicular(_pts[1].$subtract(md[1])).p1.$add(md[1]),\n ];\n return Line.intersectRay2D(a, b);\n }\n\n /**\n * Get circumcenter, which is the intersection point of its 3 perpendicular bisectors lines ( each of which divides a side in half and is perpendicular to the side).\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @param center Optional parameter if the circumcenter is already known. Otherwise, leave it empty and the circumcenter will be calculated\n */\n static circumcircle(tri: PtIterable, center?: Pt): Group | undefined {\n let _pts = Util.iterToArray(tri);\n let c = center ? center : Triangle.circumcenter(_pts);\n if (!c) return undefined; // degenerate (collinear) triangle\n let r = _pts[0].$subtract(c).magnitude();\n return Circle.fromCenter(c, r);\n }\n}\n\n/**\n * Polygon class provides static functions to create and operate on polygons. A polygon is usually represented as a Group of 3 or more Pts.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Polygon {\n /**\n * Get the centroid of a polygon, which is the average of all its points.\n * @param pts a Group or an Iterable<PtLike> representing a polygon\n */\n static centroid(pts: PtLikeIterable): Pt {\n return Geom.centroid(pts);\n }\n\n /**\n * Create a rectangular polygon. Same as creating a Rectangle and then getting its corners via [`Rectangle.corners`](#link).\n * @param center center point of the rectangle\n * @param widthOrSize width as number, or a Pt representing the size of the rectangle\n * @param height optional height\n */\n static rectangle(\n center: PtLike,\n widthOrSize: number | PtLike,\n height?: number,\n ): Group {\n return Rectangle.corners(Rectangle.fromCenter(center, widthOrSize, height));\n }\n\n /**\n * Create a regular polygon.\n * @param center The center position of the polygon\n * @param radius The radius, ie, a length from the center position to one of the polygon's corners.\n * @param sides Number of sides\n */\n static fromCenter(center: PtLike, radius: number, sides: number) {\n let g = new Group();\n for (let i = 0; i < sides; i++) {\n let ang = (Math.PI * 2 * i) / sides;\n g.push(\n new Pt(Math.cos(ang) * radius, Math.sin(ang) * radius).add(center),\n );\n }\n return g;\n }\n\n /**\n * Given a polygon, get one edge using an index.\n * @param pts a Group or an Iterable<PtLike> representing a polygon\n * @param index index of a Pt in the Group\n */\n static lineAt(pts: PtLikeIterable, index: number) {\n let _pts = Util.iterToArray(pts);\n if (index < 0 || index >= _pts.length)\n throw new Error(\"index out of the Polygon's range\");\n return new Group(\n _pts[index],\n index === _pts.length - 1 ? _pts[0] : _pts[index + 1],\n );\n }\n\n /**\n * Get the line segments in this polygon.\n * @param poly a Group or an Iterable<Pt>\n * @param closePath a boolean to specify whether the polygon should be closed (ie, whether the final segment should be counted).\n * @returns an array of Groups which has 2 Pts in each group\n */\n static lines(poly: PtIterable, closePath: boolean = true): Group[] {\n let _pts = Util.iterToArray(poly);\n if (_pts.length < 2) return _errorLength(new Group(), 2);\n // build real Groups; indexed assignment avoids the slow spread through\n // the Array subclass constructor\n const count = closePath ? _pts.length : _pts.length - 1;\n const sp: Group[] = new Array(count);\n for (let i = 0; i < count; i++) {\n const seg = new Group();\n seg[0] = _pts[i];\n seg[1] = _pts[i === _pts.length - 1 ? 0 : i + 1];\n sp[i] = seg;\n }\n return sp;\n }\n\n /**\n * Get a new polygon group that is derived from midpoints in this polygon.\n * @param poly a Group or an Iterable<Pt>\n * @param closePath a boolean to specify whether the polygon should be closed (ie, whether the final segment should be counted).\n * @param t a value between 0 to 1 for interpolation. Default to 0.5 which will get the middle point.\n */\n static midpoints(\n poly: PtIterable,\n closePath: boolean = false,\n t: number = 0.5,\n ): Group {\n const sides = Polygon.lines(poly, closePath);\n const mids = new Group();\n for (let i = 0, len = sides.length; i < len; i++) {\n mids[i] = Geom.interpolate(sides[i][0], sides[i][1], t);\n }\n return mids;\n }\n\n /**\n * Given a Pt in the polygon group, the adjacent sides are the two sides which the Pt touches.\n * @param poly a Group or an Iterable<Pt>\n * @param index the target Pt\n * @param closePath a boolean to specify whether the polygon should be closed (ie, whether the final segment should be counted).\n */\n static adjacentSides(\n poly: PtIterable,\n index: number,\n closePath: boolean = false,\n ): Group[] {\n let _pts = Util.iterToArray(poly);\n if (_pts.length < 2) return _errorLength(new Group(), 2);\n if (index < 0 || index >= _pts.length)\n return _errorOutofBound(new Group(), index);\n\n let gs = [];\n let left = index - 1;\n if (closePath && left < 0) left = _pts.length - 1;\n if (left >= 0) gs.push(new Group(_pts[index], _pts[left]));\n\n let right = index + 1;\n if (closePath && right > _pts.length - 1) right = 0;\n if (right <= _pts.length - 1) gs.push(new Group(_pts[index], _pts[right]));\n\n return gs;\n }\n\n /**\n * Get a bisector which is a line that split between two sides of a polygon equally.\n * @param poly a Group or an Iterable<Pt>\n * @param index the Pt in the polygon to bisect from\n * @returns a bisector direction Pt, the average of the two adjacent sides' unit vectors (not itself normalized)\n */\n static bisector(poly: PtIterable, index: number): Pt | undefined {\n let sides = Polygon.adjacentSides(poly, index, true);\n if (sides.length >= 2) {\n let a = sides[0][1].$subtract(sides[0][0]).unit();\n let b = sides[1][1].$subtract(sides[1][0]).unit();\n return a.add(b).divide(2);\n } else {\n return undefined;\n }\n }\n\n /**\n * Find the perimeter of this polygon, ie, the lengths of its sides.\n * @param poly a Group or an Iterable<Pt>\n * @param closePath a boolean to specify whether the polygon should be closed (ie, whether the final segment should be counted).\n * @returns an object with `total` length, and `segments` which is a Pt that stores each segment's length\n */\n static perimeter(\n poly: PtIterable,\n closePath: boolean = false,\n ): { total: number; segments: Pt } {\n const _pts = Util.iterToArray(poly);\n if (_pts.length < 2) {\n _errorLength(new Group(), 2);\n return { total: 0, segments: Pt.make(0, 0) };\n }\n\n const count = closePath ? _pts.length : _pts.length - 1;\n const p = Pt.make(count, 0);\n let mag = 0;\n\n for (let i = 0; i < count; i++) {\n const a = _pts[i];\n const b = _pts[i === _pts.length - 1 ? 0 : i + 1];\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const m = Math.sqrt(dx * dx + dy * dy);\n mag += m;\n p[i] = m;\n }\n\n return {\n total: mag,\n segments: p,\n };\n }\n\n /**\n * Find the area of a simple (non-self-intersecting) polygon using the shoelace formula.\n * @param pts a Group or an Iterable<PtLike> representing a polygon\n */\n static area(pts: PtLikeIterable): number {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 3) return _errorLength(0, 3);\n // determinant\n let det = (a: PtLike, b: PtLike) => a[0] * b[1] - a[1] * b[0];\n\n let area = 0;\n for (let i = 0, len = _pts.length; i < len; i++) {\n if (i < _pts.length - 1) {\n area += det(_pts[i], _pts[i + 1]);\n } else {\n area += det(_pts[i], _pts[0]);\n }\n }\n return Math.abs(area / 2);\n }\n\n /**\n * Get a convex hull of a set of points, using Melkman's algorithm. ([Reference](http://geomalgorithms.com/a12-_hull-3.html)).\n * @param pts a Group or an Iterable<PtLike>\n * @param sorted a boolean value to indicate if the group is pre-sorted by x position. Default is false.\n * @returns a group of Pt that defines the convex hull polygon\n */\n static convexHull(pts: PtLikeIterable, sorted: boolean = false): Group {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 3) return _errorLength(new Group(), 3);\n\n if (!sorted) {\n _pts = _pts.slice();\n _pts.sort((a, b) => a[0] - b[0]);\n }\n\n // check if is on left of ray a-b\n let left = (a: PtLike, b: PtLike, c: PtLike) => {\n return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]) > 0;\n };\n\n // double end queue\n let dq = [];\n let bot = _pts.length - 2;\n let top = bot + 3;\n dq[bot] = _pts[2];\n dq[top] = _pts[2];\n\n // first 3 pt as counter-clockwise triangle\n if (left(_pts[0], _pts[1], _pts[2])) {\n dq[bot + 1] = _pts[0];\n dq[bot + 2] = _pts[1];\n } else {\n dq[bot + 1] = _pts[1];\n dq[bot + 2] = _pts[0];\n }\n\n // remaining pts\n for (let i = 3, len = _pts.length; i < len; i++) {\n let pt = _pts[i];\n\n // if inside the hull\n if (left(dq[bot], dq[bot + 1], pt) && left(dq[top - 1], dq[top], pt)) {\n continue;\n }\n\n // rightmost tangent\n while (!left(dq[bot], dq[bot + 1], pt)) {\n bot += 1;\n }\n bot -= 1;\n dq[bot] = pt;\n\n // leftmost tangent\n while (!left(dq[top - 1], dq[top], pt)) {\n top -= 1;\n }\n top += 1;\n dq[top] = pt;\n }\n\n let hull = new Group();\n for (let h = 0; h < top - bot; h++) {\n hull.push(dq[bot + h]);\n }\n\n return hull;\n }\n\n /**\n * Given a point in the polygon as an origin, get an array of lines that connect all the remaining points to the origin point.\n * @param poly a Group or an Iterable<Pt> representing a polygon\n * @param originIndex the origin point's index in the polygon\n * @returns an array of Groups of line segments\n */\n static network(poly: PtIterable, originIndex: number = 0): Group[] {\n let _pts = Util.iterToArray(poly);\n let g = [];\n for (let i = 0, len = _pts.length; i < len; i++) {\n if (i != originIndex) g.push(new Group(_pts[originIndex], _pts[i]));\n }\n return g;\n }\n\n /**\n * Given a target Pt, find a Pt in the polygon's corners that's nearest to it.\n * @param poly a Group or an Iterable<Pt>\n * @param pt Pt to check\n * @returns an index in the pts indicating the nearest Pt, or -1 if none found\n */\n static nearestPt(poly: PtIterable, pt: PtLike): number {\n const _poly = Util.iterToArray(poly);\n const px = pt[0];\n const py = pt[1];\n let _near = Number.MAX_VALUE;\n let _item = -1;\n for (let i = 0, len = _poly.length; i < len; i++) {\n const dx = _poly[i][0] - px;\n const dy = _poly[i][1] - py;\n const d = dx * dx + dy * dy;\n if (d < _near) {\n _near = d;\n _item = i;\n }\n }\n return _item;\n }\n\n /**\n * Project axis (eg, for use in Separation Axis Theorem).\n * @param poly a Group or an Iterable<Pt>\n * @param unitAxis unit axis for calculating dot product\n */\n static projectAxis(poly: PtIterable, unitAxis: Pt): Pt {\n let _poly = Util.iterToArray(poly);\n let min = unitAxis.dot(_poly[0]);\n let max = min;\n for (let n = 1, len = _poly.length; n < len; n++) {\n const dot = unitAxis.dot(_poly[n]);\n if (dot < min) min = dot;\n else if (dot > max) max = dot;\n }\n return new Pt(min, max);\n }\n\n /**\n * Scalar core of the axis-overlap test used by the SAT functions: project both polygons on\n * the unit axis (ax, ay) and return the gap between the intervals (negative means overlap).\n */\n private static _axisOverlap2D(\n poly1: Pt[],\n poly2: Pt[],\n ax: number,\n ay: number,\n ): number {\n let min1 = ax * poly1[0][0] + ay * poly1[0][1];\n let max1 = min1;\n for (let n = 1, len = poly1.length; n < len; n++) {\n const d = ax * poly1[n][0] + ay * poly1[n][1];\n if (d < min1) min1 = d;\n else if (d > max1) max1 = d;\n }\n let min2 = ax * poly2[0][0] + ay * poly2[0][1];\n let max2 = min2;\n for (let n = 1, len = poly2.length; n < len; n++) {\n const d = ax * poly2[n][0] + ay * poly2[n][1];\n if (d < min2) min2 = d;\n else if (d > max2) max2 = d;\n }\n return min1 < min2 ? min2 - max1 : min1 - max2;\n }\n\n /**\n * Check overlap distance from projected axis.\n * @param poly1 a Group or an Iterable<Pt> representing the first polygon\n * @param poly2 a Group or an Iterable<Pt> representing the second polygon\n * @param unitAxis unit axis\n */\n protected static _axisOverlap(\n poly1: PtIterable,\n poly2: PtIterable,\n unitAxis: Pt,\n ) {\n let pa = Polygon.projectAxis(poly1, unitAxis);\n let pb = Polygon.projectAxis(poly2, unitAxis);\n return pa[0] < pb[0] ? pb[0] - pa[1] : pa[0] - pb[1];\n }\n\n /**\n * Check if a Pt is inside a convex polygon.\n * @param poly a Group or an Iterable<PtLike> representing a convex polygon\n * @param pt the Pt to check\n */\n static hasIntersectPoint(poly: PtLikeIterable, pt: PtLike): boolean {\n const _poly = Util.iterToArray(poly);\n const px = pt[0];\n const py = pt[1];\n let c = false;\n // same ray-cast as before, without a Group allocation per edge\n for (let i = 0, len = _poly.length; i < len; i++) {\n const a = _poly[i];\n const b = _poly[i === len - 1 ? 0 : i + 1];\n if (\n a[1] > py != b[1] > py &&\n px < ((b[0] - a[0]) * (py - a[1])) / (b[1] - a[1]) + a[0]\n ) {\n c = !c;\n }\n }\n return c;\n }\n\n /**\n * Check if a convex polygon and a circle has intersections using Separating Axis Theorem.\n * @param poly a Group or an Iterable<Pt> representing a convex polygon\n * @param circle a Group or an Iterable<Pt> representing a circle\n * @returns an `IntersectContext` object that stores the intersection info, or undefined if there's no intersection\n */\n static hasIntersectCircle(\n poly: PtIterable,\n circle: PtIterable,\n ): IntersectContext | null {\n let _poly = Util.iterToArray(poly);\n let _circle = Util.iterToArray(circle);\n\n const c = _circle[0];\n const r = _circle[1][0];\n\n // AABB pre-reject against the circle's bounding box. The corner cases this\n // skips are exactly those the perpendicular-foot check below would reject.\n let bx0 = Infinity;\n let by0 = Infinity;\n let bx1 = -Infinity;\n let by1 = -Infinity;\n for (let i = 0, len = _poly.length; i < len; i++) {\n const p = _poly[i];\n if (p[0] < bx0) bx0 = p[0];\n if (p[0] > bx1) bx1 = p[0];\n if (p[1] < by0) by0 = p[1];\n if (p[1] > by1) by1 = p[1];\n }\n if (c[0] + r < bx0 || c[0] - r > bx1 || c[1] + r < by0 || c[1] - r > by1) {\n return null;\n }\n\n let minDist = Number.MAX_SAFE_INTEGER;\n let minEdge: Group | null = null;\n let minAx = 0;\n let minAy = 0;\n let which = -1;\n\n for (let i = 0, len = _poly.length; i < len; i++) {\n const ea = _poly[i];\n const eb = _poly[i === len - 1 ? 0 : i + 1];\n let ax = ea[1] - eb[1]; // unit perpendicular of the edge\n let ay = eb[0] - ea[0];\n const alen = Math.sqrt(ax * ax + ay * ay);\n if (alen === 0) continue; // degenerate edge (duplicate points)\n ax /= alen;\n ay /= alen;\n\n // the circle projects onto the axis as [center·axis − r, center·axis + r]\n let minP = ax * _poly[0][0] + ay * _poly[0][1];\n let maxP = minP;\n for (let n = 1; n < len; n++) {\n const d = ax * _poly[n][0] + ay * _poly[n][1];\n if (d < minP) minP = d;\n else if (d > maxP) maxP = d;\n }\n const dotC = ax * c[0] + ay * c[1];\n const dist = minP < dotC - r ? dotC - r - maxP : minP - (dotC + r);\n\n if (dist > 0) {\n return null;\n } else if (Math.abs(dist) < minDist) {\n // Fix edge case and make sure the circle is intersecting. To be improved.\n const edge = Polygon.lineAt(_poly, i);\n const check =\n Rectangle.withinBound(edge, Line.perpendicularFromPt(edge, c)!) ||\n Circle.intersectLine2D(_circle, edge).length > 0;\n\n if (check) {\n minEdge = edge;\n minAx = ax;\n minAy = ay;\n minDist = Math.abs(dist);\n which = i;\n }\n }\n }\n\n if (!minEdge) return null;\n\n // Edge normals alone miss the case where the circle sits past a vertex:\n // the separating axis there runs from the nearest vertex to the center.\n let vx = 0;\n let vy = 0;\n let vd = Infinity;\n for (let i = 0, len = _poly.length; i < len; i++) {\n const dx = c[0] - _poly[i][0];\n const dy = c[1] - _poly[i][1];\n const d = dx * dx + dy * dy;\n if (d < vd) {\n vd = d;\n vx = dx;\n vy = dy;\n }\n }\n if (vd > 0) {\n const vlen = Math.sqrt(vd);\n vx /= vlen;\n vy /= vlen;\n let minP = Infinity;\n let maxP = -Infinity;\n for (let i = 0, len = _poly.length; i < len; i++) {\n const d = vx * _poly[i][0] + vy * _poly[i][1];\n if (d < minP) minP = d;\n if (d > maxP) maxP = d;\n }\n const dotC = vx * c[0] + vy * c[1];\n if (dotC - r > maxP || dotC + r < minP) return null;\n }\n\n // direction\n const centroid = Polygon.centroid(_poly);\n if (minAx * (c[0] - centroid[0]) + minAy * (c[1] - centroid[1]) < 0) {\n minAx = -minAx;\n minAy = -minAy;\n }\n\n return {\n which,\n dist: minDist,\n normal: new Pt(minAx, minAy),\n edge: minEdge,\n vertex: c,\n };\n }\n\n /**\n * Check if two convex polygons have intersections using Separating Axis Theorem.\n * @param poly1 a Group or an Iterable<Pt> representing a convex polygon\n * @param poly2 a Group or an Iterable<Pt> representing another convex polygon\n * @return an `IntersectContext` object that stores the intersection info, or undefined if there's no intersection\n */\n static hasIntersectPolygon(\n poly1: PtIterable,\n poly2: PtIterable,\n ): IntersectContext | null {\n // Reference: https://www.gamedev.net/articles/programming/math-and-physics/a-verlet-based-approach-for-2d-game-physics-r2714/\n let _poly1 = Util.iterToArray(poly1);\n let _poly2 = Util.iterToArray(poly2);\n const len1 = _poly1.length;\n const len2 = _poly2.length;\n\n // AABB pre-reject: for convex polygons, disjoint bounding boxes guarantee\n // that a separating edge normal exists, so the axis scan can be skipped\n let ax0 = Infinity;\n let ay0 = Infinity;\n let ax1 = -Infinity;\n let ay1 = -Infinity;\n for (let i = 0; i < len1; i++) {\n const p = _poly1[i];\n if (p[0] < ax0) ax0 = p[0];\n if (p[0] > ax1) ax1 = p[0];\n if (p[1] < ay0) ay0 = p[1];\n if (p[1] > ay1) ay1 = p[1];\n }\n let bx0 = Infinity;\n let by0 = Infinity;\n let bx1 = -Infinity;\n let by1 = -Infinity;\n for (let i = 0; i < len2; i++) {\n const p = _poly2[i];\n if (p[0] < bx0) bx0 = p[0];\n if (p[0] > bx1) bx1 = p[0];\n if (p[1] < by0) by0 = p[1];\n if (p[1] > by1) by1 = p[1];\n }\n if (ax0 > bx1 || bx0 > ax1 || ay0 > by1 || by0 > ay1) return null;\n\n // scan all edge normals as separating axes, tracking the smallest overlap\n let minDist = Number.MAX_SAFE_INTEGER;\n let minIndex = -1;\n let minAx = 0;\n let minAy = 0;\n\n for (let i = 0, plen = len1 + len2; i < plen; i++) {\n const src = i < len1 ? _poly1 : _poly2;\n const ei = i < len1 ? i : i - len1;\n const ea = src[ei];\n const eb = src[ei === src.length - 1 ? 0 : ei + 1];\n let ax = ea[1] - eb[1]; // unit perpendicular of the edge\n let ay = eb[0] - ea[0];\n const alen = Math.sqrt(ax * ax + ay * ay);\n if (alen === 0) continue; // degenerate edge (duplicate points)\n ax /= alen;\n ay /= alen;\n\n const dist = Polygon._axisOverlap2D(_poly1, _poly2, ax, ay);\n if (dist > 0) {\n return null;\n } else if (Math.abs(dist) < minDist) {\n minDist = Math.abs(dist);\n minIndex = i;\n minAx = ax;\n minAy = ay;\n }\n }\n\n if (minIndex < 0) return null;\n\n const which = minIndex < len1 ? 0 : 1;\n const edge =\n which === 0\n ? Polygon.lineAt(_poly1, minIndex)\n : Polygon.lineAt(_poly2, minIndex - len1);\n\n // flip if needed to make sure vertex and edge are in corresponding polygons\n const b1 = which === 0 ? _poly2 : _poly1;\n const b2 = which === 0 ? _poly1 : _poly2;\n\n const c1 = Polygon.centroid(b1);\n const c2 = Polygon.centroid(b2);\n\n // direction\n if (minAx * (c1[0] - c2[0]) + minAy * (c1[1] - c2[1]) < 0) {\n minAx = -minAx;\n minAy = -minAy;\n }\n\n // find vertex at smallest distance\n let smallest = Number.MAX_SAFE_INTEGER;\n let vertex: Pt = null!;\n for (let i = 0, len = b1.length; i < len; i++) {\n const d = minAx * (b1[i][0] - c2[0]) + minAy * (b1[i][1] - c2[1]);\n if (d < smallest) {\n smallest = d;\n vertex = b1[i];\n }\n }\n\n return {\n which,\n dist: minDist,\n normal: new Pt(minAx, minAy),\n edge,\n vertex,\n };\n }\n\n /**\n * Find intersection points of 2 polygons by checking every side of both polygons. Performance may be slow for complex polygons.\n * @param poly1 a Group or an Iterable<Pt> representing a polygon\n * @param poly2 a Group or an Iterable<Pt> representing another polygon\n */\n static intersectPolygon2D(poly1: PtIterable, poly2: PtIterable): Group {\n let _poly1 = Util.iterToArray(poly1);\n let _poly2 = Util.iterToArray(poly2);\n\n let lp = Polygon.lines(_poly1);\n let g = [];\n for (let i = 0, len = lp.length; i < len; i++) {\n let ins = Line.intersectPolygon2D(lp[i], _poly2, false);\n if (ins) g.push(ins);\n }\n return Util.flatten(g, true) as Group;\n }\n\n /**\n * Get a bounding box for each polygon group, as well as a union bounding-box for all groups.\n * @param polys an Array/Iterable of (Groups or Iterables<Pt>)\n */\n static toRects(polys: Iterable<PtIterable>): Group[] {\n let boxes = [];\n for (let g of polys) {\n boxes.push(Geom.boundingBox(g));\n }\n\n let merged = Util.flatten(boxes, false);\n boxes.unshift(Geom.boundingBox(merged));\n return boxes;\n }\n}\n\n/**\n * Curve class provides static functions to interpolate curves. A curve is usually represented as a Group of 3 or more control points.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Curve {\n /**\n * Get a precalculated coefficients per step.\n * @param steps number of steps\n */\n static getSteps(steps: number): Group {\n let ts = new Group();\n for (let i = 0; i <= steps; i++) {\n let t = i / steps;\n ts.push(new Pt(t * t * t, t * t, t, 1));\n }\n return ts;\n }\n\n /**\n * Given an index for the starting position in a Pt group, get the control and/or end points of a curve segment.\n * @param pts a Group or an Iterable<PtLike>\n * @param index start index in `pts` array. Default is 0.\n * @param copyStart an optional boolean value to indicate if the start index should be used twice. Default is false.\n * @returns a group of 4 Pts\n */\n static controlPoints(\n pts: PtLikeIterable,\n index: number = 0,\n copyStart: boolean = false,\n ): Group {\n let _pts = Util.iterToArray(pts);\n\n if (index > _pts.length - 1) return new Group();\n let _index = (i: number) => (i < _pts.length - 1 ? i : _pts.length - 1);\n\n let p0 = _pts[index];\n index = copyStart ? index : index + 1;\n\n // get points based on index\n return new Group(\n p0,\n _pts[_index(index++)],\n _pts[_index(index++)],\n _pts[_index(index++)],\n );\n }\n\n /**\n * Build a per-step table of the 4 control-point weights for a curve family.\n * Computing these once per call (instead of a matrix product per output\n * point) is what makes the curve functions fast.\n */\n private static _weights(\n steps: number,\n fill: (t: number, out: Float64Array, o: number) => void,\n ): Float64Array {\n const w = new Float64Array((steps + 1) * 4);\n for (let i = 0; i <= steps; i++) {\n fill(i / steps, w, i * 4);\n }\n return w;\n }\n\n /**\n * Evaluate one curve segment with a precomputed weight table, pushing one\n * interpolated Pt per step into `out`. Control values are read by index so\n * both Pts and plain arrays work.\n */\n private static _evalSegment(\n out: Group,\n c: GroupLike,\n w: Float64Array,\n steps: number,\n ): void {\n const c0 = c[0];\n const c1 = c[1];\n const c2 = c[2];\n const c3 = c[3];\n const dim3 = c0.length > 2;\n for (let i = 0; i <= steps; i++) {\n const o = i * 4;\n const w0 = w[o];\n const w1 = w[o + 1];\n const w2 = w[o + 2];\n const w3 = w[o + 3];\n const x = w0 * c0[0] + w1 * c1[0] + w2 * c2[0] + w3 * c3[0];\n const y = w0 * c0[1] + w1 * c1[1] + w2 * c2[1] + w3 * c3[1];\n out.push(\n dim3\n ? new Pt(x, y, w0 * c0[2] + w1 * c1[2] + w2 * c2[2] + w3 * c3[2])\n : new Pt(x, y),\n );\n }\n }\n\n /**\n * Calulcate weighted sum to get the interpolated points.\n * @param ctrls anchors\n * @param params parameters\n */\n static _calcPt(ctrls: GroupLike, params: PtLike): Pt {\n let x = ctrls.reduce((a, c, i) => a + c.x * params[i], 0);\n let y = ctrls.reduce((a, c, i) => a + c.y * params[i], 0);\n if (ctrls[0].length > 2) {\n let z = ctrls.reduce((a, c, i) => a + c.z * params[i], 0);\n return new Pt(x, y, z);\n }\n return new Pt(x, y);\n }\n\n /**\n * Weighted sum of 4 control points with scalar weights — the shared core\n * of the single-point step functions, kept consistent with the batch\n * `_weights` tables by construction.\n */\n private static _stepPt(\n ctrls: GroupLike,\n w0: number,\n w1: number,\n w2: number,\n w3: number,\n ): Pt {\n const c0 = ctrls[0];\n const c1 = ctrls[1];\n const c2 = ctrls[2];\n const c3 = ctrls[3];\n const x = w0 * c0[0] + w1 * c1[0] + w2 * c2[0] + w3 * c3[0];\n const y = w0 * c0[1] + w1 * c1[1] + w2 * c2[1] + w3 * c3[1];\n return c0.length > 2\n ? new Pt(x, y, w0 * c0[2] + w1 * c1[2] + w2 * c2[2] + w3 * c3[2])\n : new Pt(x, y);\n }\n\n /**\n * Create a Catmull-Rom curve. Catmull-Rom is a kind of smooth-looking Cardinal curve.\n * @param pts a Group or an Iterable<PtLike>\n * @param steps the number of line segments per curve. Defaults to 10 steps\n * @returns a curve as a group of interpolated Pt\n */\n static catmullRom(pts: PtLikeIterable, steps: number = 10): Group {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 2) return new Group();\n\n let ps = new Group();\n const w = Curve._weights(steps, (t, out, o) => {\n const t2 = t * t;\n const t3 = t2 * t;\n out[o] = -0.5 * t3 + t2 - 0.5 * t;\n out[o + 1] = 1.5 * t3 - 2.5 * t2 + 1;\n out[o + 2] = -1.5 * t3 + 2 * t2 + 0.5 * t;\n out[o + 3] = 0.5 * t3 - 0.5 * t2;\n });\n\n // use first point twice\n Curve._evalSegment(ps, Curve.controlPoints(_pts, 0, true), w, steps);\n\n let k = 0;\n while (k < _pts.length - 2) {\n let cp = Curve.controlPoints(_pts, k);\n if (cp.length > 0) {\n Curve._evalSegment(ps, cp, w, steps);\n k++;\n }\n }\n\n return ps;\n }\n\n /**\n * Interpolate to get a point on Catmull-Rom curve.\n * @param step the coefficients [t*t*t, t*t, t, 1]\n * @param ctrls a group of anchor Pts\n * @return an interpolated Pt on the curve\n */\n static catmullRomStep(step: Pt, ctrls: GroupLike): Pt {\n // same coefficients as the batch `catmullRom` weight table\n const t3 = step[0];\n const t2 = step[1];\n const t = step[2];\n return Curve._stepPt(\n ctrls,\n -0.5 * t3 + t2 - 0.5 * t,\n 1.5 * t3 - 2.5 * t2 + 1,\n -1.5 * t3 + 2 * t2 + 0.5 * t,\n 0.5 * t3 - 0.5 * t2,\n );\n }\n\n /**\n * Create a Cardinal curve.\n * @param pts a Group or an Iterable<PtLike>\n * @param steps the number of line segments per curve. Defaults to 10 steps.\n * @param tension optional value between 0 to 1 to specify a \"tension\". Default to 0.5 which is the tension for Catmull-Rom curve.\n * @returns a curve as a group of interpolated Pt\n */\n static cardinal(\n pts: PtLikeIterable,\n steps: number = 10,\n tension = 0.5,\n ): Group {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 2) return new Group();\n\n let ps = new Group();\n const w = Curve._weights(steps, (t, out, o) => {\n const t2 = t * t;\n const t3 = t2 * t;\n out[o] = tension * (-t3 + 2 * t2 - t);\n out[o + 1] = tension * (-t3 + t2) + (2 * t3 - 3 * t2 + 1);\n out[o + 2] = tension * (t3 - 2 * t2 + t) + (-2 * t3 + 3 * t2);\n out[o + 3] = tension * (t3 - t2);\n });\n\n // use first point twice\n Curve._evalSegment(ps, Curve.controlPoints(_pts, 0, true), w, steps);\n\n let k = 0;\n while (k < _pts.length - 2) {\n let cp = Curve.controlPoints(_pts, k);\n if (cp.length > 0) {\n Curve._evalSegment(ps, cp, w, steps);\n k++;\n }\n }\n\n return ps;\n }\n\n /**\n * Interpolate to get a point on Cardinal curve.\n * @param step the coefficients [t*t*t, t*t, t, 1]\n * @param ctrls a group of anchor Pts\n * @param tension optional value between 0 to 1 to specify a \"tension\". Default to 0.5 which is the tension for Catmull-Rom curve\n * @return an interpolated Pt on the curve\n */\n static cardinalStep(step: Pt, ctrls: GroupLike, tension: number = 0.5): Pt {\n // same coefficients as the batch `cardinal` weight table\n const t3 = step[0];\n const t2 = step[1];\n const t = step[2];\n return Curve._stepPt(\n ctrls,\n tension * (-t3 + 2 * t2 - t),\n tension * (-t3 + t2) + (2 * t3 - 3 * t2 + 1),\n tension * (t3 - 2 * t2 + t) + (-2 * t3 + 3 * t2),\n tension * (t3 - t2),\n );\n }\n\n /**\n * Create a Bezier curve. In a cubic bezier curve, the first and 4th anchors are end-points, and 2nd and 3rd anchors are control-points.\n * @param pts a group of anchor Pt\n * @param steps the number of line segments per curve. Defaults to 10 steps.\n * @returns a curve as a group of interpolated Pt\n */\n static bezier(pts: GroupLike, steps: number = 10) {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 4) return new Group();\n\n let ps = new Group();\n const w = Curve._weights(steps, (t, out, o) => {\n const t2 = t * t;\n const t3 = t2 * t;\n out[o] = -t3 + 3 * t2 - 3 * t + 1;\n out[o + 1] = 3 * t3 - 6 * t2 + 3 * t;\n out[o + 2] = -3 * t3 + 3 * t2;\n out[o + 3] = t3;\n });\n\n let k = 0;\n while (k < _pts.length - 3) {\n let c = Curve.controlPoints(_pts, k);\n if (c.length > 0) {\n Curve._evalSegment(ps, c, w, steps);\n\n // go to the next set of point, but assume current end pt is next start pt\n k += 3;\n }\n }\n\n return ps;\n }\n\n /**\n * Interpolate to get a point on a cubic Bezier curve.\n * @param step the coefficients [t*t*t, t*t, t, 1]\n * @param ctrls a group of anchor Pts\n * @return an interpolated Pt on the curve\n */\n static bezierStep(step: Pt, ctrls: GroupLike) {\n // same coefficients as the batch `bezier` weight table\n const t3 = step[0];\n const t2 = step[1];\n const t = step[2];\n return Curve._stepPt(\n ctrls,\n -t3 + 3 * t2 - 3 * t + 1,\n 3 * t3 - 6 * t2 + 3 * t,\n -3 * t3 + 3 * t2,\n t3,\n );\n }\n\n /**\n * Create a basis spline (NURBS) curve.\n * @param pts a group of anchor Pt\n * @param steps the number of line segments per curve. Defaults to 10 steps.\n * @param tension optional value between 0 to n to specify a \"tension\". Default is 1 which is the usual tension.\n * @returns a curve as a group of interpolated Pt\n */\n static bspline(\n pts: GroupLike,\n steps: number = 10,\n tension: number = 1,\n ): Group {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 2) return new Group();\n\n let ps = new Group();\n const w =\n tension !== 1\n ? Curve._weights(steps, (t, out, o) => {\n const t2 = t * t;\n const t3 = t2 * t;\n const b1 = 2 * t3 - 3 * t2 + 1;\n const b2 = -2 * t3 + 3 * t2;\n out[o] = tension * (-t3 / 6 + 0.5 * t2 - 0.5 * t + 1 / 6);\n out[o + 1] = tension * (-1.5 * t3 + 2 * t2 - 1 / 3) + b1;\n out[o + 2] = tension * (1.5 * t3 - 2.5 * t2 + 0.5 * t + 1 / 6) + b2;\n out[o + 3] = tension * (t3 / 6);\n })\n : Curve._weights(steps, (t, out, o) => {\n const t2 = t * t;\n const t3 = t2 * t;\n out[o] = -t3 / 6 + 0.5 * t2 - 0.5 * t + 1 / 6;\n out[o + 1] = 0.5 * t3 - t2 + 2 / 3;\n out[o + 2] = -0.5 * t3 + 0.5 * t2 + 0.5 * t + 1 / 6;\n out[o + 3] = t3 / 6;\n });\n\n let k = 0;\n while (k < _pts.length - 3) {\n let c = Curve.controlPoints(_pts, k);\n if (c.length > 0) {\n Curve._evalSegment(ps, c, w, steps);\n k++;\n }\n }\n\n return ps;\n }\n\n /**\n * Interpolate to get a point on a basis spline curve.\n * @param step the coefficients [t*t*t, t*t, t, 1]\n * @param ctrls a group of anchor Pts\n * @return an interpolated Pt on the curve\n */\n static bsplineStep(step: Pt, ctrls: GroupLike): Pt {\n // same coefficients as the batch `bspline` weight table\n const t3 = step[0];\n const t2 = step[1];\n const t = step[2];\n return Curve._stepPt(\n ctrls,\n -t3 / 6 + 0.5 * t2 - 0.5 * t + 1 / 6,\n 0.5 * t3 - t2 + 2 / 3,\n -0.5 * t3 + 0.5 * t2 + 0.5 * t + 1 / 6,\n t3 / 6,\n );\n }\n\n /**\n * Interpolate to get a point on a basis spline curve with tension.\n * @param step the coefficients [t*t*t, t*t, t, 1]\n * @param ctrls a group of anchor Pts\n * @param tension optional value between 0 to n to specify a \"tension\". Default to 1 which is the usual tension.\n * @return an interpolated Pt on the curve\n */\n static bsplineTensionStep(\n step: Pt,\n ctrls: GroupLike,\n tension: number = 1,\n ): Pt {\n // same coefficients as the batch `bspline` tension weight table\n const t3 = step[0];\n const t2 = step[1];\n const t = step[2];\n const b1 = 2 * t3 - 3 * t2 + 1;\n const b2 = -2 * t3 + 3 * t2;\n return Curve._stepPt(\n ctrls,\n tension * (-t3 / 6 + 0.5 * t2 - 0.5 * t + 1 / 6),\n tension * (-1.5 * t3 + 2 * t2 - 1 / 3) + b1,\n tension * (1.5 * t3 - 2.5 * t2 + 0.5 * t + 1 / 6) + b2,\n tension * (t3 / 6),\n );\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Group } from \"./Pt\";\nimport { Line } from \"./Op\";\nimport { type PtLike, type GroupLike } from \"./Types\";\n\n/**\n * Vec provides various static functions for vector operations. It's not fully optimized but good enough to use.\n */\nexport class Vec {\n /**\n * Add `b` to vector `a`. Unlike `multiply`/`divide`, a shorter `b` is tolerated: missing (or NaN) dimensions are treated as 0.\n * @returns vector `a`\n */\n static add(a: PtLike, b: PtLike | number): PtLike {\n if (typeof b == \"number\") {\n for (let i = 0, len = a.length; i < len; i++) a[i] += b;\n } else {\n for (let i = 0, len = a.length; i < len; i++) a[i] += b[i] || 0;\n }\n return a;\n }\n\n /**\n * Subtract `b` from vector `a`. Unlike `multiply`/`divide`, a shorter `b` is tolerated: missing (or NaN) dimensions are treated as 0.\n * @returns vector `a`\n */\n static subtract(a: PtLike, b: PtLike | number): PtLike {\n if (typeof b == \"number\") {\n for (let i = 0, len = a.length; i < len; i++) a[i] -= b;\n } else {\n for (let i = 0, len = a.length; i < len; i++) a[i] -= b[i] || 0;\n }\n return a;\n }\n\n /**\n * Multiply `b` with vector `a`.\n * @returns vector `a`\n */\n static multiply(a: PtLike, b: PtLike | number): PtLike {\n if (typeof b == \"number\") {\n for (let i = 0, len = a.length; i < len; i++) a[i] *= b;\n } else {\n if (a.length != b.length) {\n throw new Error(\n `Cannot do element-wise multiply since the array lengths don't match: ${a.toString()} multiply-with ${b.toString()}`,\n );\n }\n for (let i = 0, len = a.length; i < len; i++) a[i] *= b[i];\n }\n return a;\n }\n\n /**\n * Divide `a` over `b`.\n * @returns vector `a`\n */\n static divide(a: PtLike, b: PtLike | number): PtLike {\n if (typeof b == \"number\") {\n if (b === 0) throw new Error(\"Cannot divide by zero\");\n for (let i = 0, len = a.length; i < len; i++) a[i] /= b;\n } else {\n if (a.length != b.length) {\n throw new Error(\n `Cannot do element-wise divide since the array lengths don't match. ${a.toString()} divide-by ${b.toString()}`,\n );\n }\n for (let i = 0, len = a.length; i < len; i++) a[i] /= b[i];\n }\n return a;\n }\n\n /**\n * Dot product of `a` and `b`.\n */\n static dot(a: PtLike, b: PtLike): number {\n if (a.length != b.length) throw new Error(\"Array lengths don't match\");\n let d = 0;\n for (let i = 0, len = a.length; i < len; i++) {\n d += a[i] * b[i];\n }\n return d;\n }\n\n /**\n * 2D cross product of `a` and `b`.\n */\n static cross2D(a: PtLike, b: PtLike): number {\n return a[0] * b[1] - a[1] * b[0];\n }\n\n /**\n * 3D Cross product of `a` and `b`.\n */\n static cross(a: PtLike, b: PtLike): Pt {\n return new Pt(\n a[1] * b[2] - a[2] * b[1],\n a[2] * b[0] - a[0] * b[2],\n a[0] * b[1] - a[1] * b[0],\n );\n }\n\n /**\n * Magnitude of `a`.\n */\n static magnitude(a: PtLike): number {\n return Math.sqrt(Vec.dot(a, a));\n }\n\n /**\n * Unit vector of `a`. If magnitude of `a` is already known, pass it in the second paramter to optimize calculation.\n */\n static unit(a: PtLike, magnitude: number | undefined = undefined): PtLike {\n const m = magnitude === undefined ? Vec.magnitude(a) : magnitude;\n if (m === 0) return a; // zero vector: values are already zeros\n return Vec.divide(a, m);\n }\n\n /**\n * Set `a` to its absolute value in each dimension.\n * @returns vector `a`\n */\n static abs(a: PtLike): PtLike {\n return Vec.map(a, Math.abs);\n }\n\n /**\n * Set `a` to its floor value in each dimension.\n * @returns vector `a`\n */\n static floor(a: PtLike): PtLike {\n return Vec.map(a, Math.floor);\n }\n\n /**\n * Set `a` to its ceiling value in each dimension.\n * @returns vector `a`\n */\n static ceil(a: PtLike): PtLike {\n return Vec.map(a, Math.ceil);\n }\n\n /**\n * Set `a` to its rounded value in each dimension.\n * @returns vector `a`\n */\n static round(a: PtLike): PtLike {\n return Vec.map(a, Math.round);\n }\n\n /**\n * Find the max value within a vector's dimensions.\n * @returns an object with `value` and `index` that specifies the max value and its corresponding dimension.\n */\n static max(a: PtLike): { value: number; index: number } {\n // -Infinity, not Number.MIN_VALUE (the smallest positive double), so\n // all-negative vectors report a correct maximum\n let m = -Infinity;\n let index = 0;\n for (let i = 0, len = a.length; i < len; i++) {\n if (a[i] >= m) {\n m = a[i];\n index = i;\n }\n }\n return { value: m, index: index };\n }\n\n /**\n * Find the min value within a vector's dimensions.\n * @returns an object with `value` and `index` that specifies the min value and its corresponding dimension.\n */\n static min(a: PtLike): { value: number; index: number } {\n let m = Infinity;\n let index = 0;\n for (let i = 0, len = a.length; i < len; i++) {\n if (a[i] <= m) {\n m = a[i];\n index = i;\n }\n }\n return { value: m, index: index };\n }\n\n /**\n * Add up all the dimensions' values and returns a scalar of the sum.\n */\n static sum(a: PtLike): number {\n let s = 0;\n for (let i = 0, len = a.length; i < len; i++) s += a[i];\n return s;\n }\n\n /**\n * Given a mapping function, update `a`'s value in each dimension.\n * @returns vector `a`\n */\n static map(\n a: PtLike,\n fn: (n: number, index: number, arr: PtLike) => number,\n ): PtLike {\n for (let i = 0, len = a.length; i < len; i++) {\n a[i] = fn(a[i], i, a);\n }\n return a;\n }\n}\n\n/**\n * Mat provides various static functions for matrix operations as well as a convenient way to chain a 3x3 transformation matrix. It's not fully optimized but good enough to use.\n */\nexport class Mat {\n protected _33!: GroupLike;\n\n constructor() {\n this.reset();\n }\n\n /**\n * Get the current value of its stored 3x3 matrix\n */\n get value(): GroupLike {\n return this._33;\n }\n\n /**\n * Convert the value of its stored 3x3 matrix to a 2D [`DOMMatrix`](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix) instance\n */\n get domMatrix(): DOMMatrix {\n return new DOMMatrix(Mat.toDOMMatrix(this._33));\n }\n\n /**\n * Reset the internal 3x3 matrix to its identity\n */\n reset() {\n this._33 = Mat.scale2DMatrix(1, 1);\n }\n\n /**\n * Scale the internal 3x3 matrix. You can chain this function with other related functions.\n * @param val [x, y] scale factors\n * @param at Optional origin location to scale from.\n */\n scale2D(val: PtLike, at: PtLike = [0, 0]): this {\n const m = Mat.scaleAt2DMatrix(val[0] ?? 1, val[1] ?? 1, at);\n this._33 = Mat.multiply(this._33, m);\n return this;\n }\n\n /**\n * Scale the internal 3x3 matrix. You can chain this function with other related functions.\n * @param ang Angle of rotation\n * @param at Optional origin location to rotate from.\n */\n rotate2D(ang: number, at: PtLike = [0, 0]): this {\n const m = Mat.rotateAt2DMatrix(Math.cos(ang), Math.sin(ang), at);\n this._33 = Mat.multiply(this._33, m);\n return this;\n }\n\n /**\n * Translate the internal 3x3 matrix. You can chain this function with other related functions.\n * @param val [x, y] offset values\n */\n translate2D(val: PtLike): this {\n const m = Mat.translate2DMatrix(val[0] || 0, val[1] || 0);\n this._33 = Mat.multiply(this._33, m);\n return this;\n }\n\n /**\n * Shear the internal 3x3 matrix. You can chain this function with other related functions.\n * @param val [x, y] shear factors (before tan() operation)\n * @param at Optional origin location to scale from.\n */\n shear2D(val: PtLike, at: PtLike = [0, 0]): this {\n const m = Mat.shearAt2DMatrix(\n Math.tan(val[0] ?? 0),\n Math.tan(val[1] ?? 0),\n at,\n );\n this._33 = Mat.multiply(this._33, m);\n return this;\n }\n\n /**\n * Matrix addition. Matrices should have the same rows and columns.\n * @param a a group of Pt\n * @param b a scalar number, an array of numeric arrays, or a group of Pt\n * @returns a new group with the same rows and columns as a and b\n */\n static add(a: GroupLike, b: GroupLike | number[][] | number): Group {\n if (typeof b != \"number\") {\n if (a[0].length != b[0].length)\n throw new Error(\n \"Cannot add matrix if rows' and columns' size don't match.\",\n );\n if (a.length != b.length)\n throw new Error(\n \"Cannot add matrix if rows' and columns' size don't match.\",\n );\n }\n\n const g = new Group();\n const isNum = typeof b == \"number\";\n for (let i = 0, len = a.length; i < len; i++) {\n g.push(a[i].$add(isNum ? b : b[i]));\n }\n\n return g;\n }\n\n /**\n * Matrix multiplication.\n * @param a a Group of M Pts, each with K dimensions (M-rows, K-columns)\n * @param b a scalar number, an array of numeric arrays, or a Group of K Pts, each with N dimensions (K-rows, N-columns) -- or if transposed is true, then N Pts with K dimensions\n * @param transposed (Only applicable if it's not elementwise multiplication) If true, then a and b's columns should match (ie, each Pt should have the same dimensions). Default is `false`.\n * @param elementwise if true, then the multiplication is done element-wise. Default is `false`.\n * @returns If not elementwise, this will return a new group with M Pt, each with N dimensions (M-rows, N-columns).\n */\n static multiply(\n a: GroupLike,\n b: GroupLike | number[][] | number,\n transposed: boolean = false,\n elementwise: boolean = false,\n ): Group {\n const g = new Group();\n\n if (typeof b != \"number\") {\n if (elementwise) {\n if (a.length != b.length)\n throw new Error(\n \"Cannot multiply matrix element-wise because the matrices' sizes don't match.\",\n );\n for (let ai = 0, alen = a.length; ai < alen; ai++) {\n g.push(a[ai].$multiply(b[ai]));\n }\n } else {\n if (!transposed && a[0].length != b.length)\n throw new Error(\n \"Cannot multiply matrix if rows in matrix-a don't match columns in matrix-b.\",\n );\n if (transposed && a[0].length != b[0].length)\n throw new Error(\n \"Cannot multiply matrix if transposed and the columns in both matrices don't match.\",\n );\n\n if (!transposed) b = Mat.transpose(b);\n\n for (let ai = 0, alen = a.length; ai < alen; ai++) {\n const p = Pt.make(b.length, 0);\n for (let bi = 0, blen = b.length; bi < blen; bi++) {\n p[bi] = Vec.dot(a[ai], b[bi]);\n }\n g.push(p);\n }\n }\n } else {\n for (let ai = 0, alen = a.length; ai < alen; ai++) {\n g.push(a[ai].$multiply(b));\n }\n }\n\n return g;\n }\n\n /**\n * Zip one slice of an array of Pts. For example, if the input `g` are organized in rows, then this function will take the values in a specific column.\n * @param g a group of Pt\n * @param index index to zip at\n * @param defaultValue a default value to fill if index out of bound. If not provided, it will throw an error instead.\n */\n static zipSlice(\n g: GroupLike | number[][],\n index: number,\n defaultValue: number | boolean = false,\n ): Pt {\n const z: number[] = [];\n for (let i = 0, len = g.length; i < len; i++) {\n if (g[i].length - 1 < index) {\n if (defaultValue === false)\n throw new Error(`Index ${index} is out of bounds`);\n z.push(defaultValue as number);\n } else {\n z.push(g[i][index]);\n }\n }\n return new Pt(z);\n }\n\n /**\n * Zip a group of Pt. For example, `[[1,2],[3,4],[5,6]]` will become `[[1,3,5],[2,4,6]]`.\n * @param g a group of Pt\n * @param defaultValue a default value to fill if index out of bound. If not provided, it will throw an error instead.\n * @param useLongest If true, find the longest list of values in a Pt and use its length for zipping. Default is false, which uses the first item's length for zipping.\n */\n static zip(\n g: GroupLike | number[][],\n defaultValue: number | boolean = false,\n useLongest = false,\n ): Group {\n const ps = new Group();\n const len: number = useLongest\n ? (g as Array<number[] | Pt>).reduce((a, b) => Math.max(a, b.length), 0)\n : g[0].length;\n for (let i = 0; i < len; i++) {\n ps.push(Mat.zipSlice(g, i, defaultValue));\n }\n return ps;\n }\n\n /**\n * Same as `zip` function.\n */\n static transpose(\n g: GroupLike | number[][],\n defaultValue: number | boolean = false,\n useLongest = false,\n ): Group {\n return Mat.zip(g, defaultValue, useLongest);\n }\n\n static toDOMMatrix(m: GroupLike | number[][]) {\n return [m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1]];\n }\n\n /**\n * Transform a 2D point given a 2x3 or 3x3 matrix.\n * @param pt a Pt to be transformed\n * @param m 2x3 or 3x3 matrix\n * @returns a new transformed Pt\n */\n static transform2D(pt: PtLike, m: GroupLike | number[][]): Pt {\n const x = pt[0] * m[0][0] + pt[1] * m[1][0] + m[2][0];\n const y = pt[0] * m[0][1] + pt[1] * m[1][1] + m[2][1];\n return new Pt(x, y);\n }\n\n /**\n * Get a scale matrix for use in `transform2D`.\n */\n static scale2DMatrix(x: number, y: number): GroupLike {\n return new Group(new Pt(x, 0, 0), new Pt(0, y, 0), new Pt(0, 0, 1));\n }\n\n /**\n * Get a rotate matrix for use in `transform2D`.\n */\n static rotate2DMatrix(cosA: number, sinA: number): GroupLike {\n return new Group(\n new Pt(cosA, sinA, 0),\n new Pt(-sinA, cosA, 0),\n new Pt(0, 0, 1),\n );\n }\n\n /**\n * Get a shear matrix for use in `transform2D`.\n */\n static shear2DMatrix(tanX: number, tanY: number): GroupLike {\n return new Group(new Pt(1, tanX, 0), new Pt(tanY, 1, 0), new Pt(0, 0, 1));\n }\n\n /**\n * Get a translate matrix for use in `transform2D`.\n */\n static translate2DMatrix(x: number, y: number): GroupLike {\n return new Group(new Pt(1, 0, 0), new Pt(0, 1, 0), new Pt(x, y, 1));\n }\n\n /**\n * Get a matrix to scale a point from an origin point. For use in `transform2D`.\n */\n static scaleAt2DMatrix(sx: number, sy: number, at: PtLike): GroupLike {\n const m = Mat.scale2DMatrix(sx, sy);\n m[2][0] = -at[0] * sx + at[0];\n m[2][1] = -at[1] * sy + at[1];\n return m;\n }\n\n /**\n * Get a matrix to rotate a point from an origin point. For use in `transform2D`.\n */\n static rotateAt2DMatrix(cosA: number, sinA: number, at: PtLike): GroupLike {\n const m = Mat.rotate2DMatrix(cosA, sinA);\n m[2][0] = at[0] * (1 - cosA) + at[1] * sinA;\n m[2][1] = at[1] * (1 - cosA) - at[0] * sinA;\n return m;\n }\n\n /**\n * Get a matrix to shear a point from an origin point. For use in `transform2D`.\n */\n static shearAt2DMatrix(tanX: number, tanY: number, at: PtLike): GroupLike {\n const m = Mat.shear2DMatrix(tanX, tanY);\n m[2][0] = -at[1] * tanY;\n m[2][1] = -at[0] * tanX;\n return m;\n }\n\n /**\n * Get a matrix to reflect a point along a line. For use in `transform2D`.\n * @param p1 first end point to define the reflection line\n * @param p1 second end point to define the reflection line\n */\n static reflectAt2DMatrix(p1: PtLike, p2: PtLike) {\n const intercept = Line.intercept(p1, p2);\n\n if (intercept == undefined) {\n return [\n new Pt([-1, 0, 0]),\n new Pt([0, 1, 0]),\n new Pt([p1[0] + p2[0], 0, 1]),\n ];\n } else {\n const yi = intercept.yi;\n const ang2 = Math.atan(intercept.slope) * 2;\n const cosA = Math.cos(ang2);\n const sinA = Math.sin(ang2);\n\n return [\n new Pt([cosA, sinA, 0]),\n new Pt([sinA, -cosA, 0]),\n new Pt([-yi * sinA, yi + yi * cosA, 1]),\n ];\n }\n }\n}\n","/* This code has been written by Steve Gibson and can be found here:\n *\n * https://www.grc.com/otg/uheprng.htm\n *\n * The code has been converted to typescript and unused functions have\n * been removed.\n *\n * Port notes:\n * - Only the seeded, deterministic path survives: the original's\n * nondeterministic startup fill (from the host's `Math.random`) fed a\n * usage this port removed, so it is omitted and seeding consumes no\n * outside entropy.\n * - `random()` returns the raw 32-bit MWC fraction — every draw is an\n * exact multiple of 2^-32. The original composed two draws into a\n * 53-bit double; callers here (Float32-based Pts) don't need that.\n * - Despite the original header below, this is not a cryptographically\n * secure PRNG by modern standards (its state is recoverable from its\n * outputs). Pts uses it for reproducible generative art only.\n */\n\n/*\t============================================================================\n Gibson Research Corporation\n UHEPRNG - Ultra High Entropy Pseudo-Random Number Generator\n ============================================================================\n LICENSE AND COPYRIGHT: THIS CODE IS HEREBY RELEASED INTO THE PUBLIC DOMAIN\n Gibson Research Corporation releases and disclaims ALL RIGHTS AND TITLE IN\n THIS CODE OR ANY DERIVATIVES. Anyone may be freely use it for any purpose.\n ============================================================================\n This is GRC's cryptographically strong PRNG (pseudo-random number generator)\n for JavaScript. It is driven by 1536 bits of entropy, stored in an array of\n 48, 32-bit JavaScript variables. Since many applications of this generator,\n including ours with the \"Off The Grid\" Latin Square generator, may require\n the deteriministic re-generation of a sequence of PRNs, this PRNG's initial\n entropic state can be read and written as a static whole, and incrementally\n evolved by pouring new source entropy into the generator's internal state.\n ----------------------------------------------------------------------------\n ENDLESS THANKS are due Johannes Baagoe for his careful development of highly\n robust JavaScript implementations of JS PRNGs. This work was based upon his\n JavaScript \"Alea\" PRNG which is based upon the extremely robust Multiply-\n With-Carry (MWC) PRNG invented by George Marsaglia. MWC Algorithm References:\n http://www.GRC.com/otg/Marsaglia_PRNGs.pdf\n http://www.GRC.com/otg/Marsaglia_MWC_Generators.pdf\n ----------------------------------------------------------------------------\n The quality of this algorithm's pseudo-random numbers have been verified by\n multiple independent researchers. It handily passes the fermilab.ch tests as\n well as the \"diehard\" and \"dieharder\" test suites. For individuals wishing\n to further verify the quality of this algorithm's pseudo-random numbers, a\n 256-megabyte file of this algorithm's output may be downloaded from GRC.com,\n and a Microsoft Windows scripting host (WSH) version of this algorithm may be\n downloaded and run from the Windows command prompt to generate unique files\n of any size:\n The Fermilab \"ENT\" tests: http://fourmilab.ch/random/\n The 256-megabyte sample PRN file at GRC: https://www.GRC.com/otg/uheprng.bin\n The Windows scripting host version: https://www.GRC.com/otg/wsh-uheprng.js\n ----------------------------------------------------------------------------\n Qualifying MWC multipliers are: 187884, 686118, 898134, 1104375, 1250205,\n 1460910 and 1768863. (We use the largest one that's < 2^21)\n ============================================================================\n*/\n\n/*\t============================================================================\n This is based upon Johannes Baagoe's carefully designed and efficient hash\n function for use with JavaScript. It has a proven \"avalanche\" effect such\n that every bit of the input affects every bit of the output 50% of the time,\n which is good.\tSee: http://baagoe.com/en/RandomMusings/hash/avalanche.xhtml\n ============================================================================\n*/\n// calling with no (or a falsy) argument resets the hash state instead of\n// hashing — initState and the empty-seed path rely on that contract (the\n// reset path's return value is never consumed)\nfunction Mash(): (data?: string) => number {\n let n = 0xefc8249d;\n return function (data?: string): number {\n if (data) {\n data = data.toString();\n for (let i = 0; i < data.length; i++) {\n n += data.charCodeAt(i);\n let h = 0.02519603282416938 * n;\n n = h >>> 0;\n h -= n;\n h *= n;\n n = h >>> 0;\n h -= n;\n n += h * 0x100000000; // 2^32\n }\n return (n >>> 0) * 2.3283064365386963e-10; // 2^-32\n }\n n = 0xefc8249d;\n return 0;\n };\n}\n\nexport default function uheprng(seed: string) {\n const o = 48; // set the 'order' number of ENTROPY-holding 32-bit values\n let c = 1; // init the 'carry' used by the multiply-with-carry (MWC) algorithm\n let p = o; // init the 'phase' (max-1) of the intermediate variable pointer\n const s: number[] = new Array(o); // declare our intermediate variables array\n\n const mash = Mash(); // get a pointer to our high-performance \"Mash\" hash\n\n // initialize the mash hash and the PRNG's internal state to a fixed,\n // deterministic startup context before hashing in the seeding input\n function initState() {\n mash(); // pass a null arg to force mash hash to init\n for (let i = 0; i < o; i++) s[i] = mash(\" \"); // fill the array with initial mash hash values\n c = 1; // init our multiply-with-carry carry\n p = o; // init our phase\n }\n\n // this \"clean string\" function removes leading and trailing spaces and non-printing\n // control characters, including any embedded carriage-return (CR) and line-feed (LF)\n // characters, from any string it is handed. this is used by the 'hashString' function\n // (below) so users always obtain the same EFFECTIVE uheprng seeding key: seeds that\n // differ only by surrounding whitespace or embedded control characters collide.\n function cleanString(inStr: string): string {\n inStr = inStr.replace(/(^\\s*)|(\\s*$)/gi, \"\"); // remove any/all leading spaces\n inStr = inStr.replace(/[\\x00-\\x1F]/gi, \"\"); // remove any/all control characters\n return inStr; // return the cleaned up result\n }\n\n // this \"hash string\" function hashes the provided character string after first cleaning\n // it (above); an empty effective seed leaves the fixed initState context untouched\n function hashString(inStr: string) {\n inStr = cleanString(inStr);\n mash(inStr); // use the string to evolve the 'mash' state\n for (let i = 0; i < inStr.length; i++) {\n // scan through the characters in our string\n const k = inStr.charCodeAt(i).toString(); // stringify once per character, not per slot\n for (let j = 0; j < o; j++) {\n // \t\"mash\" it into the UHEPRNG state\n s[j] -= mash(k);\n if (s[j] < 0) s[j] += 1;\n }\n }\n }\n\n initState();\n hashString(seed);\n\n return {\n /**\n * this (not anymore) PRIVATE (internal access only) function is the heart of the multiply-with-carry\n * (MWC) PRNG algorithm. When called it returns a pseudo-random number in the form of a\n * 32-bit JavaScript fraction (0.0 to <1.0) — an exact multiple of 2^-32.\n * @returns a number between 0.0 and 1.0\n */\n random(): number {\n if (++p >= o) p = 0;\n const t = 1768863 * s[p] + c * 2.3283064365386963e-10; // 2^-32\n return (s[p] = t - (c = t | 0));\n },\n };\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Const, Util } from \"./Util\";\nimport { Curve } from \"./Op\";\nimport { Pt, Group } from \"./Pt\";\nimport { Vec, Mat } from \"./LinearAlgebra\";\nimport {\n type PtLike,\n type GroupLike,\n type PtLikeIterable,\n type PtIterable,\n} from \"./Types\";\n\nimport generator from \"./uheprng\";\n\n/**\n * Num class provides static helper functions for basic numeric operations.\n */\nexport class Num {\n static generator: any;\n\n /**\n * Check if two numbers are equal or almost equal within a threshold.\n * @param a number a\n * @param b number b\n * @param threshold threshold value that specifies the minimum difference within which the two numbers are considered equal\n */\n static equals(a: number, b: number, threshold = 0.00001): boolean {\n return Math.abs(a - b) < threshold;\n }\n\n /**\n * Calculate linear interpolation between 2 values.\n * @param a start value\n * @param b end value\n * @param t an interpolation value, usually between 0 to 1\n */\n static lerp(a: number, b: number, t: number): number {\n return (1 - t) * a + t * b;\n }\n\n /**\n * Clamp values between min and max.\n * @param val value to clamp\n * @param min min value\n * @param max max value\n */\n static clamp(val: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, val));\n }\n\n /**\n * Different from [`Num.clamp`](#link) in that the value out-of-bound will be \"looped back\" to the other end.\n * @param val value to bound\n * @param min min value\n * @param max max value\n * @example `boundValue(361, 0, 360)` will return 1\n */\n static boundValue(val: number, min: number, max: number): number {\n const len = Math.abs(max - min);\n let a = (val - min) % len;\n if (a < 0) a += len;\n return a + min;\n }\n\n /**\n * Check if a value is within two other values\n * @param p value to check\n * @param a first bounding value\n * @param b second bounding value\n */\n static within(p: number, a: number, b: number): boolean {\n return p >= Math.min(a, b) && p <= Math.max(a, b);\n }\n\n /**\n * Get a random number within a range.\n * @param a range value 1\n * @param b range value 2\n */\n static randomRange(a: number, b: number = 0): number {\n const r = a > b ? a - b : b - a;\n return Math.min(a, b) + Num.random() * r;\n }\n\n /**\n * Get a random Pt within the range defined by either 1 or 2 Pt\n * @param a the range if only one Pt is used, or the start of the range if two Pt were used\n * @param b optional Pt to define the end of the range\n */\n static randomPt(a: PtLike, b?: PtLike): Pt {\n const p = new Pt(a.length);\n const range = b ? Vec.subtract(b.slice(), a) : a;\n const start = b ? a : new Pt(a.length).fill(0);\n for (let i = 0, len = p.length; i < len; i++) {\n p[i] = Num.random() * range[i] + start[i];\n }\n return p;\n }\n\n /**\n * Normalize a value within a range.\n * @param n the value to normalize\n * @param a range value 1\n * @param b range value 1\n */\n static normalizeValue(n: number, a: number, b: number): number {\n const min = Math.min(a, b);\n const max = Math.max(a, b);\n return (n - min) / (max - min);\n }\n\n /**\n * Sum a group of numeric arrays.\n * @param pts a Group or an Iterable<PtLike>\n * @returns a Pt of the dimensional sums\n */\n static sum(pts: PtLikeIterable): Pt {\n const _pts = Util.iterToArray(pts);\n const c = new Pt(_pts[0]);\n for (let i = 1, len = _pts.length; i < len; i++) {\n Vec.add(c, _pts[i]);\n }\n return c;\n }\n\n /**\n * Average a group of numeric arrays\n * @param pts a Group or an Iterable<PtLike>\n * @returns a Pt of averages\n */\n static average(pts: PtLikeIterable): Pt {\n const _pts = Util.iterToArray(pts);\n return Num.sum(_pts).divide(_pts.length);\n }\n\n /**\n * Given a value between 0 to 1, returns a value that cycles between 0 -> 1 -> 0 using the provided shaping method.\n * @param t a value between 0 to 1\n * @param method a shaping method. Default to [`Shaping.sineInOut`](#link).\n * @return a value between 0 to 1\n */\n static cycle(\n t: number,\n method: (t: number) => number = Shaping.sineInOut,\n ): number {\n return method(t > 0.5 ? 2 - t * 2 : t * 2);\n }\n\n /**\n * Map a value from one range to another.\n * @param n a value in the first range\n * @param currA first endpoint of the input range\n * @param currB second endpoint of the input range\n * @param targetA first endpoint of the output range\n * @param targetB second endpoint of the output range\n * @returns a remapped value in the second range\n */\n static mapToRange(\n n: number,\n currA: number,\n currB: number,\n targetA: number,\n targetB: number,\n ) {\n if (currA == currB)\n throw new Error(\n \"[currMin, currMax] must define a range that is not zero\",\n );\n // signed normalization so that reversed source or target ranges map\n // directionally instead of being silently reoriented\n const t = (n - currA) / (currB - currA);\n return targetA + t * (targetB - targetA);\n }\n\n /**\n * Seed the pseudorandom generator for reproducible [`Num.random`](#link) sequences.\n * The seed is hashed by its *effective* key: leading/trailing whitespace and embedded\n * control characters are stripped first, so seeds differing only in those collide.\n * An empty (or whitespace-only) seed yields a fixed default sequence. This generator\n * is deterministic and statistically strong, but not cryptographically secure.\n * @param seed seed string\n */\n static seed(seed: string): void {\n this.generator = generator(seed);\n }\n\n /**\n * Return a random number between 0 and 1. If a seed was set via [`Num.seed`](#link),\n * draws come from the seeded generator with 32-bit resolution (exact multiples of 2^-32);\n * otherwise it uses `Math.random`.\n * @returns a number between 0 and 1\n */\n static random(): number {\n return this.generator ? this.generator.random() : Math.random();\n }\n}\n\n/**\n * Geom class provides static helper functions for basic geometric operations.\n */\nexport class Geom {\n /**\n * Bound an angle between 0 to 360 degrees.\n * @param angle angle value\n */\n static boundAngle(angle: number): number {\n return Num.boundValue(angle, 0, 360);\n }\n\n /**\n * Bound a radian between 0 to two PI.\n * @param radian radian value\n */\n static boundRadian(radian: number): number {\n return Num.boundValue(radian, 0, Const.two_pi);\n }\n\n /**\n * Convert an angle in degree to radian.\n * @param angle angle value\n */\n static toRadian(angle: number): number {\n return angle * Const.deg_to_rad;\n }\n\n /**\n * Convert an angle in radian to degree.\n * @param radian radian value\n */\n static toDegree(radian: number): number {\n return radian * Const.rad_to_deg;\n }\n\n /**\n * Get a bounding box for a set of Pts.\n * @param pts a Group or an Iterable<Pt>\n * @return a Group of two Pts, representing the top-left and bottom-right corners\n */\n static boundingBox(pts: PtIterable): Group {\n let minPt: Pt | undefined, maxPt: Pt | undefined;\n for (const p of pts) {\n if (minPt == undefined) {\n minPt = p.clone();\n maxPt = p.clone();\n } else {\n // in-place equivalent of `$min` / `$max`, without 2 clones per point\n for (let i = 0, len = Math.min(minPt.length, p.length); i < len; i++) {\n minPt[i] = Math.min(minPt[i], p[i]);\n maxPt![i] = Math.max(maxPt![i], p[i]);\n }\n }\n }\n return new Group(minPt!, maxPt!);\n }\n\n /**\n * Get a centroid (the average middle point) for a set of Pts.\n * @param pts a Group or an Iterable<PtLike>\n * @return a centroid Pt\n */\n static centroid(pts: PtLikeIterable): Pt {\n return Num.average(pts);\n }\n\n /**\n * Given an anchor Pt, rebase all Pts in this group either to or from this anchor base.\n * @param pts a Group or an Iterable<PtLike>\n * @param ptOrIndex an index for the Pt array, or an external Pt\n * @param direction a string either \"to\" (subtract all Pt with this anchor base), or \"from\" (add all Pt from this anchor base)\n */\n static anchor(\n pts: PtLikeIterable,\n ptOrIndex: PtLike | number = 0,\n direction: \"to\" | \"from\" = \"to\",\n ) {\n const method = direction == \"to\" ? \"subtract\" : \"add\";\n let i = 0;\n for (const p of pts) {\n if (typeof ptOrIndex == \"number\") {\n if (ptOrIndex !== i) (p as any)[method]((pts as any)[ptOrIndex]);\n } else {\n (p as any)[method](ptOrIndex);\n }\n i++;\n }\n }\n\n /**\n * Get an interpolated (or extrapolated) value between two Pts. For linear interpolation between 2 scalar values, use [`Num.lerp`](#link).\n * @param a first Pt\n * @param b second Pt\n * @param t a value between 0 to 1 to interpolate, or any other value to extrapolate\n * @returns interpolated point as a new Pt\n */\n static interpolate(a: PtLike, b: PtLike, t: number = 0.5): Pt {\n const len = Math.min(a.length, b.length);\n const d = Pt.make(len);\n for (let i = 0; i < len; i++) {\n d[i] = a[i] * (1 - t) + b[i] * t;\n }\n return d;\n }\n\n /**\n * Find two Pts that are perpendicular to this Pt (2D only).\n * @param axis a string such as \"xy\" (use Const.xy) or an array to specify index for two dimensions\n * @returns an array of two Pt that are perpendicular to this Pt\n */\n static perpendicular(pt: PtLike, axis: string | PtLike = Const.xy): Group {\n const y = axis[1];\n const x = axis[0];\n\n const p = new Pt(pt);\n const pa = new Pt(p);\n (pa as any)[x] = -(p as any)[y];\n (pa as any)[y] = (p as any)[x];\n const pb = new Pt(p);\n (pb as any)[x] = (p as any)[y];\n (pb as any)[y] = -(p as any)[x];\n\n return new Group(pa, pb);\n }\n\n /**\n * Check if two Pts are perpendicular to each other (2D only).\n */\n static isPerpendicular(p1: PtLike, p2: PtLike): boolean {\n // relative epsilon: |a·b| <= ε·|a|·|b| (zero vectors keep returning true)\n let dot = 0;\n let ma = 0;\n let mb = 0;\n for (let i = 0, len = Math.min(p1.length, p2.length); i < len; i++) {\n dot += p1[i] * p2[i];\n ma += p1[i] * p1[i];\n mb += p2[i] * p2[i];\n }\n return Math.abs(dot) <= Const.epsilon * Math.sqrt(ma * mb);\n }\n\n /**\n * Check if a Pt is within the rectangular boundary defined by two Pts.\n * @param pt the Pt to check\n * @param boundPt1 boundary Pt 1\n * @param boundPt2 boundary Pt 2\n */\n static withinBound(pt: PtLike, boundPt1: PtLike, boundPt2: PtLike): boolean {\n for (\n let i = 0, len = Math.min(pt.length, boundPt1.length, boundPt2.length);\n i < len;\n i++\n ) {\n if (!Num.within(pt[i], boundPt1[i], boundPt2[i])) return false;\n }\n return true;\n }\n\n /**\n * Sort the Pts so that their edges will form a non-overlapping polygon. ([Reference](https://stackoverflow.com/questions/6989100/sort-points-in-clockwise-order))\n * @param pts a Group or an Iterable<Pt>\n */\n static sortEdges(pts: PtIterable): GroupLike {\n const _pts = Util.iterToArray(pts);\n const bounds = Geom.boundingBox(_pts);\n const center = bounds[1].add(bounds[0]).divide(2);\n const cx = center[0];\n const cy = center[1];\n\n // same ordering as before, with scalar math instead of two Pt\n // allocations per comparison\n const fn = (a: Pt, b: Pt): number => {\n if (a.length < 2 || b.length < 2)\n throw new Error(\"Pt dimension cannot be less than 2\");\n\n const dax = a[0] - cx;\n const day = a[1] - cy;\n const dbx = b[0] - cx;\n const dby = b[1] - cy;\n\n if (dax >= 0 && dbx < 0) return 1;\n if (dax < 0 && dbx >= 0) return -1;\n if (dax == 0 && dbx == 0) {\n if (day >= 0 || dby >= 0) return day > dby ? 1 : -1;\n return dby > day ? 1 : -1;\n }\n\n // cross product of vectors (center -> a) x (center -> b)\n const det = dax * dby - day * dbx;\n if (det < 0) return 1;\n if (det > 0) return -1;\n\n // points a and b are on the same line from the center\n // check which point is closer to the center\n return dax * dax + day * day > dbx * dbx + dby * dby ? 1 : -1;\n };\n\n return _pts.sort(fn);\n }\n\n /**\n * Scale a Pt or a Group of Pts. You may also use [`Pt.scale`](#link) instance method.\n * @param ps either a single Pt, or a Group or an Iterable<Pt>\n * @param scale scale value\n * @param anchor optional anchor point to scale from\n */\n static scale(\n ps: Pt | PtIterable,\n scale: number | PtLike,\n anchor?: PtLike,\n ): Geom {\n const pts = Util.iterToArray(\n (ps as any)[0] !== undefined && typeof (ps as any)[0] == \"number\"\n ? [ps]\n : ps,\n );\n const scs =\n typeof scale == \"number\" ? Pt.make(pts[0].length, scale) : scale;\n if (!anchor) anchor = Pt.make(pts[0].length, 0);\n\n for (let i = 0, len = pts.length; i < len; i++) {\n const p = pts[i];\n for (let k = 0, lenP = p.length; k < lenP; k++) {\n p[k] =\n anchor && anchor[k]\n ? anchor[k] + (p[k] - anchor[k]) * scs[k]\n : p[k] * scs[k];\n }\n }\n\n return Geom;\n }\n\n /**\n * Rotate a Pt or a Group of Pts in 2D space. You may also use [`Pt.rotate2D`](#link) instance method.\n * @param ps either a single Pt, or a Group or an Iterable<Pt>\n * @param angle rotate angle\n * @param anchor optional anchor point to rotate from\n * @param axis optional axis such as \"xy\" (use Const.xy) to define a 2D plane, or a number array to specify indices\n */\n static rotate2D(\n ps: Pt | PtIterable,\n angle: number,\n anchor?: PtLike,\n axis?: string | PtLike,\n ): Geom {\n const pts = Util.iterToArray(\n (ps as any)[0] !== undefined && typeof (ps as any)[0] == \"number\"\n ? [ps]\n : ps,\n );\n const fn = anchor ? Mat.rotateAt2DMatrix : Mat.rotate2DMatrix;\n if (!anchor) anchor = Pt.make(pts[0].length, 0);\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n // the anchor is a fixed point of the rotation even when it aliases one\n // of the transformed points, so the matrix can be built once\n const mat = fn(cos, sin, anchor);\n\n for (let i = 0, len = pts.length; i < len; i++) {\n const p = axis ? pts[i].$take(axis) : pts[i];\n p.to(Mat.transform2D(p, mat));\n if (axis) {\n for (let k = 0; k < axis.length; k++) {\n pts[i][axis[k]] = p[k];\n }\n }\n }\n\n return Geom;\n }\n\n /**\n * Shear a Pt or a Group of Pts in 2D space. You may also use [`Pt.shear2D`](#link) instance method.\n * @param ps either a single Pt, or a Group or an Iterable<Pt>\n * @param scale shearing value which can be a number or an array of 2 numbers\n * @param anchor optional anchor point to shear from\n * @param axis optional axis such as \"xy\" (use Const.xy) to define a 2D plane, or a number array to specify indices\n */\n static shear2D(\n ps: Pt | PtIterable,\n scale: number | PtLike,\n anchor?: PtLike,\n axis?: string | PtLike,\n ): Geom {\n const pts = Util.iterToArray(\n (ps as any)[0] !== undefined && typeof (ps as any)[0] == \"number\"\n ? [ps]\n : ps,\n );\n const s = typeof scale == \"number\" ? [scale, scale] : scale;\n if (!anchor) anchor = Pt.make(pts[0].length, 0);\n const fn = anchor ? Mat.shearAt2DMatrix : Mat.shear2DMatrix;\n const tanx = Math.tan(s[0]);\n const tany = Math.tan(s[1]);\n // like rotate2D, the anchor is invariant under its own shear\n const mat = fn(tanx, tany, anchor);\n\n for (let i = 0, len = pts.length; i < len; i++) {\n const p = axis ? pts[i].$take(axis) : pts[i];\n p.to(Mat.transform2D(p, mat));\n if (axis) {\n for (let k = 0; k < axis.length; k++) {\n pts[i][axis[k]] = p[k];\n }\n }\n }\n\n return Geom;\n }\n\n /**\n * Reflect a Pt or a Group of Pts along a 2D line. You may also use [`Pt.reflect2D`](#link) instance method.\n * @param ps either a single Pt, or a Group or an Iterable<Pt>\n * @param line a Group or an Iterable<PtLike> that defines a line for reflection\n * @param axis optional axis such as \"xy\" (use Const.xy) to define a 2D plane, or a number array to specify indices\n */\n static reflect2D(\n ps: Pt | PtIterable,\n line: PtLikeIterable,\n axis?: string | PtLike,\n ): Geom {\n const pts = Util.iterToArray(\n (ps as any)[0] !== undefined && typeof (ps as any)[0] == \"number\"\n ? [ps]\n : ps,\n );\n const _line = Util.iterToArray(line);\n const mat = Mat.reflectAt2DMatrix(_line[0], _line[1]);\n\n for (let i = 0, len = pts.length; i < len; i++) {\n const p = axis ? pts[i].$take(axis) : pts[i];\n p.to(Mat.transform2D(p, mat));\n if (axis) {\n for (let k = 0; k < axis.length; k++) {\n pts[i][axis[k]] = p[k];\n }\n }\n }\n\n return Geom;\n }\n\n /**\n * Generate a cosine lookup table.\n * @returns an object with a cosine tables (array of 360 values) and a function to get cosine given a radian input.\n */\n static cosTable() {\n const cos = new Float64Array(360);\n\n for (let i = 0; i < 360; i++) cos[i] = Math.cos((i * Math.PI) / 180);\n const find = (rad: number) =>\n cos[Math.floor(Geom.boundAngle(Geom.toDegree(rad)))];\n\n return { table: cos, cos: find };\n }\n\n /**\n * Generate a sine lookup table.\n * @returns an object with a sine tables (array of 360 values) and a function to get sine value given a radian input.\n */\n static sinTable() {\n const sin = new Float64Array(360);\n\n for (let i = 0; i < 360; i++) sin[i] = Math.sin((i * Math.PI) / 180);\n const find = (rad: number) =>\n sin[Math.floor(Geom.boundAngle(Geom.toDegree(rad)))];\n\n return { table: sin, sin: find };\n }\n}\n\n/**\n * Shaping provides shaping functions to interpolate a value. These are useful for easing and transitions.\n */\nexport class Shaping {\n /**\n * Linear mapping.\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static linear(t: number, c: number = 1): number {\n return c * t;\n }\n\n /**\n * Quadratic in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static quadraticIn(t: number, c: number = 1): number {\n return c * t * t;\n }\n\n /**\n * Quadratic out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static quadraticOut(t: number, c: number = 1): number {\n return -c * t * (t - 2);\n }\n\n /**\n * Quadratic in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static quadraticInOut(t: number, c: number = 1): number {\n const dt = t * 2;\n return t < 0.5 ? (c / 2) * t * t * 4 : (-c / 2) * ((dt - 1) * (dt - 3) - 1);\n }\n\n /**\n * Cubic in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static cubicIn(t: number, c: number = 1): number {\n return c * t * t * t;\n }\n\n /**\n * Cubic out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static cubicOut(t: number, c: number = 1): number {\n const dt = t - 1;\n return c * (dt * dt * dt + 1);\n }\n\n /**\n * Cubic in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static cubicInOut(t: number, c: number = 1): number {\n const dt = t * 2;\n return t < 0.5\n ? (c / 2) * dt * dt * dt\n : (c / 2) * ((dt - 2) * (dt - 2) * (dt - 2) + 2);\n }\n\n /**\n * Exponential ease in, adapted from Golan Levin's [polynomial shapers](http://www.flong.com/texts/code/shapers_poly/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p a value between 0 to 1 to control the curve. Default is 0.25.\n */\n static exponentialIn(t: number, c: number = 1, p: number = 0.25): number {\n return c * Math.pow(t, 1 / p);\n }\n\n /**\n * Exponential ease out, adapted from Golan Levin's [polynomial shapers](http://www.flong.com/texts/code/shapers_poly/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p a value between 0 to 1 to control the curve. Default is 0.25.\n */\n static exponentialOut(t: number, c: number = 1, p: number = 0.25): number {\n return c * Math.pow(t, p);\n }\n\n /**\n * Sinuous in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static sineIn(t: number, c: number = 1): number {\n return -c * Math.cos(t * Const.half_pi) + c;\n }\n\n /**\n * Sinuous out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static sineOut(t: number, c: number = 1): number {\n return c * Math.sin(t * Const.half_pi);\n }\n\n /**\n * Sinuous in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static sineInOut(t: number, c: number = 1): number {\n return (-c / 2) * (Math.cos(Math.PI * t) - 1);\n }\n\n /**\n * A faster way to approximate cosine ease in-out using Blinn-Wyvill Approximation. Adapated from Golan Levin's [polynomial shaping](http://www.flong.com/texts/code/shapers_poly/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static cosineApprox(t: number, c: number = 1) {\n const t2 = t * t;\n const t4 = t2 * t2;\n const t6 = t4 * t2;\n return c * ((4 * t6) / 9 - (17 * t4) / 9 + (22 * t2) / 9);\n }\n\n /**\n * Circular in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static circularIn(t: number, c: number = 1): number {\n return -c * (Math.sqrt(1 - t * t) - 1);\n }\n\n /**\n * Circular out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static circularOut(t: number, c: number = 1): number {\n const dt = t - 1;\n return c * Math.sqrt(1 - dt * dt);\n }\n\n /**\n * Circular in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static circularInOut(t: number, c: number = 1): number {\n const dt = t * 2;\n return t < 0.5\n ? (-c / 2) * (Math.sqrt(1 - dt * dt) - 1)\n : (c / 2) * (Math.sqrt(1 - (dt - 2) * (dt - 2)) + 1);\n }\n\n /**\n * Elastic in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p elastic parmeter between 0 to 1. The lower the number, the more elastic it will be. Default is 0.7.\n */\n static elasticIn(t: number, c: number = 1, p: number = 0.7): number {\n const dt = t - 1;\n const s = (p / Const.two_pi) * 1.5707963267948966;\n return (\n c * (-Math.pow(2, 10 * dt) * Math.sin(((dt - s) * Const.two_pi) / p))\n );\n }\n\n /**\n * Elastic out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p elastic parmeter between 0 to 1. The lower the number, the more elastic it will be. Default is 0.7.\n */\n static elasticOut(t: number, c: number = 1, p: number = 0.7): number {\n const s = (p / Const.two_pi) * 1.5707963267948966;\n return (\n c * (Math.pow(2, -10 * t) * Math.sin(((t - s) * Const.two_pi) / p)) + c\n );\n }\n\n /**\n * Elastic in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p elastic parmeter between 0 to 1. The lower the number, the more elastic it will be. Default is 0.6.\n */\n static elasticInOut(t: number, c: number = 1, p: number = 0.6): number {\n let dt = t * 2;\n const s = (p / Const.two_pi) * 1.5707963267948966;\n if (t < 0.5) {\n dt -= 1;\n return (\n c *\n (-0.5 *\n (Math.pow(2, 10 * dt) * Math.sin(((dt - s) * Const.two_pi) / p)))\n );\n } else {\n dt -= 1;\n return (\n c *\n (0.5 *\n (Math.pow(2, -10 * dt) * Math.sin(((dt - s) * Const.two_pi) / p))) +\n c\n );\n }\n }\n\n /**\n * Bounce in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static bounceIn(t: number, c: number = 1): number {\n return c - Shaping.bounceOut(1 - t, c);\n }\n\n /**\n * Bounce out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static bounceOut(t: number, c: number = 1) {\n if (t < 1 / 2.75) {\n return c * (7.5625 * t * t);\n } else if (t < 2 / 2.75) {\n t -= 1.5 / 2.75;\n return c * (7.5625 * t * t + 0.75);\n } else if (t < 2.5 / 2.75) {\n t -= 2.25 / 2.75;\n return c * (7.5625 * t * t + 0.9375);\n } else {\n t -= 2.625 / 2.75;\n return c * (7.5625 * t * t + 0.984375);\n }\n }\n\n /**\n * Bounce in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static bounceInOut(t: number, c: number = 1): number {\n return t < 0.5\n ? Shaping.bounceIn(t * 2, c) / 2\n : Shaping.bounceOut(t * 2 - 1, c) / 2 + c / 2;\n }\n\n /**\n * Sigmoid curve changes its shape adapted from the input value, but always returns a value between 0 to 1.\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p the larger the value, the \"steeper\" the curve will be. Default is 10.\n */\n static sigmoid(t: number, c: number = 1, p: number = 10): number {\n const d = p * (t - 0.5);\n return c / (1 + Math.exp(-d));\n }\n\n /**\n * Logistic sigmoid, adapted from Golan Levin's [shaping function](http://www.flong.com/texts/code/shapers_exp/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p a parameter between 0 to 1 to control the steepness of the curve. Higher is steeper. Default is 0.7.\n */\n static logSigmoid(t: number, c: number = 1, p: number = 0.7): number {\n p = Math.max(Const.epsilon, Math.min(1 - Const.epsilon, p));\n p = 1 / (1 - p);\n\n const A = 1 / (1 + Math.exp((t - 0.5) * p * -2));\n const B = 1 / (1 + Math.exp(p));\n const C = 1 / (1 + Math.exp(-p));\n return (c * (A - B)) / (C - B);\n }\n\n /**\n * Exponential seat curve, adapted from Golan Levin's [shaping functions](http://www.flong.com/texts/code/shapers_exp/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p a parameter between 0 to 1 to control the steepness of the curve. Higher is steeper. Default is 0.5.\n */\n static seat(t: number, c: number = 1, p: number = 0.5): number {\n if (t < 0.5) {\n return (c * Math.pow(2 * t, 1 - p)) / 2;\n } else {\n return c * (1 - Math.pow(2 * (1 - t), 1 - p) / 2);\n }\n }\n\n /**\n * Quadratic bezier curve, adapted from Golan Levin's [shaping functions](http://www.flong.com/texts/code/shapers_exp/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p a Pt object specifying the control Pt, or a value specifying its x position (its y position will default to 0.5). Default is `[0.05, 0.95]`.\n */\n static quadraticBezier(\n t: number,\n c: number = 1,\n p: number | PtLike = [0.05, 0.95],\n ): number {\n const a: number = typeof p != \"number\" ? p[0] : p;\n const b: number = typeof p != \"number\" ? p[1] : 0.5;\n let om2a = 1 - 2 * a;\n if (om2a === 0) {\n om2a = Const.epsilon;\n }\n const d = (Math.sqrt(a * a + om2a * t) - a) / om2a;\n return c * ((1 - 2 * b) * (d * d) + 2 * b * d);\n }\n\n /**\n * Cubic bezier curve. This reuses the bezier functions in Curve class. Note that `t` is the curve parameter, not the x position: unlike CSS `cubic-bezier(...)`, this returns the curve's y value at parameter `t` rather than solving y at x = t.\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p1` a Pt object specifying the first control Pt. Default is `Pt(0.1, 0.7).\n * @param p2` a Pt object specifying the second control Pt. Default is `Pt(0.9, 0.2).\n */\n static cubicBezier(\n t: number,\n c: number = 1,\n p1: PtLike = [0.1, 0.7],\n p2: PtLike = [0.9, 0.2],\n ): number {\n const curve = new Group(new Pt(0, 0), new Pt(p1), new Pt(p2), new Pt(1, 1));\n return (\n c *\n Curve.bezierStep(\n new Pt(t * t * t, t * t, t, 1),\n Curve.controlPoints(curve),\n ).y\n );\n }\n\n /**\n * Give a Pt, draw a quadratic curve that will pass through that Pt as closely as possible. Adapted from Golan Levin's [shaping functions](http://www.flong.com/texts/code/shapers_poly/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p1` a Pt object specifying the Pt to pass through. Default is `Pt(0.2, 0.35)\n */\n static quadraticTarget(\n t: number,\n c: number = 1,\n p1: PtLike = [0.2, 0.35],\n ): number {\n const a = Math.min(1 - Const.epsilon, Math.max(Const.epsilon, p1[0]));\n const b = Math.min(1, Math.max(0, p1[1]));\n const A = (1 - b) / (1 - a) - b / a;\n const B = (A * (a * a) - b) / a;\n const y = A * (t * t) - B * t;\n return c * Math.min(1, Math.max(0, y));\n }\n\n /**\n * Step function is a simple jump from 0 to 1 at a specific Pt in time.\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p usually a value between 0 to 1, which specify the Pt to \"jump\". Default is 0.5 which is in the middle.\n */\n static cliff(t: number, c: number = 1, p: number = 0.5): number {\n return t > p ? c : 0;\n }\n\n /**\n * Convert any shaping functions into a series of steps.\n * @param fn the original shaping function\n * @param steps the number of steps\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param args optional paramters to pass to original function\n */\n static step(\n fn: (t: number, c: number, ...args: any[]) => number,\n steps: number,\n t: number,\n c: number,\n ...args: any[]\n ) {\n const s = 1 / steps;\n const tt = Math.floor(t / s) * s;\n return fn(tt, c, ...args);\n }\n}\n\n/**\n * Range object keeps track of a Group of n-dimensional Pts to provide its minimum, maximum, and magnitude in each dimension.\n * It also provides convenient functions such as mapping the Group to another range. This class may be useful for visualizing data in charts.\n */\nexport class Range {\n protected _source: Group;\n protected _max!: Pt;\n protected _min!: Pt;\n protected _mag!: Pt;\n protected _dims: number = 0;\n\n /**\n * Construct a Range instance for a Group of Pts.\n * @param g a Group or an Iterable<Pt>\n */\n constructor(g: PtIterable) {\n this._source = Group.fromPtArray(g);\n this.calc();\n }\n\n /**\n * Get this Range's maximum values per dimension.\n */\n get max(): Pt {\n return this._max.clone();\n }\n\n /**\n * Get this Range's minimum values per dimension.\n */\n get min(): Pt {\n return this._min.clone();\n }\n\n /**\n * Get this Range's magnitude in each dimension.\n */\n get magnitude(): Pt {\n return this._mag.clone();\n }\n\n /**\n * Go through the group and find its min and max values. Usually you don't need to call this function directly.\n */\n calc(): this | undefined {\n if (!this._source) return;\n const dims = this._source[0].length;\n this._dims = dims;\n const max = new Pt(dims);\n const min = new Pt(dims);\n const mag = new Pt(dims);\n\n for (let i = 0; i < dims; i++) {\n // Infinity, not MAX_VALUE/MIN_VALUE: MIN_VALUE is the smallest positive\n // double (flushes to 0 in the Float32 Pt), which would cap the maximum\n // of all-negative data at 0\n max[i] = -Infinity;\n min[i] = Infinity;\n mag[i] = 0;\n\n const s = this._source.zipSlice(i);\n for (let k = 0, len = s.length; k < len; k++) {\n max[i] = Math.max(max[i], s[k]);\n min[i] = Math.min(min[i], s[k]);\n mag[i] = max[i] - min[i];\n }\n }\n\n this._max = max;\n this._min = min;\n this._mag = mag;\n return this;\n }\n\n /**\n * Map this Range to another range of values.\n * @param min target range's minimum value\n * @param max target range's maximum value\n * @param exclude Optional boolean array where `true` means excluding the conversion in that specific dimension.\n */\n mapTo(min: number, max: number, exclude?: boolean[]): Group {\n const target = new Group();\n for (let i = 0, len = this._source.length; i < len; i++) {\n const g = this._source[i];\n const n = new Pt(this._dims);\n for (let k = 0; k < this._dims; k++) {\n n[k] =\n exclude && exclude[k]\n ? g[k]\n : Num.mapToRange(g[k], this._min[k], this._max[k], min, max);\n }\n target.push(n);\n }\n return target;\n }\n\n /**\n * Add more Pts to this Range and recalculate its min and max values.\n * @param pts a Group or an Iterable<PtLike> to append to this Range\n * @param update Optional. Set the parameter to `false` if you want to append without immediately updating this Range's min and max values. Default is `true`.\n */\n append(pts: PtLikeIterable, update: boolean = true): this {\n const _pts = Util.iterToArray(pts);\n if (_pts[0].length !== this._dims)\n throw new Error(\n `Dimensions don't match. ${this._dims} dimensions in Range and ${_pts[0].length} provided in parameter. `,\n );\n this._source = this._source.concat(_pts) as Group;\n if (update) this.calc();\n return this;\n }\n\n /**\n * Create a number of evenly spaced \"ticks\" that span this Range's min and max value.\n * @param count number of subdivision. For example, 10 subdivision will return 11 tick values, which include first(min) and last(max) values.\n */\n ticks(count: number): Group {\n const g = new Group();\n for (let i = 0; i <= count; i++) {\n const p = new Pt(this._dims);\n const t = count > 0 ? i / count : 0;\n for (let k = 0, len = this._max.length; k < len; k++) {\n p[k] = Num.lerp(this._min[k], this._max[k], t);\n }\n g.push(p);\n }\n return g;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport type { CanvasSpace } from \"./Canvas\";\nimport { Num } from \"./Num\";\nimport { Group, Pt } from \"./Pt\";\nimport { type WarningType, type PtLike, type PtLikeIterable } from \"./Types\";\n\n/**\n * Various constant values for enumerations and calculations.\n */\nexport const Const = {\n /** A string to indicate xy plane. */\n xy: \"xy\",\n\n /** A string to indicate yz plane. */\n yz: \"yz\",\n\n /** A string to indicate xz plane. */\n xz: \"xz\",\n\n /** A string to indicate xyz space. */\n xyz: \"xyz\",\n\n /** Represents horizontal direction. */\n horizontal: 0,\n\n /** Represents vertical direction. */\n vertical: 1,\n\n /** Represents identical point or value */\n identical: 0,\n\n /** Represents right position or direction */\n right: 4,\n\n /** Represents bottom right position or direction */\n bottom_right: 5,\n\n /** Represents bottom position or direction */\n bottom: 6,\n\n /** Represents bottom left position or direction */\n bottom_left: 7,\n\n /** Represents left position or direction */\n left: 8,\n\n /** Represents top left position or direction */\n top_left: 1,\n\n /** Represents top position or direction */\n top: 2,\n\n /** Represents top right position or direction */\n top_right: 3,\n\n /** Represents an arbitrary very small number. It is set as 0.0001 here. */\n epsilon: 0.0001,\n\n /** Represents Number.MAX_VALUE. Note: as a Float32 Pt value this overflows to Infinity. */\n max: Number.MAX_VALUE,\n\n /** Represents Number.MIN_VALUE, the smallest *positive* number (5e-324) — not the most negative number. Do not use it to initialize a running maximum; use -Infinity instead. As a Float32 Pt value this flushes to 0. */\n min: Number.MIN_VALUE,\n\n /** π radian (180 deg) */\n pi: Math.PI,\n\n /** Two π radian (360deg) */\n two_pi: 6.283185307179586,\n\n /** Half π radian (90deg) */\n half_pi: 1.5707963267948966,\n\n /** π/4 radian (45deg) */\n quarter_pi: 0.7853981633974483,\n\n /** π/180 or 1 degree in radian */\n one_degree: 0.017453292519943295,\n\n /** Multiply this constant with a radian to get a degree */\n rad_to_deg: 57.29577951308232,\n\n /** Multiply this constant with a degree to get a radian */\n deg_to_rad: 0.017453292519943295,\n\n /** Gravity acceleration (unit: m/s^2) and gravity force (unit: Newton) on 1kg of mass. */\n gravity: 9.81,\n\n /** 1 Newton: 0.10197 Kilogram-force */\n newton: 0.10197,\n\n /** Gaussian constant (1 / Math.sqrt(2 * Math.PI)) */\n gaussian: 0.3989422804014327,\n};\n\n/**\n * Util class provides static helper functions.\n */\nexport class Util {\n static _warnLevel: WarningType = \"mute\";\n\n /**\n * Set a global warning level setting. If no parameter is passed, this will return the current warn-level. See [`Util.warn`](#link).\n * @param lv a [`WarningType`](#link) option, where \"error\" will throw an error, \"warn\" will log in console, and \"mute\" will ignore the error.\n */\n static warnLevel(lv?: WarningType): WarningType {\n if (lv) {\n Util._warnLevel = lv;\n }\n return Util._warnLevel;\n }\n\n /**\n * Convert different kinds of parameters (arguments, array, object) into an array of numbers.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n static getArgs(args: any[]): Array<number> {\n if (args.length < 1) return [];\n\n let pos = [];\n\n let isArray = Array.isArray(args[0]) || ArrayBuffer.isView(args[0]);\n\n // positional arguments: x,y,z,w,...\n if (typeof args[0] === \"number\") {\n pos = Array.prototype.slice.call(args);\n\n // as an object of {x, y?, z?, w?}\n } else if (typeof args[0] === \"object\" && !isArray) {\n let a = [\"x\", \"y\", \"z\", \"w\"];\n let p = args[0];\n for (let i = 0; i < a.length; i++) {\n if ((p.length && i >= p.length) || !(a[i] in p)) break; // check for length and key exist\n pos.push(p[a[i]]);\n }\n\n // as an array of values\n } else if (isArray) {\n pos = Util.toNumericArray(args[0]);\n }\n\n return pos;\n }\n\n /**\n * Copy an array or typed array of numbers into a fresh plain array.\n * @param a an array or typed array\n */\n static toNumericArray(a: ArrayLike<number>): number[] {\n // native slice is a fast path for plain arrays, but `[].slice.call` on a\n // typed array falls back to the generic per-element protocol\n if (Array.isArray(a)) return a.slice();\n const out = [];\n for (let i = 0, len = a.length; i < len; i++) {\n out.push(a[i]);\n }\n return out;\n }\n\n /**\n * Like [`Util.getArgs`](#link), but avoids copying when the arguments are already\n * a numeric array, a typed array (eg, a Pt), or a list of numbers. The result may be\n * the caller's own object, so it must be treated as read-only.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n static getPtLike(args: any[]): PtLike {\n const a0 = args[0];\n if (typeof a0 === \"number\") return args; // rest args are a fresh, private array\n if (args.length === 1 && (Array.isArray(a0) || ArrayBuffer.isView(a0))) {\n return a0 as PtLike;\n }\n return Util.getArgs(args);\n }\n\n /**\n * Send a warning message based on [`Util.warnLevel`](#link) global setting. This allows you to dynamically set whether minor errors should be thrown or printed in console or muted.\n * @param message any error or warning message\n * @param defaultReturn optional return value\n */\n static warn(message: string = \"error\", defaultReturn: any = undefined): any {\n if (Util.warnLevel() == \"error\") {\n throw new Error(message);\n } else if (Util.warnLevel() == \"warn\") {\n console.warn(message);\n }\n return defaultReturn;\n }\n\n /**\n * Get a random integer. This can be useful for selecting a random index in an array.\n * @deprecated Use [`Num.randomRange`](#link) instead, for example `Math.floor( Num.randomRange( start, start + range ) )`.\n * @param range value range\n * @param start Optional starting value\n */\n static randomInt(range: number, start: number = 0) {\n Util.warn(\"Util.randomInt is deprecated. Please use `Num.randomRange`\");\n return Math.floor(Num.random() * range) + start;\n }\n\n /**\n * Split an array into chunks of sub-array.\n * @param pts an array\n * @param size chunk size, ie, number of items in a chunk\n * @param stride optional parameter to \"walk through\" the array in steps\n * @param loopBack if `true`, always go through the array till the end and loop back to the beginning to complete the segments if needed.\n * @param matchSize if `true`, all chunks's length must match `size`.\n */\n static split(\n pts: any[],\n size: number,\n stride?: number,\n loopBack: boolean = false,\n matchSize = true,\n ): any[][] {\n let chunks: any[] = [];\n let part: any[] = [];\n let st: number = stride || size;\n let index: number = 0;\n if (pts.length <= 0 || st <= 0) return [];\n\n while (index < pts.length) {\n part = [];\n for (let k = 0; k < size; k++) {\n if (loopBack) {\n part.push(pts[(index + k) % pts.length]);\n } else {\n if (index + k >= pts.length) break;\n part.push(pts[index + k]);\n }\n }\n index += st;\n if (!matchSize || (matchSize && part.length === size)) chunks.push(part);\n }\n\n return chunks;\n }\n\n /**\n * Flatten an array of arrays such as Group[] to a flat Array or Group.\n * @param pts an array, usually an array of Groups\n * @param flattenAsGroup a boolean to specify whether the return type should be a Group or Array. Default is `true` which returns a Group.\n */\n static flatten(pts: any[], flattenAsGroup: boolean = true): any {\n // loop instead of concat.apply: spreading `pts` as arguments overflows\n // the JS argument-count limit for very large inputs\n const arr: unknown[] = flattenAsGroup ? new Group() : [];\n for (let i = 0, len = pts.length; i < len; i++) {\n const p = pts[i];\n if (Array.isArray(p)) {\n for (let k = 0, lenP = p.length; k < lenP; k++) arr.push(p[k]);\n } else {\n arr.push(p);\n }\n }\n return arr;\n }\n\n /**\n * Given two arrays of objects, and a function that operate on two objects, return an array. Objects must be of same type.\n * @param a an array of object, eg `[Group, Group, ...]`\n * @param b another array of object\n * @param op a function that takes two parameters (a, b) and returns an object.\n */\n static combine<T>(a: T[], b: T[], op: (a: T, b: T) => T): T[] {\n let result = [];\n for (let i = 0, len = a.length; i < len; i++) {\n for (let k = 0, lenB = b.length; k < lenB; k++) {\n result.push(op(a[i], b[k]));\n }\n }\n return result;\n }\n\n /**\n * Zip arrays. eg, `[[1,2],[3,4],[5,6]] => [[1,3,5],[2,4,6]]`.\n * @param arrays an array of arrays\n */\n static zip(arrays: Array<any>[]) {\n let z = [];\n for (let i = 0, len = arrays[0].length; i < len; i++) {\n let p = [];\n for (let k = 0; k < arrays.length; k++) {\n p.push(arrays[k][i]);\n }\n z.push(p);\n }\n return z;\n }\n\n /**\n * Create a convenient stepper. This returns a function which you can call repeatedly to step a counter.\n * @param max Maximum of the stepper range. The resulting stepper will return values within [min, max). Note that the first call returns `min + stride`, not `min`.\n * @param min Minimum of the stepper range. Default is 0.\n * @param stride Stride of the step. Default is 1.\n * @param callback An optional callback function `fn( step )`, which will be called each time when stepper function is called.\n * @example `let counter = stepper(100); let c = counter(); c = counter(); ...`\n * @returns a function which will increment the stepper and return its value at each call.\n */\n static stepper(\n max: number,\n min: number = 0,\n stride: number = 1,\n callback?: (n: number) => void,\n ): () => number {\n let c = min;\n return function () {\n c += stride;\n if (c >= max) {\n // anchored modulo keeps c in [min, max) even when stride > max - min\n c = min + ((c - min) % (max - min));\n }\n if (callback) callback(c);\n return c;\n };\n }\n\n /**\n * A convenient way to step through a range. Same as `for (i=0; i<range; i++)`, except this also stores the resulting return values at each step and return them as an array.\n * @param range a range to step through\n * @param fn a callback function `fn(index)`. If this function returns a value, it will be stored at each step\n * @returns an index-aligned array of returned values: entries sit at their step index, so with a non-zero `start` the positions below `start` are empty holes\n */\n static forRange(\n fn: (index: number) => any,\n range: number,\n start: number = 0,\n step: number = 1,\n ): any[] {\n let temp = [];\n for (let i = start, len = range; i < len; i += step) {\n temp[i] = fn(i);\n }\n return temp;\n }\n\n /**\n * A helper function to load data from a url via XMLHttpRequest GET. Since the response passed into callback is a string, if you're loading json data, you may use standard `JSON.parse(response)` to get a JSON object. For csv, try using a javascript csv library like papaparse or vega/datalib.\n * @param url the request url\n * @param callback a function to capture the data. It receives two parameters: a `response` as string, and a `success` status as boolean.\n */\n static load(\n url: string,\n callback: (response: string, success: boolean) => void,\n ) {\n let request = new XMLHttpRequest();\n request.open(\"GET\", url, true);\n\n request.onload = function () {\n if (request.status >= 200 && request.status < 400) {\n callback(request.responseText, true);\n } else {\n callback(\n `Server error (${request.status}) when loading \"${url}\"`,\n false,\n );\n }\n };\n\n request.onerror = function () {\n callback(`Unknown network error`, false);\n };\n\n request.send();\n }\n\n /**\n * Download the current `CanvasSpace` as an image (jpg/png/webp). Calling this function will automatically trigger a download.\n * @param space an instance of `CanvasSpace`\n * @param filename the name of the file, without the extension name.\n * @param filetype the image type (jpg/png/webp)\n * @param quality a value between 0 to 1, if filetype is either \"jpg\" or \"png\"\n */\n static download(\n space: CanvasSpace,\n filename: string = \"pts_canvas_image\",\n filetype: \"jpeg\" | \"jpg\" | \"png\" | \"webp\" = \"png\",\n quality: number = 1,\n ) {\n const ftype = filetype === \"jpg\" ? \"jpeg\" : filetype;\n space.element.toBlob(\n function (blob) {\n const link = document.createElement(\"a\");\n // toBlob yields null on encoding failure; createObjectURL then throws\n // a TypeError, same as it always has — kept, not silently swallowed\n const url = URL.createObjectURL(blob!);\n link.href = url;\n link.download = `${filename}.${filetype}`;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n },\n `image/${ftype}`,\n quality,\n );\n }\n\n /**\n * Estimate performance by checking how long it takes to render a frame\n * @param avgFrames The number of frames used calculate to average\n * @example `let perf = Util.performance(); perf();`\n * @returns milliseconds per frame\n */\n static performance(avgFrames: number = 10): () => number {\n let last = Date.now();\n let avg = [];\n return function () {\n const now = Date.now();\n avg.push(now - last);\n if (avg.length > avgFrames) avg.shift();\n last = now;\n return Math.floor(avg.reduce((a, b) => a + b, 0) / avg.length);\n };\n }\n\n /**\n * Check number of items in a Group against a required number\n * @param pts a Group or an Iterable<PtLike>\n * @param minRequired minimum number of items required\n */\n static arrayCheck(pts: PtLikeIterable, minRequired: number = 2): boolean {\n if (Array.isArray(pts) && pts.length < minRequired) {\n Util.warn(`Requires ${minRequired} or more Pts in this Group.`);\n return false;\n }\n return true;\n }\n\n /**\n * Convert an iterable into an array\n * @param it an iterable\n */\n static iterToArray(it: Iterable<any>): any[] {\n return !Array.isArray(it) ? [...it] : it;\n }\n\n /**\n * Check if accessing from a mobile device. Can be useful since some experimental features may not be availble in mobile browsers.\n */\n static isMobile() {\n return /iPhone|iPad|Android/i.test(navigator.userAgent);\n }\n\n /**\n * Generate a time-based unique ID or a crypto-based ID.\n * @returns\n */\n static uniqueId(useCrypto = false) {\n return useCrypto && typeof crypto !== \"undefined\" && crypto?.randomUUID\n ? crypto.randomUUID()\n : Date.now().toString(36) + Math.random().toString(36).substring(2);\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Util, Const } from \"./Util\";\nimport { Geom, Num } from \"./Num\";\nimport { Vec, Mat } from \"./LinearAlgebra\";\nimport {\n type IPt,\n type GroupLike,\n type PtLike,\n type PtIterable,\n type PtLikeIterable,\n} from \"./Types\";\n\n/**\n * Pt is a subclass of standard [`Float32Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array) with additional properties and functions to support vector and geometric calculations.\n * See [Pt guide](../guide/Pt-0200.html) for details.\n */\nexport class Pt extends Float32Array implements IPt, Iterable<number> {\n protected _id!: string;\n\n /**\n * Create a Pt. If no parameter is provided, this will instantiate a Pt with 2 dimensions [0, 0].\n * Note that `new Pt(3)` will only instantiate Pt with length of 3 (ie, same as `new Float32Array(3)` ). If you need a Pt with 1 dimension of value 3, use `new Pt([3])`.\n * @example `new Pt()`, `new Pt(1,2,3,4,5)`, `new Pt([1,2])`, `new Pt({x:0, y:1})`, `new Pt(pt)`\n * @param args a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n constructor(...args: Array<number | number[] | IPt | Float32Array>) {\n // each branch below produces a valid Float32Array constructor argument\n let params: any;\n const a0 = args[0];\n if (args.length === 1 && typeof a0 == \"number\") {\n params = a0; // init with the TypedArray's length. Needed this in order to make \".map\", \".slice\" etc work.\n } else if (args.length === 0) {\n params = 2; // default is [0, 0]\n } else if (\n args.length === 1 &&\n (Array.isArray(a0) || ArrayBuffer.isView(a0))\n ) {\n params = a0; // the Float32Array constructor copies array-likes natively\n } else if (typeof a0 === \"number\") {\n params = args; // a list of numbers; rest args are already a fresh array\n } else {\n params = Util.getArgs(args);\n }\n super(params);\n }\n\n /**\n * Create an n-dimensional Pt with either default value or random values.\n * @param dimensions number of dimensions\n * @param defaultValue optional default value to fill the dimensions\n * @param randomize if `true`, randomize the value between 0 to default value\n */\n static make(\n dimensions: number,\n defaultValue: number = 0,\n randomize: boolean = false,\n ): Pt {\n const p = new Pt(dimensions);\n if (defaultValue) p.fill(defaultValue);\n if (randomize) {\n for (let i = 0, len = p.length; i < len; i++) {\n p[i] = p[i] * Num.random();\n }\n }\n return p;\n }\n\n /**\n * ID string of this Pt\n */\n get id(): string {\n return this._id;\n }\n set id(s: string) {\n this._id = s;\n }\n\n /**\n * Value in the first dimensional of this Pt\n */\n get x(): number {\n return this[0];\n }\n set x(n: number) {\n this[0] = n;\n }\n\n /**\n * Value in the second dimension of this Pt\n */\n get y(): number {\n return this[1];\n }\n set y(n: number) {\n this[1] = n;\n }\n\n /**\n * Value in the third dimension of this Pt\n */\n get z(): number {\n return this[2];\n }\n set z(n: number) {\n this[2] = n;\n }\n\n /**\n * Value in the forth dimension of this Pt\n */\n get w(): number {\n return this[3];\n }\n set w(n: number) {\n this[3] = n;\n }\n\n /**\n * Clone this Pt and return it as a new Pt.\n */\n clone(): Pt {\n return new Pt(this);\n }\n\n /**\n * Check if another Pt is equal to this Pt, within a threshold. Every dimension of this Pt must be matched: a shorter Pt, or one with a NaN dimension, is not equal (following IEEE semantics, NaN never equals NaN).\n * @param p another Pt to compare with\n * @param threshold a threshold value within which the two Pts are considered equal. Default is 0.000001.\n */\n equals(p: PtLike, threshold = 0.000001): boolean {\n for (let i = 0, len = this.length; i < len; i++) {\n // written so that a missing or NaN dimension fails the comparison\n if (!(Math.abs(this[i] - p[i]) <= threshold)) return false;\n }\n return true;\n }\n\n /**\n * Update the values of this Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n to(...args: any[]): this {\n const p = Util.getPtLike(args);\n for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {\n this[i] = p[i];\n }\n return this;\n }\n\n /**\n * Like [`Pt.to`](#link) but returns a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $to(...args: any[]): Pt {\n return this.clone().to(...args);\n }\n\n /**\n * Update the values of this Pt to point at a specific angle.\n * @param radian target angle in radian\n * @param magnitude Optional magnitude if known. If not provided, it'll calculate and use this Pt's magnitude.\n * @param anchorFromPt If `true`, add it from this Pt's current position. Default is `false` which update the position from origin (0,0). See also [`Geom.rotate2D`](#link) for rotating a point from another anchor point.\n */\n toAngle(\n radian: number,\n magnitude?: number,\n anchorFromPt: boolean = false,\n ): this {\n const m = magnitude != undefined ? magnitude : this.magnitude();\n const change = [Math.cos(radian) * m, Math.sin(radian) * m];\n return anchorFromPt ? this.add(change) : this.to(change);\n }\n\n /**\n * Create an operation using this Pt, passing this Pt into a custom function's first parameter. See the [Op guide](../guide/Op-0400.html) for details.\n * @param fn any function that takes a Pt as its first parameter\n * @example `let myOp = pt.op( fn ); let result = myOp( [1,2,3] );`\n * @returns a resulting function that takes other parameters required in `fn`\n */\n op(fn: (p1: PtLike, ...rest: any[]) => any): (...rest: any[]) => any {\n const self = this;\n return (...params: any[]) => {\n return fn(self, ...params);\n };\n }\n\n /**\n * This combines a series of operations into an array. See the [Op guide](../guide/Op-0400.html) for details.\n * @param fns an array of functions for `op`\n * @example `let myOps = pt.ops([fn1, fn2, fn3]); let results = myOps.map( (op) => op([1,2,3]) );`\n * @returns an array of resulting functions\n */\n ops(\n fns: ((p1: PtLike, ...rest: any[]) => any)[],\n ): ((...rest: any[]) => any)[] {\n const _ops = [];\n for (let i = 0, len = fns.length; i < len; i++) {\n _ops.push(this.op(fns[i]));\n }\n return _ops;\n }\n\n /**\n * Take specific dimensional values from this Pt and create a new Pt.\n * @param axis a string such as \"xy\" (use Const.xy) or an array to specify indices\n */\n $take(axis: string | number[]): Pt {\n const p = [];\n for (let i = 0, len = axis.length; i < len; i++) {\n p.push((this as any)[axis[i]] || 0);\n }\n return new Pt(p);\n }\n\n /**\n * Concatenate this Pt with addition dimensional values and return as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $concat(...args: any[]): Pt {\n return new Pt(this.toArray().concat(Util.getArgs(args)));\n }\n\n /**\n * Add scalar or vector values to this Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n add(...args: any[]): this {\n args.length === 1 && typeof args[0] == \"number\"\n ? Vec.add(this, args[0])\n : Vec.add(this, Util.getPtLike(args));\n return this;\n }\n\n /**\n * Like [`Pt.add`](#link), but returns result as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $add(...args: any[]): Pt {\n return this.clone().add(...args);\n }\n\n /**\n * Subtract scalar or vector values from this Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n subtract(...args: any[]): this {\n args.length === 1 && typeof args[0] == \"number\"\n ? Vec.subtract(this, args[0])\n : Vec.subtract(this, Util.getPtLike(args));\n return this;\n }\n\n /**\n * Like [`Pt.subtract`](#link), but returns result as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $subtract(...args: any[]): Pt {\n return this.clone().subtract(...args);\n }\n\n /**\n * Multiply scalar or vector values (as element-wise) with this Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n multiply(...args: any[]): this {\n args.length === 1 && typeof args[0] == \"number\"\n ? Vec.multiply(this, args[0])\n : Vec.multiply(this, Util.getPtLike(args));\n return this;\n }\n\n /**\n * Like [`Pt.multiply`](#link), but returns result as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $multiply(...args: any[]): Pt {\n return this.clone().multiply(...args);\n }\n\n /**\n * Divide this Pt over scalar or vector values (as element-wise).\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n divide(...args: any[]): this {\n args.length === 1 && typeof args[0] == \"number\"\n ? Vec.divide(this, args[0])\n : Vec.divide(this, Util.getPtLike(args));\n return this;\n }\n\n /**\n * Like [`Pt.divide`](#link), but returns result as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $divide(...args: any[]): Pt {\n return this.clone().divide(...args);\n }\n\n /**\n * Get the squared distance (magnitude) of this Pt from origin.\n */\n magnitudeSq(): number {\n return Vec.dot(this, this);\n }\n\n /**\n * Get the distance (magnitude) of this Pt from origin.\n */\n magnitude(): number {\n return Vec.magnitude(this);\n }\n\n /**\n * Convert to a unit vector, which is a normalized vector whose magnitude equals to 1.\n * @param magnitude Optional: if the magnitude is known, pass it as a parameter to avoid duplicate calculation.\n */\n unit(magnitude: number | undefined = undefined): Pt {\n Vec.unit(this, magnitude);\n return this;\n }\n\n /**\n * Get a new unit vector from this Pt.\n */\n $unit(magnitude: number | undefined = undefined): Pt {\n return this.clone().unit(magnitude);\n }\n\n /**\n * Dot product of this Pt and another Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n dot(...args: any[]): number {\n return Vec.dot(this, Util.getPtLike(args));\n }\n\n /**\n * 2D Cross product of this Pt and another Pt. Return results as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $cross2D(...args: any[]): number {\n return Vec.cross2D(this, Util.getPtLike(args));\n }\n\n /**\n * 3D Cross product of this Pt and another Pt. Return results as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $cross(...args: any[]): Pt {\n return Vec.cross(this, Util.getPtLike(args));\n }\n\n /**\n * Calculate the vector projection of another Pt onto this Pt — ie, the component of the other Pt along this Pt's direction. Note that this Pt must be non-zero.\n * @param args the other Pt, as either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n * @returns the projection vector as a Pt\n */\n $project(...args: any[]): Pt {\n return this.$multiply(this.dot(...args) / this.magnitudeSq());\n }\n\n /**\n * Calculate the scalar projection of another Pt onto this Pt — the signed length of the other Pt's component along this Pt's direction. Note that this Pt must be non-zero.\n * @param args the other Pt, as either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n projectScalar(...args: any[]): number {\n return this.dot(...args) / this.magnitude();\n }\n\n /**\n * Absolute values for all values in this pt.\n */\n abs(): Pt {\n Vec.abs(this);\n return this;\n }\n\n /**\n * Get a new Pt with absolute values of this Pt.\n */\n $abs(): Pt {\n return this.clone().abs();\n }\n\n /**\n * Floor values for all values in this Pt.\n */\n floor(): Pt {\n Vec.floor(this);\n return this;\n }\n\n /**\n * Get a new Pt with floor values of this Pt.\n */\n $floor(): Pt {\n return this.clone().floor();\n }\n\n /**\n * Ceiling values for all values in this Pt.\n */\n ceil(): Pt {\n Vec.ceil(this);\n return this;\n }\n\n /**\n * Get a new Pt with ceiling values of this Pt.\n */\n $ceil(): Pt {\n return this.clone().ceil();\n }\n\n /**\n * Rounded values for all values in this Pt.\n */\n round(): Pt {\n Vec.round(this);\n return this;\n }\n\n /**\n * Get a new Pt with rounded values of this Pt.\n */\n $round(): Pt {\n return this.clone().round();\n }\n\n /**\n * Find the minimum value across all dimensions in this Pt.\n * @returns an object with `value` and `index` which returns the minimum value and its dimensional index\n */\n minValue(): { value: number; index: number } {\n return Vec.min(this);\n }\n\n /**\n * Find the maximum value across all dimensions in this Pt.\n * @returns an object with `value` and `index` which returns the maximum value and its dimensional index\n */\n maxValue(): { value: number; index: number } {\n return Vec.max(this);\n }\n\n /**\n * Get a new Pt that has the minimum dimensional values of this Pt and another Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $min(...args: any[]): Pt {\n const p = Util.getPtLike(args);\n const m = this.clone();\n for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {\n m[i] = Math.min(this[i], p[i]);\n }\n return m;\n }\n\n /**\n * Get a new Pt that has the maximum dimensional values of this Pt and another Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $max(...args: any[]): Pt {\n const p = Util.getPtLike(args);\n const m = this.clone();\n for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {\n m[i] = Math.max(this[i], p[i]);\n }\n return m;\n }\n\n /**\n * Get angle of this Pt from origin.\n * @param axis a string such as \"xy\" (use Const.xy) or an array to specify index for two dimensions\n */\n angle(axis: string | number[] = Const.xy): number {\n return Math.atan2((this as any)[axis[1]], (this as any)[axis[0]]);\n }\n\n /**\n * Get the signed angle between this and another Pt, normalized to [-π, π).\n * @param p the other Pt\n * @param axis a string such as \"xy\" (use Const.xy) or an array to specify index for two dimensions\n */\n angleBetween(p: Pt, axis: string | number[] = Const.xy): number {\n // normalize the difference so results don't jump across the ±π wrap\n return (\n Geom.boundRadian(this.angle(axis) - p.angle(axis) + Math.PI) - Math.PI\n );\n }\n\n /**\n * Scale this Pt from origin or from an anchor point.\n * @param scale scale ratio\n * @param anchor optional anchor point to scale from\n */\n scale(scale: number | number[] | PtLike, anchor?: PtLike) {\n Geom.scale(this, scale, anchor || Pt.make(this.length, 0));\n return this;\n }\n\n /**\n * Rotate this Pt from origin or from an anchor point in 2D.\n * @param angle rotate angle\n * @param anchor optional anchor point to scale from\n * @param axis optional string such as \"yz\" to specify a 2D plane\n */\n rotate2D(angle: number, anchor?: PtLike, axis?: string) {\n Geom.rotate2D(this, angle, anchor || Pt.make(this.length, 0), axis);\n return this;\n }\n\n /**\n * Shear this Pt from origin or from an anchor point in 2D.\n * @param scale shearing value which can be a number or an array of 2 numbers\n * @param anchor optional anchor point to scale from\n * @param axis optional string such as \"yz\" to specify a 2D plane\n */\n shear2D(scale: number | number[] | PtLike, anchor?: PtLike, axis?: string) {\n Geom.shear2D(this, scale, anchor || Pt.make(this.length, 0), axis);\n return this;\n }\n\n /**\n * Reflect this Pt along a 2D line.\n * @param line a Group of 2 Pts that defines a line for reflection\n * @param axis optional axis such as \"yz\" to define a 2D plane of reflection\n */\n reflect2D(line: GroupLike, axis?: string): this {\n Geom.reflect2D(this, line, axis);\n return this;\n }\n\n /**\n * A string representation of this Pt. Eg, \"Pt(1, 2, 3)\".\n */\n toString(): string {\n return `Pt(${this.join(\", \")})`;\n }\n\n /**\n * Convert this Pt to a javascript Array.\n */\n toArray(): number[] {\n const a = [];\n for (let i = 0, len = this.length; i < len; i++) a.push(this[i]);\n return a;\n }\n\n /**\n * Convert this Pt to a Group as new Group([0,...], pt)\n */\n toGroup(): Group {\n return new Group(Pt.make(this.length), this.clone());\n }\n\n /**\n * Convert this Pt to a Bound as new Group([0,...], pt)\n */\n toBound(): Bound {\n return new Bound(Pt.make(this.length), this.clone());\n }\n}\n\n/**\n * A Group is a subclass of standard javascript [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array). It should only contain Pt instances. You can think of it as an array of Float32Arrays.\n * See [Group guide](../guide/Group-0300.html) for details.\n */\nexport class Group extends Array<Pt> {\n protected _id!: string;\n\n /**\n * Create a Group by passing an array of [`Pt`](#link). You may also create a Group using [`Group.fromArray`](#link) or [`Group.fromPtArray`](#link).\n * @param args an array of Pts\n */\n constructor(...args: Pt[]) {\n super(...args);\n }\n\n /**\n * ID string of this Group\n */\n get id(): string {\n return this._id;\n }\n set id(s: string) {\n this._id = s;\n }\n\n /**\n * The first Pt in this Group\n */\n get p1(): Pt {\n return this[0];\n }\n\n /**\n * The second Pt in this Group\n */\n get p2(): Pt {\n return this[1];\n }\n\n /**\n * The third Pt in this Group\n */\n get p3(): Pt {\n return this[2];\n }\n\n /**\n * The forth Pt in this Group\n */\n get p4(): Pt {\n return this[3];\n }\n\n /**\n * The last Pt in this Group\n */\n get q1(): Pt {\n return this[this.length - 1];\n }\n\n /**\n * The second-last Pt in this Group\n */\n get q2(): Pt {\n return this[this.length - 2];\n }\n\n /**\n * The third-last Pt in this Group\n */\n get q3(): Pt {\n return this[this.length - 3];\n }\n\n /**\n * The forth-last Pt in this Group\n */\n get q4(): Pt {\n return this[this.length - 4];\n }\n\n /**\n * Depp clone this group and its Pts.\n */\n clone(): Group {\n const group = new Group();\n for (let i = 0, len = this.length; i < len; i++) {\n group.push(this[i].clone());\n }\n return group;\n }\n\n /**\n * Convert an array of numeric arrays into a Group.\n * @param list an Iterable<PtLike> such as an array or a generator (of PtLike numeric arrays)\n * @example `Group.fromArray( [[1,2], [3,4], [5,6]] )`\n */\n static fromArray(list: PtLikeIterable): Group {\n const g = new Group();\n for (const li of list) {\n const p = li instanceof Pt ? (li as Pt) : new Pt(li);\n g.push(p);\n }\n return g;\n }\n\n /**\n * Convert an Array/Iterable of Pt into a Group.\n * @param list an Iterable<Pt>\n */\n static fromPtArray(list: PtIterable): Group {\n return Group.from(list) as Group;\n }\n\n /**\n * Split this Group into an array of sub-groups.\n * @param chunkSize number of items per sub-group\n * @param stride forward-steps after each sub-group\n * @param loopBack if `true`, always go through the array till the end and loop back to the beginning to complete the segments if needed\n */\n split(\n chunkSize: number,\n stride?: number,\n loopBack: boolean = false,\n ): Group[] {\n // build real Groups (Util.split returns plain arrays); indexed assignment\n // avoids the slow spread through the Array subclass constructor\n const st = stride || chunkSize;\n const chunks: Group[] = [];\n if (this.length <= 0 || st <= 0) return chunks;\n\n let index = 0;\n while (index < this.length) {\n const g = new Group();\n let size = 0;\n for (let k = 0; k < chunkSize; k++) {\n if (loopBack) {\n g[size++] = this[(index + k) % this.length];\n } else {\n if (index + k >= this.length) break;\n g[size++] = this[index + k];\n }\n }\n index += st;\n if (size === chunkSize) chunks.push(g);\n }\n return chunks;\n }\n\n /**\n * Insert more Pt into this group.\n * @param pts a Group or an Iterable<Pt>\n * @param index the index position to insert into\n */\n insert(pts: PtIterable, index = 0): this {\n // iterToArray returns an array input as-is; inserting a group into itself\n // must read a snapshot, not the tail it is about to shift\n let _pts = Util.iterToArray(pts);\n if ((_pts as unknown) === this) _pts = _pts.slice();\n const len = this.length;\n const n = _pts.length;\n if (n === 0) return this;\n // normalize like Array.prototype.splice, including negative index\n let start = Math.trunc(index) || 0;\n start = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);\n // shift the tail and copy in place: splice's argument-spread overflows\n // the call stack for very large inputs\n this.length = len + n;\n for (let i = len - 1; i >= start; i--) this[i + n] = this[i];\n for (let i = 0; i < n; i++) this[start + i] = _pts[i];\n return this;\n }\n\n /**\n * Like Array's splice function, with support for negative index and a friendlier name.\n * @param index start index, which can be negative (where -1 is at index 0, -2 at index 1, etc)\n * @param count number of items to remove\n * @returns The items that are removed.\n */\n remove(index = 0, count: number = 1): Group {\n const param: [number, number] =\n index < 0 ? [index * -1 - 1, count] : [index, count];\n return Group.prototype.splice.apply(this, param) as Group;\n }\n\n /**\n * Split this group into an array of sub-group segments.\n * @param pts_per_segment number of Pts in each segment\n * @param stride forward-step to take\n * @param loopBack if `true`, always go through the array till the end and loop back to the beginning to complete the segments if needed\n */\n segments(\n pts_per_segment: number = 2,\n stride: number = 1,\n loopBack: boolean = false,\n ): Group[] {\n return this.split(pts_per_segment, stride, loopBack);\n }\n\n /**\n * Get all the line segments (ie, edges in a graph) of this group.\n */\n lines(): Group[] {\n return this.segments(2, 1);\n }\n\n /**\n * Find the centroid of this group's Pts, which is the average middle point.\n */\n centroid(): Pt {\n return Geom.centroid(this);\n }\n\n /**\n * Find the rectangular bounding box of this group's Pts.\n * @returns a Group of 2 Pts representing the top-left and bottom-right of the rectangle\n */\n boundingBox(): Group {\n return Geom.boundingBox(this);\n }\n\n /**\n * Anchor all the Pts in this Group using a target Pt as origin. (ie, subtract all Pt with the target anchor to get a relative position). All the Pts' values will be updated.\n * @param ptOrIndex a Pt, or a numeric index to target a specific Pt in this Group\n */\n anchorTo(ptOrIndex: PtLike | number = 0) {\n Geom.anchor(this, ptOrIndex, \"to\");\n }\n\n /**\n * Anchor all the Pts in this Group by its absolute position from a target Pt. (ie, add all Pt with the target anchor to get an absolute position). All the Pts' values will be updated.\n * @param ptOrIndex a Pt, or a numeric index to target a specific Pt in this Group\n */\n anchorFrom(ptOrIndex: PtLike | number = 0) {\n Geom.anchor(this, ptOrIndex, \"from\");\n }\n\n /**\n * Create an operation using this Group, passing this Group into a custom function's first parameter. See the [Op guide](../guide/Op-0400.html) for details.\n * @param fn any function that takes a Group as its first parameter\n * @example `let myOp = group.op( fn ); let result = myOp( [1,2,3] );`\n * @returns a resulting function that takes other parameters required in `fn`\n */\n op(fn: (g1: PtIterable, ...rest: any[]) => any): (...rest: any[]) => any {\n const self = this;\n return (...params: any[]) => {\n return fn(self, ...params);\n };\n }\n\n /**\n * This combines a series of operations into an array. See the [Op guide](../guide/Op-0400.html) for details.\n * @param fns an array of functions for `op`\n * @example `let myOps = pt.ops([fn1, fn2, fn3]); let results = myOps.map( (op) => op([1,2,3]) );`\n * @returns an array of resulting functions\n */\n ops(\n fns: ((g1: PtIterable, ...rest: any[]) => any)[],\n ): ((...rest: any[]) => any)[] {\n const _ops = [];\n for (let i = 0, len = fns.length; i < len; i++) {\n _ops.push(this.op(fns[i]));\n }\n return _ops;\n }\n\n /**\n * Get an interpolated point on the line segments defined by this Group.\n * @param t a value between 0 to 1 usually\n */\n interpolate(t: number): Pt {\n t = Num.clamp(t, 0, 1);\n const chunk = this.length - 1;\n const tc = 1 / (this.length - 1);\n const idx = Math.floor(t / tc);\n return Geom.interpolate(\n this[idx],\n this[Math.min(this.length - 1, idx + 1)],\n (t - idx * tc) * chunk,\n );\n }\n\n /**\n * Move every Pt's position by a specific amount. Same as [`Group.add`](#link).\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n moveBy(...args: any[]): this {\n return this.add(...args);\n }\n\n /**\n * Move the first Pt in this group to a specific position, and move all the other Pts correspondingly.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n moveTo(...args: any[]): this {\n const d = new Pt(...args).subtract(this[0]);\n this.moveBy(d);\n return this;\n }\n\n /**\n * Scale this group's Pts from an anchor point. Default anchor point is the first Pt in this group.\n * @param scale scale ratio\n * @param anchor optional anchor point to scale from\n */\n scale(scale: number | number[] | PtLike, anchor?: PtLike): this {\n for (let i = 0, len = this.length; i < len; i++) {\n Geom.scale(this[i], scale, anchor || this[0]);\n }\n return this;\n }\n\n /**\n * Rotate this group's Pt from an anchor point in 2D. Default anchor point is the first Pt in this group.\n * @param angle rotate angle\n * @param anchor optional anchor point to scale from\n * @param axis optional string such as \"yz\" to specify a 2D plane\n */\n rotate2D(angle: number, anchor?: PtLike, axis?: string): this {\n for (let i = 0, len = this.length; i < len; i++) {\n Geom.rotate2D(this[i], angle, anchor || this[0], axis);\n }\n return this;\n }\n\n /**\n * Shear this group's Pt from an anchor point in 2D. Default anchor point is the first Pt in this group.\n * @param scale shearing value which can be a number or an array of 2 numbers\n * @param anchor optional anchor point to scale from\n * @param axis optional string such as \"yz\" to specify a 2D plane\n */\n shear2D(\n scale: number | number[] | PtLike,\n anchor?: PtLike,\n axis?: string,\n ): this {\n for (let i = 0, len = this.length; i < len; i++) {\n Geom.shear2D(this[i], scale, anchor || this[0], axis);\n }\n return this;\n }\n\n /**\n * Reflect this group's Pts along a 2D line. Default anchor point is the first Pt in this group.\n * @param line a Group or an Iterable<PtLike> with 2 Pt that defines a line for reflection\n * @param axis optional axis such as \"yz\" to define a 2D plane of reflection\n */\n reflect2D(line: PtLikeIterable, axis?: string): this {\n for (let i = 0, len = this.length; i < len; i++) {\n Geom.reflect2D(this[i], line, axis);\n }\n return this;\n }\n\n /**\n * Sort this group's Pts by values in a specific dimension.\n * @param dim dimensional index\n * @param desc if true, sort descending. Default is false (ascending)\n */\n sortByDimension(dim: number, desc: boolean = false): this {\n return this.sort((a, b) => (desc ? b[dim] - a[dim] : a[dim] - b[dim]));\n }\n\n /**\n * Update each Pt in this Group with an existing Pt function.\n * @param ptFn string name of an existing Pt function. Note that the function must return Pt.\n * @param args arguments for the function specified in ptFn\n */\n forEachPt(ptFn: string, ...args: any[]): this {\n if (this.length === 0) return this;\n if (!(this[0] as any)[ptFn]) {\n Util.warn(`${ptFn} is not a function of Pt`);\n return this;\n }\n for (let i = 0, len = this.length; i < len; i++) {\n this[i] = (this[i] as any)[ptFn](...args);\n }\n return this;\n }\n\n /**\n * Apply a Vec operation to every Pt, parsing the arguments once for the whole\n * group rather than once per Pt.\n */\n protected _vecOp(\n fn: (a: PtLike, b: PtLike | number) => PtLike,\n args: any[],\n ): this {\n const b =\n args.length === 1 && typeof args[0] == \"number\"\n ? args[0]\n : Util.getPtLike(args);\n for (let i = 0, len = this.length; i < len; i++) {\n fn(this[i], b);\n }\n return this;\n }\n\n /**\n * Add scalar or vector values to this group's Pts.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n add(...args: any[]): this {\n return this._vecOp(Vec.add, args);\n }\n\n /**\n * Subtract scalar or vector values from this group's Pts.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n subtract(...args: any[]): this {\n return this._vecOp(Vec.subtract, args);\n }\n\n /**\n * Multiply scalar or vector values (as element-wise) with this group's Pts.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n multiply(...args: any[]): this {\n return this._vecOp(Vec.multiply, args);\n }\n\n /**\n * Divide this group's Pts over scalar or vector values (as element-wise).\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n divide(...args: any[]): this {\n return this._vecOp(Vec.divide, args);\n }\n\n /**\n * Apply this group as a matrix and calculate matrix addition.\n * @param g a scalar number, an array of numeric arrays, or a group of Pt\n * @returns a new Group\n */\n $matrixAdd(g: GroupLike | number[][] | number): Group {\n return Mat.add(this, g);\n }\n\n /**\n * Apply this group as a matrix and calculate matrix multiplication.\n * @param g a scalar number, an array of numeric arrays, or a Group of K Pts, each with N dimensions (K-rows, N-columns) -- or if transposed is true, then N Pts with K dimensions\n * @param transposed (Only applicable if it's not elementwise multiplication) If true, then a and b's columns should match (ie, each Pt should have the same dimensions). Default is `false`.\n * @param elementwise if true, then the multiplication is done element-wise. Default is `false`.\n * @returns If not elementwise, this will return a new Group with M Pt, each with N dimensions (M-rows, N-columns).\n */\n $matrixMultiply(\n g: GroupLike | number,\n transposed: boolean = false,\n elementwise: boolean = false,\n ): Group {\n return Mat.multiply(this, g, transposed, elementwise);\n }\n\n /**\n * Zip one slice of an array of Pt. Imagine the Pts are organized in rows, then this function will take the values in a specific column.\n * @param index index to zip at\n * @param defaultValue a default value to fill if index out of bound. If not provided, it will throw an error instead.\n */\n zipSlice(index: number, defaultValue: number | boolean = false): Pt {\n return Mat.zipSlice(this, index, defaultValue);\n }\n\n /**\n * Zip a group of Pt. eg, [[1,2],[3,4],[5,6]] => [[1,3,5],[2,4,6]].\n * @param defaultValue a default value to fill if index out of bound. If not provided, it will throw an error instead.\n * @param useLongest If true, find the longest list of values in a Pt and use its length for zipping. Default is false, which uses the first item's length for zipping.\n */\n $zip(\n defaultValue: number | boolean | undefined = undefined,\n useLongest = false,\n ): Group {\n return Mat.zip(this, defaultValue, useLongest);\n }\n\n /**\n * Get a Bound instance of this group\n */\n toBound(): Bound {\n return Bound.fromGroup(this);\n }\n\n /**\n * Get a string representation of this group.\n */\n toString(): string {\n return \"Group[ \" + this.reduce((p, c) => p + c.toString() + \" \", \"\") + \" ]\";\n }\n}\n\n/**\n * Bound is a subclass of [`Group`](#link) that represents a rectangular boundary.\n * It includes some convenient accessors (eg, bottomRight, center) for bounding box calculations.\n */\nexport class Bound extends Group implements IPt {\n protected _center: Pt = new Pt();\n protected _size: Pt = new Pt();\n protected _inited = false;\n\n /**\n * Create a Bound. This is similar to the Group constructor. You can also create a Bound via the static function [`Bound.fromGroup`](#link), or alternatively via the [Group.toBound](#link) function.\n * @param args a list of Pt as parameters\n * @see Bound.fromGroup\n */\n constructor(...args: Pt[]) {\n super(...args);\n this.init();\n }\n\n /**\n * Create a Bound from a [`ClientRect`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) object.\n * @param rect an object that has {top, left, bottom, right, width, height} properties\n * @returns a Bound object\n */\n static fromBoundingRect(rect: ClientRect): Bound {\n const b = new Bound(\n new Pt(rect.left || 0, rect.top || 0),\n new Pt(rect.right || 0, rect.bottom || 0),\n );\n if (rect.width && rect.height) b.size = new Pt(rect.width, rect.height);\n return b;\n }\n\n /**\n * Create a Bound from a Group or an array of Pts\n * @param g a Group or an Iterable<PtLike>\n */\n static fromGroup(g: PtLikeIterable): Bound {\n const _g = Util.iterToArray(g);\n if (_g.length < 2)\n throw new Error(\n \"Cannot create a Bound from a group that has less than 2 Pt\",\n );\n const first = _g[0];\n const last = _g[_g.length - 1];\n return new Bound(\n first instanceof Pt ? first : new Pt(first),\n last instanceof Pt ? last : new Pt(last),\n );\n }\n\n /**\n * Initiate the bound's properties.\n */\n protected init() {\n if (this.p1) {\n this._size = this.p1.clone();\n this._inited = true;\n }\n if (this.p1 && this.p2) {\n this._updateSize();\n this._inited = true;\n }\n }\n\n /**\n * Clone this bound and return a new one.\n */\n clone(): Bound {\n // the topLeft and bottomRight getters already return fresh Pts\n return new Bound(this.topLeft, this.bottomRight);\n }\n\n /**\n * Recalculte size and center.\n */\n protected _updateSize() {\n // In-place equivalent of `bottomRight.$subtract(topLeft).abs()`: dimensions\n // follow this[1], with missing/NaN topLeft values treated as 0.\n const a = this[0];\n const b = this[1];\n const n = b ? b.length : 0;\n if (this._size.length !== n) this._size = new Pt(n);\n for (let i = 0; i < n; i++) {\n this._size[i] = Math.abs(b[i] - (a ? a[i] || 0 : 0));\n }\n this._updateCenter();\n }\n\n /**\n * Recalculate center.\n */\n protected _updateCenter() {\n // In-place equivalent of `size.$multiply(0.5).add(topLeft)`\n const a = this[0];\n const n = this._size.length;\n if (this._center.length !== n) this._center = new Pt(n);\n for (let i = 0; i < n; i++) {\n this._center[i] = this._size[i] * 0.5 + (a ? a[i] || 0 : 0);\n }\n }\n\n /**\n * Recalculate based on top-left position and size.\n */\n protected _updatePosFromTop() {\n this.bottomRight = this.topLeft.$add(this._size);\n this._updateCenter();\n }\n\n /**\n * Recalculate based on bottom-right position and size.\n */\n protected _updatePosFromBottom() {\n this.topLeft = this.bottomRight.$subtract(this._size);\n this._updateCenter();\n }\n\n /**\n * Recalculate based on center position and size.\n */\n protected _updatePosFromCenter() {\n const half = this._size.$multiply(0.5);\n // Assign the corner Pts directly. Going through the `topLeft` and\n // `bottomRight` setters would call `_updateSize` after the first of the two,\n // recomputing size and center from a half-updated pair — so the second line\n // would read a `_center` that no longer holds the value being applied.\n const center = this._center;\n this[0] = center.$subtract(half);\n this[1] = center.$add(half);\n }\n\n /**\n * Size of this Bound\n */\n get size(): Pt {\n return new Pt(this._size);\n }\n set size(p: Pt) {\n this._size = new Pt(p);\n this._updatePosFromTop();\n }\n\n /**\n * Center position of this Bound\n */\n get center(): Pt {\n return new Pt(this._center);\n }\n set center(p: Pt) {\n this._center = new Pt(p);\n this._updatePosFromCenter();\n }\n\n /**\n * Top-left position of this Bound\n */\n get topLeft(): Pt {\n return new Pt(this[0]);\n }\n set topLeft(p: Pt) {\n this[0] = new Pt(p);\n this._updateSize();\n }\n\n /**\n * Bottom-right position of this Bound\n */\n get bottomRight(): Pt {\n return new Pt(this[1]);\n }\n set bottomRight(p: Pt) {\n this[1] = new Pt(p);\n this._updateSize();\n }\n\n /**\n * Width of this Bound\n */\n get width(): number {\n return this._size.length > 0 ? this._size.x : 0;\n }\n set width(w: number) {\n this._size.x = w;\n this._updatePosFromTop();\n }\n\n /**\n * Height of this Bound\n */\n get height(): number {\n return this._size.length > 1 ? this._size.y : 0;\n }\n set height(h: number) {\n this._size.y = h;\n this._updatePosFromTop();\n }\n\n /**\n * Depth of this Bound\n */\n get depth(): number {\n return this._size.length > 2 ? this._size.z : 0;\n }\n set depth(d: number) {\n this._size.z = d;\n this._updatePosFromTop();\n }\n\n /**\n * First value of the Bound's top-left position\n */\n get x(): number | undefined {\n // direct read: going through the `topLeft` getter clones a Pt per access\n return this[0] ? this[0][0] : undefined;\n }\n\n /**\n * Second value of the Bound's top-left position\n */\n get y(): number | undefined {\n return this[0] ? this[0][1] : undefined;\n }\n\n /**\n * Third value of the Bound's top-left position\n */\n get z(): number | undefined {\n return this[0] ? this[0][2] : undefined;\n }\n\n /**\n * Whether this Bound has been initiated\n */\n get inited(): boolean {\n return this._inited;\n }\n\n /**\n * If the Bound's Pts are changed, call this function to update the Bound's properties.\n * It's simpler and preferable to change the Bound's properties (eg, topLeft, bottomRight) instead of updating the Bound's Pts.\n * Note that this recomputes from the current corner Pts in place; it does not replace them with fresh instances.\n */\n update() {\n this._updateSize();\n return this;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Group } from \"./Pt\";\nimport { Rectangle, Circle, Polygon } from \"./Op\";\nimport {\n type UIHandler,\n type UIActionEvent,\n type GroupLike,\n type PtLike,\n type PtLikeIterable,\n} from \"./Types\";\n\n/** A hit-test function for a UI shape: given the UI's group, a point, and the UI's states, return whether the point is within the shape. */\nexport type UIShapeTest = (\n group: Group,\n pt: PtLike,\n states: { [key: string]: any },\n) => boolean;\n\nfunction _withinSegment(\n a: PtLike,\n b: PtLike,\n pt: PtLike,\n threshold: number,\n): boolean {\n if (threshold < 0) return false;\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const lengthSq = dx * dx + dy * dy;\n const t =\n lengthSq === 0\n ? 0\n : Math.max(\n 0,\n Math.min(1, ((pt[0] - a[0]) * dx + (pt[1] - a[1]) * dy) / lengthSq),\n );\n const px = pt[0] - a[0] - t * dx;\n const py = pt[1] - a[1] - t * dy;\n return px * px + py * py <= threshold * threshold;\n}\n\n// Shape hit tests, keyed by shape name. Extensible via `UI.registerShape`.\nconst _shapeTests: { [key: string]: UIShapeTest } = {\n rectangle: (group, pt) => Rectangle.withinBound(group, pt),\n circle: (group, pt) => Circle.withinBound(group, pt),\n polygon: (group, pt) => Polygon.hasIntersectPoint(group, pt),\n line: (group, pt, states) => {\n const threshold = states.lineThreshold ?? 5;\n return (\n group.length >= 2 && _withinSegment(group[0], group[1], pt, threshold)\n );\n },\n polyline: (group, pt, states) => {\n const threshold = states.lineThreshold ?? 5;\n for (let i = 0, len = group.length - 1; i < len; i++) {\n if (_withinSegment(group[i], group[i + 1], pt, threshold)) return true;\n }\n return false;\n },\n};\n\n/**\n * **[Experimental]** A set of string constatns to represent different UI types, for use in [`UI`](#link) instances.\n */\nexport const UIShape = {\n rectangle: \"rectangle\",\n circle: \"circle\",\n polygon: \"polygon\",\n polyline: \"polyline\",\n line: \"line\",\n};\n\n/**\n * **[Experimental]** A set of string constants to represent different UI event types.\n */\nexport const UIPointerActions = {\n up: \"up\",\n down: \"down\",\n move: \"move\",\n drag: \"drag\",\n uidrag: \"uidrag\",\n drop: \"drop\",\n uidrop: \"uidrop\",\n over: \"over\",\n out: \"out\",\n enter: \"enter\",\n leave: \"leave\",\n click: \"click\",\n keydown: \"keydown\",\n keyup: \"keyup\",\n pointerdown: \"pointerdown\",\n pointerup: \"pointerup\",\n contextmenu: \"contextmenu\",\n all: \"all\",\n} as const;\n\n/** A known pointer, touch, or keyboard action dispatched by a Pts space. */\nexport type UIPointerAction =\n (typeof UIPointerActions)[keyof typeof UIPointerActions];\n\n/**\n * **[Experimental]** An abstract class that represents an UI element. It wraps a [`Group`](#link) and supports UI event handling.\n * Extend this class to create custom UI elements.\n */\nexport class UI {\n private _abortCleanup: { [type: string]: Map<number, () => void> } = {};\n _group: Group;\n _shape: string;\n\n protected static _counter: number = 0;\n protected _id: string;\n protected _actions: { [type: string]: (UIHandler | null)[] };\n // built-in machinery (UIButton hover, UIDragger drag) registers here, so\n // public `off(type)` cannot remove it along with user handlers\n protected _sysActions: { [type: string]: (UIHandler | null)[] };\n protected _states: { [key: string]: any };\n\n protected _holds = new Map<number, string>();\n\n /**\n * Create an UI element. You may also create a new UI using one of the static helper like [`UI.fromRectangle`](#link) or [`UI.fromCircle`](#link).\n * @param group a Group or an Iterable<PtLike> that defines the UI's appearance\n * @param shape specifies the shape of the Group\n * @param states optional a state object keep track of custom states for this UI\n * @param id optional id string\n */\n constructor(\n group: PtLikeIterable,\n shape: string,\n states: { [key: string]: any } = {},\n id?: string,\n ) {\n this._group = Group.fromArray(group);\n this._shape = shape;\n this._id = id === undefined ? `ui_${UI._counter++}` : id;\n this._states = states;\n this._actions = {};\n this._sysActions = {};\n }\n\n /**\n * Register a custom shape hit test, or override a built-in one. The shape\n * name can then be used when constructing a UI.\n * @param shape shape name\n * @param fn a function `(group, pt, states) => boolean` that returns whether the point hits the shape\n */\n static registerShape(shape: string, fn: UIShapeTest): void {\n _shapeTests[shape] = fn;\n }\n\n /**\n * A static helper function to create a Rectangle UI.\n * @param group a Group or an Iterable<PtLike> with 2 Pt representing a rectangle\n * @param states optional a state object keep track of custom states for this UI\n * @param id optional id string\n */\n static fromRectangle(group: PtLikeIterable, states: {}, id?: string): UI {\n return new this(group, UIShape.rectangle, states, id);\n }\n\n /**\n * A static helper function to create a Circle UI.\n * @param group a Group or an Iterable<PtLike> with 2 Pt representing a circle\n * @param states optional a state object keep track of custom states for this UI\n * @param id optional id string\n */\n static fromCircle(group: PtLikeIterable, states: {}, id?: string): UI {\n return new this(group, UIShape.circle, states, id);\n }\n\n /**\n * A static helper function to create a Polygon UI.\n * @param group a Group or an Iterable<PtLike> representing a polygon\n * @param states optional a state object keep track of custom states for this UI\n * @param id optional id string\n */\n static fromPolygon(group: PtLikeIterable, states: {}, id?: string): UI {\n return new this(group, UIShape.polygon, states, id);\n }\n\n /**\n * A static helper function to create a new UI based on another UI.\n * @param ui base UI\n * @param states optional a state object keep track of custom states for this UI\n */\n static fromUI(ui: UI, states?: object, id?: string): UI {\n // copy the source states so the new UI doesn't share mutations\n return new this(ui.group, ui.shape, states || { ...ui._states }, id);\n }\n\n /**\n * An unique id of the UI.\n */\n get id(): string {\n return this._id;\n }\n set id(d: string) {\n this._id = d;\n }\n\n /**\n * A group of Pts that defines this UI's shape.\n */\n get group(): Group {\n return this._group;\n }\n set group(d: Group) {\n this._group = d;\n }\n\n /**\n * A string that describes this UI's shape.\n */\n get shape(): string {\n return this._shape;\n }\n set shape(d: string) {\n this._shape = d;\n }\n\n /**\n * Get and/or set a specific UI state.\n * @param key state's name\n * @param value optionally set a new value for this state.key\n * @returns If `value` is changed, return this instance. Otherwise, return the value of the specific key.\n */\n state(key: string, value?: any): any {\n if (!key) return null;\n if (value !== undefined) {\n this._states[key] = value;\n return this;\n }\n return this._states[key];\n }\n\n /**\n * Get a specific UI state. Unlike [`UI.state`](#link), this is a plain typed getter.\n * @param key state's name\n */\n getState<T = any>(key: string): T {\n return this._states[key];\n }\n\n /**\n * Set a specific UI state. Unlike [`UI.state`](#link), this can also store `undefined`.\n * @param key state's name\n * @param value the value to set\n */\n setState(key: string, value: any): this {\n this._states[key] = value;\n return this;\n }\n\n /**\n * Add an event handler. Remember this UI will also need to be tracked for events, via `UI.track` or [`MultiTouchSpace.track`](#link).\n * @param type event type, either one of [`UIPointerActions`](#link) or a custom type\n * @param fn a [`UIHandler`](#link) callback function: `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @param options optionally `{ once }` to remove the handler after its first call, and/or `{ signal }` with an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that removes it on abort (an already-aborted signal registers nothing)\n * @returns an id number that reference to this handler, for use in [`UI.off`](#link), or -1 if nothing was registered\n */\n on(\n type: UIPointerAction | (string & {}),\n fn: UIHandler,\n options?: { once?: boolean; signal?: AbortSignal },\n ): number {\n if (!fn) return -1;\n if (options?.signal?.aborted) return -1;\n if (!this._actions[type]) this._actions[type] = [];\n\n let handler = fn;\n let id = -1;\n if (options?.once) {\n handler = (t, p, ty, e) => {\n this.off(type, id);\n fn(t, p, ty, e);\n };\n }\n id = UI._addHandler(this._actions[type], handler);\n if (options?.signal) {\n const signal = options.signal;\n const abort = () => this.off(type, id);\n signal.addEventListener(\"abort\", abort, { once: true });\n if (!this._abortCleanup[type]) this._abortCleanup[type] = new Map();\n this._abortCleanup[type].set(id, () =>\n signal.removeEventListener(\"abort\", abort),\n );\n }\n return id;\n }\n\n /**\n * Remove an event handler.\n * @param type event type\n * @param which an ID number returned by [`UI.on`](#link). If this is not defined, all handlers in this type will be removed (built-in machinery like UIButton's click counting is unaffected). Note that after removal an id is stale — removing it twice may affect a handler that has since reused the slot.\n */\n off(type: UIPointerAction | (string & {}), which?: number): boolean {\n if (!this._actions[type]) return false;\n if (which === undefined) {\n this._abortCleanup[type]?.forEach((cleanup) => cleanup());\n delete this._abortCleanup[type];\n delete this._actions[type];\n return true;\n } else {\n this._abortCleanup[type]?.get(which)?.();\n this._abortCleanup[type]?.delete(which);\n return UI._removeHandler(this._actions[type], which);\n }\n }\n\n /**\n * Listen for UI events and trigger action handlers.\n * @param type an action type. Can be one of UIPointerActions or a custom one.\n * @param p a point to check\n * @param evt a MouseEvent emitted by the browser (See [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent))\n */\n listen(\n type: UIPointerAction | (string & {}),\n p: PtLike,\n evt: UIActionEvent,\n ): boolean {\n let fired = false;\n const userActions = this._actions[type];\n const sysActions = this._sysActions[type];\n\n if (userActions || sysActions) {\n if (this._within(p) || this._holdsType(type)) {\n if (sysActions) {\n UI._trigger(sysActions, this, p, type, evt);\n fired = true;\n }\n if (userActions) {\n UI._trigger(userActions, this, p, type, evt);\n fired = true;\n }\n }\n }\n\n // \"all\" handlers observe every event, regardless of position\n if (this._actions[\"all\"]) {\n UI._trigger(this._actions[\"all\"], this, p, type, evt);\n fired = true;\n }\n\n return fired;\n }\n\n /** Check whether an action type is currently held, without allocating. */\n private _holdsType(type: string): boolean {\n for (const held of this._holds.values()) {\n if (held === type) return true;\n }\n return false;\n }\n\n /** Register a built-in handler unaffected by public `off`. */\n protected _sysOn(type: string, fn: UIHandler): number {\n if (!this._sysActions[type]) this._sysActions[type] = [];\n return UI._addHandler(this._sysActions[type], fn);\n }\n\n /** Remove a built-in handler registered with `_sysOn`. */\n protected _sysOff(type: string, which: number): boolean {\n if (!this._sysActions[type]) return false;\n return UI._removeHandler(this._sysActions[type], which);\n }\n\n /**\n * Continue to keep track of an actions even if it's not within this UI. Useful for hover-leave and drag-outside.\n * @param type a string defined in [`UIPointerActions`](#link)\n */\n protected hold(type: string): number {\n let newKey = Math.max(0, ...Array.from(this._holds.keys())) + 1;\n this._holds.set(newKey, type);\n return newKey;\n }\n\n /**\n * Stop keeping track of this action\n * @param key an id returned by the [`UI.hold`](#link) function\n */\n protected unhold(key?: number): void {\n if (key !== undefined) {\n this._holds.delete(key);\n } else {\n this._holds.clear();\n }\n }\n\n /**\n * A static function to listen for a list of UIs. See also [`UI.listen`](#link).\n * @param uis an array of UI\n * @param type an action type. Can be one of `UIPointerActions` or a custom one.\n * @param p a point to check\n * @param evt a MouseEvent emitted by the browser (See [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent))\n */\n static track(uis: UI[], type: string, p: PtLike, evt: UIActionEvent): void {\n for (let i = 0, len = uis.length; i < len; i++) {\n uis[i].listen(type, p, evt);\n }\n }\n\n /**\n * Take a custom render function to render this UI.\n * @param fn a render function\n */\n render(fn: (group: Group, states: { [key: string]: any }) => void): void {\n fn(this._group, this._states);\n }\n\n /**\n * Returns a string representation of this UI\n */\n toString(): string {\n return `UI ${this.group.toString()}`;\n }\n\n /**\n * Check intersection using the hit test registered for this UI's shape.\n * @param p a point to check\n * @returns a boolean to indicate if the event should be triggered\n */\n protected _within(p: PtLike): boolean {\n const fn = _shapeTests[this._shape];\n if (!fn) return false;\n return fn(this._group, p, this._states);\n }\n\n /**\n * Static function to trigger an array of UIHandlers\n */\n protected static _trigger(\n fns: (UIHandler | null)[],\n target: UI,\n pt: PtLike,\n type: string,\n evt: UIActionEvent,\n ) {\n if (fns) {\n for (let i = 0, len = fns.length; i < len; i++) {\n if (fns[i]) fns[i]!(target, pt, type, evt);\n }\n }\n }\n\n /**\n * Static function to add a new handler to an array store of UIHandlers.\n */\n protected static _addHandler(\n fns: (UIHandler | null)[],\n fn: UIHandler,\n ): number {\n if (!fn) return -1;\n // reuse a removed slot so ids stay stable and the array doesn't grow\n // unboundedly when handlers are added and removed repeatedly\n for (let i = 0, len = fns.length; i < len; i++) {\n if (fns[i] === null) {\n fns[i] = fn;\n return i;\n }\n }\n fns.push(fn);\n return fns.length - 1;\n }\n\n /**\n * Static function to remove an existing handler from an array store of UIHandlers.\n * The slot is nulled (not spliced) so other handlers' ids remain valid.\n */\n protected static _removeHandler(\n fns: (UIHandler | null)[],\n index: number,\n ): boolean {\n if (index >= 0 && index < fns.length && fns[index]) {\n fns[index] = null;\n return true;\n }\n return false;\n }\n}\n\n/**\n * **[Experimental]** A simple button that extends [`UI`](#link) to track clicks and hovers.\n */\nexport class UIButton extends UI {\n private _hoverID: number = -1;\n\n /**\n * Create an UIButton. A button has 2 states, \"clicks\" (number) and \"hover\" (boolean), which you can access through [`UI.state`](#link) function. You may also create a new UIButton using one of the static helper like [`UI.fromRectangle`](#link) or [`UI.fromCircle`](#link).\n * @param group a Group or an Iterable<PtLike> that defines the UI's appearance\n * @param shape specifies the shape of the Group\n * @param states Optional default state object\n * @param id Optional id string\n */\n constructor(\n group: PtLikeIterable,\n shape: string,\n states: { [key: string]: any } = {},\n id?: string,\n ) {\n super(group, shape, states, id);\n\n if (states.hover === undefined) this._states[\"hover\"] = false;\n if (states.clicks === undefined) this._states[\"clicks\"] = 0;\n\n const UA = UIPointerActions;\n\n // listen for clicks when mouse up and increment clicks\n this._sysOn(UA.up, () => {\n this.state(\"clicks\", this._states.clicks + 1);\n });\n\n // listen for move events and fire enter and leave events accordingly\n this._sysOn(\n UA.move,\n (target: UI, pt: PtLike, type: string, evt: UIActionEvent) => {\n let hover = this._within(pt);\n\n // hover on\n if (hover && !this._states.hover) {\n this.state(\"hover\", true);\n\n // enter trigger\n UI._trigger(this._actions[UA.enter], this, pt, UA.enter, evt);\n\n // listen for hover off\n let _capID = this.hold(UA.move); // keep hold of second move\n this._hoverID = this._sysOn(\n UA.move,\n (t: UI, p: PtLike, ty: string, e: UIActionEvent) => {\n if (!this._within(p) && !this.state(\"dragging\")) {\n this.state(\"hover\", false);\n // leave trigger, with the current position and event\n UI._trigger(this._actions[UA.leave], this, p, UA.leave, e);\n this._sysOff(UA.move, this._hoverID); // remove second move listener\n this.unhold(_capID); // stop keeping hold of second move\n }\n },\n );\n }\n },\n );\n }\n\n /**\n * Add a new click handler. Remember this button will also need to be tracked for events via `UI.track`. If you want to track right clicks, you may also consider [`UIButton.onContextMenu`](#link).\n * @param fn a [`UIHandler`](#link) callback function: `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @returns an id number that refers to this handler, for use in [`UIButton.offClick`](#link) or [`UI.off`](#link).\n */\n onClick(fn: UIHandler): number {\n return this.on(UIPointerActions.up, fn);\n }\n\n /**\n * Remove an existing click handler\n * @param id an ID number returned by [`UIButton.onClick`](#link). If this is not defined, all handlers in this type will be removed.\n * @returns a boolean indicating whether the handler was removed successfully\n */\n offClick(id: number): boolean {\n return this.off(UIPointerActions.up, id);\n }\n\n /**\n * Add a new contextmenu handler. `contextmenu` is similar to right click, see the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event). Remember this button will also need to be tracked for events via `UI.track`. Also note that you may need to use `event.preventDefault()` in the callback function to prevent other events from triggering.\n * @param fn a [`UIHandler`](#link) callback function: `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @returns an id number that refers to this handler, for use in [`UIButton.offContextMenu`](#link) or [`UI.off`](#link).\n */\n onContextMenu(fn: UIHandler): number {\n return this.on(UIPointerActions.contextmenu, fn);\n }\n\n /**\n * Remove an existing contextmenu handler\n * @param id an ID number returned by [`UIButton.onContextMenu`](#link). If this is not defined, all handlers in this type will be removed.\n * @returns a boolean indicating whether the handler was removed successfully\n */\n offContextMenu(id: number): boolean {\n return this.off(UIPointerActions.contextmenu, id);\n }\n\n /**\n * Add handlers for hover events. Remember this button will also need to be tracked for events via `UI.track`.\n * @param enter an optional [`UIHandler`](#link) function to handle when pointer enters hover. Eg, `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @param leave an optional [`UIHandler`](#link) function to handle when pointer exits hover. Eg, `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @returns id numbers that refer to enter/leave handlers, for use in [`UIButton.offHover`](#link) or [`UI.off`](#link).\n */\n onHover(enter?: UIHandler, leave?: UIHandler): (number | undefined)[] {\n let ids: (number | undefined)[] = [undefined, undefined];\n if (enter) ids[0] = this.on(UIPointerActions.enter, enter);\n if (leave) ids[1] = this.on(UIPointerActions.leave, leave);\n return ids;\n }\n\n /**\n * Remove handlers for hover events.\n * @param enterID an ID number returned by [`UI.onClick`](#link), or -1 to skip. If this is not defined, all handlers in this type will be removed.\n * @param leaveID an ID number returned by [`UI.onClick`](#link), or -1 to skip. If this is not defined, all handlers in this type will be removed.\n * @returns an array of booleans indicating whether the handlers were removed successfully\n */\n offHover(enterID?: number, leaveID?: number): boolean[] {\n let s = [false, false];\n if (enterID === undefined || enterID >= 0)\n s[0] = this.off(UIPointerActions.enter, enterID);\n if (leaveID === undefined || leaveID >= 0)\n s[1] = this.off(UIPointerActions.leave, leaveID);\n return s;\n }\n}\n\n/**\n * [Experimental] A draggable UI that provides handler such as [`UIDragger.onDrag`](#link) and [`UIDragger.onDrop`](#link).\n */\nexport class UIDragger extends UIButton {\n private _draggingID: number = -1;\n private _dragID: number = -1;\n private _moveHoldID: number = -1;\n private _dragHoldID: number = -1;\n private _dropHoldID: number = -1;\n private _upHoldID: number = -1;\n private _outHoldID: number = -1;\n private _lastMoveEvent: UIActionEvent | undefined;\n\n /**\n * Create a dragger which has all the states in UIButton, with additional \"dragging\" (a boolean indicating whether it's currently being dragged) and \"offset\" (a Pt representing the offset between this UI's position and the pointer's position when dragged) states. (See [`UI.state`](#link)) You may also create a new UIDragger using one of the static helper like [`UI.fromRectangle`](#link) or [`UI.fromCircle`](#link).\n * @param group a Group or an Iterable<PtLike> that defines the UI's appearance\n * @param shape specifies the shape of the Group\n * @param states Optional default state object\n * @param id Optional id string\n */\n constructor(\n group: PtLikeIterable,\n shape: string,\n states: { [key: string]: any } = {},\n id?: string,\n ) {\n super(group, shape, states, id);\n if (states.dragging === undefined) this._states[\"dragging\"] = false;\n if (states.moved === undefined) this._states[\"moved\"] = false;\n if (states.offset === undefined) this._states[\"offset\"] = new Pt();\n\n const UA = UIPointerActions;\n\n /*\n * Note: drag/drop is implemented in Space.ts, uidrag/uidrop is\n * reimplemented here so that we can keep track of move events happening\n * outside of the UI element. E.g. when the mouse moves faster than the\n * UI refreshes.\n */\n\n // Handle pointer down and begin dragging\n this._sysOn(\n UA.down,\n (target: UI, pt: PtLike, type: string, evt: UIActionEvent) => {\n // begin listening for all events after dragging starts\n if (this._moveHoldID === -1) {\n this.state(\"dragging\", true);\n this.state(\"offset\", new Pt(pt).subtract(target.group[0]));\n this._moveHoldID = this.hold(UA.move); // keep hold of move\n this._dragHoldID = this.hold(UA.drag);\n this._outHoldID = this.hold(UA.out);\n }\n if (this._dropHoldID === -1) {\n this._dropHoldID = this.hold(UA.drop); // keep hold of drop (normal drag and drop)\n }\n if (this._upHoldID === -1) {\n this._upHoldID = this.hold(UA.up); // keep hold of up (cancel dragging if simple click)\n }\n if (this._draggingID === -1) {\n const drag = (t: UI, p: PtLike, ty: string, e: UIActionEvent) => {\n // Touch movement forwards both move and drag for the same event.\n const paired = ty === UA.drag && e === this._lastMoveEvent;\n this._lastMoveEvent = ty === UA.move ? e : undefined;\n if (paired) return;\n if (this.state(\"dragging\")) {\n UI._trigger(this._actions[UA.uidrag], t, p, UA.uidrag, e);\n this.state(\"moved\", true);\n }\n };\n this._draggingID = this._sysOn(UA.move, drag);\n this._dragID = this._sysOn(UA.drag, drag);\n }\n },\n );\n\n // Handle pointer drop or up and end dragging\n const endDrag = (\n target: UI,\n pt: PtLike,\n type: string,\n evt: UIActionEvent,\n ) => {\n this.state(\"dragging\", false);\n // remove move listener\n this._sysOff(UA.move, this._draggingID);\n this._sysOff(UA.drag, this._dragID);\n this._draggingID = -1;\n this._dragID = -1;\n this._lastMoveEvent = undefined;\n // stop keeping hold of move\n this.unhold(this._moveHoldID);\n this._moveHoldID = -1;\n this.unhold(this._dragHoldID);\n this._dragHoldID = -1;\n this.unhold(this._outHoldID);\n this._outHoldID = -1;\n // stop keeping hold of drop\n this.unhold(this._dropHoldID);\n this._dropHoldID = -1;\n // stop keeping hold of up\n this.unhold(this._upHoldID);\n this._upHoldID = -1;\n // trigger event\n if (this.state(\"moved\")) {\n UI._trigger(this._actions[UA.uidrop], target, pt, UA.uidrop, evt);\n this.state(\"moved\", false);\n }\n };\n this._sysOn(UA.drop, endDrag);\n this._sysOn(UA.up, endDrag);\n this._sysOn(UA.out, endDrag);\n }\n\n /**\n * Add a new drag handler. Remember this button will also need to be tracked for events via `UI.track`.\n * @param fn a [`UIHandler`](#link) callback function: `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`. You can access the states \"dragging\" and \"offset\" (See [`UI.state`](#link)) in the callback.\n * @returns an id number that refers to this handler, for use in [`UIDragger.offDrag`](#link) or [`UI.off`](#link).\n */\n onDrag(fn: UIHandler): number {\n return this.on(UIPointerActions.uidrag, fn);\n }\n\n /**\n * Remove an existing drag handler\n * @param id an ID number returned by [`UIDragger.onDrag`](#link). If this is not defined, all handlers in this type will be removed.\n * @returns a boolean indicating whether the handler was removed successfully\n */\n offDrag(id: number): boolean {\n return this.off(UIPointerActions.uidrag, id);\n }\n\n /**\n * Add a new drop handler. Remember this button will also need to be tracked for events via `UI.track`.\n * @param fn a [`UIHandler`](#link) callback function: `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @returns an id number that refers to this handler, for use in [`UIDragger.offDrop`](#link) or [`UI.off`](#link).\n */\n onDrop(fn: UIHandler): number {\n return this.on(UIPointerActions.uidrop, fn);\n }\n\n /**\n * Remove an existing drop handler\n * @param id an ID number returned by [`UIDragger.onDrag`](#link). If this is not defined, all handlers in this type will be removed.\n * @returns a boolean indicating whether the handler was removed successfully\n */\n offDrop(id: number): boolean {\n return this.off(UIPointerActions.uidrop, id);\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Bound } from \"./Pt\";\nimport { type Form } from \"./Form\";\nimport { UI, UIPointerActions as UIA } from \"./UI\";\nimport {\n type ITimer,\n type ISpacePlayers,\n type IPlayer,\n type AnimateCallbackFn,\n type TouchPointsKey,\n type UIActionEvent,\n} from \"./Types\";\n\n/**\n * Space is an abstract class that represents a general context for expressing Pts. It's extended through subclasses such as [`CanvasSpace`](#link) and [`SVGSpace`](#link). You can also create your own extension of Space.\n * See [Space guide](../guide/Space-0500.html) for details.\n */\nexport abstract class Space {\n id: string = \"space\";\n protected bound: Bound = new Bound();\n\n protected _time: ITimer = { prev: 0, diff: 0, end: -1, min: 0 };\n private _stopAfter = -1; // a stop(t) period awaiting the next frame's clock\n protected players: ISpacePlayers = {};\n protected playerCount = 0;\n protected _ctx: any;\n\n private _animID: number = -1;\n private _fromFrame = false;\n\n private _pause: boolean = false;\n private _refresh: boolean | undefined = undefined;\n private _renderFunc!: (context: any, self: Space) => null;\n\n protected _pointer: Pt = new Pt();\n\n protected _isReady = false;\n protected _playing = false;\n private _firstFrame = true;\n\n /**\n * Set whether the rendering should be repainted on each frame.\n * @param b a boolean value to set whether to repaint each frame\n */\n refresh(b: boolean): this {\n this._refresh = b;\n return this;\n }\n\n /**\n * Set a minimum frame time\n * @param ms at least this amount of milliseconds must have elapsed before frame advances\n */\n minFrameTime(ms: number = 0): this {\n this._time.min = ms;\n return this;\n }\n\n /**\n * Add an [`IPlayer`](#link) object or a [`AnimateCallbackFn`](#link) callback function to handle events in this Space. An IPlayer is an object with the following callback functions:\n * - required: `animate: fn( time, ftime, space )`\n * - optional: `start: fn(bound, space)`\n * - optional: `resize: fn( size, event )`\n * - optional: `action: fn( type, x, y, event )`\n * Subclasses of Space may define other callback functions.\n * @param p an [`IPlayer`](#link) object with animate function, or a callback function `fn(time, ftime)`.\n */\n add(p: IPlayer | AnimateCallbackFn): this {\n const player: IPlayer = typeof p == \"function\" ? { animate: p } : p;\n\n const k = this.playerCount++;\n const pid = player.animateID || this.id + k;\n\n this.players[pid] = player;\n player.animateID = pid;\n // resize callbacks receive the live bound (as they do on space resize);\n // treat it as read-only\n if (player.resize && this.bound.inited) player.resize(this.bound);\n\n // if _refresh is not set, set it to true\n if (this._refresh === undefined) this._refresh = true;\n\n return this;\n }\n\n /**\n * Remove a player from this Space.\n * @param player an IPlayer that has an `animateID` property\n */\n remove(player: IPlayer): this {\n delete this.players[player.animateID!];\n return this;\n }\n\n /**\n * Remove all players from this Space.\n */\n removeAll(): this {\n this.players = {};\n return this;\n }\n\n /**\n * Main play loop. This implements `window.requestAnimationFrame` and calls it recursively.\n * You may override this `play()` function to implement your own animation loop.\n * @param time current time\n */\n play(time = 0): this {\n // A real RAF can have timestamp 0 too. Consume its marker before invoking\n // players so a nested manual play() still cannot start a second loop.\n const fromFrame = this._fromFrame;\n this._fromFrame = false;\n // make sure only one play loop is active: an external play() while the\n // loop runs is a no-op...\n if (time === 0 && this._animID !== -1 && !fromFrame) {\n return this;\n }\n // ...and any other call (a frame callback, or a manual play(t)) replaces\n // the pending frame instead of stacking a parallel chain — cancelling an\n // already-fired frame id is a spec-defined no-op\n if (this._animID !== -1) cancelAnimationFrame(this._animID);\n this._animID = requestAnimationFrame((frameTime) => {\n this._fromFrame = true;\n try {\n this.play(frameTime);\n } finally {\n this._fromFrame = false;\n }\n });\n\n if (this._pause) {\n // track time while paused so resuming doesn't deliver the entire\n // pause duration as one frame's ftime\n this._time.prev = time;\n return this;\n }\n\n if (this._firstFrame) {\n // the first frame after a fresh start renders immediately with no\n // elapsed time — `time` is an arbitrary clock timestamp, not a delta\n // play() draws synchronously at synthetic time 0. Keep initialization\n // pending until RAF supplies its first real clock timestamp.\n this._firstFrame = time === 0 && !fromFrame;\n this._time.diff = 0;\n this._time.prev = time;\n } else {\n const diff = time - this._time.prev;\n // accumulate until the minimum frame time is reached\n if (diff < this._time.min) return this;\n this._time.diff = diff;\n this._time.prev = time;\n }\n\n try {\n this.playItems(time);\n } catch (err) {\n cancelAnimationFrame(this._animID);\n this._animID = -1;\n this._playing = false;\n this._firstFrame = true;\n throw err;\n }\n\n return this;\n }\n\n /**\n * Replay the animation after [`Space.stop`](#link). This resets the end-time counter.\n * You may also use [`Space.pause`](#link) and [`resume`](#link) for temporary pause.\n */\n replay() {\n this._time.end = -1;\n this.play();\n }\n\n /**\n * Main animate function. This calls all the items to perform.\n * @param time current time\n */\n protected playItems(time: number) {\n this._playing = true;\n\n // clear before draw if refresh is true\n if (this._refresh) this.clear();\n\n // animate all players\n if (this._isReady) {\n for (const k in this.players) {\n if (this.players[k].animate)\n this.players[k].animate(time, this._time.diff, this);\n }\n }\n\n // resolve a stop period against the frame clock\n if (this._stopAfter >= 0) {\n this._time.end = time + this._stopAfter;\n this._stopAfter = -1;\n }\n\n // stop if time ended\n if (this._time.end >= 0 && time > this._time.end) {\n cancelAnimationFrame(this._animID);\n this._animID = -1;\n this._playing = false;\n this._firstFrame = true;\n }\n }\n\n /**\n * Pause the animation.\n * @param toggle a boolean value to set if this function call should be a toggle (between pause and resume)\n */\n pause(toggle = false): this {\n this._pause = toggle ? !this._pause : true;\n return this;\n }\n\n /**\n * Resume the pause animation.\n */\n resume(): this {\n this._pause = false;\n return this;\n }\n\n /**\n * Specify when the animation should stop: immediately, after a time period, or never stops.\n * After stopping, use [`Space.replay`](#link) to play again.\n * @param t a value in millisecond to specify a time period to play before stopping, or `-1` to play forever, or `0` to end immediately. Default is 0 which will stop the animation immediately.\n */\n stop(t = 0): this {\n // a period is measured from the next frame's clock, since frame\n // timestamps are absolute and not comparable with a duration\n this._stopAfter = t > 0 ? t : -1;\n this._time.end = t > 0 ? -1 : t;\n return this;\n }\n\n /**\n * Cancel the active animation frame immediately. Subclasses should call this\n * when they dispose browser resources instead of waiting for `stop()` to be\n * observed by the next frame.\n */\n protected _cancelAnimation(): this {\n if (this._animID !== -1) cancelAnimationFrame(this._animID);\n this._animID = -1;\n this._playing = false;\n this._firstFrame = true;\n return this;\n }\n\n /**\n * Play animation loop once. Optionally set a `duration` time to play for that specific duration.\n * @param duration a value in millisecond to specify a time period to play before stopping, or `-1` to play forever\n */\n playOnce(duration = 0): this {\n this.play();\n this.stop(duration);\n return this;\n }\n\n /**\n * Custom rendering.\n * @param context rendering context\n */\n protected render(context: any): this {\n if (this._renderFunc) this._renderFunc(context, this);\n return this;\n }\n\n /**\n * Set a custom rendering function `fn(graphics_context, canvas_space)` if needed.\n */\n set customRendering(f: (context: any, self: Space) => null) {\n this._renderFunc = f;\n }\n get customRendering(): (context: any, self: Space) => null {\n return this._renderFunc;\n }\n\n /**\n * Indicate whether the animation is playing.\n */\n get isPlaying(): boolean {\n return this._playing;\n }\n\n /**\n * The outer bounding box which includes its positions.\n */\n get outerBound(): Bound {\n return this.bound.clone();\n }\n\n /**\n * The inner bounding box of the space, excluding its positions.\n */\n public get innerBound(): Bound {\n return new Bound(Pt.make(this.size.length, 0), this.size.clone());\n }\n\n /**\n * The size of this space's bounding box.\n */\n get size(): Pt {\n return this.bound.size.clone();\n }\n\n /**\n * The center of this space's bounding box.\n */\n get center(): Pt {\n return this.size.divide(2);\n }\n\n /**\n * The width of this space's bounding box.\n */\n get width(): number {\n return this.bound.width;\n }\n\n /**\n * The height of this space's bounding box.\n */\n get height(): number {\n return this.bound.height;\n }\n\n /**\n * Resize the space. To be implemented in subclasses.\n * @param b a Bound representing the position and size of the space\n * @param evt event\n */\n abstract resize(b: Bound, evt?: Event | null): this;\n\n /**\n * clear all contents in the space. To be implemented in subclasses.\n */\n abstract clear(): this;\n\n /**\n * Get a default form for drawing in this space. To be implemented in subclasses.\n */\n abstract getForm(): Form;\n}\n\n/**\n * MultiTouchSpace is an abstract class that extends [`Space`](#link) to support user interactions via touch events.\n * It's extended through subclasses such as [`CanvasSpace`](#link) and [`SVGSpace`](#link).\n */\nexport abstract class MultiTouchSpace extends Space {\n // track mouse dragging\n protected _pressed = false;\n protected _dragged = false;\n\n protected _hasMouse = false;\n protected _hasTouch = false;\n protected _hasKeyboard = false;\n\n private _mouseTarget: Element | undefined;\n private _touchTarget: Element | undefined;\n private _keyboardTarget: EventTarget | undefined;\n private _touchPassive = false;\n\n private readonly _mouseDownBind = this._mouseDown.bind(\n this,\n ) as unknown as EventListener;\n private readonly _mouseUpBind = this._mouseUp.bind(\n this,\n ) as unknown as EventListener;\n private readonly _mouseOverBind = this._mouseOver.bind(\n this,\n ) as unknown as EventListener;\n private readonly _mouseOutBind = this._mouseOut.bind(\n this,\n ) as unknown as EventListener;\n private readonly _mouseMoveBind = this._mouseMove.bind(\n this,\n ) as unknown as EventListener;\n private readonly _mouseClickBind = this._mouseClick.bind(\n this,\n ) as unknown as EventListener;\n private readonly _contextMenuBind = this._contextMenu.bind(\n this,\n ) as unknown as EventListener;\n private readonly _touchStartBind = this._touchStart.bind(\n this,\n ) as unknown as EventListener;\n private readonly _touchMoveBind = this._touchMove.bind(\n this,\n ) as unknown as EventListener;\n private readonly _keyDownBind = this._keyDown.bind(\n this,\n ) as unknown as EventListener;\n private readonly _keyUpBind = this._keyUp.bind(\n this,\n ) as unknown as EventListener;\n\n // accept subclasses that implements addEventListener, removeEventListener, dispatchEvent\n protected _canvas!: EventTarget;\n\n /**\n * Get the mouse or touch pointer that stores the last action.\n */\n public get pointer(): Pt {\n const p = this._pointer.clone();\n p.id = this._pointer.id;\n return p;\n }\n\n /**\n * Bind event listener in canvas element. You can also use [`MultiTouchSpace.bindMouse`](#link) or [`MultiTouchSpace.bindTouch`](#link) to bind mouse or touch events conveniently.\n * @param evt an event string such as \"mousedown\"\n * @param callback callback function for this event\n * @param options options for [addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener).\n * @param customTarget an optional event target to use instead of the canvas element\n */\n bindCanvas(\n evt: string,\n callback: EventListener,\n options: any = {},\n customTarget?: Element,\n ) {\n const target = customTarget ? customTarget : this._canvas;\n target.addEventListener(evt, callback, options);\n }\n\n /**\n * Unbind a callback from the event listener.\n * @param evt an event string such as \"mousedown\"\n * @param callback callback function to unbind\n * @param options options for [removeEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener). This should match the options set in bindCanvas.\n * @param customTarget If customTarget is set in bindCanvas, you'll need to pass the same instance here to unbind\n */\n unbindCanvas(\n evt: string,\n callback: EventListener,\n options: any = {},\n customTarget?: Element,\n ) {\n const target = customTarget ? customTarget : this._canvas;\n target.removeEventListener(evt, callback, options);\n }\n\n bindDoc(evt: string, callback: EventListener, options: any = {}) {\n if (typeof document !== \"undefined\") {\n document.addEventListener(evt, callback, options);\n }\n }\n\n unbindDoc(evt: string, callback: EventListener, options: any = {}) {\n if (typeof document !== \"undefined\") {\n document.removeEventListener(evt, callback, options);\n }\n }\n\n /**\n * A convenient method to bind (or unbind) all mouse events in canvas element.\n * All [`IPlayer`](#link) objects added to this space that implement an `action` callback property will receive mouse event callbacks.\n * Mouse action names are defined by [`UIPointerActions`](#link), including \"up\", \"down\", \"move\", \"drag\", \"drop\", \"over\", \"out\", \"click\", \"pointerdown\", \"pointerup\", and \"contextmenu\".\n * @param bind a boolean value to bind mouse events if set to `true`. If `false`, all mouse events will be unbound. Default is true.\n * @param customTarget an optional event target to use instead of the canvas element\n * @see [`Space.add`](#link)\n */\n bindMouse(bind: boolean = true, customTarget?: Element): this {\n if (bind) {\n if (this._hasMouse) {\n if (this._mouseTarget === customTarget) return this;\n this.bindMouse(false);\n }\n\n this._mouseTarget = customTarget;\n this.bindCanvas(\"pointerdown\", this._mouseDownBind, {}, customTarget);\n this.bindCanvas(\"pointerup\", this._mouseUpBind, {}, customTarget);\n this.bindCanvas(\"pointerover\", this._mouseOverBind, {}, customTarget);\n this.bindCanvas(\"pointerout\", this._mouseOutBind, {}, customTarget);\n this.bindCanvas(\"pointercancel\", this._mouseOutBind, {}, customTarget);\n this.bindCanvas(\"pointermove\", this._mouseMoveBind, {}, customTarget);\n this.bindCanvas(\"click\", this._mouseClickBind, {}, customTarget);\n this.bindCanvas(\"contextmenu\", this._contextMenuBind, {}, customTarget);\n this._hasMouse = true;\n } else if (this._hasMouse) {\n const target = this._mouseTarget;\n this.unbindCanvas(\"pointerdown\", this._mouseDownBind, {}, target);\n this.unbindCanvas(\"pointerup\", this._mouseUpBind, {}, target);\n this.unbindCanvas(\"pointerover\", this._mouseOverBind, {}, target);\n this.unbindCanvas(\"pointerout\", this._mouseOutBind, {}, target);\n this.unbindCanvas(\"pointercancel\", this._mouseOutBind, {}, target);\n this.unbindCanvas(\"pointermove\", this._mouseMoveBind, {}, target);\n this.unbindCanvas(\"click\", this._mouseClickBind, {}, target);\n this.unbindCanvas(\"contextmenu\", this._contextMenuBind, {}, target);\n this._hasMouse = false;\n this._mouseTarget = undefined;\n }\n return this;\n }\n\n /**\n * A convenient method to bind (or unbind) all touch events in canvas element.\n * All [`IPlayer`](#link) objects added to this space that implement an `action` callback property will receive touch event callbacks.\n * Touch action names are defined by [`UIPointerActions`](#link), including \"up\", \"down\", \"move\", \"drag\", \"drop\", \"over\", and \"out\".\n * @param bind a boolean value to bind touch events if set to `true`. If `false`, all touch events will be unbound. Default is true.\n * @param passive a boolean value to set passive mode, ie, it won't block scrolling. Default is false.\n * @param customTarget an optional event target to use instead of the canvas element\n * @see [`Space.add`](#link)\n */\n bindTouch(\n bind: boolean = true,\n passive: boolean = false,\n customTarget?: Element,\n ): this {\n if (bind) {\n if (this._hasTouch) {\n if (\n this._touchTarget === customTarget &&\n this._touchPassive === passive\n )\n return this;\n this.bindTouch(false);\n }\n\n this._touchTarget = customTarget;\n this._touchPassive = passive;\n this.bindCanvas(\n \"touchstart\",\n this._touchStartBind,\n { passive: passive },\n customTarget,\n );\n this.bindCanvas(\"touchend\", this._mouseUpBind, {}, customTarget);\n this.bindCanvas(\n \"touchmove\",\n this._touchMoveBind,\n { passive: passive },\n customTarget,\n );\n this.bindCanvas(\"touchcancel\", this._mouseOutBind, {}, customTarget);\n this._hasTouch = true;\n } else if (this._hasTouch) {\n const target = this._touchTarget;\n const options = { passive: this._touchPassive };\n this.unbindCanvas(\"touchstart\", this._touchStartBind, options, target);\n this.unbindCanvas(\"touchend\", this._mouseUpBind, {}, target);\n this.unbindCanvas(\"touchmove\", this._touchMoveBind, options, target);\n this.unbindCanvas(\"touchcancel\", this._mouseOutBind, {}, target);\n this._hasTouch = false;\n this._touchTarget = undefined;\n }\n return this;\n }\n\n /**\n * Bind or unbind keyboard events. Events are attached to `document` by\n * default, or to `customTarget` when one is provided.\n */\n bindKeyboard(bind: boolean = true, customTarget?: EventTarget): this {\n if (bind) {\n const target = customTarget || document;\n if (this._hasKeyboard) {\n if (this._keyboardTarget === target) return this;\n this.bindKeyboard(false);\n }\n\n target.addEventListener(\"keydown\", this._keyDownBind, {});\n target.addEventListener(\"keyup\", this._keyUpBind, {});\n this._keyboardTarget = target;\n this._hasKeyboard = true;\n } else if (this._hasKeyboard) {\n this._keyboardTarget!.removeEventListener(\n \"keydown\",\n this._keyDownBind,\n {},\n );\n this._keyboardTarget!.removeEventListener(\"keyup\", this._keyUpBind, {});\n this._keyboardTarget = undefined;\n this._hasKeyboard = false;\n }\n return this;\n }\n\n /** Unbind all pointer, touch, and keyboard listeners owned by this space. */\n protected _unbindAll(): this {\n this.bindMouse(false);\n this.bindTouch(false);\n this.bindKeyboard(false);\n return this;\n }\n\n private _trackedUIs: UI[] = [];\n private _uiPlayer: IPlayer | null = null;\n\n /** Remove all players and the UI registrations forwarded by them. */\n removeAll(): this {\n this.untrack();\n this._uiPlayer = null;\n return super.removeAll();\n }\n\n /**\n * Track one or more [`UI`](#link) elements: every pointer, touch, and keyboard\n * action dispatched by this space is forwarded to them via [`UI.track`](#link),\n * so no manual `action` wiring is needed. Remember to also bind the events,\n * eg via [`MultiTouchSpace.bindMouse`](#link). Keyboard actions are forwarded\n * too (their x/y carry the shift/alt flags, as the space dispatches them).\n * @param uis a UI, or an array of UIs\n */\n track(uis: UI | UI[]): this {\n const list = Array.isArray(uis) ? uis : [uis];\n for (let i = 0, len = list.length; i < len; i++) {\n if (this._trackedUIs.indexOf(list[i]) < 0) this._trackedUIs.push(list[i]);\n }\n if (!this._uiPlayer) {\n this._uiPlayer = {\n animate: () => {},\n action: (type: string, px: number, py: number, evt: Event) => {\n UI.track(this._trackedUIs, type, new Pt(px, py), evt as MouseEvent);\n },\n };\n this.add(this._uiPlayer);\n }\n return this;\n }\n\n /**\n * Stop tracking one or more [`UI`](#link) elements added via [`MultiTouchSpace.track`](#link).\n * @param uis a UI or an array of UIs to remove from tracking, or omit to stop tracking all\n */\n untrack(uis?: UI | UI[]): this {\n const list =\n uis === undefined\n ? this._trackedUIs.slice()\n : Array.isArray(uis)\n ? uis\n : [uis];\n for (let i = 0, len = list.length; i < len; i++) {\n const at = this._trackedUIs.indexOf(list[i]);\n if (at < 0) continue;\n this._trackedUIs.splice(at, 1);\n // a dragger removed mid-drag would otherwise stay \"dragging\" and\n // resume on its next move without a press; end the drag as a drop\n if (list[i].state(\"dragging\")) {\n list[i].listen(\n UIA.drop,\n this._pointer,\n new Event(\"pointercancel\") as unknown as UIActionEvent,\n );\n }\n }\n return this;\n }\n\n // Input is relative to the rendered element, not a cached container position\n // or the event target (which may be an overlay). Read once per event.\n private _inputTransform(): [number, number, number, number] {\n if (typeof Element !== \"undefined\" && this._canvas instanceof Element) {\n const rect = this._canvas.getBoundingClientRect();\n return [\n rect.left,\n rect.top,\n rect.width ? this.width / rect.width : 1,\n rect.height ? this.height / rect.height : 1,\n ];\n }\n // Non-DOM subclasses may supply their own EventTarget and explicit bounds.\n return [\n this.bound.topLeft.x -\n (typeof window === \"undefined\" ? 0 : window.scrollX),\n this.bound.topLeft.y -\n (typeof window === \"undefined\" ? 0 : window.scrollY),\n 1,\n 1,\n ];\n }\n\n /**\n * A convenient method to convert the touch points in a touch event to an array of Pts.\n * @param evt a touch event which contains touches, changedTouches, and targetTouches list\n * @param which a string to select a touches list: \"touches\", \"changedTouches\", or \"targetTouches\". Default is \"touches\"\n * @return an array of Pt, whose origin position (0,0) is offset to the top-left of this space\n */\n touchesToPoints(evt: TouchEvent, which: TouchPointsKey = \"touches\"): Pt[] {\n if (!evt || !evt[which]) return [];\n const ts = [];\n const [left, top, scaleX, scaleY] = this._inputTransform();\n for (let i = 0; i < evt[which].length; i++) {\n const t = evt[which].item(i)!;\n ts.push(new Pt((t.clientX - left) * scaleX, (t.clientY - top) * scaleY));\n }\n return ts;\n }\n\n /**\n * Go through all the added [`IPlayer`](#link) objects and call its `action` callback function.\n * @param type a [`UIPointerActions`](#link) constant or custom action string\n * @param evt mouse or touch event\n * @see [`Space.add`](#link)\n */\n protected _mouseAction(\n type: string,\n evt: MouseEvent | TouchEvent | PointerEvent,\n ) {\n if (!this.isPlaying) return;\n\n // compute the event position once — not per player, and independent of\n // whether any player is registered (the pointer must track regardless)\n const [left, top, scaleX, scaleY] = this._inputTransform();\n let px = 0,\n py = 0;\n\n if (evt instanceof MouseEvent) {\n px = (evt.clientX - left) * scaleX;\n py = (evt.clientY - top) * scaleY;\n } else {\n const touch =\n evt.changedTouches && evt.changedTouches.length > 0\n ? evt.changedTouches.item(0)\n : null;\n if (touch) {\n px = (touch.clientX - left) * scaleX;\n py = (touch.clientY - top) * scaleY;\n }\n }\n\n if (type) {\n this._pointer.to(px, py);\n this._pointer.id = type;\n }\n\n for (const k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n const v = this.players[k];\n if (v.action) v.action(type, px, py, evt);\n }\n }\n }\n\n // Ignore the duplicate pointer stream only when this event also reaches our\n // touch listener. Mouse and touch bindings may use separate custom targets.\n private _isTouchHandled(evt: PointerEvent | TouchEvent): boolean {\n return (\n \"pointerType\" in evt &&\n evt.pointerType === \"touch\" &&\n this._hasTouch &&\n evt.composedPath().includes(this._touchTarget || this._canvas)\n );\n }\n\n /**\n * MouseDown handler.\n * @param evt\n */\n protected _mouseDown(evt: PointerEvent) {\n if (this._isTouchHandled(evt)) return false;\n this._mouseAction(UIA.down, evt);\n this._mouseAction(UIA.pointerdown, evt);\n this._pressed = true;\n if (evt.target instanceof Element) {\n try {\n evt.target.setPointerCapture(evt.pointerId);\n } catch {\n // a synthetic or re-dispatched event has no active pointer to capture;\n // dragging still works through the element's own move/up listeners\n }\n }\n return false;\n }\n\n /**\n * MouseUp handler.\n * @param evt\n */\n protected _mouseUp(evt: PointerEvent | TouchEvent) {\n if (this._isTouchHandled(evt)) return false;\n this._mouseAction(UIA.pointerup, evt);\n if (this._dragged) {\n this._mouseAction(UIA.drop, evt);\n } else {\n this._mouseAction(UIA.up, evt);\n }\n this._pressed = false;\n this._dragged = false;\n if (\n evt instanceof PointerEvent &&\n evt.target instanceof Element &&\n evt.target.hasPointerCapture(evt.pointerId)\n ) {\n evt.target.releasePointerCapture(evt.pointerId);\n }\n return false;\n }\n\n /**\n * MouseMove handler.\n * @param evt\n */\n protected _mouseMove(evt: PointerEvent) {\n if (this._isTouchHandled(evt)) return false;\n if (this._pressed) {\n this._dragged = true;\n this._mouseAction(UIA.drag, evt);\n } else {\n this._mouseAction(UIA.move, evt);\n }\n return false;\n }\n\n /**\n * MouseOver handler.\n * @param evt\n */\n protected _mouseOver(evt: PointerEvent) {\n if (this._isTouchHandled(evt)) return false;\n this._mouseAction(UIA.over, evt);\n return false;\n }\n\n /**\n * MouseOut handler.\n * @param evt\n */\n protected _mouseOut(evt: PointerEvent | TouchEvent) {\n if (this._isTouchHandled(evt)) return false;\n this._mouseAction(UIA.out, evt);\n if (this._dragged) this._mouseAction(UIA.drop, evt);\n this._pressed = false;\n this._dragged = false;\n return false;\n }\n\n /**\n * MouseClick handler.\n * @param evt\n */\n protected _mouseClick(evt: MouseEvent | TouchEvent) {\n this._mouseAction(UIA.click, evt);\n this._pressed = false;\n this._dragged = false;\n return false;\n }\n\n /**\n * ContextMenu handler.\n * @param evt\n */\n protected _contextMenu(evt: MouseEvent) {\n this._mouseAction(UIA.contextmenu, evt);\n return false;\n }\n\n /**\n * TouchMove handler.\n * @param evt\n */\n protected _touchMove(evt: TouchEvent) {\n this._mouseAction(UIA.move, evt);\n if (this._pressed) {\n this._dragged = true;\n this._mouseAction(UIA.drag, evt);\n }\n // preventDefault is ignored (and logs an error) inside passive listeners\n if (!this._touchPassive) evt.preventDefault();\n return false;\n }\n\n /**\n * TouchStart handler.\n * @param evt\n */\n protected _touchStart(evt: TouchEvent) {\n this._mouseAction(UIA.down, evt);\n this._pressed = true;\n if (!this._touchPassive) evt.preventDefault();\n return false;\n }\n\n protected _keyDown(evt: KeyboardEvent) {\n this._keyboardAction(UIA.keydown, evt);\n return false;\n }\n\n protected _keyUp(evt: KeyboardEvent) {\n this._keyboardAction(UIA.keyup, evt);\n return false;\n }\n\n protected _keyboardAction(type: string, evt: KeyboardEvent) {\n if (!this.isPlaying) return;\n for (const k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n const v = this.players[k];\n if (v.action)\n v.action(type, evt.shiftKey ? 1 : 0, evt.altKey ? 1 : 0, evt);\n }\n }\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { type Pt } from \"./Pt\";\nimport { Util } from \"./Util\";\nimport { type PtLike, type GroupLike } from \"./Types\";\n\n/**\n * Form is an abstract class that represents a form that's used in a Space for expressions. Learn more about Space and Form in [this guide](../guide/Space-0500.html).\n */\nexport abstract class Form {\n protected _ready: boolean = false;\n\n /**\n * get whether the Form has received the Space's rendering context.\n */\n get ready(): boolean {\n return this._ready;\n }\n}\n\n/**\n * VisualForm is an abstract class that represents a form that can be used to express Pts visually.\n * For example, [`CanvasForm`](#link) is an implementation of VisualForm that draws on [`CanvasSpace`](#link) which represents a html canvas. Learn more about Space and Form in [this guide](../guide/Space-0500.html).\n */\nexport abstract class VisualForm extends Form {\n protected _filled = true;\n protected _stroked = true;\n protected _font: Font = new Font(14, \"sans-serif\");\n\n /**\n * Check whether this form currently has fill style.\n */\n get filled(): boolean {\n return this._filled;\n }\n set filled(b: boolean) {\n this._filled = b;\n }\n\n /**\n * Check whether this form currently has stroke style.\n */\n get stroked(): boolean {\n return this._stroked;\n }\n set stroked(b: boolean) {\n this._stroked = b;\n }\n\n /**\n * Get the current font in use in this form.\n */\n get currentFont(): Font {\n return this._font;\n }\n\n protected _multiple(\n groups: GroupLike[],\n shape: string,\n ...rest: unknown[]\n ): this {\n if (!groups) return this;\n for (let i = 0, len = groups.length; i < len; i++) {\n // dynamic dispatch to the named shape method\n (this as any)[shape](groups[i], ...rest);\n }\n return this;\n }\n\n /**\n * Abstract reset style\n */\n abstract reset(): this;\n\n /**\n * Set alpha (not implemented here -- to be implemented in subclasses).\n * @param a alpha value between 0 and 1\n */\n alpha(a: number): this {\n return this;\n }\n\n /**\n * Set fill color (not implemented here -- to be implemented in subclasses).\n * @param c fill color as string or `false` to specify transparent.\n */\n fill(c: string | boolean): this {\n return this;\n }\n\n /**\n * Set current fill style and remove stroke style. (not implemented here -- to be implemented in subclasses).\n * @param c fill color as string or `false` to specify transparent.\n */\n fillOnly(c: string | boolean): this {\n this.stroke(false);\n return this.fill(c);\n }\n\n /**\n * Set stroke style (not implemented here -- to be implemented in subclasses).\n * @param c stroke color as string or `false` to specify transparent.\n * @param width Optional value (can be floating point) to set line width\n * @param linejoin Optional string to set line joint style. Can be \"miter\", \"bevel\", or \"round\".\n * @param linecap Optional string to set line cap style. Can be \"butt\", \"round\", or \"square\".\n */\n stroke(\n c: string | boolean,\n width?: number,\n linejoin?: string,\n linecap?: string,\n ): this {\n return this;\n }\n\n /**\n * Set stroke style and remove fill style. (not implemented here -- to be implemented in subclasses).\n * @param c stroke color as string or `false` to specify transparent.\n * @param width Optional value (can be floating point) to set line width\n * @param linejoin Optional string to set line joint style. Can be \"miter\", \"bevel\", or \"round\".\n * @param linecap Optional string to set line cap style. Can be \"butt\", \"round\", or \"square\".\n */\n strokeOnly(\n c: string | boolean,\n width?: number,\n linejoin?: string,\n linecap?: string,\n ): this {\n this.fill(false);\n return this.stroke(c, width, linejoin, linecap);\n }\n\n /**\n * Draw a point (not implemented here -- to be implemented in subclasses).\n * @param p a Pt object\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `form.point( p )`, `form.point( p, 10, \"circle\" )`\n */\n abstract point(p: PtLike, radius: number, shape: string): this;\n\n /**\n * Draw multiple points at once.\n * @param pts an array of Pt or an array of number arrays\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n */\n points(pts: GroupLike | number[][], radius: number, shape: string): this {\n if (!pts) return this;\n for (let i = 0, len = pts.length; i < len; i++) {\n this.point(pts[i], radius, shape);\n }\n return this;\n }\n\n /**\n * Draw a circle (not implemented here -- to be implemented in subclasses).\n * @param pts usually a Group of 2 Pts, but it can also take an array of two numeric arrays [ [position], [size] ]\n * @see [`Circle.fromCenter`](#link)\n */\n abstract circle(pts: GroupLike | number[][]): this;\n\n /**\n * Draw multiple circles at once.\n * @param groups an array of Groups that defines multiple circles\n */\n circles(groups: GroupLike[]): this {\n return this._multiple(groups, \"circle\");\n }\n\n /**\n * Draw multiple squares at once.\n * @param groups an array of Groups that defines multiple circles\n */\n squares(groups: GroupLike[]): this {\n return this._multiple(groups, \"square\");\n }\n\n /**\n * Draw an arc (not implemented here -- to be implemented in subclasses).\n * @param pt center position\n * @param radius radius of the arc circle\n * @param startAngle start angle of the arc\n * @param endAngle end angle of the arc\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n abstract arc(\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): this;\n\n /**\n * Draw a line or polyline (not implemented here -- to be implemented in subclasses).\n * @param pts a Group of multiple Pts, or an array of multiple numeric arrays\n */\n abstract line(pts: GroupLike | number[][]): this;\n\n /**\n * Draw multiple lines at once.\n * @param groups An array of Groups of Pts\n */\n lines(groups: GroupLike[]): this {\n return this._multiple(groups, \"line\");\n }\n\n /**\n * Draw a polygon (not implemented here -- to be implemented in subclasses).\n * @param pts a Group of multiple Pts, or an array of multiple numeric arrays\n */\n abstract polygon(pts: GroupLike | number[][]): this;\n\n /**\n * Draw multiple polygons at once.\n * @param groups An array of Groups of Pts\n */\n polygons(groups: GroupLike[]): this {\n return this._multiple(groups, \"polygon\");\n }\n\n /**\n * Draw a rectangle (not implemented here -- to be implemented in subclasses).\n * @param pts usually a Group of 2 Pts specifying the top-left and bottom-right positions. Alternatively it can be an array of numeric arrays.\n */\n abstract rect(pts: number[][] | Pt[]): this;\n\n /**\n * Draw multiple rectangles at once.\n * @param groups An array of Groups of Pts\n */\n rects(groups: GroupLike[]): this {\n return this._multiple(groups, \"rect\");\n }\n\n /**\n * Draw text (not implemented here -- to be implemented in subclasses).\n * @param pt a Pt or numeric array to specify the anchor point\n * @param txt text\n * @param maxWidth specify a maximum width per line\n */\n abstract text(pt: PtLike, txt: string, maxWidth?: number): this;\n\n /**\n * Set font style (not implemented here -- to be implemented in subclasses).\n * @param sizeOrFont either a number to specify font-size, or a `Font` object to specify all font properties\n * @param weight Optional font-weight string such as \"bold\"\n * @param style Optional font-style string such as \"italic\"\n * @param lineHeight Optional line-height number suchas 1.5\n * @param family Optional font-family such as \"Helvetica, sans-serif\"\n * @see `Font` class\n * @example `form.font( myFont )`, `form.font(14, \"bold\")`\n */\n abstract font(\n sizeOrFont: number | Font,\n weight?: string,\n style?: string,\n lineHeight?: number,\n family?: string,\n ): this;\n}\n\n/**\n * Font class lets you create a specific font style with properties for its size and style. A font instance can be passed as parameter to set a form's font. For example, see [`CanvasForm.font`](#link).\n */\nexport class Font {\n public size: number;\n public lineHeight: number;\n public face: string;\n public style: string;\n public weight: string;\n\n /**\n * Create a font style.\n * @param size font size. Defaults is 12px.\n * @param face Optional font-family, use css-like string such as \"Helvetica\" or \"Helvetica, sans-serif\". Default is \"sans-serif\".\n * @param weight Optional font weight such as \"bold\". Default is \"\" (none).\n * @param style Optional font style such as \"italic\". Default is \"\" (none).\n * @param lineHeight Optional line height. Default is 1.5.\n * @example `new Font(12, \"Frutiger, sans-serif\", \"bold\", \"underline\", 1.5)`\n */\n constructor(\n size: number = 12,\n face: string = \"sans-serif\",\n weight: string = \"\",\n style: string = \"\",\n lineHeight: number = 1.5,\n ) {\n this.size = size;\n this.face = face;\n this.style = style;\n this.weight = weight;\n this.lineHeight = lineHeight;\n }\n\n /**\n * Get a string representing the font style, in css-like string such as \"italic bold 12px/1.5 sans-serif\".\n */\n get value(): string {\n const prefix = [this.style, this.weight].filter(Boolean).join(\" \");\n const base = `${this.size}px/${this.lineHeight} ${this.face}`;\n return prefix ? `${prefix} ${base}` : base;\n }\n\n /**\n * Get a string representing the font style, in css-like string such as \"italic bold 12px/1.5 sans-serif\".\n */\n toString(): string {\n return this.value;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Bound } from \"./Pt\";\nimport { Util } from \"./Util\";\nimport { type PtLikeIterable, type TextMeasure } from \"./Types\";\n\n/**\n * Typography provides helper functions to support typographic layouts. For a concrete example, see [a demo here](https://ptsjs.org/demo/?name=canvasform.textBox) that uses the [`CanvasForm.textBox`](#link) function.\n */\nexport class Typography {\n /**\n * Create a heuristic text width estimate function. It will be less accurate but faster.\n * @param fn a reference function that can measure text width accurately\n * @param samples a list of string samples. Default is [\"M\", \"n\", \".\"]\n * @param distribution a list of the samples' probability distribution, which should have the same length as `samples` and sum to 1. Default is [0.06, 0.8, 0.14]. (A distribution that sums to more or less than 1 will proportionally inflate or deflate every estimate.)\n * @return a function that can estimate text width\n */\n static textWidthEstimator(\n fn: TextMeasure,\n samples: string[] = [\"M\", \"n\", \".\"],\n distribution: number[] = [0.06, 0.8, 0.14],\n ): TextMeasure {\n if (samples.length !== distribution.length) {\n throw new Error(\n `textWidthEstimator: samples (${samples.length}) and distribution (${distribution.length}) must have the same length`,\n );\n }\n const m = samples.map(fn);\n const avg = new Pt(distribution).dot(m);\n return (text: string): number => text.length * avg;\n }\n\n /**\n * Create a memoizing text width function that measures each distinct character once and sums the cached widths. Nearly as accurate as the reference function for most texts (kerning and ligatures excepted) at close to estimator speed after warmup. The cache is keyed by character, so create a new instance whenever the font changes.\n * @param fn a reference function that can measure text width accurately\n * @return a function that measures text width using per-character caching\n */\n static charWidthCache(fn: TextMeasure): TextMeasure {\n // Latin-1 goes through a typed array — a Map lookup per character would\n // cost as much as the measurement it replaces. NaN marks \"not yet measured\".\n const latin = new Float64Array(256).fill(NaN);\n const cache = new Map<string, number>();\n return (text: string): number => {\n let sum = 0;\n for (let i = 0, len = text.length; i < len; i++) {\n const code = text.charCodeAt(i);\n if (code < 256) {\n let w = latin[code];\n if (w !== w) {\n w = fn(text[i]);\n latin[code] = w;\n }\n sum += w;\n } else {\n let ch = text[i];\n if (code >= 0xd800 && code <= 0xdbff && i + 1 < len) {\n ch += text[i + 1]; // measure a surrogate pair as one character\n i++;\n }\n let w = cache.get(ch);\n if (w === undefined) {\n w = fn(ch);\n cache.set(ch, w);\n }\n sum += w;\n }\n }\n return sum;\n };\n }\n\n /**\n * Truncate text to fit width. The result is guaranteed to fit: the largest prefix (possibly empty) is kept such that the prefix plus the tail measures within `width`. The cut never splits a surrogate pair. If even the tail alone cannot fit, `[\"\", 0]` is returned.\n * @param fn a function that can measure text width\n * @param str text to truncate\n * @param width width to fit\n * @param tail text to indicate overflow such as \"...\". Default is empty \"\".\n * @param hint optional expected number of characters to keep — a pure performance hint (any value yields the same result) that seeds the search, such as the previous line's length when wrapping. With an empty `tail`, a hint also avoids measuring the entire string.\n * @return a tuple of the truncated text (tail included) and the number of characters kept from `str`\n */\n static truncate(\n fn: TextMeasure,\n str: string,\n width: number,\n tail: string = \"\",\n hint?: number,\n ): [string, number] {\n const len = str.length;\n let budget: number;\n let max: number;\n let seed: number;\n\n if (hint !== undefined && !tail) {\n // Hinted search with no tail: skip the full-string measure. The domain\n // includes `len` itself, so \"everything fits\" is discovered by the\n // search rather than by a separate upfront measurement.\n budget = width;\n max = len;\n seed = Math.min(max, Math.max(0, Math.floor(hint)));\n } else {\n const full = fn(str);\n if (full <= width) return [str, len];\n budget = width - (tail ? fn(tail) : 0);\n max = len - 1;\n seed =\n hint !== undefined\n ? Math.min(max, Math.max(0, Math.floor(hint)))\n : Math.min(max, Math.max(0, Math.floor((len * budget) / full)));\n }\n\n const fits = (k: number): boolean => fn(str.slice(0, k)) <= budget;\n\n // Find the largest k in [0, max] where the prefix fits, starting from the\n // seed — exact for linear measures, so the gallop below usually settles\n // the boundary in two probes.\n let best = -1;\n let lo = 0;\n let hi = max;\n\n if (budget >= 0) {\n const k = seed;\n if (fits(k)) {\n best = k;\n lo = k + 1;\n for (let inc = 1; lo <= hi; inc *= 2) {\n const p = Math.min(hi, k + inc);\n if (!fits(p)) {\n hi = p - 1;\n break;\n }\n best = p;\n lo = p + 1;\n }\n } else {\n hi = k - 1;\n for (let inc = 1; lo <= hi; inc *= 2) {\n const p = Math.max(lo, k - inc);\n if (fits(p)) {\n best = p;\n lo = p + 1;\n break;\n }\n hi = p - 1;\n }\n }\n while (lo <= hi) {\n const p = (lo + hi) >> 1;\n if (fits(p)) {\n best = p;\n lo = p + 1;\n } else {\n hi = p - 1;\n }\n }\n }\n\n if (best < 0) return [\"\", 0];\n if (best === len) return [str, len]; // hinted search found the whole string fits\n\n // Don't cut between a surrogate pair's halves; a shorter prefix still fits.\n let cut = best;\n if (cut > 0) {\n const code = str.charCodeAt(cut - 1);\n if (code >= 0xd800 && code <= 0xdbff) cut--;\n }\n\n return [str.slice(0, cut) + tail, cut];\n }\n\n /**\n * Get a function to scale font size proportionally to a box's size. (Deprecated form: passing an initial box as the first parameter is deprecated — it never affected the result — and will be removed in a future version.)\n * @param ratio font-size to box-size ratio. Default is 1.\n * @param byHeight `true` to scale by the box's height, `false` to scale by its width. Default is `true`.\n * @returns a function where input parameter is a box, and returns a font size value (`ratio` multiplied by the box's height or width)\n */\n static fontSizeToBox(\n ratio?: number,\n byHeight?: boolean,\n ): (box: PtLikeIterable) => number;\n /**\n * @deprecated The initial box never affected the result. Use `fontSizeToBox(ratio, byHeight)` instead.\n */\n static fontSizeToBox(\n box: PtLikeIterable,\n ratio?: number,\n byHeight?: boolean,\n ): (box: PtLikeIterable) => number;\n static fontSizeToBox(\n ratio: number | PtLikeIterable = 1,\n byHeight: boolean | number = true,\n legacyByHeight?: boolean,\n ): (box: PtLikeIterable) => number {\n if (typeof ratio !== \"number\") {\n Util.warn(\n \"Typography.fontSizeToBox(box, ratio, byHeight) is deprecated: the initial box never affected the result. Use fontSizeToBox(ratio, byHeight) instead.\",\n );\n ratio = typeof byHeight === \"number\" ? byHeight : 1;\n byHeight = legacyByHeight === undefined ? true : legacyByHeight;\n }\n const r = ratio as number;\n const by = byHeight as boolean;\n return (box: PtLikeIterable): number => {\n const bound = Bound.fromGroup(box);\n return r * (by ? bound.height : bound.width);\n };\n }\n\n /**\n * Get a function to scale font size based on a threshold value.\n * @param threshold threshold value. Cannot be 0.\n * @param direction if negative, get a font size <= defaultSize; if positive, get a font size >= defaultSize; Default is 0 which will scale font without min or max limits.\n * @returns a function whose input parameters are a default font size and a value to compare with threshold, and which returns a new font size value\n */\n static fontSizeToThreshold(\n threshold: number,\n direction: number = 0,\n ): (defaultSize: number, val: number) => number {\n if (threshold === 0) {\n throw new Error(\"fontSizeToThreshold: threshold cannot be 0\");\n }\n return function (defaultSize: number, val: number): number {\n const d = (defaultSize * val) / threshold;\n if (direction < 0) return Math.min(d, defaultSize);\n if (direction > 0) return Math.max(d, defaultSize);\n return d;\n };\n }\n}\n","import { CanvasForm, type CanvasSpace } from \"./Canvas\";\nimport { type Bound, Pt } from \"./Pt\";\nimport { Mat } from \"./LinearAlgebra\";\nimport { type PtLike, type CanvasPatternRepetition } from \"./Types\";\nimport { Util } from \"./Util\";\nimport { type RenderingContext2D } from \"./Types\";\n\n/**\n * Options for creating an [`Img`](#link).\n */\nexport type ImgOptions = {\n /** Specify if you want to manipulate pixels of this image. Default is `false`. */\n editable?: boolean;\n /** Set the `CanvasSpace` reference so the image's pixelScale matches the canvas. */\n space?: CanvasSpace;\n /** Enable loading cross-domain images. The image server must also allow it. */\n crossOrigin?: boolean;\n /** Set a specific pixel scale, overriding the space's. */\n pixelScale?: number;\n};\n\n/**\n * Img provides convenient functions to support image operations on HTML Canvas and [`CanvasSpace`](#link). Combine this with other Pts functions to experiment with visual forms that integrate bitmaps and vector graphics.\n */\nexport class Img {\n protected _img!: HTMLImageElement;\n protected _data!: ImageData;\n protected _cv!: HTMLCanvasElement;\n protected _ctx!: RenderingContext2D;\n protected _scale: number = 1;\n\n protected _loaded: boolean = false;\n protected _editable: boolean;\n\n protected _space: CanvasSpace | undefined;\n protected _patternCtx!: RenderingContext2D; // lazy fallback when no space is set\n protected _objectUrl!: string | null; // tracked for revocation on dispose\n private _pendingLoadReject: ((err: Error) => void) | null = null; // newer loads supersede pending ones\n private _disposed = false;\n protected _dataDirty: boolean = false; // ImageData refreshes lazily on first read\n\n /**\n * Create an Img\n * @param editable either an [`ImgOptions`](#link) object, or a boolean specifying if you want to manipulate pixels of this image. Default is `false`.\n * @param space Set the `CanvasSpace` reference. This is optional but will make sure the image's pixelScale match the canvas and set the context for creating pattern.\n * @param crossOrigin an optional parameter to enable loading cross-domain images if set to true. The image server's configuration must also be set correctly. For more, see [this documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image).\n * @example `new Img(true, space)`, `new Img({ editable: true, pixelScale: 2 })`\n */\n constructor(\n editable: boolean | ImgOptions = false,\n space?: CanvasSpace,\n crossOrigin?: boolean,\n ) {\n const opts: ImgOptions =\n typeof editable === \"object\"\n ? editable\n : { editable, space, crossOrigin };\n this._editable = !!opts.editable;\n this._space = opts.space;\n this._scale = opts.pixelScale ?? (this._space ? this._space.pixelScale : 1);\n this._img = new Image();\n if (opts.crossOrigin) this._img.crossOrigin = \"Anonymous\";\n }\n\n /**\n * A static function to load an image, returning a Promise that resolves to the loaded Img.\n * A load failure rejects the Promise.\n * @param src an url of the image in same domain. Alternatively you can use a base64 string. To load from Blob, use `Img.fromBlob`.\n * @param editable either an [`ImgOptions`](#link) object, or a boolean specifying if you want to manipulate pixels of this image. Default is `false`.\n * @param space Set the `CanvasSpace` reference. This is optional but will make sure the image's pixelScale match the canvas and set the context for creating pattern.\n * @param ready An optional callback, invoked with the Img when loading succeeds\n * @example `const img = await Img.load(\"photo.jpg\", true)`\n */\n static load(\n src: string,\n editable: boolean | ImgOptions = false,\n space?: CanvasSpace,\n ready?: (img: Img) => void,\n ): Promise<Img> {\n return new Img(editable, space).load(src).then((res) => {\n if (ready) ready(res);\n return res;\n });\n }\n\n /**\n * A static method to load an image using async/await.\n * @deprecated Use [`Img.load`](#link), which now returns a Promise.\n * @param src an url of the image in same domain. Alternatively you can use a base64 string. To load from Blob, use `Img.fromBlob`.\n * @param editable Specify if you want to manipulate pixels of this image. Default is `false`.\n * @param space Set the `CanvasSpace` reference. This is optional but will make sure the image's pixelScale match the canvas and set the context for creating pattern.\n */\n static async loadAsync(\n src: string,\n editable: boolean | ImgOptions = false,\n space?: CanvasSpace,\n ): Promise<Img> {\n return Img.load(src, editable, space);\n }\n\n /**\n * A static method to load an image pattern using async/await.\n * @param src an url of the image in same domain. Alternatively you can use a base64 string. To load from Blob, use `Img.fromBlob`.\n * @param space Set the `CanvasSpace` reference. This is optional but will make sure the image's pixelScale match the canvas and set the context for creating pattern.\n * @param repeat set how the pattern will repeat fills\n * @param editable Specify if you want to manipulate pixels of this image. Default is `false`.\n * @returns a `CanvasPattern` instance for use in `fill()`\n */\n static async loadPattern(\n src: string,\n space: CanvasSpace,\n repeat: CanvasPatternRepetition = \"repeat\",\n editable: boolean = false,\n ) {\n const img = await Img.loadAsync(src, editable, space);\n return img.pattern(repeat);\n }\n\n /**\n * Create an editable blank image\n * @param size of image\n * @param space Optionally set the `CanvasSpace` reference. This is optional but will make sure the image's pixelScale match the canvas and set the context for creating pattern.\n * @param scale Optionally set a specific pixel scale (density) of the image canvas.\n */\n static blank(size: PtLike, space?: CanvasSpace, scale?: number): Img {\n let img = new Img(true, space);\n const s = scale ? scale : space ? space.pixelScale : 1;\n img.initCanvas(size[0], size[1], s);\n return img;\n }\n\n /**\n * Load an image.\n * @param src an url of the image in same domain. Alternatively you can use a base64 string. To load from Blob, use `Img.fromBlob`.\n * @returns a Promise that resolves to an Img\n */\n load(src: string): Promise<Img> {\n if (this._editable && typeof document === \"undefined\") {\n return Promise.reject(\n new Error(\"Cannot create html canvas element. document not found.\"),\n );\n }\n\n return this._loadImageSrc(src).then(() => {\n if (this._disposed) throw new Error(\"Img has been disposed\");\n if (this._editable) {\n if (!this._cv)\n this._cv = document.createElement(\"canvas\") as HTMLCanvasElement;\n this._drawToScale(this._scale, this._img);\n this._dataDirty = true;\n }\n this._loaded = true;\n return this;\n });\n }\n\n /**\n * Swap the underlying image's source and await its load — without the editable\n * pipeline. Shared by `load()` and `sync()` so both respect the supersede rule.\n */\n protected _loadImageSrc(src: string): Promise<void> {\n if (this._disposed)\n return Promise.reject(new Error(\"Img has been disposed\"));\n return new Promise<void>((resolve, reject) => {\n // a newer load replaces this one's handlers on the shared <img>, so a\n // pending previous promise must be rejected proactively\n if (this._pendingLoadReject) {\n this._pendingLoadReject(\n new Error(\"Img loading superseded by a newer load\"),\n );\n }\n this._pendingLoadReject = reject;\n\n this._img.onload = () => {\n this._pendingLoadReject = null;\n resolve();\n };\n\n this._img.onerror = () => {\n this._pendingLoadReject = null;\n reject(new Error(`Img cannot load ${src}`));\n };\n\n this._img.src = src;\n });\n }\n\n /** Refresh the cached `ImageData` from the current canvas. */\n protected _refreshData(): void {\n this._data = this._ctx.getImageData(0, 0, this._cv.width, this._cv.height);\n this._dataDirty = false;\n }\n\n /** Materialize the cached `ImageData` lazily, on first read after a change. */\n protected _ensureData(): void {\n if ((this._dataDirty || !this._data) && this._ctx && this._cv) {\n this._refreshData();\n }\n }\n\n /**\n * Rescale the canvas and draw an image-source on it.\n * @param canvasScale rescale factor for the canvas\n * @param img an image source like Image, Canvas, or ImageBitmap.\n */\n protected _drawToScale(\n canvasScale: number | PtLike,\n img:\n | HTMLImageElement\n | HTMLCanvasElement\n | ImageBitmap\n | OffscreenCanvas\n | HTMLVideoElement,\n ) {\n const nw = img.width as number;\n const nh = img.height as number;\n this._initCanvas(nw, nh, canvasScale);\n if (img)\n this._ctx.drawImage(\n img,\n 0,\n 0,\n nw,\n nh,\n 0,\n 0,\n this._cv.width,\n this._cv.height,\n );\n }\n\n /**\n * Initiate an editable canvas\n * @param width width of canvas\n * @param height height of canvas\n * @param canvasScale pixel scale\n */\n initCanvas(width: number, height: number, canvasScale: number | PtLike = 1) {\n this._initCanvas(width, height, canvasScale);\n }\n\n /**\n * Internal canvas setup without the pixel-data refresh — callers that draw\n * immediately afterwards refresh once after their draw instead.\n */\n protected _initCanvas(\n width: number,\n height: number,\n canvasScale: number | PtLike = 1,\n ) {\n if (!this._editable) {\n Util.warn(\n \"Cannot initiate canvas because this Img is not set to be editable\",\n );\n return;\n }\n\n if (!this._cv)\n this._cv = document.createElement(\"canvas\") as HTMLCanvasElement;\n\n const cms =\n typeof canvasScale === \"number\"\n ? [canvasScale, canvasScale]\n : canvasScale;\n this._cv.width = width * cms[0];\n this._cv.height = height * cms[1];\n // the whole point of an editable Img is repeated readback\n this._ctx = this._cv.getContext(\"2d\", { willReadFrequently: true })!;\n // resizing resets the context state; forget any cached style values so a\n // CanvasForm from getForm() re-applies its styles\n CanvasForm.resetStyleCache(this._ctx);\n // keep the pixel-density field coherent with the actual canvas scaling,\n // which `pixel( p, true )` depends on\n if (typeof canvasScale === \"number\") this._scale = canvasScale;\n this._dataDirty = true; // pixel reads materialize lazily\n this._loaded = true;\n }\n\n /**\n * Get an efficient, readonly bitmap of the current canvas.\n * @param size Optional size to crop\n * @returns a Promise that resolves to an ImageBitmap\n */\n bitmap(size?: PtLike): Promise<ImageBitmap> {\n const w = size ? size[0] : this._cv.width;\n const h = size ? size[1] : this._cv.height;\n return createImageBitmap(this._cv, 0, 0, w, h);\n }\n\n /**\n * Create a canvas pattern for `fill()`\n * @param reptition set how the pattern should repeat-fill\n * @param dynamic If true, use this Img's internal canvas content as pattern fill. This enables the pattern to update dynamically.\n * @returns a `CanvasPattern` instance for use in `fill()`\n */\n pattern(\n reptition: CanvasPatternRepetition = \"repeat\",\n dynamic: boolean = false,\n ): CanvasPattern {\n // any 2D context can create a pattern; fall back to an internal one so a\n // CanvasSpace reference is optional\n let ctx: RenderingContext2D | undefined = this._space\n ? this._space.ctx\n : undefined;\n if (!ctx) {\n if (!this._patternCtx) {\n this._patternCtx = document.createElement(\"canvas\").getContext(\"2d\")!;\n }\n ctx = this._patternCtx;\n }\n return ctx.createPattern(dynamic ? this._cv : this._img, reptition)!;\n }\n\n /**\n * Replace the image with the current canvas data. For example, you can use CanvasForm's static functions to draw on `this.ctx` and then update the current image.\n * To display the internal canvas, use `form.image( [0, 0], img.current )`.\n */\n async sync(): Promise<Img> {\n if (this._disposed) throw new Error(\"Img has been disposed\");\n // Blob-blit instead of a base64 round-trip: encode asynchronously, load\n // the result into the image, and leave the working canvas untouched (the\n // canvas is already the source of truth, so no redraw or readback is\n // needed — and the retina canvas is no longer squashed through a lossy\n // reload; a temporary canvas produces the logical-size image instead).\n let source: HTMLCanvasElement = this._cv;\n if (this._scale !== 1) {\n source = document.createElement(\"canvas\");\n source.width = this._cv.width / this._scale;\n source.height = this._cv.height / this._scale;\n source\n .getContext(\"2d\")!\n .drawImage(\n this._cv,\n 0,\n 0,\n this._cv.width,\n this._cv.height,\n 0,\n 0,\n source.width,\n source.height,\n );\n }\n\n const blob = await new Promise<Blob>((resolve, reject) => {\n source.toBlob((b) =>\n b ? resolve(b) : reject(new Error(\"Img cannot export canvas to blob\")),\n );\n });\n\n const url = URL.createObjectURL(blob);\n this._objectUrl = url;\n try {\n await this._loadImageSrc(url);\n if (this._disposed) throw new Error(\"Img has been disposed\");\n this._loaded = true;\n } finally {\n URL.revokeObjectURL(url);\n this._objectUrl = null;\n }\n return this;\n }\n\n /**\n * Get the RGBA values of a pixel in the image\n * @param p position of the pixel\n * @param rescale Specify if the pixel position should be scaled. Usually use rescale when tracking image and don't rescale when tracking canvas. You may also set a custom scale value.\n * @returns [R,G,B,A] values of the pixel at the specific position\n */\n pixel(p: PtLike, rescale: boolean | number = true): Pt {\n this._ensureData();\n if (!this._data) {\n Util.warn(\n \"Img has no pixel data — create it as editable and wait for load\",\n );\n return new Pt(0, 0, 0, 0);\n }\n const s = typeof rescale == \"number\" ? rescale : rescale ? this._scale : 1;\n return Img.getPixel(this._data, [p[0] * s, p[1] * s]);\n }\n\n /**\n * Set the RGBA values of a pixel in the cached `ImageData`. Call [`Img.updatePixels`](#link)\n * to write the changes onto the canvas.\n * @param p position of the pixel\n * @param rgba [R,G,B,A] values, 0-255\n * @param rescale Specify if the pixel position should be scaled, matching [`Img.pixel`](#link)\n */\n setPixel(p: PtLike, rgba: PtLike, rescale: boolean | number = true): this {\n this._ensureData();\n if (!this._data) {\n Util.warn(\"Img has no pixel data — create it as editable\");\n return this;\n }\n const s = typeof rescale == \"number\" ? rescale : rescale ? this._scale : 1;\n const x = Math.floor(p[0] * s);\n const y = Math.floor(p[1] * s);\n if (x < 0 || y < 0 || x >= this._data.width || y >= this._data.height) {\n return this;\n }\n const i = y * this._data.width * 4 + x * 4;\n this._data.data[i] = rgba[0];\n this._data.data[i + 1] = rgba[1];\n this._data.data[i + 2] = rgba[2];\n this._data.data[i + 3] = rgba[3] !== undefined ? rgba[3] : 255;\n return this;\n }\n\n /**\n * Refresh the cached `ImageData` from the canvas — call this after drawing on the\n * canvas (eg, via [`Img.getForm`](#link)) before reading pixels.\n */\n loadPixels(): this {\n if (!this._ctx) {\n Util.warn(\"Img has no canvas — create it as editable\");\n return this;\n }\n this._refreshData();\n return this;\n }\n\n /**\n * Write the cached `ImageData` (eg, after [`Img.setPixel`](#link) calls) back onto\n * the canvas.\n */\n updatePixels(): this {\n if (!this._ctx || !this._data) {\n Util.warn(\"Img has no canvas — create it as editable\");\n return this;\n }\n this._ctx.putImageData(this._data, 0, 0);\n this._dataDirty = false; // canvas now equals the cached data\n return this;\n }\n\n /**\n * Given an ImaegData object and a position, return the RGBA pixel value at that position.\n * @param imgData an ImageData object\n * @param p a position on the image\n * @returns [R,G,B,A] values of the pixel at the specific position\n */\n static getPixel(imgData: ImageData, p: PtLike): Pt {\n // `new Pt(4)` + element stores is ~8x faster than the 4-argument\n // constructor path, and out-of-bound reads return the zeroed Pt as before\n const out = new Pt(4);\n if (\n p[0] < 0 ||\n p[1] < 0 ||\n p[0] >= imgData.width ||\n p[1] >= imgData.height\n ) {\n return out;\n }\n\n const i = Math.floor(p[1]) * (imgData.width * 4) + Math.floor(p[0]) * 4;\n const d = imgData.data;\n if (i > d.length - 4) return out;\n\n out[0] = d[i];\n out[1] = d[i + 1];\n out[2] = d[i + 2];\n out[3] = d[i + 3];\n return out;\n }\n\n /**\n * Resize the canvas image. The original image is unchanged until `sync()`.\n * @param sizeOrScale A PtLike array specifying either [x, y] scales or [x, y] sizes.\n * @param asScale If true, treat the first parameter as scales. Otherwise, treat it as specific sizes.\n */\n resize(sizeOrScale: PtLike, asScale: boolean = false): this {\n const hasImage = this._img.naturalWidth > 0;\n // canvas-only images (eg, from `Img.blank`) scale relative to the canvas\n // size, and need a snapshot since `_drawToScale` clears the canvas first\n const refW = hasImage ? this._img.naturalWidth : this._cv.width;\n const refH = hasImage ? this._img.naturalHeight : this._cv.height;\n if (!refW || !refH) {\n Util.warn(\"Img cannot resize before an image or canvas exists\");\n return this;\n }\n const s = asScale\n ? sizeOrScale\n : [sizeOrScale[0] / refW, sizeOrScale[1] / refH];\n\n let source: HTMLImageElement | HTMLCanvasElement = this._img;\n if (!hasImage) {\n const snap = document.createElement(\"canvas\");\n snap.width = this._cv.width;\n snap.height = this._cv.height;\n snap.getContext(\"2d\")!.drawImage(this._cv, 0, 0);\n source = snap;\n }\n this._drawToScale(s, source);\n this._dataDirty = true;\n return this;\n }\n\n /**\n * Crop an area of the image.\n * @param box bounding box\n */\n crop(box: Bound): ImageData {\n const s = this._scale;\n return this._ctx.getImageData(\n box[0][0] * s,\n box[0][1] * s,\n box.width * s,\n box.height * s,\n );\n }\n\n /**\n * Apply filters such as blur and grayscale to the canvas image. The original image is unchanged until `sync()`.\n * @param css a css filter string such as \"blur(10px) contrast(200%)\". See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter#browser_compatibility) for a list of filter functions.\n */\n filter(css: string): this {\n // \"copy\" replaces the canvas with the filtered result (the source is\n // snapshotted before compositing) — plain source-over would blend the\n // filtered copy with the original wherever the filter introduces alpha\n const op = this._ctx.globalCompositeOperation;\n this._ctx.globalCompositeOperation = \"copy\";\n this._ctx.filter = css;\n this._ctx.drawImage(this._cv, 0, 0);\n this._ctx.filter = \"none\";\n this._ctx.globalCompositeOperation = op;\n this._dataDirty = true;\n return this;\n }\n\n /**\n * Dispose of the elements, data, and any object URL associated with this Img. Pending loads reject; the instance should not be reused.\n */\n dispose(): this {\n this._disposed = true;\n this._pendingLoadReject?.(new Error(\"Img has been disposed\"));\n this._pendingLoadReject = null;\n if (this._img) {\n this._img.onload = null;\n this._img.onerror = null;\n this._img.removeAttribute(\"src\");\n }\n if (this._objectUrl) {\n URL.revokeObjectURL(this._objectUrl);\n this._objectUrl = null;\n }\n if (this._cv) this._cv.remove();\n if (this._img) this._img.remove();\n this._cv = null!;\n this._ctx = null!;\n this._patternCtx = null!;\n this._img = null!;\n this._data = null!;\n this._loaded = false;\n return this;\n }\n\n /**\n * Remove the elements and data associated with this Img.\n * @deprecated Use [`Img.dispose`](#link).\n */\n cleanup() {\n this.dispose();\n }\n\n /**\n * Create a blob url that can be passed to `Img.load`\n * @param blob an image blob such as `new Blob([my_Uint8Array], {type: 'image/png'})`\n * @param editable Specify if you want to manipulate pixels of this image. Default is `false`.\n */\n static fromBlob(\n blob: Blob,\n editable: boolean | ImgOptions = false,\n space?: CanvasSpace,\n ): Promise<Img> {\n const url = URL.createObjectURL(blob);\n const img = new Img(editable, space);\n img._objectUrl = url;\n // the decoded image no longer needs the URL once the load settles;\n // dispose() also guards this\n const done = () => {\n URL.revokeObjectURL(url);\n img._objectUrl = null;\n };\n return img.load(url).then(\n (res) => {\n done();\n return res;\n },\n (err) => {\n done();\n throw err;\n },\n );\n }\n\n /**\n * Convert ImageData object to a Blob, which you can then create an Img instance via [`Img.fromBlob`](#link). Note that the resulting image's dimensions will not account for pixel density.\n * @param data\n */\n static imageDataToBlob(data: ImageData): Promise<Blob> {\n return new Promise(function (resolve, reject) {\n if (typeof document === \"undefined\") {\n reject(\n new Error(\"Cannot create html canvas element. document not found.\"),\n );\n return;\n }\n let cv = document.createElement(\"canvas\") as HTMLCanvasElement;\n cv.width = data.width;\n cv.height = data.height;\n cv.getContext(\"2d\")!.putImageData(data, 0, 0);\n cv.toBlob((blob) => {\n resolve(blob!);\n cv.remove();\n });\n });\n }\n\n /**\n * Export current canvas image as base64 string\n */\n toBase64(): string {\n return this._cv.toDataURL();\n }\n\n /**\n * Export current canvas image as a blob\n */\n toBlob(): Promise<Blob> {\n return new Promise((resolve) => {\n this._cv.toBlob((blob) => resolve(blob!));\n });\n }\n\n /**\n * Get a CanvasForm for drawing on the internal canvas if this Img is editable\n */\n getForm(): CanvasForm | undefined {\n if (!this._editable) {\n Util.warn(\"Cannot get a CanvasForm because this Img is not editable\");\n }\n return this._ctx ? new CanvasForm(this._ctx) : undefined;\n }\n\n /**\n * Get current image source. If editable, this will return the canvas, otherwise it will return the original image.\n */\n get current(): CanvasImageSource {\n return this._editable ? this._cv : this._img;\n }\n\n /**\n * Get the original image\n */\n get image(): HTMLImageElement {\n return this._img;\n }\n\n /**\n * Get the internal canvas\n */\n get canvas(): HTMLCanvasElement {\n return this._cv;\n }\n\n /**\n * Get the internal canvas' ImageData\n */\n get data(): ImageData {\n this._ensureData();\n return this._data;\n }\n\n /**\n * Get the internal canvas' context. You can use this to draw directly on canvas, or create a new [CanvasForm](#link) instance with it.\n */\n get ctx(): RenderingContext2D {\n return this._ctx;\n }\n\n /**\n * Get whether the image is loaded\n */\n get loaded(): boolean {\n return this._loaded;\n }\n\n /**\n * Get pixel density scale\n */\n get pixelScale(): number {\n return this._scale;\n }\n\n /**\n * Get size of the original image\n */\n get imageSize(): Pt {\n if (!this._img || !this._img.width || !this._img.height) {\n return this._cv ? this.canvasSize.$divide(this._scale) : new Pt(0, 0);\n } else {\n return new Pt(this._img.width, this._img.height);\n }\n }\n\n /**\n * Get size of the canvas\n */\n get canvasSize(): Pt {\n return new Pt(this._cv.width, this._cv.height);\n }\n\n /**\n * Get a Mat instance with a scale transform based on current `pixelScale`.\n * This can be useful for generating a domMatrix for transforming patterns consistently across different pixel-density screens.\n * @example `img.scaledMatrix.translate2d(...).rotate2D(...).domMatrix`\n */\n get scaledMatrix(): Mat {\n const s = 1 / this._scale;\n return new Mat().scale2D([s, s]);\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { MultiTouchSpace } from \"./Space\";\nimport { VisualForm, Font } from \"./Form\";\nimport { Pt, Group, Bound } from \"./Pt\";\nimport { Const, Util } from \"./Util\";\nimport { Typography as Typo } from \"./Typography\";\nimport { Rectangle } from \"./Op\";\nimport { Img } from \"./Image\";\nimport {\n type PtLike,\n type GroupLike,\n type RenderingContext2D,\n type DefaultFormStyle,\n type PtLikeIterable,\n type PtIterable,\n type CanvasSpaceOptions,\n type TextMeasure,\n type TextVerticalAlign,\n} from \"./Types\";\n\n/**\n * CanvasSpace is an implementation of the abstract class [`Space`](#link). It represents a space for HTML Canvas.\n * Learn more about the concept of Space in [this guide](../guide/Space-0500.html).\n */\nexport class CanvasSpace extends MultiTouchSpace {\n protected _canvas: HTMLCanvasElement;\n protected _container!: Element;\n\n protected _pixelScale = 1;\n protected _bgcolor = \"#e1e9f0\";\n protected _ctx: CanvasRenderingContext2D;\n\n protected _offscreen = false;\n protected _offCanvas!: HTMLCanvasElement;\n protected _offCtx!: RenderingContext2D;\n\n protected _resizeObserver: ResizeObserver | undefined;\n protected _autoResize = true;\n protected _initialResize = false;\n\n private _readyObserver: MutationObserver | undefined;\n private _readyTimer: number | undefined;\n private _disposed = false;\n private _ownsCanvas = false;\n private _ownsContainer = false;\n\n /**\n * Create a CanvasSpace which represents a HTML Canvas Space\n * @param elem Specify an element by its \"id\" attribute as string, or by the element object itself. An element can be an existing `<canvas>`, or a `<div>` container in which a new `<canvas>` will be created. If left empty, a `<div id=\"pt_container\"><canvas id=\"pt\" /></div>` will be added to DOM. Use css to customize its appearance if needed.\n * @param callback an optional callback `function(boundingBox, spaceElement)` to be called when canvas is appended and ready. Alternatively, a \"ready\" event will also be fired from the `<canvas>` element when it's appended, which can be traced with `spaceInstance.canvas.addEventListener(\"ready\")`\n * @example `new CanvasSpace( \"#myElementID\" )`\n */\n constructor(\n elem: string | Element | null = \"pt\",\n callback?: (bound: Bound, elem: EventTarget) => void,\n ) {\n super();\n\n let _selector: Element | null = null;\n let _existed = false;\n this.id = Util.uniqueId();\n\n // get selector element depending on whether `elem` is an element id string or an element object\n if (elem instanceof Element) {\n _selector = elem;\n this.id = _selector.id || this.id;\n } else {\n const target = elem || \"pt\";\n const id = target[0] === \"#\" || target[0] === \".\" ? target : \"#\" + target;\n _selector = document.querySelector(id);\n this.id = id.substr(1);\n }\n\n // if selector is not defined, create a default canvas\n if (!_selector) {\n this._ownsContainer = true;\n this._container = this._createElement(\"div\", this.id + \"_container\");\n this._canvas = this._createElement(\n \"canvas\",\n this.id,\n ) as HTMLCanvasElement;\n document.body.appendChild(this._container);\n\n // if selector is element but not canvas, create a canvas inside it\n } else if (_selector.nodeName.toLowerCase() != \"canvas\") {\n this._container = _selector;\n this._canvas = this._createElement(\n \"canvas\",\n this.id + \"_canvas\",\n ) as HTMLCanvasElement;\n this._initialResize = true;\n\n // if selector is an existing canvas\n } else {\n this._canvas = _selector as HTMLCanvasElement;\n this._container = _selector.parentElement!;\n this._autoResize = false;\n _existed = true;\n }\n\n // store canvas 2d rendering context\n this._ctx = this._canvas.getContext(\"2d\")!;\n\n // if we created the canvas, add it to the container and observe mutation for readiness\n if (!_existed) {\n this._ownsCanvas = true;\n this._readyObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (mutation.type === \"childList\" && mutation.addedNodes.length) {\n for (let node of mutation.addedNodes) {\n if (node === this._canvas) {\n this._ready(callback);\n this._readyObserver?.disconnect();\n this._readyObserver = undefined;\n return;\n }\n }\n }\n });\n });\n\n this._readyObserver.observe(this._container, { childList: true });\n this._container.appendChild(this._canvas);\n } else {\n // Wait one turn for .setup() to be called before firing ready event\n this._readyTimer = window.setTimeout(() => this._ready(callback), 100);\n }\n }\n\n /**\n * Helper function to create a DOM element\n * @param elem element tag name\n * @param id element id attribute\n */\n protected _createElement(elem = \"div\", id: string) {\n const d = document.createElement(elem);\n d.setAttribute(\"id\", id);\n return d;\n }\n\n /**\n * Handle callbacks after element is mounted in DOM\n * @param callback\n */\n private _ready(callback?: (bound: Bound, elem: EventTarget) => void) {\n if (this._disposed) return;\n\n this._readyTimer = undefined;\n if (!this._container)\n throw new Error(`Cannot initiate #${this.id} element`);\n\n this._isReady = true;\n\n this._resizeHandler(null);\n\n this.clear(this._bgcolor);\n this._canvas.dispatchEvent(new Event(\"ready\"));\n\n for (const k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n if (this.players[k].start)\n this.players[k].start(this.bound.clone(), this);\n }\n }\n\n this._pointer = this.center;\n this._initialResize = false; // unset\n\n if (callback) callback(this.bound, this._canvas);\n }\n\n /**\n * Set up various options for CanvasSpace. The `opt` parameter is an object with the following fields. This is usually set during instantiation, eg `new CanvasSpace(...).setup( { opt } )`\n * @param opt a [`CanvasSpaceOptions`](#link) object with optional settings, ie `{ bgcolor:string, resize:boolean, retina:boolean, offscreen:boolean, pixelDensity:number }`. Note that omitting `bgcolor` sets a transparent background (a long-standing behavior that differs from `DOMSpace.setup`, which keeps the current background when the option is absent).\n * @example `space.setup({ bgcolor: \"#f00\", retina: true, resize: true })`\n */\n setup(opt: CanvasSpaceOptions): this {\n this._bgcolor = opt.bgcolor ? opt.bgcolor : \"transparent\";\n\n this.autoResize = opt.resize != undefined ? opt.resize : false;\n\n if (opt.retina !== false) {\n const r1 = window ? window.devicePixelRatio || 1 : 1;\n this._pixelScale = Math.max(1, r1);\n }\n\n if (opt.offscreen) {\n this._offscreen = true;\n this._offCanvas = this._createElement(\n \"canvas\",\n this.id + \"_offscreen\",\n ) as HTMLCanvasElement;\n this._offCtx = this._offCanvas.getContext(\"2d\")!;\n } else {\n this._offscreen = false;\n }\n\n if (opt.pixelDensity) {\n this._pixelScale = opt.pixelDensity;\n }\n\n return this;\n }\n\n /**\n * Set whether the canvas element should resize when its container is resized.\n * @param auto a boolean value indicating if auto size is set\n */\n set autoResize(auto) {\n if (this._autoResize === auto && (!auto || this._resizeObserver)) return;\n\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n this._resizeObserver = undefined;\n }\n\n this._autoResize = auto;\n\n if (auto) {\n this._resizeObserver = new ResizeObserver((entries) => {\n this._resizeHandler(null);\n });\n this._resizeObserver.observe(this._container);\n }\n }\n get autoResize(): boolean {\n return this._autoResize;\n }\n\n /**\n * This overrides Space's `resize` function. It's used as a callback function for window's resize event and not usually called directly. You can keep track of resize events with `resize: (bound ,evt)` callback in your player objects.\n * @param b a Bound object to resize to\n * @param evt Optionally pass a resize event\n * @see Space.add\n */\n resize(b: Bound, evt?: Event | null): this {\n this.bound = b;\n\n // The buffer needs whole device pixels, so round up to cover the bound.\n this._canvas.width = Math.ceil(this.bound.size.x) * this._pixelScale;\n this._canvas.height = Math.ceil(this.bound.size.y) * this._pixelScale;\n // The CSS size must not round up: a canvas even a fraction of a pixel\n // larger than its container overflows it, and on systems whose scrollbars\n // take up layout space that summons scrollbars, shrinking the container —\n // which the resize observer answers by shrinking the canvas, letting the\n // scrollbars retract, growing the container again, and so on forever. The\n // oscillation clears the canvas on every pass (it looks blank) and the\n // endless relayout can eventually crash the tab.\n this._canvas.style.width = this.bound.size.x + \"px\";\n this._canvas.style.height = this.bound.size.y + \"px\";\n\n if (this._offscreen) {\n this._offCanvas.width = Math.ceil(this.bound.size.x) * this._pixelScale;\n this._offCanvas.height = Math.ceil(this.bound.size.y) * this._pixelScale;\n // this._offCanvas.style.width = Math.floor(this.bound.size.x) + \"px\";\n // this._offCanvas.style.height = Math.floor(this.bound.size.y) + \"px\";\n }\n\n if (this._pixelScale != 1) {\n this._ctx.scale(this._pixelScale, this._pixelScale);\n\n if (this._offscreen) {\n this._offCtx.scale(this._pixelScale, this._pixelScale);\n }\n }\n\n // Assigning canvas width/height resets the context's entire state to\n // defaults, so any cached style values no longer describe the context —\n // without this, a form's style write matching the stale cache would be\n // skipped and the context would stay at its black defaults.\n CanvasForm.resetStyleCache(this._ctx);\n if (this._offscreen) CanvasForm.resetStyleCache(this._offCtx);\n\n for (const k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n const p = this.players[k];\n if (p.resize) p.resize(this.bound, evt);\n }\n }\n\n this.render(this._ctx);\n\n // if it's a valid resize event and space is not playing, repaint the canvas once\n if (evt && !this.isPlaying) this.playOnce(0);\n\n return this;\n }\n\n /**\n * Window resize handling\n * @param evt\n */\n protected _resizeHandler(evt: Event | null) {\n const b =\n this._autoResize || this._initialResize\n ? this._container.getBoundingClientRect()\n : this._canvas.getBoundingClientRect();\n\n if (b) {\n const box = Bound.fromBoundingRect(b);\n\n // Need to compute offset from window scroll. See outerBound calculation in Space's _mouseAction\n box.center = box.center.add(window?.scrollX || 0, window?.scrollY || 0);\n this.resize(box, evt);\n }\n }\n\n /**\n * Set a background color for this canvas. Alternatively, you may use `clear()` function.\n @param bg background color as hex or rgba string\n */\n set background(bg: string) {\n this._bgcolor = bg;\n }\n get background(): string {\n return this._bgcolor;\n }\n\n /**\n * `pixelScale` property returns a number that let you determine if the screen is \"retina\" (when value >= 2)\n */\n public get pixelScale(): number {\n return this._pixelScale;\n }\n\n /**\n * Check if an offscreen canvas is created\n */\n public get hasOffscreen(): boolean {\n return this._offscreen;\n }\n\n /**\n * Get the rendering context of offscreen canvas (if created via `setup()`)\n */\n public get offscreenCtx(): RenderingContext2D {\n return this._offCtx;\n }\n\n /**\n * Get the offscreen canvas element\n */\n public get offscreenCanvas(): HTMLCanvasElement {\n return this._offCanvas;\n }\n\n /**\n * Get a new `CanvasForm` for drawing\n * @see `CanvasForm`\n */\n public getForm(): CanvasForm {\n return new CanvasForm(this);\n }\n\n /**\n * Get the html canvas element\n */\n get element(): HTMLCanvasElement {\n return this._canvas;\n }\n\n /**\n * Get the parent element that contains the canvas element\n */\n get parent(): Element {\n return this._container;\n }\n\n /**\n * A property to indicate if the Space is ready\n */\n get ready(): boolean {\n return this._isReady;\n }\n\n /**\n * Get the rendering context of canvas\n * @example `form.ctx.clip()`\n */\n public get ctx(): CanvasRenderingContext2D {\n return this._ctx;\n }\n\n /**\n * Clear the canvas with its background color. Overrides Space's `clear` function.\n * @param bg Optionally specify a custom background color in hex or rgba string, or \"transparent\". If not defined, it will use its `bgcolor` property as background color to clear the canvas.\n */\n clear(bg?: string): this {\n if (bg) this._bgcolor = bg;\n const lastColor = this._ctx.fillStyle;\n const px = Math.ceil(this.pixelScale);\n\n if (!this._bgcolor || this._bgcolor === \"transparent\") {\n this._ctx.clearRect(\n -px,\n -px,\n this._canvas.width + px,\n this._canvas.height + px,\n );\n } else {\n // semi-transparent bg needs to be cleared first\n if (\n this._bgcolor.indexOf(\"rgba\") === 0 ||\n (this._bgcolor.length === 9 && this._bgcolor.indexOf(\"#\") === 0)\n ) {\n this._ctx.clearRect(\n -px,\n -px,\n this._canvas.width + px,\n this._canvas.height + px,\n );\n }\n this._ctx.fillStyle = this._bgcolor;\n this._ctx.fillRect(\n -px,\n -px,\n this._canvas.width + px,\n this._canvas.height + px,\n );\n }\n\n this._ctx.fillStyle = lastColor;\n return this;\n }\n\n /**\n * Similiar to `clear()` but clear the offscreen canvas instead\n * @param bg Optionally specify a custom background color in hex or rgba string, or \"transparent\". If not defined, it will use its `bgcolor` property as background color to clear the canvas.\n */\n clearOffscreen(bg?: string | null): this {\n if (this._offscreen) {\n const px = Math.ceil(this.pixelScale);\n if (bg) {\n this._offCtx.fillStyle = bg;\n this._offCtx.fillRect(\n -px,\n -px,\n this._canvas.width + px,\n this._canvas.height + px,\n );\n } else {\n this._offCtx.clearRect(\n -px,\n -px,\n this._offCanvas.width + px,\n this._offCanvas.height + px,\n );\n }\n }\n return this;\n }\n\n /**\n * Main animation function.\n * @param time current time\n */\n protected playItems(time: number) {\n if (this._isReady) {\n this._ctx.save();\n if (this._offscreen) this._offCtx.save();\n super.playItems(time);\n this._ctx.restore();\n if (this._offscreen) this._offCtx.restore();\n // restore() reverted the context's style state without going through the\n // forms' style cache, so the cached values no longer describe the context\n CanvasForm.resetStyleCache(this._ctx);\n if (this._offscreen) CanvasForm.resetStyleCache(this._offCtx);\n this.render(this._ctx);\n }\n }\n\n /**\n * Dispose of browser resources held by this space and remove all players. Call this before unmounting the canvas.\n */\n dispose(): this {\n if (this._disposed) return this;\n this._disposed = true;\n\n if (this._readyTimer !== undefined) {\n window.clearTimeout(this._readyTimer);\n this._readyTimer = undefined;\n }\n if (this._readyObserver) {\n this._readyObserver.disconnect();\n this._readyObserver = undefined;\n }\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n this._resizeObserver = undefined;\n }\n\n this._unbindAll();\n this._cancelAnimation();\n this.removeAll();\n this._isReady = false;\n if (this._ownsCanvas) this._canvas.remove();\n if (this._ownsContainer && this._container.childNodes.length === 0)\n this._container.remove();\n\n return this;\n }\n\n /**\n * Get a [`MediaRecorder`](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder) to record the current CanvasSpace. You can then call its `start()` function to start recording, and `stop()` to either download the video file or handle the blob data in the callback function you provided.\n * @param downloadOrCallback Either `true` to download the video, or provide a callback function to handle the Blob data, when recording is completed.\n * @param filetype video format. Default is \"webm\".\n * @param bitrate bitrate per second\n * @example `let rec = space.recorder(true); rec.start(); setTimeout( () => rec.stop(), 5000); // record 5s of video and download the file`\n */\n recorder(\n downloadOrCallback: boolean | ((blobURL: string) => {}),\n filetype: string = \"webm\",\n bitrate: number = 15000000,\n ): MediaRecorder {\n const stream = this._canvas.captureStream();\n const recorder = new MediaRecorder(stream, {\n mimeType: `video/${filetype}`,\n bitsPerSecond: bitrate,\n });\n\n recorder.ondataavailable = function (d) {\n const url = URL.createObjectURL(\n new Blob([d.data], { type: `video/${filetype}` }),\n );\n\n if (typeof downloadOrCallback === \"function\") {\n downloadOrCallback(url);\n } else if (downloadOrCallback) {\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `canvas_video.${filetype}`;\n a.click();\n a.remove();\n // the download has started from the blob by now; release the URL\n // (callback consumers own the URL and release it themselves)\n setTimeout(() => URL.revokeObjectURL(url), 100);\n }\n };\n\n return recorder;\n }\n}\n\n/**\n * CanvasForm is an implementation of abstract class [`VisualForm`](#link). It provide methods to express Pts on [`CanvasSpace`](#link).\n * You may extend CanvasForm to implement your own expressions for CanvasSpace.\n */\n// Last-written style values per rendering context, so identical values are\n// not re-applied (color parsing in particular is costly). Keyed by context —\n// not by form — because multiple forms can share one context (see `reset()`),\n// and a per-form cache would skip writes another form made stale.\nconst _ctxStyleCache = new WeakMap<object, Record<string, unknown>>();\n\nexport class CanvasForm<\n S extends MultiTouchSpace = CanvasSpace,\n> extends VisualForm {\n protected _space!: CanvasSpace;\n protected _ctx!: RenderingContext2D;\n protected _estimateTextWidth: TextMeasure | undefined;\n protected _estimateMode: \"sample\" | \"char\" | undefined;\n\n // the shared cache object for this._ctx, revalidated only when the context\n // changes so the hot path avoids a WeakMap lookup per style write\n private _styleCache: Record<string, unknown> | null = null;\n private _styleCacheCtx: RenderingContext2D | null = null;\n\n /** Get the style cache shared by all forms drawing on this context. */\n protected _cacheForCtx(): Record<string, unknown> {\n if (this._styleCacheCtx !== this._ctx) {\n let cache = _ctxStyleCache.get(this._ctx);\n if (!cache) {\n cache = {};\n _ctxStyleCache.set(this._ctx, cache);\n }\n this._styleCache = cache;\n this._styleCacheCtx = this._ctx;\n }\n return this._styleCache!;\n }\n\n /**\n * Forget the cached style values for a rendering context, so every\n * subsequent style write applies. Call this after anything that resets or\n * desyncs a context's state outside a form — most commonly assigning a\n * canvas's `width` or `height`, which resets the context to its defaults.\n * (Within a form, [`CanvasForm.reset`](#link) is the equivalent recovery.)\n * @param ctx the rendering context to forget\n */\n static resetStyleCache(ctx: RenderingContext2D | object): void {\n // clear the shared object in place: forms cache a reference to it, so\n // deleting the WeakMap entry would leave them holding stale values\n const cache = _ctxStyleCache.get(ctx);\n if (cache) {\n for (const k in cache) delete cache[k];\n }\n }\n\n /**\n * Write a context style property only when it differs from the last value\n * written to this context. After setting style properties directly on\n * [`CanvasForm.ctx`](#link), call [`CanvasForm.reset`](#link) to resync.\n */\n protected _set(key: string, value: unknown): void {\n const cache = this._cacheForCtx();\n if (cache[key] !== value) {\n cache[key] = value;\n (this._ctx as any)[key] = value;\n }\n }\n\n /**\n * store common styles so that they can be restored to canvas context when using multiple forms. See `reset()`.\n */\n protected _style: DefaultFormStyle = {\n fillStyle: \"#f03\",\n strokeStyle: \"#fff\",\n lineWidth: 1,\n lineJoin: \"bevel\",\n lineCap: \"butt\",\n globalAlpha: 1,\n };\n\n /**\n * Create a new CanvasForm. You may also use [`CanvasSpace.getForm()`](#link) to get the default form.\n * @param space an instance of CanvasSpace, or a rendering context. Passing a context is the\n * renderer extension point: any object implementing the context surface documented in\n * [`SVGContext2D`](#link) (the reference implementation) receives this form's full drawing\n * API — this is how SVG output works, and how custom renderers can be built.\n */\n constructor(space?: CanvasSpace | RenderingContext2D) {\n super();\n\n // allow for undefined context to support custom contexts via subclassing.\n if (!space) return this;\n\n const _setup = (ctx: RenderingContext2D) => {\n this._ctx = ctx;\n this._set(\"fillStyle\", this._style.fillStyle);\n this._set(\"strokeStyle\", this._style.strokeStyle);\n this._set(\"lineJoin\", \"bevel\");\n this._set(\"font\", this._font.value);\n this._ready = true;\n };\n\n if (space instanceof CanvasSpace) {\n this._space = space;\n if (this._space.ready && this._space.ctx) {\n _setup(this._space.ctx);\n } else {\n this._space.add({\n start: () => {\n _setup(this._space.ctx);\n },\n });\n }\n } else {\n _setup(space);\n }\n }\n\n /**\n * get the CanvasSpace instance that this form is associated with\n */\n get space(): S {\n // subclasses for other backends (eg, SVGForm) narrow S to their own space type\n return this._space as unknown as S;\n }\n\n /**\n * Get the rendering context of canvas to perform other canvas functions.\n * @example `form.ctx.clip()`\n */\n get ctx(): RenderingContext2D {\n return this._ctx;\n }\n\n /**\n * Toggle whether to draw on offscreen canvas (if offscreen is set in CanvasSpace)\n * @param off if `true`, draw on offscreen canvas instead of the visible canvas. Default is `true`\n * @param clear optionally provide a valid color string to fill a bg color. see CanvasSpace's `clearOffscreen` function.\n */\n useOffscreen(off: boolean = true, clear: boolean | string = false) {\n if (clear)\n this._space.clearOffscreen(typeof clear == \"string\" ? clear : null);\n this._ctx =\n this._space.hasOffscreen && off\n ? this._space.offscreenCtx\n : this._space.ctx;\n return this;\n }\n\n /**\n * Render the offscreen canvas's content on the visible canvas\n * @param offset Optional offset on the top-left position when drawing on the visible canvas\n */\n renderOffscreen(offset: PtLike = [0, 0]) {\n if (this._space.hasOffscreen) {\n this._space.ctx.drawImage(\n this._space.offscreenCanvas,\n offset[0],\n offset[1],\n this._space.width,\n this._space.height,\n );\n }\n }\n\n /**\n * Set current alpha value.\n * @example `form.alpha(0.6)`\n * @param a alpha value between 0 and 1\n */\n alpha(a: number): this {\n this._set(\"globalAlpha\", a);\n this._style.globalAlpha = a;\n return this;\n }\n\n /**\n * Set current fill style. Provide a valid color string such as `\"#FFF\"` or `\"rgba(255,0,100,0.5)\"` or `false` to specify no fill color.\n * @example `form.fill(\"#F90\")`, `form.fill(\"rgba(0,0,0,.5\")`, `form.fill(false)`\n * @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))\n */\n fill(c: string | boolean | CanvasGradient | CanvasPattern): this {\n if (typeof c == \"boolean\") {\n this.filled = c;\n } else {\n this.filled = true;\n this._style.fillStyle = c;\n this._set(\"fillStyle\", c);\n }\n return this;\n }\n\n /**\n * Set current fill style and remove stroke style.\n * @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))\n */\n fillOnly(c: string | boolean | CanvasGradient | CanvasPattern): this {\n this.stroke(false);\n return this.fill(c);\n }\n\n /**\n * Set current stroke style. Provide a valid color string or `false` to specify no stroke color.\n * @example `form.stroke(\"#F90\")`, `form.stroke(\"rgba(0,0,0,.5\")`, `form.stroke(false)`, `form.stroke(\"#000\", 0.5, 'round', 'square')`\n * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))\n * @param width Optional value (can be floating point) to set line width\n * @param linejoin Optional string to set line joint style. Can be \"miter\", \"bevel\", or \"round\".\n * @param linecap Optional string to set line cap style. Can be \"butt\", \"round\", or \"square\".\n */\n stroke(\n c: string | boolean | CanvasGradient | CanvasPattern,\n width?: number,\n linejoin?: CanvasLineJoin,\n linecap?: CanvasLineCap,\n ): this {\n if (typeof c == \"boolean\") {\n this.stroked = c;\n } else {\n this.stroked = true;\n this._style.strokeStyle = c;\n this._set(\"strokeStyle\", c);\n if (width) {\n this._set(\"lineWidth\", width);\n this._style.lineWidth = width;\n }\n if (linejoin) {\n this._set(\"lineJoin\", linejoin);\n this._style.lineJoin = linejoin;\n }\n if (linecap) {\n this._set(\"lineCap\", linecap);\n this._style.lineCap = linecap;\n }\n }\n return this;\n }\n\n /**\n * Set stroke style and remove fill style.\n * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))\n * @param width Optional value (can be floating point) to set line width\n * @param linejoin Optional string to set line joint style. Can be \"miter\", \"bevel\", or \"round\".\n * @param linecap Optional string to set line cap style. Can be \"butt\", \"round\", or \"square\".\n */\n strokeOnly(\n c: string | boolean | CanvasGradient | CanvasPattern,\n width?: number,\n linejoin?: CanvasLineJoin,\n linecap?: CanvasLineCap,\n ): this {\n this.fill(false);\n return this.stroke(c, width, linejoin, linecap);\n }\n\n /**\n * A convenient function to apply fill and/or stroke after custom drawings using canvas context (eg, `form.ctx.ellipse(...)`).\n * You don't need to call this function if you're using Pts' drawing functions like `form.point` or `form.rect`\n * @param filled apply fill when set to `true`\n * @param stroked apply stroke when set to `true`\n * @param strokeWidth optionally set a stroke width\n * @example `form.ctx.beginPath(); form.ctx.ellipse(...); form.applyFillStroke();`\n */\n applyFillStroke(\n filled: boolean | string = true,\n stroked: boolean | string = true,\n strokeWidth: number = 1,\n ) {\n if (filled) {\n if (typeof filled === \"string\") this.fill(filled);\n this._ctx.fill();\n }\n\n if (stroked) {\n if (typeof stroked === \"string\") this.stroke(stroked, strokeWidth);\n this._ctx.stroke();\n }\n\n return this;\n }\n\n /**\n * This function takes an array of gradient colors, and returns a function to define the areas of the gradient fill. See demo code in [CanvasForm.gradient](https://ptsjs.org/demo/?name=canvasform.textBox).\n * @param stops an array of gradient stops. This can be an array of colors `[\"#f00\", \"#0f0\", ...]` for evenly distributed gradient, or an array of [stop, color] like `[[0.1, \"#f00\"], [0.7, \"#0f0\"]]`\n * @returns a function that takes 1 or 2 `Group` as parameters. Use a single `Group` to specify a rectangular area for linear gradient, or use 2 `Groups` to specify 2 `Circles` for radial gradient.\n * @example `c1 = Circle.fromCenter(...); grad = form.gradient([\"#f00\", \"#00f\"]); form.fill( grad( c1, c2 ) ).circle( c1 )`\n */\n gradient(\n stops: [number, string][] | string[],\n ): (area1: GroupLike, area2?: GroupLike) => CanvasGradient {\n const vals: [number, string][] = [];\n // copy before padding so the caller's array is never mutated\n if (stops.length < 2) {\n stops = [...stops, [0.99, \"#000\"], [1, \"#000\"]] as\n [number, string][] | string[];\n }\n\n for (let i = 0, len = stops.length; i < len; i++) {\n const t: number =\n typeof stops[i] === \"string\"\n ? i * (1 / (stops.length - 1))\n : (stops[i][0] as number);\n const v: string =\n typeof stops[i] === \"string\"\n ? (stops[i] as string)\n : (stops[i][1] as string);\n vals.push([t, v]);\n }\n\n return (area1: GroupLike, area2?: GroupLike) => {\n const grad = area2\n ? this._ctx.createRadialGradient(\n area1[0][0],\n area1[0][1],\n Math.abs(area1[1][0]),\n area2[0][0],\n area2[0][1],\n Math.abs(area2[1][0]),\n )\n : this._ctx.createLinearGradient(\n area1[0][0],\n area1[0][1],\n area1[1][0],\n area1[1][1],\n );\n\n for (let i = 0, len = vals.length; i < len; i++) {\n grad.addColorStop(vals[i][0], vals[i][1]);\n }\n\n return grad;\n };\n }\n\n /**\n * Set composite operation (also known as blend mode). You can also call this function without parameters to get back to default 'source-over' mode. See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) for the full list of operations you can use.\n * @param mode a composite operation such as 'lighten', 'multiply', 'overlay', and 'color-burn'.\n */\n composite(mode: GlobalCompositeOperation = \"source-over\"): this {\n this._set(\"globalCompositeOperation\", mode);\n return this;\n }\n\n /**\n * Create a clipping mask from the current path. See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip) for details.\n */\n clip(): this {\n this._ctx.clip();\n return this;\n }\n\n /**\n * Activate dashed stroke and set dash style. You can customize the segments and offset.\n * @example `form.dash()`, `form.dash([5, 10])`, `form.dash([5, 5], 5)`, `form.dash(false)`\n * @param segments Dash segments. Defaults to `true` which corresponds to `[5, 5]`. Pass `false` to deactivate dashes. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash))\n * @param offset Dash offset. Defaults to 0. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)\n */\n dash(segments: PtLike | boolean = true, offset: number = 0): this {\n // dedupe via a compact key since getLineDash() allocates\n const cache = this._cacheForCtx();\n if (segments === false || (segments !== true && segments.length === 0)) {\n // false or [], deactivate dashed strokes\n if (cache.dash !== \"/0\") {\n cache.dash = \"/0\";\n this._ctx.setLineDash([]);\n this._ctx.lineDashOffset = 0;\n }\n } else {\n const seg: PtLike = segments === true ? [5, 5] : segments;\n const key = `${Array.prototype.join.call(seg, \",\")}/${offset}`;\n if (cache.dash !== key) {\n cache.dash = key;\n this._ctx.setLineDash(seg as number[]);\n this._ctx.lineDashOffset = offset;\n }\n }\n return this;\n }\n\n /**\n * Set the current font.\n * @param sizeOrFont either a number to specify font-size, or a `Font` object to specify all font properties\n * @param weight Optional font-weight string such as \"bold\"\n * @param style Optional font-style string such as \"italic\"\n * @param lineHeight Optional line-height number suchas 1.5\n * @param family Optional font-family such as \"Helvetica, sans-serif\"\n * @example `form.font( myFont )`, `form.font(14, \"bold\")`\n */\n font(\n sizeOrFont: number | Font,\n weight?: string,\n style?: string,\n lineHeight?: number,\n family?: string,\n ): this {\n if (typeof sizeOrFont == \"number\") {\n this._font.size = sizeOrFont;\n if (family) this._font.face = family;\n if (weight) this._font.weight = weight;\n if (style) this._font.style = style;\n if (lineHeight) this._font.lineHeight = lineHeight;\n } else {\n this._font = sizeOrFont;\n }\n\n this._set(\"font\", this._font.value);\n\n // If using estimate, reapply the same mode with the new font's metrics.\n if (this._estimateMode) this.fontWidthEstimate(this._estimateMode);\n\n return this;\n }\n\n /**\n * Set whether to use html canvas' [`measureText`](#link) function, or a faster but less accurate estimate.\n * @param estimate `false` to use ctx.measureText; `true` or `\"sample\"` to use a sampled-average estimator (fastest); `\"char\"` to use a per-character width cache (nearly as accurate as measureText for most texts, and much faster after warmup)\n */\n fontWidthEstimate(estimate: boolean | \"sample\" | \"char\" = true): this {\n if (!estimate) {\n this._estimateMode = undefined;\n this._estimateTextWidth = undefined;\n } else {\n const measure: TextMeasure = (c: string) =>\n this._ctx.measureText(c).width;\n this._estimateMode = estimate === true ? \"sample\" : estimate;\n this._estimateTextWidth =\n this._estimateMode === \"char\"\n ? Typo.charWidthCache(measure)\n : Typo.textWidthEstimator(measure);\n }\n return this;\n }\n\n /**\n * Get the width of this text. It will return an actual measurement or an estimate based on [`fontWidthEstimate`](#link) setting. Default is an actual measurement using canvas context's measureText.\n * @param c a string of text contents\n */\n getTextWidth(c: string): number {\n return !this._estimateTextWidth\n ? this._ctx.measureText(c).width\n : this._estimateTextWidth(c);\n }\n\n /**\n * Truncate text to fit width.\n * @param str text to truncate\n * @param width width to fit\n * @param tail text to indicate overflow such as \"...\". Default is empty \"\".\n */\n protected _textTruncate(\n str: string,\n width: number,\n tail: string = \"\",\n hint?: number,\n ): [string, number] {\n return Typo.truncate(this.getTextWidth.bind(this), str, width, tail, hint);\n }\n\n /**\n * Align text within a rectangle box.\n * @param box a Group or an Iterable<PtLike> that defines a rectangular box\n * @param vertical a string that specifies the vertical alignment in the box: \"top\", \"bottom\", \"middle\", \"start\", \"end\"\n * @param offset Optional offset from the edge (like padding)\n * @param center Optional center position\n */\n protected _textAlign(\n box: PtLikeIterable,\n vertical: TextVerticalAlign,\n offset?: PtLike,\n center?: Pt,\n ): Pt | undefined {\n const _box = Util.iterToArray(box);\n if (!Util.arrayCheck(_box)) return;\n\n if (!center) center = Rectangle.center(_box);\n\n let px = _box[0][0];\n if (this._ctx.textAlign == \"end\" || this._ctx.textAlign == \"right\") {\n px = _box[1][0];\n } else if (\n this._ctx.textAlign == \"center\" ||\n // @ts-expect-error CanvasTextAlign omits the legacy \"middle\" value supported here.\n this._ctx.textAlign == \"middle\"\n ) {\n px = center[0];\n }\n\n let py = center[1];\n if (vertical == \"top\" || vertical == \"start\") {\n py = _box[0][1];\n } else if (vertical == \"end\" || vertical == \"bottom\") {\n py = _box[1][1];\n }\n\n return offset ? new Pt(px + offset[0], py + offset[1]) : new Pt(px, py);\n }\n\n /**\n * Reset the rendering context's common styles to this form's styles. This supports using multiple forms on the same canvas context.\n */\n reset(): this {\n // force-write and resync the cache — this is the documented recovery\n // point after styles were set directly on the context\n const cache = this._cacheForCtx();\n for (const k in this._style) {\n if (this._style.hasOwnProperty(k)) {\n (this._ctx as any)[k] = (this._style as any)[k];\n cache[k] = (this._style as any)[k];\n }\n }\n // same default as a fresh VisualForm (14px sans-serif)\n this._font = new Font(14, \"sans-serif\");\n this._ctx.font = this._font.value;\n cache.font = this._font.value;\n return this;\n }\n\n protected _paint() {\n if (this._filled) this._ctx.fill();\n if (this._stroked) this._ctx.stroke();\n }\n\n /**\n * A static function to draw a point.\n * @param ctx canvas rendering context\n * @param p a Pt object\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `form.point( p )`, `form.point( p, 10, \"circle\" )`\n */\n static point(\n ctx: RenderingContext2D,\n p: PtLike,\n radius: number = 5,\n shape: string = \"square\",\n ) {\n if (!p) return;\n if (!(CanvasForm as any)[shape])\n throw new Error(`${shape} is not a static function of CanvasForm`);\n (CanvasForm as any)[shape](ctx, p, radius);\n }\n\n /**\n * Draws a point.\n * @param p a Pt object\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `form.point( p )`, `form.point( p, 10, \"circle\" )`\n */\n point(p: PtLike, radius: number = 5, shape: string = \"square\"): this {\n CanvasForm.point(this._ctx, p, radius, shape);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw a circle.\n * @param ctx canvas rendering context\n * @param pt center position of the circle\n * @param radius radius of the circle\n */\n static circle(ctx: RenderingContext2D, pt: PtLike, radius: number = 10) {\n if (!pt) return;\n ctx.beginPath();\n ctx.arc(pt[0], pt[1], radius, 0, Const.two_pi, false);\n ctx.closePath();\n }\n\n /**\n * Draw a circle. See also [`Circle.fromCenter`](#link)\n * @param pts usually a Group or an Iterable<PtLike> with 2 Pt, but it can also take an array of two numeric arrays [ [position], [size] ]\n */\n circle(pts: PtLikeIterable): this {\n const p = Util.iterToArray(pts);\n CanvasForm.circle(this._ctx, p[0], p[1][0]);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw an ellipse.\n * @param ctx canvas rendering context\n * @param pt center position\n * @param radius radius [x, y] of the ellipse\n * @param rotation rotation of the ellipse in radian. Default is 0.\n * @param startAngle start angle of the ellipse. Default is 0.\n * @param endAngle end angle of the ellipse. Default is 2 PI.\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n static ellipse(\n ctx: RenderingContext2D,\n pt: PtLike,\n radius: PtLike,\n rotation: number = 0,\n startAngle: number = 0,\n endAngle: number = Const.two_pi,\n cc: boolean = false,\n ) {\n if (!pt || !radius) return;\n ctx.beginPath();\n ctx.ellipse(\n pt[0],\n pt[1],\n radius[0],\n radius[1],\n rotation,\n startAngle,\n endAngle,\n cc,\n );\n }\n\n /**\n * Draw an ellipse.\n * @param pt center position\n * @param radius radius [x, y] of the ellipse\n * @param rotation rotation of the ellipse in radian. Default is 0.\n * @param startAngle start angle of the ellipse. Default is 0.\n * @param endAngle end angle of the ellipse. Default is 2 PI.\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n ellipse(\n pt: PtLike,\n radius: PtLike,\n rotation: number = 0,\n startAngle: number = 0,\n endAngle: number = Const.two_pi,\n cc: boolean = false,\n ) {\n CanvasForm.ellipse(\n this._ctx,\n pt,\n radius,\n rotation,\n startAngle,\n endAngle,\n cc,\n );\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw an arc.\n * @param ctx canvas rendering context\n * @param pt center position\n * @param radius radius of the arc circle\n * @param startAngle start angle of the arc\n * @param endAngle end angle of the arc\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n static arc(\n ctx: RenderingContext2D,\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ) {\n if (!pt) return;\n ctx.beginPath();\n ctx.arc(pt[0], pt[1], radius, startAngle, endAngle, cc);\n }\n\n /**\n * Draw an arc.\n * @param pt center position\n * @param radius radius of the arc circle\n * @param startAngle start angle of the arc\n * @param endAngle end angle of the arc\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n arc(\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): this {\n CanvasForm.arc(this._ctx, pt, radius, startAngle, endAngle, cc);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw a square.\n * @param ctx canvas rendering context\n * @param pt center position of the square\n * @param halfsize half size of the square\n */\n static square(ctx: RenderingContext2D, pt: PtLike, halfsize: number) {\n if (!pt) return;\n const x1 = pt[0] - halfsize;\n const y1 = pt[1] - halfsize;\n const x2 = pt[0] + halfsize;\n const y2 = pt[1] + halfsize;\n\n // faster than using `rect`\n ctx.beginPath();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x1, y2);\n ctx.lineTo(x2, y2);\n ctx.lineTo(x2, y1);\n ctx.closePath();\n }\n\n /**\n * Draw a square, given a center and its half-size.\n * @param pt center Pt\n * @param halfsize half-size\n */\n square(pt: PtLike, halfsize: number) {\n CanvasForm.square(this._ctx, pt, halfsize);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw a line or polyline.\n * @param ctx canvas rendering context\n * @param pts a Group or an Iterable<PtLike> representing a line\n */\n static line(ctx: RenderingContext2D, pts: PtLikeIterable) {\n if (!Util.arrayCheck(pts)) return;\n ctx.beginPath();\n let i = 0;\n if (Array.isArray(pts)) {\n // indexed fast path — inputs are nearly always Groups (Array subclass)\n for (let k = 0, len = pts.length; k < len; k++) {\n const it = pts[k];\n if (it) {\n if (i++ > 0) {\n ctx.lineTo(it[0], it[1]);\n } else {\n ctx.moveTo(it[0], it[1]);\n }\n }\n }\n } else {\n for (const it of pts) {\n if (it) {\n if (i++ > 0) {\n ctx.lineTo(it[0], it[1]);\n } else {\n ctx.moveTo(it[0], it[1]);\n }\n }\n }\n }\n }\n\n /**\n * Draw a line or polyline.\n * @param pts a Group or an Iterable<PtLike> representing a line\n */\n line(pts: PtLikeIterable): this {\n CanvasForm.line(this._ctx, pts);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw a polygon.\n * @param ctx canvas rendering context\n * @param pts a Group or an Iterable<PtLike> representing a polygon\n */\n static polygon(ctx: RenderingContext2D, pts: PtLikeIterable) {\n if (!Util.arrayCheck(pts)) return;\n CanvasForm.line(ctx, pts);\n ctx.closePath();\n }\n\n /**\n * Draw a polygon.\n * @param pts a Group or an Iterable<PtLike> representingg a polygon\n */\n polygon(pts: PtLikeIterable): this {\n CanvasForm.polygon(this._ctx, pts);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw a rectangle.\n * @param ctx canvas rendering context\n * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.\n */\n static rect(ctx: RenderingContext2D, pts: PtLikeIterable) {\n const p = Util.iterToArray(pts);\n if (!Util.arrayCheck(p)) return;\n ctx.beginPath();\n ctx.moveTo(p[0][0], p[0][1]);\n ctx.lineTo(p[0][0], p[1][1]);\n ctx.lineTo(p[1][0], p[1][1]);\n ctx.lineTo(p[1][0], p[0][1]);\n ctx.closePath();\n }\n\n /**\n * Draw a rectangle.\n * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.\n */\n rect(pts: PtLikeIterable): this {\n CanvasForm.rect(this._ctx, pts);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw an image.\n * @param ctx canvas rendering context\n * @param img either an [Img](#link) instance or an [`CanvasImageSource`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource) instance (eg the image from `<img>`, `<video>` or `<canvas>`)\n * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.\n * @param orig optionally a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a cropping box in the original target.\n */\n static image(\n ctx: RenderingContext2D,\n ptOrRect: PtLike | PtLikeIterable,\n img: CanvasImageSource | Img,\n orig?: PtLikeIterable,\n ) {\n const t = Util.iterToArray(ptOrRect);\n let pos: number[];\n\n if (typeof t[0] === \"number\") {\n // no crop\n pos = t as number[];\n } else {\n if (orig) {\n // crop\n const o = Util.iterToArray(orig);\n pos = [\n o[0][0],\n o[0][1],\n o[1][0] - o[0][0],\n o[1][1] - o[0][1],\n t[0][0],\n t[0][1],\n t[1][0] - t[0][0],\n t[1][1] - t[0][1],\n ];\n } else {\n // bounding box resize\n pos = [t[0][0], t[0][1], t[1][0] - t[0][0], t[1][1] - t[0][1]];\n }\n }\n\n if (img instanceof Img) {\n if (img.loaded) {\n // @ts-expect-error legacy DOM lib types omit these vendor/optional members\n ctx.drawImage(img.image, ...pos);\n }\n } else {\n // @ts-expect-error legacy DOM lib types omit these vendor/optional members\n ctx.drawImage(img, ...pos);\n }\n }\n\n /**\n * Draw an image.\n * @param img either an [Img](#link) instance or an [`CanvasImageSource`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource) instance (eg the image from `<img>`, `<video>` or `<canvas>`)\n * @param ptOrRect a target area to place the image. Either a PtLike specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left position, bottom-right position) that specifies a bounding box. Default is (0,0) at top-left.\n * @param orig optionally a Group or an Iterable<PtLike> with 2 Pt (top-left position, bottom-right position) that specifies a cropping box in the original target.\n */\n image(\n ptOrRect: PtLike | PtLikeIterable,\n img: CanvasImageSource | Img,\n orig?: PtLikeIterable,\n ) {\n if (img instanceof Img) {\n if (img.loaded) {\n CanvasForm.image(this._ctx, ptOrRect, img.image, orig);\n }\n } else {\n CanvasForm.image(this._ctx, ptOrRect, img, orig);\n }\n return this;\n }\n\n /**\n * A static function to draw ImageData on canvas\n * @param ctx canvas rendering context\n * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that places a region of the image data of that size at that position. Note that `putImageData` cannot resize: the rect clips, not scales. Default is (0,0) at top-left.\n * @param img an ImageData object\n */\n static imageData(\n ctx: RenderingContext2D,\n ptOrRect: PtLike | PtLikeIterable,\n img: ImageData,\n ) {\n const t = Util.iterToArray(ptOrRect);\n if (typeof t[0] === \"number\") {\n // Pt\n ctx.putImageData(img, t[0], t[1]);\n } else {\n // rect: place the image data's top-left region of the rect's size at\n // the rect's position (dirty coordinates are relative to the data)\n ctx.putImageData(\n img,\n t[0][0],\n t[0][1],\n 0,\n 0,\n t[1][0] - t[0][0],\n t[1][1] - t[0][1],\n );\n }\n }\n\n /**\n * Draw ImageData on canvas using ImageData\n * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.\n * @param img an ImageData object\n */\n imageData(ptOrRect: PtLike | PtLikeIterable, img: ImageData) {\n CanvasForm.imageData(this._ctx, ptOrRect, img);\n return this;\n }\n\n /**\n * A static function to draw text.\n * @param ctx canvas rendering context\n * @param pt a Point object to specify the anchor point\n * @param txt a string of text to draw\n * @param maxWidth specify a maximum width per line\n */\n static text(\n ctx: RenderingContext2D,\n pt: PtLike,\n txt: string,\n maxWidth?: number,\n ) {\n if (!pt) return;\n ctx.fillText(txt, pt[0], pt[1], maxWidth);\n }\n\n /**\n * Draw text on canvas.\n * @param pt a Pt or numeric array to specify the anchor point\n * @param txt text\n * @param maxWidth specify a maximum width per line\n */\n text(pt: PtLike, txt: string, maxWidth?: number): this {\n CanvasForm.text(this._ctx, pt, txt, maxWidth);\n return this;\n }\n\n /**\n * Fit a single-line text in a rectangular box.\n * @param box a rectangle box defined by a Group or an Iterable<Pt>\n * @param txt string of text\n * @param tail text to indicate overflow such as \"...\". Default is empty \"\".\n * @param verticalAlign \"top\", \"middle\", or \"bottom\" to specify vertical alignment inside the box\n * @param overrideBaseline If `true`, use the corresponding baseline as verticalAlign. If `false`, use the current canvas context's textBaseline setting. Default is `true`.\n */\n textBox(\n box: PtIterable,\n txt: string,\n verticalAlign: TextVerticalAlign = \"middle\",\n tail: string = \"\",\n overrideBaseline: boolean = true,\n ): this {\n // \"center\", \"start\", and \"end\" are box alignments, not canvas baselines;\n // assigning them to textBaseline is silently ignored by the context\n if (overrideBaseline) {\n this._ctx.textBaseline =\n verticalAlign === \"center\"\n ? \"middle\"\n : verticalAlign === \"start\"\n ? \"top\"\n : verticalAlign === \"end\"\n ? \"bottom\"\n : verticalAlign;\n }\n const size = Rectangle.size(box);\n const t = this._textTruncate(txt, size[0], tail);\n this.text(this._textAlign(box, verticalAlign)!, t[0]);\n return this;\n }\n\n /**\n * Fit multi-line text in a rectangular box. Note that this will also set canvas context's textBaseline to \"top\".\n * @param box a Group or an Iterable<PtLike> with 2 Pt that represents a bounding box\n * @param txt string of text\n * @param lineHeight line height as a ratio of font size. Default is 1.2.\n * @param verticalAlign \"top\", \"middle\", or \"bottom\" to specify vertical alignment inside the box\n * @param crop a boolean to specify whether to crop text when overflowing\n */\n paragraphBox(\n box: PtLikeIterable,\n txt: string,\n lineHeight: number = 1.2,\n verticalAlign: TextVerticalAlign = \"top\",\n crop: boolean = true,\n ): this {\n const b = Group.fromArray(box);\n const size = Rectangle.size(b);\n this._ctx.textBaseline = \"top\"; // override textBaseline\n\n const lstep = this._font.size * lineHeight;\n\n // Seed each line's cut search with the previous line's fitted length, so\n // truncate probes near the boundary instead of measuring the whole\n // remainder (which made wrapping quadratic in text length). The first\n // line's seed is estimated from a single character sample.\n let hint = Math.ceil(size[0] / Math.max(1, this.getTextWidth(\"n\")));\n\n const lines: string[] = [];\n let sub = txt;\n while (sub) {\n // crop when the next line would no longer fit inside the box\n if (crop && (lines.length + 1) * lstep > size[1]) break;\n\n const t = this._textTruncate(sub, size[0], \"\", hint);\n if (t[1] > 0) hint = t[1];\n\n // new line\n const newln = t[0].indexOf(\"\\n\");\n if (newln >= 0) {\n lines.push(t[0].slice(0, newln));\n sub = sub.slice(newln + 1);\n continue;\n }\n\n // word wrap\n const consumedAll = t[1] === sub.length;\n let dt: number | undefined;\n if (consumedAll) {\n dt = undefined;\n } else if (sub[t[1]] === \" \") {\n // the line ends exactly at a word boundary: keep the whole line and\n // drop the space, instead of wrapping before its last word\n dt = t[1] + 1;\n } else {\n dt = t[0].lastIndexOf(\" \") + 1;\n if (dt <= 0) dt = undefined;\n }\n lines.push(dt === undefined ? t[0] : t[0].slice(0, dt));\n\n if (t[1] <= 0 || consumedAll) break;\n sub = sub.slice(dt ?? t[1]);\n }\n const lsize = lines.length * lstep; // total height\n let lbox = b;\n\n if (verticalAlign == \"middle\" || verticalAlign == \"center\") {\n let lpad = (size[1] - lsize) / 2;\n if (crop) lpad = Math.max(0, lpad);\n lbox = new Group(b[0].$add(0, lpad), b[1].$subtract(0, lpad));\n } else if (verticalAlign == \"bottom\") {\n lbox = new Group(b[0].$add(0, size[1] - lsize), b[1]);\n } else {\n lbox = new Group(b[0], b[0].$add(size[0], lsize));\n }\n\n const center = Rectangle.center(lbox);\n for (let i = 0, len = lines.length; i < len; i++) {\n this.text(\n this._textAlign(lbox, \"top\", [0, i * lstep], center)!,\n lines[i],\n );\n }\n\n return this;\n }\n\n /**\n * Set text alignment and baseline (eg, vertical-align).\n * @param alignment HTML canvas' textAlign option: \"left\", \"right\", \"center\", \"start\", or \"end\"\n * @param baseline HTML canvas' textBaseline option: \"top\", \"hanging\", \"middle\", \"alphabetic\", \"ideographic\", \"bottom\". For convenience, you can also use \"center\" (same as \"middle\"), and \"baseline\" (same as \"alphabetic\")\n */\n alignText(\n alignment: CanvasTextAlign = \"left\",\n baseline: CanvasTextBaseline = \"alphabetic\",\n ) {\n // @ts-expect-error legacy DOM lib types omit these vendor/optional members\n if (baseline == \"center\") baseline = \"middle\";\n // @ts-expect-error legacy DOM lib types omit these vendor/optional members\n if (baseline == \"baseline\") baseline = \"alphabetic\";\n this._ctx.textAlign = alignment;\n this._ctx.textBaseline = baseline;\n return this;\n }\n\n /**\n * A convenient way to draw some text on canvas for logging or debugging. It'll be draw on the top-left of the canvas as an overlay.\n * @param txt text\n */\n log(txt: any): this {\n const w = this._ctx.measureText(txt).width + 20;\n this.stroke(false)\n .fill(\"rgba(0,0,0,.4)\")\n .rect([\n [0, 0],\n [w, 20],\n ]);\n this.fill(\"#fff\").text([10, 14], txt);\n return this;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\n/**\n * Internal 2D Delaunay triangulation used by [`Delaunay`](#link).\n *\n * Points are inserted one at a time in Hilbert-curve order, so each point is\n * found by a short walk from the previous insertion. An insertion removes every\n * triangle whose circumcircle contains the point and fans the resulting cavity\n * from it (Bowyer–Watson). The convex hull is represented by ghost triangles\n * that share one vertex \"at infinity\", which lets hull growth use the same\n * cavity step as interior insertion and keeps every half-edge paired.\n *\n * Orientation and in-circle decisions are exact. A floating-point error\n * bound settles the easy cases; integer coordinates below 2^25 are resolved\n * with limb arithmetic in doubles; anything else is evaluated in BigInt from\n * the exact binary value of each coordinate. Exact decisions are what make\n * cocircular grids, collinear runs, points on edges, and duplicate points\n * safe: they can never produce a degenerate triangle or an endless walk.\n */\n\n/** A triangulation of the finite, distinct input points. */\nexport type Triangulation = {\n /** Point indices, three per triangle, counterclockwise. */\n triangles: Uint32Array;\n /**\n * For half-edge `h = 3t + e` (from `triangles[h]` to the triangle's next vertex),\n * the index of the opposite half-edge in the adjacent triangle, or -1 on the hull.\n */\n neighbors: Int32Array;\n /** Point indices of the convex hull, counterclockwise. Empty when there are no triangles. */\n hull: Uint32Array;\n};\n\nconst EMPTY: Triangulation = {\n triangles: new Uint32Array(0),\n neighbors: new Int32Array(0),\n hull: new Uint32Array(0),\n};\n\n// ---------------------------------------------------------------- predicates\n\n// 2^-53: half an ulp at 1, the rounding error of one double operation\nconst EPS = 1.1102230246251565e-16;\n// Bounds on the rounding error of the determinants below, relative to the sum\n// of the absolute values of their terms (the classic forward error analysis\n// of the orientation and in-circle determinants).\nconst ORIENT_BOUND = (3 + 16 * EPS) * EPS;\nconst INCIRCLE_BOUND = (10 + 96 * EPS) * EPS;\n// Coordinates that become integers below 2^31 when scaled by one power of two\n// (pixel grids, halves, quarters, every Float32 value in a sane range) keep\n// their differences exact in a double; the products those differences form are\n// then evaluated exactly in limb arithmetic without BigInt.\nconst INT_LIMIT = 2147483648;\nconst _input = new Float64Array(8);\n// the scale shared by every coordinate of the set being triangulated, when\n// one exists (set by `triangulate`); 0 means decide per call\nlet _presetScale = 0;\n\n/**\n * The smallest power of two that turns every value in `_input[0..count)` into\n * an integer below 2^31 in magnitude, or 0 when no scale up to 2^30 does.\n */\nfunction _integerScale(count: number): number {\n if (_presetScale > 0) return _presetScale;\n let scale = 1;\n for (let k = 0; k <= 30; k++) {\n let exact = true;\n for (let i = 0; i < count; i++) {\n const v = _input[i] * scale;\n if (v >= INT_LIMIT || v <= -INT_LIMIT) return 0; // scaling only grows\n if ((v | 0) !== v) exact = false;\n }\n if (exact) return scale;\n scale *= 2;\n }\n return 0;\n}\n\n/**\n * Orientation of `c` relative to the directed line `a → b`:\n * 1 when `c` is to the left (counterclockwise turn), -1 to the right, 0 when collinear.\n * The result is exact for any finite doubles.\n */\nexport function orient2d(\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n): number {\n const left = (ax - cx) * (by - cy);\n const right = (ay - cy) * (bx - cx);\n const det = left - right;\n const bound = ORIENT_BOUND * (Math.abs(left) + Math.abs(right));\n if (det > bound) return 1;\n if (-det > bound) return -1;\n _input[0] = ax;\n _input[1] = ay;\n _input[2] = bx;\n _input[3] = by;\n _input[4] = cx;\n _input[5] = cy;\n const scale = _integerScale(6);\n if (scale !== 0) {\n return _orientInt(\n (ax - cx) * scale,\n (by - cy) * scale,\n (ay - cy) * scale,\n (bx - cx) * scale,\n );\n }\n return orient2dExact(ax, ay, bx, by, cx, cy);\n}\n\n/**\n * In-circle test: 1 when `d` is strictly inside the circle through the\n * counterclockwise triangle `a, b, c`, -1 when outside, 0 when on the circle.\n * The result is exact for any finite doubles.\n */\nexport function incircle(\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n dx: number,\n dy: number,\n): number {\n const adx = ax - dx;\n const ady = ay - dy;\n const bdx = bx - dx;\n const bdy = by - dy;\n const cdx = cx - dx;\n const cdy = cy - dy;\n\n const bdxcdy = bdx * cdy;\n const cdxbdy = cdx * bdy;\n const alift = adx * adx + ady * ady;\n const cdxady = cdx * ady;\n const adxcdy = adx * cdy;\n const blift = bdx * bdx + bdy * bdy;\n const adxbdy = adx * bdy;\n const bdxady = bdx * ady;\n const clift = cdx * cdx + cdy * cdy;\n\n const det =\n alift * (bdxcdy - cdxbdy) +\n blift * (cdxady - adxcdy) +\n clift * (adxbdy - bdxady);\n const permanent =\n (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * alift +\n (Math.abs(cdxady) + Math.abs(adxcdy)) * blift +\n (Math.abs(adxbdy) + Math.abs(bdxady)) * clift;\n const bound = INCIRCLE_BOUND * permanent;\n if (det > bound) return 1;\n if (-det > bound) return -1;\n _input[0] = ax;\n _input[1] = ay;\n _input[2] = bx;\n _input[3] = by;\n _input[4] = cx;\n _input[5] = cy;\n _input[6] = dx;\n _input[7] = dy;\n const scale = _integerScale(8);\n if (scale !== 0) {\n return _incircleInt(\n adx * scale,\n ady * scale,\n bdx * scale,\n bdy * scale,\n cdx * scale,\n cdy * scale,\n );\n }\n return incircleExact(ax, ay, bx, by, cx, cy, dx, dy);\n}\n\n// ---- exact integer arithmetic on differences below 2^32, in base-2^18 limbs\n// held in doubles: a limb product is below 2^36 and no accumulated coefficient\n// reaches 2^41, so every operation is exact.\nconst LIMB = 262144;\nconst INV_LIMB = 1 / LIMB;\nconst _acc = new Float64Array(8);\nconst _liftA = new Float64Array(4);\nconst _liftB = new Float64Array(4);\nconst _liftC = new Float64Array(4);\nconst _crossA = new Float64Array(4);\nconst _crossB = new Float64Array(4);\nconst _crossC = new Float64Array(4);\n\n/** Add `sign * x * y` for non-negative integers x, y below 2^32 into `_acc[at..at+2]`. */\nfunction _mulAdd22(x: number, y: number, sign: number, at: number): void {\n const x0 = x & 0x3ffff;\n const x1 = x >>> 18;\n const y0 = y & 0x3ffff;\n const y1 = y >>> 18;\n _acc[at] += sign * x0 * y0;\n _acc[at + 1] += sign * (x0 * y1 + x1 * y0);\n _acc[at + 2] += sign * x1 * y1;\n}\n\n/** Add `sign * a * m` for four-limb non-negative numbers into `_acc[0..6]`. */\nfunction _mulAdd44(a: Float64Array, m: Float64Array, sign: number): void {\n for (let i = 0; i < 4; i++) {\n const ai = sign * a[i];\n if (ai === 0) continue;\n for (let j = 0; j < 4; j++) _acc[i + j] += ai * m[j];\n }\n}\n\n/** Carry-normalize `_acc[0..n)` to limbs in [0, LIMB); returns the signed final carry. */\nfunction _carry(n: number): number {\n let carry = 0;\n for (let k = 0; k < n; k++) {\n const v = _acc[k] + carry;\n carry = Math.floor(v * INV_LIMB); // exact: a power-of-two scale\n _acc[k] = v - carry * LIMB;\n }\n return carry;\n}\n\n/** Sign of the normalized accumulator: the carry decides, else any nonzero limb. */\nfunction _accSign(n: number, carry: number): number {\n if (carry !== 0) return carry > 0 ? 1 : -1;\n for (let k = 0; k < n; k++) if (_acc[k] !== 0) return 1;\n return 0;\n}\n\n/**\n * Write the magnitude of the normalized accumulator (n limbs plus carry) into\n * `out[0..n]` and return its sign. A negative value is complemented limb by limb.\n */\nfunction _magnitude(n: number, carry: number, out: Float64Array): number {\n if (carry >= 0) {\n let zero = carry === 0;\n for (let k = 0; k < n; k++) {\n out[k] = _acc[k];\n if (_acc[k] !== 0) zero = false;\n }\n out[n] = carry;\n return zero ? 0 : 1;\n }\n let up = 1;\n for (let k = 0; k < n; k++) {\n let m = LIMB - 1 - _acc[k] + up;\n up = 0;\n if (m === LIMB) {\n m = 0;\n up = 1;\n }\n out[k] = m;\n }\n out[n] = -carry - 1 + up;\n return -1;\n}\n\n/** Sign of `a * b - c * d` for integers below 2^32 in magnitude. */\nfunction _orientInt(a: number, b: number, c: number, d: number): number {\n _acc[0] = 0;\n _acc[1] = 0;\n _acc[2] = 0;\n _mulAdd22(Math.abs(a), Math.abs(b), a < 0 !== b < 0 ? -1 : 1, 0);\n _mulAdd22(Math.abs(c), Math.abs(d), c < 0 !== d < 0 ? 1 : -1, 0);\n return _accSign(3, _carry(3));\n}\n\n/** `dx² + dy²` as four limbs. */\nfunction _lift(dx: number, dy: number, out: Float64Array): void {\n _acc[0] = 0;\n _acc[1] = 0;\n _acc[2] = 0;\n _mulAdd22(Math.abs(dx), Math.abs(dx), 1, 0);\n _mulAdd22(Math.abs(dy), Math.abs(dy), 1, 0);\n const carry = _carry(3);\n out[0] = _acc[0];\n out[1] = _acc[1];\n out[2] = _acc[2];\n out[3] = carry;\n}\n\n/** Sign of `p * q - r * t`, with its magnitude written as four limbs. */\nfunction _cross(\n p: number,\n q: number,\n r: number,\n t: number,\n out: Float64Array,\n): number {\n _acc[0] = 0;\n _acc[1] = 0;\n _acc[2] = 0;\n _mulAdd22(Math.abs(p), Math.abs(q), p < 0 !== q < 0 ? -1 : 1, 0);\n _mulAdd22(Math.abs(r), Math.abs(t), r < 0 !== t < 0 ? 1 : -1, 0);\n return _magnitude(3, _carry(3), out);\n}\n\n/** Exact in-circle sign from integer differences below 2^32 in magnitude. */\nfunction _incircleInt(\n adx: number,\n ady: number,\n bdx: number,\n bdy: number,\n cdx: number,\n cdy: number,\n): number {\n _lift(adx, ady, _liftA);\n _lift(bdx, bdy, _liftB);\n _lift(cdx, cdy, _liftC);\n const sa = _cross(bdx, cdy, cdx, bdy, _crossA);\n const sb = _cross(cdx, ady, adx, cdy, _crossB);\n const sc = _cross(adx, bdy, bdx, ady, _crossC);\n for (let k = 0; k < 7; k++) _acc[k] = 0;\n if (sa !== 0) _mulAdd44(_liftA, _crossA, sa);\n if (sb !== 0) _mulAdd44(_liftB, _crossB, sb);\n if (sc !== 0) _mulAdd44(_liftC, _crossC, sc);\n return _accSign(7, _carry(7));\n}\n\n// Exact evaluation: each double is sign * mantissa * 2^exponent with an\n// integer mantissa, so scaling every input to the smallest exponent gives\n// exact integers whose determinant has the same sign as the real one.\nconst _bits = new Float64Array(1);\nconst _words = new Uint32Array(_bits.buffer);\n_bits[0] = 1;\nconst HI = _words[1] === 0x3ff00000 ? 1 : 0;\nconst LO = HI ^ 1;\nconst _mant = new Float64Array(8);\nconst _expo = new Int32Array(8);\n// BigInt is only touched inside the exact fallback, so loading this module\n// never requires it\n\nfunction _scaled(values: Float64Array, count: number): bigint[] {\n let minExpo = 0x7fffffff;\n for (let i = 0; i < count; i++) {\n _bits[0] = values[i];\n const hi = _words[HI];\n const biased = (hi >>> 20) & 0x7ff;\n let m = (hi & 0xfffff) * 4294967296 + _words[LO];\n let e = -1074; // subnormal: the fraction is the mantissa\n if (biased !== 0) {\n m += 4503599627370496; // implicit leading bit\n e = biased - 1075;\n }\n _mant[i] = hi >>> 31 ? -m : m;\n _expo[i] = e;\n if (m !== 0 && e < minExpo) minExpo = e;\n }\n const out: bigint[] = [];\n for (let i = 0; i < count; i++) {\n out.push(\n _mant[i] === 0\n ? BigInt(0)\n : BigInt(_mant[i]) << BigInt(_expo[i] - minExpo),\n );\n }\n return out;\n}\n\n/** Exact orientation, evaluated in BigInt. Used when the fast filter cannot decide. */\nexport function orient2dExact(\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n): number {\n _input[0] = ax;\n _input[1] = ay;\n _input[2] = bx;\n _input[3] = by;\n _input[4] = cx;\n _input[5] = cy;\n const s = _scaled(_input, 6);\n const det = (s[0] - s[4]) * (s[3] - s[5]) - (s[1] - s[5]) * (s[2] - s[4]);\n const zero = BigInt(0);\n return det > zero ? 1 : det < zero ? -1 : 0;\n}\n\n/** Exact in-circle test, evaluated in BigInt. Used when the fast filter cannot decide. */\nexport function incircleExact(\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n dx: number,\n dy: number,\n): number {\n _input[0] = ax;\n _input[1] = ay;\n _input[2] = bx;\n _input[3] = by;\n _input[4] = cx;\n _input[5] = cy;\n _input[6] = dx;\n _input[7] = dy;\n const s = _scaled(_input, 8);\n const adx = s[0] - s[6];\n const ady = s[1] - s[7];\n const bdx = s[2] - s[6];\n const bdy = s[3] - s[7];\n const cdx = s[4] - s[6];\n const cdy = s[5] - s[7];\n const det =\n (adx * adx + ady * ady) * (bdx * cdy - cdx * bdy) +\n (bdx * bdx + bdy * bdy) * (cdx * ady - adx * cdy) +\n (cdx * cdx + cdy * cdy) * (adx * bdy - bdx * ady);\n const zero = BigInt(0);\n return det > zero ? 1 : det < zero ? -1 : 0;\n}\n\n// ----------------------------------------------------------- insertion order\n\n/** Distance along a Hilbert curve of order `order` for grid cell (x, y). */\nexport function hilbertIndex(order: number, x: number, y: number): number {\n const n = 1 << order;\n let d = 0;\n for (let s = n >> 1; s > 0; s >>= 1) {\n const rx = (x & s) !== 0 ? 1 : 0;\n const ry = (y & s) !== 0 ? 1 : 0;\n d += s * s * ((3 * rx) ^ ry);\n if (ry === 0) {\n if (rx === 1) {\n x = n - 1 - x;\n y = n - 1 - y;\n }\n const t = x;\n x = y;\n y = t;\n }\n }\n return d;\n}\n\n/**\n * Point indices sorted along a Hilbert curve over the bounding box, ties (and\n * duplicate points) in index order. Non-finite points sort with the origin cell.\n */\nexport function hilbertOrder(\n coords: ArrayLike<number>,\n n: number,\n): Uint32Array {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (let i = 0; i < n; i++) {\n const x = coords[2 * i];\n const y = coords[2 * i + 1];\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue;\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n }\n // about sixteen cells per point is fine enough for locality; the order is\n // capped so keys stay within 32 bits\n let order = 2;\n while (order < 16 && 1 << (2 * order) < 16 * n) order++;\n const cells = (1 << order) - 1;\n const span = Math.max(maxX - minX, maxY - minY);\n const scale = span > 0 && Number.isFinite(span) ? cells / span : 0;\n\n const keys = new Uint32Array(n);\n for (let i = 0; i < n; i++) {\n const x = coords[2 * i];\n const y = coords[2 * i + 1];\n let gx = 0;\n let gy = 0;\n if (Number.isFinite(x) && Number.isFinite(y)) {\n gx = Math.min(cells, Math.max(0, Math.floor((x - minX) * scale)));\n gy = Math.min(cells, Math.max(0, Math.floor((y - minY) * scale)));\n }\n keys[i] = hilbertIndex(order, gx, gy);\n }\n\n // stable least-significant-digit radix sort, one byte per pass, over the\n // bytes the keys actually use\n let from = new Uint32Array(n);\n let to = new Uint32Array(n);\n for (let i = 0; i < n; i++) from[i] = i;\n const counts = new Int32Array(257);\n for (let shift = 0; shift < 2 * order; shift += 8) {\n counts.fill(0);\n for (let i = 0; i < n; i++) counts[((keys[i] >>> shift) & 255) + 1]++;\n for (let b = 0; b < 256; b++) counts[b + 1] += counts[b];\n for (let i = 0; i < n; i++) {\n const p = from[i];\n to[counts[(keys[p] >>> shift) & 255]++] = p;\n }\n const swap = from;\n from = to;\n to = swap;\n }\n return from;\n}\n\n// ------------------------------------------------------------- triangulation\n\n/**\n * Delaunay-triangulate points given as a flat `[x0, y0, x1, y1, ...]` array.\n * Duplicate points and points with non-finite coordinates are left out; the\n * lowest index of a duplicate is the one used. Returns no triangles when\n * fewer than three distinct, non-collinear points exist.\n * @param coords flat coordinates\n * @param n number of points; defaults to half the array length\n */\nexport function triangulate(\n coords: Float64Array,\n n: number = coords.length >> 1,\n): Triangulation {\n if (n < 3) return EMPTY;\n _presetScale = sharedScale(coords, n);\n try {\n return _triangulate(coords, n);\n } finally {\n _presetScale = 0;\n }\n}\n\n/**\n * The smallest power of two that makes every finite coordinate an integer\n * below 2^31 in magnitude, or 0 when there is none. Float32 values (every Pt)\n * always have one in a sane coordinate range.\n */\nexport function sharedScale(coords: ArrayLike<number>, n: number): number {\n let bits = 0;\n let max = 0;\n for (let i = 0; i < 2 * n; i++) {\n const v = coords[i];\n if (!Number.isFinite(v)) continue;\n if (v === 0) continue;\n if (Math.abs(v) > max) max = Math.abs(v);\n _bits[0] = v;\n const hi = _words[HI];\n const lo = _words[LO];\n const biased = (hi >>> 20) & 0x7ff;\n // v = m * 2^e with an integer m; trailing zero bits of m move into e\n const e = biased === 0 ? -1074 : biased - 1075;\n let trailing: number;\n if (lo !== 0) {\n trailing = 31 - Math.clz32(lo & -lo);\n } else {\n const m = (hi & 0xfffff) | (biased === 0 ? 0 : 0x100000);\n trailing = 32 + (31 - Math.clz32(m & -m));\n }\n const fractional = -(e + trailing);\n if (fractional > bits) bits = fractional;\n if (bits > 30) return 0;\n }\n const scale = Math.pow(2, bits);\n return max * scale < INT_LIMIT ? scale : 0;\n}\n\nfunction _triangulate(coords: Float64Array, n: number): Triangulation {\n const order = hilbertOrder(coords, n);\n\n // the first three non-collinear distinct points seed the triangulation\n let i0 = -1;\n let i1 = -1;\n let i2 = -1;\n let k = 0;\n for (; k < n; k++) {\n const i = order[k];\n if (Number.isFinite(coords[2 * i]) && Number.isFinite(coords[2 * i + 1])) {\n i0 = i;\n k++;\n break;\n }\n }\n if (i0 < 0) return EMPTY;\n for (; k < n; k++) {\n const i = order[k];\n const x = coords[2 * i];\n const y = coords[2 * i + 1];\n if (\n Number.isFinite(x) &&\n Number.isFinite(y) &&\n (x !== coords[2 * i0] || y !== coords[2 * i0 + 1])\n ) {\n i1 = i;\n k++;\n break;\n }\n }\n if (i1 < 0) return EMPTY;\n for (; k < n; k++) {\n const i = order[k];\n const x = coords[2 * i];\n const y = coords[2 * i + 1];\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue;\n const o = orient2d(\n coords[2 * i0],\n coords[2 * i0 + 1],\n coords[2 * i1],\n coords[2 * i1 + 1],\n x,\n y,\n );\n if (o !== 0) {\n i2 = i;\n if (o < 0) {\n const swap = i1;\n i1 = i2;\n i2 = swap;\n }\n break;\n }\n }\n if (i2 < 0) return EMPTY; // every point is on one line\n\n // Triangles are stored as vertex triples with their twin half-edges. Ghost\n // triangles carry the infinite vertex INF in slot 2; their slot-0 → slot-1\n // edge is a hull edge traversed with the outside on the left.\n const INF = n;\n const capacity = 2 * n + 4;\n const tv = new Int32Array(capacity * 3);\n const adj = new Int32Array(capacity * 3);\n const live = new Uint8Array(capacity);\n const mark = new Int32Array(capacity);\n const freed = new Int32Array(capacity);\n let freedCount = 0;\n let triCount = 0;\n const stack = new Int32Array(capacity);\n const cavity = new Int32Array(capacity);\n const edgeFrom = new Int32Array(capacity * 3);\n const edgeTo = new Int32Array(capacity * 3);\n const edgeTwin = new Int32Array(capacity * 3);\n const toPoint = new Int32Array(n + 1);\n const fromPoint = new Int32Array(n + 1);\n let stamp = 0;\n\n const alloc = (a: number, b: number, c: number): number => {\n const t = freedCount > 0 ? freed[--freedCount] : triCount++;\n const h = 3 * t;\n tv[h] = a;\n tv[h + 1] = b;\n tv[h + 2] = c;\n live[t] = 1;\n return t;\n };\n const link = (h: number, g: number): void => {\n adj[h] = g;\n adj[g] = h;\n };\n\n // first triangle and its three ghosts\n const t0 = alloc(i0, i1, i2);\n const g0 = alloc(i1, i0, INF);\n const g1 = alloc(i2, i1, INF);\n const g2 = alloc(i0, i2, INF);\n link(3 * t0, 3 * g0);\n link(3 * t0 + 1, 3 * g1);\n link(3 * t0 + 2, 3 * g2);\n link(3 * g0 + 1, 3 * g2 + 2);\n link(3 * g1 + 1, 3 * g0 + 2);\n link(3 * g2 + 1, 3 * g1 + 2);\n\n // Whether p lies in the \"circumdisk\" of ghost g: strictly outside its hull\n // edge u → v, or on the open segment between u and v.\n const inGhostDisk = (g: number, px: number, py: number): boolean => {\n const u = tv[3 * g];\n const v = tv[3 * g + 1];\n const ux = coords[2 * u];\n const uy = coords[2 * u + 1];\n const vx = coords[2 * v];\n const vy = coords[2 * v + 1];\n const o = orient2d(ux, uy, vx, vy, px, py);\n if (o !== 0) return o > 0;\n // collinear: strictly between the endpoints along the wider axis\n return Math.abs(vx - ux) >= Math.abs(vy - uy)\n ? vx > ux\n ? px > ux && px < vx\n : px < ux && px > vx\n : vy > uy\n ? py > uy && py < vy\n : py < uy && py > vy;\n };\n\n // Whether p is inside the circumdisk of triangle t (for a ghost: its\n // outer half-plane plus the open hull edge). Vertices are never inside.\n const inDisk = (t: number, px: number, py: number): boolean => {\n const h = 3 * t;\n if (tv[h + 2] === INF) return inGhostDisk(t, px, py);\n const a = tv[h];\n const b = tv[h + 1];\n const c = tv[h + 2];\n return (\n incircle(\n coords[2 * a],\n coords[2 * a + 1],\n coords[2 * b],\n coords[2 * b + 1],\n coords[2 * c],\n coords[2 * c + 1],\n px,\n py,\n ) > 0\n );\n };\n\n // Walk from triangle t to a triangle whose circumdisk contains p. Returns\n // -1 when p coincides with an existing vertex. The walk always starts from a\n // finite triangle and enters a ghost only across a hull edge that p lies\n // strictly outside of; a ghost reached any other way (p collinear with its\n // edge, or inside the hull) hands the walk back to the finite side, which\n // then locates p or crosses the right hull edge.\n const locate = (t: number, px: number, py: number): number => {\n let steps = 0;\n const limit = 4 * triCount + 64;\n while (true) {\n const h = 3 * t;\n const a = tv[h];\n const b = tv[h + 1];\n const c = tv[h + 2];\n const ax = coords[2 * a];\n const ay = coords[2 * a + 1];\n const bx = coords[2 * b];\n const by = coords[2 * b + 1];\n if (c === INF) {\n if (orient2d(ax, ay, bx, by, px, py) > 0) return t;\n t = (adj[h] / 3) | 0;\n } else {\n const cx = coords[2 * c];\n const cy = coords[2 * c + 1];\n if (orient2d(ax, ay, bx, by, px, py) < 0) {\n t = (adj[h] / 3) | 0;\n } else if (orient2d(bx, by, cx, cy, px, py) < 0) {\n t = (adj[h + 1] / 3) | 0;\n } else if (orient2d(cx, cy, ax, ay, px, py) < 0) {\n t = (adj[h + 2] / 3) | 0;\n } else if (\n (px === ax && py === ay) ||\n (px === bx && py === by) ||\n (px === cx && py === cy)\n ) {\n return -1;\n } else {\n return t;\n }\n }\n // the visibility walk terminates on a Delaunay triangulation; never spin\n if (++steps > limit) throw new Error(\"Delaunay walk did not terminate\");\n }\n };\n\n const insert = (p: number, start: number): number => {\n const px = coords[2 * p];\n const py = coords[2 * p + 1];\n const t = locate(start, px, py);\n if (t < 0) return start; // p is an existing vertex\n\n // the cavity: every triangle whose circumdisk contains p, by adjacency\n stamp++;\n let top = 0;\n let count = 0;\n stack[top++] = t;\n mark[t] = stamp;\n while (top > 0) {\n const s = stack[--top];\n cavity[count++] = s;\n const h = 3 * s;\n for (let e = 0; e < 3; e++) {\n const o = (adj[h + e] / 3) | 0;\n if (mark[o] !== stamp && inDisk(o, px, py)) {\n mark[o] = stamp;\n stack[top++] = o;\n }\n }\n }\n\n // its boundary: cavity half-edges whose twin lies outside the cavity,\n // recorded by vertex before the cavity's slots are recycled\n let edges = 0;\n for (let i = 0; i < count; i++) {\n const h = 3 * cavity[i];\n for (let e = 0; e < 3; e++) {\n const twin = adj[h + e];\n if (mark[(twin / 3) | 0] !== stamp) {\n edgeFrom[edges] = tv[h + e];\n edgeTo[edges] = tv[h + ((e + 1) % 3)];\n edgeTwin[edges] = twin;\n edges++;\n }\n }\n }\n for (let i = 0; i < count; i++) {\n live[cavity[i]] = 0;\n freed[freedCount++] = cavity[i];\n }\n\n // fan the cavity: one triangle (u, v, p) per boundary edge u → v, with\n // the infinite vertex kept in slot 2\n let first = -1;\n for (let i = 0; i < edges; i++) {\n const u = edgeFrom[i];\n const v = edgeTo[i];\n let t2: number;\n let hEdge: number;\n let hToP: number;\n let hFromP: number;\n if (u === INF) {\n t2 = alloc(v, p, INF);\n hEdge = 3 * t2 + 2;\n hToP = 3 * t2;\n hFromP = 3 * t2 + 1;\n } else if (v === INF) {\n t2 = alloc(p, u, INF);\n hEdge = 3 * t2 + 1;\n hToP = 3 * t2 + 2;\n hFromP = 3 * t2;\n } else {\n t2 = alloc(u, v, p);\n hEdge = 3 * t2;\n hToP = 3 * t2 + 1;\n hFromP = 3 * t2 + 2;\n if (first < 0) first = t2;\n }\n link(hEdge, edgeTwin[i]);\n toPoint[v] = hToP;\n fromPoint[u] = hFromP;\n }\n for (let i = 0; i < edges; i++) {\n const v = edgeTo[i];\n link(toPoint[v], fromPoint[v]);\n }\n return first < 0 ? start : first;\n };\n\n let last = t0;\n for (let j = 0; j < n; j++) {\n const i = order[j];\n if (i === i0 || i === i1 || i === i2) continue;\n if (!Number.isFinite(coords[2 * i]) || !Number.isFinite(coords[2 * i + 1]))\n continue;\n last = insert(i, last);\n }\n\n // compact the finite triangles and renumber their adjacency\n const index = new Int32Array(triCount);\n let m = 0;\n let ghost = -1;\n for (let t = 0; t < triCount; t++) {\n if (!live[t]) {\n index[t] = -1;\n } else if (tv[3 * t + 2] === INF) {\n index[t] = -1;\n ghost = t;\n } else {\n index[t] = m++;\n }\n }\n const triangles = new Uint32Array(m * 3);\n const neighbors = new Int32Array(m * 3);\n for (let t = 0; t < triCount; t++) {\n const k2 = index[t];\n if (k2 < 0) continue;\n for (let e = 0; e < 3; e++) {\n triangles[3 * k2 + e] = tv[3 * t + e];\n const o = adj[3 * t + e];\n const ot = index[(o / 3) | 0];\n neighbors[3 * k2 + e] = ot < 0 ? -1 : 3 * ot + (o % 3);\n }\n }\n // the hull, counterclockwise, by walking the ring of ghosts\n let hullCount = 0;\n let g = ghost;\n do {\n hullCount++;\n g = (adj[3 * g + 2] / 3) | 0;\n } while (g !== ghost);\n const hull = new Uint32Array(hullCount);\n g = ghost;\n for (let i = 0; i < hullCount; i++) {\n hull[i] = tv[3 * g + 1];\n g = (adj[3 * g + 2] / 3) | 0;\n }\n return { triangles, neighbors, hull };\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Group, type Bound } from \"./Pt\";\nimport { Line, Triangle } from \"./Op\";\nimport { Const, Util } from \"./Util\";\nimport { Num, Geom } from \"./Num\";\nimport { triangulate, type Triangulation } from \"./_triangulate\";\nimport {\n type PtLike,\n type PtLikeIterable,\n type GroupLike,\n type PtIterable,\n type DelaunayMesh,\n type DelaunayShape,\n type FlockBoundary,\n type FlockOptions,\n} from \"./Types\";\n\n/**\n * The `Create` class helps you create structures from sets of points.\n */\nexport class Create {\n /**\n * Create a set of random points inside a bounday.\n * @param bound the rectangular boundary\n * @param count number of random points to create\n * @param dimensions number of dimensions in each point\n */\n static distributeRandom(\n bound: Bound,\n count: number,\n dimensions: number = 2,\n ): Group {\n let pts = new Group();\n for (let i = 0; i < count; i++) {\n let p = [bound.x! + Num.random() * bound.width];\n if (dimensions > 1) p.push(bound.y! + Num.random() * bound.height);\n if (dimensions > 2) p.push(bound.z! + Num.random() * bound.depth);\n pts.push(new Pt(p));\n }\n return pts;\n }\n\n /**\n * Create a set of points that distribute evenly on a line. Similar to [`Line.subpoints`](#link) but includes the end points.\n * @param line a Group or an Iterable<Pt> representing a line\n * @param count number of points to create\n */\n static distributeLinear(line: PtIterable, count: number): Group {\n if (count <= 0) return new Group();\n let _line = Util.iterToArray(line);\n if (count === 1) return new Group(_line[0]);\n let ln = Line.subpoints(_line, count - 2);\n ln.unshift(_line[0]);\n ln.push(_line[_line.length - 1]);\n return ln;\n }\n\n /**\n * Create an evenly distributed set of points (like a grid of points) inside a boundary.\n * @param bound the rectangular boundary\n * @param columns number of columns\n * @param rows number of rows\n * @param orientation a Pt or number array to specify where the point should be inside a cell. Default is [0.5, 0.5] which places the point in the middle.\n * @returns a Group of Pts\n */\n static gridPts(\n bound: Bound,\n columns: number,\n rows: number,\n orientation: PtLike = [0.5, 0.5],\n ): Group {\n if (columns === 0 || rows === 0)\n throw new Error(\"grid columns and rows cannot be 0\");\n let unit = bound.size.$subtract(1).$divide(columns, rows);\n let offset = unit.$multiply(orientation);\n let g = new Group();\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < columns; c++) {\n g.push(bound.topLeft.$add(unit.$multiply(c, r)).add(offset));\n }\n }\n return g;\n }\n\n /**\n * Create a grid of cells inside a boundary, where each cell is defined by a group of 2 Pt.\n * @param bound the rectangular boundary\n * @param columns number of columns\n * @param rows number of rows\n * @returns an array of Groups, where each group represents a rectangular cell\n */\n static gridCells(bound: Bound, columns: number, rows: number): Group[] {\n if (columns === 0 || rows === 0)\n throw new Error(\"grid columns and rows cannot be 0\");\n let unit = bound.size.$subtract(1).divide(columns, rows); // subtract 1 to fill whole border of rectangles\n let g = [];\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < columns; c++) {\n g.push(\n new Group(\n bound.topLeft.$add(unit.$multiply(c, r)),\n bound.topLeft.$add(unit.$multiply(c, r).add(unit)),\n ),\n );\n }\n }\n return g;\n }\n\n /**\n * Create a set of Pts around a circular path.\n * @param center circle center\n * @param radius circle radius\n * @param count number of Pts to create\n * @param angleOffset offset starting angle\n */\n static radialPts(\n center: PtLike,\n radius: number,\n count: number,\n angleOffset: number = -Const.half_pi,\n ): Group {\n let g = new Group();\n let a = Const.two_pi / count;\n for (let i = 0; i < count; i++) {\n g.push(new Pt(center).toAngle(a * i + angleOffset, radius, true));\n }\n return g;\n }\n\n /**\n * Given a group of Pts, return a new group of `Noise` Pts.\n * @param pts a Group or an Iterable<Pt>, in row-major order when treated as a grid\n * @param dx small increment value in x dimension\n * @param dy small increment value in y dimension\n * @param rows Optional row count to generate 2D noise\n * @param columns Optional column count (points per row) to generate 2D noise. When provided, each point's noise offset is (dx·column, dy·row) with row = floor(i/columns); when only `rows` is provided it is used as the points-per-row divisor instead.\n */\n static noisePts(\n pts: PtIterable,\n dx = 0.01,\n dy = 0.01,\n rows = 0,\n columns = 0,\n ): Group {\n let seed = Num.random();\n let g = new Group();\n let i = 0;\n // row-major grid: one consistent per-row divisor for both row and column\n const perRow = columns > 0 ? columns : rows > 0 ? rows : 0;\n for (let p of pts) {\n let np = new Noise(p);\n let r = perRow > 0 ? Math.floor(i / perRow) : i;\n let c = perRow > 0 ? i % perRow : i;\n np.initNoise(dx * c, dy * r);\n np.seed(seed);\n g.push(np);\n i++;\n }\n return g;\n }\n\n /**\n * Create a Delaunay Group. Use the [`Delaunay.delaunay()`](#link) and [`Delaunay.voronoi()`](#link) functions in the returned group to generate tessellations.\n * @param pts a Group or an array of Pts\n * @returns an instance of the Delaunay class\n */\n static delaunay(pts: GroupLike): Delaunay {\n return Delaunay.from(pts) as Delaunay;\n }\n\n /**\n * Create a [`Flock`](#link) of [`Boid`](#link) agents that simulate flocking (also known as \"boids\"),\n * where each agent steers by three local rules: separation, alignment, and cohesion.\n * Advance the simulation by calling [`Flock.step`](#link) with the elapsed time.\n * See a [flocking demo here](https://ptsjs.org/demo/?name=create.flock).\n *\n * Each agent starts with a random heading, drawn from [`Num.random`](#link), so seeding with\n * [`Num.seed`](#link) makes a flock reproducible.\n *\n * @param pts a Group or an Iterable<Pt> of starting positions\n * @param options optional [`FlockOptions`](#link) to tune the behavior\n * @returns an instance of the Flock class, which is a Group of Boids\n * @example `Create.flock( Create.distributeRandom( space.innerBound, 200 ), { bound: space.innerBound } )`\n */\n static flock(pts: PtLikeIterable, options: FlockOptions = {}): Flock {\n const flock = new Flock();\n flock.setup(options);\n for (const p of pts) flock.addBoid(p);\n return flock;\n }\n}\n\n/**\n * Perlin noise gradient indices\n */\nconst __noise_grad3 = [\n [1, 1, 0],\n [-1, 1, 0],\n [1, -1, 0],\n [-1, -1, 0],\n [1, 0, 1],\n [-1, 0, 1],\n [1, 0, -1],\n [-1, 0, -1],\n [0, 1, 1],\n [0, -1, 1],\n [0, 1, -1],\n [0, -1, -1],\n];\n\n/**\n * Perlin noise permutation table\n */\nconst __noise_permTable = [\n 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140,\n 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234,\n 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237,\n 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48,\n 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105,\n 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73,\n 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86,\n 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38,\n 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189,\n 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101,\n 155, 167, 43, 172, 9, 129, 22, 39, 253, 9, 98, 108, 110, 79, 113, 224, 232,\n 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12,\n 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31,\n 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254,\n 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215,\n 61, 156, 180,\n];\n\n// The doubled base permutation table, built once and shared by every unseeded\n// Noise instance (a per-instance copy would allocate 512 entries per point in\n// `Create.noisePts`). `seed()` swaps in a seeded table instead of mutating.\nconst __noise_permDoubled = __noise_permTable.concat(__noise_permTable);\n\n// Memoize the last seeded table: `Create.noisePts` seeds every point with the\n// same value, so all its Noise Pts share one table.\nlet __noise_lastSeed: number | undefined = undefined;\nlet __noise_lastPerm: number[] | null = null;\n\nfunction __noise_seededPerm(seed: number): number[] {\n if (seed === __noise_lastSeed && __noise_lastPerm) return __noise_lastPerm;\n\n let s = seed;\n if (s > 0 && s < 1) s *= 65536;\n s = Math.floor(s);\n if (s < 256) s |= s << 8;\n\n const perm = new Array<number>(512);\n for (let i = 0; i < 256; i++) {\n const v =\n i & 1\n ? __noise_permTable[i] ^ (s & 255)\n : __noise_permTable[i] ^ ((s >> 8) & 255);\n perm[i] = perm[i + 256] = v;\n }\n\n __noise_lastSeed = seed;\n __noise_lastPerm = perm;\n return perm;\n}\n\n/**\n * Noise is a subclass of Pt that generates Perlin noise. Current implementation supports basic 2D noise.\n * This implementation is based on this [gist](https://gist.github.com/banksean/304522).\n */\nexport class Noise extends Pt {\n protected perm: number[] = [];\n private _n: Pt = new Pt(0.01, 0.01);\n\n /**\n * Create a Noise Pt that can generate noise continuously. See a [Noise demo here](https://ptsjs.org/demo/?name=create.noisePts).\n * @param args a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n constructor(...args: any[]) {\n super(...args);\n\n // shared doubled table for easy index wrapping; replaced by seed()\n this.perm = __noise_permDoubled;\n }\n\n /**\n * Set the initial dimensional values of the noise.\n * @param args a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n * @example `noise.initNoise( 0.01, 0.1 )`\n */\n initNoise(...args: any[]) {\n this._n = new Pt(...args);\n return this;\n }\n\n /**\n * Add a small increment to the noise values.\n * @param x step in x dimension\n * @param y step in y dimension\n */\n step(x = 0, y = 0) {\n this._n.add(x, y);\n return this;\n }\n\n /**\n * Specify a seed for this Noise.\n * @param s seed value\n */\n seed(s: number) {\n this.perm = __noise_seededPerm(s);\n return this;\n }\n\n /**\n * Generate a 2D Perlin noise value.\n */\n noise2D() {\n const perm = this.perm;\n const nx = this._n[0];\n const ny = this._n[1];\n\n // integer cell (wrapped to the table via two's-complement &, which also\n // handles negative coordinates seamlessly) and the position within it\n const cx = Math.floor(nx);\n const cy = Math.floor(ny);\n const i = cx & 255;\n const j = cy & 255;\n const x = nx - cx;\n const y = ny - cy;\n\n // standard Perlin gradient hashing through the permutation table; the\n // doubled table makes i + perm[j + 1] safe without extra wrapping\n const g00 = __noise_grad3[perm[i + perm[j]] % 12];\n const g01 = __noise_grad3[perm[i + perm[j + 1]] % 12];\n const g10 = __noise_grad3[perm[i + 1 + perm[j]] % 12];\n const g11 = __noise_grad3[perm[i + 1 + perm[j + 1]] % 12];\n\n const n00 = g00[0] * x + g00[1] * y;\n const n01 = g01[0] * x + g01[1] * (y - 1);\n const n10 = g10[0] * (x - 1) + g10[1] * y;\n const n11 = g11[0] * (x - 1) + g11[1] * (y - 1);\n\n const _fade = (f: number) => f * f * f * (f * (f * 6 - 15) + 10);\n const tx = _fade(x);\n const u = n00 + tx * (n10 - n00);\n const v = n01 + tx * (n11 - n01);\n return u + _fade(y) * (v - u);\n }\n}\n\n/**\n * Clip a convex cell polygon against an axis-aligned rectangle\n * (Sutherland–Hodgman). Returns the input Group unchanged (shared Pt\n * references) when every vertex is already inside.\n */\nfunction _clipCellToRect(\n cell: Group,\n x0: number,\n y0: number,\n x1: number,\n y1: number,\n): Group {\n // fast path: fully inside\n let inside = true;\n for (let i = 0, len = cell.length; i < len; i++) {\n const px = cell[i][0];\n const py = cell[i][1];\n if (px < x0 || px > x1 || py < y0 || py > y1 || !Number.isFinite(px + py)) {\n inside = false;\n break;\n }\n }\n if (inside) return cell;\n\n // degenerate hull fragments (1-2 vertices) cannot form a polygon to clip;\n // keep only their in-bound vertices\n if (cell.length < 3) {\n const kept = new Group();\n for (let i = 0, len = cell.length; i < len; i++) {\n const px = cell[i][0];\n const py = cell[i][1];\n if (px >= x0 && px <= x1 && py >= y0 && py <= y1) kept.push(cell[i]);\n }\n return kept;\n }\n\n // clamp non-finite coordinates so intersection math stays finite\n const big = 1e7;\n let pts: number[][] = [];\n for (let i = 0, len = cell.length; i < len; i++) {\n let px = cell[i][0];\n let py = cell[i][1];\n if (!Number.isFinite(px)) px = px > 0 ? big : -big;\n if (!Number.isFinite(py)) py = py > 0 ? big : -big;\n if (Number.isNaN(px) || Number.isNaN(py)) continue;\n pts.push([px, py]);\n }\n\n // clip against each rect edge: keep(p) tests inside, cross(a,b) intersects\n const clip = (\n input: number[][],\n keep: (p: number[]) => boolean,\n cross: (a: number[], b: number[]) => number[],\n ): number[][] => {\n const output: number[][] = [];\n for (let i = 0, len = input.length; i < len; i++) {\n const a = input[i === 0 ? len - 1 : i - 1];\n const b = input[i];\n const keepB = keep(b);\n if (keep(a)) {\n if (keepB) output.push(b);\n else output.push(cross(a, b));\n } else if (keepB) {\n output.push(cross(a, b), b);\n }\n }\n return output;\n };\n\n const lerpAt = (a: number[], b: number[], t: number): number[] => [\n a[0] + (b[0] - a[0]) * t,\n a[1] + (b[1] - a[1]) * t,\n ];\n\n pts = clip(\n pts,\n (p) => p[0] >= x0,\n (a, b) => lerpAt(a, b, (x0 - a[0]) / (b[0] - a[0])),\n );\n pts = clip(\n pts,\n (p) => p[0] <= x1,\n (a, b) => lerpAt(a, b, (x1 - a[0]) / (b[0] - a[0])),\n );\n pts = clip(\n pts,\n (p) => p[1] >= y0,\n (a, b) => lerpAt(a, b, (y0 - a[1]) / (b[1] - a[1])),\n );\n pts = clip(\n pts,\n (p) => p[1] <= y1,\n (a, b) => lerpAt(a, b, (y1 - a[1]) / (b[1] - a[1])),\n );\n\n const out = new Group();\n for (let i = 0, len = pts.length; i < len; i++) {\n out.push(new Pt(pts[i]));\n }\n return out;\n}\n\n/** Keep the part of a convex cell nearer to site a than site b. */\nfunction _clipCellToBisector(cell: Group, a: Pt, b: Pt): Group {\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const mx = a[0] + dx / 2;\n const my = a[1] + dy / 2;\n const out = new Group();\n for (let i = 0; i < cell.length; i++) {\n const p = cell[i === 0 ? cell.length - 1 : i - 1];\n const q = cell[i];\n const dp = (p[0] - mx) * dx + (p[1] - my) * dy;\n const dq = (q[0] - mx) * dx + (q[1] - my) * dy;\n if (dp <= 0 !== dq <= 0) {\n const t = dp / (dp - dq);\n out.push(new Pt(p[0] + (q[0] - p[0]) * t, p[1] + (q[1] - p[1]) * t));\n }\n if (dq <= 0) out.push(q);\n }\n return out;\n}\n\n/** Circumcenter and radius of a triangle, as `[x, y, r]`. */\nfunction _circumcircle(\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n): [number, number, number] {\n const bx2 = bx - ax;\n const by2 = by - ay;\n const cx2 = cx - ax;\n const cy2 = cy - ay;\n const d = 2 * (bx2 * cy2 - by2 * cx2);\n const bl = bx2 * bx2 + by2 * by2;\n const cl = cx2 * cx2 + cy2 * cy2;\n const ux = (cy2 * bl - by2 * cl) / d;\n const uy = (bx2 * cl - cx2 * bl) / d;\n return [ax + ux, ay + uy, Math.sqrt(ux * ux + uy * uy)];\n}\n\n/**\n * Delaunay is a [`Group`](#link) of Pts that generates Delaunay and Voronoi tessellations.\n * Points are triangulated by incremental insertion in Hilbert-curve order with exact\n * orientation and in-circle tests, so grids, collinear runs, points on edges, and duplicate\n * points are handled without degenerate triangles.\n */\nexport class Delaunay extends Group {\n private _mesh: DelaunayMesh = [];\n private _meshBuilt = true;\n private _count = 0;\n private _tri: Triangulation | null = null;\n private _shapes: DelaunayShape[] | null = null;\n\n /**\n * Generate Delaunay triangles. This function also caches the mesh that is used to generate Voronoi tessellation in `voronoi()`. See a [Delaunay demo here](https://ptsjs.org/demo/?name=create.delaunay).\n * @param triangleOnly if true, returns an array of triangles in Groups, otherwise return the whole DelaunayShape\n * @returns an array of Groups or an array of DelaunayShapes `{i, j, k, triangle, circle}` which records the indices of the vertices, and the calculated triangles and circumcircles\n */\n delaunay(triangleOnly: boolean = true): GroupLike[] | DelaunayShape[] {\n const n = this.length;\n this._count = n;\n this._mesh = [];\n this._meshBuilt = false;\n this._tri = null;\n this._shapes = null;\n if (n < 3) return [];\n\n const coords = new Float64Array(n * 2);\n for (let i = 0; i < n; i++) {\n coords[2 * i] = this[i][0];\n coords[2 * i + 1] = this[i][1];\n }\n\n const tri = triangulate(coords, n);\n if (tri.triangles.length === 0) return [];\n this._tri = tri;\n const indices = tri.triangles;\n\n const shapes: DelaunayShape[] = [];\n const tris: GroupLike[] = [];\n for (let t = 0, len = indices.length; t < len; t += 3) {\n const i = indices[t];\n const j = indices[t + 1];\n const k = indices[t + 2];\n const triangle = this._triangle(i, j, k);\n // scalar circumcircle, matching the shape of `Triangle.circumcircle`\n const [ccx, ccy, r] = _circumcircle(\n coords[2 * i],\n coords[2 * i + 1],\n coords[2 * j],\n coords[2 * j + 1],\n coords[2 * k],\n coords[2 * k + 1],\n );\n const circle = new Group(new Pt(ccx, ccy), new Pt(r, r));\n\n shapes.push({ i, j, k, triangle, circle });\n tris.push(triangle);\n }\n this._shapes = shapes;\n\n return triangleOnly ? tris : shapes;\n }\n\n /**\n * The per-point mesh cache is keyed by neighbor-pair strings, which costs\n * more than the triangulation itself; build it the first time it is read.\n */\n private _ensureMesh(): DelaunayMesh {\n if (!this._meshBuilt) {\n this._meshBuilt = true;\n this._mesh = [];\n for (let i = 0; i < this._count; i++) this._mesh[i] = {};\n if (this._shapes) {\n for (let s = 0, len = this._shapes.length; s < len; s++) {\n this._cache(this._shapes[s]);\n }\n }\n }\n return this._mesh;\n }\n\n /**\n * Generate Voronoi cells. `delaunay()` must be called before calling this function. See a [Voronoi demo here](https://ptsjs.org/demo/?name=create.delaunay).\n * @param bound Optionally provide a rectangular bound (eg, `space.innerBound`) to clip the cells against, including the unbounded cells on the convex hull.\n * Without a bound, cells around sliver triangles can extend to enormous coordinates (circumcenters of\n * nearly-collinear points), which is technically correct but extremely slow to draw.\n * @returns an array of Groups, each of which represents a Voronoi cell. Unclipped cells share their vertex Pts with the cached mesh (see [`Delaunay.mesh`](#link)), so treat them as read-only or clone before mutating.\n */\n voronoi(bound?: PtIterable): Group[] {\n const cells = this._voronoiCells();\n if (!bound) return cells;\n\n const _bound = Geom.boundingBox(Util.iterToArray(bound) as Group);\n const x0 = _bound[0][0];\n const y0 = _bound[0][1];\n const x1 = _bound[1][0];\n const y1 = _bound[1][1];\n const hull = new Set<number>();\n if (this._tri) for (const i of this._tri.hull) hull.add(i);\n const seen = new Set<string>();\n for (let i = 0, len = cells.length; i < len; i++) {\n const key = `${this[i][0]},${this[i][1]}`;\n if (seen.has(key)) {\n cells[i] = new Group();\n continue;\n }\n seen.add(key);\n if (!hull.has(i) && cells[i].length >= 3) {\n cells[i] = _clipCellToRect(cells[i], x0, y0, x1, y1);\n continue;\n }\n\n // Hull fans do not enclose their unbounded Voronoi regions. Start\n // with the bound and intersect the half-planes of neighboring sites.\n const neighbors = new Set<number>();\n for (const shape of this.neighbors(i)) {\n for (const index of [shape.i, shape.j, shape.k]) {\n if (index !== i) neighbors.add(index);\n }\n }\n // Collinear and small point sets have no triangles; every site is a\n // candidate neighbor. Duplicate sites leave the first cell unchanged.\n if (neighbors.size === 0) {\n for (let j = 0; j < this.length; j++) if (j !== i) neighbors.add(j);\n }\n let cell = Group.fromArray([\n [x0, y0],\n [x1, y0],\n [x1, y1],\n [x0, y1],\n ]);\n for (const j of neighbors)\n cell = _clipCellToBisector(cell, this[i], this[j]);\n cells[i] = cell;\n }\n return cells;\n }\n\n /** Assemble unclipped Voronoi cells. */\n private _voronoiCells(): Group[] {\n const tri = this._tri;\n const shapes = this._shapes;\n if (!tri || !shapes) {\n // fallback (eg, subclasses bypassing delaunay()): sort per cell\n const vs: Group[] = [];\n const n = this._ensureMesh();\n for (let i = 0, len = n.length; i < len; i++) {\n vs.push(this.neighborPts(i, true) as Group);\n }\n return vs;\n }\n\n // Walk the triangles around each point counterclockwise, so its\n // circumcenters come out already in polygon order. A hull point's fan is\n // open: start it at the triangle whose outgoing edge is on the hull.\n const n = this._count;\n const triangles = tri.triangles;\n const neighbors = tri.neighbors;\n const start = new Int32Array(n).fill(-1);\n for (let h = 0, len = triangles.length; h < len; h++) {\n const p = triangles[h];\n if (neighbors[h] === -1 || start[p] === -1) start[p] = h;\n }\n\n const vs: Group[] = [];\n for (let i = 0; i < n; i++) {\n const cell = new Group();\n let h = start[i];\n if (h !== -1) {\n const first = (h / 3) | 0;\n for (;;) {\n const t = (h / 3) | 0;\n cell.push(shapes[t].circle[0]);\n // the edge entering this point leads to the next triangle around it\n const twin = neighbors[3 * t + ((h + 2) % 3)];\n if (twin === -1 || ((twin / 3) | 0) === first) break;\n h = twin;\n }\n }\n vs.push(cell);\n }\n return vs;\n }\n\n /**\n * Get the cached mesh. The mesh is an array of objects, each of which representing the enclosing triangles around a Pt in this Delaunay group.\n * @return an array of objects that store a series of DelaunayShapes\n */\n mesh(): DelaunayMesh {\n return this._ensureMesh();\n }\n\n /**\n * Given an index of a Pt in this Delaunay Group, returns its neighboring Pts in the network.\n * @param i index of a Pt\n * @param sort if true, sort the neighbors so that their edges will form a polygon\n * @returns an array of Pts\n */\n neighborPts(i: number, sort = false): GroupLike {\n let cs = new Group();\n let n = this._ensureMesh();\n for (let k in n[i]) {\n if (n[i].hasOwnProperty(k)) cs.push(n[i][k].circle[0]);\n }\n return sort && cs.length > 1 ? Geom.sortEdges(cs) : cs;\n }\n\n /**\n * Given an index of a Pt in this Delaunay Group, returns its neighboring DelaunayShapes.\n * @param i index of a Pt\n * @returns an array of DelaunayShapes `{i, j, k, triangle, circle}`\n */\n neighbors(i: number): DelaunayShape[] {\n let cs = [];\n let n = this._ensureMesh();\n for (let k in n[i]) {\n if (n[i].hasOwnProperty(k)) cs.push(n[i][k]);\n }\n return cs;\n }\n\n /**\n * Record a DelaunayShape in the mesh.\n * @param o DelaunayShape instance\n */\n protected _cache(o: DelaunayShape): void {\n this._mesh[o.i][`${Math.min(o.j, o.k)}-${Math.max(o.j, o.k)}`] = o;\n this._mesh[o.j][`${Math.min(o.i, o.k)}-${Math.max(o.i, o.k)}`] = o;\n this._mesh[o.k][`${Math.min(o.i, o.j)}-${Math.max(o.i, o.j)}`] = o;\n }\n\n /**\n * Get the initial \"super triangle\" that contains all the points in this set.\n * Not used by the current triangulation core; kept for subclass compatibility.\n * @returns a Group representing a triangle\n */\n protected _superTriangle(): Group {\n let minPt = this[0];\n let maxPt = this[0];\n for (let i = 1, len = this.length; i < len; i++) {\n minPt = minPt.$min(this[i]);\n maxPt = maxPt.$max(this[i]);\n }\n\n let d = maxPt.$subtract(minPt);\n let mid = minPt.$add(maxPt).divide(2);\n let dmax = Math.max(d[0], d[1]);\n\n return new Group(\n mid.$subtract(20 * dmax, dmax),\n mid.$add(0, 20 * dmax),\n mid.$add(20 * dmax, -dmax),\n );\n }\n\n /**\n * Get a triangle from 3 points in a list of points\n * @param i index 1\n * @param j index 2\n * @param k index 3\n * @param pts a Group of Pts\n */\n protected _triangle(\n i: number,\n j: number,\n k: number,\n pts: GroupLike = this,\n ): Group {\n return new Group(pts[i], pts[j], pts[k]);\n }\n\n /**\n * Get a circumcircle and triangle from 3 points in a list of points\n * @param i index 1\n * @param j index 2\n * @param k index 3\n * @param tri a Group representing a triangle, or `false` to create it from indices\n * @param pts a Group of Pts\n */\n protected _circum(\n i: number,\n j: number,\n k: number,\n tri: GroupLike | false,\n pts: GroupLike = this,\n ): DelaunayShape {\n let t = tri || this._triangle(i, j, k, pts);\n return {\n i: i,\n j: j,\n k: k,\n triangle: t,\n circle: Triangle.circumcircle(t)!,\n };\n }\n\n /**\n * Dedupe the edges array\n * @param edges\n */\n protected static _dedupe(edges: number[]): number[] {\n let j = edges.length;\n\n while (j > 1) {\n let b = edges[--j];\n let a = edges[--j];\n let i = j;\n\n while (i > 1) {\n let n = edges[--i];\n let m = edges[--i];\n\n if ((a == m && b == n) || (a == n && b == m)) {\n edges.splice(j, 2);\n edges.splice(i, 2);\n break;\n }\n }\n }\n\n return edges;\n }\n}\n\n/**\n * Accumulate one behavior's contribution as a weighted unit vector.\n *\n * The three behaviors are blended as *directions* and only then turned into a single steering\n * force, rather than each producing its own `desired - velocity` steer that are then summed.\n * Summing them would apply the `- velocity` damping term once per behavior, so with weights\n * totalling ~3.8 an agent is dragged toward a standstill whenever the behaviors disagree —\n * which is exactly what happens inside a tight cluster, where cohesion and separation nearly\n * oppose. Blending first also bounds separation structurally: its inverse-square sum is\n * normalized here, so no amount of piled-up neighbors can dominate the result.\n *\n * Does nothing when the direction is degenerate (zero length), which happens whenever neighbor\n * velocities cancel out or an agent sits exactly on its neighbors' center.\n */\nfunction __flock_accumulateUnit(\n out: Float32Array,\n dx: number,\n dy: number,\n weight: number,\n): void {\n const mag2 = dx * dx + dy * dy;\n if (mag2 <= 0) return;\n const scale = weight / Math.sqrt(mag2);\n out[0] += dx * scale;\n out[1] += dy * scale;\n}\n\n/**\n * Two agents at the exact same position have no direction to separate along. Rather than\n * leaving them fused forever, separation falls back to this offset, which the antisymmetric\n * accumulation splits into +x for one agent and -x for the other.\n */\nconst __flock_tieBreak = 1;\n\n/**\n * Separation weights each neighbor by inverse-square distance, so a pair that is nearly\n * coincident would produce an unbounded force. Distances are clamped to this fraction of the\n * separation radius. (The per-behavior `maxForce` clamp is what ultimately bounds the sum.)\n */\nconst __flock_minSepFraction = 0.01;\n\n/**\n * Cell indices are hashed through `Math.imul`, which truncates to int32, so anything past this\n * carries no information. It is also the guard that keeps the 3x3 cell walk terminating: a\n * non-finite position yields a non-finite cell index, and `gy <= cy + 1` is either always true\n * (Infinity) or leaves `gy++` unable to advance (magnitudes where adding 1 is a no-op in\n * float64). The comparison is written so NaN fails it too.\n */\nconst __flock_maxCell = 0x7fffffff;\n/** Cell coordinate of an agent with no finite neighborhood; below every valid cell. */\nconst __flock_noCell = -0x80000000;\n\n/**\n * Boid is a subclass of [`Pt`](#link) that represents a single agent in a [`Flock`](#link).\n * Its own values are the agent's position, and it carries a `velocity` that [`Flock.step`](#link)\n * integrates. Create them through [`Create.flock`](#link) or [`Flock.addBoid`](#link).\n * See [a demo here](https://ptsjs.org/demo/?name=create.flock).\n */\nexport class Boid extends Pt {\n protected _vel: Pt = new Pt(0, 0);\n\n /**\n * This agent's velocity, in units per second.\n */\n get velocity(): Pt {\n return this._vel;\n }\n set velocity(v: Pt) {\n this._vel = v;\n }\n\n /**\n * This agent's speed, in units per second.\n */\n get speed(): number {\n return Math.sqrt(this._vel[0] * this._vel[0] + this._vel[1] * this._vel[1]);\n }\n\n /**\n * The angle this agent is heading toward, in radians. Note that a stationary agent has no\n * heading and reports 0 (pointing along +x) rather than NaN. Set a [`Flock`](#link)'s\n * `minSpeed` if you are drawing headings and want to avoid that.\n */\n get heading(): number {\n return Math.atan2(this._vel[1], this._vel[0]);\n }\n}\n\n/**\n * Flock is a subclass of [`Group`](#link) that holds [`Boid`](#link) agents and simulates\n * flocking behavior (also known as \"boids\", after Craig Reynolds). Each agent steers by three\n * local rules — separation, alignment, and cohesion — evaluated over the neighbors within its\n * `perception` radius. Create one with [`Create.flock`](#link) and advance it with\n * [`Flock.step`](#link). Since a Flock is a Group of Pts, it draws directly:\n * `form.points( flock, 2, \"circle\" )`.\n *\n * Neighbors are found through a uniform spatial hash rather than by testing every pair, so the\n * cost scales with the number of agents rather than with its square.\n * See [a demo here](https://ptsjs.org/demo/?name=create.flock).\n */\nexport class Flock extends Group {\n protected _perception: number = 40;\n protected _separation: number = 20;\n protected _cohesionWeight: number = 1;\n protected _alignWeight: number = 1;\n protected _separateWeight: number = 1.5;\n protected _maxSpeed: number = 100;\n protected _minSpeed: number = 0;\n protected _maxForce: number = 200;\n protected _boundary: FlockBoundary = \"steer\";\n protected _margin: number = 50;\n protected _maxTimeStep: number = 50;\n protected _bound: GroupLike | null = null;\n protected _initialSpeed: number | undefined = undefined;\n\n // Flat per-agent state, gathered from the Boids at the start of each step and scattered back\n // at the end. The neighbor pass runs entirely on these, so it reads sequential memory instead\n // of chasing `this[i].velocity[0]` through two objects for every pair.\n private _pos: Float32Array = new Float32Array(0);\n private _vel: Float32Array = new Float32Array(0);\n // Per-agent accumulators, interleaved 6-wide: cohesion x/y, alignment x/y, separation x/y.\n private _sums: Float32Array = new Float32Array(0);\n private _counts: Uint32Array = new Uint32Array(0);\n\n // Spatial-hash scratch, grown geometrically and reused across steps.\n private _hashKeys: Uint32Array = new Uint32Array(0);\n private _cellX: Int32Array = new Int32Array(0);\n private _cellY: Int32Array = new Int32Array(0);\n private _cellStart: Uint32Array = new Uint32Array(0);\n private _cellEntries: Uint32Array = new Uint32Array(0);\n private _steerOut: Float32Array = new Float32Array(2);\n\n /**\n * Set any number of options at once. Unspecified options keep their current value.\n * @param options a [`FlockOptions`](#link) object\n */\n setup(options: FlockOptions): this {\n if (options.perception !== undefined) this.perception = options.perception;\n if (options.separation !== undefined) this.separation = options.separation;\n if (options.cohesionWeight !== undefined)\n this._cohesionWeight = options.cohesionWeight;\n if (options.alignWeight !== undefined)\n this._alignWeight = options.alignWeight;\n if (options.separateWeight !== undefined)\n this._separateWeight = options.separateWeight;\n if (options.maxSpeed !== undefined) this.maxSpeed = options.maxSpeed;\n if (options.minSpeed !== undefined) this.minSpeed = options.minSpeed;\n if (options.maxForce !== undefined) this._maxForce = options.maxForce;\n if (options.bound !== undefined) this._bound = options.bound as GroupLike;\n if (options.boundary !== undefined) this._boundary = options.boundary;\n if (options.margin !== undefined) this.margin = options.margin;\n if (options.maxTimeStep !== undefined)\n this.maxTimeStep = options.maxTimeStep;\n if (options.initialSpeed !== undefined)\n this._initialSpeed = options.initialSpeed;\n return this;\n }\n\n /**\n * Radius within which an agent sees its neighbors. This is also the spatial hash's cell size.\n */\n get perception(): number {\n return this._perception;\n }\n set perception(r: number) {\n this._perception = Math.max(0, r);\n }\n\n /**\n * Radius within which an agent steers away from its neighbors. Values above `perception`\n * have no additional effect, since an agent only considers neighbors it can see.\n */\n get separation(): number {\n return this._separation;\n }\n set separation(r: number) {\n this._separation = Math.max(0, r);\n }\n\n /**\n * Weight of the cohesion behavior, which steers an agent toward its neighbors' center.\n */\n get cohesionWeight(): number {\n return this._cohesionWeight;\n }\n set cohesionWeight(w: number) {\n this._cohesionWeight = w;\n }\n\n /**\n * Weight of the alignment behavior, which matches an agent's heading to its neighbors'.\n */\n get alignWeight(): number {\n return this._alignWeight;\n }\n set alignWeight(w: number) {\n this._alignWeight = w;\n }\n\n /**\n * Weight of the separation behavior, which steers an agent away from close neighbors.\n */\n get separateWeight(): number {\n return this._separateWeight;\n }\n set separateWeight(w: number) {\n this._separateWeight = w;\n }\n\n /**\n * Maximum speed, in units per second.\n */\n get maxSpeed(): number {\n return this._maxSpeed;\n }\n set maxSpeed(s: number) {\n this._maxSpeed = Math.max(0, s);\n }\n\n /**\n * Minimum speed, in units per second, so agents never stall. Default is 0.\n */\n get minSpeed(): number {\n return this._minSpeed;\n }\n set minSpeed(s: number) {\n this._minSpeed = Math.max(0, s);\n }\n\n /**\n * Maximum steering force, in units per second squared. This caps how sharply an agent can\n * turn toward the direction its three behaviors blend to. A boundary turn is added on top,\n * so an agent near an edge can accelerate up to twice this.\n */\n get maxForce(): number {\n return this._maxForce;\n }\n set maxForce(f: number) {\n this._maxForce = f;\n }\n\n /**\n * Boundary that keeps the flock in view, as a [`Bound`](#link) or a Group of 2 Pts.\n * When this is null, no boundary behavior is applied regardless of `boundary`.\n */\n get bound(): GroupLike | null {\n return this._bound;\n }\n set bound(b: GroupLike | null) {\n this._bound = b;\n }\n\n /**\n * How the boundary is treated: `\"steer\"`, `\"wrap\"`, `\"bounce\"`, or `\"none\"`.\n *\n * Note that `\"wrap\"` teleports agents across the bound while the neighborhood search is not\n * toroidal, so a flock loses sight of itself at the seam. Prefer `\"steer\"` when that matters.\n */\n get boundary(): FlockBoundary {\n return this._boundary;\n }\n set boundary(b: FlockBoundary) {\n this._boundary = b;\n }\n\n /**\n * Distance from an edge at which `\"steer\"` starts turning agents back.\n */\n get margin(): number {\n return this._margin;\n }\n set margin(m: number) {\n this._margin = Math.max(0, m);\n }\n\n /**\n * Maximum simulated time in milliseconds per [`Flock.step`](#link) call. Longer elapsed times\n * are clamped to this, which keeps a stalled frame from teleporting the flock. Default is 50.\n */\n get maxTimeStep(): number {\n return this._maxTimeStep;\n }\n set maxTimeStep(ms: number) {\n this._maxTimeStep = Math.max(0, ms);\n }\n\n /**\n * Speed given to an agent added without an explicit velocity. Defaults to half of `maxSpeed`.\n */\n get initialSpeed(): number {\n return this._initialSpeed === undefined\n ? this._maxSpeed * 0.5\n : this._initialSpeed;\n }\n set initialSpeed(s: number) {\n this._initialSpeed = s;\n }\n\n /**\n * Add an agent to this flock. Named `addBoid` rather than `add` because [`Group.add`](#link)\n * already means \"translate every Pt in this group\", and [`Group.moveBy`](#link) delegates to it.\n * @param pt a Pt, a Boid, or an array of numbers for the starting position\n * @param velocity optional starting velocity. When omitted, a new agent gets a random heading\n * at [`Flock.initialSpeed`](#link), drawn from [`Num.random`](#link).\n */\n addBoid(pt: PtLike | Boid, velocity?: PtLike): this {\n const isBoid = pt instanceof Boid;\n const boid = isBoid ? (pt as Boid) : new Boid(pt);\n if (velocity !== undefined) {\n boid.velocity[0] = velocity[0];\n boid.velocity[1] = velocity[1];\n } else if (!isBoid) {\n const a = Num.random() * Const.two_pi;\n const s = this.initialSpeed;\n boid.velocity[0] = Math.cos(a) * s;\n boid.velocity[1] = Math.sin(a) * s;\n }\n this.push(boid);\n return this;\n }\n\n /**\n * Advance the simulation. Call this once per frame with the frame time, eg\n * `space.add( (time, ftime) => flock.step( ftime ) )`.\n *\n * Elapsed times longer than [`Flock.maxTimeStep`](#link) are clamped, so a slow frame slows\n * the flock down instead of teleporting it. A non-positive or NaN time is a no-op.\n *\n * @param ms elapsed time in milliseconds\n */\n step(ms: number): this {\n const n = this.length;\n if (n === 0 || !(ms > 0)) return this;\n\n const dt = Math.min(ms, this._maxTimeStep) / 1000;\n if (dt <= 0) return this;\n\n this._ensureBuffers(n);\n this._gather(n);\n if (n > 1 && this._perception > 0) {\n this._accumulate(n);\n } else {\n this._sums.fill(0, 0, n * 6);\n this._counts.fill(0, 0, n);\n }\n this._integrate(n, dt);\n this._scatter(n);\n return this;\n }\n\n /**\n * Grow the flat state and hash scratch to fit `n` agents. Every buffer is fully written\n * before it is read within a step, so reallocating here never loses state.\n */\n private _ensureBuffers(n: number) {\n if (this._pos.length < n * 2) {\n const size = n * 2 * 2; // geometric growth\n this._pos = new Float32Array(size);\n this._vel = new Float32Array(size);\n this._sums = new Float32Array(size * 3);\n this._counts = new Uint32Array(size);\n this._hashKeys = new Uint32Array(size);\n this._cellX = new Int32Array(size);\n this._cellY = new Int32Array(size);\n this._cellEntries = new Uint32Array(size);\n }\n }\n\n /**\n * Copy positions and velocities out of the Boids into the flat buffers. An element that\n * reached this Group without a velocity — pushed as a plain Pt, or produced by a Group method\n * that copies through the species constructor — is upgraded to a Boid in place here rather\n * than throwing mid-simulation.\n */\n private _gather(n: number) {\n const pos = this._pos;\n const vel = this._vel;\n for (let i = 0; i < n; i++) {\n let b = this[i] as Boid;\n let v = b.velocity;\n if (v === undefined) {\n b = new Boid(b);\n v = b.velocity;\n this[i] = b;\n }\n const k = i * 2;\n pos[k] = b[0];\n pos[k + 1] = b[1];\n vel[k] = v[0];\n vel[k + 1] = v[1];\n }\n }\n\n /**\n * Write the integrated positions and velocities back into the Boids.\n */\n private _scatter(n: number) {\n const pos = this._pos;\n const vel = this._vel;\n for (let i = 0; i < n; i++) {\n const b = this[i] as Boid;\n const v = b.velocity;\n const k = i * 2;\n b[0] = pos[k];\n b[1] = pos[k + 1];\n v[0] = vel[k];\n v[1] = vel[k + 1];\n }\n }\n\n /**\n * Accumulate the three behaviors' sums for every agent in a single pass over neighboring\n * pairs, using a uniform spatial hash (a counting-sort grid) built the same way as\n * [`World`](#link)'s collision broad phase — see `World._collideParticles`. The two are kept\n * separate on purpose: this one queries a fixed radius and accumulates into flat sums, and\n * sharing an abstraction between them would put an indirect call on the per-pair path.\n *\n * Cells are exactly `perception` wide, which is the smallest size for which every neighbor\n * within that radius is guaranteed to lie in the 3x3 block around an agent's cell. Each\n * agent's cell coordinates are kept, so an entry found through a hash bucket is checked\n * against the cell actually being visited: two cells that collide into one bucket cannot\n * count a neighbor twice or hide one. That exact check is also what allows visiting only\n * half of the neighborhood — the agent's own cell (pairing with higher indices) plus the four\n * cells east, south-west, south, and south-east — since every pair of adjacent cells is then\n * seen from exactly one side.\n *\n * Each pair is accumulated into both agents: \"j is within r of i\" is symmetric, so this\n * halves the distance computations. No `sqrt` is taken here — radius tests compare squared\n * distances, and separation falls off as the inverse square, which is what makes the\n * fallback in `__flock_tieBreak` necessary.\n */\n private _accumulate(n: number) {\n const pos = this._pos;\n const vel = this._vel;\n const sums = this._sums;\n const counts = this._counts;\n\n sums.fill(0, 0, n * 6);\n counts.fill(0, 0, n);\n\n const r2 = this._perception * this._perception;\n const sep = Math.min(this._separation, this._perception);\n const sep2 = sep * sep;\n const minSep = sep * __flock_minSepFraction;\n const minSep2 = minSep * minSep;\n const inv = 1 / this._perception;\n\n // Hash table size: the next power of two above 2n, so buckets stay sparse.\n let m = 16;\n while (m < n * 2) m <<= 1;\n const mask = m - 1;\n if (this._cellStart.length < m + 1)\n this._cellStart = new Uint32Array(m + 1);\n\n const keys = this._hashKeys;\n const cellX = this._cellX;\n const cellY = this._cellY;\n const start = this._cellStart;\n const entries = this._cellEntries;\n\n // Cell coordinates once per agent. A non-finite or absurd position gets a sentinel cell\n // that no neighborhood visit can match, so it neither sees nor is seen (see\n // `__flock_maxCell`). Then count per cell, exclusive prefix sum, and scatter; after the\n // scatter, bucket k spans [start[k-1], start[k]).\n start.fill(0, 0, m + 1);\n for (let i = 0; i < n; i++) {\n const cx = Math.floor(pos[i * 2] * inv);\n const cy = Math.floor(pos[i * 2 + 1] * inv);\n if (\n cx >= -__flock_maxCell &&\n cx <= __flock_maxCell &&\n cy >= -__flock_maxCell &&\n cy <= __flock_maxCell\n ) {\n cellX[i] = cx;\n cellY[i] = cy;\n } else {\n cellX[i] = __flock_noCell;\n cellY[i] = __flock_noCell;\n }\n const key =\n ((Math.imul(cellX[i], 0x9e3779b1) ^ Math.imul(cellY[i], 0x85ebca77)) >>>\n 0) &\n mask;\n keys[i] = key;\n start[key]++;\n }\n let sum = 0;\n for (let k = 0; k < m; k++) {\n const c = start[k];\n start[k] = sum;\n sum += c;\n }\n start[m] = sum;\n for (let i = 0; i < n; i++) {\n entries[start[keys[i]]++] = i;\n }\n\n for (let i = 0; i < n; i++) {\n const cx = cellX[i];\n if (cx === __flock_noCell) continue;\n const cy = cellY[i];\n const ki = i * 2;\n const ix = pos[ki];\n const iy = pos[ki + 1];\n const ivx = vel[ki];\n const ivy = vel[ki + 1];\n const si = i * 6;\n\n // the five cells of the half neighborhood, own cell first\n for (let c = 0; c < 5; c++) {\n const gx = c === 2 ? cx - 1 : c === 0 || c === 3 ? cx : cx + 1;\n const gy = c < 2 ? cy : cy + 1;\n const key =\n ((Math.imul(gx, 0x9e3779b1) ^ Math.imul(gy, 0x85ebca77)) >>> 0) &\n mask;\n const end = start[key];\n const begin = key > 0 ? start[key - 1] : 0;\n for (let e = begin; e < end; e++) {\n const j = entries[e];\n if (cellX[j] !== gx || cellY[j] !== gy) continue; // another cell in this bucket\n if (c === 0 && j <= i) continue; // own cell: each pair once\n\n const kj = j * 2;\n const jx = pos[kj];\n const jy = pos[kj + 1];\n const dx = jx - ix;\n const dy = jy - iy;\n const d2 = dx * dx + dy * dy;\n if (!(d2 < r2)) continue;\n\n const sj = j * 6;\n sums[si] += jx;\n sums[si + 1] += jy;\n sums[sj] += ix;\n sums[sj + 1] += iy;\n sums[si + 2] += vel[kj];\n sums[si + 3] += vel[kj + 1];\n sums[sj + 2] += ivx;\n sums[sj + 3] += ivy;\n counts[i]++;\n counts[j]++;\n\n if (d2 < sep2) {\n let ox = dx;\n let oy = dy;\n let dd = d2;\n if (dd === 0) {\n // Coincident agents have no direction to separate along; split them along x.\n ox = __flock_tieBreak;\n oy = 0;\n dd = minSep2;\n } else if (dd < minSep2) {\n dd = minSep2;\n }\n const w = 1 / dd;\n const wx = ox * w;\n const wy = oy * w;\n sums[si + 4] -= wx;\n sums[si + 5] -= wy;\n sums[sj + 4] += wx;\n sums[sj + 5] += wy;\n }\n }\n }\n }\n }\n\n /**\n * Turn the accumulated sums into a steering force per agent, then integrate velocity and\n * position. This is O(n), so it uses the classic \"steer toward the desired velocity\"\n * formulation and its handful of square roots, which behaves better than weighting raw\n * offsets and keeps `maxSpeed` and `maxForce` as the only scale-dependent knobs.\n * See `__flock_accumulateUnit` for why the behaviors are blended before that steer is taken.\n */\n private _integrate(n: number, dt: number) {\n const pos = this._pos;\n const vel = this._vel;\n const sums = this._sums;\n const counts = this._counts;\n const out = this._steerOut;\n\n const maxSpeed = this._maxSpeed;\n const maxForce = this._maxForce;\n const minSpeed = Math.min(this._minSpeed, maxSpeed);\n const cw = this._cohesionWeight;\n const aw = this._alignWeight;\n const sw = this._separateWeight;\n\n const bound = this._bound;\n const boundary = bound ? this._boundary : \"none\";\n const steer = boundary === \"steer\" && this._margin > 0;\n const wrap = boundary === \"wrap\";\n const bounce = boundary === \"bounce\";\n let minX = 0;\n let minY = 0;\n let maxX = 0;\n let maxY = 0;\n if (bound && boundary !== \"none\") {\n const b0 = bound[0];\n const b1 = bound[1];\n minX = Math.min(b0[0], b1[0]);\n minY = Math.min(b0[1], b1[1]);\n maxX = Math.max(b0[0], b1[0]);\n maxY = Math.max(b0[1], b1[1]);\n }\n const margin = this._margin;\n\n for (let i = 0; i < n; i++) {\n const k = i * 2;\n const s = i * 6;\n let px = pos[k];\n let py = pos[k + 1];\n let vx = vel[k];\n let vy = vel[k + 1];\n\n // Blend the three behaviors into one desired direction...\n out[0] = 0;\n out[1] = 0;\n const c = counts[i];\n if (c > 0) {\n // steer toward the neighbors' center\n if (cw !== 0) {\n __flock_accumulateUnit(\n out,\n sums[s] / c - px,\n sums[s + 1] / c - py,\n cw,\n );\n }\n // match the neighbors' heading. The mean and the sum point the same way, and the\n // direction is normalized anyway, so the neighbor count is not needed here.\n if (aw !== 0) __flock_accumulateUnit(out, sums[s + 2], sums[s + 3], aw);\n if (sw !== 0) __flock_accumulateUnit(out, sums[s + 4], sums[s + 5], sw);\n }\n\n // ...then take a single steer toward it, so the damping is applied once.\n let ax = 0;\n let ay = 0;\n const dm2 = out[0] * out[0] + out[1] * out[1];\n if (dm2 > 0) {\n const sc = maxSpeed / Math.sqrt(dm2);\n ax = out[0] * sc - vx;\n ay = out[1] * sc - vy;\n const f2 = ax * ax + ay * ay;\n if (f2 > maxForce * maxForce) {\n const fs = maxForce / Math.sqrt(f2);\n ax *= fs;\n ay *= fs;\n }\n }\n\n if (steer) {\n // Ramp the turn from zero at the margin's inner edge to full force at the wall, and\n // hold it at full force for anything that already escaped. This is added on top of the\n // blended steer rather than mixed into it, so the flock's own rules cannot outvote it\n // and pin a cluster against an edge.\n const dl = px - minX;\n const dr = maxX - px;\n const dtp = py - minY;\n const db = maxY - py;\n if (dl < margin) ax += maxForce * (1 - Math.max(dl, 0) / margin);\n else if (dr < margin) ax -= maxForce * (1 - Math.max(dr, 0) / margin);\n if (dtp < margin) ay += maxForce * (1 - Math.max(dtp, 0) / margin);\n else if (db < margin) ay -= maxForce * (1 - Math.max(db, 0) / margin);\n }\n\n vx += ax * dt;\n vy += ay * dt;\n\n const sp2 = vx * vx + vy * vy;\n if (sp2 > maxSpeed * maxSpeed) {\n const sc = maxSpeed / Math.sqrt(sp2);\n vx *= sc;\n vy *= sc;\n } else if (minSpeed > 0 && sp2 < minSpeed * minSpeed) {\n if (sp2 > 0) {\n const sc = minSpeed / Math.sqrt(sp2);\n vx *= sc;\n vy *= sc;\n } else {\n // A dead stop has no heading to preserve; pick one deterministically.\n vx = minSpeed;\n vy = 0;\n }\n }\n\n px += vx * dt;\n py += vy * dt;\n\n if (wrap) {\n const w = maxX - minX;\n const h = maxY - minY;\n if (w > 0) {\n if (px < minX) px = maxX - ((minX - px) % w);\n else if (px > maxX) px = minX + ((px - maxX) % w);\n }\n if (h > 0) {\n if (py < minY) py = maxY - ((minY - py) % h);\n else if (py > maxY) py = minY + ((py - maxY) % h);\n }\n } else if (bounce) {\n // `<=` rather than `<`: an agent that lands exactly on the wall is still heading out,\n // and would otherwise leave on the next step without ever reflecting.\n if (px <= minX) {\n px = minX;\n if (vx < 0) vx = -vx;\n } else if (px >= maxX) {\n px = maxX;\n if (vx > 0) vx = -vx;\n }\n if (py <= minY) {\n py = minY;\n if (vy < 0) vy = -vy;\n } else if (py >= maxY) {\n py = maxY;\n if (vy > 0) vy = -vy;\n }\n }\n\n pos[k] = px;\n pos[k + 1] = py;\n vel[k] = vx;\n vel[k + 1] = vy;\n }\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Group } from \"./Pt\";\nimport { Util } from \"./Util\";\nimport { Num, Geom } from \"./Num\";\nimport { type PtLike, type ColorType } from \"./Types\";\n\n/**\n * Color is a subclass of Pt. Since a color in a color space is analogous to a point or vector in a space, you can apply all Pt operations to colors too. The Color class provides support for many color spaces like HSL and LAB.\n * Convert non-RGB colors to RGB before using `.hex`, `.rgb`, or `.rgba` for rendering. These getters format the channels; they don't convert between color spaces.\n * @example\n * ```\n * const color = Color.hsl(268, 0.37, 0.51);\n * form.fill(Color.HSLtoRGB(color).rgb);\n * ```\n */\nexport class Color extends Pt {\n // XYZ property for Standard Observer 2deg, Daylight/sRGB illuminant D65\n private static D65: PtLike = new Pt(95.047, 100, 108.883, 1);\n\n protected _mode: ColorType = \"rgb\";\n private _isNorm: boolean = false;\n\n /**\n * Value range for each color space\n */\n static ranges: { [name: string]: Group } = {\n rgb: new Group(new Pt(0, 255), new Pt(0, 255), new Pt(0, 255)),\n hsl: new Group(new Pt(0, 360), new Pt(0, 1), new Pt(0, 1)),\n hsb: new Group(new Pt(0, 360), new Pt(0, 1), new Pt(0, 1)),\n lab: new Group(new Pt(0, 100), new Pt(-128, 127), new Pt(-128, 127)),\n lch: new Group(new Pt(0, 100), new Pt(0, 100), new Pt(0, 360)),\n luv: new Group(new Pt(0, 100), new Pt(-134, 220), new Pt(-140, 122)),\n xyz: new Group(new Pt(0, 100), new Pt(0, 100), new Pt(0, 100)),\n oklab: new Group(new Pt(0, 1), new Pt(-0.4, 0.4), new Pt(-0.4, 0.4)),\n oklch: new Group(new Pt(0, 1), new Pt(0, 0.4), new Pt(0, 360)),\n };\n\n /**\n * Create a Color. Same as creating a Pt. Optionally you may use [`Color.from`](#link) to create a color.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n constructor(...args: any[]) {\n super(...args);\n }\n\n /**\n * Create a Color object with 4 default dimensional values (1,1,1,1).\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n static from(...args: any[]): Color {\n const p = [1, 1, 1, 1];\n const c = Util.getArgs(args);\n for (let i = 0, len = p.length; i < len; i++) {\n if (i < c.length) p[i] = c[i];\n }\n return new Color(p);\n }\n\n /**\n * Convert a rgb hex string like `\"#FF0000\"` or `\"#F00\"` to a Color object.\n * @param hex a hex string, with optional '#' prefix\n */\n static fromHex(hex: string): Color {\n if (hex[0] == \"#\") hex = hex.substr(1); // remove '#' if needed\n if (hex.length <= 4) {\n const fn = (i: number) => hex[i] || \"F\";\n const shortAlpha = hex.length === 4 ? `${fn(3)}${fn(3)}` : \"\"; // #RGBA\n hex = `${fn(0)}${fn(0)}${fn(1)}${fn(1)}${fn(2)}${fn(2)}${shortAlpha}`;\n }\n\n let alpha = 1;\n if (hex.length === 8) {\n alpha = parseInt(hex.substr(6, 2), 16) / 255;\n hex = hex.substring(0, 6);\n }\n\n const hexVal = parseInt(hex, 16);\n return new Color(hexVal >> 16, (hexVal >> 8) & 0xff, hexVal & 0xff, alpha);\n }\n\n /**\n * Create RGB Color. RGB color ranges are (0...255, 0...255, 0...255) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static rgb(...args: any[]): Color {\n return Color.from(...args).toMode(\"rgb\");\n }\n\n /**\n * Create HSL Color. HSL color ranges are (0...360, 0...1, 0...1) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static hsl(...args: any[]): Color {\n return Color.from(...args).toMode(\"hsl\");\n }\n\n /**\n * Create HSB Color. HSB color ranges are (0...360, 0...1, 0...1) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static hsb(...args: any[]): Color {\n return Color.from(...args).toMode(\"hsb\");\n }\n\n /**\n * Create LAB Color. LAB color ranges are (0...100, -128...127, -128...127) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static lab(...args: any[]): Color {\n return Color.from(...args).toMode(\"lab\");\n }\n\n /**\n * Create LCH Color. LCH color ranges are (0...100, 0...100, 0...360) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static lch(...args: any[]): Color {\n return Color.from(...args).toMode(\"lch\");\n }\n\n /**\n * Create LUV Color. LUV color ranges are (0...100, -134...220, -140...122) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static luv(...args: any[]): Color {\n return Color.from(...args).toMode(\"luv\");\n }\n\n /**\n * Create XYZ Color. XYZ color ranges are (0...100, 0...100, 0...100) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static xyz(...args: any[]): Color {\n return Color.from(...args).toMode(\"xyz\");\n }\n\n /**\n * Create OKLAB Color. OKLAB color ranges are (0...1, -0.4...0.4, -0.4...0.4) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static oklab(...args: any[]): Color {\n return Color.from(...args).toMode(\"oklab\");\n }\n\n /**\n * Create OKLCH Color. OKLCH color ranges are (0...1, 0...0.4, 0...360) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static oklch(...args: any[]): Color {\n return Color.from(...args).toMode(\"oklch\");\n }\n\n /**\n * Get a Color object whose values are the maximum of its mode.\n * @param mode a mode string such as \"rgb\" or \"lab\"\n * @example Color.maxValue(\"rgb\") will return a rgb Color object with values (255,255,255)\n */\n static maxValues(mode: string): Pt {\n return Color.ranges[mode].zipSlice(1).$take([0, 1, 2]);\n }\n\n /**\n * Get a hex string such as \"#FF0000\". Same as `toString(\"hex\")`.\n * For non-RGB colors, convert to RGB first.\n */\n public get hex(): string {\n return this.toString(\"hex\");\n }\n\n /**\n * Get a rgb string such as \"rgb(255,0,0)\". Same as `toString(\"rgb\")`.\n * For non-RGB colors, convert to RGB first, eg `Color.HSLtoRGB(color).rgb`.\n */\n public get rgb(): string {\n return this.toString(\"rgb\");\n }\n\n /**\n * Get a rgba string such as \"rgba(255,0,0,0.5)\". Same as `toString(\"rgba\")`.\n * For non-RGB colors, convert to RGB first.\n */\n public get rgba(): string {\n return this.toString(\"rgba\");\n }\n\n /**\n * Clone this Color.\n */\n clone(): Color {\n const c = new Color(this);\n c.toMode(this._mode);\n c._isNorm = this._isNorm;\n return c;\n }\n\n /**\n * Get a denormalized copy of a color, trusting the caller's flag over the\n * color's own normalized state so that explicit conversion arguments win.\n * Inlines the range math — this sits on the hot path of every conversion\n * that takes normalized input.\n */\n private static _denorm(c: Color): Color {\n const cc = c.clone();\n const ranges = Color.ranges[cc._mode];\n for (let i = 0; i < 3; i++) {\n const r = ranges[i];\n cc[i] = r[0] + cc[i] * (r[1] - r[0]);\n }\n cc._isNorm = false;\n return cc;\n }\n\n /**\n * Normalize a freshly computed full-range color in place and flag it.\n * Conversion outputs are always full-range, so no state check is needed.\n */\n private static _normOut(c: Color): Color {\n const ranges = Color.ranges[c._mode];\n for (let i = 0; i < 3; i++) {\n const r = ranges[i];\n c[i] = (c[i] - r[0]) / (r[1] - r[0]);\n }\n c._isNorm = true;\n return c;\n }\n\n /**\n * Convert this color from current color space to another color space.\n * @param mode a ColorType string: \"rgb\" \"hsl\" \"hsb\" \"lab\" \"lch\" \"luv\" \"xyz\";\n * @param convert if `true`, convert this Color to the new color space specified in `mode`. Default is `false`, which only sets the color mode without converting color values.\n */\n toMode(mode: ColorType, convert: boolean = false): this {\n if (convert && mode !== this._mode) {\n const fname = this._mode.toUpperCase() + \"to\" + mode.toUpperCase();\n if ((Color as any)[fname]) {\n this.to((Color as any)[fname](this, this._isNorm, this._isNorm));\n } else {\n throw new Error(\"Cannot convert color with \" + fname);\n }\n }\n\n this._mode = mode;\n return this;\n }\n\n /**\n * Get this Color's mode.\n */\n get mode(): ColorType {\n return this._mode;\n }\n\n // rgb\n /**\n * the `r` value in RGB color mode. Same as `x`.\n */\n get r(): number {\n return this[0];\n }\n set r(n: number) {\n this[0] = n;\n }\n\n /**\n * the `g` value in RGB color mode. Same as `y`.\n */\n get g(): number {\n return this[1];\n }\n set g(n: number) {\n this[1] = n;\n }\n\n /**\n * the `b` value in RGB/LAB/HSB color mode. Same as `z`.\n */\n get b(): number {\n return this[2];\n }\n set b(n: number) {\n this[2] = n;\n }\n\n // hsl, hsb\n /**\n * the `h` value in HSL/HSB or LCH color mode. Same as either `x` or `z` depending on current color mode.\n */\n get h(): number {\n return this._mode == \"lch\" || this._mode == \"oklch\" ? this[2] : this[0];\n }\n set h(n: number) {\n const i = this._mode == \"lch\" || this._mode == \"oklch\" ? 2 : 0;\n this[i] = n;\n }\n\n /**\n * the `s` value in HSL/HSB color mode. Same as `y`.\n */\n get s(): number {\n return this[1];\n }\n set s(n: number) {\n this[1] = n;\n }\n\n /**\n * the `l` value in HSL or LCH/LAB color mode. Same as either `x` or `z` depending on current color mode.\n */\n get l(): number {\n return this._mode == \"hsl\" ? this[2] : this[0];\n }\n set l(n: number) {\n const i = this._mode == \"hsl\" ? 2 : 0;\n this[i] = n;\n }\n\n // lab, lch, luv\n /**\n * the `a` value in LAB color mode. Same as `y`.\n */\n get a(): number {\n return this[1];\n }\n set a(n: number) {\n this[1] = n;\n }\n\n /**\n * the `c` value in LCH color mode. Same as `y`.\n */\n get c(): number {\n return this[1];\n }\n set c(n: number) {\n this[1] = n;\n }\n\n /**\n * the `u` value in LUV color mode. Same as `y`.\n */\n get u(): number {\n return this[1];\n }\n set u(n: number) {\n this[1] = n;\n }\n\n /**\n * the `v` value in LUV color mode. Same as `z`.\n */\n get v(): number {\n return this[2];\n }\n set v(n: number) {\n this[2] = n;\n }\n\n /**\n * Get alpha value\n */\n set alpha(n: number) {\n if (this.length > 3) this[3] = n;\n }\n get alpha(): number {\n return this.length > 3 ? this[3] : 1;\n }\n\n /**\n * Check if color values are normalized (between 0 to 1). If conversion is needed, use [`Color.normalize`](#link) function.\n */\n get normalized(): boolean {\n return this._isNorm;\n }\n set normalized(b: boolean) {\n this._isNorm = b;\n }\n\n /**\n * Normalize the color values to between 0 to 1, or revert it back to the min/max values in current color mode.\n * @param toNorm a boolean value specifying whether to normalize (`true`) or revert (`false`)\n */\n normalize(toNorm: boolean = true): Color {\n if (this._isNorm == toNorm) return this;\n\n const ranges = Color.ranges[this._mode];\n\n for (let i = 0; i < 3; i++) {\n this[i] = !toNorm\n ? Num.mapToRange(this[i], 0, 1, ranges[i][0], ranges[i][1])\n : Num.mapToRange(this[i], ranges[i][0], ranges[i][1], 0, 1);\n }\n\n this._isNorm = toNorm;\n\n return this;\n }\n\n /**\n * Like `normalize()` but returns a new Color.\n * @param toNorm a boolean value specifying whether to normalize (`true`) or revert (`false`)\n * @returns new Color\n */\n $normalize(toNorm: boolean = true): Color {\n return this.clone().normalize(toNorm);\n }\n\n /**\n * Convert this Color to a string. It can be used to get a hex or rgb string for use in rendering.\n * This formats the current channels without converting color spaces. Convert to RGB before requesting \"hex\", \"rgb\", or \"rgba\". The default \"mode\" format is for inspecting values, not for CSS rendering.\n * @param format \"hex\", \"rgb\", \"rgba\", or \"mode\" which means using current color mode label. Default is \"mode\".\n */\n toString(format: \"hex\" | \"rgb\" | \"rgba\" | \"mode\" = \"mode\"): string {\n // CSS formats need full-range values; a normalized color would floor to 0\n const v: Color | this =\n this._isNorm && format !== \"mode\" ? Color._denorm(this) : this;\n if (format == \"hex\") {\n const _hex = (n: number) => {\n const s = Math.floor(n).toString(16);\n return s.length < 2 ? \"0\" + s : s;\n };\n return `#${_hex(v[0])}${_hex(v[1])}${_hex(v[2])}`;\n } else if (format == \"rgba\") {\n return `rgba(${Math.floor(v[0])},${Math.floor(v[1])},${Math.floor(v[2])},${this.alpha})`;\n } else if (format == \"rgb\") {\n return `rgb(${Math.floor(v[0])},${Math.floor(v[1])},${Math.floor(v[2])})`;\n } else {\n return `${this._mode}(${this[0]},${this[1]},${this[2]},${this.alpha})`;\n }\n }\n\n /**\n * A static function to convert RGB to HSL.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new HSL Color\n */\n static RGBtoHSL(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const [r, g, b] = !normalizedInput ? rgb.$normalize() : rgb;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h = (max + min) / 2;\n let s = h;\n const l = h;\n\n if (max == min) {\n h = 0;\n s = 0; // achromatic\n } else {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n h = 0;\n if (max === r) {\n h = (g - b) / d + (g < b ? 6 : 0);\n } else if (max === g) {\n h = (b - r) / d + 2;\n } else if (max === b) {\n h = (r - g) / d + 4;\n }\n }\n\n const cc = Color.hsl(normalizedOutput ? h / 6 : h * 60, s, l, rgb.alpha);\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert HSL to RGB.\n * @param hsl a HSL Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static HSLtoRGB(\n hsl: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n let [h, s, l] = hsl;\n if (!normalizedInput) h = h / 360;\n h = h - Math.floor(h); // wrap hue into [0, 1)\n\n const sc = normalizedOutput ? 1 : 255;\n if (s == 0) {\n const gray = Color.rgb(sc * l, sc * l, sc * l, hsl.alpha);\n if (normalizedOutput) gray.normalized = true;\n return gray;\n }\n\n const q = l <= 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n const convert = (t: number) => {\n t = t < 0 ? t + 1 : t > 1 ? t - 1 : t;\n if (t * 6 < 1) {\n return p + (q - p) * t * 6;\n } else if (t * 2 < 1) {\n return q;\n } else if (t * 3 < 2) {\n return p + (q - p) * (2 / 3 - t) * 6;\n } else {\n return p;\n }\n };\n\n const cc = Color.rgb(\n sc * convert(h + 1 / 3),\n sc * convert(h),\n sc * convert(h - 1 / 3),\n hsl.alpha,\n );\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert RGB to HSB.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new HSB Color\n */\n static RGBtoHSB(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const [r, g, b] = !normalizedInput ? rgb.$normalize() : rgb;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const d = max - min;\n let h = 0;\n const s = max === 0 ? 0 : d / max;\n const v = max;\n\n if (max != min) {\n if (max === r) {\n h = (g - b) / d + (g < b ? 6 : 0);\n } else if (max === g) {\n h = (b - r) / d + 2;\n } else if (max === b) {\n h = (r - g) / d + 4;\n }\n }\n\n const cc = Color.hsb(normalizedOutput ? h / 6 : h * 60, s, v, rgb.alpha);\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert HSB to RGB.\n * @param hsb a HSB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static HSBtoRGB(\n hsb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n let [h, s, v] = hsb;\n if (!normalizedInput) h = h / 360;\n h = h - Math.floor(h); // wrap hue into [0, 1)\n\n const i = Math.floor(h * 6);\n const f = h * 6 - i;\n const p = v * (1 - s);\n const q = v * (1 - f * s);\n const t = v * (1 - (1 - f) * s);\n\n const pick = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q],\n ];\n const c = pick[i % 6];\n\n const sc = normalizedOutput ? 1 : 255;\n\n const cc = Color.rgb(sc * c[0], sc * c[1], sc * c[2], hsb.alpha);\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert RGB to LAB.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LAB Color\n */\n static RGBtoLAB(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(rgb) : rgb;\n return Color.XYZtoLAB(Color.RGBtoXYZ(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert LAB to RGB.\n * @param lab a LAB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static LABtoRGB(\n lab: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(lab) : lab;\n return Color.XYZtoRGB(Color.LABtoXYZ(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert RGB to LCH.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LCH Color\n */\n static RGBtoLCH(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(rgb) : rgb;\n return Color.LABtoLCH(Color.RGBtoLAB(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert LCH to RGB.\n * @param lch a LCH Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static LCHtoRGB(\n lch: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(lch) : lch;\n return Color.LABtoRGB(Color.LCHtoLAB(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert RGB to LUV.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LUV Color\n */\n static RGBtoLUV(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(rgb) : rgb;\n return Color.XYZtoLUV(Color.RGBtoXYZ(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert LUV to RGB.\n * @param luv a LUV Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static LUVtoRGB(\n luv: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(luv) : luv;\n return Color.XYZtoRGB(Color.LUVtoXYZ(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert RGB to XYZ.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new XYZ Color\n */\n static RGBtoXYZ(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = !normalizedInput ? rgb.$normalize() : rgb.clone();\n\n for (let i = 0; i < 3; i++) {\n c[i] =\n c[i] > 0.04045 ? Math.pow((c[i] + 0.055) / 1.055, 2.4) : c[i] / 12.92;\n c[i] = c[i] * 100;\n }\n\n const cc = Color.xyz(\n c[0] * 0.4124564 + c[1] * 0.3575761 + c[2] * 0.1804375,\n c[0] * 0.2126729 + c[1] * 0.7151522 + c[2] * 0.072175,\n c[0] * 0.0193339 + c[1] * 0.119192 + c[2] * 0.9503041,\n rgb.alpha,\n );\n\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert XYZ to RGB.\n * @param xyz a XYZ Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static XYZtoRGB(\n xyz: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const [x, y, z] = !normalizedInput ? xyz.$normalize() : xyz;\n\n const rgb = [\n x * 3.2406254773200533 +\n y * -1.5372079722103187 +\n z * -0.4986285986982479,\n x * -0.9689307147293197 +\n y * 1.8757560608852415 +\n z * 0.041517523842953964,\n x * 0.055710120445510616 +\n y * -0.2040210505984867 +\n z * 1.0569959422543882,\n ];\n\n // convert xyz to rgb. Note that not all colors are visible in rgb, so here we bound rgb between 0 to 1\n for (let i = 0; i < 3; i++) {\n rgb[i] =\n rgb[i] > 0.0031308\n ? 1.055 * Math.pow(rgb[i], 1 / 2.4) - 0.055\n : 12.92 * rgb[i];\n rgb[i] = Math.max(0, Math.min(1, rgb[i]));\n if (!normalizedOutput) rgb[i] = Math.round(rgb[i] * 255);\n }\n\n const cc = Color.rgb(rgb[0], rgb[1], rgb[2], xyz.alpha);\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert XYZ to LAB.\n * @param xyz a XYZ Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LAB Color\n */\n static XYZtoLAB(\n xyz: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(xyz) : xyz.clone();\n const eps = 216 / 24389;\n const kap = 24389 / 27;\n\n // adjust for D65\n c.divide(Color.D65);\n\n const fn = (n: number) => (n > eps ? Math.cbrt(n) : (kap * n + 16) / 116);\n const cy = fn(c[1]);\n\n const cc = Color.lab(\n 116 * cy - 16,\n 500 * (fn(c[0]) - cy),\n 200 * (cy - fn(c[2])),\n xyz.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert LAB to XYZ.\n * @param lab a LAB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new XYZ Color\n */\n static LABtoXYZ(\n lab: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(lab) : lab;\n const y = (c[0] + 16) / 116;\n const x = c[1] / 500 + y;\n const z = y - c[2] / 200;\n const eps = 216 / 24389;\n const kap = 24389 / 27;\n\n const d = Color.D65;\n const xxx = Math.pow(x, 3);\n const zzz = Math.pow(z, 3);\n\n // adjusted\n const cc = Color.xyz(\n d[0] * (xxx > eps ? xxx : (116 * x - 16) / kap),\n d[1] * (c[0] > kap * eps ? Math.pow((c[0] + 16) / 116, 3) : c[0] / kap),\n d[2] * (zzz > eps ? zzz : (116 * z - 16) / kap),\n lab.alpha,\n );\n\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert XYZ to LUV.\n * @param xyz a XYZ Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LUV Color\n */\n static XYZtoLUV(\n xyz: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n let [x, y, z] = normalizedInput ? Color._denorm(xyz) : xyz;\n // black has no chromaticity, so pin u'v' to avoid 0/0\n const den = x + 15 * y + 3 * z;\n const u = den === 0 ? 0 : (4 * x) / den;\n const v = den === 0 ? 0 : (9 * y) / den;\n\n const eps = 216 / 24389;\n const kap = 24389 / 27;\n y = y / 100;\n const L = y > eps ? 116 * Math.cbrt(y) - 16 : kap * y;\n\n const refU =\n (4 * Color.D65[0]) /\n (Color.D65[0] + 15 * Color.D65[1] + 3 * Color.D65[2]);\n const refV =\n (9 * Color.D65[1]) /\n (Color.D65[0] + 15 * Color.D65[1] + 3 * Color.D65[2]);\n\n const cc = Color.luv(\n L,\n 13 * L * (u - refU),\n 13 * L * (v - refV),\n xyz.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert LUV to XYZ.\n * @param luv a LUV Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new XYZ Color\n */\n static LUVtoXYZ(\n luv: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n let [l, u, v] = normalizedInput ? Color._denorm(luv) : luv;\n\n const eps = 216 / 24389;\n const kap = 24389 / 27;\n // black carries no chromaticity information\n if (l === 0) {\n const black = Color.xyz(0, 0, 0, luv.alpha);\n return normalizedOutput ? Color._normOut(black) : black;\n }\n\n const fy = (l + 16) / 116;\n let y = l > kap * eps ? fy * fy * fy : l / kap;\n\n const refU =\n (4 * Color.D65[0]) /\n (Color.D65[0] + 15 * Color.D65[1] + 3 * Color.D65[2]);\n const refV =\n (9 * Color.D65[1]) /\n (Color.D65[0] + 15 * Color.D65[1] + 3 * Color.D65[2]);\n\n u = u / (13 * l) + refU;\n v = v / (13 * l) + refV;\n\n y = y * 100;\n const x = (-1 * (9 * y * u)) / ((u - 4) * v - u * v);\n const z = (9 * y - 15 * v * y - v * x) / (3 * v);\n\n const cc = Color.xyz(x, y, z, luv.alpha);\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert LAB to LCH.\n * @param lab a LAB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LCH Color\n */\n static LABtoLCH(\n lab: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(lab) : lab;\n const h = Geom.toDegree(Geom.boundRadian(Math.atan2(c[2], c[1]))); // 0 to 360 degrees\n const cc = Color.lch(\n c[0],\n Math.sqrt(c[1] * c[1] + c[2] * c[2]),\n h,\n lab.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert LCH to LAB.\n * @param lch a LCH Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LAB Color\n */\n static LCHtoLAB(\n lch: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(lch) : lch;\n const rad = Geom.toRadian(c[2]);\n const cc = Color.lab(\n c[0],\n Math.cos(rad) * c[1],\n Math.sin(rad) * c[1],\n lch.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert RGB to OKLAB (Ottosson 2020, as specified in CSS Color 4). OKLAB improves on LAB's perceptual uniformity, especially hue stability in blues.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new OKLAB Color\n */\n static RGBtoOKLAB(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = !normalizedInput ? rgb.$normalize() : rgb;\n const lin = (v: number) =>\n v > 0.04045 ? Math.pow((v + 0.055) / 1.055, 2.4) : v / 12.92;\n const r = lin(c[0]);\n const g = lin(c[1]);\n const b = lin(c[2]);\n\n // linear sRGB -> LMS cone response, then cube root\n const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);\n const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);\n const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);\n\n const cc = Color.oklab(\n 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,\n 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,\n rgb.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert OKLAB to RGB. Out-of-gamut results are clamped to the sRGB range.\n * @param oklab an OKLAB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static OKLABtoRGB(\n oklab: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(oklab) : oklab;\n\n const l_ = c[0] + 0.3963377774 * c[1] + 0.2158037573 * c[2];\n const m_ = c[0] - 0.1055613458 * c[1] - 0.0638541728 * c[2];\n const s_ = c[0] - 0.0894841775 * c[1] - 1.291485548 * c[2];\n const l = l_ * l_ * l_;\n const m = m_ * m_ * m_;\n const s = s_ * s_ * s_;\n\n const rgb = [\n 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,\n -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,\n -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s,\n ];\n\n for (let i = 0; i < 3; i++) {\n rgb[i] =\n rgb[i] > 0.0031308\n ? 1.055 * Math.pow(rgb[i], 1 / 2.4) - 0.055\n : 12.92 * rgb[i];\n rgb[i] = Math.max(0, Math.min(1, rgb[i]));\n if (!normalizedOutput) rgb[i] = Math.round(rgb[i] * 255);\n }\n\n const cc = Color.rgb(rgb[0], rgb[1], rgb[2], oklab.alpha);\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert RGB to OKLCH, the cylindrical form of OKLAB as specified in CSS Color 4.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new OKLCH Color\n */\n static RGBtoOKLCH(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(rgb) : rgb;\n return Color.OKLABtoOKLCH(Color.RGBtoOKLAB(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert OKLCH to RGB. Out-of-gamut results are clamped to the sRGB range.\n * @param oklch an OKLCH Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static OKLCHtoRGB(\n oklch: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(oklch) : oklch;\n return Color.OKLABtoRGB(Color.OKLCHtoOKLAB(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert OKLAB to OKLCH.\n * @param oklab an OKLAB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new OKLCH Color\n */\n static OKLABtoOKLCH(\n oklab: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(oklab) : oklab;\n const h = Geom.toDegree(Geom.boundRadian(Math.atan2(c[2], c[1]))); // 0 to 360 degrees\n const cc = Color.oklch(\n c[0],\n Math.sqrt(c[1] * c[1] + c[2] * c[2]),\n h,\n oklab.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert OKLCH to OKLAB.\n * @param oklch an OKLCH Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new OKLAB Color\n */\n static OKLCHtoOKLAB(\n oklch: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(oklch) : oklch;\n const rad = Geom.toRadian(c[2]);\n const cc = Color.oklab(\n c[0],\n Math.cos(rad) * c[1],\n Math.sin(rad) * c[1],\n oklch.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { MultiTouchSpace } from \"./Space\";\nimport { type Form, VisualForm, Font } from \"./Form\";\nimport { Util } from \"./Util\";\nimport { Pt, Bound } from \"./Pt\";\nimport {\n type PtLike,\n type GroupLike,\n type IPlayer,\n type DOMFormContext,\n type PtLikeIterable,\n} from \"./Types\";\n\n/**\n * DOMSpace hosts a Space in a DOM element. It is the subclassing entry point for building\n * custom element-based spaces; usually its subclass [`SVGSpace`](#link) should be used instead.\n * Learn more about spaces in [this guide](../guide/Space-0500.html).\n *\n * When using a Space inside a component framework, create it on mount and call\n * [`DOMSpace.dispose`](#link) on unmount so listeners and the animation loop are released.\n * For example, in React:\n * ```\n * useEffect(() => {\n * const space = new SVGSpace(ref.current).setup({ resize: true });\n * space.add(...).play();\n * return () => { space.dispose(); };\n * }, []);\n * ```\n * Dispose is idempotent, and a new Space can be mounted on the same element afterwards\n * (as happens under React's StrictMode).\n */\nexport class DOMSpace extends MultiTouchSpace {\n protected _canvas: HTMLElement | SVGElement;\n protected _container: Element;\n\n id: string = \"domspace\";\n protected _autoResize = true;\n protected _bgcolor = \"#e1e9f0\";\n protected _css = {};\n private _domDisposed = false;\n private _readyTimer: ReturnType<typeof setTimeout>;\n // elements this space created for a missing target, removed on dispose\n private _ownsContainer = false;\n\n // one stable bound reference, so removeEventListener actually removes the\n // listener that addEventListener added (and double-adds dedupe)\n private readonly _resizeHandlerBound = this._resizeHandler.bind(this);\n\n /**\n * Create a DOMSpace for HTML DOM elements\n * @param elem Specify an element by its \"id\" attribute as string, or by the element object itself. If left empty, a `<div id=\"pt_container\"><div id=\"pt\" /></div>` will be added to DOM; a missing id is created the same way. Use css to customize its appearance if needed.\n * @param callback an optional callback `function(boundingBox, spaceElement)` to be called when element is appended and ready. Alternatively, a \"ready\" event will also be fired from the element when it's appended, which can be traced with `spaceInstance.element.addEventListener(\"ready\")`\n * @example `new DOMSpace( \"#myElementID\" )`\n */\n constructor(\n elem: string | Element | null = \"pt\",\n callback?: (bound: Bound, elem: Element) => void,\n ) {\n super();\n this.refresh(false); // DOM elements persist unless a renderer opts into refreshing.\n\n let _selector: Element | null = null;\n this.id = \"pts\";\n\n // check element or element id string\n if (elem instanceof Element) {\n _selector = elem;\n this.id = \"pts_existing_space\";\n } else {\n const target = elem || \"pt\";\n const id = target[0] === \"#\" || target[0] === \".\" ? target : \"#\" + target;\n _selector = document.querySelector(id);\n this.id = id.substr(1);\n }\n\n // if selector is not defined, create the elements\n if (!_selector) {\n this._container = DOMSpace.createElement(\"div\", this.id + \"_container\");\n this._canvas = this._createDefaultElement(this._container, this.id);\n document.body.appendChild(this._container);\n this._ownsContainer = true;\n } else {\n this._canvas = _selector as HTMLElement;\n this._container = _selector.parentElement!;\n }\n\n // no mutation observer, so we set a timeout for ready event\n this._readyTimer = setTimeout(this._ready.bind(this, callback), 50);\n }\n\n /**\n * Create the drawing element for a target that does not exist yet, inside the created container.\n * Subclasses that draw into a specific element type override this.\n * @param container the created container\n * @param id the id for the new element\n */\n protected _createDefaultElement(\n container: Element,\n id: string,\n ): HTMLElement | SVGElement {\n return DOMSpace.createElement(\"div\", id, container) as HTMLElement;\n }\n\n /**\n * Helper function to create a DOM element.\n * @param elem element tag name\n * @param id element id attribute\n * @param appendTo Optional, if specified, the created element will be appended to this element\n */\n static createElement(\n elem: string = \"div\",\n id: string,\n appendTo?: Element,\n ): Element {\n let d = document.createElement(elem);\n if (id) d.setAttribute(\"id\", id);\n if (appendTo && appendTo.appendChild) appendTo.appendChild(d);\n return d;\n }\n\n /**\n * Handle callbacks after element is mounted in DOM.\n * @param callback\n */\n private _ready(callback?: (bound: Bound, elem: Element) => void) {\n if (this._domDisposed) return;\n if (!this._container)\n throw new Error(`Cannot initiate #${this.id} element`);\n\n this._isReady = true;\n\n this._resizeHandler(null);\n this.clear(this._bgcolor);\n this._canvas.dispatchEvent(new Event(\"ready\"));\n\n for (let k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n if (this.players[k].start)\n this.players[k].start(this.bound.clone(), this);\n }\n }\n\n this._pointer = this.center;\n\n if (callback) callback(this.bound, this._canvas);\n }\n\n /**\n * Set up various options for DOMSpace. This is usually set during instantiation, eg `new DOMSpace(...).setup( {opt} )`.\n * @param opt an object with these optional properties: **bgcolor** is a hex or rgba string to set initial background color of the canvas, or use `false` or \"transparent\" to set a transparent background; **resize** a boolean to set whether `<canvas>` size should auto resize to match its container's size, which can also be set using `autoSize()`.\n * @example `space.setup({ bgcolor: \"#f00\", resize: true })`\n */\n setup(opt: { bgcolor?: string; resize?: boolean }): this {\n if (opt.bgcolor) {\n this._bgcolor = opt.bgcolor;\n }\n\n this.autoResize = opt.resize != undefined ? opt.resize : false;\n\n return this;\n }\n\n /**\n * Not implemented. See SVGSpace and HTMLSpace for implementation.\n */\n getForm(): Form {\n return null as unknown as Form;\n }\n\n /**\n * Set whether the canvas element should resize when its container is resized.\n * @param auto a boolean value indicating if auto size is set\n */\n set autoResize(auto: boolean) {\n this._autoResize = auto;\n if (auto) {\n window.addEventListener(\"resize\", this._resizeHandlerBound);\n } else {\n delete (this._css as any)[\"width\"];\n delete (this._css as any)[\"height\"];\n window.removeEventListener(\"resize\", this._resizeHandlerBound);\n }\n }\n get autoResize(): boolean {\n return this._autoResize;\n }\n\n /**\n * This overrides Space's `resize` function. It's used as a callback function for window's resize event and not usually called directly. You can keep track of resize events with `resize: (bound, evt)` callback in your player objects (See [`Space.add`](#link) function).\n * @param b a Bound object to resize to\n * @param evt Optionally pass a resize event\n */\n resize(b: Bound, evt?: Event | null): this {\n this.bound = b;\n this.styles({ width: `${b.width}px`, height: `${b.height}px` }, true);\n\n for (let k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n let p = this.players[k];\n if (p.resize) p.resize(this.bound, evt);\n }\n }\n\n return this;\n }\n\n /**\n * Window resize handling.\n * @param evt\n */\n protected _resizeHandler(evt: Event | null) {\n let b = Bound.fromBoundingRect(this._container.getBoundingClientRect());\n\n if (this._autoResize) {\n this.styles({ width: \"100%\", height: \"100%\" }, true);\n } else {\n this.styles({ width: `${b.width}px`, height: `${b.height}px` }, true);\n }\n\n this.resize(b, evt);\n }\n\n /**\n * Get this DOM element.\n */\n get element(): Element {\n return this._canvas;\n }\n\n /**\n * Get the parent DOM element that contains this DOM element.\n */\n get parent(): Element {\n return this._container;\n }\n\n /**\n * A property to indicate if the Space is ready.\n */\n get ready(): boolean {\n return this._isReady;\n }\n\n /**\n * Clear the element's contents, and optionally set a new background color. This overrides Space's `clear` function.\n * @param bg Optionally specify a custom background color in hex or rgba string, or \"transparent\". If not defined, it will use its `bgcolor` property as background color to clear the canvas.\n */\n clear(bg?: string): this {\n if (bg) this.background = bg;\n this._canvas.innerHTML = \"\";\n return this;\n }\n\n /**\n * Set a background color on the container element.\n @param bg background color as hex or rgba string\n */\n set background(bg: string) {\n this._bgcolor = bg;\n (this._container as HTMLElement).style.backgroundColor = this._bgcolor;\n }\n get background(): string {\n return this._bgcolor;\n }\n\n /**\n * Add or update a style definition, and optionally update that style in the Element.\n * @param key style name\n * @param val style value\n * @param update a boolean to update the element's style immediately if set to `true`. Default is `false`.\n */\n style(key: string, val: string, update: boolean = false): this {\n (this._css as any)[key] = val;\n if (update) (this._canvas.style as any)[key] = val;\n return this;\n }\n\n /**\n * Add of update a list of style definitions, and optionally update those styles in the Element.\n * @param styles a key-value objects of style definitions\n * @param update a boolean to update the element's style immediately if set to `true`. Default is `false`.\n * @return this\n */\n styles(styles: Record<string, string>, update: boolean = false): this {\n for (let k in styles) {\n if (styles.hasOwnProperty(k)) this.style(k, (styles as any)[k], update);\n }\n return this;\n }\n\n /**\n * A static helper function to add or update Element attributes.\n * @param elem Element to update\n * @param data an object with key-value pairs\n * @returns this DOM element\n */\n static setAttr(elem: Element, data: Record<string, any>): Element {\n for (let k in data) {\n if (data.hasOwnProperty(k)) {\n elem.setAttribute(k, (data as any)[k]);\n }\n }\n return elem;\n }\n\n /**\n * A static helper function to compose an inline style string from a object of styles.\n * @param data an object with key-value pairs\n * @example `DOMSpace.getInlineStyles( {width: \"100px\", \"font-size\": \"10px\"} )`\n */\n static getInlineStyles(data: Record<string, any>): string {\n let str = \"\";\n for (let k in data) {\n if (data.hasOwnProperty(k)) {\n if ((data as any)[k]) str += `${k}: ${(data as any)[k]}; `;\n }\n }\n return str;\n }\n\n /**\n * Dispose of browser resources held by this space and remove all players. Call this before\n * unmounting the DOM, eg in a framework component's unmount/cleanup callback. Dispose is\n * idempotent, and a new Space can be created on the same element afterwards.\n */\n dispose(): this {\n if (this._domDisposed) return this;\n this._domDisposed = true;\n clearTimeout(this._readyTimer);\n\n this.autoResize = false; // removes the window resize listener\n this._unbindAll(); // removes mouse/touch listeners on the element\n this._cancelAnimation(); // cancels the animation frame immediately\n\n // Remove the players without the subclass's DOM-clearing `removeAll`:\n // disposing must release resources, never destroy a user-owned host\n // element's contents (a re-mount on the same element must work).\n MultiTouchSpace.prototype.removeAll.call(this);\n this._isReady = false;\n // elements created for a missing target are this space's own\n if (this._ownsContainer) this._container.remove();\n\n return this;\n }\n}\n\n/**\n * @deprecated HTML rendering is deprecated and will be removed in a future major version. Use [`SVGSpace`](#link) for DOM-based output instead — it shares the supported subset of the [`CanvasForm`](#link) drawing API.\n * **[Experimental]** HTMLSpace is a subclass of DOMSpace that works with HTML elements. See [a demo here](https://ptsjs.org/demo/?name=htmlform.scope).\n */\nexport class HTMLSpace extends DOMSpace {\n /**\n * Get a new `HTMLForm` which provides visualization functions in html elements.\n * @see `HTMLForm`\n */\n getForm(): Form {\n return new HTMLForm(this);\n }\n\n /**\n * A static function to add a DOM element inside a node. Usually you don't need to use this directly. See methods in [`HTMLForm`](#link) instead.\n * @param parent the parent element, or `null` to use current `<svg>` as parent.\n * @param name a string of element name, such as `rect` or `circle`\n * @param id id attribute of the new element\n * @param autoClass add a class based on the id (from char 0 to index of \"-\"). Default is true.\n */\n static htmlElement(\n parent: Element | null | undefined,\n name: string,\n id?: string,\n autoClass: boolean = true,\n ): HTMLElement {\n if (!parent || !parent.appendChild)\n throw new Error(\"parent is not a valid DOM element\");\n\n // O(1) id lookup, then verify it's inside the parent so a same-id\n // element elsewhere in the document is never silently adopted\n let elem: Element | null = document.getElementById(id!);\n if (elem && !parent.contains(elem)) elem = null;\n if (!elem) {\n elem = document.createElement(name);\n elem.setAttribute(\"id\", id!);\n\n if (autoClass)\n elem.setAttribute(\"class\", id!.substring(0, id!.indexOf(\"-\")));\n parent.appendChild(elem);\n }\n return elem as HTMLElement;\n }\n\n /**\n * Remove an item from this space.\n * @param player a player item with an auto-assigned `animateID` property\n */\n remove(player: IPlayer): this {\n let temp = this._container.querySelectorAll(\".\" + HTMLForm.scopeID(player));\n\n temp.forEach((el: Element) => {\n el.parentNode!.removeChild(el);\n });\n\n return super.remove(player);\n }\n\n /**\n * Remove all items from this space. This clears the contents of the space's\n * element but never touches its container.\n */\n removeAll(): this {\n this._canvas.innerHTML = \"\";\n return super.removeAll();\n }\n}\n\nlet _htmlFormGroupID = 0;\nlet _htmlFormDomID = 0;\n\n/**\n * @deprecated HTML rendering is deprecated and will be removed in a future major version. Use [`SVGForm`](#link) for DOM-based output instead — it shares the complete [`CanvasForm`](#link) drawing API.\n * **[Experimental]** HTMLForm is an implementation of abstract class [`VisualForm`](#link). It provide methods to express Pts on [`HTMLSpace`](#link).\n */\nexport class HTMLForm extends VisualForm {\n /**\n * store common styles so that they can be restored to canvas context when using multiple forms. See `reset()`.\n */\n protected _style = {\n filled: true,\n stroked: true,\n background: \"#f03\",\n \"border-color\": \"#fff\",\n color: \"#000\",\n \"border-width\": \"1px\",\n \"border-radius\": \"0\",\n \"border-style\": \"solid\",\n opacity: 1,\n position: \"absolute\",\n top: 0,\n left: 0,\n width: 0,\n height: 0,\n };\n\n protected _ctx: DOMFormContext = {\n group: null,\n groupID: \"pts\",\n groupCount: 0,\n currentID: \"pts0\",\n currentClass: \"\",\n style: {},\n };\n\n // mutable statics are stored at module level and exposed through accessors so\n // no post-class assignment is emitted (which would defeat tree-shaking)\n static get groupID(): number {\n return _htmlFormGroupID;\n }\n static set groupID(n: number) {\n _htmlFormGroupID = n;\n }\n static get domID(): number {\n return _htmlFormDomID;\n }\n static set domID(n: number) {\n _htmlFormDomID = n;\n }\n\n protected _space: HTMLSpace;\n protected _ready: boolean = false;\n protected _formID: number = 0;\n\n /**\n * Create a new `HTMLForm`. Alternatively, you can use [`HTMLSpace.getForm`](#link) function to get an instance of HTMLForm.\n * @param space the space to use\n */\n constructor(space: HTMLSpace) {\n super();\n this._space = space;\n this._formID = HTMLForm.groupID++;\n\n const init = () => {\n this._ctx.group = this._space.element;\n this._ctx.groupID = `pts_dom_${this._formID}`;\n this._ctx.style = Object.assign({}, this._style);\n this._ready = true;\n };\n // a form created after the space is ready would otherwise never\n // initialize, since start callbacks only run at readiness\n if (this._space.ready) init();\n else this._space.add({ start: init });\n }\n\n /**\n * Get the corresponding space for this form\n */\n get space(): HTMLSpace {\n return this._space;\n }\n\n /**\n * Usually not used directly. This updates a style in `_ctx` context or throw an Error if the style doesn't exist.\n * @param k style key\n * @param v style value\n * @param unit Optional unit like 'px' to append to value\n */\n protected styleTo(k: string, v: any, unit: string = \"\") {\n if ((this._ctx.style as any)[k] === undefined)\n throw new Error(`${k} style property doesn't exist`);\n this._ctx.style[k] = `${v}${unit}`;\n }\n\n /**\n * Set current alpha value.\n * @example `form.alpha(0.6)`\n * @param a alpha value between 0 and 1\n */\n alpha(a: number): this {\n this.styleTo(\"opacity\", a);\n return this;\n }\n\n /**\n * Set current fill style. Provide a valid color string or `false` to specify no fill color.\n * @example `form.fill(\"#F90\")`, `form.fill(\"rgba(0,0,0,.5\")`, `form.fill(false)`\n * @param c fill color\n */\n fill(c: string | boolean): this {\n if (typeof c == \"boolean\") {\n this.styleTo(\"filled\", c);\n if (!c) this.styleTo(\"background\", \"transparent\");\n } else {\n this.styleTo(\"filled\", true);\n this.styleTo(\"background\", c);\n }\n return this;\n }\n\n /**\n * Set current stroke style. Provide a valid color string or `false` to specify no stroke color.\n * @example `form.stroke(\"#F90\")`, `form.stroke(\"rgba(0,0,0,.5\")`, `form.stroke(false)`, `form.stroke(\"#000\", 0.5, 'round', 'square')`\n * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))\n * @param width Optional value (can be floating point) to set line width\n * @param linejoin not implemented in HTMLForm\n * @param linecap not implemented in HTMLForm\n */\n stroke(\n c: string | boolean,\n width?: number,\n linejoin?: string,\n linecap?: string,\n ): this {\n if (typeof c == \"boolean\") {\n this.styleTo(\"stroked\", c);\n if (!c) this.styleTo(\"border-width\", 0);\n } else {\n this.styleTo(\"stroked\", true);\n this.styleTo(\"border-color\", c);\n this.styleTo(\"border-width\", (width || 1) + \"px\");\n }\n return this;\n }\n\n /**\n * Set current text color style. Provide a valid color string.\n * @example `form.fill(\"#F90\")`, `form.fill(\"rgba(0,0,0,.5\")`, `form.fill(false)`\n * @param c fill color\n */\n fillText(c: string): this {\n this.styleTo(\"color\", c);\n return this;\n }\n\n /**\n * Add custom class to the created element.\n * @param c custom class name or `false` to reset it\n * @example `form.fill(\"#f00\").cls(\"myClass\").rects(r)` `form.cls(false).circles(c)`\n */\n cls(c: string | boolean) {\n if (typeof c == \"boolean\") {\n this._ctx.currentClass = \"\";\n } else {\n this._ctx.currentClass = c;\n }\n return this;\n }\n\n /**\n * Set the current font.\n * @param sizeOrFont either a number to specify font-size, or a `Font` object to specify all font properties\n * @param weight Optional font-weight string such as \"bold\"\n * @param style Optional font-style string such as \"italic\"\n * @param lineHeight Optional line-height number suchas 1.5\n * @param family Optional font-family such as \"Helvetica, sans-serif\"\n * @example `form.font( myFont )`, `form.font(14, \"bold\")`\n */\n font(\n sizeOrFont: number | Font,\n weight?: string,\n style?: string,\n lineHeight?: number,\n family?: string,\n ): this {\n if (typeof sizeOrFont == \"number\") {\n this._font.size = sizeOrFont;\n if (family) this._font.face = family;\n if (weight) this._font.weight = weight;\n if (style) this._font.style = style;\n if (lineHeight) this._font.lineHeight = lineHeight;\n } else {\n this._font = sizeOrFont;\n }\n\n this._ctx.style[\"font\"] = this._font.value;\n\n return this;\n }\n\n /**\n * Reset the context's common styles to this form's styles. This supports using multiple forms on the same canvas context.\n */\n reset(): this {\n this._ctx.style = Object.assign({}, this._style);\n\n this._font = new Font(10, \"sans-serif\");\n this._ctx.style[\"font\"] = this._font.value;\n\n return this;\n }\n\n /**\n * Set this form's group scope by an ID, and optionally define the group's parent element. A group scope keeps track of elements by their generated IDs, and updates their properties as needed. See also `scope()`.\n * @param group_id a string to use as prefix for the group's id. For example, group_id \"hello\" will create elements with id like \"hello-1\", \"hello-2\", etc\n * @param group Optional DOM element to define this group's parent element\n * @returns this form's context\n */\n updateScope(group_id: string, group?: Element): DOMFormContext {\n this._ctx.group = group;\n this._ctx.groupID = group_id;\n this._ctx.groupCount = 0;\n this.nextID();\n return this._ctx;\n }\n\n /**\n * Set the current group scope to an item added into space, in order to keep track of any point, circle, etc created within it. The item must have an `animateID` property, so that elements created within the item will have generated IDs like \"item-{animateID}-{count}\".\n * @param item a \"player\" item that's added to space (see `space.add(...)`) and has an `animateID` property\n * @returns this form's context\n */\n scope(item: IPlayer) {\n if (!item || item.animateID == null)\n throw new Error(\"item not defined or not yet added to Space\");\n // two forms scoped to the same player must not generate the same ids\n return this.updateScope(\n `${HTMLForm.scopeID(item)}-f${this._formID}`,\n this.space.element,\n );\n }\n\n /**\n * Get next available id in the current group.\n * @returns an id string\n */\n nextID(): string {\n this._ctx.groupCount++;\n this._ctx.currentID = `${this._ctx.groupID}-${this._ctx.groupCount}`;\n return this._ctx.currentID;\n }\n\n /**\n * A static function to generate an ID string based on a context object.\n * @param ctx a context object for an HTMLForm\n */\n static getID(ctx: DOMFormContext): string {\n return ctx.currentID || `p-${HTMLForm.domID++}`;\n }\n\n /**\n * A static function to generate an ID string for a scope, based on a \"player\" item in the Space.\n * @param item a \"player\" item that's added to space (see `space.add(...)`) and has an `animateID` property\n */\n static scopeID(item: IPlayer): string {\n return `item-${item.animateID}`;\n }\n\n /**\n * A static function to help adding style object to an element. This put all styles into `style` attribute instead of individual attributes, so that the styles can be parsed by Adobe Illustrator.\n * @param elem A DOM element to add to\n * @param styles an object of style properties\n * @example `HTMLForm.style(elem, {fill: \"#f90\", stroke: false})`\n * @returns DOM element\n */\n static style(elem: Element, styles: Record<string, any>): Element {\n let st = [];\n\n if (!styles[\"filled\"]) st.push(\"background: none\");\n if (!styles[\"stroked\"]) st.push(\"border: none\");\n\n for (let k in styles) {\n if (styles.hasOwnProperty(k) && k != \"filled\" && k != \"stroked\") {\n let v = styles[k];\n if (v) {\n if (!styles[\"filled\"] && k.indexOf(\"background\") === 0) {\n continue;\n } else if (!styles[\"stroked\"] && k.indexOf(\"border-width\") === 0) {\n continue;\n } else {\n st.push(`${k}: ${v}`);\n }\n }\n }\n }\n\n return HTMLSpace.setAttr(elem, { style: st.join(\";\") });\n }\n\n /**\n * A helper function to set top, left, width, height of DOM element.\n * @param ctx the HTMLForm context whose style is updated\n * @param pt left and top position\n * @param size width and height\n */\n static rectStyle(\n ctx: DOMFormContext,\n pt: PtLike,\n size: PtLike,\n ): DOMFormContext {\n ctx.style[\"left\"] = pt[0] + \"px\";\n ctx.style[\"top\"] = pt[1] + \"px\";\n ctx.style[\"width\"] = size[0] + \"px\";\n ctx.style[\"height\"] = size[1] + \"px\";\n return ctx;\n }\n\n /**\n * A helper function to set the top and left position styling of text DOM context.\n * @param ctx context to add style to\n * @param pt a Pt object or numeric array determining the top-left position of the text\n */\n static textStyle(ctx: DOMFormContext, pt: PtLike): DOMFormContext {\n ctx.style[\"left\"] = pt[0] + \"px\";\n ctx.style[\"top\"] = pt[1] + \"px\";\n return ctx;\n }\n\n /**\n * A static function to draws a point.\n * @param ctx a context object of HTMLForm\n * @param pt a Pt object or numeric array\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `HTMLForm.point( p )`, `HTMLForm.point( p, 10, \"circle\" )`\n */\n static point(\n ctx: DOMFormContext,\n pt: PtLike,\n radius: number = 5,\n shape: string = \"square\",\n ): Element {\n if (shape === \"circle\") {\n return HTMLForm.circle(ctx, pt, radius);\n } else {\n return HTMLForm.square(ctx, pt, radius);\n }\n }\n\n /**\n * Draws a point.\n * @param pt a Pt object\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `form.point( p )`, `form.point( p, 10, \"circle\" )`\n */\n point(pt: PtLike, radius: number = 5, shape: string = \"square\"): this {\n this.nextID();\n // reset radius for squares, so a square after a circle isn't rounded\n this.styleTo(\"border-radius\", shape == \"circle\" ? \"100%\" : \"0\");\n HTMLForm.point(this._ctx, pt, radius, shape);\n return this;\n }\n\n /**\n * A static function to draw a circle.\n * @param ctx a context object of HTMLForm\n * @param pt center position of the circle\n * @param radius radius of the circle\n */\n static circle(ctx: DOMFormContext, pt: PtLike, radius: number = 10): Element {\n let elem = HTMLSpace.htmlElement(ctx.group, \"div\", HTMLForm.getID(ctx));\n HTMLSpace.setAttr(elem, {\n class: `pts-form pts-circle ${ctx.currentClass}`,\n });\n HTMLForm.rectStyle(\n ctx,\n new Pt(pt).$subtract(radius),\n new Pt(radius * 2, radius * 2),\n );\n HTMLForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * Draw a circle.\n * @param pts usually a Group of 2 Pts, but it can also take an array of two numeric arrays [ [position], [size] ]\n * @see [`Circle.fromCenter`](#link)\n */\n circle(pts: GroupLike | number[][]): this {\n this.nextID();\n this.styleTo(\"border-radius\", \"100%\");\n HTMLForm.circle(this._ctx, pts[0], pts[1][0]);\n return this;\n }\n\n /**\n * A static function to draw a square.\n * @param ctx a context object of HTMLForm\n * @param pt center position of the square\n * @param halfsize half size of the square\n */\n static square(ctx: DOMFormContext, pt: PtLike, halfsize: number) {\n let elem = HTMLSpace.htmlElement(ctx.group, \"div\", HTMLForm.getID(ctx));\n HTMLSpace.setAttr(elem, {\n class: `pts-form pts-square ${ctx.currentClass}`,\n });\n HTMLForm.rectStyle(\n ctx,\n new Pt(pt).$subtract(halfsize),\n new Pt(halfsize * 2, halfsize * 2),\n );\n HTMLForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * Draw a square, given a center and its half-size.\n * @param pt center Pt\n * @param halfsize half-size\n */\n square(pt: PtLike, halfsize: number): this {\n this.nextID();\n this.styleTo(\"border-radius\", \"0\");\n HTMLForm.square(this._ctx, pt, halfsize);\n return this;\n }\n\n /**\n * A static function to draw a rectangle.\n * @param ctx a context object of HTMLForm\n * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.\n */\n static rect(ctx: DOMFormContext, pts: PtLikeIterable): Element | undefined {\n let p = Util.iterToArray(pts);\n if (!Util.arrayCheck(p)) return;\n\n let elem = HTMLSpace.htmlElement(ctx.group, \"div\", HTMLForm.getID(ctx));\n HTMLSpace.setAttr(elem, { class: `pts-form pts-rect ${ctx.currentClass}` });\n HTMLForm.rectStyle(ctx, p[0], p[1]);\n HTMLForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * Draw a rectangle.\n * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.\n */\n rect(pts: PtLikeIterable): this {\n this.nextID();\n this.styleTo(\"border-radius\", \"0\");\n HTMLForm.rect(this._ctx, pts);\n return this;\n }\n\n /**\n * A static function to draw text.\n * @param ctx a context object of HTMLForm\n * @param pt a Point object to specify the anchor point\n * @param txt a string of text to draw\n */\n static text(ctx: DOMFormContext, pt: PtLike, txt: string): Element {\n let elem = HTMLSpace.htmlElement(ctx.group, \"div\", HTMLForm.getID(ctx));\n\n HTMLSpace.setAttr(elem, { class: `pts-form pts-text ${ctx.currentClass}` });\n\n elem.textContent = txt;\n HTMLForm.textStyle(ctx, pt);\n HTMLForm.style(elem, ctx.style);\n\n return elem;\n }\n\n /**\n * Draw text in a DOM element.\n * @param pt a Pt or numeric array to specify the anchor point\n * @param txt text\n */\n text(pt: PtLike, txt: string): this {\n this.nextID();\n HTMLForm.text(this._ctx, pt, txt);\n return this;\n }\n\n /**\n * A convenient way to draw some text on canvas for logging or debugging. It'll be draw on the top-left of the canvas as an overlay.\n * @param txt text\n */\n log(txt: any): this {\n this.fill(\"#000\").stroke(\"#fff\", 0.5).text([10, 14], txt);\n return this;\n }\n\n /**\n * Arc is not implemented in HTMLForm.\n */\n arc(\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): this {\n Util.warn(\"arc is not implemented in HTMLForm\");\n return this;\n }\n\n /**\n * Line is not implemented in HTMLForm.\n */\n line(pts: GroupLike | number[][]): this {\n Util.warn(\"line is not implemented in HTMLForm\");\n return this;\n }\n\n /**\n * Polygon is not implemented in HTMLForm.\n * @param pts\n */\n polygon(pts: GroupLike | number[][]): this {\n Util.warn(\"polygon is not implemented in HTMLForm\");\n return this;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { VisualForm, Font } from \"./Form\";\nimport { CanvasForm } from \"./Canvas\";\nimport { Geom } from \"./Num\";\nimport { Const, Util } from \"./Util\";\nimport { Pt, Group, type Bound } from \"./Pt\";\nimport { Rectangle } from \"./Op\";\nimport { DOMSpace } from \"./Dom\";\nimport {\n type PtLike,\n type PtLikeIterable,\n type IPlayer,\n type DOMFormContext,\n type RenderingContext2D,\n} from \"./Types\";\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\n// Canvas composite operations that map directly onto CSS mix-blend-mode.\n// The Porter-Duff subset (\"source-in\" etc.) has no SVG equivalent per-element.\nconst BLEND_MODES = new Set([\n \"multiply\",\n \"screen\",\n \"overlay\",\n \"darken\",\n \"lighten\",\n \"color-dodge\",\n \"color-burn\",\n \"hard-light\",\n \"soft-light\",\n \"difference\",\n \"exclusion\",\n \"hue\",\n \"saturation\",\n \"color\",\n \"luminosity\",\n]);\n\n// module-level so the class stays tree-shakable (a static field would\n// downlevel to a post-class assignment, which bundlers keep)\nlet _gradientCount = 0;\n\n/**\n * A gradient handle returned by [`SVGContext2D`](#link)'s `createLinearGradient` and\n * `createRadialGradient`. It is structurally compatible with `CanvasGradient` (it has\n * `addColorStop`), and materializes into an SVG `<defs>` gradient when first painted.\n */\nclass SVGGradient {\n readonly id: string;\n readonly kind: \"linear\" | \"radial\";\n readonly coords: number[];\n stops: [number, string][] = [];\n protected _elem: SVGElement | null = null;\n\n constructor(kind: \"linear\" | \"radial\", coords: number[]) {\n this.kind = kind;\n this.coords = coords;\n this.id = `pts_grad_${_gradientCount++}`;\n }\n\n addColorStop(offset: number, color: string): void {\n this.stops.push([offset, color]);\n if (this._elem) this._render(this._elem); // already materialized; keep it in sync\n }\n\n /** Create or update the `<defs>` element for this gradient and return its paint url. */\n materialize(defs: SVGElement): string {\n if (!this._elem) {\n this._elem = document.createElementNS(\n SVG_NS,\n this.kind === \"linear\" ? \"linearGradient\" : \"radialGradient\",\n ) as SVGElement;\n this._elem.setAttribute(\"id\", this.id);\n this._elem.setAttribute(\"gradientUnits\", \"userSpaceOnUse\");\n if (this.kind === \"linear\") {\n const [x1, y1, x2, y2] = this.coords;\n DOMSpace.setAttr(this._elem, { x1, y1, x2, y2 });\n } else {\n const [x0, y0, r0, x1, y1, r1] = this.coords;\n DOMSpace.setAttr(this._elem, { cx: x1, cy: y1, r: r1, fx: x0, fy: y0 });\n if (r0) this._elem.setAttribute(\"fr\", `${r0}`);\n }\n this._render(this._elem);\n }\n if (this._elem.parentNode !== defs) defs.appendChild(this._elem);\n return `url(#${this.id})`;\n }\n\n protected _render(elem: SVGElement) {\n elem.textContent = \"\";\n for (const [offset, color] of this.stops) {\n const stop = document.createElementNS(SVG_NS, \"stop\");\n stop.setAttribute(\"offset\", `${offset}`);\n stop.setAttribute(\"stop-color\", color);\n elem.appendChild(stop);\n }\n }\n}\n\n/** A pending draw record produced by SVGContext2D, consumed by the frame commit. */\ntype SVGRun = {\n tag: \"path\" | \"text\" | \"image\";\n attrs: Record<string, string | number>;\n text?: string;\n shapeEnds?: number[]; // per-shape boundaries in the d string, for expanded export\n};\n\n// module-level state for the same tree-shaking reason as _gradientCount above\nlet _svgMeasurer: CanvasRenderingContext2D | null = null;\nconst _svgWarned: { [k: string]: boolean } = {};\n\n/**\n * **`SVGContext2D`** implements the subset of `CanvasRenderingContext2D` that\n * [`CanvasForm`](#link) draws through, and renders it as SVG. Consecutive shapes that share\n * paint state are merged into single `<path>` elements (\"style runs\"), so the DOM cost per\n * frame is proportional to the number of style changes, not the number of shapes. This is\n * what lets sketches using the supported subset run unchanged on canvas and SVG.\n *\n * Capability notes: blend-mode composites map to `mix-blend-mode`; Porter-Duff composites,\n * `clip`, and `putImageData` warn once and no-op. Text metrics come from a hidden canvas, so\n * `textBox` layout matches canvas exactly. When shapes with both fill and stroke are merged,\n * all fills in a run paint before its strokes — visible only for overlapping same-styled\n * shapes.\n *\n * **Writing your own renderer**: this class is the reference implementation of the rendering\n * contract — any object implementing the same context surface can be handed to\n * [`CanvasForm`](#link)'s constructor to become a Pts renderer (a PDF writer, a command\n * recorder, a test snapshotter, and so on). The surface is the subset of\n * `CanvasRenderingContext2D` that `CanvasForm` draws through:\n * - path verbs: `beginPath`, `moveTo`, `lineTo`, `quadraticCurveTo`, `bezierCurveTo`,\n * `rect`, `arc`, `ellipse`, `closePath`\n * - paint: `fill`, `stroke`, `fillRect`, `clearRect`\n * - state: `save`, `restore`, `clip`, `scale`\n * - style fields: `fillStyle`, `strokeStyle`, `lineWidth`, `lineJoin`, `lineCap`,\n * `globalAlpha`, `globalCompositeOperation`, `setLineDash`, `lineDashOffset`\n * - text: `font`, `textAlign`, `textBaseline`, `fillText`, `measureText`\n * - images: `drawImage`, `putImageData`\n * - gradients: `createLinearGradient`, `createRadialGradient`\n *\n * A renderer driven by a Space should also expose a frame lifecycle like\n * [`SVGContext2D.beginFrame`](#link) / [`SVGContext2D.commitFrame`](#link), called around the\n * players' animate callbacks. The unit test \"implements every context member that CanvasForm\n * uses\" is the compatibility alarm: it fails when a new `CanvasForm` feature touches a\n * context member a renderer does not implement.\n */\nexport class SVGContext2D {\n // ---- canvas-compatible state ----\n fillStyle: string | SVGGradient = \"#f03\";\n strokeStyle: string | SVGGradient = \"#fff\";\n lineWidth: number = 1;\n lineJoin: string = \"bevel\";\n lineCap: string = \"butt\";\n globalAlpha: number = 1;\n globalCompositeOperation: string = \"source-over\";\n font: string = \"10px sans-serif\";\n textAlign: string = \"start\";\n textBaseline: string = \"alphabetic\";\n lineDashOffset: number = 0;\n\n protected _dash: number[] = [];\n protected _stateStack: object[] = [];\n\n /** Optional CSS class applied to emitted elements (see `SVGForm.cls`). */\n className: string = \"\";\n\n // ---- current path & shape ----\n protected _d: string = \"\";\n protected _shapeFill: string | null = null; // resolved paint or null\n protected _shapeStroke: string | null = null;\n protected _shapeStrokeStyle: Record<string, string | number> = {};\n protected _shapePainted: boolean = false;\n // class/alpha/blend are captured at paint time (fill/stroke), not at flush\n // time, so a style change between shapes cannot apply retroactively\n protected _shapeClass: string = \"\";\n protected _shapeAlpha: number = 1;\n protected _shapeBlend: string = \"source-over\";\n\n // ---- frame state ----\n protected _runs: SVGRun[] = [];\n protected _drawCount: number = 0;\n\n // ---- DOM ----\n protected _host: SVGElement; // the <svg> element\n protected _group: SVGElement | null = null; // managed <g> holding this context's output\n protected _defs: SVGElement | null = null;\n protected _pool: SVGElement[] = []; // pooled elements, index-aligned with runs\n protected _attrCache: Record<string, string>[] = [];\n\n constructor(host: SVGElement) {\n this._host = host;\n }\n\n protected static _warnOnce(key: string, msg: string) {\n if (!_svgWarned[key]) {\n _svgWarned[key] = true;\n Util.warn(msg);\n }\n }\n\n // -------------------------------------------------------------- lifecycle\n\n /** Start a new frame: subsequent draws build a fresh run list. */\n beginFrame(): void {\n this._runs = [];\n this._d = \"\";\n this._shapeFill = null;\n this._shapeStroke = null;\n this._shapePainted = false;\n this._drawCount = 0;\n }\n\n /** Number of paint calls since `beginFrame` — used to skip empty commits. */\n get drawCount(): number {\n return this._drawCount;\n }\n\n /** The `<g>` element holding this context's rendered output. */\n get group(): SVGElement | null {\n return this._group;\n }\n\n /**\n * Commit the frame: reconcile the run list against the pooled elements, patching only\n * changed attributes, and truncate unused elements.\n */\n commitFrame(): void {\n this._flushShape();\n if (!this._group) {\n this._group = document.createElementNS(SVG_NS, \"g\") as SVGElement;\n this._group.setAttribute(\"class\", \"pts-svgform\");\n this._host.appendChild(this._group);\n }\n\n const runs = this._runs;\n for (let i = 0; i < runs.length; i++) {\n const run = runs[i];\n let elem = this._pool[i];\n if (!elem || elem.nodeName !== run.tag) {\n const fresh = document.createElementNS(SVG_NS, run.tag) as SVGElement;\n if (elem) {\n this._group.replaceChild(fresh, elem);\n } else {\n this._group.appendChild(fresh);\n }\n elem = fresh;\n this._pool[i] = elem;\n this._attrCache[i] = {};\n }\n const cache = this._attrCache[i];\n // conditional attributes (eg, stroke-dasharray, mix-blend-mode) must not\n // survive from an earlier frame's run on this pooled element\n for (const k in cache) {\n if (!(k in run.attrs)) {\n elem.removeAttribute(k);\n delete cache[k];\n }\n }\n for (const k in run.attrs) {\n const v = `${run.attrs[k]}`;\n if (cache[k] !== v) {\n elem.setAttribute(k, v);\n cache[k] = v;\n }\n }\n if (run.tag === \"text\" && elem.textContent !== run.text) {\n elem.textContent = run.text!;\n }\n }\n\n // truncate the unused tail\n for (let i = this._pool.length - 1; i >= runs.length; i--) {\n this._group.removeChild(this._pool[i]);\n this._pool.pop();\n this._attrCache.pop();\n }\n\n // Definitions belong to the committed scene, not to every gradient ever\n // created. A retained gradient handle can materialize again when reused.\n if (this._defs) {\n const paints = new Set<string | number>();\n for (const run of runs) {\n paints.add(run.attrs.fill);\n paints.add(run.attrs.stroke);\n }\n for (const elem of Array.from(this._defs.children)) {\n if (!paints.has(`url(#${elem.id})`)) elem.remove();\n }\n }\n }\n\n /** The current frame's run list (used by expanded export). */\n get runs(): SVGRun[] {\n return this._runs;\n }\n\n /** Forget cached DOM references, eg after the host's contents were removed externally. */\n resetDom(): void {\n this._group = null;\n this._defs = null;\n this._pool = [];\n this._attrCache = [];\n }\n\n /**\n * Remove this context's managed elements from the DOM and forget them. Used when a space\n * is disposed so that a re-mounted space on the same element starts clean.\n */\n disposeDom(): void {\n if (this._group && this._group.parentNode) {\n this._group.parentNode.removeChild(this._group);\n }\n if (this._defs && this._defs.parentNode) {\n this._defs.parentNode.removeChild(this._defs);\n }\n this.resetDom();\n }\n\n // ------------------------------------------------------------ path verbs\n\n beginPath(): void {\n this._flushShape();\n this._d = \"\";\n }\n\n closePath(): void {\n this._d += \"Z\";\n }\n\n moveTo(x: number, y: number): void {\n this._d += `M${round2(x)} ${round2(y)}`;\n }\n\n lineTo(x: number, y: number): void {\n this._d += `L${round2(x)} ${round2(y)}`;\n }\n\n quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void {\n this._d += `Q${round2(cpx)} ${round2(cpy)} ${round2(x)} ${round2(y)}`;\n }\n\n bezierCurveTo(\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n x: number,\n y: number,\n ): void {\n this._d += `C${round2(cp1x)} ${round2(cp1y)} ${round2(cp2x)} ${round2(cp2y)} ${round2(x)} ${round2(y)}`;\n }\n\n rect(x: number, y: number, w: number, h: number): void {\n this._d += `M${round2(x)} ${round2(y)}h${round2(w)}v${round2(h)}h${round2(-w)}Z`;\n }\n\n arc(\n x: number,\n y: number,\n radius: number,\n startAngle: number,\n endAngle: number,\n ccw: boolean = false,\n ): void {\n this.ellipse(x, y, radius, radius, 0, startAngle, endAngle, ccw);\n }\n\n ellipse(\n x: number,\n y: number,\n rx: number,\n ry: number,\n rotation: number,\n startAngle: number,\n endAngle: number,\n ccw: boolean = false,\n ): void {\n // canvas sweep semantics: direction-signed delta, wrapped into [0, 2π),\n // where a delta of 2π or more is a full ellipse\n let delta = ccw ? startAngle - endAngle : endAngle - startAngle;\n const full = delta >= Const.two_pi;\n if (!full) delta = ((delta % Const.two_pi) + Const.two_pi) % Const.two_pi;\n\n const cosR = Math.cos(rotation);\n const sinR = Math.sin(rotation);\n const ptAt = (angle: number): [number, number] => {\n const px = rx * Math.cos(angle);\n const py = ry * Math.sin(angle);\n return [x + px * cosR - py * sinR, y + px * sinR + py * cosR];\n };\n\n const dir = ccw ? -1 : 1;\n const sweepFlag = ccw ? 0 : 1;\n const rotDeg = round2((rotation * 180) / Math.PI);\n const [sx, sy] = ptAt(startAngle);\n\n // connect from the current point like canvas does\n this._d +=\n this._d.length > 0\n ? `L${round2(sx)} ${round2(sy)}`\n : `M${round2(sx)} ${round2(sy)}`;\n\n // emit in half-turn segments so large-arc flags stay unambiguous\n const sweep = full ? Const.two_pi : delta;\n const segments = Math.max(1, Math.ceil(sweep / Const.pi - 0.000001));\n let angle = startAngle;\n for (let s = 1; s <= segments; s++) {\n const target =\n s === segments ? startAngle + dir * sweep : angle + dir * Const.pi;\n const [ex, ey] = ptAt(target);\n this._d += `A${round2(rx)} ${round2(ry)} ${rotDeg} 0 ${sweepFlag} ${round2(ex)} ${round2(ey)}`;\n angle = target;\n }\n if (full) this._d += \"Z\";\n }\n\n // ----------------------------------------------------------------- paint\n\n fill(): void {\n this._shapeFill = this._resolvePaint(this.fillStyle);\n this._capturePaintState();\n }\n\n stroke(): void {\n this._shapeStroke = this._resolvePaint(this.strokeStyle);\n this._shapeStrokeStyle = {\n \"stroke-width\": this.lineWidth,\n \"stroke-linejoin\": this.lineJoin,\n \"stroke-linecap\": this.lineCap,\n };\n if (this._dash.length > 0) {\n this._shapeStrokeStyle[\"stroke-dasharray\"] = this._dash.join(\" \");\n if (this.lineDashOffset)\n this._shapeStrokeStyle[\"stroke-dashoffset\"] = this.lineDashOffset;\n }\n this._capturePaintState();\n }\n\n protected _capturePaintState(): void {\n this._shapePainted = true;\n this._shapeClass = this.className;\n this._shapeAlpha = this.globalAlpha;\n this._shapeBlend = this.globalCompositeOperation;\n this._drawCount++;\n }\n\n fillRect(x: number, y: number, w: number, h: number): void {\n this.beginPath();\n this.rect(x, y, w, h);\n this.fill();\n }\n\n clearRect(): void {\n // background clearing is handled by SVGSpace.clear; nothing to erase mid-frame\n }\n\n fillText(txt: string, x: number, y: number, maxWidth?: number): void {\n this._flushShape();\n const anchor =\n this.textAlign === \"center\"\n ? \"middle\"\n : this.textAlign === \"right\" || this.textAlign === \"end\"\n ? \"end\"\n : \"start\";\n const baseline =\n this.textBaseline === \"top\"\n ? \"text-before-edge\"\n : this.textBaseline === \"middle\"\n ? \"central\"\n : this.textBaseline === \"bottom\"\n ? \"text-after-edge\"\n : this.textBaseline; // alphabetic, hanging, ideographic pass through\n const attrs: Record<string, string | number> = {\n x: round2(x),\n y: round2(y),\n fill: this._resolvePaint(this.fillStyle),\n \"text-anchor\": anchor,\n \"dominant-baseline\": baseline,\n style: `font: ${this.font}`,\n \"pointer-events\": \"none\",\n };\n // canvas maxWidth semantics: compress to fit only when text is wider\n if (maxWidth! > 0 && this.measureText(txt).width > maxWidth!) {\n attrs.textLength = round2(maxWidth!);\n attrs.lengthAdjust = \"spacingAndGlyphs\";\n }\n this._applyCommon(attrs);\n this._runs.push({ tag: \"text\", attrs, text: txt });\n this._drawCount++;\n }\n\n measureText(txt: string): TextMetrics {\n if (!_svgMeasurer) {\n _svgMeasurer = document.createElement(\"canvas\").getContext(\"2d\")!;\n }\n _svgMeasurer!.font = this.font;\n return _svgMeasurer!.measureText(txt);\n }\n\n drawImage(\n img: CanvasImageSource,\n x: number,\n y: number,\n w?: number,\n h?: number,\n ...rest: number[]\n ): void {\n if (rest.length > 0) {\n SVGContext2D._warnOnce(\n \"drawImage9\",\n \"SVG output does not support the 9-argument (source-cropped) drawImage\",\n );\n return;\n }\n this._flushShape();\n const src =\n (img as HTMLImageElement).src ??\n ((img as HTMLCanvasElement).toDataURL\n ? (img as HTMLCanvasElement).toDataURL()\n : null);\n if (!src) {\n SVGContext2D._warnOnce(\n \"drawImageSrc\",\n \"SVG output supports images from <img> elements or canvases only\",\n );\n return;\n }\n const attrs: Record<string, string | number> = {\n href: src,\n x: round2(x),\n y: round2(y),\n };\n const iw = w ?? (img as HTMLImageElement).width;\n const ih = h ?? (img as HTMLImageElement).height;\n if (iw != null) attrs.width = round2(iw as number);\n if (ih != null) attrs.height = round2(ih as number);\n this._applyCommon(attrs);\n this._runs.push({ tag: \"image\", attrs });\n this._drawCount++;\n }\n\n putImageData(): void {\n SVGContext2D._warnOnce(\n \"putImageData\",\n \"putImageData is not supported in SVG output\",\n );\n }\n\n // ----------------------------------------------------------- state & misc\n\n save(): void {\n this._stateStack.push({\n fillStyle: this.fillStyle,\n strokeStyle: this.strokeStyle,\n lineWidth: this.lineWidth,\n lineJoin: this.lineJoin,\n lineCap: this.lineCap,\n globalAlpha: this.globalAlpha,\n globalCompositeOperation: this.globalCompositeOperation,\n font: this.font,\n textAlign: this.textAlign,\n textBaseline: this.textBaseline,\n lineDashOffset: this.lineDashOffset,\n _dash: this._dash.slice(),\n });\n }\n\n restore(): void {\n const s = this._stateStack.pop();\n if (s) Object.assign(this, s);\n }\n\n scale(): void {\n // SVG output is resolution-independent; the canvas pixel-density scale is a no-op here\n }\n\n clip(): void {\n SVGContext2D._warnOnce(\"clip\", \"clip is not yet supported in SVG output\");\n }\n\n setLineDash(segments: number[]): void {\n this._dash = segments;\n }\n\n getLineDash(): number[] {\n return this._dash;\n }\n\n createLinearGradient(\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n ): SVGGradient {\n return new SVGGradient(\"linear\", [x1, y1, x2, y2]);\n }\n\n createRadialGradient(\n x0: number,\n y0: number,\n r0: number,\n x1: number,\n y1: number,\n r1: number,\n ): SVGGradient {\n return new SVGGradient(\"radial\", [x0, y0, r0, x1, y1, r1]);\n }\n\n // -------------------------------------------------------------- internals\n\n protected _resolvePaint(style: string | SVGGradient): string {\n if (style instanceof SVGGradient) {\n if (!this._defs) {\n this._defs = document.createElementNS(SVG_NS, \"defs\") as SVGElement;\n this._host.insertBefore(this._defs, this._host.firstChild);\n }\n return style.materialize(this._defs);\n }\n if (typeof style !== \"string\") {\n // a CanvasPattern (or other canvas paint object) has no SVG equivalent;\n // \"[object CanvasPattern]\" would otherwise be emitted as an invalid paint\n SVGContext2D._warnOnce(\n \"pattern\",\n \"canvas patterns are not supported in SVG output; use CanvasSpace\",\n );\n return \"none\";\n }\n return style;\n }\n\n /** Add class, alpha, and blend attributes shared by all run kinds. */\n protected _applyCommon(attrs: Record<string, string | number>): void {\n attrs.class = this.className\n ? `pts-svgform ${this.className}`\n : \"pts-svgform\";\n if (this.globalAlpha !== 1) attrs.opacity = this.globalAlpha;\n else attrs.opacity = 1;\n const op = this.globalCompositeOperation;\n if (op !== \"source-over\") {\n if (BLEND_MODES.has(op)) {\n // text runs already carry their font in `style`; append, never replace\n const blend = `mix-blend-mode: ${op}`;\n attrs.style = attrs.style ? `${attrs.style}; ${blend}` : blend;\n } else {\n SVGContext2D._warnOnce(\n `composite-${op}`,\n `composite operation \"${op}\" has no SVG equivalent`,\n );\n }\n }\n }\n\n /**\n * Commit the current shape (its path and fill/stroke usage) into the run list, merging\n * with the previous run when the paint state matches.\n */\n protected _flushShape(): void {\n if (!this._shapePainted || this._d.length === 0) {\n this._shapePainted = false;\n return;\n }\n\n const attrs: Record<string, string | number> = {\n d: this._d,\n fill: this._shapeFill ?? \"none\",\n stroke: this._shapeStroke ?? \"none\",\n };\n if (this._shapeStroke) {\n Object.assign(attrs, this._shapeStrokeStyle);\n }\n attrs.class = this._shapeClass\n ? `pts-svgform ${this._shapeClass}`\n : \"pts-svgform\";\n attrs.opacity = this._shapeAlpha;\n if (this._shapeBlend !== \"source-over\") {\n if (BLEND_MODES.has(this._shapeBlend)) {\n attrs.style = `mix-blend-mode: ${this._shapeBlend}`;\n } else {\n SVGContext2D._warnOnce(\n `composite-${this._shapeBlend}`,\n `composite operation \"${this._shapeBlend}\" has no SVG equivalent`,\n );\n }\n }\n\n const prev = this._runs[this._runs.length - 1];\n if (prev && prev.tag === \"path\" && sameRunStyle(prev.attrs, attrs)) {\n prev.shapeEnds!.push((prev.attrs.d as string).length);\n prev.attrs.d = (prev.attrs.d as string) + this._d;\n } else {\n this._runs.push({ tag: \"path\", attrs, shapeEnds: [] });\n }\n\n this._d = \"\";\n this._shapeFill = null;\n this._shapeStroke = null;\n this._shapePainted = false;\n }\n}\n\nfunction round2(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\n/** Compare two path-run attribute sets for style equality (everything but the path data). */\nfunction sameRunStyle(\n a: Record<string, string | number>,\n b: Record<string, string | number>,\n): boolean {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n for (const k of keysA) {\n if (k === \"d\") continue;\n if (a[k] !== b[k]) return false;\n }\n return true;\n}\n\n/**\n * SVGSpace extends [`DOMSpace`](#link) to support SVG elements. Use it with [`SVGForm`](#link),\n * which shares its drawing API and semantics with [`CanvasForm`](#link) — a sketch written for\n * canvas can run on SVG with the supported subset. Check out the [Space guide](../guide/Space-0500.html) for details.\n */\nexport class SVGSpace extends DOMSpace {\n protected _bgcolor: string = \"#999\";\n protected _svgContexts: SVGContext2D[] = [];\n protected _bgElem: SVGElement | null = null;\n protected _svgRefresh: boolean = true; // mirrors Space's private refresh flag\n\n /**\n * Create a SVGSpace which represents a Space for SVG elements.\n * @param elem Specify an element by its \"id\" attribute as string, or by the element object itself. An element can be an existing `<svg>`, or a `<div>` container in which a new `<svg>` will be created. If left empty, a `<div id=\"pt_container\"><svg id=\"pt\" /></div>` will be added to DOM. Use css to customize its appearance if needed.\n * @param callback an optional callback `function(boundingBox, spaceElement)` to be called when canvas is appended and ready. Alternatively, a \"ready\" event will also be fired from the `<svg>` element when it's appended, which can be traced with `spaceInstance.canvas.addEventListener(\"ready\")`\n * @example `new SVGSpace( \"#myElementID\" )`\n */\n constructor(\n elem: string | Element | null = \"pt\",\n callback?: (bound: Bound, elem: Element) => void,\n ) {\n super(elem, callback);\n\n if (this._canvas.nodeName.toLowerCase() != \"svg\") {\n let s = SVGSpace.svgElement(this._canvas, \"svg\", `${this.id}_svg`);\n this._container = this._canvas;\n this._canvas = s as SVGElement;\n }\n\n // immediate-mode cycle like canvas: redraw and reconcile every frame\n this.refresh(true);\n }\n\n /**\n * For a missing target, create the documented `<svg id=\"pt\">` inside the created container.\n */\n protected _createDefaultElement(container: Element, id: string): SVGElement {\n return SVGSpace.svgElement(container, \"svg\", id);\n }\n\n /**\n * Get a new [`SVGForm`](#link) for drawing. The form shares its API with\n * [`CanvasForm`](#link), rendered through a [`SVGContext2D`](#link).\n * @see `SVGForm`\n */\n getForm(): SVGForm {\n return new SVGForm(this);\n }\n\n /**\n * Get the DOM element.\n */\n get element(): Element {\n return this._canvas;\n }\n\n /** Register a rendering context so its frame lifecycle follows this space's play cycle. */\n registerContext(ctx: SVGContext2D): void {\n this._svgContexts.push(ctx);\n }\n\n /**\n * This overrides Space's `resize` function. It's used as a callback function for window's resize event and not usually called directly.\n * You can keep track of resize events with `resize: (bound ,evt)` callback in your [`IPlayer`](#link) objects (See [`Space.add`](#link)).\n * @param b a Bound object to resize to\n * @param evt Optionally pass a resize event\n */\n resize(b: Bound, evt?: Event | null): this {\n super.resize(b, evt);\n SVGSpace.setAttr(this.element, {\n viewBox: `0 0 ${this.bound.width} ${this.bound.height}`,\n width: `${this.bound.width}`,\n height: `${this.bound.height}`,\n xmlns: SVG_NS,\n version: \"1.1\",\n });\n this._updateBackground();\n return this;\n }\n\n /**\n * Clear the drawing. In SVG this maintains a background rectangle rather than erasing\n * elements — the per-frame reconciliation removes stale shapes.\n * @param bg Optionally specify a custom background color in hex or rgba string, or \"transparent\"\n */\n clear(bg?: string): this {\n if (bg) this._bgcolor = bg;\n this._updateBackground();\n return this;\n }\n\n protected _updateBackground(): void {\n const svg = this._canvas as SVGElement;\n if (!this._bgElem) {\n this._bgElem = document.createElementNS(SVG_NS, \"rect\") as SVGElement;\n this._bgElem.setAttribute(\"class\", \"pts-svg-bg\");\n svg.insertBefore(this._bgElem, svg.firstChild);\n }\n DOMSpace.setAttr(this._bgElem, {\n x: 0,\n y: 0,\n width: this.bound.width,\n height: this.bound.height,\n fill:\n !this._bgcolor || this._bgcolor === \"transparent\"\n ? \"none\"\n : this._bgcolor,\n });\n }\n\n /**\n * The per-frame cycle: begin all registered contexts' frames, run the players, then\n * commit — reconciling the SVG DOM against what was drawn this frame.\n */\n protected playItems(time: number) {\n const ctxs = this._svgContexts;\n for (let i = 0, len = ctxs.length; i < len; i++) ctxs[i].beginFrame();\n super.playItems(time);\n for (let i = 0, len = ctxs.length; i < len; i++) {\n // skip empty commits so scenes drawn once (with refresh off) persist\n if (this._svgRefresh || ctxs[i].drawCount > 0) ctxs[i].commitFrame();\n }\n }\n\n /**\n * Set whether the rendering should be repainted on each frame.\n * @param b a boolean value to set whether to repaint each frame\n */\n refresh(b: boolean): this {\n this._svgRefresh = b;\n return super.refresh(b);\n }\n\n /**\n * Serialize the current SVG output to a string.\n * @param expand if `true`, split merged style runs into one element per shape — a\n * semantic export suited for editing in vector tools. Default is `false`.\n */\n toSVG(expand: boolean = false): string {\n const svg = this._canvas as SVGElement;\n if (!expand) return svg.outerHTML;\n\n const clone = svg.cloneNode(true) as SVGElement;\n // rebuild each form's group with one element per shape\n const groups = clone.querySelectorAll(\"g.pts-svgform\");\n let gi = 0;\n for (const ctx of this._svgContexts) {\n const group = groups[gi++];\n if (!group) continue;\n group.textContent = \"\";\n for (const run of ctx.runs) {\n if (run.tag !== \"path\") {\n const elem = document.createElementNS(SVG_NS, run.tag);\n DOMSpace.setAttr(elem, run.attrs);\n if (run.text) elem.textContent = run.text;\n group.appendChild(elem);\n continue;\n }\n const d = run.attrs.d as string;\n const bounds = [...run.shapeEnds!, d.length];\n let begin = 0;\n for (const end of bounds) {\n const elem = document.createElementNS(SVG_NS, \"path\");\n DOMSpace.setAttr(elem, { ...run.attrs, d: d.slice(begin, end) });\n group.appendChild(elem);\n begin = end;\n }\n }\n }\n return clone.outerHTML;\n }\n\n /**\n * A static function to add a svg element inside a node. Usually you don't need to call this directly. See methods in [`SVGForm`](#link) instead.\n * @param parent the parent element, or `null` to use current `<svg>` as parent.\n * @param name a string of element name, such as `rect` or `circle`\n * @param id id attribute of the new element\n */\n static svgElement(\n parent: Element | null | undefined,\n name: string,\n id?: string,\n ): SVGElement {\n if (!parent || !parent.appendChild)\n throw new Error(\"parent is not a valid DOM element\");\n\n // O(1) id lookup, then verify it's inside the parent so a same-id\n // element elsewhere in the document is never silently adopted\n let elem: Element | null = document.getElementById(id!);\n if (elem && !parent.contains(elem)) elem = null;\n\n if (!elem) {\n elem = document.createElementNS(SVG_NS, name);\n elem.setAttribute(\"id\", id!);\n\n parent.appendChild(elem);\n }\n return elem as SVGElement;\n }\n\n /**\n * Remove an item from this Space.\n * @param player a player item with an auto-assigned `animateID` property\n */\n remove(player: IPlayer): this {\n let temp = this._container.querySelectorAll(\".\" + SVGForm.scopeID(player));\n\n temp.forEach((el: Element) => {\n el.parentNode!.removeChild(el);\n });\n\n return super.remove(player);\n }\n\n /**\n * Remove all items from this Space. This clears the contents of the space's\n * `<svg>` element but never touches its container, so the space keeps\n * rendering after items are re-added.\n */\n removeAll(): this {\n this._canvas.innerHTML = \"\";\n this._bgElem = null;\n for (const ctx of this._svgContexts) ctx.resetDom();\n return super.removeAll();\n }\n\n /**\n * Dispose of browser resources held by this space: listeners, the animation loop, and the\n * elements this space manages inside the `<svg>`. Call this before unmounting, eg in a\n * framework component's cleanup callback. A new space can be mounted on the same element\n * afterwards (as happens under React's StrictMode).\n */\n dispose(): this {\n super.dispose();\n for (const ctx of this._svgContexts) ctx.disposeDom();\n this._svgContexts = [];\n if (this._bgElem && this._bgElem.parentNode) {\n this._bgElem.parentNode.removeChild(this._bgElem);\n }\n this._bgElem = null;\n return this;\n }\n}\n\nlet _svgFormGroupID = 0;\nlet _svgFormDomID = 0;\n\n// rendering-context style keys and their legacy inline-style names\nconst _legacyStyleKeys: Record<string, string> = {\n fillStyle: \"fill\",\n strokeStyle: \"stroke\",\n lineWidth: \"stroke-width\",\n lineJoin: \"stroke-linejoin\",\n lineCap: \"stroke-linecap\",\n globalAlpha: \"opacity\",\n font: \"font\",\n};\n\n/**\n * SVGForm is a [`CanvasForm`](#link) rendered through a [`SVGContext2D`](#link): it inherits\n * the canvas drawing API — shapes, gradients, dashes, images, `textBox` — with SVG\n * output, subject to the capability notes in `SVGContext2D`. Sketches using this subset\n * can swap between `CanvasSpace` and `SVGSpace`. The legacy per-element static helpers and `scope()` workflow are retained\n * for compatibility but are no longer needed.\n */\nexport class SVGForm extends CanvasForm<SVGSpace> {\n protected _svgSpace: SVGSpace;\n protected _svgCtx: SVGContext2D;\n protected _formID: number = _svgFormGroupID++;\n\n protected _legacyCtx: DOMFormContext = {\n group: null,\n groupID: \"pts\",\n groupCount: 0,\n currentID: \"pts0\",\n currentClass: \"\",\n style: {},\n };\n\n // mutable statics are stored at module level and exposed through accessors so\n // no post-class assignment is emitted (which would defeat tree-shaking)\n static get groupID(): number {\n return _svgFormGroupID;\n }\n static set groupID(n: number) {\n _svgFormGroupID = n;\n }\n static get domID(): number {\n return _svgFormDomID;\n }\n static set domID(n: number) {\n _svgFormDomID = n;\n }\n\n /**\n * Create a new SVGForm. You may also use [`SVGSpace.getForm`](#link) to get a default form directly.\n * @param space an instance of SVGSpace\n */\n constructor(space: SVGSpace) {\n super();\n this._svgSpace = space;\n this._svgCtx = new SVGContext2D(space.element as SVGElement);\n space.registerContext(this._svgCtx);\n\n this._ctx = this._svgCtx as unknown as RenderingContext2D;\n // Same initial state as CanvasForm, so a sketch renders alike on both:\n // in particular, text without an explicit font() is 14px, not the\n // context's 10px default.\n this._set(\"fillStyle\", this._style.fillStyle);\n this._set(\"strokeStyle\", this._style.strokeStyle);\n this._set(\"lineJoin\", \"bevel\");\n this._set(\"font\", this._font.value);\n this._ready = true;\n\n this._legacyCtx.group = space.element;\n }\n\n /**\n * Mirror style writes into the legacy scope context, so the static per-element helpers\n * (`SVGForm.circle( form.scope(player), ... )`) draw with the form's current fill, stroke,\n * alpha, and font as they did before the rendering-context path existed.\n */\n protected _set(key: string, value: unknown): void {\n const legacy = _legacyStyleKeys[key];\n if (legacy) {\n // gradient and pattern objects have no inline-style form; keep the last color\n if (typeof value === \"string\" || typeof value === \"number\") {\n this._legacyCtx.style[legacy] = value;\n }\n }\n super._set(key, value);\n }\n\n get filled(): boolean {\n return this._filled;\n }\n set filled(b: boolean) {\n this._filled = b;\n this._legacyCtx.style.filled = b;\n }\n\n get stroked(): boolean {\n return this._stroked;\n }\n set stroked(b: boolean) {\n this._stroked = b;\n this._legacyCtx.style.stroked = b;\n }\n\n /**\n * Offscreen buffers require Canvas output. In SVG this warns once and draws directly.\n */\n useOffscreen(_off: boolean = true, _clear: boolean | string = false): this {\n SVGForm._warnOffscreen();\n return this;\n }\n\n /**\n * Offscreen buffers require Canvas output. In SVG this warns once and does nothing.\n */\n renderOffscreen(_offset: PtLike = [0, 0]): void {\n SVGForm._warnOffscreen();\n }\n\n private static _offscreenWarned = false;\n private static _warnOffscreen() {\n if (SVGForm._offscreenWarned) return;\n SVGForm._offscreenWarned = true;\n Util.warn(\n \"offscreen canvases are not supported in SVG output; use CanvasSpace\",\n );\n }\n\n /**\n * Get the [`SVGSpace`](#link) instance that this form is associated with.\n */\n get space(): SVGSpace {\n return this._svgSpace;\n }\n\n /**\n * The underlying [`SVGContext2D`](#link), for advanced use.\n */\n get svgContext(): SVGContext2D {\n return this._svgCtx;\n }\n\n /**\n * Add custom class to the created element(s). In batched rendering the class applies to\n * the current style run.\n * @param c custom class name or `false` to reset it\n * @example `form.fill(\"#f00\").cls(\"myClass\").rects(r)` `form.cls(false).circles(c)`\n */\n cls(c: string | boolean) {\n const cls = typeof c == \"boolean\" ? \"\" : c;\n this._legacyCtx.currentClass = cls;\n this._svgCtx.className = cls;\n return this;\n }\n\n // ------------------------------------------------- legacy scope workflow\n\n /**\n * @deprecated No longer needed: elements are reconciled automatically each frame. Kept\n * for compatibility with code that pairs it with the legacy static helpers.\n */\n updateScope(group_id: string, group?: Element): DOMFormContext {\n this._legacyCtx.group = group;\n this._legacyCtx.groupID = group_id;\n this._legacyCtx.groupCount = 0;\n this.nextID();\n return this._legacyCtx;\n }\n\n /**\n * @deprecated No longer needed: elements are reconciled automatically each frame. Kept\n * for compatibility; returns the legacy context used by the static helpers.\n */\n scope(item: IPlayer) {\n if (!item || item.animateID == null)\n throw new Error(\"item not defined or not yet added to Space\");\n // two forms scoped to the same player must not generate the same ids\n return this.updateScope(\n `${SVGForm.scopeID(item)}-f${this._formID}`,\n this._svgSpace.element,\n );\n }\n\n /**\n * @deprecated Part of the legacy scope workflow.\n */\n nextID(): string {\n this._legacyCtx.groupCount++;\n this._legacyCtx.currentID = `${this._legacyCtx.groupID}-${this._legacyCtx.groupCount}`;\n return this._legacyCtx.currentID;\n }\n\n /**\n * A static function to generate an ID string based on a context object.\n * @param ctx a context object for an SVGForm\n */\n static getID(ctx: DOMFormContext): string {\n return ctx.currentID || `p-${SVGForm.domID++}`;\n }\n\n /**\n * A static function to generate an ID string for a scope, based on an [`IPlayer`](#link) object in the Space.\n * @param item a [`IPlayer`](#link) object that's added to space (see [`Space.add`](#link)) and has an `animateID` property\n */\n static scopeID(item: IPlayer): string {\n return `item-${item.animateID}`;\n }\n\n // --------------------------------------- legacy per-element static helpers\n // These draw one SVG element per call using id-based lookup, exactly as\n // before. They are retained for compatibility and for expanded exports.\n\n /**\n * A static function to help adding style object to an element.\n * Note that this put all styles into `style` attribute instead of individual svg attributes, so that the styles can be parsed by Adobe Illustrator.\n * @param elem A DOM element to add to\n * @param styles an object of style properties\n * @example `SVGForm.style(elem, {fill: \"#f90\", stroke: false})`\n * @returns this DOM element\n */\n static style(elem: SVGElement, styles: Record<string, any>) {\n let st = [];\n\n if (!styles[\"filled\"]) st.push(\"fill: none\");\n if (!styles[\"stroked\"]) st.push(\"stroke: none\");\n\n for (let k in styles) {\n if (styles.hasOwnProperty(k) && k != \"filled\" && k != \"stroked\") {\n let v = styles[k];\n if (v) {\n if (!styles[\"filled\"] && k.indexOf(\"fill\") === 0) {\n continue;\n } else if (!styles[\"stroked\"] && k.indexOf(\"stroke\") === 0) {\n continue;\n } else {\n st.push(`${k}: ${v}`);\n }\n }\n }\n }\n\n return DOMSpace.setAttr(elem, { style: st.join(\";\") });\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static point(\n ctx: DOMFormContext,\n pt: PtLike,\n radius?: number,\n shape?: string,\n ): SVGElement;\n static point(\n ctx: RenderingContext2D,\n pt: PtLike,\n radius?: number,\n shape?: string,\n ): void;\n static point(\n ctx: DOMFormContext | RenderingContext2D,\n pt: PtLike,\n radius = 5,\n shape = \"square\",\n ) {\n return \"style\" in ctx\n ? SVGForm.pointElement(ctx, pt, radius, shape)\n : CanvasForm.point(ctx, pt, radius, shape);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static circle(ctx: DOMFormContext, pt: PtLike, radius?: number): SVGElement;\n static circle(ctx: RenderingContext2D, pt: PtLike, radius?: number): void;\n static circle(\n ctx: DOMFormContext | RenderingContext2D,\n pt: PtLike,\n radius = 10,\n ) {\n return \"style\" in ctx\n ? SVGForm.circleElement(ctx, pt, radius)\n : CanvasForm.circle(ctx, pt, radius);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static arc(\n ctx: DOMFormContext,\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): SVGElement;\n static arc(\n ctx: RenderingContext2D,\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): void;\n static arc(\n ctx: DOMFormContext | RenderingContext2D,\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ) {\n return \"style\" in ctx\n ? SVGForm.arcElement(ctx, pt, radius, startAngle, endAngle, cc)\n : CanvasForm.arc(ctx, pt, radius, startAngle, endAngle, cc);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static square(ctx: DOMFormContext, pt: PtLike, halfsize: number): SVGElement;\n static square(ctx: RenderingContext2D, pt: PtLike, halfsize: number): void;\n static square(\n ctx: DOMFormContext | RenderingContext2D,\n pt: PtLike,\n halfsize: number,\n ) {\n return \"style\" in ctx\n ? SVGForm.squareElement(ctx, pt, halfsize)\n : CanvasForm.square(ctx, pt, halfsize);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static line(ctx: DOMFormContext, pts: PtLikeIterable): SVGElement | undefined;\n static line(ctx: RenderingContext2D, pts: PtLikeIterable): void;\n static line(ctx: DOMFormContext | RenderingContext2D, pts: PtLikeIterable) {\n return \"style\" in ctx\n ? SVGForm.lineElement(ctx, pts)\n : CanvasForm.line(ctx, pts);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static polygon(ctx: DOMFormContext, pts: PtLikeIterable): SVGElement;\n static polygon(ctx: RenderingContext2D, pts: PtLikeIterable): void;\n static polygon(\n ctx: DOMFormContext | RenderingContext2D,\n pts: PtLikeIterable,\n ) {\n return \"style\" in ctx\n ? SVGForm.polygonElement(ctx, pts)\n : CanvasForm.polygon(ctx, pts);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static rect(ctx: DOMFormContext, pts: PtLikeIterable): SVGElement | undefined;\n static rect(ctx: RenderingContext2D, pts: PtLikeIterable): void;\n static rect(ctx: DOMFormContext | RenderingContext2D, pts: PtLikeIterable) {\n return \"style\" in ctx\n ? SVGForm.rectElement(ctx, pts)\n : CanvasForm.rect(ctx, pts);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static text(ctx: DOMFormContext, pt: PtLike, txt: string): SVGElement;\n static text(\n ctx: RenderingContext2D,\n pt: PtLike,\n txt: string,\n maxWidth?: number,\n ): void;\n static text(\n ctx: DOMFormContext | RenderingContext2D,\n pt: PtLike,\n txt: string,\n maxWidth?: number,\n ) {\n return \"style\" in ctx\n ? SVGForm.textElement(ctx, pt, txt)\n : CanvasForm.text(ctx, pt, txt, maxWidth);\n }\n\n /**\n * A static function to draw a point as a circle or square element.\n * @param ctx a context object of SVGForm\n * @param pt a Pt object or numeric array\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `SVGForm.point( ctx, p )`, `SVGForm.point( ctx, p, 10, \"circle\" )`\n */\n static pointElement(\n ctx: DOMFormContext,\n pt: PtLike,\n radius: number = 5,\n shape: string = \"square\",\n ): SVGElement {\n if (shape === \"circle\") {\n return SVGForm.circleElement(ctx, pt, radius);\n } else {\n return SVGForm.squareElement(ctx, pt, radius);\n }\n }\n\n /**\n * A static function to draw a circle element.\n * @param ctx a context object of SVGForm\n * @param pt center position of the circle\n * @param radius radius of the circle\n */\n static circleElement(\n ctx: DOMFormContext,\n pt: PtLike,\n radius: number = 10,\n ): SVGElement {\n let elem = SVGSpace.svgElement(ctx.group, \"circle\", SVGForm.getID(ctx));\n\n DOMSpace.setAttr(elem, {\n cx: pt[0],\n cy: pt[1],\n r: radius,\n class: `pts-svgform pts-circle ${ctx.currentClass}`,\n });\n\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * A static function to draw an arc element.\n * @param ctx a context object of SVGForm\n * @param pt center position\n * @param radius radius of the arc circle\n * @param startAngle start angle of the arc\n * @param endAngle end angle of the arc\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n static arcElement(\n ctx: DOMFormContext,\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): SVGElement {\n let elem = SVGSpace.svgElement(ctx.group, \"path\", SVGForm.getID(ctx));\n\n const start = new Pt(pt).toAngle(startAngle, radius, true);\n const end = new Pt(pt).toAngle(endAngle, radius, true);\n const diff = Geom.boundAngle(endAngle) - Geom.boundAngle(startAngle);\n let largeArc = diff > Const.pi ? true : false;\n if (cc) largeArc = !largeArc;\n const sweep = cc ? \"0\" : \"1\";\n\n const d = `M ${start[0]} ${start[1]} A ${radius} ${radius} 0 ${largeArc ? \"1\" : \"0\"} ${sweep} ${end[0]} ${end[1]}`;\n\n DOMSpace.setAttr(elem, {\n d: d,\n class: `pts-svgform pts-arc ${ctx.currentClass}`,\n });\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * A static function to draw a square element.\n * @param ctx a context object of SVGForm\n * @param pt center position of the square\n * @param halfsize half size of the square\n */\n static squareElement(ctx: DOMFormContext, pt: PtLike, halfsize: number) {\n let elem = SVGSpace.svgElement(ctx.group, \"rect\", SVGForm.getID(ctx));\n DOMSpace.setAttr(elem, {\n x: pt[0] - halfsize,\n y: pt[1] - halfsize,\n width: halfsize * 2,\n height: halfsize * 2,\n class: `pts-svgform pts-square ${ctx.currentClass}`,\n });\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * A static function to draw a line or polyline element.\n * @param ctx a context object of SVGForm\n * @param pts a Group or an Iterable<PtLike>\n */\n static lineElement(\n ctx: DOMFormContext,\n pts: PtLikeIterable,\n ): SVGElement | undefined {\n let points = SVGForm.pointsString(pts);\n if (points.count < 2) return;\n\n // if count > 2, treat it as poly-line\n if (points.count > 2) return SVGForm._poly(ctx, points.string, false);\n\n // if count == 2, treat it as line\n let elem = SVGSpace.svgElement(ctx.group, \"line\", SVGForm.getID(ctx));\n let p = Util.iterToArray(pts);\n\n DOMSpace.setAttr(elem, {\n x1: p[0][0],\n y1: p[0][1],\n x2: p[1][0],\n y2: p[1][1],\n class: `pts-svgform pts-line ${ctx.currentClass}`,\n });\n\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * A static helper function to draw polyline or polygon.\n * @param ctx a context object of SVGForm\n * @param points a string of points' positions. See `SVGForm.pointsString` for conversion.\n * @param closePath a boolean to specify if the polygon path should be closed\n */\n protected static _poly(\n ctx: DOMFormContext,\n points: string,\n closePath: boolean = true,\n ) {\n let elem = SVGSpace.svgElement(\n ctx.group,\n closePath ? \"polygon\" : \"polyline\",\n SVGForm.getID(ctx),\n );\n\n DOMSpace.setAttr(elem, {\n points: points,\n class: `pts-svgform pts-polygon ${ctx.currentClass}`,\n });\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * Given a list of points, return a space-separated string\n * @param pts a Group or an Iterable<PtLike>\n * @returns an object of {string, count}\n */\n protected static pointsString(pts: PtLikeIterable): {\n string: string;\n count: number;\n } {\n let points: string = \"\";\n let count = 0;\n for (let p of pts) {\n points += `${p[0]},${p[1]} `;\n count++;\n }\n return { string: points, count: count };\n }\n\n /**\n * A static function to draw a polygon element.\n * @param ctx a context object of SVGForm\n * @param pts a Group or an Iterable<PtLike> representing a polygon\n */\n static polygonElement(ctx: DOMFormContext, pts: PtLikeIterable): SVGElement {\n let points = SVGForm.pointsString(pts);\n return SVGForm._poly(ctx, points.string, true);\n }\n\n /**\n * A static function to draw a rectangle element.\n * @param ctx a context object of SVGForm\n * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.\n */\n static rectElement(\n ctx: DOMFormContext,\n pts: PtLikeIterable,\n ): SVGElement | undefined {\n if (!Util.arrayCheck(pts)) return;\n\n let elem = SVGSpace.svgElement(ctx.group, \"rect\", SVGForm.getID(ctx));\n let bound = Group.fromArray(pts).boundingBox();\n let size = Rectangle.size(bound);\n\n DOMSpace.setAttr(elem, {\n x: bound[0][0],\n y: bound[0][1],\n width: size[0],\n height: size[1],\n class: `pts-svgform pts-rect ${ctx.currentClass}`,\n });\n\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * A static function to draw a text element.\n * @param ctx a context object of SVGForm\n * @param pt a Point object to specify the anchor point\n * @param txt a string of text to draw\n */\n static textElement(ctx: DOMFormContext, pt: PtLike, txt: string): SVGElement {\n let elem = SVGSpace.svgElement(ctx.group, \"text\", SVGForm.getID(ctx));\n\n DOMSpace.setAttr(elem, {\n \"pointer-events\": \"none\",\n x: pt[0],\n y: pt[1],\n dx: 0,\n dy: 0,\n class: `pts-svgform pts-text ${ctx.currentClass}`,\n });\n\n elem.textContent = txt;\n\n SVGForm.style(elem, ctx.style);\n\n return elem;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Group, Bound } from \"./Pt\";\nimport { Polygon, Circle } from \"./Op\";\nimport { Geom } from \"./Num\";\nimport { type PtLike, type PtIterable } from \"./Types\";\n\n/**\n * A `World` stores and manages [`Body`](#link) and [`Particle`](#link) for 2D physics simulation.\n * It advances with a substepped position-based (XPBD-style) solver and a spatial-hash broad phase.\n * See a [Particle demo](https://ptsjs.org/demo/?name=physics.particles) and a [Body demo](https://ptsjs.org/demo/?name=physics.shapes) on the demo page.\n */\n// Velocities are expressed per 60 Hz frame: `hit`, drag deltas, `changed`, friction, and\n// stiffness all use this unit, so a sketch behaves the same at any display refresh rate.\nconst FRAME = 1 / 60; // seconds\nconst FRAME_MS = 1000 / 60;\n// Elapsed times below this are carried into the next update rather than solved as a\n// tiny step (a duplicate RAF timestamp would otherwise produce a 10× step-size jump).\nconst MIN_STEP_MS = 2;\n\nexport class World {\n protected _gravity: Pt = new Pt();\n protected _friction: number = 1; // general friction\n protected _damping: number = 0.75; // collision damping\n protected _iterations: number = 1; // constraint iterations per substep\n protected _substeps: number = 4; // solver substeps per update\n protected _maxTimeStep: number = 50; // clamp on ms per update\n protected _bound: Bound;\n\n protected _particles: Particle[] = [];\n protected _bodies: Body[] = [];\n protected _pnames: string[] = []; // particle name index\n protected _bnames: string[] = []; // body name index\n\n protected _drawParticles!: (p: Particle, i: number) => void;\n protected _drawBodies!: (p: Body, i: number) => void;\n\n // substep-adjusted friction, computed once per update\n private _frictionStep: number = 1;\n // elapsed time too short to solve, carried into the next update\n private _carry: number = 0;\n\n // spatial-hash and AABB scratch buffers, grown geometrically and reused\n private _hashKeys: Uint32Array = new Uint32Array(0);\n private _cellStart: Uint32Array = new Uint32Array(0);\n private _cellEntries: Uint32Array = new Uint32Array(0);\n private _neighborKeys: Uint32Array = new Uint32Array(9);\n private _bodyBounds: Float32Array = new Float32Array(0);\n\n /**\n * Create a `World` for 2D physics simulation.\n * @param bound a Group or an Iterable<Pt> representing a rectangular bounding box\n * @param friction a value between 0 to 1, where 1 means no friction. Default is 1\n * @param gravity a number of a Pt to define gravitational force. A number is a shorthand to set `new Pt(0, n)`. Default is 0.\n */\n constructor(\n bound: PtIterable,\n friction: number = 1,\n gravity: PtLike | number = 0,\n ) {\n this._bound = Bound.fromGroup(bound);\n this._friction = friction;\n this._gravity =\n typeof gravity === \"number\" ? new Pt(0, gravity) : new Pt(gravity);\n return this;\n }\n\n /**\n * Current bound in this `World`.\n */\n get bound(): Bound {\n return this._bound;\n }\n set bound(bound: Bound) {\n this._bound = bound;\n }\n\n /**\n * Current gravity in this `World`.\n */\n get gravity(): Pt {\n return this._gravity;\n }\n set gravity(g: Pt) {\n this._gravity = g;\n }\n\n /**\n * Current friction in this `World`.\n */\n get friction(): number {\n return this._friction;\n }\n set friction(f: number) {\n this._friction = f;\n }\n\n /**\n * Current damping in this `World`.\n */\n get damping(): number {\n return this._damping;\n }\n set damping(f: number) {\n this._damping = f;\n }\n\n /**\n * Constraint solver iterations per substep.\n */\n get iterations(): number {\n return this._iterations;\n }\n set iterations(f: number) {\n this._iterations = f;\n }\n\n /**\n * Target number of solver substeps per 60 Hz frame (16.7 ms). Each [`World.update`](#link)\n * runs enough substeps of about that size to cover its elapsed time, so a 30 Hz frame solves\n * twice as many substeps as a 60 Hz frame rather than larger ones. More substeps produce a\n * more stable and accurate simulation at a linear cost. Default is 4.\n */\n get substeps(): number {\n return this._substeps;\n }\n set substeps(n: number) {\n this._substeps = Math.max(1, Math.round(n));\n }\n\n /**\n * Maximum simulated time in milliseconds per [`World.update`](#link) call. Larger elapsed\n * times are clamped so that a hitch (eg, a backgrounded tab) cannot destabilize the\n * simulation. Default is 50.\n */\n get maxTimeStep(): number {\n return this._maxTimeStep;\n }\n set maxTimeStep(ms: number) {\n this._maxTimeStep = Math.max(0, ms);\n }\n\n /**\n * Get the number of bodies.\n */\n get bodyCount(): number {\n return this._bodies.length;\n }\n\n /**\n * Get the number of particles.\n */\n get particleCount(): number {\n return this._particles.length;\n }\n\n /**\n * Get a body in this world by index or string id.\n * @param id numeric index of the body, or a string id that associates with it.\n * @returns a Body, or undefined if not found\n */\n body(id: number | string) {\n if (typeof id === \"string\" && id.length > 0) {\n return this._bodies[this._bnames.indexOf(id)];\n }\n return typeof id === \"number\" && id >= 0 ? this._bodies[id] : undefined;\n }\n\n /**\n * Get a particle in this world by index or string id.\n * @param id numeric index of the particle, or a string id that associates with it.\n * @returns a Particle, or undefined if not found\n */\n particle(id: number | string) {\n if (typeof id === \"string\" && id.length > 0) {\n return this._particles[this._pnames.indexOf(id)];\n }\n return typeof id === \"number\" && id >= 0 ? this._particles[id] : undefined;\n }\n\n /**\n * Given a body's name, return its index in the bodies array, or -1 if not found.\n * @param name name of the body\n * @returns index number, or -1 if not found\n */\n bodyIndex(name: string): number {\n return this._bnames.indexOf(name);\n }\n\n /**\n * Given a particle's name, return its index in the particles array, or -1 if not found.\n * @param name name of the particle\n * @returns index number, or -1 if not found\n */\n particleIndex(name: string): number {\n return this._pnames.indexOf(name);\n }\n\n /**\n * Advance this world by an amount of time, solved in substeps sized by\n * [`World.substeps`](#link). The time is clamped to [`World.maxTimeStep`](#link), and an\n * elapsed time under 2 ms is carried into the next call. Draw callbacks fire once per call,\n * after the solve completes.\n * @param ms change in time in milliseconds\n */\n update(ms: number) {\n const elapsed = Math.min(ms, this._maxTimeStep) + this._carry;\n this._carry = 0;\n if (elapsed >= MIN_STEP_MS) {\n // The substep count follows the elapsed time, so the substep length stays\n // near its target regardless of frame timing. A step-size jump between\n // substeps is what the time-corrected integrator scales velocity by, and\n // a large ratio also amplifies contact corrections — enough to launch a\n // body that is merely resting on the floor.\n const k = Math.max(1, Math.round((elapsed * this._substeps) / FRAME_MS));\n const h = elapsed / 1000 / k;\n // friction is a per-frame drag; compound it per substep\n this._frictionStep = Math.pow(this._friction, h / FRAME);\n for (let s = 0; s < k; s++) {\n this._updateParticles(h);\n // Body contacts resolve every substep: penetrations are detected while\n // still shallow, and each positional push stays at the scale of one\n // substep's motion — resolving once per update would inject the whole\n // frame's correction at substep velocity, kicking bodies 4× harder than\n // intended. The scalarized SAT makes the extra narrow-phase passes cheap.\n this._updateBodies(h);\n }\n this._clearForces();\n } else if (elapsed > 0) {\n this._carry = elapsed;\n }\n\n if (this._drawParticles) {\n for (let i = 0, len = this._particles.length; i < len; i++) {\n this._drawParticles(this._particles[i], i);\n }\n }\n if (this._drawBodies) {\n for (let i = 0, len = this._bodies.length; i < len; i++) {\n this._drawBodies(this._bodies[i], i);\n }\n }\n }\n\n /**\n * Draw particles using the provided function.\n * @param fn a function that draws a particle passed in the parameters `(particle, index)`.\n */\n drawParticles(fn: (p: Particle, i: number) => void): void {\n this._drawParticles = fn;\n }\n\n /**\n * Draw bodies using the provided function.\n * @param fn a function that draws a body passed in the parameters `(body, index)`.\n */\n drawBodies(fn: (p: Body, i: number) => void): void {\n this._drawBodies = fn;\n }\n\n /**\n * Add a particle or body to this world.\n * @param p `Particle` or `Body` instance\n * @param name optional name, which can be referenced in `body()` or `particle()` function to retrieve this back.\n */\n add(p: Particle | Body, name: string = \"\"): this {\n if (p instanceof Body) {\n this._bodies.push(<Body>p);\n this._bnames.push(name);\n } else {\n this._particles.push(<Particle>p);\n this._pnames.push(name);\n }\n return this;\n }\n\n private _index(fn: (name: string) => number, id: string | number): number {\n let index = 0;\n if (typeof id === \"string\") {\n index = fn(id);\n if (index < 0)\n throw new Error(\n `Cannot find index of ${id}. You can use particleIndex() or bodyIndex() function to check existence by name.`,\n );\n } else {\n index = id;\n }\n return index;\n }\n\n /**\n * Remove bodies from this world. Support removing a range and negative index.\n * @param from Start index, which can be negative (where -1 is at index 0, -2 at index 1, etc)\n * @param count Number of items to remove. Default is 1.\n */\n removeBody(from: number | string, count: number = 1): this {\n const index = this._index(this.bodyIndex.bind(this), from);\n const param = index < 0 ? [index * -1 - 1, count] : [index, count];\n this._bodies.splice(param[0], param[1]);\n this._bnames.splice(param[0], param[1]);\n return this;\n }\n\n /**\n * Remove particles from this world. Support removing a range and negative index.\n * @param from Start index, which can be negative (where -1 is at index 0, -2 at index 1, etc)\n * @param count Number of items to remove. Default is 1.\n */\n removeParticle(from: number | string, count: number = 1): this {\n const index = this._index(this.particleIndex.bind(this), from);\n const param = index < 0 ? [index * -1 - 1, count] : [index, count];\n this._particles.splice(param[0], param[1]);\n this._pnames.splice(param[0], param[1]);\n return this;\n }\n\n /**\n * Static function to calculate edge constraints between 2 particles.\n * @param p1 particle 1\n * @param p2 particle 2\n * @param dist distance between particles\n * @param stiff stiffness between 0 to 1.\n * @param precise use precise distance calculation. Default is `false`.\n */\n static edgeConstraint(\n p1: Particle,\n p2: Particle,\n dist: number,\n stiff: number = 1,\n precise: boolean = false,\n ) {\n const m1 = 1 / (p1.mass || 1);\n const m2 = 1 / (p2.mass || 1);\n const mm = m1 + m2;\n\n let delta = p2.$subtract(p1);\n let distSq = dist * dist;\n let d = precise\n ? dist / delta.magnitude() - 1\n : distSq / (delta.dot(delta) + distSq) - 0.5; // approx square root\n let f = delta.$multiply(d * stiff);\n\n p1.subtract(f.$multiply(m1 / mm));\n p2.add(f.$multiply(m2 / mm));\n\n return p1;\n }\n\n /**\n * Static function to calculate bounding box constraints.\n * @param p particle\n * @param rect a Group or an Iterable<Pt> representing a bounding box\n * @param damping damping between 0 to 1, where 1 means no damping. Default is 0.75.\n */\n static boundConstraint(\n p: Particle,\n rect: PtIterable,\n damping: number = 0.75,\n ) {\n const bound = Geom.boundingBox(rect);\n World._boundParticle(\n p,\n bound[0][0],\n bound[0][1],\n bound[1][0],\n bound[1][1],\n damping,\n );\n }\n\n /**\n * Shared scalar core of the bound constraint: clamp to the rectangle inset by the\n * particle's radius, and reflect the damped velocity on each axis that hit a wall\n * (a corner hit reflects both).\n */\n protected static _boundParticle(\n p: Particle,\n minX: number,\n minY: number,\n maxX: number,\n maxY: number,\n damping: number,\n ) {\n const px = p[0];\n const py = p[1];\n const nx = Math.min(Math.max(px, minX + p.radius), maxX - p.radius);\n const ny = Math.min(Math.max(py, minY + p.radius), maxY - p.radius);\n\n if (nx !== px || ny !== py) {\n const prev = p.previous;\n const cx = (px - prev[0]) * damping;\n const cy = (py - prev[1]) * damping;\n prev[0] = nx !== px ? nx + cx : nx - cx;\n prev[1] = ny !== py ? ny + cy : ny - cy;\n p[0] = nx;\n p[1] = ny;\n }\n }\n\n /**\n * Integrate a particle for one substep: Verlet with the accumulated force plus gravity as\n * acceleration, and the substep-adjusted friction as drag. Forces are read but not cleared\n * here — they persist across the substeps of one update and are cleared when it completes.\n * @param p particle\n * @param dt substep time in seconds\n * @param prevDt time in seconds spanned by the particle's current displacement (see [`Particle.timeStep`](#link)); the velocity is rescaled to `dt` so that it is preserved when the step size changes.\n */\n protected integrate(\n p: Particle,\n dt: number,\n prevDt: number = p.timeStep || FRAME,\n ): Particle {\n const prev = p.previous;\n const ratio = prevDt > 0 ? dt / prevDt : 1;\n\n if (p.lock) {\n // A dragged lock stores its per-frame drag delta as velocity for collisions\n // to read; express it per substep so it is applied once over the frame.\n if (ratio !== 1) {\n prev[0] = p[0] - (p[0] - prev[0]) * ratio;\n prev[1] = p[1] - (p[1] - prev[1]) * ratio;\n }\n p.timeStep = dt;\n p.verlet(dt, this._frictionStep, dt); // re-pins to the lock point\n return p;\n }\n\n const force = p.force;\n const f = this._frictionStep * ratio;\n const dtSq = dt * dt;\n const px = p[0];\n const py = p[1];\n const nx = px + (px - prev[0]) * f + (force[0] + this._gravity[0]) * dtSq;\n const ny = py + (py - prev[1]) * f + (force[1] + this._gravity[1]) * dtSq;\n prev[0] = px;\n prev[1] = py;\n p[0] = nx;\n p[1] = ny;\n p.timeStep = dt;\n return p;\n }\n\n /**\n * Internal function to update free particles for one substep: integrate, constrain to the\n * bound, then resolve particle-particle collisions through the spatial hash.\n */\n protected _updateParticles(dt: number) {\n const ps = this._particles;\n const len = ps.length;\n if (len === 0) return;\n\n const b0 = this._bound[0];\n const b1 = this._bound[1];\n const minX = Math.min(b0[0], b1[0]);\n const minY = Math.min(b0[1], b1[1]);\n const maxX = Math.max(b0[0], b1[0]);\n const maxY = Math.max(b0[1], b1[1]);\n\n for (let i = 0; i < len; i++) {\n const p = ps[i];\n this.integrate(p, dt);\n World._boundParticle(p, minX, minY, maxX, maxY, this._damping);\n }\n\n this._collideParticles();\n }\n\n /**\n * Resolve particle-particle collisions using a uniform spatial hash (a counting-sort grid),\n * visiting only neighboring cells instead of testing all pairs.\n */\n private _collideParticles() {\n const ps = this._particles;\n const n = ps.length;\n if (n < 2) return;\n\n let rmax = 0;\n for (let i = 0; i < n; i++) {\n if (ps[i].radius > rmax) rmax = ps[i].radius;\n }\n if (rmax <= 0) return; // nothing can collide\n\n // cells of 2×rmax mean any colliding pair is within the 3×3 neighborhood\n const inv = 1 / (rmax * 2);\n let m = 16;\n while (m < n * 2) m <<= 1;\n const mask = m - 1;\n\n if (this._cellStart.length < m + 1)\n this._cellStart = new Uint32Array(m + 1);\n if (this._hashKeys.length < n) {\n this._hashKeys = new Uint32Array(n * 2);\n this._cellEntries = new Uint32Array(n * 2);\n }\n const keys = this._hashKeys;\n const start = this._cellStart;\n const entries = this._cellEntries;\n\n // count per cell, exclusive prefix sum, then scatter; after the scatter,\n // bucket k spans [start[k-1], start[k])\n start.fill(0, 0, m + 1);\n for (let i = 0; i < n; i++) {\n const p = ps[i];\n const key =\n ((Math.imul(Math.floor(p[0] * inv), 0x9e3779b1) ^\n Math.imul(Math.floor(p[1] * inv), 0x85ebca77)) >>>\n 0) &\n mask;\n keys[i] = key;\n start[key]++;\n }\n let sum = 0;\n for (let k = 0; k < m; k++) {\n const c = start[k];\n start[k] = sum;\n sum += c;\n }\n start[m] = sum;\n for (let i = 0; i < n; i++) {\n entries[start[keys[i]]++] = i;\n }\n\n const damping = this._damping;\n const visited = this._neighborKeys;\n for (let i = 0; i < n; i++) {\n const p = ps[i];\n const cx = Math.floor(p[0] * inv);\n const cy = Math.floor(p[1] * inv);\n // Visit each distinct hash key of the 3×3 neighborhood exactly once: two\n // neighbor cells can collide to the same bucket, and visiting it twice\n // would apply a pair's collision response twice.\n let visitedCount = 0;\n for (let gy = cy - 1; gy <= cy + 1; gy++) {\n const hy = Math.imul(gy, 0x85ebca77);\n for (let gx = cx - 1; gx <= cx + 1; gx++) {\n const key = ((Math.imul(gx, 0x9e3779b1) ^ hy) >>> 0) & mask;\n let seen = false;\n for (let v = 0; v < visitedCount; v++) {\n if (visited[v] === key) {\n seen = true;\n break;\n }\n }\n if (seen) continue;\n visited[visitedCount++] = key;\n const end = start[key];\n const begin = key > 0 ? start[key - 1] : 0;\n for (let e = begin; e < end; e++) {\n const j = entries[e];\n if (j > i) p.collide(ps[j], damping);\n }\n }\n }\n }\n }\n\n /**\n * Reset all accumulated forces after an update completes.\n */\n private _clearForces() {\n for (let i = 0, len = this._particles.length; i < len; i++) {\n this._particles[i].force.fill(0);\n }\n for (let i = 0, len = this._bodies.length; i < len; i++) {\n const bd = this._bodies[i];\n for (let k = 0, klen = bd.length; k < klen; k++) {\n (bd[k] as Particle).force.fill(0);\n }\n }\n }\n\n /**\n * Internal function to update bodies for one substep: integrate and bound-constrain every\n * body particle, resolve body-body and body-particle collisions behind an AABB broad\n * phase, then restore shapes with the edge-constraint pass.\n * @param dt substep time in seconds\n */\n protected _updateBodies(dt: number) {\n const bs = this._bodies;\n const blen = bs.length;\n if (blen === 0) return;\n\n const b0 = this._bound[0];\n const b1 = this._bound[1];\n const minX = Math.min(b0[0], b1[0]);\n const minY = Math.min(b0[1], b1[1]);\n const maxX = Math.max(b0[0], b1[0]);\n const maxY = Math.max(b0[1], b1[1]);\n\n for (let i = 0; i < blen; i++) {\n const bd = bs[i];\n if (!bd) continue;\n for (let k = 0, klen = bd.length; k < klen; k++) {\n const bk = bd[k] as Particle;\n this.integrate(bk, dt);\n World._boundParticle(bk, minX, minY, maxX, maxY, this._damping);\n }\n }\n\n this._collideBodies(blen);\n\n for (let i = 0; i < blen; i++) {\n if (bs[i]) bs[i].solveEdges(dt, this._iterations, this._substeps);\n }\n }\n\n /**\n * Resolve body-body and body-particle collisions behind an AABB broad phase.\n */\n private _collideBodies(blen: number) {\n const bs = this._bodies;\n\n // axis-aligned bounding boxes for the broad phase\n if (this._bodyBounds.length < blen * 4) {\n this._bodyBounds = new Float32Array(blen * 8);\n }\n const aabb = this._bodyBounds;\n for (let i = 0; i < blen; i++) {\n const bd = bs[i];\n let bx0 = Infinity;\n let by0 = Infinity;\n let bx1 = -Infinity;\n let by1 = -Infinity;\n if (bd) {\n for (let k = 0, klen = bd.length; k < klen; k++) {\n const v = bd[k];\n if (v[0] < bx0) bx0 = v[0];\n if (v[0] > bx1) bx1 = v[0];\n if (v[1] < by0) by0 = v[1];\n if (v[1] > by1) by1 = v[1];\n }\n }\n aabb[i * 4] = bx0;\n aabb[i * 4 + 1] = by0;\n aabb[i * 4 + 2] = bx1;\n aabb[i * 4 + 3] = by1;\n }\n\n const ps = this._particles;\n const plen = ps.length;\n\n for (let i = 0; i < blen; i++) {\n const bd = bs[i];\n if (!bd) continue;\n const ax0 = aabb[i * 4];\n const ay0 = aabb[i * 4 + 1];\n const ax1 = aabb[i * 4 + 2];\n const ay1 = aabb[i * 4 + 3];\n\n for (let k = i + 1; k < blen; k++) {\n if (\n bs[k] &&\n ax0 <= aabb[k * 4 + 2] &&\n ax1 >= aabb[k * 4] &&\n ay0 <= aabb[k * 4 + 3] &&\n ay1 >= aabb[k * 4 + 1]\n ) {\n bd.processBody(bs[k]);\n }\n }\n\n for (let mIdx = 0; mIdx < plen; mIdx++) {\n const p = ps[mIdx];\n const r = p.radius;\n if (\n p[0] >= ax0 - r &&\n p[0] <= ax1 + r &&\n p[1] >= ay0 - r &&\n p[1] <= ay1 + r\n ) {\n bd.processParticle(p);\n }\n }\n }\n }\n}\n\n/**\n * Particle is a subclass of [`Pt`](#link) that has radius and mass. It's usually added into [`World`](#link) to create physics simulations.\n * See [a demo here](https://ptsjs.org/demo/?name=physics.particles).\n */\nexport class Particle extends Pt {\n protected _mass: number = 1;\n protected _radius: number = 0;\n protected _force: Pt = new Pt();\n protected _prev: Pt = new Pt();\n protected _prevDt: number = 0; // seconds spanned by the `_prev` displacement; 0 = one frame\n\n protected _body!: Body;\n protected _lock: boolean = false;\n protected _lockPt!: Pt;\n\n /**\n * Create a particle. Once a particle is created, you can set its mass and radius via the corresponding accessors.\n * @param args a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n constructor(...args: any[]) {\n super(...args);\n this._prev = this.clone();\n }\n\n /**\n * Mass of this particle.\n */\n get mass(): number {\n return this._mass;\n }\n set mass(m: number) {\n this._mass = m;\n }\n\n /**\n * Radius of this particle.\n */\n get radius(): number {\n return this._radius;\n }\n set radius(f: number) {\n this._radius = f;\n }\n\n /**\n * Get this particle's previous position.\n */\n get previous(): Pt {\n return this._prev;\n }\n set previous(p: Pt) {\n this._prev = p;\n }\n\n /**\n * Get current accumulated force.\n */\n get force(): Pt {\n return this._force;\n }\n set force(g: Pt) {\n this._force = g;\n }\n\n /**\n * Get the body of this particle, if any.\n */\n get body(): Body {\n return this._body;\n }\n set body(b: Body) {\n this._body = b;\n }\n\n /**\n * Lock this particle in current position.\n */\n get lock(): boolean {\n return this._lock;\n }\n set lock(b: boolean) {\n // On unlock, reset `previous` to the current position: while locked, collisions\n // and dragging can leave it arbitrarily stale, and integrating that difference\n // would launch the particle. (To throw a particle on release, use `hit`.)\n if (this._lock && !b) this._prev.to(this);\n this._lock = b;\n this._lockPt = new Pt(this);\n }\n\n /**\n * Get the change in position per 60 Hz frame, ie, the current velocity in the same unit\n * as [`Particle.hit`](#link). The raw displacement since the last step is\n * `particle.$subtract( particle.previous )`.\n */\n get changed(): Pt {\n const d = this.$subtract(this._prev);\n return this._prevDt > 0 && this._prevDt !== FRAME\n ? d.multiply(FRAME / this._prevDt)\n : d;\n }\n\n /**\n * The time in seconds spanned by the displacement from [`Particle.previous`](#link) to the\n * current position. A [`World`](#link) sets it to the substep length on every step, and\n * [`Particle.hit`](#link) and the `position` setter reset it to one 60 Hz frame (1/60),\n * which is the unit of their velocities. 0 means unknown and is treated as one frame.\n */\n get timeStep(): number {\n return this._prevDt;\n }\n set timeStep(t: number) {\n this._prevDt = t;\n }\n\n /**\n * Set a new position, and update previous and lock states if needed. The move is stored as\n * this particle's velocity per frame, so dragging a locked particle knocks others away.\n */\n set position(p: Pt) {\n this.previous.to(this);\n this._prevDt = FRAME;\n if (this._lock) this._lockPt = p;\n this.to(p);\n }\n\n /**\n * Set the size of this particle. This sets both the radius and the mass.\n * @param r `radius` value, and also set `mass` to the same value.\n */\n size(r: number): this {\n this._mass = r;\n this._radius = r;\n return this;\n }\n\n /**\n * Add to the accumulated force.\n * @param args a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n addForce(...args: any[]): Pt {\n this._force.add(...args);\n return this._force;\n }\n\n /**\n * Verlet integration.\n * @param dt change in time in seconds\n * @param friction friction from 0 to 1, where 1 means no friction\n * @param lastDt optional last change in time in seconds. Default is [`Particle.timeStep`](#link), or `dt` if unknown.\n */\n verlet(dt: number, friction: number, lastDt?: number): this {\n // Positional verlet: curr + (curr - prev) + a * dt * dt\n\n if (this._lock) {\n // Pin the position only. `previous` is deliberately left alone: dragging a\n // locked particle via the `position` setter stores the drag delta there, and\n // collisions read it as the particle's velocity — this is what makes a\n // pointer-dragged particle knock others away. Stale velocity is cleared at\n // the moment of unlocking instead (see the `lock` setter).\n this.to(this._lockPt);\n } else {\n // time corrected (https://en.wikipedia.org/wiki/Verlet_integration#Non-constant_time_differences)\n const lt = lastDt ? lastDt : this._prevDt || dt;\n const adt = (dt * (dt + lt)) / 2;\n const f = (friction * dt) / lt;\n const force = this._force;\n const prev = this._prev;\n for (let i = 0, len = this.length; i < len; i++) {\n const cur = this[i];\n const v = (cur - prev[i]) * f + (force[i] || 0) * adt;\n prev[i] = cur;\n this[i] = cur + v;\n }\n force.fill(0);\n this._prevDt = dt;\n }\n return this;\n }\n\n /**\n * Hit this particle with an impulse, in pixels per 60 Hz frame. The impulse is scaled by 1/√mass, so a heavier particle moves less from the same hit.\n * The result is the same at any frame rate and any [`World.substeps`](#link) setting.\n * @param args an impulse vector defined by either a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n * @example `hit(10, 20)`, `hit( new Pt(5, 9) )`\n */\n hit(...args: any[]): this {\n // express the current velocity per frame, then add the impulse in the same unit\n const prev = this._prev;\n if (this._prevDt > 0 && this._prevDt !== FRAME) {\n const r = FRAME / this._prevDt;\n for (let i = 0, len = this.length; i < len; i++) {\n prev[i] = this[i] - (this[i] - prev[i]) * r;\n }\n }\n this._prevDt = FRAME;\n prev.subtract(new Pt(...args).$divide(Math.sqrt(this._mass)));\n return this;\n }\n\n /**\n * Check and respoond to collisions between this and another particle.\n * @param p2 another particle\n * @param damp damping value between 0 to 1, where 1 means no damping.\n */\n collide(p2: Particle, damp: number = 1): void {\n // reference: http://codeflow.org/entries/2010/nov/29/verlet-collision-with-impulse-preservation\n // simultaneous collision not yet resolved. Possible solutions in this paper: https://www2.msm.ctw.utwente.nl/sluding/PAPERS/dem07.pdf\n\n const p1 = this;\n let dx = p1[0] - p2[0];\n let dy = p1[1] - p2[1];\n let distSq = dx * dx + dy * dy;\n const dr = p1.radius + p2.radius;\n if (distSq >= dr * dr) return;\n\n const prev1 = p1.previous;\n const prev2 = p2.previous;\n let c1x = p1[0] - prev1[0];\n let c1y = p1[1] - prev1[1];\n let c2x = p2[0] - prev2[0];\n let c2y = p2[1] - prev2[1];\n\n // separation of (dist - dr) / 2 along the collision axis; for exactly\n // coincident particles, separate deterministically along the x-axis\n let dist = Math.sqrt(distSq);\n let k: number;\n if (dist < 0.000001) {\n dx = 1;\n dy = 0;\n dist = 1;\n distSq = 1;\n k = -dr / 2;\n } else {\n k = (dist - dr) / dist / 2;\n }\n\n const np1x = p1[0] - dx * k;\n const np1y = p1[1] - dy * k;\n const np2x = p2[0] + dx * k;\n const np2y = p2[1] + dy * k;\n\n const f1 = (damp * (dx * c1x + dy * c1y)) / distSq;\n const f2 = (damp * (dx * c2x + dy * c2y)) / distSq;\n const dm1 = p1.mass / (p1.mass + p2.mass);\n const dm2 = p2.mass / (p1.mass + p2.mass);\n\n c1x += (f2 - f1) * dx * dm2;\n c1y += (f2 - f1) * dy * dm2;\n c2x += (f1 - f2) * dx * dm1;\n c2y += (f1 - f2) * dy * dm1;\n\n p1[0] = np1x;\n p1[1] = np1y;\n p2[0] = np2x;\n p2[1] = np2y;\n prev1[0] = np1x - c1x;\n prev1[1] = np1y - c1y;\n prev2[0] = np2x - c2x;\n prev2[1] = np2y - c2y;\n }\n\n /**\n * Get a string representation of this particle\n */\n toString(): string {\n return `Particle: ${this[0]} ${this[1]} | previous ${this._prev[0]} ${this._prev[1]} | mass ${this._mass}`;\n }\n}\n\n/**\n * Body is a subclass of [`Group`](#link) that stores a set of [`Particle`](#link)s and edge constraints. It is usually added into a [`World`](#link) to create physics simulations.\n * See [a demo here](https://ptsjs.org/demo/?name=physics.shapes).\n */\nexport class Body extends Group {\n protected _cs: Array<number[]> = [];\n protected _stiff: number = 1;\n protected _locks: { [index: string]: Particle } = {};\n protected _mass: number = 1;\n protected _lambdas: Float32Array = new Float32Array(0); // XPBD multipliers, one per link\n\n /**\n * Create an empty Body, this is usually followed by [`Body.init`](#link) to populate the Body. Alternatively, use static function [`Body.fromGroup`](#link) to create and initate a body directly.\n */\n constructor() {\n super();\n }\n\n /**\n * Create and populate a body.\n * @param body a Group or an Iterable<Pt> to define the body\n * @param stiff stiffness value from 0 to 1, where 1 is the most stiff. Default is 1.\n * @param autoLink Automatically create links between the Pts. This usually works for regular convex polygons. Default is true.\n * @param autoMass Automatically calculate the mass based on the area of the polygon. Default is true.\n */\n static fromGroup(\n body: PtIterable,\n stiff: number = 1,\n autoLink: boolean = true,\n autoMass: boolean = true,\n ): Body {\n let b = new Body().init(body);\n if (autoLink) b.linkAll(stiff);\n if (autoMass) b.autoMass();\n return b;\n }\n\n /**\n * Initiate a body.\n * @param body a Group or an Iterable<Pt> to define a body\n * @param stiff stiffness value from 0 to 1, where 1 is the most stiff. Default is 1.\n */\n init(body: PtIterable, stiff: number = 1): this {\n for (let li of body) {\n let p = new Particle(li);\n p.body = this;\n this.push(p);\n }\n\n this._stiff = stiff;\n\n return this;\n }\n\n /**\n * Get mass of this body.\n */\n get mass(): number {\n return this._mass;\n }\n set mass(m: number) {\n this._mass = m;\n for (let i = 0, len = this.length; i < len; i++) {\n (this[i] as Particle).mass = this._mass;\n }\n }\n\n /**\n * Automatically calculate a body's `mass` based on the area of the polygon.\n */\n autoMass(): this {\n this.mass = Math.sqrt(Polygon.area(this)) / 10;\n return this;\n }\n\n /**\n * Create a linked edge between two points.\n * @param index1 first point by index\n * @param index2 first point by index\n * @param stiff optionally stiffness value between 0 to 1, where 1 is the most stiff.\n */\n link(index1: number, index2: number, stiff?: number): this {\n if (index1 < 0 || index1 >= this.length)\n throw new Error(\"index1 is not in the Group's indices\");\n if (index2 < 0 || index2 >= this.length)\n throw new Error(\"index1 is not in the Group's indices\");\n\n let d = this[index1].$subtract(this[index2]).magnitude();\n this._cs.push([index1, index2, d, stiff || this._stiff]);\n return this;\n }\n\n /**\n * Automatically create links for all the points to preserve the initial body shape. This usually works for regular convex polygon.\n * @param stiff optionally stiffness value between 0 to 1, where 1 is the most stiff.\n */\n linkAll(stiff: number): void {\n const half = this.length / 2;\n\n // skip duplicate pairs and self-pairs, which the cross-link passes below\n // can produce for odd sizes (a duplicate would double-solve an edge);\n // a linear scan of the small link list beats allocating a Set here\n const tryLink = (a: number, b: number, s?: number) => {\n if (a === b) return;\n const cs = this._cs;\n for (let k = 0, klen = cs.length; k < klen; k++) {\n const c = cs[k];\n if ((c[0] === a && c[1] === b) || (c[0] === b && c[1] === a)) return;\n }\n this.link(a, b, s);\n };\n\n for (let i = 0, len = this.length; i < len; i++) {\n const n = i >= len - 1 ? 0 : i + 1;\n tryLink(i, n, stiff);\n\n if (len > 4) {\n const nd = Math.floor(half / 2) + 1;\n const n2 = i >= len - nd ? i % len : i + nd;\n tryLink(i, n2, stiff);\n }\n\n if (i <= half - 1) {\n tryLink(i, Math.min(this.length - 1, i + Math.floor(half)));\n }\n }\n }\n\n /**\n * Return a list of all the linked edges as line segments.\n * @returns an array of Groups, each of which represents an edge\n */\n linksToLines(): Group[] {\n let gs = [];\n for (let i = 0, len = this._cs.length; i < len; i++) {\n let ln = this._cs[i];\n gs.push(new Group(this[ln[0]], this[ln[1]]));\n }\n return gs;\n }\n\n /**\n * Recalculate all edge constraints.\n */\n processEdges(): void {\n for (let i = 0, len = this._cs.length; i < len; i++) {\n let [m, n, d, s] = this._cs[i];\n World.edgeConstraint(this[m] as Particle, this[n] as Particle, d, s);\n }\n }\n\n /**\n * Solve all edge constraints for one substep in XPBD form. A link's `stiff` value is a\n * geometric knob: it is the fraction of the remaining constraint violation resolved per\n * update, independent of the particles' masses and of the substep/iteration counts\n * (per Müller et al. 2007, the per-pass fraction is `1-(1-stiff)^(1/passes)`), and\n * `stiff=1` is a rigid projection. Mapping the fraction to a mass-relative compliance\n * keeps a heavy body exactly as stiff as a light one at the same value.\n * This is the solver used internally by [`World.update`](#link);\n * [`Body.processEdges`](#link) remains the simpler relaxation for direct use.\n * @param dt substep time in seconds (reserved; the geometric stiffness does not depend on it)\n * @param iterations solver iterations for this substep. Default is 1.\n * @param substeps the caller's substeps per update, for pass-count-independent stiffness. Default is 1.\n */\n solveEdges(dt: number, iterations: number = 1, substeps: number = 1): this {\n const cs = this._cs;\n const clen = cs.length;\n if (clen === 0) return this;\n\n if (this._lambdas.length < clen) this._lambdas = new Float32Array(clen);\n const lambdas = this._lambdas;\n lambdas.fill(0, 0, clen);\n const invPasses = 1 / Math.max(1, iterations * substeps);\n\n for (let iter = 0; iter < iterations; iter++) {\n for (let ci = 0; ci < clen; ci++) {\n const c = cs[ci];\n const p1 = this[c[0]] as Particle;\n const p2 = this[c[1]] as Particle;\n const stiff = c[3];\n\n const w1 = p1.lock ? 0 : 1 / (p1.mass || 1);\n const w2 = p2.lock ? 0 : 1 / (p2.mass || 1);\n const w = w1 + w2;\n if (w === 0) continue;\n\n const dx = p2[0] - p1[0];\n const dy = p2[1] - p1[1];\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist < 0.000001) continue;\n\n // mass-relative compliance: the per-pass correction fraction is exactly\n // `sEff` regardless of mass, since w / (w + alpha) = sEff\n let alpha = 0;\n if (stiff < 1) {\n const sEff = 1 - Math.pow(1 - stiff, invPasses);\n alpha = sEff > 0.000001 ? (w * (1 - sEff)) / sEff : w * 1000000;\n }\n const dl = (-(dist - c[2]) - alpha * lambdas[ci]) / (w + alpha);\n lambdas[ci] += dl;\n\n const s = dl / dist;\n const fx = dx * s;\n const fy = dy * s;\n p1[0] -= fx * w1;\n p1[1] -= fy * w1;\n p2[0] += fx * w2;\n p2[1] += fy * w2;\n }\n }\n return this;\n }\n\n /**\n * Check and respond to collisions between two bodies.\n * @param b another body\n */\n processBody(b: Body): void {\n let b1 = this;\n let b2 = b;\n\n let hit = Polygon.hasIntersectPolygon(b1, b2);\n\n if (hit) {\n let cv = hit.normal.$multiply(hit.dist);\n\n let t;\n let eg = hit.edge;\n if (Math.abs(eg[0][0] - eg[1][0]) > Math.abs(eg[0][1] - eg[1][1])) {\n t = (hit.vertex[0] - cv[0] - eg[0][0]) / (eg[1][0] - eg[0][0]);\n } else {\n t = (hit.vertex[1] - cv[1] - eg[0][1]) / (eg[1][1] - eg[0][1]);\n }\n\n let lambda = 1 / (t * t + (1 - t) * (1 - t));\n\n let m0 = (hit.vertex as Particle).body.mass || 1;\n let m1 = (hit.edge[0] as Particle).body.mass || 1;\n let mr0 = m0 / (m0 + m1);\n let mr1 = m1 / (m0 + m1);\n\n eg[0].subtract(cv.$multiply((mr0 * (1 - t) * lambda) / 2));\n eg[1].subtract(cv.$multiply((mr0 * t * lambda) / 2));\n\n hit.vertex.add(cv.$multiply(mr1));\n }\n }\n\n /**\n * Check and respond to collisions between this body and a particle.\n * @param b a particle\n */\n processParticle(b: Particle): void {\n let b1 = this;\n let b2 = b;\n\n let hit = Polygon.hasIntersectCircle(b1, Circle.fromCenter(b, b.radius));\n\n if (hit) {\n let cv = hit.normal.$multiply(hit.dist);\n\n let t;\n let eg = hit.edge;\n if (Math.abs(eg[0][0] - eg[1][0]) > Math.abs(eg[0][1] - eg[1][1])) {\n t = (hit.vertex[0] - cv[0] - eg[0][0]) / (eg[1][0] - eg[0][0]);\n } else {\n t = (hit.vertex[1] - cv[1] - eg[0][1]) / (eg[1][1] - eg[0][1]);\n }\n\n let lambda = 1 / (t * t + (1 - t) * (1 - t));\n // hit.vertex is the circle's center Pt (not a Particle), so the\n // particle's own mass is the vertex-side mass here\n let m0 = b2.mass || 1;\n let m1 = (hit.edge[0] as Particle).body.mass || 1;\n\n let mr0 = m0 / (m0 + m1);\n let mr1 = m1 / (m0 + m1);\n\n eg[0].subtract(cv.$multiply((mr0 * (1 - t) * lambda) / 2));\n eg[1].subtract(cv.$multiply((mr0 * t * lambda) / 2));\n\n // raw displacement (not `changed`, which is per frame)\n let c1 = b.$subtract(b.previous).add(cv.$multiply(mr1));\n b.previous = b.$subtract(c1);\n }\n }\n}\n","import { Pt, Group, type Bound } from \"./Pt\";\nimport { Num } from \"./Num\";\nimport {\n type ITempoListener,\n type ITempoStartFn,\n type ITempoProgressFn,\n type ITempoResponses,\n} from \"./Types\";\nimport {\n type ISoundAnalyzer,\n type SoundType,\n type PtLike,\n type IPlayer,\n} from \"./Types\";\n\n/**\n * Tempo helps you create synchronized and rhythmic animations.\n */\nexport class Tempo implements IPlayer {\n protected _bpm!: number; // beat per minute\n protected _ms!: number; // millis per beat\n\n protected _listeners: { [key: string]: ITempoListener } = {};\n protected _listenerInc: number = 0;\n public animateID!: string;\n\n /**\n * Construct a new Tempo instance by beats-per-minute. Alternatively, you can use [`Tempo.fromBeat`](#link) to create from milliseconds.\n * @param bpm beats per minute. Must be greater than 0.\n */\n constructor(bpm: number) {\n this.bpm = bpm;\n }\n\n /**\n * Create a new Tempo instance by specifying milliseconds-per-beat.\n * @param ms milliseconds per beat. Must be greater than 0.\n */\n static fromBeat(ms: number): Tempo {\n return new Tempo(60000 / ms);\n }\n\n /**\n * Beats-per-minute value. Must be greater than 0.\n */\n get bpm(): number {\n return this._bpm;\n }\n set bpm(n: number) {\n this._bpm = n;\n this._ms = 60000 / this._bpm;\n }\n\n /**\n * Milliseconds per beat (Note that this is derived from the bpm value).\n */\n get ms(): number {\n return this._ms;\n }\n set ms(n: number) {\n this._bpm = 60000 / n;\n this._ms = n;\n }\n\n // Get a listener unique id\n protected _createID(): string {\n return \"_b\" + this._listenerInc++;\n }\n\n /**\n * This is a core function that let you specify a rhythm and then define responses by calling the `start` and `progress` functions from the returned object. See [Animation guide](../guide/Animation-0700.html) for more details.\n * The `start` function lets you set a callback on every start. It takes a function ([`ITempoStartFn`](#link)).\n * The `progress` function lets you set a callback during progress. It takes a function ([`ITempoProgressFn`](#link)). Both functions let you optionally specify a time offset and a custom name.\n * A positive offset shifts the beat earlier (fires sooner), a negative offset shifts it later.\n * @param beats a rhythm in beats as a number or an array of numbers\n * @example `tempo.every(2).start( (count) => ... )`, `tempo.every([2,4,6]).progress( (count, t) => ... )`\n * @returns an object with chainable functions\n */\n every(beats: number | number[]): ITempoResponses {\n const self = this;\n const p = Array.isArray(beats) ? beats[0] : beats;\n\n return {\n start: function (\n fn: ITempoStartFn,\n offset: number = 0,\n name?: string,\n ): ITempoResponses {\n const id = name || self._createID();\n self._listeners[id] = {\n name: id,\n beats: beats,\n period: p,\n index: 0,\n offset: offset,\n duration: -1,\n count: 0,\n continuous: false,\n fn: fn,\n };\n return this;\n },\n\n progress: function (\n fn: ITempoProgressFn,\n offset: number = 0,\n name?: string,\n ): ITempoResponses {\n const id = name || self._createID();\n self._listeners[id] = {\n name: id,\n beats: beats,\n period: p,\n index: 0,\n offset: offset,\n duration: -1,\n count: 0,\n continuous: true,\n fn: fn,\n };\n return this;\n },\n };\n }\n\n /**\n * Usually you can add a tempo instance to a space via [`Space.add`](#link) and it will track time automatically.\n * But if necessary, you can track time manually via this function.\n * @param time current time in milliseconds\n */\n track(time: number) {\n for (const k in this._listeners) {\n if (this._listeners.hasOwnProperty(k)) {\n const li = this._listeners[k];\n const _t = li.offset ? time + li.offset : time;\n const ms = li.period! * this._ms; // time per period\n let isStart = false;\n\n if (li.duration! < 0) {\n // first tick is the start of the first period\n li.duration = _t - (_t % this._ms);\n li.count = li.count || 0; // a hand-built listener may omit count\n isStart = true;\n } else if (_t > li.duration! + ms) {\n li.duration = _t - (_t % this._ms); // update\n if (Array.isArray(li.beats)) {\n // find next period from array\n li.index = (li.index! + 1) % li.beats.length;\n li.period = li.beats[li.index];\n }\n li.count = (li.count || 0) + 1;\n isStart = true;\n }\n\n let done: void | boolean | undefined;\n if (li.continuous) {\n const t = Num.clamp((_t - li.duration!) / ms, 0, 1);\n done = (li.fn as ITempoProgressFn).call(\n li,\n li.count!,\n t,\n _t,\n isStart,\n );\n } else if (isStart) {\n done = (li.fn as ITempoStartFn).call(li, li.count!);\n }\n if (done) delete this._listeners[li.name!];\n }\n }\n }\n\n /**\n * Remove a `start` or `progress` callback function from the list of callbacks. See [`Tempo.every`](#link) for details\n * @param name a name string specified when creating the callback function.\n */\n stop(name: string): void {\n if (this._listeners[name]) delete this._listeners[name];\n }\n\n /**\n * IPlayer interface. Internal implementation that calls `track( time )`.\n */\n animate(time: number, ftime: number) {\n this.track(time);\n }\n\n /**\n * IPlayer interface. Not implemented.\n */\n resize(bound: Bound, evt?: Event) {\n return; // not implemented in IPlayer\n }\n\n /**\n * IPlayer interface. Not implemented.\n */\n action(type: string, px: number, py: number, evt: Event) {\n return;\n }\n}\n\n/**\n * Sound class simplifies common tasks like audio inputs and visualizations using a subset of Web Audio API. It can be used with other audio libraries like tone.js, and extended to support additional web audio functions. See [the guide](../guide/Sound-0800.html) to get started.\n */\nexport class Sound {\n private _type: SoundType;\n\n /** The audio context */\n _ctx: AudioContext;\n\n /** The audio node, which is usually a subclass liked OscillatorNode */\n _node!: AudioNode;\n\n /**\n * The audio node to be connected to AudioContext when playing, if different than _node\n * This is useful when using the connect() function to filter, as typically the output would\n * come from the filtering nodes\n */\n _outputNode!: AudioNode;\n\n /** The audio stream when streaming from input device */\n _stream!: MediaStream;\n\n /** Audio src when loading from file */\n _source!: HTMLMediaElement;\n\n /* Audio buffer when using AudioBufferSourceNode */\n _buffer!: AudioBuffer;\n\n /** Analyzer if any */\n analyzer!: ISoundAnalyzer;\n\n protected _playing: boolean = false;\n\n protected _timestamp!: number; // Tracking play time against ctx.currentTime\n\n protected _wave!: PeriodicWave; // Wave when generating a \"custom\" oscillator\n\n protected _gain!: GainNode; // Gain node for volume control, created on first start\n\n protected _volume: number = 1;\n\n protected _connected: AudioNode[] = []; // Nodes added via connect(), re-applied on gen restart\n\n protected _bufferPlayed: boolean = false; // An AudioBufferSourceNode can only start once\n\n protected _generated: boolean = false; // Whether _node is an oscillator created by _gen\n\n // A single AudioContext shared by all Sound instances that don't provide their own\n protected static _sharedContext: AudioContext;\n\n /**\n * Construct a `Sound` instance. Usually, it's more convenient to use one of the static methods like [`Sound.load`](#function_load) or [`Sound.from`](#function_from).\n * By default, all instances share a single `AudioContext` (browsers limit how many can be live at once).\n * @param type a `SoundType` string: \"file\", \"input\", or \"gen\"\n * @param ctx Optionally provide your own AudioContext instead of the shared one\n */\n constructor(type: SoundType, ctx?: AudioContext) {\n this._type = type;\n this._ctx = ctx || Sound._getContext();\n }\n\n /**\n * Get the shared AudioContext instance, creating it on first use. This is called internally only.\n */\n protected static _getContext(): AudioContext {\n if (!Sound._sharedContext) {\n const _ctx =\n typeof window !== \"undefined\" ? window.AudioContext : undefined;\n if (!_ctx)\n throw new Error(\n \"Your browser doesn't support Web Audio. (No AudioContext)\",\n );\n Sound._sharedContext = new _ctx();\n }\n return Sound._sharedContext;\n }\n\n /**\n * Create a `Sound` given an [AudioNode](https://developer.mozilla.org/en-US/docs/Web/API/AudioNode) and an [AudioContext](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext) from Web Audio API. See also [this example](../guide/js/examples/tone.html) using tone.js in the [guide](../guide/Sound-0800.html).\n * @param node an AudioNode instance\n * @param ctx an AudioContext instance\n * @param type a string representing a type of input source: either \"file\", \"input\", or \"gen\".\n * @param stream Optionally include a MediaStream, if the type is \"input\"\n * @returns a `Sound` instance\n */\n static from(\n node: AudioNode,\n ctx: AudioContext,\n type: SoundType = \"gen\",\n stream?: MediaStream,\n ) {\n const s = new Sound(type, ctx);\n s._node = node;\n if (stream) s._stream = stream;\n return s;\n }\n\n /**\n * Create a `Sound` by loading from a sound file or an audio element.\n * @param source either an url string to load a sound file, or an audio element.\n * @param crossOrigin whether to support loading cross-origin. Default is \"anonymous\". When passing an audio element, set the attribute in markup before the element loads for it to take effect.\n * @returns a `Sound` instance\n * @example `Sound.load( '/path/to/file.mp3' )`\n */\n static load(\n source: HTMLMediaElement | string,\n crossOrigin: string = \"anonymous\",\n ): Promise<Sound> {\n return new Promise((resolve, reject) => {\n const s = new Sound(\"file\");\n if (typeof source === \"string\") {\n // crossOrigin must be set before src, or the initial request is made without CORS\n s._source = new Audio();\n s._source.crossOrigin = crossOrigin;\n s._source.src = source;\n } else {\n s._source = source;\n s._source.crossOrigin = crossOrigin;\n }\n s._source.autoplay = false;\n\n const onError = () => {\n s._source.removeEventListener(\"canplaythrough\", ready);\n reject(\n new Error(`Error loading sound: ${s._source.src || \"media element\"}`),\n );\n };\n\n const ready = () => {\n // runs once: either immediately below, or via the once-only listener\n s._source.removeEventListener(\"error\", onError);\n s._source.addEventListener(\"ended\", function () {\n s._playing = false;\n });\n s._node = s._ctx.createMediaElementSource(s._source);\n resolve(s);\n };\n\n if (s._source.readyState >= 4) {\n // already buffered enough (eg, a previously loaded element)\n ready();\n } else {\n s._source.addEventListener(\"error\", onError, { once: true });\n s._source.addEventListener(\"canplaythrough\", ready, { once: true });\n if (s._source.readyState === 0) s._source.load(); // eg, preload=\"none\"\n }\n });\n }\n\n /**\n * Create a `Sound` by loading and decoding a sound file URL as an `AudioBufferSourceNode`.\n * Unlike [`Sound.load`](#link), this loads the complete file instead of streaming it, which can provide more consistent analysis and replay behavior across browsers.\n * @param url an url to the sound file\n */\n static async loadAsBuffer(url: string): Promise<Sound> {\n const s = new Sound(\"file\");\n const res = await fetch(url);\n if (!res.ok)\n throw new Error(`Error loading sound: ${url} (status ${res.status})`);\n try {\n s.createBuffer(await s._ctx.decodeAudioData(await res.arrayBuffer()));\n } catch (err) {\n // ErrorOptions isn't in this project's TS lib target; attach cause manually\n throw Object.assign(new Error(\"Error decoding audio\"), { cause: err });\n }\n return s;\n }\n\n /**\n * Create or re-use an AudioBuffer. Only needed if you are using `Sound.loadAsBuffer` and want to prepare a replay manually — [`start`](#link) re-creates a used buffer automatically.\n * @param buf an AudioBuffer. Optionally, you can call this without parameters to re-use existing buffer.\n */\n createBuffer(buf?: AudioBuffer): this {\n if (this._node) {\n // the replaced node's late \"ended\" event must not clobber the new playback state\n (this._node as AudioBufferSourceNode).onended = null;\n this._node.disconnect();\n }\n this._node = this._ctx.createBufferSource();\n if (buf !== undefined) this._buffer = buf;\n\n (this._node as AudioBufferSourceNode).buffer = this._buffer; // apply or re-use buffer\n (this._node as AudioBufferSourceNode).onended = () => {\n this._playing = false;\n };\n this._bufferPlayed = false;\n if (this.analyzer) this._node.connect(this.analyzer.node);\n for (const n of this._connected) this._node.connect(n);\n return this;\n }\n\n /**\n * Create a `Sound` by generating a waveform using [OscillatorNode](https://developer.mozilla.org/en-US/docs/Web/API/OscillatorNode).\n * @param type a string representing the waveform type: \"sine\", \"square\", \"sawtooth\", \"triangle\", \"custom\"\n * @param val the frequency value in Hz to play, or a PeriodicWave instance if type is \"custom\".\n * @returns a `Sound` instance\n * @example `Sound.generate( 'sine', 120 )`\n */\n static generate(type: OscillatorType, val: number | PeriodicWave): Sound {\n const s = new Sound(\"gen\");\n return s._gen(type, val);\n }\n\n // Create the oscillator\n protected _gen(type: OscillatorType, val: number | PeriodicWave): Sound {\n if (this._node) this._node.disconnect(); // tidy the replaced node's edges\n this._node = this._ctx.createOscillator();\n this._generated = true;\n const osc = this._node as OscillatorNode;\n if (type === \"custom\") {\n this._wave = val as PeriodicWave;\n osc.setPeriodicWave(this._wave);\n } else {\n osc.type = type;\n osc.frequency.value = val as number;\n }\n return this;\n }\n\n /**\n * Create a `Sound` by streaming from an input device like microphone. Note that this function returns a Promise which resolves to a Sound instance, and rejects if the input device is unavailable or permission is denied.\n * @param constraint Optional constraints which can be used to select a specific input device. For example, you may use [`enumerateDevices`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices) to find a specific deviceId;\n * @returns a `Promise` which resolves to `Sound` instance\n * @example `Sound.input().then( s => sound = s ).catch( err => ... );`\n */\n static async input(constraint?: MediaStreamConstraints): Promise<Sound> {\n const s = new Sound(\"input\");\n const c = constraint ? constraint : { audio: true, video: false };\n s._stream = await navigator.mediaDevices.getUserMedia(c);\n s._node = s._ctx.createMediaStreamSource(s._stream);\n return s;\n }\n\n /**\n * Get this Sound's AudioContext instance for advanced use-cases.\n */\n get ctx(): AudioContext {\n return this._ctx;\n }\n\n /**\n * Get this Sound's AudioNode subclass instance for advanced use-cases.\n */\n get node(): AudioNode {\n return this._node;\n }\n\n /**\n * Get this Sound's Output node AudioNode instance for advanced use-cases.\n */\n get outputNode(): AudioNode {\n return this._outputNode;\n }\n\n /**\n * Get this Sound's MediaStream (eg, from microphone, if in use) instance for advanced use-cases. See [`Sound.input`](#link)\n */\n get stream(): MediaStream {\n return this._stream;\n }\n\n /**\n * Get this Sound's Audio element (if used) instance for advanced use-cases. See [`Sound.load`](#link).\n */\n get source(): HTMLMediaElement {\n return this._source;\n }\n\n /**\n * Get this Sound's AudioBuffer (if any) instance for advanced use-cases. See [`Sound.loadAsBuffer`](#link).\n */\n get buffer(): AudioBuffer {\n return this._buffer;\n }\n set buffer(b: AudioBuffer) {\n this._buffer = b;\n }\n\n /**\n * Get the type of input for this Sound instance. Either \"file\", \"input\", or \"gen\"\n */\n get type(): SoundType {\n return this._type;\n }\n\n /**\n * Indicate whether the sound is currently playing.\n */\n get playing(): boolean {\n return this._playing;\n }\n\n /**\n * A value between 0 to 1 to indicate playback progress. Returns 0 if the sound has no duration (eg, generated or input sounds).\n */\n get progress(): number {\n let dur = 0;\n let curr = 0;\n if (this._buffer) {\n dur = this._buffer.duration;\n // a timestamp of exactly 0 is valid (started when currentTime === timeAt)\n curr =\n this._timestamp !== undefined\n ? this._ctx.currentTime - this._timestamp\n : 0;\n } else if (this._source) {\n dur = this._source.duration;\n curr = this._source.currentTime;\n }\n return dur > 0 ? Num.clamp(curr / dur, 0, 1) : 0;\n }\n\n /**\n * Indicate whether the sound is ready to play. When loading from a file, this corresponds to a [\"canplaythrough\"](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState) event.\n * You can also use `this.source.addEventListener( 'canplaythrough', ...)` if needed. See also [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canplaythrough_event).\n */\n get playable(): boolean {\n if (this._type === \"input\" || this._type === \"gen\")\n return this._node !== undefined;\n return (\n !!this._buffer ||\n (this._source !== undefined && this._source.readyState === 4)\n );\n }\n\n /**\n * If an analyzer is added (see [`analyze`](#function_analyze) function), get the number of frequency bins in the analyzer. Returns 0 if no analyzer is added.\n */\n get binSize(): number {\n return this.analyzer ? this.analyzer.size : 0;\n }\n\n /**\n * Get the sample rate of the audio, for example, at 44100 hz.\n */\n get sampleRate(): number {\n return this._ctx.sampleRate;\n }\n\n /**\n * If the sound is generated, this sets and gets the frequency of the tone.\n */\n get frequency(): number {\n const osc = this._node as OscillatorNode;\n return this._type === \"gen\" && osc && osc.frequency\n ? osc.frequency.value\n : 0;\n }\n set frequency(f: number) {\n const osc = this._node as OscillatorNode;\n if (this._type === \"gen\" && osc && osc.frequency) osc.frequency.value = f;\n }\n\n /**\n * Get and set the volume of this sound. Default is 1. Values above 1 amplify the sound. Can be set before or during playback.\n */\n get volume(): number {\n return this._volume;\n }\n set volume(v: number) {\n this._volume = Math.max(0, v || 0); // `|| 0` also converts NaN\n if (this._gain) this._gain.gain.value = this._volume;\n }\n\n /**\n * Connect another AudioNode to this `Sound` instance's AudioNode. Using this function, you can extend the capabilities of this `Sound` instance for advanced use cases such as filtering. The connection is restored if a generated sound is restarted.\n * @param node another AudioNode\n */\n connect(node: AudioNode): this {\n this._connected.push(node);\n this._node.connect(node);\n return this;\n }\n\n /**\n * Sets the 'output' node for this Sound\n * This would typically be used after Sound.connect, if you are adding nodes\n * in your chain for filtering purposes.\n * @param outputNode The AudioNode that should connect to the AudioContext\n */\n setOutputNode(outputNode: AudioNode): this {\n this._outputNode = outputNode;\n return this;\n }\n\n /**\n * Removes the 'output' node added from setOutputNode\n * Note: if you start the Sound after calling this, it will play via the default node\n */\n removeOutputNode(): this {\n this._outputNode = null!;\n return this;\n }\n\n /**\n * Add an analyzer to this `Sound`. Calling it again replaces the existing analyzer.\n * @param size the number of frequency bins. Should be a power of 2.\n * @param minDb Optional minimum decibels (corresponds to `AnalyserNode.minDecibels`)\n * @param maxDb Optional maximum decibels (corresponds to `AnalyserNode.maxDecibels`)\n * @param smooth Optional smoothing value (corresponds to `AnalyserNode.smoothingTimeConstant`)\n */\n analyze(\n size: number = 256,\n minDb: number = -100,\n maxDb: number = -30,\n smooth: number = 0.8,\n ): this {\n if (this.analyzer && this._node) {\n try {\n this._node.disconnect(this.analyzer.node);\n } catch {\n // the previous analyzer node was not connected\n }\n }\n const a = this._ctx.createAnalyser();\n a.fftSize = size * 2;\n a.minDecibels = minDb;\n a.maxDecibels = maxDb;\n a.smoothingTimeConstant = smooth;\n this.analyzer = {\n node: a,\n size: a.frequencyBinCount,\n data: new Uint8Array(a.frequencyBinCount),\n };\n this._node.connect(this.analyzer.node);\n return this;\n }\n\n // Get either time-domain or frequency domain\n protected _domain(time: boolean): Uint8Array {\n if (this.analyzer) {\n if (time) {\n this.analyzer.node.getByteTimeDomainData(\n this.analyzer.data as Parameters<\n AnalyserNode[\"getByteTimeDomainData\"]\n >[0],\n );\n } else {\n this.analyzer.node.getByteFrequencyData(\n this.analyzer.data as Parameters<\n AnalyserNode[\"getByteFrequencyData\"]\n >[0],\n );\n }\n return this.analyzer.data;\n }\n return new Uint8Array(0);\n }\n\n // Map domain data to another range, reusing the Pts in `out` when provided\n protected _domainTo(\n time: boolean,\n size: PtLike,\n position: PtLike = [0, 0],\n trim = [0, 0],\n out?: Group,\n ): Group {\n const data = time ? this.timeDomain() : this.freqDomain();\n const g = out || new Group();\n const len = data.length - trim[1];\n const count = Math.max(0, len - trim[0]);\n if (g.length > count) g.length = count;\n for (let i = trim[0], j = 0; i < len; i++, j++) {\n const x = position[0] + (size[0] * i) / len;\n const y = position[1] + (size[1] * data[i]) / 255;\n const p = g[j];\n if (p && p.length >= 2) {\n p[0] = x;\n p[1] = y;\n } else {\n g[j] = new Pt(x, y);\n }\n }\n return g;\n }\n\n /**\n * Get the raw time-domain data from analyzer as unsigned 8-bit integers. An analyzer must be added before calling this function (See [analyze](#function_analyze) function).\n */\n timeDomain(): Uint8Array {\n return this._domain(true);\n }\n\n /**\n * Map the time-domain data from analyzer to a range. An analyzer must be added before calling this function (See [analyze](#function_analyze) function).\n * @param size map each data point `[index, value]` to `[width, height]`\n * @param position Optionally, set a starting `[x, y]` position. Default is `[0, 0]`\n * @param trim Optionally, trim the start and end values by `[startTrim, data.length-endTrim]`\n * @param out Optionally, provide a `Group` (usually one returned by a previous call) whose Pts will be reused instead of allocating new ones — recommended when calling once per frame\n * @returns a Group containing the mapped values\n * @example form.point( s.timeDomainTo( space.size ) )\n */\n timeDomainTo(\n size: PtLike,\n position: PtLike = [0, 0],\n trim = [0, 0],\n out?: Group,\n ): Group {\n return this._domainTo(true, size, position, trim, out);\n }\n\n /**\n * Get the raw frequency-domain data from analyzer as unsigned 8-bit integers. An analyzer must be added before calling this function (See [analyze](#function_analyze) function).\n */\n freqDomain(): Uint8Array {\n return this._domain(false);\n }\n\n /**\n * Map the frequency-domain data from analyzer to a range. An analyzer must be added before calling this function (See [analyze](#function_analyze) function).\n * @param size map each data point `[index, value]` to `[width, height]`\n * @param position Optionally, set a starting `[x, y]` position. Default is `[0, 0]`\n * @param trim Optionally, trim the start and end values by `[startTrim, data.length-endTrim]`\n * @param out Optionally, provide a `Group` (usually one returned by a previous call) whose Pts will be reused instead of allocating new ones — recommended when calling once per frame\n * @returns a Group containing the mapped values\n * @example `form.point( s.freqDomainTo( space.size ) )`\n */\n freqDomainTo(\n size: PtLike,\n position: PtLike = [0, 0],\n trim = [0, 0],\n out?: Group,\n ): Group {\n return this._domainTo(false, size, position, trim, out);\n }\n\n /**\n * Stop playing and disconnect the AudioNode.\n */\n reset(): this {\n this.stop();\n if (this._node) this._node.disconnect();\n if (this._outputNode) this._outputNode.disconnect();\n return this;\n }\n\n // Get the gain node for volume control, creating and connecting it on first use\n protected _getGain(): GainNode {\n if (!this._gain) {\n this._gain = this._ctx.createGain();\n this._gain.gain.value = this._volume;\n this._gain.connect(this._ctx.destination);\n }\n return this._gain;\n }\n\n /**\n * Start playing. Internally this connects the `AudioNode` to `AudioContext`'s destination.\n * Calling `start( timeAt )` while a file or buffer sound is playing seeks to that time; a generated sound that is already playing is unaffected.\n * @param timeAt optional parameter to play from a specific time, in seconds\n */\n start(timeAt: number = 0): this {\n if (this._ctx.state === \"suspended\") this._ctx.resume();\n\n if (this._type === \"file\") {\n if (this._buffer) {\n // An AudioBufferSourceNode can only start once; re-create it for\n // replay, seek-while-playing, or when only the buffer was assigned\n if (this._playing || this._bufferPlayed || !this._node) {\n if (this._playing && this.progress < 1) {\n (this._node as AudioBufferSourceNode).stop();\n }\n this.createBuffer();\n }\n (this._node as AudioBufferSourceNode).start(0, timeAt);\n this._bufferPlayed = true;\n this._timestamp = this._ctx.currentTime - timeAt;\n } else {\n if (timeAt > 0) this._source.currentTime = timeAt;\n const played = this._source.play();\n if (played && played.catch) {\n played.catch(() => {\n // eg, autoplay was blocked — but only if a later start hasn't succeeded\n if (this._source.paused) this._playing = false;\n });\n }\n }\n } else if (this._type === \"gen\" && this._generated) {\n // restarting while playing would orphan the old oscillator, which keeps sounding\n if (this._playing) return this;\n const osc = this._node as OscillatorNode;\n this._gen(\n osc.type,\n osc.type === \"custom\" ? this._wave : osc.frequency.value,\n );\n (this._node as OscillatorNode).start();\n }\n\n // restore analysis and filter chains; duplicate connects are no-ops\n if (this.analyzer) this._node.connect(this.analyzer.node);\n for (const n of this._connected) this._node.connect(n);\n\n (this._outputNode || this._node).connect(this._getGain());\n this._playing = true;\n return this;\n }\n\n /**\n * Stop playing. Internally this also disconnects the `AudioNode` from `AudioContext`'s destination. Calling `stop` when the sound is not playing has no effect.\n */\n stop(): this {\n if (!this._playing) return this;\n (this._outputNode || this._node).disconnect(this._gain);\n\n if (this._type === \"file\") {\n if (this._buffer) {\n // Safari throws InvalidState error if stop() is called after finished playing\n if (this.progress < 1) (this._node as AudioBufferSourceNode).stop();\n } else {\n this._source.pause();\n }\n } else if (this._type === \"gen\") {\n if (this._generated) (this._node as OscillatorNode).stop();\n } else if (this._type === \"input\" && this._stream) {\n // an input created from a node without its MediaStream has no tracks to stop\n this._stream.getAudioTracks().forEach((track) => track.stop());\n }\n\n this._playing = false;\n return this;\n }\n\n /**\n * Toggle between `start` and `stop`.\n */\n toggle(): this {\n if (this._playing) {\n this.stop();\n } else {\n this.start();\n }\n return this;\n }\n\n /**\n * Stop playing and disconnect all nodes (including analyzer and volume), and release stream, source, and buffer references.\n * The instance should not be used after calling this. Note that this never closes an `AudioContext`: the shared context lives for the page, and a context you provided is yours to close.\n */\n dispose(): this {\n // Input tracks are live as soon as they are acquired, even without start().\n if (!this._playing && this._stream) {\n this._stream.getAudioTracks().forEach((track) => track.stop());\n }\n this.reset();\n if (this.analyzer) {\n this.analyzer.node.disconnect();\n this.analyzer = undefined!;\n }\n if (this._gain) {\n this._gain.disconnect();\n this._gain = undefined!;\n }\n this._connected = [];\n this._stream = undefined!;\n this._source = undefined!;\n this._buffer = undefined!;\n return this;\n }\n}\n","import * as Canvas from \"./Canvas\";\nimport * as Create from \"./Create\";\nimport * as Form from \"./Form\";\nimport * as LinearAlgebra from \"./LinearAlgebra\";\nimport * as Num from \"./Num\";\nimport * as Op from \"./Op\";\nimport * as Pt from \"./Pt\";\nimport * as Space from \"./Space\";\nimport * as Color from \"./Color\";\nimport * as Util from \"./Util\";\nimport * as Dom from \"./Dom\";\nimport * as Svg from \"./Svg\";\nimport * as Typography from \"./Typography\";\nimport * as Physics from \"./Physics\";\nimport * as UI from \"./UI\";\nimport * as Play from \"./Play\";\nimport * as Image from \"./Image\";\nimport * as Types from \"./Types\";\n\ndeclare global {\n // the browser bundle mounts the whole library on globalThis.Pts\n\n var Pts: Record<string, any>;\n}\n\nglobalThis.Pts = {\n ...Canvas,\n ...Create,\n ...Form,\n ...LinearAlgebra,\n ...Num,\n ...Op,\n ...Pt,\n ...Space,\n ...Color,\n ...Util,\n ...Dom,\n ...Svg,\n ...Typography,\n ...Physics,\n ...UI,\n ...Play,\n ...Image,\n};\n\n// A function to switch scope for Pts library. eg, Pts.namespace( window );\nglobalThis.Pts.namespace = (scope: any) => {\n let lib = globalThis.Pts;\n for (let k in lib) {\n if (k != \"namespace\") {\n scope[k] = lib[k];\n }\n }\n};\n\nglobalThis.Pts.quickStart = (id: string | Element, bg: string = \"#9ab\") => {\n if (!window) return;\n\n let s: any = globalThis;\n globalThis.Pts.namespace(s);\n\n // pick the rendering backend from the mount element: an <svg> element (or a\n // container holding one) gets an SVGSpace, anything else a CanvasSpace —\n // so a sketch can swap renderers by changing only its HTML\n // Preserve CanvasSpace's bare-ID shorthand for both rendering backends.\n const mount =\n typeof id === \"string\" && id[0] !== \"#\" && id[0] !== \".\" ? `#${id}` : id;\n const elem =\n typeof mount === \"string\" ? document.querySelector(mount) : mount;\n const isSVG =\n elem &&\n ((elem as Element).nodeName.toLowerCase() === \"svg\" ||\n !!(elem as Element).querySelector(\":scope > svg\"));\n\n s.space = isSVG\n ? new Svg.SVGSpace(mount).setup({ bgcolor: bg, resize: true })\n : new Canvas.CanvasSpace(mount).setup({\n bgcolor: bg,\n resize: true,\n retina: true,\n });\n s.form = s.space.getForm();\n\n return function (animate = null, start = null, action = null, resize = null) {\n s.space.add({\n start: start,\n animate: animate,\n resize: resize,\n action: action,\n });\n\n s.space.bindMouse().bindTouch().play();\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAcA,IAAI,gBAAgB,KAAU,QAAyB,eACrD,KAAK,KAAK,iCAAiC,OAAO,GAAG;CACvD,IAAI,oBAAoB,KAAU,QAAyB,OACzD,KAAK,KAAK,SAAS,MAAM,4BAA4B,GAAG;CAO1D,IAAa,OAAb,MAAa,KAAK;EAQhB,OAAO,UAAU,QAAgB,OAAe,WAA0B;GACxE,IAAI,IAAI,IAAI,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;GAChD,EAAE,EAAE,CAAC,QAAQ,OAAO,WAAW,IAAI;GACnC,OAAO;EACT;EAOA,OAAO,MAAM,IAAY,IAAgC;GACvD,OAAO,GAAG,KAAK,GAAG,OAAO,IAAI,UAAa,GAAG,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG;EACzE;EAQA,OAAO,UACL,IACA,IACmE;GACnE,IAAI,GAAG,KAAK,GAAG,OAAO,GACpB;QACK;IACL,IAAI,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG;IACtC,IAAI,IAAI,GAAG,KAAK,IAAI,GAAG;IACvB,OAAO;KAAE,OAAO;KAAG,IAAI;KAAG,IAAI,MAAM,IAAI,SAAY,CAAC,IAAI;IAAE;GAC7D;EACF;EAQA,OAAO,WAAW,MAAsB,IAAoB;GAC1D,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,QACG,MAAM,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,OAAO,GAAG,KAAK,MAAM,EAAE,CAAC,OAC/C,GAAG,KAAK,MAAM,EAAE,CAAC,OAAO,MAAM,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC;EAEpD;EASA,OAAO,UACL,IACA,IACA,IACA,YAAoB,KACX;GAGT,MAAM,IAAI,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,EAAE;GAC7C,MAAM,IAAI,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,EAAE;GAC7C,MAAM,QAAQ,EAAE,YAAY,IAAI,EAAE,YAAY;GAC9C,IAAI,UAAU,GAAG,OAAO;GACxB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,SAAS,YAAY;EAC1D;EAMA,OAAO,UAAU,MAA0B;GACzC,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,OAAO,MAAM,UAAU,IAAI,MAAM,EAAE,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC,UAAU,IAAI;EACxE;EAMA,OAAO,YAAY,MAA0B;GAC3C,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,OAAO,MAAM,UAAU,IAAI,MAAM,EAAE,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC,YAAY,IAAI;EAC1E;EASA,OAAO,oBACL,MACA,IACA,eAAwB,OACR;GAChB,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,MAAM,EAAE,CAAC,OAAO,MAAM,EAAE,GAAG,OAAO;GACtC,IAAI,IAAI,MAAM,EAAE,CAAC,UAAU,MAAM,EAAE;GACnC,IAAI,IAAI,MAAM,EAAE,CAAC,UAAU,EAAE;GAC7B,IAAI,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;GAEpC,OAAO,eAAe,OAAO,KAAK,KAAK,EAAE;EAC3C;EAQA,OAAO,eAAe,MAAiB,IAA+B;GACpE,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,mBAAmB,KAAK,oBAAoB,OAAO,IAAI,IAAI;GAC/D,IAAI,kBACF,OAAO,iBAAiB,UAAU;QAGlC,OAAO,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU;EAE5C;EAQA,OAAO,eAAe,IAAgB,IAAgC;GACpE,MAAM,MAAM,KAAK,YAAY,EAAE;GAC/B,MAAM,MAAM,KAAK,YAAY,EAAE;GAE/B,MAAM,KAAK,IAAI;GACf,MAAM,KAAK,IAAI;GAIf,MAAM,KAAK,IAAI,EAAE,CAAC,KAAK,GAAG;GAC1B,MAAM,KAAK,IAAI,EAAE,CAAC,KAAK,GAAG;GAC1B,MAAM,KAAK,IAAI,EAAE,CAAC,KAAK,GAAG;GAC1B,MAAM,KAAK,IAAI,EAAE,CAAC,KAAK,GAAG;GAG1B,IAAK,OAAO,KAAK,OAAO,KAAO,OAAO,KAAK,OAAO,GAAI,OAAO;GAE7D,MAAM,MAAM,KAAK,KAAK,KAAK;GAC3B,IAAI,QAAQ,GAAG;IAEb,MAAM,MAAM,GAAG,KAAK,GAAG;IACvB,MAAM,MAAM,GAAG,KAAK,GAAG;IACvB,OAAO,MAAM,KAAK,MAAM,OAAO,IAAI,IAAI,GAAG,GAAG,IAAI,GAAG,EAAE,IAAI;GAC5D;GAEA,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,MAAM;GAC1D,OAAO,IAAI,GAAG,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,EAAE;EAC9C;EAQA,OAAO,gBAAgB,IAAgB,IAAgC;GACrE,IAAI,MAAM,KAAK,YAAY,EAAE;GAC7B,IAAI,MAAM,KAAK,YAAY,EAAE;GAE7B,IAAI,KAAK,KAAK,eAAe,KAAK,GAAG;GACrC,OAAO,MACL,KAAK,YAAY,IAAI,IAAI,IAAI,IAAI,EAAE,KACnC,KAAK,YAAY,IAAI,IAAI,IAAI,IAAI,EAAE,IACjC,KACA;EACN;EAQA,OAAO,uBACL,MACA,KACgB;GAChB,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,KAAK,eAAe,OAAO,IAAI;GACxC,OAAO,MAAM,KAAK,YAAY,IAAI,MAAM,IAAI,MAAM,EAAE,IAAI,KAAK;EAC/D;EAQA,OAAO,mBACL,WACA,MACA,cAAuB,OACJ;GACnB,IAAI,aAAa,KAAK,YAAY,SAAS;GAC3C,IAAI,QAAQ,KAAK,YAAY,IAAI;GAEjC,IAAI,KAAK,cAAc,KAAK,yBAAyB,KAAK;GAC1D,IAAI,MAAM,IAAI,MAAM;GACpB,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,IAAI,OAAO,MAAM,MAAM,IAAI,IAAI,IAAI;IACnC,IAAI,IAAI,GAAG,CAAC,MAAM,IAAI,MAAM,KAAK,GAAG,UAAU;IAC9C,IAAI,GAAG,IAAI,KAAK,CAAC;GACnB;GACA,OAAO,IAAI,SAAS,IAAI,MAAM;EAChC;EAQA,OAAO,iBACL,QACA,QACA,QAAiB,OACV;GACP,IAAI,QAAQ,IAAI,MAAM;GACtB,IAAI,KAAK,QAAQ,KAAK,yBAAyB,KAAK;GACpD,KAAK,IAAI,MAAM,QACb,KAAK,IAAI,MAAM,QAAQ;IACrB,IAAI,MAAM,GAAG,IAAI,EAAE;IACnB,IAAI,KAAK,MAAM,KAAK,GAAG;GACzB;GAEF,OAAO;EACT;EAQA,OAAO,uBAAuB,KAAiB,QAAuB;GACpE,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,IAAI,KAAK,UACX,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,SAAS,MAAM,GAC/B,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,SAAS,MAAM,CACjC;GACA,IAAI,IAAI,IAAI,MAAM;GAClB,IAAI,KAAK,EAAE,OAAO,QAAW,EAAE,KAAK,IAAI,GAAG,OAAO,KAAK,EAAE,IAAI,OAAO,EAAE,CAAC;GACvE,IAAI,KAAK,EAAE,OAAO,QAAW,EAAE,KAAK,IAAI,GAAG,OAAO,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;GACvE,OAAO;EACT;EAQA,OAAO,wBACL,MACA,QACO;GACP,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,IAAI,KAAK,uBAAuB,OAAO,MAAM;GACjD,IAAI,KAAK,IAAI,MAAM;GACnB,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,IAAI,KAAK,YAAY,EAAE,IAAI,MAAM,IAAI,MAAM,EAAE,GAAG,GAAG,KAAK,EAAE,EAAE;GAE9D,OAAO;EACT;EAQA,OAAO,gBAAgB,MAAiB,MAAwB;GAC9D,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,MAAM,KAAK,YAAY,MAAM,YAAY,KAAK,CAAC;GACnD,IAAI,CAAC,UAAU,mBAAmB,KAAK,KAAK,GAAG,OAAO,IAAI,MAAM;GAChE,OAAO,KAAK,iBAAiB,CAAC,KAAK,GAAG,UAAU,MAAM,KAAK,CAAC;EAC9D;EAOA,OAAO,UAAU,MAAsB,KAAa;GAClD,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,MAAM,IAAI,MAAM;GACpB,KAAK,IAAI,IAAI,GAAG,KAAK,KAAK,KACxB,IAAI,KAAK,KAAK,YAAY,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM,EAAE,CAAC;GAE9D,OAAO;EACT;EAUA,OAAO,KACL,MACA,MACA,QAAgB,GAChB,eAAwB,MACR;GAChB,IAAI,QAAQ,KAAK,YAAY,IAAI;GAEjC,IAAI,KAAK,MADC,UAAU,IAAI,IAAI,EACT,CAAC,UAAU,MAAM,MAAM;GAE1C,IAAI,GAAG,YAAY,MAAM,GAAG,OAAO,MAAM;GAEzC,IAAI,cAAc;IAChB,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,SAAS,KAAK,EAAE;IAClC,OAAO,MAAM,MAAM,CAAC,KAAK,CAAC;GAC5B,OAAO;IACL,IAAI,KAAK,OAAO,GAAG,OAAO,MAAM;IAChC,IAAI,OAAO,UAAU,WAAW,MAAM,QAAQ,IAAI;IAClD,IAAI,QAAQ,UAAU,MAAM,IAAI;IAChC,IAAI,UAAU;IAEd,IAAI,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK,EAAE,GACtD,UAAU,GAAG,KAAK,IAAI,IAAI;SAE1B,UAAU,GAAG,KAAK,IAAI,IAAI;IAE5B,OAAO,KAAK,eAAe,MAAM,UAAU,KAAK;GAClD;EACF;EAUA,OAAO,OACL,MACA,MACA,UAAkB,SAClB,SAAkB,MACX;GACP,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,IAAI,SAAS,IAAI;GACrB,IAAI,IAAI,SAAS,IAAI;GACrB,IAAI,OAAO,MAAM,EAAE,CAAC,UAAU,MAAM,EAAE;GAEtC,IAAI,KAAK,YAAY,MAAM,GAAG,OAAO,IAAI,MAAM;GAC/C,KAAK,KAAK;GAEV,IAAI,KAAK,KAAK,cAAc,IAAI,CAAC,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC,IAAI,MAAM,EAAE;GAChE,IAAI,WAAW,SAAS;IACtB,GAAG,IAAI,KAAK,UAAU,KAAK,EAAE,CAAC;IAC9B,OAAO,IAAI,MAAM,MAAM,IAAI,GAAG,IAAI,GAAG,EAAE;GACzC,OACE,OAAO,IAAI,MAAM,GAAG,IAAI,GAAG,EAAE;EAEjC;EAMA,OAAO,OAAO,MAAiB;GAC7B,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,OAAO,IAAI,MAAM,MAAM,EAAE,CAAC,KAAK,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC;EACnE;CACF;CAOA,IAAa,YAAb,MAAa,UAAU;EAQrB,OAAO,KACL,SACA,aACA,QACO;GACP,OAAO,UAAU,YAAY,SAAS,aAAa,MAAM;EAC3D;EASA,OAAO,YACL,SACA,aACA,QACO;GACP,IAAI,OACF,OAAO,eAAe,WAClB,CAAC,aAAa,gDAAU,WAAW,IACnC;GACN,OAAO,IAAI,MAAM,IAAI,GAAG,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC;EAC7D;EASA,OAAO,WACL,QACA,aACA,QACO;GACP,IAAI,OACF,OAAO,eAAe,WAClB,CAAC,cAAc,IAAI,gDAAU,eAAe,CAAC,IAC7C,IAAI,GAAG,WAAW,CAAC,CAAC,OAAO,CAAC;GAClC,OAAO,IAAI,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,SAAS,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC;EAC1E;EAQA,OAAO,SAAS,KAAiB,UAAmB,MAAa;GAC/D,OAAO,OAAO,SAAS,KAAK,OAAO;EACrC;EAQA,OAAO,SAAS,KAAiB,UAAU,OAAc;GACvD,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,IAAI,UAAU,KAAK,IAAI;GAC3B,IAAI,IAAI,UAAU,EAAE,SAAS,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;GACpD,OAAO,UAAU,WAAW,UAAU,OAAO,IAAI,GAAG,GAAG,CAAC;EAC1D;EAMA,OAAO,KAAK,KAAqB;GAC/B,IAAI,IAAI,KAAK,YAAY,GAAG;GAC5B,OAAO,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;EACjD;EAMA,OAAO,OAAO,KAAqB;GACjC,IAAI,IAAI,KAAK,YAAY,GAAG;GAC5B,IAAI,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE;GACxB,IAAI,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE;GACxB,OAAO,IAAI,IAAI,IAAI,UAAU,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;EAC7C;EAMA,OAAO,QAAQ,MAAyB;GACtC,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,KAAK,MAAM,EAAE,CAAC,KAAK,MAAM,EAAE;GAC/B,IAAI,KAAK,MAAM,EAAE,CAAC,KAAK,MAAM,EAAE;GAC/B,OAAO,IAAI,MAAM,IAAI,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;EACjE;EAOA,OAAO,MAAM,MAA2B;GACtC,IAAI,CAAC,IAAI,IAAI,IAAI,MAAM,UAAU,QAAQ,IAAI;GAC7C,OAAO;IACL,IAAI,MAAM,IAAI,EAAE;IAChB,IAAI,MAAM,IAAI,EAAE;IAChB,IAAI,MAAM,IAAI,EAAE;IAChB,IAAI,MAAM,IAAI,EAAE;GAClB;EACF;EAOA,OAAO,YAAY,OAAwC;GACzD,IAAI,SAAS,KAAK,YAAY,KAAK;GACnC,IAAI,SAAS,KAAK,QAAQ,QAAQ,KAAK;GACvC,IAAI,OAAO,WAAW,GAAG,OAAO,IAAI,MAAM;GAK1C,IAAI,MAAM,GAAG,KAAK,GAAG,QAAQ;GAC7B,IAAI,MAAM,GAAG,KAAK,GAAG,SAAS;GAG9B,KAAK,IAAI,IAAI,GAAG,MAAM,OAAO,QAAQ,IAAI,KAAK,KAAK;IACjD,IAAI,IAAI,OAAO;IACf,IAAI,MAAM,KAAK,IAAI,GAAG,EAAE,MAAM;IAC9B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK;KAC5B,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,EAAE,EAAE;KAC9B,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,EAAE,EAAE;IAChC;GACF;GACA,OAAO,IAAI,MAAM,KAAK,GAAG;EAC3B;EAMA,OAAO,QAAQ,MAAyB;GACtC,OAAO,UAAU,QAAQ,IAAI;EAC/B;EAOA,OAAO,UAAU,MAAkB,QAA0B;GAC3D,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,UAAU,UAAU,QAAQ,KAAK;GACrC,IAAI,UACF,UAAU,SAAY,IAAI,GAAG,MAAM,IAAI,UAAU,OAAO,KAAK;GAC/D,OAAO,QAAQ,KAAK,MAAM,IAAI,MAAM,GAAG,OAAO,CAAC,CAAC,YAAY,CAAC;EAC/D;EASA,OAAO,OACL,MACA,QAAgB,IAChB,SAAkB,OACT;GACT,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,MAAM,MAAM,EAAE,CAAC,KAAK,MAAM,EAAE;GAChC,IAAI,MAAM,MAAM,EAAE,CAAC,KAAK,MAAM,EAAE;GAChC,IAAI,MAAM,SACN,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,KAAK,IAC9B,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,KAAK;GAClC,OAAO,SACH,CACE,IAAI,MAAM,KAAK,IAAI,GAAG,IAAI,IAAI,GAAG,CAAC,GAClC,IAAI,MAAM,IAAI,GAAG,IAAI,IAAI,GAAG,GAAG,GAAG,CACpC,IACA,CACE,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC,GAClC,IAAI,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE,GAAG,GAAG,CACpC;EACN;EAOA,OAAO,YAAY,MAAiB,IAAqB;GACvD,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,OAAO,KAAK,YAAY,IAAI,MAAM,IAAI,MAAM,EAAE;EAChD;EAQA,OAAO,mBACL,OACA,OACA,mBAA4B,OACnB;GACT,IAAI,SAAS,KAAK,YAAY,KAAK;GACnC,IAAI,SAAS,KAAK,YAAY,KAAK;GAEnC,IAAI,kBAAkB;IACpB,SAAS,KAAK,YAAY,MAAM;IAChC,SAAS,KAAK,YAAY,MAAM;GAClC;GAEA,IAAI,OAAO,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC,MAAM,OAAO,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC,IAC1D,OAAO;GACT,IAAI,OAAO,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC,MAAM,OAAO,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC,IAC1D,OAAO;GACT,OAAO;EACT;EAOA,OAAO,gBAAgB,OAAkB,OAAyB;GAChE,IAAI,SAAS,KAAK,YAAY,KAAK;GACnC,IAAI,SAAS,KAAK,YAAY,KAAK;GACnC,IAAI,CAAC,UAAU,mBAAmB,QAAQ,MAAM,GAAG,OAAO,IAAI,MAAM;GACpE,OAAO,KAAK,iBACV,UAAU,MAAM,MAAM,GACtB,UAAU,MAAM,MAAM,CACxB;EACF;CACF;CAQA,IAAa,SAAb,MAAa,OAAO;EAOlB,OAAO,SAAS,KAAqB,UAAU,OAAc;GAC3D,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,IAAI;GACR,IAAI,MAAO,IAAI,UAAU,KAAK,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ;GACvD,IAAI,SAAS;IACX,IAAI,MAAM,UAAU,KAAK,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ;IAClD,IAAI,KAAK,KAAK,MAAM,MAAM,MAAM,GAAG;GACrC,OACE,IAAI;GAEN,OAAO,IAAI,MAAM,UAAU,OAAO,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;EACvD;EAQA,OAAO,aACL,KACA,UAAmB,OACA;GACnB,IAAI,SACF,OAAO,SAAS,aAAa,GAAG;QAEhC,OAAO,SAAS,SAAS,GAAG;EAEhC;EAQA,OAAO,WAAW,IAAY,QAAuB;GACnD,OAAO,IAAI,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,GAAG,QAAQ,MAAM,CAAC;EACrD;EAQA,OAAO,YACL,KACA,IACA,YAAoB,GACX;GACT,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,IAAI,KAAK,EAAE,CAAC,UAAU,EAAE;GAC5B,OAAO,EAAE,IAAI,CAAC,IAAI,YAAY,KAAK,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;EACpD;EAQA,OAAO,eAAe,QAAoB,KAAwB;GAChE,IAAI,OAAO,KAAK,YAAY,MAAM;GAClC,IAAI,OAAO,KAAK,YAAY,GAAG;GAE/B,IAAI,IAAI,KAAK,EAAE,CAAC,UAAU,KAAK,EAAE;GACjC,IAAI,IAAI,KAAK,EAAE,CAAC,UAAU,KAAK,EAAE;GAEjC,IAAI,IAAI,EAAE,IAAI,CAAC;GACf,IAAI,MAAM,GAAG,OAAO,IAAI,MAAM;GAC9B,IAAI,IAAI,EAAE,IAAI,CAAC;GACf,IAAI,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;GACvC,IAAI,IAAI,IAAI;GACZ,IAAI,IAAI,IAAI;GACZ,IAAI,OAAO,IAAI,IAAI;GAEnB,IAAI,OAAO,GACT,OAAO,IAAI,MAAM;QACZ;IACL,IAAI,WAAW,KAAK,KAAK,IAAI;IAE7B,IAAI,KAAK,CAAC,IAAI;IACd,IAAI,KAAK,KAAK,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC;IAC1C,IAAI,SAAS,GAAG,OAAO,IAAI,MAAM,EAAE;IAEnC,IAAI,KAAK,CAAC,IAAI;IACd,IAAI,KAAK,KAAK,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC;IAC1C,OAAO,IAAI,MAAM,IAAI,EAAE;GACzB;EACF;EAQA,OAAO,gBAAgB,QAAoB,MAAyB;GAClE,IAAI,OAAO,KAAK,YAAY,MAAM;GAClC,IAAI,QAAQ,KAAK,YAAY,IAAI;GAEjC,IAAI,KAAK,OAAO,eAAe,MAAM,KAAK;GAC1C,IAAI,IAAI,IAAI,MAAM;GAClB,IAAI,GAAG,SAAS,GACd;SAAK,IAAI,IAAI,GAAG,MAAM,GAAG,QAAQ,IAAI,KAAK,KACxC,IAAI,UAAU,YAAY,OAAO,GAAG,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE;GACvD;GAEF,OAAO;EACT;EAQA,OAAO,kBAAkB,SAAqB,SAA4B;GACxE,IAAI,OAAO,KAAK,YAAY,OAAO;GACnC,IAAI,UAAU,KAAK,YAAY,OAAO;GAEtC,IAAI,KAAK,QAAQ,EAAE,CAAC,UAAU,KAAK,EAAE;GACrC,IAAI,MAAM,GAAG,YAAY;GACzB,IAAI,KAAK,KAAK,KAAK,GAAG;GAEtB,IAAI,KAAK,KAAK,EAAE,CAAC;GACjB,IAAI,KAAK,QAAQ,EAAE,CAAC;GACpB,IAAI,MAAM,KAAK;GACf,IAAI,MAAM,KAAK;GAEf,IAAI,KAAK,KAAK,IAEZ,OAAO,IAAI,MAAM;QACZ,IAAI,KAAK,KAAK,IAAI,KAAK,EAAE,GAE9B,OAAO,IAAI,MAAM,KAAK,EAAE,CAAC,MAAM,CAAC;QAC3B,IAAI,OAAO,GAEhB,OAAO,IAAI,MAAM;QACZ;IACL,IAAI,KAAK,MAAM,MAAM,QAAQ,IAAI;IACjC,IAAI,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC;IAC7B,IAAI,IAAI,GAAG,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,KAAK,EAAE;IACxC,OAAO,IAAI,MACT,IAAI,GAAG,EAAE,IAAK,IAAI,GAAG,IAAK,IAAI,EAAE,IAAK,IAAI,GAAG,IAAK,EAAE,GACnD,IAAI,GAAG,EAAE,IAAK,IAAI,GAAG,IAAK,IAAI,EAAE,IAAK,IAAI,GAAG,IAAK,EAAE,CACrD;GACF;EACF;EASA,OAAO,gBAAgB,QAAoB,MAAyB;GAClE,IAAI,OAAO,KAAK,YAAY,MAAM;GAClC,IAAI,QAAQ,KAAK,YAAY,IAAI;GAEjC,IAAI,QAAQ,UAAU,MAAM,KAAK;GACjC,IAAI,IAAI,CAAC;GACT,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,IAAI,KAAK,OAAO,gBAAgB,MAAM,MAAM,EAAE;IAC9C,IAAI,GAAG,SAAS,GAAG,EAAE,KAAK,EAAE;GAC9B;GACA,OAAO,KAAK,QAAQ,CAAC;EACvB;EAQA,OAAO,OAAO,QAAoB,SAAkB,OAAc;GAChE,IAAI,OAAO,KAAK,YAAY,MAAM;GAClC,IAAI,IAAI,KAAK,EAAE,CAAC;GAChB,IAAI,QAAQ;IAEV,IAAI,OAAO,IAAI,KAAK;IACpB,OAAO,IAAI,MAAM,KAAK,EAAE,CAAC,UAAU,IAAI,GAAG,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;GAC9D,OACE,OAAO,IAAI,MAAM,KAAK,EAAE,CAAC,UAAU,CAAC,GAAG,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;EAE1D;EAOA,OAAO,WAAW,QAAoB,SAAkB,MAAa;GACnE,IAAI,OAAO,KAAK,YAAY,MAAM;GAClC,IAAI,QAAQ;IACV,IAAI,MAAM,CAAC,KAAK,KAAK;IACrB,IAAI,MAAO,KAAK,KAAK,IAAK;IAC1B,IAAI,IAAI,IAAI,MAAM;IAClB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;KAC1B,EAAE,KAAK,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;KACrD,OAAO;IACT;IACA,OAAO;GACT,OACE,OAAO,SAAS,WAAW,KAAK,IAAI,KAAK,EAAE,CAAC,EAAE;EAElD;CACF;CAOA,IAAa,WAAb,MAAa,SAAS;EAKpB,OAAO,SAAS,MAAyB;GACvC,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,MAAM,MAAM,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;GAC1C,IAAI,IAAI,MAAM,EAAE,CAAC;GACjB,IAAI,OAAO,MAAM,EAAE,CAAC,MAAM;GAC1B,KAAK,IAAI,MAAM,EAAE,CAAC;GAClB,OAAO,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC,MAAM,GAAG,IAAI;EAC9C;EAMA,OAAO,WAAW,QAA2B;GAC3C,OAAO,OAAO,WAAW,QAAQ,IAAI;EACvC;EAOA,OAAO,WAAW,IAAY,MAAqB;GACjD,OAAO,SAAS,WAAW,OAAO,WAAW,IAAI,IAAI,CAAC;EACxD;EAOA,OAAO,OAAO,KAAwB;GACpC,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,SAAS,GAAG,OAAO,aAAa,IAAI,MAAM,GAAG,CAAC;GACvD,OAAO,QAAQ,UAAU,MAAM,IAAI;EACrC;EAQA,OAAO,aAAa,KAAiB,OAAsB;GACzD,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,SAAS,GAAG,OAAO,aAAa,IAAI,MAAM,GAAG,CAAC;GACvD,IAAI,UAAU,GACZ,OAAO,MAAM,YAAY,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;QACtC,IAAI,UAAU,GACnB,OAAO,MAAM,YAAY,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;QAE3C,OAAO,MAAM,YAAY,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;EAE/C;EAQA,OAAO,SAAS,KAAiB,OAAsB;GACrD,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,MAAM,SAAS,aAAa,MAAM,KAAK;GAC3C,IAAI,IAAI,SAAS,GACf,OAAO,IAAI,MACT,KAAK,QACL,KAAK,oBAAoB,KAAK,KAAK,MAAM,CAC3C;QAEA,OAAO,IAAI,MAAM;EAErB;EAOA,OAAO,YAAY,KAAiC;GAClD,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,SAAS,GAAG,OAAO,aAAa,QAAW,CAAC;GACrD,IAAI,IAAI,SAAS,SAAS,MAAM,CAAC;GACjC,IAAI,IAAI,SAAS,SAAS,MAAM,CAAC;GACjC,OAAO,KAAK,eAAe,GAAG,CAAC;EACjC;EAOA,OAAO,SAAS,KAAiC;GAC/C,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,SAAS,GAAG,OAAO,aAAa,QAAW,CAAC;GACrD,IAAI,IAAI,QAAQ,SAAS,MAAM,CAAC,CAAC,CAAE,IAAI,KAAK,EAAE;GAC9C,IAAI,IAAI,QAAQ,SAAS,MAAM,CAAC,CAAC,CAAE,IAAI,KAAK,EAAE;GAC9C,OAAO,KAAK,eAAe,IAAI,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC;EACzE;EAOA,OAAO,SAAS,KAAiB,QAAgC;GAC/D,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,IAAI,SAAS,SAAS,SAAS,SAAS,IAAI;GAChD,IAAI,CAAC,GAAG,OAAO;GACf,IAAI,OAAO,QAAQ,KAAK,IAAI;GAC5B,IAAI,QAAQ,QAAQ,UAAU,MAAM,IAAI;GACxC,IAAI,IAAK,IAAI,OAAQ,MAAM;GAG3B,IAAI,EAAE,IAAI,IAAI,OAAO;GACrB,OAAO,OAAO,WAAW,GAAG,CAAC;EAC/B;EAOA,OAAO,aAAa,KAAiC;GACnD,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,SAAS,OAAO,IAAI;GAC7B,IAAI,IAAI,CACN,GAAG,IACH,KAAK,cAAc,KAAK,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAC5D;GACA,IAAI,IAAI,CACN,GAAG,IACH,KAAK,cAAc,KAAK,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAC5D;GACA,OAAO,KAAK,eAAe,GAAG,CAAC;EACjC;EAOA,OAAO,aAAa,KAAiB,QAAgC;GACnE,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,IAAI,SAAS,SAAS,SAAS,aAAa,IAAI;GACpD,IAAI,CAAC,GAAG,OAAO;GACf,IAAI,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU;GACvC,OAAO,OAAO,WAAW,GAAG,CAAC;EAC/B;CACF;CAOA,IAAa,UAAb,MAAa,QAAQ;EAKnB,OAAO,SAAS,KAAyB;GACvC,OAAO,KAAK,SAAS,GAAG;EAC1B;EAQA,OAAO,UACL,QACA,aACA,QACO;GACP,OAAO,UAAU,QAAQ,UAAU,WAAW,QAAQ,aAAa,MAAM,CAAC;EAC5E;EAQA,OAAO,WAAW,QAAgB,QAAgB,OAAe;GAC/D,IAAI,IAAI,IAAI,MAAM;GAClB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;IAC9B,IAAI,MAAO,KAAK,KAAK,IAAI,IAAK;IAC9B,EAAE,KACA,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,QAAQ,KAAK,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC,IAAI,MAAM,CACnE;GACF;GACA,OAAO;EACT;EAOA,OAAO,OAAO,KAAqB,OAAe;GAChD,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,QAAQ,KAAK,SAAS,KAAK,QAC7B,MAAM,IAAI,MAAM,kCAAkC;GACpD,OAAO,IAAI,MACT,KAAK,QACL,UAAU,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,QAAQ,EACrD;EACF;EAQA,OAAO,MAAM,MAAkB,YAAqB,MAAe;GACjE,IAAI,OAAO,KAAK,YAAY,IAAI;GAChC,IAAI,KAAK,SAAS,GAAG,OAAO,aAAa,IAAI,MAAM,GAAG,CAAC;GAGvD,MAAM,QAAQ,YAAY,KAAK,SAAS,KAAK,SAAS;GACtD,MAAM,KAAc,IAAI,MAAM,KAAK;GACnC,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;IAC9B,MAAM,MAAM,IAAI,MAAM;IACtB,IAAI,KAAK,KAAK;IACd,IAAI,KAAK,KAAK,MAAM,KAAK,SAAS,IAAI,IAAI,IAAI;IAC9C,GAAG,KAAK;GACV;GACA,OAAO;EACT;EAQA,OAAO,UACL,MACA,YAAqB,OACrB,IAAY,IACL;GACP,MAAM,QAAQ,QAAQ,MAAM,MAAM,SAAS;GAC3C,MAAM,OAAO,IAAI,MAAM;GACvB,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAC3C,KAAK,KAAK,KAAK,YAAY,MAAM,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,IAAI,CAAC;GAExD,OAAO;EACT;EAQA,OAAO,cACL,MACA,OACA,YAAqB,OACZ;GACT,IAAI,OAAO,KAAK,YAAY,IAAI;GAChC,IAAI,KAAK,SAAS,GAAG,OAAO,aAAa,IAAI,MAAM,GAAG,CAAC;GACvD,IAAI,QAAQ,KAAK,SAAS,KAAK,QAC7B,OAAO,iBAAiB,IAAI,MAAM,GAAG,KAAK;GAE5C,IAAI,KAAK,CAAC;GACV,IAAI,OAAO,QAAQ;GACnB,IAAI,aAAa,OAAO,GAAG,OAAO,KAAK,SAAS;GAChD,IAAI,QAAQ,GAAG,GAAG,KAAK,IAAI,MAAM,KAAK,QAAQ,KAAK,KAAK,CAAC;GAEzD,IAAI,QAAQ,QAAQ;GACpB,IAAI,aAAa,QAAQ,KAAK,SAAS,GAAG,QAAQ;GAClD,IAAI,SAAS,KAAK,SAAS,GAAG,GAAG,KAAK,IAAI,MAAM,KAAK,QAAQ,KAAK,MAAM,CAAC;GAEzE,OAAO;EACT;EAQA,OAAO,SAAS,MAAkB,OAA+B;GAC/D,IAAI,QAAQ,QAAQ,cAAc,MAAM,OAAO,IAAI;GACnD,IAAI,MAAM,UAAU,GAAG;IACrB,IAAI,IAAI,MAAM,EAAE,CAAC,EAAE,CAAC,UAAU,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK;IAChD,IAAI,IAAI,MAAM,EAAE,CAAC,EAAE,CAAC,UAAU,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK;IAChD,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;GAC1B,OACE;EAEJ;EAQA,OAAO,UACL,MACA,YAAqB,OACY;GACjC,MAAM,OAAO,KAAK,YAAY,IAAI;GAClC,IAAI,KAAK,SAAS,GAAG;IACnB,aAAa,IAAI,MAAM,GAAG,CAAC;IAC3B,OAAO;KAAE,OAAO;KAAG,UAAU,GAAG,KAAK,GAAG,CAAC;IAAE;GAC7C;GAEA,MAAM,QAAQ,YAAY,KAAK,SAAS,KAAK,SAAS;GACtD,MAAM,IAAI,GAAG,KAAK,OAAO,CAAC;GAC1B,IAAI,MAAM;GAEV,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;IAC9B,MAAM,IAAI,KAAK;IACf,MAAM,IAAI,KAAK,MAAM,KAAK,SAAS,IAAI,IAAI,IAAI;IAC/C,MAAM,KAAK,EAAE,KAAK,EAAE;IACpB,MAAM,KAAK,EAAE,KAAK,EAAE;IACpB,MAAM,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;IACrC,OAAO;IACP,EAAE,KAAK;GACT;GAEA,OAAO;IACL,OAAO;IACP,UAAU;GACZ;EACF;EAMA,OAAO,KAAK,KAA6B;GACvC,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,SAAS,GAAG,OAAO,aAAa,GAAG,CAAC;GAE7C,IAAI,OAAO,GAAW,MAAc,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;GAE3D,IAAI,OAAO;GACX,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,IAAI,IAAI,KAAK,SAAS,GACpB,QAAQ,IAAI,KAAK,IAAI,KAAK,IAAI,EAAE;QAEhC,QAAQ,IAAI,KAAK,IAAI,KAAK,EAAE;GAGhC,OAAO,KAAK,IAAI,OAAO,CAAC;EAC1B;EAQA,OAAO,WAAW,KAAqB,SAAkB,OAAc;GACrE,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,SAAS,GAAG,OAAO,aAAa,IAAI,MAAM,GAAG,CAAC;GAEvD,IAAI,CAAC,QAAQ;IACX,OAAO,KAAK,MAAM;IAClB,KAAK,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;GACjC;GAGA,IAAI,QAAQ,GAAW,GAAW,MAAc;IAC9C,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;GACzE;GAGA,IAAI,KAAK,CAAC;GACV,IAAI,MAAM,KAAK,SAAS;GACxB,IAAI,MAAM,MAAM;GAChB,GAAG,OAAO,KAAK;GACf,GAAG,OAAO,KAAK;GAGf,IAAI,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,GAAG;IACnC,GAAG,MAAM,KAAK,KAAK;IACnB,GAAG,MAAM,KAAK,KAAK;GACrB,OAAO;IACL,GAAG,MAAM,KAAK,KAAK;IACnB,GAAG,MAAM,KAAK,KAAK;GACrB;GAGA,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK;IAC/C,IAAI,KAAK,KAAK;IAGd,IAAI,KAAK,GAAG,MAAM,GAAG,MAAM,IAAI,EAAE,KAAK,KAAK,GAAG,MAAM,IAAI,GAAG,MAAM,EAAE,GACjE;IAIF,OAAO,CAAC,KAAK,GAAG,MAAM,GAAG,MAAM,IAAI,EAAE,GACnC,OAAO;IAET,OAAO;IACP,GAAG,OAAO;IAGV,OAAO,CAAC,KAAK,GAAG,MAAM,IAAI,GAAG,MAAM,EAAE,GACnC,OAAO;IAET,OAAO;IACP,GAAG,OAAO;GACZ;GAEA,IAAI,OAAO,IAAI,MAAM;GACrB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KAAK,KAC7B,KAAK,KAAK,GAAG,MAAM,EAAE;GAGvB,OAAO;EACT;EAQA,OAAO,QAAQ,MAAkB,cAAsB,GAAY;GACjE,IAAI,OAAO,KAAK,YAAY,IAAI;GAChC,IAAI,IAAI,CAAC;GACT,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,IAAI,KAAK,aAAa,EAAE,KAAK,IAAI,MAAM,KAAK,cAAc,KAAK,EAAE,CAAC;GAEpE,OAAO;EACT;EAQA,OAAO,UAAU,MAAkB,IAAoB;GACrD,MAAM,QAAQ,KAAK,YAAY,IAAI;GACnC,MAAM,KAAK,GAAG;GACd,MAAM,KAAK,GAAG;GACd,IAAI,QAAQ,OAAO;GACnB,IAAI,QAAQ;GACZ,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,MAAM,KAAK,MAAM,EAAE,CAAC,KAAK;IACzB,MAAM,KAAK,MAAM,EAAE,CAAC,KAAK;IACzB,MAAM,IAAI,KAAK,KAAK,KAAK;IACzB,IAAI,IAAI,OAAO;KACb,QAAQ;KACR,QAAQ;IACV;GACF;GACA,OAAO;EACT;EAOA,OAAO,YAAY,MAAkB,UAAkB;GACrD,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,MAAM,SAAS,IAAI,MAAM,EAAE;GAC/B,IAAI,MAAM;GACV,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,MAAM,MAAM,SAAS,IAAI,MAAM,EAAE;IACjC,IAAI,MAAM,KAAK,MAAM;SAChB,IAAI,MAAM,KAAK,MAAM;GAC5B;GACA,OAAO,IAAI,GAAG,KAAK,GAAG;EACxB;EAMA,OAAe,eACb,OACA,OACA,IACA,IACQ;GACR,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;GAC5C,IAAI,OAAO;GACX,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,MAAM,IAAI,KAAK,MAAM,EAAE,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;IAC3C,IAAI,IAAI,MAAM,OAAO;SAChB,IAAI,IAAI,MAAM,OAAO;GAC5B;GACA,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;GAC5C,IAAI,OAAO;GACX,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,MAAM,IAAI,KAAK,MAAM,EAAE,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;IAC3C,IAAI,IAAI,MAAM,OAAO;SAChB,IAAI,IAAI,MAAM,OAAO;GAC5B;GACA,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO;EAC5C;EAQA,OAAiB,aACf,OACA,OACA,UACA;GACA,IAAI,KAAK,QAAQ,YAAY,OAAO,QAAQ;GAC5C,IAAI,KAAK,QAAQ,YAAY,OAAO,QAAQ;GAC5C,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG;EACpD;EAOA,OAAO,kBAAkB,MAAsB,IAAqB;GAClE,MAAM,QAAQ,KAAK,YAAY,IAAI;GACnC,MAAM,KAAK,GAAG;GACd,MAAM,KAAK,GAAG;GACd,IAAI,IAAI;GAER,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,MAAM,IAAI,MAAM;IAChB,MAAM,IAAI,MAAM,MAAM,MAAM,IAAI,IAAI,IAAI;IACxC,IACE,EAAE,KAAK,MAAM,EAAE,KAAK,MACpB,MAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,OAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAEvD,IAAI,CAAC;GAET;GACA,OAAO;EACT;EAQA,OAAO,mBACL,MACA,QACyB;GACzB,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,UAAU,KAAK,YAAY,MAAM;GAErC,MAAM,IAAI,QAAQ;GAClB,MAAM,IAAI,QAAQ,EAAE,CAAC;GAIrB,IAAI,MAAM;GACV,IAAI,MAAM;GACV,IAAI,MAAM;GACV,IAAI,MAAM;GACV,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,MAAM,IAAI,MAAM;IAChB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;IACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;IACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;IACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;GAC1B;GACA,IAAI,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK,IAAI,KACnE,OAAO;GAGT,IAAI,UAAU,OAAO;GACrB,IAAI,UAAwB;GAC5B,IAAI,QAAQ;GACZ,IAAI,QAAQ;GACZ,IAAI,QAAQ;GAEZ,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,MAAM,KAAK,MAAM;IACjB,MAAM,KAAK,MAAM,MAAM,MAAM,IAAI,IAAI,IAAI;IACzC,IAAI,KAAK,GAAG,KAAK,GAAG;IACpB,IAAI,KAAK,GAAG,KAAK,GAAG;IACpB,MAAM,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;IACxC,IAAI,SAAS,GAAG;IAChB,MAAM;IACN,MAAM;IAGN,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;IAC5C,IAAI,OAAO;IACX,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK;KAC5B,MAAM,IAAI,KAAK,MAAM,EAAE,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;KAC3C,IAAI,IAAI,MAAM,OAAO;UAChB,IAAI,IAAI,MAAM,OAAO;IAC5B;IACA,MAAM,OAAO,KAAK,EAAE,KAAK,KAAK,EAAE;IAChC,MAAM,OAAO,OAAO,OAAO,IAAI,OAAO,IAAI,OAAO,QAAQ,OAAO;IAEhE,IAAI,OAAO,GACT,OAAO;SACF,IAAI,KAAK,IAAI,IAAI,IAAI,SAAS;KAEnC,MAAM,OAAO,QAAQ,OAAO,OAAO,CAAC;KAKpC,IAHE,UAAU,YAAY,MAAM,KAAK,oBAAoB,MAAM,CAAC,CAAE,KAC9D,OAAO,gBAAgB,SAAS,IAAI,CAAC,CAAC,SAAS,GAEtC;MACT,UAAU;MACV,QAAQ;MACR,QAAQ;MACR,UAAU,KAAK,IAAI,IAAI;MACvB,QAAQ;KACV;IACF;GACF;GAEA,IAAI,CAAC,SAAS,OAAO;GAIrB,IAAI,KAAK;GACT,IAAI,KAAK;GACT,IAAI,KAAK;GACT,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,MAAM,KAAK,EAAE,KAAK,MAAM,EAAE,CAAC;IAC3B,MAAM,KAAK,EAAE,KAAK,MAAM,EAAE,CAAC;IAC3B,MAAM,IAAI,KAAK,KAAK,KAAK;IACzB,IAAI,IAAI,IAAI;KACV,KAAK;KACL,KAAK;KACL,KAAK;IACP;GACF;GACA,IAAI,KAAK,GAAG;IACV,MAAM,OAAO,KAAK,KAAK,EAAE;IACzB,MAAM;IACN,MAAM;IACN,IAAI,OAAO;IACX,IAAI,OAAO;IACX,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;KAChD,MAAM,IAAI,KAAK,MAAM,EAAE,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;KAC3C,IAAI,IAAI,MAAM,OAAO;KACrB,IAAI,IAAI,MAAM,OAAO;IACvB;IACA,MAAM,OAAO,KAAK,EAAE,KAAK,KAAK,EAAE;IAChC,IAAI,OAAO,IAAI,QAAQ,OAAO,IAAI,MAAM,OAAO;GACjD;GAGA,MAAM,WAAW,QAAQ,SAAS,KAAK;GACvC,IAAI,SAAS,EAAE,KAAK,SAAS,MAAM,SAAS,EAAE,KAAK,SAAS,MAAM,GAAG;IACnE,QAAQ,CAAC;IACT,QAAQ,CAAC;GACX;GAEA,OAAO;IACL;IACA,MAAM;IACN,QAAQ,IAAI,GAAG,OAAO,KAAK;IAC3B,MAAM;IACN,QAAQ;GACV;EACF;EAQA,OAAO,oBACL,OACA,OACyB;GAEzB,IAAI,SAAS,KAAK,YAAY,KAAK;GACnC,IAAI,SAAS,KAAK,YAAY,KAAK;GACnC,MAAM,OAAO,OAAO;GACpB,MAAM,OAAO,OAAO;GAIpB,IAAI,MAAM;GACV,IAAI,MAAM;GACV,IAAI,MAAM;GACV,IAAI,MAAM;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KAAK;IAC7B,MAAM,IAAI,OAAO;IACjB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;IACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;IACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;IACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;GAC1B;GACA,IAAI,MAAM;GACV,IAAI,MAAM;GACV,IAAI,MAAM;GACV,IAAI,MAAM;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KAAK;IAC7B,MAAM,IAAI,OAAO;IACjB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;IACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;IACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;IACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;GAC1B;GACA,IAAI,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK,OAAO;GAG7D,IAAI,UAAU,OAAO;GACrB,IAAI,WAAW;GACf,IAAI,QAAQ;GACZ,IAAI,QAAQ;GAEZ,KAAK,IAAI,IAAI,GAAG,OAAO,OAAO,MAAM,IAAI,MAAM,KAAK;IACjD,MAAM,MAAM,IAAI,OAAO,SAAS;IAChC,MAAM,KAAK,IAAI,OAAO,IAAI,IAAI;IAC9B,MAAM,KAAK,IAAI;IACf,MAAM,KAAK,IAAI,OAAO,IAAI,SAAS,IAAI,IAAI,KAAK;IAChD,IAAI,KAAK,GAAG,KAAK,GAAG;IACpB,IAAI,KAAK,GAAG,KAAK,GAAG;IACpB,MAAM,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;IACxC,IAAI,SAAS,GAAG;IAChB,MAAM;IACN,MAAM;IAEN,MAAM,OAAO,QAAQ,eAAe,QAAQ,QAAQ,IAAI,EAAE;IAC1D,IAAI,OAAO,GACT,OAAO;SACF,IAAI,KAAK,IAAI,IAAI,IAAI,SAAS;KACnC,UAAU,KAAK,IAAI,IAAI;KACvB,WAAW;KACX,QAAQ;KACR,QAAQ;IACV;GACF;GAEA,IAAI,WAAW,GAAG,OAAO;GAEzB,MAAM,QAAQ,WAAW,OAAO,IAAI;GACpC,MAAM,OACJ,UAAU,IACN,QAAQ,OAAO,QAAQ,QAAQ,IAC/B,QAAQ,OAAO,QAAQ,WAAW,IAAI;GAG5C,MAAM,KAAK,UAAU,IAAI,SAAS;GAClC,MAAM,KAAK,UAAU,IAAI,SAAS;GAElC,MAAM,KAAK,QAAQ,SAAS,EAAE;GAC9B,MAAM,KAAK,QAAQ,SAAS,EAAE;GAG9B,IAAI,SAAS,GAAG,KAAK,GAAG,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG;IACzD,QAAQ,CAAC;IACT,QAAQ,CAAC;GACX;GAGA,IAAI,WAAW,OAAO;GACtB,IAAI,SAAa;GACjB,KAAK,IAAI,IAAI,GAAG,MAAM,GAAG,QAAQ,IAAI,KAAK,KAAK;IAC7C,MAAM,IAAI,SAAS,GAAG,EAAE,CAAC,KAAK,GAAG,MAAM,SAAS,GAAG,EAAE,CAAC,KAAK,GAAG;IAC9D,IAAI,IAAI,UAAU;KAChB,WAAW;KACX,SAAS,GAAG;IACd;GACF;GAEA,OAAO;IACL;IACA,MAAM;IACN,QAAQ,IAAI,GAAG,OAAO,KAAK;IAC3B;IACA;GACF;EACF;EAOA,OAAO,mBAAmB,OAAmB,OAA0B;GACrE,IAAI,SAAS,KAAK,YAAY,KAAK;GACnC,IAAI,SAAS,KAAK,YAAY,KAAK;GAEnC,IAAI,KAAK,QAAQ,MAAM,MAAM;GAC7B,IAAI,IAAI,CAAC;GACT,KAAK,IAAI,IAAI,GAAG,MAAM,GAAG,QAAQ,IAAI,KAAK,KAAK;IAC7C,IAAI,MAAM,KAAK,mBAAmB,GAAG,IAAI,QAAQ,KAAK;IACtD,IAAI,KAAK,EAAE,KAAK,GAAG;GACrB;GACA,OAAO,KAAK,QAAQ,GAAG,IAAI;EAC7B;EAMA,OAAO,QAAQ,OAAsC;GACnD,IAAI,QAAQ,CAAC;GACb,KAAK,IAAI,KAAK,OACZ,MAAM,KAAK,KAAK,YAAY,CAAC,CAAC;GAGhC,IAAI,SAAS,KAAK,QAAQ,OAAO,KAAK;GACtC,MAAM,QAAQ,KAAK,YAAY,MAAM,CAAC;GACtC,OAAO;EACT;CACF;CAOA,IAAa,QAAb,MAAa,MAAM;EAKjB,OAAO,SAAS,OAAsB;GACpC,IAAI,KAAK,IAAI,MAAM;GACnB,KAAK,IAAI,IAAI,GAAG,KAAK,OAAO,KAAK;IAC/B,IAAI,IAAI,IAAI;IACZ,GAAG,KAAK,IAAI,GAAG,IAAI,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;GACxC;GACA,OAAO;EACT;EASA,OAAO,cACL,KACA,QAAgB,GAChB,YAAqB,OACd;GACP,IAAI,OAAO,KAAK,YAAY,GAAG;GAE/B,IAAI,QAAQ,KAAK,SAAS,GAAG,OAAO,IAAI,MAAM;GAC9C,IAAI,UAAU,MAAe,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;GAErE,IAAI,KAAK,KAAK;GACd,QAAQ,YAAY,QAAQ,QAAQ;GAGpC,OAAO,IAAI,MACT,IACA,KAAK,OAAO,OAAO,IACnB,KAAK,OAAO,OAAO,IACnB,KAAK,OAAO,OAAO,EACrB;EACF;EAOA,OAAe,SACb,OACA,MACc;GACd,MAAM,IAAI,IAAI,cAAc,QAAQ,KAAK,CAAC;GAC1C,KAAK,IAAI,IAAI,GAAG,KAAK,OAAO,KAC1B,KAAK,IAAI,OAAO,GAAG,IAAI,CAAC;GAE1B,OAAO;EACT;EAOA,OAAe,aACb,KACA,GACA,GACA,OACM;GACN,MAAM,KAAK,EAAE;GACb,MAAM,KAAK,EAAE;GACb,MAAM,KAAK,EAAE;GACb,MAAM,KAAK,EAAE;GACb,MAAM,OAAO,GAAG,SAAS;GACzB,KAAK,IAAI,IAAI,GAAG,KAAK,OAAO,KAAK;IAC/B,MAAM,IAAI,IAAI;IACd,MAAM,KAAK,EAAE;IACb,MAAM,KAAK,EAAE,IAAI;IACjB,MAAM,KAAK,EAAE,IAAI;IACjB,MAAM,KAAK,EAAE,IAAI;IACjB,MAAM,IAAI,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG;IACzD,MAAM,IAAI,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG;IACzD,IAAI,KACF,OACI,IAAI,GAAG,GAAG,GAAG,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,EAAE,IAC9D,IAAI,GAAG,GAAG,CAAC,CACjB;GACF;EACF;EAOA,OAAO,QAAQ,OAAkB,QAAoB;GACnD,IAAI,IAAI,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,EAAE,IAAI,OAAO,IAAI,CAAC;GACxD,IAAI,IAAI,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,EAAE,IAAI,OAAO,IAAI,CAAC;GACxD,IAAI,MAAM,EAAE,CAAC,SAAS,GAAG;IACvB,IAAI,IAAI,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,EAAE,IAAI,OAAO,IAAI,CAAC;IACxD,OAAO,IAAI,GAAG,GAAG,GAAG,CAAC;GACvB;GACA,OAAO,IAAI,GAAG,GAAG,CAAC;EACpB;EAOA,OAAe,QACb,OACA,IACA,IACA,IACA,IACI;GACJ,MAAM,KAAK,MAAM;GACjB,MAAM,KAAK,MAAM;GACjB,MAAM,KAAK,MAAM;GACjB,MAAM,KAAK,MAAM;GACjB,MAAM,IAAI,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG;GACzD,MAAM,IAAI,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG;GACzD,OAAO,GAAG,SAAS,IACf,IAAI,GAAG,GAAG,GAAG,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,EAAE,IAC9D,IAAI,GAAG,GAAG,CAAC;EACjB;EAQA,OAAO,WAAW,KAAqB,QAAgB,IAAW;GAChE,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,SAAS,GAAG,OAAO,IAAI,MAAM;GAEtC,IAAI,KAAK,IAAI,MAAM;GACnB,MAAM,IAAI,MAAM,SAAS,QAAQ,GAAG,KAAK,MAAM;IAC7C,MAAM,KAAK,IAAI;IACf,MAAM,KAAK,KAAK;IAChB,IAAI,KAAK,MAAO,KAAK,KAAK,KAAM;IAChC,IAAI,IAAI,KAAK,MAAM,KAAK,MAAM,KAAK;IACnC,IAAI,IAAI,KAAK,OAAO,KAAK,IAAI,KAAK,KAAM;IACxC,IAAI,IAAI,KAAK,KAAM,KAAK,KAAM;GAChC,CAAC;GAGD,MAAM,aAAa,IAAI,MAAM,cAAc,MAAM,GAAG,IAAI,GAAG,GAAG,KAAK;GAEnE,IAAI,IAAI;GACR,OAAO,IAAI,KAAK,SAAS,GAAG;IAC1B,IAAI,KAAK,MAAM,cAAc,MAAM,CAAC;IACpC,IAAI,GAAG,SAAS,GAAG;KACjB,MAAM,aAAa,IAAI,IAAI,GAAG,KAAK;KACnC;IACF;GACF;GAEA,OAAO;EACT;EAQA,OAAO,eAAe,MAAU,OAAsB;GAEpD,MAAM,KAAK,KAAK;GAChB,MAAM,KAAK,KAAK;GAChB,MAAM,IAAI,KAAK;GACf,OAAO,MAAM,QACX,OACA,MAAO,KAAK,KAAK,KAAM,GACvB,MAAM,KAAK,MAAM,KAAK,GACtB,OAAO,KAAK,IAAI,KAAK,KAAM,GAC3B,KAAM,KAAK,KAAM,EACnB;EACF;EASA,OAAO,SACL,KACA,QAAgB,IAChB,UAAU,IACH;GACP,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,SAAS,GAAG,OAAO,IAAI,MAAM;GAEtC,IAAI,KAAK,IAAI,MAAM;GACnB,MAAM,IAAI,MAAM,SAAS,QAAQ,GAAG,KAAK,MAAM;IAC7C,MAAM,KAAK,IAAI;IACf,MAAM,KAAK,KAAK;IAChB,IAAI,KAAK,WAAW,CAAC,KAAK,IAAI,KAAK;IACnC,IAAI,IAAI,KAAK,WAAW,CAAC,KAAK,OAAO,IAAI,KAAK,IAAI,KAAK;IACvD,IAAI,IAAI,KAAK,WAAW,KAAK,IAAI,KAAK,MAAM,KAAK,KAAK,IAAI;IAC1D,IAAI,IAAI,KAAK,WAAW,KAAK;GAC/B,CAAC;GAGD,MAAM,aAAa,IAAI,MAAM,cAAc,MAAM,GAAG,IAAI,GAAG,GAAG,KAAK;GAEnE,IAAI,IAAI;GACR,OAAO,IAAI,KAAK,SAAS,GAAG;IAC1B,IAAI,KAAK,MAAM,cAAc,MAAM,CAAC;IACpC,IAAI,GAAG,SAAS,GAAG;KACjB,MAAM,aAAa,IAAI,IAAI,GAAG,KAAK;KACnC;IACF;GACF;GAEA,OAAO;EACT;EASA,OAAO,aAAa,MAAU,OAAkB,UAAkB,IAAS;GAEzE,MAAM,KAAK,KAAK;GAChB,MAAM,KAAK,KAAK;GAChB,MAAM,IAAI,KAAK;GACf,OAAO,MAAM,QACX,OACA,WAAW,CAAC,KAAK,IAAI,KAAK,IAC1B,WAAW,CAAC,KAAK,OAAO,IAAI,KAAK,IAAI,KAAK,IAC1C,WAAW,KAAK,IAAI,KAAK,MAAM,KAAK,KAAK,IAAI,KAC7C,WAAW,KAAK,GAClB;EACF;EAQA,OAAO,OAAO,KAAgB,QAAgB,IAAI;GAChD,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,SAAS,GAAG,OAAO,IAAI,MAAM;GAEtC,IAAI,KAAK,IAAI,MAAM;GACnB,MAAM,IAAI,MAAM,SAAS,QAAQ,GAAG,KAAK,MAAM;IAC7C,MAAM,KAAK,IAAI;IACf,MAAM,KAAK,KAAK;IAChB,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,IAAI,IAAI;IAChC,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI;IACnC,IAAI,IAAI,KAAK,KAAK,KAAK,IAAI;IAC3B,IAAI,IAAI,KAAK;GACf,CAAC;GAED,IAAI,IAAI;GACR,OAAO,IAAI,KAAK,SAAS,GAAG;IAC1B,IAAI,IAAI,MAAM,cAAc,MAAM,CAAC;IACnC,IAAI,EAAE,SAAS,GAAG;KAChB,MAAM,aAAa,IAAI,GAAG,GAAG,KAAK;KAGlC,KAAK;IACP;GACF;GAEA,OAAO;EACT;EAQA,OAAO,WAAW,MAAU,OAAkB;GAE5C,MAAM,KAAK,KAAK;GAChB,MAAM,KAAK,KAAK;GAChB,MAAM,IAAI,KAAK;GACf,OAAO,MAAM,QACX,OACA,CAAC,KAAK,IAAI,KAAK,IAAI,IAAI,GACvB,IAAI,KAAK,IAAI,KAAK,IAAI,GACtB,KAAK,KAAK,IAAI,IACd,EACF;EACF;EASA,OAAO,QACL,KACA,QAAgB,IAChB,UAAkB,GACX;GACP,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAI,KAAK,SAAS,GAAG,OAAO,IAAI,MAAM;GAEtC,IAAI,KAAK,IAAI,MAAM;GACnB,MAAM,IACJ,YAAY,IACR,MAAM,SAAS,QAAQ,GAAG,KAAK,MAAM;IACnC,MAAM,KAAK,IAAI;IACf,MAAM,KAAK,KAAK;IAChB,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK;IAC7B,MAAM,KAAK,KAAK,KAAK,IAAI;IACzB,IAAI,KAAK,WAAW,CAAC,KAAK,IAAI,KAAM,KAAK,KAAM,IAAI,IAAI;IACvD,IAAI,IAAI,KAAK,WAAW,OAAO,KAAK,IAAI,KAAK,IAAI,KAAK;IACtD,IAAI,IAAI,KAAK,WAAW,MAAM,KAAK,MAAM,KAAK,KAAM,IAAI,IAAI,KAAK;IACjE,IAAI,IAAI,KAAK,WAAW,KAAK;GAC/B,CAAC,IACD,MAAM,SAAS,QAAQ,GAAG,KAAK,MAAM;IACnC,MAAM,KAAK,IAAI;IACf,MAAM,KAAK,KAAK;IAChB,IAAI,KAAK,CAAC,KAAK,IAAI,KAAM,KAAK,KAAM,IAAI,IAAI;IAC5C,IAAI,IAAI,KAAK,KAAM,KAAK,KAAK,IAAI;IACjC,IAAI,IAAI,KAAK,MAAO,KAAK,KAAM,KAAK,KAAM,IAAI,IAAI;IAClD,IAAI,IAAI,KAAK,KAAK;GACpB,CAAC;GAEP,IAAI,IAAI;GACR,OAAO,IAAI,KAAK,SAAS,GAAG;IAC1B,IAAI,IAAI,MAAM,cAAc,MAAM,CAAC;IACnC,IAAI,EAAE,SAAS,GAAG;KAChB,MAAM,aAAa,IAAI,GAAG,GAAG,KAAK;KAClC;IACF;GACF;GAEA,OAAO;EACT;EAQA,OAAO,YAAY,MAAU,OAAsB;GAEjD,MAAM,KAAK,KAAK;GAChB,MAAM,KAAK,KAAK;GAChB,MAAM,IAAI,KAAK;GACf,OAAO,MAAM,QACX,OACA,CAAC,KAAK,IAAI,KAAM,KAAK,KAAM,IAAI,IAAI,GACnC,KAAM,KAAK,KAAK,IAAI,GACpB,MAAO,KAAK,KAAM,KAAK,KAAM,IAAI,IAAI,GACrC,KAAK,CACP;EACF;EASA,OAAO,mBACL,MACA,OACA,UAAkB,GACd;GAEJ,MAAM,KAAK,KAAK;GAChB,MAAM,KAAK,KAAK;GAChB,MAAM,IAAI,KAAK;GACf,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK;GAC7B,MAAM,KAAK,KAAK,KAAK,IAAI;GACzB,OAAO,MAAM,QACX,OACA,WAAW,CAAC,KAAK,IAAI,KAAM,KAAK,KAAM,IAAI,IAAI,IAC9C,WAAW,OAAO,KAAK,IAAI,KAAK,IAAI,KAAK,IACzC,WAAW,MAAM,KAAK,MAAM,KAAK,KAAM,IAAI,IAAI,KAAK,IACpD,WAAW,KAAK,EAClB;EACF;CACF;;;;;;;;CCrkEA,IAAa,MAAb,MAAa,IAAI;EAKf,OAAO,IAAI,GAAW,GAA4B;GAChD,IAAI,OAAO,KAAK,UACd,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KAAK,EAAE,MAAM;QAEtD,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KAAK,EAAE,MAAM,EAAE,MAAM;GAEhE,OAAO;EACT;EAMA,OAAO,SAAS,GAAW,GAA4B;GACrD,IAAI,OAAO,KAAK,UACd,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KAAK,EAAE,MAAM;QAEtD,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KAAK,EAAE,MAAM,EAAE,MAAM;GAEhE,OAAO;EACT;EAMA,OAAO,SAAS,GAAW,GAA4B;GACrD,IAAI,OAAO,KAAK,UACd,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KAAK,EAAE,MAAM;QACjD;IACL,IAAI,EAAE,UAAU,EAAE,QAChB,MAAM,IAAI,MACR,wEAAwE,EAAE,SAAS,EAAE,iBAAiB,EAAE,SAAS,GACnH;IAEF,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KAAK,EAAE,MAAM,EAAE;GAC1D;GACA,OAAO;EACT;EAMA,OAAO,OAAO,GAAW,GAA4B;GACnD,IAAI,OAAO,KAAK,UAAU;IACxB,IAAI,MAAM,GAAG,MAAM,IAAI,MAAM,uBAAuB;IACpD,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KAAK,EAAE,MAAM;GACxD,OAAO;IACL,IAAI,EAAE,UAAU,EAAE,QAChB,MAAM,IAAI,MACR,sEAAsE,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,GAC7G;IAEF,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KAAK,EAAE,MAAM,EAAE;GAC1D;GACA,OAAO;EACT;EAKA,OAAO,IAAI,GAAW,GAAmB;GACvC,IAAI,EAAE,UAAU,EAAE,QAAQ,MAAM,IAAI,MAAM,2BAA2B;GACrE,IAAI,IAAI;GACR,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,KAAK,EAAE,KAAK,EAAE;GAEhB,OAAO;EACT;EAKA,OAAO,QAAQ,GAAW,GAAmB;GAC3C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;EAChC;EAKA,OAAO,MAAM,GAAW,GAAe;GACrC,OAAO,IAAI,GACT,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IACvB,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IACvB,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EACzB;EACF;EAKA,OAAO,UAAU,GAAmB;GAClC,OAAO,KAAK,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC;EAChC;EAKA,OAAO,KAAK,GAAW,YAAgC,QAAmB;GACxE,MAAM,IAAI,cAAc,SAAY,IAAI,UAAU,CAAC,IAAI;GACvD,IAAI,MAAM,GAAG,OAAO;GACpB,OAAO,IAAI,OAAO,GAAG,CAAC;EACxB;EAMA,OAAO,IAAI,GAAmB;GAC5B,OAAO,IAAI,IAAI,GAAG,KAAK,GAAG;EAC5B;EAMA,OAAO,MAAM,GAAmB;GAC9B,OAAO,IAAI,IAAI,GAAG,KAAK,KAAK;EAC9B;EAMA,OAAO,KAAK,GAAmB;GAC7B,OAAO,IAAI,IAAI,GAAG,KAAK,IAAI;EAC7B;EAMA,OAAO,MAAM,GAAmB;GAC9B,OAAO,IAAI,IAAI,GAAG,KAAK,KAAK;EAC9B;EAMA,OAAO,IAAI,GAA6C;GAGtD,IAAI,IAAI;GACR,IAAI,QAAQ;GACZ,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,IAAI,EAAE,MAAM,GAAG;IACb,IAAI,EAAE;IACN,QAAQ;GACV;GAEF,OAAO;IAAE,OAAO;IAAU;GAAM;EAClC;EAMA,OAAO,IAAI,GAA6C;GACtD,IAAI,IAAI;GACR,IAAI,QAAQ;GACZ,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,IAAI,EAAE,MAAM,GAAG;IACb,IAAI,EAAE;IACN,QAAQ;GACV;GAEF,OAAO;IAAE,OAAO;IAAU;GAAM;EAClC;EAKA,OAAO,IAAI,GAAmB;GAC5B,IAAI,IAAI;GACR,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KAAK,KAAK,EAAE;GACrD,OAAO;EACT;EAMA,OAAO,IACL,GACA,IACQ;GACR,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,EAAE,KAAK,GAAG,EAAE,IAAI,GAAG,CAAC;GAEtB,OAAO;EACT;CACF;CAKA,IAAa,MAAb,MAAa,IAAI;EAGf,cAAc;GACZ,KAAK,MAAM;EACb;EAKA,IAAI,QAAmB;GACrB,OAAO,KAAK;EACd;EAKA,IAAI,YAAuB;GACzB,OAAO,IAAI,UAAU,IAAI,YAAY,KAAK,GAAG,CAAC;EAChD;EAKA,QAAQ;GACN,KAAK,MAAM,IAAI,cAAc,GAAG,CAAC;EACnC;EAOA,QAAQ,KAAa,KAAa,CAAC,GAAG,CAAC,GAAS;;GAC9C,MAAM,IAAI,IAAI,yBAAgB,IAAI,2CAAM,aAAG,IAAI,6CAAM,GAAG,EAAE;GAC1D,KAAK,MAAM,IAAI,SAAS,KAAK,KAAK,CAAC;GACnC,OAAO;EACT;EAOA,SAAS,KAAa,KAAa,CAAC,GAAG,CAAC,GAAS;GAC/C,MAAM,IAAI,IAAI,iBAAiB,KAAK,IAAI,GAAG,GAAG,KAAK,IAAI,GAAG,GAAG,EAAE;GAC/D,KAAK,MAAM,IAAI,SAAS,KAAK,KAAK,CAAC;GACnC,OAAO;EACT;EAMA,YAAY,KAAmB;GAC7B,MAAM,IAAI,IAAI,kBAAkB,IAAI,MAAM,GAAG,IAAI,MAAM,CAAC;GACxD,KAAK,MAAM,IAAI,SAAS,KAAK,KAAK,CAAC;GACnC,OAAO;EACT;EAOA,QAAQ,KAAa,KAAa,CAAC,GAAG,CAAC,GAAS;;GAC9C,MAAM,IAAI,IAAI,gBACZ,KAAK,cAAI,IAAI,6CAAM,CAAC,GACpB,KAAK,cAAI,IAAI,6CAAM,CAAC,GACpB,EACF;GACA,KAAK,MAAM,IAAI,SAAS,KAAK,KAAK,CAAC;GACnC,OAAO;EACT;EAQA,OAAO,IAAI,GAAc,GAA2C;GAClE,IAAI,OAAO,KAAK,UAAU;IACxB,IAAI,EAAE,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,QACtB,MAAM,IAAI,MACR,2DACF;IACF,IAAI,EAAE,UAAU,EAAE,QAChB,MAAM,IAAI,MACR,2DACF;GACJ;GAEA,MAAM,IAAI,IAAI,MAAM;GACpB,MAAM,QAAQ,OAAO,KAAK;GAC1B,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,QAAQ,IAAI,EAAE,EAAE,CAAC;GAGpC,OAAO;EACT;EAUA,OAAO,SACL,GACA,GACA,aAAsB,OACtB,cAAuB,OAChB;GACP,MAAM,IAAI,IAAI,MAAM;GAEpB,IAAI,OAAO,KAAK,UAAU;IACxB,IAAI,aAAa;KACf,IAAI,EAAE,UAAU,EAAE,QAChB,MAAM,IAAI,MACR,8EACF;KACF,KAAK,IAAI,KAAK,GAAG,OAAO,EAAE,QAAQ,KAAK,MAAM,MAC3C,EAAE,KAAK,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC;IAEjC,OAAO;KACL,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC,UAAU,EAAE,QAClC,MAAM,IAAI,MACR,6EACF;KACF,IAAI,cAAc,EAAE,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,QACpC,MAAM,IAAI,MACR,oFACF;KAEF,IAAI,CAAC,YAAY,IAAI,IAAI,UAAU,CAAC;KAEpC,KAAK,IAAI,KAAK,GAAG,OAAO,EAAE,QAAQ,KAAK,MAAM,MAAM;MACjD,MAAM,IAAI,GAAG,KAAK,EAAE,QAAQ,CAAC;MAC7B,KAAK,IAAI,KAAK,GAAG,OAAO,EAAE,QAAQ,KAAK,MAAM,MAC3C,EAAE,MAAM,IAAI,IAAI,EAAE,KAAK,EAAE,GAAG;MAE9B,EAAE,KAAK,CAAC;KACV;IACF;GACF,OACE,KAAK,IAAI,KAAK,GAAG,OAAO,EAAE,QAAQ,KAAK,MAAM,MAC3C,EAAE,KAAK,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;GAI7B,OAAO;EACT;EAQA,OAAO,SACL,GACA,OACA,eAAiC,OAC7B;GACJ,MAAM,IAAc,CAAC;GACrB,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,IAAI,EAAE,EAAE,CAAC,SAAS,IAAI,OAAO;IAC3B,IAAI,iBAAiB,OACnB,MAAM,IAAI,MAAM,SAAS,MAAM,kBAAkB;IACnD,EAAE,KAAK,YAAsB;GAC/B,OACE,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM;GAGtB,OAAO,IAAI,GAAG,CAAC;EACjB;EAQA,OAAO,IACL,GACA,eAAiC,OACjC,aAAa,OACN;GACP,MAAM,KAAK,IAAI,MAAM;GACrB,MAAM,MAAc,aACf,EAA2B,QAAQ,GAAG,MAAM,KAAK,IAAI,GAAG,EAAE,MAAM,GAAG,CAAC,IACrE,EAAE,EAAE,CAAC;GACT,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KACvB,GAAG,KAAK,IAAI,SAAS,GAAG,GAAG,YAAY,CAAC;GAE1C,OAAO;EACT;EAKA,OAAO,UACL,GACA,eAAiC,OACjC,aAAa,OACN;GACP,OAAO,IAAI,IAAI,GAAG,cAAc,UAAU;EAC5C;EAEA,OAAO,YAAY,GAA2B;GAC5C,OAAO;IAAC,EAAE,EAAE,CAAC;IAAI,EAAE,EAAE,CAAC;IAAI,EAAE,EAAE,CAAC;IAAI,EAAE,EAAE,CAAC;IAAI,EAAE,EAAE,CAAC;IAAI,EAAE,EAAE,CAAC;GAAE;EAC9D;EAQA,OAAO,YAAY,IAAY,GAA+B;GAC5D,MAAM,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;GACnD,MAAM,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;GACnD,OAAO,IAAI,GAAG,GAAG,CAAC;EACpB;EAKA,OAAO,cAAc,GAAW,GAAsB;GACpD,OAAO,IAAI,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;EACpE;EAKA,OAAO,eAAe,MAAc,MAAyB;GAC3D,OAAO,IAAI,MACT,IAAI,GAAG,MAAM,MAAM,CAAC,GACpB,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,GACrB,IAAI,GAAG,GAAG,GAAG,CAAC,CAChB;EACF;EAKA,OAAO,cAAc,MAAc,MAAyB;GAC1D,OAAO,IAAI,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;EAC1E;EAKA,OAAO,kBAAkB,GAAW,GAAsB;GACxD,OAAO,IAAI,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;EACpE;EAKA,OAAO,gBAAgB,IAAY,IAAY,IAAuB;GACpE,MAAM,IAAI,IAAI,cAAc,IAAI,EAAE;GAClC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,GAAG;GAC3B,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,GAAG;GAC3B,OAAO;EACT;EAKA,OAAO,iBAAiB,MAAc,MAAc,IAAuB;GACzE,MAAM,IAAI,IAAI,eAAe,MAAM,IAAI;GACvC,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,IAAI,QAAQ,GAAG,KAAK;GACvC,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,IAAI,QAAQ,GAAG,KAAK;GACvC,OAAO;EACT;EAKA,OAAO,gBAAgB,MAAc,MAAc,IAAuB;GACxE,MAAM,IAAI,IAAI,cAAc,MAAM,IAAI;GACtC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK;GACnB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK;GACnB,OAAO;EACT;EAOA,OAAO,kBAAkB,IAAY,IAAY;GAC/C,MAAM,YAAY,KAAK,UAAU,IAAI,EAAE;GAEvC,IAAI,aAAa,QACf,OAAO;IACL,IAAI,GAAG;KAAC;KAAI;KAAG;IAAC,CAAC;IACjB,IAAI,GAAG;KAAC;KAAG;KAAG;IAAC,CAAC;IAChB,IAAI,GAAG;KAAC,GAAG,KAAK,GAAG;KAAI;KAAG;IAAC,CAAC;GAC9B;QACK;IACL,MAAM,KAAK,UAAU;IACrB,MAAM,OAAO,KAAK,KAAK,UAAU,KAAK,IAAI;IAC1C,MAAM,OAAO,KAAK,IAAI,IAAI;IAC1B,MAAM,OAAO,KAAK,IAAI,IAAI;IAE1B,OAAO;KACL,IAAI,GAAG;MAAC;MAAM;MAAM;KAAC,CAAC;KACtB,IAAI,GAAG;MAAC;MAAM,CAAC;MAAM;KAAC,CAAC;KACvB,IAAI,GAAG;MAAC,CAAC,KAAK;MAAM,KAAK,KAAK;MAAM;KAAC,CAAC;IACxC;GACF;EACF;CACF;;;;CC3cA,SAAS,OAAkC;EACzC,IAAI,IAAI;EACR,OAAO,SAAU,MAAuB;GACtC,IAAI,MAAM;IACR,OAAO,KAAK,SAAS;IACrB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;KACpC,KAAK,KAAK,WAAW,CAAC;KACtB,IAAI,IAAI,qBAAsB;KAC9B,IAAI,MAAM;KACV,KAAK;KACL,KAAK;KACL,IAAI,MAAM;KACV,KAAK;KACL,KAAK,IAAI;IACX;IACA,QAAQ,MAAM,KAAK;GACrB;GACA,IAAI;GACJ,OAAO;EACT;CACF;CAEA,SAAwB,QAAQ,MAAc;EAC5C,MAAM,IAAI;EACV,IAAI,IAAI;EACR,IAAI,IAAI;EACR,MAAM,IAAc,IAAI,MAAM,CAAC;EAE/B,MAAM,OAAO,KAAK;EAIlB,SAAS,YAAY;GACnB,KAAK;GACL,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE,KAAK,KAAK,GAAG;GAC3C,IAAI;GACJ,IAAI;EACN;EAOA,SAAS,YAAY,OAAuB;GAC1C,QAAQ,MAAM,QAAQ,mBAAmB,EAAE;GAC3C,QAAQ,MAAM,QAAQ,iBAAiB,EAAE;GACzC,OAAO;EACT;EAIA,SAAS,WAAW,OAAe;GACjC,QAAQ,YAAY,KAAK;GACzB,KAAK,KAAK;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;IAErC,MAAM,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC,SAAS;IACvC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;KAE1B,EAAE,MAAM,KAAK,CAAC;KACd,IAAI,EAAE,KAAK,GAAG,EAAE,MAAM;IACxB;GACF;EACF;EAEA,UAAU;EACV,WAAW,IAAI;EAEf,OAAO,EAOL,SAAiB;GACf,IAAI,EAAE,KAAK,GAAG,IAAI;GAClB,MAAM,IAAI,UAAU,EAAE,KAAK,IAAI;GAC/B,OAAQ,EAAE,KAAK,KAAK,IAAI,IAAI;EAC9B,EACF;CACF;;;;;;;;;;CCtIA,IAAa,MAAb,MAAa,IAAI;EASf,OAAO,OAAO,GAAW,GAAW,YAAY,MAAkB;GAChE,OAAO,KAAK,IAAI,IAAI,CAAC,IAAI;EAC3B;EAQA,OAAO,KAAK,GAAW,GAAW,GAAmB;GACnD,QAAQ,IAAI,KAAK,IAAI,IAAI;EAC3B;EAQA,OAAO,MAAM,KAAa,KAAa,KAAqB;GAC1D,OAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,GAAG,CAAC;EACzC;EASA,OAAO,WAAW,KAAa,KAAa,KAAqB;GAC/D,MAAM,MAAM,KAAK,IAAI,MAAM,GAAG;GAC9B,IAAI,KAAK,MAAM,OAAO;GACtB,IAAI,IAAI,GAAG,KAAK;GAChB,OAAO,IAAI;EACb;EAQA,OAAO,OAAO,GAAW,GAAW,GAAoB;GACtD,OAAO,KAAK,KAAK,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK,IAAI,GAAG,CAAC;EAClD;EAOA,OAAO,YAAY,GAAW,IAAY,GAAW;GACnD,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;GAC9B,OAAO,KAAK,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,IAAI;EACzC;EAOA,OAAO,SAAS,GAAW,GAAgB;GACzC,MAAM,IAAI,IAAI,GAAG,EAAE,MAAM;GACzB,MAAM,QAAQ,IAAI,IAAI,SAAS,EAAE,MAAM,GAAG,CAAC,IAAI;GAC/C,MAAM,QAAQ,IAAI,IAAI,IAAI,GAAG,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC;GAC7C,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,EAAE,KAAK,IAAI,OAAO,IAAI,MAAM,KAAK,MAAM;GAEzC,OAAO;EACT;EAQA,OAAO,eAAe,GAAW,GAAW,GAAmB;GAC7D,MAAM,MAAM,KAAK,IAAI,GAAG,CAAC;GACzB,MAAM,MAAM,KAAK,IAAI,GAAG,CAAC;GACzB,QAAQ,IAAI,QAAQ,MAAM;EAC5B;EAOA,OAAO,IAAI,KAAyB;GAClC,MAAM,OAAO,KAAK,YAAY,GAAG;GACjC,MAAM,IAAI,IAAI,GAAG,KAAK,EAAE;GACxB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,IAAI,IAAI,GAAG,KAAK,EAAE;GAEpB,OAAO;EACT;EAOA,OAAO,QAAQ,KAAyB;GACtC,MAAM,OAAO,KAAK,YAAY,GAAG;GACjC,OAAO,IAAI,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,MAAM;EACzC;EAQA,OAAO,MACL,GACA,SAAgC,QAAQ,WAChC;GACR,OAAO,OAAO,IAAI,KAAM,IAAI,IAAI,IAAI,IAAI,CAAC;EAC3C;EAWA,OAAO,WACL,GACA,OACA,OACA,SACA,SACA;GACA,IAAI,SAAS,OACX,MAAM,IAAI,MACR,yDACF;GAIF,OAAO,WADI,IAAI,UAAU,QAAQ,UACX,UAAU;EAClC;EAUA,OAAO,KAAK,MAAoB;GAC9B,KAAK,YAAYA,QAAU,IAAI;EACjC;EAQA,OAAO,SAAiB;GACtB,OAAO,KAAK,YAAY,KAAK,UAAU,OAAO,IAAI,KAAK,OAAO;EAChE;CACF;CAKA,IAAa,OAAb,MAAa,KAAK;EAKhB,OAAO,WAAW,OAAuB;GACvC,OAAO,IAAI,WAAW,OAAO,GAAG,GAAG;EACrC;EAMA,OAAO,YAAY,QAAwB;GACzC,OAAO,IAAI,WAAW,QAAQ,GAAG,MAAM,MAAM;EAC/C;EAMA,OAAO,SAAS,OAAuB;GACrC,OAAO,QAAQ,MAAM;EACvB;EAMA,OAAO,SAAS,QAAwB;GACtC,OAAO,SAAS,MAAM;EACxB;EAOA,OAAO,YAAY,KAAwB;GACzC,IAAI,OAAuB;GAC3B,KAAK,MAAM,KAAK,KACd,IAAI,SAAS,QAAW;IACtB,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,MAAM;GAClB,OAEE,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,IAAI,MAAM,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,KAAK;IACpE,MAAM,KAAK,KAAK,IAAI,MAAM,IAAI,EAAE,EAAE;IAClC,MAAO,KAAK,KAAK,IAAI,MAAO,IAAI,EAAE,EAAE;GACtC;GAGJ,OAAO,IAAI,MAAM,OAAQ,KAAM;EACjC;EAOA,OAAO,SAAS,KAAyB;GACvC,OAAO,IAAI,QAAQ,GAAG;EACxB;EAQA,OAAO,OACL,KACA,YAA6B,GAC7B,YAA2B,MAC3B;GACA,MAAM,SAAS,aAAa,OAAO,aAAa;GAChD,IAAI,IAAI;GACR,KAAK,MAAM,KAAK,KAAK;IACnB,IAAI,OAAO,aAAa,UACtB;SAAI,cAAc,GAAG,AAAC,EAAU,OAAO,CAAE,IAAY,UAAU;IAAC,OAEhE,AAAC,EAAU,OAAO,CAAC,SAAS;IAE9B;GACF;EACF;EASA,OAAO,YAAY,GAAW,GAAW,IAAY,IAAS;GAC5D,MAAM,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;GACvC,MAAM,IAAI,GAAG,KAAK,GAAG;GACrB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KACvB,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,EAAE,KAAK;GAEjC,OAAO;EACT;EAOA,OAAO,cAAc,IAAY,OAAwB,MAAM,IAAW;GACxE,MAAM,IAAI,KAAK;GACf,MAAM,IAAI,KAAK;GAEf,MAAM,IAAI,IAAI,GAAG,EAAE;GACnB,MAAM,KAAK,IAAI,GAAG,CAAC;GACnB,AAAC,GAAW,KAAK,CAAE,EAAU;GAC7B,AAAC,GAAW,KAAM,EAAU;GAC5B,MAAM,KAAK,IAAI,GAAG,CAAC;GACnB,AAAC,GAAW,KAAM,EAAU;GAC5B,AAAC,GAAW,KAAK,CAAE,EAAU;GAE7B,OAAO,IAAI,MAAM,IAAI,EAAE;EACzB;EAKA,OAAO,gBAAgB,IAAY,IAAqB;GAEtD,IAAI,MAAM;GACV,IAAI,KAAK;GACT,IAAI,KAAK;GACT,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,KAAK,KAAK;IAClE,OAAO,GAAG,KAAK,GAAG;IAClB,MAAM,GAAG,KAAK,GAAG;IACjB,MAAM,GAAG,KAAK,GAAG;GACnB;GACA,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,KAAK,KAAK,KAAK,EAAE;EAC3D;EAQA,OAAO,YAAY,IAAY,UAAkB,UAA2B;GAC1E,KACE,IAAI,IAAI,GAAG,MAAM,KAAK,IAAI,GAAG,QAAQ,SAAS,QAAQ,SAAS,MAAM,GACrE,IAAI,KACJ,KAEA,IAAI,CAAC,IAAI,OAAO,GAAG,IAAI,SAAS,IAAI,SAAS,EAAE,GAAG,OAAO;GAE3D,OAAO;EACT;EAMA,OAAO,UAAU,KAA4B;GAC3C,MAAM,OAAO,KAAK,YAAY,GAAG;GACjC,MAAM,SAAS,KAAK,YAAY,IAAI;GACpC,MAAM,SAAS,OAAO,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC;GAChD,MAAM,KAAK,OAAO;GAClB,MAAM,KAAK,OAAO;GAIlB,MAAM,MAAM,GAAO,MAAkB;IACnC,IAAI,EAAE,SAAS,KAAK,EAAE,SAAS,GAC7B,MAAM,IAAI,MAAM,oCAAoC;IAEtD,MAAM,MAAM,EAAE,KAAK;IACnB,MAAM,MAAM,EAAE,KAAK;IACnB,MAAM,MAAM,EAAE,KAAK;IACnB,MAAM,MAAM,EAAE,KAAK;IAEnB,IAAI,OAAO,KAAK,MAAM,GAAG,OAAO;IAChC,IAAI,MAAM,KAAK,OAAO,GAAG,OAAO;IAChC,IAAI,OAAO,KAAK,OAAO,GAAG;KACxB,IAAI,OAAO,KAAK,OAAO,GAAG,OAAO,MAAM,MAAM,IAAI;KACjD,OAAO,MAAM,MAAM,IAAI;IACzB;IAGA,MAAM,MAAM,MAAM,MAAM,MAAM;IAC9B,IAAI,MAAM,GAAG,OAAO;IACpB,IAAI,MAAM,GAAG,OAAO;IAIpB,OAAO,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI;GAC7D;GAEA,OAAO,KAAK,KAAK,EAAE;EACrB;EAQA,OAAO,MACL,IACA,OACA,QACM;GACN,MAAM,MAAM,KAAK,YACd,GAAW,OAAO,UAAa,OAAQ,GAAW,MAAM,WACrD,CAAC,EAAE,IACH,EACN;GACA,MAAM,MACJ,OAAO,SAAS,WAAW,GAAG,KAAK,IAAI,EAAE,CAAC,QAAQ,KAAK,IAAI;GAC7D,IAAI,CAAC,QAAQ,SAAS,GAAG,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC;GAE9C,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KAAK;IAC9C,MAAM,IAAI,IAAI;IACd,KAAK,IAAI,IAAI,GAAG,OAAO,EAAE,QAAQ,IAAI,MAAM,KACzC,EAAE,KACA,UAAU,OAAO,KACb,OAAO,MAAM,EAAE,KAAK,OAAO,MAAM,IAAI,KACrC,EAAE,KAAK,IAAI;GAErB;GAEA,OAAO;EACT;EASA,OAAO,SACL,IACA,OACA,QACA,MACM;GACN,MAAM,MAAM,KAAK,YACd,GAAW,OAAO,UAAa,OAAQ,GAAW,MAAM,WACrD,CAAC,EAAE,IACH,EACN;GACA,MAAM,KAAK,SAAS,IAAI,mBAAmB,IAAI;GAC/C,IAAI,CAAC,QAAQ,SAAS,GAAG,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC;GAK9C,MAAM,MAAM,GAJA,KAAK,IAAI,KAIJ,GAHL,KAAK,IAAI,KAGC,GAAG,MAAM;GAE/B,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KAAK;IAC9C,MAAM,IAAI,OAAO,IAAI,EAAE,CAAC,MAAM,IAAI,IAAI,IAAI;IAC1C,EAAE,GAAG,IAAI,YAAY,GAAG,GAAG,CAAC;IAC5B,IAAI,MACF,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAC/B,IAAI,EAAE,CAAC,KAAK,MAAM,EAAE;GAG1B;GAEA,OAAO;EACT;EASA,OAAO,QACL,IACA,OACA,QACA,MACM;GACN,MAAM,MAAM,KAAK,YACd,GAAW,OAAO,UAAa,OAAQ,GAAW,MAAM,WACrD,CAAC,EAAE,IACH,EACN;GACA,MAAM,IAAI,OAAO,SAAS,WAAW,CAAC,OAAO,KAAK,IAAI;GACtD,IAAI,CAAC,QAAQ,SAAS,GAAG,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC;GAK9C,MAAM,OAJK,SAAS,IAAI,kBAAkB,IAAI,cAIhC,CAHD,KAAK,IAAI,EAAE,EAGN,GAFL,KAAK,IAAI,EAAE,EAEA,GAAG,MAAM;GAEjC,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KAAK;IAC9C,MAAM,IAAI,OAAO,IAAI,EAAE,CAAC,MAAM,IAAI,IAAI,IAAI;IAC1C,EAAE,GAAG,IAAI,YAAY,GAAG,GAAG,CAAC;IAC5B,IAAI,MACF,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAC/B,IAAI,EAAE,CAAC,KAAK,MAAM,EAAE;GAG1B;GAEA,OAAO;EACT;EAQA,OAAO,UACL,IACA,MACA,MACM;GACN,MAAM,MAAM,KAAK,YACd,GAAW,OAAO,UAAa,OAAQ,GAAW,MAAM,WACrD,CAAC,EAAE,IACH,EACN;GACA,MAAM,QAAQ,KAAK,YAAY,IAAI;GACnC,MAAM,MAAM,IAAI,kBAAkB,MAAM,IAAI,MAAM,EAAE;GAEpD,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KAAK;IAC9C,MAAM,IAAI,OAAO,IAAI,EAAE,CAAC,MAAM,IAAI,IAAI,IAAI;IAC1C,EAAE,GAAG,IAAI,YAAY,GAAG,GAAG,CAAC;IAC5B,IAAI,MACF,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAC/B,IAAI,EAAE,CAAC,KAAK,MAAM,EAAE;GAG1B;GAEA,OAAO;EACT;EAMA,OAAO,WAAW;GAChB,MAAM,sBAAM,IAAI,aAAa,GAAG;GAEhC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,IAAK,IAAI,KAAK,KAAM,GAAG;GACnE,MAAM,QAAQ,QACZ,IAAI,KAAK,MAAM,KAAK,WAAW,KAAK,SAAS,GAAG,CAAC,CAAC;GAEpD,OAAO;IAAE,OAAO;IAAK,KAAK;GAAK;EACjC;EAMA,OAAO,WAAW;GAChB,MAAM,sBAAM,IAAI,aAAa,GAAG;GAEhC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,IAAK,IAAI,KAAK,KAAM,GAAG;GACnE,MAAM,QAAQ,QACZ,IAAI,KAAK,MAAM,KAAK,WAAW,KAAK,SAAS,GAAG,CAAC,CAAC;GAEpD,OAAO;IAAE,OAAO;IAAK,KAAK;GAAK;EACjC;CACF;CAKA,IAAa,UAAb,MAAa,QAAQ;EAMnB,OAAO,OAAO,GAAW,IAAY,GAAW;GAC9C,OAAO,IAAI;EACb;EAOA,OAAO,YAAY,GAAW,IAAY,GAAW;GACnD,OAAO,IAAI,IAAI;EACjB;EAOA,OAAO,aAAa,GAAW,IAAY,GAAW;GACpD,OAAO,CAAC,IAAI,KAAK,IAAI;EACvB;EAOA,OAAO,eAAe,GAAW,IAAY,GAAW;GACtD,MAAM,KAAK,IAAI;GACf,OAAO,IAAI,KAAO,IAAI,IAAK,IAAI,IAAI,IAAK,CAAC,IAAI,MAAO,KAAK,MAAM,KAAK,KAAK;EAC3E;EAOA,OAAO,QAAQ,GAAW,IAAY,GAAW;GAC/C,OAAO,IAAI,IAAI,IAAI;EACrB;EAOA,OAAO,SAAS,GAAW,IAAY,GAAW;GAChD,MAAM,KAAK,IAAI;GACf,OAAO,KAAK,KAAK,KAAK,KAAK;EAC7B;EAOA,OAAO,WAAW,GAAW,IAAY,GAAW;GAClD,MAAM,KAAK,IAAI;GACf,OAAO,IAAI,KACN,IAAI,IAAK,KAAK,KAAK,KACnB,IAAI,MAAO,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK;EAClD;EAQA,OAAO,cAAc,GAAW,IAAY,GAAG,IAAY,KAAc;GACvE,OAAO,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;EAC9B;EAQA,OAAO,eAAe,GAAW,IAAY,GAAG,IAAY,KAAc;GACxE,OAAO,IAAI,KAAK,IAAI,GAAG,CAAC;EAC1B;EAOA,OAAO,OAAO,GAAW,IAAY,GAAW;GAC9C,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,MAAM,OAAO,IAAI;EAC5C;EAOA,OAAO,QAAQ,GAAW,IAAY,GAAW;GAC/C,OAAO,IAAI,KAAK,IAAI,IAAI,MAAM,OAAO;EACvC;EAOA,OAAO,UAAU,GAAW,IAAY,GAAW;GACjD,OAAQ,CAAC,IAAI,KAAM,KAAK,IAAI,KAAK,KAAK,CAAC,IAAI;EAC7C;EAOA,OAAO,aAAa,GAAW,IAAY,GAAG;GAC5C,MAAM,KAAK,IAAI;GACf,MAAM,KAAK,KAAK;GAEhB,OAAO,KAAM,KADF,KAAK,MACO,IAAK,KAAK,KAAM,IAAK,KAAK,KAAM;EACzD;EAOA,OAAO,WAAW,GAAW,IAAY,GAAW;GAClD,OAAO,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI;EACtC;EAOA,OAAO,YAAY,GAAW,IAAY,GAAW;GACnD,MAAM,KAAK,IAAI;GACf,OAAO,IAAI,KAAK,KAAK,IAAI,KAAK,EAAE;EAClC;EAOA,OAAO,cAAc,GAAW,IAAY,GAAW;GACrD,MAAM,KAAK,IAAI;GACf,OAAO,IAAI,KACN,CAAC,IAAI,KAAM,KAAK,KAAK,IAAI,KAAK,EAAE,IAAI,KACpC,IAAI,KAAM,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK,EAAE,IAAI;EACtD;EAQA,OAAO,UAAU,GAAW,IAAY,GAAG,IAAY,IAAa;GAClE,MAAM,KAAK,IAAI;GACf,MAAM,IAAK,IAAI,MAAM,SAAU;GAC/B,OACE,KAAK,CAAC,KAAK,IAAI,GAAG,KAAK,EAAE,IAAI,KAAK,KAAM,KAAK,KAAK,MAAM,SAAU,CAAC;EAEvE;EAQA,OAAO,WAAW,GAAW,IAAY,GAAG,IAAY,IAAa;GACnE,MAAM,IAAK,IAAI,MAAM,SAAU;GAC/B,OACE,KAAK,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,KAAM,IAAI,KAAK,MAAM,SAAU,CAAC,KAAK;EAE1E;EAQA,OAAO,aAAa,GAAW,IAAY,GAAG,IAAY,IAAa;GACrE,IAAI,KAAK,IAAI;GACb,MAAM,IAAK,IAAI,MAAM,SAAU;GAC/B,IAAI,IAAI,IAAK;IACX,MAAM;IACN,OACE,KACC,OACE,KAAK,IAAI,GAAG,KAAK,EAAE,IAAI,KAAK,KAAM,KAAK,KAAK,MAAM,SAAU,CAAC;GAEpE,OAAO;IACL,MAAM;IACN,OACE,KACG,MACE,KAAK,IAAI,GAAG,MAAM,EAAE,IAAI,KAAK,KAAM,KAAK,KAAK,MAAM,SAAU,CAAC,MACnE;GAEJ;EACF;EAOA,OAAO,SAAS,GAAW,IAAY,GAAW;GAChD,OAAO,IAAI,QAAQ,UAAU,IAAI,GAAG,CAAC;EACvC;EAOA,OAAO,UAAU,GAAW,IAAY,GAAG;GACzC,IAAI,IAAI,IAAI,MACV,OAAO,KAAK,SAAS,IAAI;QACpB,IAAI,IAAI,IAAI,MAAM;IACvB,KAAK,MAAM;IACX,OAAO,KAAK,SAAS,IAAI,IAAI;GAC/B,OAAO,IAAI,IAAI,MAAM,MAAM;IACzB,KAAK,OAAO;IACZ,OAAO,KAAK,SAAS,IAAI,IAAI;GAC/B,OAAO;IACL,KAAK,QAAQ;IACb,OAAO,KAAK,SAAS,IAAI,IAAI;GAC/B;EACF;EAOA,OAAO,YAAY,GAAW,IAAY,GAAW;GACnD,OAAO,IAAI,KACP,QAAQ,SAAS,IAAI,GAAG,CAAC,IAAI,IAC7B,QAAQ,UAAU,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI;EAChD;EAQA,OAAO,QAAQ,GAAW,IAAY,GAAG,IAAY,IAAY;GAC/D,MAAM,IAAI,KAAK,IAAI;GACnB,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;EAC7B;EAQA,OAAO,WAAW,GAAW,IAAY,GAAG,IAAY,IAAa;GACnE,IAAI,KAAK,IAAI,MAAM,SAAS,KAAK,IAAI,IAAI,MAAM,SAAS,CAAC,CAAC;GAC1D,IAAI,KAAK,IAAI;GAEb,MAAM,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,MAAO,IAAI,EAAE;GAC9C,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC;GAC7B,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;GAC9B,OAAQ,KAAK,IAAI,MAAO,IAAI;EAC9B;EAQA,OAAO,KAAK,GAAW,IAAY,GAAG,IAAY,IAAa;GAC7D,IAAI,IAAI,IACN,OAAQ,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,IAAK;QAEtC,OAAO,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI;EAEnD;EAQA,OAAO,gBACL,GACA,IAAY,GACZ,IAAqB,CAAC,KAAM,GAAI,GACxB;GACR,MAAM,IAAY,OAAO,KAAK,WAAW,EAAE,KAAK;GAChD,MAAM,IAAY,OAAO,KAAK,WAAW,EAAE,KAAK;GAChD,IAAI,OAAO,IAAI,IAAI;GACnB,IAAI,SAAS,GACX,OAAO,MAAM;GAEf,MAAM,KAAK,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK;GAC9C,OAAO,MAAM,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,IAAI;EAC9C;EASA,OAAO,YACL,GACA,IAAY,GACZ,KAAa,CAAC,IAAK,EAAG,GACtB,KAAa,CAAC,IAAK,EAAG,GACd;GACR,MAAM,QAAQ,IAAI,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;GAC1E,OACE,IACA,MAAM,WACJ,IAAI,GAAG,IAAI,IAAI,GAAG,IAAI,GAAG,GAAG,CAAC,GAC7B,MAAM,cAAc,KAAK,CAC3B,CAAC,CAAC;EAEN;EAQA,OAAO,gBACL,GACA,IAAY,GACZ,KAAa,CAAC,IAAK,GAAI,GACf;GACR,MAAM,IAAI,KAAK,IAAI,IAAI,MAAM,SAAS,KAAK,IAAI,MAAM,SAAS,GAAG,EAAE,CAAC;GACpE,MAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,GAAG,EAAE,CAAC;GACxC,MAAM,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI;GAClC,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK;GAC9B,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI;GAC5B,OAAO,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;EACvC;EAQA,OAAO,MAAM,GAAW,IAAY,GAAG,IAAY,IAAa;GAC9D,OAAO,IAAI,IAAI,IAAI;EACrB;EAUA,OAAO,KACL,IACA,OACA,GACA,GACA,GAAG,MACH;GACA,MAAM,IAAI,IAAI;GAEd,OAAO,GADI,KAAK,MAAM,IAAI,CAAC,IAAI,GACjB,GAAG,GAAG,IAAI;EAC1B;CACF;CAMA,IAAa,QAAb,MAAmB;EAWjB,YAAY,GAAe;GAN3B,KAAU,QAAgB;GAOxB,KAAK,UAAU,MAAM,YAAY,CAAC;GAClC,KAAK,KAAK;EACZ;EAKA,IAAI,MAAU;GACZ,OAAO,KAAK,KAAK,MAAM;EACzB;EAKA,IAAI,MAAU;GACZ,OAAO,KAAK,KAAK,MAAM;EACzB;EAKA,IAAI,YAAgB;GAClB,OAAO,KAAK,KAAK,MAAM;EACzB;EAKA,OAAyB;GACvB,IAAI,CAAC,KAAK,SAAS;GACnB,MAAM,OAAO,KAAK,QAAQ,EAAE,CAAC;GAC7B,KAAK,QAAQ;GACb,MAAM,MAAM,IAAI,GAAG,IAAI;GACvB,MAAM,MAAM,IAAI,GAAG,IAAI;GACvB,MAAM,MAAM,IAAI,GAAG,IAAI;GAEvB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KAAK;IAI7B,IAAI,KAAK;IACT,IAAI,KAAK;IACT,IAAI,KAAK;IAET,MAAM,IAAI,KAAK,QAAQ,SAAS,CAAC;IACjC,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KAAK;KAC5C,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,EAAE,EAAE;KAC9B,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,EAAE,EAAE;KAC9B,IAAI,KAAK,IAAI,KAAK,IAAI;IACxB;GACF;GAEA,KAAK,OAAO;GACZ,KAAK,OAAO;GACZ,KAAK,OAAO;GACZ,OAAO;EACT;EAQA,MAAM,KAAa,KAAa,SAA4B;GAC1D,MAAM,SAAS,IAAI,MAAM;GACzB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,QAAQ,IAAI,KAAK,KAAK;IACvD,MAAM,IAAI,KAAK,QAAQ;IACvB,MAAM,IAAI,IAAI,GAAG,KAAK,KAAK;IAC3B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,OAAO,KAC9B,EAAE,KACA,WAAW,QAAQ,KACf,EAAE,KACF,IAAI,WAAW,EAAE,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,GAAG;IAEjE,OAAO,KAAK,CAAC;GACf;GACA,OAAO;EACT;EAOA,OAAO,KAAqB,SAAkB,MAAY;GACxD,MAAM,OAAO,KAAK,YAAY,GAAG;GACjC,IAAI,KAAK,EAAE,CAAC,WAAW,KAAK,OAC1B,MAAM,IAAI,MACR,2BAA2B,KAAK,MAAM,2BAA2B,KAAK,EAAE,CAAC,OAAO,yBAClF;GACF,KAAK,UAAU,KAAK,QAAQ,OAAO,IAAI;GACvC,IAAI,QAAQ,KAAK,KAAK;GACtB,OAAO;EACT;EAMA,MAAM,OAAsB;GAC1B,MAAM,IAAI,IAAI,MAAM;GACpB,KAAK,IAAI,IAAI,GAAG,KAAK,OAAO,KAAK;IAC/B,MAAM,IAAI,IAAI,GAAG,KAAK,KAAK;IAC3B,MAAM,IAAI,QAAQ,IAAI,IAAI,QAAQ;IAClC,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,KAAK,QAAQ,IAAI,KAAK,KAC/C,EAAE,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI,CAAC;IAE/C,EAAE,KAAK,CAAC;GACV;GACA,OAAO;EACT;CACF;;;;;;;;CCxjCA,MAAa,QAAQ;EAEnB,IAAI;EAGJ,IAAI;EAGJ,IAAI;EAGJ,KAAK;EAGL,YAAY;EAGZ,UAAU;EAGV,WAAW;EAGX,OAAO;EAGP,cAAc;EAGd,QAAQ;EAGR,aAAa;EAGb,MAAM;EAGN,UAAU;EAGV,KAAK;EAGL,WAAW;EAGX,SAAS;EAGT,KAAK,OAAO;EAGZ,KAAK,OAAO;EAGZ,IAAI,KAAK;EAGT,QAAQ;EAGR,SAAS;EAGT,YAAY;EAGZ,YAAY;EAGZ,YAAY;EAGZ,YAAY;EAGZ,SAAS;EAGT,QAAQ;EAGR,UAAU;CACZ;CAKA,IAAa,OAAb,MAAa,KAAK;EAOhB,OAAO,UAAU,IAA+B;GAC9C,IAAI,IACF,KAAK,aAAa;GAEpB,OAAO,KAAK;EACd;EAMA,OAAO,QAAQ,MAA4B;GACzC,IAAI,KAAK,SAAS,GAAG,OAAO,CAAC;GAE7B,IAAI,MAAM,CAAC;GAEX,IAAI,UAAU,MAAM,QAAQ,KAAK,EAAE,KAAK,YAAY,OAAO,KAAK,EAAE;GAGlE,IAAI,OAAO,KAAK,OAAO,UACrB,MAAM,MAAM,UAAU,MAAM,KAAK,IAAI;QAGhC,IAAI,OAAO,KAAK,OAAO,YAAY,CAAC,SAAS;IAClD,IAAI,IAAI;KAAC;KAAK;KAAK;KAAK;IAAG;IAC3B,IAAI,IAAI,KAAK;IACb,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;KACjC,IAAK,EAAE,UAAU,KAAK,EAAE,UAAW,EAAE,EAAE,MAAM,IAAI;KACjD,IAAI,KAAK,EAAE,EAAE,GAAG;IAClB;GAGF,OAAO,IAAI,SACT,MAAM,KAAK,eAAe,KAAK,EAAE;GAGnC,OAAO;EACT;EAMA,OAAO,eAAe,GAAgC;GAGpD,IAAI,MAAM,QAAQ,CAAC,GAAG,OAAO,EAAE,MAAM;GACrC,MAAM,MAAM,CAAC;GACb,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,IAAI,KAAK,EAAE,EAAE;GAEf,OAAO;EACT;EAQA,OAAO,UAAU,MAAqB;GACpC,MAAM,KAAK,KAAK;GAChB,IAAI,OAAO,OAAO,UAAU,OAAO;GACnC,IAAI,KAAK,WAAW,MAAM,MAAM,QAAQ,EAAE,KAAK,YAAY,OAAO,EAAE,IAClE,OAAO;GAET,OAAO,KAAK,QAAQ,IAAI;EAC1B;EAOA,OAAO,KAAK,UAAkB,SAAS,gBAAqB,QAAgB;GAC1E,IAAI,KAAK,UAAU,KAAK,SACtB,MAAM,IAAI,MAAM,OAAO;QAClB,IAAI,KAAK,UAAU,KAAK,QAC7B,QAAQ,KAAK,OAAO;GAEtB,OAAO;EACT;EAQA,OAAO,UAAU,OAAe,QAAgB,GAAG;GACjD,KAAK,KAAK,4DAA4D;GACtE,OAAO,KAAK,MAAM,IAAI,OAAO,IAAI,KAAK,IAAI;EAC5C;EAUA,OAAO,MACL,KACA,MACA,QACA,WAAoB,OACpB,YAAY,MACH;GACT,IAAI,SAAgB,CAAC;GACrB,IAAI,OAAc,CAAC;GACnB,IAAI,KAAa,UAAU;GAC3B,IAAI,QAAgB;GACpB,IAAI,IAAI,UAAU,KAAK,MAAM,GAAG,OAAO,CAAC;GAExC,OAAO,QAAQ,IAAI,QAAQ;IACzB,OAAO,CAAC;IACR,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KACxB,IAAI,UACF,KAAK,KAAK,KAAK,QAAQ,KAAK,IAAI,OAAO;SAClC;KACL,IAAI,QAAQ,KAAK,IAAI,QAAQ;KAC7B,KAAK,KAAK,IAAI,QAAQ,EAAE;IAC1B;IAEF,SAAS;IACT,IAAI,CAAC,aAAc,aAAa,KAAK,WAAW,MAAO,OAAO,KAAK,IAAI;GACzE;GAEA,OAAO;EACT;EAOA,OAAO,QAAQ,KAAY,iBAA0B,MAAW;GAG9D,MAAM,MAAiB,iBAAiB,IAAI,MAAM,IAAI,CAAC;GACvD,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KAAK;IAC9C,MAAM,IAAI,IAAI;IACd,IAAI,MAAM,QAAQ,CAAC,GACjB,KAAK,IAAI,IAAI,GAAG,OAAO,EAAE,QAAQ,IAAI,MAAM,KAAK,IAAI,KAAK,EAAE,EAAE;SAE7D,IAAI,KAAK,CAAC;GAEd;GACA,OAAO;EACT;EAQA,OAAO,QAAW,GAAQ,GAAQ,IAA4B;GAC5D,IAAI,SAAS,CAAC;GACd,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,KAAK,IAAI,IAAI,GAAG,OAAO,EAAE,QAAQ,IAAI,MAAM,KACzC,OAAO,KAAK,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;GAG9B,OAAO;EACT;EAMA,OAAO,IAAI,QAAsB;GAC/B,IAAI,IAAI,CAAC;GACT,KAAK,IAAI,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC,QAAQ,IAAI,KAAK,KAAK;IACpD,IAAI,IAAI,CAAC;IACT,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KACjC,EAAE,KAAK,OAAO,EAAE,CAAC,EAAE;IAErB,EAAE,KAAK,CAAC;GACV;GACA,OAAO;EACT;EAWA,OAAO,QACL,KACA,MAAc,GACd,SAAiB,GACjB,UACc;GACd,IAAI,IAAI;GACR,OAAO,WAAY;IACjB,KAAK;IACL,IAAI,KAAK,KAEP,IAAI,OAAQ,IAAI,QAAQ,MAAM;IAEhC,IAAI,UAAU,SAAS,CAAC;IACxB,OAAO;GACT;EACF;EAQA,OAAO,SACL,IACA,OACA,QAAgB,GAChB,OAAe,GACR;GACP,IAAI,OAAO,CAAC;GACZ,KAAK,IAAI,IAAI,OAAO,MAAM,OAAO,IAAI,KAAK,KAAK,MAC7C,KAAK,KAAK,GAAG,CAAC;GAEhB,OAAO;EACT;EAOA,OAAO,KACL,KACA,UACA;GACA,IAAI,UAAU,IAAI,eAAe;GACjC,QAAQ,KAAK,OAAO,KAAK,IAAI;GAE7B,QAAQ,SAAS,WAAY;IAC3B,IAAI,QAAQ,UAAU,OAAO,QAAQ,SAAS,KAC5C,SAAS,QAAQ,cAAc,IAAI;SAEnC,SACE,iBAAiB,QAAQ,OAAO,kBAAkB,IAAI,IACtD,KACF;GAEJ;GAEA,QAAQ,UAAU,WAAY;IAC5B,SAAS,yBAAyB,KAAK;GACzC;GAEA,QAAQ,KAAK;EACf;EASA,OAAO,SACL,OACA,WAAmB,oBACnB,WAA4C,OAC5C,UAAkB,GAClB;GACA,MAAM,QAAQ,aAAa,QAAQ,SAAS;GAC5C,MAAM,QAAQ,OACZ,SAAU,MAAM;IACd,MAAM,OAAO,SAAS,cAAc,GAAG;IAGvC,MAAM,MAAM,IAAI,gBAAgB,IAAK;IACrC,KAAK,OAAO;IACZ,KAAK,WAAW,GAAG,SAAS,GAAG;IAC/B,SAAS,KAAK,YAAY,IAAI;IAC9B,KAAK,MAAM;IACX,SAAS,KAAK,YAAY,IAAI;IAC9B,IAAI,gBAAgB,GAAG;GACzB,GACA,SAAS,SACT,OACF;EACF;EAQA,OAAO,YAAY,YAAoB,IAAkB;GACvD,IAAI,OAAO,KAAK,IAAI;GACpB,IAAI,MAAM,CAAC;GACX,OAAO,WAAY;IACjB,MAAM,MAAM,KAAK,IAAI;IACrB,IAAI,KAAK,MAAM,IAAI;IACnB,IAAI,IAAI,SAAS,WAAW,IAAI,MAAM;IACtC,OAAO;IACP,OAAO,KAAK,MAAM,IAAI,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,MAAM;GAC/D;EACF;EAOA,OAAO,WAAW,KAAqB,cAAsB,GAAY;GACvE,IAAI,MAAM,QAAQ,GAAG,KAAK,IAAI,SAAS,aAAa;IAClD,KAAK,KAAK,YAAY,YAAY,4BAA4B;IAC9D,OAAO;GACT;GACA,OAAO;EACT;EAMA,OAAO,YAAY,IAA0B;GAC3C,OAAO,CAAC,MAAM,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI;EACxC;EAKA,OAAO,WAAW;GAChB,OAAO,uBAAuB,KAAK,UAAU,SAAS;EACxD;EAMA,OAAO,SAAS,YAAY,OAAO;;GACjC,OAAO,aAAa,OAAO,WAAW,2BAAe,0DAAQ,cACzD,OAAO,WAAW,IAClB,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC;EACtE;CACF;CAjWE,KAAO,aAA0B;;;;;;;;;CCnFnC,IAAa,KAAb,MAAa,WAAW,aAA8C;EASpE,YAAY,GAAG,MAAqD;GAElE,IAAI;GACJ,MAAM,KAAK,KAAK;GAChB,IAAI,KAAK,WAAW,KAAK,OAAO,MAAM,UACpC,SAAS;QACJ,IAAI,KAAK,WAAW,GACzB,SAAS;QACJ,IACL,KAAK,WAAW,MACf,MAAM,QAAQ,EAAE,KAAK,YAAY,OAAO,EAAE,IAE3C,SAAS;QACJ,IAAI,OAAO,OAAO,UACvB,SAAS;QAET,SAAS,KAAK,QAAQ,IAAI;GAE5B,MAAM,MAAM;EACd;EAQA,OAAO,KACL,YACA,eAAuB,GACvB,YAAqB,OACjB;GACJ,MAAM,IAAI,IAAI,GAAG,UAAU;GAC3B,IAAI,cAAc,EAAE,KAAK,YAAY;GACrC,IAAI,WACF,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,EAAE,KAAK,EAAE,KAAK,IAAI,OAAO;GAG7B,OAAO;EACT;EAKA,IAAI,KAAa;GACf,OAAO,KAAK;EACd;EACA,IAAI,GAAG,GAAW;GAChB,KAAK,MAAM;EACb;EAKA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAKA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAKA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAKA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAKA,QAAY;GACV,OAAO,IAAI,GAAG,IAAI;EACpB;EAOA,OAAO,GAAW,YAAY,MAAmB;GAC/C,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAE1C,IAAI,EAAE,KAAK,IAAI,KAAK,KAAK,EAAE,EAAE,KAAK,YAAY,OAAO;GAEvD,OAAO;EACT;EAMA,GAAG,GAAG,MAAmB;GACvB,MAAM,IAAI,KAAK,UAAU,IAAI;GAC7B,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,IAAI,KAAK,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,KAC9D,KAAK,KAAK,EAAE;GAEd,OAAO;EACT;EAMA,IAAI,GAAG,MAAiB;GACtB,OAAO,KAAK,MAAM,CAAC,CAAC,GAAG,GAAG,IAAI;EAChC;EAQA,QACE,QACA,WACA,eAAwB,OAClB;GACN,MAAM,IAAI,aAAa,SAAY,YAAY,KAAK,UAAU;GAC9D,MAAM,SAAS,CAAC,KAAK,IAAI,MAAM,IAAI,GAAG,KAAK,IAAI,MAAM,IAAI,CAAC;GAC1D,OAAO,eAAe,KAAK,IAAI,MAAM,IAAI,KAAK,GAAG,MAAM;EACzD;EAQA,GAAG,IAAkE;GACnE,MAAM,OAAO;GACb,QAAQ,GAAG,WAAkB;IAC3B,OAAO,GAAG,MAAM,GAAG,MAAM;GAC3B;EACF;EAQA,IACE,KAC6B;GAC7B,MAAM,OAAO,CAAC;GACd,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KACzC,KAAK,KAAK,KAAK,GAAG,IAAI,EAAE,CAAC;GAE3B,OAAO;EACT;EAMA,MAAM,MAA6B;GACjC,MAAM,IAAI,CAAC;GACX,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,EAAE,KAAM,KAAa,KAAK,OAAO,CAAC;GAEpC,OAAO,IAAI,GAAG,CAAC;EACjB;EAMA,QAAQ,GAAG,MAAiB;GAC1B,OAAO,IAAI,GAAG,KAAK,QAAQ,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC;EACzD;EAMA,IAAI,GAAG,MAAmB;GACxB,KAAK,WAAW,KAAK,OAAO,KAAK,MAAM,WACnC,IAAI,IAAI,MAAM,KAAK,EAAE,IACrB,IAAI,IAAI,MAAM,KAAK,UAAU,IAAI,CAAC;GACtC,OAAO;EACT;EAMA,KAAK,GAAG,MAAiB;GACvB,OAAO,KAAK,MAAM,CAAC,CAAC,IAAI,GAAG,IAAI;EACjC;EAMA,SAAS,GAAG,MAAmB;GAC7B,KAAK,WAAW,KAAK,OAAO,KAAK,MAAM,WACnC,IAAI,SAAS,MAAM,KAAK,EAAE,IAC1B,IAAI,SAAS,MAAM,KAAK,UAAU,IAAI,CAAC;GAC3C,OAAO;EACT;EAMA,UAAU,GAAG,MAAiB;GAC5B,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,GAAG,IAAI;EACtC;EAMA,SAAS,GAAG,MAAmB;GAC7B,KAAK,WAAW,KAAK,OAAO,KAAK,MAAM,WACnC,IAAI,SAAS,MAAM,KAAK,EAAE,IAC1B,IAAI,SAAS,MAAM,KAAK,UAAU,IAAI,CAAC;GAC3C,OAAO;EACT;EAMA,UAAU,GAAG,MAAiB;GAC5B,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,GAAG,IAAI;EACtC;EAMA,OAAO,GAAG,MAAmB;GAC3B,KAAK,WAAW,KAAK,OAAO,KAAK,MAAM,WACnC,IAAI,OAAO,MAAM,KAAK,EAAE,IACxB,IAAI,OAAO,MAAM,KAAK,UAAU,IAAI,CAAC;GACzC,OAAO;EACT;EAMA,QAAQ,GAAG,MAAiB;GAC1B,OAAO,KAAK,MAAM,CAAC,CAAC,OAAO,GAAG,IAAI;EACpC;EAKA,cAAsB;GACpB,OAAO,IAAI,IAAI,MAAM,IAAI;EAC3B;EAKA,YAAoB;GAClB,OAAO,IAAI,UAAU,IAAI;EAC3B;EAMA,KAAK,YAAgC,QAAe;GAClD,IAAI,KAAK,MAAM,SAAS;GACxB,OAAO;EACT;EAKA,MAAM,YAAgC,QAAe;GACnD,OAAO,KAAK,MAAM,CAAC,CAAC,KAAK,SAAS;EACpC;EAMA,IAAI,GAAG,MAAqB;GAC1B,OAAO,IAAI,IAAI,MAAM,KAAK,UAAU,IAAI,CAAC;EAC3C;EAMA,SAAS,GAAG,MAAqB;GAC/B,OAAO,IAAI,QAAQ,MAAM,KAAK,UAAU,IAAI,CAAC;EAC/C;EAMA,OAAO,GAAG,MAAiB;GACzB,OAAO,IAAI,MAAM,MAAM,KAAK,UAAU,IAAI,CAAC;EAC7C;EAOA,SAAS,GAAG,MAAiB;GAC3B,OAAO,KAAK,UAAU,KAAK,IAAI,GAAG,IAAI,IAAI,KAAK,YAAY,CAAC;EAC9D;EAMA,cAAc,GAAG,MAAqB;GACpC,OAAO,KAAK,IAAI,GAAG,IAAI,IAAI,KAAK,UAAU;EAC5C;EAKA,MAAU;GACR,IAAI,IAAI,IAAI;GACZ,OAAO;EACT;EAKA,OAAW;GACT,OAAO,KAAK,MAAM,CAAC,CAAC,IAAI;EAC1B;EAKA,QAAY;GACV,IAAI,MAAM,IAAI;GACd,OAAO;EACT;EAKA,SAAa;GACX,OAAO,KAAK,MAAM,CAAC,CAAC,MAAM;EAC5B;EAKA,OAAW;GACT,IAAI,KAAK,IAAI;GACb,OAAO;EACT;EAKA,QAAY;GACV,OAAO,KAAK,MAAM,CAAC,CAAC,KAAK;EAC3B;EAKA,QAAY;GACV,IAAI,MAAM,IAAI;GACd,OAAO;EACT;EAKA,SAAa;GACX,OAAO,KAAK,MAAM,CAAC,CAAC,MAAM;EAC5B;EAMA,WAA6C;GAC3C,OAAO,IAAI,IAAI,IAAI;EACrB;EAMA,WAA6C;GAC3C,OAAO,IAAI,IAAI,IAAI;EACrB;EAMA,KAAK,GAAG,MAAiB;GACvB,MAAM,IAAI,KAAK,UAAU,IAAI;GAC7B,MAAM,IAAI,KAAK,MAAM;GACrB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,IAAI,KAAK,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,KAC9D,EAAE,KAAK,KAAK,IAAI,KAAK,IAAI,EAAE,EAAE;GAE/B,OAAO;EACT;EAMA,KAAK,GAAG,MAAiB;GACvB,MAAM,IAAI,KAAK,UAAU,IAAI;GAC7B,MAAM,IAAI,KAAK,MAAM;GACrB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,IAAI,KAAK,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,KAC9D,EAAE,KAAK,KAAK,IAAI,KAAK,IAAI,EAAE,EAAE;GAE/B,OAAO;EACT;EAMA,MAAM,OAA0B,MAAM,IAAY;GAChD,OAAO,KAAK,MAAO,KAAa,KAAK,KAAM,KAAa,KAAK,GAAG;EAClE;EAOA,aAAa,GAAO,OAA0B,MAAM,IAAY;GAE9D,OACE,KAAK,YAAY,KAAK,MAAM,IAAI,IAAI,EAAE,MAAM,IAAI,IAAI,KAAK,EAAE,IAAI,KAAK;EAExE;EAOA,MAAM,OAAmC,QAAiB;GACxD,KAAK,MAAM,MAAM,OAAO,UAAU,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC;GACzD,OAAO;EACT;EAQA,SAAS,OAAe,QAAiB,MAAe;GACtD,KAAK,SAAS,MAAM,OAAO,UAAU,GAAG,KAAK,KAAK,QAAQ,CAAC,GAAG,IAAI;GAClE,OAAO;EACT;EAQA,QAAQ,OAAmC,QAAiB,MAAe;GACzE,KAAK,QAAQ,MAAM,OAAO,UAAU,GAAG,KAAK,KAAK,QAAQ,CAAC,GAAG,IAAI;GACjE,OAAO;EACT;EAOA,UAAU,MAAiB,MAAqB;GAC9C,KAAK,UAAU,MAAM,MAAM,IAAI;GAC/B,OAAO;EACT;EAKA,WAAmB;GACjB,OAAO,MAAM,KAAK,KAAK,IAAI,EAAE;EAC/B;EAKA,UAAoB;GAClB,MAAM,IAAI,CAAC;GACX,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,KAAK,KAAK,EAAE;GAC/D,OAAO;EACT;EAKA,UAAiB;GACf,OAAO,IAAI,MAAM,GAAG,KAAK,KAAK,MAAM,GAAG,KAAK,MAAM,CAAC;EACrD;EAKA,UAAiB;GACf,OAAO,IAAI,MAAM,GAAG,KAAK,KAAK,MAAM,GAAG,KAAK,MAAM,CAAC;EACrD;CACF;CAMA,IAAa,QAAb,MAAa,cAAc,MAAU;EAOnC,YAAY,GAAG,MAAY;GACzB,MAAM,GAAG,IAAI;EACf;EAKA,IAAI,KAAa;GACf,OAAO,KAAK;EACd;EACA,IAAI,GAAG,GAAW;GAChB,KAAK,MAAM;EACb;EAKA,IAAI,KAAS;GACX,OAAO,KAAK;EACd;EAKA,IAAI,KAAS;GACX,OAAO,KAAK;EACd;EAKA,IAAI,KAAS;GACX,OAAO,KAAK;EACd;EAKA,IAAI,KAAS;GACX,OAAO,KAAK;EACd;EAKA,IAAI,KAAS;GACX,OAAO,KAAK,KAAK,SAAS;EAC5B;EAKA,IAAI,KAAS;GACX,OAAO,KAAK,KAAK,SAAS;EAC5B;EAKA,IAAI,KAAS;GACX,OAAO,KAAK,KAAK,SAAS;EAC5B;EAKA,IAAI,KAAS;GACX,OAAO,KAAK,KAAK,SAAS;EAC5B;EAKA,QAAe;GACb,MAAM,QAAQ,IAAI,MAAM;GACxB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,MAAM,KAAK,KAAK,EAAE,CAAC,MAAM,CAAC;GAE5B,OAAO;EACT;EAOA,OAAO,UAAU,MAA6B;GAC5C,MAAM,IAAI,IAAI,MAAM;GACpB,KAAK,MAAM,MAAM,MAAM;IACrB,MAAM,IAAI,cAAc,KAAM,KAAY,IAAI,GAAG,EAAE;IACnD,EAAE,KAAK,CAAC;GACV;GACA,OAAO;EACT;EAMA,OAAO,YAAY,MAAyB;GAC1C,OAAO,MAAM,KAAK,IAAI;EACxB;EAQA,MACE,WACA,QACA,WAAoB,OACX;GAGT,MAAM,KAAK,UAAU;GACrB,MAAM,SAAkB,CAAC;GACzB,IAAI,KAAK,UAAU,KAAK,MAAM,GAAG,OAAO;GAExC,IAAI,QAAQ;GACZ,OAAO,QAAQ,KAAK,QAAQ;IAC1B,MAAM,IAAI,IAAI,MAAM;IACpB,IAAI,OAAO;IACX,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAC7B,IAAI,UACF,EAAE,UAAU,MAAM,QAAQ,KAAK,KAAK;SAC/B;KACL,IAAI,QAAQ,KAAK,KAAK,QAAQ;KAC9B,EAAE,UAAU,KAAK,QAAQ;IAC3B;IAEF,SAAS;IACT,IAAI,SAAS,WAAW,OAAO,KAAK,CAAC;GACvC;GACA,OAAO;EACT;EAOA,OAAO,KAAiB,QAAQ,GAAS;GAGvC,IAAI,OAAO,KAAK,YAAY,GAAG;GAC/B,IAAK,SAAqB,MAAM,OAAO,KAAK,MAAM;GAClD,MAAM,MAAM,KAAK;GACjB,MAAM,IAAI,KAAK;GACf,IAAI,MAAM,GAAG,OAAO;GAEpB,IAAI,QAAQ,KAAK,MAAM,KAAK,KAAK;GACjC,QAAQ,QAAQ,IAAI,KAAK,IAAI,MAAM,OAAO,CAAC,IAAI,KAAK,IAAI,OAAO,GAAG;GAGlE,KAAK,SAAS,MAAM;GACpB,KAAK,IAAI,IAAI,MAAM,GAAG,KAAK,OAAO,KAAK,KAAK,IAAI,KAAK,KAAK;GAC1D,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAK,QAAQ,KAAK,KAAK;GACnD,OAAO;EACT;EAQA,OAAO,QAAQ,GAAG,QAAgB,GAAU;GAC1C,MAAM,QACJ,QAAQ,IAAI,CAAC,QAAQ,KAAK,GAAG,KAAK,IAAI,CAAC,OAAO,KAAK;GACrD,OAAO,MAAM,UAAU,OAAO,MAAM,MAAM,KAAK;EACjD;EAQA,SACE,kBAA0B,GAC1B,SAAiB,GACjB,WAAoB,OACX;GACT,OAAO,KAAK,MAAM,iBAAiB,QAAQ,QAAQ;EACrD;EAKA,QAAiB;GACf,OAAO,KAAK,SAAS,GAAG,CAAC;EAC3B;EAKA,WAAe;GACb,OAAO,KAAK,SAAS,IAAI;EAC3B;EAMA,cAAqB;GACnB,OAAO,KAAK,YAAY,IAAI;EAC9B;EAMA,SAAS,YAA6B,GAAG;GACvC,KAAK,OAAO,MAAM,WAAW,IAAI;EACnC;EAMA,WAAW,YAA6B,GAAG;GACzC,KAAK,OAAO,MAAM,WAAW,MAAM;EACrC;EAQA,GAAG,IAAsE;GACvE,MAAM,OAAO;GACb,QAAQ,GAAG,WAAkB;IAC3B,OAAO,GAAG,MAAM,GAAG,MAAM;GAC3B;EACF;EAQA,IACE,KAC6B;GAC7B,MAAM,OAAO,CAAC;GACd,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KACzC,KAAK,KAAK,KAAK,GAAG,IAAI,EAAE,CAAC;GAE3B,OAAO;EACT;EAMA,YAAY,GAAe;GACzB,IAAI,IAAI,MAAM,GAAG,GAAG,CAAC;GACrB,MAAM,QAAQ,KAAK,SAAS;GAC5B,MAAM,KAAK,KAAK,KAAK,SAAS;GAC9B,MAAM,MAAM,KAAK,MAAM,IAAI,EAAE;GAC7B,OAAO,KAAK,YACV,KAAK,MACL,KAAK,KAAK,IAAI,KAAK,SAAS,GAAG,MAAM,CAAC,KACrC,IAAI,MAAM,MAAM,KACnB;EACF;EAMA,OAAO,GAAG,MAAmB;GAC3B,OAAO,KAAK,IAAI,GAAG,IAAI;EACzB;EAMA,OAAO,GAAG,MAAmB;GAC3B,MAAM,IAAI,IAAI,GAAG,GAAG,IAAI,CAAC,CAAC,SAAS,KAAK,EAAE;GAC1C,KAAK,OAAO,CAAC;GACb,OAAO;EACT;EAOA,MAAM,OAAmC,QAAuB;GAC9D,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,KAAK,MAAM,KAAK,IAAI,OAAO,UAAU,KAAK,EAAE;GAE9C,OAAO;EACT;EAQA,SAAS,OAAe,QAAiB,MAAqB;GAC5D,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,KAAK,SAAS,KAAK,IAAI,OAAO,UAAU,KAAK,IAAI,IAAI;GAEvD,OAAO;EACT;EAQA,QACE,OACA,QACA,MACM;GACN,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,KAAK,QAAQ,KAAK,IAAI,OAAO,UAAU,KAAK,IAAI,IAAI;GAEtD,OAAO;EACT;EAOA,UAAU,MAAsB,MAAqB;GACnD,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,KAAK,UAAU,KAAK,IAAI,MAAM,IAAI;GAEpC,OAAO;EACT;EAOA,gBAAgB,KAAa,OAAgB,OAAa;GACxD,OAAO,KAAK,MAAM,GAAG,MAAO,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAK;EACvE;EAOA,UAAU,MAAc,GAAG,MAAmB;GAC5C,IAAI,KAAK,WAAW,GAAG,OAAO;GAC9B,IAAI,CAAE,KAAK,EAAE,CAAS,OAAO;IAC3B,KAAK,KAAK,GAAG,KAAK,yBAAyB;IAC3C,OAAO;GACT;GACA,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,KAAK,KAAM,KAAK,EAAE,CAAS,KAAK,CAAC,GAAG,IAAI;GAE1C,OAAO;EACT;EAMA,AAAU,OACR,IACA,MACM;GACN,MAAM,IACJ,KAAK,WAAW,KAAK,OAAO,KAAK,MAAM,WACnC,KAAK,KACL,KAAK,UAAU,IAAI;GACzB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,GAAG,KAAK,IAAI,CAAC;GAEf,OAAO;EACT;EAMA,IAAI,GAAG,MAAmB;GACxB,OAAO,KAAK,OAAO,IAAI,KAAK,IAAI;EAClC;EAMA,SAAS,GAAG,MAAmB;GAC7B,OAAO,KAAK,OAAO,IAAI,UAAU,IAAI;EACvC;EAMA,SAAS,GAAG,MAAmB;GAC7B,OAAO,KAAK,OAAO,IAAI,UAAU,IAAI;EACvC;EAMA,OAAO,GAAG,MAAmB;GAC3B,OAAO,KAAK,OAAO,IAAI,QAAQ,IAAI;EACrC;EAOA,WAAW,GAA2C;GACpD,OAAO,IAAI,IAAI,MAAM,CAAC;EACxB;EASA,gBACE,GACA,aAAsB,OACtB,cAAuB,OAChB;GACP,OAAO,IAAI,SAAS,MAAM,GAAG,YAAY,WAAW;EACtD;EAOA,SAAS,OAAe,eAAiC,OAAW;GAClE,OAAO,IAAI,SAAS,MAAM,OAAO,YAAY;EAC/C;EAOA,KACE,eAA6C,QAC7C,aAAa,OACN;GACP,OAAO,IAAI,IAAI,MAAM,cAAc,UAAU;EAC/C;EAKA,UAAiB;GACf,OAAO,MAAM,UAAU,IAAI;EAC7B;EAKA,WAAmB;GACjB,OAAO,YAAY,KAAK,QAAQ,GAAG,MAAM,IAAI,EAAE,SAAS,IAAI,KAAK,EAAE,IAAI;EACzE;CACF;CAMA,IAAa,QAAb,MAAa,cAAc,MAAqB;EAU9C,YAAY,GAAG,MAAY;GACzB,MAAM,GAAG,IAAI;GAVf,KAAU,UAAc,IAAI,GAAG;GAC/B,KAAU,QAAY,IAAI,GAAG;GAC7B,KAAU,UAAU;GASlB,KAAK,KAAK;EACZ;EAOA,OAAO,iBAAiB,MAAyB;GAC/C,MAAM,IAAI,IAAI,MACZ,IAAI,GAAG,KAAK,QAAQ,GAAG,KAAK,OAAO,CAAC,GACpC,IAAI,GAAG,KAAK,SAAS,GAAG,KAAK,UAAU,CAAC,CAC1C;GACA,IAAI,KAAK,SAAS,KAAK,QAAQ,EAAE,OAAO,IAAI,GAAG,KAAK,OAAO,KAAK,MAAM;GACtE,OAAO;EACT;EAMA,OAAO,UAAU,GAA0B;GACzC,MAAM,KAAK,KAAK,YAAY,CAAC;GAC7B,IAAI,GAAG,SAAS,GACd,MAAM,IAAI,MACR,4DACF;GACF,MAAM,QAAQ,GAAG;GACjB,MAAM,OAAO,GAAG,GAAG,SAAS;GAC5B,OAAO,IAAI,MACT,iBAAiB,KAAK,QAAQ,IAAI,GAAG,KAAK,GAC1C,gBAAgB,KAAK,OAAO,IAAI,GAAG,IAAI,CACzC;EACF;EAKA,AAAU,OAAO;GACf,IAAI,KAAK,IAAI;IACX,KAAK,QAAQ,KAAK,GAAG,MAAM;IAC3B,KAAK,UAAU;GACjB;GACA,IAAI,KAAK,MAAM,KAAK,IAAI;IACtB,KAAK,YAAY;IACjB,KAAK,UAAU;GACjB;EACF;EAKA,QAAe;GAEb,OAAO,IAAI,MAAM,KAAK,SAAS,KAAK,WAAW;EACjD;EAKA,AAAU,cAAc;GAGtB,MAAM,IAAI,KAAK;GACf,MAAM,IAAI,KAAK;GACf,MAAM,IAAI,IAAI,EAAE,SAAS;GACzB,IAAI,KAAK,MAAM,WAAW,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC;GAClD,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,KAAK,MAAM,KAAK,KAAK,IAAI,EAAE,MAAM,IAAI,EAAE,MAAM,IAAI,EAAE;GAErD,KAAK,cAAc;EACrB;EAKA,AAAU,gBAAgB;GAExB,MAAM,IAAI,KAAK;GACf,MAAM,IAAI,KAAK,MAAM;GACrB,IAAI,KAAK,QAAQ,WAAW,GAAG,KAAK,UAAU,IAAI,GAAG,CAAC;GACtD,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,KAAK,QAAQ,KAAK,KAAK,MAAM,KAAK,MAAO,IAAI,EAAE,MAAM,IAAI;EAE7D;EAKA,AAAU,oBAAoB;GAC5B,KAAK,cAAc,KAAK,QAAQ,KAAK,KAAK,KAAK;GAC/C,KAAK,cAAc;EACrB;EAKA,AAAU,uBAAuB;GAC/B,KAAK,UAAU,KAAK,YAAY,UAAU,KAAK,KAAK;GACpD,KAAK,cAAc;EACrB;EAKA,AAAU,uBAAuB;GAC/B,MAAM,OAAO,KAAK,MAAM,UAAU,EAAG;GAKrC,MAAM,SAAS,KAAK;GACpB,KAAK,KAAK,OAAO,UAAU,IAAI;GAC/B,KAAK,KAAK,OAAO,KAAK,IAAI;EAC5B;EAKA,IAAI,OAAW;GACb,OAAO,IAAI,GAAG,KAAK,KAAK;EAC1B;EACA,IAAI,KAAK,GAAO;GACd,KAAK,QAAQ,IAAI,GAAG,CAAC;GACrB,KAAK,kBAAkB;EACzB;EAKA,IAAI,SAAa;GACf,OAAO,IAAI,GAAG,KAAK,OAAO;EAC5B;EACA,IAAI,OAAO,GAAO;GAChB,KAAK,UAAU,IAAI,GAAG,CAAC;GACvB,KAAK,qBAAqB;EAC5B;EAKA,IAAI,UAAc;GAChB,OAAO,IAAI,GAAG,KAAK,EAAE;EACvB;EACA,IAAI,QAAQ,GAAO;GACjB,KAAK,KAAK,IAAI,GAAG,CAAC;GAClB,KAAK,YAAY;EACnB;EAKA,IAAI,cAAkB;GACpB,OAAO,IAAI,GAAG,KAAK,EAAE;EACvB;EACA,IAAI,YAAY,GAAO;GACrB,KAAK,KAAK,IAAI,GAAG,CAAC;GAClB,KAAK,YAAY;EACnB;EAKA,IAAI,QAAgB;GAClB,OAAO,KAAK,MAAM,SAAS,IAAI,KAAK,MAAM,IAAI;EAChD;EACA,IAAI,MAAM,GAAW;GACnB,KAAK,MAAM,IAAI;GACf,KAAK,kBAAkB;EACzB;EAKA,IAAI,SAAiB;GACnB,OAAO,KAAK,MAAM,SAAS,IAAI,KAAK,MAAM,IAAI;EAChD;EACA,IAAI,OAAO,GAAW;GACpB,KAAK,MAAM,IAAI;GACf,KAAK,kBAAkB;EACzB;EAKA,IAAI,QAAgB;GAClB,OAAO,KAAK,MAAM,SAAS,IAAI,KAAK,MAAM,IAAI;EAChD;EACA,IAAI,MAAM,GAAW;GACnB,KAAK,MAAM,IAAI;GACf,KAAK,kBAAkB;EACzB;EAKA,IAAI,IAAwB;GAE1B,OAAO,KAAK,KAAK,KAAK,EAAE,CAAC,KAAK;EAChC;EAKA,IAAI,IAAwB;GAC1B,OAAO,KAAK,KAAK,KAAK,EAAE,CAAC,KAAK;EAChC;EAKA,IAAI,IAAwB;GAC1B,OAAO,KAAK,KAAK,KAAK,EAAE,CAAC,KAAK;EAChC;EAKA,IAAI,SAAkB;GACpB,OAAO,KAAK;EACd;EAOA,SAAS;GACP,KAAK,YAAY;GACjB,OAAO;EACT;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCnwCA,SAAS,eACP,GACA,GACA,IACA,WACS;EACT,IAAI,YAAY,GAAG,OAAO;EAC1B,MAAM,KAAK,EAAE,KAAK,EAAE;EACpB,MAAM,KAAK,EAAE,KAAK,EAAE;EACpB,MAAM,WAAW,KAAK,KAAK,KAAK;EAChC,MAAM,IACJ,aAAa,IACT,IACA,KAAK,IACH,GACA,KAAK,IAAI,KAAK,GAAG,KAAK,EAAE,MAAM,MAAM,GAAG,KAAK,EAAE,MAAM,MAAM,QAAQ,CACpE;EACN,MAAM,KAAK,GAAG,KAAK,EAAE,KAAK,IAAI;EAC9B,MAAM,KAAK,GAAG,KAAK,EAAE,KAAK,IAAI;EAC9B,OAAO,KAAK,KAAK,KAAK,MAAM,YAAY;CAC1C;CAGA,MAAM,cAA8C;EAClD,YAAY,OAAO,OAAO,UAAU,YAAY,OAAO,EAAE;EACzD,SAAS,OAAO,OAAO,OAAO,YAAY,OAAO,EAAE;EACnD,UAAU,OAAO,OAAO,QAAQ,kBAAkB,OAAO,EAAE;EAC3D,OAAO,OAAO,IAAI,WAAW;;GAC3B,MAAM,qCAAY,OAAO,sFAAiB;GAC1C,OACE,MAAM,UAAU,KAAK,eAAe,MAAM,IAAI,MAAM,IAAI,IAAI,SAAS;EAEzE;EACA,WAAW,OAAO,IAAI,WAAW;;GAC/B,MAAM,sCAAY,OAAO,wFAAiB;GAC1C,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,SAAS,GAAG,IAAI,KAAK,KAC/C,IAAI,eAAe,MAAM,IAAI,MAAM,IAAI,IAAI,IAAI,SAAS,GAAG,OAAO;GAEpE,OAAO;EACT;CACF;CAKA,MAAa,UAAU;EACrB,WAAW;EACX,QAAQ;EACR,SAAS;EACT,UAAU;EACV,MAAM;CACR;CAKA,MAAa,mBAAmB;EAC9B,IAAI;EACJ,MAAM;EACN,MAAM;EACN,MAAM;EACN,QAAQ;EACR,MAAM;EACN,QAAQ;EACR,MAAM;EACN,KAAK;EACL,OAAO;EACP,OAAO;EACP,OAAO;EACP,SAAS;EACT,OAAO;EACP,aAAa;EACb,WAAW;EACX,aAAa;EACb,KAAK;CACP;CAUA,IAAa,KAAb,MAAa,GAAG;EAsBd,YACE,OACA,OACA,SAAiC,CAAC,GAClC,IACA;GA1BF,KAAQ,gBAA6D,CAAC;GAYtE,KAAU,yBAAS,IAAI,IAAoB;GAezC,KAAK,SAAS,MAAM,UAAU,KAAK;GACnC,KAAK,SAAS;GACd,KAAK,MAAM,OAAO,SAAY,MAAM,GAAG,eAAe;GACtD,KAAK,UAAU;GACf,KAAK,WAAW,CAAC;GACjB,KAAK,cAAc,CAAC;EACtB;EAQA,OAAO,cAAc,OAAe,IAAuB;GACzD,YAAY,SAAS;EACvB;EAQA,OAAO,cAAc,OAAuB,QAAY,IAAiB;GACvE,OAAO,IAAI,KAAK,OAAO,QAAQ,WAAW,QAAQ,EAAE;EACtD;EAQA,OAAO,WAAW,OAAuB,QAAY,IAAiB;GACpE,OAAO,IAAI,KAAK,OAAO,QAAQ,QAAQ,QAAQ,EAAE;EACnD;EAQA,OAAO,YAAY,OAAuB,QAAY,IAAiB;GACrE,OAAO,IAAI,KAAK,OAAO,QAAQ,SAAS,QAAQ,EAAE;EACpD;EAOA,OAAO,OAAO,IAAQ,QAAiB,IAAiB;GAEtD,OAAO,IAAI,KAAK,GAAG,OAAO,GAAG,OAAO,6BAAe,GAAG,OAAQ,GAAG,EAAE;EACrE;EAKA,IAAI,KAAa;GACf,OAAO,KAAK;EACd;EACA,IAAI,GAAG,GAAW;GAChB,KAAK,MAAM;EACb;EAKA,IAAI,QAAe;GACjB,OAAO,KAAK;EACd;EACA,IAAI,MAAM,GAAU;GAClB,KAAK,SAAS;EAChB;EAKA,IAAI,QAAgB;GAClB,OAAO,KAAK;EACd;EACA,IAAI,MAAM,GAAW;GACnB,KAAK,SAAS;EAChB;EAQA,MAAM,KAAa,OAAkB;GACnC,IAAI,CAAC,KAAK,OAAO;GACjB,IAAI,UAAU,QAAW;IACvB,KAAK,QAAQ,OAAO;IACpB,OAAO;GACT;GACA,OAAO,KAAK,QAAQ;EACtB;EAMA,SAAkB,KAAgB;GAChC,OAAO,KAAK,QAAQ;EACtB;EAOA,SAAS,KAAa,OAAkB;GACtC,KAAK,QAAQ,OAAO;GACpB,OAAO;EACT;EASA,GACE,MACA,IACA,SACQ;;GACR,IAAI,CAAC,IAAI,OAAO;GAChB,iEAAI,QAAS,0EAAQ,SAAS,OAAO;GACrC,IAAI,CAAC,KAAK,SAAS,OAAO,KAAK,SAAS,QAAQ,CAAC;GAEjD,IAAI,UAAU;GACd,IAAI,KAAK;GACT,sDAAI,QAAS,MACX,WAAW,GAAG,GAAG,IAAI,MAAM;IACzB,KAAK,IAAI,MAAM,EAAE;IACjB,GAAG,GAAG,GAAG,IAAI,CAAC;GAChB;GAEF,KAAK,GAAG,YAAY,KAAK,SAAS,OAAO,OAAO;GAChD,sDAAI,QAAS,QAAQ;IACnB,MAAM,SAAS,QAAQ;IACvB,MAAM,cAAc,KAAK,IAAI,MAAM,EAAE;IACrC,OAAO,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;IACtD,IAAI,CAAC,KAAK,cAAc,OAAO,KAAK,cAAc,wBAAQ,IAAI,IAAI;IAClE,KAAK,cAAc,KAAK,CAAC,IAAI,UAC3B,OAAO,oBAAoB,SAAS,KAAK,CAC3C;GACF;GACA,OAAO;EACT;EAOA,IAAI,MAAuC,OAAyB;GAClE,IAAI,CAAC,KAAK,SAAS,OAAO,OAAO;GACjC,IAAI,UAAU,QAAW;;IACvB,8BAAK,cAAc,6EAAO,SAAS,YAAY,QAAQ,CAAC;IACxD,OAAO,KAAK,cAAc;IAC1B,OAAO,KAAK,SAAS;IACrB,OAAO;GACT,OAAO;;IACL,+BAAK,cAAc,yGAAO,IAAI,KAAK,sGAAI;IACvC,+BAAK,cAAc,+EAAO,OAAO,KAAK;IACtC,OAAO,GAAG,eAAe,KAAK,SAAS,OAAO,KAAK;GACrD;EACF;EAQA,OACE,MACA,GACA,KACS;GACT,IAAI,QAAQ;GACZ,MAAM,cAAc,KAAK,SAAS;GAClC,MAAM,aAAa,KAAK,YAAY;GAEpC,IAAI,eAAe,YACjB;QAAI,KAAK,QAAQ,CAAC,KAAK,KAAK,WAAW,IAAI,GAAG;KAC5C,IAAI,YAAY;MACd,GAAG,SAAS,YAAY,MAAM,GAAG,MAAM,GAAG;MAC1C,QAAQ;KACV;KACA,IAAI,aAAa;MACf,GAAG,SAAS,aAAa,MAAM,GAAG,MAAM,GAAG;MAC3C,QAAQ;KACV;IACF;;GAIF,IAAI,KAAK,SAAS,QAAQ;IACxB,GAAG,SAAS,KAAK,SAAS,QAAQ,MAAM,GAAG,MAAM,GAAG;IACpD,QAAQ;GACV;GAEA,OAAO;EACT;EAGA,AAAQ,WAAW,MAAuB;GACxC,KAAK,MAAM,QAAQ,KAAK,OAAO,OAAO,GACpC,IAAI,SAAS,MAAM,OAAO;GAE5B,OAAO;EACT;EAGA,AAAU,OAAO,MAAc,IAAuB;GACpD,IAAI,CAAC,KAAK,YAAY,OAAO,KAAK,YAAY,QAAQ,CAAC;GACvD,OAAO,GAAG,YAAY,KAAK,YAAY,OAAO,EAAE;EAClD;EAGA,AAAU,QAAQ,MAAc,OAAwB;GACtD,IAAI,CAAC,KAAK,YAAY,OAAO,OAAO;GACpC,OAAO,GAAG,eAAe,KAAK,YAAY,OAAO,KAAK;EACxD;EAMA,AAAU,KAAK,MAAsB;GACnC,IAAI,SAAS,KAAK,IAAI,GAAG,GAAG,MAAM,KAAK,KAAK,OAAO,KAAK,CAAC,CAAC,IAAI;GAC9D,KAAK,OAAO,IAAI,QAAQ,IAAI;GAC5B,OAAO;EACT;EAMA,AAAU,OAAO,KAAoB;GACnC,IAAI,QAAQ,QACV,KAAK,OAAO,OAAO,GAAG;QAEtB,KAAK,OAAO,MAAM;EAEtB;EASA,OAAO,MAAM,KAAW,MAAc,GAAW,KAA0B;GACzE,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KACzC,IAAI,EAAE,CAAC,OAAO,MAAM,GAAG,GAAG;EAE9B;EAMA,OAAO,IAAkE;GACvE,GAAG,KAAK,QAAQ,KAAK,OAAO;EAC9B;EAKA,WAAmB;GACjB,OAAO,MAAM,KAAK,MAAM,SAAS;EACnC;EAOA,AAAU,QAAQ,GAAoB;GACpC,MAAM,KAAK,YAAY,KAAK;GAC5B,IAAI,CAAC,IAAI,OAAO;GAChB,OAAO,GAAG,KAAK,QAAQ,GAAG,KAAK,OAAO;EACxC;EAKA,OAAiB,SACf,KACA,QACA,IACA,MACA,KACA;GACA,IAAI,KACF;SAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KACzC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAE,QAAQ,IAAI,MAAM,GAAG;GAC3C;EAEJ;EAKA,OAAiB,YACf,KACA,IACQ;GACR,IAAI,CAAC,IAAI,OAAO;GAGhB,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KACzC,IAAI,IAAI,OAAO,MAAM;IACnB,IAAI,KAAK;IACT,OAAO;GACT;GAEF,IAAI,KAAK,EAAE;GACX,OAAO,IAAI,SAAS;EACtB;EAMA,OAAiB,eACf,KACA,OACS;GACT,IAAI,SAAS,KAAK,QAAQ,IAAI,UAAU,IAAI,QAAQ;IAClD,IAAI,SAAS;IACb,OAAO;GACT;GACA,OAAO;EACT;CACF;CAjXE,GAAiB,WAAmB;CAsXtC,IAAa,WAAb,cAA8B,GAAG;EAU/B,YACE,OACA,OACA,SAAiC,CAAC,GAClC,IACA;GACA,MAAM,OAAO,OAAO,QAAQ,EAAE;GAfhC,KAAQ,WAAmB;GAiBzB,IAAI,OAAO,UAAU,QAAW,KAAK,QAAQ,WAAW;GACxD,IAAI,OAAO,WAAW,QAAW,KAAK,QAAQ,YAAY;GAE1D,MAAM,KAAK;GAGX,KAAK,OAAO,GAAG,UAAU;IACvB,KAAK,MAAM,UAAU,KAAK,QAAQ,SAAS,CAAC;GAC9C,CAAC;GAGD,KAAK,OACH,GAAG,OACF,QAAY,IAAY,MAAc,QAAuB;IAI5D,IAHY,KAAK,QAAQ,EAGjB,KAAK,CAAC,KAAK,QAAQ,OAAO;KAChC,KAAK,MAAM,SAAS,IAAI;KAGxB,GAAG,SAAS,KAAK,SAAS,GAAG,QAAQ,MAAM,IAAI,GAAG,OAAO,GAAG;KAG5D,IAAI,SAAS,KAAK,KAAK,GAAG,IAAI;KAC9B,KAAK,WAAW,KAAK,OACnB,GAAG,OACF,GAAO,GAAW,IAAY,MAAqB;MAClD,IAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC,KAAK,MAAM,UAAU,GAAG;OAC/C,KAAK,MAAM,SAAS,KAAK;OAEzB,GAAG,SAAS,KAAK,SAAS,GAAG,QAAQ,MAAM,GAAG,GAAG,OAAO,CAAC;OACzD,KAAK,QAAQ,GAAG,MAAM,KAAK,QAAQ;OACnC,KAAK,OAAO,MAAM;MACpB;KACF,CACF;IACF;GACF,CACF;EACF;EAOA,QAAQ,IAAuB;GAC7B,OAAO,KAAK,GAAG,iBAAiB,IAAI,EAAE;EACxC;EAOA,SAAS,IAAqB;GAC5B,OAAO,KAAK,IAAI,iBAAiB,IAAI,EAAE;EACzC;EAOA,cAAc,IAAuB;GACnC,OAAO,KAAK,GAAG,iBAAiB,aAAa,EAAE;EACjD;EAOA,eAAe,IAAqB;GAClC,OAAO,KAAK,IAAI,iBAAiB,aAAa,EAAE;EAClD;EAQA,QAAQ,OAAmB,OAA2C;GACpE,IAAI,MAA8B,CAAC,QAAW,MAAS;GACvD,IAAI,OAAO,IAAI,KAAK,KAAK,GAAG,iBAAiB,OAAO,KAAK;GACzD,IAAI,OAAO,IAAI,KAAK,KAAK,GAAG,iBAAiB,OAAO,KAAK;GACzD,OAAO;EACT;EAQA,SAAS,SAAkB,SAA6B;GACtD,IAAI,IAAI,CAAC,OAAO,KAAK;GACrB,IAAI,YAAY,UAAa,WAAW,GACtC,EAAE,KAAK,KAAK,IAAI,iBAAiB,OAAO,OAAO;GACjD,IAAI,YAAY,UAAa,WAAW,GACtC,EAAE,KAAK,KAAK,IAAI,iBAAiB,OAAO,OAAO;GACjD,OAAO;EACT;CACF;CAKA,IAAa,YAAb,cAA+B,SAAS;EAiBtC,YACE,OACA,OACA,SAAiC,CAAC,GAClC,IACA;GACA,MAAM,OAAO,OAAO,QAAQ,EAAE;GAtBhC,KAAQ,cAAsB;GAC9B,KAAQ,UAAkB;GAC1B,KAAQ,cAAsB;GAC9B,KAAQ,cAAsB;GAC9B,KAAQ,cAAsB;GAC9B,KAAQ,YAAoB;GAC5B,KAAQ,aAAqB;GAiB3B,IAAI,OAAO,aAAa,QAAW,KAAK,QAAQ,cAAc;GAC9D,IAAI,OAAO,UAAU,QAAW,KAAK,QAAQ,WAAW;GACxD,IAAI,OAAO,WAAW,QAAW,KAAK,QAAQ,YAAY,IAAI,GAAG;GAEjE,MAAM,KAAK;GAUX,KAAK,OACH,GAAG,OACF,QAAY,IAAY,MAAc,QAAuB;IAE5D,IAAI,KAAK,gBAAgB,IAAI;KAC3B,KAAK,MAAM,YAAY,IAAI;KAC3B,KAAK,MAAM,UAAU,IAAI,GAAG,EAAE,CAAC,CAAC,SAAS,OAAO,MAAM,EAAE,CAAC;KACzD,KAAK,cAAc,KAAK,KAAK,GAAG,IAAI;KACpC,KAAK,cAAc,KAAK,KAAK,GAAG,IAAI;KACpC,KAAK,aAAa,KAAK,KAAK,GAAG,GAAG;IACpC;IACA,IAAI,KAAK,gBAAgB,IACvB,KAAK,cAAc,KAAK,KAAK,GAAG,IAAI;IAEtC,IAAI,KAAK,cAAc,IACrB,KAAK,YAAY,KAAK,KAAK,GAAG,EAAE;IAElC,IAAI,KAAK,gBAAgB,IAAI;KAC3B,MAAM,QAAQ,GAAO,GAAW,IAAY,MAAqB;MAE/D,MAAM,SAAS,OAAO,GAAG,QAAQ,MAAM,KAAK;MAC5C,KAAK,iBAAiB,OAAO,GAAG,OAAO,IAAI;MAC3C,IAAI,QAAQ;MACZ,IAAI,KAAK,MAAM,UAAU,GAAG;OAC1B,GAAG,SAAS,KAAK,SAAS,GAAG,SAAS,GAAG,GAAG,GAAG,QAAQ,CAAC;OACxD,KAAK,MAAM,SAAS,IAAI;MAC1B;KACF;KACA,KAAK,cAAc,KAAK,OAAO,GAAG,MAAM,IAAI;KAC5C,KAAK,UAAU,KAAK,OAAO,GAAG,MAAM,IAAI;IAC1C;GACF,CACF;GAGA,MAAM,WACJ,QACA,IACA,MACA,QACG;IACH,KAAK,MAAM,YAAY,KAAK;IAE5B,KAAK,QAAQ,GAAG,MAAM,KAAK,WAAW;IACtC,KAAK,QAAQ,GAAG,MAAM,KAAK,OAAO;IAClC,KAAK,cAAc;IACnB,KAAK,UAAU;IACf,KAAK,iBAAiB;IAEtB,KAAK,OAAO,KAAK,WAAW;IAC5B,KAAK,cAAc;IACnB,KAAK,OAAO,KAAK,WAAW;IAC5B,KAAK,cAAc;IACnB,KAAK,OAAO,KAAK,UAAU;IAC3B,KAAK,aAAa;IAElB,KAAK,OAAO,KAAK,WAAW;IAC5B,KAAK,cAAc;IAEnB,KAAK,OAAO,KAAK,SAAS;IAC1B,KAAK,YAAY;IAEjB,IAAI,KAAK,MAAM,OAAO,GAAG;KACvB,GAAG,SAAS,KAAK,SAAS,GAAG,SAAS,QAAQ,IAAI,GAAG,QAAQ,GAAG;KAChE,KAAK,MAAM,SAAS,KAAK;IAC3B;GACF;GACA,KAAK,OAAO,GAAG,MAAM,OAAO;GAC5B,KAAK,OAAO,GAAG,IAAI,OAAO;GAC1B,KAAK,OAAO,GAAG,KAAK,OAAO;EAC7B;EAOA,OAAO,IAAuB;GAC5B,OAAO,KAAK,GAAG,iBAAiB,QAAQ,EAAE;EAC5C;EAOA,QAAQ,IAAqB;GAC3B,OAAO,KAAK,IAAI,iBAAiB,QAAQ,EAAE;EAC7C;EAOA,OAAO,IAAuB;GAC5B,OAAO,KAAK,GAAG,iBAAiB,QAAQ,EAAE;EAC5C;EAOA,QAAQ,IAAqB;GAC3B,OAAO,KAAK,IAAI,iBAAiB,QAAQ,EAAE;EAC7C;CACF;;;;;;;;CCluBA,IAAsB,QAAtB,MAA4B;;GAC1B,UAAa;GACb,KAAU,QAAe,IAAI,MAAM;GAEnC,KAAU,QAAgB;IAAE,MAAM;IAAG,MAAM;IAAG,KAAK;IAAI,KAAK;GAAE;GAC9D,KAAQ,aAAa;GACrB,KAAU,UAAyB,CAAC;GACpC,KAAU,cAAc;GAGxB,KAAQ,UAAkB;GAC1B,KAAQ,aAAa;GAErB,KAAQ,SAAkB;GAC1B,KAAQ,WAAgC;GAGxC,KAAU,WAAe,IAAI,GAAG;GAEhC,KAAU,WAAW;GACrB,KAAU,WAAW;GACrB,KAAQ,cAAc;;EAMtB,QAAQ,GAAkB;GACxB,KAAK,WAAW;GAChB,OAAO;EACT;EAMA,aAAa,KAAa,GAAS;GACjC,KAAK,MAAM,MAAM;GACjB,OAAO;EACT;EAWA,IAAI,GAAsC;GACxC,MAAM,SAAkB,OAAO,KAAK,aAAa,EAAE,SAAS,EAAE,IAAI;GAElE,MAAM,IAAI,KAAK;GACf,MAAM,MAAM,OAAO,aAAa,KAAK,KAAK;GAE1C,KAAK,QAAQ,OAAO;GACpB,OAAO,YAAY;GAGnB,IAAI,OAAO,UAAU,KAAK,MAAM,QAAQ,OAAO,OAAO,KAAK,KAAK;GAGhE,IAAI,KAAK,aAAa,QAAW,KAAK,WAAW;GAEjD,OAAO;EACT;EAMA,OAAO,QAAuB;GAC5B,OAAO,KAAK,QAAQ,OAAO;GAC3B,OAAO;EACT;EAKA,YAAkB;GAChB,KAAK,UAAU,CAAC;GAChB,OAAO;EACT;EAOA,KAAK,OAAO,GAAS;GAGnB,MAAM,YAAY,KAAK;GACvB,KAAK,aAAa;GAGlB,IAAI,SAAS,KAAK,KAAK,YAAY,MAAM,CAAC,WACxC,OAAO;GAKT,IAAI,KAAK,YAAY,IAAI,qBAAqB,KAAK,OAAO;GAC1D,KAAK,UAAU,uBAAuB,cAAc;IAClD,KAAK,aAAa;IAClB,IAAI;KACF,KAAK,KAAK,SAAS;IACrB,UAAU;KACR,KAAK,aAAa;IACpB;GACF,CAAC;GAED,IAAI,KAAK,QAAQ;IAGf,KAAK,MAAM,OAAO;IAClB,OAAO;GACT;GAEA,IAAI,KAAK,aAAa;IAKpB,KAAK,cAAc,SAAS,KAAK,CAAC;IAClC,KAAK,MAAM,OAAO;IAClB,KAAK,MAAM,OAAO;GACpB,OAAO;IACL,MAAM,OAAO,OAAO,KAAK,MAAM;IAE/B,IAAI,OAAO,KAAK,MAAM,KAAK,OAAO;IAClC,KAAK,MAAM,OAAO;IAClB,KAAK,MAAM,OAAO;GACpB;GAEA,IAAI;IACF,KAAK,UAAU,IAAI;GACrB,SAAS,KAAK;IACZ,qBAAqB,KAAK,OAAO;IACjC,KAAK,UAAU;IACf,KAAK,WAAW;IAChB,KAAK,cAAc;IACnB,MAAM;GACR;GAEA,OAAO;EACT;EAMA,SAAS;GACP,KAAK,MAAM,MAAM;GACjB,KAAK,KAAK;EACZ;EAMA,AAAU,UAAU,MAAc;GAChC,KAAK,WAAW;GAGhB,IAAI,KAAK,UAAU,KAAK,MAAM;GAG9B,IAAI,KAAK,UACP;SAAK,MAAM,KAAK,KAAK,SACnB,IAAI,KAAK,QAAQ,EAAE,CAAC,SAClB,KAAK,QAAQ,EAAE,CAAC,QAAQ,MAAM,KAAK,MAAM,MAAM,IAAI;GACvD;GAIF,IAAI,KAAK,cAAc,GAAG;IACxB,KAAK,MAAM,MAAM,OAAO,KAAK;IAC7B,KAAK,aAAa;GACpB;GAGA,IAAI,KAAK,MAAM,OAAO,KAAK,OAAO,KAAK,MAAM,KAAK;IAChD,qBAAqB,KAAK,OAAO;IACjC,KAAK,UAAU;IACf,KAAK,WAAW;IAChB,KAAK,cAAc;GACrB;EACF;EAMA,MAAM,SAAS,OAAa;GAC1B,KAAK,SAAS,SAAS,CAAC,KAAK,SAAS;GACtC,OAAO;EACT;EAKA,SAAe;GACb,KAAK,SAAS;GACd,OAAO;EACT;EAOA,KAAK,IAAI,GAAS;GAGhB,KAAK,aAAa,IAAI,IAAI,IAAI;GAC9B,KAAK,MAAM,MAAM,IAAI,IAAI,KAAK;GAC9B,OAAO;EACT;EAOA,AAAU,mBAAyB;GACjC,IAAI,KAAK,YAAY,IAAI,qBAAqB,KAAK,OAAO;GAC1D,KAAK,UAAU;GACf,KAAK,WAAW;GAChB,KAAK,cAAc;GACnB,OAAO;EACT;EAMA,SAAS,WAAW,GAAS;GAC3B,KAAK,KAAK;GACV,KAAK,KAAK,QAAQ;GAClB,OAAO;EACT;EAMA,AAAU,OAAO,SAAoB;GACnC,IAAI,KAAK,aAAa,KAAK,YAAY,SAAS,IAAI;GACpD,OAAO;EACT;EAKA,IAAI,gBAAgB,GAAwC;GAC1D,KAAK,cAAc;EACrB;EACA,IAAI,kBAAuD;GACzD,OAAO,KAAK;EACd;EAKA,IAAI,YAAqB;GACvB,OAAO,KAAK;EACd;EAKA,IAAI,aAAoB;GACtB,OAAO,KAAK,MAAM,MAAM;EAC1B;EAKA,IAAW,aAAoB;GAC7B,OAAO,IAAI,MAAM,GAAG,KAAK,KAAK,KAAK,QAAQ,CAAC,GAAG,KAAK,KAAK,MAAM,CAAC;EAClE;EAKA,IAAI,OAAW;GACb,OAAO,KAAK,MAAM,KAAK,MAAM;EAC/B;EAKA,IAAI,SAAa;GACf,OAAO,KAAK,KAAK,OAAO,CAAC;EAC3B;EAKA,IAAI,QAAgB;GAClB,OAAO,KAAK,MAAM;EACpB;EAKA,IAAI,SAAiB;GACnB,OAAO,KAAK,MAAM;EACpB;CAkBF;CAMA,IAAsB,kBAAtB,cAA8C,MAAM;;;GAElD,KAAU,WAAW;GACrB,KAAU,WAAW;GAErB,KAAU,YAAY;GACtB,KAAU,YAAY;GACtB,KAAU,eAAe;GAKzB,KAAQ,gBAAgB;GAExB,KAAiB,iBAAiB,KAAK,WAAW,KAChD,IACF;GACA,KAAiB,eAAe,KAAK,SAAS,KAC5C,IACF;GACA,KAAiB,iBAAiB,KAAK,WAAW,KAChD,IACF;GACA,KAAiB,gBAAgB,KAAK,UAAU,KAC9C,IACF;GACA,KAAiB,iBAAiB,KAAK,WAAW,KAChD,IACF;GACA,KAAiB,kBAAkB,KAAK,YAAY,KAClD,IACF;GACA,KAAiB,mBAAmB,KAAK,aAAa,KACpD,IACF;GACA,KAAiB,kBAAkB,KAAK,YAAY,KAClD,IACF;GACA,KAAiB,iBAAiB,KAAK,WAAW,KAChD,IACF;GACA,KAAiB,eAAe,KAAK,SAAS,KAC5C,IACF;GACA,KAAiB,aAAa,KAAK,OAAO,KACxC,IACF;GAgMA,KAAQ,cAAoB,CAAC;GAC7B,KAAQ,YAA4B;;EAzLpC,IAAW,UAAc;GACvB,MAAM,IAAI,KAAK,SAAS,MAAM;GAC9B,EAAE,KAAK,KAAK,SAAS;GACrB,OAAO;EACT;EASA,WACE,KACA,UACA,UAAe,CAAC,GAChB,cACA;GAEA,CADe,eAAe,eAAe,KAAK,QAC5C,CAAC,iBAAiB,KAAK,UAAU,OAAO;EAChD;EASA,aACE,KACA,UACA,UAAe,CAAC,GAChB,cACA;GAEA,CADe,eAAe,eAAe,KAAK,QAC5C,CAAC,oBAAoB,KAAK,UAAU,OAAO;EACnD;EAEA,QAAQ,KAAa,UAAyB,UAAe,CAAC,GAAG;GAC/D,IAAI,OAAO,aAAa,aACtB,SAAS,iBAAiB,KAAK,UAAU,OAAO;EAEpD;EAEA,UAAU,KAAa,UAAyB,UAAe,CAAC,GAAG;GACjE,IAAI,OAAO,aAAa,aACtB,SAAS,oBAAoB,KAAK,UAAU,OAAO;EAEvD;EAUA,UAAU,OAAgB,MAAM,cAA8B;GAC5D,IAAI,MAAM;IACR,IAAI,KAAK,WAAW;KAClB,IAAI,KAAK,iBAAiB,cAAc,OAAO;KAC/C,KAAK,UAAU,KAAK;IACtB;IAEA,KAAK,eAAe;IACpB,KAAK,WAAW,eAAe,KAAK,gBAAgB,CAAC,GAAG,YAAY;IACpE,KAAK,WAAW,aAAa,KAAK,cAAc,CAAC,GAAG,YAAY;IAChE,KAAK,WAAW,eAAe,KAAK,gBAAgB,CAAC,GAAG,YAAY;IACpE,KAAK,WAAW,cAAc,KAAK,eAAe,CAAC,GAAG,YAAY;IAClE,KAAK,WAAW,iBAAiB,KAAK,eAAe,CAAC,GAAG,YAAY;IACrE,KAAK,WAAW,eAAe,KAAK,gBAAgB,CAAC,GAAG,YAAY;IACpE,KAAK,WAAW,SAAS,KAAK,iBAAiB,CAAC,GAAG,YAAY;IAC/D,KAAK,WAAW,eAAe,KAAK,kBAAkB,CAAC,GAAG,YAAY;IACtE,KAAK,YAAY;GACnB,OAAO,IAAI,KAAK,WAAW;IACzB,MAAM,SAAS,KAAK;IACpB,KAAK,aAAa,eAAe,KAAK,gBAAgB,CAAC,GAAG,MAAM;IAChE,KAAK,aAAa,aAAa,KAAK,cAAc,CAAC,GAAG,MAAM;IAC5D,KAAK,aAAa,eAAe,KAAK,gBAAgB,CAAC,GAAG,MAAM;IAChE,KAAK,aAAa,cAAc,KAAK,eAAe,CAAC,GAAG,MAAM;IAC9D,KAAK,aAAa,iBAAiB,KAAK,eAAe,CAAC,GAAG,MAAM;IACjE,KAAK,aAAa,eAAe,KAAK,gBAAgB,CAAC,GAAG,MAAM;IAChE,KAAK,aAAa,SAAS,KAAK,iBAAiB,CAAC,GAAG,MAAM;IAC3D,KAAK,aAAa,eAAe,KAAK,kBAAkB,CAAC,GAAG,MAAM;IAClE,KAAK,YAAY;IACjB,KAAK,eAAe;GACtB;GACA,OAAO;EACT;EAWA,UACE,OAAgB,MAChB,UAAmB,OACnB,cACM;GACN,IAAI,MAAM;IACR,IAAI,KAAK,WAAW;KAClB,IACE,KAAK,iBAAiB,gBACtB,KAAK,kBAAkB,SAEvB,OAAO;KACT,KAAK,UAAU,KAAK;IACtB;IAEA,KAAK,eAAe;IACpB,KAAK,gBAAgB;IACrB,KAAK,WACH,cACA,KAAK,iBACL,EAAW,QAAQ,GACnB,YACF;IACA,KAAK,WAAW,YAAY,KAAK,cAAc,CAAC,GAAG,YAAY;IAC/D,KAAK,WACH,aACA,KAAK,gBACL,EAAW,QAAQ,GACnB,YACF;IACA,KAAK,WAAW,eAAe,KAAK,eAAe,CAAC,GAAG,YAAY;IACnE,KAAK,YAAY;GACnB,OAAO,IAAI,KAAK,WAAW;IACzB,MAAM,SAAS,KAAK;IACpB,MAAM,UAAU,EAAE,SAAS,KAAK,cAAc;IAC9C,KAAK,aAAa,cAAc,KAAK,iBAAiB,SAAS,MAAM;IACrE,KAAK,aAAa,YAAY,KAAK,cAAc,CAAC,GAAG,MAAM;IAC3D,KAAK,aAAa,aAAa,KAAK,gBAAgB,SAAS,MAAM;IACnE,KAAK,aAAa,eAAe,KAAK,eAAe,CAAC,GAAG,MAAM;IAC/D,KAAK,YAAY;IACjB,KAAK,eAAe;GACtB;GACA,OAAO;EACT;EAMA,aAAa,OAAgB,MAAM,cAAkC;GACnE,IAAI,MAAM;IACR,MAAM,SAAS,gBAAgB;IAC/B,IAAI,KAAK,cAAc;KACrB,IAAI,KAAK,oBAAoB,QAAQ,OAAO;KAC5C,KAAK,aAAa,KAAK;IACzB;IAEA,OAAO,iBAAiB,WAAW,KAAK,cAAc,CAAC,CAAC;IACxD,OAAO,iBAAiB,SAAS,KAAK,YAAY,CAAC,CAAC;IACpD,KAAK,kBAAkB;IACvB,KAAK,eAAe;GACtB,OAAO,IAAI,KAAK,cAAc;IAC5B,KAAK,gBAAiB,oBACpB,WACA,KAAK,cACL,CAAC,CACH;IACA,KAAK,gBAAiB,oBAAoB,SAAS,KAAK,YAAY,CAAC,CAAC;IACtE,KAAK,kBAAkB;IACvB,KAAK,eAAe;GACtB;GACA,OAAO;EACT;EAGA,AAAU,aAAmB;GAC3B,KAAK,UAAU,KAAK;GACpB,KAAK,UAAU,KAAK;GACpB,KAAK,aAAa,KAAK;GACvB,OAAO;EACT;EAMA,YAAkB;GAChB,KAAK,QAAQ;GACb,KAAK,YAAY;GACjB,OAAO,MAAM,UAAU;EACzB;EAUA,MAAM,KAAsB;GAC1B,MAAM,OAAO,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,GAAG;GAC5C,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,IAAI,KAAK,YAAY,QAAQ,KAAK,EAAE,IAAI,GAAG,KAAK,YAAY,KAAK,KAAK,EAAE;GAE1E,IAAI,CAAC,KAAK,WAAW;IACnB,KAAK,YAAY;KACf,eAAe,CAAC;KAChB,SAAS,MAAc,IAAY,IAAY,QAAe;MAC5D,GAAG,MAAM,KAAK,aAAa,MAAM,IAAI,GAAG,IAAI,EAAE,GAAG,GAAiB;KACpE;IACF;IACA,KAAK,IAAI,KAAK,SAAS;GACzB;GACA,OAAO;EACT;EAMA,QAAQ,KAAuB;GAC7B,MAAM,OACJ,QAAQ,SACJ,KAAK,YAAY,MAAM,IACvB,MAAM,QAAQ,GAAG,IACf,MACA,CAAC,GAAG;GACZ,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK;IAC/C,MAAM,KAAK,KAAK,YAAY,QAAQ,KAAK,EAAE;IAC3C,IAAI,KAAK,GAAG;IACZ,KAAK,YAAY,OAAO,IAAI,CAAC;IAG7B,IAAI,KAAK,EAAE,CAAC,MAAM,UAAU,GAC1B,KAAK,EAAE,CAAC,OACNC,iBAAI,MACJ,KAAK,UACL,IAAI,MAAM,eAAe,CAC3B;GAEJ;GACA,OAAO;EACT;EAIA,AAAQ,kBAAoD;GAC1D,IAAI,OAAO,YAAY,eAAe,KAAK,mBAAmB,SAAS;IACrE,MAAM,OAAO,KAAK,QAAQ,sBAAsB;IAChD,OAAO;KACL,KAAK;KACL,KAAK;KACL,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ;KACvC,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS;IAC5C;GACF;GAEA,OAAO;IACL,KAAK,MAAM,QAAQ,KAChB,OAAO,WAAW,cAAc,IAAI,OAAO;IAC9C,KAAK,MAAM,QAAQ,KAChB,OAAO,WAAW,cAAc,IAAI,OAAO;IAC9C;IACA;GACF;EACF;EAQA,gBAAgB,KAAiB,QAAwB,WAAiB;GACxE,IAAI,CAAC,OAAO,CAAC,IAAI,QAAQ,OAAO,CAAC;GACjC,MAAM,KAAK,CAAC;GACZ,MAAM,CAAC,MAAM,KAAK,QAAQ,UAAU,KAAK,gBAAgB;GACzD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,QAAQ,KAAK;IAC1C,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC;IAC3B,GAAG,KAAK,IAAI,IAAI,EAAE,UAAU,QAAQ,SAAS,EAAE,UAAU,OAAO,MAAM,CAAC;GACzE;GACA,OAAO;EACT;EAQA,AAAU,aACR,MACA,KACA;GACA,IAAI,CAAC,KAAK,WAAW;GAIrB,MAAM,CAAC,MAAM,KAAK,QAAQ,UAAU,KAAK,gBAAgB;GACzD,IAAI,KAAK,GACP,KAAK;GAEP,IAAI,eAAe,YAAY;IAC7B,MAAM,IAAI,UAAU,QAAQ;IAC5B,MAAM,IAAI,UAAU,OAAO;GAC7B,OAAO;IACL,MAAM,QACJ,IAAI,kBAAkB,IAAI,eAAe,SAAS,IAC9C,IAAI,eAAe,KAAK,CAAC,IACzB;IACN,IAAI,OAAO;KACT,MAAM,MAAM,UAAU,QAAQ;KAC9B,MAAM,MAAM,UAAU,OAAO;IAC/B;GACF;GAEA,IAAI,MAAM;IACR,KAAK,SAAS,GAAG,IAAI,EAAE;IACvB,KAAK,SAAS,KAAK;GACrB;GAEA,KAAK,MAAM,KAAK,KAAK,SACnB,IAAI,KAAK,QAAQ,eAAe,CAAC,GAAG;IAClC,MAAM,IAAI,KAAK,QAAQ;IACvB,IAAI,EAAE,QAAQ,EAAE,OAAO,MAAM,IAAI,IAAI,GAAG;GAC1C;EAEJ;EAIA,AAAQ,gBAAgB,KAAyC;GAC/D,OACE,iBAAiB,OACjB,IAAI,gBAAgB,WACpB,KAAK,aACL,IAAI,aAAa,CAAC,CAAC,SAAS,KAAK,gBAAgB,KAAK,OAAO;EAEjE;EAMA,AAAU,WAAW,KAAmB;GACtC,IAAI,KAAK,gBAAgB,GAAG,GAAG,OAAO;GACtC,KAAK,aAAaA,iBAAI,MAAM,GAAG;GAC/B,KAAK,aAAaA,iBAAI,aAAa,GAAG;GACtC,KAAK,WAAW;GAChB,IAAI,IAAI,kBAAkB,SACxB,IAAI;IACF,IAAI,OAAO,kBAAkB,IAAI,SAAS;GAC5C,kBAAQ,CAGR;GAEF,OAAO;EACT;EAMA,AAAU,SAAS,KAAgC;GACjD,IAAI,KAAK,gBAAgB,GAAG,GAAG,OAAO;GACtC,KAAK,aAAaA,iBAAI,WAAW,GAAG;GACpC,IAAI,KAAK,UACP,KAAK,aAAaA,iBAAI,MAAM,GAAG;QAE/B,KAAK,aAAaA,iBAAI,IAAI,GAAG;GAE/B,KAAK,WAAW;GAChB,KAAK,WAAW;GAChB,IACE,eAAe,gBACf,IAAI,kBAAkB,WACtB,IAAI,OAAO,kBAAkB,IAAI,SAAS,GAE1C,IAAI,OAAO,sBAAsB,IAAI,SAAS;GAEhD,OAAO;EACT;EAMA,AAAU,WAAW,KAAmB;GACtC,IAAI,KAAK,gBAAgB,GAAG,GAAG,OAAO;GACtC,IAAI,KAAK,UAAU;IACjB,KAAK,WAAW;IAChB,KAAK,aAAaA,iBAAI,MAAM,GAAG;GACjC,OACE,KAAK,aAAaA,iBAAI,MAAM,GAAG;GAEjC,OAAO;EACT;EAMA,AAAU,WAAW,KAAmB;GACtC,IAAI,KAAK,gBAAgB,GAAG,GAAG,OAAO;GACtC,KAAK,aAAaA,iBAAI,MAAM,GAAG;GAC/B,OAAO;EACT;EAMA,AAAU,UAAU,KAAgC;GAClD,IAAI,KAAK,gBAAgB,GAAG,GAAG,OAAO;GACtC,KAAK,aAAaA,iBAAI,KAAK,GAAG;GAC9B,IAAI,KAAK,UAAU,KAAK,aAAaA,iBAAI,MAAM,GAAG;GAClD,KAAK,WAAW;GAChB,KAAK,WAAW;GAChB,OAAO;EACT;EAMA,AAAU,YAAY,KAA8B;GAClD,KAAK,aAAaA,iBAAI,OAAO,GAAG;GAChC,KAAK,WAAW;GAChB,KAAK,WAAW;GAChB,OAAO;EACT;EAMA,AAAU,aAAa,KAAiB;GACtC,KAAK,aAAaA,iBAAI,aAAa,GAAG;GACtC,OAAO;EACT;EAMA,AAAU,WAAW,KAAiB;GACpC,KAAK,aAAaA,iBAAI,MAAM,GAAG;GAC/B,IAAI,KAAK,UAAU;IACjB,KAAK,WAAW;IAChB,KAAK,aAAaA,iBAAI,MAAM,GAAG;GACjC;GAEA,IAAI,CAAC,KAAK,eAAe,IAAI,eAAe;GAC5C,OAAO;EACT;EAMA,AAAU,YAAY,KAAiB;GACrC,KAAK,aAAaA,iBAAI,MAAM,GAAG;GAC/B,KAAK,WAAW;GAChB,IAAI,CAAC,KAAK,eAAe,IAAI,eAAe;GAC5C,OAAO;EACT;EAEA,AAAU,SAAS,KAAoB;GACrC,KAAK,gBAAgBA,iBAAI,SAAS,GAAG;GACrC,OAAO;EACT;EAEA,AAAU,OAAO,KAAoB;GACnC,KAAK,gBAAgBA,iBAAI,OAAO,GAAG;GACnC,OAAO;EACT;EAEA,AAAU,gBAAgB,MAAc,KAAoB;GAC1D,IAAI,CAAC,KAAK,WAAW;GACrB,KAAK,MAAM,KAAK,KAAK,SACnB,IAAI,KAAK,QAAQ,eAAe,CAAC,GAAG;IAClC,MAAM,IAAI,KAAK,QAAQ;IACvB,IAAI,EAAE,QACJ,EAAE,OAAO,MAAM,IAAI,WAAW,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,GAAG;GAChE;EAEJ;CACF;;;;;;;;;CCx3BA,IAAsB,OAAtB,MAA2B;;GACzB,KAAU,SAAkB;;EAK5B,IAAI,QAAiB;GACnB,OAAO,KAAK;EACd;CACF;CAMA,IAAsB,aAAtB,cAAyC,KAAK;;;GAC5C,KAAU,UAAU;GACpB,KAAU,WAAW;GACrB,KAAU,QAAc,IAAI,KAAK,IAAI,YAAY;;EAKjD,IAAI,SAAkB;GACpB,OAAO,KAAK;EACd;EACA,IAAI,OAAO,GAAY;GACrB,KAAK,UAAU;EACjB;EAKA,IAAI,UAAmB;GACrB,OAAO,KAAK;EACd;EACA,IAAI,QAAQ,GAAY;GACtB,KAAK,WAAW;EAClB;EAKA,IAAI,cAAoB;GACtB,OAAO,KAAK;EACd;EAEA,AAAU,UACR,QACA,OACA,GAAG,MACG;GACN,IAAI,CAAC,QAAQ,OAAO;GACpB,KAAK,IAAI,IAAI,GAAG,MAAM,OAAO,QAAQ,IAAI,KAAK,KAE5C,AAAC,KAAa,MAAM,CAAC,OAAO,IAAI,GAAG,IAAI;GAEzC,OAAO;EACT;EAWA,MAAM,GAAiB;GACrB,OAAO;EACT;EAMA,KAAK,GAA2B;GAC9B,OAAO;EACT;EAMA,SAAS,GAA2B;GAClC,KAAK,OAAO,KAAK;GACjB,OAAO,KAAK,KAAK,CAAC;EACpB;EASA,OACE,GACA,OACA,UACA,SACM;GACN,OAAO;EACT;EASA,WACE,GACA,OACA,UACA,SACM;GACN,KAAK,KAAK,KAAK;GACf,OAAO,KAAK,OAAO,GAAG,OAAO,UAAU,OAAO;EAChD;EAiBA,OAAO,KAA6B,QAAgB,OAAqB;GACvE,IAAI,CAAC,KAAK,OAAO;GACjB,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KACzC,KAAK,MAAM,IAAI,IAAI,QAAQ,KAAK;GAElC,OAAO;EACT;EAaA,QAAQ,QAA2B;GACjC,OAAO,KAAK,UAAU,QAAQ,QAAQ;EACxC;EAMA,QAAQ,QAA2B;GACjC,OAAO,KAAK,UAAU,QAAQ,QAAQ;EACxC;EA4BA,MAAM,QAA2B;GAC/B,OAAO,KAAK,UAAU,QAAQ,MAAM;EACtC;EAYA,SAAS,QAA2B;GAClC,OAAO,KAAK,UAAU,QAAQ,SAAS;EACzC;EAYA,MAAM,QAA2B;GAC/B,OAAO,KAAK,UAAU,QAAQ,MAAM;EACtC;CA2BF;CAKA,IAAa,OAAb,MAAkB;EAgBhB,YACE,OAAe,IACf,OAAe,cACf,SAAiB,IACjB,QAAgB,IAChB,aAAqB,KACrB;GACA,KAAK,OAAO;GACZ,KAAK,OAAO;GACZ,KAAK,QAAQ;GACb,KAAK,SAAS;GACd,KAAK,aAAa;EACpB;EAKA,IAAI,QAAgB;GAClB,MAAM,SAAS,CAAC,KAAK,OAAO,KAAK,MAAM,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;GACjE,MAAM,OAAO,GAAG,KAAK,KAAK,KAAK,KAAK,WAAW,GAAG,KAAK;GACvD,OAAO,SAAS,GAAG,OAAO,GAAG,SAAS;EACxC;EAKA,WAAmB;GACjB,OAAO,KAAK;EACd;CACF;;;;;CC9SA,IAAa,aAAb,MAAwB;EAQtB,OAAO,mBACL,IACA,UAAoB;GAAC;GAAK;GAAK;EAAG,GAClC,eAAyB;GAAC;GAAM;GAAK;EAAI,GAC5B;GACb,IAAI,QAAQ,WAAW,aAAa,QAClC,MAAM,IAAI,MACR,gCAAgC,QAAQ,OAAO,sBAAsB,aAAa,OAAO,4BAC3F;GAEF,MAAM,IAAI,QAAQ,IAAI,EAAE;GACxB,MAAM,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC;GACtC,QAAQ,SAAyB,KAAK,SAAS;EACjD;EAOA,OAAO,eAAe,IAA8B;GAGlD,MAAM,yBAAQ,IAAI,aAAa,GAAG,EAAC,CAAC,KAAK,GAAG;GAC5C,MAAM,wBAAQ,IAAI,IAAoB;GACtC,QAAQ,SAAyB;IAC/B,IAAI,MAAM;IACV,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK;KAC/C,MAAM,OAAO,KAAK,WAAW,CAAC;KAC9B,IAAI,OAAO,KAAK;MACd,IAAI,IAAI,MAAM;MACd,IAAI,MAAM,GAAG;OACX,IAAI,GAAG,KAAK,EAAE;OACd,MAAM,QAAQ;MAChB;MACA,OAAO;KACT,OAAO;MACL,IAAI,KAAK,KAAK;MACd,IAAI,QAAQ,SAAU,QAAQ,SAAU,IAAI,IAAI,KAAK;OACnD,MAAM,KAAK,IAAI;OACf;MACF;MACA,IAAI,IAAI,MAAM,IAAI,EAAE;MACpB,IAAI,MAAM,QAAW;OACnB,IAAI,GAAG,EAAE;OACT,MAAM,IAAI,IAAI,CAAC;MACjB;MACA,OAAO;KACT;IACF;IACA,OAAO;GACT;EACF;EAWA,OAAO,SACL,IACA,KACA,OACA,OAAe,IACf,MACkB;GAClB,MAAM,MAAM,IAAI;GAChB,IAAI;GACJ,IAAI;GACJ,IAAI;GAEJ,IAAI,SAAS,UAAa,CAAC,MAAM;IAI/B,SAAS;IACT,MAAM;IACN,OAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;GACpD,OAAO;IACL,MAAM,OAAO,GAAG,GAAG;IACnB,IAAI,QAAQ,OAAO,OAAO,CAAC,KAAK,GAAG;IACnC,SAAS,SAAS,OAAO,GAAG,IAAI,IAAI;IACpC,MAAM,MAAM;IACZ,OACE,SAAS,SACL,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC,IAC3C,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAO,MAAM,SAAU,IAAI,CAAC,CAAC;GACpE;GAEA,MAAM,QAAQ,MAAuB,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC,KAAK;GAK5D,IAAI,OAAO;GACX,IAAI,KAAK;GACT,IAAI,KAAK;GAET,IAAI,UAAU,GAAG;IACf,MAAM,IAAI;IACV,IAAI,KAAK,CAAC,GAAG;KACX,OAAO;KACP,KAAK,IAAI;KACT,KAAK,IAAI,MAAM,GAAG,MAAM,IAAI,OAAO,GAAG;MACpC,MAAM,IAAI,KAAK,IAAI,IAAI,IAAI,GAAG;MAC9B,IAAI,CAAC,KAAK,CAAC,GAAG;OACZ,KAAK,IAAI;OACT;MACF;MACA,OAAO;MACP,KAAK,IAAI;KACX;IACF,OAAO;KACL,KAAK,IAAI;KACT,KAAK,IAAI,MAAM,GAAG,MAAM,IAAI,OAAO,GAAG;MACpC,MAAM,IAAI,KAAK,IAAI,IAAI,IAAI,GAAG;MAC9B,IAAI,KAAK,CAAC,GAAG;OACX,OAAO;OACP,KAAK,IAAI;OACT;MACF;MACA,KAAK,IAAI;KACX;IACF;IACA,OAAO,MAAM,IAAI;KACf,MAAM,IAAK,KAAK,MAAO;KACvB,IAAI,KAAK,CAAC,GAAG;MACX,OAAO;MACP,KAAK,IAAI;KACX,OACE,KAAK,IAAI;IAEb;GACF;GAEA,IAAI,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;GAC3B,IAAI,SAAS,KAAK,OAAO,CAAC,KAAK,GAAG;GAGlC,IAAI,MAAM;GACV,IAAI,MAAM,GAAG;IACX,MAAM,OAAO,IAAI,WAAW,MAAM,CAAC;IACnC,IAAI,QAAQ,SAAU,QAAQ,OAAQ;GACxC;GAEA,OAAO,CAAC,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,GAAG;EACvC;EAoBA,OAAO,cACL,QAAiC,GACjC,WAA6B,MAC7B,gBACiC;GACjC,IAAI,OAAO,UAAU,UAAU;IAC7B,KAAK,KACH,sJACF;IACA,QAAQ,OAAO,aAAa,WAAW,WAAW;IAClD,WAAW,mBAAmB,SAAY,OAAO;GACnD;GACA,MAAM,IAAI;GACV,MAAM,KAAK;GACX,QAAQ,QAAgC;IACtC,MAAM,QAAQ,MAAM,UAAU,GAAG;IACjC,OAAO,KAAK,KAAK,MAAM,SAAS,MAAM;GACxC;EACF;EAQA,OAAO,oBACL,WACA,YAAoB,GAC0B;GAC9C,IAAI,cAAc,GAChB,MAAM,IAAI,MAAM,4CAA4C;GAE9D,OAAO,SAAU,aAAqB,KAAqB;IACzD,MAAM,IAAK,cAAc,MAAO;IAChC,IAAI,YAAY,GAAG,OAAO,KAAK,IAAI,GAAG,WAAW;IACjD,IAAI,YAAY,GAAG,OAAO,KAAK,IAAI,GAAG,WAAW;IACjD,OAAO;GACT;EACF;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CC3MA,IAAa,MAAb,MAAa,IAAI;EAwBf,YACE,WAAiC,OACjC,OACA,aACA;;GAvBF,KAAU,SAAiB;GAE3B,KAAU,UAAmB;GAM7B,KAAQ,qBAAoD;GAC5D,KAAQ,YAAY;GACpB,KAAU,aAAsB;GAc9B,MAAM,OACJ,OAAO,aAAa,WAChB,WACA;IAAE;IAAU;IAAO;GAAY;GACrC,KAAK,YAAY,CAAC,CAAC,KAAK;GACxB,KAAK,SAAS,KAAK;GACnB,KAAK,6BAAS,KAAK,yEAAe,KAAK,SAAS,KAAK,OAAO,aAAa;GACzE,KAAK,OAAO,IAAI,MAAM;GACtB,IAAI,KAAK,aAAa,KAAK,KAAK,cAAc;EAChD;EAWA,OAAO,KACL,KACA,WAAiC,OACjC,OACA,OACc;GACd,OAAO,IAAI,IAAI,UAAU,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,QAAQ;IACtD,IAAI,OAAO,MAAM,GAAG;IACpB,OAAO;GACT,CAAC;EACH;EASA,OAAa,UACX,KACA,WAAiC,OACjC;yCACc;IACd,OAAO,IAAI,KAAK,KAAK,UAAU,KAAK;GACtC;;EAUA,OAAa,YACX,KACA,OACA,SAAkC,UAClC,WAAoB;yCACpB;IAEA,QAAO,MADW,IAAI,UAAU,KAAK,UAAU,KAAK,EAC1C,CAAC,QAAQ,MAAM;GAC3B;;EAQA,OAAO,MAAM,MAAc,OAAqB,OAAqB;GACnE,IAAI,MAAM,IAAI,IAAI,MAAM,KAAK;GAC7B,MAAM,IAAI,QAAQ,QAAQ,QAAQ,MAAM,aAAa;GACrD,IAAI,WAAW,KAAK,IAAI,KAAK,IAAI,CAAC;GAClC,OAAO;EACT;EAOA,KAAK,KAA2B;GAC9B,IAAI,KAAK,aAAa,OAAO,aAAa,aACxC,OAAO,QAAQ,uBACb,IAAI,MAAM,wDAAwD,CACpE;GAGF,OAAO,KAAK,cAAc,GAAG,CAAC,CAAC,WAAW;IACxC,IAAI,KAAK,WAAW,MAAM,IAAI,MAAM,uBAAuB;IAC3D,IAAI,KAAK,WAAW;KAClB,IAAI,CAAC,KAAK,KACR,KAAK,MAAM,SAAS,cAAc,QAAQ;KAC5C,KAAK,aAAa,KAAK,QAAQ,KAAK,IAAI;KACxC,KAAK,aAAa;IACpB;IACA,KAAK,UAAU;IACf,OAAO;GACT,CAAC;EACH;EAMA,AAAU,cAAc,KAA4B;GAClD,IAAI,KAAK,WACP,OAAO,QAAQ,uBAAO,IAAI,MAAM,uBAAuB,CAAC;GAC1D,OAAO,IAAI,SAAe,SAAS,WAAW;IAG5C,IAAI,KAAK,oBACP,KAAK,mCACH,IAAI,MAAM,wCAAwC,CACpD;IAEF,KAAK,qBAAqB;IAE1B,KAAK,KAAK,eAAe;KACvB,KAAK,qBAAqB;KAC1B,QAAQ;IACV;IAEA,KAAK,KAAK,gBAAgB;KACxB,KAAK,qBAAqB;KAC1B,uBAAO,IAAI,MAAM,mBAAmB,KAAK,CAAC;IAC5C;IAEA,KAAK,KAAK,MAAM;GAClB,CAAC;EACH;EAGA,AAAU,eAAqB;GAC7B,KAAK,QAAQ,KAAK,KAAK,aAAa,GAAG,GAAG,KAAK,IAAI,OAAO,KAAK,IAAI,MAAM;GACzE,KAAK,aAAa;EACpB;EAGA,AAAU,cAAoB;GAC5B,KAAK,KAAK,cAAc,CAAC,KAAK,UAAU,KAAK,QAAQ,KAAK,KACxD,KAAK,aAAa;EAEtB;EAOA,AAAU,aACR,aACA,KAMA;GACA,MAAM,KAAK,IAAI;GACf,MAAM,KAAK,IAAI;GACf,KAAK,YAAY,IAAI,IAAI,WAAW;GACpC,IAAI,KACF,KAAK,KAAK,UACR,KACA,GACA,GACA,IACA,IACA,GACA,GACA,KAAK,IAAI,OACT,KAAK,IAAI,MACX;EACJ;EAQA,WAAW,OAAe,QAAgB,cAA+B,GAAG;GAC1E,KAAK,YAAY,OAAO,QAAQ,WAAW;EAC7C;EAMA,AAAU,YACR,OACA,QACA,cAA+B,GAC/B;GACA,IAAI,CAAC,KAAK,WAAW;IACnB,KAAK,KACH,mEACF;IACA;GACF;GAEA,IAAI,CAAC,KAAK,KACR,KAAK,MAAM,SAAS,cAAc,QAAQ;GAE5C,MAAM,MACJ,OAAO,gBAAgB,WACnB,CAAC,aAAa,WAAW,IACzB;GACN,KAAK,IAAI,QAAQ,QAAQ,IAAI;GAC7B,KAAK,IAAI,SAAS,SAAS,IAAI;GAE/B,KAAK,OAAO,KAAK,IAAI,WAAW,MAAM,EAAE,oBAAoB,KAAK,CAAC;GAGlE,WAAW,gBAAgB,KAAK,IAAI;GAGpC,IAAI,OAAO,gBAAgB,UAAU,KAAK,SAAS;GACnD,KAAK,aAAa;GAClB,KAAK,UAAU;EACjB;EAOA,OAAO,MAAqC;GAC1C,MAAM,IAAI,OAAO,KAAK,KAAK,KAAK,IAAI;GACpC,MAAM,IAAI,OAAO,KAAK,KAAK,KAAK,IAAI;GACpC,OAAO,kBAAkB,KAAK,KAAK,GAAG,GAAG,GAAG,CAAC;EAC/C;EAQA,QACE,YAAqC,UACrC,UAAmB,OACJ;GAGf,IAAI,MAAsC,KAAK,SAC3C,KAAK,OAAO,MACZ;GACJ,IAAI,CAAC,KAAK;IACR,IAAI,CAAC,KAAK,aACR,KAAK,cAAc,SAAS,cAAc,QAAQ,CAAC,CAAC,WAAW,IAAI;IAErE,MAAM,KAAK;GACb;GACA,OAAO,IAAI,cAAc,UAAU,KAAK,MAAM,KAAK,MAAM,SAAS;EACpE;EAMA,AAAM;;yCAAqB;IACzB,IAAIC,MAAK,WAAW,MAAM,IAAI,MAAM,uBAAuB;IAM3D,IAAI,SAA4BA,MAAK;IACrC,IAAIA,MAAK,WAAW,GAAG;KACrB,SAAS,SAAS,cAAc,QAAQ;KACxC,OAAO,QAAQA,MAAK,IAAI,QAAQA,MAAK;KACrC,OAAO,SAASA,MAAK,IAAI,SAASA,MAAK;KACvC,OACG,WAAW,IAAI,CAAC,CAChB,UACCA,MAAK,KACL,GACA,GACAA,MAAK,IAAI,OACTA,MAAK,IAAI,QACT,GACA,GACA,OAAO,OACP,OAAO,MACT;IACJ;IAEA,MAAM,OAAO,MAAM,IAAI,SAAe,SAAS,WAAW;KACxD,OAAO,QAAQ,MACb,IAAI,QAAQ,CAAC,IAAI,uBAAO,IAAI,MAAM,kCAAkC,CAAC,CACvE;IACF,CAAC;IAED,MAAM,MAAM,IAAI,gBAAgB,IAAI;IACpC,MAAK,aAAa;IAClB,IAAI;KACF,MAAMA,MAAK,cAAc,GAAG;KAC5B,IAAIA,MAAK,WAAW,MAAM,IAAI,MAAM,uBAAuB;KAC3D,MAAK,UAAU;IACjB,UAAU;KACR,IAAI,gBAAgB,GAAG;KACvB,MAAK,aAAa;IACpB;IACA,OAAOA;GACT;;EAQA,MAAM,GAAW,UAA4B,MAAU;GACrD,KAAK,YAAY;GACjB,IAAI,CAAC,KAAK,OAAO;IACf,KAAK,KACH,iEACF;IACA,OAAO,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC;GAC1B;GACA,MAAM,IAAI,OAAO,WAAW,WAAW,UAAU,UAAU,KAAK,SAAS;GACzE,OAAO,IAAI,SAAS,KAAK,OAAO,CAAC,EAAE,KAAK,GAAG,EAAE,KAAK,CAAC,CAAC;EACtD;EASA,SAAS,GAAW,MAAc,UAA4B,MAAY;GACxE,KAAK,YAAY;GACjB,IAAI,CAAC,KAAK,OAAO;IACf,KAAK,KAAK,+CAA+C;IACzD,OAAO;GACT;GACA,MAAM,IAAI,OAAO,WAAW,WAAW,UAAU,UAAU,KAAK,SAAS;GACzE,MAAM,IAAI,KAAK,MAAM,EAAE,KAAK,CAAC;GAC7B,MAAM,IAAI,KAAK,MAAM,EAAE,KAAK,CAAC;GAC7B,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK,MAAM,SAAS,KAAK,KAAK,MAAM,QAC7D,OAAO;GAET,MAAM,IAAI,IAAI,KAAK,MAAM,QAAQ,IAAI,IAAI;GACzC,KAAK,MAAM,KAAK,KAAK,KAAK;GAC1B,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK;GAC9B,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK;GAC9B,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,OAAO,SAAY,KAAK,KAAK;GAC3D,OAAO;EACT;EAMA,aAAmB;GACjB,IAAI,CAAC,KAAK,MAAM;IACd,KAAK,KAAK,2CAA2C;IACrD,OAAO;GACT;GACA,KAAK,aAAa;GAClB,OAAO;EACT;EAMA,eAAqB;GACnB,IAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,OAAO;IAC7B,KAAK,KAAK,2CAA2C;IACrD,OAAO;GACT;GACA,KAAK,KAAK,aAAa,KAAK,OAAO,GAAG,CAAC;GACvC,KAAK,aAAa;GAClB,OAAO;EACT;EAQA,OAAO,SAAS,SAAoB,GAAe;GAGjD,MAAM,MAAM,IAAI,GAAG,CAAC;GACpB,IACE,EAAE,KAAK,KACP,EAAE,KAAK,KACP,EAAE,MAAM,QAAQ,SAChB,EAAE,MAAM,QAAQ,QAEhB,OAAO;GAGT,MAAM,IAAI,KAAK,MAAM,EAAE,EAAE,KAAK,QAAQ,QAAQ,KAAK,KAAK,MAAM,EAAE,EAAE,IAAI;GACtE,MAAM,IAAI,QAAQ;GAClB,IAAI,IAAI,EAAE,SAAS,GAAG,OAAO;GAE7B,IAAI,KAAK,EAAE;GACX,IAAI,KAAK,EAAE,IAAI;GACf,IAAI,KAAK,EAAE,IAAI;GACf,IAAI,KAAK,EAAE,IAAI;GACf,OAAO;EACT;EAOA,OAAO,aAAqB,UAAmB,OAAa;GAC1D,MAAM,WAAW,KAAK,KAAK,eAAe;GAG1C,MAAM,OAAO,WAAW,KAAK,KAAK,eAAe,KAAK,IAAI;GAC1D,MAAM,OAAO,WAAW,KAAK,KAAK,gBAAgB,KAAK,IAAI;GAC3D,IAAI,CAAC,QAAQ,CAAC,MAAM;IAClB,KAAK,KAAK,oDAAoD;IAC9D,OAAO;GACT;GACA,MAAM,IAAI,UACN,cACA,CAAC,YAAY,KAAK,MAAM,YAAY,KAAK,IAAI;GAEjD,IAAI,SAA+C,KAAK;GACxD,IAAI,CAAC,UAAU;IACb,MAAM,OAAO,SAAS,cAAc,QAAQ;IAC5C,KAAK,QAAQ,KAAK,IAAI;IACtB,KAAK,SAAS,KAAK,IAAI;IACvB,KAAK,WAAW,IAAI,CAAC,CAAE,UAAU,KAAK,KAAK,GAAG,CAAC;IAC/C,SAAS;GACX;GACA,KAAK,aAAa,GAAG,MAAM;GAC3B,KAAK,aAAa;GAClB,OAAO;EACT;EAMA,KAAK,KAAuB;GAC1B,MAAM,IAAI,KAAK;GACf,OAAO,KAAK,KAAK,aACf,IAAI,EAAE,CAAC,KAAK,GACZ,IAAI,EAAE,CAAC,KAAK,GACZ,IAAI,QAAQ,GACZ,IAAI,SAAS,CACf;EACF;EAMA,OAAO,KAAmB;GAIxB,MAAM,KAAK,KAAK,KAAK;GACrB,KAAK,KAAK,2BAA2B;GACrC,KAAK,KAAK,SAAS;GACnB,KAAK,KAAK,UAAU,KAAK,KAAK,GAAG,CAAC;GAClC,KAAK,KAAK,SAAS;GACnB,KAAK,KAAK,2BAA2B;GACrC,KAAK,aAAa;GAClB,OAAO;EACT;EAKA,UAAgB;;GACd,KAAK,YAAY;GACjB,8BAAK,qHAAqB,IAAI,MAAM,uBAAuB,CAAC;GAC5D,KAAK,qBAAqB;GAC1B,IAAI,KAAK,MAAM;IACb,KAAK,KAAK,SAAS;IACnB,KAAK,KAAK,UAAU;IACpB,KAAK,KAAK,gBAAgB,KAAK;GACjC;GACA,IAAI,KAAK,YAAY;IACnB,IAAI,gBAAgB,KAAK,UAAU;IACnC,KAAK,aAAa;GACpB;GACA,IAAI,KAAK,KAAK,KAAK,IAAI,OAAO;GAC9B,IAAI,KAAK,MAAM,KAAK,KAAK,OAAO;GAChC,KAAK,MAAM;GACX,KAAK,OAAO;GACZ,KAAK,cAAc;GACnB,KAAK,OAAO;GACZ,KAAK,QAAQ;GACb,KAAK,UAAU;GACf,OAAO;EACT;EAMA,UAAU;GACR,KAAK,QAAQ;EACf;EAOA,OAAO,SACL,MACA,WAAiC,OACjC,OACc;GACd,MAAM,MAAM,IAAI,gBAAgB,IAAI;GACpC,MAAM,MAAM,IAAI,IAAI,UAAU,KAAK;GACnC,IAAI,aAAa;GAGjB,MAAM,aAAa;IACjB,IAAI,gBAAgB,GAAG;IACvB,IAAI,aAAa;GACnB;GACA,OAAO,IAAI,KAAK,GAAG,CAAC,CAAC,MAClB,QAAQ;IACP,KAAK;IACL,OAAO;GACT,IACC,QAAQ;IACP,KAAK;IACL,MAAM;GACR,CACF;EACF;EAMA,OAAO,gBAAgB,MAAgC;GACrD,OAAO,IAAI,QAAQ,SAAU,SAAS,QAAQ;IAC5C,IAAI,OAAO,aAAa,aAAa;KACnC,uBACE,IAAI,MAAM,wDAAwD,CACpE;KACA;IACF;IACA,IAAI,KAAK,SAAS,cAAc,QAAQ;IACxC,GAAG,QAAQ,KAAK;IAChB,GAAG,SAAS,KAAK;IACjB,GAAG,WAAW,IAAI,CAAC,CAAE,aAAa,MAAM,GAAG,CAAC;IAC5C,GAAG,QAAQ,SAAS;KAClB,QAAQ,IAAK;KACb,GAAG,OAAO;IACZ,CAAC;GACH,CAAC;EACH;EAKA,WAAmB;GACjB,OAAO,KAAK,IAAI,UAAU;EAC5B;EAKA,SAAwB;GACtB,OAAO,IAAI,SAAS,YAAY;IAC9B,KAAK,IAAI,QAAQ,SAAS,QAAQ,IAAK,CAAC;GAC1C,CAAC;EACH;EAKA,UAAkC;GAChC,IAAI,CAAC,KAAK,WACR,KAAK,KAAK,0DAA0D;GAEtE,OAAO,KAAK,OAAO,IAAI,WAAW,KAAK,IAAI,IAAI;EACjD;EAKA,IAAI,UAA6B;GAC/B,OAAO,KAAK,YAAY,KAAK,MAAM,KAAK;EAC1C;EAKA,IAAI,QAA0B;GAC5B,OAAO,KAAK;EACd;EAKA,IAAI,SAA4B;GAC9B,OAAO,KAAK;EACd;EAKA,IAAI,OAAkB;GACpB,KAAK,YAAY;GACjB,OAAO,KAAK;EACd;EAKA,IAAI,MAA0B;GAC5B,OAAO,KAAK;EACd;EAKA,IAAI,SAAkB;GACpB,OAAO,KAAK;EACd;EAKA,IAAI,aAAqB;GACvB,OAAO,KAAK;EACd;EAKA,IAAI,YAAgB;GAClB,IAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK,KAAK,QAC/C,OAAO,KAAK,MAAM,KAAK,WAAW,QAAQ,KAAK,MAAM,IAAI,IAAI,GAAG,GAAG,CAAC;QAEpE,OAAO,IAAI,GAAG,KAAK,KAAK,OAAO,KAAK,KAAK,MAAM;EAEnD;EAKA,IAAI,aAAiB;GACnB,OAAO,IAAI,GAAG,KAAK,IAAI,OAAO,KAAK,IAAI,MAAM;EAC/C;EAOA,IAAI,eAAoB;GACtB,MAAM,IAAI,IAAI,KAAK;GACnB,OAAO,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;EACjC;CACF;;;;;;;;CCxrBA,IAAa,cAAb,cAAiC,gBAAgB;EA4B/C,YACE,OAAgC,MAChC,UACA;GACA,MAAM;GA5BR,KAAU,cAAc;GACxB,KAAU,WAAW;GAGrB,KAAU,aAAa;GAKvB,KAAU,cAAc;GACxB,KAAU,iBAAiB;GAI3B,KAAQ,YAAY;GACpB,KAAQ,cAAc;GACtB,KAAQ,iBAAiB;GAcvB,IAAI,YAA4B;GAChC,IAAI,WAAW;GACf,KAAK,KAAK,KAAK,SAAS;GAGxB,IAAI,gBAAgB,SAAS;IAC3B,YAAY;IACZ,KAAK,KAAK,UAAU,MAAM,KAAK;GACjC,OAAO;IACL,MAAM,SAAS,QAAQ;IACvB,MAAM,KAAK,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM,SAAS,MAAM;IACnE,YAAY,SAAS,cAAc,EAAE;IACrC,KAAK,KAAK,GAAG,OAAO,CAAC;GACvB;GAGA,IAAI,CAAC,WAAW;IACd,KAAK,iBAAiB;IACtB,KAAK,aAAa,KAAK,eAAe,OAAO,KAAK,KAAK,YAAY;IACnE,KAAK,UAAU,KAAK,eAClB,UACA,KAAK,EACP;IACA,SAAS,KAAK,YAAY,KAAK,UAAU;GAG3C,OAAO,IAAI,UAAU,SAAS,YAAY,KAAK,UAAU;IACvD,KAAK,aAAa;IAClB,KAAK,UAAU,KAAK,eAClB,UACA,KAAK,KAAK,SACZ;IACA,KAAK,iBAAiB;GAGxB,OAAO;IACL,KAAK,UAAU;IACf,KAAK,aAAa,UAAU;IAC5B,KAAK,cAAc;IACnB,WAAW;GACb;GAGA,KAAK,OAAO,KAAK,QAAQ,WAAW,IAAI;GAGxC,IAAI,CAAC,UAAU;IACb,KAAK,cAAc;IACnB,KAAK,iBAAiB,IAAI,kBAAkB,cAAc;KACxD,UAAU,SAAS,aAAa;MAC9B,IAAI,SAAS,SAAS,eAAe,SAAS,WAAW,QACvD;YAAK,IAAI,QAAQ,SAAS,YACxB,IAAI,SAAS,KAAK,SAAS;;QACzB,KAAK,OAAO,QAAQ;QACpB,6BAAK,oFAAgB,WAAW;QAChC,KAAK,iBAAiB;QACtB;OACF;MACF;KAEJ,CAAC;IACH,CAAC;IAED,KAAK,eAAe,QAAQ,KAAK,YAAY,EAAE,WAAW,KAAK,CAAC;IAChE,KAAK,WAAW,YAAY,KAAK,OAAO;GAC1C,OAEE,KAAK,cAAc,OAAO,iBAAiB,KAAK,OAAO,QAAQ,GAAG,GAAG;EAEzE;EAOA,AAAU,eAAe,OAAO,OAAO,IAAY;GACjD,MAAM,IAAI,SAAS,cAAc,IAAI;GACrC,EAAE,aAAa,MAAM,EAAE;GACvB,OAAO;EACT;EAMA,AAAQ,OAAO,UAAsD;GACnE,IAAI,KAAK,WAAW;GAEpB,KAAK,cAAc;GACnB,IAAI,CAAC,KAAK,YACR,MAAM,IAAI,MAAM,oBAAoB,KAAK,GAAG,SAAS;GAEvD,KAAK,WAAW;GAEhB,KAAK,eAAe,IAAI;GAExB,KAAK,MAAM,KAAK,QAAQ;GACxB,KAAK,QAAQ,cAAc,IAAI,MAAM,OAAO,CAAC;GAE7C,KAAK,MAAM,KAAK,KAAK,SACnB,IAAI,KAAK,QAAQ,eAAe,CAAC,GAC/B;QAAI,KAAK,QAAQ,EAAE,CAAC,OAClB,KAAK,QAAQ,EAAE,CAAC,MAAM,KAAK,MAAM,MAAM,GAAG,IAAI;GAAC;GAIrD,KAAK,WAAW,KAAK;GACrB,KAAK,iBAAiB;GAEtB,IAAI,UAAU,SAAS,KAAK,OAAO,KAAK,OAAO;EACjD;EAOA,MAAM,KAA+B;GACnC,KAAK,WAAW,IAAI,UAAU,IAAI,UAAU;GAE5C,KAAK,aAAa,IAAI,UAAU,SAAY,IAAI,SAAS;GAEzD,IAAI,IAAI,WAAW,OAAO;IACxB,MAAM,KAAK,SAAS,OAAO,oBAAoB,IAAI;IACnD,KAAK,cAAc,KAAK,IAAI,GAAG,EAAE;GACnC;GAEA,IAAI,IAAI,WAAW;IACjB,KAAK,aAAa;IAClB,KAAK,aAAa,KAAK,eACrB,UACA,KAAK,KAAK,YACZ;IACA,KAAK,UAAU,KAAK,WAAW,WAAW,IAAI;GAChD,OACE,KAAK,aAAa;GAGpB,IAAI,IAAI,cACN,KAAK,cAAc,IAAI;GAGzB,OAAO;EACT;EAMA,IAAI,WAAW,MAAM;GACnB,IAAI,KAAK,gBAAgB,SAAS,CAAC,QAAQ,KAAK,kBAAkB;GAElE,IAAI,KAAK,iBAAiB;IACxB,KAAK,gBAAgB,WAAW;IAChC,KAAK,kBAAkB;GACzB;GAEA,KAAK,cAAc;GAEnB,IAAI,MAAM;IACR,KAAK,kBAAkB,IAAI,gBAAgB,YAAY;KACrD,KAAK,eAAe,IAAI;IAC1B,CAAC;IACD,KAAK,gBAAgB,QAAQ,KAAK,UAAU;GAC9C;EACF;EACA,IAAI,aAAsB;GACxB,OAAO,KAAK;EACd;EAQA,OAAO,GAAU,KAA0B;GACzC,KAAK,QAAQ;GAGb,KAAK,QAAQ,QAAQ,KAAK,KAAK,KAAK,MAAM,KAAK,CAAC,IAAI,KAAK;GACzD,KAAK,QAAQ,SAAS,KAAK,KAAK,KAAK,MAAM,KAAK,CAAC,IAAI,KAAK;GAQ1D,KAAK,QAAQ,MAAM,QAAQ,KAAK,MAAM,KAAK,IAAI;GAC/C,KAAK,QAAQ,MAAM,SAAS,KAAK,MAAM,KAAK,IAAI;GAEhD,IAAI,KAAK,YAAY;IACnB,KAAK,WAAW,QAAQ,KAAK,KAAK,KAAK,MAAM,KAAK,CAAC,IAAI,KAAK;IAC5D,KAAK,WAAW,SAAS,KAAK,KAAK,KAAK,MAAM,KAAK,CAAC,IAAI,KAAK;GAG/D;GAEA,IAAI,KAAK,eAAe,GAAG;IACzB,KAAK,KAAK,MAAM,KAAK,aAAa,KAAK,WAAW;IAElD,IAAI,KAAK,YACP,KAAK,QAAQ,MAAM,KAAK,aAAa,KAAK,WAAW;GAEzD;GAMA,WAAW,gBAAgB,KAAK,IAAI;GACpC,IAAI,KAAK,YAAY,WAAW,gBAAgB,KAAK,OAAO;GAE5D,KAAK,MAAM,KAAK,KAAK,SACnB,IAAI,KAAK,QAAQ,eAAe,CAAC,GAAG;IAClC,MAAM,IAAI,KAAK,QAAQ;IACvB,IAAI,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,GAAG;GACxC;GAGF,KAAK,OAAO,KAAK,IAAI;GAGrB,IAAI,OAAO,CAAC,KAAK,WAAW,KAAK,SAAS,CAAC;GAE3C,OAAO;EACT;EAMA,AAAU,eAAe,KAAmB;GAC1C,MAAM,IACJ,KAAK,eAAe,KAAK,iBACrB,KAAK,WAAW,sBAAsB,IACtC,KAAK,QAAQ,sBAAsB;GAEzC,IAAI,GAAG;;IACL,MAAM,MAAM,MAAM,iBAAiB,CAAC;IAGpC,IAAI,SAAS,IAAI,OAAO,gBAAI,0DAAQ,YAAW,gBAAG,4DAAQ,YAAW,CAAC;IACtE,KAAK,OAAO,KAAK,GAAG;GACtB;EACF;EAMA,IAAI,WAAW,IAAY;GACzB,KAAK,WAAW;EAClB;EACA,IAAI,aAAqB;GACvB,OAAO,KAAK;EACd;EAKA,IAAW,aAAqB;GAC9B,OAAO,KAAK;EACd;EAKA,IAAW,eAAwB;GACjC,OAAO,KAAK;EACd;EAKA,IAAW,eAAmC;GAC5C,OAAO,KAAK;EACd;EAKA,IAAW,kBAAqC;GAC9C,OAAO,KAAK;EACd;EAMA,AAAO,UAAsB;GAC3B,OAAO,IAAI,WAAW,IAAI;EAC5B;EAKA,IAAI,UAA6B;GAC/B,OAAO,KAAK;EACd;EAKA,IAAI,SAAkB;GACpB,OAAO,KAAK;EACd;EAKA,IAAI,QAAiB;GACnB,OAAO,KAAK;EACd;EAMA,IAAW,MAAgC;GACzC,OAAO,KAAK;EACd;EAMA,MAAM,IAAmB;GACvB,IAAI,IAAI,KAAK,WAAW;GACxB,MAAM,YAAY,KAAK,KAAK;GAC5B,MAAM,KAAK,KAAK,KAAK,KAAK,UAAU;GAEpC,IAAI,CAAC,KAAK,YAAY,KAAK,aAAa,eACtC,KAAK,KAAK,UACR,CAAC,IACD,CAAC,IACD,KAAK,QAAQ,QAAQ,IACrB,KAAK,QAAQ,SAAS,EACxB;QACK;IAEL,IACE,KAAK,SAAS,QAAQ,MAAM,MAAM,KACjC,KAAK,SAAS,WAAW,KAAK,KAAK,SAAS,QAAQ,GAAG,MAAM,GAE9D,KAAK,KAAK,UACR,CAAC,IACD,CAAC,IACD,KAAK,QAAQ,QAAQ,IACrB,KAAK,QAAQ,SAAS,EACxB;IAEF,KAAK,KAAK,YAAY,KAAK;IAC3B,KAAK,KAAK,SACR,CAAC,IACD,CAAC,IACD,KAAK,QAAQ,QAAQ,IACrB,KAAK,QAAQ,SAAS,EACxB;GACF;GAEA,KAAK,KAAK,YAAY;GACtB,OAAO;EACT;EAMA,eAAe,IAA0B;GACvC,IAAI,KAAK,YAAY;IACnB,MAAM,KAAK,KAAK,KAAK,KAAK,UAAU;IACpC,IAAI,IAAI;KACN,KAAK,QAAQ,YAAY;KACzB,KAAK,QAAQ,SACX,CAAC,IACD,CAAC,IACD,KAAK,QAAQ,QAAQ,IACrB,KAAK,QAAQ,SAAS,EACxB;IACF,OACE,KAAK,QAAQ,UACX,CAAC,IACD,CAAC,IACD,KAAK,WAAW,QAAQ,IACxB,KAAK,WAAW,SAAS,EAC3B;GAEJ;GACA,OAAO;EACT;EAMA,AAAU,UAAU,MAAc;GAChC,IAAI,KAAK,UAAU;IACjB,KAAK,KAAK,KAAK;IACf,IAAI,KAAK,YAAY,KAAK,QAAQ,KAAK;IACvC,MAAM,UAAU,IAAI;IACpB,KAAK,KAAK,QAAQ;IAClB,IAAI,KAAK,YAAY,KAAK,QAAQ,QAAQ;IAG1C,WAAW,gBAAgB,KAAK,IAAI;IACpC,IAAI,KAAK,YAAY,WAAW,gBAAgB,KAAK,OAAO;IAC5D,KAAK,OAAO,KAAK,IAAI;GACvB;EACF;EAKA,UAAgB;GACd,IAAI,KAAK,WAAW,OAAO;GAC3B,KAAK,YAAY;GAEjB,IAAI,KAAK,gBAAgB,QAAW;IAClC,OAAO,aAAa,KAAK,WAAW;IACpC,KAAK,cAAc;GACrB;GACA,IAAI,KAAK,gBAAgB;IACvB,KAAK,eAAe,WAAW;IAC/B,KAAK,iBAAiB;GACxB;GACA,IAAI,KAAK,iBAAiB;IACxB,KAAK,gBAAgB,WAAW;IAChC,KAAK,kBAAkB;GACzB;GAEA,KAAK,WAAW;GAChB,KAAK,iBAAiB;GACtB,KAAK,UAAU;GACf,KAAK,WAAW;GAChB,IAAI,KAAK,aAAa,KAAK,QAAQ,OAAO;GAC1C,IAAI,KAAK,kBAAkB,KAAK,WAAW,WAAW,WAAW,GAC/D,KAAK,WAAW,OAAO;GAEzB,OAAO;EACT;EASA,SACE,oBACA,WAAmB,QACnB,UAAkB,MACH;GACf,MAAM,SAAS,KAAK,QAAQ,cAAc;GAC1C,MAAM,WAAW,IAAI,cAAc,QAAQ;IACzC,UAAU,SAAS;IACnB,eAAe;GACjB,CAAC;GAED,SAAS,kBAAkB,SAAU,GAAG;IACtC,MAAM,MAAM,IAAI,gBACd,IAAI,KAAK,CAAC,EAAE,IAAI,GAAG,EAAE,MAAM,SAAS,WAAW,CAAC,CAClD;IAEA,IAAI,OAAO,uBAAuB,YAChC,mBAAmB,GAAG;SACjB,IAAI,oBAAoB;KAC7B,MAAM,IAAI,SAAS,cAAc,GAAG;KACpC,EAAE,OAAO;KACT,EAAE,WAAW,gBAAgB;KAC7B,EAAE,MAAM;KACR,EAAE,OAAO;KAGT,iBAAiB,IAAI,gBAAgB,GAAG,GAAG,GAAG;IAChD;GACF;GAEA,OAAO;EACT;CACF;CAUA,MAAM,iCAAiB,IAAI,QAAyC;CAEpE,IAAa,aAAb,MAAa,mBAEH,WAAW;EAYnB,AAAU,eAAwC;GAChD,IAAI,KAAK,mBAAmB,KAAK,MAAM;IACrC,IAAI,QAAQ,eAAe,IAAI,KAAK,IAAI;IACxC,IAAI,CAAC,OAAO;KACV,QAAQ,CAAC;KACT,eAAe,IAAI,KAAK,MAAM,KAAK;IACrC;IACA,KAAK,cAAc;IACnB,KAAK,iBAAiB,KAAK;GAC7B;GACA,OAAO,KAAK;EACd;EAUA,OAAO,gBAAgB,KAAwC;GAG7D,MAAM,QAAQ,eAAe,IAAI,GAAG;GACpC,IAAI,OACF,KAAK,MAAM,KAAK,OAAO,OAAO,MAAM;EAExC;EAOA,AAAU,KAAK,KAAa,OAAsB;GAChD,MAAM,QAAQ,KAAK,aAAa;GAChC,IAAI,MAAM,SAAS,OAAO;IACxB,MAAM,OAAO;IACb,AAAC,KAAK,KAAa,OAAO;GAC5B;EACF;EAqBA,YAAY,OAA0C;GACpD,MAAM;GAnER,KAAQ,cAA8C;GACtD,KAAQ,iBAA4C;GAiDpD,KAAU,SAA2B;IACnC,WAAW;IACX,aAAa;IACb,WAAW;IACX,UAAU;IACV,SAAS;IACT,aAAa;GACf;GAaE,IAAI,CAAC,OAAO,OAAO;GAEnB,MAAM,UAAU,QAA4B;IAC1C,KAAK,OAAO;IACZ,KAAK,KAAK,aAAa,KAAK,OAAO,SAAS;IAC5C,KAAK,KAAK,eAAe,KAAK,OAAO,WAAW;IAChD,KAAK,KAAK,YAAY,OAAO;IAC7B,KAAK,KAAK,QAAQ,KAAK,MAAM,KAAK;IAClC,KAAK,SAAS;GAChB;GAEA,IAAI,iBAAiB,aAAa;IAChC,KAAK,SAAS;IACd,IAAI,KAAK,OAAO,SAAS,KAAK,OAAO,KACnC,OAAO,KAAK,OAAO,GAAG;SAEtB,KAAK,OAAO,IAAI,EACd,aAAa;KACX,OAAO,KAAK,OAAO,GAAG;IACxB,EACF,CAAC;GAEL,OACE,OAAO,KAAK;EAEhB;EAKA,IAAI,QAAW;GAEb,OAAO,KAAK;EACd;EAMA,IAAI,MAA0B;GAC5B,OAAO,KAAK;EACd;EAOA,aAAa,MAAe,MAAM,QAA0B,OAAO;GACjE,IAAI,OACF,KAAK,OAAO,eAAe,OAAO,SAAS,WAAW,QAAQ,IAAI;GACpE,KAAK,OACH,KAAK,OAAO,gBAAgB,MACxB,KAAK,OAAO,eACZ,KAAK,OAAO;GAClB,OAAO;EACT;EAMA,gBAAgB,SAAiB,CAAC,GAAG,CAAC,GAAG;GACvC,IAAI,KAAK,OAAO,cACd,KAAK,OAAO,IAAI,UACd,KAAK,OAAO,iBACZ,OAAO,IACP,OAAO,IACP,KAAK,OAAO,OACZ,KAAK,OAAO,MACd;EAEJ;EAOA,MAAM,GAAiB;GACrB,KAAK,KAAK,eAAe,CAAC;GAC1B,KAAK,OAAO,cAAc;GAC1B,OAAO;EACT;EAOA,KAAK,GAA4D;GAC/D,IAAI,OAAO,KAAK,WACd,KAAK,SAAS;QACT;IACL,KAAK,SAAS;IACd,KAAK,OAAO,YAAY;IACxB,KAAK,KAAK,aAAa,CAAC;GAC1B;GACA,OAAO;EACT;EAMA,SAAS,GAA4D;GACnE,KAAK,OAAO,KAAK;GACjB,OAAO,KAAK,KAAK,CAAC;EACpB;EAUA,OACE,GACA,OACA,UACA,SACM;GACN,IAAI,OAAO,KAAK,WACd,KAAK,UAAU;QACV;IACL,KAAK,UAAU;IACf,KAAK,OAAO,cAAc;IAC1B,KAAK,KAAK,eAAe,CAAC;IAC1B,IAAI,OAAO;KACT,KAAK,KAAK,aAAa,KAAK;KAC5B,KAAK,OAAO,YAAY;IAC1B;IACA,IAAI,UAAU;KACZ,KAAK,KAAK,YAAY,QAAQ;KAC9B,KAAK,OAAO,WAAW;IACzB;IACA,IAAI,SAAS;KACX,KAAK,KAAK,WAAW,OAAO;KAC5B,KAAK,OAAO,UAAU;IACxB;GACF;GACA,OAAO;EACT;EASA,WACE,GACA,OACA,UACA,SACM;GACN,KAAK,KAAK,KAAK;GACf,OAAO,KAAK,OAAO,GAAG,OAAO,UAAU,OAAO;EAChD;EAUA,gBACE,SAA2B,MAC3B,UAA4B,MAC5B,cAAsB,GACtB;GACA,IAAI,QAAQ;IACV,IAAI,OAAO,WAAW,UAAU,KAAK,KAAK,MAAM;IAChD,KAAK,KAAK,KAAK;GACjB;GAEA,IAAI,SAAS;IACX,IAAI,OAAO,YAAY,UAAU,KAAK,OAAO,SAAS,WAAW;IACjE,KAAK,KAAK,OAAO;GACnB;GAEA,OAAO;EACT;EAQA,SACE,OACyD;GACzD,MAAM,OAA2B,CAAC;GAElC,IAAI,MAAM,SAAS,GACjB,QAAQ;IAAC,GAAG;IAAO,CAAC,KAAM,MAAM;IAAG,CAAC,GAAG,MAAM;GAAC;GAIhD,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,MAAM,IACJ,OAAO,MAAM,OAAO,WAChB,KAAK,KAAK,MAAM,SAAS,MACxB,MAAM,EAAE,CAAC;IAChB,MAAM,IACJ,OAAO,MAAM,OAAO,WACf,MAAM,KACN,MAAM,EAAE,CAAC;IAChB,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC;GAClB;GAEA,QAAQ,OAAkB,UAAsB;IAC9C,MAAM,OAAO,QACT,KAAK,KAAK,qBACR,MAAM,EAAE,CAAC,IACT,MAAM,EAAE,CAAC,IACT,KAAK,IAAI,MAAM,EAAE,CAAC,EAAE,GACpB,MAAM,EAAE,CAAC,IACT,MAAM,EAAE,CAAC,IACT,KAAK,IAAI,MAAM,EAAE,CAAC,EAAE,CACtB,IACA,KAAK,KAAK,qBACR,MAAM,EAAE,CAAC,IACT,MAAM,EAAE,CAAC,IACT,MAAM,EAAE,CAAC,IACT,MAAM,EAAE,CAAC,EACX;IAEJ,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,KAAK,aAAa,KAAK,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE;IAG1C,OAAO;GACT;EACF;EAMA,UAAU,OAAiC,eAAqB;GAC9D,KAAK,KAAK,4BAA4B,IAAI;GAC1C,OAAO;EACT;EAKA,OAAa;GACX,KAAK,KAAK,KAAK;GACf,OAAO;EACT;EAQA,KAAK,WAA6B,MAAM,SAAiB,GAAS;GAEhE,MAAM,QAAQ,KAAK,aAAa;GAChC,IAAI,aAAa,SAAU,aAAa,QAAQ,SAAS,WAAW,GAElE;QAAI,MAAM,SAAS,MAAM;KACvB,MAAM,OAAO;KACb,KAAK,KAAK,YAAY,CAAC,CAAC;KACxB,KAAK,KAAK,iBAAiB;IAC7B;UACK;IACL,MAAM,MAAc,aAAa,OAAO,CAAC,GAAG,CAAC,IAAI;IACjD,MAAM,MAAM,GAAG,MAAM,UAAU,KAAK,KAAK,KAAK,GAAG,EAAE,GAAG;IACtD,IAAI,MAAM,SAAS,KAAK;KACtB,MAAM,OAAO;KACb,KAAK,KAAK,YAAY,GAAe;KACrC,KAAK,KAAK,iBAAiB;IAC7B;GACF;GACA,OAAO;EACT;EAWA,KACE,YACA,QACA,OACA,YACA,QACM;GACN,IAAI,OAAO,cAAc,UAAU;IACjC,KAAK,MAAM,OAAO;IAClB,IAAI,QAAQ,KAAK,MAAM,OAAO;IAC9B,IAAI,QAAQ,KAAK,MAAM,SAAS;IAChC,IAAI,OAAO,KAAK,MAAM,QAAQ;IAC9B,IAAI,YAAY,KAAK,MAAM,aAAa;GAC1C,OACE,KAAK,QAAQ;GAGf,KAAK,KAAK,QAAQ,KAAK,MAAM,KAAK;GAGlC,IAAI,KAAK,eAAe,KAAK,kBAAkB,KAAK,aAAa;GAEjE,OAAO;EACT;EAMA,kBAAkB,WAAwC,MAAY;GACpE,IAAI,CAAC,UAAU;IACb,KAAK,gBAAgB;IACrB,KAAK,qBAAqB;GAC5B,OAAO;IACL,MAAM,WAAwB,MAC5B,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC;IAC3B,KAAK,gBAAgB,aAAa,OAAO,WAAW;IACpD,KAAK,qBACH,KAAK,kBAAkB,SACnBC,WAAK,eAAe,OAAO,IAC3BA,WAAK,mBAAmB,OAAO;GACvC;GACA,OAAO;EACT;EAMA,aAAa,GAAmB;GAC9B,OAAO,CAAC,KAAK,qBACT,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,QACzB,KAAK,mBAAmB,CAAC;EAC/B;EAQA,AAAU,cACR,KACA,OACA,OAAe,IACf,MACkB;GAClB,OAAOA,WAAK,SAAS,KAAK,aAAa,KAAK,IAAI,GAAG,KAAK,OAAO,MAAM,IAAI;EAC3E;EASA,AAAU,WACR,KACA,UACA,QACA,QACgB;GAChB,MAAM,OAAO,KAAK,YAAY,GAAG;GACjC,IAAI,CAAC,KAAK,WAAW,IAAI,GAAG;GAE5B,IAAI,CAAC,QAAQ,SAAS,UAAU,OAAO,IAAI;GAE3C,IAAI,KAAK,KAAK,EAAE,CAAC;GACjB,IAAI,KAAK,KAAK,aAAa,SAAS,KAAK,KAAK,aAAa,SACzD,KAAK,KAAK,EAAE,CAAC;QACR,IACL,KAAK,KAAK,aAAa,YAEvB,KAAK,KAAK,aAAa,UAEvB,KAAK,OAAO;GAGd,IAAI,KAAK,OAAO;GAChB,IAAI,YAAY,SAAS,YAAY,SACnC,KAAK,KAAK,EAAE,CAAC;QACR,IAAI,YAAY,SAAS,YAAY,UAC1C,KAAK,KAAK,EAAE,CAAC;GAGf,OAAO,SAAS,IAAI,GAAG,KAAK,OAAO,IAAI,KAAK,OAAO,EAAE,IAAI,IAAI,GAAG,IAAI,EAAE;EACxE;EAKA,QAAc;GAGZ,MAAM,QAAQ,KAAK,aAAa;GAChC,KAAK,MAAM,KAAK,KAAK,QACnB,IAAI,KAAK,OAAO,eAAe,CAAC,GAAG;IACjC,AAAC,KAAK,KAAa,KAAM,KAAK,OAAe;IAC7C,MAAM,KAAM,KAAK,OAAe;GAClC;GAGF,KAAK,QAAQ,IAAI,KAAK,IAAI,YAAY;GACtC,KAAK,KAAK,OAAO,KAAK,MAAM;GAC5B,MAAM,OAAO,KAAK,MAAM;GACxB,OAAO;EACT;EAEA,AAAU,SAAS;GACjB,IAAI,KAAK,SAAS,KAAK,KAAK,KAAK;GACjC,IAAI,KAAK,UAAU,KAAK,KAAK,OAAO;EACtC;EAUA,OAAO,MACL,KACA,GACA,SAAiB,GACjB,QAAgB,UAChB;GACA,IAAI,CAAC,GAAG;GACR,IAAI,CAAE,WAAmB,QACvB,MAAM,IAAI,MAAM,GAAG,MAAM,wCAAwC;GACnE,AAAC,WAAmB,MAAM,CAAC,KAAK,GAAG,MAAM;EAC3C;EASA,MAAM,GAAW,SAAiB,GAAG,QAAgB,UAAgB;GACnE,WAAW,MAAM,KAAK,MAAM,GAAG,QAAQ,KAAK;GAC5C,KAAK,OAAO;GACZ,OAAO;EACT;EAQA,OAAO,OAAO,KAAyB,IAAY,SAAiB,IAAI;GACtE,IAAI,CAAC,IAAI;GACT,IAAI,UAAU;GACd,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,QAAQ,GAAG,MAAM,QAAQ,KAAK;GACpD,IAAI,UAAU;EAChB;EAMA,OAAO,KAA2B;GAChC,MAAM,IAAI,KAAK,YAAY,GAAG;GAC9B,WAAW,OAAO,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE;GAC1C,KAAK,OAAO;GACZ,OAAO;EACT;EAYA,OAAO,QACL,KACA,IACA,QACA,WAAmB,GACnB,aAAqB,GACrB,WAAmB,MAAM,QACzB,KAAc,OACd;GACA,IAAI,CAAC,MAAM,CAAC,QAAQ;GACpB,IAAI,UAAU;GACd,IAAI,QACF,GAAG,IACH,GAAG,IACH,OAAO,IACP,OAAO,IACP,UACA,YACA,UACA,EACF;EACF;EAWA,QACE,IACA,QACA,WAAmB,GACnB,aAAqB,GACrB,WAAmB,MAAM,QACzB,KAAc,OACd;GACA,WAAW,QACT,KAAK,MACL,IACA,QACA,UACA,YACA,UACA,EACF;GACA,KAAK,OAAO;GACZ,OAAO;EACT;EAWA,OAAO,IACL,KACA,IACA,QACA,YACA,UACA,IACA;GACA,IAAI,CAAC,IAAI;GACT,IAAI,UAAU;GACd,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,QAAQ,YAAY,UAAU,EAAE;EACxD;EAUA,IACE,IACA,QACA,YACA,UACA,IACM;GACN,WAAW,IAAI,KAAK,MAAM,IAAI,QAAQ,YAAY,UAAU,EAAE;GAC9D,KAAK,OAAO;GACZ,OAAO;EACT;EAQA,OAAO,OAAO,KAAyB,IAAY,UAAkB;GACnE,IAAI,CAAC,IAAI;GACT,MAAM,KAAK,GAAG,KAAK;GACnB,MAAM,KAAK,GAAG,KAAK;GACnB,MAAM,KAAK,GAAG,KAAK;GACnB,MAAM,KAAK,GAAG,KAAK;GAGnB,IAAI,UAAU;GACd,IAAI,OAAO,IAAI,EAAE;GACjB,IAAI,OAAO,IAAI,EAAE;GACjB,IAAI,OAAO,IAAI,EAAE;GACjB,IAAI,OAAO,IAAI,EAAE;GACjB,IAAI,UAAU;EAChB;EAOA,OAAO,IAAY,UAAkB;GACnC,WAAW,OAAO,KAAK,MAAM,IAAI,QAAQ;GACzC,KAAK,OAAO;GACZ,OAAO;EACT;EAOA,OAAO,KAAK,KAAyB,KAAqB;GACxD,IAAI,CAAC,KAAK,WAAW,GAAG,GAAG;GAC3B,IAAI,UAAU;GACd,IAAI,IAAI;GACR,IAAI,MAAM,QAAQ,GAAG,GAEnB,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KAAK;IAC9C,MAAM,KAAK,IAAI;IACf,IAAI,IAAI;KACN,IAAI,MAAM,GACR,IAAI,OAAO,GAAG,IAAI,GAAG,EAAE;UAEvB,IAAI,OAAO,GAAG,IAAI,GAAG,EAAE;IAE3B;GACF;QAEA,KAAK,MAAM,MAAM,KACf,IAAI,IAAI;IACN,IAAI,MAAM,GACR,IAAI,OAAO,GAAG,IAAI,GAAG,EAAE;SAEvB,IAAI,OAAO,GAAG,IAAI,GAAG,EAAE;GAE3B;EAGN;EAMA,KAAK,KAA2B;GAC9B,WAAW,KAAK,KAAK,MAAM,GAAG;GAC9B,KAAK,OAAO;GACZ,OAAO;EACT;EAOA,OAAO,QAAQ,KAAyB,KAAqB;GAC3D,IAAI,CAAC,KAAK,WAAW,GAAG,GAAG;GAC3B,WAAW,KAAK,KAAK,GAAG;GACxB,IAAI,UAAU;EAChB;EAMA,QAAQ,KAA2B;GACjC,WAAW,QAAQ,KAAK,MAAM,GAAG;GACjC,KAAK,OAAO;GACZ,OAAO;EACT;EAOA,OAAO,KAAK,KAAyB,KAAqB;GACxD,MAAM,IAAI,KAAK,YAAY,GAAG;GAC9B,IAAI,CAAC,KAAK,WAAW,CAAC,GAAG;GACzB,IAAI,UAAU;GACd,IAAI,OAAO,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE;GAC3B,IAAI,OAAO,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE;GAC3B,IAAI,OAAO,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE;GAC3B,IAAI,OAAO,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE;GAC3B,IAAI,UAAU;EAChB;EAMA,KAAK,KAA2B;GAC9B,WAAW,KAAK,KAAK,MAAM,GAAG;GAC9B,KAAK,OAAO;GACZ,OAAO;EACT;EASA,OAAO,MACL,KACA,UACA,KACA,MACA;GACA,MAAM,IAAI,KAAK,YAAY,QAAQ;GACnC,IAAI;GAEJ,IAAI,OAAO,EAAE,OAAO,UAElB,MAAM;QAEN,IAAI,MAAM;IAER,MAAM,IAAI,KAAK,YAAY,IAAI;IAC/B,MAAM;KACJ,EAAE,EAAE,CAAC;KACL,EAAE,EAAE,CAAC;KACL,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;KACf,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;KACf,EAAE,EAAE,CAAC;KACL,EAAE,EAAE,CAAC;KACL,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;KACf,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;IACjB;GACF,OAEE,MAAM;IAAC,EAAE,EAAE,CAAC;IAAI,EAAE,EAAE,CAAC;IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;GAAE;GAIjE,IAAI,eAAe,KACjB;QAAI,IAAI,QAEN,IAAI,UAAU,IAAI,OAAO,GAAG,GAAG;GACjC,OAGA,IAAI,UAAU,KAAK,GAAG,GAAG;EAE7B;EAQA,MACE,UACA,KACA,MACA;GACA,IAAI,eAAe,KACjB;QAAI,IAAI,QACN,WAAW,MAAM,KAAK,MAAM,UAAU,IAAI,OAAO,IAAI;GACvD,OAEA,WAAW,MAAM,KAAK,MAAM,UAAU,KAAK,IAAI;GAEjD,OAAO;EACT;EAQA,OAAO,UACL,KACA,UACA,KACA;GACA,MAAM,IAAI,KAAK,YAAY,QAAQ;GACnC,IAAI,OAAO,EAAE,OAAO,UAElB,IAAI,aAAa,KAAK,EAAE,IAAI,EAAE,EAAE;QAIhC,IAAI,aACF,KACA,EAAE,EAAE,CAAC,IACL,EAAE,EAAE,CAAC,IACL,GACA,GACA,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IACf,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,EACjB;EAEJ;EAOA,UAAU,UAAmC,KAAgB;GAC3D,WAAW,UAAU,KAAK,MAAM,UAAU,GAAG;GAC7C,OAAO;EACT;EASA,OAAO,KACL,KACA,IACA,KACA,UACA;GACA,IAAI,CAAC,IAAI;GACT,IAAI,SAAS,KAAK,GAAG,IAAI,GAAG,IAAI,QAAQ;EAC1C;EAQA,KAAK,IAAY,KAAa,UAAyB;GACrD,WAAW,KAAK,KAAK,MAAM,IAAI,KAAK,QAAQ;GAC5C,OAAO;EACT;EAUA,QACE,KACA,KACA,gBAAmC,UACnC,OAAe,IACf,mBAA4B,MACtB;GAGN,IAAI,kBACF,KAAK,KAAK,eACR,kBAAkB,WACd,WACA,kBAAkB,UAChB,QACA,kBAAkB,QAChB,WACA;GAEZ,MAAM,OAAO,UAAU,KAAK,GAAG;GAC/B,MAAM,IAAI,KAAK,cAAc,KAAK,KAAK,IAAI,IAAI;GAC/C,KAAK,KAAK,KAAK,WAAW,KAAK,aAAa,GAAI,EAAE,EAAE;GACpD,OAAO;EACT;EAUA,aACE,KACA,KACA,aAAqB,KACrB,gBAAmC,OACnC,OAAgB,MACV;GACN,MAAM,IAAI,MAAM,UAAU,GAAG;GAC7B,MAAM,OAAO,UAAU,KAAK,CAAC;GAC7B,KAAK,KAAK,eAAe;GAEzB,MAAM,QAAQ,KAAK,MAAM,OAAO;GAMhC,IAAI,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,GAAG,KAAK,aAAa,GAAG,CAAC,CAAC;GAElE,MAAM,QAAkB,CAAC;GACzB,IAAI,MAAM;GACV,OAAO,KAAK;;IAEV,IAAI,SAAS,MAAM,SAAS,KAAK,QAAQ,KAAK,IAAI;IAElD,MAAM,IAAI,KAAK,cAAc,KAAK,KAAK,IAAI,IAAI,IAAI;IACnD,IAAI,EAAE,KAAK,GAAG,OAAO,EAAE;IAGvB,MAAM,QAAQ,EAAE,EAAE,CAAC,QAAQ,IAAI;IAC/B,IAAI,SAAS,GAAG;KACd,MAAM,KAAK,EAAE,EAAE,CAAC,MAAM,GAAG,KAAK,CAAC;KAC/B,MAAM,IAAI,MAAM,QAAQ,CAAC;KACzB;IACF;IAGA,MAAM,cAAc,EAAE,OAAO,IAAI;IACjC,IAAI;IACJ,IAAI,aACF,KAAK;SACA,IAAI,IAAI,EAAE,QAAQ,KAGvB,KAAK,EAAE,KAAK;SACP;KACL,KAAK,EAAE,EAAE,CAAC,YAAY,GAAG,IAAI;KAC7B,IAAI,MAAM,GAAG,KAAK;IACpB;IACA,MAAM,KAAK,OAAO,SAAY,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC;IAEtD,IAAI,EAAE,MAAM,KAAK,aAAa;IAC9B,MAAM,IAAI,aAAM,uCAAM,EAAE,EAAE;GAC5B;GACA,MAAM,QAAQ,MAAM,SAAS;GAC7B,IAAI,OAAO;GAEX,IAAI,iBAAiB,YAAY,iBAAiB,UAAU;IAC1D,IAAI,QAAQ,KAAK,KAAK,SAAS;IAC/B,IAAI,MAAM,OAAO,KAAK,IAAI,GAAG,IAAI;IACjC,OAAO,IAAI,MAAM,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,GAAG,EAAE,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC;GAC9D,OAAO,IAAI,iBAAiB,UAC1B,OAAO,IAAI,MAAM,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,KAAK,KAAK,GAAG,EAAE,EAAE;QAEpD,OAAO,IAAI,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,KAAK,CAAC;GAGlD,MAAM,SAAS,UAAU,OAAO,IAAI;GACpC,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAC3C,KAAK,KACH,KAAK,WAAW,MAAM,OAAO,CAAC,GAAG,IAAI,KAAK,GAAG,MAAM,GACnD,MAAM,EACR;GAGF,OAAO;EACT;EAOA,UACE,YAA6B,QAC7B,WAA+B,cAC/B;GAEA,IAAI,YAAY,UAAU,WAAW;GAErC,IAAI,YAAY,YAAY,WAAW;GACvC,KAAK,KAAK,YAAY;GACtB,KAAK,KAAK,eAAe;GACzB,OAAO;EACT;EAMA,IAAI,KAAgB;GAClB,MAAM,IAAI,KAAK,KAAK,YAAY,GAAG,CAAC,CAAC,QAAQ;GAC7C,KAAK,OAAO,KAAK,CAAC,CACf,KAAK,gBAAgB,CAAC,CACtB,KAAK,CACJ,CAAC,GAAG,CAAC,GACL,CAAC,GAAG,EAAE,CACR,CAAC;GACH,KAAK,KAAK,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,GAAG;GACpC,OAAO;EACT;CACF;;;;CCxkDA,MAAM,QAAuB;EAC3B,2BAAW,IAAI,YAAY,CAAC;EAC5B,2BAAW,IAAI,WAAW,CAAC;EAC3B,sBAAM,IAAI,YAAY,CAAC;CACzB;CAKA,MAAM,MAAM;CAIZ,MAAM,eAAgB,qBAAgB;CACtC,MAAM,iBAAkB,oBAAiB;CAKzC,MAAM,YAAY;CAClB,MAAM,yBAAS,IAAI,aAAa,CAAC;CAGjC,IAAI,eAAe;CAMnB,SAAS,cAAc,OAAuB;EAC5C,IAAI,eAAe,GAAG,OAAO;EAC7B,IAAI,QAAQ;EACZ,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,KAAK;GAC5B,IAAI,QAAQ;GACZ,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;IAC9B,MAAM,IAAI,OAAO,KAAK;IACtB,IAAI,KAAK,aAAa,KAAK,aAAY,OAAO;IAC9C,KAAK,IAAI,OAAO,GAAG,QAAQ;GAC7B;GACA,IAAI,OAAO,OAAO;GAClB,SAAS;EACX;EACA,OAAO;CACT;CAOA,SAAgB,SACd,IACA,IACA,IACA,IACA,IACA,IACQ;EACR,MAAM,QAAQ,KAAK,OAAO,KAAK;EAC/B,MAAM,SAAS,KAAK,OAAO,KAAK;EAChC,MAAM,MAAM,OAAO;EACnB,MAAM,QAAQ,gBAAgB,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK;EAC7D,IAAI,MAAM,OAAO,OAAO;EACxB,IAAI,CAAC,MAAM,OAAO,OAAO;EACzB,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,MAAM,QAAQ,cAAc,CAAC;EAC7B,IAAI,UAAU,GACZ,OAAO,YACJ,KAAK,MAAM,QACX,KAAK,MAAM,QACX,KAAK,MAAM,QACX,KAAK,MAAM,KACd;EAEF,OAAO,cAAc,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;CAC7C;CAOA,SAAgB,SACd,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACQ;EACR,MAAM,MAAM,KAAK;EACjB,MAAM,MAAM,KAAK;EACjB,MAAM,MAAM,KAAK;EACjB,MAAM,MAAM,KAAK;EACjB,MAAM,MAAM,KAAK;EACjB,MAAM,MAAM,KAAK;EAEjB,MAAM,SAAS,MAAM;EACrB,MAAM,SAAS,MAAM;EACrB,MAAM,QAAQ,MAAM,MAAM,MAAM;EAChC,MAAM,SAAS,MAAM;EACrB,MAAM,SAAS,MAAM;EACrB,MAAM,QAAQ,MAAM,MAAM,MAAM;EAChC,MAAM,SAAS,MAAM;EACrB,MAAM,SAAS,MAAM;EACrB,MAAM,QAAQ,MAAM,MAAM,MAAM;EAEhC,MAAM,MACJ,SAAS,SAAS,UAClB,SAAS,SAAS,UAClB,SAAS,SAAS;EACpB,MAAM,aACH,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,KAAK,SACvC,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,KAAK,SACvC,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,KAAK;EAC1C,MAAM,QAAQ,iBAAiB;EAC/B,IAAI,MAAM,OAAO,OAAO;EACxB,IAAI,CAAC,MAAM,OAAO,OAAO;EACzB,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,MAAM,QAAQ,cAAc,CAAC;EAC7B,IAAI,UAAU,GACZ,OAAO,aACL,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,OACN,MAAM,KACR;EAEF,OAAO,cAAc,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;CACrD;CAKA,MAAM,OAAO;CACb,MAAM,WAAW,IAAI;CACrB,MAAM,uBAAO,IAAI,aAAa,CAAC;CAC/B,MAAM,yBAAS,IAAI,aAAa,CAAC;CACjC,MAAM,yBAAS,IAAI,aAAa,CAAC;CACjC,MAAM,yBAAS,IAAI,aAAa,CAAC;CACjC,MAAM,0BAAU,IAAI,aAAa,CAAC;CAClC,MAAM,0BAAU,IAAI,aAAa,CAAC;CAClC,MAAM,0BAAU,IAAI,aAAa,CAAC;CAGlC,SAAS,UAAU,GAAW,GAAW,MAAc,IAAkB;EACvE,MAAM,KAAK,IAAI;EACf,MAAM,KAAK,MAAM;EACjB,MAAM,KAAK,IAAI;EACf,MAAM,KAAK,MAAM;EACjB,KAAK,OAAO,OAAO,KAAK;EACxB,KAAK,KAAK,MAAM,QAAQ,KAAK,KAAK,KAAK;EACvC,KAAK,KAAK,MAAM,OAAO,KAAK;CAC9B;CAGA,SAAS,UAAU,GAAiB,GAAiB,MAAoB;EACvE,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,MAAM,KAAK,OAAO,EAAE;GACpB,IAAI,OAAO,GAAG;GACd,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAK,IAAI,MAAM,KAAK,EAAE;EACpD;CACF;CAGA,SAAS,OAAO,GAAmB;EACjC,IAAI,QAAQ;EACZ,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,MAAM,IAAI,KAAK,KAAK;GACpB,QAAQ,KAAK,MAAM,IAAI,QAAQ;GAC/B,KAAK,KAAK,IAAI,QAAQ;EACxB;EACA,OAAO;CACT;CAGA,SAAS,SAAS,GAAW,OAAuB;EAClD,IAAI,UAAU,GAAG,OAAO,QAAQ,IAAI,IAAI;EACxC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,KAAK,OAAO,GAAG,OAAO;EACtD,OAAO;CACT;CAMA,SAAS,WAAW,GAAW,OAAe,KAA2B;EACvE,IAAI,SAAS,GAAG;GACd,IAAI,OAAO,UAAU;GACrB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,IAAI,KAAK,KAAK;IACd,IAAI,KAAK,OAAO,GAAG,OAAO;GAC5B;GACA,IAAI,KAAK;GACT,OAAO,OAAO,IAAI;EACpB;EACA,IAAI,KAAK;EACT,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,IAAI,IAAI,SAAW,KAAK,KAAK;GAC7B,KAAK;GACL,IAAI,MAAM,MAAM;IACd,IAAI;IACJ,KAAK;GACP;GACA,IAAI,KAAK;EACX;EACA,IAAI,KAAK,CAAC,QAAQ,IAAI;EACtB,OAAO;CACT;CAGA,SAAS,WAAW,GAAW,GAAW,GAAW,GAAmB;EACtE,KAAK,KAAK;EACV,KAAK,KAAK;EACV,KAAK,KAAK;EACV,UAAU,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,IAAI,MAAM,IAAI,IAAI,KAAK,GAAG,CAAC;EAC/D,UAAU,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC;EAC/D,OAAO,SAAS,GAAG,OAAO,CAAC,CAAC;CAC9B;CAGA,SAAS,MAAM,IAAY,IAAY,KAAyB;EAC9D,KAAK,KAAK;EACV,KAAK,KAAK;EACV,KAAK,KAAK;EACV,UAAU,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,GAAG,CAAC;EAC1C,UAAU,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,GAAG,CAAC;EAC1C,MAAM,QAAQ,OAAO,CAAC;EACtB,IAAI,KAAK,KAAK;EACd,IAAI,KAAK,KAAK;EACd,IAAI,KAAK,KAAK;EACd,IAAI,KAAK;CACX;CAGA,SAAS,OACP,GACA,GACA,GACA,GACA,KACQ;EACR,KAAK,KAAK;EACV,KAAK,KAAK;EACV,KAAK,KAAK;EACV,UAAU,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,IAAI,MAAM,IAAI,IAAI,KAAK,GAAG,CAAC;EAC/D,UAAU,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC;EAC/D,OAAO,WAAW,GAAG,OAAO,CAAC,GAAG,GAAG;CACrC;CAGA,SAAS,aACP,KACA,KACA,KACA,KACA,KACA,KACQ;EACR,MAAM,KAAK,KAAK,MAAM;EACtB,MAAM,KAAK,KAAK,MAAM;EACtB,MAAM,KAAK,KAAK,MAAM;EACtB,MAAM,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK,OAAO;EAC7C,MAAM,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK,OAAO;EAC7C,MAAM,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK,OAAO;EAC7C,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAK,KAAK;EACtC,IAAI,OAAO,GAAG,UAAU,QAAQ,SAAS,EAAE;EAC3C,IAAI,OAAO,GAAG,UAAU,QAAQ,SAAS,EAAE;EAC3C,IAAI,OAAO,GAAG,UAAU,QAAQ,SAAS,EAAE;EAC3C,OAAO,SAAS,GAAG,OAAO,CAAC,CAAC;CAC9B;CAKA,MAAM,wBAAQ,IAAI,aAAa,CAAC;CAChC,MAAM,SAAS,IAAI,YAAY,MAAM,MAAM;CAC3C,MAAM,KAAK;CACX,MAAM,KAAK,OAAO,OAAO,aAAa,IAAI;CAC1C,MAAM,KAAK,KAAK;CAChB,MAAM,wBAAQ,IAAI,aAAa,CAAC;CAChC,MAAM,wBAAQ,IAAI,WAAW,CAAC;CAI9B,SAAS,QAAQ,QAAsB,OAAyB;EAC9D,IAAI,UAAU;EACd,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;GAC9B,MAAM,KAAK,OAAO;GAClB,MAAM,KAAK,OAAO;GAClB,MAAM,SAAU,OAAO,KAAM;GAC7B,IAAI,KAAK,KAAK,WAAW,aAAa,OAAO;GAC7C,IAAI,IAAI;GACR,IAAI,WAAW,GAAG;IAChB,KAAK;IACL,IAAI,SAAS;GACf;GACA,MAAM,KAAK,OAAO,KAAK,CAAC,IAAI;GAC5B,MAAM,KAAK;GACX,IAAI,MAAM,KAAK,IAAI,SAAS,UAAU;EACxC;EACA,MAAM,MAAgB,CAAC;EACvB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KACzB,IAAI,KACF,MAAM,OAAO,IACT,OAAO,CAAC,IACR,OAAO,MAAM,EAAE,KAAK,OAAO,MAAM,KAAK,OAAO,CACnD;EAEF,OAAO;CACT;CAGA,SAAgB,cACd,IACA,IACA,IACA,IACA,IACA,IACQ;EACR,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,MAAM,IAAI,QAAQ,QAAQ,CAAC;EAC3B,MAAM,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;EACtE,MAAM,OAAO,OAAO,CAAC;EACrB,OAAO,MAAM,OAAO,IAAI,MAAM,OAAO,KAAK;CAC5C;CAGA,SAAgB,cACd,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACQ;EACR,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,MAAM,IAAI,QAAQ,QAAQ,CAAC;EAC3B,MAAM,MAAM,EAAE,KAAK,EAAE;EACrB,MAAM,MAAM,EAAE,KAAK,EAAE;EACrB,MAAM,MAAM,EAAE,KAAK,EAAE;EACrB,MAAM,MAAM,EAAE,KAAK,EAAE;EACrB,MAAM,MAAM,EAAE,KAAK,EAAE;EACrB,MAAM,MAAM,EAAE,KAAK,EAAE;EACrB,MAAM,OACH,MAAM,MAAM,MAAM,QAAQ,MAAM,MAAM,MAAM,QAC5C,MAAM,MAAM,MAAM,QAAQ,MAAM,MAAM,MAAM,QAC5C,MAAM,MAAM,MAAM,QAAQ,MAAM,MAAM,MAAM;EAC/C,MAAM,OAAO,OAAO,CAAC;EACrB,OAAO,MAAM,OAAO,IAAI,MAAM,OAAO,KAAK;CAC5C;CAKA,SAAgB,aAAa,OAAe,GAAW,GAAmB;EACxE,MAAM,IAAI,KAAK;EACf,IAAI,IAAI;EACR,KAAK,IAAI,IAAI,KAAK,GAAG,IAAI,GAAG,MAAM,GAAG;GACnC,MAAM,MAAM,IAAI,OAAO,IAAI,IAAI;GAC/B,MAAM,MAAM,IAAI,OAAO,IAAI,IAAI;GAC/B,KAAK,IAAI,KAAM,IAAI,KAAM;GACzB,IAAI,OAAO,GAAG;IACZ,IAAI,OAAO,GAAG;KACZ,IAAI,IAAI,IAAI;KACZ,IAAI,IAAI,IAAI;IACd;IACA,MAAM,IAAI;IACV,IAAI;IACJ,IAAI;GACN;EACF;EACA,OAAO;CACT;CAMA,SAAgB,aACd,QACA,GACa;EACb,IAAI,OAAO;EACX,IAAI,OAAO;EACX,IAAI,OAAO;EACX,IAAI,OAAO;EACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,MAAM,IAAI,OAAO,IAAI;GACrB,MAAM,IAAI,OAAO,IAAI,IAAI;GACzB,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,GAAG;GAChD,IAAI,IAAI,MAAM,OAAO;GACrB,IAAI,IAAI,MAAM,OAAO;GACrB,IAAI,IAAI,MAAM,OAAO;GACrB,IAAI,IAAI,MAAM,OAAO;EACvB;EAGA,IAAI,QAAQ;EACZ,OAAO,QAAQ,MAAM,KAAM,IAAI,QAAS,KAAK,GAAG;EAChD,MAAM,SAAS,KAAK,SAAS;EAC7B,MAAM,OAAO,KAAK,IAAI,OAAO,MAAM,OAAO,IAAI;EAC9C,MAAM,QAAQ,OAAO,KAAK,OAAO,SAAS,IAAI,IAAI,QAAQ,OAAO;EAEjE,MAAM,OAAO,IAAI,YAAY,CAAC;EAC9B,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,MAAM,IAAI,OAAO,IAAI;GACrB,MAAM,IAAI,OAAO,IAAI,IAAI;GACzB,IAAI,KAAK;GACT,IAAI,KAAK;GACT,IAAI,OAAO,SAAS,CAAC,KAAK,OAAO,SAAS,CAAC,GAAG;IAC5C,KAAK,KAAK,IAAI,OAAO,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,QAAQ,KAAK,CAAC,CAAC;IAChE,KAAK,KAAK,IAAI,OAAO,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,QAAQ,KAAK,CAAC,CAAC;GAClE;GACA,KAAK,KAAK,aAAa,OAAO,IAAI,EAAE;EACtC;EAIA,IAAI,OAAO,IAAI,YAAY,CAAC;EAC5B,IAAI,KAAK,IAAI,YAAY,CAAC;EAC1B,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAK,KAAK;EACtC,MAAM,yBAAS,IAAI,WAAW,GAAG;EACjC,KAAK,IAAI,QAAQ,GAAG,QAAQ,IAAI,OAAO,SAAS,GAAG;GACjD,OAAO,KAAK,CAAC;GACb,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,QAAS,KAAK,OAAO,QAAS,OAAO,EAAE;GACnE,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,OAAO,IAAI,MAAM,OAAO;GACtD,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,KAAK;IACf,GAAG,OAAQ,KAAK,OAAO,QAAS,IAAI,MAAM;GAC5C;GACA,MAAM,OAAO;GACb,OAAO;GACP,KAAK;EACP;EACA,OAAO;CACT;CAYA,SAAgB,YACd,QACA,IAAY,OAAO,UAAU,GACd;EACf,IAAI,IAAI,GAAG,OAAO;EAClB,eAAe,YAAY,QAAQ,CAAC;EACpC,IAAI;GACF,OAAO,aAAa,QAAQ,CAAC;EAC/B,UAAU;GACR,eAAe;EACjB;CACF;CAOA,SAAgB,YAAY,QAA2B,GAAmB;EACxE,IAAI,OAAO;EACX,IAAI,MAAM;EACV,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,GAAG,KAAK;GAC9B,MAAM,IAAI,OAAO;GACjB,IAAI,CAAC,OAAO,SAAS,CAAC,GAAG;GACzB,IAAI,MAAM,GAAG;GACb,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,MAAM,KAAK,IAAI,CAAC;GACvC,MAAM,KAAK;GACX,MAAM,KAAK,OAAO;GAClB,MAAM,KAAK,OAAO;GAClB,MAAM,SAAU,OAAO,KAAM;GAE7B,MAAM,IAAI,WAAW,IAAI,QAAQ,SAAS;GAC1C,IAAI;GACJ,IAAI,OAAO,GACT,WAAW,KAAK,KAAK,MAAM,KAAK,CAAC,EAAE;QAC9B;IACL,MAAM,IAAK,KAAK,WAAY,WAAW,IAAI,IAAI;IAC/C,WAAW,MAAM,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC;GACzC;GACA,MAAM,aAAa,EAAE,IAAI;GACzB,IAAI,aAAa,MAAM,OAAO;GAC9B,IAAI,OAAO,IAAI,OAAO;EACxB;EACA,MAAM,QAAQ,KAAK,IAAI,GAAG,IAAI;EAC9B,OAAO,MAAM,QAAQ,YAAY,QAAQ;CAC3C;CAEA,SAAS,aAAa,QAAsB,GAA0B;EACpE,MAAM,QAAQ,aAAa,QAAQ,CAAC;EAGpC,IAAI,KAAK;EACT,IAAI,KAAK;EACT,IAAI,KAAK;EACT,IAAI,IAAI;EACR,OAAO,IAAI,GAAG,KAAK;GACjB,MAAM,IAAI,MAAM;GAChB,IAAI,OAAO,SAAS,OAAO,IAAI,EAAE,KAAK,OAAO,SAAS,OAAO,IAAI,IAAI,EAAE,GAAG;IACxE,KAAK;IACL;IACA;GACF;EACF;EACA,IAAI,KAAK,GAAG,OAAO;EACnB,OAAO,IAAI,GAAG,KAAK;GACjB,MAAM,IAAI,MAAM;GAChB,MAAM,IAAI,OAAO,IAAI;GACrB,MAAM,IAAI,OAAO,IAAI,IAAI;GACzB,IACE,OAAO,SAAS,CAAC,KACjB,OAAO,SAAS,CAAC,MAChB,MAAM,OAAO,IAAI,OAAO,MAAM,OAAO,IAAI,KAAK,KAC/C;IACA,KAAK;IACL;IACA;GACF;EACF;EACA,IAAI,KAAK,GAAG,OAAO;EACnB,OAAO,IAAI,GAAG,KAAK;GACjB,MAAM,IAAI,MAAM;GAChB,MAAM,IAAI,OAAO,IAAI;GACrB,MAAM,IAAI,OAAO,IAAI,IAAI;GACzB,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,GAAG;GAChD,MAAM,IAAI,SACR,OAAO,IAAI,KACX,OAAO,IAAI,KAAK,IAChB,OAAO,IAAI,KACX,OAAO,IAAI,KAAK,IAChB,GACA,CACF;GACA,IAAI,MAAM,GAAG;IACX,KAAK;IACL,IAAI,IAAI,GAAG;KACT,MAAM,OAAO;KACb,KAAK;KACL,KAAK;IACP;IACA;GACF;EACF;EACA,IAAI,KAAK,GAAG,OAAO;EAKnB,MAAM,MAAM;EACZ,MAAM,WAAW,IAAI,IAAI;EACzB,MAAM,KAAK,IAAI,WAAW,WAAW,CAAC;EACtC,MAAM,MAAM,IAAI,WAAW,WAAW,CAAC;EACvC,MAAM,OAAO,IAAI,WAAW,QAAQ;EACpC,MAAM,OAAO,IAAI,WAAW,QAAQ;EACpC,MAAM,QAAQ,IAAI,WAAW,QAAQ;EACrC,IAAI,aAAa;EACjB,IAAI,WAAW;EACf,MAAM,QAAQ,IAAI,WAAW,QAAQ;EACrC,MAAM,SAAS,IAAI,WAAW,QAAQ;EACtC,MAAM,WAAW,IAAI,WAAW,WAAW,CAAC;EAC5C,MAAM,SAAS,IAAI,WAAW,WAAW,CAAC;EAC1C,MAAM,WAAW,IAAI,WAAW,WAAW,CAAC;EAC5C,MAAM,UAAU,IAAI,WAAW,IAAI,CAAC;EACpC,MAAM,YAAY,IAAI,WAAW,IAAI,CAAC;EACtC,IAAI,QAAQ;EAEZ,MAAM,SAAS,GAAW,GAAW,MAAsB;GACzD,MAAM,IAAI,aAAa,IAAI,MAAM,EAAE,cAAc;GACjD,MAAM,IAAI,IAAI;GACd,GAAG,KAAK;GACR,GAAG,IAAI,KAAK;GACZ,GAAG,IAAI,KAAK;GACZ,KAAK,KAAK;GACV,OAAO;EACT;EACA,MAAM,QAAQ,GAAW,MAAoB;GAC3C,IAAI,KAAK;GACT,IAAI,KAAK;EACX;EAGA,MAAM,KAAK,MAAM,IAAI,IAAI,EAAE;EAC3B,MAAM,KAAK,MAAM,IAAI,IAAI,GAAG;EAC5B,MAAM,KAAK,MAAM,IAAI,IAAI,GAAG;EAC5B,MAAM,KAAK,MAAM,IAAI,IAAI,GAAG;EAC5B,KAAK,IAAI,IAAI,IAAI,EAAE;EACnB,KAAK,IAAI,KAAK,GAAG,IAAI,EAAE;EACvB,KAAK,IAAI,KAAK,GAAG,IAAI,EAAE;EACvB,KAAK,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC;EAC3B,KAAK,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC;EAC3B,KAAK,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC;EAI3B,MAAM,eAAe,GAAW,IAAY,OAAwB;GAClE,MAAM,IAAI,GAAG,IAAI;GACjB,MAAM,IAAI,GAAG,IAAI,IAAI;GACrB,MAAM,KAAK,OAAO,IAAI;GACtB,MAAM,KAAK,OAAO,IAAI,IAAI;GAC1B,MAAM,KAAK,OAAO,IAAI;GACtB,MAAM,KAAK,OAAO,IAAI,IAAI;GAC1B,MAAM,IAAI,SAAS,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;GACzC,IAAI,MAAM,GAAG,OAAO,IAAI;GAExB,OAAO,KAAK,IAAI,KAAK,EAAE,KAAK,KAAK,IAAI,KAAK,EAAE,IACxC,KAAK,KACH,KAAK,MAAM,KAAK,KAChB,KAAK,MAAM,KAAK,KAClB,KAAK,KACH,KAAK,MAAM,KAAK,KAChB,KAAK,MAAM,KAAK;EACxB;EAIA,MAAM,UAAU,GAAW,IAAY,OAAwB;GAC7D,MAAM,IAAI,IAAI;GACd,IAAI,GAAG,IAAI,OAAO,KAAK,OAAO,YAAY,GAAG,IAAI,EAAE;GACnD,MAAM,IAAI,GAAG;GACb,MAAM,IAAI,GAAG,IAAI;GACjB,MAAM,IAAI,GAAG,IAAI;GACjB,OACE,SACE,OAAO,IAAI,IACX,OAAO,IAAI,IAAI,IACf,OAAO,IAAI,IACX,OAAO,IAAI,IAAI,IACf,OAAO,IAAI,IACX,OAAO,IAAI,IAAI,IACf,IACA,EACF,IAAI;EAER;EAQA,MAAM,UAAU,GAAW,IAAY,OAAuB;GAC5D,IAAI,QAAQ;GACZ,MAAM,QAAQ,IAAI,WAAW;GAC7B,OAAO,MAAM;IACX,MAAM,IAAI,IAAI;IACd,MAAM,IAAI,GAAG;IACb,MAAM,IAAI,GAAG,IAAI;IACjB,MAAM,IAAI,GAAG,IAAI;IACjB,MAAM,KAAK,OAAO,IAAI;IACtB,MAAM,KAAK,OAAO,IAAI,IAAI;IAC1B,MAAM,KAAK,OAAO,IAAI;IACtB,MAAM,KAAK,OAAO,IAAI,IAAI;IAC1B,IAAI,MAAM,KAAK;KACb,IAAI,SAAS,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,IAAI,GAAG,OAAO;KACjD,IAAK,IAAI,KAAK,IAAK;IACrB,OAAO;KACL,MAAM,KAAK,OAAO,IAAI;KACtB,MAAM,KAAK,OAAO,IAAI,IAAI;KAC1B,IAAI,SAAS,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,IAAI,GACrC,IAAK,IAAI,KAAK,IAAK;UACd,IAAI,SAAS,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,IAAI,GAC5C,IAAK,IAAI,IAAI,KAAK,IAAK;UAClB,IAAI,SAAS,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,IAAI,GAC5C,IAAK,IAAI,IAAI,KAAK,IAAK;UAClB,IACJ,OAAO,MAAM,OAAO,MACpB,OAAO,MAAM,OAAO,MACpB,OAAO,MAAM,OAAO,IAErB,OAAO;UAEP,OAAO;IAEX;IAEA,IAAI,EAAE,QAAQ,OAAO,MAAM,IAAI,MAAM,iCAAiC;GACxE;EACF;EAEA,MAAM,UAAU,GAAW,UAA0B;GACnD,MAAM,KAAK,OAAO,IAAI;GACtB,MAAM,KAAK,OAAO,IAAI,IAAI;GAC1B,MAAM,IAAI,OAAO,OAAO,IAAI,EAAE;GAC9B,IAAI,IAAI,GAAG,OAAO;GAGlB;GACA,IAAI,MAAM;GACV,IAAI,QAAQ;GACZ,MAAM,SAAS;GACf,KAAK,KAAK;GACV,OAAO,MAAM,GAAG;IACd,MAAM,IAAI,MAAM,EAAE;IAClB,OAAO,WAAW;IAClB,MAAM,IAAI,IAAI;IACd,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;KAC1B,MAAM,IAAK,IAAI,IAAI,KAAK,IAAK;KAC7B,IAAI,KAAK,OAAO,SAAS,OAAO,GAAG,IAAI,EAAE,GAAG;MAC1C,KAAK,KAAK;MACV,MAAM,SAAS;KACjB;IACF;GACF;GAIA,IAAI,QAAQ;GACZ,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;IAC9B,MAAM,IAAI,IAAI,OAAO;IACrB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;KAC1B,MAAM,OAAO,IAAI,IAAI;KACrB,IAAI,KAAM,OAAO,IAAK,OAAO,OAAO;MAClC,SAAS,SAAS,GAAG,IAAI;MACzB,OAAO,SAAS,GAAG,KAAM,IAAI,KAAK;MAClC,SAAS,SAAS;MAClB;KACF;IACF;GACF;GACA,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;IAC9B,KAAK,OAAO,MAAM;IAClB,MAAM,gBAAgB,OAAO;GAC/B;GAIA,IAAI,QAAQ;GACZ,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;IAC9B,MAAM,IAAI,SAAS;IACnB,MAAM,IAAI,OAAO;IACjB,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI,MAAM,KAAK;KACb,KAAK,MAAM,GAAG,GAAG,GAAG;KACpB,QAAQ,IAAI,KAAK;KACjB,OAAO,IAAI;KACX,SAAS,IAAI,KAAK;IACpB,OAAO,IAAI,MAAM,KAAK;KACpB,KAAK,MAAM,GAAG,GAAG,GAAG;KACpB,QAAQ,IAAI,KAAK;KACjB,OAAO,IAAI,KAAK;KAChB,SAAS,IAAI;IACf,OAAO;KACL,KAAK,MAAM,GAAG,GAAG,CAAC;KAClB,QAAQ,IAAI;KACZ,OAAO,IAAI,KAAK;KAChB,SAAS,IAAI,KAAK;KAClB,IAAI,QAAQ,GAAG,QAAQ;IACzB;IACA,KAAK,OAAO,SAAS,EAAE;IACvB,QAAQ,KAAK;IACb,UAAU,KAAK;GACjB;GACA,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;IAC9B,MAAM,IAAI,OAAO;IACjB,KAAK,QAAQ,IAAI,UAAU,EAAE;GAC/B;GACA,OAAO,QAAQ,IAAI,QAAQ;EAC7B;EAEA,IAAI,OAAO;EACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,MAAM,IAAI,MAAM;GAChB,IAAI,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI;GACtC,IAAI,CAAC,OAAO,SAAS,OAAO,IAAI,EAAE,KAAK,CAAC,OAAO,SAAS,OAAO,IAAI,IAAI,EAAE,GACvE;GACF,OAAO,OAAO,GAAG,IAAI;EACvB;EAGA,MAAM,QAAQ,IAAI,WAAW,QAAQ;EACrC,IAAI,IAAI;EACR,IAAI,QAAQ;EACZ,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,KAC5B,IAAI,CAAC,KAAK,IACR,MAAM,KAAK;OACN,IAAI,GAAG,IAAI,IAAI,OAAO,KAAK;GAChC,MAAM,KAAK;GACX,QAAQ;EACV,OACE,MAAM,KAAK;EAGf,MAAM,YAAY,IAAI,YAAY,IAAI,CAAC;EACvC,MAAM,YAAY,IAAI,WAAW,IAAI,CAAC;EACtC,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,KAAK;GACjC,MAAM,KAAK,MAAM;GACjB,IAAI,KAAK,GAAG;GACZ,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,UAAU,IAAI,KAAK,KAAK,GAAG,IAAI,IAAI;IACnC,MAAM,IAAI,IAAI,IAAI,IAAI;IACtB,MAAM,KAAK,MAAO,IAAI,IAAK;IAC3B,UAAU,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,IAAI,KAAM,IAAI;GACtD;EACF;EAEA,IAAI,YAAY;EAChB,IAAI,IAAI;EACR,GAAG;GACD;GACA,IAAK,IAAI,IAAI,IAAI,KAAK,IAAK;EAC7B,SAAS,MAAM;EACf,MAAM,OAAO,IAAI,YAAY,SAAS;EACtC,IAAI;EACJ,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAAK;GAClC,KAAK,KAAK,GAAG,IAAI,IAAI;GACrB,IAAK,IAAI,IAAI,IAAI,KAAK,IAAK;EAC7B;EACA,OAAO;GAAE;GAAW;GAAW;EAAK;CACtC;;;;;;;;;;;CC91BA,IAAa,SAAb,MAAoB;EAOlB,OAAO,iBACL,OACA,OACA,aAAqB,GACd;GACP,IAAI,MAAM,IAAI,MAAM;GACpB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;IAC9B,IAAI,IAAI,CAAC,MAAM,IAAK,IAAI,OAAO,IAAI,MAAM,KAAK;IAC9C,IAAI,aAAa,GAAG,EAAE,KAAK,MAAM,IAAK,IAAI,OAAO,IAAI,MAAM,MAAM;IACjE,IAAI,aAAa,GAAG,EAAE,KAAK,MAAM,IAAK,IAAI,OAAO,IAAI,MAAM,KAAK;IAChE,IAAI,KAAK,IAAI,GAAG,CAAC,CAAC;GACpB;GACA,OAAO;EACT;EAOA,OAAO,iBAAiB,MAAkB,OAAsB;GAC9D,IAAI,SAAS,GAAG,OAAO,IAAI,MAAM;GACjC,IAAI,QAAQ,KAAK,YAAY,IAAI;GACjC,IAAI,UAAU,GAAG,OAAO,IAAI,MAAM,MAAM,EAAE;GAC1C,IAAI,KAAK,KAAK,UAAU,OAAO,QAAQ,CAAC;GACxC,GAAG,QAAQ,MAAM,EAAE;GACnB,GAAG,KAAK,MAAM,MAAM,SAAS,EAAE;GAC/B,OAAO;EACT;EAUA,OAAO,QACL,OACA,SACA,MACA,cAAsB,CAAC,IAAK,EAAG,GACxB;GACP,IAAI,YAAY,KAAK,SAAS,GAC5B,MAAM,IAAI,MAAM,mCAAmC;GACrD,IAAI,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,SAAS,IAAI;GACxD,IAAI,SAAS,KAAK,UAAU,WAAW;GACvC,IAAI,IAAI,IAAI,MAAM;GAClB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KACxB,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,KAC3B,EAAE,KAAK,MAAM,QAAQ,KAAK,KAAK,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;GAG/D,OAAO;EACT;EASA,OAAO,UAAU,OAAc,SAAiB,MAAuB;GACrE,IAAI,YAAY,KAAK,SAAS,GAC5B,MAAM,IAAI,MAAM,mCAAmC;GACrD,IAAI,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,SAAS,IAAI;GACvD,IAAI,IAAI,CAAC;GACT,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KACxB,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,KAC3B,EAAE,KACA,IAAI,MACF,MAAM,QAAQ,KAAK,KAAK,UAAU,GAAG,CAAC,CAAC,GACvC,MAAM,QAAQ,KAAK,KAAK,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CACnD,CACF;GAGJ,OAAO;EACT;EASA,OAAO,UACL,QACA,QACA,OACA,cAAsB,CAAC,MAAM,SACtB;GACP,IAAI,IAAI,IAAI,MAAM;GAClB,IAAI,IAAI,MAAM,SAAS;GACvB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KACzB,EAAE,KAAK,IAAI,GAAG,MAAM,CAAC,CAAC,QAAQ,IAAI,IAAI,aAAa,QAAQ,IAAI,CAAC;GAElE,OAAO;EACT;EAUA,OAAO,SACL,KACA,KAAK,KACL,KAAK,KACL,OAAO,GACP,UAAU,GACH;GACP,IAAI,OAAO,IAAI,OAAO;GACtB,IAAI,IAAI,IAAI,MAAM;GAClB,IAAI,IAAI;GAER,MAAM,SAAS,UAAU,IAAI,UAAU,OAAO,IAAI,OAAO;GACzD,KAAK,IAAI,KAAK,KAAK;IACjB,IAAI,KAAK,IAAI,MAAM,CAAC;IACpB,IAAI,IAAI,SAAS,IAAI,KAAK,MAAM,IAAI,MAAM,IAAI;IAC9C,IAAI,IAAI,SAAS,IAAI,IAAI,SAAS;IAClC,GAAG,UAAU,KAAK,GAAG,KAAK,CAAC;IAC3B,GAAG,KAAK,IAAI;IACZ,EAAE,KAAK,EAAE;IACT;GACF;GACA,OAAO;EACT;EAOA,OAAO,SAAS,KAA0B;GACxC,OAAO,SAAS,KAAK,GAAG;EAC1B;EAgBA,OAAO,MAAM,KAAqB,UAAwB,CAAC,GAAU;GACnE,MAAM,QAAQ,IAAI,MAAM;GACxB,MAAM,MAAM,OAAO;GACnB,KAAK,MAAM,KAAK,KAAK,MAAM,QAAQ,CAAC;GACpC,OAAO;EACT;CACF;CAKA,MAAM,gBAAgB;EACpB;GAAC;GAAG;GAAG;EAAC;EACR;GAAC;GAAI;GAAG;EAAC;EACT;GAAC;GAAG;GAAI;EAAC;EACT;GAAC;GAAI;GAAI;EAAC;EACV;GAAC;GAAG;GAAG;EAAC;EACR;GAAC;GAAI;GAAG;EAAC;EACT;GAAC;GAAG;GAAG;EAAE;EACT;GAAC;GAAI;GAAG;EAAE;EACV;GAAC;GAAG;GAAG;EAAC;EACR;GAAC;GAAG;GAAI;EAAC;EACT;GAAC;GAAG;GAAG;EAAE;EACT;GAAC;GAAG;GAAI;EAAE;CACZ;CAKA,MAAM,oBAAoB;EACxB;EAAK;EAAK;EAAK;EAAI;EAAI;EAAI;EAAK;EAAI;EAAK;EAAI;EAAI;EAAI;EAAK;EAAK;EAAG;EAAK;EACvE;EAAI;EAAK;EAAI;EAAI;EAAK;EAAG;EAAI;EAAI;EAAK;EAAI;EAAI;EAAI;EAAK;EAAG;EAAK;EAAK;EAAK;EACzE;EAAI;EAAG;EAAI;EAAK;EAAI;EAAI;EAAK;EAAK;EAAK;EAAK;EAAI;EAAI;EAAI;EAAI;EAAK;EAAI;EAAI;EACzE;EAAK;EAAI;EAAI;EAAK;EAAI;EAAK;EAAK;EAAK;EAAK;EAAI;EAAK;EAAI;EAAK;EAAI;EAAK;EAAK;EAC1E;EAAI;EAAK;EAAI;EAAK;EAAK;EAAK;EAAI;EAAK;EAAK;EAAK;EAAI;EAAK;EAAK;EAAK;EAAK;EACvE;EAAI;EAAI;EAAI;EAAI;EAAK;EAAI;EAAK;EAAK;EAAK;EAAI;EAAI;EAAI;EAAI;EAAK;EAAG;EAAK;EAAI;EACzE;EAAK;EAAI;EAAK;EAAK;EAAK;EAAI;EAAI;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EACxE;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAG;EAAI;EAAI;EAAK;EAAK;EAAK;EAAK;EAAK;EAAG;EAAK;EAC1E;EAAK;EAAK;EAAK;EAAK;EAAI;EAAI;EAAK;EAAK;EAAK;EAAI;EAAK;EAAI;EAAI;EAAI;EAAI;EAAK;EACzE;EAAI;EAAI;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAG;EAAI;EAAK;EAAK;EAAI;EAAK;EAAK;EAC1E;EAAK;EAAK;EAAI;EAAK;EAAG;EAAK;EAAI;EAAI;EAAK;EAAG;EAAI;EAAK;EAAK;EAAI;EAAK;EAAK;EACvE;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAI;EAAK;EAAK;EAAI;EAAK;EAAK;EAAK;EAAK;EAAK;EACzE;EAAK;EAAK;EAAK;EAAK;EAAI;EAAI;EAAK;EAAK;EAAK;EAAI;EAAK;EAAK;EAAI;EAAK;EAAK;EACvE;EAAK;EAAK;EAAK;EAAK;EAAK;EAAI;EAAK;EAAK;EAAK;EAAK;EAAI;EAAI;EAAK;EAAG;EAAK;EACtE;EAAK;EAAK;EAAK;EAAI;EAAK;EAAK;EAAI;EAAI;EAAI;EAAI;EAAK;EAAK;EAAK;EAAK;EAAI;EAAI;EACzE;EAAI;EAAK;CACX;CAKA,MAAM,sBAAsB,kBAAkB,OAAO,iBAAiB;CAItE,IAAI,mBAAuC;CAC3C,IAAI,mBAAoC;CAExC,SAAS,mBAAmB,MAAwB;EAClD,IAAI,SAAS,oBAAoB,kBAAkB,OAAO;EAE1D,IAAI,IAAI;EACR,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK;EACzB,IAAI,KAAK,MAAM,CAAC;EAChB,IAAI,IAAI,KAAK,KAAK,KAAK;EAEvB,MAAM,OAAO,IAAI,MAAc,GAAG;EAClC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK;GAC5B,MAAM,IACJ,IAAI,IACA,kBAAkB,KAAM,IAAI,MAC5B,kBAAkB,KAAO,KAAK,IAAK;GACzC,KAAK,KAAK,KAAK,IAAI,OAAO;EAC5B;EAEA,mBAAmB;EACnB,mBAAmB;EACnB,OAAO;CACT;CAMA,IAAa,QAAb,cAA2B,GAAG;EAQ5B,YAAY,GAAG,MAAa;GAC1B,MAAM,GAAG,IAAI;GARf,KAAU,OAAiB,CAAC;GAC5B,KAAQ,KAAS,IAAI,GAAG,KAAM,GAAI;GAUhC,KAAK,OAAO;EACd;EAOA,UAAU,GAAG,MAAa;GACxB,KAAK,KAAK,IAAI,GAAG,GAAG,IAAI;GACxB,OAAO;EACT;EAOA,KAAK,IAAI,GAAG,IAAI,GAAG;GACjB,KAAK,GAAG,IAAI,GAAG,CAAC;GAChB,OAAO;EACT;EAMA,KAAK,GAAW;GACd,KAAK,OAAO,mBAAmB,CAAC;GAChC,OAAO;EACT;EAKA,UAAU;GACR,MAAM,OAAO,KAAK;GAClB,MAAM,KAAK,KAAK,GAAG;GACnB,MAAM,KAAK,KAAK,GAAG;GAInB,MAAM,KAAK,KAAK,MAAM,EAAE;GACxB,MAAM,KAAK,KAAK,MAAM,EAAE;GACxB,MAAM,IAAI,KAAK;GACf,MAAM,IAAI,KAAK;GACf,MAAM,IAAI,KAAK;GACf,MAAM,IAAI,KAAK;GAIf,MAAM,MAAM,cAAc,KAAK,IAAI,KAAK,MAAM;GAC9C,MAAM,MAAM,cAAc,KAAK,IAAI,KAAK,IAAI,MAAM;GAClD,MAAM,MAAM,cAAc,KAAK,IAAI,IAAI,KAAK,MAAM;GAClD,MAAM,MAAM,cAAc,KAAK,IAAI,IAAI,KAAK,IAAI,MAAM;GAEtD,MAAM,MAAM,IAAI,KAAK,IAAI,IAAI,KAAK;GAClC,MAAM,MAAM,IAAI,KAAK,IAAI,IAAI,MAAM,IAAI;GACvC,MAAM,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK;GACxC,MAAM,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI;GAE7C,MAAM,SAAS,MAAc,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM;GAC7D,MAAM,KAAK,MAAM,CAAC;GAClB,MAAM,IAAI,MAAM,MAAM,MAAM;GAC5B,MAAM,IAAI,MAAM,MAAM,MAAM;GAC5B,OAAO,IAAI,MAAM,CAAC,KAAK,IAAI;EAC7B;CACF;CAOA,SAAS,gBACP,MACA,IACA,IACA,IACA,IACO;EAEP,IAAI,SAAS;EACb,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK;GAC/C,MAAM,KAAK,KAAK,EAAE,CAAC;GACnB,MAAM,KAAK,KAAK,EAAE,CAAC;GACnB,IAAI,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,CAAC,OAAO,SAAS,KAAK,EAAE,GAAG;IACzE,SAAS;IACT;GACF;EACF;EACA,IAAI,QAAQ,OAAO;EAInB,IAAI,KAAK,SAAS,GAAG;GACnB,MAAM,OAAO,IAAI,MAAM;GACvB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK;IAC/C,MAAM,KAAK,KAAK,EAAE,CAAC;IACnB,MAAM,KAAK,KAAK,EAAE,CAAC;IACnB,IAAI,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI,KAAK,KAAK,KAAK,EAAE;GACrE;GACA,OAAO;EACT;EAGA,MAAM,MAAM;EACZ,IAAI,MAAkB,CAAC;EACvB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK;GAC/C,IAAI,KAAK,KAAK,EAAE,CAAC;GACjB,IAAI,KAAK,KAAK,EAAE,CAAC;GACjB,IAAI,CAAC,OAAO,SAAS,EAAE,GAAG,KAAK,KAAK,IAAI,MAAM;GAC9C,IAAI,CAAC,OAAO,SAAS,EAAE,GAAG,KAAK,KAAK,IAAI,MAAM;GAC9C,IAAI,OAAO,MAAM,EAAE,KAAK,OAAO,MAAM,EAAE,GAAG;GAC1C,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;EACnB;EAGA,MAAM,QACJ,OACA,MACA,UACe;GACf,MAAM,SAAqB,CAAC;GAC5B,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,IAAI,IAAI;IACxC,MAAM,IAAI,MAAM;IAChB,MAAM,QAAQ,KAAK,CAAC;IACpB,IAAI,KAAK,CAAC,GAAG;KACX,IAAI,OAAO,OAAO,KAAK,CAAC;UACnB,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC;IAC9B,OAAO,IAAI,OACT,OAAO,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC;GAE9B;GACA,OAAO;EACT;EAEA,MAAM,UAAU,GAAa,GAAa,MAAwB,CAChE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GACvB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CACzB;EAEA,MAAM,KACJ,MACC,MAAM,EAAE,MAAM,KACd,GAAG,MAAM,OAAO,GAAG,IAAI,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CACpD;EACA,MAAM,KACJ,MACC,MAAM,EAAE,MAAM,KACd,GAAG,MAAM,OAAO,GAAG,IAAI,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CACpD;EACA,MAAM,KACJ,MACC,MAAM,EAAE,MAAM,KACd,GAAG,MAAM,OAAO,GAAG,IAAI,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CACpD;EACA,MAAM,KACJ,MACC,MAAM,EAAE,MAAM,KACd,GAAG,MAAM,OAAO,GAAG,IAAI,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CACpD;EAEA,MAAM,MAAM,IAAI,MAAM;EACtB,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK,KACzC,IAAI,KAAK,IAAI,GAAG,IAAI,EAAE,CAAC;EAEzB,OAAO;CACT;CAGA,SAAS,oBAAoB,MAAa,GAAO,GAAc;EAC7D,MAAM,KAAK,EAAE,KAAK,EAAE;EACpB,MAAM,KAAK,EAAE,KAAK,EAAE;EACpB,MAAM,KAAK,EAAE,KAAK,KAAK;EACvB,MAAM,KAAK,EAAE,KAAK,KAAK;EACvB,MAAM,MAAM,IAAI,MAAM;EACtB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,IAAI,KAAK,MAAM,IAAI,KAAK,SAAS,IAAI,IAAI;GAC/C,MAAM,IAAI,KAAK;GACf,MAAM,MAAM,EAAE,KAAK,MAAM,MAAM,EAAE,KAAK,MAAM;GAC5C,MAAM,MAAM,EAAE,KAAK,MAAM,MAAM,EAAE,KAAK,MAAM;GAC5C,IAAI,MAAM,MAAM,MAAM,GAAG;IACvB,MAAM,IAAI,MAAM,KAAK;IACrB,IAAI,KAAK,IAAI,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;GACrE;GACA,IAAI,MAAM,GAAG,IAAI,KAAK,CAAC;EACzB;EACA,OAAO;CACT;CAGA,SAAS,cACP,IACA,IACA,IACA,IACA,IACA,IAC0B;EAC1B,MAAM,MAAM,KAAK;EACjB,MAAM,MAAM,KAAK;EACjB,MAAM,MAAM,KAAK;EACjB,MAAM,MAAM,KAAK;EACjB,MAAM,IAAI,KAAK,MAAM,MAAM,MAAM;EACjC,MAAM,KAAK,MAAM,MAAM,MAAM;EAC7B,MAAM,KAAK,MAAM,MAAM,MAAM;EAC7B,MAAM,MAAM,MAAM,KAAK,MAAM,MAAM;EACnC,MAAM,MAAM,MAAM,KAAK,MAAM,MAAM;EACnC,OAAO;GAAC,KAAK;GAAI,KAAK;GAAI,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;EAAC;CACxD;CAQA,IAAa,WAAb,cAA8B,MAAM;;;GAClC,KAAQ,QAAsB,CAAC;GAC/B,KAAQ,aAAa;GACrB,KAAQ,SAAS;GACjB,KAAQ,OAA6B;GACrC,KAAQ,UAAkC;;EAO1C,SAAS,eAAwB,MAAqC;GACpE,MAAM,IAAI,KAAK;GACf,KAAK,SAAS;GACd,KAAK,QAAQ,CAAC;GACd,KAAK,aAAa;GAClB,KAAK,OAAO;GACZ,KAAK,UAAU;GACf,IAAI,IAAI,GAAG,OAAO,CAAC;GAEnB,MAAM,SAAS,IAAI,aAAa,IAAI,CAAC;GACrC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,OAAO,IAAI,KAAK,KAAK,EAAE,CAAC;IACxB,OAAO,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;GAC9B;GAEA,MAAM,MAAM,YAAY,QAAQ,CAAC;GACjC,IAAI,IAAI,UAAU,WAAW,GAAG,OAAO,CAAC;GACxC,KAAK,OAAO;GACZ,MAAM,UAAU,IAAI;GAEpB,MAAM,SAA0B,CAAC;GACjC,MAAM,OAAoB,CAAC;GAC3B,KAAK,IAAI,IAAI,GAAG,MAAM,QAAQ,QAAQ,IAAI,KAAK,KAAK,GAAG;IACrD,MAAM,IAAI,QAAQ;IAClB,MAAM,IAAI,QAAQ,IAAI;IACtB,MAAM,IAAI,QAAQ,IAAI;IACtB,MAAM,WAAW,KAAK,UAAU,GAAG,GAAG,CAAC;IAEvC,MAAM,CAAC,KAAK,KAAK,KAAK,cACpB,OAAO,IAAI,IACX,OAAO,IAAI,IAAI,IACf,OAAO,IAAI,IACX,OAAO,IAAI,IAAI,IACf,OAAO,IAAI,IACX,OAAO,IAAI,IAAI,EACjB;IACA,MAAM,SAAS,IAAI,MAAM,IAAI,GAAG,KAAK,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;IAEvD,OAAO,KAAK;KAAE;KAAG;KAAG;KAAG;KAAU;IAAO,CAAC;IACzC,KAAK,KAAK,QAAQ;GACpB;GACA,KAAK,UAAU;GAEf,OAAO,eAAe,OAAO;EAC/B;EAMA,AAAQ,cAA4B;GAClC,IAAI,CAAC,KAAK,YAAY;IACpB,KAAK,aAAa;IAClB,KAAK,QAAQ,CAAC;IACd,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,KAAK,MAAM,KAAK,CAAC;IACvD,IAAI,KAAK,SACP,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,QAAQ,IAAI,KAAK,KAClD,KAAK,OAAO,KAAK,QAAQ,EAAE;GAGjC;GACA,OAAO,KAAK;EACd;EASA,QAAQ,OAA6B;GACnC,MAAM,QAAQ,KAAK,cAAc;GACjC,IAAI,CAAC,OAAO,OAAO;GAEnB,MAAM,SAAS,KAAK,YAAY,KAAK,YAAY,KAAK,CAAU;GAChE,MAAM,KAAK,OAAO,EAAE,CAAC;GACrB,MAAM,KAAK,OAAO,EAAE,CAAC;GACrB,MAAM,KAAK,OAAO,EAAE,CAAC;GACrB,MAAM,KAAK,OAAO,EAAE,CAAC;GACrB,MAAM,uBAAO,IAAI,IAAY;GAC7B,IAAI,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,CAAC;GACzD,MAAM,uBAAO,IAAI,IAAY;GAC7B,KAAK,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,IAAI,KAAK,KAAK;IAChD,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC;IACrC,IAAI,KAAK,IAAI,GAAG,GAAG;KACjB,MAAM,KAAK,IAAI,MAAM;KACrB;IACF;IACA,KAAK,IAAI,GAAG;IACZ,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC,UAAU,GAAG;KACxC,MAAM,KAAK,gBAAgB,MAAM,IAAI,IAAI,IAAI,IAAI,EAAE;KACnD;IACF;IAIA,MAAM,4BAAY,IAAI,IAAY;IAClC,KAAK,MAAM,SAAS,KAAK,UAAU,CAAC,GAClC,KAAK,MAAM,SAAS;KAAC,MAAM;KAAG,MAAM;KAAG,MAAM;IAAC,GAC5C,IAAI,UAAU,GAAG,UAAU,IAAI,KAAK;IAKxC,IAAI,UAAU,SAAS,GACrB;UAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,IAAI,MAAM,GAAG,UAAU,IAAI,CAAC;IAAC;IAErE,IAAI,OAAO,MAAM,UAAU;KACzB,CAAC,IAAI,EAAE;KACP,CAAC,IAAI,EAAE;KACP,CAAC,IAAI,EAAE;KACP,CAAC,IAAI,EAAE;IACT,CAAC;IACD,KAAK,MAAM,KAAK,WACd,OAAO,oBAAoB,MAAM,KAAK,IAAI,KAAK,EAAE;IACnD,MAAM,KAAK;GACb;GACA,OAAO;EACT;EAGA,AAAQ,gBAAyB;GAC/B,MAAM,MAAM,KAAK;GACjB,MAAM,SAAS,KAAK;GACpB,IAAI,CAAC,OAAO,CAAC,QAAQ;IAEnB,MAAM,KAAc,CAAC;IACrB,MAAM,IAAI,KAAK,YAAY;IAC3B,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,GAAG,KAAK,KAAK,YAAY,GAAG,IAAI,CAAU;IAE5C,OAAO;GACT;GAKA,MAAM,IAAI,KAAK;GACf,MAAM,YAAY,IAAI;GACtB,MAAM,YAAY,IAAI;GACtB,MAAM,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE;GACvC,KAAK,IAAI,IAAI,GAAG,MAAM,UAAU,QAAQ,IAAI,KAAK,KAAK;IACpD,MAAM,IAAI,UAAU;IACpB,IAAI,UAAU,OAAO,MAAM,MAAM,OAAO,IAAI,MAAM,KAAK;GACzD;GAEA,MAAM,KAAc,CAAC;GACrB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,OAAO,IAAI,MAAM;IACvB,IAAI,IAAI,MAAM;IACd,IAAI,MAAM,IAAI;KACZ,MAAM,QAAS,IAAI,IAAK;KACxB,SAAS;MACP,MAAM,IAAK,IAAI,IAAK;MACpB,KAAK,KAAK,OAAO,EAAE,CAAC,OAAO,EAAE;MAE7B,MAAM,OAAO,UAAU,IAAI,KAAM,IAAI,KAAK;MAC1C,IAAI,SAAS,OAAQ,OAAO,IAAK,OAAO,OAAO;MAC/C,IAAI;KACN;IACF;IACA,GAAG,KAAK,IAAI;GACd;GACA,OAAO;EACT;EAMA,OAAqB;GACnB,OAAO,KAAK,YAAY;EAC1B;EAQA,YAAY,GAAW,OAAO,OAAkB;GAC9C,IAAI,KAAK,IAAI,MAAM;GACnB,IAAI,IAAI,KAAK,YAAY;GACzB,KAAK,IAAI,KAAK,EAAE,IACd,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,GAAG,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE;GAEvD,OAAO,QAAQ,GAAG,SAAS,IAAI,KAAK,UAAU,EAAE,IAAI;EACtD;EAOA,UAAU,GAA4B;GACpC,IAAI,KAAK,CAAC;GACV,IAAI,IAAI,KAAK,YAAY;GACzB,KAAK,IAAI,KAAK,EAAE,IACd,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,GAAG,KAAK,EAAE,EAAE,CAAC,EAAE;GAE7C,OAAO;EACT;EAMA,AAAU,OAAO,GAAwB;GACvC,KAAK,MAAM,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO;GACjE,KAAK,MAAM,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO;GACjE,KAAK,MAAM,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO;EACnE;EAOA,AAAU,iBAAwB;GAChC,IAAI,QAAQ,KAAK;GACjB,IAAI,QAAQ,KAAK;GACjB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK;IAC/C,QAAQ,MAAM,KAAK,KAAK,EAAE;IAC1B,QAAQ,MAAM,KAAK,KAAK,EAAE;GAC5B;GAEA,IAAI,IAAI,MAAM,UAAU,KAAK;GAC7B,IAAI,MAAM,MAAM,KAAK,KAAK,CAAC,CAAC,OAAO,CAAC;GACpC,IAAI,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,EAAE;GAE9B,OAAO,IAAI,MACT,IAAI,UAAU,KAAK,MAAM,IAAI,GAC7B,IAAI,KAAK,GAAG,KAAK,IAAI,GACrB,IAAI,KAAK,KAAK,MAAM,CAAC,IAAI,CAC3B;EACF;EASA,AAAU,UACR,GACA,GACA,GACA,MAAiB,MACV;GACP,OAAO,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;EACzC;EAUA,AAAU,QACR,GACA,GACA,GACA,KACA,MAAiB,MACF;GACf,IAAI,IAAI,OAAO,KAAK,UAAU,GAAG,GAAG,GAAG,GAAG;GAC1C,OAAO;IACF;IACA;IACA;IACH,UAAU;IACV,QAAQ,SAAS,aAAa,CAAC;GACjC;EACF;EAMA,OAAiB,QAAQ,OAA2B;GAClD,IAAI,IAAI,MAAM;GAEd,OAAO,IAAI,GAAG;IACZ,IAAI,IAAI,MAAM,EAAE;IAChB,IAAI,IAAI,MAAM,EAAE;IAChB,IAAI,IAAI;IAER,OAAO,IAAI,GAAG;KACZ,IAAI,IAAI,MAAM,EAAE;KAChB,IAAI,IAAI,MAAM,EAAE;KAEhB,IAAK,KAAK,KAAK,KAAK,KAAO,KAAK,KAAK,KAAK,GAAI;MAC5C,MAAM,OAAO,GAAG,CAAC;MACjB,MAAM,OAAO,GAAG,CAAC;MACjB;KACF;IACF;GACF;GAEA,OAAO;EACT;CACF;CAgBA,SAAS,uBACP,KACA,IACA,IACA,QACM;EACN,MAAM,OAAO,KAAK,KAAK,KAAK;EAC5B,IAAI,QAAQ,GAAG;EACf,MAAM,QAAQ,SAAS,KAAK,KAAK,IAAI;EACrC,IAAI,MAAM,KAAK;EACf,IAAI,MAAM,KAAK;CACjB;CAOA,MAAM,mBAAmB;CAOzB,MAAM,yBAAyB;CAS/B,MAAM,kBAAkB;CAExB,MAAM,iBAAiB;CAQvB,IAAa,OAAb,cAA0B,GAAG;;;GAC3B,KAAU,OAAW,IAAI,GAAG,GAAG,CAAC;;EAKhC,IAAI,WAAe;GACjB,OAAO,KAAK;EACd;EACA,IAAI,SAAS,GAAO;GAClB,KAAK,OAAO;EACd;EAKA,IAAI,QAAgB;GAClB,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;EAC5E;EAOA,IAAI,UAAkB;GACpB,OAAO,KAAK,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,EAAE;EAC9C;CACF;CAcA,IAAa,QAAb,cAA2B,MAAM;;;GAC/B,KAAU,cAAsB;GAChC,KAAU,cAAsB;GAChC,KAAU,kBAA0B;GACpC,KAAU,eAAuB;GACjC,KAAU,kBAA0B;GACpC,KAAU,YAAoB;GAC9B,KAAU,YAAoB;GAC9B,KAAU,YAAoB;GAC9B,KAAU,YAA2B;GACrC,KAAU,UAAkB;GAC5B,KAAU,eAAuB;GACjC,KAAU,SAA2B;GACrC,KAAU,gBAAoC;GAK9C,KAAQ,uBAAqB,IAAI,aAAa,CAAC;GAC/C,KAAQ,uBAAqB,IAAI,aAAa,CAAC;GAE/C,KAAQ,wBAAsB,IAAI,aAAa,CAAC;GAChD,KAAQ,0BAAuB,IAAI,YAAY,CAAC;GAGhD,KAAQ,4BAAyB,IAAI,YAAY,CAAC;GAClD,KAAQ,yBAAqB,IAAI,WAAW,CAAC;GAC7C,KAAQ,yBAAqB,IAAI,WAAW,CAAC;GAC7C,KAAQ,6BAA0B,IAAI,YAAY,CAAC;GACnD,KAAQ,+BAA4B,IAAI,YAAY,CAAC;GACrD,KAAQ,4BAA0B,IAAI,aAAa,CAAC;;EAMpD,MAAM,SAA6B;GACjC,IAAI,QAAQ,eAAe,QAAW,KAAK,aAAa,QAAQ;GAChE,IAAI,QAAQ,eAAe,QAAW,KAAK,aAAa,QAAQ;GAChE,IAAI,QAAQ,mBAAmB,QAC7B,KAAK,kBAAkB,QAAQ;GACjC,IAAI,QAAQ,gBAAgB,QAC1B,KAAK,eAAe,QAAQ;GAC9B,IAAI,QAAQ,mBAAmB,QAC7B,KAAK,kBAAkB,QAAQ;GACjC,IAAI,QAAQ,aAAa,QAAW,KAAK,WAAW,QAAQ;GAC5D,IAAI,QAAQ,aAAa,QAAW,KAAK,WAAW,QAAQ;GAC5D,IAAI,QAAQ,aAAa,QAAW,KAAK,YAAY,QAAQ;GAC7D,IAAI,QAAQ,UAAU,QAAW,KAAK,SAAS,QAAQ;GACvD,IAAI,QAAQ,aAAa,QAAW,KAAK,YAAY,QAAQ;GAC7D,IAAI,QAAQ,WAAW,QAAW,KAAK,SAAS,QAAQ;GACxD,IAAI,QAAQ,gBAAgB,QAC1B,KAAK,cAAc,QAAQ;GAC7B,IAAI,QAAQ,iBAAiB,QAC3B,KAAK,gBAAgB,QAAQ;GAC/B,OAAO;EACT;EAKA,IAAI,aAAqB;GACvB,OAAO,KAAK;EACd;EACA,IAAI,WAAW,GAAW;GACxB,KAAK,cAAc,KAAK,IAAI,GAAG,CAAC;EAClC;EAMA,IAAI,aAAqB;GACvB,OAAO,KAAK;EACd;EACA,IAAI,WAAW,GAAW;GACxB,KAAK,cAAc,KAAK,IAAI,GAAG,CAAC;EAClC;EAKA,IAAI,iBAAyB;GAC3B,OAAO,KAAK;EACd;EACA,IAAI,eAAe,GAAW;GAC5B,KAAK,kBAAkB;EACzB;EAKA,IAAI,cAAsB;GACxB,OAAO,KAAK;EACd;EACA,IAAI,YAAY,GAAW;GACzB,KAAK,eAAe;EACtB;EAKA,IAAI,iBAAyB;GAC3B,OAAO,KAAK;EACd;EACA,IAAI,eAAe,GAAW;GAC5B,KAAK,kBAAkB;EACzB;EAKA,IAAI,WAAmB;GACrB,OAAO,KAAK;EACd;EACA,IAAI,SAAS,GAAW;GACtB,KAAK,YAAY,KAAK,IAAI,GAAG,CAAC;EAChC;EAKA,IAAI,WAAmB;GACrB,OAAO,KAAK;EACd;EACA,IAAI,SAAS,GAAW;GACtB,KAAK,YAAY,KAAK,IAAI,GAAG,CAAC;EAChC;EAOA,IAAI,WAAmB;GACrB,OAAO,KAAK;EACd;EACA,IAAI,SAAS,GAAW;GACtB,KAAK,YAAY;EACnB;EAMA,IAAI,QAA0B;GAC5B,OAAO,KAAK;EACd;EACA,IAAI,MAAM,GAAqB;GAC7B,KAAK,SAAS;EAChB;EAQA,IAAI,WAA0B;GAC5B,OAAO,KAAK;EACd;EACA,IAAI,SAAS,GAAkB;GAC7B,KAAK,YAAY;EACnB;EAKA,IAAI,SAAiB;GACnB,OAAO,KAAK;EACd;EACA,IAAI,OAAO,GAAW;GACpB,KAAK,UAAU,KAAK,IAAI,GAAG,CAAC;EAC9B;EAMA,IAAI,cAAsB;GACxB,OAAO,KAAK;EACd;EACA,IAAI,YAAY,IAAY;GAC1B,KAAK,eAAe,KAAK,IAAI,GAAG,EAAE;EACpC;EAKA,IAAI,eAAuB;GACzB,OAAO,KAAK,kBAAkB,SAC1B,KAAK,YAAY,KACjB,KAAK;EACX;EACA,IAAI,aAAa,GAAW;GAC1B,KAAK,gBAAgB;EACvB;EASA,QAAQ,IAAmB,UAAyB;GAClD,MAAM,SAAS,cAAc;GAC7B,MAAM,OAAO,SAAU,KAAc,IAAI,KAAK,EAAE;GAChD,IAAI,aAAa,QAAW;IAC1B,KAAK,SAAS,KAAK,SAAS;IAC5B,KAAK,SAAS,KAAK,SAAS;GAC9B,OAAO,IAAI,CAAC,QAAQ;IAClB,MAAM,IAAI,IAAI,OAAO,IAAI,MAAM;IAC/B,MAAM,IAAI,KAAK;IACf,KAAK,SAAS,KAAK,KAAK,IAAI,CAAC,IAAI;IACjC,KAAK,SAAS,KAAK,KAAK,IAAI,CAAC,IAAI;GACnC;GACA,KAAK,KAAK,IAAI;GACd,OAAO;EACT;EAWA,KAAK,IAAkB;GACrB,MAAM,IAAI,KAAK;GACf,IAAI,MAAM,KAAK,EAAE,KAAK,IAAI,OAAO;GAEjC,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,YAAY,IAAI;GAC7C,IAAI,MAAM,GAAG,OAAO;GAEpB,KAAK,eAAe,CAAC;GACrB,KAAK,QAAQ,CAAC;GACd,IAAI,IAAI,KAAK,KAAK,cAAc,GAC9B,KAAK,YAAY,CAAC;QACb;IACL,KAAK,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC;IAC3B,KAAK,QAAQ,KAAK,GAAG,GAAG,CAAC;GAC3B;GACA,KAAK,WAAW,GAAG,EAAE;GACrB,KAAK,SAAS,CAAC;GACf,OAAO;EACT;EAMA,AAAQ,eAAe,GAAW;GAChC,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG;IAC5B,MAAM,OAAO,IAAI,IAAI;IACrB,KAAK,OAAO,IAAI,aAAa,IAAI;IACjC,KAAK,OAAO,IAAI,aAAa,IAAI;IACjC,KAAK,QAAQ,IAAI,aAAa,OAAO,CAAC;IACtC,KAAK,UAAU,IAAI,YAAY,IAAI;IACnC,KAAK,YAAY,IAAI,YAAY,IAAI;IACrC,KAAK,SAAS,IAAI,WAAW,IAAI;IACjC,KAAK,SAAS,IAAI,WAAW,IAAI;IACjC,KAAK,eAAe,IAAI,YAAY,IAAI;GAC1C;EACF;EAQA,AAAQ,QAAQ,GAAW;GACzB,MAAM,MAAM,KAAK;GACjB,MAAM,MAAM,KAAK;GACjB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,IAAI,IAAI,KAAK;IACb,IAAI,IAAI,EAAE;IACV,IAAI,MAAM,QAAW;KACnB,IAAI,IAAI,KAAK,CAAC;KACd,IAAI,EAAE;KACN,KAAK,KAAK;IACZ;IACA,MAAM,IAAI,IAAI;IACd,IAAI,KAAK,EAAE;IACX,IAAI,IAAI,KAAK,EAAE;IACf,IAAI,KAAK,EAAE;IACX,IAAI,IAAI,KAAK,EAAE;GACjB;EACF;EAKA,AAAQ,SAAS,GAAW;GAC1B,MAAM,MAAM,KAAK;GACjB,MAAM,MAAM,KAAK;GACjB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,KAAK;IACf,MAAM,IAAI,EAAE;IACZ,MAAM,IAAI,IAAI;IACd,EAAE,KAAK,IAAI;IACX,EAAE,KAAK,IAAI,IAAI;IACf,EAAE,KAAK,IAAI;IACX,EAAE,KAAK,IAAI,IAAI;GACjB;EACF;EAuBA,AAAQ,YAAY,GAAW;GAC7B,MAAM,MAAM,KAAK;GACjB,MAAM,MAAM,KAAK;GACjB,MAAM,OAAO,KAAK;GAClB,MAAM,SAAS,KAAK;GAEpB,KAAK,KAAK,GAAG,GAAG,IAAI,CAAC;GACrB,OAAO,KAAK,GAAG,GAAG,CAAC;GAEnB,MAAM,KAAK,KAAK,cAAc,KAAK;GACnC,MAAM,MAAM,KAAK,IAAI,KAAK,aAAa,KAAK,WAAW;GACvD,MAAM,OAAO,MAAM;GACnB,MAAM,SAAS,MAAM;GACrB,MAAM,UAAU,SAAS;GACzB,MAAM,MAAM,IAAI,KAAK;GAGrB,IAAI,IAAI;GACR,OAAO,IAAI,IAAI,GAAG,MAAM;GACxB,MAAM,OAAO,IAAI;GACjB,IAAI,KAAK,WAAW,SAAS,IAAI,GAC/B,KAAK,aAAa,IAAI,YAAY,IAAI,CAAC;GAEzC,MAAM,OAAO,KAAK;GAClB,MAAM,QAAQ,KAAK;GACnB,MAAM,QAAQ,KAAK;GACnB,MAAM,QAAQ,KAAK;GACnB,MAAM,UAAU,KAAK;GAMrB,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC;GACtB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,KAAK,KAAK,MAAM,IAAI,IAAI,KAAK,GAAG;IACtC,MAAM,KAAK,KAAK,MAAM,IAAI,IAAI,IAAI,KAAK,GAAG;IAC1C,IACE,MAAM,eACN,MAAM,mBACN,MAAM,eACN,MAAM,iBACN;KACA,MAAM,KAAK;KACX,MAAM,KAAK;IACb,OAAO;KACL,MAAM,KAAK;KACX,MAAM,KAAK;IACb;IACA,MAAM,OACF,KAAK,KAAK,MAAM,IAAI,UAAU,IAAI,KAAK,KAAK,MAAM,IAAI,UAAU,OAChE,IACF;IACF,KAAK,KAAK;IACV,MAAM,IAAI;GACZ;GACA,IAAI,MAAM;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,MAAM;IAChB,MAAM,KAAK;IACX,OAAO;GACT;GACA,MAAM,KAAK;GACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,QAAQ,MAAM,KAAK,GAAG,MAAM;GAG9B,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,KAAK,MAAM;IACjB,IAAI,OAAO,gBAAgB;IAC3B,MAAM,KAAK,MAAM;IACjB,MAAM,KAAK,IAAI;IACf,MAAM,KAAK,IAAI;IACf,MAAM,KAAK,IAAI,KAAK;IACpB,MAAM,MAAM,IAAI;IAChB,MAAM,MAAM,IAAI,KAAK;IACrB,MAAM,KAAK,IAAI;IAGf,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;KAC1B,MAAM,KAAK,MAAM,IAAI,KAAK,IAAI,MAAM,KAAK,MAAM,IAAI,KAAK,KAAK;KAC7D,MAAM,KAAK,IAAI,IAAI,KAAK,KAAK;KAC7B,MAAM,OACF,KAAK,KAAK,IAAI,UAAU,IAAI,KAAK,KAAK,IAAI,UAAU,OAAO,IAC7D;KACF,MAAM,MAAM,MAAM;KAClB,MAAM,QAAQ,MAAM,IAAI,MAAM,MAAM,KAAK;KACzC,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,KAAK;MAChC,MAAM,IAAI,QAAQ;MAClB,IAAI,MAAM,OAAO,MAAM,MAAM,OAAO,IAAI;MACxC,IAAI,MAAM,KAAK,KAAK,GAAG;MAEvB,MAAM,KAAK,IAAI;MACf,MAAM,KAAK,IAAI;MACf,MAAM,KAAK,IAAI,KAAK;MACpB,MAAM,KAAK,KAAK;MAChB,MAAM,KAAK,KAAK;MAChB,MAAM,KAAK,KAAK,KAAK,KAAK;MAC1B,IAAI,EAAE,KAAK,KAAK;MAEhB,MAAM,KAAK,IAAI;MACf,KAAK,OAAO;MACZ,KAAK,KAAK,MAAM;MAChB,KAAK,OAAO;MACZ,KAAK,KAAK,MAAM;MAChB,KAAK,KAAK,MAAM,IAAI;MACpB,KAAK,KAAK,MAAM,IAAI,KAAK;MACzB,KAAK,KAAK,MAAM;MAChB,KAAK,KAAK,MAAM;MAChB,OAAO,EAAE;MACT,OAAO,EAAE;MAET,IAAI,KAAK,MAAM;OACb,IAAI,KAAK;OACT,IAAI,KAAK;OACT,IAAI,KAAK;OACT,IAAI,OAAO,GAAG;QAEZ,KAAK;QACL,KAAK;QACL,KAAK;OACP,OAAO,IAAI,KAAK,SACd,KAAK;OAEP,MAAM,IAAI,IAAI;OACd,MAAM,KAAK,KAAK;OAChB,MAAM,KAAK,KAAK;OAChB,KAAK,KAAK,MAAM;OAChB,KAAK,KAAK,MAAM;OAChB,KAAK,KAAK,MAAM;OAChB,KAAK,KAAK,MAAM;MAClB;KACF;IACF;GACF;EACF;EASA,AAAQ,WAAW,GAAW,IAAY;GACxC,MAAM,MAAM,KAAK;GACjB,MAAM,MAAM,KAAK;GACjB,MAAM,OAAO,KAAK;GAClB,MAAM,SAAS,KAAK;GACpB,MAAM,MAAM,KAAK;GAEjB,MAAM,WAAW,KAAK;GACtB,MAAM,WAAW,KAAK;GACtB,MAAM,WAAW,KAAK,IAAI,KAAK,WAAW,QAAQ;GAClD,MAAM,KAAK,KAAK;GAChB,MAAM,KAAK,KAAK;GAChB,MAAM,KAAK,KAAK;GAEhB,MAAM,QAAQ,KAAK;GACnB,MAAM,WAAW,QAAQ,KAAK,YAAY;GAC1C,MAAM,QAAQ,aAAa,WAAW,KAAK,UAAU;GACrD,MAAM,OAAO,aAAa;GAC1B,MAAM,SAAS,aAAa;GAC5B,IAAI,OAAO;GACX,IAAI,OAAO;GACX,IAAI,OAAO;GACX,IAAI,OAAO;GACX,IAAI,SAAS,aAAa,QAAQ;IAChC,MAAM,KAAK,MAAM;IACjB,MAAM,KAAK,MAAM;IACjB,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;IAC5B,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;IAC5B,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;IAC5B,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;GAC9B;GACA,MAAM,SAAS,KAAK;GAEpB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,IAAI;IACd,MAAM,IAAI,IAAI;IACd,IAAI,KAAK,IAAI;IACb,IAAI,KAAK,IAAI,IAAI;IACjB,IAAI,KAAK,IAAI;IACb,IAAI,KAAK,IAAI,IAAI;IAGjB,IAAI,KAAK;IACT,IAAI,KAAK;IACT,MAAM,IAAI,OAAO;IACjB,IAAI,IAAI,GAAG;KAET,IAAI,OAAO,GACT,uBACE,KACA,KAAK,KAAK,IAAI,IACd,KAAK,IAAI,KAAK,IAAI,IAClB,EACF;KAIF,IAAI,OAAO,GAAG,uBAAuB,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE;KACtE,IAAI,OAAO,GAAG,uBAAuB,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE;IACxE;IAGA,IAAI,KAAK;IACT,IAAI,KAAK;IACT,MAAM,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI;IAC3C,IAAI,MAAM,GAAG;KACX,MAAM,KAAK,WAAW,KAAK,KAAK,GAAG;KACnC,KAAK,IAAI,KAAK,KAAK;KACnB,KAAK,IAAI,KAAK,KAAK;KACnB,MAAM,KAAK,KAAK,KAAK,KAAK;KAC1B,IAAI,KAAK,WAAW,UAAU;MAC5B,MAAM,KAAK,WAAW,KAAK,KAAK,EAAE;MAClC,MAAM;MACN,MAAM;KACR;IACF;IAEA,IAAI,OAAO;KAKT,MAAM,KAAK,KAAK;KAChB,MAAM,KAAK,OAAO;KAClB,MAAM,MAAM,KAAK;KACjB,MAAM,KAAK,OAAO;KAClB,IAAI,KAAK,QAAQ,MAAM,YAAY,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI;UACpD,IAAI,KAAK,QAAQ,MAAM,YAAY,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI;KAC9D,IAAI,MAAM,QAAQ,MAAM,YAAY,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI;UACtD,IAAI,KAAK,QAAQ,MAAM,YAAY,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI;IAChE;IAEA,MAAM,KAAK;IACX,MAAM,KAAK;IAEX,MAAM,MAAM,KAAK,KAAK,KAAK;IAC3B,IAAI,MAAM,WAAW,UAAU;KAC7B,MAAM,KAAK,WAAW,KAAK,KAAK,GAAG;KACnC,MAAM;KACN,MAAM;IACR,OAAO,IAAI,WAAW,KAAK,MAAM,WAAW,UAAU;KACpD,IAAI,MAAM,GAAG;MACX,MAAM,KAAK,WAAW,KAAK,KAAK,GAAG;MACnC,MAAM;MACN,MAAM;KACR,OAAO;MAEL,KAAK;MACL,KAAK;KACP;IACF;IAEA,MAAM,KAAK;IACX,MAAM,KAAK;IAEX,IAAI,MAAM;KACR,MAAM,IAAI,OAAO;KACjB,MAAM,IAAI,OAAO;KACjB,IAAI,IAAI,GAAG;MACT,IAAI,KAAK,MAAM,KAAK,QAAS,OAAO,MAAM;WACrC,IAAI,KAAK,MAAM,KAAK,QAAS,KAAK,QAAQ;KACjD;KACA,IAAI,IAAI,GAAG;MACT,IAAI,KAAK,MAAM,KAAK,QAAS,OAAO,MAAM;WACrC,IAAI,KAAK,MAAM,KAAK,QAAS,KAAK,QAAQ;KACjD;IACF,OAAO,IAAI,QAAQ;KAGjB,IAAI,MAAM,MAAM;MACd,KAAK;MACL,IAAI,KAAK,GAAG,KAAK,CAAC;KACpB,OAAO,IAAI,MAAM,MAAM;MACrB,KAAK;MACL,IAAI,KAAK,GAAG,KAAK,CAAC;KACpB;KACA,IAAI,MAAM,MAAM;MACd,KAAK;MACL,IAAI,KAAK,GAAG,KAAK,CAAC;KACpB,OAAO,IAAI,MAAM,MAAM;MACrB,KAAK;MACL,IAAI,KAAK,GAAG,KAAK,CAAC;KACpB;IACF;IAEA,IAAI,KAAK;IACT,IAAI,IAAI,KAAK;IACb,IAAI,KAAK;IACT,IAAI,IAAI,KAAK;GACf;EACF;CACF;;;;;CC1/CA,IAAa,QAAb,MAAa,cAAc,GAAG;EA0B5B,YAAY,GAAG,MAAa;GAC1B,MAAM,GAAG,IAAI;GAvBf,KAAU,QAAmB;GAC7B,KAAQ,UAAmB;EAuB3B;EAMA,OAAO,KAAK,GAAG,MAAoB;GACjC,MAAM,IAAI;IAAC;IAAG;IAAG;IAAG;GAAC;GACrB,MAAM,IAAI,KAAK,QAAQ,IAAI;GAC3B,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,KACvC,IAAI,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;GAE7B,OAAO,IAAI,MAAM,CAAC;EACpB;EAMA,OAAO,QAAQ,KAAoB;GACjC,IAAI,IAAI,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC;GACrC,IAAI,IAAI,UAAU,GAAG;IACnB,MAAM,MAAM,MAAc,IAAI,MAAM;IACpC,MAAM,aAAa,IAAI,WAAW,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM;IAC3D,MAAM,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI;GAC3D;GAEA,IAAI,QAAQ;GACZ,IAAI,IAAI,WAAW,GAAG;IACpB,QAAQ,SAAS,IAAI,OAAO,GAAG,CAAC,GAAG,EAAE,IAAI;IACzC,MAAM,IAAI,UAAU,GAAG,CAAC;GAC1B;GAEA,MAAM,SAAS,SAAS,KAAK,EAAE;GAC/B,OAAO,IAAI,MAAM,UAAU,IAAK,UAAU,IAAK,KAAM,SAAS,KAAM,KAAK;EAC3E;EAMA,OAAO,IAAI,GAAG,MAAoB;GAChC,OAAO,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,KAAK;EACzC;EAMA,OAAO,IAAI,GAAG,MAAoB;GAChC,OAAO,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,KAAK;EACzC;EAMA,OAAO,IAAI,GAAG,MAAoB;GAChC,OAAO,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,KAAK;EACzC;EAMA,OAAO,IAAI,GAAG,MAAoB;GAChC,OAAO,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,KAAK;EACzC;EAMA,OAAO,IAAI,GAAG,MAAoB;GAChC,OAAO,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,KAAK;EACzC;EAMA,OAAO,IAAI,GAAG,MAAoB;GAChC,OAAO,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,KAAK;EACzC;EAMA,OAAO,IAAI,GAAG,MAAoB;GAChC,OAAO,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,KAAK;EACzC;EAMA,OAAO,MAAM,GAAG,MAAoB;GAClC,OAAO,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,OAAO;EAC3C;EAMA,OAAO,MAAM,GAAG,MAAoB;GAClC,OAAO,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,OAAO;EAC3C;EAOA,OAAO,UAAU,MAAkB;GACjC,OAAO,MAAM,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;IAAC;IAAG;IAAG;GAAC,CAAC;EACvD;EAMA,IAAW,MAAc;GACvB,OAAO,KAAK,SAAS,KAAK;EAC5B;EAMA,IAAW,MAAc;GACvB,OAAO,KAAK,SAAS,KAAK;EAC5B;EAMA,IAAW,OAAe;GACxB,OAAO,KAAK,SAAS,MAAM;EAC7B;EAKA,QAAe;GACb,MAAM,IAAI,IAAI,MAAM,IAAI;GACxB,EAAE,OAAO,KAAK,KAAK;GACnB,EAAE,UAAU,KAAK;GACjB,OAAO;EACT;EAQA,OAAe,QAAQ,GAAiB;GACtC,MAAM,KAAK,EAAE,MAAM;GACnB,MAAM,SAAS,MAAM,OAAO,GAAG;GAC/B,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,OAAO;IACjB,GAAG,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE;GACnC;GACA,GAAG,UAAU;GACb,OAAO;EACT;EAMA,OAAe,SAAS,GAAiB;GACvC,MAAM,SAAS,MAAM,OAAO,EAAE;GAC9B,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,OAAO;IACjB,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;GACnC;GACA,EAAE,UAAU;GACZ,OAAO;EACT;EAOA,OAAO,MAAiB,UAAmB,OAAa;GACtD,IAAI,WAAW,SAAS,KAAK,OAAO;IAClC,MAAM,QAAQ,KAAK,MAAM,YAAY,IAAI,OAAO,KAAK,YAAY;IACjE,IAAK,MAAc,QACjB,KAAK,GAAI,MAAc,MAAM,CAAC,MAAM,KAAK,SAAS,KAAK,OAAO,CAAC;SAE/D,MAAM,IAAI,MAAM,+BAA+B,KAAK;GAExD;GAEA,KAAK,QAAQ;GACb,OAAO;EACT;EAKA,IAAI,OAAkB;GACpB,OAAO,KAAK;EACd;EAMA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAKA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAKA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAMA,IAAI,IAAY;GACd,OAAO,KAAK,SAAS,SAAS,KAAK,SAAS,UAAU,KAAK,KAAK,KAAK;EACvE;EACA,IAAI,EAAE,GAAW;GACf,MAAM,IAAI,KAAK,SAAS,SAAS,KAAK,SAAS,UAAU,IAAI;GAC7D,KAAK,KAAK;EACZ;EAKA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAKA,IAAI,IAAY;GACd,OAAO,KAAK,SAAS,QAAQ,KAAK,KAAK,KAAK;EAC9C;EACA,IAAI,EAAE,GAAW;GACf,MAAM,IAAI,KAAK,SAAS,QAAQ,IAAI;GACpC,KAAK,KAAK;EACZ;EAMA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAKA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAKA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAKA,IAAI,IAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,EAAE,GAAW;GACf,KAAK,KAAK;EACZ;EAKA,IAAI,MAAM,GAAW;GACnB,IAAI,KAAK,SAAS,GAAG,KAAK,KAAK;EACjC;EACA,IAAI,QAAgB;GAClB,OAAO,KAAK,SAAS,IAAI,KAAK,KAAK;EACrC;EAKA,IAAI,aAAsB;GACxB,OAAO,KAAK;EACd;EACA,IAAI,WAAW,GAAY;GACzB,KAAK,UAAU;EACjB;EAMA,UAAU,SAAkB,MAAa;GACvC,IAAI,KAAK,WAAW,QAAQ,OAAO;GAEnC,MAAM,SAAS,MAAM,OAAO,KAAK;GAEjC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,KAAK,KAAK,CAAC,SACP,IAAI,WAAW,KAAK,IAAI,GAAG,GAAG,OAAO,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,IACxD,IAAI,WAAW,KAAK,IAAI,OAAO,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,IAAI,GAAG,CAAC;GAG9D,KAAK,UAAU;GAEf,OAAO;EACT;EAOA,WAAW,SAAkB,MAAa;GACxC,OAAO,KAAK,MAAM,CAAC,CAAC,UAAU,MAAM;EACtC;EAOA,SAAS,SAA0C,QAAgB;GAEjE,MAAM,IACJ,KAAK,WAAW,WAAW,SAAS,MAAM,QAAQ,IAAI,IAAI;GAC5D,IAAI,UAAU,OAAO;IACnB,MAAM,QAAQ,MAAc;KAC1B,MAAM,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE;KACnC,OAAO,EAAE,SAAS,IAAI,MAAM,IAAI;IAClC;IACA,OAAO,IAAI,KAAK,EAAE,EAAE,IAAI,KAAK,EAAE,EAAE,IAAI,KAAK,EAAE,EAAE;GAChD,OAAO,IAAI,UAAU,QACnB,OAAO,QAAQ,KAAK,MAAM,EAAE,EAAE,EAAE,GAAG,KAAK,MAAM,EAAE,EAAE,EAAE,GAAG,KAAK,MAAM,EAAE,EAAE,EAAE,GAAG,KAAK,MAAM;QACjF,IAAI,UAAU,OACnB,OAAO,OAAO,KAAK,MAAM,EAAE,EAAE,EAAE,GAAG,KAAK,MAAM,EAAE,EAAE,EAAE,GAAG,KAAK,MAAM,EAAE,EAAE,EAAE;QAEvE,OAAO,GAAG,KAAK,MAAM,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,GAAG,KAAK,MAAM;EAExE;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,kBAAkB,IAAI,WAAW,IAAI;GAExD,MAAM,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC;GAC5B,MAAM,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC;GAC5B,IAAI,KAAK,MAAM,OAAO;GACtB,IAAI,IAAI;GACR,MAAM,IAAI;GAEV,IAAI,OAAO,KAAK;IACd,IAAI;IACJ,IAAI;GACN,OAAO;IACL,MAAM,IAAI,MAAM;IAChB,IAAI,IAAI,KAAM,KAAK,IAAI,MAAM,OAAO,KAAK,MAAM;IAE/C,IAAI;IACJ,IAAI,QAAQ,GACV,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI;SAC1B,IAAI,QAAQ,GACjB,KAAK,IAAI,KAAK,IAAI;SACb,IAAI,QAAQ,GACjB,KAAK,IAAI,KAAK,IAAI;GAEtB;GAEA,MAAM,KAAK,MAAM,IAAI,mBAAmB,IAAI,IAAI,IAAI,IAAI,GAAG,GAAG,IAAI,KAAK;GACvE,IAAI,kBAAkB,GAAG,aAAa;GACtC,OAAO;EACT;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,IAAI,CAAC,GAAG,GAAG,KAAK;GAChB,IAAI,CAAC,iBAAiB,IAAI,IAAI;GAC9B,IAAI,IAAI,KAAK,MAAM,CAAC;GAEpB,MAAM,KAAK,mBAAmB,IAAI;GAClC,IAAI,KAAK,GAAG;IACV,MAAM,OAAO,MAAM,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,KAAK;IACxD,IAAI,kBAAkB,KAAK,aAAa;IACxC,OAAO;GACT;GAEA,MAAM,IAAI,KAAK,KAAM,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI;GAC/C,MAAM,IAAI,IAAI,IAAI;GAElB,MAAM,WAAW,MAAc;IAC7B,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;IACpC,IAAI,IAAI,IAAI,GACV,OAAO,KAAK,IAAI,KAAK,IAAI;SACpB,IAAI,IAAI,IAAI,GACjB,OAAO;SACF,IAAI,IAAI,IAAI,GACjB,OAAO,KAAK,IAAI,MAAM,IAAI,IAAI,KAAK;SAEnC,OAAO;GAEX;GAEA,MAAM,KAAK,MAAM,IACf,KAAK,QAAQ,IAAI,IAAI,CAAC,GACtB,KAAK,QAAQ,CAAC,GACd,KAAK,QAAQ,IAAI,IAAI,CAAC,GACtB,IAAI,KACN;GACA,IAAI,kBAAkB,GAAG,aAAa;GACtC,OAAO;EACT;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,kBAAkB,IAAI,WAAW,IAAI;GAExD,MAAM,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC;GAC5B,MAAM,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC;GAC5B,MAAM,IAAI,MAAM;GAChB,IAAI,IAAI;GACR,MAAM,IAAI,QAAQ,IAAI,IAAI,IAAI;GAC9B,MAAM,IAAI;GAEV,IAAI,OAAO,KAAK;IACd,IAAI,QAAQ,GACV,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI;SAC1B,IAAI,QAAQ,GACjB,KAAK,IAAI,KAAK,IAAI;SACb,IAAI,QAAQ,GACjB,KAAK,IAAI,KAAK,IAAI;GAEtB;GAEA,MAAM,KAAK,MAAM,IAAI,mBAAmB,IAAI,IAAI,IAAI,IAAI,GAAG,GAAG,IAAI,KAAK;GACvE,IAAI,kBAAkB,GAAG,aAAa;GACtC,OAAO;EACT;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,IAAI,CAAC,GAAG,GAAG,KAAK;GAChB,IAAI,CAAC,iBAAiB,IAAI,IAAI;GAC9B,IAAI,IAAI,KAAK,MAAM,CAAC;GAEpB,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;GAC1B,MAAM,IAAI,IAAI,IAAI;GAClB,MAAM,IAAI,KAAK,IAAI;GACnB,MAAM,IAAI,KAAK,IAAI,IAAI;GACvB,MAAM,IAAI,KAAK,KAAK,IAAI,KAAK;GAU7B,MAAM,IAAI;IAPR;KAAC;KAAG;KAAG;IAAC;IACR;KAAC;KAAG;KAAG;IAAC;IACR;KAAC;KAAG;KAAG;IAAC;IACR;KAAC;KAAG;KAAG;IAAC;IACR;KAAC;KAAG;KAAG;IAAC;IACR;KAAC;KAAG;KAAG;IAAC;GAEG,CAAC,CAAC,IAAI;GAEnB,MAAM,KAAK,mBAAmB,IAAI;GAElC,MAAM,KAAK,MAAM,IAAI,KAAK,EAAE,IAAI,KAAK,EAAE,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK;GAC/D,IAAI,kBAAkB,GAAG,aAAa;GACtC,OAAO;EACT;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GACjD,OAAO,MAAM,SAAS,MAAM,SAAS,CAAC,GAAG,OAAO,gBAAgB;EAClE;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GACjD,OAAO,MAAM,SAAS,MAAM,SAAS,CAAC,GAAG,OAAO,gBAAgB;EAClE;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GACjD,OAAO,MAAM,SAAS,MAAM,SAAS,CAAC,GAAG,OAAO,gBAAgB;EAClE;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GACjD,OAAO,MAAM,SAAS,MAAM,SAAS,CAAC,GAAG,OAAO,gBAAgB;EAClE;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GACjD,OAAO,MAAM,SAAS,MAAM,SAAS,CAAC,GAAG,OAAO,gBAAgB;EAClE;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GACjD,OAAO,MAAM,SAAS,MAAM,SAAS,CAAC,GAAG,OAAO,gBAAgB;EAClE;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,CAAC,kBAAkB,IAAI,WAAW,IAAI,IAAI,MAAM;GAE1D,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,EAAE,KACA,EAAE,KAAK,SAAU,KAAK,KAAK,EAAE,KAAK,QAAS,OAAO,GAAG,IAAI,EAAE,KAAK;IAClE,EAAE,KAAK,EAAE,KAAK;GAChB;GAEA,MAAM,KAAK,MAAM,IACf,EAAE,KAAK,WAAY,EAAE,KAAK,WAAY,EAAE,KAAK,UAC7C,EAAE,KAAK,WAAY,EAAE,KAAK,WAAY,EAAE,KAAK,SAC7C,EAAE,KAAK,WAAY,EAAE,KAAK,UAAW,EAAE,KAAK,UAC5C,IAAI,KACN;GAEA,OAAO,mBAAmB,MAAM,SAAS,EAAE,IAAI;EACjD;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,kBAAkB,IAAI,WAAW,IAAI;GAExD,MAAM,MAAM;IACV,IAAI,qBACF,IAAI,sBACJ,IAAI;IACN,IAAI,qBACF,IAAI,qBACJ,IAAI;IACN,IAAI,sBACF,IAAI,qBACJ,IAAI;GACR;GAGA,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,IAAI,KACF,IAAI,KAAK,WACL,QAAQ,KAAK,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,OACpC,QAAQ,IAAI;IAClB,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,kBAAkB,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,GAAG;GACzD;GAEA,MAAM,KAAK,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK;GACtD,IAAI,kBAAkB,GAAG,aAAa;GACtC,OAAO;EACT;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,GAAG,IAAI,IAAI,MAAM;GAC3D,MAAM,MAAM,MAAM;GAClB,MAAM,MAAM,QAAQ;GAGpB,EAAE,OAAO,MAAM,GAAG;GAElB,MAAM,MAAM,MAAe,IAAI,MAAM,KAAK,KAAK,CAAC,KAAK,MAAM,IAAI,MAAM;GACrE,MAAM,KAAK,GAAG,EAAE,EAAE;GAElB,MAAM,KAAK,MAAM,IACf,MAAM,KAAK,IACX,OAAO,GAAG,EAAE,EAAE,IAAI,KAClB,OAAO,KAAK,GAAG,EAAE,EAAE,IACnB,IAAI,KACN;GACA,OAAO,mBAAmB,MAAM,SAAS,EAAE,IAAI;EACjD;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GACjD,MAAM,KAAK,EAAE,KAAK,MAAM;GACxB,MAAM,IAAI,EAAE,KAAK,MAAM;GACvB,MAAM,IAAI,IAAI,EAAE,KAAK;GACrB,MAAM,MAAM,MAAM;GAClB,MAAM,MAAM,QAAQ;GAEpB,MAAM,IAAI,MAAM;GAChB,MAAM,MAAM,KAAK,IAAI,GAAG,CAAC;GACzB,MAAM,MAAM,KAAK,IAAI,GAAG,CAAC;GAGzB,MAAM,KAAK,MAAM,IACf,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,IAAI,MAAM,MAC3C,EAAE,MAAM,EAAE,KAAK,MAAM,MAAM,KAAK,KAAK,EAAE,KAAK,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,MACnE,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,IAAI,MAAM,MAC3C,IAAI,KACN;GAEA,OAAO,mBAAmB,MAAM,SAAS,EAAE,IAAI;EACjD;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,IAAI,CAAC,GAAG,GAAG,KAAK,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GAEvD,MAAM,MAAM,IAAI,KAAK,IAAI,IAAI;GAC7B,MAAM,IAAI,QAAQ,IAAI,IAAK,IAAI,IAAK;GACpC,MAAM,IAAI,QAAQ,IAAI,IAAK,IAAI,IAAK;GAEpC,MAAM,MAAM,MAAM;GAClB,MAAM,MAAM,QAAQ;GACpB,IAAI,IAAI;GACR,MAAM,IAAI,IAAI,MAAM,MAAM,KAAK,KAAK,CAAC,IAAI,KAAK,MAAM;GAEpD,MAAM,OACH,IAAI,MAAM,IAAI,MACd,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI;GACpD,MAAM,OACH,IAAI,MAAM,IAAI,MACd,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI;GAEpD,MAAM,KAAK,MAAM,IACf,GACA,KAAK,KAAK,IAAI,OACd,KAAK,KAAK,IAAI,OACd,IAAI,KACN;GACA,OAAO,mBAAmB,MAAM,SAAS,EAAE,IAAI;EACjD;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,IAAI,CAAC,GAAG,GAAG,KAAK,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GAEvD,MAAM,MAAM,MAAM;GAClB,MAAM,MAAM,QAAQ;GAEpB,IAAI,MAAM,GAAG;IACX,MAAM,QAAQ,MAAM,IAAI,GAAG,GAAG,GAAG,IAAI,KAAK;IAC1C,OAAO,mBAAmB,MAAM,SAAS,KAAK,IAAI;GACpD;GAEA,MAAM,MAAM,IAAI,MAAM;GACtB,IAAI,IAAI,IAAI,MAAM,MAAM,KAAK,KAAK,KAAK,IAAI;GAE3C,MAAM,OACH,IAAI,MAAM,IAAI,MACd,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI;GACpD,MAAM,OACH,IAAI,MAAM,IAAI,MACd,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI;GAEpD,IAAI,KAAK,KAAK,KAAK;GACnB,IAAI,KAAK,KAAK,KAAK;GAEnB,IAAI,IAAI;GACR,MAAM,IAAK,MAAM,IAAI,IAAI,OAAQ,IAAI,KAAK,IAAI,IAAI;GAClD,MAAM,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM,IAAI;GAE9C,MAAM,KAAK,MAAM,IAAI,GAAG,GAAG,GAAG,IAAI,KAAK;GACvC,OAAO,mBAAmB,MAAM,SAAS,EAAE,IAAI;EACjD;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GACjD,MAAM,IAAI,KAAK,SAAS,KAAK,YAAY,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;GAChE,MAAM,KAAK,MAAM,IACf,EAAE,IACF,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,GACnC,GACA,IAAI,KACN;GACA,OAAO,mBAAmB,MAAM,SAAS,EAAE,IAAI;EACjD;EASA,OAAO,SACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GACjD,MAAM,MAAM,KAAK,SAAS,EAAE,EAAE;GAC9B,MAAM,KAAK,MAAM,IACf,EAAE,IACF,KAAK,IAAI,GAAG,IAAI,EAAE,IAClB,KAAK,IAAI,GAAG,IAAI,EAAE,IAClB,IAAI,KACN;GACA,OAAO,mBAAmB,MAAM,SAAS,EAAE,IAAI;EACjD;EASA,OAAO,WACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,CAAC,kBAAkB,IAAI,WAAW,IAAI;GAChD,MAAM,OAAO,MACX,IAAI,SAAU,KAAK,KAAK,IAAI,QAAS,OAAO,GAAG,IAAI,IAAI;GACzD,MAAM,IAAI,IAAI,EAAE,EAAE;GAClB,MAAM,IAAI,IAAI,EAAE,EAAE;GAClB,MAAM,IAAI,IAAI,EAAE,EAAE;GAGlB,MAAM,IAAI,KAAK,KAAK,cAAe,IAAI,cAAe,IAAI,cAAe,CAAC;GAC1E,MAAM,IAAI,KAAK,KAAK,cAAe,IAAI,cAAe,IAAI,cAAe,CAAC;GAC1E,MAAM,IAAI,KAAK,KAAK,cAAe,IAAI,cAAe,IAAI,cAAe,CAAC;GAE1E,MAAM,KAAK,MAAM,MACf,cAAe,IAAI,aAAc,IAAI,cAAe,GACpD,eAAe,IAAI,cAAc,IAAI,cAAe,GACpD,cAAe,IAAI,cAAe,IAAI,aAAc,GACpD,IAAI,KACN;GACA,OAAO,mBAAmB,MAAM,SAAS,EAAE,IAAI;EACjD;EASA,OAAO,WACL,OACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,KAAK,IAAI;GAEnD,MAAM,KAAK,EAAE,KAAK,cAAe,EAAE,KAAK,cAAe,EAAE;GACzD,MAAM,KAAK,EAAE,KAAK,cAAe,EAAE,KAAK,cAAe,EAAE;GACzD,MAAM,KAAK,EAAE,KAAK,cAAe,EAAE,KAAK,cAAc,EAAE;GACxD,MAAM,IAAI,KAAK,KAAK;GACpB,MAAM,IAAI,KAAK,KAAK;GACpB,MAAM,IAAI,KAAK,KAAK;GAEpB,MAAM,MAAM;IACV,eAAe,IAAI,eAAe,IAAI,cAAe;IACrD,gBAAgB,IAAI,eAAe,IAAI,cAAe;IACtD,eAAgB,IAAI,cAAe,IAAI,cAAc;GACvD;GAEA,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,IAAI,KACF,IAAI,KAAK,WACL,QAAQ,KAAK,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,OACpC,QAAQ,IAAI;IAClB,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,kBAAkB,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,GAAG;GACzD;GAEA,MAAM,KAAK,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,MAAM,KAAK;GACxD,IAAI,kBAAkB,GAAG,aAAa;GACtC,OAAO;EACT;EASA,OAAO,WACL,KACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,GAAG,IAAI;GACjD,OAAO,MAAM,aAAa,MAAM,WAAW,CAAC,GAAG,OAAO,gBAAgB;EACxE;EASA,OAAO,WACL,OACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,KAAK,IAAI;GACnD,OAAO,MAAM,WAAW,MAAM,aAAa,CAAC,GAAG,OAAO,gBAAgB;EACxE;EASA,OAAO,aACL,OACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,KAAK,IAAI;GACnD,MAAM,IAAI,KAAK,SAAS,KAAK,YAAY,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;GAChE,MAAM,KAAK,MAAM,MACf,EAAE,IACF,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,GACnC,GACA,MAAM,KACR;GACA,OAAO,mBAAmB,MAAM,SAAS,EAAE,IAAI;EACjD;EASA,OAAO,aACL,OACA,kBAA2B,OAC3B,mBAA4B,OACrB;GACP,MAAM,IAAI,kBAAkB,MAAM,QAAQ,KAAK,IAAI;GACnD,MAAM,MAAM,KAAK,SAAS,EAAE,EAAE;GAC9B,MAAM,KAAK,MAAM,MACf,EAAE,IACF,KAAK,IAAI,GAAG,IAAI,EAAE,IAClB,KAAK,IAAI,GAAG,IAAI,EAAE,IAClB,MAAM,KACR;GACA,OAAO,mBAAmB,MAAM,SAAS,EAAE,IAAI;EACjD;CACF;CAlkCE,MAAe,MAAc,IAAI,GAAG,QAAQ,KAAK,SAAS,CAAC;CAQ3D,MAAO,SAAoC;EACzC,KAAK,IAAI,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC;EAC7D,KAAK,IAAI,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;EACzD,KAAK,IAAI,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;EACzD,KAAK,IAAI,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,MAAM,GAAG,GAAG,IAAI,GAAG,MAAM,GAAG,CAAC;EACnE,KAAK,IAAI,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC;EAC7D,KAAK,IAAI,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,MAAM,GAAG,GAAG,IAAI,GAAG,MAAM,GAAG,CAAC;EACnE,KAAK,IAAI,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC;EAC7D,OAAO,IAAI,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,KAAM,EAAG,GAAG,IAAI,GAAG,KAAM,EAAG,CAAC;EACnE,OAAO,IAAI,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,EAAG,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC;CAC/D;;;;;;;;;CCJF,IAAa,WAAb,MAAa,iBAAiB,gBAAgB;EAuB5C,YACE,OAAgC,MAChC,UACA;GACA,MAAM;GAvBR,UAAa;GACb,KAAU,cAAc;GACxB,KAAU,WAAW;GACrB,KAAU,OAAO,CAAC;GAClB,KAAQ,eAAe;GAGvB,KAAQ,iBAAiB;GAIzB,KAAiB,sBAAsB,KAAK,eAAe,KAAK,IAAI;GAalE,KAAK,QAAQ,KAAK;GAElB,IAAI,YAA4B;GAChC,KAAK,KAAK;GAGV,IAAI,gBAAgB,SAAS;IAC3B,YAAY;IACZ,KAAK,KAAK;GACZ,OAAO;IACL,MAAM,SAAS,QAAQ;IACvB,MAAM,KAAK,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM,SAAS,MAAM;IACnE,YAAY,SAAS,cAAc,EAAE;IACrC,KAAK,KAAK,GAAG,OAAO,CAAC;GACvB;GAGA,IAAI,CAAC,WAAW;IACd,KAAK,aAAa,SAAS,cAAc,OAAO,KAAK,KAAK,YAAY;IACtE,KAAK,UAAU,KAAK,sBAAsB,KAAK,YAAY,KAAK,EAAE;IAClE,SAAS,KAAK,YAAY,KAAK,UAAU;IACzC,KAAK,iBAAiB;GACxB,OAAO;IACL,KAAK,UAAU;IACf,KAAK,aAAa,UAAU;GAC9B;GAGA,KAAK,cAAc,WAAW,KAAK,OAAO,KAAK,MAAM,QAAQ,GAAG,EAAE;EACpE;EAQA,AAAU,sBACR,WACA,IAC0B;GAC1B,OAAO,SAAS,cAAc,OAAO,IAAI,SAAS;EACpD;EAQA,OAAO,cACL,OAAe,OACf,IACA,UACS;GACT,IAAI,IAAI,SAAS,cAAc,IAAI;GACnC,IAAI,IAAI,EAAE,aAAa,MAAM,EAAE;GAC/B,IAAI,YAAY,SAAS,aAAa,SAAS,YAAY,CAAC;GAC5D,OAAO;EACT;EAMA,AAAQ,OAAO,UAAkD;GAC/D,IAAI,KAAK,cAAc;GACvB,IAAI,CAAC,KAAK,YACR,MAAM,IAAI,MAAM,oBAAoB,KAAK,GAAG,SAAS;GAEvD,KAAK,WAAW;GAEhB,KAAK,eAAe,IAAI;GACxB,KAAK,MAAM,KAAK,QAAQ;GACxB,KAAK,QAAQ,cAAc,IAAI,MAAM,OAAO,CAAC;GAE7C,KAAK,IAAI,KAAK,KAAK,SACjB,IAAI,KAAK,QAAQ,eAAe,CAAC,GAC/B;QAAI,KAAK,QAAQ,EAAE,CAAC,OAClB,KAAK,QAAQ,EAAE,CAAC,MAAM,KAAK,MAAM,MAAM,GAAG,IAAI;GAAC;GAIrD,KAAK,WAAW,KAAK;GAErB,IAAI,UAAU,SAAS,KAAK,OAAO,KAAK,OAAO;EACjD;EAOA,MAAM,KAAmD;GACvD,IAAI,IAAI,SACN,KAAK,WAAW,IAAI;GAGtB,KAAK,aAAa,IAAI,UAAU,SAAY,IAAI,SAAS;GAEzD,OAAO;EACT;EAKA,UAAgB;GACd,OAAO;EACT;EAMA,IAAI,WAAW,MAAe;GAC5B,KAAK,cAAc;GACnB,IAAI,MACF,OAAO,iBAAiB,UAAU,KAAK,mBAAmB;QACrD;IACL,OAAQ,KAAK,KAAa;IAC1B,OAAQ,KAAK,KAAa;IAC1B,OAAO,oBAAoB,UAAU,KAAK,mBAAmB;GAC/D;EACF;EACA,IAAI,aAAsB;GACxB,OAAO,KAAK;EACd;EAOA,OAAO,GAAU,KAA0B;GACzC,KAAK,QAAQ;GACb,KAAK,OAAO;IAAE,OAAO,GAAG,EAAE,MAAM;IAAK,QAAQ,GAAG,EAAE,OAAO;GAAI,GAAG,IAAI;GAEpE,KAAK,IAAI,KAAK,KAAK,SACjB,IAAI,KAAK,QAAQ,eAAe,CAAC,GAAG;IAClC,IAAI,IAAI,KAAK,QAAQ;IACrB,IAAI,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,GAAG;GACxC;GAGF,OAAO;EACT;EAMA,AAAU,eAAe,KAAmB;GAC1C,IAAI,IAAI,MAAM,iBAAiB,KAAK,WAAW,sBAAsB,CAAC;GAEtE,IAAI,KAAK,aACP,KAAK,OAAO;IAAE,OAAO;IAAQ,QAAQ;GAAO,GAAG,IAAI;QAEnD,KAAK,OAAO;IAAE,OAAO,GAAG,EAAE,MAAM;IAAK,QAAQ,GAAG,EAAE,OAAO;GAAI,GAAG,IAAI;GAGtE,KAAK,OAAO,GAAG,GAAG;EACpB;EAKA,IAAI,UAAmB;GACrB,OAAO,KAAK;EACd;EAKA,IAAI,SAAkB;GACpB,OAAO,KAAK;EACd;EAKA,IAAI,QAAiB;GACnB,OAAO,KAAK;EACd;EAMA,MAAM,IAAmB;GACvB,IAAI,IAAI,KAAK,aAAa;GAC1B,KAAK,QAAQ,YAAY;GACzB,OAAO;EACT;EAMA,IAAI,WAAW,IAAY;GACzB,KAAK,WAAW;GAChB,AAAC,KAAK,WAA2B,MAAM,kBAAkB,KAAK;EAChE;EACA,IAAI,aAAqB;GACvB,OAAO,KAAK;EACd;EAQA,MAAM,KAAa,KAAa,SAAkB,OAAa;GAC7D,AAAC,KAAK,KAAa,OAAO;GAC1B,IAAI,QAAQ,AAAC,KAAK,QAAQ,MAAc,OAAO;GAC/C,OAAO;EACT;EAQA,OAAO,QAAgC,SAAkB,OAAa;GACpE,KAAK,IAAI,KAAK,QACZ,IAAI,OAAO,eAAe,CAAC,GAAG,KAAK,MAAM,GAAI,OAAe,IAAI,MAAM;GAExE,OAAO;EACT;EAQA,OAAO,QAAQ,MAAe,MAAoC;GAChE,KAAK,IAAI,KAAK,MACZ,IAAI,KAAK,eAAe,CAAC,GACvB,KAAK,aAAa,GAAI,KAAa,EAAE;GAGzC,OAAO;EACT;EAOA,OAAO,gBAAgB,MAAmC;GACxD,IAAI,MAAM;GACV,KAAK,IAAI,KAAK,MACZ,IAAI,KAAK,eAAe,CAAC,GACvB;QAAK,KAAa,IAAI,OAAO,GAAG,EAAE,IAAK,KAAa,GAAG;GAAG;GAG9D,OAAO;EACT;EAOA,UAAgB;GACd,IAAI,KAAK,cAAc,OAAO;GAC9B,KAAK,eAAe;GACpB,aAAa,KAAK,WAAW;GAE7B,KAAK,aAAa;GAClB,KAAK,WAAW;GAChB,KAAK,iBAAiB;GAKtB,gBAAgB,UAAU,UAAU,KAAK,IAAI;GAC7C,KAAK,WAAW;GAEhB,IAAI,KAAK,gBAAgB,KAAK,WAAW,OAAO;GAEhD,OAAO;EACT;CACF;CAMA,IAAa,YAAb,cAA+B,SAAS;EAKtC,UAAgB;GACd,OAAO,IAAI,SAAS,IAAI;EAC1B;EASA,OAAO,YACL,QACA,MACA,IACA,YAAqB,MACR;GACb,IAAI,CAAC,UAAU,CAAC,OAAO,aACrB,MAAM,IAAI,MAAM,mCAAmC;GAIrD,IAAI,OAAuB,SAAS,eAAe,EAAG;GACtD,IAAI,QAAQ,CAAC,OAAO,SAAS,IAAI,GAAG,OAAO;GAC3C,IAAI,CAAC,MAAM;IACT,OAAO,SAAS,cAAc,IAAI;IAClC,KAAK,aAAa,MAAM,EAAG;IAE3B,IAAI,WACF,KAAK,aAAa,SAAS,GAAI,UAAU,GAAG,GAAI,QAAQ,GAAG,CAAC,CAAC;IAC/D,OAAO,YAAY,IAAI;GACzB;GACA,OAAO;EACT;EAMA,OAAO,QAAuB;GAG5B,AAFW,KAAK,WAAW,iBAAiB,MAAM,SAAS,QAAQ,MAAM,CAEtE,CAAC,CAAC,SAAS,OAAgB;IAC5B,GAAG,WAAY,YAAY,EAAE;GAC/B,CAAC;GAED,OAAO,MAAM,OAAO,MAAM;EAC5B;EAMA,YAAkB;GAChB,KAAK,QAAQ,YAAY;GACzB,OAAO,MAAM,UAAU;EACzB;CACF;CAEA,IAAI,mBAAmB;CACvB,IAAI,iBAAiB;CAMrB,IAAa,WAAb,MAAa,iBAAiB,WAAW;EAgCvC,WAAW,UAAkB;GAC3B,OAAO;EACT;EACA,WAAW,QAAQ,GAAW;GAC5B,mBAAmB;EACrB;EACA,WAAW,QAAgB;GACzB,OAAO;EACT;EACA,WAAW,MAAM,GAAW;GAC1B,iBAAiB;EACnB;EAUA,YAAY,OAAkB;GAC5B,MAAM;GAlDR,KAAU,SAAS;IACjB,QAAQ;IACR,SAAS;IACT,YAAY;IACZ,gBAAgB;IAChB,OAAO;IACP,gBAAgB;IAChB,iBAAiB;IACjB,gBAAgB;IAChB,SAAS;IACT,UAAU;IACV,KAAK;IACL,MAAM;IACN,OAAO;IACP,QAAQ;GACV;GAEA,KAAU,OAAuB;IAC/B,OAAO;IACP,SAAS;IACT,YAAY;IACZ,WAAW;IACX,cAAc;IACd,OAAO,CAAC;GACV;GAkBA,KAAU,SAAkB;GAC5B,KAAU,UAAkB;GAQ1B,KAAK,SAAS;GACd,KAAK,UAAU,SAAS;GAExB,MAAM,aAAa;IACjB,KAAK,KAAK,QAAQ,KAAK,OAAO;IAC9B,KAAK,KAAK,UAAU,WAAW,KAAK;IACpC,KAAK,KAAK,QAAQ,OAAO,OAAO,CAAC,GAAG,KAAK,MAAM;IAC/C,KAAK,SAAS;GAChB;GAGA,IAAI,KAAK,OAAO,OAAO,KAAK;QACvB,KAAK,OAAO,IAAI,EAAE,OAAO,KAAK,CAAC;EACtC;EAKA,IAAI,QAAmB;GACrB,OAAO,KAAK;EACd;EAQA,AAAU,QAAQ,GAAW,GAAQ,OAAe,IAAI;GACtD,IAAK,KAAK,KAAK,MAAc,OAAO,QAClC,MAAM,IAAI,MAAM,GAAG,EAAE,8BAA8B;GACrD,KAAK,KAAK,MAAM,KAAK,GAAG,IAAI;EAC9B;EAOA,MAAM,GAAiB;GACrB,KAAK,QAAQ,WAAW,CAAC;GACzB,OAAO;EACT;EAOA,KAAK,GAA2B;GAC9B,IAAI,OAAO,KAAK,WAAW;IACzB,KAAK,QAAQ,UAAU,CAAC;IACxB,IAAI,CAAC,GAAG,KAAK,QAAQ,cAAc,aAAa;GAClD,OAAO;IACL,KAAK,QAAQ,UAAU,IAAI;IAC3B,KAAK,QAAQ,cAAc,CAAC;GAC9B;GACA,OAAO;EACT;EAUA,OACE,GACA,OACA,UACA,SACM;GACN,IAAI,OAAO,KAAK,WAAW;IACzB,KAAK,QAAQ,WAAW,CAAC;IACzB,IAAI,CAAC,GAAG,KAAK,QAAQ,gBAAgB,CAAC;GACxC,OAAO;IACL,KAAK,QAAQ,WAAW,IAAI;IAC5B,KAAK,QAAQ,gBAAgB,CAAC;IAC9B,KAAK,QAAQ,iBAAiB,SAAS,KAAK,IAAI;GAClD;GACA,OAAO;EACT;EAOA,SAAS,GAAiB;GACxB,KAAK,QAAQ,SAAS,CAAC;GACvB,OAAO;EACT;EAOA,IAAI,GAAqB;GACvB,IAAI,OAAO,KAAK,WACd,KAAK,KAAK,eAAe;QAEzB,KAAK,KAAK,eAAe;GAE3B,OAAO;EACT;EAWA,KACE,YACA,QACA,OACA,YACA,QACM;GACN,IAAI,OAAO,cAAc,UAAU;IACjC,KAAK,MAAM,OAAO;IAClB,IAAI,QAAQ,KAAK,MAAM,OAAO;IAC9B,IAAI,QAAQ,KAAK,MAAM,SAAS;IAChC,IAAI,OAAO,KAAK,MAAM,QAAQ;IAC9B,IAAI,YAAY,KAAK,MAAM,aAAa;GAC1C,OACE,KAAK,QAAQ;GAGf,KAAK,KAAK,MAAM,UAAU,KAAK,MAAM;GAErC,OAAO;EACT;EAKA,QAAc;GACZ,KAAK,KAAK,QAAQ,OAAO,OAAO,CAAC,GAAG,KAAK,MAAM;GAE/C,KAAK,QAAQ,IAAI,KAAK,IAAI,YAAY;GACtC,KAAK,KAAK,MAAM,UAAU,KAAK,MAAM;GAErC,OAAO;EACT;EAQA,YAAY,UAAkB,OAAiC;GAC7D,KAAK,KAAK,QAAQ;GAClB,KAAK,KAAK,UAAU;GACpB,KAAK,KAAK,aAAa;GACvB,KAAK,OAAO;GACZ,OAAO,KAAK;EACd;EAOA,MAAM,MAAe;GACnB,IAAI,CAAC,QAAQ,KAAK,aAAa,MAC7B,MAAM,IAAI,MAAM,4CAA4C;GAE9D,OAAO,KAAK,YACV,GAAG,SAAS,QAAQ,IAAI,EAAE,IAAI,KAAK,WACnC,KAAK,MAAM,OACb;EACF;EAMA,SAAiB;GACf,KAAK,KAAK;GACV,KAAK,KAAK,YAAY,GAAG,KAAK,KAAK,QAAQ,GAAG,KAAK,KAAK;GACxD,OAAO,KAAK,KAAK;EACnB;EAMA,OAAO,MAAM,KAA6B;GACxC,OAAO,IAAI,aAAa,KAAK,SAAS;EACxC;EAMA,OAAO,QAAQ,MAAuB;GACpC,OAAO,QAAQ,KAAK;EACtB;EASA,OAAO,MAAM,MAAe,QAAsC;GAChE,IAAI,KAAK,CAAC;GAEV,IAAI,CAAC,OAAO,WAAW,GAAG,KAAK,kBAAkB;GACjD,IAAI,CAAC,OAAO,YAAY,GAAG,KAAK,cAAc;GAE9C,KAAK,IAAI,KAAK,QACZ,IAAI,OAAO,eAAe,CAAC,KAAK,KAAK,YAAY,KAAK,WAAW;IAC/D,IAAI,IAAI,OAAO;IACf,IAAI,GAAG;KACL,IAAI,CAAC,OAAO,aAAa,EAAE,QAAQ,YAAY,MAAM,GACnD;UACK,IAAI,CAAC,OAAO,cAAc,EAAE,QAAQ,cAAc,MAAM,GAC7D;UAEA,GAAG,KAAK,GAAG,EAAE,IAAI,GAAG;IAExB;GACF;GAGF,OAAO,UAAU,QAAQ,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,EAAE,CAAC;EACxD;EAQA,OAAO,UACL,KACA,IACA,MACgB;GAChB,IAAI,MAAM,UAAU,GAAG,KAAK;GAC5B,IAAI,MAAM,SAAS,GAAG,KAAK;GAC3B,IAAI,MAAM,WAAW,KAAK,KAAK;GAC/B,IAAI,MAAM,YAAY,KAAK,KAAK;GAChC,OAAO;EACT;EAOA,OAAO,UAAU,KAAqB,IAA4B;GAChE,IAAI,MAAM,UAAU,GAAG,KAAK;GAC5B,IAAI,MAAM,SAAS,GAAG,KAAK;GAC3B,OAAO;EACT;EAUA,OAAO,MACL,KACA,IACA,SAAiB,GACjB,QAAgB,UACP;GACT,IAAI,UAAU,UACZ,OAAO,SAAS,OAAO,KAAK,IAAI,MAAM;QAEtC,OAAO,SAAS,OAAO,KAAK,IAAI,MAAM;EAE1C;EASA,MAAM,IAAY,SAAiB,GAAG,QAAgB,UAAgB;GACpE,KAAK,OAAO;GAEZ,KAAK,QAAQ,iBAAiB,SAAS,WAAW,SAAS,GAAG;GAC9D,SAAS,MAAM,KAAK,MAAM,IAAI,QAAQ,KAAK;GAC3C,OAAO;EACT;EAQA,OAAO,OAAO,KAAqB,IAAY,SAAiB,IAAa;GAC3E,IAAI,OAAO,UAAU,YAAY,IAAI,OAAO,OAAO,SAAS,MAAM,GAAG,CAAC;GACtE,UAAU,QAAQ,MAAM,EACtB,OAAO,uBAAuB,IAAI,eACpC,CAAC;GACD,SAAS,UACP,KACA,IAAI,GAAG,EAAE,CAAC,CAAC,UAAU,MAAM,GAC3B,IAAI,GAAG,SAAS,GAAG,SAAS,CAAC,CAC/B;GACA,SAAS,MAAM,MAAM,IAAI,KAAK;GAC9B,OAAO;EACT;EAOA,OAAO,KAAmC;GACxC,KAAK,OAAO;GACZ,KAAK,QAAQ,iBAAiB,MAAM;GACpC,SAAS,OAAO,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC,EAAE;GAC5C,OAAO;EACT;EAQA,OAAO,OAAO,KAAqB,IAAY,UAAkB;GAC/D,IAAI,OAAO,UAAU,YAAY,IAAI,OAAO,OAAO,SAAS,MAAM,GAAG,CAAC;GACtE,UAAU,QAAQ,MAAM,EACtB,OAAO,uBAAuB,IAAI,eACpC,CAAC;GACD,SAAS,UACP,KACA,IAAI,GAAG,EAAE,CAAC,CAAC,UAAU,QAAQ,GAC7B,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,CACnC;GACA,SAAS,MAAM,MAAM,IAAI,KAAK;GAC9B,OAAO;EACT;EAOA,OAAO,IAAY,UAAwB;GACzC,KAAK,OAAO;GACZ,KAAK,QAAQ,iBAAiB,GAAG;GACjC,SAAS,OAAO,KAAK,MAAM,IAAI,QAAQ;GACvC,OAAO;EACT;EAOA,OAAO,KAAK,KAAqB,KAA0C;GACzE,IAAI,IAAI,KAAK,YAAY,GAAG;GAC5B,IAAI,CAAC,KAAK,WAAW,CAAC,GAAG;GAEzB,IAAI,OAAO,UAAU,YAAY,IAAI,OAAO,OAAO,SAAS,MAAM,GAAG,CAAC;GACtE,UAAU,QAAQ,MAAM,EAAE,OAAO,qBAAqB,IAAI,eAAe,CAAC;GAC1E,SAAS,UAAU,KAAK,EAAE,IAAI,EAAE,EAAE;GAClC,SAAS,MAAM,MAAM,IAAI,KAAK;GAC9B,OAAO;EACT;EAMA,KAAK,KAA2B;GAC9B,KAAK,OAAO;GACZ,KAAK,QAAQ,iBAAiB,GAAG;GACjC,SAAS,KAAK,KAAK,MAAM,GAAG;GAC5B,OAAO;EACT;EAQA,OAAO,KAAK,KAAqB,IAAY,KAAsB;GACjE,IAAI,OAAO,UAAU,YAAY,IAAI,OAAO,OAAO,SAAS,MAAM,GAAG,CAAC;GAEtE,UAAU,QAAQ,MAAM,EAAE,OAAO,qBAAqB,IAAI,eAAe,CAAC;GAE1E,KAAK,cAAc;GACnB,SAAS,UAAU,KAAK,EAAE;GAC1B,SAAS,MAAM,MAAM,IAAI,KAAK;GAE9B,OAAO;EACT;EAOA,KAAK,IAAY,KAAmB;GAClC,KAAK,OAAO;GACZ,SAAS,KAAK,KAAK,MAAM,IAAI,GAAG;GAChC,OAAO;EACT;EAMA,IAAI,KAAgB;GAClB,KAAK,KAAK,MAAM,CAAC,CAAC,OAAO,QAAQ,EAAG,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,GAAG;GACxD,OAAO;EACT;EAKA,IACE,IACA,QACA,YACA,UACA,IACM;GACN,KAAK,KAAK,oCAAoC;GAC9C,OAAO;EACT;EAKA,KAAK,KAAmC;GACtC,KAAK,KAAK,qCAAqC;GAC/C,OAAO;EACT;EAMA,QAAQ,KAAmC;GACzC,KAAK,KAAK,wCAAwC;GAClD,OAAO;EACT;CACF;;;;;;;;;CC15BA,MAAM,SAAS;CAIf,MAAM,8BAAc,IAAI,IAAI;EAC1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAID,IAAI,iBAAiB;CAOrB,IAAM,cAAN,MAAkB;EAOhB,YAAY,MAA2B,QAAkB;GAHzD,aAA4B,CAAC;GAC7B,KAAU,QAA2B;GAGnC,KAAK,OAAO;GACZ,KAAK,SAAS;GACd,KAAK,KAAK,YAAY;EACxB;EAEA,aAAa,QAAgB,OAAqB;GAChD,KAAK,MAAM,KAAK,CAAC,QAAQ,KAAK,CAAC;GAC/B,IAAI,KAAK,OAAO,KAAK,QAAQ,KAAK,KAAK;EACzC;EAGA,YAAY,MAA0B;GACpC,IAAI,CAAC,KAAK,OAAO;IACf,KAAK,QAAQ,SAAS,gBACpB,QACA,KAAK,SAAS,WAAW,mBAAmB,gBAC9C;IACA,KAAK,MAAM,aAAa,MAAM,KAAK,EAAE;IACrC,KAAK,MAAM,aAAa,iBAAiB,gBAAgB;IACzD,IAAI,KAAK,SAAS,UAAU;KAC1B,MAAM,CAAC,IAAI,IAAI,IAAI,MAAM,KAAK;KAC9B,SAAS,QAAQ,KAAK,OAAO;MAAE;MAAI;MAAI;MAAI;KAAG,CAAC;IACjD,OAAO;KACL,MAAM,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,MAAM,KAAK;KACtC,SAAS,QAAQ,KAAK,OAAO;MAAE,IAAI;MAAI,IAAI;MAAI,GAAG;MAAI,IAAI;MAAI,IAAI;KAAG,CAAC;KACtE,IAAI,IAAI,KAAK,MAAM,aAAa,MAAM,GAAG,IAAI;IAC/C;IACA,KAAK,QAAQ,KAAK,KAAK;GACzB;GACA,IAAI,KAAK,MAAM,eAAe,MAAM,KAAK,YAAY,KAAK,KAAK;GAC/D,OAAO,QAAQ,KAAK,GAAG;EACzB;EAEA,AAAU,QAAQ,MAAkB;GAClC,KAAK,cAAc;GACnB,KAAK,MAAM,CAAC,QAAQ,UAAU,KAAK,OAAO;IACxC,MAAM,OAAO,SAAS,gBAAgB,QAAQ,MAAM;IACpD,KAAK,aAAa,UAAU,GAAG,QAAQ;IACvC,KAAK,aAAa,cAAc,KAAK;IACrC,KAAK,YAAY,IAAI;GACvB;EACF;CACF;CAWA,IAAI,eAAgD;CACpD,MAAM,aAAuC,CAAC;CAoC9C,IAAa,eAAb,MAAa,aAAa;EA2CxB,YAAY,MAAkB;GAzC9B,iBAAkC;GAClC,mBAAoC;GACpC,iBAAoB;GACpB,gBAAmB;GACnB,eAAkB;GAClB,mBAAsB;GACtB,gCAAmC;GACnC,YAAe;GACf,iBAAoB;GACpB,oBAAuB;GACvB,sBAAyB;GAEzB,KAAU,QAAkB,CAAC;GAC7B,KAAU,cAAwB,CAAC;GAGnC,iBAAoB;GAGpB,KAAU,KAAa;GACvB,KAAU,aAA4B;GACtC,KAAU,eAA8B;GACxC,KAAU,oBAAqD,CAAC;GAChE,KAAU,gBAAyB;GAGnC,KAAU,cAAsB;GAChC,KAAU,cAAsB;GAChC,KAAU,cAAsB;GAGhC,KAAU,QAAkB,CAAC;GAC7B,KAAU,aAAqB;GAI/B,KAAU,SAA4B;GACtC,KAAU,QAA2B;GACrC,KAAU,QAAsB,CAAC;GACjC,KAAU,aAAuC,CAAC;GAGhD,KAAK,QAAQ;EACf;EAEA,OAAiB,UAAU,KAAa,KAAa;GACnD,IAAI,CAAC,WAAW,MAAM;IACpB,WAAW,OAAO;IAClB,KAAK,KAAK,GAAG;GACf;EACF;EAKA,aAAmB;GACjB,KAAK,QAAQ,CAAC;GACd,KAAK,KAAK;GACV,KAAK,aAAa;GAClB,KAAK,eAAe;GACpB,KAAK,gBAAgB;GACrB,KAAK,aAAa;EACpB;EAGA,IAAI,YAAoB;GACtB,OAAO,KAAK;EACd;EAGA,IAAI,QAA2B;GAC7B,OAAO,KAAK;EACd;EAMA,cAAoB;GAClB,KAAK,YAAY;GACjB,IAAI,CAAC,KAAK,QAAQ;IAChB,KAAK,SAAS,SAAS,gBAAgB,QAAQ,GAAG;IAClD,KAAK,OAAO,aAAa,SAAS,aAAa;IAC/C,KAAK,MAAM,YAAY,KAAK,MAAM;GACpC;GAEA,MAAM,OAAO,KAAK;GAClB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;IACpC,MAAM,MAAM,KAAK;IACjB,IAAI,OAAO,KAAK,MAAM;IACtB,IAAI,CAAC,QAAQ,KAAK,aAAa,IAAI,KAAK;KACtC,MAAM,QAAQ,SAAS,gBAAgB,QAAQ,IAAI,GAAG;KACtD,IAAI,MACF,KAAK,OAAO,aAAa,OAAO,IAAI;UAEpC,KAAK,OAAO,YAAY,KAAK;KAE/B,OAAO;KACP,KAAK,MAAM,KAAK;KAChB,KAAK,WAAW,KAAK,CAAC;IACxB;IACA,MAAM,QAAQ,KAAK,WAAW;IAG9B,KAAK,MAAM,KAAK,OACd,IAAI,EAAE,KAAK,IAAI,QAAQ;KACrB,KAAK,gBAAgB,CAAC;KACtB,OAAO,MAAM;IACf;IAEF,KAAK,MAAM,KAAK,IAAI,OAAO;KACzB,MAAM,IAAI,GAAG,IAAI,MAAM;KACvB,IAAI,MAAM,OAAO,GAAG;MAClB,KAAK,aAAa,GAAG,CAAC;MACtB,MAAM,KAAK;KACb;IACF;IACA,IAAI,IAAI,QAAQ,UAAU,KAAK,gBAAgB,IAAI,MACjD,KAAK,cAAc,IAAI;GAE3B;GAGA,KAAK,IAAI,IAAI,KAAK,MAAM,SAAS,GAAG,KAAK,KAAK,QAAQ,KAAK;IACzD,KAAK,OAAO,YAAY,KAAK,MAAM,EAAE;IACrC,KAAK,MAAM,IAAI;IACf,KAAK,WAAW,IAAI;GACtB;GAIA,IAAI,KAAK,OAAO;IACd,MAAM,yBAAS,IAAI,IAAqB;IACxC,KAAK,MAAM,OAAO,MAAM;KACtB,OAAO,IAAI,IAAI,MAAM,IAAI;KACzB,OAAO,IAAI,IAAI,MAAM,MAAM;IAC7B;IACA,KAAK,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,QAAQ,GAC/C,IAAI,CAAC,OAAO,IAAI,QAAQ,KAAK,GAAG,EAAE,GAAG,KAAK,OAAO;GAErD;EACF;EAGA,IAAI,OAAiB;GACnB,OAAO,KAAK;EACd;EAGA,WAAiB;GACf,KAAK,SAAS;GACd,KAAK,QAAQ;GACb,KAAK,QAAQ,CAAC;GACd,KAAK,aAAa,CAAC;EACrB;EAMA,aAAmB;GACjB,IAAI,KAAK,UAAU,KAAK,OAAO,YAC7B,KAAK,OAAO,WAAW,YAAY,KAAK,MAAM;GAEhD,IAAI,KAAK,SAAS,KAAK,MAAM,YAC3B,KAAK,MAAM,WAAW,YAAY,KAAK,KAAK;GAE9C,KAAK,SAAS;EAChB;EAIA,YAAkB;GAChB,KAAK,YAAY;GACjB,KAAK,KAAK;EACZ;EAEA,YAAkB;GAChB,KAAK,MAAM;EACb;EAEA,OAAO,GAAW,GAAiB;GACjC,KAAK,MAAM,IAAI,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC;EACtC;EAEA,OAAO,GAAW,GAAiB;GACjC,KAAK,MAAM,IAAI,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC;EACtC;EAEA,iBAAiB,KAAa,KAAa,GAAW,GAAiB;GACrE,KAAK,MAAM,IAAI,OAAO,GAAG,EAAE,GAAG,OAAO,GAAG,EAAE,GAAG,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC;EACpE;EAEA,cACE,MACA,MACA,MACA,MACA,GACA,GACM;GACN,KAAK,MAAM,IAAI,OAAO,IAAI,EAAE,GAAG,OAAO,IAAI,EAAE,GAAG,OAAO,IAAI,EAAE,GAAG,OAAO,IAAI,EAAE,GAAG,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC;EACtG;EAEA,KAAK,GAAW,GAAW,GAAW,GAAiB;GACrD,KAAK,MAAM,IAAI,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE;EAChF;EAEA,IACE,GACA,GACA,QACA,YACA,UACA,MAAe,OACT;GACN,KAAK,QAAQ,GAAG,GAAG,QAAQ,QAAQ,GAAG,YAAY,UAAU,GAAG;EACjE;EAEA,QACE,GACA,GACA,IACA,IACA,UACA,YACA,UACA,MAAe,OACT;GAGN,IAAI,QAAQ,MAAM,aAAa,WAAW,WAAW;GACrD,MAAM,OAAO,SAAS,MAAM;GAC5B,IAAI,CAAC,MAAM,SAAU,QAAQ,MAAM,SAAU,MAAM,UAAU,MAAM;GAEnE,MAAM,OAAO,KAAK,IAAI,QAAQ;GAC9B,MAAM,OAAO,KAAK,IAAI,QAAQ;GAC9B,MAAM,QAAQ,UAAoC;IAChD,MAAM,KAAK,KAAK,KAAK,IAAI,KAAK;IAC9B,MAAM,KAAK,KAAK,KAAK,IAAI,KAAK;IAC9B,OAAO,CAAC,IAAI,KAAK,OAAO,KAAK,MAAM,IAAI,KAAK,OAAO,KAAK,IAAI;GAC9D;GAEA,MAAM,MAAM,MAAM,KAAK;GACvB,MAAM,YAAY,MAAM,IAAI;GAC5B,MAAM,SAAS,OAAQ,WAAW,MAAO,KAAK,EAAE;GAChD,MAAM,CAAC,IAAI,MAAM,KAAK,UAAU;GAGhC,KAAK,MACH,KAAK,GAAG,SAAS,IACb,IAAI,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,MAC3B,IAAI,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE;GAGjC,MAAM,QAAQ,OAAO,MAAM,SAAS;GACpC,MAAM,WAAW,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,MAAM,KAAK,IAAQ,CAAC;GACnE,IAAI,QAAQ;GACZ,KAAK,IAAI,IAAI,GAAG,KAAK,UAAU,KAAK;IAClC,MAAM,SACJ,MAAM,WAAW,aAAa,MAAM,QAAQ,QAAQ,MAAM,MAAM;IAClE,MAAM,CAAC,IAAI,MAAM,KAAK,MAAM;IAC5B,KAAK,MAAM,IAAI,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,GAAG,OAAO,KAAK,UAAU,GAAG,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE;IAC3F,QAAQ;GACV;GACA,IAAI,MAAM,KAAK,MAAM;EACvB;EAIA,OAAa;GACX,KAAK,aAAa,KAAK,cAAc,KAAK,SAAS;GACnD,KAAK,mBAAmB;EAC1B;EAEA,SAAe;GACb,KAAK,eAAe,KAAK,cAAc,KAAK,WAAW;GACvD,KAAK,oBAAoB;IACvB,gBAAgB,KAAK;IACrB,mBAAmB,KAAK;IACxB,kBAAkB,KAAK;GACzB;GACA,IAAI,KAAK,MAAM,SAAS,GAAG;IACzB,KAAK,kBAAkB,sBAAsB,KAAK,MAAM,KAAK,GAAG;IAChE,IAAI,KAAK,gBACP,KAAK,kBAAkB,uBAAuB,KAAK;GACvD;GACA,KAAK,mBAAmB;EAC1B;EAEA,AAAU,qBAA2B;GACnC,KAAK,gBAAgB;GACrB,KAAK,cAAc,KAAK;GACxB,KAAK,cAAc,KAAK;GACxB,KAAK,cAAc,KAAK;GACxB,KAAK;EACP;EAEA,SAAS,GAAW,GAAW,GAAW,GAAiB;GACzD,KAAK,UAAU;GACf,KAAK,KAAK,GAAG,GAAG,GAAG,CAAC;GACpB,KAAK,KAAK;EACZ;EAEA,YAAkB,CAElB;EAEA,SAAS,KAAa,GAAW,GAAW,UAAyB;GACnE,KAAK,YAAY;GACjB,MAAM,SACJ,KAAK,cAAc,WACf,WACA,KAAK,cAAc,WAAW,KAAK,cAAc,QAC/C,QACA;GACR,MAAM,WACJ,KAAK,iBAAiB,QAClB,qBACA,KAAK,iBAAiB,WACpB,YACA,KAAK,iBAAiB,WACpB,oBACA,KAAK;GACf,MAAM,QAAyC;IAC7C,GAAG,OAAO,CAAC;IACX,GAAG,OAAO,CAAC;IACX,MAAM,KAAK,cAAc,KAAK,SAAS;IACvC,eAAe;IACf,qBAAqB;IACrB,OAAO,SAAS,KAAK;IACrB,kBAAkB;GACpB;GAEA,IAAI,WAAY,KAAK,KAAK,YAAY,GAAG,CAAC,CAAC,QAAQ,UAAW;IAC5D,MAAM,aAAa,OAAO,QAAS;IACnC,MAAM,eAAe;GACvB;GACA,KAAK,aAAa,KAAK;GACvB,KAAK,MAAM,KAAK;IAAE,KAAK;IAAQ;IAAO,MAAM;GAAI,CAAC;GACjD,KAAK;EACP;EAEA,YAAY,KAA0B;GACpC,IAAI,CAAC,cACH,eAAe,SAAS,cAAc,QAAQ,CAAC,CAAC,WAAW,IAAI;GAEjE,aAAc,OAAO,KAAK;GAC1B,OAAO,aAAc,YAAY,GAAG;EACtC;EAEA,UACE,KACA,GACA,GACA,GACA,GACA,GAAG,MACG;;GACN,IAAI,KAAK,SAAS,GAAG;IACnB,aAAa,UACX,cACA,uEACF;IACA;GACF;GACA,KAAK,YAAY;GACjB,MAAM,cACH,IAAyB,0CACxB,IAA0B,YACvB,IAA0B,UAAU,IACrC;GACN,IAAI,CAAC,KAAK;IACR,aAAa,UACX,gBACA,iEACF;IACA;GACF;GACA,MAAM,QAAyC;IAC7C,MAAM;IACN,GAAG,OAAO,CAAC;IACX,GAAG,OAAO,CAAC;GACb;GACA,MAAM,KAAK,iCAAM,IAAyB;GAC1C,MAAM,KAAK,iCAAM,IAAyB;GAC1C,IAAI,MAAM,MAAM,MAAM,QAAQ,OAAO,EAAY;GACjD,IAAI,MAAM,MAAM,MAAM,SAAS,OAAO,EAAY;GAClD,KAAK,aAAa,KAAK;GACvB,KAAK,MAAM,KAAK;IAAE,KAAK;IAAS;GAAM,CAAC;GACvC,KAAK;EACP;EAEA,eAAqB;GACnB,aAAa,UACX,gBACA,6CACF;EACF;EAIA,OAAa;GACX,KAAK,YAAY,KAAK;IACpB,WAAW,KAAK;IAChB,aAAa,KAAK;IAClB,WAAW,KAAK;IAChB,UAAU,KAAK;IACf,SAAS,KAAK;IACd,aAAa,KAAK;IAClB,0BAA0B,KAAK;IAC/B,MAAM,KAAK;IACX,WAAW,KAAK;IAChB,cAAc,KAAK;IACnB,gBAAgB,KAAK;IACrB,OAAO,KAAK,MAAM,MAAM;GAC1B,CAAC;EACH;EAEA,UAAgB;GACd,MAAM,IAAI,KAAK,YAAY,IAAI;GAC/B,IAAI,GAAG,OAAO,OAAO,MAAM,CAAC;EAC9B;EAEA,QAAc,CAEd;EAEA,OAAa;GACX,aAAa,UAAU,QAAQ,yCAAyC;EAC1E;EAEA,YAAY,UAA0B;GACpC,KAAK,QAAQ;EACf;EAEA,cAAwB;GACtB,OAAO,KAAK;EACd;EAEA,qBACE,IACA,IACA,IACA,IACa;GACb,OAAO,IAAI,YAAY,UAAU;IAAC;IAAI;IAAI;IAAI;GAAE,CAAC;EACnD;EAEA,qBACE,IACA,IACA,IACA,IACA,IACA,IACa;GACb,OAAO,IAAI,YAAY,UAAU;IAAC;IAAI;IAAI;IAAI;IAAI;IAAI;GAAE,CAAC;EAC3D;EAIA,AAAU,cAAc,OAAqC;GAC3D,IAAI,iBAAiB,aAAa;IAChC,IAAI,CAAC,KAAK,OAAO;KACf,KAAK,QAAQ,SAAS,gBAAgB,QAAQ,MAAM;KACpD,KAAK,MAAM,aAAa,KAAK,OAAO,KAAK,MAAM,UAAU;IAC3D;IACA,OAAO,MAAM,YAAY,KAAK,KAAK;GACrC;GACA,IAAI,OAAO,UAAU,UAAU;IAG7B,aAAa,UACX,WACA,kEACF;IACA,OAAO;GACT;GACA,OAAO;EACT;EAGA,AAAU,aAAa,OAA8C;GACnE,MAAM,QAAQ,KAAK,YACf,eAAe,KAAK,cACpB;GACJ,IAAI,KAAK,gBAAgB,GAAG,MAAM,UAAU,KAAK;QAC5C,MAAM,UAAU;GACrB,MAAM,KAAK,KAAK;GAChB,IAAI,OAAO,eAAe;IACxB,IAAI,YAAY,IAAI,EAAE,GAAG;KAEvB,MAAM,QAAQ,mBAAmB;KACjC,MAAM,QAAQ,MAAM,QAAQ,GAAG,MAAM,MAAM,IAAI,UAAU;IAC3D,OACE,aAAa,UACX,aAAa,MACb,wBAAwB,GAAG,wBAC7B;GAEJ;EACF;EAMA,AAAU,cAAoB;;GAC5B,IAAI,CAAC,KAAK,iBAAiB,KAAK,GAAG,WAAW,GAAG;IAC/C,KAAK,gBAAgB;IACrB;GACF;GAEA,MAAM,QAAyC;IAC7C,GAAG,KAAK;IACR,0BAAM,KAAK,yEAAc;IACzB,8BAAQ,KAAK,+EAAgB;GAC/B;GACA,IAAI,KAAK,cACP,OAAO,OAAO,OAAO,KAAK,iBAAiB;GAE7C,MAAM,QAAQ,KAAK,cACf,eAAe,KAAK,gBACpB;GACJ,MAAM,UAAU,KAAK;GACrB,IAAI,KAAK,gBAAgB,eAAe;IACtC,IAAI,YAAY,IAAI,KAAK,WAAW,GAClC,MAAM,QAAQ,mBAAmB,KAAK;SAEtC,aAAa,UACX,aAAa,KAAK,eAClB,wBAAwB,KAAK,YAAY,wBAC3C;GAEJ;GAEA,MAAM,OAAO,KAAK,MAAM,KAAK,MAAM,SAAS;GAC5C,IAAI,QAAQ,KAAK,QAAQ,UAAU,aAAa,KAAK,OAAO,KAAK,GAAG;IAClE,KAAK,UAAW,KAAM,KAAK,MAAM,EAAa,MAAM;IACpD,KAAK,MAAM,IAAK,KAAK,MAAM,IAAe,KAAK;GACjD,OACE,KAAK,MAAM,KAAK;IAAE,KAAK;IAAQ;IAAO,WAAW,CAAC;GAAE,CAAC;GAGvD,KAAK,KAAK;GACV,KAAK,aAAa;GAClB,KAAK,eAAe;GACpB,KAAK,gBAAgB;EACvB;CACF;CAEA,SAAS,OAAO,GAAmB;EACjC,OAAO,KAAK,MAAM,IAAI,GAAG,IAAI;CAC/B;CAGA,SAAS,aACP,GACA,GACS;EACT,MAAM,QAAQ,OAAO,KAAK,CAAC;EAC3B,MAAM,QAAQ,OAAO,KAAK,CAAC;EAC3B,IAAI,MAAM,WAAW,MAAM,QAAQ,OAAO;EAC1C,KAAK,MAAM,KAAK,OAAO;GACrB,IAAI,MAAM,KAAK;GACf,IAAI,EAAE,OAAO,EAAE,IAAI,OAAO;EAC5B;EACA,OAAO;CACT;CAOA,IAAa,WAAb,MAAa,iBAAiB,SAAS;EAYrC,YACE,OAAgC,MAChC,UACA;GACA,MAAM,MAAM,QAAQ;GAftB,KAAU,WAAmB;GAC7B,KAAU,eAA+B,CAAC;GAC1C,KAAU,UAA6B;GACvC,KAAU,cAAuB;GAc/B,IAAI,KAAK,QAAQ,SAAS,YAAY,KAAK,OAAO;IAChD,IAAI,IAAI,SAAS,WAAW,KAAK,SAAS,OAAO,GAAG,KAAK,GAAG,KAAK;IACjE,KAAK,aAAa,KAAK;IACvB,KAAK,UAAU;GACjB;GAGA,KAAK,QAAQ,IAAI;EACnB;EAKA,AAAU,sBAAsB,WAAoB,IAAwB;GAC1E,OAAO,SAAS,WAAW,WAAW,OAAO,EAAE;EACjD;EAOA,UAAmB;GACjB,OAAO,IAAI,QAAQ,IAAI;EACzB;EAKA,IAAI,UAAmB;GACrB,OAAO,KAAK;EACd;EAGA,gBAAgB,KAAyB;GACvC,KAAK,aAAa,KAAK,GAAG;EAC5B;EAQA,OAAO,GAAU,KAA0B;GACzC,MAAM,OAAO,GAAG,GAAG;GACnB,SAAS,QAAQ,KAAK,SAAS;IAC7B,SAAS,OAAO,KAAK,MAAM,MAAM,GAAG,KAAK,MAAM;IAC/C,OAAO,GAAG,KAAK,MAAM;IACrB,QAAQ,GAAG,KAAK,MAAM;IACtB,OAAO;IACP,SAAS;GACX,CAAC;GACD,KAAK,kBAAkB;GACvB,OAAO;EACT;EAOA,MAAM,IAAmB;GACvB,IAAI,IAAI,KAAK,WAAW;GACxB,KAAK,kBAAkB;GACvB,OAAO;EACT;EAEA,AAAU,oBAA0B;GAClC,MAAM,MAAM,KAAK;GACjB,IAAI,CAAC,KAAK,SAAS;IACjB,KAAK,UAAU,SAAS,gBAAgB,QAAQ,MAAM;IACtD,KAAK,QAAQ,aAAa,SAAS,YAAY;IAC/C,IAAI,aAAa,KAAK,SAAS,IAAI,UAAU;GAC/C;GACA,SAAS,QAAQ,KAAK,SAAS;IAC7B,GAAG;IACH,GAAG;IACH,OAAO,KAAK,MAAM;IAClB,QAAQ,KAAK,MAAM;IACnB,MACE,CAAC,KAAK,YAAY,KAAK,aAAa,gBAChC,SACA,KAAK;GACb,CAAC;EACH;EAMA,AAAU,UAAU,MAAc;GAChC,MAAM,OAAO,KAAK;GAClB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC,WAAW;GACpE,MAAM,UAAU,IAAI;GACpB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAE1C,IAAI,KAAK,eAAe,KAAK,EAAE,CAAC,YAAY,GAAG,KAAK,EAAE,CAAC,YAAY;EAEvE;EAMA,QAAQ,GAAkB;GACxB,KAAK,cAAc;GACnB,OAAO,MAAM,QAAQ,CAAC;EACxB;EAOA,MAAM,SAAkB,OAAe;GACrC,MAAM,MAAM,KAAK;GACjB,IAAI,CAAC,QAAQ,OAAO,IAAI;GAExB,MAAM,QAAQ,IAAI,UAAU,IAAI;GAEhC,MAAM,SAAS,MAAM,iBAAiB,eAAe;GACrD,IAAI,KAAK;GACT,KAAK,MAAM,OAAO,KAAK,cAAc;IACnC,MAAM,QAAQ,OAAO;IACrB,IAAI,CAAC,OAAO;IACZ,MAAM,cAAc;IACpB,KAAK,MAAM,OAAO,IAAI,MAAM;KAC1B,IAAI,IAAI,QAAQ,QAAQ;MACtB,MAAM,OAAO,SAAS,gBAAgB,QAAQ,IAAI,GAAG;MACrD,SAAS,QAAQ,MAAM,IAAI,KAAK;MAChC,IAAI,IAAI,MAAM,KAAK,cAAc,IAAI;MACrC,MAAM,YAAY,IAAI;MACtB;KACF;KACA,MAAM,IAAI,IAAI,MAAM;KACpB,MAAM,SAAS,CAAC,GAAG,IAAI,WAAY,EAAE,MAAM;KAC3C,IAAI,QAAQ;KACZ,KAAK,MAAM,OAAO,QAAQ;MACxB,MAAM,OAAO,SAAS,gBAAgB,QAAQ,MAAM;MACpD,SAAS,QAAQ,wCAAW,IAAI,cAAO,GAAG,EAAE,MAAM,OAAO,GAAG,GAAE,CAAC;MAC/D,MAAM,YAAY,IAAI;MACtB,QAAQ;KACV;IACF;GACF;GACA,OAAO,MAAM;EACf;EAQA,OAAO,WACL,QACA,MACA,IACY;GACZ,IAAI,CAAC,UAAU,CAAC,OAAO,aACrB,MAAM,IAAI,MAAM,mCAAmC;GAIrD,IAAI,OAAuB,SAAS,eAAe,EAAG;GACtD,IAAI,QAAQ,CAAC,OAAO,SAAS,IAAI,GAAG,OAAO;GAE3C,IAAI,CAAC,MAAM;IACT,OAAO,SAAS,gBAAgB,QAAQ,IAAI;IAC5C,KAAK,aAAa,MAAM,EAAG;IAE3B,OAAO,YAAY,IAAI;GACzB;GACA,OAAO;EACT;EAMA,OAAO,QAAuB;GAG5B,AAFW,KAAK,WAAW,iBAAiB,MAAM,QAAQ,QAAQ,MAAM,CAErE,CAAC,CAAC,SAAS,OAAgB;IAC5B,GAAG,WAAY,YAAY,EAAE;GAC/B,CAAC;GAED,OAAO,MAAM,OAAO,MAAM;EAC5B;EAOA,YAAkB;GAChB,KAAK,QAAQ,YAAY;GACzB,KAAK,UAAU;GACf,KAAK,MAAM,OAAO,KAAK,cAAc,IAAI,SAAS;GAClD,OAAO,MAAM,UAAU;EACzB;EAQA,UAAgB;GACd,MAAM,QAAQ;GACd,KAAK,MAAM,OAAO,KAAK,cAAc,IAAI,WAAW;GACpD,KAAK,eAAe,CAAC;GACrB,IAAI,KAAK,WAAW,KAAK,QAAQ,YAC/B,KAAK,QAAQ,WAAW,YAAY,KAAK,OAAO;GAElD,KAAK,UAAU;GACf,OAAO;EACT;CACF;CAEA,IAAI,kBAAkB;CACtB,IAAI,gBAAgB;CAGpB,MAAM,mBAA2C;EAC/C,WAAW;EACX,aAAa;EACb,WAAW;EACX,UAAU;EACV,SAAS;EACT,aAAa;EACb,MAAM;CACR;CASA,IAAa,UAAb,MAAa,gBAAgB,WAAqB;EAgBhD,WAAW,UAAkB;GAC3B,OAAO;EACT;EACA,WAAW,QAAQ,GAAW;GAC5B,kBAAkB;EACpB;EACA,WAAW,QAAgB;GACzB,OAAO;EACT;EACA,WAAW,MAAM,GAAW;GAC1B,gBAAgB;EAClB;EAMA,YAAY,OAAiB;GAC3B,MAAM;GA/BR,KAAU,UAAkB;GAE5B,KAAU,aAA6B;IACrC,OAAO;IACP,SAAS;IACT,YAAY;IACZ,WAAW;IACX,cAAc;IACd,OAAO,CAAC;GACV;GAuBE,KAAK,YAAY;GACjB,KAAK,UAAU,IAAI,aAAa,MAAM,OAAqB;GAC3D,MAAM,gBAAgB,KAAK,OAAO;GAElC,KAAK,OAAO,KAAK;GAIjB,KAAK,KAAK,aAAa,KAAK,OAAO,SAAS;GAC5C,KAAK,KAAK,eAAe,KAAK,OAAO,WAAW;GAChD,KAAK,KAAK,YAAY,OAAO;GAC7B,KAAK,KAAK,QAAQ,KAAK,MAAM,KAAK;GAClC,KAAK,SAAS;GAEd,KAAK,WAAW,QAAQ,MAAM;EAChC;EAOA,AAAU,KAAK,KAAa,OAAsB;GAChD,MAAM,SAAS,iBAAiB;GAChC,IAAI,QAEF;QAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAChD,KAAK,WAAW,MAAM,UAAU;GAClC;GAEF,MAAM,KAAK,KAAK,KAAK;EACvB;EAEA,IAAI,SAAkB;GACpB,OAAO,KAAK;EACd;EACA,IAAI,OAAO,GAAY;GACrB,KAAK,UAAU;GACf,KAAK,WAAW,MAAM,SAAS;EACjC;EAEA,IAAI,UAAmB;GACrB,OAAO,KAAK;EACd;EACA,IAAI,QAAQ,GAAY;GACtB,KAAK,WAAW;GAChB,KAAK,WAAW,MAAM,UAAU;EAClC;EAKA,aAAa,OAAgB,MAAM,SAA2B,OAAa;GACzE,QAAQ,eAAe;GACvB,OAAO;EACT;EAKA,gBAAgB,UAAkB,CAAC,GAAG,CAAC,GAAS;GAC9C,QAAQ,eAAe;EACzB;EAGA,OAAe,iBAAiB;GAC9B,IAAI,QAAQ,kBAAkB;GAC9B,QAAQ,mBAAmB;GAC3B,KAAK,KACH,qEACF;EACF;EAKA,IAAI,QAAkB;GACpB,OAAO,KAAK;EACd;EAKA,IAAI,aAA2B;GAC7B,OAAO,KAAK;EACd;EAQA,IAAI,GAAqB;GACvB,MAAM,MAAM,OAAO,KAAK,YAAY,KAAK;GACzC,KAAK,WAAW,eAAe;GAC/B,KAAK,QAAQ,YAAY;GACzB,OAAO;EACT;EAQA,YAAY,UAAkB,OAAiC;GAC7D,KAAK,WAAW,QAAQ;GACxB,KAAK,WAAW,UAAU;GAC1B,KAAK,WAAW,aAAa;GAC7B,KAAK,OAAO;GACZ,OAAO,KAAK;EACd;EAMA,MAAM,MAAe;GACnB,IAAI,CAAC,QAAQ,KAAK,aAAa,MAC7B,MAAM,IAAI,MAAM,4CAA4C;GAE9D,OAAO,KAAK,YACV,GAAG,QAAQ,QAAQ,IAAI,EAAE,IAAI,KAAK,WAClC,KAAK,UAAU,OACjB;EACF;EAKA,SAAiB;GACf,KAAK,WAAW;GAChB,KAAK,WAAW,YAAY,GAAG,KAAK,WAAW,QAAQ,GAAG,KAAK,WAAW;GAC1E,OAAO,KAAK,WAAW;EACzB;EAMA,OAAO,MAAM,KAA6B;GACxC,OAAO,IAAI,aAAa,KAAK,QAAQ;EACvC;EAMA,OAAO,QAAQ,MAAuB;GACpC,OAAO,QAAQ,KAAK;EACtB;EAcA,OAAO,MAAM,MAAkB,QAA6B;GAC1D,IAAI,KAAK,CAAC;GAEV,IAAI,CAAC,OAAO,WAAW,GAAG,KAAK,YAAY;GAC3C,IAAI,CAAC,OAAO,YAAY,GAAG,KAAK,cAAc;GAE9C,KAAK,IAAI,KAAK,QACZ,IAAI,OAAO,eAAe,CAAC,KAAK,KAAK,YAAY,KAAK,WAAW;IAC/D,IAAI,IAAI,OAAO;IACf,IAAI,GAAG;KACL,IAAI,CAAC,OAAO,aAAa,EAAE,QAAQ,MAAM,MAAM,GAC7C;UACK,IAAI,CAAC,OAAO,cAAc,EAAE,QAAQ,QAAQ,MAAM,GACvD;UAEA,GAAG,KAAK,GAAG,EAAE,IAAI,GAAG;IAExB;GACF;GAGF,OAAO,SAAS,QAAQ,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,EAAE,CAAC;EACvD;EAeA,OAAO,MACL,KACA,IACA,SAAS,GACT,QAAQ,UACR;GACA,OAAO,WAAW,MACd,QAAQ,aAAa,KAAK,IAAI,QAAQ,KAAK,IAC3C,WAAW,MAAM,KAAK,IAAI,QAAQ,KAAK;EAC7C;EAKA,OAAO,OACL,KACA,IACA,SAAS,IACT;GACA,OAAO,WAAW,MACd,QAAQ,cAAc,KAAK,IAAI,MAAM,IACrC,WAAW,OAAO,KAAK,IAAI,MAAM;EACvC;EAmBA,OAAO,IACL,KACA,IACA,QACA,YACA,UACA,IACA;GACA,OAAO,WAAW,MACd,QAAQ,WAAW,KAAK,IAAI,QAAQ,YAAY,UAAU,EAAE,IAC5D,WAAW,IAAI,KAAK,IAAI,QAAQ,YAAY,UAAU,EAAE;EAC9D;EAKA,OAAO,OACL,KACA,IACA,UACA;GACA,OAAO,WAAW,MACd,QAAQ,cAAc,KAAK,IAAI,QAAQ,IACvC,WAAW,OAAO,KAAK,IAAI,QAAQ;EACzC;EAKA,OAAO,KAAK,KAA0C,KAAqB;GACzE,OAAO,WAAW,MACd,QAAQ,YAAY,KAAK,GAAG,IAC5B,WAAW,KAAK,KAAK,GAAG;EAC9B;EAKA,OAAO,QACL,KACA,KACA;GACA,OAAO,WAAW,MACd,QAAQ,eAAe,KAAK,GAAG,IAC/B,WAAW,QAAQ,KAAK,GAAG;EACjC;EAKA,OAAO,KAAK,KAA0C,KAAqB;GACzE,OAAO,WAAW,MACd,QAAQ,YAAY,KAAK,GAAG,IAC5B,WAAW,KAAK,KAAK,GAAG;EAC9B;EAUA,OAAO,KACL,KACA,IACA,KACA,UACA;GACA,OAAO,WAAW,MACd,QAAQ,YAAY,KAAK,IAAI,GAAG,IAChC,WAAW,KAAK,KAAK,IAAI,KAAK,QAAQ;EAC5C;EAUA,OAAO,aACL,KACA,IACA,SAAiB,GACjB,QAAgB,UACJ;GACZ,IAAI,UAAU,UACZ,OAAO,QAAQ,cAAc,KAAK,IAAI,MAAM;QAE5C,OAAO,QAAQ,cAAc,KAAK,IAAI,MAAM;EAEhD;EAQA,OAAO,cACL,KACA,IACA,SAAiB,IACL;GACZ,IAAI,OAAO,SAAS,WAAW,IAAI,OAAO,UAAU,QAAQ,MAAM,GAAG,CAAC;GAEtE,SAAS,QAAQ,MAAM;IACrB,IAAI,GAAG;IACP,IAAI,GAAG;IACP,GAAG;IACH,OAAO,0BAA0B,IAAI;GACvC,CAAC;GAED,QAAQ,MAAM,MAAM,IAAI,KAAK;GAC7B,OAAO;EACT;EAWA,OAAO,WACL,KACA,IACA,QACA,YACA,UACA,IACY;GACZ,IAAI,OAAO,SAAS,WAAW,IAAI,OAAO,QAAQ,QAAQ,MAAM,GAAG,CAAC;GAEpE,MAAM,QAAQ,IAAI,GAAG,EAAE,CAAC,CAAC,QAAQ,YAAY,QAAQ,IAAI;GACzD,MAAM,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,QAAQ,UAAU,QAAQ,IAAI;GAErD,IAAI,WADS,KAAK,WAAW,QAAQ,IAAI,KAAK,WAAW,UAAU,IAC7C,MAAM,KAAK,OAAO;GACxC,IAAI,IAAI,WAAW,CAAC;GACpB,MAAM,QAAQ,KAAK,MAAM;GAEzB,MAAM,IAAI,KAAK,MAAM,GAAG,GAAG,MAAM,GAAG,KAAK,OAAO,GAAG,OAAO,KAAK,WAAW,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,GAAG,IAAI;GAE9G,SAAS,QAAQ,MAAM;IAClB;IACH,OAAO,uBAAuB,IAAI;GACpC,CAAC;GACD,QAAQ,MAAM,MAAM,IAAI,KAAK;GAC7B,OAAO;EACT;EAQA,OAAO,cAAc,KAAqB,IAAY,UAAkB;GACtE,IAAI,OAAO,SAAS,WAAW,IAAI,OAAO,QAAQ,QAAQ,MAAM,GAAG,CAAC;GACpE,SAAS,QAAQ,MAAM;IACrB,GAAG,GAAG,KAAK;IACX,GAAG,GAAG,KAAK;IACX,OAAO,WAAW;IAClB,QAAQ,WAAW;IACnB,OAAO,0BAA0B,IAAI;GACvC,CAAC;GACD,QAAQ,MAAM,MAAM,IAAI,KAAK;GAC7B,OAAO;EACT;EAOA,OAAO,YACL,KACA,KACwB;GACxB,IAAI,SAAS,QAAQ,aAAa,GAAG;GACrC,IAAI,OAAO,QAAQ,GAAG;GAGtB,IAAI,OAAO,QAAQ,GAAG,OAAO,QAAQ,MAAM,KAAK,OAAO,QAAQ,KAAK;GAGpE,IAAI,OAAO,SAAS,WAAW,IAAI,OAAO,QAAQ,QAAQ,MAAM,GAAG,CAAC;GACpE,IAAI,IAAI,KAAK,YAAY,GAAG;GAE5B,SAAS,QAAQ,MAAM;IACrB,IAAI,EAAE,EAAE,CAAC;IACT,IAAI,EAAE,EAAE,CAAC;IACT,IAAI,EAAE,EAAE,CAAC;IACT,IAAI,EAAE,EAAE,CAAC;IACT,OAAO,wBAAwB,IAAI;GACrC,CAAC;GAED,QAAQ,MAAM,MAAM,IAAI,KAAK;GAC7B,OAAO;EACT;EAQA,OAAiB,MACf,KACA,QACA,YAAqB,MACrB;GACA,IAAI,OAAO,SAAS,WAClB,IAAI,OACJ,YAAY,YAAY,YACxB,QAAQ,MAAM,GAAG,CACnB;GAEA,SAAS,QAAQ,MAAM;IACb;IACR,OAAO,2BAA2B,IAAI;GACxC,CAAC;GACD,QAAQ,MAAM,MAAM,IAAI,KAAK;GAC7B,OAAO;EACT;EAOA,OAAiB,aAAa,KAG5B;GACA,IAAI,SAAiB;GACrB,IAAI,QAAQ;GACZ,KAAK,IAAI,KAAK,KAAK;IACjB,UAAU,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG;IAC1B;GACF;GACA,OAAO;IAAE,QAAQ;IAAe;GAAM;EACxC;EAOA,OAAO,eAAe,KAAqB,KAAiC;GAC1E,IAAI,SAAS,QAAQ,aAAa,GAAG;GACrC,OAAO,QAAQ,MAAM,KAAK,OAAO,QAAQ,IAAI;EAC/C;EAOA,OAAO,YACL,KACA,KACwB;GACxB,IAAI,CAAC,KAAK,WAAW,GAAG,GAAG;GAE3B,IAAI,OAAO,SAAS,WAAW,IAAI,OAAO,QAAQ,QAAQ,MAAM,GAAG,CAAC;GACpE,IAAI,QAAQ,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY;GAC7C,IAAI,OAAO,UAAU,KAAK,KAAK;GAE/B,SAAS,QAAQ,MAAM;IACrB,GAAG,MAAM,EAAE,CAAC;IACZ,GAAG,MAAM,EAAE,CAAC;IACZ,OAAO,KAAK;IACZ,QAAQ,KAAK;IACb,OAAO,wBAAwB,IAAI;GACrC,CAAC;GAED,QAAQ,MAAM,MAAM,IAAI,KAAK;GAC7B,OAAO;EACT;EAQA,OAAO,YAAY,KAAqB,IAAY,KAAyB;GAC3E,IAAI,OAAO,SAAS,WAAW,IAAI,OAAO,QAAQ,QAAQ,MAAM,GAAG,CAAC;GAEpE,SAAS,QAAQ,MAAM;IACrB,kBAAkB;IAClB,GAAG,GAAG;IACN,GAAG,GAAG;IACN,IAAI;IACJ,IAAI;IACJ,OAAO,wBAAwB,IAAI;GACrC,CAAC;GAED,KAAK,cAAc;GAEnB,QAAQ,MAAM,MAAM,IAAI,KAAK;GAE7B,OAAO;EACT;CACF;CAzeE,QAAe,mBAAmB;;;;;;;;;CC7iCpC,MAAM,QAAQ,IAAI;CAClB,MAAM,WAAW,MAAO;CAGxB,MAAM,cAAc;CAEpB,IAAa,QAAb,MAAa,MAAM;EAmCjB,YACE,OACA,WAAmB,GACnB,UAA2B,GAC3B;GAtCF,KAAU,WAAe,IAAI,GAAG;GAChC,KAAU,YAAoB;GAC9B,KAAU,WAAmB;GAC7B,KAAU,cAAsB;GAChC,KAAU,YAAoB;GAC9B,KAAU,eAAuB;GAGjC,KAAU,aAAyB,CAAC;GACpC,KAAU,UAAkB,CAAC;GAC7B,KAAU,UAAoB,CAAC;GAC/B,KAAU,UAAoB,CAAC;GAM/B,KAAQ,gBAAwB;GAEhC,KAAQ,SAAiB;GAGzB,KAAQ,4BAAyB,IAAI,YAAY,CAAC;GAClD,KAAQ,6BAA0B,IAAI,YAAY,CAAC;GACnD,KAAQ,+BAA4B,IAAI,YAAY,CAAC;GACrD,KAAQ,gCAA6B,IAAI,YAAY,CAAC;GACtD,KAAQ,8BAA4B,IAAI,aAAa,CAAC;GAapD,KAAK,SAAS,MAAM,UAAU,KAAK;GACnC,KAAK,YAAY;GACjB,KAAK,WACH,OAAO,YAAY,WAAW,IAAI,GAAG,GAAG,OAAO,IAAI,IAAI,GAAG,OAAO;GACnE,OAAO;EACT;EAKA,IAAI,QAAe;GACjB,OAAO,KAAK;EACd;EACA,IAAI,MAAM,OAAc;GACtB,KAAK,SAAS;EAChB;EAKA,IAAI,UAAc;GAChB,OAAO,KAAK;EACd;EACA,IAAI,QAAQ,GAAO;GACjB,KAAK,WAAW;EAClB;EAKA,IAAI,WAAmB;GACrB,OAAO,KAAK;EACd;EACA,IAAI,SAAS,GAAW;GACtB,KAAK,YAAY;EACnB;EAKA,IAAI,UAAkB;GACpB,OAAO,KAAK;EACd;EACA,IAAI,QAAQ,GAAW;GACrB,KAAK,WAAW;EAClB;EAKA,IAAI,aAAqB;GACvB,OAAO,KAAK;EACd;EACA,IAAI,WAAW,GAAW;GACxB,KAAK,cAAc;EACrB;EAQA,IAAI,WAAmB;GACrB,OAAO,KAAK;EACd;EACA,IAAI,SAAS,GAAW;GACtB,KAAK,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,CAAC,CAAC;EAC5C;EAOA,IAAI,cAAsB;GACxB,OAAO,KAAK;EACd;EACA,IAAI,YAAY,IAAY;GAC1B,KAAK,eAAe,KAAK,IAAI,GAAG,EAAE;EACpC;EAKA,IAAI,YAAoB;GACtB,OAAO,KAAK,QAAQ;EACtB;EAKA,IAAI,gBAAwB;GAC1B,OAAO,KAAK,WAAW;EACzB;EAOA,KAAK,IAAqB;GACxB,IAAI,OAAO,OAAO,YAAY,GAAG,SAAS,GACxC,OAAO,KAAK,QAAQ,KAAK,QAAQ,QAAQ,EAAE;GAE7C,OAAO,OAAO,OAAO,YAAY,MAAM,IAAI,KAAK,QAAQ,MAAM;EAChE;EAOA,SAAS,IAAqB;GAC5B,IAAI,OAAO,OAAO,YAAY,GAAG,SAAS,GACxC,OAAO,KAAK,WAAW,KAAK,QAAQ,QAAQ,EAAE;GAEhD,OAAO,OAAO,OAAO,YAAY,MAAM,IAAI,KAAK,WAAW,MAAM;EACnE;EAOA,UAAU,MAAsB;GAC9B,OAAO,KAAK,QAAQ,QAAQ,IAAI;EAClC;EAOA,cAAc,MAAsB;GAClC,OAAO,KAAK,QAAQ,QAAQ,IAAI;EAClC;EASA,OAAO,IAAY;GACjB,MAAM,UAAU,KAAK,IAAI,IAAI,KAAK,YAAY,IAAI,KAAK;GACvD,KAAK,SAAS;GACd,IAAI,WAAW,aAAa;IAM1B,MAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAO,UAAU,KAAK,YAAa,QAAQ,CAAC;IACvE,MAAM,IAAI,UAAU,MAAO;IAE3B,KAAK,gBAAgB,KAAK,IAAI,KAAK,WAAW,IAAI,KAAK;IACvD,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;KAC1B,KAAK,iBAAiB,CAAC;KAMvB,KAAK,cAAc,CAAC;IACtB;IACA,KAAK,aAAa;GACpB,OAAO,IAAI,UAAU,GACnB,KAAK,SAAS;GAGhB,IAAI,KAAK,gBACP,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,WAAW,QAAQ,IAAI,KAAK,KACrD,KAAK,eAAe,KAAK,WAAW,IAAI,CAAC;GAG7C,IAAI,KAAK,aACP,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,QAAQ,IAAI,KAAK,KAClD,KAAK,YAAY,KAAK,QAAQ,IAAI,CAAC;EAGzC;EAMA,cAAc,IAA4C;GACxD,KAAK,iBAAiB;EACxB;EAMA,WAAW,IAAwC;GACjD,KAAK,cAAc;EACrB;EAOA,IAAI,GAAoB,OAAe,IAAU;GAC/C,IAAI,aAAa,MAAM;IACrB,KAAK,QAAQ,KAAW,CAAC;IACzB,KAAK,QAAQ,KAAK,IAAI;GACxB,OAAO;IACL,KAAK,WAAW,KAAe,CAAC;IAChC,KAAK,QAAQ,KAAK,IAAI;GACxB;GACA,OAAO;EACT;EAEA,AAAQ,OAAO,IAA8B,IAA6B;GACxE,IAAI,QAAQ;GACZ,IAAI,OAAO,OAAO,UAAU;IAC1B,QAAQ,GAAG,EAAE;IACb,IAAI,QAAQ,GACV,MAAM,IAAI,MACR,wBAAwB,GAAG,kFAC7B;GACJ,OACE,QAAQ;GAEV,OAAO;EACT;EAOA,WAAW,MAAuB,QAAgB,GAAS;GACzD,MAAM,QAAQ,KAAK,OAAO,KAAK,UAAU,KAAK,IAAI,GAAG,IAAI;GACzD,MAAM,QAAQ,QAAQ,IAAI,CAAC,QAAQ,KAAK,GAAG,KAAK,IAAI,CAAC,OAAO,KAAK;GACjE,KAAK,QAAQ,OAAO,MAAM,IAAI,MAAM,EAAE;GACtC,KAAK,QAAQ,OAAO,MAAM,IAAI,MAAM,EAAE;GACtC,OAAO;EACT;EAOA,eAAe,MAAuB,QAAgB,GAAS;GAC7D,MAAM,QAAQ,KAAK,OAAO,KAAK,cAAc,KAAK,IAAI,GAAG,IAAI;GAC7D,MAAM,QAAQ,QAAQ,IAAI,CAAC,QAAQ,KAAK,GAAG,KAAK,IAAI,CAAC,OAAO,KAAK;GACjE,KAAK,WAAW,OAAO,MAAM,IAAI,MAAM,EAAE;GACzC,KAAK,QAAQ,OAAO,MAAM,IAAI,MAAM,EAAE;GACtC,OAAO;EACT;EAUA,OAAO,eACL,IACA,IACA,MACA,QAAgB,GAChB,UAAmB,OACnB;GACA,MAAM,KAAK,KAAK,GAAG,QAAQ;GAC3B,MAAM,KAAK,KAAK,GAAG,QAAQ;GAC3B,MAAM,KAAK,KAAK;GAEhB,IAAI,QAAQ,GAAG,UAAU,EAAE;GAC3B,IAAI,SAAS,OAAO;GACpB,IAAI,IAAI,UACJ,OAAO,MAAM,UAAU,IAAI,IAC3B,UAAU,MAAM,IAAI,KAAK,IAAI,UAAU;GAC3C,IAAI,IAAI,MAAM,UAAU,IAAI,KAAK;GAEjC,GAAG,SAAS,EAAE,UAAU,KAAK,EAAE,CAAC;GAChC,GAAG,IAAI,EAAE,UAAU,KAAK,EAAE,CAAC;GAE3B,OAAO;EACT;EAQA,OAAO,gBACL,GACA,MACA,UAAkB,KAClB;GACA,MAAM,QAAQ,KAAK,YAAY,IAAI;GACnC,MAAM,eACJ,GACA,MAAM,EAAE,CAAC,IACT,MAAM,EAAE,CAAC,IACT,MAAM,EAAE,CAAC,IACT,MAAM,EAAE,CAAC,IACT,OACF;EACF;EAOA,OAAiB,eACf,GACA,MACA,MACA,MACA,MACA,SACA;GACA,MAAM,KAAK,EAAE;GACb,MAAM,KAAK,EAAE;GACb,MAAM,KAAK,KAAK,IAAI,KAAK,IAAI,IAAI,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,MAAM;GAClE,MAAM,KAAK,KAAK,IAAI,KAAK,IAAI,IAAI,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,MAAM;GAElE,IAAI,OAAO,MAAM,OAAO,IAAI;IAC1B,MAAM,OAAO,EAAE;IACf,MAAM,MAAM,KAAK,KAAK,MAAM;IAC5B,MAAM,MAAM,KAAK,KAAK,MAAM;IAC5B,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK;IACrC,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK;IACrC,EAAE,KAAK;IACP,EAAE,KAAK;GACT;EACF;EAUA,AAAU,UACR,GACA,IACA,SAAiB,EAAE,YAAY,OACrB;GACV,MAAM,OAAO,EAAE;GACf,MAAM,QAAQ,SAAS,IAAI,KAAK,SAAS;GAEzC,IAAI,EAAE,MAAM;IAGV,IAAI,UAAU,GAAG;KACf,KAAK,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK,MAAM;KACpC,KAAK,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK,MAAM;IACtC;IACA,EAAE,WAAW;IACb,EAAE,OAAO,IAAI,KAAK,eAAe,EAAE;IACnC,OAAO;GACT;GAEA,MAAM,QAAQ,EAAE;GAChB,MAAM,IAAI,KAAK,gBAAgB;GAC/B,MAAM,OAAO,KAAK;GAClB,MAAM,KAAK,EAAE;GACb,MAAM,KAAK,EAAE;GACb,MAAM,KAAK,MAAM,KAAK,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,SAAS,MAAM;GACrE,MAAM,KAAK,MAAM,KAAK,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,SAAS,MAAM;GACrE,KAAK,KAAK;GACV,KAAK,KAAK;GACV,EAAE,KAAK;GACP,EAAE,KAAK;GACP,EAAE,WAAW;GACb,OAAO;EACT;EAMA,AAAU,iBAAiB,IAAY;GACrC,MAAM,KAAK,KAAK;GAChB,MAAM,MAAM,GAAG;GACf,IAAI,QAAQ,GAAG;GAEf,MAAM,KAAK,KAAK,OAAO;GACvB,MAAM,KAAK,KAAK,OAAO;GACvB,MAAM,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;GAClC,MAAM,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;GAClC,MAAM,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;GAClC,MAAM,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;GAElC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK;IAC5B,MAAM,IAAI,GAAG;IACb,KAAK,UAAU,GAAG,EAAE;IACpB,MAAM,eAAe,GAAG,MAAM,MAAM,MAAM,MAAM,KAAK,QAAQ;GAC/D;GAEA,KAAK,kBAAkB;EACzB;EAMA,AAAQ,oBAAoB;GAC1B,MAAM,KAAK,KAAK;GAChB,MAAM,IAAI,GAAG;GACb,IAAI,IAAI,GAAG;GAEX,IAAI,OAAO;GACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,IAAI,GAAG,EAAE,CAAC,SAAS,MAAM,OAAO,GAAG,EAAE,CAAC;GAExC,IAAI,QAAQ,GAAG;GAGf,MAAM,MAAM,KAAK,OAAO;GACxB,IAAI,IAAI;GACR,OAAO,IAAI,IAAI,GAAG,MAAM;GACxB,MAAM,OAAO,IAAI;GAEjB,IAAI,KAAK,WAAW,SAAS,IAAI,GAC/B,KAAK,aAAa,IAAI,YAAY,IAAI,CAAC;GACzC,IAAI,KAAK,UAAU,SAAS,GAAG;IAC7B,KAAK,YAAY,IAAI,YAAY,IAAI,CAAC;IACtC,KAAK,eAAe,IAAI,YAAY,IAAI,CAAC;GAC3C;GACA,MAAM,OAAO,KAAK;GAClB,MAAM,QAAQ,KAAK;GACnB,MAAM,UAAU,KAAK;GAIrB,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC;GACtB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,GAAG;IACb,MAAM,OACF,KAAK,KAAK,KAAK,MAAM,EAAE,KAAK,GAAG,GAAG,UAAU,IAC5C,KAAK,KAAK,KAAK,MAAM,EAAE,KAAK,GAAG,GAAG,UAAU,OAC5C,IACF;IACF,KAAK,KAAK;IACV,MAAM,IAAI;GACZ;GACA,IAAI,MAAM;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,MAAM;IAChB,MAAM,KAAK;IACX,OAAO;GACT;GACA,MAAM,KAAK;GACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,QAAQ,MAAM,KAAK,GAAG,MAAM;GAG9B,MAAM,UAAU,KAAK;GACrB,MAAM,UAAU,KAAK;GACrB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,GAAG;IACb,MAAM,KAAK,KAAK,MAAM,EAAE,KAAK,GAAG;IAChC,MAAM,KAAK,KAAK,MAAM,EAAE,KAAK,GAAG;IAIhC,IAAI,eAAe;IACnB,KAAK,IAAI,KAAK,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM;KACxC,MAAM,KAAK,KAAK,KAAK,IAAI,UAAU;KACnC,KAAK,IAAI,KAAK,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM;MACxC,MAAM,OAAQ,KAAK,KAAK,IAAI,UAAU,IAAI,QAAQ,IAAK;MACvD,IAAI,OAAO;MACX,KAAK,IAAI,IAAI,GAAG,IAAI,cAAc,KAChC,IAAI,QAAQ,OAAO,KAAK;OACtB,OAAO;OACP;MACF;MAEF,IAAI,MAAM;MACV,QAAQ,kBAAkB;MAC1B,MAAM,MAAM,MAAM;MAClB,MAAM,QAAQ,MAAM,IAAI,MAAM,MAAM,KAAK;MACzC,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,KAAK;OAChC,MAAM,IAAI,QAAQ;OAClB,IAAI,IAAI,GAAG,EAAE,QAAQ,GAAG,IAAI,OAAO;MACrC;KACF;IACF;GACF;EACF;EAKA,AAAQ,eAAe;GACrB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,WAAW,QAAQ,IAAI,KAAK,KACrD,KAAK,WAAW,EAAE,CAAC,MAAM,KAAK,CAAC;GAEjC,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,QAAQ,IAAI,KAAK,KAAK;IACvD,MAAM,KAAK,KAAK,QAAQ;IACxB,KAAK,IAAI,IAAI,GAAG,OAAO,GAAG,QAAQ,IAAI,MAAM,KAC1C,AAAC,GAAG,EAAE,CAAc,MAAM,KAAK,CAAC;GAEpC;EACF;EAQA,AAAU,cAAc,IAAY;GAClC,MAAM,KAAK,KAAK;GAChB,MAAM,OAAO,GAAG;GAChB,IAAI,SAAS,GAAG;GAEhB,MAAM,KAAK,KAAK,OAAO;GACvB,MAAM,KAAK,KAAK,OAAO;GACvB,MAAM,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;GAClC,MAAM,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;GAClC,MAAM,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;GAClC,MAAM,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;GAElC,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KAAK;IAC7B,MAAM,KAAK,GAAG;IACd,IAAI,CAAC,IAAI;IACT,KAAK,IAAI,IAAI,GAAG,OAAO,GAAG,QAAQ,IAAI,MAAM,KAAK;KAC/C,MAAM,KAAK,GAAG;KACd,KAAK,UAAU,IAAI,EAAE;KACrB,MAAM,eAAe,IAAI,MAAM,MAAM,MAAM,MAAM,KAAK,QAAQ;IAChE;GACF;GAEA,KAAK,eAAe,IAAI;GAExB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KACxB,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC,WAAW,IAAI,KAAK,aAAa,KAAK,SAAS;EAEpE;EAKA,AAAQ,eAAe,MAAc;GACnC,MAAM,KAAK,KAAK;GAGhB,IAAI,KAAK,YAAY,SAAS,OAAO,GACnC,KAAK,cAAc,IAAI,aAAa,OAAO,CAAC;GAE9C,MAAM,OAAO,KAAK;GAClB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KAAK;IAC7B,MAAM,KAAK,GAAG;IACd,IAAI,MAAM;IACV,IAAI,MAAM;IACV,IAAI,MAAM;IACV,IAAI,MAAM;IACV,IAAI,IACF,KAAK,IAAI,IAAI,GAAG,OAAO,GAAG,QAAQ,IAAI,MAAM,KAAK;KAC/C,MAAM,IAAI,GAAG;KACb,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;KACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;KACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;KACxB,IAAI,EAAE,KAAK,KAAK,MAAM,EAAE;IAC1B;IAEF,KAAK,IAAI,KAAK;IACd,KAAK,IAAI,IAAI,KAAK;IAClB,KAAK,IAAI,IAAI,KAAK;IAClB,KAAK,IAAI,IAAI,KAAK;GACpB;GAEA,MAAM,KAAK,KAAK;GAChB,MAAM,OAAO,GAAG;GAEhB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KAAK;IAC7B,MAAM,KAAK,GAAG;IACd,IAAI,CAAC,IAAI;IACT,MAAM,MAAM,KAAK,IAAI;IACrB,MAAM,MAAM,KAAK,IAAI,IAAI;IACzB,MAAM,MAAM,KAAK,IAAI,IAAI;IACzB,MAAM,MAAM,KAAK,IAAI,IAAI;IAEzB,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,MAAM,KAC5B,IACE,GAAG,MACH,OAAO,KAAK,IAAI,IAAI,MACpB,OAAO,KAAK,IAAI,MAChB,OAAO,KAAK,IAAI,IAAI,MACpB,OAAO,KAAK,IAAI,IAAI,IAEpB,GAAG,YAAY,GAAG,EAAE;IAIxB,KAAK,IAAI,OAAO,GAAG,OAAO,MAAM,QAAQ;KACtC,MAAM,IAAI,GAAG;KACb,MAAM,IAAI,EAAE;KACZ,IACE,EAAE,MAAM,MAAM,KACd,EAAE,MAAM,MAAM,KACd,EAAE,MAAM,MAAM,KACd,EAAE,MAAM,MAAM,GAEd,GAAG,gBAAgB,CAAC;IAExB;GACF;EACF;CACF;CAMA,IAAa,WAAb,cAA8B,GAAG;EAe/B,YAAY,GAAG,MAAa;GAC1B,MAAM,GAAG,IAAI;GAff,KAAU,QAAgB;GAC1B,KAAU,UAAkB;GAC5B,KAAU,SAAa,IAAI,GAAG;GAC9B,KAAU,QAAY,IAAI,GAAG;GAC7B,KAAU,UAAkB;GAG5B,KAAU,QAAiB;GASzB,KAAK,QAAQ,KAAK,MAAM;EAC1B;EAKA,IAAI,OAAe;GACjB,OAAO,KAAK;EACd;EACA,IAAI,KAAK,GAAW;GAClB,KAAK,QAAQ;EACf;EAKA,IAAI,SAAiB;GACnB,OAAO,KAAK;EACd;EACA,IAAI,OAAO,GAAW;GACpB,KAAK,UAAU;EACjB;EAKA,IAAI,WAAe;GACjB,OAAO,KAAK;EACd;EACA,IAAI,SAAS,GAAO;GAClB,KAAK,QAAQ;EACf;EAKA,IAAI,QAAY;GACd,OAAO,KAAK;EACd;EACA,IAAI,MAAM,GAAO;GACf,KAAK,SAAS;EAChB;EAKA,IAAI,OAAa;GACf,OAAO,KAAK;EACd;EACA,IAAI,KAAK,GAAS;GAChB,KAAK,QAAQ;EACf;EAKA,IAAI,OAAgB;GAClB,OAAO,KAAK;EACd;EACA,IAAI,KAAK,GAAY;GAInB,IAAI,KAAK,SAAS,CAAC,GAAG,KAAK,MAAM,GAAG,IAAI;GACxC,KAAK,QAAQ;GACb,KAAK,UAAU,IAAI,GAAG,IAAI;EAC5B;EAOA,IAAI,UAAc;GAChB,MAAM,IAAI,KAAK,UAAU,KAAK,KAAK;GACnC,OAAO,KAAK,UAAU,KAAK,KAAK,YAAY,QACxC,EAAE,SAAS,QAAQ,KAAK,OAAO,IAC/B;EACN;EAQA,IAAI,WAAmB;GACrB,OAAO,KAAK;EACd;EACA,IAAI,SAAS,GAAW;GACtB,KAAK,UAAU;EACjB;EAMA,IAAI,SAAS,GAAO;GAClB,KAAK,SAAS,GAAG,IAAI;GACrB,KAAK,UAAU;GACf,IAAI,KAAK,OAAO,KAAK,UAAU;GAC/B,KAAK,GAAG,CAAC;EACX;EAMA,KAAK,GAAiB;GACpB,KAAK,QAAQ;GACb,KAAK,UAAU;GACf,OAAO;EACT;EAMA,SAAS,GAAG,MAAiB;GAC3B,KAAK,OAAO,IAAI,GAAG,IAAI;GACvB,OAAO,KAAK;EACd;EAQA,OAAO,IAAY,UAAkB,QAAuB;GAG1D,IAAI,KAAK,OAMP,KAAK,GAAG,KAAK,OAAO;QACf;IAEL,MAAM,KAAK,SAAS,SAAS,KAAK,WAAW;IAC7C,MAAM,MAAO,MAAM,KAAK,MAAO;IAC/B,MAAM,IAAK,WAAW,KAAM;IAC5B,MAAM,QAAQ,KAAK;IACnB,MAAM,OAAO,KAAK;IAClB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK;KAC/C,MAAM,MAAM,KAAK;KACjB,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,MAAM,KAAK;KAClD,KAAK,KAAK;KACV,KAAK,KAAK,MAAM;IAClB;IACA,MAAM,KAAK,CAAC;IACZ,KAAK,UAAU;GACjB;GACA,OAAO;EACT;EAQA,IAAI,GAAG,MAAmB;GAExB,MAAM,OAAO,KAAK;GAClB,IAAI,KAAK,UAAU,KAAK,KAAK,YAAY,OAAO;IAC9C,MAAM,IAAI,QAAQ,KAAK;IACvB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK,KAAK,MAAM;GAE9C;GACA,KAAK,UAAU;GACf,KAAK,SAAS,IAAI,GAAG,GAAG,IAAI,CAAC,CAAC,QAAQ,KAAK,KAAK,KAAK,KAAK,CAAC,CAAC;GAC5D,OAAO;EACT;EAOA,QAAQ,IAAc,OAAe,GAAS;GAI5C,MAAM,KAAK;GACX,IAAI,KAAK,GAAG,KAAK,GAAG;GACpB,IAAI,KAAK,GAAG,KAAK,GAAG;GACpB,IAAI,SAAS,KAAK,KAAK,KAAK;GAC5B,MAAM,KAAK,GAAG,SAAS,GAAG;GAC1B,IAAI,UAAU,KAAK,IAAI;GAEvB,MAAM,QAAQ,GAAG;GACjB,MAAM,QAAQ,GAAG;GACjB,IAAI,MAAM,GAAG,KAAK,MAAM;GACxB,IAAI,MAAM,GAAG,KAAK,MAAM;GACxB,IAAI,MAAM,GAAG,KAAK,MAAM;GACxB,IAAI,MAAM,GAAG,KAAK,MAAM;GAIxB,IAAI,OAAO,KAAK,KAAK,MAAM;GAC3B,IAAI;GACJ,IAAI,OAAO,MAAU;IACnB,KAAK;IACL,KAAK;IACL,OAAO;IACP,SAAS;IACT,IAAI,CAAC,KAAK;GACZ,OACE,KAAK,OAAO,MAAM,OAAO;GAG3B,MAAM,OAAO,GAAG,KAAK,KAAK;GAC1B,MAAM,OAAO,GAAG,KAAK,KAAK;GAC1B,MAAM,OAAO,GAAG,KAAK,KAAK;GAC1B,MAAM,OAAO,GAAG,KAAK,KAAK;GAE1B,MAAM,KAAM,QAAQ,KAAK,MAAM,KAAK,OAAQ;GAC5C,MAAM,KAAM,QAAQ,KAAK,MAAM,KAAK,OAAQ;GAC5C,MAAM,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG;GACpC,MAAM,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG;GAEpC,QAAQ,KAAK,MAAM,KAAK;GACxB,QAAQ,KAAK,MAAM,KAAK;GACxB,QAAQ,KAAK,MAAM,KAAK;GACxB,QAAQ,KAAK,MAAM,KAAK;GAExB,GAAG,KAAK;GACR,GAAG,KAAK;GACR,GAAG,KAAK;GACR,GAAG,KAAK;GACR,MAAM,KAAK,OAAO;GAClB,MAAM,KAAK,OAAO;GAClB,MAAM,KAAK,OAAO;GAClB,MAAM,KAAK,OAAO;EACpB;EAKA,WAAmB;GACjB,OAAO,aAAa,KAAK,GAAG,GAAG,KAAK,GAAG,cAAc,KAAK,MAAM,GAAG,GAAG,KAAK,MAAM,GAAG,UAAU,KAAK;EACrG;CACF;CAMA,IAAa,OAAb,MAAa,aAAa,MAAM;EAU9B,cAAc;GACZ,MAAM;GAVR,KAAU,MAAuB,CAAC;GAClC,KAAU,SAAiB;GAC3B,KAAU,SAAwC,CAAC;GACnD,KAAU,QAAgB;GAC1B,KAAU,2BAAyB,IAAI,aAAa,CAAC;EAOrD;EASA,OAAO,UACL,MACA,QAAgB,GAChB,WAAoB,MACpB,WAAoB,MACd;GACN,IAAI,IAAI,IAAI,KAAK,CAAC,CAAC,KAAK,IAAI;GAC5B,IAAI,UAAU,EAAE,QAAQ,KAAK;GAC7B,IAAI,UAAU,EAAE,SAAS;GACzB,OAAO;EACT;EAOA,KAAK,MAAkB,QAAgB,GAAS;GAC9C,KAAK,IAAI,MAAM,MAAM;IACnB,IAAI,IAAI,IAAI,SAAS,EAAE;IACvB,EAAE,OAAO;IACT,KAAK,KAAK,CAAC;GACb;GAEA,KAAK,SAAS;GAEd,OAAO;EACT;EAKA,IAAI,OAAe;GACjB,OAAO,KAAK;EACd;EACA,IAAI,KAAK,GAAW;GAClB,KAAK,QAAQ;GACb,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAC1C,AAAC,KAAK,EAAE,CAAc,OAAO,KAAK;EAEtC;EAKA,WAAiB;GACf,KAAK,OAAO,KAAK,KAAK,QAAQ,KAAK,IAAI,CAAC,IAAI;GAC5C,OAAO;EACT;EAQA,KAAK,QAAgB,QAAgB,OAAsB;GACzD,IAAI,SAAS,KAAK,UAAU,KAAK,QAC/B,MAAM,IAAI,MAAM,sCAAsC;GACxD,IAAI,SAAS,KAAK,UAAU,KAAK,QAC/B,MAAM,IAAI,MAAM,sCAAsC;GAExD,IAAI,IAAI,KAAK,OAAO,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,UAAU;GACvD,KAAK,IAAI,KAAK;IAAC;IAAQ;IAAQ;IAAG,SAAS,KAAK;GAAM,CAAC;GACvD,OAAO;EACT;EAMA,QAAQ,OAAqB;GAC3B,MAAM,OAAO,KAAK,SAAS;GAK3B,MAAM,WAAW,GAAW,GAAW,MAAe;IACpD,IAAI,MAAM,GAAG;IACb,MAAM,KAAK,KAAK;IAChB,KAAK,IAAI,IAAI,GAAG,OAAO,GAAG,QAAQ,IAAI,MAAM,KAAK;KAC/C,MAAM,IAAI,GAAG;KACb,IAAK,EAAE,OAAO,KAAK,EAAE,OAAO,KAAO,EAAE,OAAO,KAAK,EAAE,OAAO,GAAI;IAChE;IACA,KAAK,KAAK,GAAG,GAAG,CAAC;GACnB;GAEA,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,IAAI,KAAK,KAAK;IAC/C,MAAM,IAAI,KAAK,MAAM,IAAI,IAAI,IAAI;IACjC,QAAQ,GAAG,GAAG,KAAK;IAEnB,IAAI,MAAM,GAAG;KACX,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC,IAAI;KAClC,MAAM,KAAK,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI;KACzC,QAAQ,GAAG,IAAI,KAAK;IACtB;IAEA,IAAI,KAAK,OAAO,GACd,QAAQ,GAAG,KAAK,IAAI,KAAK,SAAS,GAAG,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC;GAE9D;EACF;EAMA,eAAwB;GACtB,IAAI,KAAK,CAAC;GACV,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,IAAI,QAAQ,IAAI,KAAK,KAAK;IACnD,IAAI,KAAK,KAAK,IAAI;IAClB,GAAG,KAAK,IAAI,MAAM,KAAK,GAAG,KAAK,KAAK,GAAG,GAAG,CAAC;GAC7C;GACA,OAAO;EACT;EAKA,eAAqB;GACnB,KAAK,IAAI,IAAI,GAAG,MAAM,KAAK,IAAI,QAAQ,IAAI,KAAK,KAAK;IACnD,IAAI,CAAC,GAAG,GAAG,GAAG,KAAK,KAAK,IAAI;IAC5B,MAAM,eAAe,KAAK,IAAgB,KAAK,IAAgB,GAAG,CAAC;GACrE;EACF;EAeA,WAAW,IAAY,aAAqB,GAAG,WAAmB,GAAS;GACzE,MAAM,KAAK,KAAK;GAChB,MAAM,OAAO,GAAG;GAChB,IAAI,SAAS,GAAG,OAAO;GAEvB,IAAI,KAAK,SAAS,SAAS,MAAM,KAAK,WAAW,IAAI,aAAa,IAAI;GACtE,MAAM,UAAU,KAAK;GACrB,QAAQ,KAAK,GAAG,GAAG,IAAI;GACvB,MAAM,YAAY,IAAI,KAAK,IAAI,GAAG,aAAa,QAAQ;GAEvD,KAAK,IAAI,OAAO,GAAG,OAAO,YAAY,QACpC,KAAK,IAAI,KAAK,GAAG,KAAK,MAAM,MAAM;IAChC,MAAM,IAAI,GAAG;IACb,MAAM,KAAK,KAAK,EAAE;IAClB,MAAM,KAAK,KAAK,EAAE;IAClB,MAAM,QAAQ,EAAE;IAEhB,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,GAAG,QAAQ;IACzC,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,GAAG,QAAQ;IACzC,MAAM,IAAI,KAAK;IACf,IAAI,MAAM,GAAG;IAEb,MAAM,KAAK,GAAG,KAAK,GAAG;IACtB,MAAM,KAAK,GAAG,KAAK,GAAG;IACtB,MAAM,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;IACxC,IAAI,OAAO,MAAU;IAIrB,IAAI,QAAQ;IACZ,IAAI,QAAQ,GAAG;KACb,MAAM,OAAO,IAAI,KAAK,IAAI,IAAI,OAAO,SAAS;KAC9C,QAAQ,OAAO,OAAY,KAAK,IAAI,QAAS,OAAO,IAAI;IAC1D;IACA,MAAM,MAAM,EAAE,OAAO,EAAE,MAAM,QAAQ,QAAQ,QAAQ,IAAI;IACzD,QAAQ,OAAO;IAEf,MAAM,IAAI,KAAK;IACf,MAAM,KAAK,KAAK;IAChB,MAAM,KAAK,KAAK;IAChB,GAAG,MAAM,KAAK;IACd,GAAG,MAAM,KAAK;IACd,GAAG,MAAM,KAAK;IACd,GAAG,MAAM,KAAK;GAChB;GAEF,OAAO;EACT;EAMA,YAAY,GAAe;GACzB,IAAI,KAAK;GACT,IAAI,KAAK;GAET,IAAI,MAAM,QAAQ,oBAAoB,IAAI,EAAE;GAE5C,IAAI,KAAK;IACP,IAAI,KAAK,IAAI,OAAO,UAAU,IAAI,IAAI;IAEtC,IAAI;IACJ,IAAI,KAAK,IAAI;IACb,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,GAC9D,KAAK,IAAI,OAAO,KAAK,GAAG,KAAK,GAAG,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC;SAE3D,KAAK,IAAI,OAAO,KAAK,GAAG,KAAK,GAAG,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC;IAG7D,IAAI,SAAS,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI;IAEzC,IAAI,KAAM,IAAI,OAAoB,KAAK,QAAQ;IAC/C,IAAI,KAAM,IAAI,KAAK,EAAE,CAAc,KAAK,QAAQ;IAChD,IAAI,MAAM,MAAM,KAAK;IACrB,IAAI,MAAM,MAAM,KAAK;IAErB,GAAG,EAAE,CAAC,SAAS,GAAG,UAAW,OAAO,IAAI,KAAK,SAAU,CAAC,CAAC;IACzD,GAAG,EAAE,CAAC,SAAS,GAAG,UAAW,MAAM,IAAI,SAAU,CAAC,CAAC;IAEnD,IAAI,OAAO,IAAI,GAAG,UAAU,GAAG,CAAC;GAClC;EACF;EAMA,gBAAgB,GAAmB;GACjC,IAAI,KAAK;GACT,IAAI,KAAK;GAET,IAAI,MAAM,QAAQ,mBAAmB,IAAI,OAAO,WAAW,GAAG,EAAE,MAAM,CAAC;GAEvE,IAAI,KAAK;IACP,IAAI,KAAK,IAAI,OAAO,UAAU,IAAI,IAAI;IAEtC,IAAI;IACJ,IAAI,KAAK,IAAI;IACb,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,GAC9D,KAAK,IAAI,OAAO,KAAK,GAAG,KAAK,GAAG,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC;SAE3D,KAAK,IAAI,OAAO,KAAK,GAAG,KAAK,GAAG,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC;IAG7D,IAAI,SAAS,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI;IAGzC,IAAI,KAAK,GAAG,QAAQ;IACpB,IAAI,KAAM,IAAI,KAAK,EAAE,CAAc,KAAK,QAAQ;IAEhD,IAAI,MAAM,MAAM,KAAK;IACrB,IAAI,MAAM,MAAM,KAAK;IAErB,GAAG,EAAE,CAAC,SAAS,GAAG,UAAW,OAAO,IAAI,KAAK,SAAU,CAAC,CAAC;IACzD,GAAG,EAAE,CAAC,SAAS,GAAG,UAAW,MAAM,IAAI,SAAU,CAAC,CAAC;IAGnD,IAAI,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,IAAI,GAAG,UAAU,GAAG,CAAC;IACtD,EAAE,WAAW,EAAE,UAAU,EAAE;GAC7B;EACF;CACF;;;;;;;;CC9rCA,IAAa,QAAb,MAAa,MAAyB;EAYpC,YAAY,KAAa;GARzB,KAAU,aAAgD,CAAC;GAC3D,KAAU,eAAuB;GAQ/B,KAAK,MAAM;EACb;EAMA,OAAO,SAAS,IAAmB;GACjC,OAAO,IAAI,MAAM,MAAQ,EAAE;EAC7B;EAKA,IAAI,MAAc;GAChB,OAAO,KAAK;EACd;EACA,IAAI,IAAI,GAAW;GACjB,KAAK,OAAO;GACZ,KAAK,MAAM,MAAQ,KAAK;EAC1B;EAKA,IAAI,KAAa;GACf,OAAO,KAAK;EACd;EACA,IAAI,GAAG,GAAW;GAChB,KAAK,OAAO,MAAQ;GACpB,KAAK,MAAM;EACb;EAGA,AAAU,YAAoB;GAC5B,OAAO,OAAO,KAAK;EACrB;EAWA,MAAM,OAA2C;GAC/C,MAAM,OAAO;GACb,MAAM,IAAI,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK;GAE5C,OAAO;IACL,OAAO,SACL,IACA,SAAiB,GACjB,MACiB;KACjB,MAAM,KAAK,QAAQ,KAAK,UAAU;KAClC,KAAK,WAAW,MAAM;MACpB,MAAM;MACC;MACP,QAAQ;MACR,OAAO;MACC;MACR,UAAU;MACV,OAAO;MACP,YAAY;MACR;KACN;KACA,OAAO;IACT;IAEA,UAAU,SACR,IACA,SAAiB,GACjB,MACiB;KACjB,MAAM,KAAK,QAAQ,KAAK,UAAU;KAClC,KAAK,WAAW,MAAM;MACpB,MAAM;MACC;MACP,QAAQ;MACR,OAAO;MACC;MACR,UAAU;MACV,OAAO;MACP,YAAY;MACR;KACN;KACA,OAAO;IACT;GACF;EACF;EAOA,MAAM,MAAc;GAClB,KAAK,MAAM,KAAK,KAAK,YACnB,IAAI,KAAK,WAAW,eAAe,CAAC,GAAG;IACrC,MAAM,KAAK,KAAK,WAAW;IAC3B,MAAM,KAAK,GAAG,SAAS,OAAO,GAAG,SAAS;IAC1C,MAAM,KAAK,GAAG,SAAU,KAAK;IAC7B,IAAI,UAAU;IAEd,IAAI,GAAG,WAAY,GAAG;KAEpB,GAAG,WAAW,KAAM,KAAK,KAAK;KAC9B,GAAG,QAAQ,GAAG,SAAS;KACvB,UAAU;IACZ,OAAO,IAAI,KAAK,GAAG,WAAY,IAAI;KACjC,GAAG,WAAW,KAAM,KAAK,KAAK;KAC9B,IAAI,MAAM,QAAQ,GAAG,KAAK,GAAG;MAE3B,GAAG,SAAS,GAAG,QAAS,KAAK,GAAG,MAAM;MACtC,GAAG,SAAS,GAAG,MAAM,GAAG;KAC1B;KACA,GAAG,SAAS,GAAG,SAAS,KAAK;KAC7B,UAAU;IACZ;IAEA,IAAI;IACJ,IAAI,GAAG,YAAY;KACjB,MAAM,IAAI,IAAI,OAAO,KAAK,GAAG,YAAa,IAAI,GAAG,CAAC;KAClD,OAAQ,GAAG,GAAwB,KACjC,IACA,GAAG,OACH,GACA,IACA,OACF;IACF,OAAO,IAAI,SACT,OAAQ,GAAG,GAAqB,KAAK,IAAI,GAAG,KAAM;IAEpD,IAAI,MAAM,OAAO,KAAK,WAAW,GAAG;GACtC;EAEJ;EAMA,KAAK,MAAoB;GACvB,IAAI,KAAK,WAAW,OAAO,OAAO,KAAK,WAAW;EACpD;EAKA,QAAQ,MAAc,OAAe;GACnC,KAAK,MAAM,IAAI;EACjB;EAKA,OAAO,OAAc,KAAa,CAElC;EAKA,OAAO,MAAc,IAAY,IAAY,KAAY,CAEzD;CACF;CAKA,IAAa,QAAb,MAAa,MAAM;EAqDjB,YAAY,MAAiB,KAAoB;GAzBjD,KAAU,WAAoB;GAQ9B,KAAU,UAAkB;GAE5B,KAAU,aAA0B,CAAC;GAErC,KAAU,gBAAyB;GAEnC,KAAU,aAAsB;GAY9B,KAAK,QAAQ;GACb,KAAK,OAAO,OAAO,MAAM,YAAY;EACvC;EAKA,OAAiB,cAA4B;GAC3C,IAAI,CAAC,MAAM,gBAAgB;IACzB,MAAM,OACJ,OAAO,WAAW,cAAc,OAAO,eAAe;IACxD,IAAI,CAAC,MACH,MAAM,IAAI,MACR,2DACF;IACF,MAAM,iBAAiB,IAAI,KAAK;GAClC;GACA,OAAO,MAAM;EACf;EAUA,OAAO,KACL,MACA,KACA,OAAkB,OAClB,QACA;GACA,MAAM,IAAI,IAAI,MAAM,MAAM,GAAG;GAC7B,EAAE,QAAQ;GACV,IAAI,QAAQ,EAAE,UAAU;GACxB,OAAO;EACT;EASA,OAAO,KACL,QACA,cAAsB,aACN;GAChB,OAAO,IAAI,SAAS,SAAS,WAAW;IACtC,MAAM,IAAI,IAAI,MAAM,MAAM;IAC1B,IAAI,OAAO,WAAW,UAAU;KAE9B,EAAE,UAAU,IAAI,MAAM;KACtB,EAAE,QAAQ,cAAc;KACxB,EAAE,QAAQ,MAAM;IAClB,OAAO;KACL,EAAE,UAAU;KACZ,EAAE,QAAQ,cAAc;IAC1B;IACA,EAAE,QAAQ,WAAW;IAErB,MAAM,gBAAgB;KACpB,EAAE,QAAQ,oBAAoB,kBAAkB,KAAK;KACrD,uBACE,IAAI,MAAM,wBAAwB,EAAE,QAAQ,OAAO,iBAAiB,CACtE;IACF;IAEA,MAAM,cAAc;KAElB,EAAE,QAAQ,oBAAoB,SAAS,OAAO;KAC9C,EAAE,QAAQ,iBAAiB,SAAS,WAAY;MAC9C,EAAE,WAAW;KACf,CAAC;KACD,EAAE,QAAQ,EAAE,KAAK,yBAAyB,EAAE,OAAO;KACnD,QAAQ,CAAC;IACX;IAEA,IAAI,EAAE,QAAQ,cAAc,GAE1B,MAAM;SACD;KACL,EAAE,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;KAC3D,EAAE,QAAQ,iBAAiB,kBAAkB,OAAO,EAAE,MAAM,KAAK,CAAC;KAClE,IAAI,EAAE,QAAQ,eAAe,GAAG,EAAE,QAAQ,KAAK;IACjD;GACF,CAAC;EACH;EAOA,OAAa,aAAa;yCAA6B;IACrD,MAAM,IAAI,IAAI,MAAM,MAAM;IAC1B,MAAM,MAAM,MAAM,MAAM,GAAG;IAC3B,IAAI,CAAC,IAAI,IACP,MAAM,IAAI,MAAM,wBAAwB,IAAI,WAAW,IAAI,OAAO,EAAE;IACtE,IAAI;KACF,EAAE,aAAa,MAAM,EAAE,KAAK,gBAAgB,MAAM,IAAI,YAAY,CAAC,CAAC;IACtE,SAAS,KAAK;KAEZ,MAAM,OAAO,uBAAO,IAAI,MAAM,sBAAsB,GAAG,EAAE,OAAO,IAAI,CAAC;IACvE;IACA,OAAO;GACT;;EAMA,aAAa,KAAyB;GACpC,IAAI,KAAK,OAAO;IAEd,AAAC,KAAK,MAAgC,UAAU;IAChD,KAAK,MAAM,WAAW;GACxB;GACA,KAAK,QAAQ,KAAK,KAAK,mBAAmB;GAC1C,IAAI,QAAQ,QAAW,KAAK,UAAU;GAEtC,AAAC,KAAK,MAAgC,SAAS,KAAK;GACpD,AAAC,KAAK,MAAgC,gBAAgB;IACpD,KAAK,WAAW;GAClB;GACA,KAAK,gBAAgB;GACrB,IAAI,KAAK,UAAU,KAAK,MAAM,QAAQ,KAAK,SAAS,IAAI;GACxD,KAAK,MAAM,KAAK,KAAK,YAAY,KAAK,MAAM,QAAQ,CAAC;GACrD,OAAO;EACT;EASA,OAAO,SAAS,MAAsB,KAAmC;GAEvE,OAAO,IADO,MAAM,KACb,CAAC,CAAC,KAAK,MAAM,GAAG;EACzB;EAGA,AAAU,KAAK,MAAsB,KAAmC;GACtE,IAAI,KAAK,OAAO,KAAK,MAAM,WAAW;GACtC,KAAK,QAAQ,KAAK,KAAK,iBAAiB;GACxC,KAAK,aAAa;GAClB,MAAM,MAAM,KAAK;GACjB,IAAI,SAAS,UAAU;IACrB,KAAK,QAAQ;IACb,IAAI,gBAAgB,KAAK,KAAK;GAChC,OAAO;IACL,IAAI,OAAO;IACX,IAAI,UAAU,QAAQ;GACxB;GACA,OAAO;EACT;EAQA,OAAa,MAAM;yCAAqD;IACtE,MAAM,IAAI,IAAI,MAAM,OAAO;IAC3B,MAAM,IAAI,aAAa,aAAa;KAAE,OAAO;KAAM,OAAO;IAAM;IAChE,EAAE,UAAU,MAAM,UAAU,aAAa,aAAa,CAAC;IACvD,EAAE,QAAQ,EAAE,KAAK,wBAAwB,EAAE,OAAO;IAClD,OAAO;GACT;;EAKA,IAAI,MAAoB;GACtB,OAAO,KAAK;EACd;EAKA,IAAI,OAAkB;GACpB,OAAO,KAAK;EACd;EAKA,IAAI,aAAwB;GAC1B,OAAO,KAAK;EACd;EAKA,IAAI,SAAsB;GACxB,OAAO,KAAK;EACd;EAKA,IAAI,SAA2B;GAC7B,OAAO,KAAK;EACd;EAKA,IAAI,SAAsB;GACxB,OAAO,KAAK;EACd;EACA,IAAI,OAAO,GAAgB;GACzB,KAAK,UAAU;EACjB;EAKA,IAAI,OAAkB;GACpB,OAAO,KAAK;EACd;EAKA,IAAI,UAAmB;GACrB,OAAO,KAAK;EACd;EAKA,IAAI,WAAmB;GACrB,IAAI,MAAM;GACV,IAAI,OAAO;GACX,IAAI,KAAK,SAAS;IAChB,MAAM,KAAK,QAAQ;IAEnB,OACE,KAAK,eAAe,SAChB,KAAK,KAAK,cAAc,KAAK,aAC7B;GACR,OAAO,IAAI,KAAK,SAAS;IACvB,MAAM,KAAK,QAAQ;IACnB,OAAO,KAAK,QAAQ;GACtB;GACA,OAAO,MAAM,IAAI,IAAI,MAAM,OAAO,KAAK,GAAG,CAAC,IAAI;EACjD;EAMA,IAAI,WAAoB;GACtB,IAAI,KAAK,UAAU,WAAW,KAAK,UAAU,OAC3C,OAAO,KAAK,UAAU;GACxB,OACE,CAAC,CAAC,KAAK,WACN,KAAK,YAAY,UAAa,KAAK,QAAQ,eAAe;EAE/D;EAKA,IAAI,UAAkB;GACpB,OAAO,KAAK,WAAW,KAAK,SAAS,OAAO;EAC9C;EAKA,IAAI,aAAqB;GACvB,OAAO,KAAK,KAAK;EACnB;EAKA,IAAI,YAAoB;GACtB,MAAM,MAAM,KAAK;GACjB,OAAO,KAAK,UAAU,SAAS,OAAO,IAAI,YACtC,IAAI,UAAU,QACd;EACN;EACA,IAAI,UAAU,GAAW;GACvB,MAAM,MAAM,KAAK;GACjB,IAAI,KAAK,UAAU,SAAS,OAAO,IAAI,WAAW,IAAI,UAAU,QAAQ;EAC1E;EAKA,IAAI,SAAiB;GACnB,OAAO,KAAK;EACd;EACA,IAAI,OAAO,GAAW;GACpB,KAAK,UAAU,KAAK,IAAI,GAAG,KAAK,CAAC;GACjC,IAAI,KAAK,OAAO,KAAK,MAAM,KAAK,QAAQ,KAAK;EAC/C;EAMA,QAAQ,MAAuB;GAC7B,KAAK,WAAW,KAAK,IAAI;GACzB,KAAK,MAAM,QAAQ,IAAI;GACvB,OAAO;EACT;EAQA,cAAc,YAA6B;GACzC,KAAK,cAAc;GACnB,OAAO;EACT;EAMA,mBAAyB;GACvB,KAAK,cAAc;GACnB,OAAO;EACT;EASA,QACE,OAAe,KACf,QAAgB,MAChB,QAAgB,KAChB,SAAiB,IACX;GACN,IAAI,KAAK,YAAY,KAAK,OACxB,IAAI;IACF,KAAK,MAAM,WAAW,KAAK,SAAS,IAAI;GAC1C,kBAAQ,CAER;GAEF,MAAM,IAAI,KAAK,KAAK,eAAe;GACnC,EAAE,UAAU,OAAO;GACnB,EAAE,cAAc;GAChB,EAAE,cAAc;GAChB,EAAE,wBAAwB;GAC1B,KAAK,WAAW;IACd,MAAM;IACN,MAAM,EAAE;IACR,MAAM,IAAI,WAAW,EAAE,iBAAiB;GAC1C;GACA,KAAK,MAAM,QAAQ,KAAK,SAAS,IAAI;GACrC,OAAO;EACT;EAGA,AAAU,QAAQ,MAA2B;GAC3C,IAAI,KAAK,UAAU;IACjB,IAAI,MACF,KAAK,SAAS,KAAK,sBACjB,KAAK,SAAS,IAGhB;SAEA,KAAK,SAAS,KAAK,qBACjB,KAAK,SAAS,IAGhB;IAEF,OAAO,KAAK,SAAS;GACvB;GACA,uBAAO,IAAI,WAAW,CAAC;EACzB;EAGA,AAAU,UACR,MACA,MACA,WAAmB,CAAC,GAAG,CAAC,GACxB,OAAO,CAAC,GAAG,CAAC,GACZ,KACO;GACP,MAAM,OAAO,OAAO,KAAK,WAAW,IAAI,KAAK,WAAW;GACxD,MAAM,IAAI,OAAO,IAAI,MAAM;GAC3B,MAAM,MAAM,KAAK,SAAS,KAAK;GAC/B,MAAM,QAAQ,KAAK,IAAI,GAAG,MAAM,KAAK,EAAE;GACvC,IAAI,EAAE,SAAS,OAAO,EAAE,SAAS;GACjC,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,KAAK;IAC9C,MAAM,IAAI,SAAS,KAAM,KAAK,KAAK,IAAK;IACxC,MAAM,IAAI,SAAS,KAAM,KAAK,KAAK,KAAK,KAAM;IAC9C,MAAM,IAAI,EAAE;IACZ,IAAI,KAAK,EAAE,UAAU,GAAG;KACtB,EAAE,KAAK;KACP,EAAE,KAAK;IACT,OACE,EAAE,KAAK,IAAI,GAAG,GAAG,CAAC;GAEtB;GACA,OAAO;EACT;EAKA,aAAyB;GACvB,OAAO,KAAK,QAAQ,IAAI;EAC1B;EAWA,aACE,MACA,WAAmB,CAAC,GAAG,CAAC,GACxB,OAAO,CAAC,GAAG,CAAC,GACZ,KACO;GACP,OAAO,KAAK,UAAU,MAAM,MAAM,UAAU,MAAM,GAAG;EACvD;EAKA,aAAyB;GACvB,OAAO,KAAK,QAAQ,KAAK;EAC3B;EAWA,aACE,MACA,WAAmB,CAAC,GAAG,CAAC,GACxB,OAAO,CAAC,GAAG,CAAC,GACZ,KACO;GACP,OAAO,KAAK,UAAU,OAAO,MAAM,UAAU,MAAM,GAAG;EACxD;EAKA,QAAc;GACZ,KAAK,KAAK;GACV,IAAI,KAAK,OAAO,KAAK,MAAM,WAAW;GACtC,IAAI,KAAK,aAAa,KAAK,YAAY,WAAW;GAClD,OAAO;EACT;EAGA,AAAU,WAAqB;GAC7B,IAAI,CAAC,KAAK,OAAO;IACf,KAAK,QAAQ,KAAK,KAAK,WAAW;IAClC,KAAK,MAAM,KAAK,QAAQ,KAAK;IAC7B,KAAK,MAAM,QAAQ,KAAK,KAAK,WAAW;GAC1C;GACA,OAAO,KAAK;EACd;EAOA,MAAM,SAAiB,GAAS;GAC9B,IAAI,KAAK,KAAK,UAAU,aAAa,KAAK,KAAK,OAAO;GAEtD,IAAI,KAAK,UAAU,QAAQ;IACzB,IAAI,KAAK,SAAS;KAGhB,IAAI,KAAK,YAAY,KAAK,iBAAiB,CAAC,KAAK,OAAO;MACtD,IAAI,KAAK,YAAY,KAAK,WAAW,GACnC,AAAC,KAAK,MAAgC,KAAK;MAE7C,KAAK,aAAa;KACpB;KACA,AAAC,KAAK,MAAgC,MAAM,GAAG,MAAM;KACrD,KAAK,gBAAgB;KACrB,KAAK,aAAa,KAAK,KAAK,cAAc;IAC5C,OAAO;KACL,IAAI,SAAS,GAAG,KAAK,QAAQ,cAAc;KAC3C,MAAM,SAAS,KAAK,QAAQ,KAAK;KACjC,IAAI,UAAU,OAAO,OACnB,OAAO,YAAY;MAEjB,IAAI,KAAK,QAAQ,QAAQ,KAAK,WAAW;KAC3C,CAAC;IAEL;GACF,OAAO,IAAI,KAAK,UAAU,SAAS,KAAK,YAAY;IAElD,IAAI,KAAK,UAAU,OAAO;IAC1B,MAAM,MAAM,KAAK;IACjB,KAAK,KACH,IAAI,MACJ,IAAI,SAAS,WAAW,KAAK,QAAQ,IAAI,UAAU,KACrD;IACA,AAAC,KAAK,MAAyB,MAAM;GACvC;GAGA,IAAI,KAAK,UAAU,KAAK,MAAM,QAAQ,KAAK,SAAS,IAAI;GACxD,KAAK,MAAM,KAAK,KAAK,YAAY,KAAK,MAAM,QAAQ,CAAC;GAErD,CAAC,KAAK,eAAe,KAAK,MAAK,CAAE,QAAQ,KAAK,SAAS,CAAC;GACxD,KAAK,WAAW;GAChB,OAAO;EACT;EAKA,OAAa;GACX,IAAI,CAAC,KAAK,UAAU,OAAO;GAC3B,CAAC,KAAK,eAAe,KAAK,MAAK,CAAE,WAAW,KAAK,KAAK;GAEtD,IAAI,KAAK,UAAU,QAAQ;IACzB,IAAI,KAAK,SAEP;SAAI,KAAK,WAAW,GAAG,AAAC,KAAK,MAAgC,KAAK;IAAC,OAEnE,KAAK,QAAQ,MAAM;GAEvB,OAAO,IAAI,KAAK,UAAU,OACxB;QAAI,KAAK,YAAY,AAAC,KAAK,MAAyB,KAAK;GAAC,OACrD,IAAI,KAAK,UAAU,WAAW,KAAK,SAExC,KAAK,QAAQ,eAAe,CAAC,CAAC,SAAS,UAAU,MAAM,KAAK,CAAC;GAG/D,KAAK,WAAW;GAChB,OAAO;EACT;EAKA,SAAe;GACb,IAAI,KAAK,UACP,KAAK,KAAK;QAEV,KAAK,MAAM;GAEb,OAAO;EACT;EAMA,UAAgB;GAEd,IAAI,CAAC,KAAK,YAAY,KAAK,SACzB,KAAK,QAAQ,eAAe,CAAC,CAAC,SAAS,UAAU,MAAM,KAAK,CAAC;GAE/D,KAAK,MAAM;GACX,IAAI,KAAK,UAAU;IACjB,KAAK,SAAS,KAAK,WAAW;IAC9B,KAAK,WAAW;GAClB;GACA,IAAI,KAAK,OAAO;IACd,KAAK,MAAM,WAAW;IACtB,KAAK,QAAQ;GACf;GACA,KAAK,aAAa,CAAC;GACnB,KAAK,UAAU;GACf,KAAK,UAAU;GACf,KAAK,UAAU;GACf,OAAO;EACT;CACF;;;;CCn0BA,WAAW,yQACNC,iBACAC,iBACAC,eACAC,wBACAC,cACAC,aACAC,aACAC,gBACAC,gBACAC,eACAC,cACAC,cACAC,qBACAC,kBACAC,aACAC,eACAC,aACL;CAGA,WAAW,IAAI,aAAa,UAAe;EACzC,IAAI,MAAM,WAAW;EACrB,KAAK,IAAI,KAAK,KACZ,IAAI,KAAK,aACP,MAAM,KAAK,IAAI;CAGrB;CAEA,WAAW,IAAI,cAAc,IAAsB,KAAa,WAAW;EACzE,IAAI,CAAC,QAAQ;EAEb,IAAI,IAAS;EACb,WAAW,IAAI,UAAU,CAAC;EAM1B,MAAM,QACJ,OAAO,OAAO,YAAY,GAAG,OAAO,OAAO,GAAG,OAAO,MAAM,IAAI,OAAO;EACxE,MAAM,OACJ,OAAO,UAAU,WAAW,SAAS,cAAc,KAAK,IAAI;EAM9D,EAAE,QAJA,SACE,KAAiB,SAAS,YAAY,MAAM,SAC5C,CAAC,CAAE,KAAiB,cAAc,cAAc,KAGhD,IAAIC,SAAa,KAAK,CAAC,CAAC,MAAM;GAAE,SAAS;GAAI,QAAQ;EAAK,CAAC,IAC3D,IAAIC,YAAmB,KAAK,CAAC,CAAC,MAAM;GAClC,SAAS;GACT,QAAQ;GACR,QAAQ;EACV,CAAC;EACL,EAAE,OAAO,EAAE,MAAM,QAAQ;EAEzB,OAAO,SAAU,UAAU,MAAM,QAAQ,MAAM,SAAS,MAAM,SAAS,MAAM;GAC3E,EAAE,MAAM,IAAI;IACH;IACE;IACD;IACA;GACV,CAAC;GAED,EAAE,MAAM,UAAU,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK;EACvC;CACF"}
1
+ {"version":3,"file":"pts.js","names":["generator","UIA","this","Typo","Canvas","Create","Form","LinearAlgebra","Num","Op","Pt","Space","Color","Util","Dom","Svg","Typography","Physics","UI","Play","Image","Svg.SVGSpace","Canvas.CanvasSpace"],"sources":["../src/_triangulate.ts","../src/_path.ts","../src/Op.ts","../src/LinearAlgebra.ts","../src/uheprng.ts","../src/Num.ts","../src/Util.ts","../src/Pt.ts","../src/UI.ts","../src/Space.ts","../src/Form.ts","../src/Typography.ts","../src/Image.ts","../src/Canvas.ts","../src/Create.ts","../src/Color.ts","../src/Dom.ts","../src/Svg.ts","../src/Physics.ts","../src/Play.ts","../src/_script.ts"],"sourcesContent":["/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\n/**\n * Internal 2D Delaunay triangulation used by [`Delaunay`](#link).\n *\n * Points are inserted one at a time in Hilbert-curve order, so each point is\n * found by a short walk from the previous insertion. An insertion removes every\n * triangle whose circumcircle contains the point and fans the resulting cavity\n * from it (Bowyer–Watson). The convex hull is represented by ghost triangles\n * that share one vertex \"at infinity\", which lets hull growth use the same\n * cavity step as interior insertion and keeps every half-edge paired.\n *\n * Orientation and in-circle decisions are exact. A floating-point error\n * bound settles the easy cases; integer coordinates below 2^25 are resolved\n * with limb arithmetic in doubles; anything else is evaluated in BigInt from\n * the exact binary value of each coordinate. Exact decisions are what make\n * cocircular grids, collinear runs, points on edges, and duplicate points\n * safe: they can never produce a degenerate triangle or an endless walk.\n */\n\n/** A triangulation of the finite, distinct input points. */\nexport type Triangulation = {\n /** Point indices, three per triangle, counterclockwise. */\n triangles: Uint32Array;\n /**\n * For half-edge `h = 3t + e` (from `triangles[h]` to the triangle's next vertex),\n * the index of the opposite half-edge in the adjacent triangle, or -1 on the hull.\n */\n neighbors: Int32Array;\n /** Point indices of the convex hull, counterclockwise. Empty when there are no triangles. */\n hull: Uint32Array;\n};\n\nconst EMPTY: Triangulation = {\n triangles: new Uint32Array(0),\n neighbors: new Int32Array(0),\n hull: new Uint32Array(0),\n};\n\n// ---------------------------------------------------------------- predicates\n\n// 2^-53: half an ulp at 1, the rounding error of one double operation\nconst EPS = 1.1102230246251565e-16;\n// Bounds on the rounding error of the determinants below, relative to the sum\n// of the absolute values of their terms (the classic forward error analysis\n// of the orientation and in-circle determinants).\nconst ORIENT_BOUND = (3 + 16 * EPS) * EPS;\nconst INCIRCLE_BOUND = (10 + 96 * EPS) * EPS;\n// Coordinates that become integers below 2^31 when scaled by one power of two\n// (pixel grids, halves, quarters, every Float32 value in a sane range) keep\n// their differences exact in a double; the products those differences form are\n// then evaluated exactly in limb arithmetic without BigInt.\nconst INT_LIMIT = 2147483648;\nconst _input = new Float64Array(8);\n// the scale shared by every coordinate of the set being triangulated, when\n// one exists (set by `triangulate`); 0 means decide per call\nlet _presetScale = 0;\n\n/**\n * The smallest power of two that turns every value in `_input[0..count)` into\n * an integer below 2^31 in magnitude, or 0 when no scale up to 2^30 does.\n */\nfunction _integerScale(count: number): number {\n if (_presetScale > 0) return _presetScale;\n let scale = 1;\n for (let k = 0; k <= 30; k++) {\n let exact = true;\n for (let i = 0; i < count; i++) {\n const v = _input[i] * scale;\n if (v >= INT_LIMIT || v <= -INT_LIMIT) return 0; // scaling only grows\n if ((v | 0) !== v) exact = false;\n }\n if (exact) return scale;\n scale *= 2;\n }\n return 0;\n}\n\n/**\n * Orientation of `c` relative to the directed line `a → b`:\n * 1 when `c` is to the left (counterclockwise turn), -1 to the right, 0 when collinear.\n * The result is exact for any finite doubles.\n */\nexport function orient2d(\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n): number {\n const left = (ax - cx) * (by - cy);\n const right = (ay - cy) * (bx - cx);\n const det = left - right;\n const bound = ORIENT_BOUND * (Math.abs(left) + Math.abs(right));\n if (det > bound) return 1;\n if (-det > bound) return -1;\n _input[0] = ax;\n _input[1] = ay;\n _input[2] = bx;\n _input[3] = by;\n _input[4] = cx;\n _input[5] = cy;\n const scale = _integerScale(6);\n if (scale !== 0) {\n return _orientInt(\n (ax - cx) * scale,\n (by - cy) * scale,\n (ay - cy) * scale,\n (bx - cx) * scale,\n );\n }\n return orient2dExact(ax, ay, bx, by, cx, cy);\n}\n\n/**\n * In-circle test: 1 when `d` is strictly inside the circle through the\n * counterclockwise triangle `a, b, c`, -1 when outside, 0 when on the circle.\n * The result is exact for any finite doubles.\n */\nexport function incircle(\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n dx: number,\n dy: number,\n): number {\n const adx = ax - dx;\n const ady = ay - dy;\n const bdx = bx - dx;\n const bdy = by - dy;\n const cdx = cx - dx;\n const cdy = cy - dy;\n\n const bdxcdy = bdx * cdy;\n const cdxbdy = cdx * bdy;\n const alift = adx * adx + ady * ady;\n const cdxady = cdx * ady;\n const adxcdy = adx * cdy;\n const blift = bdx * bdx + bdy * bdy;\n const adxbdy = adx * bdy;\n const bdxady = bdx * ady;\n const clift = cdx * cdx + cdy * cdy;\n\n const det =\n alift * (bdxcdy - cdxbdy) +\n blift * (cdxady - adxcdy) +\n clift * (adxbdy - bdxady);\n const permanent =\n (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * alift +\n (Math.abs(cdxady) + Math.abs(adxcdy)) * blift +\n (Math.abs(adxbdy) + Math.abs(bdxady)) * clift;\n const bound = INCIRCLE_BOUND * permanent;\n if (det > bound) return 1;\n if (-det > bound) return -1;\n _input[0] = ax;\n _input[1] = ay;\n _input[2] = bx;\n _input[3] = by;\n _input[4] = cx;\n _input[5] = cy;\n _input[6] = dx;\n _input[7] = dy;\n const scale = _integerScale(8);\n if (scale !== 0) {\n return _incircleInt(\n adx * scale,\n ady * scale,\n bdx * scale,\n bdy * scale,\n cdx * scale,\n cdy * scale,\n );\n }\n return incircleExact(ax, ay, bx, by, cx, cy, dx, dy);\n}\n\n// ---- exact integer arithmetic on differences below 2^32, in base-2^18 limbs\n// held in doubles: a limb product is below 2^36 and no accumulated coefficient\n// reaches 2^41, so every operation is exact.\nconst LIMB = 262144;\nconst INV_LIMB = 1 / LIMB;\nconst _acc = new Float64Array(8);\nconst _liftA = new Float64Array(4);\nconst _liftB = new Float64Array(4);\nconst _liftC = new Float64Array(4);\nconst _crossA = new Float64Array(4);\nconst _crossB = new Float64Array(4);\nconst _crossC = new Float64Array(4);\n\n/** Add `sign * x * y` for non-negative integers x, y below 2^32 into `_acc[at..at+2]`. */\nfunction _mulAdd22(x: number, y: number, sign: number, at: number): void {\n const x0 = x & 0x3ffff;\n const x1 = x >>> 18;\n const y0 = y & 0x3ffff;\n const y1 = y >>> 18;\n _acc[at] += sign * x0 * y0;\n _acc[at + 1] += sign * (x0 * y1 + x1 * y0);\n _acc[at + 2] += sign * x1 * y1;\n}\n\n/** Add `sign * a * m` for four-limb non-negative numbers into `_acc[0..6]`. */\nfunction _mulAdd44(a: Float64Array, m: Float64Array, sign: number): void {\n for (let i = 0; i < 4; i++) {\n const ai = sign * a[i];\n if (ai === 0) continue;\n for (let j = 0; j < 4; j++) _acc[i + j] += ai * m[j];\n }\n}\n\n/** Carry-normalize `_acc[0..n)` to limbs in [0, LIMB); returns the signed final carry. */\nfunction _carry(n: number): number {\n let carry = 0;\n for (let k = 0; k < n; k++) {\n const v = _acc[k] + carry;\n carry = Math.floor(v * INV_LIMB); // exact: a power-of-two scale\n _acc[k] = v - carry * LIMB;\n }\n return carry;\n}\n\n/** Sign of the normalized accumulator: the carry decides, else any nonzero limb. */\nfunction _accSign(n: number, carry: number): number {\n if (carry !== 0) return carry > 0 ? 1 : -1;\n for (let k = 0; k < n; k++) if (_acc[k] !== 0) return 1;\n return 0;\n}\n\n/**\n * Write the magnitude of the normalized accumulator (n limbs plus carry) into\n * `out[0..n]` and return its sign. A negative value is complemented limb by limb.\n */\nfunction _magnitude(n: number, carry: number, out: Float64Array): number {\n if (carry >= 0) {\n let zero = carry === 0;\n for (let k = 0; k < n; k++) {\n out[k] = _acc[k];\n if (_acc[k] !== 0) zero = false;\n }\n out[n] = carry;\n return zero ? 0 : 1;\n }\n let up = 1;\n for (let k = 0; k < n; k++) {\n let m = LIMB - 1 - _acc[k] + up;\n up = 0;\n if (m === LIMB) {\n m = 0;\n up = 1;\n }\n out[k] = m;\n }\n out[n] = -carry - 1 + up;\n return -1;\n}\n\n/** Sign of `a * b - c * d` for integers below 2^32 in magnitude. */\nfunction _orientInt(a: number, b: number, c: number, d: number): number {\n _acc[0] = 0;\n _acc[1] = 0;\n _acc[2] = 0;\n _mulAdd22(Math.abs(a), Math.abs(b), a < 0 !== b < 0 ? -1 : 1, 0);\n _mulAdd22(Math.abs(c), Math.abs(d), c < 0 !== d < 0 ? 1 : -1, 0);\n return _accSign(3, _carry(3));\n}\n\n/** `dx² + dy²` as four limbs. */\nfunction _lift(dx: number, dy: number, out: Float64Array): void {\n _acc[0] = 0;\n _acc[1] = 0;\n _acc[2] = 0;\n _mulAdd22(Math.abs(dx), Math.abs(dx), 1, 0);\n _mulAdd22(Math.abs(dy), Math.abs(dy), 1, 0);\n const carry = _carry(3);\n out[0] = _acc[0];\n out[1] = _acc[1];\n out[2] = _acc[2];\n out[3] = carry;\n}\n\n/** Sign of `p * q - r * t`, with its magnitude written as four limbs. */\nfunction _cross(\n p: number,\n q: number,\n r: number,\n t: number,\n out: Float64Array,\n): number {\n _acc[0] = 0;\n _acc[1] = 0;\n _acc[2] = 0;\n _mulAdd22(Math.abs(p), Math.abs(q), p < 0 !== q < 0 ? -1 : 1, 0);\n _mulAdd22(Math.abs(r), Math.abs(t), r < 0 !== t < 0 ? 1 : -1, 0);\n return _magnitude(3, _carry(3), out);\n}\n\n/** Exact in-circle sign from integer differences below 2^32 in magnitude. */\nfunction _incircleInt(\n adx: number,\n ady: number,\n bdx: number,\n bdy: number,\n cdx: number,\n cdy: number,\n): number {\n _lift(adx, ady, _liftA);\n _lift(bdx, bdy, _liftB);\n _lift(cdx, cdy, _liftC);\n const sa = _cross(bdx, cdy, cdx, bdy, _crossA);\n const sb = _cross(cdx, ady, adx, cdy, _crossB);\n const sc = _cross(adx, bdy, bdx, ady, _crossC);\n for (let k = 0; k < 7; k++) _acc[k] = 0;\n if (sa !== 0) _mulAdd44(_liftA, _crossA, sa);\n if (sb !== 0) _mulAdd44(_liftB, _crossB, sb);\n if (sc !== 0) _mulAdd44(_liftC, _crossC, sc);\n return _accSign(7, _carry(7));\n}\n\n// Exact evaluation: each double is sign * mantissa * 2^exponent with an\n// integer mantissa, so scaling every input to the smallest exponent gives\n// exact integers whose determinant has the same sign as the real one.\nconst _bits = new Float64Array(1);\nconst _words = new Uint32Array(_bits.buffer);\n_bits[0] = 1;\nconst HI = _words[1] === 0x3ff00000 ? 1 : 0;\nconst LO = HI ^ 1;\nconst _mant = new Float64Array(8);\nconst _expo = new Int32Array(8);\n// BigInt is only touched inside the exact fallback, so loading this module\n// never requires it\n\nfunction _scaled(values: Float64Array, count: number): bigint[] {\n let minExpo = 0x7fffffff;\n for (let i = 0; i < count; i++) {\n _bits[0] = values[i];\n const hi = _words[HI];\n const biased = (hi >>> 20) & 0x7ff;\n let m = (hi & 0xfffff) * 4294967296 + _words[LO];\n let e = -1074; // subnormal: the fraction is the mantissa\n if (biased !== 0) {\n m += 4503599627370496; // implicit leading bit\n e = biased - 1075;\n }\n _mant[i] = hi >>> 31 ? -m : m;\n _expo[i] = e;\n if (m !== 0 && e < minExpo) minExpo = e;\n }\n const out: bigint[] = [];\n for (let i = 0; i < count; i++) {\n out.push(\n _mant[i] === 0\n ? BigInt(0)\n : BigInt(_mant[i]) << BigInt(_expo[i] - minExpo),\n );\n }\n return out;\n}\n\n// `Number(bigint)` is finite below 2^1024; shift in whole limbs until then.\nconst FINITE_LIMIT = BigInt(1) << BigInt(1023);\nconst SHIFT_STEP = BigInt(64);\n\n/**\n * Parameter of a known proper crossing along a→b. Evaluate the determinants\n * exactly before division: shallow crossings can lose most of their digits\n * when two rounded products are subtracted. Used by the polygon overlay.\n */\nexport function crossingParameter(\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n dx: number,\n dy: number,\n): number {\n _input.set([ax, ay, bx, by, cx, cy, dx, dy]);\n const [a, b, c, d, e, f, g, h] = _scaled(_input, 8);\n const rx = g - e;\n const ry = h - f;\n let numerator = rx * (b - f) - ry * (a - e);\n let denominator = numerator - (rx * (d - f) - ry * (c - e));\n if (denominator < BigInt(0)) {\n numerator = -numerator;\n denominator = -denominator;\n }\n // Keep the conversion finite even when the input doubles span hundreds of\n // binary exponents. The numerator is between zero and the denominator, and\n // a denominator of ordinary size needs no shift at all.\n let shift = BigInt(0);\n let scaled = denominator;\n while (scaled >= FINITE_LIMIT) {\n scaled >>= SHIFT_STEP;\n shift += SHIFT_STEP;\n }\n return Number(numerator >> shift) / Number(scaled);\n}\n\n/** Exact orientation, evaluated in BigInt. Used when the fast filter cannot decide. */\nexport function orient2dExact(\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n): number {\n _input[0] = ax;\n _input[1] = ay;\n _input[2] = bx;\n _input[3] = by;\n _input[4] = cx;\n _input[5] = cy;\n const s = _scaled(_input, 6);\n const det = (s[0] - s[4]) * (s[3] - s[5]) - (s[1] - s[5]) * (s[2] - s[4]);\n const zero = BigInt(0);\n return det > zero ? 1 : det < zero ? -1 : 0;\n}\n\n/** Exact in-circle test, evaluated in BigInt. Used when the fast filter cannot decide. */\nexport function incircleExact(\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n dx: number,\n dy: number,\n): number {\n _input[0] = ax;\n _input[1] = ay;\n _input[2] = bx;\n _input[3] = by;\n _input[4] = cx;\n _input[5] = cy;\n _input[6] = dx;\n _input[7] = dy;\n const s = _scaled(_input, 8);\n const adx = s[0] - s[6];\n const ady = s[1] - s[7];\n const bdx = s[2] - s[6];\n const bdy = s[3] - s[7];\n const cdx = s[4] - s[6];\n const cdy = s[5] - s[7];\n const det =\n (adx * adx + ady * ady) * (bdx * cdy - cdx * bdy) +\n (bdx * bdx + bdy * bdy) * (cdx * ady - adx * cdy) +\n (cdx * cdx + cdy * cdy) * (adx * bdy - bdx * ady);\n const zero = BigInt(0);\n return det > zero ? 1 : det < zero ? -1 : 0;\n}\n\n// ----------------------------------------------------------- insertion order\n\n/** Distance along a Hilbert curve of order `order` for grid cell (x, y). */\nexport function hilbertIndex(order: number, x: number, y: number): number {\n const n = 1 << order;\n let d = 0;\n for (let s = n >> 1; s > 0; s >>= 1) {\n const rx = (x & s) !== 0 ? 1 : 0;\n const ry = (y & s) !== 0 ? 1 : 0;\n d += s * s * ((3 * rx) ^ ry);\n if (ry === 0) {\n if (rx === 1) {\n x = n - 1 - x;\n y = n - 1 - y;\n }\n const t = x;\n x = y;\n y = t;\n }\n }\n return d;\n}\n\n/**\n * Point indices sorted along a Hilbert curve over the bounding box, ties (and\n * duplicate points) in index order. Non-finite points sort with the origin cell.\n */\nexport function hilbertOrder(\n coords: ArrayLike<number>,\n n: number,\n): Uint32Array {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (let i = 0; i < n; i++) {\n const x = coords[2 * i];\n const y = coords[2 * i + 1];\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue;\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n }\n // about sixteen cells per point is fine enough for locality; the order is\n // capped so keys stay within 32 bits\n let order = 2;\n while (order < 16 && 1 << (2 * order) < 16 * n) order++;\n const cells = (1 << order) - 1;\n const span = Math.max(maxX - minX, maxY - minY);\n const scale = span > 0 && Number.isFinite(span) ? cells / span : 0;\n\n const keys = new Uint32Array(n);\n for (let i = 0; i < n; i++) {\n const x = coords[2 * i];\n const y = coords[2 * i + 1];\n let gx = 0;\n let gy = 0;\n if (Number.isFinite(x) && Number.isFinite(y)) {\n gx = Math.min(cells, Math.max(0, Math.floor((x - minX) * scale)));\n gy = Math.min(cells, Math.max(0, Math.floor((y - minY) * scale)));\n }\n keys[i] = hilbertIndex(order, gx, gy);\n }\n\n // stable least-significant-digit radix sort, one byte per pass, over the\n // bytes the keys actually use\n let from = new Uint32Array(n);\n let to = new Uint32Array(n);\n for (let i = 0; i < n; i++) from[i] = i;\n const counts = new Int32Array(257);\n for (let shift = 0; shift < 2 * order; shift += 8) {\n counts.fill(0);\n for (let i = 0; i < n; i++) counts[((keys[i] >>> shift) & 255) + 1]++;\n for (let b = 0; b < 256; b++) counts[b + 1] += counts[b];\n for (let i = 0; i < n; i++) {\n const p = from[i];\n to[counts[(keys[p] >>> shift) & 255]++] = p;\n }\n const swap = from;\n from = to;\n to = swap;\n }\n return from;\n}\n\n// ------------------------------------------------------------- triangulation\n\n/**\n * Delaunay-triangulate points given as a flat `[x0, y0, x1, y1, ...]` array.\n * Duplicate points and points with non-finite coordinates are left out; the\n * lowest index of a duplicate is the one used. Returns no triangles when\n * fewer than three distinct, non-collinear points exist.\n * @param coords flat coordinates\n * @param n number of points; defaults to half the array length\n */\nexport function triangulate(\n coords: Float64Array,\n n: number = coords.length >> 1,\n): Triangulation {\n if (n < 3) return EMPTY;\n _presetScale = sharedScale(coords, n);\n try {\n return _triangulate(coords, n);\n } finally {\n _presetScale = 0;\n }\n}\n\n/**\n * The smallest power of two that makes every finite coordinate an integer\n * below 2^31 in magnitude, or 0 when there is none. Float32 values (every Pt)\n * always have one in a sane coordinate range.\n */\nexport function sharedScale(coords: ArrayLike<number>, n: number): number {\n let bits = 0;\n let max = 0;\n for (let i = 0; i < 2 * n; i++) {\n const v = coords[i];\n if (!Number.isFinite(v)) continue;\n if (v === 0) continue;\n if (Math.abs(v) > max) max = Math.abs(v);\n _bits[0] = v;\n const hi = _words[HI];\n const lo = _words[LO];\n const biased = (hi >>> 20) & 0x7ff;\n // v = m * 2^e with an integer m; trailing zero bits of m move into e\n const e = biased === 0 ? -1074 : biased - 1075;\n let trailing: number;\n if (lo !== 0) {\n trailing = 31 - Math.clz32(lo & -lo);\n } else {\n const m = (hi & 0xfffff) | (biased === 0 ? 0 : 0x100000);\n trailing = 32 + (31 - Math.clz32(m & -m));\n }\n const fractional = -(e + trailing);\n if (fractional > bits) bits = fractional;\n if (bits > 30) return 0;\n }\n const scale = Math.pow(2, bits);\n return max * scale < INT_LIMIT ? scale : 0;\n}\n\nfunction _triangulate(coords: Float64Array, n: number): Triangulation {\n const order = hilbertOrder(coords, n);\n\n // the first three non-collinear distinct points seed the triangulation\n let i0 = -1;\n let i1 = -1;\n let i2 = -1;\n let k = 0;\n for (; k < n; k++) {\n const i = order[k];\n if (Number.isFinite(coords[2 * i]) && Number.isFinite(coords[2 * i + 1])) {\n i0 = i;\n k++;\n break;\n }\n }\n if (i0 < 0) return EMPTY;\n for (; k < n; k++) {\n const i = order[k];\n const x = coords[2 * i];\n const y = coords[2 * i + 1];\n if (\n Number.isFinite(x) &&\n Number.isFinite(y) &&\n (x !== coords[2 * i0] || y !== coords[2 * i0 + 1])\n ) {\n i1 = i;\n k++;\n break;\n }\n }\n if (i1 < 0) return EMPTY;\n for (; k < n; k++) {\n const i = order[k];\n const x = coords[2 * i];\n const y = coords[2 * i + 1];\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue;\n const o = orient2d(\n coords[2 * i0],\n coords[2 * i0 + 1],\n coords[2 * i1],\n coords[2 * i1 + 1],\n x,\n y,\n );\n if (o !== 0) {\n i2 = i;\n if (o < 0) {\n const swap = i1;\n i1 = i2;\n i2 = swap;\n }\n break;\n }\n }\n if (i2 < 0) return EMPTY; // every point is on one line\n\n // Triangles are stored as vertex triples with their twin half-edges. Ghost\n // triangles carry the infinite vertex INF in slot 2; their slot-0 → slot-1\n // edge is a hull edge traversed with the outside on the left.\n const INF = n;\n const capacity = 2 * n + 4;\n const tv = new Int32Array(capacity * 3);\n const adj = new Int32Array(capacity * 3);\n const live = new Uint8Array(capacity);\n const mark = new Int32Array(capacity);\n const freed = new Int32Array(capacity);\n let freedCount = 0;\n let triCount = 0;\n const stack = new Int32Array(capacity);\n const cavity = new Int32Array(capacity);\n const edgeFrom = new Int32Array(capacity * 3);\n const edgeTo = new Int32Array(capacity * 3);\n const edgeTwin = new Int32Array(capacity * 3);\n const toPoint = new Int32Array(n + 1);\n const fromPoint = new Int32Array(n + 1);\n let stamp = 0;\n\n const alloc = (a: number, b: number, c: number): number => {\n const t = freedCount > 0 ? freed[--freedCount] : triCount++;\n const h = 3 * t;\n tv[h] = a;\n tv[h + 1] = b;\n tv[h + 2] = c;\n live[t] = 1;\n return t;\n };\n const link = (h: number, g: number): void => {\n adj[h] = g;\n adj[g] = h;\n };\n\n // first triangle and its three ghosts\n const t0 = alloc(i0, i1, i2);\n const g0 = alloc(i1, i0, INF);\n const g1 = alloc(i2, i1, INF);\n const g2 = alloc(i0, i2, INF);\n link(3 * t0, 3 * g0);\n link(3 * t0 + 1, 3 * g1);\n link(3 * t0 + 2, 3 * g2);\n link(3 * g0 + 1, 3 * g2 + 2);\n link(3 * g1 + 1, 3 * g0 + 2);\n link(3 * g2 + 1, 3 * g1 + 2);\n\n // Whether p lies in the \"circumdisk\" of ghost g: strictly outside its hull\n // edge u → v, or on the open segment between u and v.\n const inGhostDisk = (g: number, px: number, py: number): boolean => {\n const u = tv[3 * g];\n const v = tv[3 * g + 1];\n const ux = coords[2 * u];\n const uy = coords[2 * u + 1];\n const vx = coords[2 * v];\n const vy = coords[2 * v + 1];\n const o = orient2d(ux, uy, vx, vy, px, py);\n if (o !== 0) return o > 0;\n // collinear: strictly between the endpoints along the wider axis\n return Math.abs(vx - ux) >= Math.abs(vy - uy)\n ? vx > ux\n ? px > ux && px < vx\n : px < ux && px > vx\n : vy > uy\n ? py > uy && py < vy\n : py < uy && py > vy;\n };\n\n // Whether p is inside the circumdisk of triangle t (for a ghost: its\n // outer half-plane plus the open hull edge). Vertices are never inside.\n const inDisk = (t: number, px: number, py: number): boolean => {\n const h = 3 * t;\n if (tv[h + 2] === INF) return inGhostDisk(t, px, py);\n const a = tv[h];\n const b = tv[h + 1];\n const c = tv[h + 2];\n return (\n incircle(\n coords[2 * a],\n coords[2 * a + 1],\n coords[2 * b],\n coords[2 * b + 1],\n coords[2 * c],\n coords[2 * c + 1],\n px,\n py,\n ) > 0\n );\n };\n\n // Walk from triangle t to a triangle whose circumdisk contains p. Returns\n // -1 when p coincides with an existing vertex. The walk always starts from a\n // finite triangle and enters a ghost only across a hull edge that p lies\n // strictly outside of; a ghost reached any other way (p collinear with its\n // edge, or inside the hull) hands the walk back to the finite side, which\n // then locates p or crosses the right hull edge.\n const locate = (t: number, px: number, py: number): number => {\n let steps = 0;\n const limit = 4 * triCount + 64;\n while (true) {\n const h = 3 * t;\n const a = tv[h];\n const b = tv[h + 1];\n const c = tv[h + 2];\n const ax = coords[2 * a];\n const ay = coords[2 * a + 1];\n const bx = coords[2 * b];\n const by = coords[2 * b + 1];\n if (c === INF) {\n if (orient2d(ax, ay, bx, by, px, py) > 0) return t;\n t = (adj[h] / 3) | 0;\n } else {\n const cx = coords[2 * c];\n const cy = coords[2 * c + 1];\n if (orient2d(ax, ay, bx, by, px, py) < 0) {\n t = (adj[h] / 3) | 0;\n } else if (orient2d(bx, by, cx, cy, px, py) < 0) {\n t = (adj[h + 1] / 3) | 0;\n } else if (orient2d(cx, cy, ax, ay, px, py) < 0) {\n t = (adj[h + 2] / 3) | 0;\n } else if (\n (px === ax && py === ay) ||\n (px === bx && py === by) ||\n (px === cx && py === cy)\n ) {\n return -1;\n } else {\n return t;\n }\n }\n // the visibility walk terminates on a Delaunay triangulation; never spin\n if (++steps > limit) throw new Error(\"Delaunay walk did not terminate\");\n }\n };\n\n const insert = (p: number, start: number): number => {\n const px = coords[2 * p];\n const py = coords[2 * p + 1];\n const t = locate(start, px, py);\n if (t < 0) return start; // p is an existing vertex\n\n // the cavity: every triangle whose circumdisk contains p, by adjacency\n stamp++;\n let top = 0;\n let count = 0;\n stack[top++] = t;\n mark[t] = stamp;\n while (top > 0) {\n const s = stack[--top];\n cavity[count++] = s;\n const h = 3 * s;\n for (let e = 0; e < 3; e++) {\n const o = (adj[h + e] / 3) | 0;\n if (mark[o] !== stamp && inDisk(o, px, py)) {\n mark[o] = stamp;\n stack[top++] = o;\n }\n }\n }\n\n // its boundary: cavity half-edges whose twin lies outside the cavity,\n // recorded by vertex before the cavity's slots are recycled\n let edges = 0;\n for (let i = 0; i < count; i++) {\n const h = 3 * cavity[i];\n for (let e = 0; e < 3; e++) {\n const twin = adj[h + e];\n if (mark[(twin / 3) | 0] !== stamp) {\n edgeFrom[edges] = tv[h + e];\n edgeTo[edges] = tv[h + ((e + 1) % 3)];\n edgeTwin[edges] = twin;\n edges++;\n }\n }\n }\n for (let i = 0; i < count; i++) {\n live[cavity[i]] = 0;\n freed[freedCount++] = cavity[i];\n }\n\n // fan the cavity: one triangle (u, v, p) per boundary edge u → v, with\n // the infinite vertex kept in slot 2\n let first = -1;\n for (let i = 0; i < edges; i++) {\n const u = edgeFrom[i];\n const v = edgeTo[i];\n let t2: number;\n let hEdge: number;\n let hToP: number;\n let hFromP: number;\n if (u === INF) {\n t2 = alloc(v, p, INF);\n hEdge = 3 * t2 + 2;\n hToP = 3 * t2;\n hFromP = 3 * t2 + 1;\n } else if (v === INF) {\n t2 = alloc(p, u, INF);\n hEdge = 3 * t2 + 1;\n hToP = 3 * t2 + 2;\n hFromP = 3 * t2;\n } else {\n t2 = alloc(u, v, p);\n hEdge = 3 * t2;\n hToP = 3 * t2 + 1;\n hFromP = 3 * t2 + 2;\n if (first < 0) first = t2;\n }\n link(hEdge, edgeTwin[i]);\n toPoint[v] = hToP;\n fromPoint[u] = hFromP;\n }\n for (let i = 0; i < edges; i++) {\n const v = edgeTo[i];\n link(toPoint[v], fromPoint[v]);\n }\n return first < 0 ? start : first;\n };\n\n let last = t0;\n for (let j = 0; j < n; j++) {\n const i = order[j];\n if (i === i0 || i === i1 || i === i2) continue;\n if (!Number.isFinite(coords[2 * i]) || !Number.isFinite(coords[2 * i + 1]))\n continue;\n last = insert(i, last);\n }\n\n // compact the finite triangles and renumber their adjacency\n const index = new Int32Array(triCount);\n let m = 0;\n let ghost = -1;\n for (let t = 0; t < triCount; t++) {\n if (!live[t]) {\n index[t] = -1;\n } else if (tv[3 * t + 2] === INF) {\n index[t] = -1;\n ghost = t;\n } else {\n index[t] = m++;\n }\n }\n const triangles = new Uint32Array(m * 3);\n const neighbors = new Int32Array(m * 3);\n for (let t = 0; t < triCount; t++) {\n const k2 = index[t];\n if (k2 < 0) continue;\n for (let e = 0; e < 3; e++) {\n triangles[3 * k2 + e] = tv[3 * t + e];\n const o = adj[3 * t + e];\n const ot = index[(o / 3) | 0];\n neighbors[3 * k2 + e] = ot < 0 ? -1 : 3 * ot + (o % 3);\n }\n }\n // the hull, counterclockwise, by walking the ring of ghosts\n let hullCount = 0;\n let g = ghost;\n do {\n hullCount++;\n g = (adj[3 * g + 2] / 3) | 0;\n } while (g !== ghost);\n const hull = new Uint32Array(hullCount);\n g = ghost;\n for (let i = 0; i < hullCount; i++) {\n hull[i] = tv[3 * g + 1];\n g = (adj[3 * g + 2] / 3) | 0;\n }\n return { triangles, neighbors, hull };\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Group } from \"./Pt\";\nimport { Util } from \"./Util\";\nimport { crossingParameter, orient2d } from \"./_triangulate\";\nimport { type PolygonLike, type PtLike, type PtLikeIterable } from \"./Types\";\n\n/**\n * Internal planar overlay used by [`Path`](#link).\n *\n * Every mode is the same computation: build the arrangement of all input\n * edges, label each face with the winding number of every shape, keep the\n * faces the mode asks for, and either merge them (unite, intersect, exclude,\n * minus front, minus back) or emit each one (divide, crop).\n *\n * Input vertices within `tol` are merged before constructing edges, and a\n * vertex within `tol` of an edge's interior then splits that edge. This is an\n * intentional geometric tolerance, not the precision of a Float32 point: it\n * makes T-junctions, shared edges, and edges that coincide up to rounding\n * share their vertices. Both happen before any crossing is computed, so no\n * crossing is decided on geometry that a later split would bend. The proper\n * crossings of the resulting sub-edges are then found with exact orientation\n * predicates and an exactly evaluated crossing parameter, and merged at\n * double rounding precision, independently of the input tolerance.\n * Coincident sub-edges carry sparse per-shape winding deltas. Faces are\n * half-edge cycles, labeled by flooding from one seed per component. Holes\n * find their outer ring with a ray to the west. Output coordinates are\n * Float32 Pts, so features below that precision may still collapse, and\n * rings thinner than `tol` (hairlines left by edges that coincide up to\n * rounding) are dropped.\n */\n\n/** The seven Path modes. */\nexport type PathMode =\n | \"unite\"\n | \"intersect\"\n | \"exclude\"\n | \"minusFront\"\n | \"minusBack\"\n | \"divide\"\n | \"crop\";\n\n// The snapping grid has cells of 64 tol, so a point only needs a neighboring\n// cell checked when it lies within tol of that cell's border, and the cell\n// indices stay within ±2^14 (tol is a fixed fraction of the largest\n// coordinate), which keeps every key a small integer.\nconst CELL_TOLS = 64;\nconst CELL_OFFSET = 16384;\nconst CELL_SPAN = 32768;\n// A westward ray query either scans every edge or walks the bounding-box\n// tree; scanning costs about E per query and the tree about E log E to build,\n// so the tree pays off after this many queries times log2(E). The number of\n// queries is known before they start: components for the seeds, holes for\n// the owners.\nconst RAY_TREE_PER_LOG = 1.5;\n// Candidate pairs from the first sweep are kept, up to this many, so that the\n// second sweep can replay them when the first registered no split (the common\n// case). Beyond the cap they are streamed and enumerated again.\nconst PAIR_BUFFER = 1 << 18;\n\n/** The rings of a shape as arrays of points: one ring (its first item is a point) or a list of rings. */\nfunction ringsOf(shape: PolygonLike): PtLike[][] {\n const list = Util.iterToArray(shape as Iterable<unknown>);\n if (list.length === 0) return [];\n const first = list[0];\n if (first != null && typeof first[0] === \"number\") return [list];\n const rings: PtLike[][] = new Array(list.length);\n for (let i = 0; i < list.length; i++) rings[i] = Util.iterToArray(list[i]);\n return rings;\n}\n\n/**\n * A trig-free stand-in for `atan2`: increases counterclockwise over [0, 4),\n * starting at west like atan2's range does, so the sort order and the\n * \"largest angle\" at a leftmost vertex are the same as with atan2.\n */\nfunction pseudoAngle(dx: number, dy: number): number {\n const s = (dx < 0 ? -dx : dx) + (dy < 0 ? -dy : dy);\n // counterclockwise from east: [0, 4)\n const d =\n dy >= 0\n ? dx >= 0\n ? dy / s\n : 1 - dx / s\n : dx < 0\n ? 2 - dy / s\n : 3 + dx / s;\n return d >= 2 ? d - 2 : d + 2;\n}\n\n/** Add a winding delta, keeping zero entries out of the sparse vector. */\nfunction addWinding(\n vector: Map<number, number>,\n shape: number,\n delta: number,\n): void {\n const value = (vector.get(shape) ?? 0) + delta;\n if (value === 0) vector.delete(shape);\n else vector.set(shape, value);\n}\n\n/** How many distinct points a ring has, up to three: enough to tell a real ring from a degenerate one. */\nfunction distinctPoints(ring: PtLike[]): number {\n const seen: PtLike[] = [];\n for (let i = 0; i < ring.length && seen.length < 3; i++) {\n const p = ring[i];\n let dup = false;\n for (let j = 0; j < seen.length; j++) {\n if (seen[j][0] === p[0] && seen[j][1] === p[1]) {\n dup = true;\n break;\n }\n }\n if (!dup) seen.push(p);\n }\n return seen.length;\n}\n\n/**\n * Reorder `items[lo, hi)` so the item at `k` has the key it would have when\n * sorted, smaller keys before it and larger after (Hoare quickselect).\n */\nfunction selectByKey(\n items: Uint32Array,\n key: Float64Array,\n lo: number,\n hi: number,\n k: number,\n): void {\n let l = lo;\n let r = hi - 1;\n while (l < r) {\n const pivot = key[items[(l + r) >> 1]];\n let i = l;\n let j = r;\n while (i <= j) {\n while (key[items[i]] < pivot) i++;\n while (key[items[j]] > pivot) j--;\n if (i <= j) {\n const t = items[i];\n items[i] = items[j];\n items[j] = t;\n i++;\n j--;\n }\n }\n if (k <= j) r = j;\n else if (k >= i) l = i;\n else return;\n }\n}\n\n/** Output perimeter, for the hairline test. */\nfunction outputPerimeter(ring: Group): number {\n let length = 0;\n for (let i = 0, n = ring.length; i < n; i++) {\n const a = ring[i];\n const b = ring[i === n - 1 ? 0 : i + 1];\n length += Math.hypot(b[0] - a[0], b[1] - a[1]);\n }\n return length;\n}\n\n/** Output area relative to the first point, avoiding large-offset cancellation. */\nfunction outputArea(ring: Group): number {\n let area = 0;\n const a = ring[0];\n for (let i = 1; i + 1 < ring.length; i++) {\n const b = ring[i],\n c = ring[i + 1];\n area += (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]);\n }\n return area / 2;\n}\n\n/** Edge bounding boxes and the edges ordered by their left side, for a sweep. */\ntype SweepBoxes = {\n minX: Float64Array;\n maxX: Float64Array;\n minY: Float64Array;\n maxY: Float64Array;\n order: Uint32Array;\n};\n\n/** Bounds of nonhorizontal edges used by westward rays. */\ntype RayNode = {\n x0: number;\n x1: number;\n y0: number;\n y1: number;\n // A ray in this interval crosses every edge in the node. If the node is\n // wholly west of the query, its aggregate winding can be added at once.\n allY0: number;\n allY1: number;\n sum: Map<number, number>;\n edges?: number[];\n left?: RayNode;\n right?: RayNode;\n};\n\n/** Internal arrangement, also exposed to the geometry invariant tests. */\nexport class Overlay {\n tol = 0;\n private rounding = 0;\n k = 0; // number of shapes\n\n // vertices in doubles, with a grid hash for snapping\n vx: number[] = [];\n vy: number[] = [];\n private cells = new Map<number, number[]>();\n\n // input edges, directed, one shape each\n ea: number[] = [];\n eb: number[] = [];\n es: number[] = [];\n\n // split events: (edge, parameter, vertex)\n private spE: number[] = [];\n private spT: number[] = [];\n private spV: number[] = [];\n\n // graph edges, low vertex to high vertex, with nonzero per-shape deltas\n gu: number[] = [];\n gv: number[] = [];\n deltas: Map<number, number>[] = [];\n\n // half-edges: 2e runs low to high, 2e + 1 the other way\n offset!: Int32Array; // outgoing half-edges of vertex v are out[offset[v] .. offset[v + 1])\n out!: Int32Array;\n slot!: Int32Array; // index of each half-edge in its origin's sorted list\n next!: Int32Array; // the next half-edge of the face on the left\n cycle!: Int32Array; // cycle id per half-edge\n cycleArea: number[] = [];\n cycleStart: number[] = [];\n // per cycle: how many shapes wind around its face, and whether the first\n // and last shapes do. That is all the modes need, so the full sparse\n // winding vectors are kept only when `label(true)` asks for them (tests).\n count!: Int32Array;\n hasFirst!: Uint8Array;\n hasLast!: Uint8Array;\n labels?: Map<number, number>[];\n // undefined: not built yet; null: built, but no edge can cross a ray\n private rayIndex: RayNode | null | undefined;\n\n origin(h: number): number {\n return h & 1 ? this.gv[h >> 1] : this.gu[h >> 1];\n }\n\n target(h: number): number {\n return h & 1 ? this.gu[h >> 1] : this.gv[h >> 1];\n }\n\n // ------------------------------------------------------------- input\n\n /** Read the shapes into snapped vertices and directed edges. False when there is nothing to combine. */\n read(shapes: Iterable<PolygonLike> | PtLikeIterable): boolean {\n let list: unknown[] = Util.iterToArray(shapes as Iterable<unknown>);\n // A single ring of points is the likeliest misuse (every Polygon function\n // takes one Group); treat it as a list of one shape.\n if (\n list.length > 0 &&\n list[0] != null &&\n typeof (list[0] as ArrayLike<unknown>)[0] === \"number\"\n ) {\n list = [list];\n }\n this.k = list.length;\n const rings: PtLike[][] = [];\n const ringShape: number[] = [];\n let maxAbs = 0;\n\n // first pass: the scale that sets the tolerance, and which rings are usable\n for (let s = 0; s < list.length; s++) {\n const shapeRings = ringsOf(list[s] as PolygonLike);\n for (let r = 0; r < shapeRings.length; r++) {\n const ring = shapeRings[r];\n if (ring.length < 3) continue;\n let finite = true;\n let max = maxAbs;\n for (let i = 0, n = ring.length; i < n; i++) {\n const x = +ring[i][0];\n const y = +ring[i][1];\n if (!(Number.isFinite(x) && Number.isFinite(y))) {\n finite = false;\n break;\n }\n const ax = x < 0 ? -x : x;\n const ay = y < 0 ? -y : y;\n if (ax > max) max = ax;\n if (ay > max) max = ay;\n }\n if (!finite) {\n Util.warn(\"Path skipped a ring with a non-finite coordinate\");\n continue;\n }\n maxAbs = max;\n rings.push(ring);\n ringShape.push(s);\n }\n }\n if (rings.length === 0 || maxAbs === 0) return false;\n this.tol = maxAbs * 1e-6;\n this.rounding = maxAbs * Number.EPSILON * 8;\n\n // second pass: snap each ring's points to vertices, dropping consecutive\n // repeats and the closing repeat, then emit its edges\n const ids: number[] = [];\n for (let r = 0; r < rings.length; r++) {\n const ring = rings[r];\n ids.length = 0;\n let prev = -1;\n for (let i = 0, n = ring.length; i < n; i++) {\n const v = this.vertexAt(+ring[i][0], +ring[i][1]);\n if (v !== prev) {\n ids.push(v);\n prev = v;\n }\n }\n while (ids.length > 1 && ids[ids.length - 1] === ids[0]) ids.pop();\n if (ids.length >= 3) {\n for (let i = 0, n = ids.length; i < n; i++) {\n this.ea.push(ids[i]);\n this.eb.push(ids[i === n - 1 ? 0 : i + 1]);\n this.es.push(ringShape[r]);\n }\n } else if (distinctPoints(ring) >= 3) {\n Util.warn(\n \"Path dropped a ring whose points merge within the tolerance; use local coordinates for small shapes at large offsets\",\n );\n }\n }\n return this.ea.length > 0;\n }\n\n /** The vertex within `tol` of (x, y), or a new one. */\n vertexAt(x: number, y: number, tol = this.tol): number {\n const cellSize = this.tol * CELL_TOLS;\n const fx = x / cellSize;\n const fy = y / cellSize;\n const cx = Math.floor(fx);\n const cy = Math.floor(fy);\n // neighbors to check: only across a border closer than tol\n const border = tol / cellSize;\n const x0 = fx - cx <= border ? -1 : 0;\n const x1 = fx - cx >= 1 - border ? 1 : 0;\n const y0 = fy - cy <= border ? -1 : 0;\n const y1 = fy - cy >= 1 - border ? 1 : 0;\n const t2 = tol * tol;\n for (let i = x0; i <= x1; i++) {\n for (let j = y0; j <= y1; j++) {\n const cell = this.cells.get(\n (cx + i + CELL_OFFSET) * CELL_SPAN + (cy + j + CELL_OFFSET),\n );\n if (!cell) continue;\n for (let n = 0; n < cell.length; n++) {\n const v = cell[n];\n const dx = this.vx[v] - x;\n const dy = this.vy[v] - y;\n if (dx * dx + dy * dy <= t2) return v;\n }\n }\n }\n const id = this.vx.length;\n this.vx.push(x);\n this.vy.push(y);\n const key = (cx + CELL_OFFSET) * CELL_SPAN + (cy + CELL_OFFSET);\n const cell = this.cells.get(key);\n if (cell) cell.push(id);\n else this.cells.set(key, [id]);\n return id;\n }\n\n // ------------------------------------------------------------ splits\n\n /**\n * Split edges where they meet, in two phases. First, a vertex within tol of\n * an edge's interior splits that edge there, so T-junctions, shared and\n * overlapping edges, and vertices that miss an edge by rounding all become\n * shared vertices. That bends edges by up to tol, which is why it happens\n * before any crossing is computed. The second phase finds the proper\n * crossings of the resulting sub-edges with exact predicates, so no\n * crossing is decided on geometry that a later split would change.\n */\n split(): void {\n let boxes = this.boxes();\n const pairs = this.sweep(boxes, this.tol, true);\n if (this.spE.length > 0) {\n // the sub-edges are new edges; enumerate their pairs again, exactly\n this.applySplits();\n boxes = this.boxes();\n this.sweep(boxes, 0, false);\n } else if (pairs) {\n for (let i = 0; i < pairs.length; i += 2) {\n this.crossPair(pairs[i], pairs[i + 1]);\n }\n } else {\n this.sweep(boxes, 0, false);\n }\n }\n\n /** Bounding boxes of the current edges, with the edges ordered by their left side. */\n private boxes(): SweepBoxes {\n const E = this.ea.length;\n const vx = this.vx;\n const vy = this.vy;\n const minX = new Float64Array(E);\n const maxX = new Float64Array(E);\n const minY = new Float64Array(E);\n const maxY = new Float64Array(E);\n for (let e = 0; e < E; e++) {\n const ax = vx[this.ea[e]];\n const ay = vy[this.ea[e]];\n const bx = vx[this.eb[e]];\n const by = vy[this.eb[e]];\n minX[e] = ax < bx ? ax : bx;\n maxX[e] = ax < bx ? bx : ax;\n minY[e] = ay < by ? ay : by;\n maxY[e] = ay < by ? by : ay;\n }\n const order = new Uint32Array(E);\n for (let e = 0; e < E; e++) order[e] = e;\n order.sort((p, q) => minX[p] - minX[q]);\n return { minX, maxX, minY, maxY, order };\n }\n\n /**\n * Run a phase over every two edges whose boxes, grown by `margin`, overlap:\n * the touch phase (which also returns the pairs, unless there are more than\n * the buffer holds) or the crossing phase. Pairs are visited as they are\n * found rather than listed first: shapes that all share a vertex have\n * quadratically many candidate pairs, more than an array can hold.\n */\n private sweep(\n boxes: SweepBoxes,\n margin: number,\n touching: boolean,\n ): number[] | undefined {\n const { minX, maxX, minY, maxY, order } = boxes;\n let pairs: number[] | undefined = touching ? [] : undefined;\n for (let i = 0, E = order.length; i < E; i++) {\n const e1 = order[i];\n const limit = maxX[e1] + margin;\n const lo = minY[e1] - margin;\n const hi = maxY[e1] + margin;\n for (let j = i + 1; j < E; j++) {\n const e2 = order[j];\n if (minX[e2] > limit) break;\n if (minY[e2] > hi || maxY[e2] < lo) continue;\n if (touching) {\n this.touchPair(e1, e2, boxes);\n if (pairs) {\n if (pairs.length < 2 * PAIR_BUFFER) pairs.push(e1, e2);\n else pairs = undefined;\n }\n } else {\n this.crossPair(e1, e2);\n }\n }\n }\n return pairs;\n }\n\n /** Phase one: each endpoint of one edge within tol of the other edge's interior splits it. */\n private touchPair(e1: number, e2: number, boxes: SweepBoxes): void {\n const a = this.ea[e1];\n const b = this.eb[e1];\n const c = this.ea[e2];\n const d = this.eb[e2];\n // an endpoint can only touch an edge whose box it is in (grown by tol)\n if (this.inBox(a, e2, boxes)) this.touch(e2, a, c, d);\n if (this.inBox(b, e2, boxes)) this.touch(e2, b, c, d);\n if (this.inBox(c, e1, boxes)) this.touch(e1, c, a, b);\n if (this.inBox(d, e1, boxes)) this.touch(e1, d, a, b);\n }\n\n private inBox(v: number, e: number, boxes: SweepBoxes): boolean {\n const x = this.vx[v];\n const y = this.vy[v];\n const tol = this.tol;\n return (\n x >= boxes.minX[e] - tol &&\n x <= boxes.maxX[e] + tol &&\n y >= boxes.minY[e] - tol &&\n y <= boxes.maxY[e] + tol\n );\n }\n\n /** Register vertex `v` on edge `e` (from `p` to `q`) when it lies within tol of the edge's interior. */\n private touch(e: number, v: number, p: number, q: number): void {\n if (v === p || v === q) return;\n const vx = this.vx;\n const vy = this.vy;\n const px = vx[p];\n const py = vy[p];\n const rx = vx[q] - px;\n const ry = vy[q] - py;\n const len2 = rx * rx + ry * ry;\n const dx = vx[v] - px;\n const dy = vy[v] - py;\n const t = (dx * rx + dy * ry) / len2;\n if (t <= 0 || t >= 1) return;\n const cross = rx * dy - ry * dx;\n if (cross * cross > this.tol * this.tol * len2) return;\n this.registerSplit(e, v);\n }\n\n /** Phase two: split two sub-edges that share no vertex at their proper crossing. */\n private crossPair(e1: number, e2: number): void {\n const a = this.ea[e1];\n const b = this.eb[e1];\n const c = this.ea[e2];\n const d = this.eb[e2];\n if (a === c || a === d || b === c || b === d) return;\n\n // Exact signs keep shallow crossings distinct from collinear overlaps.\n const vx = this.vx;\n const vy = this.vy;\n const ax = vx[a];\n const ay = vy[a];\n const bx = vx[b];\n const by = vy[b];\n const cx = vx[c];\n const cy = vy[c];\n const dx = vx[d];\n const dy = vy[d];\n if (\n orient2d(ax, ay, bx, by, cx, cy) * orient2d(ax, ay, bx, by, dx, dy) >=\n 0\n )\n return;\n if (\n orient2d(cx, cy, dx, dy, ax, ay) * orient2d(cx, cy, dx, dy, bx, by) >=\n 0\n )\n return;\n const t = crossingParameter(ax, ay, bx, by, cx, cy, dx, dy);\n const v = this.vertexAt(\n ax + t * (bx - ax),\n ay + t * (by - ay),\n this.rounding,\n );\n this.registerSplit(e1, v);\n this.registerSplit(e2, v);\n }\n\n /** Replace every edge by its pieces between the registered split vertices, in order. */\n private applySplits(): void {\n const E = this.ea.length;\n const S = this.spE.length;\n const spE = this.spE;\n const spT = this.spT;\n const spV = this.spV;\n const order = new Uint32Array(S);\n for (let i = 0; i < S; i++) order[i] = i;\n order.sort((p, q) => spE[p] - spE[q] || spT[p] - spT[q]);\n const ea: number[] = [];\n const eb: number[] = [];\n const es: number[] = [];\n let si = 0;\n for (let e = 0; e < E; e++) {\n let u = this.ea[e];\n const end = this.eb[e];\n const s = this.es[e];\n while (si < S && spE[order[si]] === e) {\n const v = spV[order[si++]];\n if (v === u) continue;\n ea.push(u);\n eb.push(v);\n es.push(s);\n u = v;\n }\n if (u !== end) {\n ea.push(u);\n eb.push(end);\n es.push(s);\n }\n }\n this.ea = ea;\n this.eb = eb;\n this.es = es;\n spE.length = 0;\n spT.length = 0;\n spV.length = 0;\n }\n\n /** Record that edge `e` passes through vertex `v`. The parameter is always the projection, so repeats sort together. */\n private registerSplit(e: number, v: number): void {\n const a = this.ea[e];\n const b = this.eb[e];\n if (v === a || v === b) return;\n const ax = this.vx[a];\n const ay = this.vy[a];\n const rx = this.vx[b] - ax;\n const ry = this.vy[b] - ay;\n const t =\n ((this.vx[v] - ax) * rx + (this.vy[v] - ay) * ry) / (rx * rx + ry * ry);\n if (t <= 0 || t >= 1) return;\n this.spE.push(e);\n this.spT.push(t);\n this.spV.push(v);\n }\n\n // ------------------------------------------------------------- graph\n\n /** Turn the split edges into unique graph edges with per-shape deltas; drop edges that separate nothing. */\n merge(): void {\n if (this.spE.length > 0) this.applySplits();\n const V = this.vx.length;\n const index = new Map<number, number>();\n const gu = this.gu;\n const gv = this.gv;\n const deltas = this.deltas;\n for (let e = 0, E = this.ea.length; e < E; e++) {\n const u = this.ea[e];\n const v = this.eb[e];\n const lo = u < v ? u : v;\n const hi = u < v ? v : u;\n const key = lo * V + hi;\n let g = index.get(key);\n if (g === undefined) {\n g = gu.length;\n gu.push(lo);\n gv.push(hi);\n deltas.push(new Map());\n index.set(key, g);\n }\n addWinding(deltas[g], this.es[e], u === lo ? 1 : -1);\n }\n\n // compact away edges whose deltas are all zero\n let n = 0;\n for (let e = 0, len = gu.length; e < len; e++) {\n if (deltas[e].size === 0) continue;\n if (n !== e) {\n gu[n] = gu[e];\n gv[n] = gv[e];\n deltas[n] = deltas[e];\n }\n n++;\n }\n gu.length = n;\n gv.length = n;\n deltas.length = n;\n }\n\n /** The ray tree once enough queries justify building it; until then callers scan every edge. */\n private rayTree(): RayNode | null | undefined {\n return this.rayIndex;\n }\n\n /** Build the ray tree if the coming `queries` are more than scanning is worth. */\n private expectRayQueries(queries: number): void {\n const E = this.gu.length;\n if (\n this.rayIndex === undefined &&\n queries > RAY_TREE_PER_LOG * Math.log2(E + 1) + 1\n ) {\n this.rayIndex = this.indexRays() ?? null;\n }\n }\n\n /** Balanced bounding-box tree for seed winding and nearest boundary queries. */\n private indexRays(): RayNode | undefined {\n const E = this.gu.length;\n const vx = this.vx;\n const vy = this.vy;\n let n = 0;\n const edges = new Uint32Array(E);\n for (let e = 0; e < E; e++) {\n if (vy[this.gu[e]] !== vy[this.gv[e]]) edges[n++] = e;\n }\n if (n === 0) return undefined;\n // edge centers, so each level partitions by a plain number\n const cx = new Float64Array(E);\n const cy = new Float64Array(E);\n for (let e = 0; e < E; e++) {\n cx[e] = vx[this.gu[e]] + vx[this.gv[e]];\n cy[e] = vy[this.gu[e]] + vy[this.gv[e]];\n }\n const build = (lo: number, hi: number): RayNode => {\n const node: RayNode = {\n x0: Infinity,\n x1: -Infinity,\n y0: Infinity,\n y1: -Infinity,\n allY0: -Infinity,\n allY1: Infinity,\n sum: new Map(),\n };\n for (let i = lo; i < hi; i++) {\n const e = edges[i];\n const u = this.gu[e];\n const v = this.gv[e];\n const y0 = Math.min(vy[u], vy[v]);\n const y1 = Math.max(vy[u], vy[v]);\n node.x0 = Math.min(node.x0, vx[u], vx[v]);\n node.x1 = Math.max(node.x1, vx[u], vx[v]);\n node.y0 = Math.min(node.y0, y0);\n node.y1 = Math.max(node.y1, y1);\n node.allY0 = Math.max(node.allY0, y0);\n node.allY1 = Math.min(node.allY1, y1);\n }\n if (hi - lo <= 8) {\n node.edges = Array.from(edges.subarray(lo, hi));\n if (node.allY0 < node.allY1) {\n for (const e of node.edges) {\n const sign = vy[this.gv[e]] > vy[this.gu[e]] ? -1 : 1;\n for (const [s, d] of this.deltas[e])\n addWinding(node.sum, s, sign * d);\n }\n }\n } else {\n const key = node.x1 - node.x0 >= node.y1 - node.y0 ? cx : cy;\n const mid = (lo + hi) >> 1;\n selectByKey(edges, key, lo, hi, mid);\n node.left = build(lo, mid);\n node.right = build(mid, hi);\n if (node.allY0 < node.allY1) {\n for (const child of [node.left, node.right])\n for (const [s, d] of child.sum) addWinding(node.sum, s, d);\n }\n }\n return node;\n };\n return build(0, n);\n }\n\n // ------------------------------------------------------------- faces\n\n /** Order the half-edges around each vertex and trace the cycles that bound the faces. */\n trace(): void {\n const E = this.gu.length;\n const H = 2 * E;\n const V = this.vx.length;\n const vx = this.vx;\n const vy = this.vy;\n const gu = this.gu;\n const gv = this.gv;\n\n const angle = new Float64Array(H);\n for (let e = 0; e < E; e++) {\n const dx = vx[gv[e]] - vx[gu[e]];\n const dy = vy[gv[e]] - vy[gu[e]];\n angle[2 * e] = pseudoAngle(dx, dy);\n angle[2 * e + 1] = pseudoAngle(-dx, -dy);\n }\n\n const offset = new Int32Array(V + 1);\n for (let e = 0; e < E; e++) {\n offset[gu[e] + 1]++;\n offset[gv[e] + 1]++;\n }\n for (let v = 0; v < V; v++) offset[v + 1] += offset[v];\n const out = new Int32Array(H);\n const cursor = offset.slice(0, V);\n for (let e = 0; e < E; e++) {\n out[cursor[gu[e]]++] = 2 * e;\n out[cursor[gv[e]]++] = 2 * e + 1;\n }\n\n // counterclockwise order around each vertex; the lists are tiny, so an\n // insertion sort in place beats extracting them\n const slot = new Int32Array(H);\n for (let v = 0; v < V; v++) {\n const lo = offset[v];\n const hi = offset[v + 1];\n for (let i = lo + 1; i < hi; i++) {\n const h = out[i];\n const a = angle[h];\n let j = i - 1;\n while (\n j >= lo &&\n (angle[out[j]] > a ||\n (angle[out[j]] === a && this.target(out[j]) > this.target(h)))\n ) {\n out[j + 1] = out[j];\n j--;\n }\n out[j + 1] = h;\n }\n for (let i = lo; i < hi; i++) slot[out[i]] = i - lo;\n }\n\n // the face on the left of h continues along the first outgoing half-edge\n // clockwise from h's twin\n const next = new Int32Array(H);\n for (let h = 0; h < H; h++) {\n const v = this.target(h);\n const base = offset[v];\n const n = offset[v + 1] - base;\n const s = slot[h ^ 1];\n next[h] = out[base + (s === 0 ? n - 1 : s - 1)];\n }\n\n const cycle = new Int32Array(H).fill(-1);\n const cycleArea = this.cycleArea;\n const cycleStart = this.cycleStart;\n for (let h = 0; h < H; h++) {\n if (cycle[h] >= 0) continue;\n const c = cycleArea.length;\n let area = 0;\n let cur = h;\n do {\n cycle[cur] = c;\n const o = this.origin(cur);\n const t = this.target(cur);\n area += vx[o] * vy[t] - vx[t] * vy[o];\n cur = next[cur];\n } while (cur !== h);\n cycleArea.push(area / 2);\n cycleStart.push(h);\n }\n\n this.offset = offset;\n this.out = out;\n this.slot = slot;\n this.next = next;\n this.cycle = cycle;\n }\n\n /**\n * Label every cycle with what the modes need to know about the winding\n * numbers on its face. With `full`, the sparse winding vectors are kept too.\n */\n label(full = false): void {\n const V = this.vx.length;\n const E = this.gu.length;\n const C = this.cycleArea.length;\n const vx = this.vx;\n const vy = this.vy;\n const offset = this.offset;\n\n // connected components by union-find over the graph edges\n const parent = new Int32Array(V);\n for (let v = 0; v < V; v++) parent[v] = v;\n const find = (v: number) => {\n while (parent[v] !== v) {\n parent[v] = parent[parent[v]];\n v = parent[v];\n }\n return v;\n };\n for (let e = 0; e < E; e++) {\n const a = find(this.gu[e]);\n const b = find(this.gv[e]);\n if (a !== b) parent[a] = b;\n }\n const leftmost = new Int32Array(V).fill(-1);\n let components = 0;\n for (let v = 0; v < V; v++) {\n if (offset[v + 1] === offset[v]) continue; // no edges left\n const r = find(v);\n const l = leftmost[r];\n if (l < 0) components++;\n if (l < 0 || vx[v] < vx[l] || (vx[v] === vx[l] && vy[v] < vy[l])) {\n leftmost[r] = v;\n }\n }\n\n const count = new Int32Array(C);\n const hasFirst = new Uint8Array(C);\n const hasLast = new Uint8Array(C);\n const labels = full ? new Array<Map<number, number>>(C) : undefined;\n const labeled = new Uint8Array(C);\n const last = this.k - 1;\n // One winding vector, edited on the way into a neighboring face and\n // restored on the way back, so the memory is one vector plus three\n // numbers per face rather than a vector per face.\n const w = new Map<number, number>();\n const record = (c: number) => {\n count[c] = w.size;\n hasFirst[c] = w.has(0) ? 1 : 0;\n hasLast[c] = w.has(last) ? 1 : 0;\n if (labels) labels[c] = new Map(w);\n labeled[c] = 1;\n };\n const step = (h: number, dir: number) => {\n const sign = (h & 1 ? 1 : -1) * dir;\n for (const [s, d] of this.deltas[h >> 1]) addWinding(w, s, sign * d);\n };\n // depth-first frames: the cycle, the next half-edge to look across, and\n // the half-edge that led into the cycle\n const fc = new Int32Array(C);\n const fh = new Int32Array(C);\n const fvia = new Int32Array(C);\n if (components > 1) this.expectRayQueries(components);\n for (let r = 0; r < V; r++) {\n const p = leftmost[r];\n if (p < 0) continue;\n // Every edge at the leftmost vertex points into the east half-plane, so\n // the outgoing half-edge with the largest angle has the component's\n // unbounded face on its left. Its winding numbers are exactly the\n // graph's crossings of the ray going west from here.\n const g = this.out[offset[p + 1] - 1];\n const c0 = this.cycle[g];\n if (labeled[c0]) continue;\n w.clear();\n // A connected graph has no other component around its unbounded face.\n if (components > 1) this.windingWest(p, w);\n record(c0);\n let depth = 0;\n fc[0] = c0;\n fh[0] = this.cycleStart[c0];\n fvia[0] = -1;\n while (depth >= 0) {\n const h = fh[depth];\n if (h < 0) {\n // every neighbor of this cycle is labeled: restore and back out\n if (fvia[depth] >= 0) step(fvia[depth], -1);\n depth--;\n continue;\n }\n const hn = this.next[h];\n fh[depth] = hn === this.cycleStart[fc[depth]] ? -1 : hn;\n const c2 = this.cycle[h ^ 1];\n if (labeled[c2]) continue;\n step(h, 1);\n record(c2);\n depth++;\n fc[depth] = c2;\n fh[depth] = this.cycleStart[c2];\n fvia[depth] = h;\n }\n }\n this.count = count;\n this.hasFirst = hasFirst;\n this.hasLast = hasLast;\n this.labels = labels;\n }\n\n /** Add the winding numbers just west of vertex p into a sparse label. */\n private windingWest(p: number, labels: Map<number, number>): void {\n const px = this.vx[p];\n const py = this.vy[p];\n const gu = this.gu;\n const gv = this.gv;\n const vy = this.vy;\n const deltas = this.deltas;\n const cross = (e: number) => {\n const u = gu[e];\n const v = gv[e];\n if (u === p || v === p) return; // meets the ray at p itself\n const uy = vy[u];\n const wy = vy[v];\n if (uy > py === wy > py) return;\n if (this.crossingX(u, v, py) >= px) return;\n // a ring winding counterclockwise around p crosses the west ray downward\n const sign = wy > uy ? -1 : 1;\n for (const [s, d] of deltas[e]) addWinding(labels, s, sign * d);\n };\n const tree = this.rayTree();\n if (tree === undefined) {\n for (let e = 0, E = this.gu.length; e < E; e++) cross(e);\n return;\n }\n const stack = tree ? [tree] : [];\n while (stack.length > 0) {\n const node = stack.pop()!;\n if (node.x0 >= px || py < node.y0 || py >= node.y1) continue;\n if (node.x1 < px && py >= node.allY0 && py < node.allY1) {\n for (const [s, d] of node.sum) addWinding(labels, s, d);\n continue;\n }\n if (!node.edges) {\n stack.push(node.left!, node.right!);\n continue;\n }\n for (const e of node.edges) cross(e);\n }\n }\n\n /**\n * Where edge u→v crosses the horizontal line at y, given that it straddles it\n * by the half-open rule. An endpoint on the line is the crossing itself, taken\n * exactly so that ties at a vertex are exact ties.\n */\n private crossingX(u: number, v: number, y: number): number {\n const uy = this.vy[u];\n const wy = this.vy[v];\n if (uy === y) return this.vx[u];\n if (wy === y) return this.vx[v];\n const ux = this.vx[u];\n return ux + ((y - uy) * (this.vx[v] - ux)) / (wy - uy);\n }\n\n // ----------------------------------------------------------- selection\n\n /** Which cycles bound kept faces (on their left) for a mode. */\n select(mode: PathMode): Uint8Array {\n const C = this.cycleArea.length;\n const k = this.k;\n const keep = new Uint8Array(C);\n for (let c = 0; c < C; c++) {\n const count = this.count[c];\n const first = this.hasFirst[c] === 1;\n const last = this.hasLast[c] === 1;\n let on = false;\n switch (mode) {\n case \"intersect\":\n on = count === k;\n break;\n case \"exclude\":\n on = (count & 1) === 1;\n break;\n case \"minusFront\":\n on = first && count === 1;\n break;\n case \"minusBack\":\n on = last && count === 1;\n break;\n case \"crop\":\n on = last && count >= 2;\n break;\n default: // unite, divide\n on = count > 0;\n }\n keep[c] = on ? 1 : 0;\n }\n return keep;\n }\n\n /**\n * Rings of the merged kept region: the half-edges with a kept face on the\n * left and an unkept face on the right, traced with the same turning rule\n * restricted to those half-edges.\n */\n mergedRings(keep: Uint8Array, ringOf: Int32Array): number[][] {\n const H = ringOf.length;\n const cycle = this.cycle;\n const boundary = (h: number) =>\n keep[cycle[h]] === 1 && keep[cycle[h ^ 1]] === 0;\n const rings: number[][] = [];\n for (let h = 0; h < H; h++) {\n if (ringOf[h] >= 0 || !boundary(h)) continue;\n const r = rings.length;\n const seq: number[] = [];\n let cur = h;\n do {\n ringOf[cur] = r;\n seq.push(cur);\n // first boundary half-edge clockwise from the twin\n const v = this.target(cur);\n const base = this.offset[v];\n const n = this.offset[v + 1] - base;\n const s = this.slot[cur ^ 1];\n let found = -1;\n for (let i = 1; i <= n; i++) {\n const cand = this.out[base + ((s - i + n) % n)];\n if (boundary(cand)) {\n found = cand;\n break;\n }\n }\n if (found < 0) break; // cannot happen on a planar graph; end the ring\n cur = found;\n } while (cur !== h);\n rings.push(seq);\n }\n return rings;\n }\n\n /**\n * Split each traced walk at repeated vertices into simple rings. A boundary\n * that touches itself at a vertex (a hole pinched to its outer ring, two\n * holes meeting, two regions meeting at a corner) is one closed walk; its\n * simple pieces are separate rings. Returns the walk each ring came from.\n */\n simpleRings(\n walks: number[][],\n ringOf: Int32Array,\n ): { rings: number[][]; walk: number[] } {\n const at = new Int32Array(this.vx.length).fill(-1); // stack position of a vertex\n const rings: number[][] = [];\n const walk: number[] = [];\n const emit = (seq: number[], w: number) => {\n for (let i = 0; i < seq.length; i++) ringOf[seq[i]] = rings.length;\n rings.push(seq);\n walk.push(w);\n };\n for (let w = 0; w < walks.length; w++) {\n const seq = walks[w];\n const open: number[] = [];\n for (let i = 0; i < seq.length; i++) {\n const h = seq[i];\n const o = this.origin(h);\n const pos = at[o];\n if (pos >= 0) {\n // back at a vertex already on the walk: the part since then is a loop\n const loop = open.splice(pos);\n for (let j = 0; j < loop.length; j++) at[this.origin(loop[j])] = -1;\n emit(loop, w);\n }\n at[o] = open.length;\n open.push(h);\n }\n for (let j = 0; j < open.length; j++) at[this.origin(open[j])] = -1;\n emit(open, w);\n }\n return { rings, walk };\n }\n\n /** Rings of every kept face, one per cycle. */\n faceRings(keep: Uint8Array, ringOf: Int32Array): number[][] {\n const rings: number[][] = [];\n for (let c = 0, C = this.cycleArea.length; c < C; c++) {\n if (!keep[c]) continue;\n const r = rings.length;\n const seq: number[] = [];\n const start = this.cycleStart[c];\n let h = start;\n do {\n ringOf[h] = r;\n seq.push(h);\n h = this.next[h];\n } while (h !== start);\n rings.push(seq);\n }\n return rings;\n }\n\n /**\n * Group the rings into polygons: each counterclockwise ring followed by the\n * clockwise rings (holes) that puncture its face. A hole's face is found by\n * a ray west from its leftmost vertex: the nearest ring edge crossed has\n * that face on its east side.\n */\n assemble(rings: number[][], ringOf: Int32Array, walk: number[]): Group[][] {\n const R = rings.length;\n const vx = this.vx;\n const vy = this.vy;\n const area = new Float64Array(R);\n const left = new Int32Array(R);\n for (let r = 0; r < R; r++) {\n const seq = rings[r];\n let a = 0;\n let l = this.origin(seq[0]);\n for (let i = 0; i < seq.length; i++) {\n const o = this.origin(seq[i]);\n const t = this.target(seq[i]);\n a += vx[o] * vy[t] - vx[t] * vy[o];\n if (vx[o] < vx[l] || (vx[o] === vx[l] && vy[o] < vy[l])) l = o;\n }\n area[r] = a / 2;\n left[r] = l;\n }\n\n const sliver = this.tol * this.tol;\n const parent = new Int32Array(R).fill(-2); // -2 unresolved, -1 none\n\n // A hole split off a pinched walk may have another piece of the walk at\n // its own leftmost vertex, where a westward ray starts inside that piece\n // or finds nothing. The pieces of one walk bound one region: a hole's\n // outer is the smallest counterclockwise piece of the walk that contains\n // it, and a hole inside none of them shares the walk's outermost piece's\n // surroundings, found by a ray from the walk's leftmost vertex.\n const rayFrom = left;\n const pieces = new Map<number, number[]>();\n if (walk.length > 0 && walk[walk.length - 1] !== R - 1) {\n // some walk split into several rings (walk ids repeat)\n for (let r = 0; r < R; r++) {\n const list = pieces.get(walk[r]);\n if (list) list.push(r);\n else pieces.set(walk[r], [r]);\n }\n }\n for (const list of pieces.values()) {\n if (list.length < 2) continue;\n let l = left[list[0]];\n for (const q of list) {\n const v = left[q];\n if (vx[v] < vx[l] || (vx[v] === vx[l] && vy[v] < vy[l])) l = v;\n }\n for (const r of list) {\n if (area[r] >= 0) continue;\n const o = this.origin(rings[r][0]);\n const t = this.target(rings[r][0]);\n const mx = (vx[o] + vx[t]) / 2;\n const my = (vy[o] + vy[t]) / 2;\n let best = -1;\n for (const q of list) {\n if (area[q] <= sliver || (best >= 0 && area[q] >= area[best]))\n continue;\n if (this.encloses(rings[q], mx, my)) best = q;\n }\n if (best >= 0) parent[r] = best;\n else rayFrom[r] = l;\n }\n }\n\n let holes = 0;\n for (let r = 0; r < R; r++) if (area[r] < 0 && parent[r] === -2) holes++;\n this.expectRayQueries(holes);\n const resolve = (r: number): number => {\n const chain: number[] = [];\n let p = r;\n while (p >= 0 && area[p] < 0 && parent[p] === -2) {\n chain.push(p);\n parent[p] = -1; // stop if inconsistent geometry creates a cycle\n p = this.westHit(rayFrom[p], ringOf);\n }\n if (p >= 0 && area[p] < 0) p = parent[p];\n if (p >= 0 && !(area[p] > sliver)) p = -1;\n for (const hole of chain) parent[hole] = p;\n return p;\n };\n\n // A ring whose mean width (twice the area over the perimeter) is below the\n // tolerance is a hairline: the trace of edges that coincide up to rounding,\n // such as a vertex that touches an edge to float32 precision. It is\n // invisible filled and a stray line stroked, so it is dropped.\n const hairline = (ring: Group, a: number) =>\n Math.abs(a) < (this.tol * outputPerimeter(ring)) / 2;\n const outers = new Int32Array(R).fill(-1);\n const polygons: Group[][] = [];\n for (let r = 0; r < R; r++) {\n if (area[r] > sliver) {\n const outer = this.ring(rings[r]);\n const a = outputArea(outer);\n if (a <= 0 || hairline(outer, a)) continue;\n outers[r] = polygons.length;\n polygons.push([outer]);\n }\n }\n for (let r = 0; r < R; r++) {\n if (area[r] >= -sliver) continue;\n const p = resolve(r);\n if (p >= 0 && outers[p] >= 0) {\n const hole = this.ring(rings[r]);\n const a = outputArea(hole);\n if (a < 0 && !hairline(hole, a)) polygons[outers[p]].push(hole);\n }\n }\n return polygons;\n }\n\n /** Whether a simple ring encloses a point that is not on its boundary (crossing parity). */\n private encloses(seq: number[], x: number, y: number): boolean {\n const vx = this.vx;\n const vy = this.vy;\n let inside = false;\n for (let i = 0; i < seq.length; i++) {\n const o = this.origin(seq[i]);\n const t = this.target(seq[i]);\n const oy = vy[o];\n const ty = vy[t];\n if (oy > y === ty > y) continue;\n const xc = vx[o] + ((y - oy) * (vx[t] - vx[o])) / (ty - oy);\n if (xc < x) inside = !inside;\n }\n return inside;\n }\n\n /** The ring, among those in `ringOf`, whose edge is the nearest crossing of the ray west from vertex p and faces it. */\n private westHit(p: number, ringOf: Int32Array): number {\n const px = this.vx[p];\n const py = this.vy[p];\n let best = -Infinity;\n let bestSlope = -Infinity;\n let ring = -1;\n const gu = this.gu;\n const gv = this.gv;\n const vx = this.vx;\n const vy = this.vy;\n const visit = (e: number) => {\n if (ringOf[2 * e] < 0 && ringOf[2 * e + 1] < 0) return;\n const u = gu[e];\n const v = gv[e];\n if (u === p || v === p) return; // meets the ray at p itself\n const uy = vy[u];\n const wy = vy[v];\n if (uy > py === wy > py) return;\n const xc = this.crossingX(u, v, py);\n if (xc >= px) return;\n // Crossings exactly at a vertex tie on x; the ray sits just above the\n // vertex, so the most eastward upward edge is the nearest.\n const ux = vx[u];\n const wx = vx[v];\n const up = wy > uy;\n const slope = up ? (wx - ux) / (wy - uy) : (ux - wx) / (uy - wy);\n if (xc > best || (xc === best && slope > bestSlope)) {\n best = xc;\n bestSlope = slope;\n // The face east of the crossing is on the left of the downward\n // half-edge. If that half-edge has no ring the geometry is inconsistent\n // at the tol scale, and the hole is dropped rather than misplaced.\n ring = ringOf[up ? 2 * e + 1 : 2 * e];\n }\n };\n const tree = this.rayTree();\n if (tree === undefined) {\n for (let e = 0, E = this.gu.length; e < E; e++) visit(e);\n return ring;\n }\n const stack = tree ? [tree] : [];\n while (stack.length > 0) {\n const node = stack.pop()!;\n if (node.x0 >= px || node.x1 < best || py < node.y0 || py >= node.y1)\n continue;\n if (!node.edges) {\n // Search the more eastward child first so its hit can prune the west.\n const a = node.left!,\n b = node.right!;\n if (a.x1 < b.x1) stack.push(a, b);\n else stack.push(b, a);\n continue;\n }\n for (const e of node.edges) visit(e);\n }\n return ring;\n }\n\n /** Remove straight-through vertices without changing any bend in the boundary. */\n private ring(seq: number[]): Group {\n const vx = this.vx;\n const vy = this.vy;\n const n = seq.length;\n const ids: number[] = [];\n for (let i = 0; i < n; i++) ids.push(this.origin(seq[i]));\n const keep: number[] = [ids[0]];\n const straight = (prev: number, v: number, w: number) => {\n const rx = vx[w] - vx[prev];\n const ry = vy[w] - vy[prev];\n const t =\n ((vx[v] - vx[prev]) * rx + (vy[v] - vy[prev]) * ry) /\n (rx * rx + ry * ry);\n return (\n t > 0 &&\n t < 1 &&\n orient2d(vx[prev], vy[prev], vx[w], vy[w], vx[v], vy[v]) === 0\n );\n };\n // Keep an anchor through the linear pass. Only reconsider it after the\n // closing edge's actual neighbors are known.\n for (let i = 1; i < n; i++) {\n const v = ids[i];\n const w = ids[i === n - 1 ? 0 : i + 1];\n if (straight(keep[keep.length - 1], v, w)) continue;\n keep.push(v);\n }\n if (keep.length > 3 && straight(keep[keep.length - 1], keep[0], keep[1]))\n keep.shift();\n const g = new Group();\n for (let i = 0; i < keep.length; i++) {\n const pt = new Pt(2);\n pt[0] = vx[keep[i]];\n pt[1] = vy[keep[i]];\n const prev = g[g.length - 1];\n // Distinct double intersections can round to the same output Pt.\n if (!prev || prev[0] !== pt[0] || prev[1] !== pt[1]) g.push(pt);\n }\n if (\n g.length > 1 &&\n g[0][0] === g[g.length - 1][0] &&\n g[0][1] === g[g.length - 1][1]\n )\n g.pop();\n return g;\n }\n}\n\n/**\n * Combine shapes with a Path mode. Returns the rings of the merged region\n * for the merging modes, or one ring list per face for `divide` and `crop`.\n */\nexport function overlay(\n shapes: Iterable<PolygonLike> | PtLikeIterable,\n mode: \"divide\" | \"crop\",\n): Group[][];\nexport function overlay(\n shapes: Iterable<PolygonLike> | PtLikeIterable,\n mode: Exclude<PathMode, \"divide\" | \"crop\">,\n): Group[];\nexport function overlay(\n shapes: Iterable<PolygonLike> | PtLikeIterable,\n mode: PathMode,\n): Group[] | Group[][];\nexport function overlay(\n shapes: Iterable<PolygonLike> | PtLikeIterable,\n mode: PathMode,\n): Group[] | Group[][] {\n const faces = mode === \"divide\" || mode === \"crop\";\n const ov = new Overlay();\n if (!ov.read(shapes)) return [];\n ov.split();\n ov.merge();\n if (ov.gu.length === 0) return [];\n ov.trace();\n ov.label();\n const keep = ov.select(mode);\n const ringOf = new Int32Array(2 * ov.gu.length).fill(-1);\n const walks = faces\n ? ov.faceRings(keep, ringOf)\n : ov.mergedRings(keep, ringOf);\n const { rings, walk } = ov.simpleRings(walks, ringOf);\n const polygons = ov.assemble(rings, ringOf, walk);\n if (faces) return polygons;\n const flat: Group[] = [];\n for (let i = 0; i < polygons.length; i++) {\n for (let j = 0; j < polygons[i].length; j++) flat.push(polygons[i][j]);\n }\n return flat;\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Util } from \"./Util\";\nimport { Geom, Num } from \"./Num\";\nimport { Pt, Group } from \"./Pt\";\nimport { Mat } from \"./LinearAlgebra\";\nimport { overlay } from \"./_path\";\nimport {\n type PtLike,\n type GroupLike,\n type PtLikeIterable,\n type IntersectContext,\n type PtIterable,\n type PolygonLike,\n} from \"./Types\";\n\nlet _errorLength = (obj: any, param: number | string = \"expected\") =>\n Util.warn(\"Group's length is less than \" + param, obj);\nlet _errorOutofBound = (obj: any, param: number | string = \"\") =>\n Util.warn(`Index ${param} is out of bound in Group`, obj);\n\n/**\n * Line class provides static functions to create and operate on lines. A line is usually represented as a Group of 2 Pts.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Line {\n /**\n * Create a line that originates from an anchor point, given an angle and a magnitude.\n * @param anchor an anchor Pt\n * @param angle an angle in radian\n * @param magnitude magnitude of the line\n * @return a Group of 2 Pts representing a line segement\n */\n static fromAngle(anchor: PtLike, angle: number, magnitude: number): Group {\n let g = new Group(new Pt(anchor), new Pt(anchor));\n g[1].toAngle(angle, magnitude, true);\n return g;\n }\n\n /**\n * Calculate the slope of a line.\n * @param p1 line's first end point\n * @param p2 line's second end point\n */\n static slope(p1: PtLike, p2: PtLike): number | undefined {\n return p2[0] - p1[0] === 0 ? undefined : (p2[1] - p1[1]) / (p2[0] - p1[0]);\n }\n\n /**\n * Calculate the slope and xy intercepts of a line.\n * @param p1 line's first end point\n * @param p2 line's second end point\n * @returns an object with `slope`, `xi`, `yi` properties\n */\n static intercept(\n p1: PtLike,\n p2: PtLike,\n ): { slope: number; xi: number | undefined; yi: number } | undefined {\n if (p2[0] - p1[0] === 0) {\n return undefined;\n } else {\n let m = (p2[1] - p1[1]) / (p2[0] - p1[0]);\n let c = p1[1] - m * p1[0];\n return { slope: m, yi: c, xi: m === 0 ? undefined : -c / m };\n }\n }\n\n /**\n * Given a 2D path and a point, find whether the point is on left or right side of the line.\n * @param line a Group or an Iterable<PtLike> representing a line\n * @param pt a Pt or numeric array\n * @returns a negative value if on left and a positive value if on right. If collinear, then the return value is 0.\n */\n static sideOfPt2D(line: PtLikeIterable, pt: PtLike): number {\n let _line = Util.iterToArray(line);\n return (\n (_line[1][0] - _line[0][0]) * (pt[1] - _line[0][1]) -\n (pt[0] - _line[0][0]) * (_line[1][1] - _line[0][1])\n );\n }\n\n /**\n * Check if three Pts are collinear, ie, on the same straight path.\n * @param p1 first Pt\n * @param p2 second Pt\n * @param p3 third Pt\n * @param threshold a threshold where a smaller value means higher precision threshold for the straight line. Default is 0.01.\n */\n static collinear(\n p1: PtLike,\n p2: PtLike,\n p3: PtLike,\n threshold: number = 0.01,\n ): boolean {\n // Compare the cross product normalized by the segment magnitudes (the\n // sine of the angle between them), so the threshold is scale-free.\n const a = new Pt(0, 0, 0).to(p1).$subtract(p2);\n const b = new Pt(0, 0, 0).to(p1).$subtract(p3);\n const magSq = a.magnitudeSq() * b.magnitudeSq();\n if (magSq === 0) return true; // coincident points are collinear\n return a.$cross(b).magnitudeSq() / magSq <= threshold * threshold;\n }\n\n /**\n * Get magnitude of a line segment.\n * @param line a Group or an Iterable<Pt> with at least 2 Pt\n */\n static magnitude(line: PtIterable): number {\n let _line = Util.iterToArray(line);\n return _line.length >= 2 ? _line[1].$subtract(_line[0]).magnitude() : 0;\n }\n\n /**\n * Get squared magnitude of a line segment.\n * @param line a Group or an Iterable<Pt> with at least 2 Pt\n */\n static magnitudeSq(line: PtIterable): number {\n let _line = Util.iterToArray(line);\n return _line.length >= 2 ? _line[1].$subtract(_line[0]).magnitudeSq() : 0;\n }\n\n /**\n * Find a point on a line that is perpendicular (shortest distance) to a target point.\n * @param line a Group or an Iterable<Pt> that defines a line\n * @param pt a target Pt\n * @param asProjection if true, this returns the projection vector instead. Default is false.\n * @returns a Pt on the line that is perpendicular to the target Pt, or a projection vector if `asProjection` is true.\n */\n static perpendicularFromPt(\n line: PtIterable,\n pt: PtLike,\n asProjection: boolean = false,\n ): Pt | undefined {\n let _line = Util.iterToArray(line);\n if (_line[0].equals(_line[1])) return undefined;\n let a = _line[0].$subtract(_line[1]);\n let b = _line[1].$subtract(pt);\n let proj = b.$subtract(a.$project(b));\n\n return asProjection ? proj : proj.$add(pt);\n }\n\n /**\n * Given a line and a point, find the shortest distance from the point to the line.\n * @param line a Group of 2 Pts\n * @param pt a Pt\n * @see `Line.perpendicularFromPt`\n */\n static distanceFromPt(line: GroupLike, pt: PtLike | number[]): number {\n let _line = Util.iterToArray(line);\n let projectionVector = Line.perpendicularFromPt(_line, pt, true);\n if (projectionVector) {\n return projectionVector.magnitude();\n } else {\n // line is made of 2 identical points, return distance between this point and pt\n return _line[0].$subtract(pt).magnitude();\n }\n }\n\n /**\n * Given two lines as rays (infinite lines), find their intersection point if any.\n * @param la a Group or an Iterable<Pt> with 2 Pt representing a ray\n * @param lb a Group or an Iterable<Pt> with 2 Pts representing another ray\n * @returns an intersection Pt or undefined if no intersection\n */\n static intersectRay2D(la: PtIterable, lb: PtIterable): Pt | undefined {\n const _la = Util.iterToArray(la);\n const _lb = Util.iterToArray(lb);\n\n const pa = _la[0];\n const pb = _lb[0];\n\n // parametric form: no slope blow-up near vertical lines and uniform\n // handling of vertical/horizontal cases\n const rx = _la[1][0] - pa[0];\n const ry = _la[1][1] - pa[1];\n const sx = _lb[1][0] - pb[0];\n const sy = _lb[1][1] - pb[1];\n\n // a zero-length input does not define a ray\n if ((rx === 0 && ry === 0) || (sx === 0 && sy === 0)) return undefined;\n\n const det = rx * sy - ry * sx;\n if (det === 0) {\n // parallel; if collinear, keep legacy behavior of returning la's start\n const qpx = pb[0] - pa[0];\n const qpy = pb[1] - pa[1];\n return qpx * ry - qpy * rx === 0 ? new Pt(pa[0], pa[1]) : undefined;\n }\n\n const t = ((pb[0] - pa[0]) * sy - (pb[1] - pa[1]) * sx) / det;\n return new Pt(pa[0] + t * rx, pa[1] + t * ry);\n }\n\n /**\n * Given two line segemnts, find their intersection point if any.\n * @param la a Group or an Iterable<Pt> with 2 Pt representing a line segment\n * @param lb a Group or an Iterable<Pt> with 2 Pt representing a line segment\n * @returns an intersection Pt or undefined if no intersection\n */\n static intersectLine2D(la: PtIterable, lb: PtIterable): Pt | undefined {\n let _la = Util.iterToArray(la);\n let _lb = Util.iterToArray(lb);\n\n let pt = Line.intersectRay2D(_la, _lb);\n return pt &&\n Geom.withinBound(pt, _la[0], _la[1]) &&\n Geom.withinBound(pt, _lb[0], _lb[1])\n ? pt\n : undefined;\n }\n\n /**\n * Given a line segemnt and a ray (infinite line), find their intersection point if any.\n * @param line a Group of 2 Pts representing a line segment\n * @param ray a Group of 2 Pts representing a ray\n * @returns an intersection Pt or undefined if no intersection\n */\n static intersectLineWithRay2D(\n line: PtIterable,\n ray: PtIterable,\n ): Pt | undefined {\n let _line = Util.iterToArray(line);\n let _ray = Util.iterToArray(ray);\n let pt = Line.intersectRay2D(_line, _ray);\n return pt && Geom.withinBound(pt, _line[0], _line[1]) ? pt : undefined;\n }\n\n /**\n * Given a line segemnt or a ray (infinite line), find its intersection point(s) with a polygon.\n * @param lineOrRay a Group or an Iterable<Pt> with 2 Pt representing a line or ray\n * @param poly a Group or an Iterable<Pt> representing a polygon\n * @param sourceIsRay a boolean value to treat the line as a ray (infinite line). Default is `false`.\n */\n static intersectPolygon2D(\n lineOrRay: PtIterable,\n poly: PtIterable,\n sourceIsRay: boolean = false,\n ): Group | undefined {\n let _lineOrRay = Util.iterToArray(lineOrRay);\n let _poly = Util.iterToArray(poly);\n\n let fn = sourceIsRay ? Line.intersectLineWithRay2D : Line.intersectLine2D;\n let pts = new Group();\n for (let i = 0, len = _poly.length; i < len; i++) {\n let next = i === len - 1 ? 0 : i + 1;\n let d = fn([_poly[i], _poly[next]], _lineOrRay);\n if (d) pts.push(d);\n }\n return pts.length > 0 ? pts : undefined;\n }\n\n /**\n * Find intersection points of 2 sets of lines. This checks all line segments in the two lists. Consider using a bounding-box check before calling this. If you are checking convex polygon intersections, using [`Polygon.intersectPolygon2D`](#link) will be more efficient.\n * @param lines1 an Array/Iterable of (Groups or Iterables<Pt>)\n * @param lines2 an Array/Iterable of (Groups or Iterables<Pt>)\n * @param isRay a boolean value to treat the line as a ray (infinite line). Default is `false`.\n */\n static intersectLines2D(\n lines1: Iterable<PtIterable>,\n lines2: Iterable<PtIterable>,\n isRay: boolean = false,\n ): Group {\n let group = new Group();\n let fn = isRay ? Line.intersectLineWithRay2D : Line.intersectLine2D;\n for (let l1 of lines1) {\n for (let l2 of lines2) {\n let _ip = fn(l1, l2);\n if (_ip) group.push(_ip);\n }\n }\n return group;\n }\n\n /**\n * Get two points of a ray that intersects with a point on a 2D grid.\n * @param ray a Group or an Iterable<Pt> representing a ray\n * @param gridPt a Pt on the grid\n * @returns a group of two intersecting Pts. The first one is horizontal intersection and the second one is vertical intersection.\n */\n static intersectGridWithRay2D(ray: PtIterable, gridPt: PtLike): Group {\n let _ray = Util.iterToArray(ray);\n let t = Line.intercept(\n new Pt(_ray[0]).subtract(gridPt),\n new Pt(_ray[1]).subtract(gridPt),\n );\n let g = new Group();\n if (t && t.xi !== undefined) g.push(new Pt(gridPt[0] + t.xi, gridPt[1]));\n if (t && t.yi !== undefined) g.push(new Pt(gridPt[0], gridPt[1] + t.yi));\n return g;\n }\n\n /**\n * Get two intersection Pts of a line segment with a 2D grid point.\n * @param line a ray specified by 2 Pts\n * @param gridPt a Pt on the grid\n * @returns a group of two intersecting Pts. The first one is horizontal intersection and the second one is vertical intersection.\n */\n static intersectGridWithLine2D(\n line: GroupLike,\n gridPt: PtLike | number[],\n ): Group {\n let _line = Util.iterToArray(line);\n let g = Line.intersectGridWithRay2D(_line, gridPt);\n let gg = new Group();\n for (let i = 0, len = g.length; i < len; i++) {\n if (Geom.withinBound(g[i], _line[0], _line[1])) gg.push(g[i]);\n }\n return gg;\n }\n\n /**\n * An easy way to get rectangle-line intersection points. For more optimized implementation, store the rectangle's sides separately (eg, `Rectangle.sides()`) and use `Polygon.intersectPolygon2D()`.\n * @param line a Group representing a line\n * @param rect a Group representing a rectangle\n * @returns a Group of intersecting Pts\n */\n static intersectRect2D(line: GroupLike, rect: GroupLike): Group {\n let _line = Util.iterToArray(line);\n let _rect = Util.iterToArray(rect);\n let box = Geom.boundingBox(Group.fromPtArray(_line));\n if (!Rectangle.hasIntersectRect2D(box, _rect)) return new Group();\n return Line.intersectLines2D([_line], Rectangle.sides(_rect));\n }\n\n /**\n * Get evenly distributed points on a line. Similar to [`Create.distributeLinear`](#link) but excluding end points.\n * @param line a Group or an Iterable<PtLike> representing a line\n * @param num number of points to get\n */\n static subpoints(line: PtLikeIterable, num: number) {\n let _line = Util.iterToArray(line);\n let pts = new Group();\n for (let i = 1; i <= num; i++) {\n pts.push(Geom.interpolate(_line[0], _line[1], i / (num + 1)));\n }\n return pts;\n }\n\n /**\n * Crop this line by a circle or rectangle at end points. This can be useful for creating arrows that connect to an object's edge.\n * @param line a Group or an Iterable<Pt> representing a line to crop\n * @param size size of circle or rectangle as Pt\n * @param index line's end point index, ie, 0 = start and 1 = end.\n * @param cropAsCircle a boolean to specify whether the `size` parameter should be treated as circle. Default is `true`.\n * @return an intersecting point on the line that can be used for cropping.\n */\n static crop(\n line: PtIterable,\n size: PtLike,\n index: number = 0,\n cropAsCircle: boolean = true,\n ): Pt | undefined {\n let _line = Util.iterToArray(line);\n let tdx = index === 0 ? 1 : 0;\n let ls = _line[tdx].$subtract(_line[index]);\n\n if (ls.magnitudeSq() === 0) return _line[index]; // zero-length line\n\n if (cropAsCircle) {\n let d = ls.unit().multiply(size[1]);\n return _line[index].$add(d);\n } else {\n if (size[0] === 0) return _line[index]; // degenerate rectangle\n let rect = Rectangle.fromCenter(_line[index], size);\n let sides = Rectangle.sides(rect);\n let sideIdx = 0;\n\n if (Math.abs(ls[1] / ls[0]) > Math.abs(size[1] / size[0])) {\n sideIdx = ls[1] < 0 ? 0 : 2;\n } else {\n sideIdx = ls[0] < 0 ? 3 : 1;\n }\n return Line.intersectRay2D(sides[sideIdx], _line);\n }\n }\n\n /**\n * Create an marker arrow or line, placed at an end point of this line.\n * @param line a Group or an Iterable<Pt> representing a line to place marker\n * @param size size of the marker as Pt\n * @param graphic either \"arrow\" or \"line\"\n * @param atTail a boolean, if `true`, the marker will be positioned at tail of the line (ie, index = 1). Default is `true`.\n * @returns a Group that defines the marker's shape\n */\n static marker(\n line: PtIterable,\n size: PtLike,\n graphic: string = \"arrow\",\n atTail: boolean = true,\n ): Group {\n let _line = Util.iterToArray(line);\n let h = atTail ? 0 : 1;\n let t = atTail ? 1 : 0;\n let unit = _line[h].$subtract(_line[t]);\n\n if (unit.magnitudeSq() === 0) return new Group();\n unit.unit();\n\n let ps = Geom.perpendicular(unit).multiply(size[0]).add(_line[t]);\n if (graphic == \"arrow\") {\n ps.add(unit.$multiply(size[1]));\n return new Group(_line[t], ps[0], ps[1]);\n } else {\n return new Group(ps[0], ps[1]);\n }\n }\n\n /**\n * Convert this line to a new rectangle representation.\n * @param line a Group representing a line\n */\n static toRect(line: GroupLike) {\n let _line = Util.iterToArray(line);\n return new Group(_line[0].$min(_line[1]), _line[0].$max(_line[1]));\n }\n}\n\n/**\n * Rectangle class provides static functions to create and operate on rectangles. A rectangle is usually represented as a Group of 2 Pts, marking the top-left and bottom-right corners of the rectangle.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Rectangle {\n /**\n * Create a rectangle from top-left anchor point. Same as [`Rectangle.fromTopLeft`](#link).\n * @param topLeft top-left point\n * @param widthOrSize width as a number, or a Pt that defines its size\n * @param height optional height as a number\n * @returns a Group of 2 Pts representing a rectangle\n */\n static from(\n topLeft: PtLike,\n widthOrSize: number | PtLike,\n height?: number,\n ): Group {\n return Rectangle.fromTopLeft(topLeft, widthOrSize, height);\n }\n\n /**\n * Create a rectangle given a top-left position and a size.\n * @param topLeft top-left point\n * @param widthOrSize width as a number, or a Pt that defines its size\n * @param height optional height as a number\n * @returns a Group of 2 Pts representing a rectangle\n */\n static fromTopLeft(\n topLeft: PtLike,\n widthOrSize: number | PtLike,\n height?: number,\n ): Group {\n let size =\n typeof widthOrSize == \"number\"\n ? [widthOrSize, height ?? widthOrSize]\n : widthOrSize;\n return new Group(new Pt(topLeft), new Pt(topLeft).add(size));\n }\n\n /**\n * Create a rectangle given a center position and a size.\n * @param center center point\n * @param widthOrSize width as a number, or a Pt that defines its size\n * @param height optional height as a number\n * @returns a Group of 2 Pts representing a rectangle\n */\n static fromCenter(\n center: PtLike,\n widthOrSize: number | PtLike,\n height?: number,\n ): Group {\n let half =\n typeof widthOrSize == \"number\"\n ? [widthOrSize / 2, (height ?? widthOrSize) / 2]\n : new Pt(widthOrSize).divide(2);\n return new Group(new Pt(center).subtract(half), new Pt(center).add(half));\n }\n\n /**\n * Create a new circle that either fits within or encloses the rectangle. Same as [`Circle.fromRect`](#link).\n * @param pts a Group or an Iterable<Pt> with 2 Pt representing a rectangle\n * @param enclose if `true`, the circle will enclose the rectangle. If `false`, the circle will fit inside the rectangle.\n * @returns a Group that represents a circle\n */\n static toCircle(pts: PtIterable, enclose: boolean = true): Group {\n return Circle.fromRect(pts, enclose);\n }\n\n /**\n * Create a square that either fits within or encloses a rectangle.\n * @param pts a Group or an Iterable<Pt> with 2 Pt representing a rectangle\n * @param enclose if `true`, the square will enclose the rectangle. Default is `false`, which will fit the square inside the rectangle.\n * @returns a Group of 2 Pts representing a rectangle\n */\n static toSquare(pts: PtIterable, enclose = false): Group {\n let _pts = Util.iterToArray(pts);\n let s = Rectangle.size(_pts);\n let m = enclose ? s.maxValue().value : s.minValue().value;\n return Rectangle.fromCenter(Rectangle.center(_pts), m, m);\n }\n\n /**\n * Get the size of this rectangle as a Pt.\n * @param pts a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n */\n static size(pts: PtIterable): Pt {\n let p = Util.iterToArray(pts);\n return p[0].$max(p[1]).subtract(p[0].$min(p[1]));\n }\n\n /**\n * Get the center of this rectangle.\n * @param pts a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n */\n static center(pts: PtIterable): Pt {\n let p = Util.iterToArray(pts);\n let min = p[0].$min(p[1]);\n let max = p[0].$max(p[1]);\n return min.add(max.$subtract(min).divide(2));\n }\n\n /**\n * Get the 4 corners of this rectangle as a Group.\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n */\n static corners(rect: PtIterable): Group {\n let _rect = Util.iterToArray(rect);\n let p0 = _rect[0].$min(_rect[1]);\n let p2 = _rect[0].$max(_rect[1]);\n return new Group(p0, new Pt(p2.x, p0.y), p2, new Pt(p0.x, p2.y));\n }\n\n /**\n * Get the 4 sides of this rectangle as an array of 4 Groups.\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n * @returns an array of 4 Groups, each of which represents a line segment\n */\n static sides(rect: PtIterable): Group[] {\n let [p0, p1, p2, p3] = Rectangle.corners(rect);\n return [\n new Group(p0, p1),\n new Group(p1, p2),\n new Group(p2, p3),\n new Group(p3, p0),\n ];\n }\n\n /**\n * Given an array of rectangles, get a rectangle that bounds all of them.\n * @param rects an array of (Groups or Iterables<PtLike>) that represents a set of rectangles\n * @returns the bounding rectangle as a Group\n */\n static boundingBox(rects: Iterable<PtLikeIterable>): Group {\n let _rects = Util.iterToArray(rects);\n let merged = Util.flatten(_rects, false);\n if (merged.length === 0) return new Group();\n\n // Infinity, not Number.MAX_VALUE/MIN_VALUE. Pt is a Float32Array, in which\n // MAX_VALUE overflows to Infinity and MIN_VALUE flushes to 0, which would\n // leave the running maximum starting above every negative coordinate.\n let min = Pt.make(2, Infinity);\n let max = Pt.make(2, -Infinity);\n\n // calculate min max in a single pass\n for (let i = 0, len = merged.length; i < len; i++) {\n let p = merged[i];\n let dim = Math.min(2, p.length);\n for (let k = 0; k < dim; k++) {\n min[k] = Math.min(min[k], p[k]);\n max[k] = Math.max(max[k], p[k]);\n }\n }\n return new Group(min, max);\n }\n\n /**\n * Convert this rectangle into a Group representing a polygon. An alias for [`Rectangle.corners`](#link)\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n */\n static polygon(rect: PtIterable): Group {\n return Rectangle.corners(rect);\n }\n\n /**\n * Subdivide a rectangle into 4 rectangles, one for each quadrant.\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n * @returns an array of 4 Groups of rectangles\n */\n static quadrants(rect: PtIterable, center?: PtLike): Group[] {\n let _rect = Util.iterToArray(rect);\n let corners = Rectangle.corners(_rect);\n let _center =\n center != undefined ? new Pt(center) : Rectangle.center(_rect);\n return corners.map((c) => new Group(c, _center).boundingBox());\n }\n\n /**\n * Subdivde a rectangle into 2 rectangles, by row or by column.\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle\n * @param ratio a value between 0 to 1 to indicate the split ratio\n * @param asRows if `true`, split into 2 rows. Default is `false` which splits into 2 columns.\n * @returns an array of 2 Groups of rectangles\n */\n static halves(\n rect: PtIterable,\n ratio: number = 0.5,\n asRows: boolean = false,\n ): Group[] {\n let _rect = Util.iterToArray(rect);\n let min = _rect[0].$min(_rect[1]);\n let max = _rect[0].$max(_rect[1]);\n let mid = asRows\n ? Num.lerp(min[1], max[1], ratio)\n : Num.lerp(min[0], max[0], ratio);\n return asRows\n ? [\n new Group(min, new Pt(max[0], mid)),\n new Group(new Pt(min[0], mid), max),\n ]\n : [\n new Group(min, new Pt(mid, max[1])),\n new Group(new Pt(mid, min[1]), max),\n ];\n }\n\n /**\n * Check if a point is within a rectangle.\n * @param rect a Group of 2 Pts representing a Rectangle\n * @param pt the point to check\n */\n static withinBound(rect: GroupLike, pt: PtLike): boolean {\n let _rect = Util.iterToArray(rect);\n return Geom.withinBound(pt, _rect[0], _rect[1]);\n }\n\n /**\n * Check if a rectangle is within the bounds of another rectangle.\n * @param rect1 a Group of 2 Pts representing a rectangle\n * @param rect2 a Group of 2 Pts representing a rectangle\n * @param resetBoundingBox if `true`, reset the bounding box. Default is `false` which assumes the rect's first Pt at is its top-left corner.\n */\n static hasIntersectRect2D(\n rect1: GroupLike,\n rect2: GroupLike,\n resetBoundingBox: boolean = false,\n ): boolean {\n let _rect1 = Util.iterToArray(rect1);\n let _rect2 = Util.iterToArray(rect2);\n\n if (resetBoundingBox) {\n _rect1 = Geom.boundingBox(_rect1);\n _rect2 = Geom.boundingBox(_rect2);\n }\n\n if (_rect1[0][0] > _rect2[1][0] || _rect2[0][0] > _rect1[1][0])\n return false;\n if (_rect1[0][1] > _rect2[1][1] || _rect2[0][1] > _rect1[1][1])\n return false;\n return true;\n }\n\n /**\n * An easy way to get rectangle-rectangle intersection points. For more optimized implementation, store the rectangle's sides separately (eg, `Rectangle.sides()`) and use `Polygon.intersectPolygon2D()`.\n * @param rect1 a Group of 2 Pts representing a rectangle\n * @param rect2 a Group of 2 Pts representing a rectangle\n */\n static intersectRect2D(rect1: GroupLike, rect2: GroupLike): Group {\n let _rect1 = Util.iterToArray(rect1);\n let _rect2 = Util.iterToArray(rect2);\n if (!Rectangle.hasIntersectRect2D(_rect1, _rect2)) return new Group();\n return Line.intersectLines2D(\n Rectangle.sides(_rect1),\n Rectangle.sides(_rect2),\n );\n }\n}\n\n/**\n * Circle class provides static functions to create and operate on circles. A circle is usually represented as a Group of 2 Pts, where the first Pt specifies the center, and the second Pt specifies the radius.\n * To move a circle without changing its radius, move only its center, eg `circle[0].to(20, 20)`. Group transforms such as `circle.moveTo(20, 20)` affect both Pts, including the radius.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Circle {\n /**\n * Create a circle that either fits within, or encloses, a rectangle.\n * @param pts a Group or an Iterable<PtLike> with 2 Pt representing a rectangle\n * @param enclose if `true`, the circle will enclose the rectangle. Default is `false`, which will fit the circle inside the rectangle.\n * @returns a Group that represents a circle\n */\n static fromRect(pts: PtLikeIterable, enclose = false): Group {\n let _pts = Util.iterToArray(pts);\n let r = 0;\n let min = (r = Rectangle.size(_pts).minValue().value / 2);\n if (enclose) {\n let max = Rectangle.size(_pts).maxValue().value / 2;\n r = Math.sqrt(min * min + max * max);\n } else {\n r = min;\n }\n return new Group(Rectangle.center(_pts), new Pt(r, r));\n }\n\n /**\n * Create a circle that either fits within, or encloses, a triangle. Same as [`Triangle.circumcircle`](#link) or [`Triangle.incircle`](#link).\n * @param pts a Group or an Iterable<Pt> with 3 Pt representing a rectangle\n * @param enclose if `true`, the circle will enclose the triangle. Default is `false`, which will fit the circle inside the triangle.\n * @returns a Group that represents a circle\n */\n static fromTriangle(\n pts: PtIterable,\n enclose: boolean = false,\n ): Group | undefined {\n if (enclose) {\n return Triangle.circumcircle(pts);\n } else {\n return Triangle.incircle(pts);\n }\n }\n\n /**\n * Create a circle based on a center point and a radius.\n * @param pt center point of circle\n * @param radius radius of circle\n * @returns a Group that represents a circle\n */\n static fromCenter(pt: PtLike, radius: number): Group {\n return new Group(new Pt(pt), new Pt(radius, radius));\n }\n\n /**\n * Check if a point is within a circle.\n * @param pts a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param pt the point to checks\n * @param threshold an optional small number to set threshold. Default is 0.\n */\n static withinBound(\n pts: PtIterable,\n pt: PtLike,\n threshold: number = 0,\n ): boolean {\n let _pts = Util.iterToArray(pts);\n let d = _pts[0].$subtract(pt);\n return d.dot(d) + threshold < _pts[1].x * _pts[1].x;\n }\n\n /**\n * Get the intersection points between a circle and a ray (infinite line).\n * @param circle a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param ray a Group or an Iterable<Pt> with 2 Pt representing a ray\n * @returns a Group of intersection points, or an empty Group if no intersection is found\n */\n static intersectRay2D(circle: PtIterable, ray: PtIterable): Group {\n let _pts = Util.iterToArray(circle);\n let _ray = Util.iterToArray(ray);\n\n let d = _ray[0].$subtract(_ray[1]);\n let f = _pts[0].$subtract(_ray[0]);\n\n let a = d.dot(d);\n if (a === 0) return new Group(); // degenerate ray (two identical points)\n let b = f.dot(d);\n let c = f.dot(f) - _pts[1].x * _pts[1].x;\n let p = b / a;\n let q = c / a;\n let disc = p * p - q; // discriminant\n\n if (disc < 0) {\n return new Group();\n } else {\n let discSqrt = Math.sqrt(disc);\n\n let t1 = -p + discSqrt;\n let p1 = _ray[0].$subtract(d.$multiply(t1));\n if (disc === 0) return new Group(p1);\n\n let t2 = -p - discSqrt;\n let p2 = _ray[0].$subtract(d.$multiply(t2));\n return new Group(p1, p2);\n }\n }\n\n /**\n * Get the intersection points between a circle and a line segment.\n * @param circle a Group or an Iterable<Pt> with Pt representing a circle\n * @param line a Group or an Iterable<Pt> with 2 Pt representing a line\n * @returns a Group of intersection points, or an empty Group if no intersection is found\n */\n static intersectLine2D(circle: PtIterable, line: PtIterable): Group {\n let _pts = Util.iterToArray(circle);\n let _line = Util.iterToArray(line);\n\n let ps = Circle.intersectRay2D(_pts, _line);\n let g = new Group();\n if (ps.length > 0) {\n for (let i = 0, len = ps.length; i < len; i++) {\n if (Rectangle.withinBound(_line, ps[i])) g.push(ps[i]);\n }\n }\n return g;\n }\n\n /**\n * Get the intersection points between two circles.\n * @param circle1 a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param circle2 a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @returns a Group of intersection points, or an empty Group if no intersection is found\n */\n static intersectCircle2D(circle1: PtIterable, circle2: PtIterable): Group {\n let _pts = Util.iterToArray(circle1);\n let _circle = Util.iterToArray(circle2);\n\n let dv = _circle[0].$subtract(_pts[0]);\n let dr2 = dv.magnitudeSq();\n let dr = Math.sqrt(dr2);\n\n let ar = _pts[1].x;\n let br = _circle[1].x;\n let ar2 = ar * ar;\n let br2 = br * br;\n\n if (dr > ar + br) {\n // not intersected\n return new Group();\n } else if (dr < Math.abs(ar - br)) {\n // completely enclosed\n return new Group(_pts[0].clone());\n } else if (dr === 0) {\n // coincident circles: no discrete intersection points\n return new Group();\n } else {\n let a = (ar2 - br2 + dr2) / (2 * dr);\n let h = Math.sqrt(ar2 - a * a);\n let p = dv.$multiply(a / dr).add(_pts[0]);\n return new Group(\n new Pt(p.x + (h * dv.y) / dr, p.y - (h * dv.x) / dr),\n new Pt(p.x - (h * dv.y) / dr, p.y + (h * dv.x) / dr),\n );\n }\n }\n\n /**\n * Quick way to check rectangle intersection with a circle.\n * For more optimized implementation, store the rectangle's sides separately (eg, [`Rectangle.sides`](#link)) and use [`Polygon.intersectPolygon2D()`](#link).\n * @param circle a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a rectangle\n * @returns a Group of intersection points, or an empty Group if no intersection is found\n */\n static intersectRect2D(circle: PtIterable, rect: PtIterable): Group {\n let _pts = Util.iterToArray(circle);\n let _rect = Util.iterToArray(rect);\n\n let sides = Rectangle.sides(_rect);\n let g = [];\n for (let i = 0, len = sides.length; i < len; i++) {\n let ps = Circle.intersectLine2D(_pts, sides[i]);\n if (ps.length > 0) g.push(ps);\n }\n return Util.flatten(g);\n }\n\n /**\n * Get a rectangle that either fits within or encloses this circle. See also [`Rectangle.toCircle`](#link)\n * @param circle a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param within if `true`, the rectangle will be within the circle. If `false`, the rectangle will enclose the circle.\n * @returns a Group representing a rectangle\n */\n static toRect(circle: PtIterable, within: boolean = false): Group {\n let _pts = Util.iterToArray(circle);\n let r = _pts[1][0];\n if (within) {\n // half-side of the maximal inscribed square (its corners on the circle)\n let half = r / Math.SQRT2;\n return new Group(_pts[0].$subtract(half), _pts[0].$add(half));\n } else {\n return new Group(_pts[0].$subtract(r), _pts[0].$add(r));\n }\n }\n\n /**\n * Get a triangle that fits within this circle.\n * @param circle a Group or an Iterable<Pt> with 2 Pt representing a circle\n * @param within if `true`, the triangle will be within the circle. If `false`, the triangle will enclose the circle.\n */\n static toTriangle(circle: PtIterable, within: boolean = true): Group {\n let _pts = Util.iterToArray(circle);\n if (within) {\n let ang = -Math.PI / 2;\n let inc = (Math.PI * 2) / 3;\n let g = new Group();\n for (let i = 0; i < 3; i++) {\n g.push(_pts[0].clone().toAngle(ang, _pts[1][0], true));\n ang += inc;\n }\n return g;\n } else {\n return Triangle.fromCenter(_pts[0], _pts[1][0]);\n }\n }\n}\n\n/**\n * Triangle class provides static functions to create and operate on trianges. A triange is a polygon represented as a Group of 3 Pts.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Triangle {\n /**\n * Create a triangle from a rectangle. The triangle will be isosceles, with the bottom of the rectangle as its base.\n * @param rect a Group or an Iterable<Pt> with 2 Pt representing a rectangle\n */\n static fromRect(rect: PtIterable): Group {\n let _rect = Util.iterToArray(rect);\n let top = _rect[0].$add(_rect[1]).divide(2);\n top.y = _rect[0][1];\n let left = _rect[1].clone();\n left.x = _rect[0][0];\n return new Group(top, _rect[1].clone(), left);\n }\n\n /**\n * Create a triangle that fits within a circle.\n * @param circle a Group or an Iterable<Pt> with 2 Pt representing a circle\n */\n static fromCircle(circle: PtIterable): Group {\n return Circle.toTriangle(circle, true);\n }\n\n /**\n * Create an equilateral triangle based on a center point and a size.\n * @param pt the center point\n * @param size size is the magnitude of lines from center to the triangle's vertices, like a \"radius\".\n */\n static fromCenter(pt: PtLike, size: number): Group {\n return Triangle.fromCircle(Circle.fromCenter(pt, size));\n }\n\n /**\n * Get the medial, which is an inner triangle formed by connecting the midpoints of this triangle's sides.\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @returns a Group representing a medial triangle\n */\n static medial(tri: PtIterable): Group {\n let _pts = Util.iterToArray(tri);\n if (_pts.length < 3) return _errorLength(new Group(), 3);\n return Polygon.midpoints(_pts, true);\n }\n\n /**\n * Given a point of the triangle, the opposite side is the side which the point doesn't touch.\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @param index a Pt on the triangle group\n * @returns a Group that represents a line of the opposite side\n */\n static oppositeSide(tri: PtIterable, index: number): Group {\n let _pts = Util.iterToArray(tri);\n if (_pts.length < 3) return _errorLength(new Group(), 3);\n if (index === 0) {\n return Group.fromPtArray([_pts[1], _pts[2]]);\n } else if (index === 1) {\n return Group.fromPtArray([_pts[0], _pts[2]]);\n } else {\n return Group.fromPtArray([_pts[0], _pts[1]]);\n }\n }\n\n /**\n * Get a triangle's altitude, which is a line from a triangle's point to its opposite side, and perpendicular to its opposite side.\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @param index a Pt on the triangle group\n * @returns a Group that represents the altitude line\n */\n static altitude(tri: PtIterable, index: number): Group {\n let _pts = Util.iterToArray(tri);\n let opp = Triangle.oppositeSide(_pts, index);\n if (opp.length > 1) {\n return new Group(\n _pts[index],\n Line.perpendicularFromPt(opp, _pts[index])!,\n );\n } else {\n return new Group();\n }\n }\n\n /**\n * Get orthocenter, which is the intersection point of a triangle's 3 altitudes (the 3 lines that are perpendicular to its 3 opposite sides).\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @returns the orthocenter as a Pt\n */\n static orthocenter(tri: PtIterable): Pt | undefined {\n let _pts = Util.iterToArray(tri);\n if (_pts.length < 3) return _errorLength(undefined, 3);\n let a = Triangle.altitude(_pts, 0);\n let b = Triangle.altitude(_pts, 1);\n return Line.intersectRay2D(a, b);\n }\n\n /**\n * Get incenter, which is the center point of its inner circle, and also the intersection point of its 3 angle bisector lines (each of which cuts one of the 3 angles in half).\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @returns the incenter as a Pt\n */\n static incenter(tri: PtIterable): Pt | undefined {\n let _pts = Util.iterToArray(tri);\n if (_pts.length < 3) return _errorLength(undefined, 3);\n let a = Polygon.bisector(_pts, 0)!.add(_pts[0]);\n let b = Polygon.bisector(_pts, 1)!.add(_pts[1]);\n return Line.intersectRay2D(new Group(_pts[0], a), new Group(_pts[1], b));\n }\n\n /**\n * Get an interior circle, which is the largest circle completed enclosed by this triangle.\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @param center Optional parameter if the incenter is already known. Otherwise, leave it empty and the incenter will be calculated\n */\n static incircle(tri: PtIterable, center?: Pt): Group | undefined {\n let _pts = Util.iterToArray(tri);\n let c = center ? center : Triangle.incenter(_pts);\n if (!c) return undefined; // degenerate (collinear) triangle\n let area = Polygon.area(_pts);\n let perim = Polygon.perimeter(_pts, true);\n let r = (2 * area) / perim.total;\n // incenter can still resolve for some collinear orderings; a zero-area\n // triangle has no incircle regardless of point order\n if (!(r > 0)) return undefined;\n return Circle.fromCenter(c, r);\n }\n\n /**\n * Get circumcenter, which is the intersection point of its 3 perpendicular bisectors lines ( each of which divides a side in half and is perpendicular to the side).\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @returns the circumcenter as a Pt\n */\n static circumcenter(tri: PtIterable): Pt | undefined {\n let _pts = Util.iterToArray(tri);\n let md = Triangle.medial(_pts);\n let a = [\n md[0],\n Geom.perpendicular(_pts[0].$subtract(md[0])).p1.$add(md[0]),\n ];\n let b = [\n md[1],\n Geom.perpendicular(_pts[1].$subtract(md[1])).p1.$add(md[1]),\n ];\n return Line.intersectRay2D(a, b);\n }\n\n /**\n * Get circumcenter, which is the intersection point of its 3 perpendicular bisectors lines ( each of which divides a side in half and is perpendicular to the side).\n * @param tri a Group or an Iterable<Pt> representing a triangle\n * @param center Optional parameter if the circumcenter is already known. Otherwise, leave it empty and the circumcenter will be calculated\n */\n static circumcircle(tri: PtIterable, center?: Pt): Group | undefined {\n let _pts = Util.iterToArray(tri);\n let c = center ? center : Triangle.circumcenter(_pts);\n if (!c) return undefined; // degenerate (collinear) triangle\n let r = _pts[0].$subtract(c).magnitude();\n return Circle.fromCenter(c, r);\n }\n}\n\n/**\n * Polygon class provides static functions to create and operate on polygons. A polygon is usually represented as a Group of 3 or more Pts.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Polygon {\n /**\n * Get the centroid of a polygon, which is the average of all its points.\n * @param pts a Group or an Iterable<PtLike> representing a polygon\n */\n static centroid(pts: PtLikeIterable): Pt {\n return Geom.centroid(pts);\n }\n\n /**\n * Create a rectangular polygon. Same as creating a Rectangle and then getting its corners via [`Rectangle.corners`](#link).\n * @param center center point of the rectangle\n * @param widthOrSize width as number, or a Pt representing the size of the rectangle\n * @param height optional height\n */\n static rectangle(\n center: PtLike,\n widthOrSize: number | PtLike,\n height?: number,\n ): Group {\n return Rectangle.corners(Rectangle.fromCenter(center, widthOrSize, height));\n }\n\n /**\n * Create a regular polygon.\n * @param center The center position of the polygon\n * @param radius The radius, ie, a length from the center position to one of the polygon's corners.\n * @param sides Number of sides\n */\n static fromCenter(center: PtLike, radius: number, sides: number) {\n let g = new Group();\n for (let i = 0; i < sides; i++) {\n let ang = (Math.PI * 2 * i) / sides;\n g.push(\n new Pt(Math.cos(ang) * radius, Math.sin(ang) * radius).add(center),\n );\n }\n return g;\n }\n\n /**\n * Given a polygon, get one edge using an index.\n * @param pts a Group or an Iterable<PtLike> representing a polygon\n * @param index index of a Pt in the Group\n */\n static lineAt(pts: PtLikeIterable, index: number) {\n let _pts = Util.iterToArray(pts);\n if (index < 0 || index >= _pts.length)\n throw new Error(\"index out of the Polygon's range\");\n return new Group(\n _pts[index],\n index === _pts.length - 1 ? _pts[0] : _pts[index + 1],\n );\n }\n\n /**\n * Get the line segments in this polygon.\n * @param poly a Group or an Iterable<Pt>\n * @param closePath a boolean to specify whether the polygon should be closed (ie, whether the final segment should be counted).\n * @returns an array of Groups which has 2 Pts in each group\n */\n static lines(poly: PtIterable, closePath: boolean = true): Group[] {\n let _pts = Util.iterToArray(poly);\n if (_pts.length < 2) return _errorLength(new Group(), 2);\n // build real Groups; indexed assignment avoids the slow spread through\n // the Array subclass constructor\n const count = closePath ? _pts.length : _pts.length - 1;\n const sp: Group[] = new Array(count);\n for (let i = 0; i < count; i++) {\n const seg = new Group();\n seg[0] = _pts[i];\n seg[1] = _pts[i === _pts.length - 1 ? 0 : i + 1];\n sp[i] = seg;\n }\n return sp;\n }\n\n /**\n * Get a new polygon group that is derived from midpoints in this polygon.\n * @param poly a Group or an Iterable<Pt>\n * @param closePath a boolean to specify whether the polygon should be closed (ie, whether the final segment should be counted).\n * @param t a value between 0 to 1 for interpolation. Default to 0.5 which will get the middle point.\n */\n static midpoints(\n poly: PtIterable,\n closePath: boolean = false,\n t: number = 0.5,\n ): Group {\n const sides = Polygon.lines(poly, closePath);\n const mids = new Group();\n for (let i = 0, len = sides.length; i < len; i++) {\n mids[i] = Geom.interpolate(sides[i][0], sides[i][1], t);\n }\n return mids;\n }\n\n /**\n * Given a Pt in the polygon group, the adjacent sides are the two sides which the Pt touches.\n * @param poly a Group or an Iterable<Pt>\n * @param index the target Pt\n * @param closePath a boolean to specify whether the polygon should be closed (ie, whether the final segment should be counted).\n */\n static adjacentSides(\n poly: PtIterable,\n index: number,\n closePath: boolean = false,\n ): Group[] {\n let _pts = Util.iterToArray(poly);\n if (_pts.length < 2) return _errorLength(new Group(), 2);\n if (index < 0 || index >= _pts.length)\n return _errorOutofBound(new Group(), index);\n\n let gs = [];\n let left = index - 1;\n if (closePath && left < 0) left = _pts.length - 1;\n if (left >= 0) gs.push(new Group(_pts[index], _pts[left]));\n\n let right = index + 1;\n if (closePath && right > _pts.length - 1) right = 0;\n if (right <= _pts.length - 1) gs.push(new Group(_pts[index], _pts[right]));\n\n return gs;\n }\n\n /**\n * Get a bisector which is a line that split between two sides of a polygon equally.\n * @param poly a Group or an Iterable<Pt>\n * @param index the Pt in the polygon to bisect from\n * @returns a bisector direction Pt, the average of the two adjacent sides' unit vectors (not itself normalized)\n */\n static bisector(poly: PtIterable, index: number): Pt | undefined {\n let sides = Polygon.adjacentSides(poly, index, true);\n if (sides.length >= 2) {\n let a = sides[0][1].$subtract(sides[0][0]).unit();\n let b = sides[1][1].$subtract(sides[1][0]).unit();\n return a.add(b).divide(2);\n } else {\n return undefined;\n }\n }\n\n /**\n * Find the perimeter of this polygon, ie, the lengths of its sides.\n * @param poly a Group or an Iterable<Pt>\n * @param closePath a boolean to specify whether the polygon should be closed (ie, whether the final segment should be counted).\n * @returns an object with `total` length, and `segments` which is a Pt that stores each segment's length\n */\n static perimeter(\n poly: PtIterable,\n closePath: boolean = false,\n ): { total: number; segments: Pt } {\n const _pts = Util.iterToArray(poly);\n if (_pts.length < 2) {\n _errorLength(new Group(), 2);\n return { total: 0, segments: Pt.make(0, 0) };\n }\n\n const count = closePath ? _pts.length : _pts.length - 1;\n const p = Pt.make(count, 0);\n let mag = 0;\n\n for (let i = 0; i < count; i++) {\n const a = _pts[i];\n const b = _pts[i === _pts.length - 1 ? 0 : i + 1];\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const m = Math.sqrt(dx * dx + dy * dy);\n mag += m;\n p[i] = m;\n }\n\n return {\n total: mag,\n segments: p,\n };\n }\n\n /**\n * Find the area of a simple (non-self-intersecting) polygon using the shoelace formula.\n * @param pts a Group or an Iterable<PtLike> representing a polygon\n */\n static area(pts: PtLikeIterable): number {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 3) return _errorLength(0, 3);\n // determinant\n let det = (a: PtLike, b: PtLike) => a[0] * b[1] - a[1] * b[0];\n\n let area = 0;\n for (let i = 0, len = _pts.length; i < len; i++) {\n if (i < _pts.length - 1) {\n area += det(_pts[i], _pts[i + 1]);\n } else {\n area += det(_pts[i], _pts[0]);\n }\n }\n return Math.abs(area / 2);\n }\n\n /**\n * Get a convex hull of a set of points, using Melkman's algorithm. ([Reference](http://geomalgorithms.com/a12-_hull-3.html)).\n * @param pts a Group or an Iterable<PtLike>\n * @param sorted a boolean value to indicate if the group is pre-sorted by x position. Default is false.\n * @returns a group of Pt that defines the convex hull polygon\n */\n static convexHull(pts: PtLikeIterable, sorted: boolean = false): Group {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 3) return _errorLength(new Group(), 3);\n\n if (!sorted) {\n _pts = _pts.slice();\n _pts.sort((a, b) => a[0] - b[0]);\n }\n\n // check if is on left of ray a-b\n let left = (a: PtLike, b: PtLike, c: PtLike) => {\n return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]) > 0;\n };\n\n // double end queue\n let dq = [];\n let bot = _pts.length - 2;\n let top = bot + 3;\n dq[bot] = _pts[2];\n dq[top] = _pts[2];\n\n // first 3 pt as counter-clockwise triangle\n if (left(_pts[0], _pts[1], _pts[2])) {\n dq[bot + 1] = _pts[0];\n dq[bot + 2] = _pts[1];\n } else {\n dq[bot + 1] = _pts[1];\n dq[bot + 2] = _pts[0];\n }\n\n // remaining pts\n for (let i = 3, len = _pts.length; i < len; i++) {\n let pt = _pts[i];\n\n // if inside the hull\n if (left(dq[bot], dq[bot + 1], pt) && left(dq[top - 1], dq[top], pt)) {\n continue;\n }\n\n // rightmost tangent\n while (!left(dq[bot], dq[bot + 1], pt)) {\n bot += 1;\n }\n bot -= 1;\n dq[bot] = pt;\n\n // leftmost tangent\n while (!left(dq[top - 1], dq[top], pt)) {\n top -= 1;\n }\n top += 1;\n dq[top] = pt;\n }\n\n let hull = new Group();\n for (let h = 0; h < top - bot; h++) {\n hull.push(dq[bot + h]);\n }\n\n return hull;\n }\n\n /**\n * Given a point in the polygon as an origin, get an array of lines that connect all the remaining points to the origin point.\n * @param poly a Group or an Iterable<Pt> representing a polygon\n * @param originIndex the origin point's index in the polygon\n * @returns an array of Groups of line segments\n */\n static network(poly: PtIterable, originIndex: number = 0): Group[] {\n let _pts = Util.iterToArray(poly);\n let g = [];\n for (let i = 0, len = _pts.length; i < len; i++) {\n if (i != originIndex) g.push(new Group(_pts[originIndex], _pts[i]));\n }\n return g;\n }\n\n /**\n * Given a target Pt, find a Pt in the polygon's corners that's nearest to it.\n * @param poly a Group or an Iterable<Pt>\n * @param pt Pt to check\n * @returns an index in the pts indicating the nearest Pt, or -1 if none found\n */\n static nearestPt(poly: PtIterable, pt: PtLike): number {\n const _poly = Util.iterToArray(poly);\n const px = pt[0];\n const py = pt[1];\n let _near = Number.MAX_VALUE;\n let _item = -1;\n for (let i = 0, len = _poly.length; i < len; i++) {\n const dx = _poly[i][0] - px;\n const dy = _poly[i][1] - py;\n const d = dx * dx + dy * dy;\n if (d < _near) {\n _near = d;\n _item = i;\n }\n }\n return _item;\n }\n\n /**\n * Project axis (eg, for use in Separation Axis Theorem).\n * @param poly a Group or an Iterable<Pt>\n * @param unitAxis unit axis for calculating dot product\n */\n static projectAxis(poly: PtIterable, unitAxis: Pt): Pt {\n let _poly = Util.iterToArray(poly);\n let min = unitAxis.dot(_poly[0]);\n let max = min;\n for (let n = 1, len = _poly.length; n < len; n++) {\n const dot = unitAxis.dot(_poly[n]);\n if (dot < min) min = dot;\n else if (dot > max) max = dot;\n }\n return new Pt(min, max);\n }\n\n /**\n * Scalar core of the axis-overlap test used by the SAT functions: project both polygons on\n * the unit axis (ax, ay) and return the gap between the intervals (negative means overlap).\n */\n private static _axisOverlap2D(\n poly1: Pt[],\n poly2: Pt[],\n ax: number,\n ay: number,\n ): number {\n let min1 = ax * poly1[0][0] + ay * poly1[0][1];\n let max1 = min1;\n for (let n = 1, len = poly1.length; n < len; n++) {\n const d = ax * poly1[n][0] + ay * poly1[n][1];\n if (d < min1) min1 = d;\n else if (d > max1) max1 = d;\n }\n let min2 = ax * poly2[0][0] + ay * poly2[0][1];\n let max2 = min2;\n for (let n = 1, len = poly2.length; n < len; n++) {\n const d = ax * poly2[n][0] + ay * poly2[n][1];\n if (d < min2) min2 = d;\n else if (d > max2) max2 = d;\n }\n return min1 < min2 ? min2 - max1 : min1 - max2;\n }\n\n /**\n * Check overlap distance from projected axis.\n * @param poly1 a Group or an Iterable<Pt> representing the first polygon\n * @param poly2 a Group or an Iterable<Pt> representing the second polygon\n * @param unitAxis unit axis\n */\n protected static _axisOverlap(\n poly1: PtIterable,\n poly2: PtIterable,\n unitAxis: Pt,\n ) {\n let pa = Polygon.projectAxis(poly1, unitAxis);\n let pb = Polygon.projectAxis(poly2, unitAxis);\n return pa[0] < pb[0] ? pb[0] - pa[1] : pa[0] - pb[1];\n }\n\n /**\n * Check if a Pt is inside a convex polygon.\n * @param poly a Group or an Iterable<PtLike> representing a convex polygon\n * @param pt the Pt to check\n */\n static hasIntersectPoint(poly: PtLikeIterable, pt: PtLike): boolean {\n const _poly = Util.iterToArray(poly);\n const px = pt[0];\n const py = pt[1];\n let c = false;\n // same ray-cast as before, without a Group allocation per edge\n for (let i = 0, len = _poly.length; i < len; i++) {\n const a = _poly[i];\n const b = _poly[i === len - 1 ? 0 : i + 1];\n if (\n a[1] > py != b[1] > py &&\n px < ((b[0] - a[0]) * (py - a[1])) / (b[1] - a[1]) + a[0]\n ) {\n c = !c;\n }\n }\n return c;\n }\n\n /**\n * Check if a convex polygon and a circle has intersections using Separating Axis Theorem.\n * @param poly a Group or an Iterable<Pt> representing a convex polygon\n * @param circle a Group or an Iterable<Pt> representing a circle\n * @returns an `IntersectContext` object that stores the intersection info, or undefined if there's no intersection\n */\n static hasIntersectCircle(\n poly: PtIterable,\n circle: PtIterable,\n ): IntersectContext | null {\n let _poly = Util.iterToArray(poly);\n let _circle = Util.iterToArray(circle);\n\n const c = _circle[0];\n const r = _circle[1][0];\n\n // AABB pre-reject against the circle's bounding box. The corner cases this\n // skips are exactly those the perpendicular-foot check below would reject.\n let bx0 = Infinity;\n let by0 = Infinity;\n let bx1 = -Infinity;\n let by1 = -Infinity;\n for (let i = 0, len = _poly.length; i < len; i++) {\n const p = _poly[i];\n if (p[0] < bx0) bx0 = p[0];\n if (p[0] > bx1) bx1 = p[0];\n if (p[1] < by0) by0 = p[1];\n if (p[1] > by1) by1 = p[1];\n }\n if (c[0] + r < bx0 || c[0] - r > bx1 || c[1] + r < by0 || c[1] - r > by1) {\n return null;\n }\n\n let minDist = Number.MAX_SAFE_INTEGER;\n let minEdge: Group | null = null;\n let minAx = 0;\n let minAy = 0;\n let which = -1;\n\n for (let i = 0, len = _poly.length; i < len; i++) {\n const ea = _poly[i];\n const eb = _poly[i === len - 1 ? 0 : i + 1];\n let ax = ea[1] - eb[1]; // unit perpendicular of the edge\n let ay = eb[0] - ea[0];\n const alen = Math.sqrt(ax * ax + ay * ay);\n if (alen === 0) continue; // degenerate edge (duplicate points)\n ax /= alen;\n ay /= alen;\n\n // the circle projects onto the axis as [center·axis − r, center·axis + r]\n let minP = ax * _poly[0][0] + ay * _poly[0][1];\n let maxP = minP;\n for (let n = 1; n < len; n++) {\n const d = ax * _poly[n][0] + ay * _poly[n][1];\n if (d < minP) minP = d;\n else if (d > maxP) maxP = d;\n }\n const dotC = ax * c[0] + ay * c[1];\n const dist = minP < dotC - r ? dotC - r - maxP : minP - (dotC + r);\n\n if (dist > 0) {\n return null;\n } else if (Math.abs(dist) < minDist) {\n // Fix edge case and make sure the circle is intersecting. To be improved.\n const edge = Polygon.lineAt(_poly, i);\n const check =\n Rectangle.withinBound(edge, Line.perpendicularFromPt(edge, c)!) ||\n Circle.intersectLine2D(_circle, edge).length > 0;\n\n if (check) {\n minEdge = edge;\n minAx = ax;\n minAy = ay;\n minDist = Math.abs(dist);\n which = i;\n }\n }\n }\n\n if (!minEdge) return null;\n\n // Edge normals alone miss the case where the circle sits past a vertex:\n // the separating axis there runs from the nearest vertex to the center.\n let vx = 0;\n let vy = 0;\n let vd = Infinity;\n for (let i = 0, len = _poly.length; i < len; i++) {\n const dx = c[0] - _poly[i][0];\n const dy = c[1] - _poly[i][1];\n const d = dx * dx + dy * dy;\n if (d < vd) {\n vd = d;\n vx = dx;\n vy = dy;\n }\n }\n if (vd > 0) {\n const vlen = Math.sqrt(vd);\n vx /= vlen;\n vy /= vlen;\n let minP = Infinity;\n let maxP = -Infinity;\n for (let i = 0, len = _poly.length; i < len; i++) {\n const d = vx * _poly[i][0] + vy * _poly[i][1];\n if (d < minP) minP = d;\n if (d > maxP) maxP = d;\n }\n const dotC = vx * c[0] + vy * c[1];\n if (dotC - r > maxP || dotC + r < minP) return null;\n }\n\n // direction\n const centroid = Polygon.centroid(_poly);\n if (minAx * (c[0] - centroid[0]) + minAy * (c[1] - centroid[1]) < 0) {\n minAx = -minAx;\n minAy = -minAy;\n }\n\n return {\n which,\n dist: minDist,\n normal: new Pt(minAx, minAy),\n edge: minEdge,\n vertex: c,\n };\n }\n\n /**\n * Check if two convex polygons have intersections using Separating Axis Theorem.\n * @param poly1 a Group or an Iterable<Pt> representing a convex polygon\n * @param poly2 a Group or an Iterable<Pt> representing another convex polygon\n * @return an `IntersectContext` object that stores the intersection info, or undefined if there's no intersection\n */\n static hasIntersectPolygon(\n poly1: PtIterable,\n poly2: PtIterable,\n ): IntersectContext | null {\n // Reference: https://www.gamedev.net/articles/programming/math-and-physics/a-verlet-based-approach-for-2d-game-physics-r2714/\n let _poly1 = Util.iterToArray(poly1);\n let _poly2 = Util.iterToArray(poly2);\n const len1 = _poly1.length;\n const len2 = _poly2.length;\n\n // AABB pre-reject: for convex polygons, disjoint bounding boxes guarantee\n // that a separating edge normal exists, so the axis scan can be skipped\n let ax0 = Infinity;\n let ay0 = Infinity;\n let ax1 = -Infinity;\n let ay1 = -Infinity;\n for (let i = 0; i < len1; i++) {\n const p = _poly1[i];\n if (p[0] < ax0) ax0 = p[0];\n if (p[0] > ax1) ax1 = p[0];\n if (p[1] < ay0) ay0 = p[1];\n if (p[1] > ay1) ay1 = p[1];\n }\n let bx0 = Infinity;\n let by0 = Infinity;\n let bx1 = -Infinity;\n let by1 = -Infinity;\n for (let i = 0; i < len2; i++) {\n const p = _poly2[i];\n if (p[0] < bx0) bx0 = p[0];\n if (p[0] > bx1) bx1 = p[0];\n if (p[1] < by0) by0 = p[1];\n if (p[1] > by1) by1 = p[1];\n }\n if (ax0 > bx1 || bx0 > ax1 || ay0 > by1 || by0 > ay1) return null;\n\n // scan all edge normals as separating axes, tracking the smallest overlap\n let minDist = Number.MAX_SAFE_INTEGER;\n let minIndex = -1;\n let minAx = 0;\n let minAy = 0;\n\n for (let i = 0, plen = len1 + len2; i < plen; i++) {\n const src = i < len1 ? _poly1 : _poly2;\n const ei = i < len1 ? i : i - len1;\n const ea = src[ei];\n const eb = src[ei === src.length - 1 ? 0 : ei + 1];\n let ax = ea[1] - eb[1]; // unit perpendicular of the edge\n let ay = eb[0] - ea[0];\n const alen = Math.sqrt(ax * ax + ay * ay);\n if (alen === 0) continue; // degenerate edge (duplicate points)\n ax /= alen;\n ay /= alen;\n\n const dist = Polygon._axisOverlap2D(_poly1, _poly2, ax, ay);\n if (dist > 0) {\n return null;\n } else if (Math.abs(dist) < minDist) {\n minDist = Math.abs(dist);\n minIndex = i;\n minAx = ax;\n minAy = ay;\n }\n }\n\n if (minIndex < 0) return null;\n\n const which = minIndex < len1 ? 0 : 1;\n const edge =\n which === 0\n ? Polygon.lineAt(_poly1, minIndex)\n : Polygon.lineAt(_poly2, minIndex - len1);\n\n // flip if needed to make sure vertex and edge are in corresponding polygons\n const b1 = which === 0 ? _poly2 : _poly1;\n const b2 = which === 0 ? _poly1 : _poly2;\n\n const c1 = Polygon.centroid(b1);\n const c2 = Polygon.centroid(b2);\n\n // direction\n if (minAx * (c1[0] - c2[0]) + minAy * (c1[1] - c2[1]) < 0) {\n minAx = -minAx;\n minAy = -minAy;\n }\n\n // find vertex at smallest distance\n let smallest = Number.MAX_SAFE_INTEGER;\n let vertex: Pt = null!;\n for (let i = 0, len = b1.length; i < len; i++) {\n const d = minAx * (b1[i][0] - c2[0]) + minAy * (b1[i][1] - c2[1]);\n if (d < smallest) {\n smallest = d;\n vertex = b1[i];\n }\n }\n\n return {\n which,\n dist: minDist,\n normal: new Pt(minAx, minAy),\n edge,\n vertex,\n };\n }\n\n /**\n * Find intersection points of 2 polygons by checking every side of both polygons. Performance may be slow for complex polygons.\n * @param poly1 a Group or an Iterable<Pt> representing a polygon\n * @param poly2 a Group or an Iterable<Pt> representing another polygon\n */\n static intersectPolygon2D(poly1: PtIterable, poly2: PtIterable): Group {\n let _poly1 = Util.iterToArray(poly1);\n let _poly2 = Util.iterToArray(poly2);\n\n let lp = Polygon.lines(_poly1);\n let g = [];\n for (let i = 0, len = lp.length; i < len; i++) {\n let ins = Line.intersectPolygon2D(lp[i], _poly2, false);\n if (ins) g.push(ins);\n }\n return Util.flatten(g, true) as Group;\n }\n\n /**\n * Get a bounding box for each polygon group, as well as a union bounding-box for all groups.\n * @param polys an Array/Iterable of (Groups or Iterables<Pt>)\n */\n static toRects(polys: Iterable<PtIterable>): Group[] {\n let boxes = [];\n for (let g of polys) {\n boxes.push(Geom.boundingBox(g));\n }\n\n let merged = Util.flatten(boxes, false);\n boxes.unshift(Geom.boundingBox(merged));\n return boxes;\n }\n}\n\n/**\n * Path class provides static functions to combine polygons with boolean operations:\n * unite, intersect, exclude, subtract the shapes in front or behind, divide into faces, or crop by the top shape.\n * Shapes are listed in stacking order, the first at the back and the last in front, like the order you would draw them in.\n * A shape is a polygon (a Group, or any iterable of points), or a list of rings that together form a polygon with holes,\n * such as the result of another Path function. Every result is such a list of rings: an outer ring followed by its\n * holes, in opposite orientations, which [`CanvasForm.compound`](#link) draws as one path. Rings are open (the first point\n * is not repeated), 2D, and never share Pts with the input. Clockwise and counterclockwise rings are the same shape, and\n * a self-intersecting ring covers what `form.polygon` would fill (the nonzero rule). Input vertices closer together than a\n * millionth of the largest absolute coordinate are merged before finding intersections. For small shapes at large offsets,\n * work in local coordinates to avoid losing detail to this tolerance or the Float32 output.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Path {\n /**\n * Unite: merge all shapes into one polygon (the area inside any shape).\n * @param shapes an Array/Iterable of polygons in stacking order, back to front. Each is a Group or an Iterable<PtLike>, or a list of rings for a polygon with holes. A single ring is taken as one shape.\n * @returns the rings of the merged polygon: each outer ring followed by its holes; empty if the shapes have no area\n * @example `form.fillOnly(\"#f03\").compound( Path.unite( [star, disc] ) )`\n */\n static unite(shapes: Iterable<PolygonLike> | PtLikeIterable): Group[] {\n return overlay(shapes, \"unite\");\n }\n\n /**\n * Intersect: keep only the area inside every shape.\n * @param shapes an Array/Iterable of polygons in stacking order, back to front. Each is a Group or an Iterable<PtLike>, or a list of rings for a polygon with holes. A single ring is taken as one shape.\n * @returns the rings of the common polygon: each outer ring followed by its holes; empty if the shapes do not all overlap\n * @example `Path.intersect( [a, b, c] )`\n */\n static intersect(shapes: Iterable<PolygonLike> | PtLikeIterable): Group[] {\n return overlay(shapes, \"intersect\");\n }\n\n /**\n * Exclude: keep the area inside an odd number of shapes, so where two shapes overlap becomes a hole.\n * @param shapes an Array/Iterable of polygons in stacking order, back to front. Each is a Group or an Iterable<PtLike>, or a list of rings for a polygon with holes. A single ring is taken as one shape.\n * @returns the rings of the result: each outer ring followed by its holes; empty if the shapes cancel out\n * @example `Path.exclude( [a, b] )`\n */\n static exclude(shapes: Iterable<PolygonLike> | PtLikeIterable): Group[] {\n return overlay(shapes, \"exclude\");\n }\n\n /**\n * Minus Front: subtract every shape in front from the backmost (first) shape.\n * @param shapes an Array/Iterable of polygons in stacking order, back to front. Each is a Group or an Iterable<PtLike>, or a list of rings for a polygon with holes. A single ring is taken as one shape.\n * @returns the rings of what remains of the first shape: each outer ring followed by its holes; empty if nothing remains\n * @example `Path.minusFront( [disc, hole] )` cuts `hole` out of `disc`\n */\n static minusFront(shapes: Iterable<PolygonLike> | PtLikeIterable): Group[] {\n return overlay(shapes, \"minusFront\");\n }\n\n /**\n * Minus Back: subtract every shape behind from the frontmost (last) shape.\n * @param shapes an Array/Iterable of polygons in stacking order, back to front. Each is a Group or an Iterable<PtLike>, or a list of rings for a polygon with holes. A single ring is taken as one shape.\n * @returns the rings of what remains of the last shape: each outer ring followed by its holes; empty if nothing remains\n * @example `Path.minusBack( [wall, window] )` keeps the part of `window` not covered by `wall`\n */\n static minusBack(shapes: Iterable<PolygonLike> | PtLikeIterable): Group[] {\n return overlay(shapes, \"minusBack\");\n }\n\n /**\n * Divide: split the shapes at every crossing into separate faces. Each face is the largest area not cut by any edge, so\n * a region inside two shapes is its own face, and a self-overlapping region of one shape is too.\n * @param shapes an Array/Iterable of polygons in stacking order, back to front. Each is a Group or an Iterable<PtLike>, or a list of rings for a polygon with holes. A single ring is taken as one shape.\n * @returns an array of polygons, one per face, each an outer ring followed by its holes\n * @example `Path.divide( [a, b] ).forEach( (face, i) => form.fillOnly( colors[i] ).compound( face ) )`\n */\n static divide(shapes: Iterable<PolygonLike> | PtLikeIterable): Group[][] {\n return overlay(shapes, \"divide\");\n }\n\n /**\n * Crop: use the frontmost (last) shape as a mask, keeping the faces of the other shapes inside it and deleting the mask itself.\n * Like [`Path.divide`](#link), the shapes under the mask stay divided where they overlap.\n * See a [demo here](https://ptsjs.org/demo/?name=path.crop).\n * @param shapes an Array/Iterable of polygons in stacking order, back to front. Each is a Group or an Iterable<PtLike>, or a list of rings for a polygon with holes. A single ring is taken as one shape.\n * @returns an array of polygons, one per face inside the mask, each an outer ring followed by its holes\n * @example `Path.crop( [photo, frame] )`\n */\n static crop(shapes: Iterable<PolygonLike> | PtLikeIterable): Group[][] {\n return overlay(shapes, \"crop\");\n }\n}\n\n/**\n * Curve class provides static functions to interpolate curves. A curve is usually represented as a Group of 3 or more control points.\n * You can use the static functions as-is, or apply the [`Group.op`](#link) or [`Pt.op`](#link) to enable functional programming.\n * See [Op guide](../guide/Op-0400.html) for details.\n */\nexport class Curve {\n /**\n * Get a precalculated coefficients per step.\n * @param steps number of steps\n */\n static getSteps(steps: number): Group {\n let ts = new Group();\n for (let i = 0; i <= steps; i++) {\n let t = i / steps;\n ts.push(new Pt(t * t * t, t * t, t, 1));\n }\n return ts;\n }\n\n /**\n * Given an index for the starting position in a Pt group, get the control and/or end points of a curve segment.\n * @param pts a Group or an Iterable<PtLike>\n * @param index start index in `pts` array. Default is 0.\n * @param copyStart an optional boolean value to indicate if the start index should be used twice. Default is false.\n * @returns a group of 4 Pts\n */\n static controlPoints(\n pts: PtLikeIterable,\n index: number = 0,\n copyStart: boolean = false,\n ): Group {\n let _pts = Util.iterToArray(pts);\n\n if (index > _pts.length - 1) return new Group();\n let _index = (i: number) => (i < _pts.length - 1 ? i : _pts.length - 1);\n\n let p0 = _pts[index];\n index = copyStart ? index : index + 1;\n\n // get points based on index\n return new Group(\n p0,\n _pts[_index(index++)],\n _pts[_index(index++)],\n _pts[_index(index++)],\n );\n }\n\n /**\n * Build a per-step table of the 4 control-point weights for a curve family.\n * Computing these once per call (instead of a matrix product per output\n * point) is what makes the curve functions fast.\n */\n private static _weights(\n steps: number,\n fill: (t: number, out: Float64Array, o: number) => void,\n ): Float64Array {\n const w = new Float64Array((steps + 1) * 4);\n for (let i = 0; i <= steps; i++) {\n fill(i / steps, w, i * 4);\n }\n return w;\n }\n\n /**\n * Evaluate one curve segment with a precomputed weight table, pushing one\n * interpolated Pt per step into `out`. Control values are read by index so\n * both Pts and plain arrays work.\n */\n private static _evalSegment(\n out: Group,\n c: GroupLike,\n w: Float64Array,\n steps: number,\n ): void {\n const c0 = c[0];\n const c1 = c[1];\n const c2 = c[2];\n const c3 = c[3];\n const dim3 = c0.length > 2;\n for (let i = 0; i <= steps; i++) {\n const o = i * 4;\n const w0 = w[o];\n const w1 = w[o + 1];\n const w2 = w[o + 2];\n const w3 = w[o + 3];\n const x = w0 * c0[0] + w1 * c1[0] + w2 * c2[0] + w3 * c3[0];\n const y = w0 * c0[1] + w1 * c1[1] + w2 * c2[1] + w3 * c3[1];\n out.push(\n dim3\n ? new Pt(x, y, w0 * c0[2] + w1 * c1[2] + w2 * c2[2] + w3 * c3[2])\n : new Pt(x, y),\n );\n }\n }\n\n /**\n * Calulcate weighted sum to get the interpolated points.\n * @param ctrls anchors\n * @param params parameters\n */\n static _calcPt(ctrls: GroupLike, params: PtLike): Pt {\n let x = ctrls.reduce((a, c, i) => a + c.x * params[i], 0);\n let y = ctrls.reduce((a, c, i) => a + c.y * params[i], 0);\n if (ctrls[0].length > 2) {\n let z = ctrls.reduce((a, c, i) => a + c.z * params[i], 0);\n return new Pt(x, y, z);\n }\n return new Pt(x, y);\n }\n\n /**\n * Weighted sum of 4 control points with scalar weights — the shared core\n * of the single-point step functions, kept consistent with the batch\n * `_weights` tables by construction.\n */\n private static _stepPt(\n ctrls: GroupLike,\n w0: number,\n w1: number,\n w2: number,\n w3: number,\n ): Pt {\n const c0 = ctrls[0];\n const c1 = ctrls[1];\n const c2 = ctrls[2];\n const c3 = ctrls[3];\n const x = w0 * c0[0] + w1 * c1[0] + w2 * c2[0] + w3 * c3[0];\n const y = w0 * c0[1] + w1 * c1[1] + w2 * c2[1] + w3 * c3[1];\n return c0.length > 2\n ? new Pt(x, y, w0 * c0[2] + w1 * c1[2] + w2 * c2[2] + w3 * c3[2])\n : new Pt(x, y);\n }\n\n /**\n * Create a Catmull-Rom curve. Catmull-Rom is a kind of smooth-looking Cardinal curve.\n * @param pts a Group or an Iterable<PtLike>\n * @param steps the number of line segments per curve. Defaults to 10 steps\n * @returns a curve as a group of interpolated Pt\n */\n static catmullRom(pts: PtLikeIterable, steps: number = 10): Group {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 2) return new Group();\n\n let ps = new Group();\n const w = Curve._weights(steps, (t, out, o) => {\n const t2 = t * t;\n const t3 = t2 * t;\n out[o] = -0.5 * t3 + t2 - 0.5 * t;\n out[o + 1] = 1.5 * t3 - 2.5 * t2 + 1;\n out[o + 2] = -1.5 * t3 + 2 * t2 + 0.5 * t;\n out[o + 3] = 0.5 * t3 - 0.5 * t2;\n });\n\n // use first point twice\n Curve._evalSegment(ps, Curve.controlPoints(_pts, 0, true), w, steps);\n\n let k = 0;\n while (k < _pts.length - 2) {\n let cp = Curve.controlPoints(_pts, k);\n if (cp.length > 0) {\n Curve._evalSegment(ps, cp, w, steps);\n k++;\n }\n }\n\n return ps;\n }\n\n /**\n * Interpolate to get a point on Catmull-Rom curve.\n * @param step the coefficients [t*t*t, t*t, t, 1]\n * @param ctrls a group of anchor Pts\n * @return an interpolated Pt on the curve\n */\n static catmullRomStep(step: Pt, ctrls: GroupLike): Pt {\n // same coefficients as the batch `catmullRom` weight table\n const t3 = step[0];\n const t2 = step[1];\n const t = step[2];\n return Curve._stepPt(\n ctrls,\n -0.5 * t3 + t2 - 0.5 * t,\n 1.5 * t3 - 2.5 * t2 + 1,\n -1.5 * t3 + 2 * t2 + 0.5 * t,\n 0.5 * t3 - 0.5 * t2,\n );\n }\n\n /**\n * Create a Cardinal curve.\n * @param pts a Group or an Iterable<PtLike>\n * @param steps the number of line segments per curve. Defaults to 10 steps.\n * @param tension optional value between 0 to 1 to specify a \"tension\". Default to 0.5 which is the tension for Catmull-Rom curve.\n * @returns a curve as a group of interpolated Pt\n */\n static cardinal(\n pts: PtLikeIterable,\n steps: number = 10,\n tension = 0.5,\n ): Group {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 2) return new Group();\n\n let ps = new Group();\n const w = Curve._weights(steps, (t, out, o) => {\n const t2 = t * t;\n const t3 = t2 * t;\n out[o] = tension * (-t3 + 2 * t2 - t);\n out[o + 1] = tension * (-t3 + t2) + (2 * t3 - 3 * t2 + 1);\n out[o + 2] = tension * (t3 - 2 * t2 + t) + (-2 * t3 + 3 * t2);\n out[o + 3] = tension * (t3 - t2);\n });\n\n // use first point twice\n Curve._evalSegment(ps, Curve.controlPoints(_pts, 0, true), w, steps);\n\n let k = 0;\n while (k < _pts.length - 2) {\n let cp = Curve.controlPoints(_pts, k);\n if (cp.length > 0) {\n Curve._evalSegment(ps, cp, w, steps);\n k++;\n }\n }\n\n return ps;\n }\n\n /**\n * Interpolate to get a point on Cardinal curve.\n * @param step the coefficients [t*t*t, t*t, t, 1]\n * @param ctrls a group of anchor Pts\n * @param tension optional value between 0 to 1 to specify a \"tension\". Default to 0.5 which is the tension for Catmull-Rom curve\n * @return an interpolated Pt on the curve\n */\n static cardinalStep(step: Pt, ctrls: GroupLike, tension: number = 0.5): Pt {\n // same coefficients as the batch `cardinal` weight table\n const t3 = step[0];\n const t2 = step[1];\n const t = step[2];\n return Curve._stepPt(\n ctrls,\n tension * (-t3 + 2 * t2 - t),\n tension * (-t3 + t2) + (2 * t3 - 3 * t2 + 1),\n tension * (t3 - 2 * t2 + t) + (-2 * t3 + 3 * t2),\n tension * (t3 - t2),\n );\n }\n\n /**\n * Convert the anchors of a Cardinal curve into cubic Bezier control points, so the same curve can be drawn as a native path\n * with [`CanvasForm.bezier`](#link) or sampled with [`Curve.bezier`](#link).\n * With the default `alpha`, the Bezier traces the curve that [`Curve.cardinal`](#link) approximates with line segments,\n * subject to the float32 rounding of a Pt.\n * See a [demo here](https://ptsjs.org/demo/?name=curve.cardinal).\n *\n * Set `alpha` to 0.5 for centripetal or to 1 for chordal parameterization. At the default tension of 0.5,\n * centripetal Catmull-Rom segments with distinct adjacent anchors have no internal loops or cusps\n * (Yuksel, Schaefer and Keyser, 2011); changing tension can introduce them.\n * For non-uniform curves, coincident consecutive anchors give a constant segment and zero tangents at its ends.\n * @param pts a Group or an Iterable<PtLike> of anchor points\n * @param tension optional value between 0 to 1 to specify a \"tension\". Default to 0.5 which is the tension for Catmull-Rom curve.\n * @param alpha optional knot parameterization: 0 (default) is uniform, 0.5 is centripetal, 1 is chordal\n * @returns a Group of `3(n-1)+1` Pts in the layout that [`Curve.bezier`](#link) takes: each anchor is followed by the 2 control points of the segment that starts there\n * @example `form.bezier( Curve.cardinalToBezier( pts ) )`\n */\n static cardinalToBezier(\n pts: PtLikeIterable,\n tension: number = 0.5,\n alpha: number = 0,\n ): Group {\n const out = new Group();\n if (!(alpha >= 0) || alpha === Infinity) {\n return Util.warn(\n \"cardinalToBezier needs a finite alpha of 0 or more\",\n out,\n );\n }\n const p = Util.iterToArray(pts);\n const n = p.length;\n if (n < 2) return out;\n const dim3 = p[0].length > 2;\n\n // Uniform curves need no knot array. Keep small nonzero distances: replacing them\n // with an absolute epsilon changes the curve when coordinates are scaled.\n const dt = alpha === 0 ? undefined : new Float64Array(n - 1);\n if (dt) {\n for (let i = 0; i < n - 1; i++) {\n const dx = p[i + 1][0] - p[i][0];\n const dy = p[i + 1][1] - p[i][1];\n const dz = dim3 ? p[i + 1][2] - p[i][2] : 0;\n const d = Math.pow(Math.hypot(dx, dy, dz), alpha);\n dt[i] = d < Infinity ? d : 0; // an overflowing interval acts like a repeated anchor\n }\n }\n\n // Each segment is a cubic Hermite between two anchors, and a Hermite converts to a Bezier by\n // placing the control points a third of the way along the end tangents. The tangent at an\n // anchor comes from its two neighbors in the non-uniform Catmull-Rom form; an end anchor stands\n // in for its missing neighbor, which is the duplicated-endpoint convention of `Curve.cardinal`.\n const control = (\n o: PtLike,\n k: number,\n mx: number,\n my: number,\n mz: number,\n ) => {\n const pt = new Pt(dim3 ? 3 : 2);\n pt[0] = o[0] + k * mx;\n pt[1] = o[1] + k * my;\n if (dim3) pt[2] = o[2] + k * mz;\n return pt;\n };\n\n for (let i = 0; i < n; i++) {\n const p0 = p[Math.max(i - 1, 0)];\n const p1 = p[i];\n const p2 = p[Math.min(i + 1, n - 1)];\n const a = dt ? dt[Math.max(i - 1, 0)] : 1;\n const b = dt ? dt[Math.min(i, n - 2)] : 1;\n // Weighted adjacent differences, with weights shared across coordinates.\n // A repeated anchor has zero tangent on both sides: constant segments stay\n // constant, and reversing the anchors applies the same degeneracy policy.\n let wa = 0;\n let wb = 0;\n if (dt && a > 0 && b > 0) {\n const s = (2 * tension) / (a + b);\n wa = s * (b / a);\n wb = s * (a / b);\n }\n const mx = dt\n ? wa * (p1[0] - p0[0]) + wb * (p2[0] - p1[0])\n : tension * (p2[0] - p0[0]);\n const my = dt\n ? wa * (p1[1] - p0[1]) + wb * (p2[1] - p1[1])\n : tension * (p2[1] - p0[1]);\n const mz = dim3\n ? dt\n ? wa * (p1[2] - p0[2]) + wb * (p2[2] - p1[2])\n : tension * (p2[2] - p0[2])\n : 0;\n\n if (i > 0) out.push(control(p1, -a / 3, mx, my, mz));\n out.push(new Pt(p1));\n if (i < n - 1) out.push(control(p1, b / 3, mx, my, mz));\n }\n return out;\n }\n\n /**\n * Convert a chain of cubic Bezier curves into the anchors of a Cardinal curve: the inverse of [`Curve.cardinalToBezier`](#link).\n * A Cardinal curve's tangents come from its neighboring anchors, so this keeps every Bezier anchor and drops the Bezier handles.\n * The Cardinal curve still passes through the same anchors; between them it follows the handles only when they were\n * in Cardinal form to begin with and the original tension and alpha are reused. Coordinates are rounded to float32.\n * @param pts a Group or an Iterable<PtLike> in the layout of [`Curve.bezier`](#link); an incomplete trailing segment is ignored\n * @returns a Group of anchors for [`Curve.cardinal`](#link) or [`Curve.cardinalToBezier`](#link), with the tension and alpha of your choice\n * @example `Curve.cardinal( Curve.bezierToCardinal( chain ), 10, 0.5 )`\n */\n static bezierToCardinal(pts: PtLikeIterable): Group {\n const p = Util.iterToArray(pts);\n const m = Math.floor((p.length - 1) / 3); // complete segments\n const out = new Group();\n if (m < 1) return out;\n for (let k = 0; k <= m; k++) out.push(new Pt(p[3 * k]));\n return out;\n }\n\n /**\n * Create a Bezier curve. In a cubic bezier curve, the first and 4th anchors are end-points, and 2nd and 3rd anchors are control-points.\n * @param pts a group of anchor Pt\n * @param steps the number of line segments per curve. Defaults to 10 steps.\n * @returns a curve as a group of interpolated Pt\n */\n static bezier(pts: GroupLike, steps: number = 10) {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 4) return new Group();\n\n let ps = new Group();\n const w = Curve._weights(steps, (t, out, o) => {\n const t2 = t * t;\n const t3 = t2 * t;\n out[o] = -t3 + 3 * t2 - 3 * t + 1;\n out[o + 1] = 3 * t3 - 6 * t2 + 3 * t;\n out[o + 2] = -3 * t3 + 3 * t2;\n out[o + 3] = t3;\n });\n\n let k = 0;\n while (k < _pts.length - 3) {\n let c = Curve.controlPoints(_pts, k);\n if (c.length > 0) {\n Curve._evalSegment(ps, c, w, steps);\n\n // go to the next set of point, but assume current end pt is next start pt\n k += 3;\n }\n }\n\n return ps;\n }\n\n /**\n * Interpolate to get a point on a cubic Bezier curve.\n * @param step the coefficients [t*t*t, t*t, t, 1]\n * @param ctrls a group of anchor Pts\n * @return an interpolated Pt on the curve\n */\n static bezierStep(step: Pt, ctrls: GroupLike) {\n // same coefficients as the batch `bezier` weight table\n const t3 = step[0];\n const t2 = step[1];\n const t = step[2];\n return Curve._stepPt(\n ctrls,\n -t3 + 3 * t2 - 3 * t + 1,\n 3 * t3 - 6 * t2 + 3 * t,\n -3 * t3 + 3 * t2,\n t3,\n );\n }\n\n /**\n * Create a basis spline (NURBS) curve.\n * @param pts a group of anchor Pt\n * @param steps the number of line segments per curve. Defaults to 10 steps.\n * @param tension optional value between 0 to n to specify a \"tension\". Default is 1 which is the usual tension.\n * @returns a curve as a group of interpolated Pt\n */\n static bspline(\n pts: GroupLike,\n steps: number = 10,\n tension: number = 1,\n ): Group {\n let _pts = Util.iterToArray(pts);\n if (_pts.length < 2) return new Group();\n\n let ps = new Group();\n const w =\n tension !== 1\n ? Curve._weights(steps, (t, out, o) => {\n const t2 = t * t;\n const t3 = t2 * t;\n const b1 = 2 * t3 - 3 * t2 + 1;\n const b2 = -2 * t3 + 3 * t2;\n out[o] = tension * (-t3 / 6 + 0.5 * t2 - 0.5 * t + 1 / 6);\n out[o + 1] = tension * (-1.5 * t3 + 2 * t2 - 1 / 3) + b1;\n out[o + 2] = tension * (1.5 * t3 - 2.5 * t2 + 0.5 * t + 1 / 6) + b2;\n out[o + 3] = tension * (t3 / 6);\n })\n : Curve._weights(steps, (t, out, o) => {\n const t2 = t * t;\n const t3 = t2 * t;\n out[o] = -t3 / 6 + 0.5 * t2 - 0.5 * t + 1 / 6;\n out[o + 1] = 0.5 * t3 - t2 + 2 / 3;\n out[o + 2] = -0.5 * t3 + 0.5 * t2 + 0.5 * t + 1 / 6;\n out[o + 3] = t3 / 6;\n });\n\n let k = 0;\n while (k < _pts.length - 3) {\n let c = Curve.controlPoints(_pts, k);\n if (c.length > 0) {\n Curve._evalSegment(ps, c, w, steps);\n k++;\n }\n }\n\n return ps;\n }\n\n /**\n * Interpolate to get a point on a basis spline curve.\n * @param step the coefficients [t*t*t, t*t, t, 1]\n * @param ctrls a group of anchor Pts\n * @return an interpolated Pt on the curve\n */\n static bsplineStep(step: Pt, ctrls: GroupLike): Pt {\n // same coefficients as the batch `bspline` weight table\n const t3 = step[0];\n const t2 = step[1];\n const t = step[2];\n return Curve._stepPt(\n ctrls,\n -t3 / 6 + 0.5 * t2 - 0.5 * t + 1 / 6,\n 0.5 * t3 - t2 + 2 / 3,\n -0.5 * t3 + 0.5 * t2 + 0.5 * t + 1 / 6,\n t3 / 6,\n );\n }\n\n /**\n * Interpolate to get a point on a basis spline curve with tension.\n * @param step the coefficients [t*t*t, t*t, t, 1]\n * @param ctrls a group of anchor Pts\n * @param tension optional value between 0 to n to specify a \"tension\". Default to 1 which is the usual tension.\n * @return an interpolated Pt on the curve\n */\n static bsplineTensionStep(\n step: Pt,\n ctrls: GroupLike,\n tension: number = 1,\n ): Pt {\n // same coefficients as the batch `bspline` tension weight table\n const t3 = step[0];\n const t2 = step[1];\n const t = step[2];\n const b1 = 2 * t3 - 3 * t2 + 1;\n const b2 = -2 * t3 + 3 * t2;\n return Curve._stepPt(\n ctrls,\n tension * (-t3 / 6 + 0.5 * t2 - 0.5 * t + 1 / 6),\n tension * (-1.5 * t3 + 2 * t2 - 1 / 3) + b1,\n tension * (1.5 * t3 - 2.5 * t2 + 0.5 * t + 1 / 6) + b2,\n tension * (t3 / 6),\n );\n }\n\n /**\n * Convert the anchors of a B-spline curve into cubic Bezier control points, so the same curve can be drawn as a native path\n * with [`CanvasForm.bezier`](#link) or sampled with [`Curve.bezier`](#link).\n * The Bezier traces the curve that [`Curve.bspline`](#link) approximates with line segments,\n * subject to the float32 rounding of a Pt. See a [demo here](https://ptsjs.org/demo/?name=curve.bspline).\n * @param pts a Group or an Iterable<PtLike> of at least 4 anchor points\n * @param tension optional value between 0 to n to specify a \"tension\". Default is 1 which is the usual tension.\n * @returns a Group of `3(n-3)+1` Pts in the layout that [`Curve.bezier`](#link) takes\n * @example `form.bezier( Curve.bsplineToBezier( pts ) )`\n */\n static bsplineToBezier(pts: PtLikeIterable, tension: number = 1): Group {\n const p = Util.iterToArray(pts);\n const n = p.length;\n const out = new Group();\n if (n < 4) return out;\n const dim3 = p[0].length > 2;\n\n // A segment spans anchors p1..p2 with neighbors p0 and p3. Its end points blend three\n // anchors (a, 1-2a, a) and its control points blend p1 and p2 only; at tension 1 these\n // are the (1, 4, 1)/6 and (2, 1)/3 weights of Böhm's knot insertion.\n const a = tension / 6;\n const c = 1 - 2 * a;\n const blend = (\n u: PtLike,\n v: PtLike,\n w: PtLike,\n wu: number,\n wv: number,\n ww: number,\n ) => {\n const pt = new Pt(dim3 ? 3 : 2);\n pt[0] = wu * u[0] + wv * v[0] + ww * w[0];\n pt[1] = wu * u[1] + wv * v[1] + ww * w[1];\n if (dim3) pt[2] = wu * u[2] + wv * v[2] + ww * w[2];\n return pt;\n };\n\n out.push(blend(p[0], p[1], p[2], a, c, a));\n for (let i = 1; i < n - 2; i++) {\n const p1 = p[i];\n const p2 = p[i + 1];\n out.push(\n blend(p1, p2, p2, c, 2 * a, 0),\n blend(p1, p2, p2, 2 * a, c, 0),\n blend(p1, p2, p[i + 2], a, c, a),\n );\n }\n return out;\n }\n\n /**\n * Convert a chain of cubic Bezier curves into the anchors of a B-spline curve: the inverse of [`Curve.bsplineToBezier`](#link) at its default tension.\n * A B-spline does not pass through its anchors, so they are solved for: the result is the B-spline that passes through\n * every Bezier anchor and starts and ends along the Bezier's end handles (a tridiagonal system, solved in linear time).\n * For a chain that `bsplineToBezier` produced at tension 1 this recovers its anchors up to float32 rounding; for any other chain the B-spline keeps\n * the anchors and the end tangents, and its interior, being smooth to the second derivative, can only approximate the other handles.\n * @param pts a Group or an Iterable<PtLike> in the layout of [`Curve.bezier`](#link); an incomplete trailing segment is ignored\n * @returns a Group of `m+3` anchors for `m` Bezier segments, for [`Curve.bspline`](#link) or [`Curve.bsplineToBezier`](#link)\n * @example `Curve.bspline( Curve.bezierToBspline( chain ) )`\n */\n static bezierToBspline(pts: PtLikeIterable): Group {\n const p = Util.iterToArray(pts);\n const m = Math.floor((p.length - 1) / 3); // complete segments\n const out = new Group();\n if (m < 1) return out;\n const dim = p[0].length > 2 ? 3 : 2;\n\n // Unknowns are the anchors P1..P(m+1). Each Bezier anchor gives one row of (1, 4, 1)·P = 6·A,\n // and the two end rows fold in the end tangents, which also fix P0 and P(m+2) afterwards.\n // The right-hand sides then simplify to 3× the first handle, 6× each interior anchor, and 3× the last handle.\n const n = m + 1;\n const r = new Float64Array(n * dim);\n const d = new Float64Array(n); // pivots of the tridiagonal (2, 4, ..., 4, 2) with unit off-diagonals\n for (let k = 0; k < n; k++) {\n const src = k === 0 ? p[1] : k === m ? p[3 * m - 1] : p[3 * k];\n const w = k === 0 || k === m ? 3 : 6;\n for (let j = 0; j < dim; j++) r[k * dim + j] = w * src[j];\n }\n d[0] = 2;\n for (let k = 1; k < n; k++) {\n const w = 1 / d[k - 1];\n d[k] = (k < m ? 4 : 2) - w;\n for (let j = 0; j < dim; j++) r[k * dim + j] -= w * r[(k - 1) * dim + j];\n }\n for (let j = 0; j < dim; j++) r[(n - 1) * dim + j] /= d[n - 1];\n for (let k = n - 2; k >= 0; k--) {\n for (let j = 0; j < dim; j++) {\n r[k * dim + j] = (r[k * dim + j] - r[(k + 1) * dim + j]) / d[k];\n }\n }\n\n const first = new Pt(dim);\n const last = new Pt(dim);\n for (let j = 0; j < dim; j++) {\n first[j] = r[dim + j] - 6 * (p[1][j] - p[0][j]);\n last[j] = r[(m - 1) * dim + j] + 6 * (p[3 * m][j] - p[3 * m - 1][j]);\n }\n out.push(first);\n for (let k = 0; k < n; k++) {\n const pt = new Pt(dim);\n for (let j = 0; j < dim; j++) pt[j] = r[k * dim + j];\n out.push(pt);\n }\n out.push(last);\n return out;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Group } from \"./Pt\";\nimport { Line } from \"./Op\";\nimport { type PtLike, type GroupLike } from \"./Types\";\n\n/**\n * Vec provides various static functions for vector operations. It's not fully optimized but good enough to use.\n */\nexport class Vec {\n /**\n * Add `b` to vector `a`. Unlike `multiply`/`divide`, a shorter `b` is tolerated: missing (or NaN) dimensions are treated as 0.\n * @returns vector `a`\n */\n static add(a: PtLike, b: PtLike | number): PtLike {\n if (typeof b == \"number\") {\n for (let i = 0, len = a.length; i < len; i++) a[i] += b;\n } else {\n for (let i = 0, len = a.length; i < len; i++) a[i] += b[i] || 0;\n }\n return a;\n }\n\n /**\n * Subtract `b` from vector `a`. Unlike `multiply`/`divide`, a shorter `b` is tolerated: missing (or NaN) dimensions are treated as 0.\n * @returns vector `a`\n */\n static subtract(a: PtLike, b: PtLike | number): PtLike {\n if (typeof b == \"number\") {\n for (let i = 0, len = a.length; i < len; i++) a[i] -= b;\n } else {\n for (let i = 0, len = a.length; i < len; i++) a[i] -= b[i] || 0;\n }\n return a;\n }\n\n /**\n * Multiply `b` with vector `a`.\n * @returns vector `a`\n */\n static multiply(a: PtLike, b: PtLike | number): PtLike {\n if (typeof b == \"number\") {\n for (let i = 0, len = a.length; i < len; i++) a[i] *= b;\n } else {\n if (a.length != b.length) {\n throw new Error(\n `Cannot do element-wise multiply since the array lengths don't match: ${a.toString()} multiply-with ${b.toString()}`,\n );\n }\n for (let i = 0, len = a.length; i < len; i++) a[i] *= b[i];\n }\n return a;\n }\n\n /**\n * Divide `a` over `b`.\n * @returns vector `a`\n */\n static divide(a: PtLike, b: PtLike | number): PtLike {\n if (typeof b == \"number\") {\n if (b === 0) throw new Error(\"Cannot divide by zero\");\n for (let i = 0, len = a.length; i < len; i++) a[i] /= b;\n } else {\n if (a.length != b.length) {\n throw new Error(\n `Cannot do element-wise divide since the array lengths don't match. ${a.toString()} divide-by ${b.toString()}`,\n );\n }\n for (let i = 0, len = a.length; i < len; i++) a[i] /= b[i];\n }\n return a;\n }\n\n /**\n * Dot product of `a` and `b`.\n */\n static dot(a: PtLike, b: PtLike): number {\n if (a.length != b.length) throw new Error(\"Array lengths don't match\");\n let d = 0;\n for (let i = 0, len = a.length; i < len; i++) {\n d += a[i] * b[i];\n }\n return d;\n }\n\n /**\n * 2D cross product of `a` and `b`.\n */\n static cross2D(a: PtLike, b: PtLike): number {\n return a[0] * b[1] - a[1] * b[0];\n }\n\n /**\n * 3D Cross product of `a` and `b`.\n */\n static cross(a: PtLike, b: PtLike): Pt {\n return new Pt(\n a[1] * b[2] - a[2] * b[1],\n a[2] * b[0] - a[0] * b[2],\n a[0] * b[1] - a[1] * b[0],\n );\n }\n\n /**\n * Magnitude of `a`.\n */\n static magnitude(a: PtLike): number {\n return Math.sqrt(Vec.dot(a, a));\n }\n\n /**\n * Unit vector of `a`. If magnitude of `a` is already known, pass it in the second paramter to optimize calculation.\n */\n static unit(a: PtLike, magnitude: number | undefined = undefined): PtLike {\n const m = magnitude === undefined ? Vec.magnitude(a) : magnitude;\n if (m === 0) return a; // zero vector: values are already zeros\n return Vec.divide(a, m);\n }\n\n /**\n * Set `a` to its absolute value in each dimension.\n * @returns vector `a`\n */\n static abs(a: PtLike): PtLike {\n return Vec.map(a, Math.abs);\n }\n\n /**\n * Set `a` to its floor value in each dimension.\n * @returns vector `a`\n */\n static floor(a: PtLike): PtLike {\n return Vec.map(a, Math.floor);\n }\n\n /**\n * Set `a` to its ceiling value in each dimension.\n * @returns vector `a`\n */\n static ceil(a: PtLike): PtLike {\n return Vec.map(a, Math.ceil);\n }\n\n /**\n * Set `a` to its rounded value in each dimension.\n * @returns vector `a`\n */\n static round(a: PtLike): PtLike {\n return Vec.map(a, Math.round);\n }\n\n /**\n * Find the max value within a vector's dimensions.\n * @returns an object with `value` and `index` that specifies the max value and its corresponding dimension.\n */\n static max(a: PtLike): { value: number; index: number } {\n // -Infinity, not Number.MIN_VALUE (the smallest positive double), so\n // all-negative vectors report a correct maximum\n let m = -Infinity;\n let index = 0;\n for (let i = 0, len = a.length; i < len; i++) {\n if (a[i] >= m) {\n m = a[i];\n index = i;\n }\n }\n return { value: m, index: index };\n }\n\n /**\n * Find the min value within a vector's dimensions.\n * @returns an object with `value` and `index` that specifies the min value and its corresponding dimension.\n */\n static min(a: PtLike): { value: number; index: number } {\n let m = Infinity;\n let index = 0;\n for (let i = 0, len = a.length; i < len; i++) {\n if (a[i] <= m) {\n m = a[i];\n index = i;\n }\n }\n return { value: m, index: index };\n }\n\n /**\n * Add up all the dimensions' values and returns a scalar of the sum.\n */\n static sum(a: PtLike): number {\n let s = 0;\n for (let i = 0, len = a.length; i < len; i++) s += a[i];\n return s;\n }\n\n /**\n * Given a mapping function, update `a`'s value in each dimension.\n * @returns vector `a`\n */\n static map(\n a: PtLike,\n fn: (n: number, index: number, arr: PtLike) => number,\n ): PtLike {\n for (let i = 0, len = a.length; i < len; i++) {\n a[i] = fn(a[i], i, a);\n }\n return a;\n }\n}\n\n/**\n * Mat provides various static functions for matrix operations as well as a convenient way to chain a 3x3 transformation matrix. It's not fully optimized but good enough to use.\n */\nexport class Mat {\n protected _33!: GroupLike;\n\n constructor() {\n this.reset();\n }\n\n /**\n * Get the current value of its stored 3x3 matrix\n */\n get value(): GroupLike {\n return this._33;\n }\n\n /**\n * Convert the value of its stored 3x3 matrix to a 2D [`DOMMatrix`](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix) instance\n */\n get domMatrix(): DOMMatrix {\n return new DOMMatrix(Mat.toDOMMatrix(this._33));\n }\n\n /**\n * Reset the internal 3x3 matrix to its identity\n */\n reset() {\n this._33 = Mat.scale2DMatrix(1, 1);\n }\n\n /**\n * Scale the internal 3x3 matrix. You can chain this function with other related functions.\n * @param val [x, y] scale factors\n * @param at Optional origin location to scale from.\n */\n scale2D(val: PtLike, at: PtLike = [0, 0]): this {\n const m = Mat.scaleAt2DMatrix(val[0] ?? 1, val[1] ?? 1, at);\n this._33 = Mat.multiply(this._33, m);\n return this;\n }\n\n /**\n * Scale the internal 3x3 matrix. You can chain this function with other related functions.\n * @param ang Angle of rotation\n * @param at Optional origin location to rotate from.\n */\n rotate2D(ang: number, at: PtLike = [0, 0]): this {\n const m = Mat.rotateAt2DMatrix(Math.cos(ang), Math.sin(ang), at);\n this._33 = Mat.multiply(this._33, m);\n return this;\n }\n\n /**\n * Translate the internal 3x3 matrix. You can chain this function with other related functions.\n * @param val [x, y] offset values\n */\n translate2D(val: PtLike): this {\n const m = Mat.translate2DMatrix(val[0] || 0, val[1] || 0);\n this._33 = Mat.multiply(this._33, m);\n return this;\n }\n\n /**\n * Shear the internal 3x3 matrix. You can chain this function with other related functions.\n * @param val [x, y] shear factors (before tan() operation)\n * @param at Optional origin location to scale from.\n */\n shear2D(val: PtLike, at: PtLike = [0, 0]): this {\n const m = Mat.shearAt2DMatrix(\n Math.tan(val[0] ?? 0),\n Math.tan(val[1] ?? 0),\n at,\n );\n this._33 = Mat.multiply(this._33, m);\n return this;\n }\n\n /**\n * Matrix addition. Matrices should have the same rows and columns.\n * @param a a group of Pt\n * @param b a scalar number, an array of numeric arrays, or a group of Pt\n * @returns a new group with the same rows and columns as a and b\n */\n static add(a: GroupLike, b: GroupLike | number[][] | number): Group {\n if (typeof b != \"number\") {\n if (a[0].length != b[0].length)\n throw new Error(\n \"Cannot add matrix if rows' and columns' size don't match.\",\n );\n if (a.length != b.length)\n throw new Error(\n \"Cannot add matrix if rows' and columns' size don't match.\",\n );\n }\n\n const g = new Group();\n const isNum = typeof b == \"number\";\n for (let i = 0, len = a.length; i < len; i++) {\n g.push(a[i].$add(isNum ? b : b[i]));\n }\n\n return g;\n }\n\n /**\n * Matrix multiplication.\n * @param a a Group of M Pts, each with K dimensions (M-rows, K-columns)\n * @param b a scalar number, an array of numeric arrays, or a Group of K Pts, each with N dimensions (K-rows, N-columns) -- or if transposed is true, then N Pts with K dimensions\n * @param transposed (Only applicable if it's not elementwise multiplication) If true, then a and b's columns should match (ie, each Pt should have the same dimensions). Default is `false`.\n * @param elementwise if true, then the multiplication is done element-wise. Default is `false`.\n * @returns If not elementwise, this will return a new group with M Pt, each with N dimensions (M-rows, N-columns).\n */\n static multiply(\n a: GroupLike,\n b: GroupLike | number[][] | number,\n transposed: boolean = false,\n elementwise: boolean = false,\n ): Group {\n const g = new Group();\n\n if (typeof b != \"number\") {\n if (elementwise) {\n if (a.length != b.length)\n throw new Error(\n \"Cannot multiply matrix element-wise because the matrices' sizes don't match.\",\n );\n for (let ai = 0, alen = a.length; ai < alen; ai++) {\n g.push(a[ai].$multiply(b[ai]));\n }\n } else {\n if (!transposed && a[0].length != b.length)\n throw new Error(\n \"Cannot multiply matrix if rows in matrix-a don't match columns in matrix-b.\",\n );\n if (transposed && a[0].length != b[0].length)\n throw new Error(\n \"Cannot multiply matrix if transposed and the columns in both matrices don't match.\",\n );\n\n if (!transposed) b = Mat.transpose(b);\n\n for (let ai = 0, alen = a.length; ai < alen; ai++) {\n const p = Pt.make(b.length, 0);\n for (let bi = 0, blen = b.length; bi < blen; bi++) {\n p[bi] = Vec.dot(a[ai], b[bi]);\n }\n g.push(p);\n }\n }\n } else {\n for (let ai = 0, alen = a.length; ai < alen; ai++) {\n g.push(a[ai].$multiply(b));\n }\n }\n\n return g;\n }\n\n /**\n * Zip one slice of an array of Pts. For example, if the input `g` are organized in rows, then this function will take the values in a specific column.\n * @param g a group of Pt\n * @param index index to zip at\n * @param defaultValue a default value to fill if index out of bound. If not provided, it will throw an error instead.\n */\n static zipSlice(\n g: GroupLike | number[][],\n index: number,\n defaultValue: number | boolean = false,\n ): Pt {\n const z: number[] = [];\n for (let i = 0, len = g.length; i < len; i++) {\n if (g[i].length - 1 < index) {\n if (defaultValue === false)\n throw new Error(`Index ${index} is out of bounds`);\n z.push(defaultValue as number);\n } else {\n z.push(g[i][index]);\n }\n }\n return new Pt(z);\n }\n\n /**\n * Zip a group of Pt. For example, `[[1,2],[3,4],[5,6]]` will become `[[1,3,5],[2,4,6]]`.\n * @param g a group of Pt\n * @param defaultValue a default value to fill if index out of bound. If not provided, it will throw an error instead.\n * @param useLongest If true, find the longest list of values in a Pt and use its length for zipping. Default is false, which uses the first item's length for zipping.\n */\n static zip(\n g: GroupLike | number[][],\n defaultValue: number | boolean = false,\n useLongest = false,\n ): Group {\n const ps = new Group();\n const len: number = useLongest\n ? (g as Array<number[] | Pt>).reduce((a, b) => Math.max(a, b.length), 0)\n : g[0].length;\n for (let i = 0; i < len; i++) {\n ps.push(Mat.zipSlice(g, i, defaultValue));\n }\n return ps;\n }\n\n /**\n * Same as `zip` function.\n */\n static transpose(\n g: GroupLike | number[][],\n defaultValue: number | boolean = false,\n useLongest = false,\n ): Group {\n return Mat.zip(g, defaultValue, useLongest);\n }\n\n static toDOMMatrix(m: GroupLike | number[][]) {\n return [m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1]];\n }\n\n /**\n * Transform a 2D point given a 2x3 or 3x3 matrix.\n * @param pt a Pt to be transformed\n * @param m 2x3 or 3x3 matrix\n * @returns a new transformed Pt\n */\n static transform2D(pt: PtLike, m: GroupLike | number[][]): Pt {\n const x = pt[0] * m[0][0] + pt[1] * m[1][0] + m[2][0];\n const y = pt[0] * m[0][1] + pt[1] * m[1][1] + m[2][1];\n return new Pt(x, y);\n }\n\n /**\n * Get a scale matrix for use in `transform2D`.\n */\n static scale2DMatrix(x: number, y: number): GroupLike {\n return new Group(new Pt(x, 0, 0), new Pt(0, y, 0), new Pt(0, 0, 1));\n }\n\n /**\n * Get a rotate matrix for use in `transform2D`.\n */\n static rotate2DMatrix(cosA: number, sinA: number): GroupLike {\n return new Group(\n new Pt(cosA, sinA, 0),\n new Pt(-sinA, cosA, 0),\n new Pt(0, 0, 1),\n );\n }\n\n /**\n * Get a shear matrix for use in `transform2D`.\n */\n static shear2DMatrix(tanX: number, tanY: number): GroupLike {\n return new Group(new Pt(1, tanX, 0), new Pt(tanY, 1, 0), new Pt(0, 0, 1));\n }\n\n /**\n * Get a translate matrix for use in `transform2D`.\n */\n static translate2DMatrix(x: number, y: number): GroupLike {\n return new Group(new Pt(1, 0, 0), new Pt(0, 1, 0), new Pt(x, y, 1));\n }\n\n /**\n * Get a matrix to scale a point from an origin point. For use in `transform2D`.\n */\n static scaleAt2DMatrix(sx: number, sy: number, at: PtLike): GroupLike {\n const m = Mat.scale2DMatrix(sx, sy);\n m[2][0] = -at[0] * sx + at[0];\n m[2][1] = -at[1] * sy + at[1];\n return m;\n }\n\n /**\n * Get a matrix to rotate a point from an origin point. For use in `transform2D`.\n */\n static rotateAt2DMatrix(cosA: number, sinA: number, at: PtLike): GroupLike {\n const m = Mat.rotate2DMatrix(cosA, sinA);\n m[2][0] = at[0] * (1 - cosA) + at[1] * sinA;\n m[2][1] = at[1] * (1 - cosA) - at[0] * sinA;\n return m;\n }\n\n /**\n * Get a matrix to shear a point from an origin point. For use in `transform2D`.\n */\n static shearAt2DMatrix(tanX: number, tanY: number, at: PtLike): GroupLike {\n const m = Mat.shear2DMatrix(tanX, tanY);\n m[2][0] = -at[1] * tanY;\n m[2][1] = -at[0] * tanX;\n return m;\n }\n\n /**\n * Get a matrix to reflect a point along a line. For use in `transform2D`.\n * @param p1 first end point to define the reflection line\n * @param p1 second end point to define the reflection line\n */\n static reflectAt2DMatrix(p1: PtLike, p2: PtLike) {\n const intercept = Line.intercept(p1, p2);\n\n if (intercept == undefined) {\n return [\n new Pt([-1, 0, 0]),\n new Pt([0, 1, 0]),\n new Pt([p1[0] + p2[0], 0, 1]),\n ];\n } else {\n const yi = intercept.yi;\n const ang2 = Math.atan(intercept.slope) * 2;\n const cosA = Math.cos(ang2);\n const sinA = Math.sin(ang2);\n\n return [\n new Pt([cosA, sinA, 0]),\n new Pt([sinA, -cosA, 0]),\n new Pt([-yi * sinA, yi + yi * cosA, 1]),\n ];\n }\n }\n}\n","/* This code has been written by Steve Gibson and can be found here:\n *\n * https://www.grc.com/otg/uheprng.htm\n *\n * The code has been converted to typescript and unused functions have\n * been removed.\n *\n * Port notes:\n * - Only the seeded, deterministic path survives: the original's\n * nondeterministic startup fill (from the host's `Math.random`) fed a\n * usage this port removed, so it is omitted and seeding consumes no\n * outside entropy.\n * - `random()` returns the raw 32-bit MWC fraction — every draw is an\n * exact multiple of 2^-32. The original composed two draws into a\n * 53-bit double; callers here (Float32-based Pts) don't need that.\n * - Despite the original header below, this is not a cryptographically\n * secure PRNG by modern standards (its state is recoverable from its\n * outputs). Pts uses it for reproducible generative art only.\n */\n\n/*\t============================================================================\n Gibson Research Corporation\n UHEPRNG - Ultra High Entropy Pseudo-Random Number Generator\n ============================================================================\n LICENSE AND COPYRIGHT: THIS CODE IS HEREBY RELEASED INTO THE PUBLIC DOMAIN\n Gibson Research Corporation releases and disclaims ALL RIGHTS AND TITLE IN\n THIS CODE OR ANY DERIVATIVES. Anyone may be freely use it for any purpose.\n ============================================================================\n This is GRC's cryptographically strong PRNG (pseudo-random number generator)\n for JavaScript. It is driven by 1536 bits of entropy, stored in an array of\n 48, 32-bit JavaScript variables. Since many applications of this generator,\n including ours with the \"Off The Grid\" Latin Square generator, may require\n the deteriministic re-generation of a sequence of PRNs, this PRNG's initial\n entropic state can be read and written as a static whole, and incrementally\n evolved by pouring new source entropy into the generator's internal state.\n ----------------------------------------------------------------------------\n ENDLESS THANKS are due Johannes Baagoe for his careful development of highly\n robust JavaScript implementations of JS PRNGs. This work was based upon his\n JavaScript \"Alea\" PRNG which is based upon the extremely robust Multiply-\n With-Carry (MWC) PRNG invented by George Marsaglia. MWC Algorithm References:\n http://www.GRC.com/otg/Marsaglia_PRNGs.pdf\n http://www.GRC.com/otg/Marsaglia_MWC_Generators.pdf\n ----------------------------------------------------------------------------\n The quality of this algorithm's pseudo-random numbers have been verified by\n multiple independent researchers. It handily passes the fermilab.ch tests as\n well as the \"diehard\" and \"dieharder\" test suites. For individuals wishing\n to further verify the quality of this algorithm's pseudo-random numbers, a\n 256-megabyte file of this algorithm's output may be downloaded from GRC.com,\n and a Microsoft Windows scripting host (WSH) version of this algorithm may be\n downloaded and run from the Windows command prompt to generate unique files\n of any size:\n The Fermilab \"ENT\" tests: http://fourmilab.ch/random/\n The 256-megabyte sample PRN file at GRC: https://www.GRC.com/otg/uheprng.bin\n The Windows scripting host version: https://www.GRC.com/otg/wsh-uheprng.js\n ----------------------------------------------------------------------------\n Qualifying MWC multipliers are: 187884, 686118, 898134, 1104375, 1250205,\n 1460910 and 1768863. (We use the largest one that's < 2^21)\n ============================================================================\n*/\n\n/*\t============================================================================\n This is based upon Johannes Baagoe's carefully designed and efficient hash\n function for use with JavaScript. It has a proven \"avalanche\" effect such\n that every bit of the input affects every bit of the output 50% of the time,\n which is good.\tSee: http://baagoe.com/en/RandomMusings/hash/avalanche.xhtml\n ============================================================================\n*/\n// calling with no (or a falsy) argument resets the hash state instead of\n// hashing — initState and the empty-seed path rely on that contract (the\n// reset path's return value is never consumed)\nfunction Mash(): (data?: string) => number {\n let n = 0xefc8249d;\n return function (data?: string): number {\n if (data) {\n data = data.toString();\n for (let i = 0; i < data.length; i++) {\n n += data.charCodeAt(i);\n let h = 0.02519603282416938 * n;\n n = h >>> 0;\n h -= n;\n h *= n;\n n = h >>> 0;\n h -= n;\n n += h * 0x100000000; // 2^32\n }\n return (n >>> 0) * 2.3283064365386963e-10; // 2^-32\n }\n n = 0xefc8249d;\n return 0;\n };\n}\n\nexport default function uheprng(seed: string) {\n const o = 48; // set the 'order' number of ENTROPY-holding 32-bit values\n let c = 1; // init the 'carry' used by the multiply-with-carry (MWC) algorithm\n let p = o; // init the 'phase' (max-1) of the intermediate variable pointer\n const s: number[] = new Array(o); // declare our intermediate variables array\n\n const mash = Mash(); // get a pointer to our high-performance \"Mash\" hash\n\n // initialize the mash hash and the PRNG's internal state to a fixed,\n // deterministic startup context before hashing in the seeding input\n function initState() {\n mash(); // pass a null arg to force mash hash to init\n for (let i = 0; i < o; i++) s[i] = mash(\" \"); // fill the array with initial mash hash values\n c = 1; // init our multiply-with-carry carry\n p = o; // init our phase\n }\n\n // this \"clean string\" function removes leading and trailing spaces and non-printing\n // control characters, including any embedded carriage-return (CR) and line-feed (LF)\n // characters, from any string it is handed. this is used by the 'hashString' function\n // (below) so users always obtain the same EFFECTIVE uheprng seeding key: seeds that\n // differ only by surrounding whitespace or embedded control characters collide.\n function cleanString(inStr: string): string {\n inStr = inStr.replace(/(^\\s*)|(\\s*$)/gi, \"\"); // remove any/all leading spaces\n inStr = inStr.replace(/[\\x00-\\x1F]/gi, \"\"); // remove any/all control characters\n return inStr; // return the cleaned up result\n }\n\n // this \"hash string\" function hashes the provided character string after first cleaning\n // it (above); an empty effective seed leaves the fixed initState context untouched\n function hashString(inStr: string) {\n inStr = cleanString(inStr);\n mash(inStr); // use the string to evolve the 'mash' state\n for (let i = 0; i < inStr.length; i++) {\n // scan through the characters in our string\n const k = inStr.charCodeAt(i).toString(); // stringify once per character, not per slot\n for (let j = 0; j < o; j++) {\n // \t\"mash\" it into the UHEPRNG state\n s[j] -= mash(k);\n if (s[j] < 0) s[j] += 1;\n }\n }\n }\n\n initState();\n hashString(seed);\n\n return {\n /**\n * this (not anymore) PRIVATE (internal access only) function is the heart of the multiply-with-carry\n * (MWC) PRNG algorithm. When called it returns a pseudo-random number in the form of a\n * 32-bit JavaScript fraction (0.0 to <1.0) — an exact multiple of 2^-32.\n * @returns a number between 0.0 and 1.0\n */\n random(): number {\n if (++p >= o) p = 0;\n const t = 1768863 * s[p] + c * 2.3283064365386963e-10; // 2^-32\n return (s[p] = t - (c = t | 0));\n },\n };\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Const, Util } from \"./Util\";\nimport { Curve } from \"./Op\";\nimport { Pt, Group } from \"./Pt\";\nimport { Vec, Mat } from \"./LinearAlgebra\";\nimport {\n type PtLike,\n type GroupLike,\n type PtLikeIterable,\n type PtIterable,\n} from \"./Types\";\n\nimport generator from \"./uheprng\";\n\n/**\n * Num class provides static helper functions for basic numeric operations.\n */\nexport class Num {\n static generator: any;\n\n /**\n * Check if two numbers are equal or almost equal within a threshold.\n * @param a number a\n * @param b number b\n * @param threshold threshold value that specifies the minimum difference within which the two numbers are considered equal\n */\n static equals(a: number, b: number, threshold = 0.00001): boolean {\n // A value equals itself (infinities included, whose difference is NaN),\n // and a difference equal to the threshold is included, as in Pt.equals.\n return a === b || Math.abs(a - b) <= threshold;\n }\n\n /**\n * Calculate linear interpolation between 2 values.\n * @param a start value\n * @param b end value\n * @param t an interpolation value, usually between 0 to 1\n */\n static lerp(a: number, b: number, t: number): number {\n return (1 - t) * a + t * b;\n }\n\n /**\n * Clamp values between min and max.\n * @param val value to clamp\n * @param min min value\n * @param max max value\n */\n static clamp(val: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, val));\n }\n\n /**\n * Different from [`Num.clamp`](#link) in that the value out-of-bound will be \"looped back\" to the other end.\n * @param val value to bound\n * @param min min value\n * @param max max value\n * @example `boundValue(361, 0, 360)` will return 1\n */\n static boundValue(val: number, min: number, max: number): number {\n const len = Math.abs(max - min);\n let a = (val - min) % len;\n if (a < 0) a += len;\n return a + min;\n }\n\n /**\n * Check if a value is within two other values\n * @param p value to check\n * @param a first bounding value\n * @param b second bounding value\n */\n static within(p: number, a: number, b: number): boolean {\n return p >= Math.min(a, b) && p <= Math.max(a, b);\n }\n\n /**\n * Get a random number within a range.\n * @param a range value 1\n * @param b range value 2\n */\n static randomRange(a: number, b: number = 0): number {\n const r = a > b ? a - b : b - a;\n return Math.min(a, b) + Num.random() * r;\n }\n\n /**\n * Get a random Pt within the range defined by either 1 or 2 Pt\n * @param a the range if only one Pt is used, or the start of the range if two Pt were used\n * @param b optional Pt to define the end of the range\n */\n static randomPt(a: PtLike, b?: PtLike): Pt {\n const p = new Pt(a.length);\n const range = b ? Vec.subtract(b.slice(), a) : a;\n const start = b ? a : new Pt(a.length).fill(0);\n for (let i = 0, len = p.length; i < len; i++) {\n p[i] = Num.random() * range[i] + start[i];\n }\n return p;\n }\n\n /**\n * Normalize a value within a range.\n * @param n the value to normalize\n * @param a range value 1\n * @param b range value 1\n */\n static normalizeValue(n: number, a: number, b: number): number {\n const min = Math.min(a, b);\n const max = Math.max(a, b);\n return (n - min) / (max - min);\n }\n\n /**\n * Sum a group of numeric arrays.\n * @param pts a Group or an Iterable<PtLike>\n * @returns a Pt of the dimensional sums\n */\n static sum(pts: PtLikeIterable): Pt {\n const _pts = Util.iterToArray(pts);\n const c = new Pt(_pts[0]);\n for (let i = 1, len = _pts.length; i < len; i++) {\n Vec.add(c, _pts[i]);\n }\n return c;\n }\n\n /**\n * Average a group of numeric arrays\n * @param pts a Group or an Iterable<PtLike>\n * @returns a Pt of averages\n */\n static average(pts: PtLikeIterable): Pt {\n const _pts = Util.iterToArray(pts);\n return Num.sum(_pts).divide(_pts.length);\n }\n\n /**\n * Given a value between 0 to 1, returns a value that cycles between 0 -> 1 -> 0 using the provided shaping method.\n * @param t a value between 0 to 1\n * @param method a shaping method. Default to [`Shaping.sineInOut`](#link).\n * @return a value between 0 to 1\n */\n static cycle(\n t: number,\n method: (t: number) => number = Shaping.sineInOut,\n ): number {\n return method(t > 0.5 ? 2 - t * 2 : t * 2);\n }\n\n /**\n * Map a value from one range to another.\n * @param n a value in the first range\n * @param currA first endpoint of the input range\n * @param currB second endpoint of the input range\n * @param targetA first endpoint of the output range\n * @param targetB second endpoint of the output range\n * @returns a remapped value in the second range\n */\n static mapToRange(\n n: number,\n currA: number,\n currB: number,\n targetA: number,\n targetB: number,\n ) {\n if (currA == currB)\n throw new Error(\n \"[currMin, currMax] must define a range that is not zero\",\n );\n // signed normalization so that reversed source or target ranges map\n // directionally instead of being silently reoriented\n const t = (n - currA) / (currB - currA);\n return targetA + t * (targetB - targetA);\n }\n\n /**\n * Seed the pseudorandom generator for reproducible [`Num.random`](#link) sequences.\n * The seed is hashed by its *effective* key: leading/trailing whitespace and embedded\n * control characters are stripped first, so seeds differing only in those collide.\n * An empty (or whitespace-only) seed yields a fixed default sequence. This generator\n * is deterministic and statistically strong, but not cryptographically secure.\n * @param seed seed string\n */\n static seed(seed: string): void {\n this.generator = generator(seed);\n }\n\n /**\n * Return a random number between 0 and 1. If a seed was set via [`Num.seed`](#link),\n * draws come from the seeded generator with 32-bit resolution (exact multiples of 2^-32);\n * otherwise it uses `Math.random`.\n * @returns a number between 0 and 1\n */\n static random(): number {\n return this.generator ? this.generator.random() : Math.random();\n }\n}\n\n/**\n * Geom class provides static helper functions for basic geometric operations.\n */\nexport class Geom {\n /**\n * Bound an angle between 0 to 360 degrees.\n * @param angle angle value\n */\n static boundAngle(angle: number): number {\n return Num.boundValue(angle, 0, 360);\n }\n\n /**\n * Bound a radian between 0 to two PI.\n * @param radian radian value\n */\n static boundRadian(radian: number): number {\n return Num.boundValue(radian, 0, Const.two_pi);\n }\n\n /**\n * Convert an angle in degree to radian.\n * @param angle angle value\n */\n static toRadian(angle: number): number {\n return angle * Const.deg_to_rad;\n }\n\n /**\n * Convert an angle in radian to degree.\n * @param radian radian value\n */\n static toDegree(radian: number): number {\n return radian * Const.rad_to_deg;\n }\n\n /**\n * Get a bounding box for a set of Pts.\n * @param pts a Group or an Iterable<Pt>\n * @return a Group of two Pts, representing the top-left and bottom-right corners\n */\n static boundingBox(pts: PtIterable): Group {\n let minPt: Pt | undefined, maxPt: Pt | undefined;\n for (const p of pts) {\n if (minPt == undefined) {\n minPt = p.clone();\n maxPt = p.clone();\n } else {\n // in-place equivalent of `$min` / `$max`, without 2 clones per point\n for (let i = 0, len = Math.min(minPt.length, p.length); i < len; i++) {\n minPt[i] = Math.min(minPt[i], p[i]);\n maxPt![i] = Math.max(maxPt![i], p[i]);\n }\n }\n }\n return new Group(minPt!, maxPt!);\n }\n\n /**\n * Get a centroid (the average middle point) for a set of Pts.\n * @param pts a Group or an Iterable<PtLike>\n * @return a centroid Pt\n */\n static centroid(pts: PtLikeIterable): Pt {\n return Num.average(pts);\n }\n\n /**\n * Given an anchor Pt, rebase all Pts in this group either to or from this anchor base.\n * @param pts a Group or an Iterable<PtLike>\n * @param ptOrIndex an index for the Pt array, or an external Pt\n * @param direction a string either \"to\" (subtract all Pt with this anchor base), or \"from\" (add all Pt from this anchor base)\n */\n static anchor(\n pts: PtLikeIterable,\n ptOrIndex: PtLike | number = 0,\n direction: \"to\" | \"from\" = \"to\",\n ) {\n const method = direction == \"to\" ? \"subtract\" : \"add\";\n let i = 0;\n for (const p of pts) {\n if (typeof ptOrIndex == \"number\") {\n if (ptOrIndex !== i) (p as any)[method]((pts as any)[ptOrIndex]);\n } else {\n (p as any)[method](ptOrIndex);\n }\n i++;\n }\n }\n\n /**\n * Get an interpolated (or extrapolated) value between two Pts. For linear interpolation between 2 scalar values, use [`Num.lerp`](#link).\n * @param a first Pt\n * @param b second Pt\n * @param t a value between 0 to 1 to interpolate, or any other value to extrapolate\n * @returns interpolated point as a new Pt\n */\n static interpolate(a: PtLike, b: PtLike, t: number = 0.5): Pt {\n const len = Math.min(a.length, b.length);\n const d = Pt.make(len);\n for (let i = 0; i < len; i++) {\n d[i] = a[i] * (1 - t) + b[i] * t;\n }\n return d;\n }\n\n /**\n * Find two Pts that are perpendicular to this Pt (2D only).\n * @param axis a string such as \"xy\" (use Const.xy) or an array to specify index for two dimensions\n * @returns an array of two Pt that are perpendicular to this Pt\n */\n static perpendicular(pt: PtLike, axis: string | PtLike = Const.xy): Group {\n const y = axis[1];\n const x = axis[0];\n\n const p = new Pt(pt);\n const pa = new Pt(p);\n (pa as any)[x] = -(p as any)[y];\n (pa as any)[y] = (p as any)[x];\n const pb = new Pt(p);\n (pb as any)[x] = (p as any)[y];\n (pb as any)[y] = -(p as any)[x];\n\n return new Group(pa, pb);\n }\n\n /**\n * Check if two Pts are perpendicular to each other (2D only).\n */\n static isPerpendicular(p1: PtLike, p2: PtLike): boolean {\n // relative epsilon: |a·b| <= ε·|a|·|b| (zero vectors keep returning true)\n let dot = 0;\n let ma = 0;\n let mb = 0;\n for (let i = 0, len = Math.min(p1.length, p2.length); i < len; i++) {\n dot += p1[i] * p2[i];\n ma += p1[i] * p1[i];\n mb += p2[i] * p2[i];\n }\n return Math.abs(dot) <= Const.epsilon * Math.sqrt(ma * mb);\n }\n\n /**\n * Check if a Pt is within the rectangular boundary defined by two Pts.\n * @param pt the Pt to check\n * @param boundPt1 boundary Pt 1\n * @param boundPt2 boundary Pt 2\n */\n static withinBound(pt: PtLike, boundPt1: PtLike, boundPt2: PtLike): boolean {\n for (\n let i = 0, len = Math.min(pt.length, boundPt1.length, boundPt2.length);\n i < len;\n i++\n ) {\n if (!Num.within(pt[i], boundPt1[i], boundPt2[i])) return false;\n }\n return true;\n }\n\n /**\n * Sort the Pts so that their edges will form a non-overlapping polygon. ([Reference](https://stackoverflow.com/questions/6989100/sort-points-in-clockwise-order))\n * @param pts a Group or an Iterable<Pt>\n */\n static sortEdges(pts: PtIterable): GroupLike {\n const _pts = Util.iterToArray(pts);\n const bounds = Geom.boundingBox(_pts);\n const center = bounds[1].add(bounds[0]).divide(2);\n const cx = center[0];\n const cy = center[1];\n\n // same ordering as before, with scalar math instead of two Pt\n // allocations per comparison\n const fn = (a: Pt, b: Pt): number => {\n if (a.length < 2 || b.length < 2)\n throw new Error(\"Pt dimension cannot be less than 2\");\n\n const dax = a[0] - cx;\n const day = a[1] - cy;\n const dbx = b[0] - cx;\n const dby = b[1] - cy;\n\n if (dax >= 0 && dbx < 0) return 1;\n if (dax < 0 && dbx >= 0) return -1;\n if (dax == 0 && dbx == 0) {\n if (day >= 0 || dby >= 0) return day > dby ? 1 : -1;\n return dby > day ? 1 : -1;\n }\n\n // cross product of vectors (center -> a) x (center -> b)\n const det = dax * dby - day * dbx;\n if (det < 0) return 1;\n if (det > 0) return -1;\n\n // points a and b are on the same line from the center\n // check which point is closer to the center\n return dax * dax + day * day > dbx * dbx + dby * dby ? 1 : -1;\n };\n\n return _pts.sort(fn);\n }\n\n /**\n * Scale a Pt or a Group of Pts. You may also use [`Pt.scale`](#link) instance method.\n * @param ps either a single Pt, or a Group or an Iterable<Pt>\n * @param scale scale value\n * @param anchor optional anchor point to scale from\n */\n static scale(\n ps: Pt | PtIterable,\n scale: number | PtLike,\n anchor?: PtLike,\n ): Geom {\n const pts = Util.iterToArray(\n (ps as any)[0] !== undefined && typeof (ps as any)[0] == \"number\"\n ? [ps]\n : ps,\n );\n const scs =\n typeof scale == \"number\" ? Pt.make(pts[0].length, scale) : scale;\n if (!anchor) anchor = Pt.make(pts[0].length, 0);\n\n for (let i = 0, len = pts.length; i < len; i++) {\n const p = pts[i];\n for (let k = 0, lenP = p.length; k < lenP; k++) {\n p[k] =\n anchor && anchor[k]\n ? anchor[k] + (p[k] - anchor[k]) * scs[k]\n : p[k] * scs[k];\n }\n }\n\n return Geom;\n }\n\n /**\n * Rotate a Pt or a Group of Pts in 2D space. You may also use [`Pt.rotate2D`](#link) instance method.\n * @param ps either a single Pt, or a Group or an Iterable<Pt>\n * @param angle rotate angle\n * @param anchor optional anchor point to rotate from\n * @param axis optional axis such as \"xy\" (use Const.xy) to define a 2D plane, or a number array to specify indices\n */\n static rotate2D(\n ps: Pt | PtIterable,\n angle: number,\n anchor?: PtLike,\n axis?: string | PtLike,\n ): Geom {\n const pts = Util.iterToArray(\n (ps as any)[0] !== undefined && typeof (ps as any)[0] == \"number\"\n ? [ps]\n : ps,\n );\n const fn = anchor ? Mat.rotateAt2DMatrix : Mat.rotate2DMatrix;\n if (!anchor) anchor = Pt.make(pts[0].length, 0);\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n // the anchor is a fixed point of the rotation even when it aliases one\n // of the transformed points, so the matrix can be built once\n const mat = fn(cos, sin, anchor);\n\n for (let i = 0, len = pts.length; i < len; i++) {\n const p = axis ? pts[i].$take(axis) : pts[i];\n p.to(Mat.transform2D(p, mat));\n if (axis) {\n for (let k = 0; k < axis.length; k++) {\n pts[i][axis[k]] = p[k];\n }\n }\n }\n\n return Geom;\n }\n\n /**\n * Shear a Pt or a Group of Pts in 2D space. You may also use [`Pt.shear2D`](#link) instance method.\n * @param ps either a single Pt, or a Group or an Iterable<Pt>\n * @param scale shearing value which can be a number or an array of 2 numbers\n * @param anchor optional anchor point to shear from\n * @param axis optional axis such as \"xy\" (use Const.xy) to define a 2D plane, or a number array to specify indices\n */\n static shear2D(\n ps: Pt | PtIterable,\n scale: number | PtLike,\n anchor?: PtLike,\n axis?: string | PtLike,\n ): Geom {\n const pts = Util.iterToArray(\n (ps as any)[0] !== undefined && typeof (ps as any)[0] == \"number\"\n ? [ps]\n : ps,\n );\n const s = typeof scale == \"number\" ? [scale, scale] : scale;\n if (!anchor) anchor = Pt.make(pts[0].length, 0);\n const fn = anchor ? Mat.shearAt2DMatrix : Mat.shear2DMatrix;\n const tanx = Math.tan(s[0]);\n const tany = Math.tan(s[1]);\n // like rotate2D, the anchor is invariant under its own shear\n const mat = fn(tanx, tany, anchor);\n\n for (let i = 0, len = pts.length; i < len; i++) {\n const p = axis ? pts[i].$take(axis) : pts[i];\n p.to(Mat.transform2D(p, mat));\n if (axis) {\n for (let k = 0; k < axis.length; k++) {\n pts[i][axis[k]] = p[k];\n }\n }\n }\n\n return Geom;\n }\n\n /**\n * Reflect a Pt or a Group of Pts along a 2D line. You may also use [`Pt.reflect2D`](#link) instance method.\n * @param ps either a single Pt, or a Group or an Iterable<Pt>\n * @param line a Group or an Iterable<PtLike> that defines a line for reflection\n * @param axis optional axis such as \"xy\" (use Const.xy) to define a 2D plane, or a number array to specify indices\n */\n static reflect2D(\n ps: Pt | PtIterable,\n line: PtLikeIterable,\n axis?: string | PtLike,\n ): Geom {\n const pts = Util.iterToArray(\n (ps as any)[0] !== undefined && typeof (ps as any)[0] == \"number\"\n ? [ps]\n : ps,\n );\n const _line = Util.iterToArray(line);\n const mat = Mat.reflectAt2DMatrix(_line[0], _line[1]);\n\n for (let i = 0, len = pts.length; i < len; i++) {\n const p = axis ? pts[i].$take(axis) : pts[i];\n p.to(Mat.transform2D(p, mat));\n if (axis) {\n for (let k = 0; k < axis.length; k++) {\n pts[i][axis[k]] = p[k];\n }\n }\n }\n\n return Geom;\n }\n\n /**\n * Generate a cosine lookup table.\n * @returns an object with a cosine tables (array of 360 values) and a function to get cosine given a radian input.\n */\n static cosTable() {\n const cos = new Float64Array(360);\n\n for (let i = 0; i < 360; i++) cos[i] = Math.cos((i * Math.PI) / 180);\n const find = (rad: number) =>\n cos[Math.floor(Geom.boundAngle(Geom.toDegree(rad)))];\n\n return { table: cos, cos: find };\n }\n\n /**\n * Generate a sine lookup table.\n * @returns an object with a sine tables (array of 360 values) and a function to get sine value given a radian input.\n */\n static sinTable() {\n const sin = new Float64Array(360);\n\n for (let i = 0; i < 360; i++) sin[i] = Math.sin((i * Math.PI) / 180);\n const find = (rad: number) =>\n sin[Math.floor(Geom.boundAngle(Geom.toDegree(rad)))];\n\n return { table: sin, sin: find };\n }\n}\n\n/**\n * Shaping provides shaping functions to interpolate a value. These are useful for easing and transitions.\n */\nexport class Shaping {\n /**\n * Linear mapping.\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static linear(t: number, c: number = 1): number {\n return c * t;\n }\n\n /**\n * Quadratic in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static quadraticIn(t: number, c: number = 1): number {\n return c * t * t;\n }\n\n /**\n * Quadratic out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static quadraticOut(t: number, c: number = 1): number {\n return -c * t * (t - 2);\n }\n\n /**\n * Quadratic in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static quadraticInOut(t: number, c: number = 1): number {\n const dt = t * 2;\n return t < 0.5 ? (c / 2) * t * t * 4 : (-c / 2) * ((dt - 1) * (dt - 3) - 1);\n }\n\n /**\n * Cubic in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static cubicIn(t: number, c: number = 1): number {\n return c * t * t * t;\n }\n\n /**\n * Cubic out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static cubicOut(t: number, c: number = 1): number {\n const dt = t - 1;\n return c * (dt * dt * dt + 1);\n }\n\n /**\n * Cubic in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static cubicInOut(t: number, c: number = 1): number {\n const dt = t * 2;\n return t < 0.5\n ? (c / 2) * dt * dt * dt\n : (c / 2) * ((dt - 2) * (dt - 2) * (dt - 2) + 2);\n }\n\n /**\n * Exponential ease in, adapted from Golan Levin's [polynomial shapers](http://www.flong.com/texts/code/shapers_poly/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p a value between 0 to 1 to control the curve. Default is 0.25.\n */\n static exponentialIn(t: number, c: number = 1, p: number = 0.25): number {\n return c * Math.pow(t, 1 / p);\n }\n\n /**\n * Exponential ease out, adapted from Golan Levin's [polynomial shapers](http://www.flong.com/texts/code/shapers_poly/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p a value between 0 to 1 to control the curve. Default is 0.25.\n */\n static exponentialOut(t: number, c: number = 1, p: number = 0.25): number {\n return c * Math.pow(t, p);\n }\n\n /**\n * Sinuous in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static sineIn(t: number, c: number = 1): number {\n return -c * Math.cos(t * Const.half_pi) + c;\n }\n\n /**\n * Sinuous out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static sineOut(t: number, c: number = 1): number {\n return c * Math.sin(t * Const.half_pi);\n }\n\n /**\n * Sinuous in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static sineInOut(t: number, c: number = 1): number {\n return (-c / 2) * (Math.cos(Math.PI * t) - 1);\n }\n\n /**\n * A faster way to approximate cosine ease in-out using Blinn-Wyvill Approximation. Adapated from Golan Levin's [polynomial shaping](http://www.flong.com/texts/code/shapers_poly/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static cosineApprox(t: number, c: number = 1) {\n const t2 = t * t;\n const t4 = t2 * t2;\n const t6 = t4 * t2;\n return c * ((4 * t6) / 9 - (17 * t4) / 9 + (22 * t2) / 9);\n }\n\n /**\n * Circular in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static circularIn(t: number, c: number = 1): number {\n return -c * (Math.sqrt(1 - t * t) - 1);\n }\n\n /**\n * Circular out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static circularOut(t: number, c: number = 1): number {\n const dt = t - 1;\n return c * Math.sqrt(1 - dt * dt);\n }\n\n /**\n * Circular in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static circularInOut(t: number, c: number = 1): number {\n const dt = t * 2;\n return t < 0.5\n ? (-c / 2) * (Math.sqrt(1 - dt * dt) - 1)\n : (c / 2) * (Math.sqrt(1 - (dt - 2) * (dt - 2)) + 1);\n }\n\n /**\n * Elastic in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p elastic parmeter between 0 to 1. The lower the number, the more elastic it will be. Default is 0.7.\n */\n static elasticIn(t: number, c: number = 1, p: number = 0.7): number {\n const dt = t - 1;\n const s = (p / Const.two_pi) * 1.5707963267948966;\n return (\n c * (-Math.pow(2, 10 * dt) * Math.sin(((dt - s) * Const.two_pi) / p))\n );\n }\n\n /**\n * Elastic out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p elastic parmeter between 0 to 1. The lower the number, the more elastic it will be. Default is 0.7.\n */\n static elasticOut(t: number, c: number = 1, p: number = 0.7): number {\n const s = (p / Const.two_pi) * 1.5707963267948966;\n return (\n c * (Math.pow(2, -10 * t) * Math.sin(((t - s) * Const.two_pi) / p)) + c\n );\n }\n\n /**\n * Elastic in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p elastic parmeter between 0 to 1. The lower the number, the more elastic it will be. Default is 0.6.\n */\n static elasticInOut(t: number, c: number = 1, p: number = 0.6): number {\n let dt = t * 2;\n const s = (p / Const.two_pi) * 1.5707963267948966;\n if (t < 0.5) {\n dt -= 1;\n return (\n c *\n (-0.5 *\n (Math.pow(2, 10 * dt) * Math.sin(((dt - s) * Const.two_pi) / p)))\n );\n } else {\n dt -= 1;\n return (\n c *\n (0.5 *\n (Math.pow(2, -10 * dt) * Math.sin(((dt - s) * Const.two_pi) / p))) +\n c\n );\n }\n }\n\n /**\n * Bounce in, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static bounceIn(t: number, c: number = 1): number {\n return c - Shaping.bounceOut(1 - t, c);\n }\n\n /**\n * Bounce out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static bounceOut(t: number, c: number = 1) {\n if (t < 1 / 2.75) {\n return c * (7.5625 * t * t);\n } else if (t < 2 / 2.75) {\n t -= 1.5 / 2.75;\n return c * (7.5625 * t * t + 0.75);\n } else if (t < 2.5 / 2.75) {\n t -= 2.25 / 2.75;\n return c * (7.5625 * t * t + 0.9375);\n } else {\n t -= 2.625 / 2.75;\n return c * (7.5625 * t * t + 0.984375);\n }\n }\n\n /**\n * Bounce in-out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n */\n static bounceInOut(t: number, c: number = 1): number {\n return t < 0.5\n ? Shaping.bounceIn(t * 2, c) / 2\n : Shaping.bounceOut(t * 2 - 1, c) / 2 + c / 2;\n }\n\n /**\n * Sigmoid curve changes its shape adapted from the input value, but always returns a value between 0 to 1.\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p the larger the value, the \"steeper\" the curve will be. Default is 10.\n */\n static sigmoid(t: number, c: number = 1, p: number = 10): number {\n const d = p * (t - 0.5);\n return c / (1 + Math.exp(-d));\n }\n\n /**\n * Logistic sigmoid, adapted from Golan Levin's [shaping function](http://www.flong.com/texts/code/shapers_exp/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p a parameter between 0 to 1 to control the steepness of the curve. Higher is steeper. Default is 0.7.\n */\n static logSigmoid(t: number, c: number = 1, p: number = 0.7): number {\n p = Math.max(Const.epsilon, Math.min(1 - Const.epsilon, p));\n p = 1 / (1 - p);\n\n const A = 1 / (1 + Math.exp((t - 0.5) * p * -2));\n const B = 1 / (1 + Math.exp(p));\n const C = 1 / (1 + Math.exp(-p));\n return (c * (A - B)) / (C - B);\n }\n\n /**\n * Exponential seat curve, adapted from Golan Levin's [shaping functions](http://www.flong.com/texts/code/shapers_exp/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p a parameter between 0 to 1 to control the steepness of the curve. Higher is steeper. Default is 0.5.\n */\n static seat(t: number, c: number = 1, p: number = 0.5): number {\n if (t < 0.5) {\n return (c * Math.pow(2 * t, 1 - p)) / 2;\n } else {\n return c * (1 - Math.pow(2 * (1 - t), 1 - p) / 2);\n }\n }\n\n /**\n * Quadratic bezier curve, adapted from Golan Levin's [shaping functions](http://www.flong.com/texts/code/shapers_exp/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p a Pt object specifying the control Pt, or a value specifying its x position (its y position will default to 0.5). Default is `[0.05, 0.95]`.\n */\n static quadraticBezier(\n t: number,\n c: number = 1,\n p: number | PtLike = [0.05, 0.95],\n ): number {\n const a: number = typeof p != \"number\" ? p[0] : p;\n const b: number = typeof p != \"number\" ? p[1] : 0.5;\n let om2a = 1 - 2 * a;\n if (om2a === 0) {\n om2a = Const.epsilon;\n }\n const d = (Math.sqrt(a * a + om2a * t) - a) / om2a;\n return c * ((1 - 2 * b) * (d * d) + 2 * b * d);\n }\n\n /**\n * Cubic bezier curve. This reuses the bezier functions in Curve class. Note that `t` is the curve parameter, not the x position: unlike CSS `cubic-bezier(...)`, this returns the curve's y value at parameter `t` rather than solving y at x = t.\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p1` a Pt object specifying the first control Pt. Default is `Pt(0.1, 0.7).\n * @param p2` a Pt object specifying the second control Pt. Default is `Pt(0.9, 0.2).\n */\n static cubicBezier(\n t: number,\n c: number = 1,\n p1: PtLike = [0.1, 0.7],\n p2: PtLike = [0.9, 0.2],\n ): number {\n const curve = new Group(new Pt(0, 0), new Pt(p1), new Pt(p2), new Pt(1, 1));\n return (\n c *\n Curve.bezierStep(\n new Pt(t * t * t, t * t, t, 1),\n Curve.controlPoints(curve),\n ).y\n );\n }\n\n /**\n * Give a Pt, draw a quadratic curve that will pass through that Pt as closely as possible. Adapted from Golan Levin's [shaping functions](http://www.flong.com/texts/code/shapers_poly/).\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p1` a Pt object specifying the Pt to pass through. Default is `Pt(0.2, 0.35)\n */\n static quadraticTarget(\n t: number,\n c: number = 1,\n p1: PtLike = [0.2, 0.35],\n ): number {\n const a = Math.min(1 - Const.epsilon, Math.max(Const.epsilon, p1[0]));\n const b = Math.min(1, Math.max(0, p1[1]));\n const A = (1 - b) / (1 - a) - b / a;\n const B = (A * (a * a) - b) / a;\n const y = A * (t * t) - B * t;\n return c * Math.min(1, Math.max(0, y));\n }\n\n /**\n * Step function is a simple jump from 0 to 1 at a specific Pt in time.\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param p usually a value between 0 to 1, which specify the Pt to \"jump\". Default is 0.5 which is in the middle.\n */\n static cliff(t: number, c: number = 1, p: number = 0.5): number {\n return t > p ? c : 0;\n }\n\n /**\n * Convert any shaping functions into a series of steps.\n * @param fn the original shaping function\n * @param steps the number of steps\n * @param t a value between 0 to 1\n * @param c the value to shape, default is 1\n * @param args optional paramters to pass to original function\n */\n static step(\n fn: (t: number, c: number, ...args: any[]) => number,\n steps: number,\n t: number,\n c: number,\n ...args: any[]\n ) {\n const s = 1 / steps;\n const tt = Math.floor(t / s) * s;\n return fn(tt, c, ...args);\n }\n}\n\n/**\n * Range object keeps track of a Group of n-dimensional Pts to provide its minimum, maximum, and magnitude in each dimension.\n * It also provides convenient functions such as mapping the Group to another range. This class may be useful for visualizing data in charts.\n */\nexport class Range {\n protected _source: Group;\n protected _max!: Pt;\n protected _min!: Pt;\n protected _mag!: Pt;\n protected _dims: number = 0;\n\n /**\n * Construct a Range instance for a Group of Pts.\n * @param g a Group or an Iterable<Pt>\n */\n constructor(g: PtIterable) {\n this._source = Group.fromPtArray(g);\n this.calc();\n }\n\n /**\n * Get this Range's maximum values per dimension.\n */\n get max(): Pt {\n return this._max.clone();\n }\n\n /**\n * Get this Range's minimum values per dimension.\n */\n get min(): Pt {\n return this._min.clone();\n }\n\n /**\n * Get this Range's magnitude in each dimension.\n */\n get magnitude(): Pt {\n return this._mag.clone();\n }\n\n /**\n * Go through the group and find its min and max values. Usually you don't need to call this function directly.\n */\n calc(): this | undefined {\n if (!this._source) return;\n const dims = this._source[0].length;\n this._dims = dims;\n const max = new Pt(dims);\n const min = new Pt(dims);\n const mag = new Pt(dims);\n\n for (let i = 0; i < dims; i++) {\n // Infinity, not MAX_VALUE/MIN_VALUE: MIN_VALUE is the smallest positive\n // double (flushes to 0 in the Float32 Pt), which would cap the maximum\n // of all-negative data at 0\n max[i] = -Infinity;\n min[i] = Infinity;\n mag[i] = 0;\n\n const s = this._source.zipSlice(i);\n for (let k = 0, len = s.length; k < len; k++) {\n max[i] = Math.max(max[i], s[k]);\n min[i] = Math.min(min[i], s[k]);\n mag[i] = max[i] - min[i];\n }\n }\n\n this._max = max;\n this._min = min;\n this._mag = mag;\n return this;\n }\n\n /**\n * Map this Range to another range of values.\n * @param min target range's minimum value\n * @param max target range's maximum value\n * @param exclude Optional boolean array where `true` means excluding the conversion in that specific dimension.\n */\n mapTo(min: number, max: number, exclude?: boolean[]): Group {\n const target = new Group();\n for (let i = 0, len = this._source.length; i < len; i++) {\n const g = this._source[i];\n const n = new Pt(this._dims);\n for (let k = 0; k < this._dims; k++) {\n n[k] =\n exclude && exclude[k]\n ? g[k]\n : Num.mapToRange(g[k], this._min[k], this._max[k], min, max);\n }\n target.push(n);\n }\n return target;\n }\n\n /**\n * Add more Pts to this Range and recalculate its min and max values.\n * @param pts a Group or an Iterable<PtLike> to append to this Range\n * @param update Optional. Set the parameter to `false` if you want to append without immediately updating this Range's min and max values. Default is `true`.\n */\n append(pts: PtLikeIterable, update: boolean = true): this {\n const _pts = Util.iterToArray(pts);\n if (_pts[0].length !== this._dims)\n throw new Error(\n `Dimensions don't match. ${this._dims} dimensions in Range and ${_pts[0].length} provided in parameter. `,\n );\n this._source = this._source.concat(_pts) as Group;\n if (update) this.calc();\n return this;\n }\n\n /**\n * Create a number of evenly spaced \"ticks\" that span this Range's min and max value.\n * @param count number of subdivision. For example, 10 subdivision will return 11 tick values, which include first(min) and last(max) values.\n */\n ticks(count: number): Group {\n const g = new Group();\n for (let i = 0; i <= count; i++) {\n const p = new Pt(this._dims);\n const t = count > 0 ? i / count : 0;\n for (let k = 0, len = this._max.length; k < len; k++) {\n p[k] = Num.lerp(this._min[k], this._max[k], t);\n }\n g.push(p);\n }\n return g;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport type { CanvasSpace } from \"./Canvas\";\nimport { Num } from \"./Num\";\nimport { Group, Pt } from \"./Pt\";\nimport { type WarningType, type PtLike, type PtLikeIterable } from \"./Types\";\n\n/**\n * Various constant values for enumerations and calculations.\n */\nexport const Const = {\n /** A string to indicate xy plane. */\n xy: \"xy\",\n\n /** A string to indicate yz plane. */\n yz: \"yz\",\n\n /** A string to indicate xz plane. */\n xz: \"xz\",\n\n /** A string to indicate xyz space. */\n xyz: \"xyz\",\n\n /** Represents horizontal direction. */\n horizontal: 0,\n\n /** Represents vertical direction. */\n vertical: 1,\n\n /** Represents identical point or value */\n identical: 0,\n\n /** Represents right position or direction */\n right: 4,\n\n /** Represents bottom right position or direction */\n bottom_right: 5,\n\n /** Represents bottom position or direction */\n bottom: 6,\n\n /** Represents bottom left position or direction */\n bottom_left: 7,\n\n /** Represents left position or direction */\n left: 8,\n\n /** Represents top left position or direction */\n top_left: 1,\n\n /** Represents top position or direction */\n top: 2,\n\n /** Represents top right position or direction */\n top_right: 3,\n\n /** Represents an arbitrary very small number. It is set as 0.0001 here. */\n epsilon: 0.0001,\n\n /** Represents Number.MAX_VALUE. Note: as a Float32 Pt value this overflows to Infinity. */\n max: Number.MAX_VALUE,\n\n /** Represents Number.MIN_VALUE, the smallest *positive* number (5e-324) — not the most negative number. Do not use it to initialize a running maximum; use -Infinity instead. As a Float32 Pt value this flushes to 0. */\n min: Number.MIN_VALUE,\n\n /** π radian (180 deg) */\n pi: Math.PI,\n\n /** Two π radian (360deg) */\n two_pi: 6.283185307179586,\n\n /** Half π radian (90deg) */\n half_pi: 1.5707963267948966,\n\n /** π/4 radian (45deg) */\n quarter_pi: 0.7853981633974483,\n\n /** π/180 or 1 degree in radian */\n one_degree: 0.017453292519943295,\n\n /** Multiply this constant with a radian to get a degree */\n rad_to_deg: 57.29577951308232,\n\n /** Multiply this constant with a degree to get a radian */\n deg_to_rad: 0.017453292519943295,\n\n /** Gravity acceleration (unit: m/s^2) and gravity force (unit: Newton) on 1kg of mass. */\n gravity: 9.81,\n\n /** 1 Newton: 0.10197 Kilogram-force */\n newton: 0.10197,\n\n /** Gaussian constant (1 / Math.sqrt(2 * Math.PI)) */\n gaussian: 0.3989422804014327,\n};\n\n/**\n * Util class provides static helper functions.\n */\nexport class Util {\n static _warnLevel: WarningType = \"mute\";\n\n /**\n * Set a global warning level setting. If no parameter is passed, this will return the current warn-level. See [`Util.warn`](#link).\n * @param lv a [`WarningType`](#link) option, where \"error\" will throw an error, \"warn\" will log in console, and \"mute\" will ignore the error.\n */\n static warnLevel(lv?: WarningType): WarningType {\n if (lv) {\n Util._warnLevel = lv;\n }\n return Util._warnLevel;\n }\n\n /**\n * Convert different kinds of parameters (arguments, array, object) into an array of numbers.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n static getArgs(args: any[]): Array<number> {\n if (args.length < 1) return [];\n\n let pos = [];\n\n let isArray = Array.isArray(args[0]) || ArrayBuffer.isView(args[0]);\n\n // positional arguments: x,y,z,w,...\n if (typeof args[0] === \"number\") {\n pos = Array.prototype.slice.call(args);\n\n // as an object of {x, y?, z?, w?}\n } else if (typeof args[0] === \"object\" && !isArray) {\n let a = [\"x\", \"y\", \"z\", \"w\"];\n let p = args[0];\n for (let i = 0; i < a.length; i++) {\n if ((p.length && i >= p.length) || !(a[i] in p)) break; // check for length and key exist\n pos.push(p[a[i]]);\n }\n\n // as an array of values\n } else if (isArray) {\n pos = Util.toNumericArray(args[0]);\n }\n\n return pos;\n }\n\n /**\n * Copy an array or typed array of numbers into a fresh plain array.\n * @param a an array or typed array\n */\n static toNumericArray(a: ArrayLike<number>): number[] {\n // native slice is a fast path for plain arrays, but `[].slice.call` on a\n // typed array falls back to the generic per-element protocol\n if (Array.isArray(a)) return a.slice();\n const out = [];\n for (let i = 0, len = a.length; i < len; i++) {\n out.push(a[i]);\n }\n return out;\n }\n\n /**\n * Like [`Util.getArgs`](#link), but avoids copying when the arguments are already\n * a numeric array, a typed array (eg, a Pt), or a list of numbers. The result may be\n * the caller's own object, so it must be treated as read-only.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n static getPtLike(args: any[]): PtLike {\n const a0 = args[0];\n if (typeof a0 === \"number\") return args; // rest args are a fresh, private array\n if (args.length === 1 && (Array.isArray(a0) || ArrayBuffer.isView(a0))) {\n return a0 as PtLike;\n }\n return Util.getArgs(args);\n }\n\n /**\n * Send a warning message based on [`Util.warnLevel`](#link) global setting. This allows you to dynamically set whether minor errors should be thrown or printed in console or muted.\n * @param message any error or warning message\n * @param defaultReturn optional return value\n */\n static warn(message: string = \"error\", defaultReturn: any = undefined): any {\n if (Util.warnLevel() == \"error\") {\n throw new Error(message);\n } else if (Util.warnLevel() == \"warn\") {\n console.warn(message);\n }\n return defaultReturn;\n }\n\n /**\n * Get a random integer. This can be useful for selecting a random index in an array.\n * @deprecated Use [`Num.randomRange`](#link) instead, for example `Math.floor( Num.randomRange( start, start + range ) )`.\n * @param range value range\n * @param start Optional starting value\n */\n static randomInt(range: number, start: number = 0) {\n Util.warn(\"Util.randomInt is deprecated. Please use `Num.randomRange`\");\n return Math.floor(Num.random() * range) + start;\n }\n\n /**\n * Split an array into chunks of sub-array.\n * @param pts an array\n * @param size chunk size, ie, number of items in a chunk\n * @param stride optional parameter to \"walk through\" the array in steps\n * @param loopBack if `true`, always go through the array till the end and loop back to the beginning to complete the segments if needed.\n * @param matchSize if `true`, all chunks's length must match `size`.\n */\n static split(\n pts: any[],\n size: number,\n stride?: number,\n loopBack: boolean = false,\n matchSize = true,\n ): any[][] {\n let chunks: any[] = [];\n let part: any[] = [];\n let st: number = stride || size;\n let index: number = 0;\n if (pts.length <= 0 || st <= 0) return [];\n\n while (index < pts.length) {\n part = [];\n for (let k = 0; k < size; k++) {\n if (loopBack) {\n part.push(pts[(index + k) % pts.length]);\n } else {\n if (index + k >= pts.length) break;\n part.push(pts[index + k]);\n }\n }\n index += st;\n if (!matchSize || (matchSize && part.length === size)) chunks.push(part);\n }\n\n return chunks;\n }\n\n /**\n * Flatten an array of arrays such as Group[] to a flat Array or Group.\n * @param pts an array, usually an array of Groups\n * @param flattenAsGroup a boolean to specify whether the return type should be a Group or Array. Default is `true` which returns a Group.\n */\n static flatten(pts: any[], flattenAsGroup: boolean = true): any {\n // loop instead of concat.apply: spreading `pts` as arguments overflows\n // the JS argument-count limit for very large inputs\n const arr: unknown[] = flattenAsGroup ? new Group() : [];\n for (let i = 0, len = pts.length; i < len; i++) {\n const p = pts[i];\n if (Array.isArray(p)) {\n for (let k = 0, lenP = p.length; k < lenP; k++) arr.push(p[k]);\n } else {\n arr.push(p);\n }\n }\n return arr;\n }\n\n /**\n * Given two arrays of objects, and a function that operate on two objects, return an array. Objects must be of same type.\n * @param a an array of object, eg `[Group, Group, ...]`\n * @param b another array of object\n * @param op a function that takes two parameters (a, b) and returns an object.\n */\n static combine<T>(a: T[], b: T[], op: (a: T, b: T) => T): T[] {\n let result = [];\n for (let i = 0, len = a.length; i < len; i++) {\n for (let k = 0, lenB = b.length; k < lenB; k++) {\n result.push(op(a[i], b[k]));\n }\n }\n return result;\n }\n\n /**\n * Zip arrays. eg, `[[1,2],[3,4],[5,6]] => [[1,3,5],[2,4,6]]`.\n * @param arrays an array of arrays\n */\n static zip(arrays: Array<any>[]) {\n let z = [];\n for (let i = 0, len = arrays[0].length; i < len; i++) {\n let p = [];\n for (let k = 0; k < arrays.length; k++) {\n p.push(arrays[k][i]);\n }\n z.push(p);\n }\n return z;\n }\n\n /**\n * Create a convenient stepper. This returns a function which you can call repeatedly to step a counter.\n * @param max Maximum of the stepper range. The resulting stepper will return values within [min, max). Note that the first call returns `min + stride`, not `min`.\n * @param min Minimum of the stepper range. Default is 0.\n * @param stride Stride of the step. Default is 1.\n * @param callback An optional callback function `fn( step )`, which will be called each time when stepper function is called.\n * @example `let counter = stepper(100); let c = counter(); c = counter(); ...`\n * @returns a function which will increment the stepper and return its value at each call.\n */\n static stepper(\n max: number,\n min: number = 0,\n stride: number = 1,\n callback?: (n: number) => void,\n ): () => number {\n let c = min;\n return function () {\n c += stride;\n if (c >= max) {\n // anchored modulo keeps c in [min, max) even when stride > max - min\n c = min + ((c - min) % (max - min));\n }\n if (callback) callback(c);\n return c;\n };\n }\n\n /**\n * A convenient way to step through a range. Same as `for (i=0; i<range; i++)`, except this also stores the resulting return values at each step and return them as an array.\n * @param range a range to step through\n * @param fn a callback function `fn(index)`. If this function returns a value, it will be stored at each step\n * @returns an index-aligned array of returned values: entries sit at their step index, so with a non-zero `start` the positions below `start` are empty holes\n */\n static forRange(\n fn: (index: number) => any,\n range: number,\n start: number = 0,\n step: number = 1,\n ): any[] {\n let temp = [];\n for (let i = start, len = range; i < len; i += step) {\n temp[i] = fn(i);\n }\n return temp;\n }\n\n /**\n * A helper function to load data from a url via XMLHttpRequest GET. Since the response passed into callback is a string, if you're loading json data, you may use standard `JSON.parse(response)` to get a JSON object. For csv, try using a javascript csv library like papaparse or vega/datalib.\n * @param url the request url\n * @param callback a function to capture the data. It receives two parameters: a `response` as string, and a `success` status as boolean.\n */\n static load(\n url: string,\n callback: (response: string, success: boolean) => void,\n ) {\n let request = new XMLHttpRequest();\n request.open(\"GET\", url, true);\n\n request.onload = function () {\n if (request.status >= 200 && request.status < 400) {\n callback(request.responseText, true);\n } else {\n callback(\n `Server error (${request.status}) when loading \"${url}\"`,\n false,\n );\n }\n };\n\n request.onerror = function () {\n callback(`Unknown network error`, false);\n };\n\n request.send();\n }\n\n /**\n * Download the current `CanvasSpace` as an image (jpg/png/webp). Calling this function will automatically trigger a download.\n * @param space an instance of `CanvasSpace`\n * @param filename the name of the file, without the extension name.\n * @param filetype the image type (jpg/png/webp)\n * @param quality a value between 0 to 1, if filetype is either \"jpg\" or \"png\"\n */\n static download(\n space: CanvasSpace,\n filename: string = \"pts_canvas_image\",\n filetype: \"jpeg\" | \"jpg\" | \"png\" | \"webp\" = \"png\",\n quality: number = 1,\n ) {\n const ftype = filetype === \"jpg\" ? \"jpeg\" : filetype;\n space.element.toBlob(\n function (blob) {\n const link = document.createElement(\"a\");\n // toBlob yields null on encoding failure; createObjectURL then throws\n // a TypeError, same as it always has — kept, not silently swallowed\n const url = URL.createObjectURL(blob!);\n link.href = url;\n link.download = `${filename}.${filetype}`;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n },\n `image/${ftype}`,\n quality,\n );\n }\n\n /**\n * Estimate performance by checking how long it takes to render a frame\n * @param avgFrames The number of frames used calculate to average\n * @example `let perf = Util.performance(); perf();`\n * @returns milliseconds per frame\n */\n static performance(avgFrames: number = 10): () => number {\n let last = Date.now();\n let avg = [];\n return function () {\n const now = Date.now();\n avg.push(now - last);\n if (avg.length > avgFrames) avg.shift();\n last = now;\n return Math.floor(avg.reduce((a, b) => a + b, 0) / avg.length);\n };\n }\n\n /**\n * Check number of items in a Group against a required number\n * @param pts a Group or an Iterable<PtLike>\n * @param minRequired minimum number of items required\n */\n static arrayCheck(pts: PtLikeIterable, minRequired: number = 2): boolean {\n if (Array.isArray(pts) && pts.length < minRequired) {\n Util.warn(`Requires ${minRequired} or more Pts in this Group.`);\n return false;\n }\n return true;\n }\n\n /**\n * Convert an iterable into an array\n * @param it an iterable\n */\n static iterToArray(it: Iterable<any>): any[] {\n return !Array.isArray(it) ? [...it] : it;\n }\n\n /**\n * Check if accessing from a mobile device. Can be useful since some experimental features may not be availble in mobile browsers.\n */\n static isMobile() {\n return /iPhone|iPad|Android/i.test(navigator.userAgent);\n }\n\n /**\n * Generate a time-based unique ID or a crypto-based ID.\n * @returns\n */\n static uniqueId(useCrypto = false) {\n return useCrypto && typeof crypto !== \"undefined\" && crypto?.randomUUID\n ? crypto.randomUUID()\n : Date.now().toString(36) + Math.random().toString(36).substring(2);\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Util, Const } from \"./Util\";\nimport { Geom, Num } from \"./Num\";\nimport { Vec, Mat } from \"./LinearAlgebra\";\nimport {\n type IPt,\n type GroupLike,\n type PtLike,\n type PtIterable,\n type PtLikeIterable,\n} from \"./Types\";\n\n/**\n * Pt is a subclass of standard [`Float32Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array) with additional properties and functions to support vector and geometric calculations.\n * See [Pt guide](../guide/Pt-0200.html) for details.\n */\nexport class Pt extends Float32Array implements IPt, Iterable<number> {\n protected _id!: string;\n\n /**\n * Create a Pt. If no parameter is provided, this will instantiate a Pt with 2 dimensions [0, 0].\n * Note that `new Pt(3)` will only instantiate Pt with length of 3 (ie, same as `new Float32Array(3)` ). If you need a Pt with 1 dimension of value 3, use `new Pt([3])`.\n * @example `new Pt()`, `new Pt(1,2,3,4,5)`, `new Pt([1,2])`, `new Pt({x:0, y:1})`, `new Pt(pt)`\n * @param args a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n constructor(...args: Array<number | number[] | IPt | Float32Array>) {\n // each branch below produces a valid Float32Array constructor argument\n let params: any;\n const a0 = args[0];\n if (args.length === 1 && typeof a0 == \"number\") {\n params = a0; // init with the TypedArray's length. Needed this in order to make \".map\", \".slice\" etc work.\n } else if (args.length === 0) {\n params = 2; // default is [0, 0]\n } else if (\n args.length === 1 &&\n (Array.isArray(a0) || ArrayBuffer.isView(a0))\n ) {\n params = a0; // the Float32Array constructor copies array-likes natively\n } else if (typeof a0 === \"number\") {\n params = args; // a list of numbers; rest args are already a fresh array\n } else {\n params = Util.getArgs(args);\n }\n super(params);\n }\n\n /**\n * Create an n-dimensional Pt with either default value or random values.\n * @param dimensions number of dimensions\n * @param defaultValue optional default value to fill the dimensions\n * @param randomize if `true`, randomize the value between 0 to default value\n */\n static make(\n dimensions: number,\n defaultValue: number = 0,\n randomize: boolean = false,\n ): Pt {\n const p = new Pt(dimensions);\n if (defaultValue) p.fill(defaultValue);\n if (randomize) {\n for (let i = 0, len = p.length; i < len; i++) {\n p[i] = p[i] * Num.random();\n }\n }\n return p;\n }\n\n /**\n * ID string of this Pt\n */\n get id(): string {\n return this._id;\n }\n set id(s: string) {\n this._id = s;\n }\n\n /**\n * Value in the first dimensional of this Pt\n */\n get x(): number {\n return this[0];\n }\n set x(n: number) {\n this[0] = n;\n }\n\n /**\n * Value in the second dimension of this Pt\n */\n get y(): number {\n return this[1];\n }\n set y(n: number) {\n this[1] = n;\n }\n\n /**\n * Value in the third dimension of this Pt\n */\n get z(): number {\n return this[2];\n }\n set z(n: number) {\n this[2] = n;\n }\n\n /**\n * Value in the forth dimension of this Pt\n */\n get w(): number {\n return this[3];\n }\n set w(n: number) {\n this[3] = n;\n }\n\n /**\n * Clone this Pt and return it as a new Pt.\n */\n clone(): Pt {\n return new Pt(this);\n }\n\n /**\n * Check if another Pt is equal to this Pt, within a threshold. Every dimension of this Pt must be matched: a shorter Pt, or one with a NaN dimension, is not equal (following IEEE semantics, NaN never equals NaN).\n * @param p another Pt to compare with\n * @param threshold a threshold value within which the two Pts are considered equal. Default is 0.000001.\n */\n equals(p: PtLike, threshold = 0.000001): boolean {\n for (let i = 0, len = this.length; i < len; i++) {\n // written so that a missing or NaN dimension fails the comparison\n if (!(Math.abs(this[i] - p[i]) <= threshold)) return false;\n }\n return true;\n }\n\n /**\n * Update the values of this Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n to(...args: any[]): this {\n const p = Util.getPtLike(args);\n for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {\n this[i] = p[i];\n }\n return this;\n }\n\n /**\n * Like [`Pt.to`](#link) but returns a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $to(...args: any[]): Pt {\n return this.clone().to(...args);\n }\n\n /**\n * Update the values of this Pt to point at a specific angle.\n * @param radian target angle in radian\n * @param magnitude Optional magnitude if known. If not provided, it'll calculate and use this Pt's magnitude.\n * @param anchorFromPt If `true`, add it from this Pt's current position. Default is `false` which update the position from origin (0,0). See also [`Geom.rotate2D`](#link) for rotating a point from another anchor point.\n */\n toAngle(\n radian: number,\n magnitude?: number,\n anchorFromPt: boolean = false,\n ): this {\n const m = magnitude != undefined ? magnitude : this.magnitude();\n const change = [Math.cos(radian) * m, Math.sin(radian) * m];\n return anchorFromPt ? this.add(change) : this.to(change);\n }\n\n /**\n * Create an operation using this Pt, passing this Pt into a custom function's first parameter. See the [Op guide](../guide/Op-0400.html) for details.\n * @param fn any function that takes a Pt as its first parameter\n * @example `let myOp = pt.op( fn ); let result = myOp( [1,2,3] );`\n * @returns a resulting function that takes other parameters required in `fn`\n */\n op(fn: (p1: PtLike, ...rest: any[]) => any): (...rest: any[]) => any {\n const self = this;\n return (...params: any[]) => {\n return fn(self, ...params);\n };\n }\n\n /**\n * This combines a series of operations into an array. See the [Op guide](../guide/Op-0400.html) for details.\n * @param fns an array of functions for `op`\n * @example `let myOps = pt.ops([fn1, fn2, fn3]); let results = myOps.map( (op) => op([1,2,3]) );`\n * @returns an array of resulting functions\n */\n ops(\n fns: ((p1: PtLike, ...rest: any[]) => any)[],\n ): ((...rest: any[]) => any)[] {\n const _ops = [];\n for (let i = 0, len = fns.length; i < len; i++) {\n _ops.push(this.op(fns[i]));\n }\n return _ops;\n }\n\n /**\n * Take specific dimensional values from this Pt and create a new Pt.\n * @param axis a string such as \"xy\" (use Const.xy) or an array to specify indices\n */\n $take(axis: string | number[]): Pt {\n const p = [];\n for (let i = 0, len = axis.length; i < len; i++) {\n p.push((this as any)[axis[i]] || 0);\n }\n return new Pt(p);\n }\n\n /**\n * Concatenate this Pt with addition dimensional values and return as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $concat(...args: any[]): Pt {\n return new Pt(this.toArray().concat(Util.getArgs(args)));\n }\n\n /**\n * Add scalar or vector values to this Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n add(...args: any[]): this {\n args.length === 1 && typeof args[0] == \"number\"\n ? Vec.add(this, args[0])\n : Vec.add(this, Util.getPtLike(args));\n return this;\n }\n\n /**\n * Like [`Pt.add`](#link), but returns result as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $add(...args: any[]): Pt {\n return this.clone().add(...args);\n }\n\n /**\n * Subtract scalar or vector values from this Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n subtract(...args: any[]): this {\n args.length === 1 && typeof args[0] == \"number\"\n ? Vec.subtract(this, args[0])\n : Vec.subtract(this, Util.getPtLike(args));\n return this;\n }\n\n /**\n * Like [`Pt.subtract`](#link), but returns result as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $subtract(...args: any[]): Pt {\n return this.clone().subtract(...args);\n }\n\n /**\n * Multiply scalar or vector values (as element-wise) with this Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n multiply(...args: any[]): this {\n args.length === 1 && typeof args[0] == \"number\"\n ? Vec.multiply(this, args[0])\n : Vec.multiply(this, Util.getPtLike(args));\n return this;\n }\n\n /**\n * Like [`Pt.multiply`](#link), but returns result as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $multiply(...args: any[]): Pt {\n return this.clone().multiply(...args);\n }\n\n /**\n * Divide this Pt over scalar or vector values (as element-wise).\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n divide(...args: any[]): this {\n args.length === 1 && typeof args[0] == \"number\"\n ? Vec.divide(this, args[0])\n : Vec.divide(this, Util.getPtLike(args));\n return this;\n }\n\n /**\n * Like [`Pt.divide`](#link), but returns result as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $divide(...args: any[]): Pt {\n return this.clone().divide(...args);\n }\n\n /**\n * Get the squared distance (magnitude) of this Pt from origin.\n */\n magnitudeSq(): number {\n return Vec.dot(this, this);\n }\n\n /**\n * Get the distance (magnitude) of this Pt from origin.\n */\n magnitude(): number {\n return Vec.magnitude(this);\n }\n\n /**\n * Convert to a unit vector, which is a normalized vector whose magnitude equals to 1.\n * @param magnitude Optional: if the magnitude is known, pass it as a parameter to avoid duplicate calculation.\n */\n unit(magnitude: number | undefined = undefined): Pt {\n Vec.unit(this, magnitude);\n return this;\n }\n\n /**\n * Get a new unit vector from this Pt.\n */\n $unit(magnitude: number | undefined = undefined): Pt {\n return this.clone().unit(magnitude);\n }\n\n /**\n * Dot product of this Pt and another Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n dot(...args: any[]): number {\n return Vec.dot(this, Util.getPtLike(args));\n }\n\n /**\n * 2D Cross product of this Pt and another Pt. Return results as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $cross2D(...args: any[]): number {\n return Vec.cross2D(this, Util.getPtLike(args));\n }\n\n /**\n * 3D Cross product of this Pt and another Pt. Return results as a new Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $cross(...args: any[]): Pt {\n return Vec.cross(this, Util.getPtLike(args));\n }\n\n /**\n * Calculate the vector projection of another Pt onto this Pt — ie, the component of the other Pt along this Pt's direction. Note that this Pt must be non-zero.\n * @param args the other Pt, as either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n * @returns the projection vector as a Pt\n */\n $project(...args: any[]): Pt {\n return this.$multiply(this.dot(...args) / this.magnitudeSq());\n }\n\n /**\n * Calculate the scalar projection of another Pt onto this Pt — the signed length of the other Pt's component along this Pt's direction. Note that this Pt must be non-zero.\n * @param args the other Pt, as either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n projectScalar(...args: any[]): number {\n return this.dot(...args) / this.magnitude();\n }\n\n /**\n * Absolute values for all values in this pt.\n */\n abs(): Pt {\n Vec.abs(this);\n return this;\n }\n\n /**\n * Get a new Pt with absolute values of this Pt.\n */\n $abs(): Pt {\n return this.clone().abs();\n }\n\n /**\n * Floor values for all values in this Pt.\n */\n floor(): Pt {\n Vec.floor(this);\n return this;\n }\n\n /**\n * Get a new Pt with floor values of this Pt.\n */\n $floor(): Pt {\n return this.clone().floor();\n }\n\n /**\n * Ceiling values for all values in this Pt.\n */\n ceil(): Pt {\n Vec.ceil(this);\n return this;\n }\n\n /**\n * Get a new Pt with ceiling values of this Pt.\n */\n $ceil(): Pt {\n return this.clone().ceil();\n }\n\n /**\n * Rounded values for all values in this Pt.\n */\n round(): Pt {\n Vec.round(this);\n return this;\n }\n\n /**\n * Get a new Pt with rounded values of this Pt.\n */\n $round(): Pt {\n return this.clone().round();\n }\n\n /**\n * Find the minimum value across all dimensions in this Pt.\n * @returns an object with `value` and `index` which returns the minimum value and its dimensional index\n */\n minValue(): { value: number; index: number } {\n return Vec.min(this);\n }\n\n /**\n * Find the maximum value across all dimensions in this Pt.\n * @returns an object with `value` and `index` which returns the maximum value and its dimensional index\n */\n maxValue(): { value: number; index: number } {\n return Vec.max(this);\n }\n\n /**\n * Get a new Pt that has the minimum dimensional values of this Pt and another Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $min(...args: any[]): Pt {\n const p = Util.getPtLike(args);\n const m = this.clone();\n for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {\n m[i] = Math.min(this[i], p[i]);\n }\n return m;\n }\n\n /**\n * Get a new Pt that has the maximum dimensional values of this Pt and another Pt.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n $max(...args: any[]): Pt {\n const p = Util.getPtLike(args);\n const m = this.clone();\n for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {\n m[i] = Math.max(this[i], p[i]);\n }\n return m;\n }\n\n /**\n * Get angle of this Pt from origin.\n * @param axis a string such as \"xy\" (use Const.xy) or an array to specify index for two dimensions\n */\n angle(axis: string | number[] = Const.xy): number {\n return Math.atan2((this as any)[axis[1]], (this as any)[axis[0]]);\n }\n\n /**\n * Get the signed angle between this and another Pt, normalized to [-π, π).\n * @param p the other Pt\n * @param axis a string such as \"xy\" (use Const.xy) or an array to specify index for two dimensions\n */\n angleBetween(p: Pt, axis: string | number[] = Const.xy): number {\n // normalize the difference so results don't jump across the ±π wrap\n return (\n Geom.boundRadian(this.angle(axis) - p.angle(axis) + Math.PI) - Math.PI\n );\n }\n\n /**\n * Scale this Pt from origin or from an anchor point.\n * @param scale scale ratio\n * @param anchor optional anchor point to scale from\n */\n scale(scale: number | number[] | PtLike, anchor?: PtLike) {\n Geom.scale(this, scale, anchor || Pt.make(this.length, 0));\n return this;\n }\n\n /**\n * Rotate this Pt from origin or from an anchor point in 2D.\n * @param angle rotate angle\n * @param anchor optional anchor point to scale from\n * @param axis optional string such as \"yz\" to specify a 2D plane\n */\n rotate2D(angle: number, anchor?: PtLike, axis?: string) {\n Geom.rotate2D(this, angle, anchor || Pt.make(this.length, 0), axis);\n return this;\n }\n\n /**\n * Shear this Pt from origin or from an anchor point in 2D.\n * @param scale shearing value which can be a number or an array of 2 numbers\n * @param anchor optional anchor point to scale from\n * @param axis optional string such as \"yz\" to specify a 2D plane\n */\n shear2D(scale: number | number[] | PtLike, anchor?: PtLike, axis?: string) {\n Geom.shear2D(this, scale, anchor || Pt.make(this.length, 0), axis);\n return this;\n }\n\n /**\n * Reflect this Pt along a 2D line.\n * @param line a Group of 2 Pts that defines a line for reflection\n * @param axis optional axis such as \"yz\" to define a 2D plane of reflection\n */\n reflect2D(line: GroupLike, axis?: string): this {\n Geom.reflect2D(this, line, axis);\n return this;\n }\n\n /**\n * A string representation of this Pt. Eg, \"Pt(1, 2, 3)\".\n */\n toString(): string {\n return `Pt(${this.join(\", \")})`;\n }\n\n /**\n * Convert this Pt to a javascript Array.\n */\n toArray(): number[] {\n const a = [];\n for (let i = 0, len = this.length; i < len; i++) a.push(this[i]);\n return a;\n }\n\n /**\n * Convert this Pt to a Group as new Group([0,...], pt)\n */\n toGroup(): Group {\n return new Group(Pt.make(this.length), this.clone());\n }\n\n /**\n * Convert this Pt to a Bound as new Group([0,...], pt)\n */\n toBound(): Bound {\n return new Bound(Pt.make(this.length), this.clone());\n }\n}\n\n/**\n * A Group is a subclass of standard javascript [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array). It should only contain Pt instances. You can think of it as an array of Float32Arrays.\n * See [Group guide](../guide/Group-0300.html) for details.\n */\nexport class Group extends Array<Pt> {\n protected _id!: string;\n\n /**\n * Create a Group by passing an array of [`Pt`](#link). You may also create a Group using [`Group.fromArray`](#link) or [`Group.fromPtArray`](#link).\n * @param args an array of Pts\n */\n constructor(...args: Pt[]) {\n super(...args);\n }\n\n /**\n * ID string of this Group\n */\n get id(): string {\n return this._id;\n }\n set id(s: string) {\n this._id = s;\n }\n\n /**\n * The first Pt in this Group\n */\n get p1(): Pt {\n return this[0];\n }\n\n /**\n * The second Pt in this Group\n */\n get p2(): Pt {\n return this[1];\n }\n\n /**\n * The third Pt in this Group\n */\n get p3(): Pt {\n return this[2];\n }\n\n /**\n * The forth Pt in this Group\n */\n get p4(): Pt {\n return this[3];\n }\n\n /**\n * The last Pt in this Group\n */\n get q1(): Pt {\n return this[this.length - 1];\n }\n\n /**\n * The second-last Pt in this Group\n */\n get q2(): Pt {\n return this[this.length - 2];\n }\n\n /**\n * The third-last Pt in this Group\n */\n get q3(): Pt {\n return this[this.length - 3];\n }\n\n /**\n * The forth-last Pt in this Group\n */\n get q4(): Pt {\n return this[this.length - 4];\n }\n\n /**\n * Depp clone this group and its Pts.\n */\n clone(): Group {\n const group = new Group();\n for (let i = 0, len = this.length; i < len; i++) {\n group.push(this[i].clone());\n }\n return group;\n }\n\n /**\n * Convert an array of numeric arrays into a Group.\n * @param list an Iterable<PtLike> such as an array or a generator (of PtLike numeric arrays)\n * @example `Group.fromArray( [[1,2], [3,4], [5,6]] )`\n */\n static fromArray(list: PtLikeIterable): Group {\n const g = new Group();\n for (const li of list) {\n const p = li instanceof Pt ? (li as Pt) : new Pt(li);\n g.push(p);\n }\n return g;\n }\n\n /**\n * Convert an Array/Iterable of Pt into a Group.\n * @param list an Iterable<Pt>\n */\n static fromPtArray(list: PtIterable): Group {\n return Group.from(list) as Group;\n }\n\n /**\n * Split this Group into an array of sub-groups.\n * @param chunkSize number of items per sub-group\n * @param stride forward-steps after each sub-group\n * @param loopBack if `true`, always go through the array till the end and loop back to the beginning to complete the segments if needed\n */\n split(\n chunkSize: number,\n stride?: number,\n loopBack: boolean = false,\n ): Group[] {\n // build real Groups (Util.split returns plain arrays); indexed assignment\n // avoids the slow spread through the Array subclass constructor\n const st = stride || chunkSize;\n const chunks: Group[] = [];\n if (this.length <= 0 || st <= 0) return chunks;\n\n let index = 0;\n while (index < this.length) {\n const g = new Group();\n let size = 0;\n for (let k = 0; k < chunkSize; k++) {\n if (loopBack) {\n g[size++] = this[(index + k) % this.length];\n } else {\n if (index + k >= this.length) break;\n g[size++] = this[index + k];\n }\n }\n index += st;\n if (size === chunkSize) chunks.push(g);\n }\n return chunks;\n }\n\n /**\n * Insert more Pt into this group.\n * @param pts a Group or an Iterable<Pt>\n * @param index the index position to insert into\n */\n insert(pts: PtIterable, index = 0): this {\n // iterToArray returns an array input as-is; inserting a group into itself\n // must read a snapshot, not the tail it is about to shift\n let _pts = Util.iterToArray(pts);\n if ((_pts as unknown) === this) _pts = _pts.slice();\n const len = this.length;\n const n = _pts.length;\n if (n === 0) return this;\n // normalize like Array.prototype.splice, including negative index\n let start = Math.trunc(index) || 0;\n start = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);\n // shift the tail and copy in place: splice's argument-spread overflows\n // the call stack for very large inputs\n this.length = len + n;\n for (let i = len - 1; i >= start; i--) this[i + n] = this[i];\n for (let i = 0; i < n; i++) this[start + i] = _pts[i];\n return this;\n }\n\n /**\n * Like Array's splice function, with support for negative index and a friendlier name.\n * @param index start index, which can be negative (where -1 is at index 0, -2 at index 1, etc)\n * @param count number of items to remove\n * @returns The items that are removed.\n */\n remove(index = 0, count: number = 1): Group {\n const param: [number, number] =\n index < 0 ? [index * -1 - 1, count] : [index, count];\n return Group.prototype.splice.apply(this, param) as Group;\n }\n\n /**\n * Split this group into an array of sub-group segments.\n * @param pts_per_segment number of Pts in each segment\n * @param stride forward-step to take\n * @param loopBack if `true`, always go through the array till the end and loop back to the beginning to complete the segments if needed\n */\n segments(\n pts_per_segment: number = 2,\n stride: number = 1,\n loopBack: boolean = false,\n ): Group[] {\n return this.split(pts_per_segment, stride, loopBack);\n }\n\n /**\n * Get all the line segments (ie, edges in a graph) of this group.\n */\n lines(): Group[] {\n return this.segments(2, 1);\n }\n\n /**\n * Find the centroid of this group's Pts, which is the average middle point.\n */\n centroid(): Pt {\n return Geom.centroid(this);\n }\n\n /**\n * Find the rectangular bounding box of this group's Pts.\n * @returns a Group of 2 Pts representing the top-left and bottom-right of the rectangle\n */\n boundingBox(): Group {\n return Geom.boundingBox(this);\n }\n\n /**\n * Anchor all the Pts in this Group using a target Pt as origin. (ie, subtract all Pt with the target anchor to get a relative position). All the Pts' values will be updated.\n * @param ptOrIndex a Pt, or a numeric index to target a specific Pt in this Group\n */\n anchorTo(ptOrIndex: PtLike | number = 0) {\n Geom.anchor(this, ptOrIndex, \"to\");\n }\n\n /**\n * Anchor all the Pts in this Group by its absolute position from a target Pt. (ie, add all Pt with the target anchor to get an absolute position). All the Pts' values will be updated.\n * @param ptOrIndex a Pt, or a numeric index to target a specific Pt in this Group\n */\n anchorFrom(ptOrIndex: PtLike | number = 0) {\n Geom.anchor(this, ptOrIndex, \"from\");\n }\n\n /**\n * Create an operation using this Group, passing this Group into a custom function's first parameter. See the [Op guide](../guide/Op-0400.html) for details.\n * @param fn any function that takes a Group as its first parameter\n * @example `let myOp = group.op( fn ); let result = myOp( [1,2,3] );`\n * @returns a resulting function that takes other parameters required in `fn`\n */\n op(fn: (g1: PtIterable, ...rest: any[]) => any): (...rest: any[]) => any {\n const self = this;\n return (...params: any[]) => {\n return fn(self, ...params);\n };\n }\n\n /**\n * This combines a series of operations into an array. See the [Op guide](../guide/Op-0400.html) for details.\n * @param fns an array of functions for `op`\n * @example `let myOps = pt.ops([fn1, fn2, fn3]); let results = myOps.map( (op) => op([1,2,3]) );`\n * @returns an array of resulting functions\n */\n ops(\n fns: ((g1: PtIterable, ...rest: any[]) => any)[],\n ): ((...rest: any[]) => any)[] {\n const _ops = [];\n for (let i = 0, len = fns.length; i < len; i++) {\n _ops.push(this.op(fns[i]));\n }\n return _ops;\n }\n\n /**\n * Get an interpolated point on the line segments defined by this Group.\n * @param t a value between 0 to 1 usually\n */\n interpolate(t: number): Pt {\n t = Num.clamp(t, 0, 1);\n const chunk = this.length - 1;\n const tc = 1 / (this.length - 1);\n const idx = Math.floor(t / tc);\n return Geom.interpolate(\n this[idx],\n this[Math.min(this.length - 1, idx + 1)],\n (t - idx * tc) * chunk,\n );\n }\n\n /**\n * Move every Pt's position by a specific amount. Same as [`Group.add`](#link).\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n moveBy(...args: any[]): this {\n return this.add(...args);\n }\n\n /**\n * Move the first Pt in this group to a specific position, and move all the other Pts correspondingly.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n moveTo(...args: any[]): this {\n const d = new Pt(...args).subtract(this[0]);\n this.moveBy(d);\n return this;\n }\n\n /**\n * Scale this group's Pts from an anchor point. Default anchor point is the first Pt in this group.\n * @param scale scale ratio\n * @param anchor optional anchor point to scale from\n */\n scale(scale: number | number[] | PtLike, anchor?: PtLike): this {\n for (let i = 0, len = this.length; i < len; i++) {\n Geom.scale(this[i], scale, anchor || this[0]);\n }\n return this;\n }\n\n /**\n * Rotate this group's Pt from an anchor point in 2D. Default anchor point is the first Pt in this group.\n * @param angle rotate angle\n * @param anchor optional anchor point to scale from\n * @param axis optional string such as \"yz\" to specify a 2D plane\n */\n rotate2D(angle: number, anchor?: PtLike, axis?: string): this {\n for (let i = 0, len = this.length; i < len; i++) {\n Geom.rotate2D(this[i], angle, anchor || this[0], axis);\n }\n return this;\n }\n\n /**\n * Shear this group's Pt from an anchor point in 2D. Default anchor point is the first Pt in this group.\n * @param scale shearing value which can be a number or an array of 2 numbers\n * @param anchor optional anchor point to scale from\n * @param axis optional string such as \"yz\" to specify a 2D plane\n */\n shear2D(\n scale: number | number[] | PtLike,\n anchor?: PtLike,\n axis?: string,\n ): this {\n for (let i = 0, len = this.length; i < len; i++) {\n Geom.shear2D(this[i], scale, anchor || this[0], axis);\n }\n return this;\n }\n\n /**\n * Reflect this group's Pts along a 2D line. Default anchor point is the first Pt in this group.\n * @param line a Group or an Iterable<PtLike> with 2 Pt that defines a line for reflection\n * @param axis optional axis such as \"yz\" to define a 2D plane of reflection\n */\n reflect2D(line: PtLikeIterable, axis?: string): this {\n for (let i = 0, len = this.length; i < len; i++) {\n Geom.reflect2D(this[i], line, axis);\n }\n return this;\n }\n\n /**\n * Sort this group's Pts by values in a specific dimension.\n * @param dim dimensional index\n * @param desc if true, sort descending. Default is false (ascending)\n */\n sortByDimension(dim: number, desc: boolean = false): this {\n return this.sort((a, b) => (desc ? b[dim] - a[dim] : a[dim] - b[dim]));\n }\n\n /**\n * Update each Pt in this Group with an existing Pt function.\n * @param ptFn string name of an existing Pt function. Note that the function must return Pt.\n * @param args arguments for the function specified in ptFn\n */\n forEachPt(ptFn: string, ...args: any[]): this {\n if (this.length === 0) return this;\n if (!(this[0] as any)[ptFn]) {\n Util.warn(`${ptFn} is not a function of Pt`);\n return this;\n }\n for (let i = 0, len = this.length; i < len; i++) {\n this[i] = (this[i] as any)[ptFn](...args);\n }\n return this;\n }\n\n /**\n * Apply a Vec operation to every Pt, parsing the arguments once for the whole\n * group rather than once per Pt.\n */\n protected _vecOp(\n fn: (a: PtLike, b: PtLike | number) => PtLike,\n args: any[],\n ): this {\n const b =\n args.length === 1 && typeof args[0] == \"number\"\n ? args[0]\n : Util.getPtLike(args);\n for (let i = 0, len = this.length; i < len; i++) {\n fn(this[i], b);\n }\n return this;\n }\n\n /**\n * Add scalar or vector values to this group's Pts.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n add(...args: any[]): this {\n return this._vecOp(Vec.add, args);\n }\n\n /**\n * Subtract scalar or vector values from this group's Pts.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n subtract(...args: any[]): this {\n return this._vecOp(Vec.subtract, args);\n }\n\n /**\n * Multiply scalar or vector values (as element-wise) with this group's Pts.\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n multiply(...args: any[]): this {\n return this._vecOp(Vec.multiply, args);\n }\n\n /**\n * Divide this group's Pts over scalar or vector values (as element-wise).\n * @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties\n */\n divide(...args: any[]): this {\n return this._vecOp(Vec.divide, args);\n }\n\n /**\n * Apply this group as a matrix and calculate matrix addition.\n * @param g a scalar number, an array of numeric arrays, or a group of Pt\n * @returns a new Group\n */\n $matrixAdd(g: GroupLike | number[][] | number): Group {\n return Mat.add(this, g);\n }\n\n /**\n * Apply this group as a matrix and calculate matrix multiplication.\n * @param g a scalar number, an array of numeric arrays, or a Group of K Pts, each with N dimensions (K-rows, N-columns) -- or if transposed is true, then N Pts with K dimensions\n * @param transposed (Only applicable if it's not elementwise multiplication) If true, then a and b's columns should match (ie, each Pt should have the same dimensions). Default is `false`.\n * @param elementwise if true, then the multiplication is done element-wise. Default is `false`.\n * @returns If not elementwise, this will return a new Group with M Pt, each with N dimensions (M-rows, N-columns).\n */\n $matrixMultiply(\n g: GroupLike | number,\n transposed: boolean = false,\n elementwise: boolean = false,\n ): Group {\n return Mat.multiply(this, g, transposed, elementwise);\n }\n\n /**\n * Zip one slice of an array of Pt. Imagine the Pts are organized in rows, then this function will take the values in a specific column.\n * @param index index to zip at\n * @param defaultValue a default value to fill if index out of bound. If not provided, it will throw an error instead.\n */\n zipSlice(index: number, defaultValue: number | boolean = false): Pt {\n return Mat.zipSlice(this, index, defaultValue);\n }\n\n /**\n * Zip a group of Pt. eg, [[1,2],[3,4],[5,6]] => [[1,3,5],[2,4,6]].\n * @param defaultValue a default value to fill if index out of bound. If not provided, it will throw an error instead.\n * @param useLongest If true, find the longest list of values in a Pt and use its length for zipping. Default is false, which uses the first item's length for zipping.\n */\n $zip(\n defaultValue: number | boolean | undefined = undefined,\n useLongest = false,\n ): Group {\n return Mat.zip(this, defaultValue, useLongest);\n }\n\n /**\n * Get a Bound instance of this group\n */\n toBound(): Bound {\n return Bound.fromGroup(this);\n }\n\n /**\n * Get a string representation of this group.\n */\n toString(): string {\n return \"Group[ \" + this.reduce((p, c) => p + c.toString() + \" \", \"\") + \" ]\";\n }\n}\n\n/**\n * Bound is a subclass of [`Group`](#link) that represents a rectangular boundary.\n * It includes some convenient accessors (eg, bottomRight, center) for bounding box calculations.\n */\nexport class Bound extends Group implements IPt {\n protected _center: Pt = new Pt();\n protected _size: Pt = new Pt();\n protected _inited = false;\n\n /**\n * Create a Bound. This is similar to the Group constructor. You can also create a Bound via the static function [`Bound.fromGroup`](#link), or alternatively via the [Group.toBound](#link) function.\n * @param args a list of Pt as parameters\n * @see Bound.fromGroup\n */\n constructor(...args: Pt[]) {\n super(...args);\n this.init();\n }\n\n /**\n * Create a Bound from a [`ClientRect`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) object.\n * @param rect an object that has {top, left, bottom, right, width, height} properties\n * @returns a Bound object\n */\n static fromBoundingRect(rect: ClientRect): Bound {\n const b = new Bound(\n new Pt(rect.left || 0, rect.top || 0),\n new Pt(rect.right || 0, rect.bottom || 0),\n );\n if (rect.width && rect.height) b.size = new Pt(rect.width, rect.height);\n return b;\n }\n\n /**\n * Create a Bound from a Group or an array of Pts\n * @param g a Group or an Iterable<PtLike>\n */\n static fromGroup(g: PtLikeIterable): Bound {\n const _g = Util.iterToArray(g);\n if (_g.length < 2)\n throw new Error(\n \"Cannot create a Bound from a group that has less than 2 Pt\",\n );\n const first = _g[0];\n const last = _g[_g.length - 1];\n return new Bound(\n first instanceof Pt ? first : new Pt(first),\n last instanceof Pt ? last : new Pt(last),\n );\n }\n\n /**\n * Initiate the bound's properties.\n */\n protected init() {\n if (this.p1) {\n this._size = this.p1.clone();\n this._inited = true;\n }\n if (this.p1 && this.p2) {\n this._updateSize();\n this._inited = true;\n }\n }\n\n /**\n * Clone this bound and return a new one.\n */\n clone(): Bound {\n // the topLeft and bottomRight getters already return fresh Pts\n return new Bound(this.topLeft, this.bottomRight);\n }\n\n /**\n * Recalculte size and center.\n */\n protected _updateSize() {\n // In-place equivalent of `bottomRight.$subtract(topLeft).abs()`: dimensions\n // follow this[1], with missing/NaN topLeft values treated as 0.\n const a = this[0];\n const b = this[1];\n const n = b ? b.length : 0;\n if (this._size.length !== n) this._size = new Pt(n);\n for (let i = 0; i < n; i++) {\n let lo = a ? a[i] || 0 : 0;\n if (a && b[i] < lo) {\n // corners given in the other order: keep top-left the smaller one\n a[i] = b[i];\n b[i] = lo;\n lo = a[i];\n }\n this._size[i] = Math.abs(b[i] - lo);\n }\n this._updateCenter();\n }\n\n /**\n * Recalculate center.\n */\n protected _updateCenter() {\n // In-place equivalent of `size.$multiply(0.5).add(topLeft)`\n const a = this[0];\n const n = this._size.length;\n if (this._center.length !== n) this._center = new Pt(n);\n for (let i = 0; i < n; i++) {\n this._center[i] = this._size[i] * 0.5 + (a ? a[i] || 0 : 0);\n }\n }\n\n /**\n * Recalculate based on top-left position and size.\n */\n protected _updatePosFromTop() {\n this.bottomRight = this.topLeft.$add(this._size);\n this._updateCenter();\n }\n\n /**\n * Recalculate based on bottom-right position and size.\n */\n protected _updatePosFromBottom() {\n this.topLeft = this.bottomRight.$subtract(this._size);\n this._updateCenter();\n }\n\n /**\n * Recalculate based on center position and size.\n */\n protected _updatePosFromCenter() {\n const half = this._size.$multiply(0.5);\n // Assign the corner Pts directly. Going through the `topLeft` and\n // `bottomRight` setters would call `_updateSize` after the first of the two,\n // recomputing size and center from a half-updated pair — so the second line\n // would read a `_center` that no longer holds the value being applied.\n const center = this._center;\n this[0] = center.$subtract(half);\n this[1] = center.$add(half);\n }\n\n /**\n * Size of this Bound\n */\n get size(): Pt {\n return new Pt(this._size);\n }\n set size(p: Pt) {\n this._size = new Pt(p);\n this._updatePosFromTop();\n }\n\n /**\n * Center position of this Bound\n */\n get center(): Pt {\n return new Pt(this._center);\n }\n set center(p: Pt) {\n this._center = new Pt(p);\n this._updatePosFromCenter();\n }\n\n /**\n * Top-left position of this Bound\n */\n get topLeft(): Pt {\n return new Pt(this[0]);\n }\n set topLeft(p: Pt) {\n this[0] = new Pt(p);\n this._updateSize();\n }\n\n /**\n * Bottom-right position of this Bound\n */\n get bottomRight(): Pt {\n return new Pt(this[1]);\n }\n set bottomRight(p: Pt) {\n this[1] = new Pt(p);\n this._updateSize();\n }\n\n /**\n * Width of this Bound\n */\n get width(): number {\n return this._size.length > 0 ? this._size.x : 0;\n }\n set width(w: number) {\n this._size.x = w;\n this._updatePosFromTop();\n }\n\n /**\n * Height of this Bound\n */\n get height(): number {\n return this._size.length > 1 ? this._size.y : 0;\n }\n set height(h: number) {\n this._size.y = h;\n this._updatePosFromTop();\n }\n\n /**\n * Depth of this Bound\n */\n get depth(): number {\n return this._size.length > 2 ? this._size.z : 0;\n }\n set depth(d: number) {\n this._size.z = d;\n this._updatePosFromTop();\n }\n\n /**\n * First value of the Bound's top-left position\n */\n get x(): number | undefined {\n // direct read: going through the `topLeft` getter clones a Pt per access\n return this[0] ? this[0][0] : undefined;\n }\n\n /**\n * Second value of the Bound's top-left position\n */\n get y(): number | undefined {\n return this[0] ? this[0][1] : undefined;\n }\n\n /**\n * Third value of the Bound's top-left position\n */\n get z(): number | undefined {\n return this[0] ? this[0][2] : undefined;\n }\n\n /**\n * Whether this Bound has been initiated\n */\n get inited(): boolean {\n return this._inited;\n }\n\n /**\n * If the Bound's Pts are changed, call this function to update the Bound's properties.\n * It's simpler and preferable to change the Bound's properties (eg, topLeft, bottomRight) instead of updating the Bound's Pts.\n * Note that this recomputes from the current corner Pts in place; it does not replace them with fresh instances.\n */\n update() {\n this._updateSize();\n return this;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Group } from \"./Pt\";\nimport { Rectangle, Circle, Polygon } from \"./Op\";\nimport {\n type UIHandler,\n type UIActionEvent,\n type GroupLike,\n type PtLike,\n type PtLikeIterable,\n} from \"./Types\";\n\n/** A hit-test function for a UI shape: given the UI's group, a point, and the UI's states, return whether the point is within the shape. */\nexport type UIShapeTest = (\n group: Group,\n pt: PtLike,\n states: { [key: string]: any },\n) => boolean;\n\nfunction _withinSegment(\n a: PtLike,\n b: PtLike,\n pt: PtLike,\n threshold: number,\n): boolean {\n if (threshold < 0) return false;\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const lengthSq = dx * dx + dy * dy;\n const t =\n lengthSq === 0\n ? 0\n : Math.max(\n 0,\n Math.min(1, ((pt[0] - a[0]) * dx + (pt[1] - a[1]) * dy) / lengthSq),\n );\n const px = pt[0] - a[0] - t * dx;\n const py = pt[1] - a[1] - t * dy;\n return px * px + py * py <= threshold * threshold;\n}\n\n// Shape hit tests, keyed by shape name. Extensible via `UI.registerShape`.\nconst _shapeTests: { [key: string]: UIShapeTest } = {\n rectangle: (group, pt) => Rectangle.withinBound(group, pt),\n circle: (group, pt) => Circle.withinBound(group, pt),\n polygon: (group, pt) => Polygon.hasIntersectPoint(group, pt),\n line: (group, pt, states) => {\n const threshold = states.lineThreshold ?? 5;\n return (\n group.length >= 2 && _withinSegment(group[0], group[1], pt, threshold)\n );\n },\n polyline: (group, pt, states) => {\n const threshold = states.lineThreshold ?? 5;\n for (let i = 0, len = group.length - 1; i < len; i++) {\n if (_withinSegment(group[i], group[i + 1], pt, threshold)) return true;\n }\n return false;\n },\n};\n\n/**\n * **[Experimental]** A set of string constatns to represent different UI types, for use in [`UI`](#link) instances.\n */\nexport const UIShape = {\n rectangle: \"rectangle\",\n circle: \"circle\",\n polygon: \"polygon\",\n polyline: \"polyline\",\n line: \"line\",\n};\n\n/**\n * **[Experimental]** A set of string constants to represent different UI event types.\n */\nexport const UIPointerActions = {\n up: \"up\",\n down: \"down\",\n move: \"move\",\n drag: \"drag\",\n uidrag: \"uidrag\",\n drop: \"drop\",\n uidrop: \"uidrop\",\n over: \"over\",\n out: \"out\",\n enter: \"enter\",\n leave: \"leave\",\n click: \"click\",\n keydown: \"keydown\",\n keyup: \"keyup\",\n pointerdown: \"pointerdown\",\n pointerup: \"pointerup\",\n contextmenu: \"contextmenu\",\n all: \"all\",\n} as const;\n\n/** A known pointer, touch, or keyboard action dispatched by a Pts space. */\nexport type UIPointerAction =\n (typeof UIPointerActions)[keyof typeof UIPointerActions];\n\n/**\n * **[Experimental]** An abstract class that represents an UI element. It wraps a [`Group`](#link) and supports UI event handling.\n * Extend this class to create custom UI elements.\n */\nexport class UI {\n private _abortCleanup: { [type: string]: Map<number, () => void> } = {};\n _group: Group;\n _shape: string;\n\n protected static _counter: number = 0;\n protected _id: string;\n protected _actions: { [type: string]: (UIHandler | null)[] };\n // built-in machinery (UIButton hover, UIDragger drag) registers here, so\n // public `off(type)` cannot remove it along with user handlers\n protected _sysActions: { [type: string]: (UIHandler | null)[] };\n protected _states: { [key: string]: any };\n\n protected _holds = new Map<number, string>();\n\n /**\n * Create an UI element. You may also create a new UI using one of the static helper like [`UI.fromRectangle`](#link) or [`UI.fromCircle`](#link).\n * @param group a Group or an Iterable<PtLike> that defines the UI's appearance\n * @param shape specifies the shape of the Group\n * @param states optional a state object keep track of custom states for this UI\n * @param id optional id string\n */\n constructor(\n group: PtLikeIterable,\n shape: string,\n states: { [key: string]: any } = {},\n id?: string,\n ) {\n this._group = Group.fromArray(group);\n this._shape = shape;\n this._id = id === undefined ? `ui_${UI._counter++}` : id;\n this._states = states;\n this._actions = {};\n this._sysActions = {};\n }\n\n /**\n * Register a custom shape hit test, or override a built-in one. The shape\n * name can then be used when constructing a UI.\n * @param shape shape name\n * @param fn a function `(group, pt, states) => boolean` that returns whether the point hits the shape\n */\n static registerShape(shape: string, fn: UIShapeTest): void {\n _shapeTests[shape] = fn;\n }\n\n /**\n * A static helper function to create a Rectangle UI.\n * @param group a Group or an Iterable<PtLike> with 2 Pt representing a rectangle\n * @param states optional a state object keep track of custom states for this UI\n * @param id optional id string\n */\n static fromRectangle(group: PtLikeIterable, states: {}, id?: string): UI {\n return new this(group, UIShape.rectangle, states, id);\n }\n\n /**\n * A static helper function to create a Circle UI.\n * @param group a Group or an Iterable<PtLike> with 2 Pt representing a circle\n * @param states optional a state object keep track of custom states for this UI\n * @param id optional id string\n */\n static fromCircle(group: PtLikeIterable, states: {}, id?: string): UI {\n return new this(group, UIShape.circle, states, id);\n }\n\n /**\n * A static helper function to create a Polygon UI.\n * @param group a Group or an Iterable<PtLike> representing a polygon\n * @param states optional a state object keep track of custom states for this UI\n * @param id optional id string\n */\n static fromPolygon(group: PtLikeIterable, states: {}, id?: string): UI {\n return new this(group, UIShape.polygon, states, id);\n }\n\n /**\n * A static helper function to create a new UI based on another UI.\n * @param ui base UI\n * @param states optional a state object keep track of custom states for this UI\n */\n static fromUI(ui: UI, states?: object, id?: string): UI {\n // copy the source states so the new UI doesn't share mutations\n return new this(ui.group, ui.shape, states || { ...ui._states }, id);\n }\n\n /**\n * An unique id of the UI.\n */\n get id(): string {\n return this._id;\n }\n set id(d: string) {\n this._id = d;\n }\n\n /**\n * A group of Pts that defines this UI's shape.\n */\n get group(): Group {\n return this._group;\n }\n set group(d: Group) {\n this._group = d;\n }\n\n /**\n * A string that describes this UI's shape.\n */\n get shape(): string {\n return this._shape;\n }\n set shape(d: string) {\n this._shape = d;\n }\n\n /**\n * Get and/or set a specific UI state.\n * @param key state's name\n * @param value optionally set a new value for this state.key\n * @returns If `value` is changed, return this instance. Otherwise, return the value of the specific key.\n */\n state(key: string, value?: any): any {\n if (!key) return null;\n if (value !== undefined) {\n this._states[key] = value;\n return this;\n }\n return this._states[key];\n }\n\n /**\n * Get a specific UI state. Unlike [`UI.state`](#link), this is a plain typed getter.\n * @param key state's name\n */\n getState<T = any>(key: string): T {\n return this._states[key];\n }\n\n /**\n * Set a specific UI state. Unlike [`UI.state`](#link), this can also store `undefined`.\n * @param key state's name\n * @param value the value to set\n */\n setState(key: string, value: any): this {\n this._states[key] = value;\n return this;\n }\n\n /**\n * Add an event handler. Remember this UI will also need to be tracked for events, via `UI.track` or [`MultiTouchSpace.track`](#link).\n * @param type event type, either one of [`UIPointerActions`](#link) or a custom type\n * @param fn a [`UIHandler`](#link) callback function: `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @param options optionally `{ once }` to remove the handler after its first call, and/or `{ signal }` with an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that removes it on abort (an already-aborted signal registers nothing)\n * @returns an id number that reference to this handler, for use in [`UI.off`](#link), or -1 if nothing was registered\n */\n on(\n type: UIPointerAction | (string & {}),\n fn: UIHandler,\n options?: { once?: boolean; signal?: AbortSignal },\n ): number {\n if (!fn) return -1;\n if (options?.signal?.aborted) return -1;\n if (!this._actions[type]) this._actions[type] = [];\n\n let handler = fn;\n let id = -1;\n if (options?.once) {\n handler = (t, p, ty, e) => {\n this.off(type, id);\n fn(t, p, ty, e);\n };\n }\n id = UI._addHandler(this._actions[type], handler);\n if (options?.signal) {\n const signal = options.signal;\n const abort = () => this.off(type, id);\n signal.addEventListener(\"abort\", abort, { once: true });\n if (!this._abortCleanup[type]) this._abortCleanup[type] = new Map();\n this._abortCleanup[type].set(id, () =>\n signal.removeEventListener(\"abort\", abort),\n );\n }\n return id;\n }\n\n /**\n * Remove an event handler.\n * @param type event type\n * @param which an ID number returned by [`UI.on`](#link). If this is not defined, all handlers in this type will be removed (built-in machinery like UIButton's click counting is unaffected). Note that after removal an id is stale — removing it twice may affect a handler that has since reused the slot.\n */\n off(type: UIPointerAction | (string & {}), which?: number): boolean {\n if (!this._actions[type]) return false;\n if (which === undefined) {\n this._abortCleanup[type]?.forEach((cleanup) => cleanup());\n delete this._abortCleanup[type];\n delete this._actions[type];\n return true;\n } else {\n this._abortCleanup[type]?.get(which)?.();\n this._abortCleanup[type]?.delete(which);\n return UI._removeHandler(this._actions[type], which);\n }\n }\n\n /**\n * Listen for UI events and trigger action handlers.\n * @param type an action type. Can be one of UIPointerActions or a custom one.\n * @param p a point to check\n * @param evt a MouseEvent emitted by the browser (See [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent))\n */\n listen(\n type: UIPointerAction | (string & {}),\n p: PtLike,\n evt: UIActionEvent,\n ): boolean {\n let fired = false;\n const userActions = this._actions[type];\n const sysActions = this._sysActions[type];\n\n if (userActions || sysActions) {\n if (this._within(p) || this._holdsType(type)) {\n if (sysActions) {\n UI._trigger(sysActions, this, p, type, evt);\n fired = true;\n }\n if (userActions) {\n UI._trigger(userActions, this, p, type, evt);\n fired = true;\n }\n }\n }\n\n // \"all\" handlers observe every event, regardless of position\n if (this._actions[\"all\"]) {\n UI._trigger(this._actions[\"all\"], this, p, type, evt);\n fired = true;\n }\n\n return fired;\n }\n\n /** Check whether an action type is currently held, without allocating. */\n private _holdsType(type: string): boolean {\n for (const held of this._holds.values()) {\n if (held === type) return true;\n }\n return false;\n }\n\n /** Register a built-in handler unaffected by public `off`. */\n protected _sysOn(type: string, fn: UIHandler): number {\n if (!this._sysActions[type]) this._sysActions[type] = [];\n return UI._addHandler(this._sysActions[type], fn);\n }\n\n /** Remove a built-in handler registered with `_sysOn`. */\n protected _sysOff(type: string, which: number): boolean {\n if (!this._sysActions[type]) return false;\n return UI._removeHandler(this._sysActions[type], which);\n }\n\n /**\n * Continue to keep track of an actions even if it's not within this UI. Useful for hover-leave and drag-outside.\n * @param type a string defined in [`UIPointerActions`](#link)\n */\n protected hold(type: string): number {\n let newKey = Math.max(0, ...Array.from(this._holds.keys())) + 1;\n this._holds.set(newKey, type);\n return newKey;\n }\n\n /**\n * Stop keeping track of this action\n * @param key an id returned by the [`UI.hold`](#link) function\n */\n protected unhold(key?: number): void {\n if (key !== undefined) {\n this._holds.delete(key);\n } else {\n this._holds.clear();\n }\n }\n\n /**\n * A static function to listen for a list of UIs. See also [`UI.listen`](#link).\n * @param uis an array of UI\n * @param type an action type. Can be one of `UIPointerActions` or a custom one.\n * @param p a point to check\n * @param evt a MouseEvent emitted by the browser (See [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent))\n */\n static track(uis: UI[], type: string, p: PtLike, evt: UIActionEvent): void {\n for (let i = 0, len = uis.length; i < len; i++) {\n uis[i].listen(type, p, evt);\n }\n }\n\n /**\n * Take a custom render function to render this UI.\n * @param fn a render function\n */\n render(fn: (group: Group, states: { [key: string]: any }) => void): void {\n fn(this._group, this._states);\n }\n\n /**\n * Returns a string representation of this UI\n */\n toString(): string {\n return `UI ${this.group.toString()}`;\n }\n\n /**\n * Check intersection using the hit test registered for this UI's shape.\n * @param p a point to check\n * @returns a boolean to indicate if the event should be triggered\n */\n protected _within(p: PtLike): boolean {\n const fn = _shapeTests[this._shape];\n if (!fn) return false;\n return fn(this._group, p, this._states);\n }\n\n /**\n * Static function to trigger an array of UIHandlers\n */\n protected static _trigger(\n fns: (UIHandler | null)[],\n target: UI,\n pt: PtLike,\n type: string,\n evt: UIActionEvent,\n ) {\n if (fns) {\n for (let i = 0, len = fns.length; i < len; i++) {\n if (fns[i]) fns[i]!(target, pt, type, evt);\n }\n }\n }\n\n /**\n * Static function to add a new handler to an array store of UIHandlers.\n */\n protected static _addHandler(\n fns: (UIHandler | null)[],\n fn: UIHandler,\n ): number {\n if (!fn) return -1;\n // reuse a removed slot so ids stay stable and the array doesn't grow\n // unboundedly when handlers are added and removed repeatedly\n for (let i = 0, len = fns.length; i < len; i++) {\n if (fns[i] === null) {\n fns[i] = fn;\n return i;\n }\n }\n fns.push(fn);\n return fns.length - 1;\n }\n\n /**\n * Static function to remove an existing handler from an array store of UIHandlers.\n * The slot is nulled (not spliced) so other handlers' ids remain valid.\n */\n protected static _removeHandler(\n fns: (UIHandler | null)[],\n index: number,\n ): boolean {\n if (index >= 0 && index < fns.length && fns[index]) {\n fns[index] = null;\n return true;\n }\n return false;\n }\n}\n\n/**\n * **[Experimental]** A simple button that extends [`UI`](#link) to track clicks and hovers.\n */\nexport class UIButton extends UI {\n private _hoverID: number = -1;\n\n /**\n * Create an UIButton. A button has 2 states, \"clicks\" (number) and \"hover\" (boolean), which you can access through [`UI.state`](#link) function. You may also create a new UIButton using one of the static helper like [`UI.fromRectangle`](#link) or [`UI.fromCircle`](#link).\n * @param group a Group or an Iterable<PtLike> that defines the UI's appearance\n * @param shape specifies the shape of the Group\n * @param states Optional default state object\n * @param id Optional id string\n */\n constructor(\n group: PtLikeIterable,\n shape: string,\n states: { [key: string]: any } = {},\n id?: string,\n ) {\n super(group, shape, states, id);\n\n if (states.hover === undefined) this._states[\"hover\"] = false;\n if (states.clicks === undefined) this._states[\"clicks\"] = 0;\n\n const UA = UIPointerActions;\n\n // listen for clicks when mouse up and increment clicks\n this._sysOn(UA.up, () => {\n this.state(\"clicks\", this._states.clicks + 1);\n });\n\n // listen for move events and fire enter and leave events accordingly\n this._sysOn(\n UA.move,\n (target: UI, pt: PtLike, type: string, evt: UIActionEvent) => {\n let hover = this._within(pt);\n\n // hover on\n if (hover && !this._states.hover) {\n this.state(\"hover\", true);\n\n // enter trigger\n UI._trigger(this._actions[UA.enter], this, pt, UA.enter, evt);\n\n // listen for hover off\n let _capID = this.hold(UA.move); // keep hold of second move\n this._hoverID = this._sysOn(\n UA.move,\n (t: UI, p: PtLike, ty: string, e: UIActionEvent) => {\n if (!this._within(p) && !this.state(\"dragging\")) {\n this.state(\"hover\", false);\n // leave trigger, with the current position and event\n UI._trigger(this._actions[UA.leave], this, p, UA.leave, e);\n this._sysOff(UA.move, this._hoverID); // remove second move listener\n this.unhold(_capID); // stop keeping hold of second move\n }\n },\n );\n }\n },\n );\n }\n\n /**\n * Add a new click handler. Remember this button will also need to be tracked for events via `UI.track`. If you want to track right clicks, you may also consider [`UIButton.onContextMenu`](#link).\n * @param fn a [`UIHandler`](#link) callback function: `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @returns an id number that refers to this handler, for use in [`UIButton.offClick`](#link) or [`UI.off`](#link).\n */\n onClick(fn: UIHandler): number {\n return this.on(UIPointerActions.up, fn);\n }\n\n /**\n * Remove an existing click handler\n * @param id an ID number returned by [`UIButton.onClick`](#link). If this is not defined, all handlers in this type will be removed.\n * @returns a boolean indicating whether the handler was removed successfully\n */\n offClick(id: number): boolean {\n return this.off(UIPointerActions.up, id);\n }\n\n /**\n * Add a new contextmenu handler. `contextmenu` is similar to right click, see the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event). Remember this button will also need to be tracked for events via `UI.track`. Also note that you may need to use `event.preventDefault()` in the callback function to prevent other events from triggering.\n * @param fn a [`UIHandler`](#link) callback function: `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @returns an id number that refers to this handler, for use in [`UIButton.offContextMenu`](#link) or [`UI.off`](#link).\n */\n onContextMenu(fn: UIHandler): number {\n return this.on(UIPointerActions.contextmenu, fn);\n }\n\n /**\n * Remove an existing contextmenu handler\n * @param id an ID number returned by [`UIButton.onContextMenu`](#link). If this is not defined, all handlers in this type will be removed.\n * @returns a boolean indicating whether the handler was removed successfully\n */\n offContextMenu(id: number): boolean {\n return this.off(UIPointerActions.contextmenu, id);\n }\n\n /**\n * Add handlers for hover events. Remember this button will also need to be tracked for events via `UI.track`.\n * @param enter an optional [`UIHandler`](#link) function to handle when pointer enters hover. Eg, `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @param leave an optional [`UIHandler`](#link) function to handle when pointer exits hover. Eg, `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @returns id numbers that refer to enter/leave handlers, for use in [`UIButton.offHover`](#link) or [`UI.off`](#link).\n */\n onHover(enter?: UIHandler, leave?: UIHandler): (number | undefined)[] {\n let ids: (number | undefined)[] = [undefined, undefined];\n if (enter) ids[0] = this.on(UIPointerActions.enter, enter);\n if (leave) ids[1] = this.on(UIPointerActions.leave, leave);\n return ids;\n }\n\n /**\n * Remove handlers for hover events.\n * @param enterID an ID number returned by [`UI.onClick`](#link), or -1 to skip. If this is not defined, all handlers in this type will be removed.\n * @param leaveID an ID number returned by [`UI.onClick`](#link), or -1 to skip. If this is not defined, all handlers in this type will be removed.\n * @returns an array of booleans indicating whether the handlers were removed successfully\n */\n offHover(enterID?: number, leaveID?: number): boolean[] {\n let s = [false, false];\n if (enterID === undefined || enterID >= 0)\n s[0] = this.off(UIPointerActions.enter, enterID);\n if (leaveID === undefined || leaveID >= 0)\n s[1] = this.off(UIPointerActions.leave, leaveID);\n return s;\n }\n}\n\n/**\n * [Experimental] A draggable UI that provides handler such as [`UIDragger.onDrag`](#link) and [`UIDragger.onDrop`](#link).\n */\nexport class UIDragger extends UIButton {\n private _draggingID: number = -1;\n private _dragID: number = -1;\n private _moveHoldID: number = -1;\n private _dragHoldID: number = -1;\n private _dropHoldID: number = -1;\n private _upHoldID: number = -1;\n private _outHoldID: number = -1;\n private _lastMoveEvent: UIActionEvent | undefined;\n\n /**\n * Create a dragger which has all the states in UIButton, with additional \"dragging\" (a boolean indicating whether it's currently being dragged) and \"offset\" (a Pt representing the offset between this UI's position and the pointer's position when dragged) states. (See [`UI.state`](#link)) You may also create a new UIDragger using one of the static helper like [`UI.fromRectangle`](#link) or [`UI.fromCircle`](#link).\n * @param group a Group or an Iterable<PtLike> that defines the UI's appearance\n * @param shape specifies the shape of the Group\n * @param states Optional default state object\n * @param id Optional id string\n */\n constructor(\n group: PtLikeIterable,\n shape: string,\n states: { [key: string]: any } = {},\n id?: string,\n ) {\n super(group, shape, states, id);\n if (states.dragging === undefined) this._states[\"dragging\"] = false;\n if (states.moved === undefined) this._states[\"moved\"] = false;\n if (states.offset === undefined) this._states[\"offset\"] = new Pt();\n\n const UA = UIPointerActions;\n\n /*\n * Note: drag/drop is implemented in Space.ts, uidrag/uidrop is\n * reimplemented here so that we can keep track of move events happening\n * outside of the UI element. E.g. when the mouse moves faster than the\n * UI refreshes.\n */\n\n // Handle pointer down and begin dragging\n this._sysOn(\n UA.down,\n (target: UI, pt: PtLike, type: string, evt: UIActionEvent) => {\n // begin listening for all events after dragging starts\n if (this._moveHoldID === -1) {\n this.state(\"dragging\", true);\n this.state(\"offset\", new Pt(pt).subtract(target.group[0]));\n this._moveHoldID = this.hold(UA.move); // keep hold of move\n this._dragHoldID = this.hold(UA.drag);\n this._outHoldID = this.hold(UA.out);\n }\n if (this._dropHoldID === -1) {\n this._dropHoldID = this.hold(UA.drop); // keep hold of drop (normal drag and drop)\n }\n if (this._upHoldID === -1) {\n this._upHoldID = this.hold(UA.up); // keep hold of up (cancel dragging if simple click)\n }\n if (this._draggingID === -1) {\n const drag = (t: UI, p: PtLike, ty: string, e: UIActionEvent) => {\n // Touch movement forwards both move and drag for the same event.\n const paired = ty === UA.drag && e === this._lastMoveEvent;\n this._lastMoveEvent = ty === UA.move ? e : undefined;\n if (paired) return;\n if (this.state(\"dragging\")) {\n UI._trigger(this._actions[UA.uidrag], t, p, UA.uidrag, e);\n this.state(\"moved\", true);\n }\n };\n this._draggingID = this._sysOn(UA.move, drag);\n this._dragID = this._sysOn(UA.drag, drag);\n }\n },\n );\n\n // Handle pointer drop or up and end dragging\n const endDrag = (\n target: UI,\n pt: PtLike,\n type: string,\n evt: UIActionEvent,\n ) => {\n this.state(\"dragging\", false);\n // remove move listener\n this._sysOff(UA.move, this._draggingID);\n this._sysOff(UA.drag, this._dragID);\n this._draggingID = -1;\n this._dragID = -1;\n this._lastMoveEvent = undefined;\n // stop keeping hold of move\n this.unhold(this._moveHoldID);\n this._moveHoldID = -1;\n this.unhold(this._dragHoldID);\n this._dragHoldID = -1;\n this.unhold(this._outHoldID);\n this._outHoldID = -1;\n // stop keeping hold of drop\n this.unhold(this._dropHoldID);\n this._dropHoldID = -1;\n // stop keeping hold of up\n this.unhold(this._upHoldID);\n this._upHoldID = -1;\n // trigger event\n if (this.state(\"moved\")) {\n UI._trigger(this._actions[UA.uidrop], target, pt, UA.uidrop, evt);\n this.state(\"moved\", false);\n }\n };\n this._sysOn(UA.drop, endDrag);\n this._sysOn(UA.up, endDrag);\n this._sysOn(UA.out, endDrag);\n }\n\n /**\n * Add a new drag handler. Remember this button will also need to be tracked for events via `UI.track`.\n * @param fn a [`UIHandler`](#link) callback function: `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`. You can access the states \"dragging\" and \"offset\" (See [`UI.state`](#link)) in the callback.\n * @returns an id number that refers to this handler, for use in [`UIDragger.offDrag`](#link) or [`UI.off`](#link).\n */\n onDrag(fn: UIHandler): number {\n return this.on(UIPointerActions.uidrag, fn);\n }\n\n /**\n * Remove an existing drag handler\n * @param id an ID number returned by [`UIDragger.onDrag`](#link). If this is not defined, all handlers in this type will be removed.\n * @returns a boolean indicating whether the handler was removed successfully\n */\n offDrag(id: number): boolean {\n return this.off(UIPointerActions.uidrag, id);\n }\n\n /**\n * Add a new drop handler. Remember this button will also need to be tracked for events via `UI.track`.\n * @param fn a [`UIHandler`](#link) callback function: `fn( target:UI, pt:Pt, type:string, evt:MouseEvent )`\n * @returns an id number that refers to this handler, for use in [`UIDragger.offDrop`](#link) or [`UI.off`](#link).\n */\n onDrop(fn: UIHandler): number {\n return this.on(UIPointerActions.uidrop, fn);\n }\n\n /**\n * Remove an existing drop handler\n * @param id an ID number returned by [`UIDragger.onDrag`](#link). If this is not defined, all handlers in this type will be removed.\n * @returns a boolean indicating whether the handler was removed successfully\n */\n offDrop(id: number): boolean {\n return this.off(UIPointerActions.uidrop, id);\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Bound } from \"./Pt\";\nimport { type Form } from \"./Form\";\nimport { UI, UIPointerActions as UIA } from \"./UI\";\nimport {\n type ITimer,\n type ISpacePlayers,\n type IPlayer,\n type AnimateCallbackFn,\n type TouchPointsKey,\n type UIActionEvent,\n} from \"./Types\";\n\n/**\n * Space is an abstract class that represents a general context for expressing Pts. It's extended through subclasses such as [`CanvasSpace`](#link) and [`SVGSpace`](#link). You can also create your own extension of Space.\n * See [Space guide](../guide/Space-0500.html) for details.\n */\nexport abstract class Space {\n id: string = \"space\";\n protected bound: Bound = new Bound();\n\n protected _time: ITimer = { prev: 0, diff: 0, end: -1, min: 0 };\n private _stopAfter = -1; // a stop(t) period awaiting the next frame's clock\n protected players: ISpacePlayers = {};\n protected playerCount = 0;\n protected _ctx: any;\n\n private _animID: number = -1;\n private _fromFrame = false;\n\n private _pause: boolean = false;\n private _refresh: boolean | undefined = undefined;\n private _renderFunc!: (context: any, self: Space) => null;\n\n protected _pointer: Pt = new Pt();\n\n protected _isReady = false;\n protected _playing = false;\n private _firstFrame = true;\n\n /**\n * Set whether the rendering should be repainted on each frame.\n * @param b a boolean value to set whether to repaint each frame\n */\n refresh(b: boolean): this {\n this._refresh = b;\n return this;\n }\n\n /**\n * Set a minimum frame time\n * @param ms at least this amount of milliseconds must have elapsed before frame advances\n */\n minFrameTime(ms: number = 0): this {\n this._time.min = ms;\n return this;\n }\n\n /**\n * Add an [`IPlayer`](#link) object or a [`AnimateCallbackFn`](#link) callback function to handle events in this Space. An IPlayer is an object with the following callback functions:\n * - required: `animate: fn( time, ftime, space )`\n * - optional: `start: fn(bound, space)`\n * - optional: `resize: fn( size, event )`\n * - optional: `action: fn( type, x, y, event )`\n * Subclasses of Space may define other callback functions.\n * @param p an [`IPlayer`](#link) object with animate function, or a callback function `fn(time, ftime)`.\n */\n add(p: IPlayer | AnimateCallbackFn): this {\n const player: IPlayer = typeof p == \"function\" ? { animate: p } : p;\n\n const k = this.playerCount++;\n const pid = player.animateID || this.id + k;\n\n this.players[pid] = player;\n player.animateID = pid;\n // resize callbacks receive the live bound (as they do on space resize);\n // treat it as read-only\n if (player.resize && this.bound.inited) player.resize(this.bound);\n\n // if _refresh is not set, set it to true\n if (this._refresh === undefined) this._refresh = true;\n\n return this;\n }\n\n /**\n * Remove a player from this Space.\n * @param player an IPlayer that has an `animateID` property\n */\n remove(player: IPlayer): this {\n delete this.players[player.animateID!];\n return this;\n }\n\n /**\n * Remove all players from this Space.\n */\n removeAll(): this {\n this.players = {};\n return this;\n }\n\n /**\n * Main play loop. This implements `window.requestAnimationFrame` and calls it recursively.\n * You may override this `play()` function to implement your own animation loop.\n * @param time current time\n */\n play(time = 0): this {\n // A real RAF can have timestamp 0 too. Consume its marker before invoking\n // players so a nested manual play() still cannot start a second loop.\n const fromFrame = this._fromFrame;\n this._fromFrame = false;\n // make sure only one play loop is active: an external play() while the\n // loop runs is a no-op...\n if (time === 0 && this._animID !== -1 && !fromFrame) {\n return this;\n }\n // ...and any other call (a frame callback, or a manual play(t)) replaces\n // the pending frame instead of stacking a parallel chain — cancelling an\n // already-fired frame id is a spec-defined no-op\n if (this._animID !== -1) cancelAnimationFrame(this._animID);\n this._animID = requestAnimationFrame((frameTime) => {\n this._fromFrame = true;\n try {\n this.play(frameTime);\n } finally {\n this._fromFrame = false;\n }\n });\n\n if (this._pause) {\n // track time while paused so resuming doesn't deliver the entire\n // pause duration as one frame's ftime\n this._time.prev = time;\n return this;\n }\n\n if (this._firstFrame) {\n // the first frame after a fresh start renders immediately with no\n // elapsed time — `time` is an arbitrary clock timestamp, not a delta\n // play() draws synchronously at synthetic time 0. Keep initialization\n // pending until RAF supplies its first real clock timestamp.\n this._firstFrame = time === 0 && !fromFrame;\n this._time.diff = 0;\n this._time.prev = time;\n } else {\n const diff = time - this._time.prev;\n // accumulate until the minimum frame time is reached\n if (diff < this._time.min) return this;\n this._time.diff = diff;\n this._time.prev = time;\n }\n\n try {\n this.playItems(time);\n } catch (err) {\n cancelAnimationFrame(this._animID);\n this._animID = -1;\n this._playing = false;\n this._firstFrame = true;\n throw err;\n }\n\n return this;\n }\n\n /**\n * Replay the animation after [`Space.stop`](#link). This resets the end-time counter.\n * You may also use [`Space.pause`](#link) and [`resume`](#link) for temporary pause.\n */\n replay() {\n this._time.end = -1;\n this.play();\n }\n\n /**\n * Main animate function. This calls all the items to perform.\n * @param time current time\n */\n protected playItems(time: number) {\n this._playing = true;\n\n // clear before draw if refresh is true\n if (this._refresh) this.clear();\n\n // animate all players\n if (this._isReady) {\n for (const k in this.players) {\n if (this.players[k].animate)\n this.players[k].animate(time, this._time.diff, this);\n }\n }\n\n // resolve a stop period against the frame clock\n if (this._stopAfter >= 0) {\n this._time.end = time + this._stopAfter;\n this._stopAfter = -1;\n }\n\n // stop if time ended\n if (this._time.end >= 0 && time > this._time.end) {\n cancelAnimationFrame(this._animID);\n this._animID = -1;\n this._playing = false;\n this._firstFrame = true;\n }\n }\n\n /**\n * Pause the animation.\n * @param toggle a boolean value to set if this function call should be a toggle (between pause and resume)\n */\n pause(toggle = false): this {\n this._pause = toggle ? !this._pause : true;\n return this;\n }\n\n /**\n * Resume the pause animation.\n */\n resume(): this {\n this._pause = false;\n return this;\n }\n\n /**\n * Specify when the animation should stop: immediately, after a time period, or never stops.\n * After stopping, use [`Space.replay`](#link) to play again.\n * @param t a value in millisecond to specify a time period to play before stopping, or `-1` to play forever, or `0` to end immediately. Default is 0 which will stop the animation immediately.\n */\n stop(t = 0): this {\n // a period is measured from the next frame's clock, since frame\n // timestamps are absolute and not comparable with a duration\n this._stopAfter = t > 0 ? t : -1;\n this._time.end = t > 0 ? -1 : t;\n return this;\n }\n\n /**\n * Cancel the active animation frame immediately. Subclasses should call this\n * when they dispose browser resources instead of waiting for `stop()` to be\n * observed by the next frame.\n */\n protected _cancelAnimation(): this {\n if (this._animID !== -1) cancelAnimationFrame(this._animID);\n this._animID = -1;\n this._playing = false;\n this._firstFrame = true;\n return this;\n }\n\n /**\n * Play animation loop once. Optionally set a `duration` time to play for that specific duration.\n * @param duration a value in millisecond to specify a time period to play before stopping, or `-1` to play forever\n */\n playOnce(duration = 0): this {\n this.play();\n this.stop(duration);\n return this;\n }\n\n /**\n * Custom rendering.\n * @param context rendering context\n */\n protected render(context: any): this {\n if (this._renderFunc) this._renderFunc(context, this);\n return this;\n }\n\n /**\n * Set a custom rendering function `fn(graphics_context, canvas_space)` if needed.\n */\n set customRendering(f: (context: any, self: Space) => null) {\n this._renderFunc = f;\n }\n get customRendering(): (context: any, self: Space) => null {\n return this._renderFunc;\n }\n\n /**\n * Indicate whether the animation is playing.\n */\n get isPlaying(): boolean {\n return this._playing;\n }\n\n /**\n * The outer bounding box which includes its positions.\n */\n get outerBound(): Bound {\n return this.bound.clone();\n }\n\n /**\n * The inner bounding box of the space, excluding its positions.\n */\n public get innerBound(): Bound {\n return new Bound(Pt.make(this.size.length, 0), this.size.clone());\n }\n\n /**\n * The size of this space's bounding box.\n */\n get size(): Pt {\n return this.bound.size.clone();\n }\n\n /**\n * The center of this space's bounding box.\n */\n get center(): Pt {\n return this.size.divide(2);\n }\n\n /**\n * The width of this space's bounding box.\n */\n get width(): number {\n return this.bound.width;\n }\n\n /**\n * The height of this space's bounding box.\n */\n get height(): number {\n return this.bound.height;\n }\n\n /**\n * Resize the space. To be implemented in subclasses.\n * @param b a Bound representing the position and size of the space\n * @param evt event\n */\n abstract resize(b: Bound, evt?: Event | null): this;\n\n /**\n * clear all contents in the space. To be implemented in subclasses.\n */\n abstract clear(): this;\n\n /**\n * Get a default form for drawing in this space. To be implemented in subclasses.\n */\n abstract getForm(): Form;\n}\n\n/**\n * MultiTouchSpace is an abstract class that extends [`Space`](#link) to support user interactions via touch events.\n * It's extended through subclasses such as [`CanvasSpace`](#link) and [`SVGSpace`](#link).\n */\nexport abstract class MultiTouchSpace extends Space {\n // track mouse dragging\n protected _pressed = false;\n protected _dragged = false;\n\n protected _hasMouse = false;\n protected _hasTouch = false;\n protected _hasKeyboard = false;\n\n private _mouseTarget: Element | undefined;\n private _touchTarget: Element | undefined;\n private _keyboardTarget: EventTarget | undefined;\n private _touchPassive = false;\n\n private readonly _mouseDownBind = this._mouseDown.bind(\n this,\n ) as unknown as EventListener;\n private readonly _mouseUpBind = this._mouseUp.bind(\n this,\n ) as unknown as EventListener;\n private readonly _mouseOverBind = this._mouseOver.bind(\n this,\n ) as unknown as EventListener;\n private readonly _mouseOutBind = this._mouseOut.bind(\n this,\n ) as unknown as EventListener;\n private readonly _mouseMoveBind = this._mouseMove.bind(\n this,\n ) as unknown as EventListener;\n private readonly _mouseClickBind = this._mouseClick.bind(\n this,\n ) as unknown as EventListener;\n private readonly _contextMenuBind = this._contextMenu.bind(\n this,\n ) as unknown as EventListener;\n private readonly _touchStartBind = this._touchStart.bind(\n this,\n ) as unknown as EventListener;\n private readonly _touchMoveBind = this._touchMove.bind(\n this,\n ) as unknown as EventListener;\n private readonly _keyDownBind = this._keyDown.bind(\n this,\n ) as unknown as EventListener;\n private readonly _keyUpBind = this._keyUp.bind(\n this,\n ) as unknown as EventListener;\n\n // accept subclasses that implements addEventListener, removeEventListener, dispatchEvent\n protected _canvas!: EventTarget;\n\n /**\n * Get the mouse or touch pointer that stores the last action.\n */\n public get pointer(): Pt {\n const p = this._pointer.clone();\n p.id = this._pointer.id;\n return p;\n }\n\n /**\n * Bind event listener in canvas element. You can also use [`MultiTouchSpace.bindMouse`](#link) or [`MultiTouchSpace.bindTouch`](#link) to bind mouse or touch events conveniently.\n * @param evt an event string such as \"mousedown\"\n * @param callback callback function for this event\n * @param options options for [addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener).\n * @param customTarget an optional event target to use instead of the canvas element\n */\n bindCanvas(\n evt: string,\n callback: EventListener,\n options: any = {},\n customTarget?: Element,\n ) {\n const target = customTarget ? customTarget : this._canvas;\n target.addEventListener(evt, callback, options);\n }\n\n /**\n * Unbind a callback from the event listener.\n * @param evt an event string such as \"mousedown\"\n * @param callback callback function to unbind\n * @param options options for [removeEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener). This should match the options set in bindCanvas.\n * @param customTarget If customTarget is set in bindCanvas, you'll need to pass the same instance here to unbind\n */\n unbindCanvas(\n evt: string,\n callback: EventListener,\n options: any = {},\n customTarget?: Element,\n ) {\n const target = customTarget ? customTarget : this._canvas;\n target.removeEventListener(evt, callback, options);\n }\n\n bindDoc(evt: string, callback: EventListener, options: any = {}) {\n if (typeof document !== \"undefined\") {\n document.addEventListener(evt, callback, options);\n }\n }\n\n unbindDoc(evt: string, callback: EventListener, options: any = {}) {\n if (typeof document !== \"undefined\") {\n document.removeEventListener(evt, callback, options);\n }\n }\n\n /**\n * A convenient method to bind (or unbind) all mouse events in canvas element.\n * All [`IPlayer`](#link) objects added to this space that implement an `action` callback property will receive mouse event callbacks.\n * Mouse action names are defined by [`UIPointerActions`](#link), including \"up\", \"down\", \"move\", \"drag\", \"drop\", \"over\", \"out\", \"click\", \"pointerdown\", \"pointerup\", and \"contextmenu\".\n * @param bind a boolean value to bind mouse events if set to `true`. If `false`, all mouse events will be unbound. Default is true.\n * @param customTarget an optional event target to use instead of the canvas element\n * @see [`Space.add`](#link)\n */\n bindMouse(bind: boolean = true, customTarget?: Element): this {\n if (bind) {\n if (this._hasMouse) {\n if (this._mouseTarget === customTarget) return this;\n this.bindMouse(false);\n }\n\n this._mouseTarget = customTarget;\n this.bindCanvas(\"pointerdown\", this._mouseDownBind, {}, customTarget);\n this.bindCanvas(\"pointerup\", this._mouseUpBind, {}, customTarget);\n this.bindCanvas(\"pointerover\", this._mouseOverBind, {}, customTarget);\n this.bindCanvas(\"pointerout\", this._mouseOutBind, {}, customTarget);\n this.bindCanvas(\"pointercancel\", this._mouseOutBind, {}, customTarget);\n this.bindCanvas(\"pointermove\", this._mouseMoveBind, {}, customTarget);\n this.bindCanvas(\"click\", this._mouseClickBind, {}, customTarget);\n this.bindCanvas(\"contextmenu\", this._contextMenuBind, {}, customTarget);\n this._hasMouse = true;\n } else if (this._hasMouse) {\n const target = this._mouseTarget;\n this.unbindCanvas(\"pointerdown\", this._mouseDownBind, {}, target);\n this.unbindCanvas(\"pointerup\", this._mouseUpBind, {}, target);\n this.unbindCanvas(\"pointerover\", this._mouseOverBind, {}, target);\n this.unbindCanvas(\"pointerout\", this._mouseOutBind, {}, target);\n this.unbindCanvas(\"pointercancel\", this._mouseOutBind, {}, target);\n this.unbindCanvas(\"pointermove\", this._mouseMoveBind, {}, target);\n this.unbindCanvas(\"click\", this._mouseClickBind, {}, target);\n this.unbindCanvas(\"contextmenu\", this._contextMenuBind, {}, target);\n this._hasMouse = false;\n this._mouseTarget = undefined;\n }\n return this;\n }\n\n /**\n * A convenient method to bind (or unbind) all touch events in canvas element.\n * All [`IPlayer`](#link) objects added to this space that implement an `action` callback property will receive touch event callbacks.\n * Touch action names are defined by [`UIPointerActions`](#link), including \"up\", \"down\", \"move\", \"drag\", \"drop\", \"over\", and \"out\".\n * @param bind a boolean value to bind touch events if set to `true`. If `false`, all touch events will be unbound. Default is true.\n * @param passive a boolean value to set passive mode, ie, it won't block scrolling. Default is false.\n * @param customTarget an optional event target to use instead of the canvas element\n * @see [`Space.add`](#link)\n */\n bindTouch(\n bind: boolean = true,\n passive: boolean = false,\n customTarget?: Element,\n ): this {\n if (bind) {\n if (this._hasTouch) {\n if (\n this._touchTarget === customTarget &&\n this._touchPassive === passive\n )\n return this;\n this.bindTouch(false);\n }\n\n this._touchTarget = customTarget;\n this._touchPassive = passive;\n this.bindCanvas(\n \"touchstart\",\n this._touchStartBind,\n { passive: passive },\n customTarget,\n );\n this.bindCanvas(\"touchend\", this._mouseUpBind, {}, customTarget);\n this.bindCanvas(\n \"touchmove\",\n this._touchMoveBind,\n { passive: passive },\n customTarget,\n );\n this.bindCanvas(\"touchcancel\", this._mouseOutBind, {}, customTarget);\n this._hasTouch = true;\n } else if (this._hasTouch) {\n const target = this._touchTarget;\n const options = { passive: this._touchPassive };\n this.unbindCanvas(\"touchstart\", this._touchStartBind, options, target);\n this.unbindCanvas(\"touchend\", this._mouseUpBind, {}, target);\n this.unbindCanvas(\"touchmove\", this._touchMoveBind, options, target);\n this.unbindCanvas(\"touchcancel\", this._mouseOutBind, {}, target);\n this._hasTouch = false;\n this._touchTarget = undefined;\n }\n return this;\n }\n\n /**\n * Bind or unbind keyboard events. Events are attached to `document` by\n * default, or to `customTarget` when one is provided.\n */\n bindKeyboard(bind: boolean = true, customTarget?: EventTarget): this {\n if (bind) {\n const target = customTarget || document;\n if (this._hasKeyboard) {\n if (this._keyboardTarget === target) return this;\n this.bindKeyboard(false);\n }\n\n target.addEventListener(\"keydown\", this._keyDownBind, {});\n target.addEventListener(\"keyup\", this._keyUpBind, {});\n this._keyboardTarget = target;\n this._hasKeyboard = true;\n } else if (this._hasKeyboard) {\n this._keyboardTarget!.removeEventListener(\n \"keydown\",\n this._keyDownBind,\n {},\n );\n this._keyboardTarget!.removeEventListener(\"keyup\", this._keyUpBind, {});\n this._keyboardTarget = undefined;\n this._hasKeyboard = false;\n }\n return this;\n }\n\n /** Unbind all pointer, touch, and keyboard listeners owned by this space. */\n protected _unbindAll(): this {\n this.bindMouse(false);\n this.bindTouch(false);\n this.bindKeyboard(false);\n return this;\n }\n\n private _trackedUIs: UI[] = [];\n private _uiPlayer: IPlayer | null = null;\n\n /** Remove all players and the UI registrations forwarded by them. */\n removeAll(): this {\n this.untrack();\n this._uiPlayer = null;\n return super.removeAll();\n }\n\n /**\n * Track one or more [`UI`](#link) elements: every pointer, touch, and keyboard\n * action dispatched by this space is forwarded to them via [`UI.track`](#link),\n * so no manual `action` wiring is needed. Remember to also bind the events,\n * eg via [`MultiTouchSpace.bindMouse`](#link). Keyboard actions are forwarded\n * too (their x/y carry the shift/alt flags, as the space dispatches them).\n * @param uis a UI, or an array of UIs\n */\n track(uis: UI | UI[]): this {\n const list = Array.isArray(uis) ? uis : [uis];\n for (let i = 0, len = list.length; i < len; i++) {\n if (this._trackedUIs.indexOf(list[i]) < 0) this._trackedUIs.push(list[i]);\n }\n if (!this._uiPlayer) {\n this._uiPlayer = {\n animate: () => {},\n action: (type: string, px: number, py: number, evt: Event) => {\n UI.track(this._trackedUIs, type, new Pt(px, py), evt as MouseEvent);\n },\n };\n this.add(this._uiPlayer);\n }\n return this;\n }\n\n /**\n * Stop tracking one or more [`UI`](#link) elements added via [`MultiTouchSpace.track`](#link).\n * @param uis a UI or an array of UIs to remove from tracking, or omit to stop tracking all\n */\n untrack(uis?: UI | UI[]): this {\n const list =\n uis === undefined\n ? this._trackedUIs.slice()\n : Array.isArray(uis)\n ? uis\n : [uis];\n for (let i = 0, len = list.length; i < len; i++) {\n const at = this._trackedUIs.indexOf(list[i]);\n if (at < 0) continue;\n this._trackedUIs.splice(at, 1);\n // a dragger removed mid-drag would otherwise stay \"dragging\" and\n // resume on its next move without a press; end the drag as a drop\n if (list[i].state(\"dragging\")) {\n list[i].listen(\n UIA.drop,\n this._pointer,\n new Event(\"pointercancel\") as unknown as UIActionEvent,\n );\n }\n }\n return this;\n }\n\n // Input is relative to the rendered element, not a cached container position\n // or the event target (which may be an overlay). Read once per event.\n private _inputTransform(): [number, number, number, number] {\n if (typeof Element !== \"undefined\" && this._canvas instanceof Element) {\n const rect = this._canvas.getBoundingClientRect();\n return [\n rect.left,\n rect.top,\n rect.width ? this.width / rect.width : 1,\n rect.height ? this.height / rect.height : 1,\n ];\n }\n // Non-DOM subclasses may supply their own EventTarget and explicit bounds.\n return [\n this.bound.topLeft.x -\n (typeof window === \"undefined\" ? 0 : window.scrollX),\n this.bound.topLeft.y -\n (typeof window === \"undefined\" ? 0 : window.scrollY),\n 1,\n 1,\n ];\n }\n\n /**\n * A convenient method to convert the touch points in a touch event to an array of Pts.\n * @param evt a touch event which contains touches, changedTouches, and targetTouches list\n * @param which a string to select a touches list: \"touches\", \"changedTouches\", or \"targetTouches\". Default is \"touches\"\n * @return an array of Pt, whose origin position (0,0) is offset to the top-left of this space\n */\n touchesToPoints(evt: TouchEvent, which: TouchPointsKey = \"touches\"): Pt[] {\n if (!evt || !evt[which]) return [];\n const ts = [];\n const [left, top, scaleX, scaleY] = this._inputTransform();\n for (let i = 0; i < evt[which].length; i++) {\n const t = evt[which].item(i)!;\n ts.push(new Pt((t.clientX - left) * scaleX, (t.clientY - top) * scaleY));\n }\n return ts;\n }\n\n /**\n * Go through all the added [`IPlayer`](#link) objects and call its `action` callback function.\n * @param type a [`UIPointerActions`](#link) constant or custom action string\n * @param evt mouse or touch event\n * @see [`Space.add`](#link)\n */\n protected _mouseAction(\n type: string,\n evt: MouseEvent | TouchEvent | PointerEvent,\n ) {\n if (!this.isPlaying) return;\n\n // compute the event position once — not per player, and independent of\n // whether any player is registered (the pointer must track regardless)\n const [left, top, scaleX, scaleY] = this._inputTransform();\n let px = 0,\n py = 0;\n\n if (evt instanceof MouseEvent) {\n px = (evt.clientX - left) * scaleX;\n py = (evt.clientY - top) * scaleY;\n } else {\n const touch =\n evt.changedTouches && evt.changedTouches.length > 0\n ? evt.changedTouches.item(0)\n : null;\n if (touch) {\n px = (touch.clientX - left) * scaleX;\n py = (touch.clientY - top) * scaleY;\n }\n }\n\n if (type) {\n this._pointer.to(px, py);\n this._pointer.id = type;\n }\n\n for (const k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n const v = this.players[k];\n if (v.action) v.action(type, px, py, evt);\n }\n }\n }\n\n // Ignore the duplicate pointer stream only when this event also reaches our\n // touch listener. Mouse and touch bindings may use separate custom targets.\n private _isTouchHandled(evt: PointerEvent | TouchEvent): boolean {\n return (\n \"pointerType\" in evt &&\n evt.pointerType === \"touch\" &&\n this._hasTouch &&\n evt.composedPath().includes(this._touchTarget || this._canvas)\n );\n }\n\n /**\n * MouseDown handler.\n * @param evt\n */\n protected _mouseDown(evt: PointerEvent) {\n if (this._isTouchHandled(evt)) return false;\n this._mouseAction(UIA.down, evt);\n this._mouseAction(UIA.pointerdown, evt);\n this._pressed = true;\n if (evt.target instanceof Element) {\n try {\n evt.target.setPointerCapture(evt.pointerId);\n } catch {\n // a synthetic or re-dispatched event has no active pointer to capture;\n // dragging still works through the element's own move/up listeners\n }\n }\n return false;\n }\n\n /**\n * MouseUp handler.\n * @param evt\n */\n protected _mouseUp(evt: PointerEvent | TouchEvent) {\n if (this._isTouchHandled(evt)) return false;\n this._mouseAction(UIA.pointerup, evt);\n if (this._dragged) {\n this._mouseAction(UIA.drop, evt);\n } else {\n this._mouseAction(UIA.up, evt);\n }\n this._pressed = false;\n this._dragged = false;\n if (\n evt instanceof PointerEvent &&\n evt.target instanceof Element &&\n evt.target.hasPointerCapture(evt.pointerId)\n ) {\n evt.target.releasePointerCapture(evt.pointerId);\n }\n return false;\n }\n\n /**\n * MouseMove handler.\n * @param evt\n */\n protected _mouseMove(evt: PointerEvent) {\n if (this._isTouchHandled(evt)) return false;\n if (this._pressed) {\n this._dragged = true;\n this._mouseAction(UIA.drag, evt);\n } else {\n this._mouseAction(UIA.move, evt);\n }\n return false;\n }\n\n /**\n * MouseOver handler.\n * @param evt\n */\n protected _mouseOver(evt: PointerEvent) {\n if (this._isTouchHandled(evt)) return false;\n this._mouseAction(UIA.over, evt);\n return false;\n }\n\n /**\n * MouseOut handler.\n * @param evt\n */\n protected _mouseOut(evt: PointerEvent | TouchEvent) {\n if (this._isTouchHandled(evt)) return false;\n this._mouseAction(UIA.out, evt);\n if (this._dragged) this._mouseAction(UIA.drop, evt);\n this._pressed = false;\n this._dragged = false;\n return false;\n }\n\n /**\n * MouseClick handler.\n * @param evt\n */\n protected _mouseClick(evt: MouseEvent | TouchEvent) {\n this._mouseAction(UIA.click, evt);\n this._pressed = false;\n this._dragged = false;\n return false;\n }\n\n /**\n * ContextMenu handler.\n * @param evt\n */\n protected _contextMenu(evt: MouseEvent) {\n this._mouseAction(UIA.contextmenu, evt);\n return false;\n }\n\n /**\n * TouchMove handler.\n * @param evt\n */\n protected _touchMove(evt: TouchEvent) {\n this._mouseAction(UIA.move, evt);\n if (this._pressed) {\n this._dragged = true;\n this._mouseAction(UIA.drag, evt);\n }\n // preventDefault is ignored (and logs an error) inside passive listeners\n if (!this._touchPassive) evt.preventDefault();\n return false;\n }\n\n /**\n * TouchStart handler.\n * @param evt\n */\n protected _touchStart(evt: TouchEvent) {\n this._mouseAction(UIA.down, evt);\n this._pressed = true;\n if (!this._touchPassive) evt.preventDefault();\n return false;\n }\n\n protected _keyDown(evt: KeyboardEvent) {\n this._keyboardAction(UIA.keydown, evt);\n return false;\n }\n\n protected _keyUp(evt: KeyboardEvent) {\n this._keyboardAction(UIA.keyup, evt);\n return false;\n }\n\n protected _keyboardAction(type: string, evt: KeyboardEvent) {\n if (!this.isPlaying) return;\n for (const k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n const v = this.players[k];\n if (v.action)\n v.action(type, evt.shiftKey ? 1 : 0, evt.altKey ? 1 : 0, evt);\n }\n }\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { type Pt } from \"./Pt\";\nimport { Util } from \"./Util\";\nimport { type PtLike, type GroupLike } from \"./Types\";\n\n/**\n * Form is an abstract class that represents a form that's used in a Space for expressions. Learn more about Space and Form in [this guide](../guide/Space-0500.html).\n */\nexport abstract class Form {\n protected _ready: boolean = false;\n\n /**\n * get whether the Form has received the Space's rendering context.\n */\n get ready(): boolean {\n return this._ready;\n }\n}\n\n/**\n * VisualForm is an abstract class that represents a form that can be used to express Pts visually.\n * For example, [`CanvasForm`](#link) is an implementation of VisualForm that draws on [`CanvasSpace`](#link) which represents a html canvas. Learn more about Space and Form in [this guide](../guide/Space-0500.html).\n */\nexport abstract class VisualForm extends Form {\n protected _filled = true;\n protected _stroked = true;\n protected _font: Font = new Font(14, \"sans-serif\");\n\n /**\n * Check whether this form currently has fill style.\n */\n get filled(): boolean {\n return this._filled;\n }\n set filled(b: boolean) {\n this._filled = b;\n }\n\n /**\n * Check whether this form currently has stroke style.\n */\n get stroked(): boolean {\n return this._stroked;\n }\n set stroked(b: boolean) {\n this._stroked = b;\n }\n\n /**\n * Get the current font in use in this form.\n */\n get currentFont(): Font {\n return this._font;\n }\n\n protected _multiple(\n groups: GroupLike[],\n shape: string,\n ...rest: unknown[]\n ): this {\n if (!groups) return this;\n for (let i = 0, len = groups.length; i < len; i++) {\n // dynamic dispatch to the named shape method\n (this as any)[shape](groups[i], ...rest);\n }\n return this;\n }\n\n /**\n * Abstract reset style\n */\n abstract reset(): this;\n\n /**\n * Set alpha (not implemented here -- to be implemented in subclasses).\n * @param a alpha value between 0 and 1\n */\n alpha(a: number): this {\n return this;\n }\n\n /**\n * Set fill color (not implemented here -- to be implemented in subclasses).\n * @param c fill color as string or `false` to specify transparent.\n */\n fill(c: string | boolean): this {\n return this;\n }\n\n /**\n * Set current fill style and remove stroke style. (not implemented here -- to be implemented in subclasses).\n * @param c fill color as string or `false` to specify transparent.\n */\n fillOnly(c: string | boolean): this {\n this.stroke(false);\n return this.fill(c);\n }\n\n /**\n * Set stroke style (not implemented here -- to be implemented in subclasses).\n * @param c stroke color as string or `false` to specify transparent.\n * @param width Optional value (can be floating point) to set line width\n * @param linejoin Optional string to set line joint style. Can be \"miter\", \"bevel\", or \"round\".\n * @param linecap Optional string to set line cap style. Can be \"butt\", \"round\", or \"square\".\n */\n stroke(\n c: string | boolean,\n width?: number,\n linejoin?: string,\n linecap?: string,\n ): this {\n return this;\n }\n\n /**\n * Set stroke style and remove fill style. (not implemented here -- to be implemented in subclasses).\n * @param c stroke color as string or `false` to specify transparent.\n * @param width Optional value (can be floating point) to set line width\n * @param linejoin Optional string to set line joint style. Can be \"miter\", \"bevel\", or \"round\".\n * @param linecap Optional string to set line cap style. Can be \"butt\", \"round\", or \"square\".\n */\n strokeOnly(\n c: string | boolean,\n width?: number,\n linejoin?: string,\n linecap?: string,\n ): this {\n this.fill(false);\n return this.stroke(c, width, linejoin, linecap);\n }\n\n /**\n * Draw a point (not implemented here -- to be implemented in subclasses).\n * @param p a Pt object\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `form.point( p )`, `form.point( p, 10, \"circle\" )`\n */\n abstract point(p: PtLike, radius: number, shape: string): this;\n\n /**\n * Draw multiple points at once.\n * @param pts an array of Pt or an array of number arrays\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n */\n points(pts: GroupLike | number[][], radius: number, shape: string): this {\n if (!pts) return this;\n for (let i = 0, len = pts.length; i < len; i++) {\n this.point(pts[i], radius, shape);\n }\n return this;\n }\n\n /**\n * Draw a circle (not implemented here -- to be implemented in subclasses).\n * @param pts usually a Group of 2 Pts, but it can also take an array of two numeric arrays [ [position], [size] ]\n * @see [`Circle.fromCenter`](#link)\n */\n abstract circle(pts: GroupLike | number[][]): this;\n\n /**\n * Draw multiple circles at once.\n * @param groups an array of Groups that defines multiple circles\n */\n circles(groups: GroupLike[]): this {\n return this._multiple(groups, \"circle\");\n }\n\n /**\n * Draw multiple squares at once.\n * @param groups an array of Groups that defines multiple circles\n */\n squares(groups: GroupLike[]): this {\n return this._multiple(groups, \"square\");\n }\n\n /**\n * Draw an arc (not implemented here -- to be implemented in subclasses).\n * @param pt center position\n * @param radius radius of the arc circle\n * @param startAngle start angle of the arc\n * @param endAngle end angle of the arc\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n abstract arc(\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): this;\n\n /**\n * Draw a line or polyline (not implemented here -- to be implemented in subclasses).\n * @param pts a Group of multiple Pts, or an array of multiple numeric arrays\n */\n abstract line(pts: GroupLike | number[][]): this;\n\n /**\n * Draw multiple lines at once.\n * @param groups An array of Groups of Pts\n */\n lines(groups: GroupLike[]): this {\n return this._multiple(groups, \"line\");\n }\n\n /**\n * Draw a polygon (not implemented here -- to be implemented in subclasses).\n * @param pts a Group of multiple Pts, or an array of multiple numeric arrays\n */\n abstract polygon(pts: GroupLike | number[][]): this;\n\n /**\n * Draw multiple polygons at once.\n * @param groups An array of Groups of Pts\n */\n polygons(groups: GroupLike[]): this {\n return this._multiple(groups, \"polygon\");\n }\n\n /**\n * Draw a rectangle (not implemented here -- to be implemented in subclasses).\n * @param pts usually a Group of 2 Pts specifying the top-left and bottom-right positions. Alternatively it can be an array of numeric arrays.\n */\n abstract rect(pts: number[][] | Pt[]): this;\n\n /**\n * Draw multiple rectangles at once.\n * @param groups An array of Groups of Pts\n */\n rects(groups: GroupLike[]): this {\n return this._multiple(groups, \"rect\");\n }\n\n /**\n * Draw text (not implemented here -- to be implemented in subclasses).\n * @param pt a Pt or numeric array to specify the anchor point\n * @param txt text\n * @param maxWidth specify a maximum width per line\n */\n abstract text(pt: PtLike, txt: string, maxWidth?: number): this;\n\n /**\n * Set font style (not implemented here -- to be implemented in subclasses).\n * @param sizeOrFont either a number to specify font-size, or a `Font` object to specify all font properties\n * @param weight Optional font-weight string such as \"bold\"\n * @param style Optional font-style string such as \"italic\"\n * @param lineHeight Optional line-height number suchas 1.5\n * @param family Optional font-family such as \"Helvetica, sans-serif\"\n * @see `Font` class\n * @example `form.font( myFont )`, `form.font(14, \"bold\")`\n */\n abstract font(\n sizeOrFont: number | Font,\n weight?: string,\n style?: string,\n lineHeight?: number,\n family?: string,\n ): this;\n}\n\n/**\n * Font class lets you create a specific font style with properties for its size and style. A font instance can be passed as parameter to set a form's font. For example, see [`CanvasForm.font`](#link).\n */\nexport class Font {\n public size: number;\n public lineHeight: number;\n public face: string;\n public style: string;\n public weight: string;\n\n /**\n * Create a font style.\n * @param size font size. Defaults is 12px.\n * @param face Optional font-family, use css-like string such as \"Helvetica\" or \"Helvetica, sans-serif\". Default is \"sans-serif\".\n * @param weight Optional font weight such as \"bold\". Default is \"\" (none).\n * @param style Optional font style such as \"italic\". Default is \"\" (none).\n * @param lineHeight Optional line height. Default is 1.5.\n * @example `new Font(12, \"Frutiger, sans-serif\", \"bold\", \"underline\", 1.5)`\n */\n constructor(\n size: number = 12,\n face: string = \"sans-serif\",\n weight: string = \"\",\n style: string = \"\",\n lineHeight: number = 1.5,\n ) {\n this.size = size;\n this.face = face;\n this.style = style;\n this.weight = weight;\n this.lineHeight = lineHeight;\n }\n\n /**\n * Get a string representing the font style, in css-like string such as \"italic bold 12px/1.5 sans-serif\".\n */\n get value(): string {\n const prefix = [this.style, this.weight].filter(Boolean).join(\" \");\n const base = `${this.size}px/${this.lineHeight} ${this.face}`;\n return prefix ? `${prefix} ${base}` : base;\n }\n\n /**\n * Get a string representing the font style, in css-like string such as \"italic bold 12px/1.5 sans-serif\".\n */\n toString(): string {\n return this.value;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Bound } from \"./Pt\";\nimport { Util } from \"./Util\";\nimport { type PtLikeIterable, type TextMeasure } from \"./Types\";\n\n/**\n * Typography provides helper functions to support typographic layouts. For a concrete example, see [a demo here](https://ptsjs.org/demo/?name=canvasform.textBox) that uses the [`CanvasForm.textBox`](#link) function.\n */\nexport class Typography {\n /**\n * Create a heuristic text width estimate function. It will be less accurate but faster.\n * @param fn a reference function that can measure text width accurately\n * @param samples a list of string samples. Default is [\"M\", \"n\", \".\"]\n * @param distribution a list of the samples' probability distribution, which should have the same length as `samples` and sum to 1. Default is [0.06, 0.8, 0.14]. (A distribution that sums to more or less than 1 will proportionally inflate or deflate every estimate.)\n * @return a function that can estimate text width\n */\n static textWidthEstimator(\n fn: TextMeasure,\n samples: string[] = [\"M\", \"n\", \".\"],\n distribution: number[] = [0.06, 0.8, 0.14],\n ): TextMeasure {\n if (samples.length !== distribution.length) {\n throw new Error(\n `textWidthEstimator: samples (${samples.length}) and distribution (${distribution.length}) must have the same length`,\n );\n }\n const m = samples.map(fn);\n const avg = new Pt(distribution).dot(m);\n return (text: string): number => text.length * avg;\n }\n\n /**\n * Create a memoizing text width function that measures each distinct character once and sums the cached widths. Nearly as accurate as the reference function for most texts (kerning and ligatures excepted) at close to estimator speed after warmup. The cache is keyed by character, so create a new instance whenever the font changes.\n * @param fn a reference function that can measure text width accurately\n * @return a function that measures text width using per-character caching\n */\n static charWidthCache(fn: TextMeasure): TextMeasure {\n // Latin-1 goes through a typed array — a Map lookup per character would\n // cost as much as the measurement it replaces. NaN marks \"not yet measured\".\n const latin = new Float64Array(256).fill(NaN);\n const cache = new Map<string, number>();\n return (text: string): number => {\n let sum = 0;\n for (let i = 0, len = text.length; i < len; i++) {\n const code = text.charCodeAt(i);\n if (code < 256) {\n let w = latin[code];\n if (w !== w) {\n w = fn(text[i]);\n latin[code] = w;\n }\n sum += w;\n } else {\n let ch = text[i];\n if (code >= 0xd800 && code <= 0xdbff && i + 1 < len) {\n ch += text[i + 1]; // measure a surrogate pair as one character\n i++;\n }\n let w = cache.get(ch);\n if (w === undefined) {\n w = fn(ch);\n cache.set(ch, w);\n }\n sum += w;\n }\n }\n return sum;\n };\n }\n\n /**\n * Truncate text to fit width. The result is guaranteed to fit: the largest prefix (possibly empty) is kept such that the prefix plus the tail measures within `width`. The cut never splits a surrogate pair. If even the tail alone cannot fit, `[\"\", 0]` is returned.\n * @param fn a function that can measure text width\n * @param str text to truncate\n * @param width width to fit\n * @param tail text to indicate overflow such as \"...\". Default is empty \"\".\n * @param hint optional expected number of characters to keep — a pure performance hint (any value yields the same result) that seeds the search, such as the previous line's length when wrapping. With an empty `tail`, a hint also avoids measuring the entire string.\n * @return a tuple of the truncated text (tail included) and the number of characters kept from `str`\n */\n static truncate(\n fn: TextMeasure,\n str: string,\n width: number,\n tail: string = \"\",\n hint?: number,\n ): [string, number] {\n const len = str.length;\n let budget: number;\n let max: number;\n let seed: number;\n\n if (hint !== undefined && !tail) {\n // Hinted search with no tail: skip the full-string measure. The domain\n // includes `len` itself, so \"everything fits\" is discovered by the\n // search rather than by a separate upfront measurement.\n budget = width;\n max = len;\n seed = Math.min(max, Math.max(0, Math.floor(hint)));\n } else {\n const full = fn(str);\n if (full <= width) return [str, len];\n budget = width - (tail ? fn(tail) : 0);\n max = len - 1;\n seed =\n hint !== undefined\n ? Math.min(max, Math.max(0, Math.floor(hint)))\n : Math.min(max, Math.max(0, Math.floor((len * budget) / full)));\n }\n\n const fits = (k: number): boolean => fn(str.slice(0, k)) <= budget;\n\n // Find the largest k in [0, max] where the prefix fits, starting from the\n // seed — exact for linear measures, so the gallop below usually settles\n // the boundary in two probes.\n let best = -1;\n let lo = 0;\n let hi = max;\n\n if (budget >= 0) {\n const k = seed;\n if (fits(k)) {\n best = k;\n lo = k + 1;\n for (let inc = 1; lo <= hi; inc *= 2) {\n const p = Math.min(hi, k + inc);\n if (!fits(p)) {\n hi = p - 1;\n break;\n }\n best = p;\n lo = p + 1;\n }\n } else {\n hi = k - 1;\n for (let inc = 1; lo <= hi; inc *= 2) {\n const p = Math.max(lo, k - inc);\n if (fits(p)) {\n best = p;\n lo = p + 1;\n break;\n }\n hi = p - 1;\n }\n }\n while (lo <= hi) {\n const p = (lo + hi) >> 1;\n if (fits(p)) {\n best = p;\n lo = p + 1;\n } else {\n hi = p - 1;\n }\n }\n }\n\n if (best < 0) return [\"\", 0];\n if (best === len) return [str, len]; // hinted search found the whole string fits\n\n // Don't cut between a surrogate pair's halves; a shorter prefix still fits.\n let cut = best;\n if (cut > 0) {\n const code = str.charCodeAt(cut - 1);\n if (code >= 0xd800 && code <= 0xdbff) cut--;\n }\n\n return [str.slice(0, cut) + tail, cut];\n }\n\n /**\n * Get a function to scale font size proportionally to a box's size. (Deprecated form: passing an initial box as the first parameter is deprecated — it never affected the result — and will be removed in a future version.)\n * @param ratio font-size to box-size ratio. Default is 1.\n * @param byHeight `true` to scale by the box's height, `false` to scale by its width. Default is `true`.\n * @returns a function where input parameter is a box, and returns a font size value (`ratio` multiplied by the box's height or width)\n */\n static fontSizeToBox(\n ratio?: number,\n byHeight?: boolean,\n ): (box: PtLikeIterable) => number;\n /**\n * @deprecated The initial box never affected the result. Use `fontSizeToBox(ratio, byHeight)` instead.\n */\n static fontSizeToBox(\n box: PtLikeIterable,\n ratio?: number,\n byHeight?: boolean,\n ): (box: PtLikeIterable) => number;\n static fontSizeToBox(\n ratio: number | PtLikeIterable = 1,\n byHeight: boolean | number = true,\n legacyByHeight?: boolean,\n ): (box: PtLikeIterable) => number {\n if (typeof ratio !== \"number\") {\n Util.warn(\n \"Typography.fontSizeToBox(box, ratio, byHeight) is deprecated: the initial box never affected the result. Use fontSizeToBox(ratio, byHeight) instead.\",\n );\n ratio = typeof byHeight === \"number\" ? byHeight : 1;\n byHeight = legacyByHeight === undefined ? true : legacyByHeight;\n }\n const r = ratio as number;\n const by = byHeight as boolean;\n return (box: PtLikeIterable): number => {\n const bound = Bound.fromGroup(box);\n return r * (by ? bound.height : bound.width);\n };\n }\n\n /**\n * Get a function to scale font size based on a threshold value.\n * @param threshold threshold value. Cannot be 0.\n * @param direction if negative, get a font size <= defaultSize; if positive, get a font size >= defaultSize; Default is 0 which will scale font without min or max limits.\n * @returns a function whose input parameters are a default font size and a value to compare with threshold, and which returns a new font size value\n */\n static fontSizeToThreshold(\n threshold: number,\n direction: number = 0,\n ): (defaultSize: number, val: number) => number {\n if (threshold === 0) {\n throw new Error(\"fontSizeToThreshold: threshold cannot be 0\");\n }\n return function (defaultSize: number, val: number): number {\n const d = (defaultSize * val) / threshold;\n if (direction < 0) return Math.min(d, defaultSize);\n if (direction > 0) return Math.max(d, defaultSize);\n return d;\n };\n }\n}\n","import { CanvasForm, type CanvasSpace } from \"./Canvas\";\nimport { type Bound, Pt } from \"./Pt\";\nimport { Mat } from \"./LinearAlgebra\";\nimport { type PtLike, type CanvasPatternRepetition } from \"./Types\";\nimport { Util } from \"./Util\";\nimport { type RenderingContext2D } from \"./Types\";\n\n/**\n * Options for creating an [`Img`](#link).\n */\nexport type ImgOptions = {\n /** Specify if you want to manipulate pixels of this image. Default is `false`. */\n editable?: boolean;\n /** Set the `CanvasSpace` reference so the image's pixelScale matches the canvas. */\n space?: CanvasSpace;\n /** Enable loading cross-domain images. The image server must also allow it. */\n crossOrigin?: boolean;\n /** Set a specific pixel scale, overriding the space's. */\n pixelScale?: number;\n};\n\n/**\n * Img provides convenient functions to support image operations on HTML Canvas and [`CanvasSpace`](#link). Combine this with other Pts functions to experiment with visual forms that integrate bitmaps and vector graphics.\n */\nexport class Img {\n protected _img!: HTMLImageElement;\n protected _data!: ImageData;\n protected _cv!: HTMLCanvasElement;\n protected _ctx!: RenderingContext2D;\n protected _scale: number = 1;\n\n protected _loaded: boolean = false;\n protected _editable: boolean;\n\n protected _space: CanvasSpace | undefined;\n protected _patternCtx!: RenderingContext2D; // lazy fallback when no space is set\n protected _objectUrl!: string | null; // tracked for revocation on dispose\n private _pendingLoadReject: ((err: Error) => void) | null = null; // newer loads supersede pending ones\n private _disposed = false;\n protected _dataDirty: boolean = false; // ImageData refreshes lazily on first read\n\n /**\n * Create an Img\n * @param editable either an [`ImgOptions`](#link) object, or a boolean specifying if you want to manipulate pixels of this image. Default is `false`.\n * @param space Set the `CanvasSpace` reference. This is optional but will make sure the image's pixelScale match the canvas and set the context for creating pattern.\n * @param crossOrigin an optional parameter to enable loading cross-domain images if set to true. The image server's configuration must also be set correctly. For more, see [this documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image).\n * @example `new Img(true, space)`, `new Img({ editable: true, pixelScale: 2 })`\n */\n constructor(\n editable: boolean | ImgOptions = false,\n space?: CanvasSpace,\n crossOrigin?: boolean,\n ) {\n const opts: ImgOptions =\n typeof editable === \"object\"\n ? editable\n : { editable, space, crossOrigin };\n this._editable = !!opts.editable;\n this._space = opts.space;\n this._scale = opts.pixelScale ?? (this._space ? this._space.pixelScale : 1);\n this._img = new Image();\n if (opts.crossOrigin) this._img.crossOrigin = \"Anonymous\";\n }\n\n /**\n * A static function to load an image, returning a Promise that resolves to the loaded Img.\n * A load failure rejects the Promise.\n * @param src an url of the image in same domain. Alternatively you can use a base64 string. To load from Blob, use `Img.fromBlob`.\n * @param editable either an [`ImgOptions`](#link) object, or a boolean specifying if you want to manipulate pixels of this image. Default is `false`.\n * @param space Set the `CanvasSpace` reference. This is optional but will make sure the image's pixelScale match the canvas and set the context for creating pattern.\n * @param ready An optional callback, invoked with the Img when loading succeeds\n * @example `const img = await Img.load(\"photo.jpg\", true)`\n */\n static load(\n src: string,\n editable: boolean | ImgOptions = false,\n space?: CanvasSpace,\n ready?: (img: Img) => void,\n ): Promise<Img> {\n return new Img(editable, space).load(src).then((res) => {\n if (ready) ready(res);\n return res;\n });\n }\n\n /**\n * A static method to load an image using async/await.\n * @deprecated Use [`Img.load`](#link), which now returns a Promise.\n * @param src an url of the image in same domain. Alternatively you can use a base64 string. To load from Blob, use `Img.fromBlob`.\n * @param editable Specify if you want to manipulate pixels of this image. Default is `false`.\n * @param space Set the `CanvasSpace` reference. This is optional but will make sure the image's pixelScale match the canvas and set the context for creating pattern.\n */\n static async loadAsync(\n src: string,\n editable: boolean | ImgOptions = false,\n space?: CanvasSpace,\n ): Promise<Img> {\n return Img.load(src, editable, space);\n }\n\n /**\n * A static method to load an image pattern using async/await.\n * @param src an url of the image in same domain. Alternatively you can use a base64 string. To load from Blob, use `Img.fromBlob`.\n * @param space Set the `CanvasSpace` reference. This is optional but will make sure the image's pixelScale match the canvas and set the context for creating pattern.\n * @param repeat set how the pattern will repeat fills\n * @param editable Specify if you want to manipulate pixels of this image. Default is `false`.\n * @returns a `CanvasPattern` instance for use in `fill()`\n */\n static async loadPattern(\n src: string,\n space: CanvasSpace,\n repeat: CanvasPatternRepetition = \"repeat\",\n editable: boolean = false,\n ) {\n const img = await Img.loadAsync(src, editable, space);\n return img.pattern(repeat);\n }\n\n /**\n * Create an editable blank image\n * @param size of image\n * @param space Optionally set the `CanvasSpace` reference. This is optional but will make sure the image's pixelScale match the canvas and set the context for creating pattern.\n * @param scale Optionally set a specific pixel scale (density) of the image canvas.\n */\n static blank(size: PtLike, space?: CanvasSpace, scale?: number): Img {\n let img = new Img(true, space);\n const s = scale ? scale : space ? space.pixelScale : 1;\n img.initCanvas(size[0], size[1], s);\n return img;\n }\n\n /**\n * Load an image.\n * @param src an url of the image in same domain. Alternatively you can use a base64 string. To load from Blob, use `Img.fromBlob`.\n * @returns a Promise that resolves to an Img\n */\n load(src: string): Promise<Img> {\n if (this._editable && typeof document === \"undefined\") {\n return Promise.reject(\n new Error(\"Cannot create html canvas element. document not found.\"),\n );\n }\n\n return this._loadImageSrc(src).then(() => {\n if (this._disposed) throw new Error(\"Img has been disposed\");\n if (this._editable) {\n if (!this._cv)\n this._cv = document.createElement(\"canvas\") as HTMLCanvasElement;\n this._drawToScale(this._scale, this._img);\n this._dataDirty = true;\n }\n this._loaded = true;\n return this;\n });\n }\n\n /**\n * Swap the underlying image's source and await its load — without the editable\n * pipeline. Shared by `load()` and `sync()` so both respect the supersede rule.\n */\n protected _loadImageSrc(src: string): Promise<void> {\n if (this._disposed)\n return Promise.reject(new Error(\"Img has been disposed\"));\n return new Promise<void>((resolve, reject) => {\n // a newer load replaces this one's handlers on the shared <img>, so a\n // pending previous promise must be rejected proactively\n if (this._pendingLoadReject) {\n this._pendingLoadReject(\n new Error(\"Img loading superseded by a newer load\"),\n );\n }\n this._pendingLoadReject = reject;\n\n this._img.onload = () => {\n this._pendingLoadReject = null;\n resolve();\n };\n\n this._img.onerror = () => {\n this._pendingLoadReject = null;\n reject(new Error(`Img cannot load ${src}`));\n };\n\n this._img.src = src;\n });\n }\n\n /** Refresh the cached `ImageData` from the current canvas. */\n protected _refreshData(): void {\n this._data = this._ctx.getImageData(0, 0, this._cv.width, this._cv.height);\n this._dataDirty = false;\n }\n\n /** Materialize the cached `ImageData` lazily, on first read after a change. */\n protected _ensureData(): void {\n if ((this._dataDirty || !this._data) && this._ctx && this._cv) {\n this._refreshData();\n }\n }\n\n /**\n * Rescale the canvas and draw an image-source on it.\n * @param canvasScale rescale factor for the canvas\n * @param img an image source like Image, Canvas, or ImageBitmap.\n */\n protected _drawToScale(\n canvasScale: number | PtLike,\n img:\n | HTMLImageElement\n | HTMLCanvasElement\n | ImageBitmap\n | OffscreenCanvas\n | HTMLVideoElement,\n ) {\n const nw = img.width as number;\n const nh = img.height as number;\n this._initCanvas(nw, nh, canvasScale);\n if (img)\n this._ctx.drawImage(\n img,\n 0,\n 0,\n nw,\n nh,\n 0,\n 0,\n this._cv.width,\n this._cv.height,\n );\n }\n\n /**\n * Initiate an editable canvas\n * @param width width of canvas\n * @param height height of canvas\n * @param canvasScale pixel scale\n */\n initCanvas(width: number, height: number, canvasScale: number | PtLike = 1) {\n this._initCanvas(width, height, canvasScale);\n }\n\n /**\n * Internal canvas setup without the pixel-data refresh — callers that draw\n * immediately afterwards refresh once after their draw instead.\n */\n protected _initCanvas(\n width: number,\n height: number,\n canvasScale: number | PtLike = 1,\n ) {\n if (!this._editable) {\n Util.warn(\n \"Cannot initiate canvas because this Img is not set to be editable\",\n );\n return;\n }\n\n if (!this._cv)\n this._cv = document.createElement(\"canvas\") as HTMLCanvasElement;\n\n const cms =\n typeof canvasScale === \"number\"\n ? [canvasScale, canvasScale]\n : canvasScale;\n this._cv.width = width * cms[0];\n this._cv.height = height * cms[1];\n // the whole point of an editable Img is repeated readback\n this._ctx = this._cv.getContext(\"2d\", { willReadFrequently: true })!;\n // resizing resets the context state; forget any cached style values so a\n // CanvasForm from getForm() re-applies its styles\n CanvasForm.resetStyleCache(this._ctx);\n // keep the pixel-density field coherent with the actual canvas scaling,\n // which `pixel( p, true )` depends on\n if (typeof canvasScale === \"number\") this._scale = canvasScale;\n this._dataDirty = true; // pixel reads materialize lazily\n this._loaded = true;\n }\n\n /**\n * Get an efficient, readonly bitmap of the current canvas.\n * @param size Optional size to crop\n * @returns a Promise that resolves to an ImageBitmap\n */\n bitmap(size?: PtLike): Promise<ImageBitmap> {\n const w = size ? size[0] : this._cv.width;\n const h = size ? size[1] : this._cv.height;\n return createImageBitmap(this._cv, 0, 0, w, h);\n }\n\n /**\n * Create a canvas pattern for `fill()`\n * @param reptition set how the pattern should repeat-fill\n * @param dynamic If true, use this Img's internal canvas content as pattern fill. This enables the pattern to update dynamically.\n * @returns a `CanvasPattern` instance for use in `fill()`\n */\n pattern(\n reptition: CanvasPatternRepetition = \"repeat\",\n dynamic: boolean = false,\n ): CanvasPattern {\n // any 2D context can create a pattern; fall back to an internal one so a\n // CanvasSpace reference is optional\n let ctx: RenderingContext2D | undefined = this._space\n ? this._space.ctx\n : undefined;\n if (!ctx) {\n if (!this._patternCtx) {\n this._patternCtx = document.createElement(\"canvas\").getContext(\"2d\")!;\n }\n ctx = this._patternCtx;\n }\n return ctx.createPattern(dynamic ? this._cv : this._img, reptition)!;\n }\n\n /**\n * Replace the image with the current canvas data. For example, you can use CanvasForm's static functions to draw on `this.ctx` and then update the current image.\n * To display the internal canvas, use `form.image( [0, 0], img.current )`.\n */\n async sync(): Promise<Img> {\n if (this._disposed) throw new Error(\"Img has been disposed\");\n // Blob-blit instead of a base64 round-trip: encode asynchronously, load\n // the result into the image, and leave the working canvas untouched (the\n // canvas is already the source of truth, so no redraw or readback is\n // needed — and the retina canvas is no longer squashed through a lossy\n // reload; a temporary canvas produces the logical-size image instead).\n let source: HTMLCanvasElement = this._cv;\n if (this._scale !== 1) {\n source = document.createElement(\"canvas\");\n source.width = this._cv.width / this._scale;\n source.height = this._cv.height / this._scale;\n source\n .getContext(\"2d\")!\n .drawImage(\n this._cv,\n 0,\n 0,\n this._cv.width,\n this._cv.height,\n 0,\n 0,\n source.width,\n source.height,\n );\n }\n\n const blob = await new Promise<Blob>((resolve, reject) => {\n source.toBlob((b) =>\n b ? resolve(b) : reject(new Error(\"Img cannot export canvas to blob\")),\n );\n });\n\n const url = URL.createObjectURL(blob);\n this._objectUrl = url;\n try {\n await this._loadImageSrc(url);\n if (this._disposed) throw new Error(\"Img has been disposed\");\n this._loaded = true;\n } finally {\n URL.revokeObjectURL(url);\n this._objectUrl = null;\n }\n return this;\n }\n\n /**\n * Get the RGBA values of a pixel in the image\n * @param p position of the pixel\n * @param rescale Specify if the pixel position should be scaled. Usually use rescale when tracking image and don't rescale when tracking canvas. You may also set a custom scale value.\n * @returns [R,G,B,A] values of the pixel at the specific position\n */\n pixel(p: PtLike, rescale: boolean | number = true): Pt {\n this._ensureData();\n if (!this._data) {\n Util.warn(\n \"Img has no pixel data — create it as editable and wait for load\",\n );\n return new Pt(0, 0, 0, 0);\n }\n const s = typeof rescale == \"number\" ? rescale : rescale ? this._scale : 1;\n return Img.getPixel(this._data, [p[0] * s, p[1] * s]);\n }\n\n /**\n * Set the RGBA values of a pixel in the cached `ImageData`. Call [`Img.updatePixels`](#link)\n * to write the changes onto the canvas.\n * @param p position of the pixel\n * @param rgba [R,G,B,A] values, 0-255\n * @param rescale Specify if the pixel position should be scaled, matching [`Img.pixel`](#link)\n */\n setPixel(p: PtLike, rgba: PtLike, rescale: boolean | number = true): this {\n this._ensureData();\n if (!this._data) {\n Util.warn(\"Img has no pixel data — create it as editable\");\n return this;\n }\n const s = typeof rescale == \"number\" ? rescale : rescale ? this._scale : 1;\n const x = Math.floor(p[0] * s);\n const y = Math.floor(p[1] * s);\n if (x < 0 || y < 0 || x >= this._data.width || y >= this._data.height) {\n return this;\n }\n const i = y * this._data.width * 4 + x * 4;\n this._data.data[i] = rgba[0];\n this._data.data[i + 1] = rgba[1];\n this._data.data[i + 2] = rgba[2];\n this._data.data[i + 3] = rgba[3] !== undefined ? rgba[3] : 255;\n return this;\n }\n\n /**\n * Refresh the cached `ImageData` from the canvas — call this after drawing on the\n * canvas (eg, via [`Img.getForm`](#link)) before reading pixels.\n */\n loadPixels(): this {\n if (!this._ctx) {\n Util.warn(\"Img has no canvas — create it as editable\");\n return this;\n }\n this._refreshData();\n return this;\n }\n\n /**\n * Write the cached `ImageData` (eg, after [`Img.setPixel`](#link) calls) back onto\n * the canvas.\n */\n updatePixels(): this {\n if (!this._ctx || !this._data) {\n Util.warn(\"Img has no canvas — create it as editable\");\n return this;\n }\n this._ctx.putImageData(this._data, 0, 0);\n this._dataDirty = false; // canvas now equals the cached data\n return this;\n }\n\n /**\n * Given an ImaegData object and a position, return the RGBA pixel value at that position.\n * @param imgData an ImageData object\n * @param p a position on the image\n * @returns [R,G,B,A] values of the pixel at the specific position\n */\n static getPixel(imgData: ImageData, p: PtLike): Pt {\n // `new Pt(4)` + element stores is ~8x faster than the 4-argument\n // constructor path, and out-of-bound reads return the zeroed Pt as before\n const out = new Pt(4);\n if (\n p[0] < 0 ||\n p[1] < 0 ||\n p[0] >= imgData.width ||\n p[1] >= imgData.height\n ) {\n return out;\n }\n\n const i = Math.floor(p[1]) * (imgData.width * 4) + Math.floor(p[0]) * 4;\n const d = imgData.data;\n if (i > d.length - 4) return out;\n\n out[0] = d[i];\n out[1] = d[i + 1];\n out[2] = d[i + 2];\n out[3] = d[i + 3];\n return out;\n }\n\n /**\n * Resize the canvas image. The original image is unchanged until `sync()`.\n * @param sizeOrScale A PtLike array specifying either [x, y] scales or [x, y] sizes.\n * @param asScale If true, treat the first parameter as scales. Otherwise, treat it as specific sizes.\n */\n resize(sizeOrScale: PtLike, asScale: boolean = false): this {\n const hasImage = this._img.naturalWidth > 0;\n // canvas-only images (eg, from `Img.blank`) scale relative to the canvas\n // size, and need a snapshot since `_drawToScale` clears the canvas first\n const refW = hasImage ? this._img.naturalWidth : this._cv.width;\n const refH = hasImage ? this._img.naturalHeight : this._cv.height;\n if (!refW || !refH) {\n Util.warn(\"Img cannot resize before an image or canvas exists\");\n return this;\n }\n const s = asScale\n ? sizeOrScale\n : [sizeOrScale[0] / refW, sizeOrScale[1] / refH];\n\n let source: HTMLImageElement | HTMLCanvasElement = this._img;\n if (!hasImage) {\n const snap = document.createElement(\"canvas\");\n snap.width = this._cv.width;\n snap.height = this._cv.height;\n snap.getContext(\"2d\")!.drawImage(this._cv, 0, 0);\n source = snap;\n }\n this._drawToScale(s, source);\n this._dataDirty = true;\n return this;\n }\n\n /**\n * Crop an area of the image.\n * @param box bounding box\n */\n crop(box: Bound): ImageData {\n const s = this._scale;\n return this._ctx.getImageData(\n box[0][0] * s,\n box[0][1] * s,\n box.width * s,\n box.height * s,\n );\n }\n\n /**\n * Apply filters such as blur and grayscale to the canvas image. The original image is unchanged until `sync()`.\n * @param css a css filter string such as \"blur(10px) contrast(200%)\". See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter#browser_compatibility) for a list of filter functions.\n */\n filter(css: string): this {\n // \"copy\" replaces the canvas with the filtered result (the source is\n // snapshotted before compositing) — plain source-over would blend the\n // filtered copy with the original wherever the filter introduces alpha\n const op = this._ctx.globalCompositeOperation;\n this._ctx.globalCompositeOperation = \"copy\";\n this._ctx.filter = css;\n this._ctx.drawImage(this._cv, 0, 0);\n this._ctx.filter = \"none\";\n this._ctx.globalCompositeOperation = op;\n this._dataDirty = true;\n return this;\n }\n\n /**\n * Dispose of the elements, data, and any object URL associated with this Img. Pending loads reject; the instance should not be reused.\n */\n dispose(): this {\n this._disposed = true;\n this._pendingLoadReject?.(new Error(\"Img has been disposed\"));\n this._pendingLoadReject = null;\n if (this._img) {\n this._img.onload = null;\n this._img.onerror = null;\n this._img.removeAttribute(\"src\");\n }\n if (this._objectUrl) {\n URL.revokeObjectURL(this._objectUrl);\n this._objectUrl = null;\n }\n if (this._cv) this._cv.remove();\n if (this._img) this._img.remove();\n this._cv = null!;\n this._ctx = null!;\n this._patternCtx = null!;\n this._img = null!;\n this._data = null!;\n this._loaded = false;\n return this;\n }\n\n /**\n * Remove the elements and data associated with this Img.\n * @deprecated Use [`Img.dispose`](#link).\n */\n cleanup() {\n this.dispose();\n }\n\n /**\n * Create a blob url that can be passed to `Img.load`\n * @param blob an image blob such as `new Blob([my_Uint8Array], {type: 'image/png'})`\n * @param editable Specify if you want to manipulate pixels of this image. Default is `false`.\n */\n static fromBlob(\n blob: Blob,\n editable: boolean | ImgOptions = false,\n space?: CanvasSpace,\n ): Promise<Img> {\n const url = URL.createObjectURL(blob);\n const img = new Img(editable, space);\n img._objectUrl = url;\n // the decoded image no longer needs the URL once the load settles;\n // dispose() also guards this\n const done = () => {\n URL.revokeObjectURL(url);\n img._objectUrl = null;\n };\n return img.load(url).then(\n (res) => {\n done();\n return res;\n },\n (err) => {\n done();\n throw err;\n },\n );\n }\n\n /**\n * Convert ImageData object to a Blob, which you can then create an Img instance via [`Img.fromBlob`](#link). Note that the resulting image's dimensions will not account for pixel density.\n * @param data\n */\n static imageDataToBlob(data: ImageData): Promise<Blob> {\n return new Promise(function (resolve, reject) {\n if (typeof document === \"undefined\") {\n reject(\n new Error(\"Cannot create html canvas element. document not found.\"),\n );\n return;\n }\n let cv = document.createElement(\"canvas\") as HTMLCanvasElement;\n cv.width = data.width;\n cv.height = data.height;\n cv.getContext(\"2d\")!.putImageData(data, 0, 0);\n cv.toBlob((blob) => {\n resolve(blob!);\n cv.remove();\n });\n });\n }\n\n /**\n * Export current canvas image as base64 string\n */\n toBase64(): string {\n return this._cv.toDataURL();\n }\n\n /**\n * Export current canvas image as a blob\n */\n toBlob(): Promise<Blob> {\n return new Promise((resolve) => {\n this._cv.toBlob((blob) => resolve(blob!));\n });\n }\n\n /**\n * Get a CanvasForm for drawing on the internal canvas if this Img is editable\n */\n getForm(): CanvasForm | undefined {\n if (!this._editable) {\n Util.warn(\"Cannot get a CanvasForm because this Img is not editable\");\n }\n return this._ctx ? new CanvasForm(this._ctx) : undefined;\n }\n\n /**\n * Get current image source. If editable, this will return the canvas, otherwise it will return the original image.\n */\n get current(): CanvasImageSource {\n return this._editable ? this._cv : this._img;\n }\n\n /**\n * Get the original image\n */\n get image(): HTMLImageElement {\n return this._img;\n }\n\n /**\n * Get the internal canvas\n */\n get canvas(): HTMLCanvasElement {\n return this._cv;\n }\n\n /**\n * Get the internal canvas' ImageData\n */\n get data(): ImageData {\n this._ensureData();\n return this._data;\n }\n\n /**\n * Get the internal canvas' context. You can use this to draw directly on canvas, or create a new [CanvasForm](#link) instance with it.\n */\n get ctx(): RenderingContext2D {\n return this._ctx;\n }\n\n /**\n * Get whether the image is loaded\n */\n get loaded(): boolean {\n return this._loaded;\n }\n\n /**\n * Get pixel density scale\n */\n get pixelScale(): number {\n return this._scale;\n }\n\n /**\n * Get size of the original image\n */\n get imageSize(): Pt {\n if (!this._img || !this._img.width || !this._img.height) {\n return this._cv ? this.canvasSize.$divide(this._scale) : new Pt(0, 0);\n } else {\n return new Pt(this._img.width, this._img.height);\n }\n }\n\n /**\n * Get size of the canvas\n */\n get canvasSize(): Pt {\n return new Pt(this._cv.width, this._cv.height);\n }\n\n /**\n * Get a Mat instance with a scale transform based on current `pixelScale`.\n * This can be useful for generating a domMatrix for transforming patterns consistently across different pixel-density screens.\n * @example `img.scaledMatrix.translate2d(...).rotate2D(...).domMatrix`\n */\n get scaledMatrix(): Mat {\n const s = 1 / this._scale;\n return new Mat().scale2D([s, s]);\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { MultiTouchSpace } from \"./Space\";\nimport { VisualForm, Font } from \"./Form\";\nimport { Pt, Group, Bound } from \"./Pt\";\nimport { Const, Util } from \"./Util\";\nimport { Typography as Typo } from \"./Typography\";\nimport { Rectangle } from \"./Op\";\nimport { Img } from \"./Image\";\nimport {\n type PtLike,\n type GroupLike,\n type RenderingContext2D,\n type DefaultFormStyle,\n type PtLikeIterable,\n type PtIterable,\n type CanvasSpaceOptions,\n type TextMeasure,\n type TextVerticalAlign,\n} from \"./Types\";\n\n/**\n * CanvasSpace is an implementation of the abstract class [`Space`](#link). It represents a space for HTML Canvas.\n * Learn more about the concept of Space in [this guide](../guide/Space-0500.html).\n */\nexport class CanvasSpace extends MultiTouchSpace {\n protected _canvas: HTMLCanvasElement;\n protected _container!: Element;\n\n protected _pixelScale = 1;\n protected _bgcolor = \"#e1e9f0\";\n protected _ctx: CanvasRenderingContext2D;\n\n protected _offscreen = false;\n protected _offCanvas!: HTMLCanvasElement;\n protected _offCtx!: RenderingContext2D;\n\n protected _resizeObserver: ResizeObserver | undefined;\n protected _autoResize = true;\n protected _initialResize = false;\n\n private _readyObserver: MutationObserver | undefined;\n private _readyTimer: number | undefined;\n private _disposed = false;\n private _ownsCanvas = false;\n private _ownsContainer = false;\n\n /**\n * Create a CanvasSpace which represents a HTML Canvas Space\n * @param elem Specify an element by its \"id\" attribute as string, or by the element object itself. An element can be an existing `<canvas>`, or a `<div>` container in which a new `<canvas>` will be created. If left empty, a `<div id=\"pt_container\"><canvas id=\"pt\" /></div>` will be added to DOM. Use css to customize its appearance if needed.\n * @param callback an optional callback `function(boundingBox, spaceElement)` to be called when canvas is appended and ready. Alternatively, a \"ready\" event will also be fired from the `<canvas>` element when it's appended, which can be traced with `spaceInstance.canvas.addEventListener(\"ready\")`\n * @example `new CanvasSpace( \"#myElementID\" )`\n */\n constructor(\n elem: string | Element | null = \"pt\",\n callback?: (bound: Bound, elem: EventTarget) => void,\n ) {\n super();\n\n let _selector: Element | null = null;\n let _existed = false;\n this.id = Util.uniqueId();\n\n // get selector element depending on whether `elem` is an element id string or an element object\n if (elem instanceof Element) {\n _selector = elem;\n this.id = _selector.id || this.id;\n } else {\n const target = elem || \"pt\";\n const id = target[0] === \"#\" || target[0] === \".\" ? target : \"#\" + target;\n _selector = document.querySelector(id);\n this.id = id.substr(1);\n }\n\n // if selector is not defined, create a default canvas\n if (!_selector) {\n this._ownsContainer = true;\n this._container = this._createElement(\"div\", this.id + \"_container\");\n this._canvas = this._createElement(\n \"canvas\",\n this.id,\n ) as HTMLCanvasElement;\n document.body.appendChild(this._container);\n\n // if selector is element but not canvas, create a canvas inside it\n } else if (_selector.nodeName.toLowerCase() != \"canvas\") {\n this._container = _selector;\n this._canvas = this._createElement(\n \"canvas\",\n this.id + \"_canvas\",\n ) as HTMLCanvasElement;\n this._initialResize = true;\n\n // if selector is an existing canvas\n } else {\n this._canvas = _selector as HTMLCanvasElement;\n this._container = _selector.parentElement!;\n this._autoResize = false;\n _existed = true;\n }\n\n // store canvas 2d rendering context\n this._ctx = this._canvas.getContext(\"2d\")!;\n\n // if we created the canvas, add it to the container and observe mutation for readiness\n if (!_existed) {\n this._ownsCanvas = true;\n this._readyObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (mutation.type === \"childList\" && mutation.addedNodes.length) {\n for (let node of mutation.addedNodes) {\n if (node === this._canvas) {\n this._ready(callback);\n this._readyObserver?.disconnect();\n this._readyObserver = undefined;\n return;\n }\n }\n }\n });\n });\n\n this._readyObserver.observe(this._container, { childList: true });\n this._container.appendChild(this._canvas);\n } else {\n // Wait one turn for .setup() to be called before firing ready event\n this._readyTimer = window.setTimeout(() => this._ready(callback), 100);\n }\n }\n\n /**\n * Helper function to create a DOM element\n * @param elem element tag name\n * @param id element id attribute\n */\n protected _createElement(elem = \"div\", id: string) {\n const d = document.createElement(elem);\n d.setAttribute(\"id\", id);\n return d;\n }\n\n /**\n * Handle callbacks after element is mounted in DOM\n * @param callback\n */\n private _ready(callback?: (bound: Bound, elem: EventTarget) => void) {\n if (this._disposed) return;\n\n this._readyTimer = undefined;\n if (!this._container)\n throw new Error(`Cannot initiate #${this.id} element`);\n\n this._isReady = true;\n\n this._resizeHandler(null);\n\n this.clear(this._bgcolor);\n this._canvas.dispatchEvent(new Event(\"ready\"));\n\n for (const k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n if (this.players[k].start)\n this.players[k].start(this.bound.clone(), this);\n }\n }\n\n this._pointer = this.center;\n this._initialResize = false; // unset\n\n if (callback) callback(this.bound, this._canvas);\n }\n\n /**\n * Set up various options for CanvasSpace. The `opt` parameter is an object with the following fields. This is usually set during instantiation, eg `new CanvasSpace(...).setup( { opt } )`\n * @param opt a [`CanvasSpaceOptions`](#link) object with optional settings, ie `{ bgcolor:string, resize:boolean, retina:boolean, offscreen:boolean, pixelDensity:number }`. Note that omitting `bgcolor` sets a transparent background (a long-standing behavior that differs from `DOMSpace.setup`, which keeps the current background when the option is absent).\n * @example `space.setup({ bgcolor: \"#f00\", retina: true, resize: true })`\n */\n setup(opt: CanvasSpaceOptions): this {\n this._bgcolor = opt.bgcolor ? opt.bgcolor : \"transparent\";\n\n this.autoResize = opt.resize != undefined ? opt.resize : false;\n\n if (opt.retina !== false) {\n const r1 = window ? window.devicePixelRatio || 1 : 1;\n this._pixelScale = Math.max(1, r1);\n }\n\n if (opt.offscreen) {\n this._offscreen = true;\n this._offCanvas = this._createElement(\n \"canvas\",\n this.id + \"_offscreen\",\n ) as HTMLCanvasElement;\n this._offCtx = this._offCanvas.getContext(\"2d\")!;\n } else {\n this._offscreen = false;\n }\n\n if (opt.pixelDensity) {\n this._pixelScale = opt.pixelDensity;\n }\n\n return this;\n }\n\n /**\n * Set whether the canvas element should resize when its container is resized.\n * @param auto a boolean value indicating if auto size is set\n */\n set autoResize(auto) {\n if (this._autoResize === auto && (!auto || this._resizeObserver)) return;\n\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n this._resizeObserver = undefined;\n }\n\n this._autoResize = auto;\n\n if (auto) {\n this._resizeObserver = new ResizeObserver((entries) => {\n this._resizeHandler(null);\n });\n this._resizeObserver.observe(this._container);\n }\n }\n get autoResize(): boolean {\n return this._autoResize;\n }\n\n /**\n * This overrides Space's `resize` function. It's used as a callback function for window's resize event and not usually called directly. You can keep track of resize events with `resize: (bound ,evt)` callback in your player objects.\n * @param b a Bound object to resize to\n * @param evt Optionally pass a resize event\n * @see Space.add\n */\n resize(b: Bound, evt?: Event | null): this {\n this.bound = b;\n\n // The buffer needs whole device pixels, so round up to cover the bound.\n this._canvas.width = Math.ceil(this.bound.size.x) * this._pixelScale;\n this._canvas.height = Math.ceil(this.bound.size.y) * this._pixelScale;\n // The CSS size must not round up: a canvas even a fraction of a pixel\n // larger than its container overflows it, and on systems whose scrollbars\n // take up layout space that summons scrollbars, shrinking the container —\n // which the resize observer answers by shrinking the canvas, letting the\n // scrollbars retract, growing the container again, and so on forever. The\n // oscillation clears the canvas on every pass (it looks blank) and the\n // endless relayout can eventually crash the tab.\n this._canvas.style.width = this.bound.size.x + \"px\";\n this._canvas.style.height = this.bound.size.y + \"px\";\n\n if (this._offscreen) {\n this._offCanvas.width = Math.ceil(this.bound.size.x) * this._pixelScale;\n this._offCanvas.height = Math.ceil(this.bound.size.y) * this._pixelScale;\n // this._offCanvas.style.width = Math.floor(this.bound.size.x) + \"px\";\n // this._offCanvas.style.height = Math.floor(this.bound.size.y) + \"px\";\n }\n\n if (this._pixelScale != 1) {\n this._ctx.scale(this._pixelScale, this._pixelScale);\n\n if (this._offscreen) {\n this._offCtx.scale(this._pixelScale, this._pixelScale);\n }\n }\n\n // Assigning canvas width/height resets the context's entire state to\n // defaults, so any cached style values no longer describe the context —\n // without this, a form's style write matching the stale cache would be\n // skipped and the context would stay at its black defaults.\n CanvasForm.resetStyleCache(this._ctx);\n if (this._offscreen) CanvasForm.resetStyleCache(this._offCtx);\n\n for (const k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n const p = this.players[k];\n if (p.resize) p.resize(this.bound, evt);\n }\n }\n\n this.render(this._ctx);\n\n // if it's a valid resize event and space is not playing, repaint the canvas once\n if (evt && !this.isPlaying) this.playOnce(0);\n\n return this;\n }\n\n /**\n * Window resize handling\n * @param evt\n */\n protected _resizeHandler(evt: Event | null) {\n const b =\n this._autoResize || this._initialResize\n ? this._container.getBoundingClientRect()\n : this._canvas.getBoundingClientRect();\n\n if (b) {\n const box = Bound.fromBoundingRect(b);\n\n // Need to compute offset from window scroll. See outerBound calculation in Space's _mouseAction\n box.center = box.center.add(window?.scrollX || 0, window?.scrollY || 0);\n this.resize(box, evt);\n }\n }\n\n /**\n * Set a background color for this canvas. Alternatively, you may use `clear()` function.\n @param bg background color as hex or rgba string\n */\n set background(bg: string) {\n this._bgcolor = bg;\n }\n get background(): string {\n return this._bgcolor;\n }\n\n /**\n * `pixelScale` property returns a number that let you determine if the screen is \"retina\" (when value >= 2)\n */\n public get pixelScale(): number {\n return this._pixelScale;\n }\n\n /**\n * Check if an offscreen canvas is created\n */\n public get hasOffscreen(): boolean {\n return this._offscreen;\n }\n\n /**\n * Get the rendering context of offscreen canvas (if created via `setup()`)\n */\n public get offscreenCtx(): RenderingContext2D {\n return this._offCtx;\n }\n\n /**\n * Get the offscreen canvas element\n */\n public get offscreenCanvas(): HTMLCanvasElement {\n return this._offCanvas;\n }\n\n /**\n * Get a new `CanvasForm` for drawing\n * @see `CanvasForm`\n */\n public getForm(): CanvasForm {\n return new CanvasForm(this);\n }\n\n /**\n * Get the html canvas element\n */\n get element(): HTMLCanvasElement {\n return this._canvas;\n }\n\n /**\n * Get the parent element that contains the canvas element\n */\n get parent(): Element {\n return this._container;\n }\n\n /**\n * A property to indicate if the Space is ready\n */\n get ready(): boolean {\n return this._isReady;\n }\n\n /**\n * Get the rendering context of canvas\n * @example `form.ctx.clip()`\n */\n public get ctx(): CanvasRenderingContext2D {\n return this._ctx;\n }\n\n /**\n * Clear the canvas with its background color. Overrides Space's `clear` function.\n * @param bg Optionally specify a custom background color in hex or rgba string, or \"transparent\". If not defined, it will use its `bgcolor` property as background color to clear the canvas.\n */\n clear(bg?: string): this {\n if (bg) this._bgcolor = bg;\n const lastColor = this._ctx.fillStyle;\n const px = Math.ceil(this.pixelScale);\n\n if (!this._bgcolor || this._bgcolor === \"transparent\") {\n this._ctx.clearRect(\n -px,\n -px,\n this._canvas.width + px,\n this._canvas.height + px,\n );\n } else {\n // semi-transparent bg needs to be cleared first\n if (\n this._bgcolor.indexOf(\"rgba\") === 0 ||\n (this._bgcolor.length === 9 && this._bgcolor.indexOf(\"#\") === 0)\n ) {\n this._ctx.clearRect(\n -px,\n -px,\n this._canvas.width + px,\n this._canvas.height + px,\n );\n }\n this._ctx.fillStyle = this._bgcolor;\n this._ctx.fillRect(\n -px,\n -px,\n this._canvas.width + px,\n this._canvas.height + px,\n );\n }\n\n this._ctx.fillStyle = lastColor;\n return this;\n }\n\n /**\n * Similiar to `clear()` but clear the offscreen canvas instead\n * @param bg Optionally specify a custom background color in hex or rgba string, or \"transparent\". If not defined, it will use its `bgcolor` property as background color to clear the canvas.\n */\n clearOffscreen(bg?: string | null): this {\n if (this._offscreen) {\n const px = Math.ceil(this.pixelScale);\n if (bg) {\n this._offCtx.fillStyle = bg;\n this._offCtx.fillRect(\n -px,\n -px,\n this._canvas.width + px,\n this._canvas.height + px,\n );\n } else {\n this._offCtx.clearRect(\n -px,\n -px,\n this._offCanvas.width + px,\n this._offCanvas.height + px,\n );\n }\n }\n return this;\n }\n\n /**\n * Main animation function.\n * @param time current time\n */\n protected playItems(time: number) {\n if (this._isReady) {\n this._ctx.save();\n if (this._offscreen) this._offCtx.save();\n super.playItems(time);\n this._ctx.restore();\n if (this._offscreen) this._offCtx.restore();\n // restore() reverted the context's style state without going through the\n // forms' style cache, so the cached values no longer describe the context\n CanvasForm.resetStyleCache(this._ctx);\n if (this._offscreen) CanvasForm.resetStyleCache(this._offCtx);\n this.render(this._ctx);\n }\n }\n\n /**\n * Dispose of browser resources held by this space and remove all players. Call this before unmounting the canvas.\n */\n dispose(): this {\n if (this._disposed) return this;\n this._disposed = true;\n\n if (this._readyTimer !== undefined) {\n window.clearTimeout(this._readyTimer);\n this._readyTimer = undefined;\n }\n if (this._readyObserver) {\n this._readyObserver.disconnect();\n this._readyObserver = undefined;\n }\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n this._resizeObserver = undefined;\n }\n\n this._unbindAll();\n this._cancelAnimation();\n this.removeAll();\n this._isReady = false;\n if (this._ownsCanvas) this._canvas.remove();\n if (this._ownsContainer && this._container.childNodes.length === 0)\n this._container.remove();\n\n return this;\n }\n\n /**\n * Get a [`MediaRecorder`](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder) to record the current CanvasSpace. You can then call its `start()` function to start recording, and `stop()` to either download the video file or handle the blob data in the callback function you provided.\n * @param downloadOrCallback Either `true` to download the video, or provide a callback function to handle the Blob data, when recording is completed.\n * @param filetype video format. Default is \"webm\".\n * @param bitrate bitrate per second\n * @example `let rec = space.recorder(true); rec.start(); setTimeout( () => rec.stop(), 5000); // record 5s of video and download the file`\n */\n recorder(\n downloadOrCallback: boolean | ((blobURL: string) => {}),\n filetype: string = \"webm\",\n bitrate: number = 15000000,\n ): MediaRecorder {\n const stream = this._canvas.captureStream();\n const recorder = new MediaRecorder(stream, {\n mimeType: `video/${filetype}`,\n bitsPerSecond: bitrate,\n });\n\n recorder.ondataavailable = function (d) {\n const url = URL.createObjectURL(\n new Blob([d.data], { type: `video/${filetype}` }),\n );\n\n if (typeof downloadOrCallback === \"function\") {\n downloadOrCallback(url);\n } else if (downloadOrCallback) {\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `canvas_video.${filetype}`;\n a.click();\n a.remove();\n // the download has started from the blob by now; release the URL\n // (callback consumers own the URL and release it themselves)\n setTimeout(() => URL.revokeObjectURL(url), 100);\n }\n };\n\n return recorder;\n }\n}\n\n/**\n * CanvasForm is an implementation of abstract class [`VisualForm`](#link). It provide methods to express Pts on [`CanvasSpace`](#link).\n * You may extend CanvasForm to implement your own expressions for CanvasSpace.\n */\n// Last-written style values per rendering context, so identical values are\n// not re-applied (color parsing in particular is costly). Keyed by context —\n// not by form — because multiple forms can share one context (see `reset()`),\n// and a per-form cache would skip writes another form made stale.\nconst _ctxStyleCache = new WeakMap<object, Record<string, unknown>>();\n\nexport class CanvasForm<\n S extends MultiTouchSpace = CanvasSpace,\n> extends VisualForm {\n protected _space!: CanvasSpace;\n protected _ctx!: RenderingContext2D;\n protected _estimateTextWidth: TextMeasure | undefined;\n protected _estimateMode: \"sample\" | \"char\" | undefined;\n\n // the shared cache object for this._ctx, revalidated only when the context\n // changes so the hot path avoids a WeakMap lookup per style write\n private _styleCache: Record<string, unknown> | null = null;\n private _styleCacheCtx: RenderingContext2D | null = null;\n\n /** Get the style cache shared by all forms drawing on this context. */\n protected _cacheForCtx(): Record<string, unknown> {\n if (this._styleCacheCtx !== this._ctx) {\n let cache = _ctxStyleCache.get(this._ctx);\n if (!cache) {\n cache = {};\n _ctxStyleCache.set(this._ctx, cache);\n }\n this._styleCache = cache;\n this._styleCacheCtx = this._ctx;\n }\n return this._styleCache!;\n }\n\n /**\n * Forget the cached style values for a rendering context, so every\n * subsequent style write applies. Call this after anything that resets or\n * desyncs a context's state outside a form — most commonly assigning a\n * canvas's `width` or `height`, which resets the context to its defaults.\n * (Within a form, [`CanvasForm.reset`](#link) is the equivalent recovery.)\n * @param ctx the rendering context to forget\n */\n static resetStyleCache(ctx: RenderingContext2D | object): void {\n // clear the shared object in place: forms cache a reference to it, so\n // deleting the WeakMap entry would leave them holding stale values\n const cache = _ctxStyleCache.get(ctx);\n if (cache) {\n for (const k in cache) delete cache[k];\n }\n }\n\n /**\n * Write a context style property only when it differs from the last value\n * written to this context. After setting style properties directly on\n * [`CanvasForm.ctx`](#link), call [`CanvasForm.reset`](#link) to resync.\n */\n protected _set(key: string, value: unknown): void {\n const cache = this._cacheForCtx();\n if (cache[key] !== value) {\n cache[key] = value;\n (this._ctx as any)[key] = value;\n }\n }\n\n /**\n * store common styles so that they can be restored to canvas context when using multiple forms. See `reset()`.\n */\n protected _style: DefaultFormStyle = {\n fillStyle: \"#f03\",\n strokeStyle: \"#fff\",\n lineWidth: 1,\n lineJoin: \"bevel\",\n lineCap: \"butt\",\n globalAlpha: 1,\n };\n\n /**\n * Create a new CanvasForm. You may also use [`CanvasSpace.getForm()`](#link) to get the default form.\n * @param space an instance of CanvasSpace, or a rendering context. Passing a context is the\n * renderer extension point: any object implementing the context surface documented in\n * [`SVGContext2D`](#link) (the reference implementation) receives this form's full drawing\n * API — this is how SVG output works, and how custom renderers can be built.\n */\n constructor(space?: CanvasSpace | RenderingContext2D) {\n super();\n\n // allow for undefined context to support custom contexts via subclassing.\n if (!space) return this;\n\n const _setup = (ctx: RenderingContext2D) => {\n this._ctx = ctx;\n this._set(\"fillStyle\", this._style.fillStyle);\n this._set(\"strokeStyle\", this._style.strokeStyle);\n this._set(\"lineJoin\", \"bevel\");\n this._set(\"font\", this._font.value);\n this._ready = true;\n };\n\n if (space instanceof CanvasSpace) {\n this._space = space;\n if (this._space.ready && this._space.ctx) {\n _setup(this._space.ctx);\n } else {\n this._space.add({\n start: () => {\n _setup(this._space.ctx);\n },\n });\n }\n } else {\n _setup(space);\n }\n }\n\n /**\n * get the CanvasSpace instance that this form is associated with\n */\n get space(): S {\n // subclasses for other backends (eg, SVGForm) narrow S to their own space type\n return this._space as unknown as S;\n }\n\n /**\n * Get the rendering context of canvas to perform other canvas functions.\n * @example `form.ctx.clip()`\n */\n get ctx(): RenderingContext2D {\n return this._ctx;\n }\n\n /**\n * Toggle whether to draw on offscreen canvas (if offscreen is set in CanvasSpace)\n * @param off if `true`, draw on offscreen canvas instead of the visible canvas. Default is `true`\n * @param clear optionally provide a valid color string to fill a bg color. see CanvasSpace's `clearOffscreen` function.\n */\n useOffscreen(off: boolean = true, clear: boolean | string = false) {\n if (clear)\n this._space.clearOffscreen(typeof clear == \"string\" ? clear : null);\n this._ctx =\n this._space.hasOffscreen && off\n ? this._space.offscreenCtx\n : this._space.ctx;\n return this;\n }\n\n /**\n * Render the offscreen canvas's content on the visible canvas\n * @param offset Optional offset on the top-left position when drawing on the visible canvas\n */\n renderOffscreen(offset: PtLike = [0, 0]) {\n if (this._space.hasOffscreen) {\n this._space.ctx.drawImage(\n this._space.offscreenCanvas,\n offset[0],\n offset[1],\n this._space.width,\n this._space.height,\n );\n }\n }\n\n /**\n * Set current alpha value.\n * @example `form.alpha(0.6)`\n * @param a alpha value between 0 and 1\n */\n alpha(a: number): this {\n this._set(\"globalAlpha\", a);\n this._style.globalAlpha = a;\n return this;\n }\n\n /**\n * Set current fill style. Provide a valid color string such as `\"#FFF\"` or `\"rgba(255,0,100,0.5)\"` or `false` to specify no fill color.\n * @example `form.fill(\"#F90\")`, `form.fill(\"rgba(0,0,0,.5\")`, `form.fill(false)`\n * @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))\n */\n fill(c: string | boolean | CanvasGradient | CanvasPattern): this {\n if (typeof c == \"boolean\") {\n this.filled = c;\n } else {\n this.filled = true;\n this._style.fillStyle = c;\n this._set(\"fillStyle\", c);\n }\n return this;\n }\n\n /**\n * Set current fill style and remove stroke style.\n * @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))\n */\n fillOnly(c: string | boolean | CanvasGradient | CanvasPattern): this {\n this.stroke(false);\n return this.fill(c);\n }\n\n /**\n * Set current stroke style. Provide a valid color string or `false` to specify no stroke color.\n * @example `form.stroke(\"#F90\")`, `form.stroke(\"rgba(0,0,0,.5\")`, `form.stroke(false)`, `form.stroke(\"#000\", 0.5, 'round', 'square')`\n * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))\n * @param width Optional value (can be floating point) to set line width\n * @param linejoin Optional string to set line joint style. Can be \"miter\", \"bevel\", or \"round\".\n * @param linecap Optional string to set line cap style. Can be \"butt\", \"round\", or \"square\".\n */\n stroke(\n c: string | boolean | CanvasGradient | CanvasPattern,\n width?: number,\n linejoin?: CanvasLineJoin,\n linecap?: CanvasLineCap,\n ): this {\n if (typeof c == \"boolean\") {\n this.stroked = c;\n } else {\n this.stroked = true;\n this._style.strokeStyle = c;\n this._set(\"strokeStyle\", c);\n if (width) {\n this._set(\"lineWidth\", width);\n this._style.lineWidth = width;\n }\n if (linejoin) {\n this._set(\"lineJoin\", linejoin);\n this._style.lineJoin = linejoin;\n }\n if (linecap) {\n this._set(\"lineCap\", linecap);\n this._style.lineCap = linecap;\n }\n }\n return this;\n }\n\n /**\n * Set stroke style and remove fill style.\n * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))\n * @param width Optional value (can be floating point) to set line width\n * @param linejoin Optional string to set line joint style. Can be \"miter\", \"bevel\", or \"round\".\n * @param linecap Optional string to set line cap style. Can be \"butt\", \"round\", or \"square\".\n */\n strokeOnly(\n c: string | boolean | CanvasGradient | CanvasPattern,\n width?: number,\n linejoin?: CanvasLineJoin,\n linecap?: CanvasLineCap,\n ): this {\n this.fill(false);\n return this.stroke(c, width, linejoin, linecap);\n }\n\n /**\n * A convenient function to apply fill and/or stroke after custom drawings using canvas context (eg, `form.ctx.ellipse(...)`).\n * You don't need to call this function if you're using Pts' drawing functions like `form.point` or `form.rect`\n * @param filled apply fill when set to `true`\n * @param stroked apply stroke when set to `true`\n * @param strokeWidth optionally set a stroke width\n * @example `form.ctx.beginPath(); form.ctx.ellipse(...); form.applyFillStroke();`\n */\n applyFillStroke(\n filled: boolean | string = true,\n stroked: boolean | string = true,\n strokeWidth: number = 1,\n ) {\n if (filled) {\n if (typeof filled === \"string\") this.fill(filled);\n this._ctx.fill();\n }\n\n if (stroked) {\n if (typeof stroked === \"string\") this.stroke(stroked, strokeWidth);\n this._ctx.stroke();\n }\n\n return this;\n }\n\n /**\n * This function takes an array of gradient colors, and returns a function to define the areas of the gradient fill. See demo code in [CanvasForm.gradient](https://ptsjs.org/demo/?name=canvasform.textBox).\n * @param stops an array of gradient stops. This can be an array of colors `[\"#f00\", \"#0f0\", ...]` for evenly distributed gradient, or an array of [stop, color] like `[[0.1, \"#f00\"], [0.7, \"#0f0\"]]`\n * @returns a function that takes 1 or 2 `Group` as parameters. Use a single `Group` to specify a rectangular area for linear gradient, or use 2 `Groups` to specify 2 `Circles` for radial gradient.\n * @example `c1 = Circle.fromCenter(...); grad = form.gradient([\"#f00\", \"#00f\"]); form.fill( grad( c1, c2 ) ).circle( c1 )`\n */\n gradient(\n stops: [number, string][] | string[],\n ): (area1: GroupLike, area2?: GroupLike) => CanvasGradient {\n const vals: [number, string][] = [];\n // copy before padding so the caller's array is never mutated\n if (stops.length < 2) {\n stops = [...stops, [0.99, \"#000\"], [1, \"#000\"]] as\n [number, string][] | string[];\n }\n\n for (let i = 0, len = stops.length; i < len; i++) {\n const t: number =\n typeof stops[i] === \"string\"\n ? i * (1 / (stops.length - 1))\n : (stops[i][0] as number);\n const v: string =\n typeof stops[i] === \"string\"\n ? (stops[i] as string)\n : (stops[i][1] as string);\n vals.push([t, v]);\n }\n\n return (area1: GroupLike, area2?: GroupLike) => {\n const grad = area2\n ? this._ctx.createRadialGradient(\n area1[0][0],\n area1[0][1],\n Math.abs(area1[1][0]),\n area2[0][0],\n area2[0][1],\n Math.abs(area2[1][0]),\n )\n : this._ctx.createLinearGradient(\n area1[0][0],\n area1[0][1],\n area1[1][0],\n area1[1][1],\n );\n\n for (let i = 0, len = vals.length; i < len; i++) {\n grad.addColorStop(vals[i][0], vals[i][1]);\n }\n\n return grad;\n };\n }\n\n /**\n * Set composite operation (also known as blend mode). You can also call this function without parameters to get back to default 'source-over' mode. See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) for the full list of operations you can use.\n * @param mode a composite operation such as 'lighten', 'multiply', 'overlay', and 'color-burn'.\n */\n composite(mode: GlobalCompositeOperation = \"source-over\"): this {\n this._set(\"globalCompositeOperation\", mode);\n return this;\n }\n\n /**\n * Create a clipping mask from the current path. See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip) for details.\n */\n clip(): this {\n this._ctx.clip();\n return this;\n }\n\n /**\n * Activate dashed stroke and set dash style. You can customize the segments and offset.\n * @example `form.dash()`, `form.dash([5, 10])`, `form.dash([5, 5], 5)`, `form.dash(false)`\n * @param segments Dash segments. Defaults to `true` which corresponds to `[5, 5]`. Pass `false` to deactivate dashes. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash))\n * @param offset Dash offset. Defaults to 0. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)\n */\n dash(segments: PtLike | boolean = true, offset: number = 0): this {\n // dedupe via a compact key since getLineDash() allocates\n const cache = this._cacheForCtx();\n if (segments === false || (segments !== true && segments.length === 0)) {\n // false or [], deactivate dashed strokes\n if (cache.dash !== \"/0\") {\n cache.dash = \"/0\";\n this._ctx.setLineDash([]);\n this._ctx.lineDashOffset = 0;\n }\n } else {\n const seg: PtLike = segments === true ? [5, 5] : segments;\n const key = `${Array.prototype.join.call(seg, \",\")}/${offset}`;\n if (cache.dash !== key) {\n cache.dash = key;\n this._ctx.setLineDash(seg as number[]);\n this._ctx.lineDashOffset = offset;\n }\n }\n return this;\n }\n\n /**\n * Set the current font.\n * @param sizeOrFont either a number to specify font-size, or a `Font` object to specify all font properties\n * @param weight Optional font-weight string such as \"bold\"\n * @param style Optional font-style string such as \"italic\"\n * @param lineHeight Optional line-height number suchas 1.5\n * @param family Optional font-family such as \"Helvetica, sans-serif\"\n * @example `form.font( myFont )`, `form.font(14, \"bold\")`\n */\n font(\n sizeOrFont: number | Font,\n weight?: string,\n style?: string,\n lineHeight?: number,\n family?: string,\n ): this {\n if (typeof sizeOrFont == \"number\") {\n this._font.size = sizeOrFont;\n if (family) this._font.face = family;\n if (weight) this._font.weight = weight;\n if (style) this._font.style = style;\n if (lineHeight) this._font.lineHeight = lineHeight;\n } else {\n this._font = sizeOrFont;\n }\n\n this._set(\"font\", this._font.value);\n\n // If using estimate, reapply the same mode with the new font's metrics.\n if (this._estimateMode) this.fontWidthEstimate(this._estimateMode);\n\n return this;\n }\n\n /**\n * Set whether to use html canvas' [`measureText`](#link) function, or a faster but less accurate estimate.\n * @param estimate `false` to use ctx.measureText; `true` or `\"sample\"` to use a sampled-average estimator (fastest); `\"char\"` to use a per-character width cache (nearly as accurate as measureText for most texts, and much faster after warmup)\n */\n fontWidthEstimate(estimate: boolean | \"sample\" | \"char\" = true): this {\n if (!estimate) {\n this._estimateMode = undefined;\n this._estimateTextWidth = undefined;\n } else {\n const measure: TextMeasure = (c: string) =>\n this._ctx.measureText(c).width;\n this._estimateMode = estimate === true ? \"sample\" : estimate;\n this._estimateTextWidth =\n this._estimateMode === \"char\"\n ? Typo.charWidthCache(measure)\n : Typo.textWidthEstimator(measure);\n }\n return this;\n }\n\n /**\n * Get the width of this text. It will return an actual measurement or an estimate based on [`fontWidthEstimate`](#link) setting. Default is an actual measurement using canvas context's measureText.\n * @param c a string of text contents\n */\n getTextWidth(c: string): number {\n return !this._estimateTextWidth\n ? this._ctx.measureText(c).width\n : this._estimateTextWidth(c);\n }\n\n /**\n * Truncate text to fit width.\n * @param str text to truncate\n * @param width width to fit\n * @param tail text to indicate overflow such as \"...\". Default is empty \"\".\n */\n protected _textTruncate(\n str: string,\n width: number,\n tail: string = \"\",\n hint?: number,\n ): [string, number] {\n return Typo.truncate(this.getTextWidth.bind(this), str, width, tail, hint);\n }\n\n /**\n * Align text within a rectangle box.\n * @param box a Group or an Iterable<PtLike> that defines a rectangular box\n * @param vertical a string that specifies the vertical alignment in the box: \"top\", \"bottom\", \"middle\", \"start\", \"end\"\n * @param offset Optional offset from the edge (like padding)\n * @param center Optional center position\n */\n protected _textAlign(\n box: PtLikeIterable,\n vertical: TextVerticalAlign,\n offset?: PtLike,\n center?: Pt,\n ): Pt | undefined {\n const _box = Util.iterToArray(box);\n if (!Util.arrayCheck(_box)) return;\n\n if (!center) center = Rectangle.center(_box);\n\n let px = _box[0][0];\n if (this._ctx.textAlign == \"end\" || this._ctx.textAlign == \"right\") {\n px = _box[1][0];\n } else if (\n this._ctx.textAlign == \"center\" ||\n // @ts-expect-error CanvasTextAlign omits the legacy \"middle\" value supported here.\n this._ctx.textAlign == \"middle\"\n ) {\n px = center[0];\n }\n\n let py = center[1];\n if (vertical == \"top\" || vertical == \"start\") {\n py = _box[0][1];\n } else if (vertical == \"end\" || vertical == \"bottom\") {\n py = _box[1][1];\n }\n\n return offset ? new Pt(px + offset[0], py + offset[1]) : new Pt(px, py);\n }\n\n /**\n * Reset the rendering context's common styles to this form's styles. This supports using multiple forms on the same canvas context.\n */\n reset(): this {\n // force-write and resync the cache — this is the documented recovery\n // point after styles were set directly on the context\n const cache = this._cacheForCtx();\n for (const k in this._style) {\n if (this._style.hasOwnProperty(k)) {\n (this._ctx as any)[k] = (this._style as any)[k];\n cache[k] = (this._style as any)[k];\n }\n }\n // same default as a fresh VisualForm (14px sans-serif)\n this._font = new Font(14, \"sans-serif\");\n this._ctx.font = this._font.value;\n cache.font = this._font.value;\n return this;\n }\n\n protected _paint() {\n if (this._filled) this._ctx.fill();\n if (this._stroked) this._ctx.stroke();\n }\n\n /**\n * A static function to draw a point.\n * @param ctx canvas rendering context\n * @param p a Pt object\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `form.point( p )`, `form.point( p, 10, \"circle\" )`\n */\n static point(\n ctx: RenderingContext2D,\n p: PtLike,\n radius: number = 5,\n shape: string = \"square\",\n ) {\n if (!p) return;\n if (!(CanvasForm as any)[shape])\n throw new Error(`${shape} is not a static function of CanvasForm`);\n (CanvasForm as any)[shape](ctx, p, radius);\n }\n\n /**\n * Draws a point.\n * @param p a Pt object\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `form.point( p )`, `form.point( p, 10, \"circle\" )`\n */\n point(p: PtLike, radius: number = 5, shape: string = \"square\"): this {\n CanvasForm.point(this._ctx, p, radius, shape);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw a circle.\n * @param ctx canvas rendering context\n * @param pt center position of the circle\n * @param radius radius of the circle\n */\n static circle(ctx: RenderingContext2D, pt: PtLike, radius: number = 10) {\n if (!pt) return;\n ctx.beginPath();\n ctx.arc(pt[0], pt[1], radius, 0, Const.two_pi, false);\n ctx.closePath();\n }\n\n /**\n * Draw a circle. See also [`Circle.fromCenter`](#link)\n * @param pts usually a Group or an Iterable<PtLike> with 2 Pt, but it can also take an array of two numeric arrays [ [position], [size] ]\n */\n circle(pts: PtLikeIterable): this {\n const p = Util.iterToArray(pts);\n CanvasForm.circle(this._ctx, p[0], p[1][0]);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw an ellipse.\n * @param ctx canvas rendering context\n * @param pt center position\n * @param radius radius [x, y] of the ellipse\n * @param rotation rotation of the ellipse in radian. Default is 0.\n * @param startAngle start angle of the ellipse. Default is 0.\n * @param endAngle end angle of the ellipse. Default is 2 PI.\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n static ellipse(\n ctx: RenderingContext2D,\n pt: PtLike,\n radius: PtLike,\n rotation: number = 0,\n startAngle: number = 0,\n endAngle: number = Const.two_pi,\n cc: boolean = false,\n ) {\n if (!pt || !radius) return;\n ctx.beginPath();\n ctx.ellipse(\n pt[0],\n pt[1],\n radius[0],\n radius[1],\n rotation,\n startAngle,\n endAngle,\n cc,\n );\n }\n\n /**\n * Draw an ellipse.\n * @param pt center position\n * @param radius radius [x, y] of the ellipse\n * @param rotation rotation of the ellipse in radian. Default is 0.\n * @param startAngle start angle of the ellipse. Default is 0.\n * @param endAngle end angle of the ellipse. Default is 2 PI.\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n ellipse(\n pt: PtLike,\n radius: PtLike,\n rotation: number = 0,\n startAngle: number = 0,\n endAngle: number = Const.two_pi,\n cc: boolean = false,\n ) {\n CanvasForm.ellipse(\n this._ctx,\n pt,\n radius,\n rotation,\n startAngle,\n endAngle,\n cc,\n );\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw an arc.\n * @param ctx canvas rendering context\n * @param pt center position\n * @param radius radius of the arc circle\n * @param startAngle start angle of the arc\n * @param endAngle end angle of the arc\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n static arc(\n ctx: RenderingContext2D,\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ) {\n if (!pt) return;\n ctx.beginPath();\n ctx.arc(pt[0], pt[1], radius, startAngle, endAngle, cc);\n }\n\n /**\n * Draw an arc.\n * @param pt center position\n * @param radius radius of the arc circle\n * @param startAngle start angle of the arc\n * @param endAngle end angle of the arc\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n arc(\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): this {\n CanvasForm.arc(this._ctx, pt, radius, startAngle, endAngle, cc);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw a square.\n * @param ctx canvas rendering context\n * @param pt center position of the square\n * @param halfsize half size of the square\n */\n static square(ctx: RenderingContext2D, pt: PtLike, halfsize: number) {\n if (!pt) return;\n const x1 = pt[0] - halfsize;\n const y1 = pt[1] - halfsize;\n const x2 = pt[0] + halfsize;\n const y2 = pt[1] + halfsize;\n\n // faster than using `rect`\n ctx.beginPath();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x1, y2);\n ctx.lineTo(x2, y2);\n ctx.lineTo(x2, y1);\n ctx.closePath();\n }\n\n /**\n * Draw a square, given a center and its half-size.\n * @param pt center Pt\n * @param halfsize half-size\n */\n square(pt: PtLike, halfsize: number) {\n CanvasForm.square(this._ctx, pt, halfsize);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw a line or polyline.\n * @param ctx canvas rendering context\n * @param pts a Group or an Iterable<PtLike> representing a line\n */\n static line(ctx: RenderingContext2D, pts: PtLikeIterable) {\n if (!Util.arrayCheck(pts)) return;\n ctx.beginPath();\n let i = 0;\n if (Array.isArray(pts)) {\n // indexed fast path — inputs are nearly always Groups (Array subclass)\n for (let k = 0, len = pts.length; k < len; k++) {\n const it = pts[k];\n if (it) {\n if (i++ > 0) {\n ctx.lineTo(it[0], it[1]);\n } else {\n ctx.moveTo(it[0], it[1]);\n }\n }\n }\n } else {\n for (const it of pts) {\n if (it) {\n if (i++ > 0) {\n ctx.lineTo(it[0], it[1]);\n } else {\n ctx.moveTo(it[0], it[1]);\n }\n }\n }\n }\n }\n\n /**\n * Draw a line or polyline.\n * @param pts a Group or an Iterable<PtLike> representing a line\n */\n line(pts: PtLikeIterable): this {\n const p = Util.iterToArray(pts);\n if (Util.arrayCheck(p)) {\n CanvasForm.line(this._ctx, p);\n this._paint();\n }\n return this;\n }\n\n /**\n * A static function to draw a chain of cubic Bezier curves as one native path.\n * @param ctx canvas rendering context\n * @param pts a Group or an Iterable<PtLike> in the layout of [`Curve.bezier`](#link): an anchor followed by 2 control points and an anchor per segment\n */\n static bezier(ctx: RenderingContext2D, pts: PtLikeIterable) {\n const p = Util.iterToArray(pts);\n if (p.length < 4) return;\n ctx.beginPath();\n ctx.moveTo(p[0][0], p[0][1]);\n for (let i = 3; i < p.length; i += 3) {\n const c1 = p[i - 2];\n const c2 = p[i - 1];\n ctx.bezierCurveTo(c1[0], c1[1], c2[0], c2[1], p[i][0], p[i][1]);\n }\n }\n\n /**\n * Draw a chain of cubic Bezier curves as one native path. Unlike a polyline from [`Curve.bezier`](#link),\n * the path stays smooth at any zoom and exports as compact SVG. Use [`Curve.cardinalToBezier`](#link) or\n * [`Curve.bsplineToBezier`](#link) to draw those curves this way.\n * @param pts a Group or an Iterable<PtLike> in the layout of [`Curve.bezier`](#link): an anchor followed by 2 control points and an anchor per segment\n * @example `form.bezier( Curve.cardinalToBezier( pts ) )`\n */\n bezier(pts: PtLikeIterable): this {\n const p = Util.iterToArray(pts);\n if (Util.arrayCheck(p, 4)) {\n CanvasForm.bezier(this._ctx, p);\n this._paint();\n }\n return this;\n }\n\n /**\n * A static function to draw a polygon.\n * @param ctx canvas rendering context\n * @param pts a Group or an Iterable<PtLike> representing a polygon\n */\n static polygon(ctx: RenderingContext2D, pts: PtLikeIterable) {\n if (!Util.arrayCheck(pts)) return;\n CanvasForm.line(ctx, pts);\n ctx.closePath();\n }\n\n /**\n * Draw a polygon.\n * @param pts a Group or an Iterable<PtLike> representingg a polygon\n */\n polygon(pts: PtLikeIterable): this {\n const p = Util.iterToArray(pts);\n if (Util.arrayCheck(p)) {\n CanvasForm.polygon(this._ctx, p);\n this._paint();\n }\n return this;\n }\n\n /**\n * A static function to draw a compound polygon: several rings as one path, so that a ring inside another with the opposite orientation becomes a hole (the nonzero winding rule).\n * @param ctx canvas rendering context\n * @param rings an Array/Iterable of rings, each a Group or an Iterable<PtLike>; rings with fewer than 2 points are skipped\n */\n static compound(ctx: RenderingContext2D, rings: Iterable<PtLikeIterable>) {\n let started = false;\n for (const ring of rings) {\n const p = Util.iterToArray(ring);\n if (p.length < 2) continue;\n if (typeof p[0][0] !== \"number\") {\n // a list of polygons (such as a Path.divide result) instead of a list of rings\n Util.warn(\n \"compound expects rings of points; draw each polygon of a divide or crop result separately\",\n );\n return;\n }\n if (!started) {\n ctx.beginPath();\n started = true;\n }\n ctx.moveTo(p[0][0], p[0][1]);\n for (let i = 1, len = p.length; i < len; i++)\n ctx.lineTo(p[i][0], p[i][1]);\n ctx.closePath();\n }\n }\n\n /**\n * Draw a compound polygon: several rings as one path, so that a ring inside another with the opposite orientation becomes a hole\n * (the nonzero winding rule). This is how a [`Path`](#link) result is drawn; [`CanvasForm.polygons`](#link) would fill the holes.\n * @param rings an Array/Iterable of rings, each a Group or an Iterable<PtLike>; rings with fewer than 2 points are skipped, and nothing is drawn if no ring remains\n * @example `form.fillOnly(\"#f03\").compound( Path.minusFront( [disc, hole] ) )`\n */\n compound(rings: Iterable<PtLikeIterable>): this {\n const list: PtLike[][] = [];\n let drawable = false;\n for (const ring of rings) {\n const p = Util.iterToArray(ring);\n if (p.length > 0 && typeof p[0][0] !== \"number\") {\n // a list of polygons (such as a Path.divide result) instead of a list of rings\n return Util.warn(\n \"compound expects rings of points; draw each polygon of a divide or crop result separately\",\n this,\n );\n }\n if (p.length >= 2) drawable = true;\n list.push(p);\n }\n if (drawable) {\n CanvasForm.compound(this._ctx, list);\n this._paint();\n }\n return this;\n }\n\n /**\n * A static function to draw a rectangle.\n * @param ctx canvas rendering context\n * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.\n */\n static rect(ctx: RenderingContext2D, pts: PtLikeIterable) {\n const p = Util.iterToArray(pts);\n if (!Util.arrayCheck(p)) return;\n ctx.beginPath();\n ctx.moveTo(p[0][0], p[0][1]);\n ctx.lineTo(p[0][0], p[1][1]);\n ctx.lineTo(p[1][0], p[1][1]);\n ctx.lineTo(p[1][0], p[0][1]);\n ctx.closePath();\n }\n\n /**\n * Draw a rectangle.\n * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.\n */\n rect(pts: PtLikeIterable): this {\n CanvasForm.rect(this._ctx, pts);\n this._paint();\n return this;\n }\n\n /**\n * A static function to draw an image.\n * @param ctx canvas rendering context\n * @param img either an [Img](#link) instance or an [`CanvasImageSource`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource) instance (eg the image from `<img>`, `<video>` or `<canvas>`)\n * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.\n * @param orig optionally a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a cropping box in the original target.\n */\n static image(\n ctx: RenderingContext2D,\n ptOrRect: PtLike | PtLikeIterable,\n img: CanvasImageSource | Img,\n orig?: PtLikeIterable,\n ) {\n const t = Util.iterToArray(ptOrRect);\n let pos: number[];\n\n if (typeof t[0] === \"number\") {\n // no crop\n pos = t as number[];\n } else {\n if (orig) {\n // crop\n const o = Util.iterToArray(orig);\n pos = [\n o[0][0],\n o[0][1],\n o[1][0] - o[0][0],\n o[1][1] - o[0][1],\n t[0][0],\n t[0][1],\n t[1][0] - t[0][0],\n t[1][1] - t[0][1],\n ];\n } else {\n // bounding box resize\n pos = [t[0][0], t[0][1], t[1][0] - t[0][0], t[1][1] - t[0][1]];\n }\n }\n\n if (img instanceof Img) {\n if (img.loaded) {\n // @ts-expect-error legacy DOM lib types omit these vendor/optional members\n ctx.drawImage(img.image, ...pos);\n }\n } else {\n // @ts-expect-error legacy DOM lib types omit these vendor/optional members\n ctx.drawImage(img, ...pos);\n }\n }\n\n /**\n * Draw an image.\n * @param img either an [Img](#link) instance or an [`CanvasImageSource`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource) instance (eg the image from `<img>`, `<video>` or `<canvas>`)\n * @param ptOrRect a target area to place the image. Either a PtLike specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left position, bottom-right position) that specifies a bounding box. Default is (0,0) at top-left.\n * @param orig optionally a Group or an Iterable<PtLike> with 2 Pt (top-left position, bottom-right position) that specifies a cropping box in the original target.\n */\n image(\n ptOrRect: PtLike | PtLikeIterable,\n img: CanvasImageSource | Img,\n orig?: PtLikeIterable,\n ) {\n if (img instanceof Img) {\n if (img.loaded) {\n CanvasForm.image(this._ctx, ptOrRect, img.image, orig);\n }\n } else {\n CanvasForm.image(this._ctx, ptOrRect, img, orig);\n }\n return this;\n }\n\n /**\n * A static function to draw ImageData on canvas\n * @param ctx canvas rendering context\n * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that places a region of the image data of that size at that position. Note that `putImageData` cannot resize: the rect clips, not scales. Default is (0,0) at top-left.\n * @param img an ImageData object\n */\n static imageData(\n ctx: RenderingContext2D,\n ptOrRect: PtLike | PtLikeIterable,\n img: ImageData,\n ) {\n const t = Util.iterToArray(ptOrRect);\n if (typeof t[0] === \"number\") {\n // Pt\n ctx.putImageData(img, t[0], t[1]);\n } else {\n // rect: place the image data's top-left region of the rect's size at\n // the rect's position (dirty coordinates are relative to the data)\n ctx.putImageData(\n img,\n t[0][0],\n t[0][1],\n 0,\n 0,\n t[1][0] - t[0][0],\n t[1][1] - t[0][1],\n );\n }\n }\n\n /**\n * Draw ImageData on canvas using ImageData\n * @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.\n * @param img an ImageData object\n */\n imageData(ptOrRect: PtLike | PtLikeIterable, img: ImageData) {\n CanvasForm.imageData(this._ctx, ptOrRect, img);\n return this;\n }\n\n /**\n * A static function to draw text.\n * @param ctx canvas rendering context\n * @param pt a Point object to specify the anchor point\n * @param txt a string of text to draw\n * @param maxWidth specify a maximum width per line\n */\n static text(\n ctx: RenderingContext2D,\n pt: PtLike,\n txt: string,\n maxWidth?: number,\n ) {\n if (!pt) return;\n ctx.fillText(txt, pt[0], pt[1], maxWidth);\n }\n\n /**\n * Draw text on canvas.\n * @param pt a Pt or numeric array to specify the anchor point\n * @param txt text\n * @param maxWidth specify a maximum width per line\n */\n text(pt: PtLike, txt: string, maxWidth?: number): this {\n CanvasForm.text(this._ctx, pt, txt, maxWidth);\n return this;\n }\n\n /**\n * Fit a single-line text in a rectangular box.\n * @param box a rectangle box defined by a Group or an Iterable<Pt>\n * @param txt string of text\n * @param tail text to indicate overflow such as \"...\". Default is empty \"\".\n * @param verticalAlign \"top\", \"middle\", or \"bottom\" to specify vertical alignment inside the box\n * @param overrideBaseline If `true`, use the corresponding baseline as verticalAlign. If `false`, use the current canvas context's textBaseline setting. Default is `true`.\n */\n textBox(\n box: PtIterable,\n txt: string,\n verticalAlign: TextVerticalAlign = \"middle\",\n tail: string = \"\",\n overrideBaseline: boolean = true,\n ): this {\n // \"center\", \"start\", and \"end\" are box alignments, not canvas baselines;\n // assigning them to textBaseline is silently ignored by the context\n if (overrideBaseline) {\n this._ctx.textBaseline =\n verticalAlign === \"center\"\n ? \"middle\"\n : verticalAlign === \"start\"\n ? \"top\"\n : verticalAlign === \"end\"\n ? \"bottom\"\n : verticalAlign;\n }\n const size = Rectangle.size(box);\n const t = this._textTruncate(txt, size[0], tail);\n this.text(this._textAlign(box, verticalAlign)!, t[0]);\n return this;\n }\n\n /**\n * Fit multi-line text in a rectangular box. Note that this will also set canvas context's textBaseline to \"top\".\n * @param box a Group or an Iterable<PtLike> with 2 Pt that represents a bounding box\n * @param txt string of text\n * @param lineHeight line height as a ratio of font size. Default is 1.2.\n * @param verticalAlign \"top\", \"middle\", or \"bottom\" to specify vertical alignment inside the box\n * @param crop a boolean to specify whether to crop text when overflowing\n */\n paragraphBox(\n box: PtLikeIterable,\n txt: string,\n lineHeight: number = 1.2,\n verticalAlign: TextVerticalAlign = \"top\",\n crop: boolean = true,\n ): this {\n const b = Group.fromArray(box);\n const size = Rectangle.size(b);\n this._ctx.textBaseline = \"top\"; // override textBaseline\n\n const lstep = this._font.size * lineHeight;\n\n // Seed each line's cut search with the previous line's fitted length, so\n // truncate probes near the boundary instead of measuring the whole\n // remainder (which made wrapping quadratic in text length). The first\n // line's seed is estimated from a single character sample.\n let hint = Math.ceil(size[0] / Math.max(1, this.getTextWidth(\"n\")));\n\n const lines: string[] = [];\n let sub = txt;\n while (sub) {\n // crop when the next line would no longer fit inside the box\n if (crop && (lines.length + 1) * lstep > size[1]) break;\n\n const t = this._textTruncate(sub, size[0], \"\", hint);\n if (t[1] > 0) hint = t[1];\n\n // new line\n const newln = t[0].indexOf(\"\\n\");\n if (newln >= 0) {\n lines.push(t[0].slice(0, newln));\n sub = sub.slice(newln + 1);\n continue;\n }\n\n // word wrap\n const consumedAll = t[1] === sub.length;\n let dt: number | undefined;\n if (consumedAll) {\n dt = undefined;\n } else if (sub[t[1]] === \" \") {\n // the line ends exactly at a word boundary: keep the whole line and\n // drop the space, instead of wrapping before its last word\n dt = t[1] + 1;\n } else {\n dt = t[0].lastIndexOf(\" \") + 1;\n if (dt <= 0) dt = undefined;\n }\n lines.push(dt === undefined ? t[0] : t[0].slice(0, dt));\n\n if (t[1] <= 0 || consumedAll) break;\n sub = sub.slice(dt ?? t[1]);\n }\n const lsize = lines.length * lstep; // total height\n let lbox = b;\n\n if (verticalAlign == \"middle\" || verticalAlign == \"center\") {\n let lpad = (size[1] - lsize) / 2;\n if (crop) lpad = Math.max(0, lpad);\n lbox = new Group(b[0].$add(0, lpad), b[1].$subtract(0, lpad));\n } else if (verticalAlign == \"bottom\") {\n lbox = new Group(b[0].$add(0, size[1] - lsize), b[1]);\n } else {\n lbox = new Group(b[0], b[0].$add(size[0], lsize));\n }\n\n const center = Rectangle.center(lbox);\n for (let i = 0, len = lines.length; i < len; i++) {\n this.text(\n this._textAlign(lbox, \"top\", [0, i * lstep], center)!,\n lines[i],\n );\n }\n\n return this;\n }\n\n /**\n * Set text alignment and baseline (eg, vertical-align).\n * @param alignment HTML canvas' textAlign option: \"left\", \"right\", \"center\", \"start\", or \"end\"\n * @param baseline HTML canvas' textBaseline option: \"top\", \"hanging\", \"middle\", \"alphabetic\", \"ideographic\", \"bottom\". For convenience, you can also use \"center\" (same as \"middle\"), and \"baseline\" (same as \"alphabetic\")\n */\n alignText(\n alignment: CanvasTextAlign = \"left\",\n baseline: CanvasTextBaseline = \"alphabetic\",\n ) {\n // @ts-expect-error legacy DOM lib types omit these vendor/optional members\n if (baseline == \"center\") baseline = \"middle\";\n // @ts-expect-error legacy DOM lib types omit these vendor/optional members\n if (baseline == \"baseline\") baseline = \"alphabetic\";\n this._ctx.textAlign = alignment;\n this._ctx.textBaseline = baseline;\n return this;\n }\n\n /**\n * A convenient way to draw some text on canvas for logging or debugging. It'll be draw on the top-left of the canvas as an overlay.\n * @param txt text\n */\n log(txt: any): this {\n const w = this._ctx.measureText(txt).width + 20;\n this.stroke(false)\n .fill(\"rgba(0,0,0,.4)\")\n .rect([\n [0, 0],\n [w, 20],\n ]);\n this.fill(\"#fff\").text([10, 14], txt);\n return this;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Group, Bound } from \"./Pt\";\nimport { Line, Triangle } from \"./Op\";\nimport { Const, Util } from \"./Util\";\nimport { Num, Geom } from \"./Num\";\nimport { triangulate, type Triangulation } from \"./_triangulate\";\nimport {\n type PtLike,\n type PtLikeIterable,\n type GroupLike,\n type PtIterable,\n type DelaunayMesh,\n type DelaunayShape,\n type FlockBoundary,\n type FlockOptions,\n type PoissonDiskOptions,\n} from \"./Types\";\n\n/**\n * The `Create` class helps you create structures from sets of points.\n */\nexport class Create {\n /**\n * Create a set of random points inside a bounday.\n * @param bound the rectangular boundary\n * @param count number of random points to create\n * @param dimensions number of dimensions in each point\n */\n static distributeRandom(\n bound: Bound,\n count: number,\n dimensions: number = 2,\n ): Group {\n let pts = new Group();\n for (let i = 0; i < count; i++) {\n let p = [bound.x! + Num.random() * bound.width];\n if (dimensions > 1) p.push(bound.y! + Num.random() * bound.height);\n if (dimensions > 2) p.push(bound.z! + Num.random() * bound.depth);\n pts.push(new Pt(p));\n }\n return pts;\n }\n\n /**\n * Create a set of points that distribute evenly on a line. Similar to [`Line.subpoints`](#link) but includes the end points.\n * @param line a Group or an Iterable<Pt> representing a line\n * @param count number of points to create\n */\n static distributeLinear(line: PtIterable, count: number): Group {\n if (count <= 0) return new Group();\n let _line = Util.iterToArray(line);\n if (count === 1) return new Group(_line[0]);\n let ln = Line.subpoints(_line, count - 2);\n ln.unshift(_line[0]);\n ln.push(_line[_line.length - 1]);\n return ln;\n }\n\n /**\n * Create an evenly distributed set of points (like a grid of points) inside a boundary.\n * @param bound the rectangular boundary\n * @param columns number of columns\n * @param rows number of rows\n * @param orientation a Pt or number array to specify where the point should be inside a cell. Default is [0.5, 0.5] which places the point in the middle.\n * @returns a Group of Pts\n */\n static gridPts(\n bound: Bound,\n columns: number,\n rows: number,\n orientation: PtLike = [0.5, 0.5],\n ): Group {\n if (columns === 0 || rows === 0)\n throw new Error(\"grid columns and rows cannot be 0\");\n let unit = bound.size.$subtract(1).$divide(columns, rows);\n let offset = unit.$multiply(orientation);\n let g = new Group();\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < columns; c++) {\n g.push(bound.topLeft.$add(unit.$multiply(c, r)).add(offset));\n }\n }\n return g;\n }\n\n /**\n * Create a grid of cells inside a boundary, where each cell is defined by a group of 2 Pt.\n * @param bound the rectangular boundary\n * @param columns number of columns\n * @param rows number of rows\n * @returns an array of Groups, where each group represents a rectangular cell\n */\n static gridCells(bound: Bound, columns: number, rows: number): Group[] {\n if (columns === 0 || rows === 0)\n throw new Error(\"grid columns and rows cannot be 0\");\n let unit = bound.size.$subtract(1).divide(columns, rows); // subtract 1 to fill whole border of rectangles\n let g = [];\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < columns; c++) {\n g.push(\n new Group(\n bound.topLeft.$add(unit.$multiply(c, r)),\n bound.topLeft.$add(unit.$multiply(c, r).add(unit)),\n ),\n );\n }\n }\n return g;\n }\n\n /**\n * Create a set of Pts around a circular path.\n * @param center circle center\n * @param radius circle radius\n * @param count number of Pts to create\n * @param angleOffset offset starting angle\n */\n static radialPts(\n center: PtLike,\n radius: number,\n count: number,\n angleOffset: number = -Const.half_pi,\n ): Group {\n let g = new Group();\n let a = Const.two_pi / count;\n for (let i = 0; i < count; i++) {\n g.push(new Pt(center).toAngle(a * i + angleOffset, radius, true));\n }\n return g;\n }\n\n /**\n * Given a group of Pts, return a new group of `Noise` Pts.\n * @param pts a Group or an Iterable<Pt>, in row-major order when treated as a grid\n * @param dx small increment value in x dimension\n * @param dy small increment value in y dimension\n * @param rows Optional row count to generate 2D noise\n * @param columns Optional column count (points per row) to generate 2D noise. When provided, each point's noise offset is (dx·column, dy·row) with row = floor(i/columns); when only `rows` is provided it is used as the points-per-row divisor instead.\n */\n static noisePts(\n pts: PtIterable,\n dx = 0.01,\n dy = 0.01,\n rows = 0,\n columns = 0,\n ): Group {\n let seed = Num.random();\n let g = new Group();\n let i = 0;\n // row-major grid: one consistent per-row divisor for both row and column\n const perRow = columns > 0 ? columns : rows > 0 ? rows : 0;\n for (let p of pts) {\n let np = new Noise(p);\n let r = perRow > 0 ? Math.floor(i / perRow) : i;\n let c = perRow > 0 ? i % perRow : i;\n np.initNoise(dx * c, dy * r);\n np.seed(seed);\n g.push(np);\n i++;\n }\n return g;\n }\n\n /**\n * Create a Delaunay Group. Use the [`Delaunay.delaunay()`](#link) and [`Delaunay.voronoi()`](#link) functions in the returned group to generate tessellations.\n * @param pts a Group or an array of Pts\n * @returns an instance of the Delaunay class\n */\n static delaunay(pts: GroupLike): Delaunay {\n return Delaunay.from(pts) as Delaunay;\n }\n\n /**\n * Create a [`Flock`](#link) of [`Boid`](#link) agents that simulate flocking (also known as \"boids\"),\n * where each agent steers by three local rules: separation, alignment, and cohesion.\n * Advance the simulation by calling [`Flock.step`](#link) with the elapsed time.\n * See a [flocking demo here](https://ptsjs.org/demo/?name=create.flock).\n *\n * Each agent starts with a random heading, drawn from [`Num.random`](#link), so seeding with\n * [`Num.seed`](#link) makes a flock reproducible.\n *\n * @param pts a Group or an Iterable<Pt> of starting positions\n * @param options optional [`FlockOptions`](#link) to tune the behavior\n * @returns an instance of the Flock class, which is a Group of Boids\n * @example `Create.flock( Create.distributeRandom( space.innerBound, 200 ), { bound: space.innerBound } )`\n */\n static flock(pts: PtLikeIterable, options: FlockOptions = {}): Flock {\n const flock = new Flock();\n flock.setup(options);\n for (const p of pts) flock.addBoid(p);\n return flock;\n }\n\n /**\n * Create a set of Pts that are randomly placed but never closer than `radius` to each other,\n * using Poisson-disk sampling (also called blue noise).\n * Compared with [`Create.distributeRandom`](#link), the points avoid clumping.\n * Sampling uses a finite candidate budget, so gaps can remain when it finishes.\n * The returned [`PoissonDisk`](#link) is a complete Group; to grow a set gradually instead,\n * construct a `PoissonDisk` and call its [`PoissonDisk.step`](#link) or [`PoissonDisk.sample`](#link).\n * See a [demo here](https://ptsjs.org/demo/?name=create.sampling).\n *\n * Randomness comes from [`Num.random`](#link), so seeding with [`Num.seed`](#link) makes the set reproducible.\n *\n * @param bound the rectangular boundary\n * @param radius minimum distance between any two points\n * @param options optional [`PoissonDiskOptions`](#link)\n * @returns an instance of the PoissonDisk class, which is a Group of Pts\n * @example `Create.sampling( space.innerBound, 10 )`\n */\n static sampling(\n bound: Bound,\n radius: number,\n options: PoissonDiskOptions = {},\n ): PoissonDisk {\n return new PoissonDisk().setup(bound, radius, options).sample();\n }\n}\n\n/**\n * Perlin noise gradient indices\n */\nconst __noise_grad3 = [\n [1, 1, 0],\n [-1, 1, 0],\n [1, -1, 0],\n [-1, -1, 0],\n [1, 0, 1],\n [-1, 0, 1],\n [1, 0, -1],\n [-1, 0, -1],\n [0, 1, 1],\n [0, -1, 1],\n [0, 1, -1],\n [0, -1, -1],\n];\n\n/**\n * Perlin noise permutation table\n */\nconst __noise_permTable = [\n 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140,\n 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234,\n 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237,\n 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48,\n 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105,\n 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73,\n 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86,\n 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38,\n 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189,\n 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101,\n 155, 167, 43, 172, 9, 129, 22, 39, 253, 9, 98, 108, 110, 79, 113, 224, 232,\n 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12,\n 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31,\n 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254,\n 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215,\n 61, 156, 180,\n];\n\n// The doubled base permutation table, built once and shared by every unseeded\n// Noise instance (a per-instance copy would allocate 512 entries per point in\n// `Create.noisePts`). `seed()` swaps in a seeded table instead of mutating.\nconst __noise_permDoubled = __noise_permTable.concat(__noise_permTable);\n\n// Memoize the last seeded table: `Create.noisePts` seeds every point with the\n// same value, so all its Noise Pts share one table.\nlet __noise_lastSeed: number | undefined = undefined;\nlet __noise_lastPerm: number[] | null = null;\n\nfunction __noise_seededPerm(seed: number): number[] {\n if (seed === __noise_lastSeed && __noise_lastPerm) return __noise_lastPerm;\n\n let s = seed;\n if (s > 0 && s < 1) s *= 65536;\n s = Math.floor(s);\n if (s < 256) s |= s << 8;\n\n const perm = new Array<number>(512);\n for (let i = 0; i < 256; i++) {\n const v =\n i & 1\n ? __noise_permTable[i] ^ (s & 255)\n : __noise_permTable[i] ^ ((s >> 8) & 255);\n perm[i] = perm[i + 256] = v;\n }\n\n __noise_lastSeed = seed;\n __noise_lastPerm = perm;\n return perm;\n}\n\n/**\n * Noise is a subclass of Pt that generates Perlin noise. Current implementation supports basic 2D noise.\n * This implementation is based on this [gist](https://gist.github.com/banksean/304522).\n */\nexport class Noise extends Pt {\n protected perm: number[] = [];\n private _n: Pt = new Pt(0.01, 0.01);\n\n /**\n * Create a Noise Pt that can generate noise continuously. See a [Noise demo here](https://ptsjs.org/demo/?name=create.noisePts).\n * @param args a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n constructor(...args: any[]) {\n super(...args);\n\n // shared doubled table for easy index wrapping; replaced by seed()\n this.perm = __noise_permDoubled;\n }\n\n /**\n * Set the initial dimensional values of the noise.\n * @param args a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n * @example `noise.initNoise( 0.01, 0.1 )`\n */\n initNoise(...args: any[]) {\n this._n = new Pt(...args);\n return this;\n }\n\n /**\n * Add a small increment to the noise values.\n * @param x step in x dimension\n * @param y step in y dimension\n */\n step(x = 0, y = 0) {\n this._n.add(x, y);\n return this;\n }\n\n /**\n * Specify a seed for this Noise.\n * @param s seed value\n */\n seed(s: number) {\n this.perm = __noise_seededPerm(s);\n return this;\n }\n\n /**\n * Generate a 2D Perlin noise value.\n */\n noise2D() {\n const perm = this.perm;\n const nx = this._n[0];\n const ny = this._n[1];\n\n // integer cell (wrapped to the table via two's-complement &, which also\n // handles negative coordinates seamlessly) and the position within it\n const cx = Math.floor(nx);\n const cy = Math.floor(ny);\n const i = cx & 255;\n const j = cy & 255;\n const x = nx - cx;\n const y = ny - cy;\n\n // standard Perlin gradient hashing through the permutation table; the\n // doubled table makes i + perm[j + 1] safe without extra wrapping\n const g00 = __noise_grad3[perm[i + perm[j]] % 12];\n const g01 = __noise_grad3[perm[i + perm[j + 1]] % 12];\n const g10 = __noise_grad3[perm[i + 1 + perm[j]] % 12];\n const g11 = __noise_grad3[perm[i + 1 + perm[j + 1]] % 12];\n\n const n00 = g00[0] * x + g00[1] * y;\n const n01 = g01[0] * x + g01[1] * (y - 1);\n const n10 = g10[0] * (x - 1) + g10[1] * y;\n const n11 = g11[0] * (x - 1) + g11[1] * (y - 1);\n\n const _fade = (f: number) => f * f * f * (f * (f * 6 - 15) + 10);\n const tx = _fade(x);\n const u = n00 + tx * (n10 - n00);\n const v = n01 + tx * (n11 - n01);\n return u + _fade(y) * (v - u);\n }\n}\n\n/**\n * Clip a convex cell polygon against an axis-aligned rectangle\n * (Sutherland–Hodgman). Returns the input Group unchanged (shared Pt\n * references) when every vertex is already inside.\n */\nfunction _clipCellToRect(\n cell: Group,\n x0: number,\n y0: number,\n x1: number,\n y1: number,\n): Group {\n // fast path: fully inside\n let inside = true;\n for (let i = 0, len = cell.length; i < len; i++) {\n const px = cell[i][0];\n const py = cell[i][1];\n if (px < x0 || px > x1 || py < y0 || py > y1 || !Number.isFinite(px + py)) {\n inside = false;\n break;\n }\n }\n if (inside) return cell;\n\n // degenerate hull fragments (1-2 vertices) cannot form a polygon to clip;\n // keep only their in-bound vertices\n if (cell.length < 3) {\n const kept = new Group();\n for (let i = 0, len = cell.length; i < len; i++) {\n const px = cell[i][0];\n const py = cell[i][1];\n if (px >= x0 && px <= x1 && py >= y0 && py <= y1) kept.push(cell[i]);\n }\n return kept;\n }\n\n // clamp non-finite coordinates so intersection math stays finite\n const big = 1e7;\n let pts: number[][] = [];\n for (let i = 0, len = cell.length; i < len; i++) {\n let px = cell[i][0];\n let py = cell[i][1];\n if (!Number.isFinite(px)) px = px > 0 ? big : -big;\n if (!Number.isFinite(py)) py = py > 0 ? big : -big;\n if (Number.isNaN(px) || Number.isNaN(py)) continue;\n pts.push([px, py]);\n }\n\n // clip against each rect edge: keep(p) tests inside, cross(a,b) intersects\n const clip = (\n input: number[][],\n keep: (p: number[]) => boolean,\n cross: (a: number[], b: number[]) => number[],\n ): number[][] => {\n const output: number[][] = [];\n for (let i = 0, len = input.length; i < len; i++) {\n const a = input[i === 0 ? len - 1 : i - 1];\n const b = input[i];\n const keepB = keep(b);\n if (keep(a)) {\n if (keepB) output.push(b);\n else output.push(cross(a, b));\n } else if (keepB) {\n output.push(cross(a, b), b);\n }\n }\n return output;\n };\n\n const lerpAt = (a: number[], b: number[], t: number): number[] => [\n a[0] + (b[0] - a[0]) * t,\n a[1] + (b[1] - a[1]) * t,\n ];\n\n pts = clip(\n pts,\n (p) => p[0] >= x0,\n (a, b) => lerpAt(a, b, (x0 - a[0]) / (b[0] - a[0])),\n );\n pts = clip(\n pts,\n (p) => p[0] <= x1,\n (a, b) => lerpAt(a, b, (x1 - a[0]) / (b[0] - a[0])),\n );\n pts = clip(\n pts,\n (p) => p[1] >= y0,\n (a, b) => lerpAt(a, b, (y0 - a[1]) / (b[1] - a[1])),\n );\n pts = clip(\n pts,\n (p) => p[1] <= y1,\n (a, b) => lerpAt(a, b, (y1 - a[1]) / (b[1] - a[1])),\n );\n\n const out = new Group();\n for (let i = 0, len = pts.length; i < len; i++) {\n out.push(new Pt(pts[i]));\n }\n return out;\n}\n\n/** Keep the part of a convex cell nearer to site a than site b. */\nfunction _clipCellToBisector(cell: Group, a: Pt, b: Pt): Group {\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const mx = a[0] + dx / 2;\n const my = a[1] + dy / 2;\n const out = new Group();\n for (let i = 0; i < cell.length; i++) {\n const p = cell[i === 0 ? cell.length - 1 : i - 1];\n const q = cell[i];\n const dp = (p[0] - mx) * dx + (p[1] - my) * dy;\n const dq = (q[0] - mx) * dx + (q[1] - my) * dy;\n if (dp <= 0 !== dq <= 0) {\n const t = dp / (dp - dq);\n out.push(new Pt(p[0] + (q[0] - p[0]) * t, p[1] + (q[1] - p[1]) * t));\n }\n if (dq <= 0) out.push(q);\n }\n return out;\n}\n\n/** Circumcenter and radius of a triangle, as `[x, y, r]`. */\nfunction _circumcircle(\n ax: number,\n ay: number,\n bx: number,\n by: number,\n cx: number,\n cy: number,\n): [number, number, number] {\n const bx2 = bx - ax;\n const by2 = by - ay;\n const cx2 = cx - ax;\n const cy2 = cy - ay;\n const d = 2 * (bx2 * cy2 - by2 * cx2);\n const bl = bx2 * bx2 + by2 * by2;\n const cl = cx2 * cx2 + cy2 * cy2;\n const ux = (cy2 * bl - by2 * cl) / d;\n const uy = (bx2 * cl - cx2 * bl) / d;\n return [ax + ux, ay + uy, Math.sqrt(ux * ux + uy * uy)];\n}\n\n/**\n * Delaunay is a [`Group`](#link) of Pts that generates Delaunay and Voronoi tessellations.\n * Points are triangulated by incremental insertion in Hilbert-curve order with exact\n * orientation and in-circle tests, so grids, collinear runs, points on edges, and duplicate\n * points are handled without degenerate triangles.\n */\nexport class Delaunay extends Group {\n private _mesh: DelaunayMesh = [];\n private _meshBuilt = true;\n private _count = 0;\n private _tri: Triangulation | null = null;\n private _shapes: DelaunayShape[] | null = null;\n\n /**\n * Generate Delaunay triangles. This function also caches the mesh that is used to generate Voronoi tessellation in `voronoi()`. See a [Delaunay demo here](https://ptsjs.org/demo/?name=create.delaunay).\n * @param triangleOnly if true, returns an array of triangles in Groups, otherwise return the whole DelaunayShape\n * @returns an array of Groups or an array of DelaunayShapes `{i, j, k, triangle, circle}` which records the indices of the vertices, and the calculated triangles and circumcircles\n */\n delaunay(triangleOnly: boolean = true): GroupLike[] | DelaunayShape[] {\n const n = this.length;\n this._count = n;\n this._mesh = [];\n this._meshBuilt = false;\n this._tri = null;\n this._shapes = null;\n if (n < 3) return [];\n\n const coords = new Float64Array(n * 2);\n for (let i = 0; i < n; i++) {\n coords[2 * i] = this[i][0];\n coords[2 * i + 1] = this[i][1];\n }\n\n const tri = triangulate(coords, n);\n if (tri.triangles.length === 0) return [];\n this._tri = tri;\n const indices = tri.triangles;\n\n const shapes: DelaunayShape[] = [];\n const tris: GroupLike[] = [];\n for (let t = 0, len = indices.length; t < len; t += 3) {\n const i = indices[t];\n const j = indices[t + 1];\n const k = indices[t + 2];\n const triangle = this._triangle(i, j, k);\n // scalar circumcircle, matching the shape of `Triangle.circumcircle`\n const [ccx, ccy, r] = _circumcircle(\n coords[2 * i],\n coords[2 * i + 1],\n coords[2 * j],\n coords[2 * j + 1],\n coords[2 * k],\n coords[2 * k + 1],\n );\n const circle = new Group(new Pt(ccx, ccy), new Pt(r, r));\n\n shapes.push({ i, j, k, triangle, circle });\n tris.push(triangle);\n }\n this._shapes = shapes;\n\n return triangleOnly ? tris : shapes;\n }\n\n /**\n * The per-point mesh cache is keyed by neighbor-pair strings, which costs\n * more than the triangulation itself; build it the first time it is read.\n */\n private _ensureMesh(): DelaunayMesh {\n if (!this._meshBuilt) {\n this._meshBuilt = true;\n this._mesh = [];\n for (let i = 0; i < this._count; i++) this._mesh[i] = {};\n if (this._shapes) {\n for (let s = 0, len = this._shapes.length; s < len; s++) {\n this._cache(this._shapes[s]);\n }\n }\n }\n return this._mesh;\n }\n\n /**\n * Generate Voronoi cells. `delaunay()` must be called before calling this function. See a [Voronoi demo here](https://ptsjs.org/demo/?name=create.delaunay).\n * @param bound Optionally provide a rectangular bound (eg, `space.innerBound`) to clip the cells against, including the unbounded cells on the convex hull.\n * Without a bound, cells around sliver triangles can extend to enormous coordinates (circumcenters of\n * nearly-collinear points), which is technically correct but extremely slow to draw.\n * @returns an array of Groups, each of which represents a Voronoi cell. Unclipped cells share their vertex Pts with the cached mesh (see [`Delaunay.mesh`](#link)), so treat them as read-only or clone before mutating.\n */\n voronoi(bound?: PtIterable): Group[] {\n const cells = this._voronoiCells();\n if (!bound) return cells;\n\n const _bound = Geom.boundingBox(Util.iterToArray(bound) as Group);\n const x0 = _bound[0][0];\n const y0 = _bound[0][1];\n const x1 = _bound[1][0];\n const y1 = _bound[1][1];\n const hull = new Set<number>();\n if (this._tri) for (const i of this._tri.hull) hull.add(i);\n const seen = new Set<string>();\n for (let i = 0, len = cells.length; i < len; i++) {\n const key = `${this[i][0]},${this[i][1]}`;\n if (seen.has(key)) {\n cells[i] = new Group();\n continue;\n }\n seen.add(key);\n if (!hull.has(i) && cells[i].length >= 3) {\n cells[i] = _clipCellToRect(cells[i], x0, y0, x1, y1);\n continue;\n }\n\n // Hull fans do not enclose their unbounded Voronoi regions. Start\n // with the bound and intersect the half-planes of neighboring sites.\n const neighbors = new Set<number>();\n for (const shape of this.neighbors(i)) {\n for (const index of [shape.i, shape.j, shape.k]) {\n if (index !== i) neighbors.add(index);\n }\n }\n // Collinear and small point sets have no triangles; every site is a\n // candidate neighbor. Duplicate sites leave the first cell unchanged.\n if (neighbors.size === 0) {\n for (let j = 0; j < this.length; j++) if (j !== i) neighbors.add(j);\n }\n let cell = Group.fromArray([\n [x0, y0],\n [x1, y0],\n [x1, y1],\n [x0, y1],\n ]);\n for (const j of neighbors)\n cell = _clipCellToBisector(cell, this[i], this[j]);\n cells[i] = cell;\n }\n return cells;\n }\n\n /** Assemble unclipped Voronoi cells. */\n private _voronoiCells(): Group[] {\n const tri = this._tri;\n const shapes = this._shapes;\n if (!tri || !shapes) {\n // fallback (eg, subclasses bypassing delaunay()): sort per cell\n const vs: Group[] = [];\n const n = this._ensureMesh();\n for (let i = 0, len = n.length; i < len; i++) {\n vs.push(this.neighborPts(i, true) as Group);\n }\n return vs;\n }\n\n // Walk the triangles around each point counterclockwise, so its\n // circumcenters come out already in polygon order. A hull point's fan is\n // open: start it at the triangle whose outgoing edge is on the hull.\n const n = this._count;\n const triangles = tri.triangles;\n const neighbors = tri.neighbors;\n const start = new Int32Array(n).fill(-1);\n for (let h = 0, len = triangles.length; h < len; h++) {\n const p = triangles[h];\n if (neighbors[h] === -1 || start[p] === -1) start[p] = h;\n }\n\n const vs: Group[] = [];\n for (let i = 0; i < n; i++) {\n const cell = new Group();\n let h = start[i];\n if (h !== -1) {\n const first = (h / 3) | 0;\n for (;;) {\n const t = (h / 3) | 0;\n cell.push(shapes[t].circle[0]);\n // the edge entering this point leads to the next triangle around it\n const twin = neighbors[3 * t + ((h + 2) % 3)];\n if (twin === -1 || ((twin / 3) | 0) === first) break;\n h = twin;\n }\n }\n vs.push(cell);\n }\n return vs;\n }\n\n /**\n * Get the cached mesh. The mesh is an array of objects, each of which representing the enclosing triangles around a Pt in this Delaunay group.\n * @return an array of objects that store a series of DelaunayShapes\n */\n mesh(): DelaunayMesh {\n return this._ensureMesh();\n }\n\n /**\n * Given an index of a Pt in this Delaunay Group, returns its neighboring Pts in the network.\n * @param i index of a Pt\n * @param sort if true, sort the neighbors so that their edges will form a polygon\n * @returns an array of Pts\n */\n neighborPts(i: number, sort = false): GroupLike {\n let cs = new Group();\n let n = this._ensureMesh();\n for (let k in n[i]) {\n if (n[i].hasOwnProperty(k)) cs.push(n[i][k].circle[0]);\n }\n return sort && cs.length > 1 ? Geom.sortEdges(cs) : cs;\n }\n\n /**\n * Given an index of a Pt in this Delaunay Group, returns its neighboring DelaunayShapes.\n * @param i index of a Pt\n * @returns an array of DelaunayShapes `{i, j, k, triangle, circle}`\n */\n neighbors(i: number): DelaunayShape[] {\n let cs = [];\n let n = this._ensureMesh();\n for (let k in n[i]) {\n if (n[i].hasOwnProperty(k)) cs.push(n[i][k]);\n }\n return cs;\n }\n\n /**\n * Record a DelaunayShape in the mesh.\n * @param o DelaunayShape instance\n */\n protected _cache(o: DelaunayShape): void {\n this._mesh[o.i][`${Math.min(o.j, o.k)}-${Math.max(o.j, o.k)}`] = o;\n this._mesh[o.j][`${Math.min(o.i, o.k)}-${Math.max(o.i, o.k)}`] = o;\n this._mesh[o.k][`${Math.min(o.i, o.j)}-${Math.max(o.i, o.j)}`] = o;\n }\n\n /**\n * Get the initial \"super triangle\" that contains all the points in this set.\n * Not used by the current triangulation core; kept for subclass compatibility.\n * @returns a Group representing a triangle\n */\n protected _superTriangle(): Group {\n let minPt = this[0];\n let maxPt = this[0];\n for (let i = 1, len = this.length; i < len; i++) {\n minPt = minPt.$min(this[i]);\n maxPt = maxPt.$max(this[i]);\n }\n\n let d = maxPt.$subtract(minPt);\n let mid = minPt.$add(maxPt).divide(2);\n let dmax = Math.max(d[0], d[1]);\n\n return new Group(\n mid.$subtract(20 * dmax, dmax),\n mid.$add(0, 20 * dmax),\n mid.$add(20 * dmax, -dmax),\n );\n }\n\n /**\n * Get a triangle from 3 points in a list of points\n * @param i index 1\n * @param j index 2\n * @param k index 3\n * @param pts a Group of Pts\n */\n protected _triangle(\n i: number,\n j: number,\n k: number,\n pts: GroupLike = this,\n ): Group {\n return new Group(pts[i], pts[j], pts[k]);\n }\n\n /**\n * Get a circumcircle and triangle from 3 points in a list of points\n * @param i index 1\n * @param j index 2\n * @param k index 3\n * @param tri a Group representing a triangle, or `false` to create it from indices\n * @param pts a Group of Pts\n */\n protected _circum(\n i: number,\n j: number,\n k: number,\n tri: GroupLike | false,\n pts: GroupLike = this,\n ): DelaunayShape {\n let t = tri || this._triangle(i, j, k, pts);\n return {\n i: i,\n j: j,\n k: k,\n triangle: t,\n circle: Triangle.circumcircle(t)!,\n };\n }\n\n /**\n * Dedupe the edges array\n * @param edges\n */\n protected static _dedupe(edges: number[]): number[] {\n let j = edges.length;\n\n while (j > 1) {\n let b = edges[--j];\n let a = edges[--j];\n let i = j;\n\n while (i > 1) {\n let n = edges[--i];\n let m = edges[--i];\n\n if ((a == m && b == n) || (a == n && b == m)) {\n edges.splice(j, 2);\n edges.splice(i, 2);\n break;\n }\n }\n }\n\n return edges;\n }\n}\n\n/**\n * Accumulate one behavior's contribution as a weighted unit vector.\n *\n * The three behaviors are blended as *directions* and only then turned into a single steering\n * force, rather than each producing its own `desired - velocity` steer that are then summed.\n * Summing them would apply the `- velocity` damping term once per behavior, so with weights\n * totalling ~3.8 an agent is dragged toward a standstill whenever the behaviors disagree —\n * which is exactly what happens inside a tight cluster, where cohesion and separation nearly\n * oppose. Blending first also bounds separation structurally: its inverse-square sum is\n * normalized here, so no amount of piled-up neighbors can dominate the result.\n *\n * Does nothing when the direction is degenerate (zero length), which happens whenever neighbor\n * velocities cancel out or an agent sits exactly on its neighbors' center.\n */\nfunction __flock_accumulateUnit(\n out: Float32Array,\n dx: number,\n dy: number,\n weight: number,\n): void {\n const mag2 = dx * dx + dy * dy;\n if (mag2 <= 0) return;\n const scale = weight / Math.sqrt(mag2);\n out[0] += dx * scale;\n out[1] += dy * scale;\n}\n\n/**\n * Two agents at the exact same position have no direction to separate along. Rather than\n * leaving them fused forever, separation falls back to this offset, which the antisymmetric\n * accumulation splits into +x for one agent and -x for the other.\n */\nconst __flock_tieBreak = 1;\n\n/**\n * Separation weights each neighbor by inverse-square distance, so a pair that is nearly\n * coincident would produce an unbounded force. Distances are clamped to this fraction of the\n * separation radius. (The per-behavior `maxForce` clamp is what ultimately bounds the sum.)\n */\nconst __flock_minSepFraction = 0.01;\n\n/**\n * Cell indices are hashed through `Math.imul`, which truncates to int32, so anything past this\n * carries no information. It is also the guard that keeps the 3x3 cell walk terminating: a\n * non-finite position yields a non-finite cell index, and `gy <= cy + 1` is either always true\n * (Infinity) or leaves `gy++` unable to advance (magnitudes where adding 1 is a no-op in\n * float64). The comparison is written so NaN fails it too.\n */\nconst __flock_maxCell = 0x7fffffff;\n/** Cell coordinate of an agent with no finite neighborhood; below every valid cell. */\nconst __flock_noCell = -0x80000000;\n\n/**\n * Boid is a subclass of [`Pt`](#link) that represents a single agent in a [`Flock`](#link).\n * Its own values are the agent's position, and it carries a `velocity` that [`Flock.step`](#link)\n * integrates. Create them through [`Create.flock`](#link) or [`Flock.addBoid`](#link).\n * See [a demo here](https://ptsjs.org/demo/?name=create.flock).\n */\nexport class Boid extends Pt {\n protected _vel: Pt = new Pt(0, 0);\n\n /**\n * This agent's velocity, in units per second.\n */\n get velocity(): Pt {\n return this._vel;\n }\n set velocity(v: Pt) {\n this._vel = v;\n }\n\n /**\n * This agent's speed, in units per second.\n */\n get speed(): number {\n return Math.sqrt(this._vel[0] * this._vel[0] + this._vel[1] * this._vel[1]);\n }\n\n /**\n * The angle this agent is heading toward, in radians. Note that a stationary agent has no\n * heading and reports 0 (pointing along +x) rather than NaN. Set a [`Flock`](#link)'s\n * `minSpeed` if you are drawing headings and want to avoid that.\n */\n get heading(): number {\n return Math.atan2(this._vel[1], this._vel[0]);\n }\n}\n\n/**\n * Flock is a subclass of [`Group`](#link) that holds [`Boid`](#link) agents and simulates\n * flocking behavior (also known as \"boids\", after Craig Reynolds). Each agent steers by three\n * local rules — separation, alignment, and cohesion — evaluated over the neighbors within its\n * `perception` radius. Create one with [`Create.flock`](#link) and advance it with\n * [`Flock.step`](#link). Since a Flock is a Group of Pts, it draws directly:\n * `form.points( flock, 2, \"circle\" )`.\n *\n * Neighbors are found through a uniform spatial hash rather than by testing every pair, so the\n * cost scales with the number of agents rather than with its square.\n * See [a demo here](https://ptsjs.org/demo/?name=create.flock).\n */\nexport class Flock extends Group {\n protected _perception: number = 40;\n protected _separation: number = 20;\n protected _cohesionWeight: number = 1;\n protected _alignWeight: number = 1;\n protected _separateWeight: number = 1.5;\n protected _maxSpeed: number = 100;\n protected _minSpeed: number = 0;\n protected _maxForce: number = 200;\n protected _boundary: FlockBoundary = \"steer\";\n protected _margin: number = 50;\n protected _maxTimeStep: number = 50;\n protected _bound: GroupLike | null = null;\n protected _initialSpeed: number | undefined = undefined;\n\n // Flat per-agent state, gathered from the Boids at the start of each step and scattered back\n // at the end. The neighbor pass runs entirely on these, so it reads sequential memory instead\n // of chasing `this[i].velocity[0]` through two objects for every pair.\n private _pos: Float32Array = new Float32Array(0);\n private _vel: Float32Array = new Float32Array(0);\n // Per-agent accumulators, interleaved 6-wide: cohesion x/y, alignment x/y, separation x/y.\n private _sums: Float32Array = new Float32Array(0);\n private _counts: Uint32Array = new Uint32Array(0);\n\n // Spatial-hash scratch, grown geometrically and reused across steps.\n private _hashKeys: Uint32Array = new Uint32Array(0);\n private _cellX: Int32Array = new Int32Array(0);\n private _cellY: Int32Array = new Int32Array(0);\n private _cellStart: Uint32Array = new Uint32Array(0);\n private _cellEntries: Uint32Array = new Uint32Array(0);\n private _steerOut: Float32Array = new Float32Array(2);\n\n /**\n * Set any number of options at once. Unspecified options keep their current value.\n * @param options a [`FlockOptions`](#link) object\n */\n setup(options: FlockOptions): this {\n if (options.perception !== undefined) this.perception = options.perception;\n if (options.separation !== undefined) this.separation = options.separation;\n if (options.cohesionWeight !== undefined)\n this._cohesionWeight = options.cohesionWeight;\n if (options.alignWeight !== undefined)\n this._alignWeight = options.alignWeight;\n if (options.separateWeight !== undefined)\n this._separateWeight = options.separateWeight;\n if (options.maxSpeed !== undefined) this.maxSpeed = options.maxSpeed;\n if (options.minSpeed !== undefined) this.minSpeed = options.minSpeed;\n if (options.maxForce !== undefined) this._maxForce = options.maxForce;\n if (options.bound !== undefined) this._bound = options.bound as GroupLike;\n if (options.boundary !== undefined) this._boundary = options.boundary;\n if (options.margin !== undefined) this.margin = options.margin;\n if (options.maxTimeStep !== undefined)\n this.maxTimeStep = options.maxTimeStep;\n if (options.initialSpeed !== undefined)\n this._initialSpeed = options.initialSpeed;\n return this;\n }\n\n /**\n * Radius within which an agent sees its neighbors. This is also the spatial hash's cell size.\n */\n get perception(): number {\n return this._perception;\n }\n set perception(r: number) {\n this._perception = Math.max(0, r);\n }\n\n /**\n * Radius within which an agent steers away from its neighbors. Values above `perception`\n * have no additional effect, since an agent only considers neighbors it can see.\n */\n get separation(): number {\n return this._separation;\n }\n set separation(r: number) {\n this._separation = Math.max(0, r);\n }\n\n /**\n * Weight of the cohesion behavior, which steers an agent toward its neighbors' center.\n */\n get cohesionWeight(): number {\n return this._cohesionWeight;\n }\n set cohesionWeight(w: number) {\n this._cohesionWeight = w;\n }\n\n /**\n * Weight of the alignment behavior, which matches an agent's heading to its neighbors'.\n */\n get alignWeight(): number {\n return this._alignWeight;\n }\n set alignWeight(w: number) {\n this._alignWeight = w;\n }\n\n /**\n * Weight of the separation behavior, which steers an agent away from close neighbors.\n */\n get separateWeight(): number {\n return this._separateWeight;\n }\n set separateWeight(w: number) {\n this._separateWeight = w;\n }\n\n /**\n * Maximum speed, in units per second.\n */\n get maxSpeed(): number {\n return this._maxSpeed;\n }\n set maxSpeed(s: number) {\n this._maxSpeed = Math.max(0, s);\n }\n\n /**\n * Minimum speed, in units per second, so agents never stall. Default is 0.\n */\n get minSpeed(): number {\n return this._minSpeed;\n }\n set minSpeed(s: number) {\n this._minSpeed = Math.max(0, s);\n }\n\n /**\n * Maximum steering force, in units per second squared. This caps how sharply an agent can\n * turn toward the direction its three behaviors blend to. A boundary turn is added on top,\n * so an agent near an edge can accelerate up to twice this.\n */\n get maxForce(): number {\n return this._maxForce;\n }\n set maxForce(f: number) {\n this._maxForce = f;\n }\n\n /**\n * Boundary that keeps the flock in view, as a [`Bound`](#link) or a Group of 2 Pts.\n * When this is null, no boundary behavior is applied regardless of `boundary`.\n */\n get bound(): GroupLike | null {\n return this._bound;\n }\n set bound(b: GroupLike | null) {\n this._bound = b;\n }\n\n /**\n * How the boundary is treated: `\"steer\"`, `\"wrap\"`, `\"bounce\"`, or `\"none\"`.\n *\n * Note that `\"wrap\"` teleports agents across the bound while the neighborhood search is not\n * toroidal, so a flock loses sight of itself at the seam. Prefer `\"steer\"` when that matters.\n */\n get boundary(): FlockBoundary {\n return this._boundary;\n }\n set boundary(b: FlockBoundary) {\n this._boundary = b;\n }\n\n /**\n * Distance from an edge at which `\"steer\"` starts turning agents back.\n */\n get margin(): number {\n return this._margin;\n }\n set margin(m: number) {\n this._margin = Math.max(0, m);\n }\n\n /**\n * Maximum simulated time in milliseconds per [`Flock.step`](#link) call. Longer elapsed times\n * are clamped to this, which keeps a stalled frame from teleporting the flock. Default is 50.\n */\n get maxTimeStep(): number {\n return this._maxTimeStep;\n }\n set maxTimeStep(ms: number) {\n this._maxTimeStep = Math.max(0, ms);\n }\n\n /**\n * Speed given to an agent added without an explicit velocity. Defaults to half of `maxSpeed`.\n */\n get initialSpeed(): number {\n return this._initialSpeed === undefined\n ? this._maxSpeed * 0.5\n : this._initialSpeed;\n }\n set initialSpeed(s: number) {\n this._initialSpeed = s;\n }\n\n /**\n * Add an agent to this flock. Named `addBoid` rather than `add` because [`Group.add`](#link)\n * already means \"translate every Pt in this group\", and [`Group.moveBy`](#link) delegates to it.\n * @param pt a Pt, a Boid, or an array of numbers for the starting position\n * @param velocity optional starting velocity. When omitted, a new agent gets a random heading\n * at [`Flock.initialSpeed`](#link), drawn from [`Num.random`](#link).\n */\n addBoid(pt: PtLike | Boid, velocity?: PtLike): this {\n const isBoid = pt instanceof Boid;\n const boid = isBoid ? (pt as Boid) : new Boid(pt);\n if (velocity !== undefined) {\n boid.velocity[0] = velocity[0];\n boid.velocity[1] = velocity[1];\n } else if (!isBoid) {\n const a = Num.random() * Const.two_pi;\n const s = this.initialSpeed;\n boid.velocity[0] = Math.cos(a) * s;\n boid.velocity[1] = Math.sin(a) * s;\n }\n this.push(boid);\n return this;\n }\n\n /**\n * Advance the simulation. Call this once per frame with the frame time, eg\n * `space.add( (time, ftime) => flock.step( ftime ) )`.\n *\n * Elapsed times longer than [`Flock.maxTimeStep`](#link) are clamped, so a slow frame slows\n * the flock down instead of teleporting it. A non-positive or NaN time is a no-op.\n *\n * @param ms elapsed time in milliseconds\n */\n step(ms: number): this {\n const n = this.length;\n if (n === 0 || !(ms > 0)) return this;\n\n const dt = Math.min(ms, this._maxTimeStep) / 1000;\n if (dt <= 0) return this;\n\n this._ensureBuffers(n);\n this._gather(n);\n if (n > 1 && this._perception > 0) {\n this._accumulate(n);\n } else {\n this._sums.fill(0, 0, n * 6);\n this._counts.fill(0, 0, n);\n }\n this._integrate(n, dt);\n this._scatter(n);\n return this;\n }\n\n /**\n * Grow the flat state and hash scratch to fit `n` agents. Every buffer is fully written\n * before it is read within a step, so reallocating here never loses state.\n */\n private _ensureBuffers(n: number) {\n if (this._pos.length < n * 2) {\n const size = n * 2 * 2; // geometric growth\n this._pos = new Float32Array(size);\n this._vel = new Float32Array(size);\n this._sums = new Float32Array(size * 3);\n this._counts = new Uint32Array(size);\n this._hashKeys = new Uint32Array(size);\n this._cellX = new Int32Array(size);\n this._cellY = new Int32Array(size);\n this._cellEntries = new Uint32Array(size);\n }\n }\n\n /**\n * Copy positions and velocities out of the Boids into the flat buffers. An element that\n * reached this Group without a velocity — pushed as a plain Pt, or produced by a Group method\n * that copies through the species constructor — is upgraded to a Boid in place here rather\n * than throwing mid-simulation.\n */\n private _gather(n: number) {\n const pos = this._pos;\n const vel = this._vel;\n for (let i = 0; i < n; i++) {\n let b = this[i] as Boid;\n let v = b.velocity;\n if (v === undefined) {\n b = new Boid(b);\n v = b.velocity;\n this[i] = b;\n }\n const k = i * 2;\n pos[k] = b[0];\n pos[k + 1] = b[1];\n vel[k] = v[0];\n vel[k + 1] = v[1];\n }\n }\n\n /**\n * Write the integrated positions and velocities back into the Boids.\n */\n private _scatter(n: number) {\n const pos = this._pos;\n const vel = this._vel;\n for (let i = 0; i < n; i++) {\n const b = this[i] as Boid;\n const v = b.velocity;\n const k = i * 2;\n b[0] = pos[k];\n b[1] = pos[k + 1];\n v[0] = vel[k];\n v[1] = vel[k + 1];\n }\n }\n\n /**\n * Accumulate the three behaviors' sums for every agent in a single pass over neighboring\n * pairs, using a uniform spatial hash (a counting-sort grid) built the same way as\n * [`World`](#link)'s collision broad phase — see `World._collideParticles`. The two are kept\n * separate on purpose: this one queries a fixed radius and accumulates into flat sums, and\n * sharing an abstraction between them would put an indirect call on the per-pair path.\n *\n * Cells are exactly `perception` wide, which is the smallest size for which every neighbor\n * within that radius is guaranteed to lie in the 3x3 block around an agent's cell. Each\n * agent's cell coordinates are kept, so an entry found through a hash bucket is checked\n * against the cell actually being visited: two cells that collide into one bucket cannot\n * count a neighbor twice or hide one. That exact check is also what allows visiting only\n * half of the neighborhood — the agent's own cell (pairing with higher indices) plus the four\n * cells east, south-west, south, and south-east — since every pair of adjacent cells is then\n * seen from exactly one side.\n *\n * Each pair is accumulated into both agents: \"j is within r of i\" is symmetric, so this\n * halves the distance computations. No `sqrt` is taken here — radius tests compare squared\n * distances, and separation falls off as the inverse square, which is what makes the\n * fallback in `__flock_tieBreak` necessary.\n */\n private _accumulate(n: number) {\n const pos = this._pos;\n const vel = this._vel;\n const sums = this._sums;\n const counts = this._counts;\n\n sums.fill(0, 0, n * 6);\n counts.fill(0, 0, n);\n\n const r2 = this._perception * this._perception;\n const sep = Math.min(this._separation, this._perception);\n const sep2 = sep * sep;\n const minSep = sep * __flock_minSepFraction;\n const minSep2 = minSep * minSep;\n const inv = 1 / this._perception;\n\n // Hash table size: the next power of two above 2n, so buckets stay sparse.\n let m = 16;\n while (m < n * 2) m <<= 1;\n const mask = m - 1;\n if (this._cellStart.length < m + 1)\n this._cellStart = new Uint32Array(m + 1);\n\n const keys = this._hashKeys;\n const cellX = this._cellX;\n const cellY = this._cellY;\n const start = this._cellStart;\n const entries = this._cellEntries;\n\n // Cell coordinates once per agent. A non-finite or absurd position gets a sentinel cell\n // that no neighborhood visit can match, so it neither sees nor is seen (see\n // `__flock_maxCell`). Then count per cell, exclusive prefix sum, and scatter; after the\n // scatter, bucket k spans [start[k-1], start[k]).\n start.fill(0, 0, m + 1);\n for (let i = 0; i < n; i++) {\n const cx = Math.floor(pos[i * 2] * inv);\n const cy = Math.floor(pos[i * 2 + 1] * inv);\n if (\n cx >= -__flock_maxCell &&\n cx <= __flock_maxCell &&\n cy >= -__flock_maxCell &&\n cy <= __flock_maxCell\n ) {\n cellX[i] = cx;\n cellY[i] = cy;\n } else {\n cellX[i] = __flock_noCell;\n cellY[i] = __flock_noCell;\n }\n const key =\n ((Math.imul(cellX[i], 0x9e3779b1) ^ Math.imul(cellY[i], 0x85ebca77)) >>>\n 0) &\n mask;\n keys[i] = key;\n start[key]++;\n }\n let sum = 0;\n for (let k = 0; k < m; k++) {\n const c = start[k];\n start[k] = sum;\n sum += c;\n }\n start[m] = sum;\n for (let i = 0; i < n; i++) {\n entries[start[keys[i]]++] = i;\n }\n\n for (let i = 0; i < n; i++) {\n const cx = cellX[i];\n if (cx === __flock_noCell) continue;\n const cy = cellY[i];\n const ki = i * 2;\n const ix = pos[ki];\n const iy = pos[ki + 1];\n const ivx = vel[ki];\n const ivy = vel[ki + 1];\n const si = i * 6;\n\n // the five cells of the half neighborhood, own cell first\n for (let c = 0; c < 5; c++) {\n const gx = c === 2 ? cx - 1 : c === 0 || c === 3 ? cx : cx + 1;\n const gy = c < 2 ? cy : cy + 1;\n const key =\n ((Math.imul(gx, 0x9e3779b1) ^ Math.imul(gy, 0x85ebca77)) >>> 0) &\n mask;\n const end = start[key];\n const begin = key > 0 ? start[key - 1] : 0;\n for (let e = begin; e < end; e++) {\n const j = entries[e];\n if (cellX[j] !== gx || cellY[j] !== gy) continue; // another cell in this bucket\n if (c === 0 && j <= i) continue; // own cell: each pair once\n\n const kj = j * 2;\n const jx = pos[kj];\n const jy = pos[kj + 1];\n const dx = jx - ix;\n const dy = jy - iy;\n const d2 = dx * dx + dy * dy;\n if (!(d2 < r2)) continue;\n\n const sj = j * 6;\n sums[si] += jx;\n sums[si + 1] += jy;\n sums[sj] += ix;\n sums[sj + 1] += iy;\n sums[si + 2] += vel[kj];\n sums[si + 3] += vel[kj + 1];\n sums[sj + 2] += ivx;\n sums[sj + 3] += ivy;\n counts[i]++;\n counts[j]++;\n\n if (d2 < sep2) {\n let ox = dx;\n let oy = dy;\n let dd = d2;\n if (dd === 0) {\n // Coincident agents have no direction to separate along; split them along x.\n ox = __flock_tieBreak;\n oy = 0;\n dd = minSep2;\n } else if (dd < minSep2) {\n dd = minSep2;\n }\n const w = 1 / dd;\n const wx = ox * w;\n const wy = oy * w;\n sums[si + 4] -= wx;\n sums[si + 5] -= wy;\n sums[sj + 4] += wx;\n sums[sj + 5] += wy;\n }\n }\n }\n }\n }\n\n /**\n * Turn the accumulated sums into a steering force per agent, then integrate velocity and\n * position. This is O(n), so it uses the classic \"steer toward the desired velocity\"\n * formulation and its handful of square roots, which behaves better than weighting raw\n * offsets and keeps `maxSpeed` and `maxForce` as the only scale-dependent knobs.\n * See `__flock_accumulateUnit` for why the behaviors are blended before that steer is taken.\n */\n private _integrate(n: number, dt: number) {\n const pos = this._pos;\n const vel = this._vel;\n const sums = this._sums;\n const counts = this._counts;\n const out = this._steerOut;\n\n const maxSpeed = this._maxSpeed;\n const maxForce = this._maxForce;\n const minSpeed = Math.min(this._minSpeed, maxSpeed);\n const cw = this._cohesionWeight;\n const aw = this._alignWeight;\n const sw = this._separateWeight;\n\n const bound = this._bound;\n const boundary = bound ? this._boundary : \"none\";\n const steer = boundary === \"steer\" && this._margin > 0;\n const wrap = boundary === \"wrap\";\n const bounce = boundary === \"bounce\";\n let minX = 0;\n let minY = 0;\n let maxX = 0;\n let maxY = 0;\n if (bound && boundary !== \"none\") {\n const b0 = bound[0];\n const b1 = bound[1];\n minX = Math.min(b0[0], b1[0]);\n minY = Math.min(b0[1], b1[1]);\n maxX = Math.max(b0[0], b1[0]);\n maxY = Math.max(b0[1], b1[1]);\n }\n const margin = this._margin;\n\n for (let i = 0; i < n; i++) {\n const k = i * 2;\n const s = i * 6;\n let px = pos[k];\n let py = pos[k + 1];\n let vx = vel[k];\n let vy = vel[k + 1];\n\n // Blend the three behaviors into one desired direction...\n out[0] = 0;\n out[1] = 0;\n const c = counts[i];\n if (c > 0) {\n // steer toward the neighbors' center\n if (cw !== 0) {\n __flock_accumulateUnit(\n out,\n sums[s] / c - px,\n sums[s + 1] / c - py,\n cw,\n );\n }\n // match the neighbors' heading. The mean and the sum point the same way, and the\n // direction is normalized anyway, so the neighbor count is not needed here.\n if (aw !== 0) __flock_accumulateUnit(out, sums[s + 2], sums[s + 3], aw);\n if (sw !== 0) __flock_accumulateUnit(out, sums[s + 4], sums[s + 5], sw);\n }\n\n // ...then take a single steer toward it, so the damping is applied once.\n let ax = 0;\n let ay = 0;\n const dm2 = out[0] * out[0] + out[1] * out[1];\n if (dm2 > 0) {\n const sc = maxSpeed / Math.sqrt(dm2);\n ax = out[0] * sc - vx;\n ay = out[1] * sc - vy;\n const f2 = ax * ax + ay * ay;\n if (f2 > maxForce * maxForce) {\n const fs = maxForce / Math.sqrt(f2);\n ax *= fs;\n ay *= fs;\n }\n }\n\n if (steer) {\n // Ramp the turn from zero at the margin's inner edge to full force at the wall, and\n // hold it at full force for anything that already escaped. This is added on top of the\n // blended steer rather than mixed into it, so the flock's own rules cannot outvote it\n // and pin a cluster against an edge.\n const dl = px - minX;\n const dr = maxX - px;\n const dtp = py - minY;\n const db = maxY - py;\n if (dl < margin) ax += maxForce * (1 - Math.max(dl, 0) / margin);\n else if (dr < margin) ax -= maxForce * (1 - Math.max(dr, 0) / margin);\n if (dtp < margin) ay += maxForce * (1 - Math.max(dtp, 0) / margin);\n else if (db < margin) ay -= maxForce * (1 - Math.max(db, 0) / margin);\n }\n\n vx += ax * dt;\n vy += ay * dt;\n\n const sp2 = vx * vx + vy * vy;\n if (sp2 > maxSpeed * maxSpeed) {\n const sc = maxSpeed / Math.sqrt(sp2);\n vx *= sc;\n vy *= sc;\n } else if (minSpeed > 0 && sp2 < minSpeed * minSpeed) {\n if (sp2 > 0) {\n const sc = minSpeed / Math.sqrt(sp2);\n vx *= sc;\n vy *= sc;\n } else {\n // A dead stop has no heading to preserve; pick one deterministically.\n vx = minSpeed;\n vy = 0;\n }\n }\n\n px += vx * dt;\n py += vy * dt;\n\n if (wrap) {\n const w = maxX - minX;\n const h = maxY - minY;\n if (w > 0) {\n if (px < minX) px = maxX - ((minX - px) % w);\n else if (px > maxX) px = minX + ((px - maxX) % w);\n }\n if (h > 0) {\n if (py < minY) py = maxY - ((minY - py) % h);\n else if (py > maxY) py = minY + ((py - maxY) % h);\n }\n } else if (bounce) {\n // `<=` rather than `<`: an agent that lands exactly on the wall is still heading out,\n // and would otherwise leave on the next step without ever reflecting.\n if (px <= minX) {\n px = minX;\n if (vx < 0) vx = -vx;\n } else if (px >= maxX) {\n px = maxX;\n if (vx > 0) vx = -vx;\n }\n if (py <= minY) {\n py = minY;\n if (vy < 0) vy = -vy;\n } else if (py >= maxY) {\n py = maxY;\n if (vy > 0) vy = -vy;\n }\n }\n\n pos[k] = px;\n pos[k + 1] = py;\n vel[k] = vx;\n vel[k + 1] = vy;\n }\n }\n}\n\n// Cell offsets in scan order for `PoissonDisk`, nearest first\nconst __near = [0, -1, 1, -2, 2];\n\n/**\n * PoissonDisk is a Group of Pts produced by Poisson-disk sampling: every point is at least\n * [`PoissonDisk.radius`](#link) away from every other. Create a finished set with\n * [`Create.sampling`](#link), or construct one directly and grow it with [`PoissonDisk.step`](#link)\n * (one point at a time) or [`PoissonDisk.sample`](#link) (a batch at a time), which is how the\n * [demo](https://ptsjs.org/demo/?name=create.sampling) shows the packing as it forms.\n *\n * The sampler is Bridson's grid-accelerated algorithm with Roberts' candidate placement: each\n * visit to an active point tries up to [`PoissonDisk.candidates`](#link) candidates on the circle\n * just outside `radius` around it, at evenly spaced angles from a random offset, and accepts the\n * first one with no existing point within `radius`. It runs in linear time on one small integer\n * grid. In a bound thinner than the radius, candidates take random positions across the thin\n * axis and alternate along the long one, since a circle of candidates would miss the strip.\n *\n * Three traits to know: most points sit just beyond `radius` from the point that spawned them,\n * which packs tighter than candidates at random distances; the candidate budget is finite, so\n * a finished set can still have gaps; and coordinates are compared as float32 (the precision of\n * a Pt), exact at pixel scales but rejecting some candidates when coordinates exceed roughly\n * 8000 times the radius.\n *\n * Treat the Group as read-only while sampling: pushing or moving its Pts by hand would\n * desynchronize the grid that enforces the spacing. A PoissonDisk produced by `map`, `filter`\n * or `slice` is a plain copy that reports radius 0 and `done`, and needs `setup` before sampling.\n */\nexport class PoissonDisk extends Group {\n private _radius = 0;\n private _candidates = 8;\n // per-setup constants of the candidate placement, hoisted out of step()\n private _dist = 0; // radius with an allowance for float32 rounding\n private _cos = 1; // rotation between candidates\n private _sin = 0;\n private _narrowX = false; // the bound is thinner than a candidate circle across x\n private _narrowY = false; // or across y\n private _x0 = 0;\n private _y0 = 0;\n private _x1 = 0;\n private _y1 = 0;\n private _cell = 1;\n private _cols = 0;\n private _rows = 0;\n private _grid = new Int32Array(0); // one sample index per cell, or -1\n private _active: number[] = []; // indices of samples that may still spawn neighbors\n\n /**\n * Reset this sampler and place its first sample. Calling `setup` again empties the group and\n * starts over, which is how a sketch restarts sampling after a resize.\n * @param bound the rectangular boundary\n * @param radius minimum distance between any two points\n * @param options optional [`PoissonDiskOptions`](#link)\n * @returns this\n * @example `new PoissonDisk().setup( space.innerBound, 12 ).sample( 40 )`\n */\n setup(bound: Bound, radius: number, options: PoissonDiskOptions = {}): this {\n if (!(radius > 0) || !Number.isFinite(radius)) {\n throw new Error(\"PoissonDisk radius must be a positive finite number\");\n }\n const x0 = bound.x ?? NaN;\n const y0 = bound.y ?? NaN;\n const width = bound.width;\n const height = bound.height;\n const x1 = x0 + width;\n const y1 = y0 + height;\n if (![x0, y0, x1, y1].every(Number.isFinite) || width < 0 || height < 0) {\n throw new Error(\"PoissonDisk bound must have a finite position and size\");\n }\n // A size can vanish when added to a far larger position (e.g. 1 at 1e20)\n if ((width > 0 && x1 <= x0) || (height > 0 && y1 <= y0)) {\n throw new Error(\n \"PoissonDisk bound size must be representable at its position\",\n );\n }\n const k = options.candidates ?? 8;\n if (!(k >= 1) || !Number.isFinite(k)) {\n throw new Error(\"PoissonDisk candidates must be a number of at least 1\");\n }\n\n // Each grid cell is small enough to hold at most one sample\n const cell = radius / Math.SQRT2;\n const hasArea = width > 0 && height > 0;\n const cols = hasArea ? Math.ceil(width / cell) : 0;\n const rows = hasArea ? Math.ceil(height / cell) : 0;\n if (cols * rows > 1 << 26) {\n throw new Error(\n \"PoissonDisk radius is too small for this bound: the grid would exceed 2^26 cells\",\n );\n }\n\n this.length = 0;\n this._active.length = 0;\n this._radius = radius;\n this._candidates = Math.floor(k);\n this._x0 = x0;\n this._y0 = y0;\n this._x1 = x1;\n this._y1 = y1;\n this._cell = cell;\n this._cols = cols;\n this._rows = rows;\n this._grid = new Int32Array(cols * rows).fill(-1);\n this._dist = radius * 1.001; // allow for float32 rounding at ordinary canvas scales\n this._cos = Math.cos(Const.two_pi / this._candidates);\n this._sin = Math.sin(Const.two_pi / this._candidates);\n // A full circle of candidates can miss a strip thinner than `dist` entirely; there,\n // candidates take a random position across the strip and alternate along it instead.\n this._narrowX = width < this._dist && width <= height;\n this._narrowY = height < this._dist && !this._narrowX;\n\n if (options.start !== undefined) {\n const s = options.start;\n if (!this._tryAdd(Math.fround(s[0]), Math.fround(s[1]))) {\n throw new Error(\n \"PoissonDisk start point must lie on or after the bound's top-left edges and before its bottom-right edges\",\n );\n }\n } else if (cols * rows > 0) {\n // Redraw on the rare float32 rounding that lands exactly on the far edge\n while (\n !this._tryAdd(\n Math.fround(x0 + Num.random() * width),\n Math.fround(y0 + Num.random() * height),\n )\n );\n }\n return this;\n }\n\n /**\n * Minimum distance between any two points in this set.\n */\n get radius(): number {\n return this._radius;\n }\n\n /**\n * Maximum candidates tried per visit to an active sample before retiring it if none succeed.\n */\n get candidates(): number {\n return this._candidates;\n }\n\n /**\n * The rectangular boundary that the samples fill.\n */\n get bound(): Bound {\n return new Bound(new Pt(this._x0, this._y0), new Pt(this._x1, this._y1));\n }\n\n /**\n * Whether no active samples remain. Gaps may still fit further points, but sampling has stopped.\n */\n get done(): boolean {\n return this._active.length === 0;\n }\n\n /**\n * Add the next sample and return it, or return `undefined` once no active samples remain.\n * The new Pt is also the last element of this group.\n * @example `let p = pd.step(); if (p) form.point( p, 2 );`\n */\n step(): Pt | undefined {\n const active = this._active;\n const k = this._candidates;\n const dist = this._dist;\n const cos = this._cos;\n const sin = this._sin;\n const width = this._x1 - this._x0;\n const height = this._y1 - this._y0;\n const narrowX = this._narrowX;\n const narrowY = this._narrowY;\n\n while (active.length > 0) {\n const ai = Math.floor(Num.random() * active.length);\n const p = this[active[ai]];\n const a0 = Num.random() * Const.two_pi;\n let dx = dist * Math.cos(a0);\n let dy = dist * Math.sin(a0);\n let along = a0 < Math.PI ? 1 : -1;\n for (let j = 0; j < k; j++) {\n if (narrowX) {\n dx = this._x0 + Num.random() * width - p[0];\n dy = along * Math.sqrt(Math.max(0, dist * dist - dx * dx));\n along = -along;\n } else if (narrowY) {\n dy = this._y0 + Num.random() * height - p[1];\n dx = along * Math.sqrt(Math.max(0, dist * dist - dy * dy));\n along = -along;\n } else if (j > 0) {\n const x = dx * cos - dy * sin;\n dy = dx * sin + dy * cos;\n dx = x;\n }\n if (this._tryAdd(Math.fround(p[0] + dx), Math.fround(p[1] + dy))) {\n return this[this.length - 1];\n }\n }\n // This visit exhausted its candidate budget: retire the sample\n active[ai] = active[active.length - 1];\n active.pop();\n }\n return undefined;\n }\n\n /**\n * Add up to `count` more samples, or every remaining sample by default.\n * @param count maximum number of samples to add, rounded down; nonpositive values and NaN add none\n * @example `pd.sample( 20 )` adds twenty points per frame; `pd.sample()` completes the set\n */\n sample(count: number = Infinity): this {\n const limit = Math.floor(count);\n for (let i = 0; i < limit; i++) {\n if (this.step() === undefined) break;\n }\n return this;\n }\n\n /**\n * Store the point at (x, y) if it lies inside the bound and no sample is within `radius` of it.\n * Coordinates must already be float32 values, so what is tested is exactly what is stored.\n */\n private _tryAdd(x: number, y: number): boolean {\n if (!(x >= this._x0 && x < this._x1 && y >= this._y0 && y < this._y1)) {\n return false;\n }\n const cols = this._cols;\n const rows = this._rows;\n const cx = Math.min(cols - 1, Math.floor((x - this._x0) / this._cell));\n const cy = Math.min(rows - 1, Math.floor((y - this._y0) / this._cell));\n const grid = this._grid;\n\n // A conflicting sample lies within two cells in each direction, but never in the four\n // corners of that window. Scan from the center outward: a rejected candidate usually\n // conflicts with a sample close to it, so the scan ends after a few cells.\n const r2 = this._radius * this._radius;\n for (const dj of __near) {\n const j = cy + dj;\n if (j < 0 || j >= rows) continue;\n const row = j * cols;\n const reach = dj === -2 || dj === 2 ? 1 : 2;\n for (const di of __near) {\n const i = cx + di;\n if (di > reach || di < -reach || i < 0 || i >= cols) continue;\n const s = grid[row + i];\n if (s >= 0) {\n const q = this[s];\n const dx = q[0] - x;\n const dy = q[1] - y;\n if (dx * dx + dy * dy < r2) return false;\n }\n }\n }\n\n grid[cy * cols + cx] = this.length;\n this._active.push(this.length);\n this.push(new Pt(x, y));\n return true;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Group } from \"./Pt\";\nimport { Util } from \"./Util\";\nimport { Num, Geom } from \"./Num\";\nimport { type PtLike, type ColorType } from \"./Types\";\n\n/**\n * Color is a subclass of Pt. Since a color in a color space is analogous to a point or vector in a space, you can apply all Pt operations to colors too. The Color class provides support for many color spaces like HSL and LAB.\n * Convert non-RGB colors to RGB before using `.hex`, `.rgb`, or `.rgba` for rendering. These getters format the channels; they don't convert between color spaces.\n * @example\n * ```\n * const color = Color.hsl(268, 0.37, 0.51);\n * form.fill(Color.HSLtoRGB(color).rgb);\n * ```\n */\nexport class Color extends Pt {\n // XYZ property for Standard Observer 2deg, Daylight/sRGB illuminant D65\n private static D65: PtLike = new Pt(95.047, 100, 108.883, 1);\n\n protected _mode: ColorType = \"rgb\";\n private _isNorm: boolean = false;\n\n /**\n * Value range for each color space\n */\n static ranges: { [name: string]: Group } = {\n rgb: new Group(new Pt(0, 255), new Pt(0, 255), new Pt(0, 255)),\n hsl: new Group(new Pt(0, 360), new Pt(0, 1), new Pt(0, 1)),\n hsb: new Group(new Pt(0, 360), new Pt(0, 1), new Pt(0, 1)),\n lab: new Group(new Pt(0, 100), new Pt(-128, 127), new Pt(-128, 127)),\n lch: new Group(new Pt(0, 100), new Pt(0, 100), new Pt(0, 360)),\n luv: new Group(new Pt(0, 100), new Pt(-134, 220), new Pt(-140, 122)),\n xyz: new Group(new Pt(0, 100), new Pt(0, 100), new Pt(0, 100)),\n oklab: new Group(new Pt(0, 1), new Pt(-0.4, 0.4), new Pt(-0.4, 0.4)),\n oklch: new Group(new Pt(0, 1), new Pt(0, 0.4), new Pt(0, 360)),\n };\n\n /**\n * Create a Color. Same as creating a Pt. Optionally you may use [`Color.from`](#link) to create a color.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n constructor(...args: any[]) {\n super(...args);\n }\n\n /**\n * Create a Color object with 4 default dimensional values (1,1,1,1).\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n static from(...args: any[]): Color {\n const p = [1, 1, 1, 1];\n const c = Util.getArgs(args);\n for (let i = 0, len = p.length; i < len; i++) {\n if (i < c.length) p[i] = c[i];\n }\n return new Color(p);\n }\n\n /**\n * Convert a rgb hex string like `\"#FF0000\"` or `\"#F00\"` to a Color object.\n * @param hex a hex string, with optional '#' prefix\n */\n static fromHex(hex: string): Color {\n if (hex[0] == \"#\") hex = hex.substr(1); // remove '#' if needed\n if (hex.length <= 4) {\n const fn = (i: number) => hex[i] || \"F\";\n const shortAlpha = hex.length === 4 ? `${fn(3)}${fn(3)}` : \"\"; // #RGBA\n hex = `${fn(0)}${fn(0)}${fn(1)}${fn(1)}${fn(2)}${fn(2)}${shortAlpha}`;\n }\n\n let alpha = 1;\n if (hex.length === 8) {\n alpha = parseInt(hex.substr(6, 2), 16) / 255;\n hex = hex.substring(0, 6);\n }\n\n const hexVal = parseInt(hex, 16);\n return new Color(hexVal >> 16, (hexVal >> 8) & 0xff, hexVal & 0xff, alpha);\n }\n\n /**\n * Create RGB Color. RGB color ranges are (0...255, 0...255, 0...255) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static rgb(...args: any[]): Color {\n return Color.from(...args).toMode(\"rgb\");\n }\n\n /**\n * Create HSL Color. HSL color ranges are (0...360, 0...1, 0...1) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static hsl(...args: any[]): Color {\n return Color.from(...args).toMode(\"hsl\");\n }\n\n /**\n * Create HSB Color. HSB color ranges are (0...360, 0...1, 0...1) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static hsb(...args: any[]): Color {\n return Color.from(...args).toMode(\"hsb\");\n }\n\n /**\n * Create LAB Color. LAB color ranges are (0...100, -128...127, -128...127) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static lab(...args: any[]): Color {\n return Color.from(...args).toMode(\"lab\");\n }\n\n /**\n * Create LCH Color. LCH color ranges are (0...100, 0...100, 0...360) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static lch(...args: any[]): Color {\n return Color.from(...args).toMode(\"lch\");\n }\n\n /**\n * Create LUV Color. LUV color ranges are (0...100, -134...220, -140...122) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static luv(...args: any[]): Color {\n return Color.from(...args).toMode(\"luv\");\n }\n\n /**\n * Create XYZ Color. XYZ color ranges are (0...100, 0...100, 0...100) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static xyz(...args: any[]): Color {\n return Color.from(...args).toMode(\"xyz\");\n }\n\n /**\n * Create OKLAB Color. OKLAB color ranges are (0...1, -0.4...0.4, -0.4...0.4) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static oklab(...args: any[]): Color {\n return Color.from(...args).toMode(\"oklab\");\n }\n\n /**\n * Create OKLCH Color. OKLCH color ranges are (0...1, 0...0.4, 0...360) respectively. You may use [`Color.normalize`](#link) to convert the ranges to 0...1.\n * @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties.\n */\n static oklch(...args: any[]): Color {\n return Color.from(...args).toMode(\"oklch\");\n }\n\n /**\n * Get a Color object whose values are the maximum of its mode.\n * @param mode a mode string such as \"rgb\" or \"lab\"\n * @example Color.maxValue(\"rgb\") will return a rgb Color object with values (255,255,255)\n */\n static maxValues(mode: string): Pt {\n return Color.ranges[mode].zipSlice(1).$take([0, 1, 2]);\n }\n\n /**\n * Get a hex string such as \"#FF0000\". Same as `toString(\"hex\")`.\n * For non-RGB colors, convert to RGB first.\n */\n public get hex(): string {\n return this.toString(\"hex\");\n }\n\n /**\n * Get a rgb string such as \"rgb(255,0,0)\". Same as `toString(\"rgb\")`.\n * For non-RGB colors, convert to RGB first, eg `Color.HSLtoRGB(color).rgb`.\n */\n public get rgb(): string {\n return this.toString(\"rgb\");\n }\n\n /**\n * Get a rgba string such as \"rgba(255,0,0,0.5)\". Same as `toString(\"rgba\")`.\n * For non-RGB colors, convert to RGB first.\n */\n public get rgba(): string {\n return this.toString(\"rgba\");\n }\n\n /**\n * Clone this Color.\n */\n clone(): Color {\n const c = new Color(this);\n c.toMode(this._mode);\n c._isNorm = this._isNorm;\n return c;\n }\n\n /**\n * Get a denormalized copy of a color, trusting the caller's flag over the\n * color's own normalized state so that explicit conversion arguments win.\n * Inlines the range math — this sits on the hot path of every conversion\n * that takes normalized input.\n */\n private static _denorm(c: Color): Color {\n const cc = c.clone();\n const ranges = Color.ranges[cc._mode];\n for (let i = 0; i < 3; i++) {\n const r = ranges[i];\n cc[i] = r[0] + cc[i] * (r[1] - r[0]);\n }\n cc._isNorm = false;\n return cc;\n }\n\n /**\n * Normalize a freshly computed full-range color in place and flag it.\n * Conversion outputs are always full-range, so no state check is needed.\n */\n private static _normOut(c: Color): Color {\n const ranges = Color.ranges[c._mode];\n for (let i = 0; i < 3; i++) {\n const r = ranges[i];\n c[i] = (c[i] - r[0]) / (r[1] - r[0]);\n }\n c._isNorm = true;\n return c;\n }\n\n /**\n * Convert this color from current color space to another color space.\n * @param mode a ColorType string: \"rgb\" \"hsl\" \"hsb\" \"lab\" \"lch\" \"luv\" \"xyz\";\n * @param convert if `true`, convert this Color to the new color space specified in `mode`. Default is `false`, which only sets the color mode without converting color values.\n */\n toMode(mode: ColorType, convert: boolean = false): this {\n if (convert && mode !== this._mode) {\n const fname = this._mode.toUpperCase() + \"to\" + mode.toUpperCase();\n if ((Color as any)[fname]) {\n this.to((Color as any)[fname](this, this._isNorm, this._isNorm));\n } else {\n throw new Error(\"Cannot convert color with \" + fname);\n }\n }\n\n this._mode = mode;\n return this;\n }\n\n /**\n * Get this Color's mode.\n */\n get mode(): ColorType {\n return this._mode;\n }\n\n // rgb\n /**\n * the `r` value in RGB color mode. Same as `x`.\n */\n get r(): number {\n return this[0];\n }\n set r(n: number) {\n this[0] = n;\n }\n\n /**\n * the `g` value in RGB color mode. Same as `y`.\n */\n get g(): number {\n return this[1];\n }\n set g(n: number) {\n this[1] = n;\n }\n\n /**\n * the `b` value in RGB/LAB/HSB color mode. Same as `z`.\n */\n get b(): number {\n return this[2];\n }\n set b(n: number) {\n this[2] = n;\n }\n\n // hsl, hsb\n /**\n * the `h` value in HSL/HSB or LCH color mode. Same as either `x` or `z` depending on current color mode.\n */\n get h(): number {\n return this._mode == \"lch\" || this._mode == \"oklch\" ? this[2] : this[0];\n }\n set h(n: number) {\n const i = this._mode == \"lch\" || this._mode == \"oklch\" ? 2 : 0;\n this[i] = n;\n }\n\n /**\n * the `s` value in HSL/HSB color mode. Same as `y`.\n */\n get s(): number {\n return this[1];\n }\n set s(n: number) {\n this[1] = n;\n }\n\n /**\n * the `l` value in HSL or LCH/LAB color mode. Same as either `x` or `z` depending on current color mode.\n */\n get l(): number {\n return this._mode == \"hsl\" ? this[2] : this[0];\n }\n set l(n: number) {\n const i = this._mode == \"hsl\" ? 2 : 0;\n this[i] = n;\n }\n\n // lab, lch, luv\n /**\n * the `a` value in LAB color mode. Same as `y`.\n */\n get a(): number {\n return this[1];\n }\n set a(n: number) {\n this[1] = n;\n }\n\n /**\n * the `c` value in LCH color mode. Same as `y`.\n */\n get c(): number {\n return this[1];\n }\n set c(n: number) {\n this[1] = n;\n }\n\n /**\n * the `u` value in LUV color mode. Same as `y`.\n */\n get u(): number {\n return this[1];\n }\n set u(n: number) {\n this[1] = n;\n }\n\n /**\n * the `v` value in LUV color mode. Same as `z`.\n */\n get v(): number {\n return this[2];\n }\n set v(n: number) {\n this[2] = n;\n }\n\n /**\n * Get alpha value\n */\n set alpha(n: number) {\n if (this.length > 3) this[3] = n;\n }\n get alpha(): number {\n return this.length > 3 ? this[3] : 1;\n }\n\n /**\n * Check if color values are normalized (between 0 to 1). If conversion is needed, use [`Color.normalize`](#link) function.\n */\n get normalized(): boolean {\n return this._isNorm;\n }\n set normalized(b: boolean) {\n this._isNorm = b;\n }\n\n /**\n * Normalize the color values to between 0 to 1, or revert it back to the min/max values in current color mode.\n * @param toNorm a boolean value specifying whether to normalize (`true`) or revert (`false`)\n */\n normalize(toNorm: boolean = true): Color {\n if (this._isNorm == toNorm) return this;\n\n const ranges = Color.ranges[this._mode];\n\n for (let i = 0; i < 3; i++) {\n this[i] = !toNorm\n ? Num.mapToRange(this[i], 0, 1, ranges[i][0], ranges[i][1])\n : Num.mapToRange(this[i], ranges[i][0], ranges[i][1], 0, 1);\n }\n\n this._isNorm = toNorm;\n\n return this;\n }\n\n /**\n * Like `normalize()` but returns a new Color.\n * @param toNorm a boolean value specifying whether to normalize (`true`) or revert (`false`)\n * @returns new Color\n */\n $normalize(toNorm: boolean = true): Color {\n return this.clone().normalize(toNorm);\n }\n\n /**\n * Convert this Color to a string. It can be used to get a hex or rgb string for use in rendering.\n * This formats the current channels without converting color spaces. Convert to RGB before requesting \"hex\", \"rgb\", or \"rgba\". The default \"mode\" format is for inspecting values, not for CSS rendering.\n * @param format \"hex\", \"rgb\", \"rgba\", or \"mode\" which means using current color mode label. Default is \"mode\".\n */\n toString(format: \"hex\" | \"rgb\" | \"rgba\" | \"mode\" = \"mode\"): string {\n // CSS formats need full-range values; a normalized color would floor to 0\n const v: Color | this =\n this._isNorm && format !== \"mode\" ? Color._denorm(this) : this;\n if (format == \"hex\") {\n const _hex = (n: number) => {\n const s = Math.floor(n).toString(16);\n return s.length < 2 ? \"0\" + s : s;\n };\n return `#${_hex(v[0])}${_hex(v[1])}${_hex(v[2])}`;\n } else if (format == \"rgba\") {\n return `rgba(${Math.floor(v[0])},${Math.floor(v[1])},${Math.floor(v[2])},${this.alpha})`;\n } else if (format == \"rgb\") {\n return `rgb(${Math.floor(v[0])},${Math.floor(v[1])},${Math.floor(v[2])})`;\n } else {\n return `${this._mode}(${this[0]},${this[1]},${this[2]},${this.alpha})`;\n }\n }\n\n /**\n * A static function to convert RGB to HSL.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new HSL Color\n */\n static RGBtoHSL(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const [r, g, b] = !normalizedInput ? rgb.$normalize() : rgb;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h = (max + min) / 2;\n let s = h;\n const l = h;\n\n if (max == min) {\n h = 0;\n s = 0; // achromatic\n } else {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n h = 0;\n if (max === r) {\n h = (g - b) / d + (g < b ? 6 : 0);\n } else if (max === g) {\n h = (b - r) / d + 2;\n } else if (max === b) {\n h = (r - g) / d + 4;\n }\n }\n\n const cc = Color.hsl(normalizedOutput ? h / 6 : h * 60, s, l, rgb.alpha);\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert HSL to RGB.\n * @param hsl a HSL Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static HSLtoRGB(\n hsl: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n let [h, s, l] = hsl;\n if (!normalizedInput) h = h / 360;\n h = h - Math.floor(h); // wrap hue into [0, 1)\n\n const sc = normalizedOutput ? 1 : 255;\n if (s == 0) {\n const gray = Color.rgb(sc * l, sc * l, sc * l, hsl.alpha);\n if (normalizedOutput) gray.normalized = true;\n return gray;\n }\n\n const q = l <= 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n const convert = (t: number) => {\n t = t < 0 ? t + 1 : t > 1 ? t - 1 : t;\n if (t * 6 < 1) {\n return p + (q - p) * t * 6;\n } else if (t * 2 < 1) {\n return q;\n } else if (t * 3 < 2) {\n return p + (q - p) * (2 / 3 - t) * 6;\n } else {\n return p;\n }\n };\n\n const cc = Color.rgb(\n sc * convert(h + 1 / 3),\n sc * convert(h),\n sc * convert(h - 1 / 3),\n hsl.alpha,\n );\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert RGB to HSB.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new HSB Color\n */\n static RGBtoHSB(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const [r, g, b] = !normalizedInput ? rgb.$normalize() : rgb;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const d = max - min;\n let h = 0;\n const s = max === 0 ? 0 : d / max;\n const v = max;\n\n if (max != min) {\n if (max === r) {\n h = (g - b) / d + (g < b ? 6 : 0);\n } else if (max === g) {\n h = (b - r) / d + 2;\n } else if (max === b) {\n h = (r - g) / d + 4;\n }\n }\n\n const cc = Color.hsb(normalizedOutput ? h / 6 : h * 60, s, v, rgb.alpha);\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert HSB to RGB.\n * @param hsb a HSB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static HSBtoRGB(\n hsb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n let [h, s, v] = hsb;\n if (!normalizedInput) h = h / 360;\n h = h - Math.floor(h); // wrap hue into [0, 1)\n\n const i = Math.floor(h * 6);\n const f = h * 6 - i;\n const p = v * (1 - s);\n const q = v * (1 - f * s);\n const t = v * (1 - (1 - f) * s);\n\n const pick = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q],\n ];\n const c = pick[i % 6];\n\n const sc = normalizedOutput ? 1 : 255;\n\n const cc = Color.rgb(sc * c[0], sc * c[1], sc * c[2], hsb.alpha);\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert RGB to LAB.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LAB Color\n */\n static RGBtoLAB(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(rgb) : rgb;\n return Color.XYZtoLAB(Color.RGBtoXYZ(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert LAB to RGB.\n * @param lab a LAB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static LABtoRGB(\n lab: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(lab) : lab;\n return Color.XYZtoRGB(Color.LABtoXYZ(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert RGB to LCH.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LCH Color\n */\n static RGBtoLCH(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(rgb) : rgb;\n return Color.LABtoLCH(Color.RGBtoLAB(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert LCH to RGB.\n * @param lch a LCH Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static LCHtoRGB(\n lch: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(lch) : lch;\n return Color.LABtoRGB(Color.LCHtoLAB(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert RGB to LUV.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LUV Color\n */\n static RGBtoLUV(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(rgb) : rgb;\n return Color.XYZtoLUV(Color.RGBtoXYZ(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert LUV to RGB.\n * @param luv a LUV Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static LUVtoRGB(\n luv: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(luv) : luv;\n return Color.XYZtoRGB(Color.LUVtoXYZ(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert RGB to XYZ.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new XYZ Color\n */\n static RGBtoXYZ(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = !normalizedInput ? rgb.$normalize() : rgb.clone();\n\n for (let i = 0; i < 3; i++) {\n c[i] =\n c[i] > 0.04045 ? Math.pow((c[i] + 0.055) / 1.055, 2.4) : c[i] / 12.92;\n c[i] = c[i] * 100;\n }\n\n const cc = Color.xyz(\n c[0] * 0.4124564 + c[1] * 0.3575761 + c[2] * 0.1804375,\n c[0] * 0.2126729 + c[1] * 0.7151522 + c[2] * 0.072175,\n c[0] * 0.0193339 + c[1] * 0.119192 + c[2] * 0.9503041,\n rgb.alpha,\n );\n\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert XYZ to RGB.\n * @param xyz a XYZ Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static XYZtoRGB(\n xyz: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const [x, y, z] = !normalizedInput ? xyz.$normalize() : xyz;\n\n const rgb = [\n x * 3.2406254773200533 +\n y * -1.5372079722103187 +\n z * -0.4986285986982479,\n x * -0.9689307147293197 +\n y * 1.8757560608852415 +\n z * 0.041517523842953964,\n x * 0.055710120445510616 +\n y * -0.2040210505984867 +\n z * 1.0569959422543882,\n ];\n\n // convert xyz to rgb. Note that not all colors are visible in rgb, so here we bound rgb between 0 to 1\n for (let i = 0; i < 3; i++) {\n rgb[i] =\n rgb[i] > 0.0031308\n ? 1.055 * Math.pow(rgb[i], 1 / 2.4) - 0.055\n : 12.92 * rgb[i];\n rgb[i] = Math.max(0, Math.min(1, rgb[i]));\n if (!normalizedOutput) rgb[i] = Math.round(rgb[i] * 255);\n }\n\n const cc = Color.rgb(rgb[0], rgb[1], rgb[2], xyz.alpha);\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert XYZ to LAB.\n * @param xyz a XYZ Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LAB Color\n */\n static XYZtoLAB(\n xyz: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(xyz) : xyz.clone();\n const eps = 216 / 24389;\n const kap = 24389 / 27;\n\n // adjust for D65\n c.divide(Color.D65);\n\n const fn = (n: number) => (n > eps ? Math.cbrt(n) : (kap * n + 16) / 116);\n const cy = fn(c[1]);\n\n const cc = Color.lab(\n 116 * cy - 16,\n 500 * (fn(c[0]) - cy),\n 200 * (cy - fn(c[2])),\n xyz.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert LAB to XYZ.\n * @param lab a LAB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new XYZ Color\n */\n static LABtoXYZ(\n lab: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(lab) : lab;\n const y = (c[0] + 16) / 116;\n const x = c[1] / 500 + y;\n const z = y - c[2] / 200;\n const eps = 216 / 24389;\n const kap = 24389 / 27;\n\n const d = Color.D65;\n const xxx = Math.pow(x, 3);\n const zzz = Math.pow(z, 3);\n\n // adjusted\n const cc = Color.xyz(\n d[0] * (xxx > eps ? xxx : (116 * x - 16) / kap),\n d[1] * (c[0] > kap * eps ? Math.pow((c[0] + 16) / 116, 3) : c[0] / kap),\n d[2] * (zzz > eps ? zzz : (116 * z - 16) / kap),\n lab.alpha,\n );\n\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert XYZ to LUV.\n * @param xyz a XYZ Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LUV Color\n */\n static XYZtoLUV(\n xyz: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n let [x, y, z] = normalizedInput ? Color._denorm(xyz) : xyz;\n // black has no chromaticity, so pin u'v' to avoid 0/0\n const den = x + 15 * y + 3 * z;\n const u = den === 0 ? 0 : (4 * x) / den;\n const v = den === 0 ? 0 : (9 * y) / den;\n\n const eps = 216 / 24389;\n const kap = 24389 / 27;\n y = y / 100;\n const L = y > eps ? 116 * Math.cbrt(y) - 16 : kap * y;\n\n const refU =\n (4 * Color.D65[0]) /\n (Color.D65[0] + 15 * Color.D65[1] + 3 * Color.D65[2]);\n const refV =\n (9 * Color.D65[1]) /\n (Color.D65[0] + 15 * Color.D65[1] + 3 * Color.D65[2]);\n\n const cc = Color.luv(\n L,\n 13 * L * (u - refU),\n 13 * L * (v - refV),\n xyz.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert LUV to XYZ.\n * @param luv a LUV Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new XYZ Color\n */\n static LUVtoXYZ(\n luv: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n let [l, u, v] = normalizedInput ? Color._denorm(luv) : luv;\n\n const eps = 216 / 24389;\n const kap = 24389 / 27;\n // black carries no chromaticity information\n if (l === 0) {\n const black = Color.xyz(0, 0, 0, luv.alpha);\n return normalizedOutput ? Color._normOut(black) : black;\n }\n\n const fy = (l + 16) / 116;\n let y = l > kap * eps ? fy * fy * fy : l / kap;\n\n const refU =\n (4 * Color.D65[0]) /\n (Color.D65[0] + 15 * Color.D65[1] + 3 * Color.D65[2]);\n const refV =\n (9 * Color.D65[1]) /\n (Color.D65[0] + 15 * Color.D65[1] + 3 * Color.D65[2]);\n\n u = u / (13 * l) + refU;\n v = v / (13 * l) + refV;\n\n y = y * 100;\n const x = (-1 * (9 * y * u)) / ((u - 4) * v - u * v);\n const z = (9 * y - 15 * v * y - v * x) / (3 * v);\n\n const cc = Color.xyz(x, y, z, luv.alpha);\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert LAB to LCH.\n * @param lab a LAB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LCH Color\n */\n static LABtoLCH(\n lab: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(lab) : lab;\n const h = Geom.toDegree(Geom.boundRadian(Math.atan2(c[2], c[1]))); // 0 to 360 degrees\n const cc = Color.lch(\n c[0],\n Math.sqrt(c[1] * c[1] + c[2] * c[2]),\n h,\n lab.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert LCH to LAB.\n * @param lch a LCH Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new LAB Color\n */\n static LCHtoLAB(\n lch: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(lch) : lch;\n const rad = Geom.toRadian(c[2]);\n const cc = Color.lab(\n c[0],\n Math.cos(rad) * c[1],\n Math.sin(rad) * c[1],\n lch.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert RGB to OKLAB (Ottosson 2020, as specified in CSS Color 4). OKLAB improves on LAB's perceptual uniformity, especially hue stability in blues.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new OKLAB Color\n */\n static RGBtoOKLAB(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = !normalizedInput ? rgb.$normalize() : rgb;\n const lin = (v: number) =>\n v > 0.04045 ? Math.pow((v + 0.055) / 1.055, 2.4) : v / 12.92;\n const r = lin(c[0]);\n const g = lin(c[1]);\n const b = lin(c[2]);\n\n // linear sRGB -> LMS cone response, then cube root\n const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);\n const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);\n const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);\n\n const cc = Color.oklab(\n 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,\n 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,\n rgb.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert OKLAB to RGB. Out-of-gamut results are clamped to the sRGB range.\n * @param oklab an OKLAB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static OKLABtoRGB(\n oklab: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(oklab) : oklab;\n\n const l_ = c[0] + 0.3963377774 * c[1] + 0.2158037573 * c[2];\n const m_ = c[0] - 0.1055613458 * c[1] - 0.0638541728 * c[2];\n const s_ = c[0] - 0.0894841775 * c[1] - 1.291485548 * c[2];\n const l = l_ * l_ * l_;\n const m = m_ * m_ * m_;\n const s = s_ * s_ * s_;\n\n const rgb = [\n 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,\n -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,\n -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s,\n ];\n\n for (let i = 0; i < 3; i++) {\n rgb[i] =\n rgb[i] > 0.0031308\n ? 1.055 * Math.pow(rgb[i], 1 / 2.4) - 0.055\n : 12.92 * rgb[i];\n rgb[i] = Math.max(0, Math.min(1, rgb[i]));\n if (!normalizedOutput) rgb[i] = Math.round(rgb[i] * 255);\n }\n\n const cc = Color.rgb(rgb[0], rgb[1], rgb[2], oklab.alpha);\n if (normalizedOutput) cc.normalized = true;\n return cc;\n }\n\n /**\n * A static function to convert RGB to OKLCH, the cylindrical form of OKLAB as specified in CSS Color 4.\n * @param rgb a RGB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new OKLCH Color\n */\n static RGBtoOKLCH(\n rgb: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(rgb) : rgb;\n return Color.OKLABtoOKLCH(Color.RGBtoOKLAB(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert OKLCH to RGB. Out-of-gamut results are clamped to the sRGB range.\n * @param oklch an OKLCH Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new RGB Color\n */\n static OKLCHtoRGB(\n oklch: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(oklch) : oklch;\n return Color.OKLABtoRGB(Color.OKLCHtoOKLAB(c), false, normalizedOutput);\n }\n\n /**\n * A static function to convert OKLAB to OKLCH.\n * @param oklab an OKLAB Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new OKLCH Color\n */\n static OKLABtoOKLCH(\n oklab: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(oklab) : oklab;\n const h = Geom.toDegree(Geom.boundRadian(Math.atan2(c[2], c[1]))); // 0 to 360 degrees\n const cc = Color.oklch(\n c[0],\n Math.sqrt(c[1] * c[1] + c[2] * c[2]),\n h,\n oklab.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n\n /**\n * A static function to convert OKLCH to OKLAB.\n * @param oklch an OKLCH Color\n * @param normalizedInput a boolean specifying whether input color is normalized. Default is not normalized: `false`.\n * @param normalizedOutput a boolean specifying whether output color shoud be normalized. Default is not normalized: `false`.\n * @returns a new OKLAB Color\n */\n static OKLCHtoOKLAB(\n oklch: Color,\n normalizedInput: boolean = false,\n normalizedOutput: boolean = false,\n ): Color {\n const c = normalizedInput ? Color._denorm(oklch) : oklch;\n const rad = Geom.toRadian(c[2]);\n const cc = Color.oklab(\n c[0],\n Math.cos(rad) * c[1],\n Math.sin(rad) * c[1],\n oklch.alpha,\n );\n return normalizedOutput ? Color._normOut(cc) : cc;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { MultiTouchSpace } from \"./Space\";\nimport { type Form, VisualForm, Font } from \"./Form\";\nimport { Util } from \"./Util\";\nimport { Pt, Bound } from \"./Pt\";\nimport {\n type PtLike,\n type GroupLike,\n type IPlayer,\n type DOMFormContext,\n type PtLikeIterable,\n} from \"./Types\";\n\n/**\n * DOMSpace hosts a Space in a DOM element. It is the subclassing entry point for building\n * custom element-based spaces; usually its subclass [`SVGSpace`](#link) should be used instead.\n * Learn more about spaces in [this guide](../guide/Space-0500.html).\n *\n * When using a Space inside a component framework, create it on mount and call\n * [`DOMSpace.dispose`](#link) on unmount so listeners and the animation loop are released.\n * For example, in React:\n * ```\n * useEffect(() => {\n * const space = new SVGSpace(ref.current).setup({ resize: true });\n * space.add(...).play();\n * return () => { space.dispose(); };\n * }, []);\n * ```\n * Dispose is idempotent, and a new Space can be mounted on the same element afterwards\n * (as happens under React's StrictMode).\n */\nexport class DOMSpace extends MultiTouchSpace {\n protected _canvas: HTMLElement | SVGElement;\n protected _container: Element;\n\n id: string = \"domspace\";\n protected _autoResize = true;\n protected _bgcolor = \"#e1e9f0\";\n protected _css = {};\n private _domDisposed = false;\n private _readyTimer: ReturnType<typeof setTimeout>;\n // elements this space created for a missing target, removed on dispose\n private _ownsContainer = false;\n\n // one stable bound reference, so removeEventListener actually removes the\n // listener that addEventListener added (and double-adds dedupe)\n private readonly _resizeHandlerBound = this._resizeHandler.bind(this);\n\n /**\n * Create a DOMSpace for HTML DOM elements\n * @param elem Specify an element by its \"id\" attribute as string, or by the element object itself. If left empty, a `<div id=\"pt_container\"><div id=\"pt\" /></div>` will be added to DOM; a missing id is created the same way. Use css to customize its appearance if needed.\n * @param callback an optional callback `function(boundingBox, spaceElement)` to be called when element is appended and ready. Alternatively, a \"ready\" event will also be fired from the element when it's appended, which can be traced with `spaceInstance.element.addEventListener(\"ready\")`\n * @example `new DOMSpace( \"#myElementID\" )`\n */\n constructor(\n elem: string | Element | null = \"pt\",\n callback?: (bound: Bound, elem: Element) => void,\n ) {\n super();\n this.refresh(false); // DOM elements persist unless a renderer opts into refreshing.\n\n let _selector: Element | null = null;\n this.id = \"pts\";\n\n // check element or element id string\n if (elem instanceof Element) {\n _selector = elem;\n this.id = \"pts_existing_space\";\n } else {\n const target = elem || \"pt\";\n const id = target[0] === \"#\" || target[0] === \".\" ? target : \"#\" + target;\n _selector = document.querySelector(id);\n this.id = id.substr(1);\n }\n\n // if selector is not defined, create the elements\n if (!_selector) {\n this._container = DOMSpace.createElement(\"div\", this.id + \"_container\");\n this._canvas = this._createDefaultElement(this._container, this.id);\n document.body.appendChild(this._container);\n this._ownsContainer = true;\n } else {\n this._canvas = _selector as HTMLElement;\n this._container = _selector.parentElement!;\n }\n\n // no mutation observer, so we set a timeout for ready event\n this._readyTimer = setTimeout(this._ready.bind(this, callback), 50);\n }\n\n /**\n * Create the drawing element for a target that does not exist yet, inside the created container.\n * Subclasses that draw into a specific element type override this.\n * @param container the created container\n * @param id the id for the new element\n */\n protected _createDefaultElement(\n container: Element,\n id: string,\n ): HTMLElement | SVGElement {\n return DOMSpace.createElement(\"div\", id, container) as HTMLElement;\n }\n\n /**\n * Helper function to create a DOM element.\n * @param elem element tag name\n * @param id element id attribute\n * @param appendTo Optional, if specified, the created element will be appended to this element\n */\n static createElement(\n elem: string = \"div\",\n id: string,\n appendTo?: Element,\n ): Element {\n let d = document.createElement(elem);\n if (id) d.setAttribute(\"id\", id);\n if (appendTo && appendTo.appendChild) appendTo.appendChild(d);\n return d;\n }\n\n /**\n * Handle callbacks after element is mounted in DOM.\n * @param callback\n */\n private _ready(callback?: (bound: Bound, elem: Element) => void) {\n if (this._domDisposed) return;\n if (!this._container)\n throw new Error(`Cannot initiate #${this.id} element`);\n\n this._isReady = true;\n\n this._resizeHandler(null);\n this.clear(this._bgcolor);\n this._canvas.dispatchEvent(new Event(\"ready\"));\n\n for (let k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n if (this.players[k].start)\n this.players[k].start(this.bound.clone(), this);\n }\n }\n\n this._pointer = this.center;\n\n if (callback) callback(this.bound, this._canvas);\n }\n\n /**\n * Set up various options for DOMSpace. This is usually set during instantiation, eg `new DOMSpace(...).setup( {opt} )`.\n * @param opt an object with these optional properties: **bgcolor** is a hex or rgba string to set initial background color of the canvas, or use `false` or \"transparent\" to set a transparent background; **resize** a boolean to set whether `<canvas>` size should auto resize to match its container's size, which can also be set using `autoSize()`.\n * @example `space.setup({ bgcolor: \"#f00\", resize: true })`\n */\n setup(opt: { bgcolor?: string; resize?: boolean }): this {\n if (opt.bgcolor) {\n this._bgcolor = opt.bgcolor;\n }\n\n this.autoResize = opt.resize != undefined ? opt.resize : false;\n\n return this;\n }\n\n /**\n * Not implemented. See SVGSpace and HTMLSpace for implementation.\n */\n getForm(): Form {\n return null as unknown as Form;\n }\n\n /**\n * Set whether the canvas element should resize when its container is resized.\n * @param auto a boolean value indicating if auto size is set\n */\n set autoResize(auto: boolean) {\n this._autoResize = auto;\n if (auto) {\n window.addEventListener(\"resize\", this._resizeHandlerBound);\n } else {\n delete (this._css as any)[\"width\"];\n delete (this._css as any)[\"height\"];\n window.removeEventListener(\"resize\", this._resizeHandlerBound);\n }\n }\n get autoResize(): boolean {\n return this._autoResize;\n }\n\n /**\n * This overrides Space's `resize` function. It's used as a callback function for window's resize event and not usually called directly. You can keep track of resize events with `resize: (bound, evt)` callback in your player objects (See [`Space.add`](#link) function).\n * @param b a Bound object to resize to\n * @param evt Optionally pass a resize event\n */\n resize(b: Bound, evt?: Event | null): this {\n this.bound = b;\n this.styles({ width: `${b.width}px`, height: `${b.height}px` }, true);\n\n for (let k in this.players) {\n if (this.players.hasOwnProperty(k)) {\n let p = this.players[k];\n if (p.resize) p.resize(this.bound, evt);\n }\n }\n\n return this;\n }\n\n /**\n * Window resize handling.\n * @param evt\n */\n protected _resizeHandler(evt: Event | null) {\n let b = Bound.fromBoundingRect(this._container.getBoundingClientRect());\n\n if (this._autoResize) {\n this.styles({ width: \"100%\", height: \"100%\" }, true);\n } else {\n this.styles({ width: `${b.width}px`, height: `${b.height}px` }, true);\n }\n\n this.resize(b, evt);\n }\n\n /**\n * Get this DOM element.\n */\n get element(): Element {\n return this._canvas;\n }\n\n /**\n * Get the parent DOM element that contains this DOM element.\n */\n get parent(): Element {\n return this._container;\n }\n\n /**\n * A property to indicate if the Space is ready.\n */\n get ready(): boolean {\n return this._isReady;\n }\n\n /**\n * Clear the element's contents, and optionally set a new background color. This overrides Space's `clear` function.\n * @param bg Optionally specify a custom background color in hex or rgba string, or \"transparent\". If not defined, it will use its `bgcolor` property as background color to clear the canvas.\n */\n clear(bg?: string): this {\n if (bg) this.background = bg;\n this._canvas.innerHTML = \"\";\n return this;\n }\n\n /**\n * Set a background color on the container element.\n @param bg background color as hex or rgba string\n */\n set background(bg: string) {\n this._bgcolor = bg;\n (this._container as HTMLElement).style.backgroundColor = this._bgcolor;\n }\n get background(): string {\n return this._bgcolor;\n }\n\n /**\n * Add or update a style definition, and optionally update that style in the Element.\n * @param key style name\n * @param val style value\n * @param update a boolean to update the element's style immediately if set to `true`. Default is `false`.\n */\n style(key: string, val: string, update: boolean = false): this {\n (this._css as any)[key] = val;\n if (update) (this._canvas.style as any)[key] = val;\n return this;\n }\n\n /**\n * Add of update a list of style definitions, and optionally update those styles in the Element.\n * @param styles a key-value objects of style definitions\n * @param update a boolean to update the element's style immediately if set to `true`. Default is `false`.\n * @return this\n */\n styles(styles: Record<string, string>, update: boolean = false): this {\n for (let k in styles) {\n if (styles.hasOwnProperty(k)) this.style(k, (styles as any)[k], update);\n }\n return this;\n }\n\n /**\n * A static helper function to add or update Element attributes.\n * @param elem Element to update\n * @param data an object with key-value pairs\n * @returns this DOM element\n */\n static setAttr(elem: Element, data: Record<string, any>): Element {\n for (let k in data) {\n if (data.hasOwnProperty(k)) {\n elem.setAttribute(k, (data as any)[k]);\n }\n }\n return elem;\n }\n\n /**\n * A static helper function to compose an inline style string from a object of styles.\n * @param data an object with key-value pairs\n * @example `DOMSpace.getInlineStyles( {width: \"100px\", \"font-size\": \"10px\"} )`\n */\n static getInlineStyles(data: Record<string, any>): string {\n let str = \"\";\n for (let k in data) {\n if (data.hasOwnProperty(k)) {\n if ((data as any)[k]) str += `${k}: ${(data as any)[k]}; `;\n }\n }\n return str;\n }\n\n /**\n * Dispose of browser resources held by this space and remove all players. Call this before\n * unmounting the DOM, eg in a framework component's unmount/cleanup callback. Dispose is\n * idempotent, and a new Space can be created on the same element afterwards.\n */\n dispose(): this {\n if (this._domDisposed) return this;\n this._domDisposed = true;\n clearTimeout(this._readyTimer);\n\n this.autoResize = false; // removes the window resize listener\n this._unbindAll(); // removes mouse/touch listeners on the element\n this._cancelAnimation(); // cancels the animation frame immediately\n\n // Remove the players without the subclass's DOM-clearing `removeAll`:\n // disposing must release resources, never destroy a user-owned host\n // element's contents (a re-mount on the same element must work).\n MultiTouchSpace.prototype.removeAll.call(this);\n this._isReady = false;\n // elements created for a missing target are this space's own\n if (this._ownsContainer) this._container.remove();\n\n return this;\n }\n}\n\n/**\n * @deprecated HTML rendering is deprecated and will be removed in a future major version. Use [`SVGSpace`](#link) for DOM-based output instead — it shares the supported subset of the [`CanvasForm`](#link) drawing API.\n * **[Experimental]** HTMLSpace is a subclass of DOMSpace that works with HTML elements.\n */\nexport class HTMLSpace extends DOMSpace {\n /**\n * Get a new `HTMLForm` which provides visualization functions in html elements.\n * @see `HTMLForm`\n */\n getForm(): Form {\n return new HTMLForm(this);\n }\n\n /**\n * A static function to add a DOM element inside a node. Usually you don't need to use this directly. See methods in [`HTMLForm`](#link) instead.\n * @param parent the parent element, or `null` to use current `<svg>` as parent.\n * @param name a string of element name, such as `rect` or `circle`\n * @param id id attribute of the new element\n * @param autoClass add a class based on the id (from char 0 to index of \"-\"). Default is true.\n */\n static htmlElement(\n parent: Element | null | undefined,\n name: string,\n id?: string,\n autoClass: boolean = true,\n ): HTMLElement {\n if (!parent || !parent.appendChild)\n throw new Error(\"parent is not a valid DOM element\");\n\n // O(1) id lookup, then verify it's inside the parent so a same-id\n // element elsewhere in the document is never silently adopted\n let elem: Element | null = document.getElementById(id!);\n if (elem && !parent.contains(elem)) elem = null;\n if (!elem) {\n elem = document.createElement(name);\n elem.setAttribute(\"id\", id!);\n\n if (autoClass)\n elem.setAttribute(\"class\", id!.substring(0, id!.indexOf(\"-\")));\n parent.appendChild(elem);\n }\n return elem as HTMLElement;\n }\n\n /**\n * Remove an item from this space.\n * @param player a player item with an auto-assigned `animateID` property\n */\n remove(player: IPlayer): this {\n let temp = this._container.querySelectorAll(\".\" + HTMLForm.scopeID(player));\n\n temp.forEach((el: Element) => {\n el.parentNode!.removeChild(el);\n });\n\n return super.remove(player);\n }\n\n /**\n * Remove all items from this space. This clears the contents of the space's\n * element but never touches its container.\n */\n removeAll(): this {\n this._canvas.innerHTML = \"\";\n return super.removeAll();\n }\n}\n\nlet _htmlFormGroupID = 0;\nlet _htmlFormDomID = 0;\n\n/**\n * @deprecated HTML rendering is deprecated and will be removed in a future major version. Use [`SVGForm`](#link) for DOM-based output instead — it shares the complete [`CanvasForm`](#link) drawing API.\n * **[Experimental]** HTMLForm is an implementation of abstract class [`VisualForm`](#link). It provide methods to express Pts on [`HTMLSpace`](#link).\n */\nexport class HTMLForm extends VisualForm {\n /**\n * store common styles so that they can be restored to canvas context when using multiple forms. See `reset()`.\n */\n protected _style = {\n filled: true,\n stroked: true,\n background: \"#f03\",\n \"border-color\": \"#fff\",\n color: \"#000\",\n \"border-width\": \"1px\",\n \"border-radius\": \"0\",\n \"border-style\": \"solid\",\n opacity: 1,\n position: \"absolute\",\n top: 0,\n left: 0,\n width: 0,\n height: 0,\n };\n\n protected _ctx: DOMFormContext = {\n group: null,\n groupID: \"pts\",\n groupCount: 0,\n currentID: \"pts0\",\n currentClass: \"\",\n style: {},\n };\n\n // mutable statics are stored at module level and exposed through accessors so\n // no post-class assignment is emitted (which would defeat tree-shaking)\n static get groupID(): number {\n return _htmlFormGroupID;\n }\n static set groupID(n: number) {\n _htmlFormGroupID = n;\n }\n static get domID(): number {\n return _htmlFormDomID;\n }\n static set domID(n: number) {\n _htmlFormDomID = n;\n }\n\n protected _space: HTMLSpace;\n protected _ready: boolean = false;\n protected _formID: number = 0;\n\n /**\n * Create a new `HTMLForm`. Alternatively, you can use [`HTMLSpace.getForm`](#link) function to get an instance of HTMLForm.\n * @param space the space to use\n */\n constructor(space: HTMLSpace) {\n super();\n this._space = space;\n this._formID = HTMLForm.groupID++;\n\n const init = () => {\n this._ctx.group = this._space.element;\n this._ctx.groupID = `pts_dom_${this._formID}`;\n this._ctx.style = Object.assign({}, this._style);\n this._ready = true;\n };\n // a form created after the space is ready would otherwise never\n // initialize, since start callbacks only run at readiness\n if (this._space.ready) init();\n else this._space.add({ start: init });\n }\n\n /**\n * Get the corresponding space for this form\n */\n get space(): HTMLSpace {\n return this._space;\n }\n\n /**\n * Usually not used directly. This updates a style in `_ctx` context or throw an Error if the style doesn't exist.\n * @param k style key\n * @param v style value\n * @param unit Optional unit like 'px' to append to value\n */\n protected styleTo(k: string, v: any, unit: string = \"\") {\n if ((this._ctx.style as any)[k] === undefined)\n throw new Error(`${k} style property doesn't exist`);\n this._ctx.style[k] = `${v}${unit}`;\n }\n\n /**\n * Set current alpha value.\n * @example `form.alpha(0.6)`\n * @param a alpha value between 0 and 1\n */\n alpha(a: number): this {\n this.styleTo(\"opacity\", a);\n return this;\n }\n\n /**\n * Set current fill style. Provide a valid color string or `false` to specify no fill color.\n * @example `form.fill(\"#F90\")`, `form.fill(\"rgba(0,0,0,.5\")`, `form.fill(false)`\n * @param c fill color\n */\n fill(c: string | boolean): this {\n if (typeof c == \"boolean\") {\n this.styleTo(\"filled\", c);\n if (!c) this.styleTo(\"background\", \"transparent\");\n } else {\n this.styleTo(\"filled\", true);\n this.styleTo(\"background\", c);\n }\n return this;\n }\n\n /**\n * Set current stroke style. Provide a valid color string or `false` to specify no stroke color.\n * @example `form.stroke(\"#F90\")`, `form.stroke(\"rgba(0,0,0,.5\")`, `form.stroke(false)`, `form.stroke(\"#000\", 0.5, 'round', 'square')`\n * @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))\n * @param width Optional value (can be floating point) to set line width\n * @param linejoin not implemented in HTMLForm\n * @param linecap not implemented in HTMLForm\n */\n stroke(\n c: string | boolean,\n width?: number,\n linejoin?: string,\n linecap?: string,\n ): this {\n if (typeof c == \"boolean\") {\n this.styleTo(\"stroked\", c);\n if (!c) this.styleTo(\"border-width\", 0);\n } else {\n this.styleTo(\"stroked\", true);\n this.styleTo(\"border-color\", c);\n this.styleTo(\"border-width\", (width || 1) + \"px\");\n }\n return this;\n }\n\n /**\n * Set current text color style. Provide a valid color string.\n * @example `form.fill(\"#F90\")`, `form.fill(\"rgba(0,0,0,.5\")`, `form.fill(false)`\n * @param c fill color\n */\n fillText(c: string): this {\n this.styleTo(\"color\", c);\n return this;\n }\n\n /**\n * Add custom class to the created element.\n * @param c custom class name or `false` to reset it\n * @example `form.fill(\"#f00\").cls(\"myClass\").rects(r)` `form.cls(false).circles(c)`\n */\n cls(c: string | boolean) {\n if (typeof c == \"boolean\") {\n this._ctx.currentClass = \"\";\n } else {\n this._ctx.currentClass = c;\n }\n return this;\n }\n\n /**\n * Set the current font.\n * @param sizeOrFont either a number to specify font-size, or a `Font` object to specify all font properties\n * @param weight Optional font-weight string such as \"bold\"\n * @param style Optional font-style string such as \"italic\"\n * @param lineHeight Optional line-height number suchas 1.5\n * @param family Optional font-family such as \"Helvetica, sans-serif\"\n * @example `form.font( myFont )`, `form.font(14, \"bold\")`\n */\n font(\n sizeOrFont: number | Font,\n weight?: string,\n style?: string,\n lineHeight?: number,\n family?: string,\n ): this {\n if (typeof sizeOrFont == \"number\") {\n this._font.size = sizeOrFont;\n if (family) this._font.face = family;\n if (weight) this._font.weight = weight;\n if (style) this._font.style = style;\n if (lineHeight) this._font.lineHeight = lineHeight;\n } else {\n this._font = sizeOrFont;\n }\n\n this._ctx.style[\"font\"] = this._font.value;\n\n return this;\n }\n\n /**\n * Reset the context's common styles to this form's styles. This supports using multiple forms on the same canvas context.\n */\n reset(): this {\n this._ctx.style = Object.assign({}, this._style);\n\n this._font = new Font(10, \"sans-serif\");\n this._ctx.style[\"font\"] = this._font.value;\n\n return this;\n }\n\n /**\n * Set this form's group scope by an ID, and optionally define the group's parent element. A group scope keeps track of elements by their generated IDs, and updates their properties as needed. See also `scope()`.\n * @param group_id a string to use as prefix for the group's id. For example, group_id \"hello\" will create elements with id like \"hello-1\", \"hello-2\", etc\n * @param group Optional DOM element to define this group's parent element\n * @returns this form's context\n */\n updateScope(group_id: string, group?: Element): DOMFormContext {\n this._ctx.group = group;\n this._ctx.groupID = group_id;\n this._ctx.groupCount = 0;\n this.nextID();\n return this._ctx;\n }\n\n /**\n * Set the current group scope to an item added into space, in order to keep track of any point, circle, etc created within it. The item must have an `animateID` property, so that elements created within the item will have generated IDs like \"item-{animateID}-{count}\".\n * @param item a \"player\" item that's added to space (see `space.add(...)`) and has an `animateID` property\n * @returns this form's context\n */\n scope(item: IPlayer) {\n if (!item || item.animateID == null)\n throw new Error(\"item not defined or not yet added to Space\");\n // two forms scoped to the same player must not generate the same ids\n return this.updateScope(\n `${HTMLForm.scopeID(item)}-f${this._formID}`,\n this.space.element,\n );\n }\n\n /**\n * Get next available id in the current group.\n * @returns an id string\n */\n nextID(): string {\n this._ctx.groupCount++;\n this._ctx.currentID = `${this._ctx.groupID}-${this._ctx.groupCount}`;\n return this._ctx.currentID;\n }\n\n /**\n * A static function to generate an ID string based on a context object.\n * @param ctx a context object for an HTMLForm\n */\n static getID(ctx: DOMFormContext): string {\n return ctx.currentID || `p-${HTMLForm.domID++}`;\n }\n\n /**\n * A static function to generate an ID string for a scope, based on a \"player\" item in the Space.\n * @param item a \"player\" item that's added to space (see `space.add(...)`) and has an `animateID` property\n */\n static scopeID(item: IPlayer): string {\n return `item-${item.animateID}`;\n }\n\n /**\n * A static function to help adding style object to an element. This put all styles into `style` attribute instead of individual attributes, so that the styles can be parsed by Adobe Illustrator.\n * @param elem A DOM element to add to\n * @param styles an object of style properties\n * @example `HTMLForm.style(elem, {fill: \"#f90\", stroke: false})`\n * @returns DOM element\n */\n static style(elem: Element, styles: Record<string, any>): Element {\n let st = [];\n\n if (!styles[\"filled\"]) st.push(\"background: none\");\n if (!styles[\"stroked\"]) st.push(\"border: none\");\n\n for (let k in styles) {\n if (styles.hasOwnProperty(k) && k != \"filled\" && k != \"stroked\") {\n let v = styles[k];\n if (v) {\n if (!styles[\"filled\"] && k.indexOf(\"background\") === 0) {\n continue;\n } else if (!styles[\"stroked\"] && k.indexOf(\"border-width\") === 0) {\n continue;\n } else {\n st.push(`${k}: ${v}`);\n }\n }\n }\n }\n\n return HTMLSpace.setAttr(elem, { style: st.join(\";\") });\n }\n\n /**\n * A helper function to set top, left, width, height of DOM element.\n * @param ctx the HTMLForm context whose style is updated\n * @param pt left and top position\n * @param size width and height\n */\n static rectStyle(\n ctx: DOMFormContext,\n pt: PtLike,\n size: PtLike,\n ): DOMFormContext {\n ctx.style[\"left\"] = pt[0] + \"px\";\n ctx.style[\"top\"] = pt[1] + \"px\";\n ctx.style[\"width\"] = size[0] + \"px\";\n ctx.style[\"height\"] = size[1] + \"px\";\n return ctx;\n }\n\n /**\n * A helper function to set the top and left position styling of text DOM context.\n * @param ctx context to add style to\n * @param pt a Pt object or numeric array determining the top-left position of the text\n */\n static textStyle(ctx: DOMFormContext, pt: PtLike): DOMFormContext {\n ctx.style[\"left\"] = pt[0] + \"px\";\n ctx.style[\"top\"] = pt[1] + \"px\";\n return ctx;\n }\n\n /**\n * A static function to draws a point.\n * @param ctx a context object of HTMLForm\n * @param pt a Pt object or numeric array\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `HTMLForm.point( p )`, `HTMLForm.point( p, 10, \"circle\" )`\n */\n static point(\n ctx: DOMFormContext,\n pt: PtLike,\n radius: number = 5,\n shape: string = \"square\",\n ): Element {\n if (shape === \"circle\") {\n return HTMLForm.circle(ctx, pt, radius);\n } else {\n return HTMLForm.square(ctx, pt, radius);\n }\n }\n\n /**\n * Draws a point.\n * @param pt a Pt object\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `form.point( p )`, `form.point( p, 10, \"circle\" )`\n */\n point(pt: PtLike, radius: number = 5, shape: string = \"square\"): this {\n this.nextID();\n // reset radius for squares, so a square after a circle isn't rounded\n this.styleTo(\"border-radius\", shape == \"circle\" ? \"100%\" : \"0\");\n HTMLForm.point(this._ctx, pt, radius, shape);\n return this;\n }\n\n /**\n * A static function to draw a circle.\n * @param ctx a context object of HTMLForm\n * @param pt center position of the circle\n * @param radius radius of the circle\n */\n static circle(ctx: DOMFormContext, pt: PtLike, radius: number = 10): Element {\n let elem = HTMLSpace.htmlElement(ctx.group, \"div\", HTMLForm.getID(ctx));\n HTMLSpace.setAttr(elem, {\n class: `pts-form pts-circle ${ctx.currentClass}`,\n });\n HTMLForm.rectStyle(\n ctx,\n new Pt(pt).$subtract(radius),\n new Pt(radius * 2, radius * 2),\n );\n HTMLForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * Draw a circle.\n * @param pts usually a Group of 2 Pts, but it can also take an array of two numeric arrays [ [position], [size] ]\n * @see [`Circle.fromCenter`](#link)\n */\n circle(pts: GroupLike | number[][]): this {\n this.nextID();\n this.styleTo(\"border-radius\", \"100%\");\n HTMLForm.circle(this._ctx, pts[0], pts[1][0]);\n return this;\n }\n\n /**\n * A static function to draw a square.\n * @param ctx a context object of HTMLForm\n * @param pt center position of the square\n * @param halfsize half size of the square\n */\n static square(ctx: DOMFormContext, pt: PtLike, halfsize: number) {\n let elem = HTMLSpace.htmlElement(ctx.group, \"div\", HTMLForm.getID(ctx));\n HTMLSpace.setAttr(elem, {\n class: `pts-form pts-square ${ctx.currentClass}`,\n });\n HTMLForm.rectStyle(\n ctx,\n new Pt(pt).$subtract(halfsize),\n new Pt(halfsize * 2, halfsize * 2),\n );\n HTMLForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * Draw a square, given a center and its half-size.\n * @param pt center Pt\n * @param halfsize half-size\n */\n square(pt: PtLike, halfsize: number): this {\n this.nextID();\n this.styleTo(\"border-radius\", \"0\");\n HTMLForm.square(this._ctx, pt, halfsize);\n return this;\n }\n\n /**\n * A static function to draw a rectangle.\n * @param ctx a context object of HTMLForm\n * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.\n */\n static rect(ctx: DOMFormContext, pts: PtLikeIterable): Element | undefined {\n let p = Util.iterToArray(pts);\n if (!Util.arrayCheck(p)) return;\n\n let elem = HTMLSpace.htmlElement(ctx.group, \"div\", HTMLForm.getID(ctx));\n HTMLSpace.setAttr(elem, { class: `pts-form pts-rect ${ctx.currentClass}` });\n HTMLForm.rectStyle(ctx, p[0], p[1]);\n HTMLForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * Draw a rectangle.\n * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.\n */\n rect(pts: PtLikeIterable): this {\n this.nextID();\n this.styleTo(\"border-radius\", \"0\");\n HTMLForm.rect(this._ctx, pts);\n return this;\n }\n\n /**\n * A static function to draw text.\n * @param ctx a context object of HTMLForm\n * @param pt a Point object to specify the anchor point\n * @param txt a string of text to draw\n */\n static text(ctx: DOMFormContext, pt: PtLike, txt: string): Element {\n let elem = HTMLSpace.htmlElement(ctx.group, \"div\", HTMLForm.getID(ctx));\n\n HTMLSpace.setAttr(elem, { class: `pts-form pts-text ${ctx.currentClass}` });\n\n elem.textContent = txt;\n HTMLForm.textStyle(ctx, pt);\n HTMLForm.style(elem, ctx.style);\n\n return elem;\n }\n\n /**\n * Draw text in a DOM element.\n * @param pt a Pt or numeric array to specify the anchor point\n * @param txt text\n */\n text(pt: PtLike, txt: string): this {\n this.nextID();\n HTMLForm.text(this._ctx, pt, txt);\n return this;\n }\n\n /**\n * A convenient way to draw some text on canvas for logging or debugging. It'll be draw on the top-left of the canvas as an overlay.\n * @param txt text\n */\n log(txt: any): this {\n this.fill(\"#000\").stroke(\"#fff\", 0.5).text([10, 14], txt);\n return this;\n }\n\n /**\n * Arc is not implemented in HTMLForm.\n */\n arc(\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): this {\n Util.warn(\"arc is not implemented in HTMLForm\");\n return this;\n }\n\n /**\n * Line is not implemented in HTMLForm.\n */\n line(pts: GroupLike | number[][]): this {\n Util.warn(\"line is not implemented in HTMLForm\");\n return this;\n }\n\n /**\n * Polygon is not implemented in HTMLForm.\n * @param pts\n */\n polygon(pts: GroupLike | number[][]): this {\n Util.warn(\"polygon is not implemented in HTMLForm\");\n return this;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { VisualForm, Font } from \"./Form\";\nimport { CanvasForm } from \"./Canvas\";\nimport { Geom } from \"./Num\";\nimport { Const, Util } from \"./Util\";\nimport { Pt, Group, type Bound } from \"./Pt\";\nimport { Rectangle } from \"./Op\";\nimport { DOMSpace } from \"./Dom\";\nimport {\n type PtLike,\n type PtLikeIterable,\n type IPlayer,\n type DOMFormContext,\n type RenderingContext2D,\n} from \"./Types\";\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\n// Canvas composite operations that map directly onto CSS mix-blend-mode.\n// The Porter-Duff subset (\"source-in\" etc.) has no SVG equivalent per-element.\nconst BLEND_MODES = new Set([\n \"multiply\",\n \"screen\",\n \"overlay\",\n \"darken\",\n \"lighten\",\n \"color-dodge\",\n \"color-burn\",\n \"hard-light\",\n \"soft-light\",\n \"difference\",\n \"exclusion\",\n \"hue\",\n \"saturation\",\n \"color\",\n \"luminosity\",\n]);\n\n// module-level so the class stays tree-shakable (a static field would\n// downlevel to a post-class assignment, which bundlers keep)\nlet _gradientCount = 0;\n\n/**\n * A gradient handle returned by [`SVGContext2D`](#link)'s `createLinearGradient` and\n * `createRadialGradient`. It is structurally compatible with `CanvasGradient` (it has\n * `addColorStop`), and materializes into an SVG `<defs>` gradient when first painted.\n */\nclass SVGGradient {\n readonly id: string;\n readonly kind: \"linear\" | \"radial\";\n readonly coords: number[];\n stops: [number, string][] = [];\n protected _elem: SVGElement | null = null;\n\n constructor(kind: \"linear\" | \"radial\", coords: number[]) {\n this.kind = kind;\n this.coords = coords;\n this.id = `pts_grad_${_gradientCount++}`;\n }\n\n addColorStop(offset: number, color: string): void {\n this.stops.push([offset, color]);\n if (this._elem) this._render(this._elem); // already materialized; keep it in sync\n }\n\n /** Create or update the `<defs>` element for this gradient and return its paint url. */\n materialize(defs: SVGElement): string {\n if (!this._elem) {\n this._elem = document.createElementNS(\n SVG_NS,\n this.kind === \"linear\" ? \"linearGradient\" : \"radialGradient\",\n ) as SVGElement;\n this._elem.setAttribute(\"id\", this.id);\n this._elem.setAttribute(\"gradientUnits\", \"userSpaceOnUse\");\n if (this.kind === \"linear\") {\n const [x1, y1, x2, y2] = this.coords;\n DOMSpace.setAttr(this._elem, { x1, y1, x2, y2 });\n } else {\n const [x0, y0, r0, x1, y1, r1] = this.coords;\n DOMSpace.setAttr(this._elem, { cx: x1, cy: y1, r: r1, fx: x0, fy: y0 });\n if (r0) this._elem.setAttribute(\"fr\", `${r0}`);\n }\n this._render(this._elem);\n }\n if (this._elem.parentNode !== defs) defs.appendChild(this._elem);\n return `url(#${this.id})`;\n }\n\n protected _render(elem: SVGElement) {\n elem.textContent = \"\";\n for (const [offset, color] of this.stops) {\n const stop = document.createElementNS(SVG_NS, \"stop\");\n stop.setAttribute(\"offset\", `${offset}`);\n stop.setAttribute(\"stop-color\", color);\n elem.appendChild(stop);\n }\n }\n}\n\n/** A pending draw record produced by SVGContext2D, consumed by the frame commit. */\ntype SVGRun = {\n tag: \"path\" | \"text\" | \"image\";\n attrs: Record<string, string | number>;\n text?: string;\n shapeEnds?: number[]; // per-shape boundaries in the d string, for expanded export\n};\n\n// module-level state for the same tree-shaking reason as _gradientCount above\nlet _svgMeasurer: CanvasRenderingContext2D | null = null;\nconst _svgWarned: { [k: string]: boolean } = {};\n\n/**\n * **`SVGContext2D`** implements the subset of `CanvasRenderingContext2D` that\n * [`CanvasForm`](#link) draws through, and renders it as SVG. Consecutive shapes that share\n * paint state are merged into single `<path>` elements (\"style runs\"), so the DOM cost per\n * frame is proportional to the number of style changes, not the number of shapes. This is\n * what lets sketches using the supported subset run unchanged on canvas and SVG.\n *\n * Capability notes: blend-mode composites map to `mix-blend-mode`; Porter-Duff composites,\n * `clip`, and `putImageData` warn once and no-op. Text metrics come from a hidden canvas, so\n * `textBox` layout matches canvas exactly. When shapes with both fill and stroke are merged,\n * all fills in a run paint before its strokes — visible only for overlapping same-styled\n * shapes.\n *\n * **Writing your own renderer**: this class is the reference implementation of the rendering\n * contract — any object implementing the same context surface can be handed to\n * [`CanvasForm`](#link)'s constructor to become a Pts renderer (a PDF writer, a command\n * recorder, a test snapshotter, and so on). The surface is the subset of\n * `CanvasRenderingContext2D` that `CanvasForm` draws through:\n * - path verbs: `beginPath`, `moveTo`, `lineTo`, `quadraticCurveTo`, `bezierCurveTo`,\n * `rect`, `arc`, `ellipse`, `closePath`\n * - paint: `fill`, `stroke`, `fillRect`, `clearRect`\n * - state: `save`, `restore`, `clip`, `scale`\n * - style fields: `fillStyle`, `strokeStyle`, `lineWidth`, `lineJoin`, `lineCap`,\n * `globalAlpha`, `globalCompositeOperation`, `setLineDash`, `lineDashOffset`\n * - text: `font`, `textAlign`, `textBaseline`, `fillText`, `measureText`\n * - images: `drawImage`, `putImageData`\n * - gradients: `createLinearGradient`, `createRadialGradient`\n *\n * A renderer driven by a Space should also expose a frame lifecycle like\n * [`SVGContext2D.beginFrame`](#link) / [`SVGContext2D.commitFrame`](#link), called around the\n * players' animate callbacks. The unit test \"implements every context member that CanvasForm\n * uses\" is the compatibility alarm: it fails when a new `CanvasForm` feature touches a\n * context member a renderer does not implement.\n */\nexport class SVGContext2D {\n // ---- canvas-compatible state ----\n fillStyle: string | SVGGradient = \"#f03\";\n strokeStyle: string | SVGGradient = \"#fff\";\n lineWidth: number = 1;\n lineJoin: string = \"bevel\";\n lineCap: string = \"butt\";\n globalAlpha: number = 1;\n globalCompositeOperation: string = \"source-over\";\n font: string = \"10px sans-serif\";\n textAlign: string = \"start\";\n textBaseline: string = \"alphabetic\";\n lineDashOffset: number = 0;\n\n protected _dash: number[] = [];\n protected _stateStack: object[] = [];\n\n /** Optional CSS class applied to emitted elements (see `SVGForm.cls`). */\n className: string = \"\";\n\n // ---- current path & shape ----\n protected _d: string = \"\";\n protected _shapeFill: string | null = null; // resolved paint or null\n protected _shapeStroke: string | null = null;\n protected _shapeStrokeStyle: Record<string, string | number> = {};\n protected _shapePainted: boolean = false;\n // class/alpha/blend are captured at paint time (fill/stroke), not at flush\n // time, so a style change between shapes cannot apply retroactively\n protected _shapeClass: string = \"\";\n protected _shapeAlpha: number = 1;\n protected _shapeBlend: string = \"source-over\";\n\n // ---- frame state ----\n protected _runs: SVGRun[] = [];\n protected _drawCount: number = 0;\n\n // ---- DOM ----\n protected _host: SVGElement; // the <svg> element\n protected _group: SVGElement | null = null; // managed <g> holding this context's output\n protected _defs: SVGElement | null = null;\n protected _pool: SVGElement[] = []; // pooled elements, index-aligned with runs\n protected _attrCache: Record<string, string>[] = [];\n\n constructor(host: SVGElement) {\n this._host = host;\n }\n\n protected static _warnOnce(key: string, msg: string) {\n if (!_svgWarned[key]) {\n _svgWarned[key] = true;\n Util.warn(msg);\n }\n }\n\n // -------------------------------------------------------------- lifecycle\n\n /** Start a new frame: subsequent draws build a fresh run list. */\n beginFrame(): void {\n this._runs = [];\n this._d = \"\";\n this._shapeFill = null;\n this._shapeStroke = null;\n this._shapePainted = false;\n this._drawCount = 0;\n }\n\n /** Number of paint calls since `beginFrame` — used to skip empty commits. */\n get drawCount(): number {\n return this._drawCount;\n }\n\n /** The `<g>` element holding this context's rendered output. */\n get group(): SVGElement | null {\n return this._group;\n }\n\n /**\n * Commit the frame: reconcile the run list against the pooled elements, patching only\n * changed attributes, and truncate unused elements.\n */\n commitFrame(): void {\n this._flushShape();\n if (!this._group) {\n this._group = document.createElementNS(SVG_NS, \"g\") as SVGElement;\n this._group.setAttribute(\"class\", \"pts-svgform\");\n this._host.appendChild(this._group);\n }\n\n const runs = this._runs;\n for (let i = 0; i < runs.length; i++) {\n const run = runs[i];\n let elem = this._pool[i];\n if (!elem || elem.nodeName !== run.tag) {\n const fresh = document.createElementNS(SVG_NS, run.tag) as SVGElement;\n if (elem) {\n this._group.replaceChild(fresh, elem);\n } else {\n this._group.appendChild(fresh);\n }\n elem = fresh;\n this._pool[i] = elem;\n this._attrCache[i] = {};\n }\n const cache = this._attrCache[i];\n // conditional attributes (eg, stroke-dasharray, mix-blend-mode) must not\n // survive from an earlier frame's run on this pooled element\n for (const k in cache) {\n if (!(k in run.attrs)) {\n elem.removeAttribute(k);\n delete cache[k];\n }\n }\n for (const k in run.attrs) {\n const v = `${run.attrs[k]}`;\n if (cache[k] !== v) {\n elem.setAttribute(k, v);\n cache[k] = v;\n }\n }\n if (run.tag === \"text\" && elem.textContent !== run.text) {\n elem.textContent = run.text!;\n }\n }\n\n // truncate the unused tail\n for (let i = this._pool.length - 1; i >= runs.length; i--) {\n this._group.removeChild(this._pool[i]);\n this._pool.pop();\n this._attrCache.pop();\n }\n\n // Definitions belong to the committed scene, not to every gradient ever\n // created. A retained gradient handle can materialize again when reused.\n if (this._defs) {\n const paints = new Set<string | number>();\n for (const run of runs) {\n paints.add(run.attrs.fill);\n paints.add(run.attrs.stroke);\n }\n for (const elem of Array.from(this._defs.children)) {\n if (!paints.has(`url(#${elem.id})`)) elem.remove();\n }\n }\n }\n\n /** The current frame's run list (used by expanded export). */\n get runs(): SVGRun[] {\n return this._runs;\n }\n\n /** Forget cached DOM references, eg after the host's contents were removed externally. */\n resetDom(): void {\n this._group = null;\n this._defs = null;\n this._pool = [];\n this._attrCache = [];\n }\n\n /**\n * Remove this context's managed elements from the DOM and forget them. Used when a space\n * is disposed so that a re-mounted space on the same element starts clean.\n */\n disposeDom(): void {\n if (this._group && this._group.parentNode) {\n this._group.parentNode.removeChild(this._group);\n }\n if (this._defs && this._defs.parentNode) {\n this._defs.parentNode.removeChild(this._defs);\n }\n this.resetDom();\n }\n\n // ------------------------------------------------------------ path verbs\n\n beginPath(): void {\n this._flushShape();\n this._d = \"\";\n }\n\n closePath(): void {\n this._d += \"Z\";\n }\n\n moveTo(x: number, y: number): void {\n this._d += `M${round2(x)} ${round2(y)}`;\n }\n\n lineTo(x: number, y: number): void {\n this._d += `L${round2(x)} ${round2(y)}`;\n }\n\n quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void {\n this._d += `Q${round2(cpx)} ${round2(cpy)} ${round2(x)} ${round2(y)}`;\n }\n\n bezierCurveTo(\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n x: number,\n y: number,\n ): void {\n this._d += `C${round2(cp1x)} ${round2(cp1y)} ${round2(cp2x)} ${round2(cp2y)} ${round2(x)} ${round2(y)}`;\n }\n\n rect(x: number, y: number, w: number, h: number): void {\n this._d += `M${round2(x)} ${round2(y)}h${round2(w)}v${round2(h)}h${round2(-w)}Z`;\n }\n\n arc(\n x: number,\n y: number,\n radius: number,\n startAngle: number,\n endAngle: number,\n ccw: boolean = false,\n ): void {\n this.ellipse(x, y, radius, radius, 0, startAngle, endAngle, ccw);\n }\n\n ellipse(\n x: number,\n y: number,\n rx: number,\n ry: number,\n rotation: number,\n startAngle: number,\n endAngle: number,\n ccw: boolean = false,\n ): void {\n // canvas sweep semantics: direction-signed delta, wrapped into [0, 2π),\n // where a delta of 2π or more is a full ellipse\n let delta = ccw ? startAngle - endAngle : endAngle - startAngle;\n const full = delta >= Const.two_pi;\n if (!full) delta = ((delta % Const.two_pi) + Const.two_pi) % Const.two_pi;\n\n const cosR = Math.cos(rotation);\n const sinR = Math.sin(rotation);\n const ptAt = (angle: number): [number, number] => {\n const px = rx * Math.cos(angle);\n const py = ry * Math.sin(angle);\n return [x + px * cosR - py * sinR, y + px * sinR + py * cosR];\n };\n\n const dir = ccw ? -1 : 1;\n const sweepFlag = ccw ? 0 : 1;\n const rotDeg = round2((rotation * 180) / Math.PI);\n const [sx, sy] = ptAt(startAngle);\n\n // connect from the current point like canvas does\n this._d +=\n this._d.length > 0\n ? `L${round2(sx)} ${round2(sy)}`\n : `M${round2(sx)} ${round2(sy)}`;\n\n // emit in half-turn segments so large-arc flags stay unambiguous\n const sweep = full ? Const.two_pi : delta;\n const segments = Math.max(1, Math.ceil(sweep / Const.pi - 0.000001));\n let angle = startAngle;\n for (let s = 1; s <= segments; s++) {\n const target =\n s === segments ? startAngle + dir * sweep : angle + dir * Const.pi;\n const [ex, ey] = ptAt(target);\n this._d += `A${round2(rx)} ${round2(ry)} ${rotDeg} 0 ${sweepFlag} ${round2(ex)} ${round2(ey)}`;\n angle = target;\n }\n if (full) this._d += \"Z\";\n }\n\n // ----------------------------------------------------------------- paint\n\n fill(): void {\n this._shapeFill = this._resolvePaint(this.fillStyle);\n this._capturePaintState();\n }\n\n stroke(): void {\n this._shapeStroke = this._resolvePaint(this.strokeStyle);\n this._shapeStrokeStyle = {\n \"stroke-width\": this.lineWidth,\n \"stroke-linejoin\": this.lineJoin,\n \"stroke-linecap\": this.lineCap,\n };\n if (this._dash.length > 0) {\n this._shapeStrokeStyle[\"stroke-dasharray\"] = this._dash.join(\" \");\n if (this.lineDashOffset)\n this._shapeStrokeStyle[\"stroke-dashoffset\"] = this.lineDashOffset;\n }\n this._capturePaintState();\n }\n\n protected _capturePaintState(): void {\n this._shapePainted = true;\n this._shapeClass = this.className;\n this._shapeAlpha = this.globalAlpha;\n this._shapeBlend = this.globalCompositeOperation;\n this._drawCount++;\n }\n\n fillRect(x: number, y: number, w: number, h: number): void {\n this.beginPath();\n this.rect(x, y, w, h);\n this.fill();\n }\n\n clearRect(): void {\n // background clearing is handled by SVGSpace.clear; nothing to erase mid-frame\n }\n\n fillText(txt: string, x: number, y: number, maxWidth?: number): void {\n this._flushShape();\n const anchor =\n this.textAlign === \"center\"\n ? \"middle\"\n : this.textAlign === \"right\" || this.textAlign === \"end\"\n ? \"end\"\n : \"start\";\n const baseline =\n this.textBaseline === \"top\"\n ? \"text-before-edge\"\n : this.textBaseline === \"middle\"\n ? \"central\"\n : this.textBaseline === \"bottom\"\n ? \"text-after-edge\"\n : this.textBaseline; // alphabetic, hanging, ideographic pass through\n const attrs: Record<string, string | number> = {\n x: round2(x),\n y: round2(y),\n fill: this._resolvePaint(this.fillStyle),\n \"text-anchor\": anchor,\n \"dominant-baseline\": baseline,\n style: `font: ${this.font}`,\n \"pointer-events\": \"none\",\n };\n // canvas maxWidth semantics: compress to fit only when text is wider\n if (maxWidth! > 0 && this.measureText(txt).width > maxWidth!) {\n attrs.textLength = round2(maxWidth!);\n attrs.lengthAdjust = \"spacingAndGlyphs\";\n }\n this._applyCommon(attrs);\n this._runs.push({ tag: \"text\", attrs, text: txt });\n this._drawCount++;\n }\n\n measureText(txt: string): TextMetrics {\n if (!_svgMeasurer) {\n _svgMeasurer = document.createElement(\"canvas\").getContext(\"2d\")!;\n }\n _svgMeasurer!.font = this.font;\n return _svgMeasurer!.measureText(txt);\n }\n\n drawImage(\n img: CanvasImageSource,\n x: number,\n y: number,\n w?: number,\n h?: number,\n ...rest: number[]\n ): void {\n if (rest.length > 0) {\n SVGContext2D._warnOnce(\n \"drawImage9\",\n \"SVG output does not support the 9-argument (source-cropped) drawImage\",\n );\n return;\n }\n this._flushShape();\n const src =\n (img as HTMLImageElement).src ??\n ((img as HTMLCanvasElement).toDataURL\n ? (img as HTMLCanvasElement).toDataURL()\n : null);\n if (!src) {\n SVGContext2D._warnOnce(\n \"drawImageSrc\",\n \"SVG output supports images from <img> elements or canvases only\",\n );\n return;\n }\n const attrs: Record<string, string | number> = {\n href: src,\n x: round2(x),\n y: round2(y),\n };\n const iw = w ?? (img as HTMLImageElement).width;\n const ih = h ?? (img as HTMLImageElement).height;\n if (iw != null) attrs.width = round2(iw as number);\n if (ih != null) attrs.height = round2(ih as number);\n this._applyCommon(attrs);\n this._runs.push({ tag: \"image\", attrs });\n this._drawCount++;\n }\n\n putImageData(): void {\n SVGContext2D._warnOnce(\n \"putImageData\",\n \"putImageData is not supported in SVG output\",\n );\n }\n\n // ----------------------------------------------------------- state & misc\n\n save(): void {\n this._stateStack.push({\n fillStyle: this.fillStyle,\n strokeStyle: this.strokeStyle,\n lineWidth: this.lineWidth,\n lineJoin: this.lineJoin,\n lineCap: this.lineCap,\n globalAlpha: this.globalAlpha,\n globalCompositeOperation: this.globalCompositeOperation,\n font: this.font,\n textAlign: this.textAlign,\n textBaseline: this.textBaseline,\n lineDashOffset: this.lineDashOffset,\n _dash: this._dash.slice(),\n });\n }\n\n restore(): void {\n const s = this._stateStack.pop();\n if (s) Object.assign(this, s);\n }\n\n scale(): void {\n // SVG output is resolution-independent; the canvas pixel-density scale is a no-op here\n }\n\n clip(): void {\n SVGContext2D._warnOnce(\"clip\", \"clip is not yet supported in SVG output\");\n }\n\n setLineDash(segments: number[]): void {\n this._dash = segments;\n }\n\n getLineDash(): number[] {\n return this._dash;\n }\n\n createLinearGradient(\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n ): SVGGradient {\n return new SVGGradient(\"linear\", [x1, y1, x2, y2]);\n }\n\n createRadialGradient(\n x0: number,\n y0: number,\n r0: number,\n x1: number,\n y1: number,\n r1: number,\n ): SVGGradient {\n return new SVGGradient(\"radial\", [x0, y0, r0, x1, y1, r1]);\n }\n\n // -------------------------------------------------------------- internals\n\n protected _resolvePaint(style: string | SVGGradient): string {\n if (style instanceof SVGGradient) {\n if (!this._defs) {\n this._defs = document.createElementNS(SVG_NS, \"defs\") as SVGElement;\n this._host.insertBefore(this._defs, this._host.firstChild);\n }\n return style.materialize(this._defs);\n }\n if (typeof style !== \"string\") {\n // a CanvasPattern (or other canvas paint object) has no SVG equivalent;\n // \"[object CanvasPattern]\" would otherwise be emitted as an invalid paint\n SVGContext2D._warnOnce(\n \"pattern\",\n \"canvas patterns are not supported in SVG output; use CanvasSpace\",\n );\n return \"none\";\n }\n return style;\n }\n\n /** Add class, alpha, and blend attributes shared by all run kinds. */\n protected _applyCommon(attrs: Record<string, string | number>): void {\n attrs.class = this.className\n ? `pts-svgform ${this.className}`\n : \"pts-svgform\";\n if (this.globalAlpha !== 1) attrs.opacity = this.globalAlpha;\n else attrs.opacity = 1;\n const op = this.globalCompositeOperation;\n if (op !== \"source-over\") {\n if (BLEND_MODES.has(op)) {\n // text runs already carry their font in `style`; append, never replace\n const blend = `mix-blend-mode: ${op}`;\n attrs.style = attrs.style ? `${attrs.style}; ${blend}` : blend;\n } else {\n SVGContext2D._warnOnce(\n `composite-${op}`,\n `composite operation \"${op}\" has no SVG equivalent`,\n );\n }\n }\n }\n\n /**\n * Commit the current shape (its path and fill/stroke usage) into the run list, merging\n * with the previous run when the paint state matches.\n */\n protected _flushShape(): void {\n if (!this._shapePainted || this._d.length === 0) {\n this._shapePainted = false;\n return;\n }\n\n const attrs: Record<string, string | number> = {\n d: this._d,\n fill: this._shapeFill ?? \"none\",\n stroke: this._shapeStroke ?? \"none\",\n };\n if (this._shapeStroke) {\n Object.assign(attrs, this._shapeStrokeStyle);\n }\n attrs.class = this._shapeClass\n ? `pts-svgform ${this._shapeClass}`\n : \"pts-svgform\";\n attrs.opacity = this._shapeAlpha;\n if (this._shapeBlend !== \"source-over\") {\n if (BLEND_MODES.has(this._shapeBlend)) {\n attrs.style = `mix-blend-mode: ${this._shapeBlend}`;\n } else {\n SVGContext2D._warnOnce(\n `composite-${this._shapeBlend}`,\n `composite operation \"${this._shapeBlend}\" has no SVG equivalent`,\n );\n }\n }\n\n const prev = this._runs[this._runs.length - 1];\n if (prev && prev.tag === \"path\" && sameRunStyle(prev.attrs, attrs)) {\n prev.shapeEnds!.push((prev.attrs.d as string).length);\n prev.attrs.d = (prev.attrs.d as string) + this._d;\n } else {\n this._runs.push({ tag: \"path\", attrs, shapeEnds: [] });\n }\n\n this._d = \"\";\n this._shapeFill = null;\n this._shapeStroke = null;\n this._shapePainted = false;\n }\n}\n\nfunction round2(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\n/** Compare two path-run attribute sets for style equality (everything but the path data). */\nfunction sameRunStyle(\n a: Record<string, string | number>,\n b: Record<string, string | number>,\n): boolean {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n for (const k of keysA) {\n if (k === \"d\") continue;\n if (a[k] !== b[k]) return false;\n }\n return true;\n}\n\n/**\n * SVGSpace extends [`DOMSpace`](#link) to support SVG elements. Use it with [`SVGForm`](#link),\n * which shares its drawing API and semantics with [`CanvasForm`](#link) — a sketch written for\n * canvas can run on SVG with the supported subset. Check out the [Space guide](../guide/Space-0500.html) for details.\n */\nexport class SVGSpace extends DOMSpace {\n protected _bgcolor: string = \"#999\";\n protected _svgContexts: SVGContext2D[] = [];\n protected _bgElem: SVGElement | null = null;\n protected _svgRefresh: boolean = true; // mirrors Space's private refresh flag\n\n /**\n * Create a SVGSpace which represents a Space for SVG elements.\n * @param elem Specify an element by its \"id\" attribute as string, or by the element object itself. An element can be an existing `<svg>`, or a `<div>` container in which a new `<svg>` will be created. If left empty, a `<div id=\"pt_container\"><svg id=\"pt\" /></div>` will be added to DOM. Use css to customize its appearance if needed.\n * @param callback an optional callback `function(boundingBox, spaceElement)` to be called when canvas is appended and ready. Alternatively, a \"ready\" event will also be fired from the `<svg>` element when it's appended, which can be traced with `spaceInstance.canvas.addEventListener(\"ready\")`\n * @example `new SVGSpace( \"#myElementID\" )`\n */\n constructor(\n elem: string | Element | null = \"pt\",\n callback?: (bound: Bound, elem: Element) => void,\n ) {\n super(elem, callback);\n\n if (this._canvas.nodeName.toLowerCase() != \"svg\") {\n let s = SVGSpace.svgElement(this._canvas, \"svg\", `${this.id}_svg`);\n this._container = this._canvas;\n this._canvas = s as SVGElement;\n }\n\n // immediate-mode cycle like canvas: redraw and reconcile every frame\n this.refresh(true);\n }\n\n /**\n * For a missing target, create the documented `<svg id=\"pt\">` inside the created container.\n */\n protected _createDefaultElement(container: Element, id: string): SVGElement {\n return SVGSpace.svgElement(container, \"svg\", id);\n }\n\n /**\n * Get a new [`SVGForm`](#link) for drawing. The form shares its API with\n * [`CanvasForm`](#link), rendered through a [`SVGContext2D`](#link).\n * @see `SVGForm`\n */\n getForm(): SVGForm {\n return new SVGForm(this);\n }\n\n /**\n * Get the DOM element.\n */\n get element(): Element {\n return this._canvas;\n }\n\n /** Register a rendering context so its frame lifecycle follows this space's play cycle. */\n registerContext(ctx: SVGContext2D): void {\n this._svgContexts.push(ctx);\n }\n\n /**\n * This overrides Space's `resize` function. It's used as a callback function for window's resize event and not usually called directly.\n * You can keep track of resize events with `resize: (bound ,evt)` callback in your [`IPlayer`](#link) objects (See [`Space.add`](#link)).\n * @param b a Bound object to resize to\n * @param evt Optionally pass a resize event\n */\n resize(b: Bound, evt?: Event | null): this {\n super.resize(b, evt);\n SVGSpace.setAttr(this.element, {\n viewBox: `0 0 ${this.bound.width} ${this.bound.height}`,\n width: `${this.bound.width}`,\n height: `${this.bound.height}`,\n xmlns: SVG_NS,\n version: \"1.1\",\n });\n this._updateBackground();\n return this;\n }\n\n /**\n * Clear the drawing. In SVG this maintains a background rectangle rather than erasing\n * elements — the per-frame reconciliation removes stale shapes.\n * @param bg Optionally specify a custom background color in hex or rgba string, or \"transparent\"\n */\n clear(bg?: string): this {\n if (bg) this._bgcolor = bg;\n this._updateBackground();\n return this;\n }\n\n protected _updateBackground(): void {\n const svg = this._canvas as SVGElement;\n if (!this._bgElem) {\n this._bgElem = document.createElementNS(SVG_NS, \"rect\") as SVGElement;\n this._bgElem.setAttribute(\"class\", \"pts-svg-bg\");\n svg.insertBefore(this._bgElem, svg.firstChild);\n }\n DOMSpace.setAttr(this._bgElem, {\n x: 0,\n y: 0,\n width: this.bound.width,\n height: this.bound.height,\n fill:\n !this._bgcolor || this._bgcolor === \"transparent\"\n ? \"none\"\n : this._bgcolor,\n });\n }\n\n /**\n * The per-frame cycle: begin all registered contexts' frames, run the players, then\n * commit — reconciling the SVG DOM against what was drawn this frame.\n */\n protected playItems(time: number) {\n const ctxs = this._svgContexts;\n for (let i = 0, len = ctxs.length; i < len; i++) ctxs[i].beginFrame();\n super.playItems(time);\n for (let i = 0, len = ctxs.length; i < len; i++) {\n // skip empty commits so scenes drawn once (with refresh off) persist\n if (this._svgRefresh || ctxs[i].drawCount > 0) ctxs[i].commitFrame();\n }\n }\n\n /**\n * Set whether the rendering should be repainted on each frame.\n * @param b a boolean value to set whether to repaint each frame\n */\n refresh(b: boolean): this {\n this._svgRefresh = b;\n return super.refresh(b);\n }\n\n /**\n * Serialize the current SVG output to a string.\n * @param expand if `true`, split merged style runs into one element per shape — a\n * semantic export suited for editing in vector tools. Default is `false`.\n */\n toSVG(expand: boolean = false): string {\n const svg = this._canvas as SVGElement;\n if (!expand) return svg.outerHTML;\n\n const clone = svg.cloneNode(true) as SVGElement;\n // rebuild each form's group with one element per shape\n const groups = clone.querySelectorAll(\"g.pts-svgform\");\n let gi = 0;\n for (const ctx of this._svgContexts) {\n const group = groups[gi++];\n if (!group) continue;\n group.textContent = \"\";\n for (const run of ctx.runs) {\n if (run.tag !== \"path\") {\n const elem = document.createElementNS(SVG_NS, run.tag);\n DOMSpace.setAttr(elem, run.attrs);\n if (run.text) elem.textContent = run.text;\n group.appendChild(elem);\n continue;\n }\n const d = run.attrs.d as string;\n const bounds = [...run.shapeEnds!, d.length];\n let begin = 0;\n for (const end of bounds) {\n const elem = document.createElementNS(SVG_NS, \"path\");\n DOMSpace.setAttr(elem, { ...run.attrs, d: d.slice(begin, end) });\n group.appendChild(elem);\n begin = end;\n }\n }\n }\n return clone.outerHTML;\n }\n\n /**\n * A static function to add a svg element inside a node. Usually you don't need to call this directly. See methods in [`SVGForm`](#link) instead.\n * @param parent the parent element, or `null` to use current `<svg>` as parent.\n * @param name a string of element name, such as `rect` or `circle`\n * @param id id attribute of the new element\n */\n static svgElement(\n parent: Element | null | undefined,\n name: string,\n id?: string,\n ): SVGElement {\n if (!parent || !parent.appendChild)\n throw new Error(\"parent is not a valid DOM element\");\n\n // O(1) id lookup, then verify it's inside the parent so a same-id\n // element elsewhere in the document is never silently adopted\n let elem: Element | null = document.getElementById(id!);\n if (elem && !parent.contains(elem)) elem = null;\n\n if (!elem) {\n elem = document.createElementNS(SVG_NS, name);\n elem.setAttribute(\"id\", id!);\n\n parent.appendChild(elem);\n }\n return elem as SVGElement;\n }\n\n /**\n * Remove an item from this Space.\n * @param player a player item with an auto-assigned `animateID` property\n */\n remove(player: IPlayer): this {\n let temp = this._container.querySelectorAll(\".\" + SVGForm.scopeID(player));\n\n temp.forEach((el: Element) => {\n el.parentNode!.removeChild(el);\n });\n\n return super.remove(player);\n }\n\n /**\n * Remove all items from this Space. This clears the contents of the space's\n * `<svg>` element but never touches its container, so the space keeps\n * rendering after items are re-added.\n */\n removeAll(): this {\n this._canvas.innerHTML = \"\";\n this._bgElem = null;\n for (const ctx of this._svgContexts) ctx.resetDom();\n return super.removeAll();\n }\n\n /**\n * Dispose of browser resources held by this space: listeners, the animation loop, and the\n * elements this space manages inside the `<svg>`. Call this before unmounting, eg in a\n * framework component's cleanup callback. A new space can be mounted on the same element\n * afterwards (as happens under React's StrictMode).\n */\n dispose(): this {\n super.dispose();\n for (const ctx of this._svgContexts) ctx.disposeDom();\n this._svgContexts = [];\n if (this._bgElem && this._bgElem.parentNode) {\n this._bgElem.parentNode.removeChild(this._bgElem);\n }\n this._bgElem = null;\n return this;\n }\n}\n\nlet _svgFormGroupID = 0;\nlet _svgFormDomID = 0;\n\n// rendering-context style keys and their legacy inline-style names\nconst _legacyStyleKeys: Record<string, string> = {\n fillStyle: \"fill\",\n strokeStyle: \"stroke\",\n lineWidth: \"stroke-width\",\n lineJoin: \"stroke-linejoin\",\n lineCap: \"stroke-linecap\",\n globalAlpha: \"opacity\",\n font: \"font\",\n};\n\n/**\n * SVGForm is a [`CanvasForm`](#link) rendered through a [`SVGContext2D`](#link): it inherits\n * the canvas drawing API — shapes, gradients, dashes, images, `textBox` — with SVG\n * output, subject to the capability notes in `SVGContext2D`. Sketches using this subset\n * can swap between `CanvasSpace` and `SVGSpace`. The legacy per-element static helpers and `scope()` workflow are retained\n * for compatibility but are no longer needed.\n */\nexport class SVGForm extends CanvasForm<SVGSpace> {\n protected _svgSpace: SVGSpace;\n protected _svgCtx: SVGContext2D;\n protected _formID: number = _svgFormGroupID++;\n\n protected _legacyCtx: DOMFormContext = {\n group: null,\n groupID: \"pts\",\n groupCount: 0,\n currentID: \"pts0\",\n currentClass: \"\",\n style: {},\n };\n\n // mutable statics are stored at module level and exposed through accessors so\n // no post-class assignment is emitted (which would defeat tree-shaking)\n static get groupID(): number {\n return _svgFormGroupID;\n }\n static set groupID(n: number) {\n _svgFormGroupID = n;\n }\n static get domID(): number {\n return _svgFormDomID;\n }\n static set domID(n: number) {\n _svgFormDomID = n;\n }\n\n /**\n * Create a new SVGForm. You may also use [`SVGSpace.getForm`](#link) to get a default form directly.\n * @param space an instance of SVGSpace\n */\n constructor(space: SVGSpace) {\n super();\n this._svgSpace = space;\n this._svgCtx = new SVGContext2D(space.element as SVGElement);\n space.registerContext(this._svgCtx);\n\n this._ctx = this._svgCtx as unknown as RenderingContext2D;\n // Same initial state as CanvasForm, so a sketch renders alike on both:\n // in particular, text without an explicit font() is 14px, not the\n // context's 10px default.\n this._set(\"fillStyle\", this._style.fillStyle);\n this._set(\"strokeStyle\", this._style.strokeStyle);\n this._set(\"lineJoin\", \"bevel\");\n this._set(\"font\", this._font.value);\n this._ready = true;\n\n this._legacyCtx.group = space.element;\n }\n\n /**\n * Mirror style writes into the legacy scope context, so the static per-element helpers\n * (`SVGForm.circle( form.scope(player), ... )`) draw with the form's current fill, stroke,\n * alpha, and font as they did before the rendering-context path existed.\n */\n protected _set(key: string, value: unknown): void {\n const legacy = _legacyStyleKeys[key];\n if (legacy) {\n // gradient and pattern objects have no inline-style form; keep the last color\n if (typeof value === \"string\" || typeof value === \"number\") {\n this._legacyCtx.style[legacy] = value;\n }\n }\n super._set(key, value);\n }\n\n get filled(): boolean {\n return this._filled;\n }\n set filled(b: boolean) {\n this._filled = b;\n this._legacyCtx.style.filled = b;\n }\n\n get stroked(): boolean {\n return this._stroked;\n }\n set stroked(b: boolean) {\n this._stroked = b;\n this._legacyCtx.style.stroked = b;\n }\n\n /**\n * Offscreen buffers require Canvas output. In SVG this warns once and draws directly.\n */\n useOffscreen(_off: boolean = true, _clear: boolean | string = false): this {\n SVGForm._warnOffscreen();\n return this;\n }\n\n /**\n * Offscreen buffers require Canvas output. In SVG this warns once and does nothing.\n */\n renderOffscreen(_offset: PtLike = [0, 0]): void {\n SVGForm._warnOffscreen();\n }\n\n private static _offscreenWarned = false;\n private static _warnOffscreen() {\n if (SVGForm._offscreenWarned) return;\n SVGForm._offscreenWarned = true;\n Util.warn(\n \"offscreen canvases are not supported in SVG output; use CanvasSpace\",\n );\n }\n\n /**\n * Get the [`SVGSpace`](#link) instance that this form is associated with.\n */\n get space(): SVGSpace {\n return this._svgSpace;\n }\n\n /**\n * The underlying [`SVGContext2D`](#link), for advanced use.\n */\n get svgContext(): SVGContext2D {\n return this._svgCtx;\n }\n\n /**\n * Add custom class to the created element(s). In batched rendering the class applies to\n * the current style run.\n * @param c custom class name or `false` to reset it\n * @example `form.fill(\"#f00\").cls(\"myClass\").rects(r)` `form.cls(false).circles(c)`\n */\n cls(c: string | boolean) {\n const cls = typeof c == \"boolean\" ? \"\" : c;\n this._legacyCtx.currentClass = cls;\n this._svgCtx.className = cls;\n return this;\n }\n\n // ------------------------------------------------- legacy scope workflow\n\n /**\n * @deprecated No longer needed: elements are reconciled automatically each frame. Kept\n * for compatibility with code that pairs it with the legacy static helpers.\n */\n updateScope(group_id: string, group?: Element): DOMFormContext {\n this._legacyCtx.group = group;\n this._legacyCtx.groupID = group_id;\n this._legacyCtx.groupCount = 0;\n this.nextID();\n return this._legacyCtx;\n }\n\n /**\n * @deprecated No longer needed: elements are reconciled automatically each frame. Kept\n * for compatibility; returns the legacy context used by the static helpers.\n */\n scope(item: IPlayer) {\n if (!item || item.animateID == null)\n throw new Error(\"item not defined or not yet added to Space\");\n // two forms scoped to the same player must not generate the same ids\n return this.updateScope(\n `${SVGForm.scopeID(item)}-f${this._formID}`,\n this._svgSpace.element,\n );\n }\n\n /**\n * @deprecated Part of the legacy scope workflow.\n */\n nextID(): string {\n this._legacyCtx.groupCount++;\n this._legacyCtx.currentID = `${this._legacyCtx.groupID}-${this._legacyCtx.groupCount}`;\n return this._legacyCtx.currentID;\n }\n\n /**\n * A static function to generate an ID string based on a context object.\n * @param ctx a context object for an SVGForm\n */\n static getID(ctx: DOMFormContext): string {\n return ctx.currentID || `p-${SVGForm.domID++}`;\n }\n\n /**\n * A static function to generate an ID string for a scope, based on an [`IPlayer`](#link) object in the Space.\n * @param item a [`IPlayer`](#link) object that's added to space (see [`Space.add`](#link)) and has an `animateID` property\n */\n static scopeID(item: IPlayer): string {\n return `item-${item.animateID}`;\n }\n\n // --------------------------------------- legacy per-element static helpers\n // These draw one SVG element per call using id-based lookup, exactly as\n // before. They are retained for compatibility and for expanded exports.\n\n /**\n * A static function to help adding style object to an element.\n * Note that this put all styles into `style` attribute instead of individual svg attributes, so that the styles can be parsed by Adobe Illustrator.\n * @param elem A DOM element to add to\n * @param styles an object of style properties\n * @example `SVGForm.style(elem, {fill: \"#f90\", stroke: false})`\n * @returns this DOM element\n */\n static style(elem: SVGElement, styles: Record<string, any>) {\n let st = [];\n\n if (!styles[\"filled\"]) st.push(\"fill: none\");\n if (!styles[\"stroked\"]) st.push(\"stroke: none\");\n\n for (let k in styles) {\n if (styles.hasOwnProperty(k) && k != \"filled\" && k != \"stroked\") {\n let v = styles[k];\n if (v) {\n if (!styles[\"filled\"] && k.indexOf(\"fill\") === 0) {\n continue;\n } else if (!styles[\"stroked\"] && k.indexOf(\"stroke\") === 0) {\n continue;\n } else {\n st.push(`${k}: ${v}`);\n }\n }\n }\n }\n\n return DOMSpace.setAttr(elem, { style: st.join(\";\") });\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static point(\n ctx: DOMFormContext,\n pt: PtLike,\n radius?: number,\n shape?: string,\n ): SVGElement;\n static point(\n ctx: RenderingContext2D,\n pt: PtLike,\n radius?: number,\n shape?: string,\n ): void;\n static point(\n ctx: DOMFormContext | RenderingContext2D,\n pt: PtLike,\n radius = 5,\n shape = \"square\",\n ) {\n return \"style\" in ctx\n ? SVGForm.pointElement(ctx, pt, radius, shape)\n : CanvasForm.point(ctx, pt, radius, shape);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static circle(ctx: DOMFormContext, pt: PtLike, radius?: number): SVGElement;\n static circle(ctx: RenderingContext2D, pt: PtLike, radius?: number): void;\n static circle(\n ctx: DOMFormContext | RenderingContext2D,\n pt: PtLike,\n radius = 10,\n ) {\n return \"style\" in ctx\n ? SVGForm.circleElement(ctx, pt, radius)\n : CanvasForm.circle(ctx, pt, radius);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static arc(\n ctx: DOMFormContext,\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): SVGElement;\n static arc(\n ctx: RenderingContext2D,\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): void;\n static arc(\n ctx: DOMFormContext | RenderingContext2D,\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ) {\n return \"style\" in ctx\n ? SVGForm.arcElement(ctx, pt, radius, startAngle, endAngle, cc)\n : CanvasForm.arc(ctx, pt, radius, startAngle, endAngle, cc);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static square(ctx: DOMFormContext, pt: PtLike, halfsize: number): SVGElement;\n static square(ctx: RenderingContext2D, pt: PtLike, halfsize: number): void;\n static square(\n ctx: DOMFormContext | RenderingContext2D,\n pt: PtLike,\n halfsize: number,\n ) {\n return \"style\" in ctx\n ? SVGForm.squareElement(ctx, pt, halfsize)\n : CanvasForm.square(ctx, pt, halfsize);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static line(ctx: DOMFormContext, pts: PtLikeIterable): SVGElement | undefined;\n static line(ctx: RenderingContext2D, pts: PtLikeIterable): void;\n static line(ctx: DOMFormContext | RenderingContext2D, pts: PtLikeIterable) {\n return \"style\" in ctx\n ? SVGForm.lineElement(ctx, pts)\n : CanvasForm.line(ctx, pts);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static polygon(ctx: DOMFormContext, pts: PtLikeIterable): SVGElement;\n static polygon(ctx: RenderingContext2D, pts: PtLikeIterable): void;\n static polygon(\n ctx: DOMFormContext | RenderingContext2D,\n pts: PtLikeIterable,\n ) {\n return \"style\" in ctx\n ? SVGForm.polygonElement(ctx, pts)\n : CanvasForm.polygon(ctx, pts);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static rect(ctx: DOMFormContext, pts: PtLikeIterable): SVGElement | undefined;\n static rect(ctx: RenderingContext2D, pts: PtLikeIterable): void;\n static rect(ctx: DOMFormContext | RenderingContext2D, pts: PtLikeIterable) {\n return \"style\" in ctx\n ? SVGForm.rectElement(ctx, pts)\n : CanvasForm.rect(ctx, pts);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static bezier(\n ctx: DOMFormContext,\n pts: PtLikeIterable,\n ): SVGElement | undefined;\n static bezier(ctx: RenderingContext2D, pts: PtLikeIterable): void;\n static bezier(ctx: DOMFormContext | RenderingContext2D, pts: PtLikeIterable) {\n return \"style\" in ctx\n ? SVGForm.bezierElement(ctx, pts)\n : CanvasForm.bezier(ctx, pts);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static compound(\n ctx: DOMFormContext,\n rings: Iterable<PtLikeIterable>,\n ): SVGElement | undefined;\n static compound(\n ctx: RenderingContext2D,\n rings: Iterable<PtLikeIterable>,\n ): void;\n static compound(\n ctx: DOMFormContext | RenderingContext2D,\n rings: Iterable<PtLikeIterable>,\n ) {\n return \"style\" in ctx\n ? SVGForm.compoundElement(ctx, rings)\n : CanvasForm.compound(ctx, rings);\n }\n\n /** Draw through a rendering context, or use the legacy per-element DOM context. */\n static text(ctx: DOMFormContext, pt: PtLike, txt: string): SVGElement;\n static text(\n ctx: RenderingContext2D,\n pt: PtLike,\n txt: string,\n maxWidth?: number,\n ): void;\n static text(\n ctx: DOMFormContext | RenderingContext2D,\n pt: PtLike,\n txt: string,\n maxWidth?: number,\n ) {\n return \"style\" in ctx\n ? SVGForm.textElement(ctx, pt, txt)\n : CanvasForm.text(ctx, pt, txt, maxWidth);\n }\n\n /**\n * A static function to draw a point as a circle or square element.\n * @param ctx a context object of SVGForm\n * @param pt a Pt object or numeric array\n * @param radius radius of the point. Default is 5.\n * @param shape The shape of the point. Defaults to \"square\", but it can be \"circle\" or a custom shape function in your own implementation.\n * @example `SVGForm.point( ctx, p )`, `SVGForm.point( ctx, p, 10, \"circle\" )`\n */\n static pointElement(\n ctx: DOMFormContext,\n pt: PtLike,\n radius: number = 5,\n shape: string = \"square\",\n ): SVGElement {\n if (shape === \"circle\") {\n return SVGForm.circleElement(ctx, pt, radius);\n } else {\n return SVGForm.squareElement(ctx, pt, radius);\n }\n }\n\n /**\n * A static function to draw a circle element.\n * @param ctx a context object of SVGForm\n * @param pt center position of the circle\n * @param radius radius of the circle\n */\n static circleElement(\n ctx: DOMFormContext,\n pt: PtLike,\n radius: number = 10,\n ): SVGElement {\n let elem = SVGSpace.svgElement(ctx.group, \"circle\", SVGForm.getID(ctx));\n\n DOMSpace.setAttr(elem, {\n cx: pt[0],\n cy: pt[1],\n r: radius,\n class: `pts-svgform pts-circle ${ctx.currentClass}`,\n });\n\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * A static function to draw an arc element.\n * @param ctx a context object of SVGForm\n * @param pt center position\n * @param radius radius of the arc circle\n * @param startAngle start angle of the arc\n * @param endAngle end angle of the arc\n * @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.\n */\n static arcElement(\n ctx: DOMFormContext,\n pt: PtLike,\n radius: number,\n startAngle: number,\n endAngle: number,\n cc?: boolean,\n ): SVGElement {\n let elem = SVGSpace.svgElement(ctx.group, \"path\", SVGForm.getID(ctx));\n\n const start = new Pt(pt).toAngle(startAngle, radius, true);\n const end = new Pt(pt).toAngle(endAngle, radius, true);\n const diff = Geom.boundAngle(endAngle) - Geom.boundAngle(startAngle);\n let largeArc = diff > Const.pi ? true : false;\n if (cc) largeArc = !largeArc;\n const sweep = cc ? \"0\" : \"1\";\n\n const d = `M ${start[0]} ${start[1]} A ${radius} ${radius} 0 ${largeArc ? \"1\" : \"0\"} ${sweep} ${end[0]} ${end[1]}`;\n\n DOMSpace.setAttr(elem, {\n d: d,\n class: `pts-svgform pts-arc ${ctx.currentClass}`,\n });\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * A static function to draw a square element.\n * @param ctx a context object of SVGForm\n * @param pt center position of the square\n * @param halfsize half size of the square\n */\n static squareElement(ctx: DOMFormContext, pt: PtLike, halfsize: number) {\n let elem = SVGSpace.svgElement(ctx.group, \"rect\", SVGForm.getID(ctx));\n DOMSpace.setAttr(elem, {\n x: pt[0] - halfsize,\n y: pt[1] - halfsize,\n width: halfsize * 2,\n height: halfsize * 2,\n class: `pts-svgform pts-square ${ctx.currentClass}`,\n });\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * A static function to draw a line or polyline element.\n * @param ctx a context object of SVGForm\n * @param pts a Group or an Iterable<PtLike>\n */\n static lineElement(\n ctx: DOMFormContext,\n pts: PtLikeIterable,\n ): SVGElement | undefined {\n let points = SVGForm.pointsString(pts);\n if (points.count < 2) return;\n\n // if count > 2, treat it as poly-line\n if (points.count > 2) return SVGForm._poly(ctx, points.string, false);\n\n // if count == 2, treat it as line\n let elem = SVGSpace.svgElement(ctx.group, \"line\", SVGForm.getID(ctx));\n let p = Util.iterToArray(pts);\n\n DOMSpace.setAttr(elem, {\n x1: p[0][0],\n y1: p[0][1],\n x2: p[1][0],\n y2: p[1][1],\n class: `pts-svgform pts-line ${ctx.currentClass}`,\n });\n\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * A static helper function to draw polyline or polygon.\n * @param ctx a context object of SVGForm\n * @param points a string of points' positions. See `SVGForm.pointsString` for conversion.\n * @param closePath a boolean to specify if the polygon path should be closed\n */\n protected static _poly(\n ctx: DOMFormContext,\n points: string,\n closePath: boolean = true,\n ) {\n let elem = SVGSpace.svgElement(\n ctx.group,\n closePath ? \"polygon\" : \"polyline\",\n SVGForm.getID(ctx),\n );\n\n DOMSpace.setAttr(elem, {\n points: points,\n class: `pts-svgform pts-polygon ${ctx.currentClass}`,\n });\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * Given a list of points, return a space-separated string\n * @param pts a Group or an Iterable<PtLike>\n * @returns an object of {string, count}\n */\n protected static pointsString(pts: PtLikeIterable): {\n string: string;\n count: number;\n } {\n let points: string = \"\";\n let count = 0;\n for (let p of pts) {\n points += `${p[0]},${p[1]} `;\n count++;\n }\n return { string: points, count: count };\n }\n\n /**\n * A static function to draw a polygon element.\n * @param ctx a context object of SVGForm\n * @param pts a Group or an Iterable<PtLike> representing a polygon\n */\n static polygonElement(ctx: DOMFormContext, pts: PtLikeIterable): SVGElement {\n let points = SVGForm.pointsString(pts);\n return SVGForm._poly(ctx, points.string, true);\n }\n\n /**\n * A static function to draw a chain of cubic Bezier curves as one path element.\n * @param ctx a context object of SVGForm\n * @param pts a Group or an Iterable<PtLike> in the layout of [`Curve.bezier`](#link); an incomplete trailing segment is ignored\n */\n static bezierElement(\n ctx: DOMFormContext,\n pts: PtLikeIterable,\n ): SVGElement | undefined {\n const p = Util.iterToArray(pts);\n if (p.length < 4) return;\n let d = `M${p[0][0]} ${p[0][1]}`;\n for (let i = 3; i < p.length; i += 3) {\n d += `C${p[i - 2][0]} ${p[i - 2][1]} ${p[i - 1][0]} ${p[i - 1][1]} ${p[i][0]} ${p[i][1]}`;\n }\n return SVGForm._pathElement(ctx, d);\n }\n\n /**\n * A static function to draw a compound polygon as one path element, so that a ring inside another with the opposite orientation becomes a hole.\n * @param ctx a context object of SVGForm\n * @param rings an Array/Iterable of rings, each a Group or an Iterable<PtLike>; rings with fewer than 2 points are skipped\n */\n static compoundElement(\n ctx: DOMFormContext,\n rings: Iterable<PtLikeIterable>,\n ): SVGElement | undefined {\n let d = \"\";\n for (const ring of rings) {\n const p = Util.iterToArray(ring);\n if (p.length < 2 || typeof p[0][0] !== \"number\") continue;\n d += `M${p[0][0]} ${p[0][1]}`;\n for (let i = 1; i < p.length; i++) d += `L${p[i][0]} ${p[i][1]}`;\n d += \"Z\";\n }\n if (d === \"\") return;\n return SVGForm._pathElement(ctx, d);\n }\n\n protected static _pathElement(ctx: DOMFormContext, d: string): SVGElement {\n const elem = SVGSpace.svgElement(ctx.group, \"path\", SVGForm.getID(ctx));\n DOMSpace.setAttr(elem, {\n d,\n class: `pts-svgform pts-path ${ctx.currentClass}`,\n });\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * A static function to draw a rectangle element.\n * @param ctx a context object of SVGForm\n * @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.\n */\n static rectElement(\n ctx: DOMFormContext,\n pts: PtLikeIterable,\n ): SVGElement | undefined {\n if (!Util.arrayCheck(pts)) return;\n\n let elem = SVGSpace.svgElement(ctx.group, \"rect\", SVGForm.getID(ctx));\n let bound = Group.fromArray(pts).boundingBox();\n let size = Rectangle.size(bound);\n\n DOMSpace.setAttr(elem, {\n x: bound[0][0],\n y: bound[0][1],\n width: size[0],\n height: size[1],\n class: `pts-svgform pts-rect ${ctx.currentClass}`,\n });\n\n SVGForm.style(elem, ctx.style);\n return elem;\n }\n\n /**\n * A static function to draw a text element.\n * @param ctx a context object of SVGForm\n * @param pt a Point object to specify the anchor point\n * @param txt a string of text to draw\n */\n static textElement(ctx: DOMFormContext, pt: PtLike, txt: string): SVGElement {\n let elem = SVGSpace.svgElement(ctx.group, \"text\", SVGForm.getID(ctx));\n\n DOMSpace.setAttr(elem, {\n \"pointer-events\": \"none\",\n x: pt[0],\n y: pt[1],\n dx: 0,\n dy: 0,\n class: `pts-svgform pts-text ${ctx.currentClass}`,\n });\n\n elem.textContent = txt;\n\n SVGForm.style(elem, ctx.style);\n\n return elem;\n }\n}\n","/*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */\n\nimport { Pt, Group, Bound } from \"./Pt\";\nimport { Polygon, Circle } from \"./Op\";\nimport { Geom } from \"./Num\";\nimport { type PtLike, type PtIterable } from \"./Types\";\n\n/**\n * A `World` stores and manages [`Body`](#link) and [`Particle`](#link) for 2D physics simulation.\n * It advances with a substepped position-based (XPBD-style) solver and a spatial-hash broad phase.\n * See a [Particle demo](https://ptsjs.org/demo/?name=physics.particles) and a [Body demo](https://ptsjs.org/demo/?name=physics.shapes) on the demo page.\n */\n// Velocities are expressed per 60 Hz frame: `hit`, drag deltas, `changed`, friction, and\n// stiffness all use this unit, so a sketch behaves the same at any display refresh rate.\nconst FRAME = 1 / 60; // seconds\nconst FRAME_MS = 1000 / 60;\n// Elapsed times below this are carried into the next update rather than solved as a\n// tiny step (a duplicate RAF timestamp would otherwise produce a 10× step-size jump).\nconst MIN_STEP_MS = 2;\n\nexport class World {\n protected _gravity: Pt = new Pt();\n protected _friction: number = 1; // general friction\n protected _damping: number = 0.75; // collision damping\n protected _iterations: number = 1; // constraint iterations per substep\n protected _substeps: number = 4; // solver substeps per update\n protected _maxTimeStep: number = 50; // clamp on ms per update\n protected _bound: Bound;\n\n protected _particles: Particle[] = [];\n protected _bodies: Body[] = [];\n protected _pnames: string[] = []; // particle name index\n protected _bnames: string[] = []; // body name index\n\n protected _drawParticles!: (p: Particle, i: number) => void;\n protected _drawBodies!: (p: Body, i: number) => void;\n\n // substep-adjusted friction, computed once per update\n private _frictionStep: number = 1;\n // elapsed time too short to solve, carried into the next update\n private _carry: number = 0;\n\n // spatial-hash and AABB scratch buffers, grown geometrically and reused\n private _hashKeys: Uint32Array = new Uint32Array(0);\n private _cellStart: Uint32Array = new Uint32Array(0);\n private _cellEntries: Uint32Array = new Uint32Array(0);\n private _neighborKeys: Uint32Array = new Uint32Array(9);\n private _bodyBounds: Float32Array = new Float32Array(0);\n\n /**\n * Create a `World` for 2D physics simulation.\n * @param bound a Group or an Iterable<Pt> representing a rectangular bounding box\n * @param friction a value between 0 to 1, where 1 means no friction. Default is 1\n * @param gravity a number of a Pt to define gravitational force. A number is a shorthand to set `new Pt(0, n)`. Default is 0.\n */\n constructor(\n bound: PtIterable,\n friction: number = 1,\n gravity: PtLike | number = 0,\n ) {\n this._bound = Bound.fromGroup(bound);\n this._friction = friction;\n this._gravity =\n typeof gravity === \"number\" ? new Pt(0, gravity) : new Pt(gravity);\n return this;\n }\n\n /**\n * Current bound in this `World`.\n */\n get bound(): Bound {\n return this._bound;\n }\n set bound(bound: Bound) {\n this._bound = bound;\n }\n\n /**\n * Current gravity in this `World`.\n */\n get gravity(): Pt {\n return this._gravity;\n }\n set gravity(g: Pt) {\n this._gravity = g;\n }\n\n /**\n * Current friction in this `World`.\n */\n get friction(): number {\n return this._friction;\n }\n set friction(f: number) {\n this._friction = f;\n }\n\n /**\n * Current damping in this `World`.\n */\n get damping(): number {\n return this._damping;\n }\n set damping(f: number) {\n this._damping = f;\n }\n\n /**\n * Constraint solver iterations per substep.\n */\n get iterations(): number {\n return this._iterations;\n }\n set iterations(f: number) {\n this._iterations = f;\n }\n\n /**\n * Target number of solver substeps per 60 Hz frame (16.7 ms). Each [`World.update`](#link)\n * runs enough substeps of about that size to cover its elapsed time, so a 30 Hz frame solves\n * twice as many substeps as a 60 Hz frame rather than larger ones. More substeps produce a\n * more stable and accurate simulation at a linear cost. Default is 4.\n */\n get substeps(): number {\n return this._substeps;\n }\n set substeps(n: number) {\n this._substeps = Math.max(1, Math.round(n));\n }\n\n /**\n * Maximum simulated time in milliseconds per [`World.update`](#link) call. Larger elapsed\n * times are clamped so that a hitch (eg, a backgrounded tab) cannot destabilize the\n * simulation. Default is 50.\n */\n get maxTimeStep(): number {\n return this._maxTimeStep;\n }\n set maxTimeStep(ms: number) {\n this._maxTimeStep = Math.max(0, ms);\n }\n\n /**\n * Get the number of bodies.\n */\n get bodyCount(): number {\n return this._bodies.length;\n }\n\n /**\n * Get the number of particles.\n */\n get particleCount(): number {\n return this._particles.length;\n }\n\n /**\n * Get a body in this world by index or string id.\n * @param id numeric index of the body, or a string id that associates with it.\n * @returns a Body, or undefined if not found\n */\n body(id: number | string) {\n if (typeof id === \"string\" && id.length > 0) {\n return this._bodies[this._bnames.indexOf(id)];\n }\n return typeof id === \"number\" && id >= 0 ? this._bodies[id] : undefined;\n }\n\n /**\n * Get a particle in this world by index or string id.\n * @param id numeric index of the particle, or a string id that associates with it.\n * @returns a Particle, or undefined if not found\n */\n particle(id: number | string) {\n if (typeof id === \"string\" && id.length > 0) {\n return this._particles[this._pnames.indexOf(id)];\n }\n return typeof id === \"number\" && id >= 0 ? this._particles[id] : undefined;\n }\n\n /**\n * Given a body's name, return its index in the bodies array, or -1 if not found.\n * @param name name of the body\n * @returns index number, or -1 if not found\n */\n bodyIndex(name: string): number {\n return this._bnames.indexOf(name);\n }\n\n /**\n * Given a particle's name, return its index in the particles array, or -1 if not found.\n * @param name name of the particle\n * @returns index number, or -1 if not found\n */\n particleIndex(name: string): number {\n return this._pnames.indexOf(name);\n }\n\n /**\n * Advance this world by an amount of time, solved in substeps sized by\n * [`World.substeps`](#link). The time is clamped to [`World.maxTimeStep`](#link), and an\n * elapsed time under 2 ms is carried into the next call. Draw callbacks fire once per call,\n * after the solve completes.\n * @param ms change in time in milliseconds\n */\n update(ms: number) {\n const elapsed = Math.min(ms, this._maxTimeStep) + this._carry;\n this._carry = 0;\n if (elapsed >= MIN_STEP_MS) {\n // The substep count follows the elapsed time, so the substep length stays\n // near its target regardless of frame timing. A step-size jump between\n // substeps is what the time-corrected integrator scales velocity by, and\n // a large ratio also amplifies contact corrections — enough to launch a\n // body that is merely resting on the floor.\n const k = Math.max(1, Math.round((elapsed * this._substeps) / FRAME_MS));\n const h = elapsed / 1000 / k;\n // friction is a per-frame drag; compound it per substep\n this._frictionStep = Math.pow(this._friction, h / FRAME);\n for (let s = 0; s < k; s++) {\n this._updateParticles(h);\n // Body contacts resolve every substep: penetrations are detected while\n // still shallow, and each positional push stays at the scale of one\n // substep's motion — resolving once per update would inject the whole\n // frame's correction at substep velocity, kicking bodies 4× harder than\n // intended. The scalarized SAT makes the extra narrow-phase passes cheap.\n this._updateBodies(h);\n }\n this._clearForces();\n } else if (elapsed > 0) {\n this._carry = elapsed;\n }\n\n if (this._drawParticles) {\n for (let i = 0, len = this._particles.length; i < len; i++) {\n this._drawParticles(this._particles[i], i);\n }\n }\n if (this._drawBodies) {\n for (let i = 0, len = this._bodies.length; i < len; i++) {\n this._drawBodies(this._bodies[i], i);\n }\n }\n }\n\n /**\n * Draw particles using the provided function.\n * @param fn a function that draws a particle passed in the parameters `(particle, index)`.\n */\n drawParticles(fn: (p: Particle, i: number) => void): void {\n this._drawParticles = fn;\n }\n\n /**\n * Draw bodies using the provided function.\n * @param fn a function that draws a body passed in the parameters `(body, index)`.\n */\n drawBodies(fn: (p: Body, i: number) => void): void {\n this._drawBodies = fn;\n }\n\n /**\n * Add a particle or body to this world.\n * @param p `Particle` or `Body` instance\n * @param name optional name, which can be referenced in `body()` or `particle()` function to retrieve this back.\n */\n add(p: Particle | Body, name: string = \"\"): this {\n if (p instanceof Body) {\n this._bodies.push(<Body>p);\n this._bnames.push(name);\n } else {\n this._particles.push(<Particle>p);\n this._pnames.push(name);\n }\n return this;\n }\n\n private _index(fn: (name: string) => number, id: string | number): number {\n let index = 0;\n if (typeof id === \"string\") {\n index = fn(id);\n if (index < 0)\n throw new Error(\n `Cannot find index of ${id}. You can use particleIndex() or bodyIndex() function to check existence by name.`,\n );\n } else {\n index = id;\n }\n return index;\n }\n\n /**\n * Remove bodies from this world. Support removing a range and negative index.\n * @param from Start index, which can be negative (where -1 is at index 0, -2 at index 1, etc)\n * @param count Number of items to remove. Default is 1.\n */\n removeBody(from: number | string, count: number = 1): this {\n const index = this._index(this.bodyIndex.bind(this), from);\n const param = index < 0 ? [index * -1 - 1, count] : [index, count];\n this._bodies.splice(param[0], param[1]);\n this._bnames.splice(param[0], param[1]);\n return this;\n }\n\n /**\n * Remove particles from this world. Support removing a range and negative index.\n * @param from Start index, which can be negative (where -1 is at index 0, -2 at index 1, etc)\n * @param count Number of items to remove. Default is 1.\n */\n removeParticle(from: number | string, count: number = 1): this {\n const index = this._index(this.particleIndex.bind(this), from);\n const param = index < 0 ? [index * -1 - 1, count] : [index, count];\n this._particles.splice(param[0], param[1]);\n this._pnames.splice(param[0], param[1]);\n return this;\n }\n\n /**\n * Static function to calculate edge constraints between 2 particles.\n * @param p1 particle 1\n * @param p2 particle 2\n * @param dist distance between particles\n * @param stiff stiffness between 0 to 1.\n * @param precise use precise distance calculation. Default is `false`.\n */\n static edgeConstraint(\n p1: Particle,\n p2: Particle,\n dist: number,\n stiff: number = 1,\n precise: boolean = false,\n ) {\n const m1 = 1 / (p1.mass || 1);\n const m2 = 1 / (p2.mass || 1);\n const mm = m1 + m2;\n\n let delta = p2.$subtract(p1);\n let distSq = dist * dist;\n let d = precise\n ? dist / delta.magnitude() - 1\n : distSq / (delta.dot(delta) + distSq) - 0.5; // approx square root\n let f = delta.$multiply(d * stiff);\n\n p1.subtract(f.$multiply(m1 / mm));\n p2.add(f.$multiply(m2 / mm));\n\n return p1;\n }\n\n /**\n * Static function to calculate bounding box constraints.\n * @param p particle\n * @param rect a Group or an Iterable<Pt> representing a bounding box\n * @param damping damping between 0 to 1, where 1 means no damping. Default is 0.75.\n */\n static boundConstraint(\n p: Particle,\n rect: PtIterable,\n damping: number = 0.75,\n ) {\n const bound = Geom.boundingBox(rect);\n World._boundParticle(\n p,\n bound[0][0],\n bound[0][1],\n bound[1][0],\n bound[1][1],\n damping,\n );\n }\n\n /**\n * Shared scalar core of the bound constraint: clamp to the rectangle inset by the\n * particle's radius, and reflect the damped velocity on each axis that hit a wall\n * (a corner hit reflects both).\n */\n protected static _boundParticle(\n p: Particle,\n minX: number,\n minY: number,\n maxX: number,\n maxY: number,\n damping: number,\n ) {\n const px = p[0];\n const py = p[1];\n const nx = Math.min(Math.max(px, minX + p.radius), maxX - p.radius);\n const ny = Math.min(Math.max(py, minY + p.radius), maxY - p.radius);\n\n if (nx !== px || ny !== py) {\n const prev = p.previous;\n const cx = (px - prev[0]) * damping;\n const cy = (py - prev[1]) * damping;\n prev[0] = nx !== px ? nx + cx : nx - cx;\n prev[1] = ny !== py ? ny + cy : ny - cy;\n p[0] = nx;\n p[1] = ny;\n }\n }\n\n /**\n * Integrate a particle for one substep: Verlet with the accumulated force plus gravity as\n * acceleration, and the substep-adjusted friction as drag. Forces are read but not cleared\n * here — they persist across the substeps of one update and are cleared when it completes.\n * @param p particle\n * @param dt substep time in seconds\n * @param prevDt time in seconds spanned by the particle's current displacement (see [`Particle.timeStep`](#link)); the velocity is rescaled to `dt` so that it is preserved when the step size changes.\n */\n protected integrate(\n p: Particle,\n dt: number,\n prevDt: number = p.timeStep || FRAME,\n ): Particle {\n const prev = p.previous;\n const ratio = prevDt > 0 ? dt / prevDt : 1;\n\n if (p.lock) {\n // A dragged lock stores its per-frame drag delta as velocity for collisions\n // to read; express it per substep so it is applied once over the frame.\n if (ratio !== 1) {\n prev[0] = p[0] - (p[0] - prev[0]) * ratio;\n prev[1] = p[1] - (p[1] - prev[1]) * ratio;\n }\n p.timeStep = dt;\n p.verlet(dt, this._frictionStep, dt); // re-pins to the lock point\n return p;\n }\n\n const force = p.force;\n const f = this._frictionStep * ratio;\n const dtSq = dt * dt;\n const px = p[0];\n const py = p[1];\n const nx = px + (px - prev[0]) * f + (force[0] + this._gravity[0]) * dtSq;\n const ny = py + (py - prev[1]) * f + (force[1] + this._gravity[1]) * dtSq;\n prev[0] = px;\n prev[1] = py;\n p[0] = nx;\n p[1] = ny;\n p.timeStep = dt;\n return p;\n }\n\n /**\n * Internal function to update free particles for one substep: integrate, constrain to the\n * bound, then resolve particle-particle collisions through the spatial hash.\n */\n protected _updateParticles(dt: number) {\n const ps = this._particles;\n const len = ps.length;\n if (len === 0) return;\n\n const b0 = this._bound[0];\n const b1 = this._bound[1];\n const minX = Math.min(b0[0], b1[0]);\n const minY = Math.min(b0[1], b1[1]);\n const maxX = Math.max(b0[0], b1[0]);\n const maxY = Math.max(b0[1], b1[1]);\n\n for (let i = 0; i < len; i++) {\n const p = ps[i];\n this.integrate(p, dt);\n World._boundParticle(p, minX, minY, maxX, maxY, this._damping);\n }\n\n this._collideParticles();\n }\n\n /**\n * Resolve particle-particle collisions using a uniform spatial hash (a counting-sort grid),\n * visiting only neighboring cells instead of testing all pairs.\n */\n private _collideParticles() {\n const ps = this._particles;\n const n = ps.length;\n if (n < 2) return;\n\n let rmax = 0;\n for (let i = 0; i < n; i++) {\n if (ps[i].radius > rmax) rmax = ps[i].radius;\n }\n if (rmax <= 0) return; // nothing can collide\n\n // cells of 2×rmax mean any colliding pair is within the 3×3 neighborhood\n const inv = 1 / (rmax * 2);\n let m = 16;\n while (m < n * 2) m <<= 1;\n const mask = m - 1;\n\n if (this._cellStart.length < m + 1)\n this._cellStart = new Uint32Array(m + 1);\n if (this._hashKeys.length < n) {\n this._hashKeys = new Uint32Array(n * 2);\n this._cellEntries = new Uint32Array(n * 2);\n }\n const keys = this._hashKeys;\n const start = this._cellStart;\n const entries = this._cellEntries;\n\n // count per cell, exclusive prefix sum, then scatter; after the scatter,\n // bucket k spans [start[k-1], start[k])\n start.fill(0, 0, m + 1);\n for (let i = 0; i < n; i++) {\n const p = ps[i];\n const key =\n ((Math.imul(Math.floor(p[0] * inv), 0x9e3779b1) ^\n Math.imul(Math.floor(p[1] * inv), 0x85ebca77)) >>>\n 0) &\n mask;\n keys[i] = key;\n start[key]++;\n }\n let sum = 0;\n for (let k = 0; k < m; k++) {\n const c = start[k];\n start[k] = sum;\n sum += c;\n }\n start[m] = sum;\n for (let i = 0; i < n; i++) {\n entries[start[keys[i]]++] = i;\n }\n\n const damping = this._damping;\n const visited = this._neighborKeys;\n for (let i = 0; i < n; i++) {\n const p = ps[i];\n const cx = Math.floor(p[0] * inv);\n const cy = Math.floor(p[1] * inv);\n // Visit each distinct hash key of the 3×3 neighborhood exactly once: two\n // neighbor cells can collide to the same bucket, and visiting it twice\n // would apply a pair's collision response twice.\n let visitedCount = 0;\n for (let gy = cy - 1; gy <= cy + 1; gy++) {\n const hy = Math.imul(gy, 0x85ebca77);\n for (let gx = cx - 1; gx <= cx + 1; gx++) {\n const key = ((Math.imul(gx, 0x9e3779b1) ^ hy) >>> 0) & mask;\n let seen = false;\n for (let v = 0; v < visitedCount; v++) {\n if (visited[v] === key) {\n seen = true;\n break;\n }\n }\n if (seen) continue;\n visited[visitedCount++] = key;\n const end = start[key];\n const begin = key > 0 ? start[key - 1] : 0;\n for (let e = begin; e < end; e++) {\n const j = entries[e];\n if (j > i) p.collide(ps[j], damping);\n }\n }\n }\n }\n }\n\n /**\n * Reset all accumulated forces after an update completes.\n */\n private _clearForces() {\n for (let i = 0, len = this._particles.length; i < len; i++) {\n this._particles[i].force.fill(0);\n }\n for (let i = 0, len = this._bodies.length; i < len; i++) {\n const bd = this._bodies[i];\n for (let k = 0, klen = bd.length; k < klen; k++) {\n (bd[k] as Particle).force.fill(0);\n }\n }\n }\n\n /**\n * Internal function to update bodies for one substep: integrate and bound-constrain every\n * body particle, resolve body-body and body-particle collisions behind an AABB broad\n * phase, then restore shapes with the edge-constraint pass.\n * @param dt substep time in seconds\n */\n protected _updateBodies(dt: number) {\n const bs = this._bodies;\n const blen = bs.length;\n if (blen === 0) return;\n\n const b0 = this._bound[0];\n const b1 = this._bound[1];\n const minX = Math.min(b0[0], b1[0]);\n const minY = Math.min(b0[1], b1[1]);\n const maxX = Math.max(b0[0], b1[0]);\n const maxY = Math.max(b0[1], b1[1]);\n\n for (let i = 0; i < blen; i++) {\n const bd = bs[i];\n if (!bd) continue;\n for (let k = 0, klen = bd.length; k < klen; k++) {\n const bk = bd[k] as Particle;\n this.integrate(bk, dt);\n World._boundParticle(bk, minX, minY, maxX, maxY, this._damping);\n }\n }\n\n this._collideBodies(blen);\n\n for (let i = 0; i < blen; i++) {\n if (bs[i]) bs[i].solveEdges(dt, this._iterations, this._substeps);\n }\n }\n\n /**\n * Resolve body-body and body-particle collisions behind an AABB broad phase.\n */\n private _collideBodies(blen: number) {\n const bs = this._bodies;\n\n // axis-aligned bounding boxes for the broad phase\n if (this._bodyBounds.length < blen * 4) {\n this._bodyBounds = new Float32Array(blen * 8);\n }\n const aabb = this._bodyBounds;\n for (let i = 0; i < blen; i++) {\n const bd = bs[i];\n let bx0 = Infinity;\n let by0 = Infinity;\n let bx1 = -Infinity;\n let by1 = -Infinity;\n if (bd) {\n for (let k = 0, klen = bd.length; k < klen; k++) {\n const v = bd[k];\n if (v[0] < bx0) bx0 = v[0];\n if (v[0] > bx1) bx1 = v[0];\n if (v[1] < by0) by0 = v[1];\n if (v[1] > by1) by1 = v[1];\n }\n }\n aabb[i * 4] = bx0;\n aabb[i * 4 + 1] = by0;\n aabb[i * 4 + 2] = bx1;\n aabb[i * 4 + 3] = by1;\n }\n\n const ps = this._particles;\n const plen = ps.length;\n\n for (let i = 0; i < blen; i++) {\n const bd = bs[i];\n if (!bd) continue;\n const ax0 = aabb[i * 4];\n const ay0 = aabb[i * 4 + 1];\n const ax1 = aabb[i * 4 + 2];\n const ay1 = aabb[i * 4 + 3];\n\n for (let k = i + 1; k < blen; k++) {\n if (\n bs[k] &&\n ax0 <= aabb[k * 4 + 2] &&\n ax1 >= aabb[k * 4] &&\n ay0 <= aabb[k * 4 + 3] &&\n ay1 >= aabb[k * 4 + 1]\n ) {\n bd.processBody(bs[k]);\n }\n }\n\n for (let mIdx = 0; mIdx < plen; mIdx++) {\n const p = ps[mIdx];\n const r = p.radius;\n if (\n p[0] >= ax0 - r &&\n p[0] <= ax1 + r &&\n p[1] >= ay0 - r &&\n p[1] <= ay1 + r\n ) {\n bd.processParticle(p);\n }\n }\n }\n }\n}\n\n/**\n * Particle is a subclass of [`Pt`](#link) that has radius and mass. It's usually added into [`World`](#link) to create physics simulations.\n * See [a demo here](https://ptsjs.org/demo/?name=physics.particles).\n */\nexport class Particle extends Pt {\n protected _mass: number = 1;\n protected _radius: number = 0;\n protected _force: Pt = new Pt();\n protected _prev: Pt = new Pt();\n protected _prevDt: number = 0; // seconds spanned by the `_prev` displacement; 0 = one frame\n\n protected _body!: Body;\n protected _lock: boolean = false;\n protected _lockPt!: Pt;\n\n /**\n * Create a particle. Once a particle is created, you can set its mass and radius via the corresponding accessors.\n * @param args a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n constructor(...args: any[]) {\n super(...args);\n this._prev = this.clone();\n }\n\n /**\n * Mass of this particle.\n */\n get mass(): number {\n return this._mass;\n }\n set mass(m: number) {\n this._mass = m;\n }\n\n /**\n * Radius of this particle.\n */\n get radius(): number {\n return this._radius;\n }\n set radius(f: number) {\n this._radius = f;\n }\n\n /**\n * Get this particle's previous position.\n */\n get previous(): Pt {\n return this._prev;\n }\n set previous(p: Pt) {\n this._prev = p;\n }\n\n /**\n * Get current accumulated force.\n */\n get force(): Pt {\n return this._force;\n }\n set force(g: Pt) {\n this._force = g;\n }\n\n /**\n * Get the body of this particle, if any.\n */\n get body(): Body {\n return this._body;\n }\n set body(b: Body) {\n this._body = b;\n }\n\n /**\n * Lock this particle in current position.\n */\n get lock(): boolean {\n return this._lock;\n }\n set lock(b: boolean) {\n // On unlock, reset `previous` to the current position: while locked, collisions\n // and dragging can leave it arbitrarily stale, and integrating that difference\n // would launch the particle. (To throw a particle on release, use `hit`.)\n if (this._lock && !b) this._prev.to(this);\n this._lock = b;\n this._lockPt = new Pt(this);\n }\n\n /**\n * Get the change in position per 60 Hz frame, ie, the current velocity in the same unit\n * as [`Particle.hit`](#link). The raw displacement since the last step is\n * `particle.$subtract( particle.previous )`.\n */\n get changed(): Pt {\n const d = this.$subtract(this._prev);\n return this._prevDt > 0 && this._prevDt !== FRAME\n ? d.multiply(FRAME / this._prevDt)\n : d;\n }\n\n /**\n * The time in seconds spanned by the displacement from [`Particle.previous`](#link) to the\n * current position. A [`World`](#link) sets it to the substep length on every step, and\n * [`Particle.hit`](#link) and the `position` setter reset it to one 60 Hz frame (1/60),\n * which is the unit of their velocities. 0 means unknown and is treated as one frame.\n */\n get timeStep(): number {\n return this._prevDt;\n }\n set timeStep(t: number) {\n this._prevDt = t;\n }\n\n /**\n * Set a new position, and update previous and lock states if needed. The move is stored as\n * this particle's velocity per frame, so dragging a locked particle knocks others away.\n */\n set position(p: Pt) {\n this.previous.to(this);\n this._prevDt = FRAME;\n if (this._lock) this._lockPt = p;\n this.to(p);\n }\n\n /**\n * Set the size of this particle. This sets both the radius and the mass.\n * @param r `radius` value, and also set `mass` to the same value.\n */\n size(r: number): this {\n this._mass = r;\n this._radius = r;\n return this;\n }\n\n /**\n * Add to the accumulated force.\n * @param args a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n */\n addForce(...args: any[]): Pt {\n this._force.add(...args);\n return this._force;\n }\n\n /**\n * Verlet integration.\n * @param dt change in time in seconds\n * @param friction friction from 0 to 1, where 1 means no friction\n * @param lastDt optional last change in time in seconds. Default is [`Particle.timeStep`](#link), or `dt` if unknown.\n */\n verlet(dt: number, friction: number, lastDt?: number): this {\n // Positional verlet: curr + (curr - prev) + a * dt * dt\n\n if (this._lock) {\n // Pin the position only. `previous` is deliberately left alone: dragging a\n // locked particle via the `position` setter stores the drag delta there, and\n // collisions read it as the particle's velocity — this is what makes a\n // pointer-dragged particle knock others away. Stale velocity is cleared at\n // the moment of unlocking instead (see the `lock` setter).\n this.to(this._lockPt);\n } else {\n // time corrected (https://en.wikipedia.org/wiki/Verlet_integration#Non-constant_time_differences)\n const lt = lastDt ? lastDt : this._prevDt || dt;\n const adt = (dt * (dt + lt)) / 2;\n const f = (friction * dt) / lt;\n const force = this._force;\n const prev = this._prev;\n for (let i = 0, len = this.length; i < len; i++) {\n const cur = this[i];\n const v = (cur - prev[i]) * f + (force[i] || 0) * adt;\n prev[i] = cur;\n this[i] = cur + v;\n }\n force.fill(0);\n this._prevDt = dt;\n }\n return this;\n }\n\n /**\n * Hit this particle with an impulse, in pixels per 60 Hz frame. The impulse is scaled by 1/√mass, so a heavier particle moves less from the same hit.\n * The result is the same at any frame rate and any [`World.substeps`](#link) setting.\n * @param args an impulse vector defined by either a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties\n * @example `hit(10, 20)`, `hit( new Pt(5, 9) )`\n */\n hit(...args: any[]): this {\n // express the current velocity per frame, then add the impulse in the same unit\n const prev = this._prev;\n if (this._prevDt > 0 && this._prevDt !== FRAME) {\n const r = FRAME / this._prevDt;\n for (let i = 0, len = this.length; i < len; i++) {\n prev[i] = this[i] - (this[i] - prev[i]) * r;\n }\n }\n this._prevDt = FRAME;\n prev.subtract(new Pt(...args).$divide(Math.sqrt(this._mass)));\n return this;\n }\n\n /**\n * Check and respoond to collisions between this and another particle.\n * @param p2 another particle\n * @param damp damping value between 0 to 1, where 1 means no damping.\n */\n collide(p2: Particle, damp: number = 1): void {\n // reference: http://codeflow.org/entries/2010/nov/29/verlet-collision-with-impulse-preservation\n // simultaneous collision not yet resolved. Possible solutions in this paper: https://www2.msm.ctw.utwente.nl/sluding/PAPERS/dem07.pdf\n\n const p1 = this;\n let dx = p1[0] - p2[0];\n let dy = p1[1] - p2[1];\n let distSq = dx * dx + dy * dy;\n const dr = p1.radius + p2.radius;\n if (distSq >= dr * dr) return;\n\n const prev1 = p1.previous;\n const prev2 = p2.previous;\n let c1x = p1[0] - prev1[0];\n let c1y = p1[1] - prev1[1];\n let c2x = p2[0] - prev2[0];\n let c2y = p2[1] - prev2[1];\n\n // separation of (dist - dr) / 2 along the collision axis; for exactly\n // coincident particles, separate deterministically along the x-axis\n let dist = Math.sqrt(distSq);\n let k: number;\n if (dist < 0.000001) {\n dx = 1;\n dy = 0;\n dist = 1;\n distSq = 1;\n k = -dr / 2;\n } else {\n k = (dist - dr) / dist / 2;\n }\n\n const np1x = p1[0] - dx * k;\n const np1y = p1[1] - dy * k;\n const np2x = p2[0] + dx * k;\n const np2y = p2[1] + dy * k;\n\n const f1 = (damp * (dx * c1x + dy * c1y)) / distSq;\n const f2 = (damp * (dx * c2x + dy * c2y)) / distSq;\n const dm1 = p1.mass / (p1.mass + p2.mass);\n const dm2 = p2.mass / (p1.mass + p2.mass);\n\n c1x += (f2 - f1) * dx * dm2;\n c1y += (f2 - f1) * dy * dm2;\n c2x += (f1 - f2) * dx * dm1;\n c2y += (f1 - f2) * dy * dm1;\n\n p1[0] = np1x;\n p1[1] = np1y;\n p2[0] = np2x;\n p2[1] = np2y;\n prev1[0] = np1x - c1x;\n prev1[1] = np1y - c1y;\n prev2[0] = np2x - c2x;\n prev2[1] = np2y - c2y;\n }\n\n /**\n * Get a string representation of this particle\n */\n toString(): string {\n return `Particle: ${this[0]} ${this[1]} | previous ${this._prev[0]} ${this._prev[1]} | mass ${this._mass}`;\n }\n}\n\n/**\n * Body is a subclass of [`Group`](#link) that stores a set of [`Particle`](#link)s and edge constraints. It is usually added into a [`World`](#link) to create physics simulations.\n * See [a demo here](https://ptsjs.org/demo/?name=physics.shapes).\n */\nexport class Body extends Group {\n protected _cs: Array<number[]> = [];\n protected _stiff: number = 1;\n protected _locks: { [index: string]: Particle } = {};\n protected _mass: number = 1;\n protected _lambdas: Float32Array = new Float32Array(0); // XPBD multipliers, one per link\n\n /**\n * Create an empty Body, this is usually followed by [`Body.init`](#link) to populate the Body. Alternatively, use static function [`Body.fromGroup`](#link) to create and initate a body directly.\n */\n constructor() {\n super();\n }\n\n /**\n * Create and populate a body.\n * @param body a Group or an Iterable<Pt> to define the body\n * @param stiff stiffness value from 0 to 1, where 1 is the most stiff. Default is 1.\n * @param autoLink Automatically create links between the Pts. This usually works for regular convex polygons. Default is true.\n * @param autoMass Automatically calculate the mass based on the area of the polygon. Default is true.\n */\n static fromGroup(\n body: PtIterable,\n stiff: number = 1,\n autoLink: boolean = true,\n autoMass: boolean = true,\n ): Body {\n let b = new Body().init(body);\n if (autoLink) b.linkAll(stiff);\n if (autoMass) b.autoMass();\n return b;\n }\n\n /**\n * Initiate a body.\n * @param body a Group or an Iterable<Pt> to define a body\n * @param stiff stiffness value from 0 to 1, where 1 is the most stiff. Default is 1.\n */\n init(body: PtIterable, stiff: number = 1): this {\n for (let li of body) {\n let p = new Particle(li);\n p.body = this;\n this.push(p);\n }\n\n this._stiff = stiff;\n\n return this;\n }\n\n /**\n * Get mass of this body.\n */\n get mass(): number {\n return this._mass;\n }\n set mass(m: number) {\n this._mass = m;\n for (let i = 0, len = this.length; i < len; i++) {\n (this[i] as Particle).mass = this._mass;\n }\n }\n\n /**\n * Automatically calculate a body's `mass` based on the area of the polygon.\n */\n autoMass(): this {\n this.mass = Math.sqrt(Polygon.area(this)) / 10;\n return this;\n }\n\n /**\n * Create a linked edge between two points.\n * @param index1 first point by index\n * @param index2 first point by index\n * @param stiff optionally stiffness value between 0 to 1, where 1 is the most stiff.\n */\n link(index1: number, index2: number, stiff?: number): this {\n if (index1 < 0 || index1 >= this.length)\n throw new Error(\"index1 is not in the Group's indices\");\n if (index2 < 0 || index2 >= this.length)\n throw new Error(\"index1 is not in the Group's indices\");\n\n let d = this[index1].$subtract(this[index2]).magnitude();\n this._cs.push([index1, index2, d, stiff || this._stiff]);\n return this;\n }\n\n /**\n * Automatically create links for all the points to preserve the initial body shape. This usually works for regular convex polygon.\n * @param stiff optionally stiffness value between 0 to 1, where 1 is the most stiff.\n */\n linkAll(stiff: number): void {\n const half = this.length / 2;\n\n // skip duplicate pairs and self-pairs, which the cross-link passes below\n // can produce for odd sizes (a duplicate would double-solve an edge);\n // a linear scan of the small link list beats allocating a Set here\n const tryLink = (a: number, b: number, s?: number) => {\n if (a === b) return;\n const cs = this._cs;\n for (let k = 0, klen = cs.length; k < klen; k++) {\n const c = cs[k];\n if ((c[0] === a && c[1] === b) || (c[0] === b && c[1] === a)) return;\n }\n this.link(a, b, s);\n };\n\n for (let i = 0, len = this.length; i < len; i++) {\n const n = i >= len - 1 ? 0 : i + 1;\n tryLink(i, n, stiff);\n\n if (len > 4) {\n const nd = Math.floor(half / 2) + 1;\n const n2 = i >= len - nd ? i % len : i + nd;\n tryLink(i, n2, stiff);\n }\n\n if (i <= half - 1) {\n tryLink(i, Math.min(this.length - 1, i + Math.floor(half)));\n }\n }\n }\n\n /**\n * Return a list of all the linked edges as line segments.\n * @returns an array of Groups, each of which represents an edge\n */\n linksToLines(): Group[] {\n let gs = [];\n for (let i = 0, len = this._cs.length; i < len; i++) {\n let ln = this._cs[i];\n gs.push(new Group(this[ln[0]], this[ln[1]]));\n }\n return gs;\n }\n\n /**\n * Recalculate all edge constraints.\n */\n processEdges(): void {\n for (let i = 0, len = this._cs.length; i < len; i++) {\n let [m, n, d, s] = this._cs[i];\n World.edgeConstraint(this[m] as Particle, this[n] as Particle, d, s);\n }\n }\n\n /**\n * Solve all edge constraints for one substep in XPBD form. A link's `stiff` value is a\n * geometric knob: it is the fraction of the remaining constraint violation resolved per\n * update, independent of the particles' masses and of the substep/iteration counts\n * (per Müller et al. 2007, the per-pass fraction is `1-(1-stiff)^(1/passes)`), and\n * `stiff=1` is a rigid projection. Mapping the fraction to a mass-relative compliance\n * keeps a heavy body exactly as stiff as a light one at the same value.\n * This is the solver used internally by [`World.update`](#link);\n * [`Body.processEdges`](#link) remains the simpler relaxation for direct use.\n * @param dt substep time in seconds (reserved; the geometric stiffness does not depend on it)\n * @param iterations solver iterations for this substep. Default is 1.\n * @param substeps the caller's substeps per update, for pass-count-independent stiffness. Default is 1.\n */\n solveEdges(dt: number, iterations: number = 1, substeps: number = 1): this {\n const cs = this._cs;\n const clen = cs.length;\n if (clen === 0) return this;\n\n if (this._lambdas.length < clen) this._lambdas = new Float32Array(clen);\n const lambdas = this._lambdas;\n lambdas.fill(0, 0, clen);\n const invPasses = 1 / Math.max(1, iterations * substeps);\n\n for (let iter = 0; iter < iterations; iter++) {\n for (let ci = 0; ci < clen; ci++) {\n const c = cs[ci];\n const p1 = this[c[0]] as Particle;\n const p2 = this[c[1]] as Particle;\n const stiff = c[3];\n\n const w1 = p1.lock ? 0 : 1 / (p1.mass || 1);\n const w2 = p2.lock ? 0 : 1 / (p2.mass || 1);\n const w = w1 + w2;\n if (w === 0) continue;\n\n const dx = p2[0] - p1[0];\n const dy = p2[1] - p1[1];\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist < 0.000001) continue;\n\n // mass-relative compliance: the per-pass correction fraction is exactly\n // `sEff` regardless of mass, since w / (w + alpha) = sEff\n let alpha = 0;\n if (stiff < 1) {\n const sEff = 1 - Math.pow(1 - stiff, invPasses);\n alpha = sEff > 0.000001 ? (w * (1 - sEff)) / sEff : w * 1000000;\n }\n const dl = (-(dist - c[2]) - alpha * lambdas[ci]) / (w + alpha);\n lambdas[ci] += dl;\n\n const s = dl / dist;\n const fx = dx * s;\n const fy = dy * s;\n p1[0] -= fx * w1;\n p1[1] -= fy * w1;\n p2[0] += fx * w2;\n p2[1] += fy * w2;\n }\n }\n return this;\n }\n\n /**\n * Check and respond to collisions between two bodies.\n * @param b another body\n */\n processBody(b: Body): void {\n let b1 = this;\n let b2 = b;\n\n let hit = Polygon.hasIntersectPolygon(b1, b2);\n\n if (hit) {\n let cv = hit.normal.$multiply(hit.dist);\n\n let t;\n let eg = hit.edge;\n if (Math.abs(eg[0][0] - eg[1][0]) > Math.abs(eg[0][1] - eg[1][1])) {\n t = (hit.vertex[0] - cv[0] - eg[0][0]) / (eg[1][0] - eg[0][0]);\n } else {\n t = (hit.vertex[1] - cv[1] - eg[0][1]) / (eg[1][1] - eg[0][1]);\n }\n\n let lambda = 1 / (t * t + (1 - t) * (1 - t));\n\n let m0 = (hit.vertex as Particle).body.mass || 1;\n let m1 = (hit.edge[0] as Particle).body.mass || 1;\n let mr0 = m0 / (m0 + m1);\n let mr1 = m1 / (m0 + m1);\n\n eg[0].subtract(cv.$multiply((mr0 * (1 - t) * lambda) / 2));\n eg[1].subtract(cv.$multiply((mr0 * t * lambda) / 2));\n\n hit.vertex.add(cv.$multiply(mr1));\n }\n }\n\n /**\n * Check and respond to collisions between this body and a particle.\n * @param b a particle\n */\n processParticle(b: Particle): void {\n let b1 = this;\n let b2 = b;\n\n let hit = Polygon.hasIntersectCircle(b1, Circle.fromCenter(b, b.radius));\n\n if (hit) {\n let cv = hit.normal.$multiply(hit.dist);\n\n let t;\n let eg = hit.edge;\n if (Math.abs(eg[0][0] - eg[1][0]) > Math.abs(eg[0][1] - eg[1][1])) {\n t = (hit.vertex[0] - cv[0] - eg[0][0]) / (eg[1][0] - eg[0][0]);\n } else {\n t = (hit.vertex[1] - cv[1] - eg[0][1]) / (eg[1][1] - eg[0][1]);\n }\n\n let lambda = 1 / (t * t + (1 - t) * (1 - t));\n // hit.vertex is the circle's center Pt (not a Particle), so the\n // particle's own mass is the vertex-side mass here\n let m0 = b2.mass || 1;\n let m1 = (hit.edge[0] as Particle).body.mass || 1;\n\n let mr0 = m0 / (m0 + m1);\n let mr1 = m1 / (m0 + m1);\n\n eg[0].subtract(cv.$multiply((mr0 * (1 - t) * lambda) / 2));\n eg[1].subtract(cv.$multiply((mr0 * t * lambda) / 2));\n\n // raw displacement (not `changed`, which is per frame)\n let c1 = b.$subtract(b.previous).add(cv.$multiply(mr1));\n b.previous = b.$subtract(c1);\n }\n }\n}\n","import { Pt, Group, type Bound } from \"./Pt\";\nimport { Num } from \"./Num\";\nimport {\n type ITempoListener,\n type ITempoStartFn,\n type ITempoProgressFn,\n type ITempoResponses,\n} from \"./Types\";\nimport {\n type ISoundAnalyzer,\n type SoundType,\n type PtLike,\n type IPlayer,\n} from \"./Types\";\n\n/**\n * Tempo helps you create synchronized and rhythmic animations.\n */\nexport class Tempo implements IPlayer {\n protected _bpm!: number; // beat per minute\n protected _ms!: number; // millis per beat\n\n protected _listeners: { [key: string]: ITempoListener } = {};\n protected _listenerInc: number = 0;\n public animateID!: string;\n\n /**\n * Construct a new Tempo instance by beats-per-minute. Alternatively, you can use [`Tempo.fromBeat`](#link) to create from milliseconds.\n * @param bpm beats per minute. Must be greater than 0.\n */\n constructor(bpm: number) {\n this.bpm = bpm;\n }\n\n /**\n * Create a new Tempo instance by specifying milliseconds-per-beat.\n * @param ms milliseconds per beat. Must be greater than 0.\n */\n static fromBeat(ms: number): Tempo {\n return new Tempo(60000 / ms);\n }\n\n /**\n * Beats-per-minute value. Must be greater than 0.\n */\n get bpm(): number {\n return this._bpm;\n }\n set bpm(n: number) {\n this._bpm = n;\n this._ms = 60000 / this._bpm;\n }\n\n /**\n * Milliseconds per beat (Note that this is derived from the bpm value).\n */\n get ms(): number {\n return this._ms;\n }\n set ms(n: number) {\n this._bpm = 60000 / n;\n this._ms = n;\n }\n\n // Get a listener unique id\n protected _createID(): string {\n return \"_b\" + this._listenerInc++;\n }\n\n /**\n * This is a core function that let you specify a rhythm and then define responses by calling the `start` and `progress` functions from the returned object. See [Animation guide](../guide/Animation-0700.html) for more details.\n * The `start` function lets you set a callback on every start. It takes a function ([`ITempoStartFn`](#link)).\n * The `progress` function lets you set a callback during progress. It takes a function ([`ITempoProgressFn`](#link)). Both functions let you optionally specify a time offset and a custom name.\n * A positive offset shifts the beat earlier (fires sooner), a negative offset shifts it later.\n * @param beats a rhythm in beats as a number or an array of numbers\n * @example `tempo.every(2).start( (count) => ... )`, `tempo.every([2,4,6]).progress( (count, t) => ... )`\n * @returns an object with chainable functions\n */\n every(beats: number | number[]): ITempoResponses {\n const self = this;\n const p = Array.isArray(beats) ? beats[0] : beats;\n\n return {\n start: function (\n fn: ITempoStartFn,\n offset: number = 0,\n name?: string,\n ): ITempoResponses {\n const id = name || self._createID();\n self._listeners[id] = {\n name: id,\n beats: beats,\n period: p,\n index: 0,\n offset: offset,\n duration: -1,\n count: 0,\n continuous: false,\n fn: fn,\n };\n return this;\n },\n\n progress: function (\n fn: ITempoProgressFn,\n offset: number = 0,\n name?: string,\n ): ITempoResponses {\n const id = name || self._createID();\n self._listeners[id] = {\n name: id,\n beats: beats,\n period: p,\n index: 0,\n offset: offset,\n duration: -1,\n count: 0,\n continuous: true,\n fn: fn,\n };\n return this;\n },\n };\n }\n\n /**\n * Usually you can add a tempo instance to a space via [`Space.add`](#link) and it will track time automatically.\n * But if necessary, you can track time manually via this function.\n * @param time current time in milliseconds\n */\n track(time: number) {\n for (const k in this._listeners) {\n if (this._listeners.hasOwnProperty(k)) {\n const li = this._listeners[k];\n const _t = li.offset ? time + li.offset : time;\n const ms = li.period! * this._ms; // time per period\n let isStart = false;\n\n if (li.duration! < 0) {\n // first tick is the start of the first period\n li.duration = _t - (_t % this._ms);\n li.count = li.count || 0; // a hand-built listener may omit count\n isStart = true;\n } else if (_t > li.duration! + ms) {\n li.duration = _t - (_t % this._ms); // update\n if (Array.isArray(li.beats)) {\n // find next period from array\n li.index = (li.index! + 1) % li.beats.length;\n li.period = li.beats[li.index];\n }\n li.count = (li.count || 0) + 1;\n isStart = true;\n }\n\n let done: void | boolean | undefined;\n if (li.continuous) {\n const t = Num.clamp((_t - li.duration!) / ms, 0, 1);\n done = (li.fn as ITempoProgressFn).call(\n li,\n li.count!,\n t,\n _t,\n isStart,\n );\n } else if (isStart) {\n done = (li.fn as ITempoStartFn).call(li, li.count!);\n }\n if (done) delete this._listeners[li.name!];\n }\n }\n }\n\n /**\n * Remove a `start` or `progress` callback function from the list of callbacks. See [`Tempo.every`](#link) for details\n * @param name a name string specified when creating the callback function.\n */\n stop(name: string): void {\n if (this._listeners[name]) delete this._listeners[name];\n }\n\n /**\n * IPlayer interface. Internal implementation that calls `track( time )`.\n */\n animate(time: number, ftime: number) {\n this.track(time);\n }\n\n /**\n * IPlayer interface. Not implemented.\n */\n resize(bound: Bound, evt?: Event) {\n return; // not implemented in IPlayer\n }\n\n /**\n * IPlayer interface. Not implemented.\n */\n action(type: string, px: number, py: number, evt: Event) {\n return;\n }\n}\n\n/**\n * Sound class simplifies common tasks like audio inputs and visualizations using a subset of Web Audio API. It can be used with other audio libraries like tone.js, and extended to support additional web audio functions. See [the guide](../guide/Sound-0800.html) to get started.\n */\nexport class Sound {\n private _type: SoundType;\n\n /** The audio context */\n _ctx: AudioContext;\n\n /** The audio node, which is usually a subclass liked OscillatorNode */\n _node!: AudioNode;\n\n /**\n * The audio node to be connected to AudioContext when playing, if different than _node\n * This is useful when using the connect() function to filter, as typically the output would\n * come from the filtering nodes\n */\n _outputNode!: AudioNode;\n\n /** The audio stream when streaming from input device */\n _stream!: MediaStream;\n\n /** Audio src when loading from file */\n _source!: HTMLMediaElement;\n\n /* Audio buffer when using AudioBufferSourceNode */\n _buffer!: AudioBuffer;\n\n /** Analyzer if any */\n analyzer!: ISoundAnalyzer;\n\n protected _playing: boolean = false;\n\n protected _timestamp!: number; // Tracking play time against ctx.currentTime\n\n protected _wave!: PeriodicWave; // Wave when generating a \"custom\" oscillator\n\n protected _gain!: GainNode; // Gain node for volume control, created on first start\n\n protected _volume: number = 1;\n\n protected _connected: AudioNode[] = []; // Nodes added via connect(), re-applied on gen restart\n\n protected _bufferPlayed: boolean = false; // An AudioBufferSourceNode can only start once\n\n protected _generated: boolean = false; // Whether _node is an oscillator created by _gen\n\n // A single AudioContext shared by all Sound instances that don't provide their own\n protected static _sharedContext: AudioContext;\n\n /**\n * Construct a `Sound` instance. Usually, it's more convenient to use one of the static methods like [`Sound.load`](#function_load) or [`Sound.from`](#function_from).\n * By default, all instances share a single `AudioContext` (browsers limit how many can be live at once).\n * @param type a `SoundType` string: \"file\", \"input\", or \"gen\"\n * @param ctx Optionally provide your own AudioContext instead of the shared one\n */\n constructor(type: SoundType, ctx?: AudioContext) {\n this._type = type;\n this._ctx = ctx || Sound._getContext();\n }\n\n /**\n * Get the shared AudioContext instance, creating it on first use. This is called internally only.\n */\n protected static _getContext(): AudioContext {\n if (!Sound._sharedContext) {\n const _ctx =\n typeof window !== \"undefined\" ? window.AudioContext : undefined;\n if (!_ctx)\n throw new Error(\n \"Your browser doesn't support Web Audio. (No AudioContext)\",\n );\n Sound._sharedContext = new _ctx();\n }\n return Sound._sharedContext;\n }\n\n /**\n * Create a `Sound` given an [AudioNode](https://developer.mozilla.org/en-US/docs/Web/API/AudioNode) and an [AudioContext](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext) from Web Audio API. See also [this example](../guide/js/examples/tone.html) using tone.js in the [guide](../guide/Sound-0800.html).\n * @param node an AudioNode instance\n * @param ctx an AudioContext instance\n * @param type a string representing a type of input source: either \"file\", \"input\", or \"gen\".\n * @param stream Optionally include a MediaStream, if the type is \"input\"\n * @returns a `Sound` instance\n */\n static from(\n node: AudioNode,\n ctx: AudioContext,\n type: SoundType = \"gen\",\n stream?: MediaStream,\n ) {\n const s = new Sound(type, ctx);\n s._node = node;\n if (stream) s._stream = stream;\n return s;\n }\n\n /**\n * Create a `Sound` by loading from a sound file or an audio element.\n * @param source either an url string to load a sound file, or an audio element.\n * @param crossOrigin whether to support loading cross-origin. Default is \"anonymous\". When passing an audio element, set the attribute in markup before the element loads for it to take effect.\n * @returns a `Sound` instance\n * @example `Sound.load( '/path/to/file.mp3' )`\n */\n static load(\n source: HTMLMediaElement | string,\n crossOrigin: string = \"anonymous\",\n ): Promise<Sound> {\n return new Promise((resolve, reject) => {\n const s = new Sound(\"file\");\n if (typeof source === \"string\") {\n // crossOrigin must be set before src, or the initial request is made without CORS\n s._source = new Audio();\n s._source.crossOrigin = crossOrigin;\n s._source.src = source;\n } else {\n s._source = source;\n s._source.crossOrigin = crossOrigin;\n }\n s._source.autoplay = false;\n\n const onError = () => {\n s._source.removeEventListener(\"canplaythrough\", ready);\n reject(\n new Error(`Error loading sound: ${s._source.src || \"media element\"}`),\n );\n };\n\n const ready = () => {\n // runs once: either immediately below, or via the once-only listener\n s._source.removeEventListener(\"error\", onError);\n s._source.addEventListener(\"ended\", function () {\n s._playing = false;\n });\n s._node = s._ctx.createMediaElementSource(s._source);\n resolve(s);\n };\n\n if (s._source.readyState >= 4) {\n // already buffered enough (eg, a previously loaded element)\n ready();\n } else {\n s._source.addEventListener(\"error\", onError, { once: true });\n s._source.addEventListener(\"canplaythrough\", ready, { once: true });\n if (s._source.readyState === 0) s._source.load(); // eg, preload=\"none\"\n }\n });\n }\n\n /**\n * Create a `Sound` by loading and decoding a sound file URL as an `AudioBufferSourceNode`.\n * Unlike [`Sound.load`](#link), this loads the complete file instead of streaming it, which can provide more consistent analysis and replay behavior across browsers.\n * @param url an url to the sound file\n */\n static async loadAsBuffer(url: string): Promise<Sound> {\n const s = new Sound(\"file\");\n const res = await fetch(url);\n if (!res.ok)\n throw new Error(`Error loading sound: ${url} (status ${res.status})`);\n try {\n s.createBuffer(await s._ctx.decodeAudioData(await res.arrayBuffer()));\n } catch (err) {\n // ErrorOptions isn't in this project's TS lib target; attach cause manually\n throw Object.assign(new Error(\"Error decoding audio\"), { cause: err });\n }\n return s;\n }\n\n /**\n * Create or re-use an AudioBuffer. Only needed if you are using `Sound.loadAsBuffer` and want to prepare a replay manually — [`start`](#link) re-creates a used buffer automatically.\n * @param buf an AudioBuffer. Optionally, you can call this without parameters to re-use existing buffer.\n */\n createBuffer(buf?: AudioBuffer): this {\n if (this._node) {\n // the replaced node's late \"ended\" event must not clobber the new playback state\n (this._node as AudioBufferSourceNode).onended = null;\n this._node.disconnect();\n }\n this._node = this._ctx.createBufferSource();\n if (buf !== undefined) this._buffer = buf;\n\n (this._node as AudioBufferSourceNode).buffer = this._buffer; // apply or re-use buffer\n (this._node as AudioBufferSourceNode).onended = () => {\n this._playing = false;\n };\n this._bufferPlayed = false;\n if (this.analyzer) this._node.connect(this.analyzer.node);\n for (const n of this._connected) this._node.connect(n);\n return this;\n }\n\n /**\n * Create a `Sound` by generating a waveform using [OscillatorNode](https://developer.mozilla.org/en-US/docs/Web/API/OscillatorNode).\n * @param type a string representing the waveform type: \"sine\", \"square\", \"sawtooth\", \"triangle\", \"custom\"\n * @param val the frequency value in Hz to play, or a PeriodicWave instance if type is \"custom\".\n * @returns a `Sound` instance\n * @example `Sound.generate( 'sine', 120 )`\n */\n static generate(type: OscillatorType, val: number | PeriodicWave): Sound {\n const s = new Sound(\"gen\");\n return s._gen(type, val);\n }\n\n // Create the oscillator\n protected _gen(type: OscillatorType, val: number | PeriodicWave): Sound {\n if (this._node) this._node.disconnect(); // tidy the replaced node's edges\n this._node = this._ctx.createOscillator();\n this._generated = true;\n const osc = this._node as OscillatorNode;\n if (type === \"custom\") {\n this._wave = val as PeriodicWave;\n osc.setPeriodicWave(this._wave);\n } else {\n osc.type = type;\n osc.frequency.value = val as number;\n }\n return this;\n }\n\n /**\n * Create a `Sound` by streaming from an input device like microphone. Note that this function returns a Promise which resolves to a Sound instance, and rejects if the input device is unavailable or permission is denied.\n * @param constraint Optional constraints which can be used to select a specific input device. For example, you may use [`enumerateDevices`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices) to find a specific deviceId;\n * @returns a `Promise` which resolves to `Sound` instance\n * @example `Sound.input().then( s => sound = s ).catch( err => ... );`\n */\n static async input(constraint?: MediaStreamConstraints): Promise<Sound> {\n const s = new Sound(\"input\");\n const c = constraint ? constraint : { audio: true, video: false };\n s._stream = await navigator.mediaDevices.getUserMedia(c);\n s._node = s._ctx.createMediaStreamSource(s._stream);\n return s;\n }\n\n /**\n * Get this Sound's AudioContext instance for advanced use-cases.\n */\n get ctx(): AudioContext {\n return this._ctx;\n }\n\n /**\n * Get this Sound's AudioNode subclass instance for advanced use-cases.\n */\n get node(): AudioNode {\n return this._node;\n }\n\n /**\n * Get this Sound's Output node AudioNode instance for advanced use-cases.\n */\n get outputNode(): AudioNode {\n return this._outputNode;\n }\n\n /**\n * Get this Sound's MediaStream (eg, from microphone, if in use) instance for advanced use-cases. See [`Sound.input`](#link)\n */\n get stream(): MediaStream {\n return this._stream;\n }\n\n /**\n * Get this Sound's Audio element (if used) instance for advanced use-cases. See [`Sound.load`](#link).\n */\n get source(): HTMLMediaElement {\n return this._source;\n }\n\n /**\n * Get this Sound's AudioBuffer (if any) instance for advanced use-cases. See [`Sound.loadAsBuffer`](#link).\n */\n get buffer(): AudioBuffer {\n return this._buffer;\n }\n set buffer(b: AudioBuffer) {\n this._buffer = b;\n }\n\n /**\n * Get the type of input for this Sound instance. Either \"file\", \"input\", or \"gen\"\n */\n get type(): SoundType {\n return this._type;\n }\n\n /**\n * Indicate whether the sound is currently playing.\n */\n get playing(): boolean {\n return this._playing;\n }\n\n /**\n * A value between 0 to 1 to indicate playback progress. Returns 0 if the sound has no duration (eg, generated or input sounds).\n */\n get progress(): number {\n let dur = 0;\n let curr = 0;\n if (this._buffer) {\n dur = this._buffer.duration;\n // a timestamp of exactly 0 is valid (started when currentTime === timeAt)\n curr =\n this._timestamp !== undefined\n ? this._ctx.currentTime - this._timestamp\n : 0;\n } else if (this._source) {\n dur = this._source.duration;\n curr = this._source.currentTime;\n }\n return dur > 0 ? Num.clamp(curr / dur, 0, 1) : 0;\n }\n\n /**\n * Indicate whether the sound is ready to play. When loading from a file, this corresponds to a [\"canplaythrough\"](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState) event.\n * You can also use `this.source.addEventListener( 'canplaythrough', ...)` if needed. See also [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canplaythrough_event).\n */\n get playable(): boolean {\n if (this._type === \"input\" || this._type === \"gen\")\n return this._node !== undefined;\n return (\n !!this._buffer ||\n (this._source !== undefined && this._source.readyState === 4)\n );\n }\n\n /**\n * If an analyzer is added (see [`analyze`](#function_analyze) function), get the number of frequency bins in the analyzer. Returns 0 if no analyzer is added.\n */\n get binSize(): number {\n return this.analyzer ? this.analyzer.size : 0;\n }\n\n /**\n * Get the sample rate of the audio, for example, at 44100 hz.\n */\n get sampleRate(): number {\n return this._ctx.sampleRate;\n }\n\n /**\n * If the sound is generated, this sets and gets the frequency of the tone.\n */\n get frequency(): number {\n const osc = this._node as OscillatorNode;\n return this._type === \"gen\" && osc && osc.frequency\n ? osc.frequency.value\n : 0;\n }\n set frequency(f: number) {\n const osc = this._node as OscillatorNode;\n if (this._type === \"gen\" && osc && osc.frequency) osc.frequency.value = f;\n }\n\n /**\n * Get and set the volume of this sound. Default is 1. Values above 1 amplify the sound. Can be set before or during playback.\n */\n get volume(): number {\n return this._volume;\n }\n set volume(v: number) {\n this._volume = Math.max(0, v || 0); // `|| 0` also converts NaN\n if (this._gain) this._gain.gain.value = this._volume;\n }\n\n /**\n * Connect another AudioNode to this `Sound` instance's AudioNode. Using this function, you can extend the capabilities of this `Sound` instance for advanced use cases such as filtering. The connection is restored if a generated sound is restarted.\n * @param node another AudioNode\n */\n connect(node: AudioNode): this {\n this._connected.push(node);\n this._node.connect(node);\n return this;\n }\n\n /**\n * Sets the 'output' node for this Sound\n * This would typically be used after Sound.connect, if you are adding nodes\n * in your chain for filtering purposes.\n * @param outputNode The AudioNode that should connect to the AudioContext\n */\n setOutputNode(outputNode: AudioNode): this {\n this._outputNode = outputNode;\n return this;\n }\n\n /**\n * Removes the 'output' node added from setOutputNode\n * Note: if you start the Sound after calling this, it will play via the default node\n */\n removeOutputNode(): this {\n this._outputNode = null!;\n return this;\n }\n\n /**\n * Add an analyzer to this `Sound`. Calling it again replaces the existing analyzer.\n * @param size the number of frequency bins. Should be a power of 2.\n * @param minDb Optional minimum decibels (corresponds to `AnalyserNode.minDecibels`)\n * @param maxDb Optional maximum decibels (corresponds to `AnalyserNode.maxDecibels`)\n * @param smooth Optional smoothing value (corresponds to `AnalyserNode.smoothingTimeConstant`)\n */\n analyze(\n size: number = 256,\n minDb: number = -100,\n maxDb: number = -30,\n smooth: number = 0.8,\n ): this {\n if (this.analyzer && this._node) {\n try {\n this._node.disconnect(this.analyzer.node);\n } catch {\n // the previous analyzer node was not connected\n }\n }\n const a = this._ctx.createAnalyser();\n a.fftSize = size * 2;\n a.minDecibels = minDb;\n a.maxDecibels = maxDb;\n a.smoothingTimeConstant = smooth;\n this.analyzer = {\n node: a,\n size: a.frequencyBinCount,\n data: new Uint8Array(a.frequencyBinCount),\n };\n this._node.connect(this.analyzer.node);\n return this;\n }\n\n // Get either time-domain or frequency domain\n protected _domain(time: boolean): Uint8Array {\n if (this.analyzer) {\n if (time) {\n this.analyzer.node.getByteTimeDomainData(\n this.analyzer.data as Parameters<\n AnalyserNode[\"getByteTimeDomainData\"]\n >[0],\n );\n } else {\n this.analyzer.node.getByteFrequencyData(\n this.analyzer.data as Parameters<\n AnalyserNode[\"getByteFrequencyData\"]\n >[0],\n );\n }\n return this.analyzer.data;\n }\n return new Uint8Array(0);\n }\n\n // Map domain data to another range, reusing the Pts in `out` when provided\n protected _domainTo(\n time: boolean,\n size: PtLike,\n position: PtLike = [0, 0],\n trim = [0, 0],\n out?: Group,\n ): Group {\n const data = time ? this.timeDomain() : this.freqDomain();\n const g = out || new Group();\n const len = data.length - trim[1];\n const count = Math.max(0, len - trim[0]);\n if (g.length > count) g.length = count;\n for (let i = trim[0], j = 0; i < len; i++, j++) {\n const x = position[0] + (size[0] * i) / len;\n const y = position[1] + (size[1] * data[i]) / 255;\n const p = g[j];\n if (p && p.length >= 2) {\n p[0] = x;\n p[1] = y;\n } else {\n g[j] = new Pt(x, y);\n }\n }\n return g;\n }\n\n /**\n * Get the raw time-domain data from analyzer as unsigned 8-bit integers. An analyzer must be added before calling this function (See [analyze](#function_analyze) function).\n */\n timeDomain(): Uint8Array {\n return this._domain(true);\n }\n\n /**\n * Map the time-domain data from analyzer to a range. An analyzer must be added before calling this function (See [analyze](#function_analyze) function).\n * @param size map each data point `[index, value]` to `[width, height]`\n * @param position Optionally, set a starting `[x, y]` position. Default is `[0, 0]`\n * @param trim Optionally, trim the start and end values by `[startTrim, data.length-endTrim]`\n * @param out Optionally, provide a `Group` (usually one returned by a previous call) whose Pts will be reused instead of allocating new ones — recommended when calling once per frame\n * @returns a Group containing the mapped values\n * @example form.point( s.timeDomainTo( space.size ) )\n */\n timeDomainTo(\n size: PtLike,\n position: PtLike = [0, 0],\n trim = [0, 0],\n out?: Group,\n ): Group {\n return this._domainTo(true, size, position, trim, out);\n }\n\n /**\n * Get the raw frequency-domain data from analyzer as unsigned 8-bit integers. An analyzer must be added before calling this function (See [analyze](#function_analyze) function).\n */\n freqDomain(): Uint8Array {\n return this._domain(false);\n }\n\n /**\n * Map the frequency-domain data from analyzer to a range. An analyzer must be added before calling this function (See [analyze](#function_analyze) function).\n * @param size map each data point `[index, value]` to `[width, height]`\n * @param position Optionally, set a starting `[x, y]` position. Default is `[0, 0]`\n * @param trim Optionally, trim the start and end values by `[startTrim, data.length-endTrim]`\n * @param out Optionally, provide a `Group` (usually one returned by a previous call) whose Pts will be reused instead of allocating new ones — recommended when calling once per frame\n * @returns a Group containing the mapped values\n * @example `form.point( s.freqDomainTo( space.size ) )`\n */\n freqDomainTo(\n size: PtLike,\n position: PtLike = [0, 0],\n trim = [0, 0],\n out?: Group,\n ): Group {\n return this._domainTo(false, size, position, trim, out);\n }\n\n /**\n * Stop playing and disconnect the AudioNode.\n */\n reset(): this {\n this.stop();\n if (this._node) this._node.disconnect();\n if (this._outputNode) this._outputNode.disconnect();\n return this;\n }\n\n // Get the gain node for volume control, creating and connecting it on first use\n protected _getGain(): GainNode {\n if (!this._gain) {\n this._gain = this._ctx.createGain();\n this._gain.gain.value = this._volume;\n this._gain.connect(this._ctx.destination);\n }\n return this._gain;\n }\n\n /**\n * Start playing. Internally this connects the `AudioNode` to `AudioContext`'s destination.\n * Calling `start( timeAt )` while a file or buffer sound is playing seeks to that time; a generated sound that is already playing is unaffected.\n * @param timeAt optional parameter to play from a specific time, in seconds\n */\n start(timeAt: number = 0): this {\n if (this._ctx.state === \"suspended\") this._ctx.resume();\n\n if (this._type === \"file\") {\n if (this._buffer) {\n // An AudioBufferSourceNode can only start once; re-create it for\n // replay, seek-while-playing, or when only the buffer was assigned\n if (this._playing || this._bufferPlayed || !this._node) {\n if (this._playing && this.progress < 1) {\n (this._node as AudioBufferSourceNode).stop();\n }\n this.createBuffer();\n }\n (this._node as AudioBufferSourceNode).start(0, timeAt);\n this._bufferPlayed = true;\n this._timestamp = this._ctx.currentTime - timeAt;\n } else {\n if (timeAt > 0) this._source.currentTime = timeAt;\n const played = this._source.play();\n if (played && played.catch) {\n played.catch(() => {\n // eg, autoplay was blocked — but only if a later start hasn't succeeded\n if (this._source.paused) this._playing = false;\n });\n }\n }\n } else if (this._type === \"gen\" && this._generated) {\n // restarting while playing would orphan the old oscillator, which keeps sounding\n if (this._playing) return this;\n const osc = this._node as OscillatorNode;\n this._gen(\n osc.type,\n osc.type === \"custom\" ? this._wave : osc.frequency.value,\n );\n (this._node as OscillatorNode).start();\n }\n\n // restore analysis and filter chains; duplicate connects are no-ops\n if (this.analyzer) this._node.connect(this.analyzer.node);\n for (const n of this._connected) this._node.connect(n);\n\n (this._outputNode || this._node).connect(this._getGain());\n this._playing = true;\n return this;\n }\n\n /**\n * Stop playing. Internally this also disconnects the `AudioNode` from `AudioContext`'s destination. Calling `stop` when the sound is not playing has no effect.\n */\n stop(): this {\n if (!this._playing) return this;\n (this._outputNode || this._node).disconnect(this._gain);\n\n if (this._type === \"file\") {\n if (this._buffer) {\n // Safari throws InvalidState error if stop() is called after finished playing\n if (this.progress < 1) (this._node as AudioBufferSourceNode).stop();\n } else {\n this._source.pause();\n }\n } else if (this._type === \"gen\") {\n if (this._generated) (this._node as OscillatorNode).stop();\n } else if (this._type === \"input\" && this._stream) {\n // an input created from a node without its MediaStream has no tracks to stop\n this._stream.getAudioTracks().forEach((track) => track.stop());\n }\n\n this._playing = false;\n return this;\n }\n\n /**\n * Toggle between `start` and `stop`.\n */\n toggle(): this {\n if (this._playing) {\n this.stop();\n } else {\n this.start();\n }\n return this;\n }\n\n /**\n * Stop playing and disconnect all nodes (including analyzer and volume), and release stream, source, and buffer references.\n * The instance should not be used after calling this. Note that this never closes an `AudioContext`: the shared context lives for the page, and a context you provided is yours to close.\n */\n dispose(): this {\n // Input tracks are live as soon as they are acquired, even without start().\n if (!this._playing && this._stream) {\n this._stream.getAudioTracks().forEach((track) => track.stop());\n }\n this.reset();\n if (this.analyzer) {\n this.analyzer.node.disconnect();\n this.analyzer = undefined!;\n }\n if (this._gain) {\n this._gain.disconnect();\n this._gain = undefined!;\n }\n this._connected = [];\n this._stream = undefined!;\n this._source = undefined!;\n this._buffer = undefined!;\n return this;\n }\n}\n","import * as Canvas from \"./Canvas\";\nimport * as Create from \"./Create\";\nimport * as Form from \"./Form\";\nimport * as LinearAlgebra from \"./LinearAlgebra\";\nimport * as Num from \"./Num\";\nimport * as Op from \"./Op\";\nimport * as Pt from \"./Pt\";\nimport * as Space from \"./Space\";\nimport * as Color from \"./Color\";\nimport * as Util from \"./Util\";\nimport * as Dom from \"./Dom\";\nimport * as Svg from \"./Svg\";\nimport * as Typography from \"./Typography\";\nimport * as Physics from \"./Physics\";\nimport * as UI from \"./UI\";\nimport * as Play from \"./Play\";\nimport * as Image from \"./Image\";\nimport * as Types from \"./Types\";\n\ndeclare global {\n // the browser bundle mounts the whole library on globalThis.Pts\n\n var Pts: Record<string, any>;\n}\n\nglobalThis.Pts = {\n ...Canvas,\n ...Create,\n ...Form,\n ...LinearAlgebra,\n ...Num,\n ...Op,\n ...Pt,\n ...Space,\n ...Color,\n ...Util,\n ...Dom,\n ...Svg,\n ...Typography,\n ...Physics,\n ...UI,\n ...Play,\n ...Image,\n};\n\n// A function to switch scope for Pts library. eg, Pts.namespace( window );\nglobalThis.Pts.namespace = (scope: any) => {\n let lib = globalThis.Pts;\n for (let k in lib) {\n if (k != \"namespace\") {\n scope[k] = lib[k];\n }\n }\n};\n\nglobalThis.Pts.quickStart = (id: string | Element, bg: string = \"#9ab\") => {\n if (!window) return;\n\n let s: any = globalThis;\n globalThis.Pts.namespace(s);\n\n // pick the rendering backend from the mount element: an <svg> element (or a\n // container holding one) gets an SVGSpace, anything else a CanvasSpace —\n // so a sketch can swap renderers by changing only its HTML\n // Preserve CanvasSpace's bare-ID shorthand for both rendering backends.\n const mount =\n typeof id === \"string\" && id[0] !== \"#\" && id[0] !== \".\" ? `#${id}` : id;\n const elem =\n typeof mount === \"string\" ? document.querySelector(mount) : mount;\n const isSVG =\n elem &&\n ((elem as Element).nodeName.toLowerCase() === \"svg\" ||\n !!(elem as Element).querySelector(\":scope > svg\"));\n\n s.space = isSVG\n ? new Svg.SVGSpace(mount).setup({ bgcolor: bg, resize: true })\n : new Canvas.CanvasSpace(mount).setup({\n bgcolor: bg,\n resize: true,\n retina: true,\n });\n s.form = s.space.getForm();\n\n return function (animate = null, start = null, action = null, resize = null) {\n s.space.add({\n start: start,\n animate: animate,\n resize: resize,\n action: action,\n });\n\n s.space.bindMouse().bindTouch().play();\n };\n};\n"],"mappings":"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"}