@weasel-js/geom 1.7.0 → 1.7.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/README.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # @weasel-js/geom
2
2
 
3
- Pure 2D geometry kernel for @weasel-js/core: affine, box, curve, polyline. Dependency-free core; polygon booleans in the ./booleans subpath.
3
+ Pure 2D geometry kernel for @weasel-js/core: affine, box, curve, polyline, the
4
+ `Path` command stream and the math over it (builders, SVG `d` parsing, bounds,
5
+ transforms, hit-testing, sampling, curve fitting), and easing curves.
6
+ Dependency-free core. Subpaths:
7
+
8
+ - `./curves` — alternate curve representations (cubic and quadratic Bezier, NURBS, Spiro)
9
+ - `./tessellate` — fill tessellation, polylines and trimming; needs the optional peer `earcut`
10
+ - `./booleans` — polygon booleans and path splitting; needs the optional peer `polygon-clipping`
11
+ - `./3d` — vectors, quaternions, 4x4 matrices and ray intersection
4
12
 
5
13
  Part of [weasel](https://github.com/orochi235/weasel), a domain-agnostic 2D
6
14
  scene-graph canvas kit for React. See the
@@ -17,6 +25,8 @@ npm install @weasel-js/geom
17
25
  ```ts
18
26
  import { /* … */ } from '@weasel-js/geom';
19
27
  import { /* … */ } from '@weasel-js/geom/booleans';
28
+ import { /* … */ } from '@weasel-js/geom/curves';
29
+ import { /* … */ } from '@weasel-js/geom/tessellate';
20
30
  ```
21
31
 
22
32
  ## License
@@ -15,18 +15,27 @@ interface Vec3 {
15
15
  }
16
16
  /** `[x, y, z, w]`, w last — the layout three.js and glMatrix both use. */
17
17
  type Quat = readonly [number, number, number, number];
18
+ /** `a + b`. */
18
19
  declare function add(a: Vec3, b: Vec3): Vec3;
20
+ /** `a - b`. */
19
21
  declare function sub(a: Vec3, b: Vec3): Vec3;
22
+ /** `a` multiplied by the scalar `k`. */
20
23
  declare function scale(a: Vec3, k: number): Vec3;
24
+ /** Dot product. */
21
25
  declare function dot(a: Vec3, b: Vec3): number;
26
+ /** Cross product `a × b`. */
22
27
  declare function cross(a: Vec3, b: Vec3): Vec3;
23
28
  /** Squared length. Compare distances with this and skip the square root. */
24
29
  declare function len2(a: Vec3): number;
30
+ /** Euclidean length. */
25
31
  declare function len(a: Vec3): number;
26
32
  /** A vector with no length, or no finite one, normalizes to the zero vector
27
33
  * rather than to `NaN`. Every other vector keeps its direction, however short. */
28
34
  declare function normalize(a: Vec3): Vec3;
35
+ /** The quaternion for no rotation, `[0, 0, 0, 1]`. */
29
36
  declare function quatIdentity(): Quat;
37
+ /** Rotation by `angle` radians about `axis`, which must be nonzero but need
38
+ * not be unit length. */
30
39
  declare function quatFromAxisAngle(axis: Vec3, angle: number): Quat;
31
40
 
32
41
  /** 4x4 matrices in GL's column-major order: element (row `r`, column `c`) is
@@ -35,7 +44,9 @@ declare function quatFromAxisAngle(axis: Vec3, angle: number): Quat;
35
44
 
36
45
  /** 16 numbers, column-major. */
37
46
  type Mat4 = readonly number[];
47
+ /** The identity matrix. */
38
48
  declare function identity(): Mat4;
49
+ /** The product `a · b`: applied to a point, `b` acts first. */
39
50
  declare function multiply(a: Mat4, b: Mat4): Mat4;
40
51
  /** `[x, y, z, w]` in whatever space `m` maps into — clip space, when `m` is a view-projection. */
41
52
  declare function transformPoint4(m: Mat4, p: Vec3): readonly [number, number, number, number];
@@ -45,7 +56,11 @@ declare function transformPoint(m: Mat4, p: Vec3): Vec3;
45
56
  /** Inverse, or null when the matrix is singular, non-finite, or too
46
57
  * ill-conditioned to invert meaningfully at its own scale. */
47
58
  declare function invert(m: Mat4): Mat4 | null;
59
+ /** Translation · rotation · scale: the matrix that scales a point, then
60
+ * rotates it, then moves it by `position`. */
48
61
  declare function compose(position: Vec3, rotation: Quat, scaling: Vec3): Mat4;
62
+ /** A GL-convention projection: vertical field of view `fovY` in radians, the
63
+ * camera looking down −z, and `near`..`far` mapped to clip z −1..1. */
49
64
  declare function perspective(fovY: number, aspect: number, near: number, far: number): Mat4;
50
65
  /** A view from `eye` toward `target`. With the eye on its target, or `up`
51
66
  * parallel to the view to within rounding, the view has no orientation and
@@ -54,6 +69,8 @@ declare function lookAt(eye: Vec3, target: Vec3, up: Vec3): Mat4;
54
69
 
55
70
  /** Rays, axis-aligned boxes, and the intersections picking is built from. */
56
71
 
72
+ /** A ray from `origin` along `direction`, which need not be unit length: the
73
+ * `t` the intersections return is in multiples of it. */
57
74
  interface Ray {
58
75
  origin: Vec3;
59
76
  direction: Vec3;
package/dist/3d/index.js CHANGED
@@ -1,5 +1,6 @@
1
- import { PORT_REACH, SINGULAR_RATIO, portControls, cubicAt } from '../chunk-3GFNUO4N.js';
2
- export { PORT_REACH } from '../chunk-3GFNUO4N.js';
1
+ import { PORT_REACH, portControls, cubicAt } from '../chunk-TXEGHCJ4.js';
2
+ export { PORT_REACH } from '../chunk-TXEGHCJ4.js';
3
+ import { SINGULAR_RATIO } from '../chunk-7ROQRYOA.js';
3
4
 
4
5
  // src/3d/vec3.ts
5
6
  function add(a, b) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/3d/vec3.ts","../../src/3d/mat4.ts","../../src/3d/ray3.ts","../../src/3d/portCurve3.ts"],"names":["scale","portControls","cubicAt"],"mappings":"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","file":"index.js","sourcesContent":["/** Three-component vectors and unit quaternions. `Vec3`'s fields are readonly:\n * a pose stored in a history snapshot must not be writable through the value\n * handed to a renderer.\n *\n * Named fields rather than a tuple, matching `Vec2` one tier up, so a\n * consumer writing both dimensions says `p.x` in each. `Quat` stays a tuple —\n * it is not a point, and `[x, y, z, w]` is the layout three.js and glMatrix\n * both use. */\n\nexport interface Vec3 {\n readonly x: number;\n readonly y: number;\n readonly z: number;\n}\n\n/** `[x, y, z, w]`, w last — the layout three.js and glMatrix both use. */\nexport type Quat = readonly [number, number, number, number];\n\nexport function add(a: Vec3, b: Vec3): Vec3 {\n return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };\n}\n\nexport function sub(a: Vec3, b: Vec3): Vec3 {\n return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };\n}\n\nexport function scale(a: Vec3, k: number): Vec3 {\n return { x: a.x * k, y: a.y * k, z: a.z * k };\n}\n\nexport function dot(a: Vec3, b: Vec3): number {\n return a.x * b.x + a.y * b.y + a.z * b.z;\n}\n\nexport function cross(a: Vec3, b: Vec3): Vec3 {\n return {\n x: a.y * b.z - a.z * b.y,\n y: a.z * b.x - a.x * b.z,\n z: a.x * b.y - a.y * b.x,\n };\n}\n\n/** Squared length. Compare distances with this and skip the square root. */\nexport function len2(a: Vec3): number {\n return dot(a, a);\n}\n\nexport function len(a: Vec3): number {\n return Math.sqrt(len2(a));\n}\n\n/** A vector with no length, or no finite one, normalizes to the zero vector\n * rather than to `NaN`. Every other vector keeps its direction, however short. */\nexport function normalize(a: Vec3): Vec3 {\n const l = len(a);\n return l > 0 && l < Infinity ? scale(a, 1 / l) : { x: 0, y: 0, z: 0 };\n}\n\n/** `Vec3` from loose components — the shape `Mat4`'s row math produces. */\nexport function vec3(x: number, y: number, z: number): Vec3 {\n return { x, y, z };\n}\n\nexport function quatIdentity(): Quat {\n return [0, 0, 0, 1];\n}\n\nexport function quatFromAxisAngle(axis: Vec3, angle: number): Quat {\n const a = normalize(axis);\n const half = angle / 2;\n const s = Math.sin(half);\n return [a.x * s, a.y * s, a.z * s, Math.cos(half)];\n}\n","/** 4x4 matrices in GL's column-major order: element (row `r`, column `c`) is\n * `m[c * 4 + r]`, which is the layout `gl.uniformMatrix4fv` reads without a\n * transpose and the one three.js `toArray()` emits. */\n\nimport { SINGULAR_RATIO } from '../scalar';\nimport { cross, dot, len, normalize, sub, vec3, type Quat, type Vec3 } from './vec3';\n\n/** 16 numbers, column-major. */\nexport type Mat4 = readonly number[];\n\nexport function identity(): Mat4 {\n return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];\n}\n\nexport function multiply(a: Mat4, b: Mat4): Mat4 {\n const out = new Array<number>(16);\n for (let c = 0; c < 4; c++) {\n for (let r = 0; r < 4; r++) {\n let sum = 0;\n for (let k = 0; k < 4; k++) sum += a[k * 4 + r] * b[c * 4 + k];\n out[c * 4 + r] = sum;\n }\n }\n return out;\n}\n\n/** `[x, y, z, w]` in whatever space `m` maps into — clip space, when `m` is a view-projection. */\nexport function transformPoint4(\n m: Mat4,\n p: Vec3,\n): readonly [number, number, number, number] {\n const { x, y, z } = p;\n return [\n m[0] * x + m[4] * y + m[8] * z + m[12],\n m[1] * x + m[5] * y + m[9] * z + m[13],\n m[2] * x + m[6] * y + m[10] * z + m[14],\n m[3] * x + m[7] * y + m[11] * z + m[15],\n ];\n}\n\n/** `transformPoint4` divided through by w, however small. A point on the eye\n * plane (w = 0) comes back non-finite. */\nexport function transformPoint(m: Mat4, p: Vec3): Vec3 {\n const [x, y, z, w] = transformPoint4(m, p);\n if (w === 1) return vec3(x, y, z);\n return vec3(x / w, y / w, z / w);\n}\n\n/** Inverse, or null when the matrix is singular, non-finite, or too\n * ill-conditioned to invert meaningfully at its own scale. */\nexport function invert(m: Mat4): Mat4 | null {\n const [\n m00, m01, m02, m03,\n m10, m11, m12, m13,\n m20, m21, m22, m23,\n m30, m31, m32, m33,\n ] = m;\n\n const b00 = m00 * m11 - m01 * m10;\n const b01 = m00 * m12 - m02 * m10;\n const b02 = m00 * m13 - m03 * m10;\n const b03 = m01 * m12 - m02 * m11;\n const b04 = m01 * m13 - m03 * m11;\n const b05 = m02 * m13 - m03 * m12;\n const b06 = m20 * m31 - m21 * m30;\n const b07 = m20 * m32 - m22 * m30;\n const b08 = m20 * m33 - m23 * m30;\n const b09 = m21 * m32 - m22 * m31;\n const b10 = m21 * m33 - m23 * m31;\n const b11 = m22 * m33 - m23 * m32;\n\n const det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n // Hadamard: |det| never exceeds the product of the column lengths, so the\n // ratio is a volume in [0, 1] that no per-column scale can shrink.\n const scale =\n Math.sqrt(m00 * m00 + m01 * m01 + m02 * m02 + m03 * m03) *\n Math.sqrt(m10 * m10 + m11 * m11 + m12 * m12 + m13 * m13) *\n Math.sqrt(m20 * m20 + m21 * m21 + m22 * m22 + m23 * m23) *\n Math.sqrt(m30 * m30 + m31 * m31 + m32 * m32 + m33 * m33);\n // Negated so a non-finite determinant falls out as singular.\n if (!(Math.abs(det) > SINGULAR_RATIO * scale)) return null;\n const d = 1 / det;\n\n return [\n (m11 * b11 - m12 * b10 + m13 * b09) * d,\n (m02 * b10 - m01 * b11 - m03 * b09) * d,\n (m31 * b05 - m32 * b04 + m33 * b03) * d,\n (m22 * b04 - m21 * b05 - m23 * b03) * d,\n (m12 * b08 - m10 * b11 - m13 * b07) * d,\n (m00 * b11 - m02 * b08 + m03 * b07) * d,\n (m32 * b02 - m30 * b05 - m33 * b01) * d,\n (m20 * b05 - m22 * b02 + m23 * b01) * d,\n (m10 * b10 - m11 * b08 + m13 * b06) * d,\n (m01 * b08 - m00 * b10 - m03 * b06) * d,\n (m30 * b04 - m31 * b02 + m33 * b00) * d,\n (m21 * b02 - m20 * b04 - m23 * b00) * d,\n (m11 * b07 - m10 * b09 - m12 * b06) * d,\n (m00 * b09 - m01 * b07 + m02 * b06) * d,\n (m31 * b01 - m30 * b03 - m32 * b00) * d,\n (m20 * b03 - m21 * b01 + m22 * b00) * d,\n ];\n}\n\nexport function compose(position: Vec3, rotation: Quat, scaling: Vec3): Mat4 {\n const [x, y, z, w] = rotation;\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n const { x: sx, y: sy, z: sz } = scaling;\n\n return [\n (1 - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n (xy - wz) * sy, (1 - (xx + zz)) * sy, (yz + wx) * sy, 0,\n (xz + wy) * sz, (yz - wx) * sz, (1 - (xx + yy)) * sz, 0,\n position.x, position.y, position.z, 1,\n ];\n}\n\nexport function perspective(fovY: number, aspect: number, near: number, far: number): Mat4 {\n const f = 1 / Math.tan(fovY / 2);\n const range = near - far;\n return [\n f / aspect, 0, 0, 0,\n 0, f, 0, 0,\n 0, 0, (far + near) / range, -1,\n 0, 0, (2 * far * near) / range, 0,\n ];\n}\n\n/** A view from `eye` toward `target`. With the eye on its target, or `up`\n * parallel to the view to within rounding, the view has no orientation and\n * the result is singular. */\nexport function lookAt(eye: Vec3, target: Vec3, up: Vec3): Mat4 {\n const back = normalize(sub(eye, target));\n const side = cross(up, back);\n // |side| is |up| times the sine of the angle between up and the view.\n const right = len(side) > SINGULAR_RATIO * len(up) ? normalize(side) : vec3(0, 0, 0);\n const trueUp = cross(back, right);\n return [\n right.x, trueUp.x, back.x, 0,\n right.y, trueUp.y, back.y, 0,\n right.z, trueUp.z, back.z, 0,\n -dot(right, eye), -dot(trueUp, eye), -dot(back, eye), 1,\n ];\n}\n","/** Rays, axis-aligned boxes, and the intersections picking is built from. */\n\nimport { SINGULAR_RATIO } from '../scalar';\nimport { dot, len, type Vec3 } from './vec3';\nimport { transformPoint, type Mat4 } from './mat4';\n\nexport interface Ray {\n origin: Vec3;\n direction: Vec3;\n}\n\n/** An axis-aligned box. `min` is componentwise <= `max`. */\nexport interface Aabb {\n min: Vec3;\n max: Vec3;\n}\n\n/** Distance along the ray to the box, or null. A ray starting inside returns 0. */\nexport function intersectRayAabb(ray: Ray, min: Vec3, max: Vec3): number | null {\n let tMin = Number.NEGATIVE_INFINITY;\n let tMax = Number.POSITIVE_INFINITY;\n\n for (const axis of ['x', 'y', 'z'] as const) {\n const o = ray.origin[axis];\n const d = ray.direction[axis];\n // Any other direction, however short, divides to an honest (possibly infinite) t.\n if (d === 0) {\n if (o < min[axis] || o > max[axis]) return null;\n continue;\n }\n let t1 = (min[axis] - o) / d;\n let t2 = (max[axis] - o) / d;\n if (t1 > t2) [t1, t2] = [t2, t1];\n if (t1 > tMin) tMin = t1;\n if (t2 < tMax) tMax = t2;\n if (tMin > tMax) return null;\n }\n\n if (tMax < 0) return null;\n return tMin < 0 ? 0 : tMin;\n}\n\n/** Plane is `dot(normal, p) === offset`. Null when the ray runs parallel to the\n * plane to within rounding, or points away from it. */\nexport function intersectRayPlane(ray: Ray, normal: Vec3, offset: number): number | null {\n const denom = dot(normal, ray.direction);\n if (!(Math.abs(denom) > SINGULAR_RATIO * len(normal) * len(ray.direction))) return null;\n const t = (offset - dot(normal, ray.origin)) / denom;\n return t < 0 ? null : t;\n}\n\n/**\n * The axis-aligned box enclosing `local` after `m`. All eight corners are\n * transformed and re-bounded, so a rotation widens the result rather than\n * rotating it — an AABB cannot represent an oriented box, and pretending\n * otherwise is how a hit test starts missing its own geometry.\n */\nexport function transformAabb(m: Mat4, local: Aabb): Aabb {\n let min: Vec3 = { x: Infinity, y: Infinity, z: Infinity };\n let max: Vec3 = { x: -Infinity, y: -Infinity, z: -Infinity };\n for (let i = 0; i < 8; i++) {\n const corner: Vec3 = {\n x: i & 1 ? local.max.x : local.min.x,\n y: i & 2 ? local.max.y : local.min.y,\n z: i & 4 ? local.max.z : local.min.z,\n };\n const p = transformPoint(m, corner);\n min = { x: Math.min(min.x, p.x), y: Math.min(min.y, p.y), z: Math.min(min.z, p.z) };\n max = { x: Math.max(max.x, p.x), y: Math.max(max.y, p.y), z: Math.max(max.z, p.z) };\n }\n return { min, max };\n}\n\n/** The box centred on `center` reaching `radius` along every axis. */\nexport function aabbAround(center: Vec3, radius: number): Aabb {\n return {\n min: { x: center.x - radius, y: center.y - radius, z: center.z - radius },\n max: { x: center.x + radius, y: center.y + radius, z: center.z + radius },\n };\n}\n","/**\n * The port-curve rule one dimension up, in `Vec3`. The rule itself lives in\n * `../portCurve`, stated once over components — this wrapper is types and\n * nothing else, so 2D and 3D cannot disagree about what the curve is.\n */\n\nimport { PORT_REACH, cubicAt as cubicAtN, portControls as portControlsN } from '../portCurve';\nimport type { Vec3 } from './vec3';\n\nexport { PORT_REACH };\n\nconst comps = (v: Vec3): [number, number, number] => [v.x, v.y, v.z];\nconst compsOrNull = (v: Vec3 | null | undefined) => (v == null ? v : comps(v));\nconst fromComps = (p: readonly number[]): Vec3 => ({ x: p[0]!, y: p[1]!, z: p[2]! });\n\n/** `[c1, c2]` for the cubic from `a` to `b`. A null normal falls back to a lerp\n * along the chord; see `../portCurve` for why the two ends differ. */\nexport function portControls(\n a: Vec3,\n b: Vec3,\n outNormal: Vec3 | null | undefined,\n inNormal: Vec3 | null | undefined,\n reach: number = PORT_REACH,\n): [Vec3, Vec3] {\n const [c1, c2] = portControlsN(\n comps(a),\n comps(b),\n compsOrNull(outNormal),\n compsOrNull(inNormal),\n reach,\n );\n return [fromComps(c1), fromComps(c2)];\n}\n\n/** A port curve sampled into `samples` points, excluding its start. */\nexport function portCurvePoints(\n a: Vec3,\n b: Vec3,\n outNormal: Vec3 | null | undefined,\n inNormal: Vec3 | null | undefined,\n samples: number,\n reach: number = PORT_REACH,\n): Vec3[] {\n const [c1, c2] = portControlsN(\n comps(a),\n comps(b),\n compsOrNull(outNormal),\n compsOrNull(inNormal),\n reach,\n );\n const out: Vec3[] = [];\n for (let s = 1; s <= samples; s++) {\n const p = cubicAtN(comps(a), c1, c2, comps(b), s / samples);\n out.push(fromComps(p));\n }\n return out;\n}\n\n/** A cubic evaluated at `t`. The 2D barrel's `cubicEvalAt`, one dimension up. */\nexport function cubicAt(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const p = cubicAtN(comps(p0), comps(p1), comps(p2), comps(p3), t);\n return fromComps(p);\n}\n"]}
1
+ {"version":3,"sources":["../../src/3d/vec3.ts","../../src/3d/mat4.ts","../../src/3d/ray3.ts","../../src/3d/portCurve3.ts"],"names":["scale","portControls","cubicAt"],"mappings":";;;;;AAmBO,SAAS,GAAA,CAAI,GAAS,CAAA,EAAe;AAC1C,EAAA,OAAO,EAAE,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,EAAE;AACpD;AAGO,SAAS,GAAA,CAAI,GAAS,CAAA,EAAe;AAC1C,EAAA,OAAO,EAAE,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,EAAE;AACpD;AAGO,SAAS,KAAA,CAAM,GAAS,CAAA,EAAiB;AAC9C,EAAA,OAAO,EAAE,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,CAAA,EAAG,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,CAAA,EAAG,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,CAAA,EAAE;AAC9C;AAGO,SAAS,GAAA,CAAI,GAAS,CAAA,EAAiB;AAC5C,EAAA,OAAO,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AACzC;AAGO,SAAS,KAAA,CAAM,GAAS,CAAA,EAAe;AAC5C,EAAA,OAAO;AAAA,IACL,GAAG,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,GAAI,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA;AAAA,IACvB,GAAG,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,GAAI,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA;AAAA,IACvB,GAAG,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,GAAI,CAAA,CAAE,IAAI,CAAA,CAAE;AAAA,GACzB;AACF;AAGO,SAAS,KAAK,CAAA,EAAiB;AACpC,EAAA,OAAO,GAAA,CAAI,GAAG,CAAC,CAAA;AACjB;AAGO,SAAS,IAAI,CAAA,EAAiB;AACnC,EAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA;AAC1B;AAIO,SAAS,UAAU,CAAA,EAAe;AACvC,EAAA,MAAM,CAAA,GAAI,IAAI,CAAC,CAAA;AACf,EAAA,OAAO,CAAA,GAAI,CAAA,IAAK,CAAA,GAAI,QAAA,GAAW,MAAM,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA,GAAI,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AACtE;AAGO,SAAS,IAAA,CAAK,CAAA,EAAW,CAAA,EAAW,CAAA,EAAiB;AAC1D,EAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE;AACnB;AAGO,SAAS,YAAA,GAAqB;AACnC,EAAA,OAAO,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AACpB;AAIO,SAAS,iBAAA,CAAkB,MAAY,KAAA,EAAqB;AACjE,EAAA,MAAM,CAAA,GAAI,UAAU,IAAI,CAAA;AACxB,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AACrB,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA;AACvB,EAAA,OAAO,CAAC,CAAA,CAAE,CAAA,GAAI,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,CAAA,EAAG,CAAA,CAAE,CAAA,GAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,IAAI,CAAC,CAAA;AACnD;;;ACtEO,SAAS,QAAA,GAAiB;AAC/B,EAAA,OAAO,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAC,CAAA;AACxD;AAGO,SAAS,QAAA,CAAS,GAAS,CAAA,EAAe;AAC/C,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAc,EAAE,CAAA;AAChC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,MAAA,IAAI,GAAA,GAAM,CAAA;AACV,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,KAAK,GAAA,IAAO,CAAA,CAAE,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,IAAI,CAAC,CAAA;AAC7D,MAAA,GAAA,CAAI,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,GAAI,GAAA;AAAA,IACnB;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAGO,SAAS,eAAA,CACd,GACA,CAAA,EAC2C;AAC3C,EAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE,GAAI,CAAA;AACpB,EAAA,OAAO;AAAA,IACL,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAAI,EAAE,EAAE,CAAA;AAAA,IACrC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAAI,EAAE,EAAE,CAAA;AAAA,IACrC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,EAAE,CAAA,GAAI,CAAA,GAAI,EAAE,EAAE,CAAA;AAAA,IACtC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,GAAI,CAAA,CAAE,EAAE,CAAA,GAAI,CAAA,GAAI,EAAE,EAAE;AAAA,GACxC;AACF;AAIO,SAAS,cAAA,CAAe,GAAS,CAAA,EAAe;AACrD,EAAA,MAAM,CAAC,GAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,eAAA,CAAgB,GAAG,CAAC,CAAA;AACzC,EAAA,IAAI,MAAM,CAAA,EAAG,OAAO,IAAA,CAAK,CAAA,EAAG,GAAG,CAAC,CAAA;AAChC,EAAA,OAAO,KAAK,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,IAAI,CAAC,CAAA;AACjC;AAIO,SAAS,OAAO,CAAA,EAAsB;AAC3C,EAAA,MAAM;AAAA,IACJ,GAAA;AAAA,IAAK,GAAA;AAAA,IAAK,GAAA;AAAA,IAAK,GAAA;AAAA,IACf,GAAA;AAAA,IAAK,GAAA;AAAA,IAAK,GAAA;AAAA,IAAK,GAAA;AAAA,IACf,GAAA;AAAA,IAAK,GAAA;AAAA,IAAK,GAAA;AAAA,IAAK,GAAA;AAAA,IACf,GAAA;AAAA,IAAK,GAAA;AAAA,IAAK,GAAA;AAAA,IAAK;AAAA,GACjB,GAAI,CAAA;AAEJ,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAE9B,EAAA,MAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA;AAG9E,EAAA,MAAMA,SACJ,IAAA,CAAK,IAAA,CAAK,MAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAG,CAAA,GACvD,KAAK,IAAA,CAAK,GAAA,GAAM,MAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,GAAM,GAAA,GAAM,GAAG,CAAA,GACvD,IAAA,CAAK,KAAK,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,GAAM,GAAG,IACvD,IAAA,CAAK,IAAA,CAAK,MAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAG,CAAA;AAEzD,EAAA,IAAI,EAAE,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,GAAI,cAAA,GAAiBA,SAAQ,OAAO,IAAA;AACtD,EAAA,MAAM,IAAI,CAAA,GAAI,GAAA;AAEd,EAAA,OAAO;AAAA,IAAA,CACJ,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO,CAAA;AAAA,IAAA,CACrC,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,GAAA,GAAM,MAAM,GAAA,IAAO;AAAA,GACxC;AACF;AAIO,SAAS,OAAA,CAAQ,QAAA,EAAgB,QAAA,EAAgB,OAAA,EAAqB;AAC3E,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,QAAA;AACrB,EAAA,MAAM,KAAK,CAAA,GAAI,CAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,CAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,CAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,EAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,EAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,EAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,EAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,EAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,EAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,EAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,EAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,EAAA;AACf,EAAA,MAAM,EAAE,CAAA,EAAG,EAAA,EAAI,GAAG,EAAA,EAAI,CAAA,EAAG,IAAG,GAAI,OAAA;AAEhC,EAAA,OAAO;AAAA,IAAA,CACJ,CAAA,IAAK,KAAK,EAAA,CAAA,IAAO,EAAA;AAAA,IAAA,CAAK,KAAK,EAAA,IAAM,EAAA;AAAA,IAAA,CAAK,KAAK,EAAA,IAAM,EAAA;AAAA,IAAI,CAAA;AAAA,IAAA,CACrD,KAAK,EAAA,IAAM,EAAA;AAAA,IAAA,CAAK,CAAA,IAAK,KAAK,EAAA,CAAA,IAAO,EAAA;AAAA,IAAA,CAAK,KAAK,EAAA,IAAM,EAAA;AAAA,IAAI,CAAA;AAAA,IAAA,CACrD,KAAK,EAAA,IAAM,EAAA;AAAA,IAAA,CAAK,KAAK,EAAA,IAAM,EAAA;AAAA,IAAA,CAAK,CAAA,IAAK,KAAK,EAAA,CAAA,IAAO,EAAA;AAAA,IAAI,CAAA;AAAA,IACtD,QAAA,CAAS,CAAA;AAAA,IAAG,QAAA,CAAS,CAAA;AAAA,IAAG,QAAA,CAAS,CAAA;AAAA,IAAG;AAAA,GACtC;AACF;AAIO,SAAS,WAAA,CAAY,IAAA,EAAc,MAAA,EAAgB,IAAA,EAAc,GAAA,EAAmB;AACzF,EAAA,MAAM,CAAA,GAAI,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,OAAO,CAAC,CAAA;AAC/B,EAAA,MAAM,QAAQ,IAAA,GAAO,GAAA;AACrB,EAAA,OAAO;AAAA,IACL,CAAA,GAAI,MAAA;AAAA,IAAQ,CAAA;AAAA,IAAG,CAAA;AAAA,IAAG,CAAA;AAAA,IAClB,CAAA;AAAA,IAAG,CAAA;AAAA,IAAG,CAAA;AAAA,IAAG,CAAA;AAAA,IACT,CAAA;AAAA,IAAG,CAAA;AAAA,IAAA,CAAI,MAAM,IAAA,IAAQ,KAAA;AAAA,IAAO,EAAA;AAAA,IAC5B,CAAA;AAAA,IAAG,CAAA;AAAA,IAAI,CAAA,GAAI,MAAM,IAAA,GAAQ,KAAA;AAAA,IAAO;AAAA,GAClC;AACF;AAKO,SAAS,MAAA,CAAO,GAAA,EAAW,MAAA,EAAc,EAAA,EAAgB;AAC9D,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,GAAA,CAAI,GAAA,EAAK,MAAM,CAAC,CAAA;AACvC,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,EAAA,EAAI,IAAI,CAAA;AAE3B,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,IAAI,CAAA,GAAI,iBAAiB,GAAA,CAAI,EAAE,CAAA,GAAI,SAAA,CAAU,IAAI,CAAA,GAAI,IAAA,CAAK,CAAA,EAAG,GAAG,CAAC,CAAA;AACnF,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,IAAA,EAAM,KAAK,CAAA;AAChC,EAAA,OAAO;AAAA,IACL,KAAA,CAAM,CAAA;AAAA,IAAG,MAAA,CAAO,CAAA;AAAA,IAAG,IAAA,CAAK,CAAA;AAAA,IAAG,CAAA;AAAA,IAC3B,KAAA,CAAM,CAAA;AAAA,IAAG,MAAA,CAAO,CAAA;AAAA,IAAG,IAAA,CAAK,CAAA;AAAA,IAAG,CAAA;AAAA,IAC3B,KAAA,CAAM,CAAA;AAAA,IAAG,MAAA,CAAO,CAAA;AAAA,IAAG,IAAA,CAAK,CAAA;AAAA,IAAG,CAAA;AAAA,IAC3B,CAAC,GAAA,CAAI,KAAA,EAAO,GAAG,CAAA;AAAA,IAAG,CAAC,GAAA,CAAI,MAAA,EAAQ,GAAG,CAAA;AAAA,IAAG,CAAC,GAAA,CAAI,IAAA,EAAM,GAAG,CAAA;AAAA,IAAG;AAAA,GACxD;AACF;;;AC3IO,SAAS,gBAAA,CAAiB,GAAA,EAAU,GAAA,EAAW,GAAA,EAA0B;AAC9E,EAAA,IAAI,OAAO,MAAA,CAAO,iBAAA;AAClB,EAAA,IAAI,OAAO,MAAA,CAAO,iBAAA;AAElB,EAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAY;AAC3C,IAAA,MAAM,CAAA,GAAI,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA;AACzB,IAAA,MAAM,CAAA,GAAI,GAAA,CAAI,SAAA,CAAU,IAAI,CAAA;AAE5B,IAAA,IAAI,MAAM,CAAA,EAAG;AACX,MAAA,IAAI,CAAA,GAAI,IAAI,IAAI,CAAA,IAAK,IAAI,GAAA,CAAI,IAAI,GAAG,OAAO,IAAA;AAC3C,MAAA;AAAA,IACF;AACA,IAAA,IAAI,EAAA,GAAA,CAAM,GAAA,CAAI,IAAI,CAAA,GAAI,CAAA,IAAK,CAAA;AAC3B,IAAA,IAAI,EAAA,GAAA,CAAM,GAAA,CAAI,IAAI,CAAA,GAAI,CAAA,IAAK,CAAA;AAC3B,IAAA,IAAI,EAAA,GAAK,IAAI,CAAC,EAAA,EAAI,EAAE,CAAA,GAAI,CAAC,IAAI,EAAE,CAAA;AAC/B,IAAA,IAAI,EAAA,GAAK,MAAM,IAAA,GAAO,EAAA;AACtB,IAAA,IAAI,EAAA,GAAK,MAAM,IAAA,GAAO,EAAA;AACtB,IAAA,IAAI,IAAA,GAAO,MAAM,OAAO,IAAA;AAAA,EAC1B;AAEA,EAAA,IAAI,IAAA,GAAO,GAAG,OAAO,IAAA;AACrB,EAAA,OAAO,IAAA,GAAO,IAAI,CAAA,GAAI,IAAA;AACxB;AAIO,SAAS,iBAAA,CAAkB,GAAA,EAAU,MAAA,EAAc,MAAA,EAA+B;AACvF,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,MAAA,EAAQ,GAAA,CAAI,SAAS,CAAA;AACvC,EAAA,IAAI,EAAE,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,cAAA,GAAiB,GAAA,CAAI,MAAM,CAAA,GAAI,GAAA,CAAI,GAAA,CAAI,SAAS,IAAI,OAAO,IAAA;AACnF,EAAA,MAAM,KAAK,MAAA,GAAS,GAAA,CAAI,MAAA,EAAQ,GAAA,CAAI,MAAM,CAAA,IAAK,KAAA;AAC/C,EAAA,OAAO,CAAA,GAAI,IAAI,IAAA,GAAO,CAAA;AACxB;AAQO,SAAS,aAAA,CAAc,GAAS,KAAA,EAAmB;AACxD,EAAA,IAAI,MAAY,EAAE,CAAA,EAAG,UAAU,CAAA,EAAG,QAAA,EAAU,GAAG,QAAA,EAAS;AACxD,EAAA,IAAI,MAAY,EAAE,CAAA,EAAG,WAAW,CAAA,EAAG,CAAA,QAAA,EAAW,GAAG,CAAA,QAAA,EAAU;AAC3D,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,MAAA,GAAe;AAAA,MACnB,GAAG,CAAA,GAAI,CAAA,GAAI,MAAM,GAAA,CAAI,CAAA,GAAI,MAAM,GAAA,CAAI,CAAA;AAAA,MACnC,GAAG,CAAA,GAAI,CAAA,GAAI,MAAM,GAAA,CAAI,CAAA,GAAI,MAAM,GAAA,CAAI,CAAA;AAAA,MACnC,GAAG,CAAA,GAAI,CAAA,GAAI,MAAM,GAAA,CAAI,CAAA,GAAI,MAAM,GAAA,CAAI;AAAA,KACrC;AACA,IAAA,MAAM,CAAA,GAAI,cAAA,CAAe,CAAA,EAAG,MAAM,CAAA;AAClC,IAAA,GAAA,GAAM,EAAE,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,EAAG,IAAA,CAAK,IAAI,GAAA,CAAI,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAE;AAClF,IAAA,GAAA,GAAM,EAAE,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,EAAG,IAAA,CAAK,IAAI,GAAA,CAAI,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAE;AAAA,EACpF;AACA,EAAA,OAAO,EAAE,KAAK,GAAA,EAAI;AACpB;AAGO,SAAS,UAAA,CAAW,QAAc,MAAA,EAAsB;AAC7D,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,EAAE,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAG,MAAA,CAAO,IAAI,MAAA,EAAO;AAAA,IACxE,GAAA,EAAK,EAAE,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAG,MAAA,CAAO,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAG,MAAA,CAAO,IAAI,MAAA;AAAO,GAC1E;AACF;;;ACtEA,IAAM,KAAA,GAAQ,CAAC,CAAA,KAAsC,CAAC,EAAE,CAAA,EAAG,CAAA,CAAE,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA;AACnE,IAAM,cAAc,CAAC,CAAA,KAAgC,KAAK,IAAA,GAAO,CAAA,GAAI,MAAM,CAAC,CAAA;AAC5E,IAAM,SAAA,GAAY,CAAC,CAAA,MAAgC,EAAE,GAAG,CAAA,CAAE,CAAC,CAAA,EAAI,CAAA,EAAG,EAAE,CAAC,CAAA,EAAI,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA;AAI3E,SAASC,cACd,CAAA,EACA,CAAA,EACA,SAAA,EACA,QAAA,EACA,QAAgB,UAAA,EACF;AACd,EAAA,MAAM,CAAC,EAAA,EAAI,EAAE,CAAA,GAAI,YAAA;AAAA,IACf,MAAM,CAAC,CAAA;AAAA,IACP,MAAM,CAAC,CAAA;AAAA,IACP,YAAY,SAAS,CAAA;AAAA,IACrB,YAAY,QAAQ,CAAA;AAAA,IACpB;AAAA,GACF;AACA,EAAA,OAAO,CAAC,SAAA,CAAU,EAAE,CAAA,EAAG,SAAA,CAAU,EAAE,CAAC,CAAA;AACtC;AAGO,SAAS,gBACd,CAAA,EACA,CAAA,EACA,WACA,QAAA,EACA,OAAA,EACA,QAAgB,UAAA,EACR;AACR,EAAA,MAAM,CAAC,EAAA,EAAI,EAAE,CAAA,GAAI,YAAA;AAAA,IACf,MAAM,CAAC,CAAA;AAAA,IACP,MAAM,CAAC,CAAA;AAAA,IACP,YAAY,SAAS,CAAA;AAAA,IACrB,YAAY,QAAQ,CAAA;AAAA,IACpB;AAAA,GACF;AACA,EAAA,MAAM,MAAc,EAAC;AACrB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,OAAA,EAAS,CAAA,EAAA,EAAK;AACjC,IAAA,MAAM,CAAA,GAAI,OAAA,CAAS,KAAA,CAAM,CAAC,CAAA,EAAG,EAAA,EAAI,EAAA,EAAI,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,GAAI,OAAO,CAAA;AAC1D,IAAA,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA;AAAA,EACvB;AACA,EAAA,OAAO,GAAA;AACT;AAGO,SAASC,QAAAA,CAAQ,EAAA,EAAU,EAAA,EAAU,EAAA,EAAU,IAAU,CAAA,EAAiB;AAC/E,EAAA,MAAM,CAAA,GAAI,OAAA,CAAS,KAAA,CAAM,EAAE,GAAG,KAAA,CAAM,EAAE,CAAA,EAAG,KAAA,CAAM,EAAE,CAAA,EAAG,KAAA,CAAM,EAAE,GAAG,CAAC,CAAA;AAChE,EAAA,OAAO,UAAU,CAAC,CAAA;AACpB","file":"index.js","sourcesContent":["/** Three-component vectors and unit quaternions. `Vec3`'s fields are readonly:\n * a pose stored in a history snapshot must not be writable through the value\n * handed to a renderer.\n *\n * Named fields rather than a tuple, matching `Vec2` one tier up, so a\n * consumer writing both dimensions says `p.x` in each. `Quat` stays a tuple —\n * it is not a point, and `[x, y, z, w]` is the layout three.js and glMatrix\n * both use. */\n\nexport interface Vec3 {\n readonly x: number;\n readonly y: number;\n readonly z: number;\n}\n\n/** `[x, y, z, w]`, w last — the layout three.js and glMatrix both use. */\nexport type Quat = readonly [number, number, number, number];\n\n/** `a + b`. */\nexport function add(a: Vec3, b: Vec3): Vec3 {\n return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };\n}\n\n/** `a - b`. */\nexport function sub(a: Vec3, b: Vec3): Vec3 {\n return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };\n}\n\n/** `a` multiplied by the scalar `k`. */\nexport function scale(a: Vec3, k: number): Vec3 {\n return { x: a.x * k, y: a.y * k, z: a.z * k };\n}\n\n/** Dot product. */\nexport function dot(a: Vec3, b: Vec3): number {\n return a.x * b.x + a.y * b.y + a.z * b.z;\n}\n\n/** Cross product `a × b`. */\nexport function cross(a: Vec3, b: Vec3): Vec3 {\n return {\n x: a.y * b.z - a.z * b.y,\n y: a.z * b.x - a.x * b.z,\n z: a.x * b.y - a.y * b.x,\n };\n}\n\n/** Squared length. Compare distances with this and skip the square root. */\nexport function len2(a: Vec3): number {\n return dot(a, a);\n}\n\n/** Euclidean length. */\nexport function len(a: Vec3): number {\n return Math.sqrt(len2(a));\n}\n\n/** A vector with no length, or no finite one, normalizes to the zero vector\n * rather than to `NaN`. Every other vector keeps its direction, however short. */\nexport function normalize(a: Vec3): Vec3 {\n const l = len(a);\n return l > 0 && l < Infinity ? scale(a, 1 / l) : { x: 0, y: 0, z: 0 };\n}\n\n/** `Vec3` from loose components — the shape `Mat4`'s row math produces. */\nexport function vec3(x: number, y: number, z: number): Vec3 {\n return { x, y, z };\n}\n\n/** The quaternion for no rotation, `[0, 0, 0, 1]`. */\nexport function quatIdentity(): Quat {\n return [0, 0, 0, 1];\n}\n\n/** Rotation by `angle` radians about `axis`, which must be nonzero but need\n * not be unit length. */\nexport function quatFromAxisAngle(axis: Vec3, angle: number): Quat {\n const a = normalize(axis);\n const half = angle / 2;\n const s = Math.sin(half);\n return [a.x * s, a.y * s, a.z * s, Math.cos(half)];\n}\n","/** 4x4 matrices in GL's column-major order: element (row `r`, column `c`) is\n * `m[c * 4 + r]`, which is the layout `gl.uniformMatrix4fv` reads without a\n * transpose and the one three.js `toArray()` emits. */\n\nimport { SINGULAR_RATIO } from '../scalar';\nimport { cross, dot, len, normalize, sub, vec3, type Quat, type Vec3 } from './vec3';\n\n/** 16 numbers, column-major. */\nexport type Mat4 = readonly number[];\n\n/** The identity matrix. */\nexport function identity(): Mat4 {\n return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];\n}\n\n/** The product `a · b`: applied to a point, `b` acts first. */\nexport function multiply(a: Mat4, b: Mat4): Mat4 {\n const out = new Array<number>(16);\n for (let c = 0; c < 4; c++) {\n for (let r = 0; r < 4; r++) {\n let sum = 0;\n for (let k = 0; k < 4; k++) sum += a[k * 4 + r] * b[c * 4 + k];\n out[c * 4 + r] = sum;\n }\n }\n return out;\n}\n\n/** `[x, y, z, w]` in whatever space `m` maps into — clip space, when `m` is a view-projection. */\nexport function transformPoint4(\n m: Mat4,\n p: Vec3,\n): readonly [number, number, number, number] {\n const { x, y, z } = p;\n return [\n m[0] * x + m[4] * y + m[8] * z + m[12],\n m[1] * x + m[5] * y + m[9] * z + m[13],\n m[2] * x + m[6] * y + m[10] * z + m[14],\n m[3] * x + m[7] * y + m[11] * z + m[15],\n ];\n}\n\n/** `transformPoint4` divided through by w, however small. A point on the eye\n * plane (w = 0) comes back non-finite. */\nexport function transformPoint(m: Mat4, p: Vec3): Vec3 {\n const [x, y, z, w] = transformPoint4(m, p);\n if (w === 1) return vec3(x, y, z);\n return vec3(x / w, y / w, z / w);\n}\n\n/** Inverse, or null when the matrix is singular, non-finite, or too\n * ill-conditioned to invert meaningfully at its own scale. */\nexport function invert(m: Mat4): Mat4 | null {\n const [\n m00, m01, m02, m03,\n m10, m11, m12, m13,\n m20, m21, m22, m23,\n m30, m31, m32, m33,\n ] = m;\n\n const b00 = m00 * m11 - m01 * m10;\n const b01 = m00 * m12 - m02 * m10;\n const b02 = m00 * m13 - m03 * m10;\n const b03 = m01 * m12 - m02 * m11;\n const b04 = m01 * m13 - m03 * m11;\n const b05 = m02 * m13 - m03 * m12;\n const b06 = m20 * m31 - m21 * m30;\n const b07 = m20 * m32 - m22 * m30;\n const b08 = m20 * m33 - m23 * m30;\n const b09 = m21 * m32 - m22 * m31;\n const b10 = m21 * m33 - m23 * m31;\n const b11 = m22 * m33 - m23 * m32;\n\n const det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n // Hadamard: |det| never exceeds the product of the column lengths, so the\n // ratio is a volume in [0, 1] that no per-column scale can shrink.\n const scale =\n Math.sqrt(m00 * m00 + m01 * m01 + m02 * m02 + m03 * m03) *\n Math.sqrt(m10 * m10 + m11 * m11 + m12 * m12 + m13 * m13) *\n Math.sqrt(m20 * m20 + m21 * m21 + m22 * m22 + m23 * m23) *\n Math.sqrt(m30 * m30 + m31 * m31 + m32 * m32 + m33 * m33);\n // Negated so a non-finite determinant falls out as singular.\n if (!(Math.abs(det) > SINGULAR_RATIO * scale)) return null;\n const d = 1 / det;\n\n return [\n (m11 * b11 - m12 * b10 + m13 * b09) * d,\n (m02 * b10 - m01 * b11 - m03 * b09) * d,\n (m31 * b05 - m32 * b04 + m33 * b03) * d,\n (m22 * b04 - m21 * b05 - m23 * b03) * d,\n (m12 * b08 - m10 * b11 - m13 * b07) * d,\n (m00 * b11 - m02 * b08 + m03 * b07) * d,\n (m32 * b02 - m30 * b05 - m33 * b01) * d,\n (m20 * b05 - m22 * b02 + m23 * b01) * d,\n (m10 * b10 - m11 * b08 + m13 * b06) * d,\n (m01 * b08 - m00 * b10 - m03 * b06) * d,\n (m30 * b04 - m31 * b02 + m33 * b00) * d,\n (m21 * b02 - m20 * b04 - m23 * b00) * d,\n (m11 * b07 - m10 * b09 - m12 * b06) * d,\n (m00 * b09 - m01 * b07 + m02 * b06) * d,\n (m31 * b01 - m30 * b03 - m32 * b00) * d,\n (m20 * b03 - m21 * b01 + m22 * b00) * d,\n ];\n}\n\n/** Translation · rotation · scale: the matrix that scales a point, then\n * rotates it, then moves it by `position`. */\nexport function compose(position: Vec3, rotation: Quat, scaling: Vec3): Mat4 {\n const [x, y, z, w] = rotation;\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n const { x: sx, y: sy, z: sz } = scaling;\n\n return [\n (1 - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n (xy - wz) * sy, (1 - (xx + zz)) * sy, (yz + wx) * sy, 0,\n (xz + wy) * sz, (yz - wx) * sz, (1 - (xx + yy)) * sz, 0,\n position.x, position.y, position.z, 1,\n ];\n}\n\n/** A GL-convention projection: vertical field of view `fovY` in radians, the\n * camera looking down −z, and `near`..`far` mapped to clip z −1..1. */\nexport function perspective(fovY: number, aspect: number, near: number, far: number): Mat4 {\n const f = 1 / Math.tan(fovY / 2);\n const range = near - far;\n return [\n f / aspect, 0, 0, 0,\n 0, f, 0, 0,\n 0, 0, (far + near) / range, -1,\n 0, 0, (2 * far * near) / range, 0,\n ];\n}\n\n/** A view from `eye` toward `target`. With the eye on its target, or `up`\n * parallel to the view to within rounding, the view has no orientation and\n * the result is singular. */\nexport function lookAt(eye: Vec3, target: Vec3, up: Vec3): Mat4 {\n const back = normalize(sub(eye, target));\n const side = cross(up, back);\n // |side| is |up| times the sine of the angle between up and the view.\n const right = len(side) > SINGULAR_RATIO * len(up) ? normalize(side) : vec3(0, 0, 0);\n const trueUp = cross(back, right);\n return [\n right.x, trueUp.x, back.x, 0,\n right.y, trueUp.y, back.y, 0,\n right.z, trueUp.z, back.z, 0,\n -dot(right, eye), -dot(trueUp, eye), -dot(back, eye), 1,\n ];\n}\n","/** Rays, axis-aligned boxes, and the intersections picking is built from. */\n\nimport { SINGULAR_RATIO } from '../scalar';\nimport { dot, len, type Vec3 } from './vec3';\nimport { transformPoint, type Mat4 } from './mat4';\n\n/** A ray from `origin` along `direction`, which need not be unit length: the\n * `t` the intersections return is in multiples of it. */\nexport interface Ray {\n origin: Vec3;\n direction: Vec3;\n}\n\n/** An axis-aligned box. `min` is componentwise <= `max`. */\nexport interface Aabb {\n min: Vec3;\n max: Vec3;\n}\n\n/** Distance along the ray to the box, or null. A ray starting inside returns 0. */\nexport function intersectRayAabb(ray: Ray, min: Vec3, max: Vec3): number | null {\n let tMin = Number.NEGATIVE_INFINITY;\n let tMax = Number.POSITIVE_INFINITY;\n\n for (const axis of ['x', 'y', 'z'] as const) {\n const o = ray.origin[axis];\n const d = ray.direction[axis];\n // Any other direction, however short, divides to an honest (possibly infinite) t.\n if (d === 0) {\n if (o < min[axis] || o > max[axis]) return null;\n continue;\n }\n let t1 = (min[axis] - o) / d;\n let t2 = (max[axis] - o) / d;\n if (t1 > t2) [t1, t2] = [t2, t1];\n if (t1 > tMin) tMin = t1;\n if (t2 < tMax) tMax = t2;\n if (tMin > tMax) return null;\n }\n\n if (tMax < 0) return null;\n return tMin < 0 ? 0 : tMin;\n}\n\n/** Plane is `dot(normal, p) === offset`. Null when the ray runs parallel to the\n * plane to within rounding, or points away from it. */\nexport function intersectRayPlane(ray: Ray, normal: Vec3, offset: number): number | null {\n const denom = dot(normal, ray.direction);\n if (!(Math.abs(denom) > SINGULAR_RATIO * len(normal) * len(ray.direction))) return null;\n const t = (offset - dot(normal, ray.origin)) / denom;\n return t < 0 ? null : t;\n}\n\n/**\n * The axis-aligned box enclosing `local` after `m`. All eight corners are\n * transformed and re-bounded, so a rotation widens the result rather than\n * rotating it — an AABB cannot represent an oriented box, and pretending\n * otherwise is how a hit test starts missing its own geometry.\n */\nexport function transformAabb(m: Mat4, local: Aabb): Aabb {\n let min: Vec3 = { x: Infinity, y: Infinity, z: Infinity };\n let max: Vec3 = { x: -Infinity, y: -Infinity, z: -Infinity };\n for (let i = 0; i < 8; i++) {\n const corner: Vec3 = {\n x: i & 1 ? local.max.x : local.min.x,\n y: i & 2 ? local.max.y : local.min.y,\n z: i & 4 ? local.max.z : local.min.z,\n };\n const p = transformPoint(m, corner);\n min = { x: Math.min(min.x, p.x), y: Math.min(min.y, p.y), z: Math.min(min.z, p.z) };\n max = { x: Math.max(max.x, p.x), y: Math.max(max.y, p.y), z: Math.max(max.z, p.z) };\n }\n return { min, max };\n}\n\n/** The box centred on `center` reaching `radius` along every axis. */\nexport function aabbAround(center: Vec3, radius: number): Aabb {\n return {\n min: { x: center.x - radius, y: center.y - radius, z: center.z - radius },\n max: { x: center.x + radius, y: center.y + radius, z: center.z + radius },\n };\n}\n","/**\n * The port-curve rule one dimension up, in `Vec3`. The rule itself lives in\n * `../portCurve`, stated once over components — this wrapper is types and\n * nothing else, so 2D and 3D cannot disagree about what the curve is.\n */\n\nimport { PORT_REACH, cubicAt as cubicAtN, portControls as portControlsN } from '../portCurve';\nimport type { Vec3 } from './vec3';\n\nexport { PORT_REACH };\n\nconst comps = (v: Vec3): [number, number, number] => [v.x, v.y, v.z];\nconst compsOrNull = (v: Vec3 | null | undefined) => (v == null ? v : comps(v));\nconst fromComps = (p: readonly number[]): Vec3 => ({ x: p[0]!, y: p[1]!, z: p[2]! });\n\n/** `[c1, c2]` for the cubic from `a` to `b`. A null normal falls back to a lerp\n * along the chord; see `../portCurve` for why the two ends differ. */\nexport function portControls(\n a: Vec3,\n b: Vec3,\n outNormal: Vec3 | null | undefined,\n inNormal: Vec3 | null | undefined,\n reach: number = PORT_REACH,\n): [Vec3, Vec3] {\n const [c1, c2] = portControlsN(\n comps(a),\n comps(b),\n compsOrNull(outNormal),\n compsOrNull(inNormal),\n reach,\n );\n return [fromComps(c1), fromComps(c2)];\n}\n\n/** A port curve sampled into `samples` points, excluding its start. */\nexport function portCurvePoints(\n a: Vec3,\n b: Vec3,\n outNormal: Vec3 | null | undefined,\n inNormal: Vec3 | null | undefined,\n samples: number,\n reach: number = PORT_REACH,\n): Vec3[] {\n const [c1, c2] = portControlsN(\n comps(a),\n comps(b),\n compsOrNull(outNormal),\n compsOrNull(inNormal),\n reach,\n );\n const out: Vec3[] = [];\n for (let s = 1; s <= samples; s++) {\n const p = cubicAtN(comps(a), c1, c2, comps(b), s / samples);\n out.push(fromComps(p));\n }\n return out;\n}\n\n/** A cubic evaluated at `t`. The 2D barrel's `cubicEvalAt`, one dimension up. */\nexport function cubicAt(p0: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, t: number): Vec3 {\n const p = cubicAtN(comps(p0), comps(p1), comps(p2), comps(p3), t);\n return fromComps(p);\n}\n"]}
@@ -1,49 +1,14 @@
1
- /** Minimal path input: a rect or a polygon command stream. geom does not
2
- * import @weasel-js/core's `Path`; the kit maps `Path` onto this shape. */
3
- type GeomPath = {
4
- kind: 'rect';
5
- x: number;
6
- y: number;
7
- width: number;
8
- height: number;
9
- } | {
10
- kind: 'polygon';
11
- commands: ArrayLike<number>;
12
- coords: ArrayLike<number>;
13
- fillRule?: 'nonzero' | 'evenodd';
14
- };
15
- /** A `[x, y]` 2-tuple. */
16
- type Pair = [number, number];
17
- /** Closed ring (first vertex repeated as last). */
18
- type Ring = Pair[];
19
- /** Polygon: one outer ring optionally followed by hole rings. */
20
- type Polygon = Ring[];
21
- /** MultiPolygon: list of polygons (used for boolean op I/O). */
22
- type MultiPolygon = Polygon[];
23
- interface PathToMultiPolygonOptions {
24
- /** Flattening tolerance for bezier segments. Default: `DEFAULT_FLATTEN_TOLERANCE`. */
25
- tolerance?: number;
26
- }
27
- /** Polygon result shape emitted by `multiPolygonToPath`. */
28
- type GeomPolygonPath = {
29
- kind: 'polygon';
30
- commands: Uint8Array;
31
- coords: Float32Array;
32
- fillRule: 'nonzero';
33
- };
34
- /** Convert a `GeomPath` to a `MultiPolygon` suitable for `polygon-clipping`. */
35
- declare function pathToMultiPolygon(path: GeomPath, opts?: PathToMultiPolygonOptions): MultiPolygon;
36
- /** Convert a `MultiPolygon` to a polygon path with `fillRule: 'nonzero'`. */
37
- declare function multiPolygonToPath(mp: MultiPolygon): GeomPolygonPath;
1
+ import { P as Path, a as PolygonPath } from '../path-D0CoudGM.js';
2
+ import { P as Point } from '../cubicMath-CpCvuEl8.js';
38
3
 
39
4
  /** Union of N paths. Commutative. Returns an empty path if all inputs are empty. */
40
- declare function pathUnion(...paths: GeomPath[]): GeomPolygonPath;
5
+ declare function pathUnion(...paths: Path[]): PolygonPath;
41
6
  /** Intersection of N paths. Commutative. Empty result is an empty path. */
42
- declare function pathIntersect(...paths: GeomPath[]): GeomPolygonPath;
7
+ declare function pathIntersect(...paths: Path[]): PolygonPath;
43
8
  /** Asymmetric difference: returns `a − b`. */
44
- declare function pathSubtract(a: GeomPath, b: GeomPath): GeomPolygonPath;
9
+ declare function pathSubtract(a: Path, b: Path): PolygonPath;
45
10
  /** Symmetric difference (XOR) of N paths. Commutative. */
46
- declare function pathExclude(...paths: GeomPath[]): GeomPolygonPath;
11
+ declare function pathExclude(...paths: Path[]): PolygonPath;
47
12
  /**
48
13
  * Fracture N paths along every intersection into the maximal set of
49
14
  * non-overlapping regions. Returns one polygon path per region.
@@ -58,7 +23,7 @@ declare function pathExclude(...paths: GeomPath[]): GeomPolygonPath;
58
23
  * subset count limits this to small N in practice; passing more than ~8
59
24
  * inputs is a misuse — the polygon-clipping kernel dominates anyway.
60
25
  */
61
- declare function pathDivide(...paths: GeomPath[]): GeomPolygonPath[];
26
+ declare function pathDivide(...paths: Path[]): PolygonPath[];
62
27
  /**
63
28
  * Clip each non-topmost path to the topmost path (Illustrator "Crop").
64
29
  * Returns `N - 1` results, one per source-below-top, in input order.
@@ -67,6 +32,87 @@ declare function pathDivide(...paths: GeomPath[]): GeomPolygonPath[];
67
32
  * Empty results (a source that lies entirely outside the mask) are
68
33
  * filtered. With `<2` inputs the result is empty.
69
34
  */
70
- declare function pathCrop(...paths: GeomPath[]): GeomPolygonPath[];
35
+ declare function pathCrop(...paths: Path[]): PolygonPath[];
36
+
37
+ /** A `[x, y]` 2-tuple. */
38
+ type Pair = [number, number];
39
+ /** Closed ring (first vertex repeated as last). */
40
+ type Ring = Pair[];
41
+ /** Polygon: one outer ring optionally followed by hole rings. */
42
+ type Polygon = Ring[];
43
+ /** MultiPolygon: list of polygons (used for boolean op I/O). */
44
+ type MultiPolygon = Polygon[];
45
+ /** Options for `pathToMultiPolygon`. */
46
+ interface PathToMultiPolygonOptions {
47
+ /** Flattening tolerance for bezier segments. Default: `DEFAULT_FLATTEN_TOLERANCE`. */
48
+ tolerance?: number;
49
+ }
50
+ /** Convert a `Path` to a `MultiPolygon` suitable for `polygon-clipping`. */
51
+ declare function pathToMultiPolygon(path: Path, opts?: PathToMultiPolygonOptions): MultiPolygon;
52
+ /** Convert a `MultiPolygon` to a polygon path with `fillRule: 'nonzero'`. */
53
+ declare function multiPolygonToPath(mp: MultiPolygon): PolygonPath;
54
+
55
+ /** Options for `splitPathBySegment` and `splitPathByPolyline`. */
56
+ interface SplitBySegmentOptions {
57
+ /**
58
+ * Flattening tolerance for the check that decides whether contours cross
59
+ * each other. Only a path whose contours do cross is flattened (see
60
+ * `splitPathByPolyline`).
61
+ */
62
+ flattenTolerance?: number;
63
+ }
64
+ /**
65
+ * Split `path` along the finite segment a→b into closed pieces (Knife).
66
+ * The same as {@link splitPathByPolyline} with a two-point cut.
67
+ */
68
+ declare function splitPathBySegment(path: Path, a: Point, b: Point, opts?: SplitBySegmentOptions): Path[] | null;
69
+ /**
70
+ * Split `path` along the open polyline `cut` into closed pieces (Knife). A
71
+ * freehand cut is a polyline through its samples.
72
+ *
73
+ * Only chords the cut crosses end to end are cut: a stretch of the cut that
74
+ * starts or stops inside the fill cuts nothing, and nothing beyond the cut's
75
+ * ends is touched, so a concave shape splits exactly where the stroke crosses
76
+ * it. Curves are split at the crossing parameters by de Casteljau
77
+ * subdivision, so every piece traces the original boundary exactly and keeps
78
+ * its quadratic and cubic segments; the new edges follow the cut as straight
79
+ * lines, bends included.
80
+ *
81
+ * A loop the cut draws inside the fill, where it crosses its own track, cuts
82
+ * out the region it encloses: that region is returned as its own piece, with
83
+ * any hole it surrounds, and leaves a hole in the piece around it. A chord
84
+ * running through a loop leaves the loop uncut. A closed cut (its last point
85
+ * equal to its first) is one such loop or, where it crosses the boundary, is
86
+ * cut as the chords it makes. Chords that cross each other are cut one after
87
+ * another, so a cross-hatch yields every piece.
88
+ *
89
+ * Each connected piece the cut produces is returned as its own path, holes
90
+ * included. Contours the cut misses entirely are returned together as one
91
+ * final piece. A single chord that does not disconnect the shape (across a
92
+ * ring, say) returns one slit piece.
93
+ *
94
+ * A path whose contours cross each other or themselves is first resolved into
95
+ * non-overlapping rings by a polygon union, which flattens its curves.
96
+ *
97
+ * Returns `null` when no chord is cut.
98
+ */
99
+ declare function splitPathByPolyline(path: Path, cut: readonly Point[], opts?: SplitBySegmentOptions): Path[] | null;
100
+ /**
101
+ * Split the stroke of `path` wherever the open polyline `cut` crosses it
102
+ * (Scissors).
103
+ *
104
+ * Nothing is closed the way a fill closes it: an open subpath is cut into open
105
+ * runs at each crossing, and a closed one is opened there, so a ring crossed
106
+ * once becomes a single open run that starts and ends at the crossing. Curves
107
+ * are split by de Casteljau subdivision, keeping their segment types. A
108
+ * crossing at an end of an open subpath cuts nothing, and neither does a point
109
+ * where the path only touches the cut.
110
+ *
111
+ * Each run is returned as its own path. Subpaths the cut misses are returned
112
+ * together as one final piece.
113
+ *
114
+ * Returns `null` when nothing is cut.
115
+ */
116
+ declare function snipPathByPolyline(path: Path, cut: readonly Point[]): Path[] | null;
71
117
 
72
- export { type GeomPath, type GeomPolygonPath, type MultiPolygon, type Pair, type PathToMultiPolygonOptions, type Polygon, type Ring, multiPolygonToPath, pathCrop, pathDivide, pathExclude, pathIntersect, pathSubtract, pathToMultiPolygon, pathUnion };
118
+ export { type MultiPolygon, type Pair, type PathToMultiPolygonOptions, type Polygon, type Ring, type SplitBySegmentOptions, multiPolygonToPath, pathCrop, pathDivide, pathExclude, pathIntersect, pathSubtract, pathToMultiPolygon, pathUnion, snipPathByPolyline, splitPathByPolyline, splitPathBySegment };