{"version":3,"file":"clipper2.min.mjs","names":["B0","B2","B4","B2","Clipper"],"sources":["../src/Core.ts","../src/Engine.ts","../src/Offset.ts","../src/RectClip.ts","../src/Minkowski.ts","../src/Shewchuk.ts","../src/Triangulation.ts","../src/Clipper.ts"],"sourcesContent":["/*******************************************************************************\n* Author    :  Angus Johnson                                                   *\n* Date      :  12 December 2025                                                *\n* Website   :  https://www.angusj.com                                          *\n* Copyright :  Angus Johnson 2010-2025                                         *\n* Purpose   :  Core structures and functions for the Clipper Library           *\n* License   :  https://www.boost.org/LICENSE_1_0.txt                           *\n*******************************************************************************/\n\nexport interface Point64 {\n  x: number;\n  y: number;\n  z?: number;\n}\n\nexport interface PointD {\n  x: number;\n  y: number;\n  z?: number;\n}\n\nexport type Path64 = Point64[];\nexport type PathD = PointD[];\nexport type Paths64 = Path64[];\nexport type PathsD = PathD[];\n\nexport interface Rect64 {\n  left: number;\n  top: number;\n  right: number;\n  bottom: number;\n}\n\nexport interface RectD {\n  left: number;\n  top: number;\n  right: number;\n  bottom: number;\n}\n\n// Note: all clipping operations except for Difference are commutative.\nexport enum ClipType {\n  NoClip = 0,\n  Intersection = 1,\n  Union = 2,\n  Difference = 3,\n  Xor = 4\n}\n\nexport enum PathType {\n  Subject = 0,\n  Clip = 1\n}\n\n// By far the most widely used filling rules for polygons are EvenOdd\n// and NonZero, sometimes called Alternate and Winding respectively.\n// https://en.wikipedia.org/wiki/Nonzero-rule\nexport enum FillRule {\n  EvenOdd = 0,\n  NonZero = 1,\n  Positive = 2,\n  Negative = 3\n}\n\n// PointInPolygon\nexport enum PointInPolygonResult {\n  IsOn = 0,\n  IsInside = 1,\n  IsOutside = 2\n}\n\n// Z-coordinate callbacks\n// Called at each intersection to allow custom Z value computation\nexport type ZCallback64 = (\n  bot1: Point64,\n  top1: Point64,\n  bot2: Point64,\n  top2: Point64,\n  intersectPt: Point64\n) => void;\n\nexport type ZCallbackD = (\n  bot1: PointD,\n  top1: PointD,\n  bot2: PointD,\n  top2: PointD,\n  intersectPt: PointD\n) => void;\n\n// InternalClipper - converted from namespace to plain const object to avoid\n// the IIFE wrapper that tsc emits for namespaces. All functions are defined at\n// module level so internal cross-calls (e.g. isCollinear -> productsAreEqual)\n// are direct calls without property lookup overhead. The exported object bundles\n// them for external callers that use InternalClipper.foo() syntax.\n\n// --- private helpers (module-level, not exported) ---\nconst maxSafeInteger = Number.MAX_SAFE_INTEGER;\nconst maxDeltaForSafeProduct = Math.floor(Math.sqrt(maxSafeInteger));\n\nfunction isSafeProduct(a: number, b: number): boolean {\n  if (!Number.isSafeInteger(a) || !Number.isSafeInteger(b)) return false;\n  if (a === 0 || b === 0) return true;\n  return Math.abs(a) <= maxSafeInteger / Math.abs(b);\n}\n\nfunction isSafeSum(a: number, b: number): boolean {\n  return Math.abs(a) + Math.abs(b) <= maxSafeInteger;\n}\n\nfunction safeMultiplyDifference(a: number, b: number, c: number, d: number): number {\n  if (isSafeProduct(a, b) && isSafeProduct(c, d)) {\n    const prod1 = a * b;\n    const prod2 = c * d;\n    if (isSafeSum(prod1, prod2)) {\n      return prod1 - prod2;\n    }\n  }\n\n  if (Number.isSafeInteger(a) && Number.isSafeInteger(b) &&\n    Number.isSafeInteger(c) && Number.isSafeInteger(d)) {\n    return Number((BigInt(a) * BigInt(b)) - (BigInt(c) * BigInt(d)));\n  }\n\n  return (a * b) - (c * d);\n}\n\nfunction safeMultiplySum(a: number, b: number, c: number, d: number): number {\n  if (isSafeProduct(a, b) && isSafeProduct(c, d)) {\n    const prod1 = a * b;\n    const prod2 = c * d;\n    if (isSafeSum(prod1, prod2)) {\n      return prod1 + prod2;\n    }\n  }\n\n  if (Number.isSafeInteger(a) && Number.isSafeInteger(b) &&\n    Number.isSafeInteger(c) && Number.isSafeInteger(d)) {\n    return Number((BigInt(a) * BigInt(b)) + (BigInt(c) * BigInt(d)));\n  }\n\n  return (a * b) + (c * d);\n}\n\n// BigInt constants — avoid BigInt literal syntax (0n, 4n, etc.) to sidestep\n// terser BigInt constant-folding issues in some consuming build setups.\nconst B0 = BigInt(0);\nconst B2 = BigInt(2);\nconst B4 = BigInt(4);\nconst B64 = BigInt(64);\nconst UINT64_MASK = BigInt(\"0xFFFFFFFFFFFFFFFF\");\n\n// --- public constants (module-level for cross-referencing) ---\nconst IC_MaxInt64 = BigInt(\"9223372036854775807\");\nconst IC_MaxCoord = Number(IC_MaxInt64 / B4);\nconst IC_Invalid64 = Number(IC_MaxInt64);\nconst IC_floatingPointTolerance = 1E-12;\nconst IC_defaultMinimumEdgeLength = 0.1;\nconst IC_maxCoordForSafeAreaProduct = Math.floor(maxDeltaForSafeProduct / 2);\n// Bound for |a|,|b|,|c|,|d| so cross^2 and denom stay safe\nconst IC_maxCoordForSafeCrossSq = Math.floor(Math.sqrt(Math.sqrt(maxSafeInteger / 4)));\n\n// --- public functions (module-level for direct internal calls) ---\n\nfunction maxSafeCoordinateForScale(scale: number): number {\n  if (!Number.isFinite(scale)) {\n    throw new RangeError(\"Scale must be a finite number\");\n  }\n  const absScale = Math.abs(scale);\n  if (absScale === 0) return Number.POSITIVE_INFINITY;\n  return maxSafeInteger / absScale;\n}\n\nfunction checkSafeScaleValue(value: number, maxAbs: number, context: string): void {\n  if (!Number.isFinite(value) || Math.abs(value) > maxAbs) {\n    throw new RangeError(`Scaled coordinate exceeds Number.MAX_SAFE_INTEGER in ${context}`);\n  }\n}\n\nfunction ensureSafeInteger(value: number, context: string): void {\n  if (!Number.isFinite(value) || Math.abs(value) > maxSafeInteger) {\n    throw new RangeError(`Coordinate exceeds Number.MAX_SAFE_INTEGER in ${context}`);\n  }\n}\n\nfunction crossProduct(pt1: Point64, pt2: Point64, pt3: Point64): number {\n  const a = pt2.x - pt1.x;\n  const b = pt3.y - pt2.y;\n  const c = pt2.y - pt1.y;\n  const d = pt3.x - pt2.x;\n\n  // Fast path for small coordinates\n  if (Math.abs(a) < maxDeltaForSafeProduct && Math.abs(b) < maxDeltaForSafeProduct &&\n    Math.abs(c) < maxDeltaForSafeProduct && Math.abs(d) < maxDeltaForSafeProduct) {\n    return (a * b) - (c * d);\n  }\n\n  return safeMultiplyDifference(a, b, c, d);\n}\n\nfunction crossProductSign(pt1: Point64, pt2: Point64, pt3: Point64): number {\n  const a = pt2.x - pt1.x;\n  const b = pt3.y - pt2.y;\n  const c = pt2.y - pt1.y;\n  const d = pt3.x - pt2.x;\n\n  // Fast check for safe integer range\n  // Using Math.abs inline allows short-circuiting\n  if (Math.abs(a) < maxDeltaForSafeProduct && Math.abs(b) < maxDeltaForSafeProduct &&\n    Math.abs(c) < maxDeltaForSafeProduct && Math.abs(d) < maxDeltaForSafeProduct) {\n    const prod1 = a * b;\n    const prod2 = c * d;\n    return (prod1 > prod2) ? 1 : (prod1 < prod2) ? -1 : 0;\n  }\n\n  if (!Number.isSafeInteger(a) || !Number.isSafeInteger(b) ||\n      !Number.isSafeInteger(c) || !Number.isSafeInteger(d)) {\n    const prod1 = a * b;\n    const prod2 = c * d;\n    return (prod1 > prod2) ? 1 : (prod1 < prod2) ? -1 : 0;\n  }\n\n  const bigProd1 = BigInt(a) * BigInt(b);\n  const bigProd2 = BigInt(c) * BigInt(d);\n\n  if (bigProd1 === bigProd2) return 0;\n  return (bigProd1 > bigProd2) ? 1 : -1;\n}\n\nfunction checkPrecision(precision: number): void {\n  if (precision < -8 || precision > 8) {\n    throw new Error(\"Error: Precision is out of range.\");\n  }\n}\n\nfunction isAlmostZero(value: number): boolean {\n  return Math.abs(value) <= IC_floatingPointTolerance;\n}\n\nfunction triSign(x: number): number {\n  return (x < 0) ? -1 : (x > 0) ? 1 : 0;\n}\n\nexport interface UInt128Struct {\n  lo64: bigint;\n  hi64: bigint;\n}\n\nfunction multiplyUInt64(a: number, b: number): UInt128Struct {\n  // Fix: a and b might be larger than 2^32, so don't use >>> 0\n  const aBig = BigInt(a);\n  const bBig = BigInt(b);\n  const res = aBig * bBig;\n  \n  return {\n    lo64: res & UINT64_MASK,\n    hi64: res >> B64\n  };\n}\n\n// returns true if (and only if) a * b == c * d\nfunction productsAreEqual(a: number, b: number, c: number, d: number): boolean {\n  const absA = Math.abs(a);\n  const absB = Math.abs(b);\n  const absC = Math.abs(c);\n  const absD = Math.abs(d);\n\n  // Fast path for safe integer range (covers all typical coordinates)\n  if (absA < maxDeltaForSafeProduct && absB < maxDeltaForSafeProduct &&\n    absC < maxDeltaForSafeProduct && absD < maxDeltaForSafeProduct) {\n    return a * b === c * d;\n  }\n\n  const signAb = (a < 0 ? -1 : (a > 0 ? 1 : 0)) * (b < 0 ? -1 : (b > 0 ? 1 : 0));\n  const signCd = (c < 0 ? -1 : (c > 0 ? 1 : 0)) * (d < 0 ? -1 : (d > 0 ? 1 : 0));\n  \n  if (signAb !== signCd) return false;\n  if (signAb === 0) return true;\n  if (!Number.isSafeInteger(absA) || !Number.isSafeInteger(absB) ||\n      !Number.isSafeInteger(absC) || !Number.isSafeInteger(absD)) {\n    return a * b === c * d;\n  }\n\n  const bigA = BigInt(absA);\n  const bigB = BigInt(absB);\n  const bigC = BigInt(absC);\n  const bigD = BigInt(absD);\n  \n  return (bigA * bigB) === (bigC * bigD);\n}\n\nfunction isCollinear(pt1: Point64, sharedPt: Point64, pt2: Point64): boolean {\n  const a = sharedPt.x - pt1.x;\n  const b = pt2.y - sharedPt.y;\n  const c = sharedPt.y - pt1.y;\n  const d = pt2.x - sharedPt.x;\n  // When checking for collinearity with very large coordinate values\n  // then ProductsAreEqual is more accurate than using CrossProduct.\n  return productsAreEqual(a, b, c, d);\n}\n\nfunction dotProduct(pt1: Point64, pt2: Point64, pt3: Point64): number {\n  const a = pt2.x - pt1.x;\n  const b = pt3.x - pt2.x;\n  const c = pt2.y - pt1.y;\n  const d = pt3.y - pt2.y;\n\n  // Fast path for small coordinates\n  if (Math.abs(a) < maxDeltaForSafeProduct && Math.abs(b) < maxDeltaForSafeProduct &&\n    Math.abs(c) < maxDeltaForSafeProduct && Math.abs(d) < maxDeltaForSafeProduct) {\n    return (a * b) + (c * d);\n  }\n\n  return safeMultiplySum(a, b, c, d);\n}\n\nfunction dotProductSign(pt1: Point64, pt2: Point64, pt3: Point64): number {\n  const a = pt2.x - pt1.x;\n  const b = pt3.x - pt2.x;\n  const c = pt2.y - pt1.y;\n  const d = pt3.y - pt2.y;\n\n  if (Math.abs(a) < maxDeltaForSafeProduct && Math.abs(b) < maxDeltaForSafeProduct &&\n    Math.abs(c) < maxDeltaForSafeProduct && Math.abs(d) < maxDeltaForSafeProduct) {\n    const sum = (a * b) + (c * d);\n    return sum > 0 ? 1 : (sum < 0 ? -1 : 0);\n  }\n\n  if (!Number.isSafeInteger(a) || !Number.isSafeInteger(b) ||\n    !Number.isSafeInteger(c) || !Number.isSafeInteger(d)) {\n    const sum = (a * b) + (c * d);\n    return sum > 0 ? 1 : (sum < 0 ? -1 : 0);\n  }\n\n  const bigSum = (BigInt(a) * BigInt(b)) + (BigInt(c) * BigInt(d));\n  if (bigSum === B0) return 0;\n  return bigSum > B0 ? 1 : -1;\n}\n\nfunction icArea(path: Path64): number {\n  // https://en.wikipedia.org/wiki/Shoelace_formula\n  const cnt = path.length;\n  if (cnt < 3) return 0.0;\n\n  // Fast path when coords are small enough that (y1+y2)*(x1-x2) won't overflow\n  // maxCoordForSafeAreaProduct is floor(sqrt(Number.MAX_SAFE_INTEGER) / 2)\n  let allSmall = true;\n  for (let i = 0; i < cnt && allSmall; i++) {\n    const pt = path[i];\n    if (Math.abs(pt.x) >= IC_maxCoordForSafeAreaProduct ||\n      Math.abs(pt.y) >= IC_maxCoordForSafeAreaProduct) {\n      allSmall = false;\n    }\n  }\n\n  let prevPt = path[cnt - 1];\n\n  if (allSmall) {\n    // Fast path - no overflow checks needed\n    let total = 0.0;\n    for (const pt of path) {\n      total += (prevPt.y + pt.y) * (prevPt.x - pt.x);\n      prevPt = pt;\n    }\n    return total * 0.5;\n  }\n\n  // Safe path - use BigInt for accumulation\n  let totalBig = B0;\n  for (const pt of path) {\n    const sum = prevPt.y + pt.y;\n    const diff = prevPt.x - pt.x;\n    if (Number.isSafeInteger(sum) && Number.isSafeInteger(diff)) {\n      totalBig += BigInt(sum) * BigInt(diff);\n    } else if (Number.isSafeInteger(prevPt.y) && Number.isSafeInteger(pt.y) &&\n      Number.isSafeInteger(prevPt.x) && Number.isSafeInteger(pt.x)) {\n      const sumBig = BigInt(prevPt.y) + BigInt(pt.y);\n      const diffBig = BigInt(prevPt.x) - BigInt(pt.x);\n      totalBig += sumBig * diffBig;\n    } else {\n      // Coordinates not safe integers - fall back to float\n      totalBig += BigInt(Math.round(sum * diff));\n    }\n    prevPt = pt;\n  }\n  return Number(totalBig) * 0.5;\n}\n\nfunction crossProductD(vec1: PointD, vec2: PointD): number {\n  return (vec1.y * vec2.x - vec2.y * vec1.x);\n}\n\nfunction dotProductD(vec1: PointD, vec2: PointD): number {\n  return (vec1.x * vec2.x + vec1.y * vec2.y);\n}\n\n// Banker's rounding (round half to even) to match C# MidpointRounding.ToEven.\nfunction roundToEven(value: number): number {\n  const r = Math.round(value);\n  if (value === r - 0.5 && (r & 1) !== 0) return r - 1;\n  return r;\n}\n\nfunction checkCastInt64(val: number): number {\n  if ((val >= IC_MaxCoord) || (val <= -IC_MaxCoord)) return IC_Invalid64;\n  return Math.round(val);\n}\n\n// GetLineIntersectPt - returns the intersection point if non-parallel, or null.\n// The point will be constrained to seg1. However, it's possible that the point\n// won't be inside seg2, even when it hasn't been constrained (ie inside seg1).\n// Returns Point64 | null to avoid allocating a wrapper object on every call.\nfunction getLineIntersectPt(\n  ln1a: Point64, ln1b: Point64, \n  ln2a: Point64, ln2b: Point64\n): Point64 | null {\n  const dy1 = (ln1b.y - ln1a.y);\n  const dx1 = (ln1b.x - ln1a.x);\n  const dy2 = (ln2b.y - ln2a.y);\n  const dx2 = (ln2b.x - ln2a.x);\n  const det = safeMultiplyDifference(dy1, dx2, dy2, dx1);\n  \n  if (det === 0.0) {\n    return null;\n  }\n\n  const t = safeMultiplyDifference(\n    (ln1a.x - ln2a.x),\n    dy2,\n    (ln1a.y - ln2a.y),\n    dx2\n  ) / det;\n  \n  if (t <= 0.0) {\n    // Create a copy to avoid mutating original (struct copy in C# carries Z).\n    return { x: ln1a.x, y: ln1a.y, z: (ln1a.z || 0) };\n  } else if (t >= 1.0) {\n    return { x: ln1b.x, y: ln1b.y, z: (ln1b.z || 0) };\n  } else {\n    // avoid using constructor (and rounding too) as they affect performance\n    // Use Math.trunc to match C# (long) cast behavior which truncates towards zero\n    return {\n      x: Math.trunc(ln1a.x + t * dx1),\n      y: Math.trunc(ln1a.y + t * dy1),\n      z: 0\n    };\n  }\n}\n\nfunction getLineIntersectPtD(\n  ln1a: PointD, ln1b: PointD,\n  ln2a: PointD, ln2b: PointD\n): { success: boolean; ip: PointD } {\n  const dy1 = ln1b.y - ln1a.y;\n  const dx1 = ln1b.x - ln1a.x;\n  const dy2 = ln2b.y - ln2a.y;\n  const dx2 = ln2b.x - ln2a.x;\n  const det = dy1 * dx2 - dy2 * dx1;\n  \n  if (det === 0.0) {\n    return { success: false, ip: { x: 0, y: 0, z: 0 } };\n  }\n\n  const t = ((ln1a.x - ln2a.x) * dy2 - (ln1a.y - ln2a.y) * dx2) / det;\n  let ip: PointD;\n  \n  if (t <= 0.0) {\n    ip = { ...ln1a, z: 0 };\n  } else if (t >= 1.0) {\n    ip = { ...ln1b, z: 0 };\n  } else {\n    ip = {\n      x: ln1a.x + t * dx1,\n      y: ln1a.y + t * dy1,\n      z: 0\n    };\n  }\n  \n  return { success: true, ip };\n}\n\nfunction segsIntersect(\n  seg1a: Point64, seg1b: Point64, \n  seg2a: Point64, seg2b: Point64, \n  inclusive: boolean = false\n): boolean {\n  if (!inclusive) {\n    // Match C# fast path - use cross product multiplication\n    // This avoids floating point equality checks (safer than === 0)\n    const s1 = crossProductSign(seg1a, seg2a, seg2b);\n    const s2 = crossProductSign(seg1b, seg2a, seg2b);\n    const s3 = crossProductSign(seg2a, seg1a, seg1b);\n    const s4 = crossProductSign(seg2b, seg1a, seg1b);\n    return (s1 !== 0 && s2 !== 0 && s1 !== s2) &&\n           (s3 !== 0 && s4 !== 0 && s3 !== s4);\n  }\n  \n  // Inclusive case - match C# implementation\n  const res1 = crossProductSign(seg1a, seg2a, seg2b);\n  const res2 = crossProductSign(seg1b, seg2a, seg2b);\n  if (res1 !== 0 && res1 === res2) return false;\n  const res3 = crossProductSign(seg2a, seg1a, seg1b);\n  const res4 = crossProductSign(seg2b, seg1a, seg1b);\n  if (res3 !== 0 && res3 === res4) return false;\n  // ensure NOT collinear\n  return (res1 !== 0 || res2 !== 0 || res3 !== 0 || res4 !== 0);\n}\n\nfunction icGetBounds(path: Path64): Rect64 {\n  if (path.length === 0) return { left: 0, top: 0, right: 0, bottom: 0 };\n  \n  const result: Rect64 = {\n    left: Number.MAX_SAFE_INTEGER,\n    top: Number.MAX_SAFE_INTEGER,\n    right: Number.MIN_SAFE_INTEGER,\n    bottom: Number.MIN_SAFE_INTEGER\n  };\n  \n  for (const pt of path) {\n    if (pt.x < result.left) result.left = pt.x;\n    if (pt.x > result.right) result.right = pt.x;\n    if (pt.y < result.top) result.top = pt.y;\n    if (pt.y > result.bottom) result.bottom = pt.y;\n  }\n  \n  return result.left === Number.MAX_SAFE_INTEGER ? \n    { left: 0, top: 0, right: 0, bottom: 0 } : result;\n}\n\nfunction getClosestPtOnSegment(offPt: Point64, seg1: Point64, seg2: Point64): Point64 {\n  if (seg1.x === seg2.x && seg1.y === seg2.y) return { x: seg1.x, y: seg1.y, z: 0 };  // Return copy, not reference\n  \n  const dx = (seg2.x - seg1.x);\n  const dy = (seg2.y - seg1.y);\n  const q = safeMultiplySum((offPt.x - seg1.x), dx, (offPt.y - seg1.y), dy) /\n    safeMultiplySum(dx, dx, dy, dy);\n  const qClamped = q < 0 ? 0 : (q > 1 ? 1 : q);\n  \n  return {\n    // use Math.round to match the C# MidpointRounding.ToEven behavior\n    x: Math.round(seg1.x + qClamped * dx),\n    y: Math.round(seg1.y + qClamped * dy),\n    z: 0\n  };\n}\n\nfunction icPointInPolygon(pt: Point64, polygon: Path64): PointInPolygonResult {\n  const len = polygon.length;\n  let start = 0;\n  if (len < 3) return PointInPolygonResult.IsOutside;\n\n  while (start < len && polygon[start].y === pt.y) start++;\n  if (start === len) return PointInPolygonResult.IsOutside;\n\n  let isAbove = polygon[start].y < pt.y;\n  const startingAbove = isAbove;\n  let val = 0;\n  let i = start + 1;\n  let end = len;\n  \n  while (true) {\n    if (i === end) {\n      if (end === 0 || start === 0) break;\n      end = start;\n      i = 0;\n    }\n\n    if (isAbove) {\n      while (i < end && polygon[i].y < pt.y) i++;\n    } else {\n      while (i < end && polygon[i].y > pt.y) i++;\n    }\n\n    if (i === end) continue;\n\n    const curr = polygon[i];\n    const prev = i > 0 ? polygon[i - 1] : polygon[len - 1];\n\n    if (curr.y === pt.y) {\n      if (curr.x === pt.x || (curr.y === prev.y &&\n        ((pt.x < prev.x) !== (pt.x < curr.x)))) {\n        return PointInPolygonResult.IsOn;\n      }\n      i++;\n      if (i === start) break;\n      continue;\n    }\n\n    if (pt.x < curr.x && pt.x < prev.x) {\n      // we're only interested in edges crossing on the left\n    } else if (pt.x > prev.x && pt.x > curr.x) {\n      val = 1 - val; // toggle val\n    } else {\n      const cps = crossProductSign(prev, curr, pt);\n      if (cps === 0) return PointInPolygonResult.IsOn;\n      if ((cps < 0) === isAbove) val = 1 - val;\n    }\n    isAbove = !isAbove;\n    i++;\n  }\n\n  if (isAbove === startingAbove) {\n    return val === 0 ? PointInPolygonResult.IsOutside : PointInPolygonResult.IsInside;\n  }\n  \n  if (i === len) i = 0;\n  const cps = i === 0 ? \n    crossProductSign(polygon[len - 1], polygon[0], pt) : \n    crossProductSign(polygon[i - 1], polygon[i], pt);\n  if (cps === 0) return PointInPolygonResult.IsOn;\n  if ((cps < 0) === isAbove) val = 1 - val;\n\n  return val === 0 ? PointInPolygonResult.IsOutside : PointInPolygonResult.IsInside;\n}\n\nfunction path2ContainsPath1(path1: Path64, path2: Path64): boolean {\n  // we need to make some accommodation for rounding errors\n  // so we won't jump if the first vertex is found outside\n  let pip = PointInPolygonResult.IsOn;\n  for (const pt of path1) {\n    switch (icPointInPolygon(pt, path2)) {\n      case PointInPolygonResult.IsOutside:\n        if (pip === PointInPolygonResult.IsOutside) return false;\n        pip = PointInPolygonResult.IsOutside;\n        break;\n      case PointInPolygonResult.IsInside:\n        if (pip === PointInPolygonResult.IsInside) return true;\n        pip = PointInPolygonResult.IsInside;\n        break;\n      default:\n        break;\n    }\n  }\n  // since path1's location is still equivocal, check its midpoint\n  const mp = icGetBounds(path1);\n  let midX: number, midY: number;\n  if (Number.isSafeInteger(mp.left) && Number.isSafeInteger(mp.right) &&\n      Math.abs(mp.left) + Math.abs(mp.right) > Number.MAX_SAFE_INTEGER) {\n    midX = Number((BigInt(mp.left) + BigInt(mp.right)) / B2);\n    midY = Number((BigInt(mp.top) + BigInt(mp.bottom)) / B2);\n  } else {\n    midX = Math.round((mp.left + mp.right) / 2);\n    midY = Math.round((mp.top + mp.bottom) / 2);\n  }\n  const midPt: Point64 = { x: midX, y: midY };\n  return icPointInPolygon(midPt, path2) !== PointInPolygonResult.IsOutside;\n}\n\n// Plain const object replaces the namespace. External callers use InternalClipper.foo()\n// unchanged; tsc emits a simple object literal instead of an IIFE.\nexport const InternalClipper = {\n  MaxInt64: IC_MaxInt64,\n  MaxCoord: IC_MaxCoord,\n  max_coord: IC_MaxCoord,\n  min_coord: -IC_MaxCoord,\n  Invalid64: IC_Invalid64,\n  floatingPointTolerance: IC_floatingPointTolerance,\n  defaultMinimumEdgeLength: IC_defaultMinimumEdgeLength,\n  maxCoordForSafeAreaProduct: IC_maxCoordForSafeAreaProduct,\n  maxCoordForSafeCrossSq: IC_maxCoordForSafeCrossSq,\n  maxSafeCoordinateForScale,\n  checkSafeScaleValue,\n  ensureSafeInteger,\n  crossProduct,\n  crossProductSign,\n  checkPrecision,\n  isAlmostZero,\n  triSign,\n  multiplyUInt64,\n  productsAreEqual,\n  isCollinear,\n  dotProduct,\n  dotProductSign,\n  area: icArea,\n  crossProductD,\n  dotProductD,\n  roundToEven,\n  checkCastInt64,\n  getLineIntersectPt,\n  getLineIntersectPtD,\n  segsIntersect,\n  getBounds: icGetBounds,\n  getClosestPtOnSegment,\n  pointInPolygon: icPointInPolygon,\n  path2ContainsPath1,\n}\n\n// Backward-compatible type namespace for consumers who used InternalClipper.UInt128Struct as a type.\n/** @deprecated Import UInt128Struct directly instead of using InternalClipper.UInt128Struct */\nexport namespace InternalClipper {\n  /** @deprecated Import UInt128Struct directly */\n  export type UInt128Struct = import('./Core.js').UInt128Struct;\n}\n\n// Point64 utility functions (plain object, avoids namespace IIFE)\nexport const Point64Utils = {\n  create(x: number = 0, y: number = 0, z: number = 0): Point64 {\n    return { x: Math.round(x), y: Math.round(y), z };\n  },\n\n  fromPointD(pt: PointD): Point64 {\n    InternalClipper.ensureSafeInteger(pt.x, \"Point64Utils.fromPointD\");\n    InternalClipper.ensureSafeInteger(pt.y, \"Point64Utils.fromPointD\");\n    return { x: Math.round(pt.x), y: Math.round(pt.y), z: pt.z || 0 };\n  },\n\n  scale(pt: Point64, scale: number): Point64 {\n    return {\n      x: Math.round(pt.x * scale),\n      y: Math.round(pt.y * scale),\n      z: pt.z || 0\n    };\n  },\n\n  equals(a: Point64, b: Point64): boolean {\n    return a.x === b.x && a.y === b.y;\n  },\n\n  add(a: Point64, b: Point64): Point64 {\n    if (Number.isSafeInteger(a.x) && Number.isSafeInteger(b.x) &&\n        Number.isSafeInteger(a.y) && Number.isSafeInteger(b.y)) {\n      const sumX = a.x + b.x;\n      const sumY = a.y + b.y;\n      if (Number.isSafeInteger(sumX) && Number.isSafeInteger(sumY)) {\n        return { x: sumX, y: sumY, z: 0 };\n      }\n      return { \n        x: Number(BigInt(a.x) + BigInt(b.x)), \n        y: Number(BigInt(a.y) + BigInt(b.y)), \n        z: 0 \n      };\n    }\n    return { x: a.x + b.x, y: a.y + b.y, z: 0 };\n  },\n\n  subtract(a: Point64, b: Point64): Point64 {\n    return { x: a.x - b.x, y: a.y - b.y, z: 0 };\n  },\n\n  toString(pt: Point64): string {\n    if (pt.z !== undefined && pt.z !== 0) {\n      return `${pt.x},${pt.y},${pt.z} `;\n    }\n    return `${pt.x},${pt.y} `;\n  },\n};\n\n// PointD utility functions (plain object, avoids namespace IIFE)\nexport const PointDUtils = {\n  create(x: number = 0, y: number = 0, z: number = 0): PointD {\n    return { x, y, z };\n  },\n\n  fromPoint64(pt: Point64): PointD {\n    return { x: pt.x, y: pt.y, z: pt.z || 0 };\n  },\n\n  scale(pt: PointD, scale: number): PointD {\n    return { x: pt.x * scale, y: pt.y * scale, z: pt.z || 0 };\n  },\n\n  equals(a: PointD, b: PointD): boolean {\n    return InternalClipper.isAlmostZero(a.x - b.x) && \n           InternalClipper.isAlmostZero(a.y - b.y);\n  },\n\n  negate(pt: PointD): void {\n    pt.x = -pt.x;\n    pt.y = -pt.y;\n  },\n\n  toString(pt: PointD, precision: number = 2): string {\n    if (pt.z !== undefined && pt.z !== 0) {\n      return `${pt.x.toFixed(precision)},${pt.y.toFixed(precision)},${pt.z}`;\n    }\n    return `${pt.x.toFixed(precision)},${pt.y.toFixed(precision)}`;\n  },\n};\n\n// Rect64 utility functions (plain object, avoids namespace IIFE)\nexport const Rect64Utils = {\n  create(l: number = 0, t: number = 0, r: number = 0, b: number = 0): Rect64 {\n    return { left: l, top: t, right: r, bottom: b };\n  },\n\n  createInvalid(): Rect64 {\n    return {\n      left: Number.MAX_SAFE_INTEGER,\n      top: Number.MAX_SAFE_INTEGER,\n      right: Number.MIN_SAFE_INTEGER,\n      bottom: Number.MIN_SAFE_INTEGER\n    };\n  },\n\n  width(rect: Rect64): number {\n    return rect.right - rect.left;\n  },\n\n  height(rect: Rect64): number {\n    return rect.bottom - rect.top;\n  },\n\n  isEmpty(rect: Rect64): boolean {\n    return rect.bottom <= rect.top || rect.right <= rect.left;\n  },\n\n  isValid(rect: Rect64): boolean {\n    return rect.left < Number.MAX_SAFE_INTEGER;\n  },\n\n  midPoint(rect: Rect64): Point64 {\n    if (Number.isSafeInteger(rect.left) && Number.isSafeInteger(rect.right) &&\n        Math.abs(rect.left) + Math.abs(rect.right) > Number.MAX_SAFE_INTEGER) {\n      const midX = Number((BigInt(rect.left) + BigInt(rect.right)) / B2);\n      const midY = Number((BigInt(rect.top) + BigInt(rect.bottom)) / B2);\n      return { x: midX, y: midY };\n    }\n    return {\n      x: Math.round((rect.left + rect.right) / 2),\n      y: Math.round((rect.top + rect.bottom) / 2)\n    };\n  },\n\n  contains(rect: Rect64, pt: Point64): boolean {\n    return pt.x > rect.left && pt.x < rect.right &&\n           pt.y > rect.top && pt.y < rect.bottom;\n  },\n\n  containsRect(rect: Rect64, rec: Rect64): boolean {\n    return rec.left >= rect.left && rec.right <= rect.right &&\n           rec.top >= rect.top && rec.bottom <= rect.bottom;\n  },\n\n  intersects(rect: Rect64, rec: Rect64): boolean {\n    return (Math.max(rect.left, rec.left) <= Math.min(rect.right, rec.right)) &&\n           (Math.max(rect.top, rec.top) <= Math.min(rect.bottom, rec.bottom));\n  },\n\n  asPath(rect: Rect64): Path64 {\n    return [\n      { x: rect.left, y: rect.top, z: 0 },\n      { x: rect.right, y: rect.top, z: 0 },\n      { x: rect.right, y: rect.bottom, z: 0 },\n      { x: rect.left, y: rect.bottom, z: 0 }\n    ];\n  },\n};\n\n// RectD utility functions (plain object, avoids namespace IIFE)\nexport const RectDUtils = {\n  create(l: number = 0, t: number = 0, r: number = 0, b: number = 0): RectD {\n    return { left: l, top: t, right: r, bottom: b };\n  },\n\n  createInvalid(): RectD {\n    return {\n      left: Number.MAX_VALUE,\n      top: Number.MAX_VALUE,\n      right: -Number.MAX_VALUE,\n      bottom: -Number.MAX_VALUE\n    };\n  },\n\n  width(rect: RectD): number {\n    return rect.right - rect.left;\n  },\n\n  height(rect: RectD): number {\n    return rect.bottom - rect.top;\n  },\n\n  isEmpty(rect: RectD): boolean {\n    return rect.bottom <= rect.top || rect.right <= rect.left;\n  },\n\n  midPoint(rect: RectD): PointD {\n    return {\n      x: (rect.left + rect.right) / 2,\n      y: (rect.top + rect.bottom) / 2\n    };\n  },\n\n  contains(rect: RectD, pt: PointD): boolean {\n    return pt.x > rect.left && pt.x < rect.right &&\n           pt.y > rect.top && pt.y < rect.bottom;\n  },\n\n  containsRect(rect: RectD, rec: RectD): boolean {\n    return rec.left >= rect.left && rec.right <= rect.right &&\n           rec.top >= rect.top && rec.bottom <= rect.bottom;\n  },\n\n  intersects(rect: RectD, rec: RectD): boolean {\n    return (Math.max(rect.left, rec.left) < Math.min(rect.right, rec.right)) &&\n           (Math.max(rect.top, rec.top) < Math.min(rect.bottom, rec.bottom));\n  },\n\n  asPath(rect: RectD): PathD {\n    return [\n      { x: rect.left, y: rect.top, z: 0 },\n      { x: rect.right, y: rect.top, z: 0 },\n      { x: rect.right, y: rect.bottom, z: 0 },\n      { x: rect.left, y: rect.bottom, z: 0 }\n    ];\n  },\n};\n\n// Path utility functions (plain object, avoids namespace IIFE)\nexport const PathUtils = {\n  toString64(path: Path64): string {\n    let result = \"\";\n    for (const pt of path) {\n      result += Point64Utils.toString(pt);\n    }\n    return result + '\\n';\n  },\n\n  toStringD(path: PathD, precision: number = 2): string {\n    let result = \"\";\n    for (const pt of path) {\n      result += PointDUtils.toString(pt, precision) + \", \";\n    }\n    if (result !== \"\") result = result.slice(0, -2);\n    return result;\n  },\n\n  reverse64(path: Path64): Path64 {\n    return [...path].reverse();\n  },\n\n  reverseD(path: PathD): PathD {\n    return [...path].reverse();\n  },\n};\n\nexport const PathsUtils = {\n  toString64(paths: Paths64): string {\n    let result = \"\";\n    for (const path of paths) {\n      result += PathUtils.toString64(path);\n    }\n    return result;\n  },\n\n  toStringD(paths: PathsD, precision: number = 2): string {\n    let result = \"\";\n    for (const path of paths) {\n      result += PathUtils.toStringD(path, precision) + \"\\n\";\n    }\n    return result;\n  },\n\n  reverse64(paths: Paths64): Paths64 {\n    return paths.map(path => PathUtils.reverse64(path));\n  },\n\n  reverseD(paths: PathsD): PathsD {\n    return paths.map(path => PathUtils.reverseD(path));\n  },\n};\n\n// Constants (frozen to prevent accidental mutation of shared singletons)\nexport const InvalidRect64: Rect64 = Object.freeze(Rect64Utils.createInvalid());\nexport const InvalidRectD: RectD = Object.freeze(RectDUtils.createInvalid());\n","/*******************************************************************************\n* Author    :  Angus Johnson                                                   *\n* Date      :  21 February 2026                                                *\n* Website   :  https://www.angusj.com                                          *\n* Copyright :  Angus Johnson 2010-2025                                         *\n* Purpose   :  This is the main polygon clipping module                        *\n* License   :  https://www.boost.org/LICENSE_1_0.txt                           *\n*******************************************************************************/\n\nimport {\n    Point64, Path64, PathD, Paths64, PathsD, Rect64,\n    ClipType, PathType, FillRule, PointInPolygonResult,\n    ZCallback64, ZCallbackD,\n    InternalClipper, Rect64Utils\n  } from './Core.js';\n\n// BigInt constants — avoid BigInt literal syntax (0n, 4n, etc.) to sidestep\n// terser BigInt constant-folding issues in some consuming build setups.\nconst B0 = BigInt(0);\nconst B2 = BigInt(2);\nconst B4 = BigInt(4);\n\n// Vertex: a pre-clipping data structure. It is used to separate polygons\n// into ascending and descending 'bounds' (or sides) that start at local\n// minima and ascend to a local maxima, before descending again.\nexport enum VertexFlags {\n  None = 0,\n  OpenStart = 1,\n  OpenEnd = 2,\n  LocalMax = 4,\n  LocalMin = 8\n}\n\n// C# keeps scanlines in a sorted list; here we use a heap to avoid O(n) splices.\nclass ScanlineHeap {\nprivate readonly data: number[] = [];\n\npush(value: number): void {\n  this.data.push(value);\n  this.siftUp(this.data.length - 1);\n}\n\npop(): number | null {\n  if (this.data.length === 0) return null;\n  const max = this.data[0];\n  const last = this.data.pop()!;\n  if (this.data.length > 0) {\n    this.data[0] = last;\n    this.siftDown(0);\n  }\n  return max;\n}\n\nclear(): void {\n  this.data.length = 0;\n}\n\n// Hole-sift: lift the value once, shift parents/children, then place.\n// Avoids temporary array allocation from destructuring swap on every step.\nprivate siftUp(index: number): void {\n  const val = this.data[index];\n  while (index > 0) {\n    const parent = (index - 1) >> 1;\n    if (this.data[parent] >= val) break;\n    this.data[index] = this.data[parent];\n    index = parent;\n  }\n  this.data[index] = val;\n}\n\nprivate siftDown(index: number): void {\n  const length = this.data.length;\n  const val = this.data[index];\n  while (true) {\n    const left = (index << 1) + 1;\n    if (left >= length) break;\n    const right = left + 1;\n    // Pick the larger child\n    let child = left;\n    if (right < length && this.data[right] > this.data[left]) child = right;\n    // If the larger child isn't greater than val, done\n    if (this.data[child] <= val) break;\n    this.data[index] = this.data[child];\n    index = child;\n  }\n  this.data[index] = val;\n}\n}\n\nexport class Vertex {\n  public readonly pt: Point64;\n  public next: Vertex | null = null;\n  public prev: Vertex | null = null;\n  public flags: VertexFlags;\n\n  constructor(pt: Point64, flags: VertexFlags, prev: Vertex | null) {\n    this.pt = pt;\n    this.flags = flags;\n    this.prev = prev;\n  }\n}\n\nexport class LocalMinima {\n  public readonly vertex: Vertex;\n  public readonly polytype: PathType;\n  public readonly isOpen: boolean;\n\n  constructor(vertex: Vertex, polytype: PathType, isOpen: boolean = false) {\n    this.vertex = vertex;\n    this.polytype = polytype;\n    this.isOpen = isOpen;\n  }\n\n  equals(other: LocalMinima | null): boolean {\n    return other !== null && this.vertex === other.vertex;\n  }\n}\n\n// deprecated: kept for backward compatibility, use new LocalMinima() directly\n// (no longer used internally for performance)\nexport function createLocalMinima(vertex: Vertex, polytype: PathType, isOpen: boolean = false): LocalMinima {\n  return new LocalMinima(vertex, polytype, isOpen);\n}\n\n// IntersectNode: a structure representing 2 intersecting edges.\n// Intersections must be sorted so they are processed from the largest\n// Y coordinates to the smallest while keeping edges adjacent.\nexport interface IntersectNode {\n  readonly pt: Point64;\n  readonly edge1: Active;\n  readonly edge2: Active;\n}\n\nexport function createIntersectNode(pt: Point64, edge1: Active, edge2: Active): IntersectNode {\n  // In C# this copies pt (struct semantics), but our sole caller (addNewIntersectNode)\n  // always passes a freshly-allocated point that goes out of scope immediately,\n  // so we can take ownership directly and skip the copy.\n  return { pt, edge1, edge2 };\n}\n\n// OutPt: vertex data structure for clipping solutions\nexport class OutPt {\n  public pt: Point64;\n  public next: OutPt | null;\n  public prev: OutPt;\n  public outrec: OutRec;\n  public horz: HorzSegment | null;\n\n  constructor(pt: Point64, outrec: OutRec) {\n    this.pt = pt;\n    this.outrec = outrec;\n    this.next = this;\n    this.prev = this;\n    this.horz = null;\n  }\n}\n\nexport enum JoinWith { None, Left, Right }\nexport enum HorzPosition { Bottom, Middle, Top }\n\n// OutRec: path data structure for clipping solutions\nexport class OutRec {\n  public idx: number = 0;\n  public owner: OutRec | null = null;\n  public frontEdge: Active | null = null;\n  public backEdge: Active | null = null;\n  public pts: OutPt | null = null;\n  public polypath: PolyPathBase | null = null;\n  public bounds: Rect64 = { left: 0, top: 0, right: 0, bottom: 0 };\n  public path: Path64 = [];\n  public isOpen: boolean = false;\n  public splits: number[] | null = null;\n  public recursiveSplit: OutRec | null = null;\n}\n\nexport class HorzSegment {\n  public leftOp: OutPt | null;\n  public rightOp: OutPt | null;\n  public leftToRight: boolean;\n\n  constructor(op: OutPt) {\n    this.leftOp = op;\n    this.rightOp = null;\n    this.leftToRight = true;\n  }\n}\n\nexport class HorzJoin {\n  public op1: OutPt | null;\n  public op2: OutPt | null;\n\n  constructor(ltor: OutPt, rtol: OutPt) {\n    this.op1 = ltor;\n    this.op2 = rtol;\n  }\n}\n\nfunction compareHorzSegments(hs1: HorzSegment, hs2: HorzSegment): number {\n  if (hs1.rightOp === null) {\n    return hs2.rightOp === null ? 0 : 1;\n  }\n  if (hs2.rightOp === null) return -1;\n  return hs1.leftOp!.pt.x - hs2.leftOp!.pt.x;\n}\n\nfunction compareIntersectNodes(a: IntersectNode, b: IntersectNode): number {\n  if (a.pt.y !== b.pt.y) return (a.pt.y > b.pt.y) ? -1 : 1;\n  if (a.pt.x !== b.pt.x) return (a.pt.x < b.pt.x) ? -1 : 1;\n  if (a.edge1.curX !== b.edge1.curX) return (a.edge1.curX < b.edge1.curX) ? -1 : 1;\n  return (a.edge2.curX < b.edge2.curX) ? -1 : (a.edge2.curX > b.edge2.curX) ? 1 : 0;\n}\n\n///////////////////////////////////////////////////////////////////\n// Important: UP and DOWN here are premised on Y-axis positive down\n// displays, which is the orientation used in Clipper's development.\n///////////////////////////////////////////////////////////////////\n\nexport class Active {\n  public bot: Point64 = { x: 0, y: 0 };\n  public top: Point64 = { x: 0, y: 0 };\n  public curX: number = 0; // current (updated at every new scanline) - keep as number but ensure integer precision\n  public dx: number = 0;\n  public windDx: number = 0; // 1 or -1 depending on winding direction\n  public windCount: number = 0;\n  public windCount2: number = 0; // winding count of the opposite polytype\n  public outrec: OutRec | null = null;\n\n  // AEL: 'active edge list' (Vatti's AET - active edge table)\n  //     a linked list of all edges (from left to right) that are present\n  //     (or 'active') within the current scanbeam (a horizontal 'beam' that\n  //     sweeps from bottom to top over the paths in the clipping operation).\n  public prevInAEL: Active | null = null;\n  public nextInAEL: Active | null = null;\n\n  // SEL: 'sorted edge list' (Vatti's ST - sorted table)\n  //     linked list used when sorting edges into their new positions at the\n  //     top of scanbeams, but also (re)used to process horizontals.\n  public prevInSEL: Active | null = null;\n  public nextInSEL: Active | null = null;\n  public jump: Active | null = null;\n  public vertexTop: Vertex | null = null;\n  public localMin: LocalMinima | null = null; // the bottom of an edge 'bound' (also Vatti)\n  public isLeftBound: boolean = false;\n  public joinWith: JoinWith = JoinWith.None;\n}\n\n// Plain object replaces namespace to avoid IIFE wrapper in tsc output.\nexport const ClipperEngine = {\n  addLocMin(vert: Vertex, polytype: PathType, isOpen: boolean, minimaList: LocalMinima[]): void {\n    // make sure the vertex is added only once ...\n    if ((vert.flags & VertexFlags.LocalMin) !== VertexFlags.None) return;\n    vert.flags |= VertexFlags.LocalMin;\n\n    const lm = new LocalMinima(vert, polytype, isOpen);\n    minimaList.push(lm);\n  },\n\n  addPathsToVertexList(\n    paths: Paths64, \n    polytype: PathType, \n    isOpen: boolean,\n    minimaList: LocalMinima[], \n    vertexList: Vertex[]\n  ): void {\n    for (let i = 0, len = paths.length; i < len; i++) {\n      const path = paths[i];\n      let v0: Vertex | null = null;\n      let prevV: Vertex | null = null;\n      \n      for (let j = 0, len2 = path.length; j < len2; j++) {\n        const pt = path[j];\n        if (v0 === null) {\n          v0 = new Vertex(pt, VertexFlags.None, null);\n          vertexList.push(v0);\n          prevV = v0;\n        } else if (!(prevV!.pt.x === pt.x && prevV!.pt.y === pt.y)) { // ie skips duplicates\n          const currV: Vertex = new Vertex(pt, VertexFlags.None, prevV);\n          vertexList.push(currV);\n          prevV!.next = currV;\n          prevV = currV;\n        }\n      }\n      \n      if (prevV?.prev == null) continue;\n      if (!isOpen && prevV!.pt.x === v0!.pt.x && prevV!.pt.y === v0!.pt.y) prevV = prevV!.prev;\n      prevV!.next = v0;\n      v0!.prev = prevV;\n      if (!isOpen && prevV!.next === prevV) continue;\n\n      // OK, we have a valid path\n      let goingUp: boolean;\n      if (isOpen) {\n        let currV = v0!.next;\n        while (currV !== v0 && currV!.pt.y === v0!.pt.y)\n          currV = currV!.next;\n        goingUp = currV!.pt.y <= v0!.pt.y;\n        if (goingUp) {\n          v0!.flags = VertexFlags.OpenStart;\n          ClipperEngine.addLocMin(v0!, polytype, true, minimaList);\n        } else {\n          v0!.flags = VertexFlags.OpenStart | VertexFlags.LocalMax;\n        }\n      } else { // closed path\n        prevV = v0!.prev;\n        while (prevV !== v0 && prevV!.pt.y === v0!.pt.y)\n          prevV = prevV!.prev;\n        if (prevV === v0)\n          continue; // only open paths can be completely flat\n        goingUp = prevV!.pt.y > v0!.pt.y;\n      }\n\n      const goingUp0 = goingUp;\n      prevV = v0;\n      let currV = v0!.next;\n      while (currV !== v0) {\n        if (currV!.pt.y > prevV!.pt.y && goingUp) {\n          prevV!.flags |= VertexFlags.LocalMax;\n          goingUp = false;\n        } else if (currV!.pt.y < prevV!.pt.y && !goingUp) {\n          goingUp = true;\n          ClipperEngine.addLocMin(prevV!, polytype, isOpen, minimaList);\n        }\n        prevV = currV;\n        currV = currV!.next;\n      }\n\n      if (isOpen) {\n        prevV!.flags |= VertexFlags.OpenEnd;\n        if (goingUp)\n          prevV!.flags |= VertexFlags.LocalMax;\n        else\n          ClipperEngine.addLocMin(prevV!, polytype, isOpen, minimaList);\n      } else if (goingUp !== goingUp0) {\n        if (goingUp0) ClipperEngine.addLocMin(prevV!, polytype, false, minimaList);\n        else prevV!.flags |= VertexFlags.LocalMax;\n      }\n    }\n  },\n};\n\nexport class ReuseableDataContainer64 {\n  private readonly minimaList: LocalMinima[];\n  private readonly vertexList: Vertex[];\n\n  constructor() {\n    this.minimaList = [];\n    this.vertexList = [];\n  }\n\n  public clear(): void {\n    this.minimaList.length = 0;\n    this.vertexList.length = 0;\n  }\n\n  public addPaths(paths: Paths64, pt: PathType, isOpen: boolean): void {\n    ClipperEngine.addPathsToVertexList(paths, pt, isOpen, this.minimaList, this.vertexList);\n  }\n}\n\nexport abstract class PolyPathBase {\n  protected parent: PolyPathBase | null;\n  protected children: PolyPathBase[] = [];\n\n  constructor(parent: PolyPathBase | null = null) {\n    this.parent = parent;\n  }\n\n  public get isHole(): boolean {\n    return this.getIsHole();\n  }\n\n  private getLevel(): number {\n    let result = 0;\n    let pp = this.parent;\n    while (pp !== null) {\n      ++result;\n      pp = pp.parent;\n    }\n    return result;\n  }\n\n  public get level(): number {\n    return this.getLevel();\n  }\n\n  private getIsHole(): boolean {\n    const lvl = this.getLevel();\n    return lvl !== 0 && (lvl & 1) === 0;\n  }\n\n  public get count(): number {\n    return this.children.length;\n  }\n\n  public abstract addChild(p: Path64): PolyPathBase;\n\n  public clear(): void {\n    this.children.length = 0;\n  }\n\n  protected toStringInternal(idx: number, level: number): string {\n    let result = \"\";\n    const padding = \"  \".repeat(level);\n    const plural = this.children.length === 1 ? \"\" : \"s\";\n    \n    if ((level & 1) === 0) {\n      result += `${padding}+- hole (${idx}) contains ${this.children.length} nested polygon${plural}.\\n`;\n    } else {\n      result += `${padding}+- polygon (${idx}) contains ${this.children.length} hole${plural}.\\n`;\n    }\n    \n    for (let i = 0; i < this.count; i++) {\n      if (this.children[i].count > 0) {\n        result += this.children[i].toStringInternal(i, level + 1);\n      }\n    }\n    return result;\n  }\n\n  public toString(): string {\n    if (this.level > 0) return \"\"; // only accept tree root\n    const plural = this.children.length === 1 ? \"\" : \"s\";\n    let result = `Polytree with ${this.children.length} polygon${plural}.\\n`;\n    for (let i = 0; i < this.count; i++) {\n      if (this.children[i].count > 0) {\n        result += this.children[i].toStringInternal(i, 1);\n      }\n    }\n    return result + '\\n';\n  }\n}\n\nexport class PolyPath64 extends PolyPathBase {\n  public polygon: Path64 | null = null; // polytree root's polygon == null\n\n  constructor(parent: PolyPathBase | null = null) {\n    super(parent);\n  }\n\n  public get poly(): Path64 | null {\n    return this.polygon;\n  }\n\n  public addChild(p: Path64): PolyPathBase {\n    const newChild = new PolyPath64(this);\n    newChild.polygon = p;\n    this.children.push(newChild);\n    return newChild;\n  }\n\n  public child(index: number): PolyPath64 {\n    if (index < 0 || index >= this.children.length) {\n      throw new Error(\"Index out of range\");\n    }\n    return this.children[index] as PolyPath64;\n  }\n\n  public area(): number {\n    let result = this.polygon === null ? 0 : Clipper.area(this.polygon);\n    for (const child of this.children) {\n      result += (child as PolyPath64).area();\n    }\n    return result;\n  }\n}\n\nexport class PolyPathD extends PolyPathBase {\n  public scale: number = 1.0;\n  private polygon: PathD | null = null;\n\n  constructor(parent: PolyPathBase | null = null) {\n    super(parent);\n  }\n\n  public get poly(): PathD | null {\n    return this.polygon;\n  }\n\n  public addChild(p: Path64): PolyPathBase {\n    const newChild = new PolyPathD(this);\n    newChild.scale = this.scale;\n    newChild.polygon = Clipper.scalePathD(p, 1 / this.scale);\n    this.children.push(newChild);\n    return newChild;\n  }\n\n  public addChildD(p: PathD): PolyPathBase {\n    const newChild = new PolyPathD(this);\n    newChild.scale = this.scale;\n    newChild.polygon = p;\n    this.children.push(newChild);\n    return newChild;\n  }\n\n  public child(index: number): PolyPathD {\n    if (index < 0 || index >= this.children.length) {\n      throw new Error(\"Index out of range\");\n    }\n    return this.children[index] as PolyPathD;\n  }\n\n  public area(): number {\n    let result = this.polygon === null ? 0 : Clipper.areaD(this.polygon);\n    for (const child of this.children) {\n      result += (child as PolyPathD).area();\n    }\n    return result;\n  }\n}\n\nexport class PolyTree64 extends PolyPath64 {}\n\nexport class PolyTreeD extends PolyPathD {\n  public get scaleValue(): number {\n    return this.scale;\n  }\n}\n\nexport class ClipperBase {\n  // When there are no open paths, a lot of open-path branching becomes dead code.\n  // We set this per execute to allow fast short-circuiting in hot helpers.\n  private static openPathsEnabled: boolean = true;\n\n  protected cliptype: ClipType = ClipType.NoClip;\n  protected fillrule: FillRule = FillRule.EvenOdd;\n  protected actives: Active | null = null;\n  protected sel: Active | null = null;\n  protected readonly minimaList: LocalMinima[] = [];\n  protected readonly intersectList: IntersectNode[] = [];\n  protected readonly vertexList: Vertex[] = [];\n  protected readonly outrecList: OutRec[] = [];\n  protected readonly scanlineHeap = new ScanlineHeap();\n  protected readonly scanlineSet = new Set<number>();\n  // For very small inputs, a heap + set can cost more than it saves.\n  // Use an array-based scanline mode initially, and upgrade to heap+set\n  // automatically if the scanline list grows beyond a threshold.\n  protected readonly scanlineArr: number[] = [];\n  protected useScanlineArray: boolean = false;\n  protected readonly horzSegList: HorzSegment[] = [];\n  protected readonly horzJoinList: HorzJoin[] = [];\n  protected currentLocMin: number = 0;\n  protected currentBotY: number = 0;\n  protected isSortedMinimaList: boolean = false;\n  protected hasOpenPaths: boolean = false;\n  protected usingPolytree: boolean = false;\n  protected succeeded: boolean = false;\n\n  // Cache Z callback for the duration of an execute to avoid repeated virtual calls\n  // to getZCallback() in hot paths.\n  protected zCallbackInternal: ZCallback64 | ZCallbackD | undefined = undefined;\n\n  public preserveCollinear: boolean = true;\n  public reverseSolution: boolean = false;\n\n  constructor() {}\n\n  // Z-coordinate callback support\n  // Override in subclasses (Clipper64/ClipperD) to provide callback\n  protected getZCallback(): ZCallback64 | ZCallbackD | undefined {\n    return undefined;\n  }\n\n  private xyEqual(pt1: Point64, pt2: Point64): boolean {\n    return pt1.x === pt2.x && pt1.y === pt2.y;\n  }\n\n  private setZ(ae1: Active, ae2: Active, intersectPt: Point64): void {\n    const zCallback = this.zCallbackInternal;\n    if (!zCallback) return;\n\n    // prioritize subject vertices over clip vertices\n    // and pass the subject vertices before clip vertices in the callback\n    if (ClipperBase.getPolyType(ae1) === PathType.Subject) {\n      if (this.xyEqual(intersectPt, ae1.bot)) {\n        intersectPt.z = ae1.bot.z ?? 0;\n      } else if (this.xyEqual(intersectPt, ae1.top)) {\n        intersectPt.z = ae1.top.z ?? 0;\n      } else if (this.xyEqual(intersectPt, ae2.bot)) {\n        intersectPt.z = ae2.bot.z ?? 0;\n      } else if (this.xyEqual(intersectPt, ae2.top)) {\n        intersectPt.z = ae2.top.z ?? 0;\n      } else {\n        intersectPt.z = 0; // DefaultZ\n      }\n      zCallback(ae1.bot, ae1.top, ae2.bot, ae2.top, intersectPt);\n    } else {\n      if (this.xyEqual(intersectPt, ae2.bot)) {\n        intersectPt.z = ae2.bot.z ?? 0;\n      } else if (this.xyEqual(intersectPt, ae2.top)) {\n        intersectPt.z = ae2.top.z ?? 0;\n      } else if (this.xyEqual(intersectPt, ae1.bot)) {\n        intersectPt.z = ae1.bot.z ?? 0;\n      } else if (this.xyEqual(intersectPt, ae1.top)) {\n        intersectPt.z = ae1.top.z ?? 0;\n      } else {\n        intersectPt.z = 0; // DefaultZ\n      }\n      zCallback(ae2.bot, ae2.top, ae1.bot, ae1.top, intersectPt);\n    }\n  }\n\n  // Helper functions\n  private static isOdd(val: number): boolean {\n    return (val & 1) !== 0;\n  }\n\nprivate static isHotEdge(ae: Active): boolean {\n  return ae.outrec != null;\n}\n\n  private static isOpen(ae: Active): boolean {\n    return ClipperBase.openPathsEnabled && ae.localMin!.isOpen;\n  }\n\n  private static isOpenEnd(ae: Active): boolean {\n    return ClipperBase.openPathsEnabled &&\n      ae.localMin!.isOpen &&\n      ClipperBase.isOpenEndVertex(ae.vertexTop!);\n  }\n\n  private static isOpenEndVertex(v: Vertex): boolean {\n    return (v.flags & (VertexFlags.OpenStart | VertexFlags.OpenEnd)) !== VertexFlags.None;\n  }\n\n  private static getPrevHotEdge(ae: Active): Active | null {\n    let prev = ae.prevInAEL;\n    // Fast path: when open paths are disabled, avoid calling isOpen() in the loop.\n    if (!ClipperBase.openPathsEnabled) {\n      while (prev !== null && !ClipperBase.isHotEdge(prev)) {\n        prev = prev.prevInAEL;\n      }\n      return prev;\n    }\n    while (prev !== null && (prev.localMin!.isOpen || !ClipperBase.isHotEdge(prev))) {\n      prev = prev.prevInAEL;\n    }\n    return prev;\n  }\n\nprivate static isFront(ae: Active): boolean {\n  return ae === ae.outrec!.frontEdge;\n}\n\n  /*******************************************************************************\n  *  Dx:                             0(90deg)                                    *\n  *                                  |                                           *\n  *               +inf (180deg) <--- o ---> -inf (0deg)                          *\n  *******************************************************************************/\n\n  private static getDx(pt1: Point64, pt2: Point64): number {\n    const dy = pt2.y - pt1.y;\n    if (dy !== 0) {\n      return (pt2.x - pt1.x) / dy;\n    }\n    return pt2.x > pt1.x ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY;\n  }\n\nprivate static topX(ae: Active, currentY: number): number {\n  if ((currentY === ae.top.y) || (ae.top.x === ae.bot.x)) return ae.top.x;\n  if (currentY === ae.bot.y) return ae.bot.x;\n\n  // use MidpointRounding.ToEven in order to explicitly match the nearbyint behaviour on the C++ side\n  return InternalClipper.roundToEven(ae.bot.x + ae.dx * (currentY - ae.bot.y));\n}\n\n  private static isHorizontal(ae: Active): boolean {\n    return ae.top.y === ae.bot.y;\n  }\n\n  private static isHeadingRightHorz(ae: Active): boolean {\n    return ae.dx === Number.NEGATIVE_INFINITY;\n  }\n\n  private static isHeadingLeftHorz(ae: Active): boolean {\n    return ae.dx === Number.POSITIVE_INFINITY;\n  }\n\n  private static getPolyType(ae: Active): PathType {\n    return ae.localMin!.polytype;\n  }\n\n  private static isSamePolyType(ae1: Active, ae2: Active): boolean {\n    return ae1.localMin!.polytype === ae2.localMin!.polytype;\n  }\n\n  private static setDx(ae: Active): void {\n    ae.dx = ClipperBase.getDx(ae.bot, ae.top);\n  }\n\n  private static nextVertex(ae: Active): Vertex {\n    return ae.windDx > 0 ? ae.vertexTop!.next! : ae.vertexTop!.prev!;\n  }\n\n  private static prevPrevVertex(ae: Active): Vertex {\n    return ae.windDx > 0 ? ae.vertexTop!.prev!.prev! : ae.vertexTop!.next!.next!;\n  }\n\n  private static isMaximaVertex(v: Vertex): boolean {\n    return (v.flags & VertexFlags.LocalMax) !== VertexFlags.None;\n  }\n\n  private static isMaximaEdge(ae: Active): boolean {\n    return (ae.vertexTop!.flags & VertexFlags.LocalMax) !== VertexFlags.None;\n  }\n\n  private static getMaximaPair(ae: Active): Active | null {\n    let ae2 = ae.nextInAEL;\n    while (ae2 !== null) {\n      if (ae2.vertexTop === ae.vertexTop) return ae2; // Found!\n      ae2 = ae2.nextInAEL;\n    }\n    return null;\n  }\n\n  // optimization (not in C# reference): fast bounding box overlap check for segment intersection\n  private boundingBoxesOverlap(p1: Point64, p2: Point64, p3: Point64, p4: Point64): boolean {\n    // segment 1: p1-p2, segment 2: p3-p4\n    const min1x = Math.min(p1.x, p2.x);\n    const max1x = Math.max(p1.x, p2.x);\n    const min1y = Math.min(p1.y, p2.y);\n    const max1y = Math.max(p1.y, p2.y);\n    \n    const min2x = Math.min(p3.x, p4.x);\n    const max2x = Math.max(p3.x, p4.x);\n    const min2y = Math.min(p3.y, p4.y);\n    const max2y = Math.max(p3.y, p4.y);\n    \n    return !(max1x < min2x || max2x < min1x || max1y < min2y || max2y < min1y);\n  }\n\n  protected clearSolutionOnly(): void {\n    while (this.actives !== null) this.deleteFromAEL(this.actives);\n    this.scanlineHeap.clear();\n    this.scanlineSet.clear();\n    this.scanlineArr.length = 0;\n    this.disposeIntersectNodes();\n    this.outrecList.length = 0;\n    this.horzSegList.length = 0;\n    this.horzJoinList.length = 0;\n  }\n\n  public clear(): void {\n    this.clearSolutionOnly();\n    this.minimaList.length = 0;\n    this.vertexList.length = 0;\n    this.currentLocMin = 0;\n    this.isSortedMinimaList = false;\n    this.hasOpenPaths = false;\n  }\n\n  protected reset(): void {\n    if (!this.isSortedMinimaList) {\n      this.minimaList.sort((a, b) => b.vertex.pt.y - a.vertex.pt.y);\n      this.isSortedMinimaList = true;\n    }\n\n    this.scanlineHeap.clear();\n    this.scanlineSet.clear();\n    this.scanlineArr.length = 0;\n    // Heuristic: local minima count correlates with number of scanlines and\n    // scanline insert/pop activity. For glyph-like inputs, this is typically small.\n    this.useScanlineArray = this.minimaList.length <= 16;\n    for (let i = this.minimaList.length - 1; i >= 0; i--) {\n      this.insertScanline(this.minimaList[i].vertex.pt.y);\n    }\n\n    this.currentBotY = 0;\n    this.currentLocMin = 0;\n    this.actives = null;\n    this.sel = null;\n    this.succeeded = true;\n  }\n\n  private upgradeScanlineStructureFromArray(): void {\n    // Convert scanlineArr -> scanlineSet + scanlineHeap\n    // (scanlineArr is already unique by construction).\n    const arr = this.scanlineArr;\n    for (let i = 0, len = arr.length; i < len; i++) {\n      const y = arr[i];\n      this.scanlineSet.add(y);\n      this.scanlineHeap.push(y);\n    }\n    arr.length = 0;\n    this.useScanlineArray = false;\n  }\n\n  private insertScanline(y: number): void {\n    if (this.useScanlineArray) {\n      const arr = this.scanlineArr;\n      for (let i = 0, len = arr.length; i < len; i++) {\n        if (arr[i] === y) return;\n      }\n      arr.push(y);\n      // Upgrade when scanline count grows beyond \"small\".\n      // This keeps the small-case win while avoiding O(n) scans for large cases.\n      if (arr.length > 64) this.upgradeScanlineStructureFromArray();\n      return;\n    }\n    if (this.scanlineSet.has(y)) return;\n    this.scanlineSet.add(y);\n    this.scanlineHeap.push(y);\n  }\n\n  // Returns the next scanline Y value, or null if empty.\n  // Avoids allocating a wrapper object on every call in the main sweep loop.\n  private popScanline(): number | null {\n    if (this.useScanlineArray) {\n      const arr = this.scanlineArr;\n      const len = arr.length;\n      if (len === 0) return null;\n      let bestIdx = 0;\n      let bestY = arr[0];\n      for (let i = 1; i < len; i++) {\n        const v = arr[i];\n        if (v > bestY) {\n          bestY = v;\n          bestIdx = i;\n        }\n      }\n      arr[bestIdx] = arr[len - 1];\n      arr.pop();\n      return bestY;\n    }\n    const y = this.scanlineHeap.pop();\n    if (y === null) return null;\n    this.scanlineSet.delete(y);\n    return y;\n  }\n\n  private hasLocMinAtY(y: number): boolean {\n    return this.currentLocMin < this.minimaList.length && \n            this.minimaList[this.currentLocMin].vertex.pt.y === y;\n  }\n\n  private popLocalMinima(): LocalMinima {\n    return this.minimaList[this.currentLocMin++];\n  }\n\n  protected addPath(path: Path64, polytype: PathType, isOpen: boolean = false): void {\n    const tmp: Paths64 = [path];\n    this.addPaths(tmp, polytype, isOpen);\n  }\n\n  protected addPaths(paths: Paths64, polytype: PathType, isOpen: boolean = false): void {\n    if (isOpen) this.hasOpenPaths = true;\n    this.isSortedMinimaList = false;\n    ClipperEngine.addPathsToVertexList(paths, polytype, isOpen, this.minimaList, this.vertexList);\n  }\n\n  protected addReuseableData(reuseableData: ReuseableDataContainer64): void {\n    if (reuseableData['minimaList'].length === 0) return;\n    // nb: reuseableData will continue to own the vertices, so it's important\n    // that the reuseableData object isn't destroyed before the Clipper object\n    // that's using the data.\n    this.isSortedMinimaList = false;\n    for (const lm of reuseableData['minimaList']) {\n      this.minimaList.push(new LocalMinima(lm.vertex, lm.polytype, lm.isOpen));\n      if (lm.isOpen) this.hasOpenPaths = true;\n    }\n  }\n\n  private deleteFromAEL(ae: Active): void {\n    const prev = ae.prevInAEL;\n    const next = ae.nextInAEL;\n    if (prev === null && next === null && (ae !== this.actives)) return; // already deleted\n    if (prev !== null) {\n      prev.nextInAEL = next;\n    } else {\n      this.actives = next;\n    }\n    if (next !== null) next.prevInAEL = prev;\n    // delete ae;\n  }\n\n  public getBounds(): Rect64 {\n    const bounds: Rect64 = {\n      left: Number.MAX_SAFE_INTEGER,\n      top: Number.MAX_SAFE_INTEGER,\n      right: Number.MIN_SAFE_INTEGER,\n      bottom: Number.MIN_SAFE_INTEGER\n    };\n    \n    for (const t of this.vertexList) {\n      let v = t;\n      do {\n        if (v.pt.x < bounds.left) bounds.left = v.pt.x;\n        if (v.pt.x > bounds.right) bounds.right = v.pt.x;\n        if (v.pt.y < bounds.top) bounds.top = v.pt.y;\n        if (v.pt.y > bounds.bottom) bounds.bottom = v.pt.y;\n        v = v.next!;\n      } while (v !== t);\n    }\n    \n    return Rect64Utils.isEmpty(bounds) ? { left: 0, top: 0, right: 0, bottom: 0 } : bounds;\n  }\n\nprotected executeInternal(ct: ClipType, fillRule: FillRule): void {\n  if (ct === ClipType.NoClip) return;\n  ClipperBase.openPathsEnabled = this.hasOpenPaths;\n  this.zCallbackInternal = this.getZCallback();\n  this.fillrule = fillRule;\n  this.cliptype = ct;\n  this.reset();\n  \n  let y = this.popScanline();\n  if (y === null) return;\n  \n  while (this.succeeded) {\n    this.insertLocalMinimaIntoAEL(y);\n    let ae: Active | null;\n    while ((ae = this.popHorz()) !== null) this.doHorizontal(ae);\n    if (this.horzSegList.length > 0) {\n      this.convertHorzSegsToJoins();\n      this.horzSegList.length = 0;\n    }\n    this.currentBotY = y; // bottom of scanbeam\n    const nextY = this.popScanline();\n    if (nextY === null) break; // y new top of scanbeam\n    y = nextY;\n    this.doIntersections(y);\n    this.doTopOfScanbeam(y);\n    while ((ae = this.popHorz()) !== null) this.doHorizontal(ae);\n  }\n  if (this.succeeded) this.processHorzJoins();\n}\n\n  private insertLocalMinimaIntoAEL(botY: number): void {\n    // Add any local minima (if any) at BotY ...\n    // NB horizontal local minima edges should contain locMin.vertex.prev\n    while (this.hasLocMinAtY(botY)) {\n      const localMinima = this.popLocalMinima();\n      let leftBound: Active | null;\n      \n      if ((localMinima.vertex.flags & VertexFlags.OpenStart) !== VertexFlags.None) {\n        leftBound = null;\n      } else {\n        leftBound = new Active();\n        // Avoid copying points (and avoid materializing z=0) for speed.\n        leftBound.bot = localMinima.vertex.pt;\n        leftBound.curX = localMinima.vertex.pt.x;\n        leftBound.windDx = -1;\n        leftBound.vertexTop = localMinima.vertex.prev;\n        leftBound.top = localMinima.vertex.prev!.pt;\n        leftBound.outrec = null;\n        leftBound.localMin = localMinima;\n        ClipperBase.setDx(leftBound);\n      }\n\n      let rightBound: Active | null;\n      if ((localMinima.vertex.flags & VertexFlags.OpenEnd) !== VertexFlags.None) {\n        rightBound = null;\n      } else {\n        rightBound = new Active();\n        // Avoid copying points (and avoid materializing z=0) for speed.\n        rightBound.bot = localMinima.vertex.pt;\n        rightBound.curX = localMinima.vertex.pt.x;\n        rightBound.windDx = 1;\n        rightBound.vertexTop = localMinima.vertex.next; // i.e. ascending\n        rightBound.top = localMinima.vertex.next!.pt;\n        rightBound.outrec = null;\n        rightBound.localMin = localMinima;\n        ClipperBase.setDx(rightBound);\n      }\n\n      // Currently LeftB is just the descending bound and RightB is the ascending.\n      // Now if the LeftB isn't on the left of RightB then we need swap them.\n      if (leftBound !== null && rightBound !== null) {\n        if (ClipperBase.isHorizontal(leftBound)) {\n          if (ClipperBase.isHeadingRightHorz(leftBound)) {\n            const tmp = leftBound;\n            leftBound = rightBound;\n            rightBound = tmp;\n          }\n        } else if (ClipperBase.isHorizontal(rightBound)) {\n          if (ClipperBase.isHeadingLeftHorz(rightBound)) {\n            const tmp = leftBound;\n            leftBound = rightBound;\n            rightBound = tmp;\n          }\n        } else if (leftBound.dx < rightBound.dx) {\n          const tmp = leftBound;\n          leftBound = rightBound;\n          rightBound = tmp;\n        }\n      } else if (leftBound === null) {\n        leftBound = rightBound;\n        rightBound = null;\n      }\n\n      let contributing: boolean;\n      leftBound!.isLeftBound = true;\n      this.insertLeftEdge(leftBound!);\n\n      if (!ClipperBase.openPathsEnabled) {\n        // Closed-path-only fast path.\n        this.setWindCountForClosedPathEdge(leftBound!);\n        contributing = this.isContributingClosed(leftBound!);\n      } else if (ClipperBase.isOpen(leftBound!)) {\n        this.setWindCountForOpenPathEdge(leftBound!);\n        contributing = this.isContributingOpen(leftBound!);\n      } else {\n        this.setWindCountForClosedPathEdge(leftBound!);\n        contributing = this.isContributingClosed(leftBound!);\n      }\n\n      if (rightBound !== null) {\n        rightBound.windCount = leftBound!.windCount;\n        rightBound.windCount2 = leftBound!.windCount2;\n        this.insertRightEdge(leftBound!, rightBound);\n\n        if (contributing) {\n          this.addLocalMinPoly(leftBound!, rightBound, leftBound!.bot, true);\n          if (!ClipperBase.isHorizontal(leftBound!)) {\n            this.checkJoinLeft(leftBound!, leftBound!.bot);\n          }\n        }\n\n        while (rightBound.nextInAEL !== null &&\n                this.isValidAelOrder(rightBound.nextInAEL, rightBound)) {\n          this.intersectEdges(rightBound, rightBound.nextInAEL, rightBound.bot);\n          this.swapPositionsInAEL(rightBound, rightBound.nextInAEL);\n        }\n\n        if (ClipperBase.isHorizontal(rightBound)) {\n          this.pushHorz(rightBound);\n        } else {\n          this.checkJoinRight(rightBound, rightBound.bot);\n          this.insertScanline(rightBound.top.y);\n        }\n      } else if (contributing && ClipperBase.openPathsEnabled) {\n        this.startOpenPath(leftBound!, leftBound!.bot);\n      }\n\n      if (ClipperBase.isHorizontal(leftBound!)) {\n        this.pushHorz(leftBound!);\n      } else {\n        this.insertScanline(leftBound!.top.y);\n      }\n    }\n  }\n\n  private pushHorz(ae: Active): void {\n    ae.nextInSEL = this.sel;\n    this.sel = ae;\n  }\n\n  private popHorz(): Active | null {\n    const ae = this.sel;\n    if (ae === null) return null;\n    this.sel = this.sel!.nextInSEL;\n    return ae;\n  }\n\n  private doHorizontal(horz: Active): void {\n    if (!ClipperBase.openPathsEnabled) {\n      this.doHorizontalClosed(horz);\n      return;\n    }\n\n    const horzIsOpen = ClipperBase.isOpen(horz);\n    const y = horz.bot.y;\n\n    const vertexMax = horzIsOpen ?\n      this.getCurrYMaximaVertexOpen(horz) :\n      this.getCurrYMaximaVertex(horz);\n\n    const { isLeftToRight, leftX, rightX } = this.resetHorzDirection(horz, vertexMax);\n    let leftX2 = leftX;\n    let rightX2 = rightX;\n\n    if (ClipperBase.isHotEdge(horz)) {\n      const op = this.addOutPt(horz, { x: horz.curX, y });\n      this.addToHorzSegList(op);\n    }\n\n    while (true) {\n      // loops through consec. horizontal edges (if open)\n      let ae = isLeftToRight ? horz.nextInAEL : horz.prevInAEL;\n\n      while (ae !== null) {\n        if (ae.vertexTop === vertexMax) {\n          // do this first!!\n          if (ClipperBase.isHotEdge(horz) && this.isJoined(ae)) this.split(ae, ae.top);\n\n          if (ClipperBase.isHotEdge(horz)) {\n            while (horz.vertexTop !== vertexMax) {\n              this.addOutPt(horz, horz.top);\n              this.updateEdgeIntoAEL(horz);\n            }\n            if (isLeftToRight) {\n              this.addLocalMaxPoly(horz, ae, horz.top);\n            } else {\n              this.addLocalMaxPoly(ae, horz, horz.top);\n            }\n          }\n          this.deleteFromAEL(ae);\n          this.deleteFromAEL(horz);\n          return;\n        }\n\n        // if horzEdge is a maxima, keep going until we reach\n        // its maxima pair, otherwise check for break conditions\n        if (vertexMax !== horz.vertexTop || ClipperBase.isOpenEnd(horz)) {\n          // otherwise stop when 'ae' is beyond the end of the horizontal line\n          if ((isLeftToRight && ae.curX > rightX2) ||\n              (!isLeftToRight && ae.curX < leftX2)) break;\n\n          if (ae.curX === horz.top.x && !ClipperBase.isHorizontal(ae)) {\n            const pt = ClipperBase.nextVertex(horz).pt;\n\n            // to maximize the possibility of putting open edges into\n            // solutions, we'll only break if it's past HorzEdge's end\n            if (ClipperBase.isOpen(ae) && !ClipperBase.isSamePolyType(ae, horz) && !ClipperBase.isHotEdge(ae)) {\n              if ((isLeftToRight && (ClipperBase.topX(ae, pt.y) > pt.x)) ||\n                (!isLeftToRight && (ClipperBase.topX(ae, pt.y) < pt.x))) break;\n            }\n            // otherwise for edges at horzEdge's end, only stop when horzEdge's\n            // outslope is greater than e's slope when heading right or when\n            // horzEdge's outslope is less than e's slope when heading left.\n            else if ((isLeftToRight && (ClipperBase.topX(ae, pt.y) >= pt.x)) ||\n                (!isLeftToRight && (ClipperBase.topX(ae, pt.y) <= pt.x))) break;\n          }\n        }\n\n        const pt = { x: ae.curX, y };\n\n        if (isLeftToRight) {\n          this.intersectEdges(horz, ae, pt);\n          this.swapPositionsInAEL(horz, ae);\n          this.checkJoinLeft(ae, pt);\n          horz.curX = ae.curX;\n          ae = horz.nextInAEL;\n        } else {\n          this.intersectEdges(ae, horz, pt);\n          this.swapPositionsInAEL(ae, horz);\n          this.checkJoinRight(ae, pt);\n          horz.curX = ae.curX;\n          ae = horz.prevInAEL;\n        }\n\n        if (ClipperBase.isHotEdge(horz)) {\n          this.addToHorzSegList(this.getLastOp(horz));\n        }\n      }\n\n      // check if we've finished looping\n      // through consecutive horizontals\n      if (horzIsOpen && ClipperBase.isOpenEnd(horz)) { // ie open at top\n        if (ClipperBase.isHotEdge(horz)) {\n          this.addOutPt(horz, horz.top);\n          if (ClipperBase.isFront(horz)) {\n            horz.outrec!.frontEdge = null;\n          } else {\n            horz.outrec!.backEdge = null;\n          }\n          horz.outrec = null;\n        }\n        this.deleteFromAEL(horz);\n        return;\n      }\n      if (ClipperBase.nextVertex(horz).pt.y !== horz.top.y) {\n        break;\n      }\n\n      //still more horizontals in bound to process ...\n      if (ClipperBase.isHotEdge(horz)) {\n        this.addOutPt(horz, horz.top);\n      }\n\n      this.updateEdgeIntoAEL(horz);\n\n      const resetResult = this.resetHorzDirection(horz, vertexMax);\n      leftX2 = resetResult.leftX;\n      rightX2 = resetResult.rightX;\n    }\n\n    if (ClipperBase.isHotEdge(horz)) {\n      const op = this.addOutPt(horz, horz.top);\n      this.addToHorzSegList(op);\n    }\n\n    this.updateEdgeIntoAEL(horz); // this is the end of an intermediate horiz.\n  }\n\n  // Closed-path-only horizontal processing (no open-path branching).\n  private doHorizontalClosed(horz: Active): void {\n    const y = horz.bot.y;\n    const vertexMax = this.getCurrYMaximaVertex(horz);\n\n    const { isLeftToRight, leftX, rightX } = this.resetHorzDirection(horz, vertexMax);\n    let leftX2 = leftX;\n    let rightX2 = rightX;\n\n    if (ClipperBase.isHotEdge(horz)) {\n      const op = this.addOutPt(horz, { x: horz.curX, y });\n      this.addToHorzSegList(op);\n    }\n\n    while (true) {\n      let ae = isLeftToRight ? horz.nextInAEL : horz.prevInAEL;\n\n      while (ae !== null) {\n        if (ae.vertexTop === vertexMax) {\n          if (ClipperBase.isHotEdge(horz) && this.isJoined(ae)) this.split(ae, ae.top);\n\n          if (ClipperBase.isHotEdge(horz)) {\n            while (horz.vertexTop !== vertexMax) {\n              this.addOutPt(horz, horz.top);\n              this.updateEdgeIntoAEL(horz);\n            }\n            if (isLeftToRight) {\n              this.addLocalMaxPoly(horz, ae, horz.top);\n            } else {\n              this.addLocalMaxPoly(ae, horz, horz.top);\n            }\n          }\n          this.deleteFromAEL(ae);\n          this.deleteFromAEL(horz);\n          return;\n        }\n\n        // if horzEdge is a maxima, keep going until we reach its maxima pair,\n        // otherwise check for break conditions\n        if (vertexMax !== horz.vertexTop) {\n          if ((isLeftToRight && ae.curX > rightX2) || (!isLeftToRight && ae.curX < leftX2)) break;\n\n          if (ae.curX === horz.top.x && !ClipperBase.isHorizontal(ae)) {\n            const nextPt = ClipperBase.nextVertex(horz).pt;\n            const tx = ClipperBase.topX(ae, nextPt.y);\n            if ((isLeftToRight && tx >= nextPt.x) || (!isLeftToRight && tx <= nextPt.x)) break;\n          }\n        }\n\n        const pt = { x: ae.curX, y };\n\n        if (isLeftToRight) {\n          this.intersectEdges(horz, ae, pt);\n          this.swapPositionsInAEL(horz, ae);\n          this.checkJoinLeft(ae, pt);\n          horz.curX = ae.curX;\n          ae = horz.nextInAEL;\n        } else {\n          this.intersectEdges(ae, horz, pt);\n          this.swapPositionsInAEL(ae, horz);\n          this.checkJoinRight(ae, pt);\n          horz.curX = ae.curX;\n          ae = horz.prevInAEL;\n        }\n\n        if (ClipperBase.isHotEdge(horz)) {\n          this.addToHorzSegList(this.getLastOp(horz));\n        }\n      }\n\n      if (ClipperBase.nextVertex(horz).pt.y !== horz.top.y) {\n        break;\n      }\n\n      // still more horizontals in bound to process ...\n      if (ClipperBase.isHotEdge(horz)) {\n        this.addOutPt(horz, horz.top);\n      }\n\n      this.updateEdgeIntoAEL(horz);\n\n      const resetResult = this.resetHorzDirection(horz, vertexMax);\n      leftX2 = resetResult.leftX;\n      rightX2 = resetResult.rightX;\n    }\n\n    if (ClipperBase.isHotEdge(horz)) {\n      const op = this.addOutPt(horz, horz.top);\n      this.addToHorzSegList(op);\n    }\n\n    this.updateEdgeIntoAEL(horz); // this is the end of an intermediate horiz.\n  }\n\n  private convertHorzSegsToJoins(): void {\n    let k = 0;\n    for (const hs of this.horzSegList) {\n      if (this.updateHorzSegment(hs)) k++;\n    }\n    if (k < 2) return;\n    \n    this.horzSegList.sort(compareHorzSegments);\n\n    for (let i = 0; i < k - 1; i++) {\n      const hs1 = this.horzSegList[i];\n      // for each HorzSegment, find others that overlap\n      for (let j = i + 1; j < k; j++) {\n        const hs2 = this.horzSegList[j];\n        if ((hs2.leftOp!.pt.x >= hs1.rightOp!.pt.x) || \n          (hs2.leftToRight === hs1.leftToRight) ||\n          (hs2.rightOp!.pt.x <= hs1.leftOp!.pt.x)) continue;\n        const currY = hs1.leftOp!.pt.y;\n        if (hs1.leftToRight) {\n          while (hs1.leftOp!.next!.pt.y === currY &&\n            hs1.leftOp!.next!.pt.x <= hs2.leftOp!.pt.x)\n            hs1.leftOp = hs1.leftOp!.next;\n          while (hs2.leftOp!.prev.pt.y === currY &&\n            hs2.leftOp!.prev.pt.x <= hs1.leftOp!.pt.x)\n            hs2.leftOp = hs2.leftOp!.prev;\n          const join = new HorzJoin(\n            this.duplicateOp(hs1.leftOp!, true),\n            this.duplicateOp(hs2.leftOp!, false));\n          this.horzJoinList.push(join);\n        } else {\n          while (hs1.leftOp!.prev.pt.y === currY &&\n            hs1.leftOp!.prev.pt.x <= hs2.leftOp!.pt.x)\n            hs1.leftOp = hs1.leftOp!.prev;\n          while (hs2.leftOp!.next!.pt.y === currY &&\n            hs2.leftOp!.next!.pt.x <= hs1.leftOp!.pt.x)\n            hs2.leftOp = hs2.leftOp!.next;\n          const join = new HorzJoin(\n            this.duplicateOp(hs2.leftOp!, true),\n            this.duplicateOp(hs1.leftOp!, false));\n          this.horzJoinList.push(join);\n        }\n      }\n    }\n  }\n\n  private updateHorzSegment(hs: HorzSegment): boolean {\n    const op = hs.leftOp!;\n    const outrec = this.getRealOutRec(op.outrec)!;\n    const outrecHasEdges = outrec.frontEdge !== null;\n    const currY = op.pt.y;\n    let opP = op;\n    let opN = op;\n    \n    if (outrecHasEdges) {\n      const opA = outrec.pts!;\n      const opZ = opA.next!;\n      while (opP !== opZ && opP.prev.pt.y === currY)\n        opP = opP.prev;\n      while (opN !== opA && opN.next!.pt.y === currY)\n        opN = opN.next!;\n    } else {\n      while (opP.prev !== opN && opP.prev.pt.y === currY)\n        opP = opP.prev;\n      while (opN.next !== opP && opN.next!.pt.y === currY)\n        opN = opN.next!;\n    }\n    \n    const result = this.setHorzSegHeadingForward(hs, opP, opN) && hs.leftOp!.horz === null;\n\n    if (result) {\n      hs.leftOp!.horz = hs;\n    } else {\n      hs.rightOp = null; // (for sorting)\n    }\n    return result;\n  }\n\n  private setHorzSegHeadingForward(hs: HorzSegment, opP: OutPt, opN: OutPt): boolean {\n    if (opP.pt.x === opN.pt.x) return false;\n    if (opP.pt.x < opN.pt.x) {\n      hs.leftOp = opP;\n      hs.rightOp = opN;\n      hs.leftToRight = true;\n    } else {\n      hs.leftOp = opN;\n      hs.rightOp = opP;\n      hs.leftToRight = false;\n    }\n    return true;\n  }\n\n  protected duplicateOp(op: OutPt, insertAfter: boolean): OutPt {\n    const result = new OutPt(op.pt, op.outrec);\n    if (insertAfter) {\n      result.next = op.next;\n      result.next!.prev = result;\n      result.prev = op;\n      op.next = result;\n    } else {\n      result.prev = op.prev;\n      result.prev.next = result;\n      result.next = op;\n      op.prev = result;\n    }\n    return result;\n  }\n\n  protected getRealOutRec(outRec: OutRec | null): OutRec | null {\n    while (outRec !== null && outRec.pts === null) {\n      outRec = outRec.owner;\n    }\n    return outRec;\n  }\n\n  private doIntersections(y: number): void {\n    if (this.buildIntersectList(y)) {\n      this.processIntersectList();\n      this.disposeIntersectNodes();\n    }\n  }\n\n  private doTopOfScanbeam(y: number): void {\n    this.sel = null; // sel is reused to flag horizontals (see PushHorz below)\n    let ae = this.actives;\n    while (ae !== null) {\n      // NB 'ae' will never be horizontal here\n      if (ae.top.y === y) {\n        ae.curX = ae.top.x;\n        if (ClipperBase.isMaximaEdge(ae)) {\n          ae = this.doMaxima(ae); // TOP OF BOUND (MAXIMA)\n          continue;\n        } else {\n          // INTERMEDIATE VERTEX ...\n          if (ClipperBase.isHotEdge(ae)) this.addOutPt(ae, ae.top);\n          this.updateEdgeIntoAEL(ae);\n          if (ClipperBase.isHorizontal(ae)) {\n            this.pushHorz(ae); // horizontals are processed later\n          }\n        }\n      } else { // i.e. not the top of the edge\n        ae.curX = ClipperBase.topX(ae, y);  // TopX already returns correctly rounded integer\n      }\n\n      ae = ae.nextInAEL;\n    }\n  }\n\n  private processHorzJoins(): void {\n    for (const j of this.horzJoinList) {\n      const or1 = this.getRealOutRec(j.op1!.outrec)!;\n      const or2 = this.getRealOutRec(j.op2!.outrec)!;\n\n      const op1b = j.op1!.next!;\n      const op2b = j.op2!.prev;\n      j.op1!.next = j.op2;\n      j.op2!.prev = j.op1!;\n      op1b.prev = op2b;\n      op2b.next = op1b;\n\n      if (or1 === or2) { // 'join' is really a split\n        const or2New = this.newOutRec();\n        or2New.pts = op1b;\n        this.fixOutRecPts(or2New);\n\n        //if or1->pts has moved to or2 then update or1->pts!!\n        if (or1.pts!.outrec === or2New) {\n          or1.pts = j.op1;\n          or1.pts!.outrec = or1;\n        }\n\n        if (this.usingPolytree) {\n          if (this.path1InsidePath2(or1.pts!, or2New.pts!)) {\n            //swap or1's & or2's pts\n            [or2New.pts, or1.pts] = [or1.pts, or2New.pts];\n            this.fixOutRecPts(or1);\n            this.fixOutRecPts(or2New);\n            //or2 is now inside or1\n            or2New.owner = or1;\n          } else if (this.path1InsidePath2(or2New.pts!, or1.pts!)) {\n            or2New.owner = or1;\n          } else {\n            or2New.owner = or1.owner;\n          }\n\n          if (or1.splits === null) or1.splits = [];\n          or1.splits.push(or2New.idx);\n        } else {\n          or2New.owner = or1;\n        }\n      } else {\n        or2.pts = null;\n        if (this.usingPolytree) {\n          this.setOwner(or2, or1);\n          this.moveSplits(or2, or1);\n        } else {\n          or2.owner = or1;\n        }\n      }\n    }\n  }\n\n  private fixOutRecPts(outrec: OutRec): void {\n    let op = outrec.pts!;\n    do {\n      op.outrec = outrec;\n      op = op.next!;\n    } while (op !== outrec.pts);\n  }\n\n  protected path1InsidePath2(op1: OutPt, op2: OutPt): boolean {\n    // we need to make some accommodation for rounding errors\n    // so we won't jump if the first vertex is found outside\n    let pip = PointInPolygonResult.IsOn;\n    let op = op1;\n    do {\n      switch (this.pointInOpPolygon(op.pt, op2)) {\n        case PointInPolygonResult.IsOutside:\n          if (pip === PointInPolygonResult.IsOutside) return false;\n          pip = PointInPolygonResult.IsOutside;\n          break;\n        case PointInPolygonResult.IsInside:\n          if (pip === PointInPolygonResult.IsInside) return true;\n          pip = PointInPolygonResult.IsInside;\n          break;\n        default:\n          break;\n      }\n      op = op.next!;\n    } while (op !== op1);\n    // result is unclear, so try again using cleaned paths\n    return InternalClipper.path2ContainsPath1(this.getCleanPath(op1), this.getCleanPath(op2)); // (#973)\n  }\n\n  private pointInOpPolygon(pt: Point64, op: OutPt): PointInPolygonResult {\n    if (op === op.next || op.prev === op.next) {\n      return PointInPolygonResult.IsOutside;\n    }\n\n    let op2 = op;\n    do {\n      if (op.pt.y !== pt.y) break;\n      op = op.next!;\n    } while (op !== op2);\n    if (op.pt.y === pt.y) // not a proper polygon\n      return PointInPolygonResult.IsOutside;\n\n    // must be above or below to get here\n    let isAbove = op.pt.y < pt.y;\n    const startingAbove = isAbove;\n    let val = 0;\n\n    op2 = op.next!;\n    while (op2 !== op) {\n      if (isAbove) {\n        while (op2 !== op && op2.pt.y < pt.y) op2 = op2.next!;\n      } else {\n        while (op2 !== op && op2.pt.y > pt.y) op2 = op2.next!;\n      }\n      if (op2 === op) break;\n\n      // must have touched or crossed the pt.Y horizontal\n      // and this must happen an even number of times\n\n      if (op2.pt.y === pt.y) { // touching the horizontal\n        if (op2.pt.x === pt.x || (op2.pt.y === op2.prev.pt.y &&\n          (pt.x < op2.prev.pt.x) !== (pt.x < op2.pt.x)))\n          return PointInPolygonResult.IsOn;\n        op2 = op2.next!;\n        if (op2 === op) break;\n        continue;\n      }\n\n      if (op2.pt.x <= pt.x || op2.prev.pt.x <= pt.x) {\n        if ((op2.prev.pt.x < pt.x && op2.pt.x < pt.x)) {\n          val = 1 - val; // toggle val\n        } else {\n          const d = InternalClipper.crossProductSign(op2.prev.pt, op2.pt, pt);\n          if (d === 0) return PointInPolygonResult.IsOn;\n          if ((d < 0) === isAbove) val = 1 - val;\n        }\n      }\n      isAbove = !isAbove;\n      op2 = op2.next!;\n    }\n\n    if (isAbove === startingAbove) return val === 0 ? PointInPolygonResult.IsOutside : PointInPolygonResult.IsInside;\n    {\n      const d = InternalClipper.crossProductSign(op2.prev.pt, op2.pt, pt);\n      if (d === 0) return PointInPolygonResult.IsOn;\n      if ((d < 0) === isAbove) val = 1 - val;\n    }\n\n    return val === 0 ? PointInPolygonResult.IsOutside : PointInPolygonResult.IsInside;\n  }\n\n  private getCleanPath(op: OutPt): Path64 {\n    const result: Path64 = [];\n    let op2 = op;\n    while (op2.next !== op &&\n      ((op2.pt.x === op2.next!.pt.x && op2.pt.x === op2.prev.pt.x) ||\n        (op2.pt.y === op2.next!.pt.y && op2.pt.y === op2.prev.pt.y))) op2 = op2.next!;\n    result.push(op2.pt);\n    let prevOp = op2;\n    op2 = op2.next!;\n    while (op2 !== op) {\n      if ((op2.pt.x !== op2.next!.pt.x || op2.pt.x !== prevOp.pt.x) &&\n        (op2.pt.y !== op2.next!.pt.y || op2.pt.y !== prevOp.pt.y)) {\n        result.push(op2.pt);\n        prevOp = op2;\n      }\n      op2 = op2.next!;\n    }\n    return result;\n  }\n\n  private moveSplits(fromOr: OutRec, toOr: OutRec): void {\n    if (fromOr.splits === null) return;\n    if (toOr.splits === null) toOr.splits = [];\n    for (const i of fromOr.splits) {\n      if (i !== toOr.idx) {\n        toOr.splits.push(i);\n      }\n    }\n    fromOr.splits = null;\n  }\n\n  private buildIntersectList(topY: number): boolean {\n    if (this.actives?.nextInAEL === null) return false;\n\n    // Calculate edge positions at the top of the current scanbeam, and from this\n    // we will determine the intersections required to reach these new positions.\n    this.adjustCurrXAndCopyToSEL(topY);\n\n    // Find all edge intersections in the current scanbeam using a stable merge\n    // sort that ensures only adjacent edges are intersecting. Intersect info is\n    // stored in intersectList ready to be processed in ProcessIntersectList.\n    // Re merge sorts see https://stackoverflow.com/a/46319131/359538\n\n    let left = this.sel;\n\n    while (left !== null && left.jump !== null) {\n      let prevBase: Active | null = null;\n      while (left !== null && left.jump !== null) {\n        let currBase = left;\n        let right: Active | null = left.jump;\n        let lEnd: Active | null = right;\n        const rEnd: Active | null = right?.jump || null;\n        left.jump = rEnd;\n        \n        while (left !== lEnd && right !== rEnd) {\n          if (right!.curX < left!.curX) {\n            let tmp = right!.prevInSEL!;\n            while (true) {\n              this.addNewIntersectNode(tmp, right!, topY);\n              if (tmp === left) break;\n              tmp = tmp.prevInSEL!;\n            }\n\n            tmp = right!;\n            right = this.extractFromSEL(tmp);\n            lEnd = right; // Update lEnd - this is the critical fix!\n            if (left !== null) this.insert1Before2InSEL(tmp, left);\n            if (left !== currBase) continue;\n            currBase = tmp;\n            currBase.jump = rEnd;\n            if (prevBase === null) {\n              this.sel = currBase;\n            } else {\n              prevBase.jump = currBase;\n            }\n          } else {\n            left = left!.nextInSEL;\n          }\n        }\n\n        prevBase = currBase;\n        left = rEnd;\n      }\n      left = this.sel;\n    }\n\n    return this.intersectList.length > 0;\n  }\n\n  private processIntersectList(): void {\n    // We now have a list of intersections required so that edges will be\n    // correctly positioned at the top of the scanbeam. However, it's important\n    // that edge intersections are processed from the bottom up, but it's also\n    // crucial that intersections only occur between adjacent edges.\n\n    // First we do a quicksort so intersections proceed in a bottom up order ...\n    this.intersectList.sort(compareIntersectNodes);\n\n    // Now as we process these intersections, we must sometimes adjust the order\n    // to ensure that intersecting edges are always adjacent ...\n    for (let i = 0; i < this.intersectList.length; ++i) {\n      if (!this.edgesAdjacentInAEL(this.intersectList[i])) {\n        let j = i + 1;\n        while (!this.edgesAdjacentInAEL(this.intersectList[j])) j++;\n        // swap\n        [this.intersectList[j], this.intersectList[i]] = [this.intersectList[i], this.intersectList[j]];\n      }\n\n      const node = this.intersectList[i];\n      this.intersectEdges(node.edge1, node.edge2, node.pt);\n      this.swapPositionsInAEL(node.edge1, node.edge2);\n\n      node.edge1.curX = node.pt.x;\n      node.edge2.curX = node.pt.x;\n      this.checkJoinLeft(node.edge2, node.pt, true);\n      this.checkJoinRight(node.edge1, node.pt, true);\n    }\n  }\n\n  private edgesAdjacentInAEL(inode: IntersectNode): boolean {\n    return (inode.edge1.nextInAEL === inode.edge2) || (inode.edge1.prevInAEL === inode.edge2);\n  }\n\n  private adjustCurrXAndCopyToSEL(topY: number): void {\n    let ae = this.actives;\n    this.sel = ae;\n    while (ae !== null) {\n      ae.prevInSEL = ae.prevInAEL;\n      ae.nextInSEL = ae.nextInAEL;\n      ae.jump = ae.nextInSEL;\n      // it is safe to ignore 'joined' edges here because\n      // if necessary they will be split in IntersectEdges()\n      ae.curX = ClipperBase.topX(ae, topY);\n      // NB don't update ae.curr.Y yet (see AddNewIntersectNode)\n      ae = ae.nextInAEL;\n    }\n  }\n\n  private doMaxima(ae: Active): Active | null {\n    const prevE = ae.prevInAEL;\n    let nextE = ae.nextInAEL;\n\n    if (ClipperBase.isOpenEnd(ae)) {\n      if (ClipperBase.isHotEdge(ae)) this.addOutPt(ae, ae.top);\n      if (ClipperBase.isHorizontal(ae)) return nextE;\n      if (ClipperBase.isHotEdge(ae)) {\n        if (ClipperBase.isFront(ae)) {\n          ae.outrec!.frontEdge = null;\n        } else {\n          ae.outrec!.backEdge = null;\n        }\n        ae.outrec = null;\n      }\n      this.deleteFromAEL(ae);\n      return nextE;\n    }\n\n    const maxPair = ClipperBase.getMaximaPair(ae);\n    if (maxPair === null) return nextE; // eMaxPair is horizontal\n\n    if (this.isJoined(ae)) this.split(ae, ae.top);\n    if (this.isJoined(maxPair)) this.split(maxPair, maxPair.top);\n\n    // only non-horizontal maxima here.\n    // process any edges between maxima pair ...\n    while (nextE !== maxPair) {\n      this.intersectEdges(ae, nextE!, ae.top);\n      this.swapPositionsInAEL(ae, nextE!);\n      nextE = ae.nextInAEL;\n    }\n\n    if (ClipperBase.isOpen(ae)) {\n      if (ClipperBase.isHotEdge(ae)) {\n        this.addLocalMaxPoly(ae, maxPair, ae.top);\n      }\n      this.deleteFromAEL(maxPair);\n      this.deleteFromAEL(ae);\n      return (prevE !== null ? prevE.nextInAEL : this.actives);\n    }\n\n    // here ae.nextInAel == ENext == EMaxPair ...\n    if (ClipperBase.isHotEdge(ae)) {\n      this.addLocalMaxPoly(ae, maxPair, ae.top);\n    }\n\n    this.deleteFromAEL(ae);\n    this.deleteFromAEL(maxPair);\n    return (prevE !== null ? prevE.nextInAEL : this.actives);\n  }\n\n  private updateEdgeIntoAEL(ae: Active): void {\n    // Avoid copying points (and avoid materializing z=0) for speed.\n    ae.bot = ae.top;\n    ae.vertexTop = ClipperBase.nextVertex(ae);\n    ae.top = ae.vertexTop!.pt;\n    ae.curX = ae.bot.x;\n    ClipperBase.setDx(ae);\n\n    if (this.isJoined(ae)) this.split(ae, ae.bot);\n\n    if (ClipperBase.isHorizontal(ae)) {\n      if (!ClipperBase.openPathsEnabled) {\n        // Closed-path-only fast path.\n        this.trimHorz(ae, this.preserveCollinear);\n      } else if (!ClipperBase.isOpen(ae)) {\n        this.trimHorz(ae, this.preserveCollinear);\n      }\n      return;\n    }\n    this.insertScanline(ae.top.y);\n\n    this.checkJoinLeft(ae, ae.bot);\n    this.checkJoinRight(ae, ae.bot, true); // (#500)\n  }\n\n  private trimHorz(horzEdge: Active, preserveCollinear: boolean): void {\n    let wasTrimmed = false;\n    let pt = ClipperBase.nextVertex(horzEdge).pt;\n\n    while (pt.y === horzEdge.top.y) {\n      // always trim 180 deg. spikes (in closed paths)\n      // but otherwise break if preserveCollinear = true\n      if (preserveCollinear &&\n      (pt.x < horzEdge.top.x) !== (horzEdge.bot.x < horzEdge.top.x)) {\n        break;\n      }\n\n      horzEdge.vertexTop = ClipperBase.nextVertex(horzEdge);\n      horzEdge.top = pt;\n      wasTrimmed = true;\n      if (ClipperBase.isMaximaVertex(horzEdge.vertexTop!)) break;\n      pt = ClipperBase.nextVertex(horzEdge).pt;\n    }\n    if (wasTrimmed) ClipperBase.setDx(horzEdge); // +/-infinity\n  }\n\n  private addToHorzSegList(op: OutPt): void {\n    if (op.outrec.isOpen) return;\n    this.horzSegList.push(new HorzSegment(op));\n  }\n\n  private addNewIntersectNode(ae1: Active, ae2: Active, topY: number): void {\n    let ip = InternalClipper.getLineIntersectPt(ae1.bot, ae1.top, ae2.bot, ae2.top);\n    \n    if (ip === null) {\n      ip = { x: ae1.curX, y: topY }; // parallel edges\n    }\n\n    if (ip.y > this.currentBotY || ip.y < topY) {\n      const absDx1 = Math.abs(ae1.dx);\n      const absDx2 = Math.abs(ae2.dx);\n      \n      if (absDx1 > 100 && absDx2 > 100) {\n        if (absDx1 > absDx2) {\n          ip = InternalClipper.getClosestPtOnSegment(ip, ae1.bot, ae1.top);\n        } else {\n          ip = InternalClipper.getClosestPtOnSegment(ip, ae2.bot, ae2.top);\n        }\n      } else if (absDx1 > 100) {\n        ip = InternalClipper.getClosestPtOnSegment(ip, ae1.bot, ae1.top);\n      } else if (absDx2 > 100) {\n        ip = InternalClipper.getClosestPtOnSegment(ip, ae2.bot, ae2.top);\n      } else {\n        if (ip.y < topY) ip.y = topY;\n        else ip.y = this.currentBotY;\n        if (absDx1 < absDx2) ip.x = ClipperBase.topX(ae1, ip.y);\n        else ip.x = ClipperBase.topX(ae2, ip.y);\n      }\n    }\n    \n    const node = createIntersectNode(ip, ae1, ae2);\n    this.intersectList.push(node);\n  }\n\n  private extractFromSEL(ae: Active): Active | null {\n    const res = ae.nextInSEL;\n    if (res !== null) {\n      res.prevInSEL = ae.prevInSEL;\n    }\n    ae.prevInSEL!.nextInSEL = res;\n    return res;\n  }\n\n  private insert1Before2InSEL(ae1: Active, ae2: Active): void {\n    ae1.prevInSEL = ae2.prevInSEL;\n    if (ae1.prevInSEL !== null) {\n      ae1.prevInSEL.nextInSEL = ae1;\n    }\n    ae1.nextInSEL = ae2;\n    ae2.prevInSEL = ae1;\n  }\n\n  private getCurrYMaximaVertexOpen(ae: Active): Vertex | null {\n    let result = ae.vertexTop;\n    if (ae.windDx > 0) {\n      while (result!.next!.pt.y === result!.pt.y &&\n        ((result!.flags & (VertexFlags.OpenEnd | VertexFlags.LocalMax)) === VertexFlags.None))\n        result = result!.next;\n    } else {\n      while (result!.prev!.pt.y === result!.pt.y &&\n        ((result!.flags & (VertexFlags.OpenEnd | VertexFlags.LocalMax)) === VertexFlags.None))\n        result = result!.prev;\n    }\n    if (!ClipperBase.isMaximaVertex(result!)) result = null; // not a maxima\n    return result;\n  }\n\n  private getCurrYMaximaVertex(ae: Active): Vertex | null {\n    let result = ae.vertexTop;\n    if (ae.windDx > 0) {\n      while (result!.next!.pt.y === result!.pt.y) result = result!.next;\n    } else {\n      while (result!.prev!.pt.y === result!.pt.y) result = result!.prev;\n    }\n    if (!ClipperBase.isMaximaVertex(result!)) result = null; // not a maxima\n    return result;\n  }\n\n  private resetHorzDirection(horz: Active, vertexMax: Vertex | null): { isLeftToRight: boolean; leftX: number; rightX: number } {\n    if (horz.bot.x === horz.top.x) {\n      // the horizontal edge is going nowhere ...\n      const leftX = horz.curX;\n      const rightX = horz.curX;\n      let ae = horz.nextInAEL;\n      while (ae !== null && ae.vertexTop !== vertexMax)\n        ae = ae.nextInAEL;\n      return { isLeftToRight: ae !== null, leftX, rightX };\n    }\n\n    if (horz.curX < horz.top.x) {\n      return { isLeftToRight: true, leftX: horz.curX, rightX: horz.top.x };\n    } else {\n      return { isLeftToRight: false, leftX: horz.top.x, rightX: horz.curX };\n    }\n  }\n\n  private getLastOp(hotEdge: Active): OutPt {\n    const outrec = hotEdge.outrec!;\n    return (hotEdge === outrec.frontEdge) ?\n      outrec.pts! : outrec.pts!.next!;\n  }\n\n  private insertLeftEdge(ae: Active): void {\n    if (this.actives === null) {\n      ae.prevInAEL = null;\n      ae.nextInAEL = null;\n      this.actives = ae;\n    } else if (!this.isValidAelOrder(this.actives, ae)) {\n      ae.prevInAEL = null;\n      ae.nextInAEL = this.actives;\n      this.actives.prevInAEL = ae;\n      this.actives = ae;\n    } else {\n      let ae2 = this.actives;\n      while (ae2.nextInAEL !== null && this.isValidAelOrder(ae2.nextInAEL, ae)) {\n        ae2 = ae2.nextInAEL;\n      }\n      //don't separate joined edges\n      if (ae2.joinWith === JoinWith.Right) ae2 = ae2.nextInAEL!;\n      ae.nextInAEL = ae2.nextInAEL;\n      if (ae2.nextInAEL !== null) ae2.nextInAEL.prevInAEL = ae;\n      ae.prevInAEL = ae2;\n      ae2.nextInAEL = ae;\n    }\n  }\n\n  private insertRightEdge(ae1: Active, ae2: Active): void {\n    ae2.nextInAEL = ae1.nextInAEL;\n    if (ae1.nextInAEL !== null) ae1.nextInAEL.prevInAEL = ae2;\n    ae2.prevInAEL = ae1;\n    ae1.nextInAEL = ae2;\n  }\n\n  private setWindCountForOpenPathEdge(ae: Active): void {\n    let ae2 = this.actives;\n    if (this.fillrule === FillRule.EvenOdd) {\n      let cnt1 = 0, cnt2 = 0;\n      while (ae2 !== ae) {\n        if (ClipperBase.getPolyType(ae2!) === PathType.Clip) {\n          cnt2++;\n        } else if (!ClipperBase.isOpen(ae2!)) {\n          cnt1++;\n        }\n        ae2 = ae2!.nextInAEL;\n      }\n\n      ae.windCount = (ClipperBase.isOdd(cnt1) ? 1 : 0);\n      ae.windCount2 = (ClipperBase.isOdd(cnt2) ? 1 : 0);\n    } else {\n      while (ae2 !== ae) {\n        if (ClipperBase.getPolyType(ae2!) === PathType.Clip) {\n          ae.windCount2 += ae2!.windDx;\n        } else if (!ClipperBase.isOpen(ae2!)) {\n          ae.windCount += ae2!.windDx;\n        }\n        ae2 = ae2!.nextInAEL;\n      }\n    }\n  }\n\n  private setWindCountForClosedPathEdge(ae: Active): void {\n    // Wind counts refer to polygon regions not edges, so here an edge's WindCnt\n    // indicates the higher of the wind counts for the two regions touching the\n    // edge. (nb: Adjacent regions can only ever have their wind counts differ by\n    // one. Also, open paths have no meaningful wind directions or counts.)\n\n    let ae2 = ae.prevInAEL;\n    // find the nearest closed path edge of the same PolyType in AEL (heading left)\n    const pt = ClipperBase.getPolyType(ae);\n\n    // Closed-path-only fast path (no open edges in the AEL)\n    if (!ClipperBase.openPathsEnabled) {\n      while (ae2 !== null && ClipperBase.getPolyType(ae2) !== pt) ae2 = ae2.prevInAEL;\n\n      if (ae2 === null) {\n        ae.windCount = ae.windDx;\n        ae2 = this.actives;\n      } else if (this.fillrule === FillRule.EvenOdd) {\n        ae.windCount = ae.windDx;\n        ae.windCount2 = ae2.windCount2;\n        ae2 = ae2.nextInAEL;\n      } else {\n        // NonZero, positive, or negative filling here ...\n        if (ae2.windCount * ae2.windDx < 0) {\n          if (Math.abs(ae2.windCount) > 1) {\n            if (ae2.windDx * ae.windDx < 0) {\n              ae.windCount = ae2.windCount;\n            } else {\n              ae.windCount = ae2.windCount + ae.windDx;\n            }\n          } else {\n            ae.windCount = ae.windDx;\n          }\n        } else {\n          if (ae2.windDx * ae.windDx < 0) {\n            ae.windCount = ae2.windCount;\n          } else {\n            ae.windCount = ae2.windCount + ae.windDx;\n          }\n        }\n\n        ae.windCount2 = ae2.windCount2;\n        ae2 = ae2.nextInAEL; // i.e. get ready to calc WindCnt2\n      }\n\n      // update windCount2 ...\n      if (this.fillrule === FillRule.EvenOdd) {\n        while (ae2 !== ae) {\n          if (ClipperBase.getPolyType(ae2!) !== pt) {\n            ae.windCount2 = (ae.windCount2 === 0 ? 1 : 0);\n          }\n          ae2 = ae2!.nextInAEL;\n        }\n      } else {\n        while (ae2 !== ae) {\n          if (ClipperBase.getPolyType(ae2!) !== pt) {\n            ae.windCount2 += ae2!.windDx;\n          }\n          ae2 = ae2!.nextInAEL;\n        }\n      }\n      return;\n    }\n\n    while (ae2 !== null && (ClipperBase.getPolyType(ae2) !== pt || ClipperBase.isOpen(ae2))) ae2 = ae2.prevInAEL;\n\n    if (ae2 === null) {\n      ae.windCount = ae.windDx;\n      ae2 = this.actives;\n    } else if (this.fillrule === FillRule.EvenOdd) {\n      ae.windCount = ae.windDx;\n      ae.windCount2 = ae2.windCount2;\n      ae2 = ae2.nextInAEL;\n    } else {\n      // NonZero, positive, or negative filling here ...\n      // when e2's WindCnt is in the SAME direction as its WindDx,\n      // then polygon will fill on the right of 'e2' (and 'e' will be inside)\n      // nb: neither e2.WindCnt nor e2.WindDx should ever be 0.\n      if (ae2.windCount * ae2.windDx < 0) {\n        // opposite directions so 'ae' is outside 'ae2' ...\n        if (Math.abs(ae2.windCount) > 1) {\n          // outside prev poly but still inside another.\n          if (ae2.windDx * ae.windDx < 0) {\n            // reversing direction so use the same WC\n            ae.windCount = ae2.windCount;\n          } else {\n            // otherwise keep 'reducing' the WC by 1 (i.e. towards 0) ...\n            ae.windCount = ae2.windCount + ae.windDx;\n          }\n        } else {\n          // now outside all polys of same polytype so set own WC ...\n          ae.windCount = (ClipperBase.isOpen(ae) ? 1 : ae.windDx);\n        }\n      } else {\n        //'ae' must be inside 'ae2'\n        if (ae2.windDx * ae.windDx < 0) {\n          // reversing direction so use the same WC\n          ae.windCount = ae2.windCount;\n        } else {\n          // otherwise keep 'increasing' the WC by 1 (i.e. away from 0) ...\n          ae.windCount = ae2.windCount + ae.windDx;\n        }\n      }\n\n      ae.windCount2 = ae2.windCount2;\n      ae2 = ae2.nextInAEL; // i.e. get ready to calc WindCnt2\n    }\n\n    // update windCount2 ...\n    if (this.fillrule === FillRule.EvenOdd) {\n      while (ae2 !== ae) {\n        if (ClipperBase.getPolyType(ae2!) !== pt && !ClipperBase.isOpen(ae2!)) {\n          ae.windCount2 = (ae.windCount2 === 0 ? 1 : 0);\n        }\n        ae2 = ae2!.nextInAEL;\n      }\n    } else {\n      while (ae2 !== ae) {\n        if (ClipperBase.getPolyType(ae2!) !== pt && !ClipperBase.isOpen(ae2!)) {\n          ae.windCount2 += ae2!.windDx;\n        }\n        ae2 = ae2!.nextInAEL;\n      }\n    }\n  }\n\n  private isContributingOpen(ae: Active): boolean {\n    let isInClip: boolean, isInSubj: boolean;\n    switch (this.fillrule) {\n      case FillRule.Positive:\n        isInSubj = ae.windCount > 0;\n        isInClip = ae.windCount2 > 0;\n        break;\n      case FillRule.Negative:\n        isInSubj = ae.windCount < 0;\n        isInClip = ae.windCount2 < 0;\n        break;\n      default:\n        isInSubj = ae.windCount !== 0;\n        isInClip = ae.windCount2 !== 0;\n        break;\n    }\n\n    switch (this.cliptype) {\n      case ClipType.Intersection: return isInClip;\n      case ClipType.Union: return !isInSubj && !isInClip;\n      default: return !isInClip;\n    }\n  }\n\n  private isContributingClosed(ae: Active): boolean {\n    switch (this.fillrule) {\n      case FillRule.Positive:\n        if (ae.windCount !== 1) return false;\n        break;\n      case FillRule.Negative:\n        if (ae.windCount !== -1) return false;\n        break;\n      case FillRule.NonZero:\n        if (Math.abs(ae.windCount) !== 1) return false;\n        break;\n    }\n\n    switch (this.cliptype) {\n      case ClipType.Intersection:\n        return this.fillrule === FillRule.Positive ? ae.windCount2 > 0 :\n                this.fillrule === FillRule.Negative ? ae.windCount2 < 0 :\n                ae.windCount2 !== 0;\n\n      case ClipType.Union:\n        return this.fillrule === FillRule.Positive ? ae.windCount2 <= 0 :\n                this.fillrule === FillRule.Negative ? ae.windCount2 >= 0 :\n                ae.windCount2 === 0;\n\n      case ClipType.Difference: {\n        const result = this.fillrule === FillRule.Positive ? (ae.windCount2 <= 0) :\n                        this.fillrule === FillRule.Negative ? (ae.windCount2 >= 0) :\n                        (ae.windCount2 === 0);\n        return (ClipperBase.getPolyType(ae) === PathType.Subject) ? result : !result;\n      }\n\n      case ClipType.Xor:\n        return true; // XOr is always contributing unless open\n\n      default:\n        return false;\n    }\n  }\n\nprivate addLocalMinPoly(ae1: Active, ae2: Active, pt: Point64, isNew: boolean = false): OutPt {\n  const outrec = this.newOutRec();\n  ae1.outrec = outrec;\n  ae2.outrec = outrec;\n\n  if (ClipperBase.isOpen(ae1)) {\n    outrec.owner = null;\n    outrec.isOpen = true;\n    if (ae1.windDx > 0) {\n      this.setSides(outrec, ae1, ae2);\n    } else {\n      this.setSides(outrec, ae2, ae1);\n    }\n  } else {\n    outrec.isOpen = false;\n    const prevHotEdge = ClipperBase.getPrevHotEdge(ae1);\n    // e.windDx is the winding direction of the **input** paths\n    // and unrelated to the winding direction of output polygons.\n    // Output orientation is determined by e.outrec.frontE which is\n    // the ascending edge (see AddLocalMinPoly).\n    if (prevHotEdge !== null) {\n      if (this.usingPolytree) {\n        this.setOwner(outrec, prevHotEdge.outrec!);\n      }\n      outrec.owner = prevHotEdge.outrec;\n      if (this.outrecIsAscending(prevHotEdge) === isNew) {\n        this.setSides(outrec, ae2, ae1);\n      } else {\n        this.setSides(outrec, ae1, ae2);\n      }\n    } else {\n      outrec.owner = null;\n      if (isNew) {\n        this.setSides(outrec, ae1, ae2);\n      } else {\n        this.setSides(outrec, ae2, ae1);\n      }\n    }\n  }\n\n  const op = new OutPt(pt, outrec);\n  outrec.pts = op;\n  return op;\n}\n\n  private outrecIsAscending(hotEdge: Active): boolean {\n    return hotEdge === hotEdge.outrec!.frontEdge;\n  }\n\nprotected newOutRec(): OutRec {\n  const result = new OutRec();\n  result.idx = this.outrecList.length;\n  this.outrecList.push(result);\n  return result;\n}\n\n  private startOpenPath(ae: Active, pt: Point64): OutPt {\n    const outrec = this.newOutRec();\n    outrec.isOpen = true;\n    if (ae.windDx > 0) {\n      outrec.frontEdge = ae;\n      outrec.backEdge = null;\n    } else {\n      outrec.frontEdge = null;\n      outrec.backEdge = ae;\n    }\n\n    ae.outrec = outrec;\n    const op = new OutPt(pt, outrec);\n    outrec.pts = op;\n    return op;\n  }\n\n  private checkJoinLeft(ae: Active, pt: Point64, checkCurrX: boolean = false): void {\n    const prev = ae.prevInAEL;\n    if (prev === null || \n      !ClipperBase.isHotEdge(ae) || !ClipperBase.isHotEdge(prev) || \n      ClipperBase.isHorizontal(ae) || ClipperBase.isHorizontal(prev) ||\n      ClipperBase.isOpen(ae) || ClipperBase.isOpen(prev)) return;\n    if ((pt.y < ae.top.y + 2 || pt.y < prev.top.y + 2) &&  // avoid trivial joins\n      ((ae.bot.y > pt.y) || (prev.bot.y > pt.y))) return;  // (#490)\n\n    if (checkCurrX) {\n      if (this.perpendicDistFromLineSqrdGreaterThanQuarter(pt, prev.bot, prev.top)) return;\n    } else if (ae.curX !== prev.curX) return;\n    if (!InternalClipper.isCollinear(ae.top, pt, prev.top)) return;\n\n    if (ae.outrec!.idx === prev.outrec!.idx) {\n      this.addLocalMaxPoly(prev, ae, pt);\n    } else if (ae.outrec!.idx < prev.outrec!.idx) {\n      this.joinOutrecPaths(ae, prev);\n    } else {\n      this.joinOutrecPaths(prev, ae);\n    }\n    prev.joinWith = JoinWith.Right;\n    ae.joinWith = JoinWith.Left;\n  }\n\n  private checkJoinRight(ae: Active, pt: Point64, checkCurrX: boolean = false): void {\n    const next = ae.nextInAEL;\n    if (next === null || \n      !ClipperBase.isHotEdge(ae) || !ClipperBase.isHotEdge(next) || \n      ClipperBase.isHorizontal(ae) || ClipperBase.isHorizontal(next) ||\n      ClipperBase.isOpen(ae) || ClipperBase.isOpen(next)) return; \n    if ((pt.y < ae.top.y + 2 || pt.y < next.top.y + 2) &&  // avoid trivial joins\n      ((ae.bot.y > pt.y) || (next.bot.y > pt.y)))  return; // (#490)\n\n    if (checkCurrX) {\n      if (this.perpendicDistFromLineSqrdGreaterThanQuarter(pt, next.bot, next.top)) return;\n    } else if (ae.curX !== next.curX) return;\n    if (!InternalClipper.isCollinear(ae.top, pt, next.top)) return;\n\n    if (ae.outrec!.idx === next.outrec!.idx) {\n      this.addLocalMaxPoly(ae, next, pt);\n    } else if (ae.outrec!.idx < next.outrec!.idx) {\n      this.joinOutrecPaths(ae, next);\n    } else {\n      this.joinOutrecPaths(next, ae);\n    }\n    ae.joinWith = JoinWith.Right;\n    next.joinWith = JoinWith.Left;\n  }\n\n  private perpendicDistFromLineSqrdGreaterThanQuarter(\n    pt: Point64, line1: Point64, line2: Point64\n  ): boolean {\n    const a = pt.x - line1.x;\n    const b = pt.y - line1.y;\n    const c = line2.x - line1.x;\n    const d = line2.y - line1.y;\n    if (c === 0 && d === 0) return false;\n    // Fast path: keep within safe integer range\n    const maxCoord = InternalClipper.maxCoordForSafeCrossSq;\n    if (Math.abs(a) < maxCoord && Math.abs(b) < maxCoord &&\n        Math.abs(c) < maxCoord && Math.abs(d) < maxCoord) {\n      const cross = (a * d) - (c * b);\n      return (cross * cross) / ((c * c) + (d * d)) > 0.25;\n    }\n    // Large coordinates: use BigInt for precision\n    if (Number.isSafeInteger(a) && Number.isSafeInteger(b) &&\n        Number.isSafeInteger(c) && Number.isSafeInteger(d)) {\n      const cross = (BigInt(a) * BigInt(d)) - (BigInt(c) * BigInt(b));\n      const crossSq = cross * cross;\n      const denom = (BigInt(c) * BigInt(c)) + (BigInt(d) * BigInt(d));\n      return B4 * crossSq > denom;\n    }\n    // Fallback for non-integer coords\n    const cross = (a * d) - (c * b);\n    return (cross * cross) / ((c * c) + (d * d)) > 0.25;\n  }\n\n\n  private intersectEdges(ae1: Active, ae2: Active, pt: Point64): void {\n    let resultOp: OutPt | null;\n    // MANAGE OPEN PATH INTERSECTIONS SEPARATELY ...\n    if (this.hasOpenPaths && (ClipperBase.isOpen(ae1) || ClipperBase.isOpen(ae2))) {\n      if (ClipperBase.isOpen(ae1) && ClipperBase.isOpen(ae2)) return;\n      // the following line avoids duplicating quite a bit of code\n      if (ClipperBase.isOpen(ae2)) {\n        const tmp = ae1;\n        ae1 = ae2;\n        ae2 = tmp;\n      }\n      if (this.isJoined(ae2)) this.split(ae2, pt); // needed for safety\n\n      if (this.cliptype === ClipType.Union) {\n        if (!ClipperBase.isHotEdge(ae2)) return;\n      } else if (ae2.localMin!.polytype === PathType.Subject) return;\n\n      switch (this.fillrule) {\n        case FillRule.Positive:\n          if (ae2.windCount !== 1) return;\n          break;\n        case FillRule.Negative:\n          if (ae2.windCount !== -1) return;\n          break;\n        default:\n          if (Math.abs(ae2.windCount) !== 1) return;\n          break;\n      }\n\n      // toggle contribution ...\n      if (ClipperBase.isHotEdge(ae1)) {\n        resultOp = this.addOutPt(ae1, pt);\n        this.setZ(ae1, ae2, resultOp.pt);\n        if (ClipperBase.isFront(ae1)) {\n          ae1.outrec!.frontEdge = null;\n        } else {\n          ae1.outrec!.backEdge = null;\n        }\n        ae1.outrec = null;\n      }\n\n      // horizontal edges can pass under open paths at a LocMins\n      else if (pt.x === ae1.localMin!.vertex.pt.x && pt.y === ae1.localMin!.vertex.pt.y &&\n        !ClipperBase.isOpenEndVertex(ae1.localMin!.vertex)) {\n        // find the other side of the LocMin and\n        // if it's 'hot' join up with it ...\n        const ae3 = this.findEdgeWithMatchingLocMin(ae1);\n        if (ae3 !== null && ClipperBase.isHotEdge(ae3)) {\n          ae1.outrec = ae3.outrec;\n          if (ae1.windDx > 0) {\n            this.setSides(ae3.outrec!, ae1, ae3);\n          } else {\n            this.setSides(ae3.outrec!, ae3, ae1);\n          }\n          return;\n        }\n\n        resultOp = this.startOpenPath(ae1, pt);\n      } else {\n        resultOp = this.startOpenPath(ae1, pt);\n      }\n      this.setZ(ae1, ae2, resultOp.pt);\n      return;\n    }\n\n    // MANAGING CLOSED PATHS FROM HERE ON\n    if (this.isJoined(ae1)) this.split(ae1, pt);\n    if (this.isJoined(ae2)) this.split(ae2, pt);\n\n    // UPDATE WINDING COUNTS...\n    let oldE1WindCount: number, oldE2WindCount: number;\n    if (ae1.localMin!.polytype === ae2.localMin!.polytype) {\n      if (this.fillrule === FillRule.EvenOdd) {\n        oldE1WindCount = ae1.windCount;\n        ae1.windCount = ae2.windCount;\n        ae2.windCount = oldE1WindCount;\n      } else {\n        if (ae1.windCount + ae2.windDx === 0) {\n          ae1.windCount = -ae1.windCount;\n        } else {\n          ae1.windCount += ae2.windDx;\n        }\n        if (ae2.windCount - ae1.windDx === 0) {\n          ae2.windCount = -ae2.windCount;\n        } else {\n          ae2.windCount -= ae1.windDx;\n        }\n      }\n    } else {\n      if (this.fillrule !== FillRule.EvenOdd) {\n        ae1.windCount2 += ae2.windDx;\n      } else {\n        ae1.windCount2 = (ae1.windCount2 === 0 ? 1 : 0);\n      }\n      if (this.fillrule !== FillRule.EvenOdd) {\n        ae2.windCount2 -= ae1.windDx;\n      } else {\n        ae2.windCount2 = (ae2.windCount2 === 0 ? 1 : 0);\n      }\n    }\n\n    switch (this.fillrule) {\n      case FillRule.Positive:\n        oldE1WindCount = ae1.windCount;\n        oldE2WindCount = ae2.windCount;\n        break;\n      case FillRule.Negative:\n        oldE1WindCount = -ae1.windCount;\n        oldE2WindCount = -ae2.windCount;\n        break;\n      default:\n        oldE1WindCount = Math.abs(ae1.windCount);\n        oldE2WindCount = Math.abs(ae2.windCount);\n        break;\n    }\n\n    const e1WindCountIs0or1 = oldE1WindCount === 0 || oldE1WindCount === 1;\n    const e2WindCountIs0or1 = oldE2WindCount === 0 || oldE2WindCount === 1;\n\n    if ((!ClipperBase.isHotEdge(ae1) && !e1WindCountIs0or1) || \n      (!ClipperBase.isHotEdge(ae2) && !e2WindCountIs0or1)) return;\n\n    // NOW PROCESS THE INTERSECTION ...\n\n    // if both edges are 'hot' ...\n    if (ClipperBase.isHotEdge(ae1) && ClipperBase.isHotEdge(ae2)) {\n      if ((oldE1WindCount !== 0 && oldE1WindCount !== 1) || (oldE2WindCount !== 0 && oldE2WindCount !== 1) ||\n          (ae1.localMin!.polytype !== ae2.localMin!.polytype && this.cliptype !== ClipType.Xor)) {\n        resultOp = this.addLocalMaxPoly(ae1, ae2, pt);\n        if (resultOp) this.setZ(ae1, ae2, resultOp.pt);\n      } else if (ClipperBase.isFront(ae1) || (ae1.outrec === ae2.outrec)) {\n        // this 'else if' condition isn't strictly needed but\n        // it's sensible to split polygons that only touch at\n        // a common vertex (not at common edges).\n        resultOp = this.addLocalMaxPoly(ae1, ae2, pt);\n        if (resultOp) this.setZ(ae1, ae2, resultOp.pt);\n        const op2 = this.addLocalMinPoly(ae1, ae2, pt);\n        this.setZ(ae1, ae2, op2.pt);\n      } else {\n        // can't treat as maxima & minima\n        resultOp = this.addOutPt(ae1, pt);\n        this.setZ(ae1, ae2, resultOp.pt);\n        const op2 = this.addOutPt(ae2, pt);\n        this.setZ(ae1, ae2, op2.pt);\n        this.swapOutrecs(ae1, ae2);\n      }\n    }\n\n    // if one or other edge is 'hot' ...\n    else if (ClipperBase.isHotEdge(ae1)) {\n      resultOp = this.addOutPt(ae1, pt);\n      this.setZ(ae1, ae2, resultOp.pt);\n      this.swapOutrecs(ae1, ae2);\n    } else if (ClipperBase.isHotEdge(ae2)) {\n      resultOp = this.addOutPt(ae2, pt);\n      this.setZ(ae1, ae2, resultOp.pt);\n      this.swapOutrecs(ae1, ae2);\n    }\n\n    // neither edge is 'hot'\n    else {\n      let e1Wc2: number, e2Wc2: number;\n      switch (this.fillrule) {\n        case FillRule.Positive:\n          e1Wc2 = ae1.windCount2;\n          e2Wc2 = ae2.windCount2;\n          break;\n        case FillRule.Negative:\n          e1Wc2 = -ae1.windCount2;\n          e2Wc2 = -ae2.windCount2;\n          break;\n        default:\n          e1Wc2 = Math.abs(ae1.windCount2);\n          e2Wc2 = Math.abs(ae2.windCount2);\n          break;\n      }\n\n      if (!ClipperBase.isSamePolyType(ae1, ae2)) {\n        resultOp = this.addLocalMinPoly(ae1, ae2, pt);\n        this.setZ(ae1, ae2, resultOp.pt);\n      } else if (oldE1WindCount === 1 && oldE2WindCount === 1) {\n        resultOp = null; \n        switch (this.cliptype) {\n          case ClipType.Union:\n            if (e1Wc2 > 0 && e2Wc2 > 0) return;\n            resultOp = this.addLocalMinPoly(ae1, ae2, pt);\n            break;\n\n          case ClipType.Difference:\n            if (((ClipperBase.getPolyType(ae1) === PathType.Clip) && (e1Wc2 > 0) && (e2Wc2 > 0)) ||\n                ((ClipperBase.getPolyType(ae1) === PathType.Subject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) {\n              resultOp = this.addLocalMinPoly(ae1, ae2, pt);\n            }\n            break;\n\n          case ClipType.Xor:\n            resultOp = this.addLocalMinPoly(ae1, ae2, pt);\n            break;\n\n          default: // ClipType.Intersection:\n            if (e1Wc2 <= 0 || e2Wc2 <= 0) return;\n            resultOp = this.addLocalMinPoly(ae1, ae2, pt);\n            break;\n        }\n        if (resultOp) this.setZ(ae1, ae2, resultOp.pt);\n      }\n    }\n  }\n\n  private swapPositionsInAEL(ae1: Active, ae2: Active): void {\n    // preconditon: ae1 must be immediately to the left of ae2\n    const next = ae2.nextInAEL;\n    if (next !== null) next.prevInAEL = ae1;\n    const prev = ae1.prevInAEL;\n    if (prev !== null) prev.nextInAEL = ae2;\n    ae2.prevInAEL = prev;\n    ae2.nextInAEL = ae1;\n    ae1.prevInAEL = ae2;\n    ae1.nextInAEL = next;\n    if (ae2.prevInAEL === null) this.actives = ae2;\n  }\n\n  private isValidAelOrder(resident: Active, newcomer: Active): boolean {\n    if (newcomer.curX !== resident.curX) {\n      return newcomer.curX > resident.curX;\n    }\n\n    // get the turning direction  a1.top, a2.bot, a2.top\n    const d = InternalClipper.crossProductSign(resident.top, newcomer.bot, newcomer.top);\n    if (d !== 0) return d < 0;\n\n    // edges must be collinear to get here\n\n    // for starting open paths, place them according to\n    // the direction they're about to turn\n    if (!ClipperBase.isMaximaEdge(resident) && (resident.top.y > newcomer.top.y)) {\n      return InternalClipper.crossProductSign(newcomer.bot,\n        resident.top, ClipperBase.nextVertex(resident).pt) <= 0;\n    }\n\n    if (!ClipperBase.isMaximaEdge(newcomer) && (newcomer.top.y > resident.top.y)) {\n      return InternalClipper.crossProductSign(newcomer.bot,\n        newcomer.top, ClipperBase.nextVertex(newcomer).pt) >= 0;\n    }\n\n    const y = newcomer.bot.y;\n    const newcomerIsLeft = newcomer.isLeftBound;\n\n    if (resident.bot.y !== y || resident.localMin!.vertex.pt.y !== y) {\n      return newcomer.isLeftBound;\n    }\n    // resident must also have just been inserted\n    if (resident.isLeftBound !== newcomerIsLeft) {\n      return newcomerIsLeft;\n    }\n    if (InternalClipper.isCollinear(ClipperBase.prevPrevVertex(resident).pt,\n          resident.bot, resident.top)) return true;\n    // compare turning direction of the alternate bound\n    return (InternalClipper.crossProductSign(ClipperBase.prevPrevVertex(resident).pt,\n      newcomer.bot, ClipperBase.prevPrevVertex(newcomer).pt) > 0) === newcomerIsLeft;\n  }\n\n  private isJoined(e: Active): boolean {\n    return e.joinWith !== JoinWith.None;\n  }\n\n  private split(e: Active, currPt: Point64): void {\n    if (e.joinWith === JoinWith.Right) {\n      e.joinWith = JoinWith.None;\n      e.nextInAEL!.joinWith = JoinWith.None;\n      this.addLocalMinPoly(e, e.nextInAEL!, currPt, true);\n    } else {\n      e.joinWith = JoinWith.None;\n      e.prevInAEL!.joinWith = JoinWith.None;\n      this.addLocalMinPoly(e.prevInAEL!, e, currPt, true);\n    }\n  }\n\n  private setSides(outrec: OutRec, startEdge: Active, endEdge: Active): void {\n    outrec.frontEdge = startEdge;\n    outrec.backEdge = endEdge;\n  }\n\n  private findEdgeWithMatchingLocMin(e: Active): Active | null {\n    let result = e.nextInAEL;\n    while (result !== null) {\n      if (result.localMin?.equals(e.localMin)) return result;\n      if (!ClipperBase.isHorizontal(result) && !(e.bot.x === result.bot.x && e.bot.y === result.bot.y)) result = null;\n      else result = result.nextInAEL;\n    }\n    result = e.prevInAEL;\n    while (result !== null) {\n      if (result.localMin?.equals(e.localMin)) return result;\n      if (!ClipperBase.isHorizontal(result) && !(e.bot.x === result.bot.x && e.bot.y === result.bot.y)) return null;\n      result = result.prevInAEL;\n    }\n    return result;\n  }\n\n  private addOutPt(ae: Active, pt: Point64): OutPt {\n    // Outrec.OutPts: a circular doubly-linked-list of POutPt where ...\n    // opFront[.Prev]* ~~~> opBack & opBack == opFront.Next\n    const outrec = ae.outrec!;\n    const toFront = ClipperBase.isFront(ae);\n    const opFront = outrec.pts!;\n    const opBack = opFront.next!;\n\n    if (toFront && pt.x === opFront.pt.x && pt.y === opFront.pt.y) {\n      return opFront;\n    } else if (!toFront && pt.x === opBack.pt.x && pt.y === opBack.pt.y) {\n      return opBack;\n    }\n\n    const newOp = new OutPt(pt, outrec);\n    opBack.prev = newOp;\n    newOp.prev = opFront;\n    newOp.next = opBack;\n    opFront.next = newOp;\n    if (toFront) outrec.pts = newOp;\n    return newOp;\n  }\n\nprivate addLocalMaxPoly(ae1: Active, ae2: Active, pt: Point64): OutPt | null {\n  if (this.isJoined(ae1)) this.split(ae1, pt);\n  if (this.isJoined(ae2)) this.split(ae2, pt);\n\n  if (ClipperBase.isFront(ae1) === ClipperBase.isFront(ae2)) {\n    if (ClipperBase.isOpenEnd(ae1)) {\n      this.swapFrontBackSides(ae1.outrec!);\n    } else if (ClipperBase.isOpenEnd(ae2)) {\n      this.swapFrontBackSides(ae2.outrec!);\n    } else {\n      this.succeeded = false;\n      return null;\n    }\n  }\n\n    const result = this.addOutPt(ae1, pt);\n    if (ae1.outrec === ae2.outrec) {\n      const outrec = ae1.outrec!;\n      outrec.pts = result;\n\n      if (this.usingPolytree) {\n        const e = ClipperBase.getPrevHotEdge(ae1);\n        if (e === null) {\n          outrec.owner = null;\n        } else {\n          this.setOwner(outrec, e.outrec!);\n        }\n        // nb: outRec.owner here is likely NOT the real\n        // owner but this will be fixed in DeepCheckOwner()\n      }\n      this.uncoupleOutRec(ae1);\n    }\n    // and to preserve the winding orientation of outrec ...\n    else if (ClipperBase.isOpen(ae1)) {\n      if (ae1.windDx < 0) {\n        this.joinOutrecPaths(ae1, ae2);\n      } else {\n        this.joinOutrecPaths(ae2, ae1);\n      }\n    } else if (ae1.outrec!.idx < ae2.outrec!.idx) {\n      this.joinOutrecPaths(ae1, ae2);\n    } else {\n      this.joinOutrecPaths(ae2, ae1);\n    }\n    return result;\n  }\n\n  private swapFrontBackSides(outrec: OutRec): void {\n    // while this proc. is needed for open paths\n    // it's almost never needed for closed paths\n    const ae2 = outrec.frontEdge!;\n    outrec.frontEdge = outrec.backEdge;\n    outrec.backEdge = ae2;\n    outrec.pts = outrec.pts!.next;\n  }\n\nprivate setOwner(outrec: OutRec, newOwner: OutRec): void {\n  //precondition1: new_owner is never null\n  while (newOwner.owner !== null && newOwner.owner.pts === null) {\n    newOwner.owner = newOwner.owner.owner;\n  }\n\n  //make sure that outrec isn't an owner of newOwner\n  let tmp: OutRec | null = newOwner;\n  while (tmp !== null && tmp !== outrec) {\n    tmp = tmp.owner;\n  }\n  if (tmp !== null) {\n    newOwner.owner = outrec.owner;\n  }\n  outrec.owner = newOwner;\n}\n\n  private uncoupleOutRec(ae: Active): void {\n    const outrec = ae.outrec;\n    if (outrec === null) return;\n    outrec.frontEdge!.outrec = null;\n    outrec.backEdge!.outrec = null;\n    outrec.frontEdge = null;\n    outrec.backEdge = null;\n  }\n\n  private joinOutrecPaths(ae1: Active, ae2: Active): void {\n    // join ae2 outrec path onto ae1 outrec path and then delete ae2 outrec path\n    // pointers. (NB Only very rarely do the joining ends share the same coords.)\n    const p1Start = ae1.outrec!.pts!;\n    const p2Start = ae2.outrec!.pts!;\n    const p1End = p1Start.next!;\n    const p2End = p2Start.next!;\n    if (ClipperBase.isFront(ae1)) {\n      p2End.prev = p1Start;\n      p1Start.next = p2End;\n      p2Start.next = p1End;\n      p1End.prev = p2Start;\n      ae1.outrec!.pts = p2Start;\n      // nb: if IsOpen(e1) then e1 & e2 must be a 'maximaPair'\n      ae1.outrec!.frontEdge = ae2.outrec!.frontEdge;\n      if (ae1.outrec!.frontEdge !== null) {\n        ae1.outrec!.frontEdge!.outrec = ae1.outrec;\n      }\n    } else {\n      p1End.prev = p2Start;\n      p2Start.next = p1End;\n      p1Start.next = p2End;\n      p2End.prev = p1Start;\n\n      ae1.outrec!.backEdge = ae2.outrec!.backEdge;\n      if (ae1.outrec!.backEdge !== null) {\n        ae1.outrec!.backEdge!.outrec = ae1.outrec;\n      }\n    }\n\n    // after joining, the ae2.OutRec must contains no vertices ...\n    ae2.outrec!.frontEdge = null;\n    ae2.outrec!.backEdge = null;\n    ae2.outrec!.pts = null;\n    this.setOwner(ae2.outrec!, ae1.outrec!);\n\n    if (ClipperBase.isOpenEnd(ae1)) {\n      ae2.outrec!.pts = ae1.outrec!.pts;\n      ae1.outrec!.pts = null;\n    }\n\n    // and ae1 and ae2 are maxima and are about to be dropped from the Actives list.\n    ae1.outrec = null;\n    ae2.outrec = null;\n  }\n\n  private swapOutrecs(ae1: Active, ae2: Active): void {\n    const or1 = ae1.outrec; // at least one edge has \n    const or2 = ae2.outrec; // an assigned outrec\n    if (or1 === or2) {\n      const ae = or1!.frontEdge;\n      or1!.frontEdge = or1!.backEdge;\n      or1!.backEdge = ae;\n      return;\n    }\n\n    if (or1 !== null) {\n      if (ae1 === or1.frontEdge) {\n        or1.frontEdge = ae2;\n      } else {\n        or1.backEdge = ae2;\n      }\n    }\n\n    if (or2 !== null) {\n      if (ae2 === or2.frontEdge) {\n        or2.frontEdge = ae1;\n      } else {\n        or2.backEdge = ae1;\n      }\n    }\n\n    ae1.outrec = or2;\n    ae2.outrec = or1;\n  }\n\n  private disposeIntersectNodes(): void {\n    this.intersectList.length = 0;\n  }\n\n  private static ptsReallyClose(pt1: Point64, pt2: Point64): boolean {\n    return (Math.abs(pt1.x - pt2.x) < 2) && (Math.abs(pt1.y - pt2.y) < 2);\n  }\n\n  private static isVerySmallTriangle(op: OutPt): boolean {\n    return op.next!.next === op.prev &&\n      (ClipperBase.ptsReallyClose(op.prev.pt, op.next!.pt) ||\n        ClipperBase.ptsReallyClose(op.pt, op.next!.pt) ||\n        ClipperBase.ptsReallyClose(op.pt, op.prev.pt));\n  }\n\n  protected static buildPath(op: OutPt | null, reverse: boolean, isOpen: boolean, path: Path64): boolean {\n    if (op === null || op.next === op || (!isOpen && op.next === op.prev)) return false;\n    path.length = 0;\n\n    let lastPt: Point64;\n    let op2: OutPt;\n    \n    if (reverse) {\n      lastPt = op.pt;\n      op2 = op.prev;\n    } else {\n      op = op.next!;\n      lastPt = op.pt;\n      op2 = op.next!;\n    }\n    path.push(lastPt);\n\n    while (op2 !== op) {\n      if (!(op2.pt.x === lastPt.x && op2.pt.y === lastPt.y)) {\n        lastPt = op2.pt;\n        path.push(lastPt);\n      }\n      if (reverse) {\n        op2 = op2.prev;\n      } else {\n        op2 = op2.next!;\n      }\n    }\n\n    return path.length !== 3 || isOpen || !ClipperBase.isVerySmallTriangle(op2);\n  }\n\nprotected buildPaths(solutionClosed: Paths64, solutionOpen: Paths64): boolean {\n  solutionClosed.length = 0;\n  solutionOpen.length = 0;\n  \n  let i = 0;\n  // outrecList.length is not static here because\n  // CleanCollinear can indirectly add additional OutRec\n  while (i < this.outrecList.length) {\n    const outrec = this.outrecList[i++];\n    if (outrec.pts === null) continue;\n\n    const path: Path64 = [];\n    if (outrec.isOpen) {\n      if (ClipperBase.buildPath(outrec.pts, this.reverseSolution, true, path)) {\n        solutionOpen.push(path);\n      }\n    } else {\n      this.cleanCollinear(outrec);\n      // closed paths should always return a Positive orientation\n      // except when ReverseSolution == true\n      if (ClipperBase.buildPath(outrec.pts, this.reverseSolution, false, path)) {\n          solutionClosed.push(path);\n        }\n      }\n    }\n    return true;\n  }\n\nprotected buildTree(polytree: PolyPathBase, solutionOpen: Paths64): void {\n  polytree.clear();\n  solutionOpen.length = 0;\n\n  let i = 0;\n  // outrecList.length is not static here because\n  // checkBounds below can indirectly add additional\n  // OutRec (via FixOutRecPts & CleanCollinear)\n  while (i < this.outrecList.length) {\n    const outrec = this.outrecList[i++];\n    if (outrec.pts === null) continue;\n\n    if (outrec.isOpen) {\n        const openPath: Path64 = [];\n        if (ClipperBase.buildPath(outrec.pts, this.reverseSolution, true, openPath)) {\n          solutionOpen.push(openPath);\n        }\n        continue;\n      }\n      \n      if (this.checkBounds(outrec)) {\n        this.recursiveCheckOwners(outrec, polytree);\n      }\n    }\n  }\n\n  protected checkBounds(outrec: OutRec): boolean {\n    if (outrec.pts === null) return false;\n    if (!Rect64Utils.isEmpty(outrec.bounds)) return true;\n    this.cleanCollinear(outrec);\n    if (outrec.pts === null ||\n      !ClipperBase.buildPath(outrec.pts, this.reverseSolution, false, outrec.path)) {\n        return false;\n    }\n    outrec.bounds = InternalClipper.getBounds(outrec.path);\n    return true;\n  }\n\n  protected recursiveCheckOwners(outrec: OutRec, polypath: PolyPathBase): void {\n    // pre-condition: outrec will have valid bounds\n    // post-condition: if a valid path, outrec will have a polypath\n\n    if (outrec.polypath !== null || Rect64Utils.isEmpty(outrec.bounds)) return;\n\n    while (outrec.owner !== null) {\n      if (outrec.owner.splits !== null && \n        this.checkSplitOwner(outrec, outrec.owner.splits)) break; \n      if (outrec.owner.pts !== null && this.checkBounds(outrec.owner) &&\n        // Fast reject: a container must contain the child's bounds.\n        this.containsRect(outrec.owner.bounds, outrec.bounds) &&\n        this.path1InsidePath2(outrec.pts!, outrec.owner.pts!)) break;\n      outrec.owner = outrec.owner.owner;\n    }\n\n    if (outrec.owner !== null) {\n      if (outrec.owner.polypath === null) {\n        this.recursiveCheckOwners(outrec.owner, polypath);\n      }\n      outrec.polypath = outrec.owner.polypath!.addChild(outrec.path); \n    } else {\n      outrec.polypath = polypath.addChild(outrec.path);\n    }\n  }\n\n  protected cleanCollinear(outrec: OutRec | null): void {\n    outrec = this.getRealOutRec(outrec);\n    \n    if (outrec === null || outrec.isOpen) return;\n\n    if (!this.isValidClosedPath(outrec.pts)) {\n      outrec.pts = null;\n      return;\n    }\n\n    let startOp = outrec.pts!;\n    let op2: OutPt | null = startOp;\n    \n    while (true) {\n      // NB if preserveCollinear == true, then only remove 180 deg. spikes\n      if (op2 !== null && InternalClipper.isCollinear(op2.prev.pt, op2.pt, op2.next!.pt) &&\n        ((op2.pt.x === op2.prev.pt.x && op2.pt.y === op2.prev.pt.y) || \n          (op2.pt.x === op2.next!.pt.x && op2.pt.y === op2.next!.pt.y) || \n          !this.preserveCollinear ||\n          InternalClipper.dotProductSign(op2.prev.pt, op2.pt, op2.next!.pt) < 0)) {\n        \n        if (op2 === outrec.pts) {\n          outrec.pts = op2.prev;\n        }\n        op2 = this.disposeOutPt(op2!);\n        if (!this.isValidClosedPath(op2)) {\n          outrec.pts = null;\n          return;\n        }\n        startOp = op2!;\n        continue;\n      }\n      if (op2 === null) break;\n      op2 = op2.next!;\n      if (op2 === startOp) break;\n    }\n    \n    this.fixSelfIntersects(outrec);\n  }\n\n  private isValidClosedPath(op: OutPt | null): boolean {\n    return op !== null && op.next !== op &&\n      (op.next !== op.prev || !ClipperBase.isVerySmallTriangle(op));\n  }\n\n  private disposeOutPt(op: OutPt): OutPt | null {\n    const result = (op.next === op ? null : op.next);\n    op.prev.next = op.next;\n    op.next!.prev = op.prev;\n    return result;\n  }\n\n  private fixSelfIntersects(outrec: OutRec): void {\n    let op2 = outrec.pts!;\n    if (op2.prev === op2.next!.next) {\n      return; // because triangles can't self-intersect\n    }\n    \n    while (true) {\n      if (op2.next && op2.next.next && \n          this.boundingBoxesOverlap(op2.prev.pt, op2.pt, op2.next.pt, op2.next.next.pt) &&\n          InternalClipper.segsIntersect(op2.prev.pt, op2.pt, op2.next.pt, op2.next.next.pt)) {\n          if (op2 === outrec.pts || op2.next === outrec.pts) {\n            outrec.pts = outrec.pts!.prev;\n          }\n          this.doSplitOp(outrec, op2);\n          if (outrec.pts === null) return;\n          op2 = outrec.pts;\n          if (op2.prev === op2.next!.next) break;\n          continue;\n      }\n\n      op2 = op2.next!;\n      if (op2 === outrec.pts) break;\n    }\n  }\n\nprivate doSplitOp(outrec: OutRec, splitOp: OutPt): void {\n  // splitOp.prev <=> splitOp &&\n  // splitOp.next <=> splitOp.next.next are intersecting\n  const prevOp = splitOp.prev;\n  const nextNextOp = splitOp.next!.next!;\n  outrec.pts = prevOp;\n\n  // doSplitOp is only reached when segments are known to intersect,\n  // so the result is never null here.\n  const ip = InternalClipper.getLineIntersectPt(\n    prevOp.pt, splitOp.pt, splitOp.next!.pt, nextNextOp.pt)!;\n\n  if (this.zCallbackInternal) {\n    (this.zCallbackInternal as ZCallback64)(\n      prevOp.pt, splitOp.pt, splitOp.next!.pt, nextNextOp.pt, ip);\n  }\n\n  const doubleArea1 = ClipperBase.areaOutPt(prevOp);\n  const absDoubleArea1 = doubleArea1 < B0 ? -doubleArea1 : doubleArea1;\n  \n  if (absDoubleArea1 < B4) { // area < 2\n    outrec.pts = null;\n    return;\n  }\n\n  const doubleArea2 = this.areaTriangle(ip, splitOp.pt, splitOp.next!.pt);\n  const absDoubleArea2 = doubleArea2 < B0 ? -doubleArea2 : doubleArea2;\n\n  // de-link splitOp and splitOp.next from the path\n  // while inserting the intersection point\n  if ((ip.x === prevOp.pt.x && ip.y === prevOp.pt.y) || (ip.x === nextNextOp.pt.x && ip.y === nextNextOp.pt.y)) {\n    nextNextOp.prev = prevOp;\n    prevOp.next = nextNextOp;\n  } else {\n    const newOp2 = new OutPt(ip, outrec);\n    newOp2.prev = prevOp;\n    newOp2.next = nextNextOp;\n    nextNextOp.prev = newOp2;\n    prevOp.next = newOp2;\n  }\n\n  if (!(absDoubleArea2 > B2) || // area > 1\n      (!(absDoubleArea2 > absDoubleArea1) &&\n        ((doubleArea2 > B0) !== (doubleArea1 > B0)))) return;\n        \n  const newOutRec = this.newOutRec();\n  newOutRec.owner = outrec.owner;\n  splitOp.outrec = newOutRec;\n  splitOp.next!.outrec = newOutRec;\n\n  const newOp = new OutPt(ip, newOutRec);\n  newOp.prev = splitOp.next!;\n  newOp.next = splitOp;\n  newOutRec.pts = newOp;\n  splitOp.prev = newOp;\n  splitOp.next!.next = newOp;\n\n    if (!this.usingPolytree) return;\n    \n    if (this.path1InsidePath2(prevOp, newOp)) {\n      if (newOutRec.splits === null) newOutRec.splits = [];\n      newOutRec.splits.push(outrec.idx);\n    } else {\n      if (outrec.splits === null) outrec.splits = [];\n      outrec.splits.push(newOutRec.idx);\n    }\n  }\n\n  private static areaOutPt(op: OutPt): bigint {\n    const maxCoord = InternalClipper.maxCoordForSafeAreaProduct;\n    let area = 0.0;\n    let allSmall = true;\n    let op2 = op;\n    do {\n      const prev = op2.prev;\n      const pt = op2.pt;\n      if (Math.abs(prev.pt.x) >= maxCoord || Math.abs(prev.pt.y) >= maxCoord ||\n        Math.abs(pt.x) >= maxCoord || Math.abs(pt.y) >= maxCoord) {\n        allSmall = false;\n        break;\n      }\n      area += (prev.pt.y + pt.y) * (prev.pt.x - pt.x);\n      op2 = op2.next!;\n    } while (op2 !== op);\n\n    if (allSmall) {\n      return BigInt(Math.round(area));\n    }\n\n    let areaBig = B0;\n    op2 = op;\n    do {\n      const prev = op2.prev;\n      if (Number.isSafeInteger(prev.pt.y) && Number.isSafeInteger(op2.pt.y) &&\n        Number.isSafeInteger(prev.pt.x) && Number.isSafeInteger(op2.pt.x)) {\n        const sumBig = BigInt(prev.pt.y) + BigInt(op2.pt.y);\n        const diffBig = BigInt(prev.pt.x) - BigInt(op2.pt.x);\n        areaBig += sumBig * diffBig;\n      } else {\n        const sum = prev.pt.y + op2.pt.y;\n        const diff = prev.pt.x - op2.pt.x;\n        areaBig += BigInt(Math.round(sum * diff));\n      }\n      op2 = op2.next!;\n    } while (op2 !== op);\n    return areaBig;\n  }\n\n  private areaTriangle(pt1: Point64, pt2: Point64, pt3: Point64): bigint {\n    const maxCoord = InternalClipper.maxCoordForSafeAreaProduct;\n    if (Math.abs(pt1.x) < maxCoord && Math.abs(pt1.y) < maxCoord &&\n      Math.abs(pt2.x) < maxCoord && Math.abs(pt2.y) < maxCoord &&\n      Math.abs(pt3.x) < maxCoord && Math.abs(pt3.y) < maxCoord) {\n      const area = ((pt3.y + pt1.y) * (pt3.x - pt1.x) +\n        (pt1.y + pt2.y) * (pt1.x - pt2.x) +\n        (pt2.y + pt3.y) * (pt2.x - pt3.x));\n      return BigInt(Math.round(area));\n    }\n\n    if (Number.isSafeInteger(pt1.x) && Number.isSafeInteger(pt1.y) &&\n      Number.isSafeInteger(pt2.x) && Number.isSafeInteger(pt2.y) &&\n      Number.isSafeInteger(pt3.x) && Number.isSafeInteger(pt3.y)) {\n      const term1 = (BigInt(pt3.y) + BigInt(pt1.y)) * (BigInt(pt3.x) - BigInt(pt1.x));\n      const term2 = (BigInt(pt1.y) + BigInt(pt2.y)) * (BigInt(pt1.x) - BigInt(pt2.x));\n      const term3 = (BigInt(pt2.y) + BigInt(pt3.y)) * (BigInt(pt2.x) - BigInt(pt3.x));\n      return term1 + term2 + term3;\n    }\n\n    const area = ((pt3.y + pt1.y) * (pt3.x - pt1.x) +\n      (pt1.y + pt2.y) * (pt1.x - pt2.x) +\n      (pt2.y + pt3.y) * (pt2.x - pt3.x));\n    return BigInt(Math.round(area));\n  }\n\n  private isValidOwner(outRec: OutRec | null, testOwner: OutRec | null): boolean {\n    while (testOwner !== null && testOwner !== outRec) {\n      testOwner = testOwner.owner;\n    }\n    return testOwner === null;\n  }\n\n  private containsRect(rect: Rect64, rec: Rect64): boolean {\n    return rec.left >= rect.left && rec.right <= rect.right &&\n      rec.top >= rect.top && rec.bottom <= rect.bottom;\n  }\n\nprivate checkSplitOwner(outrec: OutRec, splits: number[]): boolean {\n  // nb: use indexing (not an iterator) in case 'splits' is modified inside this loop (#1029)\n  for (let i = 0; i < splits.length; i++) {\n    let split: OutRec | null = this.outrecList[splits[i]];\n    if (split.pts === null && split.splits !== null &&\n      this.checkSplitOwner(outrec, split.splits)) return true; // #942\n    split = this.getRealOutRec(split);\n    if (split === null || split === outrec || split.recursiveSplit === outrec) continue;\n    split.recursiveSplit = outrec; // #599\n    \n    if (split.splits !== null && this.checkSplitOwner(outrec, split.splits)) return true;\n\n      if (!this.checkBounds(split) ||\n          !this.containsRect(split.bounds, outrec.bounds) ||\n          !this.path1InsidePath2(outrec.pts!, split.pts!)) continue;\n\n      if (!this.isValidOwner(outrec, split)) { // split is owned by outrec (#957)\n        split.owner = outrec.owner;\n      }\n\n      outrec.owner = split; // found in split\n      return true;\n    }\n    return false;\n  }\n}\n\nexport class Clipper64 extends ClipperBase {\n  public zCallback?: ZCallback64;\n\n  protected getZCallback(): ZCallback64 | undefined {\n    return this.zCallback;\n  }\n\n  public addPath(path: Path64, polytype: PathType, isOpen: boolean = false): void {\n    super.addPath(path, polytype, isOpen);\n  }\n\n  public addReuseableData(reuseableData: ReuseableDataContainer64): void {\n    super.addReuseableData(reuseableData);\n  }\n\npublic addPaths(paths: Paths64, polytype: PathType, isOpen: boolean = false): void {\n  super.addPaths(paths, polytype, isOpen);\n}\n\n  public addSubject(paths: Paths64): void {\n    this.addPaths(paths, PathType.Subject);\n  }\n\n  public addOpenSubject(paths: Paths64): void {\n    this.addPaths(paths, PathType.Subject, true);\n  }\n\n  public addClip(paths: Paths64): void {\n    this.addPaths(paths, PathType.Clip);\n  }\n\n  public execute(clipType: ClipType, fillRule: FillRule, solutionClosed: Paths64, solutionOpen?: Paths64): boolean;\n  public execute(clipType: ClipType, fillRule: FillRule, polytree: PolyTree64, openPaths?: Paths64): boolean;\n  public execute(clipType: ClipType, fillRule: FillRule, solutionOrTree: Paths64 | PolyTree64, openPathsOrSolutionOpen?: Paths64): boolean {\n    if (Array.isArray(solutionOrTree)) {\n      // Paths64 version\n      const solutionClosed = solutionOrTree;\n      const solutionOpen = openPathsOrSolutionOpen;\n      \n      solutionClosed.length = 0;\n      if (solutionOpen) solutionOpen.length = 0;\n      \n      try {\n        this.executeInternal(clipType, fillRule);\n        this.buildPaths(solutionClosed, solutionOpen || []);\n      } catch {\n        this.succeeded = false;\n      }\n      \n      this.clearSolutionOnly();\n      return this.succeeded;\n    } else {\n      // PolyTree64 version\n      const polytree = solutionOrTree;\n      const openPaths = openPathsOrSolutionOpen;\n      \n      polytree.clear();\n      if (openPaths) openPaths.length = 0;\n      this.usingPolytree = true;\n      \n      try {\n        this.executeInternal(clipType, fillRule);\n        this.buildTree(polytree, openPaths || []);\n      } catch {\n        this.succeeded = false;\n      }\n      \n      this.clearSolutionOnly();\n      return this.succeeded;\n    }\n  }\n}\n\nexport class ClipperD extends ClipperBase {\n  public zCallback?: ZCallbackD;\n  private readonly scale: number;\n  private readonly invScale: number;\n\n  constructor(roundingDecimalPrecision: number = 2) {\n    super();\n    InternalClipper.checkPrecision(roundingDecimalPrecision);\n    this.scale = Math.pow(10, roundingDecimalPrecision);\n    this.invScale = 1 / this.scale;\n  }\n\n  protected getZCallback(): ZCallbackD | undefined {\n    return this.zCallback;\n  }\n\n  private scalePathDFromInt(path: Path64, scale: number): PathD {\n    const result: PathD = [];\n    for (const pt of path) {\n      result.push({\n        x: pt.x * scale,\n        y: pt.y * scale,\n        z: pt.z || 0\n      });\n    }\n    return result;\n  }\n\n  public buildPathsD(solutionClosed: PathsD, solutionOpen: PathsD): boolean {\n    solutionClosed.length = 0;\n    solutionOpen.length = 0;\n    \n    let i = 0;\n    // outrecList.length is not static here because\n    // CleanCollinear can indirectly add additional OutRec\n    while (i < this.outrecList.length) {\n      const outrec = this.outrecList[i++];\n      if (outrec.pts === null) continue;\n\n      const path: Path64 = [];\n      if (outrec.isOpen) {\n        if (ClipperBase.buildPath(outrec.pts, this.reverseSolution, true, path)) {\n          solutionOpen.push(this.scalePathDFromInt(path, this.invScale));\n        }\n      } else {\n        this.cleanCollinear(outrec);\n        // closed paths should always return a Positive orientation\n        // except when ReverseSolution == true\n        if (ClipperBase.buildPath(outrec.pts, this.reverseSolution, false, path)) {\n          solutionClosed.push(this.scalePathDFromInt(path, this.invScale));\n        }\n      }\n    }\n    return true;\n  }\n\n  public buildTreeD(polytree: PolyPathBase, solutionOpen: PathsD): void {\n    polytree.clear();\n    solutionOpen.length = 0;\n\n    let i = 0;\n    // outrecList.length is not static here because\n    // BuildPathD below can indirectly add additional OutRec\n    while (i < this.outrecList.length) {\n      const outrec = this.outrecList[i++];\n      if (outrec.pts === null) continue;\n      \n      if (outrec.isOpen) {\n        const openPath: Path64 = [];\n        if (ClipperBase.buildPath(outrec.pts, this.reverseSolution, true, openPath)) {\n          solutionOpen.push(this.scalePathDFromInt(openPath, this.invScale));\n        }\n        continue;\n      }\n      \n      if (this.checkBounds(outrec)) {\n        this.recursiveCheckOwners(outrec, polytree);\n      }\n    }\n  }\n\n  public addPath(path: PathD, polytype: PathType, isOpen: boolean = false): void {\n    const tmp: PathsD = [path];\n    this.addPaths(tmp, polytype, isOpen);\n  }\n\n  public addPaths(paths: PathsD, polytype: PathType, isOpen: boolean = false): void {\n    super.addPaths(Clipper.scalePaths64(paths, this.scale), polytype, isOpen);\n  }\n\n  public addSubject(path: PathD): void {\n    this.addPath(path, PathType.Subject);\n  }\n\n  public addOpenSubject(path: PathD): void {\n    this.addPath(path, PathType.Subject, true);\n  }\n\n  public addClip(path: PathD): void {\n    this.addPath(path, PathType.Clip);\n  }\n\n  public addSubjectPaths(paths: PathsD): void {\n    this.addPaths(paths, PathType.Subject);\n  }\n\n  public addOpenSubjectPaths(paths: PathsD): void {\n    this.addPaths(paths, PathType.Subject, true);\n  }\n\n  public addClipPaths(paths: PathsD): void {\n    this.addPaths(paths, PathType.Clip);\n  }\n\n  public execute(clipType: ClipType, fillRule: FillRule, solutionClosed: PathsD, solutionOpen?: PathsD): boolean;\n  public execute(clipType: ClipType, fillRule: FillRule, polytree: PolyTreeD, openPaths?: PathsD): boolean;\n  public execute(clipType: ClipType, fillRule: FillRule, solutionOrTree: PathsD | PolyTreeD, openPathsOrSolutionOpen?: PathsD): boolean {\n    if (Array.isArray(solutionOrTree)) {\n      // PathsD version - match C# implementation exactly\n      const solutionClosed = solutionOrTree;\n      const solutionOpen = openPathsOrSolutionOpen;\n      \n      // Use Paths64 internally like C# does\n      const solClosed64: Paths64 = [];\n      const solOpen64: Paths64 = [];\n      \n      solutionClosed.length = 0;\n      if (solutionOpen) solutionOpen.length = 0;\n      \n      let success = true;\n      try {\n        this.executeInternal(clipType, fillRule);\n        // Call regular buildPaths which includes cleanCollinear and fixSelfIntersects\n        this.buildPaths(solClosed64, solOpen64);\n      } catch {\n        success = false;\n      }\n      \n      this.clearSolutionOnly();\n      if (!success) return false;\n      \n      // Convert Paths64 to PathsD\n      for (const path of solClosed64) {\n        solutionClosed.push(this.scalePathDFromInt(path, this.invScale));\n      }\n      if (solutionOpen) {\n        for (const path of solOpen64) {\n          solutionOpen.push(this.scalePathDFromInt(path, this.invScale));\n        }\n      }\n      \n      return true;\n    } else {\n      // PolyTreeD version\n      const polytree = solutionOrTree;\n      const openPaths = openPathsOrSolutionOpen;\n      \n      polytree.clear();\n      if (openPaths) openPaths.length = 0;\n      this.usingPolytree = true;\n      polytree.scale = this.scale;\n      \n      let success = true;\n      try {\n        this.executeInternal(clipType, fillRule);\n        this.buildTreeD(polytree, openPaths || []);\n      } catch {\n        success = false;\n      }\n      this.clearSolutionOnly();\n      return success;\n    }\n  }\n}\n\n// Forward declaration for Clipper class (plain object, avoids namespace IIFE)\nexport const Clipper = {\n  area(path: Path64): number {\n    return InternalClipper.area(path);\n  },\n\n  areaD(path: PathD): number {\n    let a = 0.0;\n    const cnt = path.length;\n    if (cnt < 3) return 0.0;\n    let prevPt = path[cnt - 1];\n    for (const pt of path) {\n      a += (prevPt.y + pt.y) * (prevPt.x - pt.x);\n      prevPt = pt;\n    }\n    return a * 0.5;\n  },\n\n  scalePath64(path: PathD, scale: number): Path64 {\n    const maxAbs = InternalClipper.maxSafeCoordinateForScale(scale);\n    const result: Path64 = [];\n    for (const pt of path) {\n      InternalClipper.checkSafeScaleValue(pt.x, maxAbs, \"scalePath64\");\n      InternalClipper.checkSafeScaleValue(pt.y, maxAbs, \"scalePath64\");\n      result.push({\n        x: Math.round(pt.x * scale),\n        y: Math.round(pt.y * scale)\n      });\n    }\n    return result;\n  },\n\n  scalePaths64(paths: PathsD, scale: number): Paths64 {\n    const result: Paths64 = [];\n    for (const path of paths) {\n      result.push(Clipper.scalePath64(path, scale));\n    }\n    return result;\n  },\n\n  scalePathD(path: Path64, scale: number): PathD {\n    const result: PathD = [];\n    for (const pt of path) {\n      result.push({\n        x: pt.x * scale,\n        y: pt.y * scale\n      });\n    }\n    return result;\n  },\n\n  scalePathsD(paths: Paths64, scale: number): PathsD {\n    const result: PathsD = [];\n    for (const path of paths) {\n      result.push(Clipper.scalePathD(path, scale));\n    }\n    return result;\n  },\n};","/*******************************************************************************\n* Author    :  Angus Johnson                                                   *\n* Date      :  11 October 2025                                                 *\n* Website   :  https://www.angusj.com                                          *\n* Copyright :  Angus Johnson 2010-2025                                         *\n* Purpose   :  Path Offset (Inflate/Shrink)                                    *\n* License   :  https://www.boost.org/LICENSE_1_0.txt                           *\n*******************************************************************************/\n\nimport {\n  Point64, PointD, Path64, PathD, Paths64,\n  ClipType, FillRule,\n  Point64Utils, PointDUtils, InternalClipper\n} from './Core.js';\nimport { Clipper64, PolyTree64 } from './Engine.js';\n\nexport enum JoinType {\n  Miter = 0,\n  Square = 1,\n  Bevel = 2,\n  Round = 3\n}\n\nexport enum EndType {\n  Polygon = 0,\n  Joined = 1,\n  Butt = 2,\n  Square = 3,\n  Round = 4\n}\n\nclass Group {\n  public inPaths: Paths64;\n  public joinType: JoinType;\n  public endType: EndType;\n  public pathsReversed: boolean;\n  public lowestPathIdx: number;\n\n  constructor(paths: Paths64, joinType: JoinType, endType: EndType = EndType.Polygon) {\n    this.joinType = joinType;\n    this.endType = endType;\n\n    const isJoined = (endType === EndType.Polygon) || (endType === EndType.Joined);\n    this.inPaths = [];\n    for (const path of paths) {\n      this.inPaths.push(ClipperOffset.stripDuplicates(path, isJoined));\n    }\n\n    if (endType === EndType.Polygon) {\n      const lowestInfo = ClipperOffset.getLowestPathInfo(this.inPaths);\n      this.lowestPathIdx = lowestInfo.idx;\n      // the lowermost path must be an outer path, so if its orientation is negative,\n      // then flag that the whole group is 'reversed' (will negate delta etc.)\n      // as this is much more efficient than reversing every path.\n      this.pathsReversed = (this.lowestPathIdx >= 0) && lowestInfo.isNegArea;\n    } else {\n      this.lowestPathIdx = -1;\n      this.pathsReversed = false;\n    }\n  }\n}\n\nexport class ClipperOffset {\n  private static readonly Tolerance = 1.0E-12;\n\n  // Clipper2 approximates arcs by using series of relatively short straight\n  //line segments. And logically, shorter line segments will produce better arc\n  // approximations. But very short segments can degrade performance, usually\n  // with little or no discernable improvement in curve quality. Very short\n  // segments can even detract from curve quality, due to the effects of integer\n  // rounding. Since there isn't an optimal number of line segments for any given\n  // arc radius (that perfectly balances curve approximation with performance),\n  // arc tolerance is user defined. Nevertheless, when the user doesn't define\n  // an arc tolerance (ie leaves alone the 0 default value), the calculated\n  // default arc tolerance (offset_radius / 500) generally produces good (smooth)\n  // arc approximations without producing excessively small segment lengths.\n  // See also: https://www.angusj.com/clipper2/Docs/Trigonometry.htm\n  private static readonly arc_const = 0.002; // <-- 1/500\n\n  private readonly groupList: Group[] = [];\n  private pathOut: Path64 = [];\n  private readonly normals: PathD = [];\n  private solution: Paths64 = [];\n  private solutionTree: PolyTree64 | null = null;\n\n  private groupDelta: number = 0; //*0.5 for open paths; *-1.0 for negative areas\n  private delta: number = 0;\n  private mitLimSqr: number = 0;\n  private stepsPerRad: number = 0;\n  private stepSin: number = 0;\n  private stepCos: number = 0;\n  private joinType: JoinType = JoinType.Bevel;\n  private endType: EndType = EndType.Polygon;\n\n  public arcTolerance: number = 0;\n  public mergeGroups: boolean = true;\n  public miterLimit: number = 2.0;\n  public preserveCollinear: boolean = false;\n  public reverseSolution: boolean = false;\n  public zCallback?: (bot1: Point64, top1: Point64, bot2: Point64, top2: Point64, intersectPt: Point64) => void;\n\n  public deltaCallback: ((path: Path64, pathNorms: PathD, currPt: number, prevPt: number) => number) | null = null;\n\n  constructor(\n    miterLimit: number = 2.0,\n    arcTolerance: number = 0.0,\n    preserveCollinear: boolean = false,\n    reverseSolution: boolean = false\n  ) {\n    this.miterLimit = miterLimit;\n    this.arcTolerance = arcTolerance;\n    this.mergeGroups = true;\n    this.preserveCollinear = preserveCollinear;\n    this.reverseSolution = reverseSolution;\n  }\n\n  public clear(): void {\n    this.groupList.length = 0;\n  }\n\n  // Internal Z callback that implements default Z handling before calling user callback\n  private ZCB = (bot1: Point64, top1: Point64, bot2: Point64, top2: Point64, intersectPt: Point64): void => {\n    // Default Z handling: if endpoints share a Z value, use it\n    if ((bot1.z || 0) !== 0 && ((bot1.z === bot2.z) || (bot1.z === top2.z))) {\n      intersectPt.z = bot1.z;\n    } else if ((bot2.z || 0) !== 0 && bot2.z === top1.z) {\n      intersectPt.z = bot2.z;\n    } else if ((top1.z || 0) !== 0 && top1.z === top2.z) {\n      intersectPt.z = top1.z;\n    } else if (this.zCallback) {\n      // Fall back to user callback if no default applies\n      this.zCallback(bot1, top1, bot2, top2, intersectPt);\n    }\n  }\n\n  public addPath(path: Path64, joinType: JoinType, endType: EndType): void {\n    if (path.length === 0) return;\n    const pp: Paths64 = [path];\n    this.addPaths(pp, joinType, endType);\n  }\n\n  public addPaths(paths: Paths64, joinType: JoinType, endType: EndType): void {\n    if (paths.length === 0) return;\n    this.groupList.push(new Group(paths, joinType, endType));\n  }\n\n  private calcSolutionCapacity(): number {\n    let result = 0;\n    for (const g of this.groupList) {\n      result += (g.endType === EndType.Joined) ? g.inPaths.length * 2 : g.inPaths.length;\n    }\n    return result;\n  }\n\n  private checkPathsReversed(): boolean {\n    let result = false;\n    for (const g of this.groupList) {\n      if (g.endType === EndType.Polygon) {\n        result = g.pathsReversed;\n        break;\n      }\n    }\n    return result;\n  }\n\n  private executeInternal(delta: number): void {\n    if (this.groupList.length === 0) return;\n    \n    // make sure the offset delta is significant\n    if (Math.abs(delta) < 0.5) {\n      for (const group of this.groupList) {\n        for (const path of group.inPaths) {\n          this.solution.push(path);\n        }\n      }\n      return;\n    }\n\n    this.delta = delta;\n    this.mitLimSqr = (this.miterLimit <= 1 ?\n      2.0 : 2.0 / ClipperOffset.sqr(this.miterLimit));\n\n    for (const group of this.groupList) {\n      this.doGroupOffset(group);\n    }\n\n    if (this.groupList.length === 0) return;\n\n    const pathsReversed = this.checkPathsReversed();\n    const fillRule = pathsReversed ? FillRule.Negative : FillRule.Positive;\n\n    // clean up self-intersections ...\n    const c = new Clipper64();\n    c.preserveCollinear = this.preserveCollinear;\n    c.reverseSolution = this.reverseSolution !== pathsReversed;\n    c.zCallback = this.ZCB;\n    c.addSubject(this.solution);\n    \n    if (this.solutionTree !== null) {\n      c.execute(ClipType.Union, fillRule, this.solutionTree);\n    } else {\n      c.execute(ClipType.Union, fillRule, this.solution);\n    }\n  }\n\n  public execute(delta: number, solution: Paths64): void;\n  public execute(delta: number, solutionTree: PolyTree64): void;\n  public execute(delta: number, solutionOrTree: Paths64 | PolyTree64): void {\n    if (Array.isArray(solutionOrTree)) {\n      // Paths64 version\n      const solution = solutionOrTree;\n      solution.length = 0;\n      this.solution = solution;\n      this.executeInternal(delta);\n    } else {\n      // PolyTree64 version\n      const solutionTree = solutionOrTree;\n      solutionTree.clear();\n      this.solutionTree = solutionTree;\n      this.solution = [];\n      this.executeInternal(delta);\n    }\n  }\n\n  public executeWithCallback(deltaCallback: (path: Path64, pathNorms: PathD, currPt: number, prevPt: number) => number, solution: Paths64): void {\n    this.deltaCallback = deltaCallback;\n    this.execute(1.0, solution);\n  }\n\n  public static getUnitNormal(pt1: Point64, pt2: Point64): PointD {\n    const dx = (pt2.x - pt1.x);\n    const dy = (pt2.y - pt1.y);\n    if ((dx === 0) && (dy === 0)) return { x: 0, y: 0 };\n\n    const f = 1.0 / Math.sqrt(dx * dx + dy * dy);\n    return {\n      x: dy * f,\n      y: -dx * f\n    };\n  }\n\n  public static getLowestPathInfo(paths: Paths64): { idx: number; isNegArea: boolean } {\n    let idx = -1;\n    let isNegArea = false;\n    const botPt: Point64 = { x: Number.MAX_SAFE_INTEGER, y: Number.MIN_SAFE_INTEGER };\n    \n    for (let i = 0; i < paths.length; ++i) {\n      let a = Number.MAX_VALUE;\n      for (const pt of paths[i]) {\n        if ((pt.y < botPt.y) || ((pt.y === botPt.y) && (pt.x >= botPt.x))) continue;\n        if (a === Number.MAX_VALUE) {\n          a = ClipperOffset.area(paths[i]);\n          if (a === 0) break; // invalid closed path so break from inner loop\n          isNegArea = a < 0;\n        }\n        idx = i;\n        botPt.x = pt.x;\n        botPt.y = pt.y;\n      }\n    }\n    return { idx, isNegArea };\n  }\n\n  private static translatePoint(pt: PointD, dx: number, dy: number): PointD {\n    return { x: pt.x + dx, y: pt.y + dy, z: pt.z };\n  }\n\n  private static reflectPoint(pt: PointD, pivot: PointD): PointD {\n    return { x: pivot.x + (pivot.x - pt.x), y: pivot.y + (pivot.y - pt.y), z: pt.z };\n  }\n\n  private static almostZero(value: number, epsilon: number = 0.001): boolean {\n    return Math.abs(value) < epsilon;\n  }\n\n  private static hypotenuse(x: number, y: number): number {\n    return Math.sqrt(x * x + y * y);\n  }\n\n  private static normalizeVector(vec: PointD): PointD {\n    const h = ClipperOffset.hypotenuse(vec.x, vec.y);\n    if (ClipperOffset.almostZero(h)) return { x: 0, y: 0 };\n    const inverseHypot = 1 / h;\n    return { x: vec.x * inverseHypot, y: vec.y * inverseHypot };\n  }\n\n  private static getAvgUnitVector(vec1: PointD, vec2: PointD): PointD {\n    return ClipperOffset.normalizeVector({ x: vec1.x + vec2.x, y: vec1.y + vec2.y });\n  }\n\n  private static intersectPoint(pt1a: PointD, pt1b: PointD, pt2a: PointD, pt2b: PointD): PointD {\n    if (InternalClipper.isAlmostZero(pt1a.x - pt1b.x)) { // vertical\n      if (InternalClipper.isAlmostZero(pt2a.x - pt2b.x)) return { x: 0, y: 0 };\n      const m2 = (pt2b.y - pt2a.y) / (pt2b.x - pt2a.x);\n      const b2 = pt2a.y - m2 * pt2a.x;\n      return { x: pt1a.x, y: m2 * pt1a.x + b2 };\n    }\n\n    if (InternalClipper.isAlmostZero(pt2a.x - pt2b.x)) { // vertical\n      const m1 = (pt1b.y - pt1a.y) / (pt1b.x - pt1a.x);\n      const b1 = pt1a.y - m1 * pt1a.x;\n      return { x: pt2a.x, y: m1 * pt2a.x + b1 };\n    } else {\n      const m1 = (pt1b.y - pt1a.y) / (pt1b.x - pt1a.x);\n      const b1 = pt1a.y - m1 * pt1a.x;\n      const m2 = (pt2b.y - pt2a.y) / (pt2b.x - pt2a.x);\n      const b2 = pt2a.y - m2 * pt2a.x;\n      if (InternalClipper.isAlmostZero(m1 - m2)) return { x: 0, y: 0 };\n      const x = (b2 - b1) / (m1 - m2);\n      return { x: x, y: m1 * x + b1 };\n    }\n  }\n\n  private getPerpendic(pt: Point64, norm: PointD): Point64 {\n    return {\n      x: Math.round(pt.x + norm.x * this.groupDelta),\n      y: Math.round(pt.y + norm.y * this.groupDelta),\n      z: (pt.z || 0)\n    };\n  }\n\n  private getPerpendicD(pt: Point64, norm: PointD): PointD {\n    return {\n      x: pt.x + norm.x * this.groupDelta,\n      y: pt.y + norm.y * this.groupDelta,\n      z: (pt.z || 0)\n    };\n  }\n\n  private doBevel(path: Path64, j: number, k: number): void {\n    let pt1: Point64, pt2: Point64;\n    const pjz = (path[j].z || 0);\n    if (j === k) {\n      const absDelta = Math.abs(this.groupDelta);\n      pt1 = {\n        x: Math.round(path[j].x - absDelta * this.normals[j].x),\n        y: Math.round(path[j].y - absDelta * this.normals[j].y),\n        z: pjz\n      };\n      pt2 = {\n        x: Math.round(path[j].x + absDelta * this.normals[j].x),\n        y: Math.round(path[j].y + absDelta * this.normals[j].y),\n        z: pjz\n      };\n    } else {\n      pt1 = {\n        x: Math.round(path[j].x + this.groupDelta * this.normals[k].x),\n        y: Math.round(path[j].y + this.groupDelta * this.normals[k].y),\n        z: pjz\n      };\n      pt2 = {\n        x: Math.round(path[j].x + this.groupDelta * this.normals[j].x),\n        y: Math.round(path[j].y + this.groupDelta * this.normals[j].y),\n        z: pjz\n      };\n    }\n    this.pathOut.push(pt1);\n    this.pathOut.push(pt2);\n  }\n\n  private doSquare(path: Path64, j: number, k: number): void {\n    let vec: PointD;\n    if (j === k) {\n      vec = { x: this.normals[j].y, y: -this.normals[j].x };\n    } else {\n      vec = ClipperOffset.getAvgUnitVector(\n        { x: -this.normals[k].y, y: this.normals[k].x },\n        { x: this.normals[j].y, y: -this.normals[j].x }\n      );\n    }\n\n    const absDelta = Math.abs(this.groupDelta);\n\n    // now offset the original vertex delta units along unit vector\n    let ptQ: PointD = { x: path[j].x, y: path[j].y, z: (path[j].z || 0) };\n    ptQ = ClipperOffset.translatePoint(ptQ, absDelta * vec.x, absDelta * vec.y);\n\n    // get perpendicular vertices\n    const pt1 = ClipperOffset.translatePoint(ptQ, this.groupDelta * vec.y, this.groupDelta * -vec.x);\n    const pt2 = ClipperOffset.translatePoint(ptQ, this.groupDelta * -vec.y, this.groupDelta * vec.x);\n    // get 2 vertices along one edge offset\n    const pt3 = this.getPerpendicD(path[k], this.normals[k]);\n\n    if (j === k) {\n      const pt4: PointD = {\n        x: pt3.x + vec.x * this.groupDelta,\n        y: pt3.y + vec.y * this.groupDelta\n      };\n      const pt = ClipperOffset.intersectPoint(pt1, pt2, pt3, pt4);\n      pt.z = ptQ.z;\n      //get the second intersect point through reflecion\n      this.pathOut.push(Point64Utils.fromPointD(ClipperOffset.reflectPoint(pt, ptQ)));\n      this.pathOut.push(Point64Utils.fromPointD(pt));\n    } else {\n      const pt4 = this.getPerpendicD(path[j], this.normals[k]);\n      const pt = ClipperOffset.intersectPoint(pt1, pt2, pt3, pt4);\n      pt.z = ptQ.z;\n      this.pathOut.push(Point64Utils.fromPointD(pt));\n      //get the second intersect point through reflecion\n      this.pathOut.push(Point64Utils.fromPointD(ClipperOffset.reflectPoint(pt, ptQ)));\n    }\n  }\n\n  private doMiter(path: Path64, j: number, k: number, cosA: number): void {\n    const q = this.groupDelta / (cosA + 1);\n    this.pathOut.push({\n      x: Math.round(path[j].x + (this.normals[k].x + this.normals[j].x) * q),\n      y: Math.round(path[j].y + (this.normals[k].y + this.normals[j].y) * q),\n      z: (path[j].z || 0)\n    });\n  }\n\n  private doRound(path: Path64, j: number, k: number, angle: number): void {\n    if (this.deltaCallback !== null) {\n      // when deltaCallback is assigned, groupDelta won't be constant,\n      // so we'll need to do the following calculations for *every* vertex.\n      const absDelta = Math.abs(this.groupDelta);\n      const arcTol = this.arcTolerance > 0.01 ? this.arcTolerance : absDelta * ClipperOffset.arc_const;\n      const stepsPer360 = Math.PI / Math.acos(1 - arcTol / absDelta);\n      this.stepSin = Math.sin((2 * Math.PI) / stepsPer360);\n      this.stepCos = Math.cos((2 * Math.PI) / stepsPer360);\n      if (this.groupDelta < 0.0) this.stepSin = -this.stepSin;\n      this.stepsPerRad = stepsPer360 / (2 * Math.PI);\n    }\n\n    const pt = path[j];\n    const ptz = (pt.z || 0);\n    let offsetVec: PointD = { x: this.normals[k].x * this.groupDelta, y: this.normals[k].y * this.groupDelta };\n    if (j === k) PointDUtils.negate(offsetVec);\n    \n    this.pathOut.push({\n      x: Math.round(pt.x + offsetVec.x),\n      y: Math.round(pt.y + offsetVec.y),\n      z: ptz\n    });\n    \n    const steps = Math.ceil(this.stepsPerRad * Math.abs(angle));\n    for (let i = 1; i < steps; i++) { // ie 1 less than steps\n      offsetVec = {\n        x: offsetVec.x * this.stepCos - this.stepSin * offsetVec.y,\n        y: offsetVec.x * this.stepSin + offsetVec.y * this.stepCos\n      };\n      this.pathOut.push({\n        x: Math.round(pt.x + offsetVec.x),\n        y: Math.round(pt.y + offsetVec.y),\n        z: ptz\n      });\n    }\n    this.pathOut.push(this.getPerpendic(path[j], this.normals[j]));\n  }\n\n  private buildNormals(path: Path64): void {\n    const cnt = path.length;\n    this.normals.length = 0;\n    if (cnt === 0) return;\n    \n    for (let i = 0; i < cnt - 1; i++) {\n      this.normals.push(ClipperOffset.getUnitNormal(path[i], path[i + 1]));\n    }\n    this.normals.push(ClipperOffset.getUnitNormal(path[cnt - 1], path[0]));\n  }\n\n  private offsetPoint(group: Group, path: Path64, j: number, k: number): void {\n    if (Point64Utils.equals(path[j], path[k])) return;\n\n    // Let A = change in angle where edges join\n    // A == 0: ie no change in angle (flat join)\n    // A == PI: edges 'spike'\n    // sin(A) < 0: right turning\n    // cos(A) < 0: change in angle is more than 90 degree\n    let sinA = InternalClipper.crossProductD(this.normals[j], this.normals[k]);\n    const cosA = InternalClipper.dotProductD(this.normals[j], this.normals[k]);\n    if (sinA > 1.0) sinA = 1.0;\n    else if (sinA < -1.0) sinA = -1.0;\n\n    if (this.deltaCallback !== null) {\n      this.groupDelta = this.deltaCallback(path, this.normals, j, k);\n      if (group.pathsReversed) this.groupDelta = -this.groupDelta;\n    }\n    if (Math.abs(this.groupDelta) < ClipperOffset.Tolerance) {\n      this.pathOut.push(path[j]);\n      return;\n    }\n\n    if (cosA > -0.999 && (sinA * this.groupDelta < 0)) { // test for concavity first (#593)\n      // is concave\n      // by far the simplest way to construct concave joins, especially those joining very \n      // short segments, is to insert 3 points that produce negative regions. These regions \n      // will be removed later by the finishing union operation. This is also the best way \n      // to ensure that path reversals (ie over-shrunk paths) are removed.\n      this.pathOut.push(this.getPerpendic(path[j], this.normals[k]));\n      this.pathOut.push(path[j]); // (#405, #873, #916)\n      this.pathOut.push(this.getPerpendic(path[j], this.normals[j]));\n    } else if ((cosA > 0.999) && (this.joinType !== JoinType.Round)) {\n      // almost straight - less than 2.5 degree (#424, #482, #526 & #724) \n      this.doMiter(path, j, k, cosA);\n    } else {\n      switch (this.joinType) {\n        // miter unless the angle is sufficiently acute to exceed ML\n        case JoinType.Miter:\n          if (cosA > this.mitLimSqr - 1) {\n            this.doMiter(path, j, k, cosA);\n          } else {\n            this.doSquare(path, j, k);\n          }\n          break;\n        case JoinType.Round:\n          this.doRound(path, j, k, Math.atan2(sinA, cosA));\n          break;\n        case JoinType.Bevel:\n          this.doBevel(path, j, k);\n          break;\n        default:\n          this.doSquare(path, j, k);\n          break;\n      }\n    }\n  }\n\n  private offsetPolygon(group: Group, path: Path64): void {\n    this.pathOut = [];\n    const cnt = path.length;\n    let prev = cnt - 1;\n    for (let i = 0; i < cnt; i++) {\n      this.offsetPoint(group, path, i, prev);\n      prev = i;\n    }\n    // pathOut is freshly allocated per call, so push directly (no spread clone needed)\n    this.solution.push(this.pathOut);\n  }\n\n  private offsetOpenJoined(group: Group, path: Path64): void {\n    this.offsetPolygon(group, path);\n    const reversePath = [...path].reverse();\n    this.buildNormals(reversePath);\n    this.offsetPolygon(group, reversePath);\n  }\n\n  private offsetOpenPath(group: Group, path: Path64): void {\n    this.pathOut = [];\n    const highI = path.length - 1;\n\n    if (this.deltaCallback !== null) {\n      this.groupDelta = this.deltaCallback(path, this.normals, 0, 0);\n    }\n\n    // do the line start cap\n    if (Math.abs(this.groupDelta) < ClipperOffset.Tolerance) {\n      this.pathOut.push(path[0]);\n    } else {\n      switch (this.endType) {\n        case EndType.Butt:\n          this.doBevel(path, 0, 0);\n          break;\n        case EndType.Round:\n          this.doRound(path, 0, 0, Math.PI);\n          break;\n        default:\n          this.doSquare(path, 0, 0);\n          break;\n      }\n    }\n\n    // offset the left side going forward\n    for (let i = 1, k = 0; i < highI; i++) {\n      this.offsetPoint(group, path, i, k);\n      k = i;\n    }\n\n    // reverse normals ...\n    for (let i = highI; i > 0; i--) {\n      this.normals[i] = { x: -this.normals[i - 1].x, y: -this.normals[i - 1].y };\n    }\n    this.normals[0] = this.normals[highI];\n\n    if (this.deltaCallback !== null) {\n      this.groupDelta = this.deltaCallback(path, this.normals, highI, highI);\n    }\n    \n    // do the line end cap\n    if (Math.abs(this.groupDelta) < ClipperOffset.Tolerance) {\n      this.pathOut.push(path[highI]);\n    } else {\n      switch (this.endType) {\n        case EndType.Butt:\n          this.doBevel(path, highI, highI);\n          break;\n        case EndType.Round:\n          this.doRound(path, highI, highI, Math.PI);\n          break;\n        default:\n          this.doSquare(path, highI, highI);\n          break;\n      }\n    }\n\n    // offset the left side going back\n    for (let i = highI - 1, k = highI; i > 0; i--) {\n      this.offsetPoint(group, path, i, k);\n      k = i;\n    }\n\n    // pathOut is freshly allocated per call, so push directly (no spread clone needed)\n    this.solution.push(this.pathOut);\n  }\n\n  private doGroupOffset(group: Group): void {\n    if (group.endType === EndType.Polygon) {\n      // a straight path (2 points) can now also be 'polygon' offset \n      // where the ends will be treated as (180 deg.) joins\n      if (group.lowestPathIdx < 0) this.delta = Math.abs(this.delta);\n      this.groupDelta = group.pathsReversed ? -this.delta : this.delta;\n    } else {\n      this.groupDelta = Math.abs(this.delta);\n    }\n\n    const absDelta = Math.abs(this.groupDelta);\n\n    this.joinType = group.joinType;\n    this.endType = group.endType;\n\n    if (group.joinType === JoinType.Round || group.endType === EndType.Round) {\n      const arcTol = this.arcTolerance > 0.01 ? this.arcTolerance : absDelta * ClipperOffset.arc_const;\n      const stepsPer360 = Math.PI / Math.acos(1 - arcTol / absDelta);\n      this.stepSin = Math.sin((2 * Math.PI) / stepsPer360);\n      this.stepCos = Math.cos((2 * Math.PI) / stepsPer360);\n      if (this.groupDelta < 0.0) this.stepSin = -this.stepSin;\n      this.stepsPerRad = stepsPer360 / (2 * Math.PI);\n    }\n\n    for (const pathIn of group.inPaths) {\n      this.pathOut = [];\n      const cnt = pathIn.length;\n\n      if (cnt === 1) {\n        // single point\n        const pt = pathIn[0];\n\n        if (this.deltaCallback !== null) {\n          this.groupDelta = this.deltaCallback(pathIn, this.normals, 0, 0);\n          if (group.pathsReversed) this.groupDelta = -this.groupDelta;\n        }\n\n        // single vertex so build a circle or square ...\n        const ptz = (pt.z || 0);\n        if (group.endType === EndType.Round) {\n          const steps = Math.ceil(this.stepsPerRad * 2 * Math.PI);\n          this.pathOut = ClipperOffset.ellipse(pt, Math.abs(this.groupDelta), Math.abs(this.groupDelta), steps);\n          if (ptz !== 0) for (let i = 0; i < this.pathOut.length; i++) this.pathOut[i].z = ptz;\n        } else {\n          const d = Math.ceil(Math.abs(this.groupDelta));\n          const r = { left: pt.x - d, top: pt.y - d, right: pt.x + d, bottom: pt.y + d };\n          this.pathOut = [\n            { x: r.left, y: r.top, z: ptz },\n            { x: r.right, y: r.top, z: ptz },\n            { x: r.right, y: r.bottom, z: ptz },\n            { x: r.left, y: r.bottom, z: ptz }\n          ];\n        }\n        // pathOut is freshly allocated per call, so push directly (no spread clone needed)\n        this.solution.push(this.pathOut);\n        continue; // end of offsetting a single point\n      }\n\n      if (cnt === 2 && group.endType === EndType.Joined) {\n        this.endType = (group.joinType === JoinType.Round) ?\n          EndType.Round :\n          EndType.Square;\n      }\n\n      this.buildNormals(pathIn);\n      switch (this.endType) {\n        case EndType.Polygon:\n          this.offsetPolygon(group, pathIn);\n          break;\n        case EndType.Joined:\n          this.offsetOpenJoined(group, pathIn);\n          break;\n        default:\n          this.offsetOpenPath(group, pathIn);\n          break;\n      }\n    }\n  }\n\n  public static stripDuplicates(path: Path64, isClosedPath: boolean): Path64 {\n    const cnt = path.length;\n    const result: Path64 = [];\n    if (cnt === 0) return result;\n    \n    let lastPt = path[0];\n    result.push(lastPt);\n    for (let i = 1; i < cnt; i++) {\n      if (!Point64Utils.equals(lastPt, path[i])) {\n        lastPt = path[i];\n        result.push(lastPt);\n      }\n    }\n    if (isClosedPath && Point64Utils.equals(lastPt, result[0])) {\n      result.pop();\n    }\n    return result;\n  }\n\n  public static area(path: Path64): number {\n    return InternalClipper.area(path);\n  }\n\n  public static sqr(val: number): number {\n    return val * val;\n  }\n\n  public static ellipse(center: Point64, radiusX: number, radiusY: number = 0, steps: number = 0): Path64 {\n    if (radiusX <= 0) return [];\n    if (radiusY <= 0) radiusY = radiusX;\n    if (steps <= 2) {\n      steps = Math.ceil(Math.PI * Math.sqrt((radiusX + radiusY) / 2));\n    }\n\n    const si = Math.sin(2 * Math.PI / steps);\n    const co = Math.cos(2 * Math.PI / steps);\n    let dx = co;\n    let dy = si;\n    const result: Path64 = [{ x: Math.round(center.x + radiusX), y: center.y }];\n    \n    for (let i = 1; i < steps; ++i) {\n      result.push({\n        x: Math.round(center.x + radiusX * dx),\n        y: Math.round(center.y + radiusY * dy)\n      });\n      const x = dx * co - dy * si;\n      dy = dy * co + dx * si;\n      dx = x;\n    }\n    return result;\n  }\n}\n","/*******************************************************************************\n* Author    :  Angus Johnson                                                   *\n* Date      :  11 October 2025                                                 *\n* Website   :  https://www.angusj.com                                          *\n* Copyright :  Angus Johnson 2010-2025                                         *\n* Purpose   :  FAST rectangular clipping                                       *\n* License   :  https://www.boost.org/LICENSE_1_0.txt                           *\n*******************************************************************************/\n\nimport {\n  Point64, Path64, Paths64, Rect64,\n  PointInPolygonResult, InternalClipper, Point64Utils, Rect64Utils\n} from './Core.js';\n\nexport class OutPt2 {\n  public next: OutPt2 | null = null;\n  public prev: OutPt2 | null = null;\n  public pt: Point64;\n  public ownerIdx: number = 0;\n  public edge: (OutPt2 | null)[] | null = null;\n\n  constructor(pt: Point64) {\n    this.pt = pt;\n  }\n}\n\nenum Location {\n  left = 0,\n  top = 1,\n  right = 2,\n  bottom = 3,\n  inside = 4\n}\n\nexport class RectClip64 {\n\n  protected readonly rect: Rect64;\n  protected readonly mp: Point64;\n  protected readonly rectPath: Path64;\n  protected pathBounds: Rect64 = { left: 0, top: 0, right: 0, bottom: 0 };\n  protected results: (OutPt2 | null)[] = [];\n  protected edges: (OutPt2 | null)[][] = [];\n  protected currIdx: number = -1;\n\n  constructor(rect: Rect64) {\n    this.currIdx = -1;\n    this.rect = rect;\n    this.mp = Rect64Utils.midPoint(rect);\n    this.rectPath = Rect64Utils.asPath(this.rect);\n    this.results = [];\n    this.edges = [];\n    for (let i = 0; i < 8; i++) {\n      this.edges[i] = [];\n    }\n  }\n\n  protected add(pt: Point64, startingNewPath: boolean = false): OutPt2 {\n    // this method is only called by InternalExecute.\n    // Later splitting and rejoining won't create additional op's,\n    // though they will change the (non-storage) fResults count.\n    let currIdx = this.results.length;\n    let result: OutPt2;\n    \n    if ((currIdx === 0) || startingNewPath) {\n      result = new OutPt2(pt);\n      this.results.push(result);\n      result.ownerIdx = currIdx;\n      result.prev = result;\n      result.next = result;\n    } else {\n      currIdx--;\n      const prevOp = this.results[currIdx];\n      if (prevOp && Point64Utils.equals(prevOp.pt, pt)) return prevOp;\n      \n      result = new OutPt2(pt);\n      result.ownerIdx = currIdx;\n      result.next = prevOp!.next;\n      prevOp!.next!.prev = result;\n      prevOp!.next = result;\n      result.prev = prevOp!;\n      this.results[currIdx] = result;\n    }\n    return result;\n  }\n\n  private static path1ContainsPath2(path1: Path64, path2: Path64): boolean {\n    // nb: occasionally, due to rounding, path1 may \n    // appear (momentarily) inside or outside path2.\n    let ioCount = 0;\n    for (const pt of path2) {\n      const pip = InternalClipper.pointInPolygon(pt, path1);\n      switch (pip) {\n        case PointInPolygonResult.IsInside:\n          ioCount--;\n          break;\n        case PointInPolygonResult.IsOutside:\n          ioCount++;\n          break;\n      }\n      if (Math.abs(ioCount) > 1) break;\n    }\n    return ioCount <= 0;\n  }\n\n  private static isClockwise(\n    prev: Location, \n    curr: Location,\n    prevPt: Point64, \n    currPt: Point64, \n    rectMidPoint: Point64\n  ): boolean {\n    if (RectClip64.areOpposites(prev, curr)) {\n      return InternalClipper.crossProductSign(prevPt, rectMidPoint, currPt) < 0;\n    }\n    return RectClip64.headingClockwise(prev, curr);\n  }\n\n  private static areOpposites(prev: Location, curr: Location): boolean {\n    return Math.abs(prev - curr) === 2;\n  }\n\n  private static headingClockwise(prev: Location, curr: Location): boolean {\n    return (prev + 1) % 4 === curr;\n  }\n\n  private static getAdjacentLocation(loc: Location, isClockwise: boolean): Location {\n    const delta = isClockwise ? 1 : 3;\n    return (loc + delta) % 4;\n  }\n\n  private static unlinkOp(op: OutPt2): OutPt2 | null {\n    if (op.next === op) return null;\n    op.prev!.next = op.next;\n    op.next!.prev = op.prev;\n    return op.next;\n  }\n\n  private static unlinkOpBack(op: OutPt2): OutPt2 | null {\n    if (op.next === op) return null;\n    op.prev!.next = op.next;\n    op.next!.prev = op.prev;\n    return op.prev;\n  }\n\n  private static getEdgesForPt(pt: Point64, rec: Rect64): number {\n    let result = 0;\n    if (pt.x === rec.left) result = 1;\n    else if (pt.x === rec.right) result = 4;\n    if (pt.y === rec.top) result += 2;\n    else if (pt.y === rec.bottom) result += 8;\n    return result;\n  }\n\n  private static isHeadingClockwise(pt1: Point64, pt2: Point64, edgeIdx: number): boolean {\n    switch (edgeIdx) {\n      case 0: return pt2.y < pt1.y;\n      case 1: return pt2.x > pt1.x;\n      case 2: return pt2.y > pt1.y;\n      default: return pt2.x < pt1.x;\n    }\n  }\n\n  private static hasHorzOverlap(left1: Point64, right1: Point64, left2: Point64, right2: Point64): boolean {\n    return (left1.x < right2.x) && (right1.x > left2.x);\n  }\n\n  private static hasVertOverlap(top1: Point64, bottom1: Point64, top2: Point64, bottom2: Point64): boolean {\n    return (top1.y < bottom2.y) && (bottom1.y > top2.y);\n  }\n\n  private static addToEdge(edge: (OutPt2 | null)[], op: OutPt2): void {\n    if (op.edge !== null) return;\n    op.edge = edge;\n    edge.push(op);\n  }\n\n  private static uncoupleEdge(op: OutPt2): void {\n    if (op.edge === null) return;\n    for (let i = 0; i < op.edge.length; i++) {\n      const op2 = op.edge[i];\n      if (op2 === op) {\n        op.edge[i] = null;\n        break;\n      }\n    }\n    op.edge = null;\n  }\n\n  private static setNewOwner(op: OutPt2, newIdx: number): void {\n    op.ownerIdx = newIdx;\n    let op2 = op.next!;\n    while (op2 !== op) {\n      op2.ownerIdx = newIdx;\n      op2 = op2.next!;\n    }\n  }\n\n  private addCorner(prev: Location, curr: Location): void {\n    this.add(RectClip64.headingClockwise(prev, curr) ? \n      this.rectPath[prev] : this.rectPath[curr]);\n  }\n\n  private addCornerWithDirection(loc: Location, isClockwise: boolean): Location {\n    if (isClockwise) {\n      this.add(this.rectPath[loc]);\n      return RectClip64.getAdjacentLocation(loc, true);\n    } else {\n      const newLoc = RectClip64.getAdjacentLocation(loc, false);\n      this.add(this.rectPath[newLoc]);\n      return newLoc;\n    }\n  }\n\n  protected static getLocation(rec: Rect64, pt: Point64): { location: Location; isOnRect: boolean } {\n    if (pt.x === rec.left && pt.y >= rec.top && pt.y <= rec.bottom) {\n      return { location: Location.left, isOnRect: true };\n    }\n    if (pt.x === rec.right && pt.y >= rec.top && pt.y <= rec.bottom) {\n      return { location: Location.right, isOnRect: true };\n    }\n    if (pt.y === rec.top && pt.x >= rec.left && pt.x <= rec.right) {\n      return { location: Location.top, isOnRect: true };\n    }\n    if (pt.y === rec.bottom && pt.x >= rec.left && pt.x <= rec.right) {\n      return { location: Location.bottom, isOnRect: true };\n    }\n    \n    let location: Location;\n    if (pt.x < rec.left) location = Location.left;\n    else if (pt.x > rec.right) location = Location.right;\n    else if (pt.y < rec.top) location = Location.top;\n    else if (pt.y > rec.bottom) location = Location.bottom;\n    else location = Location.inside;\n    \n    return { location, isOnRect: false };\n  }\n\n  private static isHorizontal(pt1: Point64, pt2: Point64): boolean {\n    return pt1.y === pt2.y;\n  }\n\n  // Returns the intersection point, or null if segments don't intersect.\n  // Avoids allocating a wrapper object on every call.\n  private static getSegmentIntersection(p1: Point64, p2: Point64, p3: Point64, p4: Point64): Point64 | null {\n    const res1 = InternalClipper.crossProductSign(p1, p3, p4);\n    const res2 = InternalClipper.crossProductSign(p2, p3, p4);\n    \n    if (res1 === 0) {\n      if (res2 === 0) return null; // segments are collinear\n      if (Point64Utils.equals(p1, p3) || Point64Utils.equals(p1, p4)) return p1;\n      if (RectClip64.isHorizontal(p3, p4)) {\n        return ((p1.x > p3.x) === (p1.x < p4.x)) ? p1 : null;\n      }\n      return ((p1.y > p3.y) === (p1.y < p4.y)) ? p1 : null;\n    }\n    \n    if (res2 === 0) {\n      if (Point64Utils.equals(p2, p3) || Point64Utils.equals(p2, p4)) return p2;\n      if (RectClip64.isHorizontal(p3, p4)) {\n        return ((p2.x > p3.x) === (p2.x < p4.x)) ? p2 : null;\n      }\n      return ((p2.y > p3.y) === (p2.y < p4.y)) ? p2 : null;\n    }\n    \n    if (res1 === res2) return null;\n\n    const res3 = InternalClipper.crossProductSign(p3, p1, p2);\n    const res4 = InternalClipper.crossProductSign(p4, p1, p2);\n    \n    if (res3 === 0) {\n      if (Point64Utils.equals(p3, p1) || Point64Utils.equals(p3, p2)) return p3;\n      if (RectClip64.isHorizontal(p1, p2)) {\n        return ((p3.x > p1.x) === (p3.x < p2.x)) ? p3 : null;\n      }\n      return ((p3.y > p1.y) === (p3.y < p2.y)) ? p3 : null;\n    }\n    \n    if (res4 === 0) {\n      if (Point64Utils.equals(p4, p1) || Point64Utils.equals(p4, p2)) return p4;\n      if (RectClip64.isHorizontal(p1, p2)) {\n        return ((p4.x > p1.x) === (p4.x < p2.x)) ? p4 : null;\n      }\n      return ((p4.y > p1.y) === (p4.y < p2.y)) ? p4 : null;\n    }\n    \n    if (res3 === res4) return null;\n\n    // segments must intersect to get here\n    return InternalClipper.getLineIntersectPt(p1, p2, p3, p4);\n  }\n\n  // Reusable result object for getIntersection (all callers consume immediately).\n  private static readonly _intResult = { intersects: false, point: { x: 0, y: 0 } as Point64, newLocation: Location.inside as Location };\n\n  protected static getIntersection(\n    rectPath: Path64, \n    p: Point64, \n    p2: Point64, \n    loc: Location\n  ): { intersects: boolean; point: Point64; newLocation: Location } {\n    // gets the pt of intersection between rectPath and segment(p, p2) that's closest to 'p'\n    // when result == false, loc will remain unchanged\n    const r = RectClip64._intResult;\n    let ip: Point64 | null;\n    r.newLocation = loc;\n    \n    switch (loc) {\n      case Location.left:\n        {\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[0], rectPath[3]);\n          if (ip !== null) { r.intersects = true; r.point = ip; return r; }\n          if (p.y < rectPath[0].y) {\n            ip = RectClip64.getSegmentIntersection(p, p2, rectPath[0], rectPath[1]);\n            if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.top; return r; }\n          }\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[2], rectPath[3]);\n          if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.bottom; return r; }\n          r.intersects = false; return r;\n        }\n\n      case Location.right:\n        {\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[1], rectPath[2]);\n          if (ip !== null) { r.intersects = true; r.point = ip; return r; }\n          if (p.y < rectPath[0].y) {\n            ip = RectClip64.getSegmentIntersection(p, p2, rectPath[0], rectPath[1]);\n            if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.top; return r; }\n          }\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[2], rectPath[3]);\n          if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.bottom; return r; }\n          r.intersects = false; return r;\n        }\n\n      case Location.top:\n        {\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[0], rectPath[1]);\n          if (ip !== null) { r.intersects = true; r.point = ip; return r; }\n          if (p.x < rectPath[0].x) {\n            ip = RectClip64.getSegmentIntersection(p, p2, rectPath[0], rectPath[3]);\n            if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.left; return r; }\n          }\n          if (p.x <= rectPath[1].x) { r.intersects = false; return r; }\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[1], rectPath[2]);\n          if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.right; return r; }\n          r.intersects = false; return r;\n        }\n\n      case Location.bottom:\n        {\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[2], rectPath[3]);\n          if (ip !== null) { r.intersects = true; r.point = ip; return r; }\n          if (p.x < rectPath[3].x) {\n            ip = RectClip64.getSegmentIntersection(p, p2, rectPath[0], rectPath[3]);\n            if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.left; return r; }\n          }\n          if (p.x <= rectPath[2].x) { r.intersects = false; return r; }\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[1], rectPath[2]);\n          if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.right; return r; }\n          r.intersects = false; return r;\n        }\n\n      default:\n        {\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[0], rectPath[3]);\n          if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.left; return r; }\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[0], rectPath[1]);\n          if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.top; return r; }\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[1], rectPath[2]);\n          if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.right; return r; }\n          ip = RectClip64.getSegmentIntersection(p, p2, rectPath[2], rectPath[3]);\n          if (ip !== null) { r.intersects = true; r.point = ip; r.newLocation = Location.bottom; return r; }\n          r.intersects = false; return r;\n        }\n    }\n  }\n\n  protected getNextLocation(path: Path64, loc: Location, i: number, highI: number): { location: Location; index: number } {\n    let newI = i;\n    let newLoc = loc;\n    \n    switch (loc) {\n      case Location.left:\n        while (newI <= highI && path[newI].x <= this.rect.left) newI++;\n        if (newI > highI) break;\n        if (path[newI].x >= this.rect.right) newLoc = Location.right;\n        else if (path[newI].y <= this.rect.top) newLoc = Location.top;\n        else if (path[newI].y >= this.rect.bottom) newLoc = Location.bottom;\n        else newLoc = Location.inside;\n        break;\n\n      case Location.top:\n        while (newI <= highI && path[newI].y <= this.rect.top) newI++;\n        if (newI > highI) break;\n        if (path[newI].y >= this.rect.bottom) newLoc = Location.bottom;\n        else if (path[newI].x <= this.rect.left) newLoc = Location.left;\n        else if (path[newI].x >= this.rect.right) newLoc = Location.right;\n        else newLoc = Location.inside;\n        break;\n\n      case Location.right:\n        while (newI <= highI && path[newI].x >= this.rect.right) newI++;\n        if (newI > highI) break;\n        if (path[newI].x <= this.rect.left) newLoc = Location.left;\n        else if (path[newI].y <= this.rect.top) newLoc = Location.top;\n        else if (path[newI].y >= this.rect.bottom) newLoc = Location.bottom;\n        else newLoc = Location.inside;\n        break;\n\n      case Location.bottom:\n        while (newI <= highI && path[newI].y >= this.rect.bottom) newI++;\n        if (newI > highI) break;\n        if (path[newI].y <= this.rect.top) newLoc = Location.top;\n        else if (path[newI].x <= this.rect.left) newLoc = Location.left;\n        else if (path[newI].x >= this.rect.right) newLoc = Location.right;\n        else newLoc = Location.inside;\n        break;\n\n      case Location.inside:\n        while (newI <= highI) {\n          if (path[newI].x < this.rect.left) newLoc = Location.left;\n          else if (path[newI].x > this.rect.right) newLoc = Location.right;\n          else if (path[newI].y > this.rect.bottom) newLoc = Location.bottom;\n          else if (path[newI].y < this.rect.top) newLoc = Location.top;\n          else {\n            this.add(path[newI]);\n            newI++;\n            continue;\n          }\n          break;\n        }\n        break;\n    }\n    \n    return { location: newLoc, index: newI };\n  }\n\n  private static startLocsAreClockwise(startLocs: Location[]): boolean {\n    let result = 0;\n    for (let i = 1; i < startLocs.length; i++) {\n      const d = startLocs[i] - startLocs[i - 1];\n      switch (d) {\n        case -1: result -= 1; break;\n        case 1: result += 1; break;\n        case -3: result += 1; break;\n        case 3: result -= 1; break;\n      }\n    }\n    return result > 0;\n  }\n\n  private executeInternal(path: Path64): void {\n    if (path.length < 3 || Rect64Utils.isEmpty(this.rect)) return;\n    \n    const startLocs: Location[] = [];\n    let firstCross: Location = Location.inside;\n    let crossingLoc: Location = firstCross;\n    let prev: Location = firstCross;\n\n    const highI = path.length - 1;\n    const lastLocResult = RectClip64.getLocation(this.rect, path[highI]);\n    let loc = lastLocResult.location;\n    \n    if (lastLocResult.isOnRect) {\n      let i = highI - 1;\n      while (i >= 0) {\n        const prevLocResult = RectClip64.getLocation(this.rect, path[i]);\n        if (!prevLocResult.isOnRect) {\n          prev = prevLocResult.location;\n          break;\n        }\n        i--;\n      }\n      if (i < 0) {\n        for (const pt of path) {\n          this.add(pt);\n        }\n        return;\n      }\n      if (prev === Location.inside) loc = Location.inside;\n    }\n    const startingLoc = loc;\n\n    ///////////////////////////////////////////////////\n    let i = 0;\n    while (i <= highI) {\n      prev = loc;\n      const prevCrossLoc: Location = crossingLoc;\n      \n      const nextLocResult = this.getNextLocation(path, loc, i, highI);\n      loc = nextLocResult.location;\n      i = nextLocResult.index;\n      \n      if (i > highI) break;\n\n      const prevPt = (i === 0) ? path[highI] : path[i - 1];\n      crossingLoc = loc;\n      \n      const intersectionResult = RectClip64.getIntersection(this.rectPath, path[i], prevPt, crossingLoc);\n      if (!intersectionResult.intersects) {\n        // ie remaining outside\n        if (prevCrossLoc === Location.inside) {\n          const isClockw = RectClip64.isClockwise(prev, loc, prevPt, path[i], this.mp);\n          do {\n            startLocs.push(prev);\n            prev = RectClip64.getAdjacentLocation(prev, isClockw);\n          } while (prev !== loc);\n          crossingLoc = prevCrossLoc; // still not crossed\n        } else if (prev !== Location.inside && prev !== loc) {\n          const isClockw = RectClip64.isClockwise(prev, loc, prevPt, path[i], this.mp);\n          do {\n            prev = this.addCornerWithDirection(prev, isClockw);\n          } while (prev !== loc);\n        }\n        ++i;\n        continue;\n      }\n\n      const ip = intersectionResult.point;\n      crossingLoc = intersectionResult.newLocation;\n\n      ////////////////////////////////////////////////////\n      // we must be crossing the rect boundary to get here\n      ////////////////////////////////////////////////////\n\n      if (loc === Location.inside) { // path must be entering rect\n        if (firstCross === Location.inside) {\n          firstCross = crossingLoc;\n          startLocs.push(prev);\n        } else if (prev !== crossingLoc) {\n          const isClockw = RectClip64.isClockwise(prev, crossingLoc, prevPt, path[i], this.mp);\n          do {\n            prev = this.addCornerWithDirection(prev, isClockw);\n          } while (prev !== crossingLoc);\n        }\n      } else if (prev !== Location.inside) {\n        // passing right through rect. 'ip' here will be the second \n        // intersect pt but we'll also need the first intersect pt (ip2)\n        loc = prev;\n        const intersection2Result = RectClip64.getIntersection(this.rectPath, prevPt, path[i], loc);\n        const ip2 = intersection2Result.point;\n        \n        if (prevCrossLoc !== Location.inside && prevCrossLoc !== loc) { //#597\n          this.addCorner(prevCrossLoc, loc);\n        }\n\n        if (firstCross === Location.inside) {\n          firstCross = loc;\n          startLocs.push(prev);\n        }\n\n        loc = crossingLoc;\n        this.add(ip2);\n        if (Point64Utils.equals(ip, ip2)) {\n          // it's very likely that path[i] is on rect\n          const pathLocResult = RectClip64.getLocation(this.rect, path[i]);\n          loc = pathLocResult.location;\n          this.addCorner(crossingLoc, loc);\n          crossingLoc = loc;\n          continue;\n        }\n      } else { // path must be exiting rect\n        loc = crossingLoc;\n        if (firstCross === Location.inside) {\n          firstCross = crossingLoc;\n        }\n      }\n\n      this.add(ip);\n    } //while i <= highI\n    ///////////////////////////////////////////////////\n\n    if (firstCross === Location.inside) {\n      // path never intersects\n      if (startingLoc === Location.inside) return;\n      if (!Rect64Utils.containsRect(this.pathBounds, this.rect) ||\n          !RectClip64.path1ContainsPath2(path, this.rectPath)) return;\n      \n      const startLocsClockwise = RectClip64.startLocsAreClockwise(startLocs);\n      for (let j = 0; j < 4; j++) {\n        const k = startLocsClockwise ? j : 3 - j; // ie reverse result path\n        this.add(this.rectPath[k]);\n        RectClip64.addToEdge(this.edges[k * 2], this.results[0]!);\n      }\n    } else if (loc !== Location.inside && \n      (loc !== firstCross || startLocs.length > 2)) {\n      \n      if (startLocs.length > 0) {\n        prev = loc;\n        for (const loc2 of startLocs) {\n          if (prev === loc2) continue;\n          this.addCornerWithDirection(prev, RectClip64.headingClockwise(prev, loc2));\n          prev = loc2;\n        }\n        loc = prev;\n      }\n      if (loc !== firstCross) {\n        this.addCornerWithDirection(loc, RectClip64.headingClockwise(loc, firstCross));\n      }\n    }\n  }\n\n  public execute(paths: Paths64): Paths64 {\n    const result: Paths64 = [];\n    if (Rect64Utils.isEmpty(this.rect)) return result;\n    \n    for (const path of paths) {\n      if (path.length < 3) continue;\n      this.pathBounds = InternalClipper.getBounds(path);\n      if (!Rect64Utils.intersects(this.rect, this.pathBounds)) {\n        continue; // the path must be completely outside rect\n      }\n      if (Rect64Utils.containsRect(this.rect, this.pathBounds)) {\n        // the path must be completely inside rect\n        result.push(path);\n        continue;\n      }\n      \n      this.executeInternal(path);\n      this.checkEdges();\n      for (let i = 0; i < 4; ++i) {\n        this.tidyEdgePair(i, this.edges[i * 2], this.edges[i * 2 + 1]);\n      }\n\n      for (const op of this.results) {\n        const tmp = this.getPath(op);\n        if (tmp.length > 0) result.push(tmp);\n      }\n\n      //clean up after every loop\n      this.results.length = 0;\n      for (let i = 0; i < 8; i++) {\n        this.edges[i].length = 0;\n      }\n    }\n    return result;\n  }\n\n  private checkEdges(): void {\n    for (let i = 0; i < this.results.length; i++) {\n      let op = this.results[i];\n      let op2 = op;\n      if (op === null) continue;\n      \n      do {\n        if (InternalClipper.isCollinear(op2!.prev!.pt, op2!.pt, op2!.next!.pt)) {\n          if (op2 === op) {\n            op2 = RectClip64.unlinkOpBack(op2!);\n            if (op2 === null) break;\n            op = op2.prev;\n          } else {\n            op2 = RectClip64.unlinkOpBack(op2!);\n            if (op2 === null) break;\n          }\n        } else {\n          op2 = op2!.next;\n        }\n      } while (op2 !== op);\n\n      if (op2 === null) {\n        this.results[i] = null;\n        continue;\n      }\n      this.results[i] = op2; // safety first\n\n      let edgeSet1 = RectClip64.getEdgesForPt(op!.prev!.pt, this.rect);\n      op2 = op!;\n      do {\n        const edgeSet2 = RectClip64.getEdgesForPt(op2!.pt, this.rect);\n        if (edgeSet2 !== 0 && op2!.edge === null) {\n          const combinedSet = (edgeSet1 & edgeSet2);\n          for (let j = 0; j < 4; ++j) {\n            if ((combinedSet & (1 << j)) === 0) continue;\n            if (RectClip64.isHeadingClockwise(op2!.prev!.pt, op2!.pt, j)) {\n              RectClip64.addToEdge(this.edges[j * 2], op2!);\n            } else {\n              RectClip64.addToEdge(this.edges[j * 2 + 1], op2!);\n            }\n          }\n        }\n        edgeSet1 = edgeSet2;\n        op2 = op2!.next;\n      } while (op2 !== op);\n    }\n  }\n\n  private tidyEdgePair(idx: number, cw: (OutPt2 | null)[], ccw: (OutPt2 | null)[]): void {\n    if (ccw.length === 0) return;\n    const isHorz = ((idx === 1) || (idx === 3));\n    const cwIsTowardLarger = ((idx === 1) || (idx === 2));\n    let i = 0, j = 0;\n\n    while (i < cw.length) {\n      let p1 = cw[i];\n      if (p1 === null || p1.next === p1.prev) {\n        cw[i++] = null;\n        j = 0;\n        continue;\n      }\n\n      const jLim = ccw.length;\n      while (j < jLim && (ccw[j] === null || ccw[j]!.next === ccw[j]!.prev)) ++j;\n\n      if (j === jLim) {\n        ++i;\n        j = 0;\n        continue;\n      }\n\n      let p2: OutPt2 | null;\n      let p1a: OutPt2 | null;\n      let p2a: OutPt2 | null;\n      \n      if (cwIsTowardLarger) {\n        // p1 >>>> p1a;\n        // p2 <<<< p2a;\n        p1 = cw[i]!.prev!;\n        p1a = cw[i];\n        p2 = ccw[j];\n        p2a = ccw[j]!.prev!;\n      } else {\n        // p1 <<<< p1a;\n        // p2 >>>> p2a;\n        p1 = cw[i];\n        p1a = cw[i]!.prev!;\n        p2 = ccw[j]!.prev!;\n        p2a = ccw[j];\n      }\n\n      if ((isHorz && !RectClip64.hasHorzOverlap(p1!.pt, p1a!.pt, p2!.pt, p2a!.pt)) ||\n        (!isHorz && !RectClip64.hasVertOverlap(p1!.pt, p1a!.pt, p2!.pt, p2a!.pt))) {\n        ++j;\n        continue;\n      }\n\n      // to get here we're either splitting or rejoining\n      const isRejoining = cw[i]!.ownerIdx !== ccw[j]!.ownerIdx;\n\n      if (isRejoining) {\n        this.results[p2!.ownerIdx] = null;\n        RectClip64.setNewOwner(p2!, p1!.ownerIdx);\n      }\n\n      // do the split or re-join\n      if (cwIsTowardLarger) {\n        // p1 >> | >> p1a;\n        // p2 << | << p2a;\n        p1!.next = p2;\n        p2!.prev = p1;\n        p1a!.prev = p2a;\n        p2a!.next = p1a;\n      } else {\n        // p1 << | << p1a;\n        // p2 >> | >> p2a;\n        p1!.prev = p2;\n        p2!.next = p1;\n        p1a!.next = p2a;\n        p2a!.prev = p1a;\n      }\n\n      if (!isRejoining) {\n        const newIdx = this.results.length;\n        this.results.push(p1a);\n        RectClip64.setNewOwner(p1a!, newIdx);\n      }\n\n      let op: OutPt2 | null;\n      let op2: OutPt2 | null;\n      if (cwIsTowardLarger) {\n        op = p2;\n        op2 = p1a;\n      } else {\n        op = p1;\n        op2 = p2a;\n      }\n      this.results[op!.ownerIdx] = op;\n      this.results[op2!.ownerIdx] = op2;\n\n      // and now lots of work to get ready for the next loop\n      let opIsLarger: boolean, op2IsLarger: boolean;\n      if (isHorz) { // X\n        opIsLarger = op!.pt.x > op!.prev!.pt.x;\n        op2IsLarger = op2!.pt.x > op2!.prev!.pt.x;\n      } else { // Y\n        opIsLarger = op!.pt.y > op!.prev!.pt.y;\n        op2IsLarger = op2!.pt.y > op2!.prev!.pt.y;\n      }\n\n      if ((op!.next === op!.prev) || Point64Utils.equals(op!.pt, op!.prev!.pt)) {\n        if (op2IsLarger === cwIsTowardLarger) {\n          cw[i] = op2;\n          ccw[j++] = null;\n        } else {\n          ccw[j] = op2;\n          cw[i++] = null;\n        }\n      } else if ((op2!.next === op2!.prev) || Point64Utils.equals(op2!.pt, op2!.prev!.pt)) {\n        if (opIsLarger === cwIsTowardLarger) {\n          cw[i] = op;\n          ccw[j++] = null;\n        } else {\n          ccw[j] = op;\n          cw[i++] = null;\n        }\n      } else if (opIsLarger === op2IsLarger) {\n        if (opIsLarger === cwIsTowardLarger) {\n          cw[i] = op;\n          RectClip64.uncoupleEdge(op2!);\n          RectClip64.addToEdge(cw, op2!);\n          ccw[j++] = null;\n        } else {\n          cw[i++] = null;\n          ccw[j] = op2;\n          RectClip64.uncoupleEdge(op!);\n          RectClip64.addToEdge(ccw, op!);\n          j = 0;\n        }\n      } else {\n        if (opIsLarger === cwIsTowardLarger) {\n          cw[i] = op;\n        } else {\n          ccw[j] = op;\n        }\n        if (op2IsLarger === cwIsTowardLarger) {\n          cw[i] = op2;\n        } else {\n          ccw[j] = op2;\n        }\n      }\n    }\n  }\n\n  private getPath(op: OutPt2 | null): Path64 {\n    const result: Path64 = [];\n    if (op === null || op.prev === op.next) return result;\n    \n    let op2 = op.next;\n    while (op2 !== null && op2 !== op) {\n      if (InternalClipper.isCollinear(op2.prev!.pt, op2.pt, op2.next!.pt)) {\n        op = op2.prev;\n        op2 = RectClip64.unlinkOp(op2);\n      } else {\n        op2 = op2.next;\n      }\n    }\n    if (op2 === null) return [];\n\n    result.push(op!.pt);\n    op2 = op!.next;\n    while (op2 !== op) {\n      result.push(op2!.pt);\n      op2 = op2!.next;\n    }\n    return result;\n  }\n}\n\nexport class RectClipLines64 extends RectClip64 {\n  constructor(rect: Rect64) {\n    super(rect);\n  }\n\n  public execute(paths: Paths64): Paths64 {\n    const result: Paths64 = [];\n    if (Rect64Utils.isEmpty(this.rect)) return result;\n    \n    for (const path of paths) {\n      if (path.length < 2) continue;\n      this.pathBounds = InternalClipper.getBounds(path);\n      if (!Rect64Utils.intersects(this.rect, this.pathBounds)) {\n        continue; // the path must be completely outside rect\n      }\n      // Apart from that, we can't be sure whether the path\n      // is completely outside or completed inside or intersects\n      // rect, simply by comparing path bounds with rect.\n      this.executeInternalLines(path);\n\n      for (const op of this.results) {\n        const tmp = this.getPathLines(op);\n        if (tmp.length > 0) result.push(tmp);\n      }\n\n      //clean up after every loop\n      this.results.length = 0;\n      for (let i = 0; i < 8; i++) {\n        this.edges[i].length = 0;\n      }\n    }\n    return result;\n  }\n\n  private getPathLines(op: OutPt2 | null): Path64 {\n    const result: Path64 = [];\n    if (op === null || op === op.next) return result;\n    \n    op = op.next; // starting at path beginning \n    result.push(op!.pt);\n    let op2 = op!.next!;\n    while (op2 !== op) {\n      result.push(op2.pt);\n      op2 = op2.next!;\n    }\n    return result;\n  }\n\n  private executeInternalLines(path: Path64): void {\n    this.results.length = 0;\n    if (path.length < 2 || Rect64Utils.isEmpty(this.rect)) return;\n\n    let prev = Location.inside;\n    let i = 1;\n    const highI = path.length - 1;\n    \n    const firstLocResult = RectClip64.getLocation(this.rect, path[0]);\n    let loc = firstLocResult.location;\n    \n    if (firstLocResult.isOnRect) {\n      while (i <= highI) {\n        const prevLocResult = RectClip64.getLocation(this.rect, path[i]);\n        if (!prevLocResult.isOnRect) {\n          prev = prevLocResult.location;\n          break;\n        }\n        i++;\n      }\n      if (i > highI) {\n        for (const pt of path) {\n          this.add(pt);\n        }\n        return;\n      }\n      if (prev === Location.inside) loc = Location.inside;\n      i = 1;\n    }\n    if (loc === Location.inside) this.add(path[0]);\n\n    ///////////////////////////////////////////////////\n    while (i <= highI) {\n      prev = loc;\n      const nextLocResult = this.getNextLocation(path, loc, i, highI);\n      loc = nextLocResult.location;\n      i = nextLocResult.index;\n      \n      if (i > highI) break;\n      const prevPt = path[i - 1];\n\n      let crossingLoc = loc;\n      const intersectionResult = RectClip64.getIntersection(this.rectPath, path[i], prevPt, crossingLoc);\n      if (!intersectionResult.intersects) {\n        // ie remaining outside (& crossingLoc still == loc)\n        ++i;\n        continue;\n      }\n\n      const ip = intersectionResult.point;\n\n      ////////////////////////////////////////////////////\n      // we must be crossing the rect boundary to get here\n      ////////////////////////////////////////////////////\n\n      if (loc === Location.inside) { // path must be entering rect\n        this.add(ip, true);\n      } else if (prev !== Location.inside) {\n        // passing right through rect. 'ip' here will be the second\n        // intersect pt but we'll also need the first intersect pt (ip2)\n        crossingLoc = prev;\n        const intersection2Result = RectClip64.getIntersection(this.rectPath, prevPt, path[i], crossingLoc);\n        const ip2 = intersection2Result.point;\n        this.add(ip2, true);\n        this.add(ip);\n      } else { // path must be exiting rect\n        this.add(ip);\n      }\n    } //while i <= highI\n    ///////////////////////////////////////////////////\n  }\n}\n","/*******************************************************************************\n* Author    :  Angus Johnson                                                   *\n* Date      :  10 October 2024                                                 *\n* Website   :  https://www.angusj.com                                          *\n* Copyright :  Angus Johnson 2010-2024                                         *\n* Purpose   :  Minkowski Sum and Difference                                    *\n* License   :  https://www.boost.org/LICENSE_1_0.txt                           *\n*******************************************************************************/\n\nimport {\n  Path64, PathD, Paths64, PathsD, FillRule, ClipType, PathType,\n  Point64Utils, InternalClipper\n} from './Core.js';\nimport { Clipper64 } from './Engine.js';\n\n// Private helpers for Minkowski (module-level, not exported)\nfunction minkowskiInternal(pattern: Path64, path: Path64, isSum: boolean, isClosed: boolean): Paths64 {\n  const delta = isClosed ? 0 : 1;\n  const patLen = pattern.length;\n  const pathLen = path.length;\n  const tmp: Paths64 = [];\n\n  for (const pathPt of path) {\n    const path2: Path64 = [];\n    if (isSum) {\n      for (const basePt of pattern) {\n        path2.push(Point64Utils.add(pathPt, basePt));\n      }\n    } else {\n      for (const basePt of pattern) {\n        path2.push(Point64Utils.subtract(pathPt, basePt));\n      }\n    }\n    tmp.push(path2);\n  }\n\n  const result: Paths64 = [];\n  let g = isClosed ? pathLen - 1 : 0;\n\n  let h = patLen - 1;\n  for (let i = delta; i < pathLen; i++) {\n    for (let j = 0; j < patLen; j++) {\n      const quad: Path64 = [\n        tmp[g][h],\n        tmp[i][h], \n        tmp[i][j], \n        tmp[g][j]\n      ];\n      if (!minkIsPositive(quad)) {\n        result.push(minkReversePath(quad));\n      } else {\n        result.push(quad);\n      }\n      h = j;\n    }\n    g = i;\n  }\n  return result;\n}\n\nfunction minkIsPositive(path: Path64): boolean {\n  return InternalClipper.area(path) >= 0;\n}\n\nfunction minkReversePath(path: Path64): Path64 {\n  return [...path].reverse();\n}\n\nfunction minkScalePath64(path: PathD, scale: number): Path64 {\n  const maxAbs = InternalClipper.maxSafeCoordinateForScale(scale);\n  const result: Path64 = [];\n  for (const pt of path) {\n      InternalClipper.checkSafeScaleValue(pt.x, maxAbs, \"Minkowski.scalePath64\");\n      InternalClipper.checkSafeScaleValue(pt.y, maxAbs, \"Minkowski.scalePath64\");\n      result.push({\n        x: InternalClipper.roundToEven(pt.x * scale),\n        y: InternalClipper.roundToEven(pt.y * scale)\n      });\n  }\n  return result;\n}\n\nfunction minkScalePathsD(paths: Paths64, scale: number): PathsD {\n  const result: PathsD = [];\n  for (const path of paths) {\n    const pathD: PathD = [];\n    for (const pt of path) {\n      pathD.push({\n        x: pt.x * scale,\n        y: pt.y * scale\n      });\n    }\n    result.push(pathD);\n  }\n  return result;\n}\n\n// Local union implementation to avoid circular dependency\nfunction minkUnion(paths: Paths64, fillRule: FillRule): Paths64 {\n  const solution: Paths64 = [];\n  const c = new Clipper64();\n  c.addPaths(paths, PathType.Subject);\n  c.execute(ClipType.Union, fillRule, solution);\n  return solution;\n}\n\n// Plain object replaces namespace to avoid IIFE wrapper in tsc output.\nexport const Minkowski = {\n  sum(pattern: Path64, path: Path64, isClosed: boolean): Paths64 {\n    return minkUnion(minkowskiInternal(pattern, path, true, isClosed), FillRule.NonZero);\n  },\n\n  sumD(pattern: PathD, path: PathD, isClosed: boolean, decimalPlaces: number = 2): PathsD {\n    const scale = Math.pow(10, decimalPlaces);\n    const tmp = minkUnion(\n      minkowskiInternal(\n        minkScalePath64(pattern, scale),\n        minkScalePath64(path, scale), \n        true, \n        isClosed\n      ), \n      FillRule.NonZero\n    );\n    return minkScalePathsD(tmp, 1 / scale);\n  },\n\n  diff(pattern: Path64, path: Path64, isClosed: boolean): Paths64 {\n    return minkUnion(minkowskiInternal(pattern, path, false, isClosed), FillRule.NonZero);\n  },\n\n  diffD(pattern: PathD, path: PathD, isClosed: boolean, decimalPlaces: number = 2): PathsD {\n    const scale = Math.pow(10, decimalPlaces);\n    const tmp = minkUnion(\n      minkowskiInternal(\n        minkScalePath64(pattern, scale),\n        minkScalePath64(path, scale), \n        false, \n        isClosed\n      ), \n      FillRule.NonZero\n    );\n    return minkScalePathsD(tmp, 1 / scale);\n  },\n};\n","// Adaptive precision geometric predicates ported from\n// Jonathan Richard Shewchuk's predicates.c (public domain).\n// https://www.cs.cmu.edu/~quake/robust.html\n\nconst EPSILON = 1.1102230246251565e-16; // 2^-53\nconst SPLITTER = 134217729; // 2^27 + 1\n\nconst resulterrbound = (3 + 8 * EPSILON) * EPSILON;\nconst ccwerrboundA = (3 + 16 * EPSILON) * EPSILON;\nconst ccwerrboundB = (2 + 12 * EPSILON) * EPSILON;\nconst ccwerrboundC = (9 + 64 * EPSILON) * EPSILON * EPSILON;\nconst iccerrboundA = (10 + 96 * EPSILON) * EPSILON;\nconst iccerrboundB = (4 + 48 * EPSILON) * EPSILON;\nconst iccerrboundC = (44 + 576 * EPSILON) * EPSILON * EPSILON;\n\n// Pre-allocated working arrays\nconst o2dB = new Float64Array(4);\nconst o2dC1 = new Float64Array(8);\nconst o2dC2 = new Float64Array(12);\nconst o2dD = new Float64Array(16);\nconst o2du = new Float64Array(4);\n\nconst icbc = new Float64Array(4);\nconst icca = new Float64Array(4);\nconst icab = new Float64Array(4);\nconst icaa = new Float64Array(4);\nconst icbb = new Float64Array(4);\nconst iccc = new Float64Array(4);\nconst icu = new Float64Array(4);\n\nconst icaxtbc = new Float64Array(8);\nconst icaytbc = new Float64Array(8);\nconst icbxtca = new Float64Array(8);\nconst icbytca = new Float64Array(8);\nconst iccxtab = new Float64Array(8);\nconst iccytab = new Float64Array(8);\nconst icabt = new Float64Array(8);\nconst icbct = new Float64Array(8);\nconst iccat = new Float64Array(8);\nconst icabtt = new Float64Array(4);\nconst icbctt = new Float64Array(4);\nconst iccatt = new Float64Array(4);\n\nconst ic8 = new Float64Array(8);\nconst ic16 = new Float64Array(16);\nconst ic16b = new Float64Array(16);\nconst ic16c = new Float64Array(16);\nconst ic32 = new Float64Array(32);\nconst ic32b = new Float64Array(32);\nconst ic48 = new Float64Array(48);\nconst ic64 = new Float64Array(64);\nconst icv = new Float64Array(4);\nlet icfin = new Float64Array(1152);\nlet icfin2 = new Float64Array(1152);\n\n// fast_expansion_sum_zeroelim from predicates.c\nfunction expansionSum(\n  elen: number, e: Float64Array,\n  flen: number, f: Float64Array,\n  h: Float64Array\n): number {\n  let Q: number, Qnew: number, hh: number, bvirt: number;\n  let enow = e[0];\n  let fnow = f[0];\n  let eindex = 0;\n  let findex = 0;\n\n  if ((fnow > enow) === (fnow > -enow)) {\n    Q = enow; enow = e[++eindex];\n  } else {\n    Q = fnow; fnow = f[++findex];\n  }\n\n  let hindex = 0;\n  if (eindex < elen && findex < flen) {\n    if ((fnow > enow) === (fnow > -enow)) {\n      Qnew = enow + Q; hh = Q - (Qnew - enow); enow = e[++eindex];\n    } else {\n      Qnew = fnow + Q; hh = Q - (Qnew - fnow); fnow = f[++findex];\n    }\n    Q = Qnew;\n    if (hh !== 0) h[hindex++] = hh;\n\n    while (eindex < elen && findex < flen) {\n      if ((fnow > enow) === (fnow > -enow)) {\n        Qnew = Q + enow; bvirt = Qnew - Q;\n        hh = Q - (Qnew - bvirt) + (enow - bvirt); enow = e[++eindex];\n      } else {\n        Qnew = Q + fnow; bvirt = Qnew - Q;\n        hh = Q - (Qnew - bvirt) + (fnow - bvirt); fnow = f[++findex];\n      }\n      Q = Qnew;\n      if (hh !== 0) h[hindex++] = hh;\n    }\n  }\n\n  while (eindex < elen) {\n    Qnew = Q + enow; bvirt = Qnew - Q;\n    hh = Q - (Qnew - bvirt) + (enow - bvirt); enow = e[++eindex];\n    Q = Qnew;\n    if (hh !== 0) h[hindex++] = hh;\n  }\n\n  while (findex < flen) {\n    Qnew = Q + fnow; bvirt = Qnew - Q;\n    hh = Q - (Qnew - bvirt) + (fnow - bvirt); fnow = f[++findex];\n    Q = Qnew;\n    if (hh !== 0) h[hindex++] = hh;\n  }\n\n  if (Q !== 0 || hindex === 0) h[hindex++] = Q;\n  return hindex;\n}\n\n// scale_expansion_zeroelim from predicates.c\nfunction scaleExpansion(\n  elen: number, e: Float64Array, b: number, h: Float64Array\n): number {\n  let Q: number, sum: number, hh: number, product1: number, product0: number;\n  let bvirt: number, c: number, ahi: number, alo: number, bhi: number, blo: number;\n\n  c = SPLITTER * b; bhi = c - (c - b); blo = b - bhi;\n  let enow = e[0];\n  Q = enow * b;\n  c = SPLITTER * enow; ahi = c - (c - enow); alo = enow - ahi;\n  hh = alo * blo - (Q - ahi * bhi - alo * bhi - ahi * blo);\n\n  let hindex = 0;\n  if (hh !== 0) h[hindex++] = hh;\n\n  for (let i = 1; i < elen; i++) {\n    enow = e[i];\n    product1 = enow * b;\n    c = SPLITTER * enow; ahi = c - (c - enow); alo = enow - ahi;\n    product0 = alo * blo - (product1 - ahi * bhi - alo * bhi - ahi * blo);\n\n    sum = Q + product0; bvirt = sum - Q;\n    hh = Q - (sum - bvirt) + (product0 - bvirt);\n    if (hh !== 0) h[hindex++] = hh;\n\n    Q = product1 + sum; hh = sum - (Q - product1);\n    if (hh !== 0) h[hindex++] = hh;\n  }\n\n  if (Q !== 0 || hindex === 0) h[hindex++] = Q;\n  return hindex;\n}\n\nfunction estimate(elen: number, e: Float64Array): number {\n  let Q = e[0];\n  for (let i = 1; i < elen; i++) Q += e[i];\n  return Q;\n}\n\n// orient2d\n\nfunction orient2dadapt(\n  ax: number, ay: number, bx: number, by: number,\n  cx: number, cy: number, detsum: number\n): number {\n  let bvirt: number, c: number, ahi: number, alo: number, bhi: number, blo: number;\n  let _i: number, _j: number, _0: number, s1: number, s0: number, t1: number, t0: number, u3: number;\n  let acxtail: number, acytail: number, bcxtail: number, bcytail: number;\n\n  const acx = ax - cx, bcx = bx - cx, acy = ay - cy, bcy = by - cy;\n\n  s1 = acx * bcy; c = SPLITTER * acx; ahi = c - (c - acx); alo = acx - ahi;\n  c = SPLITTER * bcy; bhi = c - (c - bcy); blo = bcy - bhi;\n  s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n  t1 = acy * bcx; c = SPLITTER * acy; ahi = c - (c - acy); alo = acy - ahi;\n  c = SPLITTER * bcx; bhi = c - (c - bcx); blo = bcx - bhi;\n  t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n\n  _i = s0 - t0; bvirt = s0 - _i;\n  o2dB[0] = s0 - (_i + bvirt) + (bvirt - t0);\n  _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n  _i = _0 - t1; bvirt = _0 - _i;\n  o2dB[1] = _0 - (_i + bvirt) + (bvirt - t1);\n  u3 = _j + _i; bvirt = u3 - _j;\n  o2dB[2] = _j - (u3 - bvirt) + (_i - bvirt);\n  o2dB[3] = u3;\n\n  let det = estimate(4, o2dB);\n  let errbound = ccwerrboundB * detsum;\n  if (det >= errbound || -det >= errbound) return det;\n\n  bvirt = ax - acx; acxtail = ax - (acx + bvirt) + (bvirt - cx);\n  bvirt = bx - bcx; bcxtail = bx - (bcx + bvirt) + (bvirt - cx);\n  bvirt = ay - acy; acytail = ay - (acy + bvirt) + (bvirt - cy);\n  bvirt = by - bcy; bcytail = by - (bcy + bvirt) + (bvirt - cy);\n\n  if (acxtail === 0 && acytail === 0 && bcxtail === 0 && bcytail === 0) return det;\n\n  errbound = ccwerrboundC * detsum + resulterrbound * Math.abs(det);\n  det += (acx * bcytail + bcy * acxtail) - (acy * bcxtail + bcx * acytail);\n  if (det >= errbound || -det >= errbound) return det;\n\n  s1 = acxtail * bcy; c = SPLITTER * acxtail; ahi = c - (c - acxtail); alo = acxtail - ahi;\n  c = SPLITTER * bcy; bhi = c - (c - bcy); blo = bcy - bhi;\n  s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n  t1 = acytail * bcx; c = SPLITTER * acytail; ahi = c - (c - acytail); alo = acytail - ahi;\n  c = SPLITTER * bcx; bhi = c - (c - bcx); blo = bcx - bhi;\n  t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n  _i = s0 - t0; bvirt = s0 - _i;\n  o2du[0] = s0 - (_i + bvirt) + (bvirt - t0);\n  _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n  _i = _0 - t1; bvirt = _0 - _i;\n  o2du[1] = _0 - (_i + bvirt) + (bvirt - t1);\n  u3 = _j + _i; bvirt = u3 - _j;\n  o2du[2] = _j - (u3 - bvirt) + (_i - bvirt); o2du[3] = u3;\n  const C1len = expansionSum(4, o2dB, 4, o2du, o2dC1);\n\n  s1 = acx * bcytail; c = SPLITTER * acx; ahi = c - (c - acx); alo = acx - ahi;\n  c = SPLITTER * bcytail; bhi = c - (c - bcytail); blo = bcytail - bhi;\n  s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n  t1 = acy * bcxtail; c = SPLITTER * acy; ahi = c - (c - acy); alo = acy - ahi;\n  c = SPLITTER * bcxtail; bhi = c - (c - bcxtail); blo = bcxtail - bhi;\n  t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n  _i = s0 - t0; bvirt = s0 - _i;\n  o2du[0] = s0 - (_i + bvirt) + (bvirt - t0);\n  _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n  _i = _0 - t1; bvirt = _0 - _i;\n  o2du[1] = _0 - (_i + bvirt) + (bvirt - t1);\n  u3 = _j + _i; bvirt = u3 - _j;\n  o2du[2] = _j - (u3 - bvirt) + (_i - bvirt); o2du[3] = u3;\n  const C2len = expansionSum(C1len, o2dC1, 4, o2du, o2dC2);\n\n  s1 = acxtail * bcytail; c = SPLITTER * acxtail; ahi = c - (c - acxtail); alo = acxtail - ahi;\n  c = SPLITTER * bcytail; bhi = c - (c - bcytail); blo = bcytail - bhi;\n  s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n  t1 = acytail * bcxtail; c = SPLITTER * acytail; ahi = c - (c - acytail); alo = acytail - ahi;\n  c = SPLITTER * bcxtail; bhi = c - (c - bcxtail); blo = bcxtail - bhi;\n  t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n  _i = s0 - t0; bvirt = s0 - _i;\n  o2du[0] = s0 - (_i + bvirt) + (bvirt - t0);\n  _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n  _i = _0 - t1; bvirt = _0 - _i;\n  o2du[1] = _0 - (_i + bvirt) + (bvirt - t1);\n  u3 = _j + _i; bvirt = u3 - _j;\n  o2du[2] = _j - (u3 - bvirt) + (_i - bvirt); o2du[3] = u3;\n  const Dlen = expansionSum(C2len, o2dC2, 4, o2du, o2dD);\n\n  return o2dD[Dlen - 1];\n}\n\n// orient2d sign, with adaptive exact fallback\nexport function adaptiveOrient2dSign(\n  ax: number, ay: number, bx: number, by: number,\n  cx: number, cy: number\n): number {\n  const detleft = (ay - cy) * (bx - cx);\n  const detright = (ax - cx) * (by - cy);\n  const det = detleft - detright;\n\n  if (detleft > 0) { if (detright <= 0) return det > 0 ? 1 : det < 0 ? -1 : 0; }\n  else if (detleft < 0) { if (detright >= 0) return det > 0 ? 1 : det < 0 ? -1 : 0; }\n  else { return det > 0 ? 1 : det < 0 ? -1 : 0; }\n\n  const detsum = detleft > 0 ? detleft + detright : -detleft - detright;\n  const errbound = ccwerrboundA * detsum;\n  if (det >= errbound || -det >= errbound) return det > 0 ? 1 : -1;\n\n  const result = orient2dadapt(ax, ay, bx, by, cx, cy, detsum);\n  return result > 0 ? 1 : result < 0 ? -1 : 0;\n}\n\n// incircle\n\nfunction icFinadd(finlen: number, alen: number, a: Float64Array): number {\n  finlen = expansionSum(finlen, icfin, alen, a, icfin2);\n  const tmp = icfin; icfin = icfin2; icfin2 = tmp;\n  return finlen;\n}\n\nfunction incircleadapt(\n  ax: number, ay: number, bx: number, by: number,\n  cx: number, cy: number, dx: number, dy: number,\n  permanent: number\n): number {\n  let bvirt: number, c: number, ahi: number, alo: number, bhi: number, blo: number;\n  let _i: number, _j: number, _0: number, s1: number, s0: number, t1: number, t0: number, u3: number;\n  let finlen: number;\n  let adxtail: number, bdxtail: number, cdxtail: number;\n  let adytail: number, bdytail: number, cdytail: number;\n  let axtbclen = 0, aytbclen = 0, bxtcalen = 0, bytcalen = 0, cxtablen = 0, cytablen = 0;\n  let n1: number, n0: number;\n\n  const adx = ax - dx, bdx = bx - dx, cdx = cx - dx;\n  const ady = ay - dy, bdy = by - dy, cdy = cy - dy;\n\n  // bc = bdx*cdy - cdx*bdy as exact expansion\n  s1 = bdx * cdy; c = SPLITTER * bdx; ahi = c - (c - bdx); alo = bdx - ahi;\n  c = SPLITTER * cdy; bhi = c - (c - cdy); blo = cdy - bhi;\n  s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n  t1 = cdx * bdy; c = SPLITTER * cdx; ahi = c - (c - cdx); alo = cdx - ahi;\n  c = SPLITTER * bdy; bhi = c - (c - bdy); blo = bdy - bhi;\n  t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n  _i = s0 - t0; bvirt = s0 - _i;\n  icbc[0] = s0 - (_i + bvirt) + (bvirt - t0);\n  _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n  _i = _0 - t1; bvirt = _0 - _i;\n  icbc[1] = _0 - (_i + bvirt) + (bvirt - t1);\n  u3 = _j + _i; bvirt = u3 - _j;\n  icbc[2] = _j - (u3 - bvirt) + (_i - bvirt); icbc[3] = u3;\n\n  // ca = cdx*ady - adx*cdy\n  s1 = cdx * ady; c = SPLITTER * cdx; ahi = c - (c - cdx); alo = cdx - ahi;\n  c = SPLITTER * ady; bhi = c - (c - ady); blo = ady - bhi;\n  s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n  t1 = adx * cdy; c = SPLITTER * adx; ahi = c - (c - adx); alo = adx - ahi;\n  c = SPLITTER * cdy; bhi = c - (c - cdy); blo = cdy - bhi;\n  t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n  _i = s0 - t0; bvirt = s0 - _i;\n  icca[0] = s0 - (_i + bvirt) + (bvirt - t0);\n  _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n  _i = _0 - t1; bvirt = _0 - _i;\n  icca[1] = _0 - (_i + bvirt) + (bvirt - t1);\n  u3 = _j + _i; bvirt = u3 - _j;\n  icca[2] = _j - (u3 - bvirt) + (_i - bvirt); icca[3] = u3;\n\n  // ab = adx*bdy - bdx*ady\n  s1 = adx * bdy; c = SPLITTER * adx; ahi = c - (c - adx); alo = adx - ahi;\n  c = SPLITTER * bdy; bhi = c - (c - bdy); blo = bdy - bhi;\n  s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n  t1 = bdx * ady; c = SPLITTER * bdx; ahi = c - (c - bdx); alo = bdx - ahi;\n  c = SPLITTER * ady; bhi = c - (c - ady); blo = ady - bhi;\n  t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n  _i = s0 - t0; bvirt = s0 - _i;\n  icab[0] = s0 - (_i + bvirt) + (bvirt - t0);\n  _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n  _i = _0 - t1; bvirt = _0 - _i;\n  icab[1] = _0 - (_i + bvirt) + (bvirt - t1);\n  u3 = _j + _i; bvirt = u3 - _j;\n  icab[2] = _j - (u3 - bvirt) + (_i - bvirt); icab[3] = u3;\n\n  finlen = expansionSum(\n    expansionSum(\n      expansionSum(\n        scaleExpansion(scaleExpansion(4, icbc, adx, ic8), ic8, adx, ic16), ic16,\n        scaleExpansion(scaleExpansion(4, icbc, ady, ic8), ic8, ady, ic16b), ic16b, ic32\n      ), ic32,\n      expansionSum(\n        scaleExpansion(scaleExpansion(4, icca, bdx, ic8), ic8, bdx, ic16), ic16,\n        scaleExpansion(scaleExpansion(4, icca, bdy, ic8), ic8, bdy, ic16b), ic16b, ic32b\n      ), ic32b, ic64\n    ), ic64,\n    expansionSum(\n      scaleExpansion(scaleExpansion(4, icab, cdx, ic8), ic8, cdx, ic16), ic16,\n      scaleExpansion(scaleExpansion(4, icab, cdy, ic8), ic8, cdy, ic16b), ic16b, ic32\n    ), ic32, icfin\n  );\n\n  let det = estimate(finlen, icfin);\n  let errbound = iccerrboundB * permanent;\n  if (det >= errbound || -det >= errbound) return det;\n\n  bvirt = ax - adx; adxtail = ax - (adx + bvirt) + (bvirt - dx);\n  bvirt = ay - ady; adytail = ay - (ady + bvirt) + (bvirt - dy);\n  bvirt = bx - bdx; bdxtail = bx - (bdx + bvirt) + (bvirt - dx);\n  bvirt = by - bdy; bdytail = by - (bdy + bvirt) + (bvirt - dy);\n  bvirt = cx - cdx; cdxtail = cx - (cdx + bvirt) + (bvirt - dx);\n  bvirt = cy - cdy; cdytail = cy - (cdy + bvirt) + (bvirt - dy);\n\n  if (adxtail === 0 && bdxtail === 0 && cdxtail === 0 &&\n      adytail === 0 && bdytail === 0 && cdytail === 0) return det;\n\n  errbound = iccerrboundC * permanent + resulterrbound * Math.abs(det);\n  det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) - (bdy * cdxtail + cdx * bdytail)) +\n      2 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx)) +\n      ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) - (cdy * adxtail + adx * cdytail)) +\n      2 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx)) +\n      ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) - (ady * bdxtail + bdx * adytail)) +\n      2 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));\n  if (det >= errbound || -det >= errbound) return det;\n\n  // Stage C: full exact arithmetic with tail terms\n  if (bdxtail !== 0 || bdytail !== 0 || cdxtail !== 0 || cdytail !== 0) {\n    s1 = adx * adx; c = SPLITTER * adx; ahi = c - (c - adx); alo = adx - ahi;\n    s0 = alo * alo - (s1 - ahi * ahi - (ahi + ahi) * alo);\n    t1 = ady * ady; c = SPLITTER * ady; ahi = c - (c - ady); alo = ady - ahi;\n    t0 = alo * alo - (t1 - ahi * ahi - (ahi + ahi) * alo);\n    _i = s0 + t0; bvirt = _i - s0; icaa[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n    _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n    _i = _0 + t1; bvirt = _i - _0; icaa[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n    u3 = _j + _i; bvirt = u3 - _j; icaa[2] = _j - (u3 - bvirt) + (_i - bvirt); icaa[3] = u3;\n  }\n  if (cdxtail !== 0 || cdytail !== 0 || adxtail !== 0 || adytail !== 0) {\n    s1 = bdx * bdx; c = SPLITTER * bdx; ahi = c - (c - bdx); alo = bdx - ahi;\n    s0 = alo * alo - (s1 - ahi * ahi - (ahi + ahi) * alo);\n    t1 = bdy * bdy; c = SPLITTER * bdy; ahi = c - (c - bdy); alo = bdy - ahi;\n    t0 = alo * alo - (t1 - ahi * ahi - (ahi + ahi) * alo);\n    _i = s0 + t0; bvirt = _i - s0; icbb[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n    _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n    _i = _0 + t1; bvirt = _i - _0; icbb[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n    u3 = _j + _i; bvirt = u3 - _j; icbb[2] = _j - (u3 - bvirt) + (_i - bvirt); icbb[3] = u3;\n  }\n  if (adxtail !== 0 || adytail !== 0 || bdxtail !== 0 || bdytail !== 0) {\n    s1 = cdx * cdx; c = SPLITTER * cdx; ahi = c - (c - cdx); alo = cdx - ahi;\n    s0 = alo * alo - (s1 - ahi * ahi - (ahi + ahi) * alo);\n    t1 = cdy * cdy; c = SPLITTER * cdy; ahi = c - (c - cdy); alo = cdy - ahi;\n    t0 = alo * alo - (t1 - ahi * ahi - (ahi + ahi) * alo);\n    _i = s0 + t0; bvirt = _i - s0; iccc[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n    _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n    _i = _0 + t1; bvirt = _i - _0; iccc[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n    u3 = _j + _i; bvirt = u3 - _j; iccc[2] = _j - (u3 - bvirt) + (_i - bvirt); iccc[3] = u3;\n  }\n\n  const sum3 = (al: number, a: Float64Array, bl: number, b: Float64Array, cl: number, cv: Float64Array): number => {\n    const tl = expansionSum(al, a, bl, b, ic32);\n    return expansionSum(tl, ic32, cl, cv, ic48);\n  };\n\n  if (adxtail !== 0) {\n    axtbclen = scaleExpansion(4, icbc, adxtail, icaxtbc);\n    finlen = icFinadd(finlen, sum3(\n      scaleExpansion(axtbclen, icaxtbc, 2 * adx, ic16), ic16,\n      scaleExpansion(scaleExpansion(4, iccc, adxtail, ic8), ic8, bdy, ic16b), ic16b,\n      scaleExpansion(scaleExpansion(4, icbb, adxtail, ic8), ic8, -cdy, ic16c), ic16c), ic48);\n  }\n  if (adytail !== 0) {\n    aytbclen = scaleExpansion(4, icbc, adytail, icaytbc);\n    finlen = icFinadd(finlen, sum3(\n      scaleExpansion(aytbclen, icaytbc, 2 * ady, ic16), ic16,\n      scaleExpansion(scaleExpansion(4, icbb, adytail, ic8), ic8, cdx, ic16b), ic16b,\n      scaleExpansion(scaleExpansion(4, iccc, adytail, ic8), ic8, -bdx, ic16c), ic16c), ic48);\n  }\n  if (bdxtail !== 0) {\n    bxtcalen = scaleExpansion(4, icca, bdxtail, icbxtca);\n    finlen = icFinadd(finlen, sum3(\n      scaleExpansion(bxtcalen, icbxtca, 2 * bdx, ic16), ic16,\n      scaleExpansion(scaleExpansion(4, icaa, bdxtail, ic8), ic8, cdy, ic16b), ic16b,\n      scaleExpansion(scaleExpansion(4, iccc, bdxtail, ic8), ic8, -ady, ic16c), ic16c), ic48);\n  }\n  if (bdytail !== 0) {\n    bytcalen = scaleExpansion(4, icca, bdytail, icbytca);\n    finlen = icFinadd(finlen, sum3(\n      scaleExpansion(bytcalen, icbytca, 2 * bdy, ic16), ic16,\n      scaleExpansion(scaleExpansion(4, iccc, bdytail, ic8), ic8, adx, ic16b), ic16b,\n      scaleExpansion(scaleExpansion(4, icaa, bdytail, ic8), ic8, -cdx, ic16c), ic16c), ic48);\n  }\n  if (cdxtail !== 0) {\n    cxtablen = scaleExpansion(4, icab, cdxtail, iccxtab);\n    finlen = icFinadd(finlen, sum3(\n      scaleExpansion(cxtablen, iccxtab, 2 * cdx, ic16), ic16,\n      scaleExpansion(scaleExpansion(4, icbb, cdxtail, ic8), ic8, ady, ic16b), ic16b,\n      scaleExpansion(scaleExpansion(4, icaa, cdxtail, ic8), ic8, -bdy, ic16c), ic16c), ic48);\n  }\n  if (cdytail !== 0) {\n    cytablen = scaleExpansion(4, icab, cdytail, iccytab);\n    finlen = icFinadd(finlen, sum3(\n      scaleExpansion(cytablen, iccytab, 2 * cdy, ic16), ic16,\n      scaleExpansion(scaleExpansion(4, icaa, cdytail, ic8), ic8, bdx, ic16b), ic16b,\n      scaleExpansion(scaleExpansion(4, icbb, cdytail, ic8), ic8, -adx, ic16c), ic16c), ic48);\n  }\n\n  // Cross-tail terms\n  let bctlen: number, catlen: number, abtlen: number;\n  let bcttlen: number, cattlen: number, abttlen: number;\n\n  if (adxtail !== 0 || adytail !== 0) {\n    if (bdxtail !== 0 || bdytail !== 0 || cdxtail !== 0 || cdytail !== 0) {\n      s1 = bdxtail * cdy; c = SPLITTER * bdxtail; ahi = c - (c - bdxtail); alo = bdxtail - ahi;\n      c = SPLITTER * cdy; bhi = c - (c - cdy); blo = cdy - bhi;\n      s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n      t1 = bdx * cdytail; c = SPLITTER * bdx; ahi = c - (c - bdx); alo = bdx - ahi;\n      c = SPLITTER * cdytail; bhi = c - (c - cdytail); blo = cdytail - bhi;\n      t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n      _i = s0 + t0; bvirt = _i - s0; icu[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n      _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n      _i = _0 + t1; bvirt = _i - _0; icu[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n      u3 = _j + _i; bvirt = u3 - _j; icu[2] = _j - (u3 - bvirt) + (_i - bvirt); icu[3] = u3;\n\n      n1 = -bdy; n0 = -bdytail;\n      s1 = cdxtail * n1; c = SPLITTER * cdxtail; ahi = c - (c - cdxtail); alo = cdxtail - ahi;\n      c = SPLITTER * n1; bhi = c - (c - n1); blo = n1 - bhi;\n      s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n      t1 = cdx * n0; c = SPLITTER * cdx; ahi = c - (c - cdx); alo = cdx - ahi;\n      c = SPLITTER * n0; bhi = c - (c - n0); blo = n0 - bhi;\n      t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n      _i = s0 + t0; bvirt = _i - s0; icv[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n      _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n      _i = _0 + t1; bvirt = _i - _0; icv[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n      u3 = _j + _i; bvirt = u3 - _j; icv[2] = _j - (u3 - bvirt) + (_i - bvirt); icv[3] = u3;\n      bctlen = expansionSum(4, icu, 4, icv, icbct);\n\n      s1 = bdxtail * cdytail; c = SPLITTER * bdxtail; ahi = c - (c - bdxtail); alo = bdxtail - ahi;\n      c = SPLITTER * cdytail; bhi = c - (c - cdytail); blo = cdytail - bhi;\n      s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n      t1 = cdxtail * bdytail; c = SPLITTER * cdxtail; ahi = c - (c - cdxtail); alo = cdxtail - ahi;\n      c = SPLITTER * bdytail; bhi = c - (c - bdytail); blo = bdytail - bhi;\n      t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n      _i = s0 - t0; bvirt = s0 - _i;\n      icbctt[0] = s0 - (_i + bvirt) + (bvirt - t0);\n      _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n      _i = _0 - t1; bvirt = _0 - _i;\n      icbctt[1] = _0 - (_i + bvirt) + (bvirt - t1);\n      u3 = _j + _i; bvirt = u3 - _j; icbctt[2] = _j - (u3 - bvirt) + (_i - bvirt); icbctt[3] = u3;\n      bcttlen = 4;\n    } else { icbct[0] = 0; bctlen = 1; icbctt[0] = 0; bcttlen = 1; }\n\n    if (adxtail !== 0) {\n      const len = scaleExpansion(bctlen, icbct, adxtail, ic16c);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(axtbclen, icaxtbc, adxtail, ic16), ic16,\n        scaleExpansion(len, ic16c, 2 * adx, ic32), ic32, ic48), ic48);\n      const len2 = scaleExpansion(bcttlen, icbctt, adxtail, ic8);\n      const t32bl = expansionSum(scaleExpansion(len2, ic8, 2 * adx, ic16), ic16,\n        scaleExpansion(len2, ic8, adxtail, ic16b), ic16b, ic32b);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(len, ic16c, adxtail, ic32), ic32, t32bl, ic32b, ic64), ic64);\n      if (bdytail !== 0) finlen = icFinadd(finlen, scaleExpansion(scaleExpansion(4, iccc, adxtail, ic8), ic8, bdytail, ic16), ic16);\n      if (cdytail !== 0) finlen = icFinadd(finlen, scaleExpansion(scaleExpansion(4, icbb, -adxtail, ic8), ic8, cdytail, ic16), ic16);\n    }\n    if (adytail !== 0) {\n      const len = scaleExpansion(bctlen, icbct, adytail, ic16c);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(aytbclen, icaytbc, adytail, ic16), ic16,\n        scaleExpansion(len, ic16c, 2 * ady, ic32), ic32, ic48), ic48);\n      const len2 = scaleExpansion(bcttlen, icbctt, adytail, ic8);\n      const t32bl = expansionSum(scaleExpansion(len2, ic8, 2 * ady, ic16), ic16,\n        scaleExpansion(len2, ic8, adytail, ic16b), ic16b, ic32b);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(len, ic16c, adytail, ic32), ic32, t32bl, ic32b, ic64), ic64);\n    }\n  }\n\n  if (bdxtail !== 0 || bdytail !== 0) {\n    if (cdxtail !== 0 || cdytail !== 0 || adxtail !== 0 || adytail !== 0) {\n      s1 = cdxtail * ady; c = SPLITTER * cdxtail; ahi = c - (c - cdxtail); alo = cdxtail - ahi;\n      c = SPLITTER * ady; bhi = c - (c - ady); blo = ady - bhi;\n      s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n      t1 = cdx * adytail; c = SPLITTER * cdx; ahi = c - (c - cdx); alo = cdx - ahi;\n      c = SPLITTER * adytail; bhi = c - (c - adytail); blo = adytail - bhi;\n      t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n      _i = s0 + t0; bvirt = _i - s0; icu[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n      _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n      _i = _0 + t1; bvirt = _i - _0; icu[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n      u3 = _j + _i; bvirt = u3 - _j; icu[2] = _j - (u3 - bvirt) + (_i - bvirt); icu[3] = u3;\n\n      n1 = -cdy; n0 = -cdytail;\n      s1 = adxtail * n1; c = SPLITTER * adxtail; ahi = c - (c - adxtail); alo = adxtail - ahi;\n      c = SPLITTER * n1; bhi = c - (c - n1); blo = n1 - bhi;\n      s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n      t1 = adx * n0; c = SPLITTER * adx; ahi = c - (c - adx); alo = adx - ahi;\n      c = SPLITTER * n0; bhi = c - (c - n0); blo = n0 - bhi;\n      t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n      _i = s0 + t0; bvirt = _i - s0; icv[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n      _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n      _i = _0 + t1; bvirt = _i - _0; icv[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n      u3 = _j + _i; bvirt = u3 - _j; icv[2] = _j - (u3 - bvirt) + (_i - bvirt); icv[3] = u3;\n      catlen = expansionSum(4, icu, 4, icv, iccat);\n\n      s1 = cdxtail * adytail; c = SPLITTER * cdxtail; ahi = c - (c - cdxtail); alo = cdxtail - ahi;\n      c = SPLITTER * adytail; bhi = c - (c - adytail); blo = adytail - bhi;\n      s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n      t1 = adxtail * cdytail; c = SPLITTER * adxtail; ahi = c - (c - adxtail); alo = adxtail - ahi;\n      c = SPLITTER * cdytail; bhi = c - (c - cdytail); blo = cdytail - bhi;\n      t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n      _i = s0 - t0; bvirt = s0 - _i;\n      iccatt[0] = s0 - (_i + bvirt) + (bvirt - t0);\n      _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n      _i = _0 - t1; bvirt = _0 - _i;\n      iccatt[1] = _0 - (_i + bvirt) + (bvirt - t1);\n      u3 = _j + _i; bvirt = u3 - _j; iccatt[2] = _j - (u3 - bvirt) + (_i - bvirt); iccatt[3] = u3;\n      cattlen = 4;\n    } else { iccat[0] = 0; catlen = 1; iccatt[0] = 0; cattlen = 1; }\n\n    if (bdxtail !== 0) {\n      const len = scaleExpansion(catlen, iccat, bdxtail, ic16c);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(bxtcalen, icbxtca, bdxtail, ic16), ic16,\n        scaleExpansion(len, ic16c, 2 * bdx, ic32), ic32, ic48), ic48);\n      const len2 = scaleExpansion(cattlen, iccatt, bdxtail, ic8);\n      const t32bl = expansionSum(scaleExpansion(len2, ic8, 2 * bdx, ic16), ic16,\n        scaleExpansion(len2, ic8, bdxtail, ic16b), ic16b, ic32b);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(len, ic16c, bdxtail, ic32), ic32, t32bl, ic32b, ic64), ic64);\n      if (cdytail !== 0) finlen = icFinadd(finlen, scaleExpansion(scaleExpansion(4, icaa, bdxtail, ic8), ic8, cdytail, ic16), ic16);\n      if (adytail !== 0) finlen = icFinadd(finlen, scaleExpansion(scaleExpansion(4, iccc, -bdxtail, ic8), ic8, adytail, ic16), ic16);\n    }\n    if (bdytail !== 0) {\n      const len = scaleExpansion(catlen, iccat, bdytail, ic16c);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(bytcalen, icbytca, bdytail, ic16), ic16,\n        scaleExpansion(len, ic16c, 2 * bdy, ic32), ic32, ic48), ic48);\n      const len2 = scaleExpansion(cattlen, iccatt, bdytail, ic8);\n      const t32bl = expansionSum(scaleExpansion(len2, ic8, 2 * bdy, ic16), ic16,\n        scaleExpansion(len2, ic8, bdytail, ic16b), ic16b, ic32b);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(len, ic16c, bdytail, ic32), ic32, t32bl, ic32b, ic64), ic64);\n    }\n  }\n\n  if (cdxtail !== 0 || cdytail !== 0) {\n    if (adxtail !== 0 || adytail !== 0 || bdxtail !== 0 || bdytail !== 0) {\n      s1 = adxtail * bdy; c = SPLITTER * adxtail; ahi = c - (c - adxtail); alo = adxtail - ahi;\n      c = SPLITTER * bdy; bhi = c - (c - bdy); blo = bdy - bhi;\n      s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n      t1 = adx * bdytail; c = SPLITTER * adx; ahi = c - (c - adx); alo = adx - ahi;\n      c = SPLITTER * bdytail; bhi = c - (c - bdytail); blo = bdytail - bhi;\n      t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n      _i = s0 + t0; bvirt = _i - s0; icu[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n      _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n      _i = _0 + t1; bvirt = _i - _0; icu[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n      u3 = _j + _i; bvirt = u3 - _j; icu[2] = _j - (u3 - bvirt) + (_i - bvirt); icu[3] = u3;\n\n      n1 = -ady; n0 = -adytail;\n      s1 = bdxtail * n1; c = SPLITTER * bdxtail; ahi = c - (c - bdxtail); alo = bdxtail - ahi;\n      c = SPLITTER * n1; bhi = c - (c - n1); blo = n1 - bhi;\n      s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n      t1 = bdx * n0; c = SPLITTER * bdx; ahi = c - (c - bdx); alo = bdx - ahi;\n      c = SPLITTER * n0; bhi = c - (c - n0); blo = n0 - bhi;\n      t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n      _i = s0 + t0; bvirt = _i - s0; icv[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n      _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n      _i = _0 + t1; bvirt = _i - _0; icv[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n      u3 = _j + _i; bvirt = u3 - _j; icv[2] = _j - (u3 - bvirt) + (_i - bvirt); icv[3] = u3;\n      abtlen = expansionSum(4, icu, 4, icv, icabt);\n\n      s1 = adxtail * bdytail; c = SPLITTER * adxtail; ahi = c - (c - adxtail); alo = adxtail - ahi;\n      c = SPLITTER * bdytail; bhi = c - (c - bdytail); blo = bdytail - bhi;\n      s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n      t1 = bdxtail * adytail; c = SPLITTER * bdxtail; ahi = c - (c - bdxtail); alo = bdxtail - ahi;\n      c = SPLITTER * adytail; bhi = c - (c - adytail); blo = adytail - bhi;\n      t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n      _i = s0 - t0; bvirt = s0 - _i;\n      icabtt[0] = s0 - (_i + bvirt) + (bvirt - t0);\n      _j = s1 + _i; bvirt = _j - s1; _0 = s1 - (_j - bvirt) + (_i - bvirt);\n      _i = _0 - t1; bvirt = _0 - _i;\n      icabtt[1] = _0 - (_i + bvirt) + (bvirt - t1);\n      u3 = _j + _i; bvirt = u3 - _j; icabtt[2] = _j - (u3 - bvirt) + (_i - bvirt); icabtt[3] = u3;\n      abttlen = 4;\n    } else { icabt[0] = 0; abtlen = 1; icabtt[0] = 0; abttlen = 1; }\n\n    if (cdxtail !== 0) {\n      const len = scaleExpansion(abtlen, icabt, cdxtail, ic16c);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(cxtablen, iccxtab, cdxtail, ic16), ic16,\n        scaleExpansion(len, ic16c, 2 * cdx, ic32), ic32, ic48), ic48);\n      const len2 = scaleExpansion(abttlen, icabtt, cdxtail, ic8);\n      const t32bl = expansionSum(scaleExpansion(len2, ic8, 2 * cdx, ic16), ic16,\n        scaleExpansion(len2, ic8, cdxtail, ic16b), ic16b, ic32b);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(len, ic16c, cdxtail, ic32), ic32, t32bl, ic32b, ic64), ic64);\n      if (adytail !== 0) finlen = icFinadd(finlen, scaleExpansion(scaleExpansion(4, icbb, cdxtail, ic8), ic8, adytail, ic16), ic16);\n      if (bdytail !== 0) finlen = icFinadd(finlen, scaleExpansion(scaleExpansion(4, icaa, -cdxtail, ic8), ic8, bdytail, ic16), ic16);\n    }\n    if (cdytail !== 0) {\n      const len = scaleExpansion(abtlen, icabt, cdytail, ic16c);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(cytablen, iccytab, cdytail, ic16), ic16,\n        scaleExpansion(len, ic16c, 2 * cdy, ic32), ic32, ic48), ic48);\n      const len2 = scaleExpansion(abttlen, icabtt, cdytail, ic8);\n      const t32bl = expansionSum(scaleExpansion(len2, ic8, 2 * cdy, ic16), ic16,\n        scaleExpansion(len2, ic8, cdytail, ic16b), ic16b, ic32b);\n      finlen = icFinadd(finlen, expansionSum(\n        scaleExpansion(len, ic16c, cdytail, ic32), ic32, t32bl, ic32b, ic64), ic64);\n    }\n  }\n\n  return icfin[finlen - 1];\n}\n\n\n// incircle sign, with adaptive exact fallback\nexport function adaptiveIncircleSign(\n  ax: number, ay: number, bx: number, by: number,\n  cx: number, cy: number, dx: number, dy: number\n): number {\n  const adx = ax - dx, bdx = bx - dx, cdx = cx - dx;\n  const ady = ay - dy, bdy = by - dy, cdy = cy - dy;\n\n  const bdxcdy = bdx * cdy, cdxbdy = cdx * bdy;\n  const alift = adx * adx + ady * ady;\n  const cdxady = cdx * ady, adxcdy = adx * cdy;\n  const blift = bdx * bdx + bdy * bdy;\n  const adxbdy = adx * bdy, bdxady = bdx * ady;\n  const clift = cdx * cdx + cdy * cdy;\n\n  const det = alift * (bdxcdy - cdxbdy) + blift * (cdxady - adxcdy) + clift * (adxbdy - bdxady);\n  const permanent = (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * alift +\n    (Math.abs(cdxady) + Math.abs(adxcdy)) * blift +\n    (Math.abs(adxbdy) + Math.abs(bdxady)) * clift;\n\n  const errbound = iccerrboundA * permanent;\n  if (det > errbound || -det > errbound) return det > 0 ? 1 : -1;\n\n  const result = incircleadapt(ax, ay, bx, by, cx, cy, dx, dy, permanent);\n  return result > 0 ? 1 : result < 0 ? -1 : 0;\n}\n","/*******************************************************************************\n* Author    :  Angus Johnson                                                   *\n* Date      :  13 December 2025                                                *\n* Release   :  BETA RELEASE                                                    *\n* Website   :  https://www.angusj.com                                          *\n* Copyright :  Angus Johnson 2010-2025                                         *\n* Purpose   :  Constrained Delaunay Triangulation                              *\n* License   :  https://www.boost.org/LICENSE_1_0.txt                           *\n*******************************************************************************/\n\nimport { Point64, Path64, Paths64 } from './Core.js';\nimport { adaptiveOrient2dSign, adaptiveIncircleSign } from './Shewchuk.js';\n\nexport enum TriangulateResult {\n  success,\n  fail,\n  noPolygons,\n  pathsIntersect\n}\n\n// -------------------------------------------------------------------------\n// Internal triangulation helpers\n// -------------------------------------------------------------------------\n\nenum EdgeKind { loose, ascend, descend } // ascend & descend are 'fixed' edges\nenum IntersectKind { none, collinear, intersect }\nenum EdgeContainsResult { neither, left, right }\n\nclass Vertex2 {\n  pt: Point64;\n  edges: Edge[] = [];\n  innerLM: boolean = false;\n\n  constructor(p64: Point64) {\n    this.pt = p64;\n  }\n}\n\nclass Edge {\n  vL: Vertex2 = null!;\n  vR: Vertex2 = null!;\n  vB: Vertex2 = null!;\n  vT: Vertex2 = null!;\n  kind: EdgeKind = EdgeKind.loose;\n  triA: Triangle | null = null;\n  triB: Triangle | null = null;\n  isActive: boolean = false;\n  pendingDelaunay: boolean = false;\n  nextE: Edge | null = null;\n  prevE: Edge | null = null;\n}\n\nclass Triangle {\n  edges: Edge[] = new Array(3);\n\n  constructor(e1: Edge, e2: Edge, e3: Edge) {\n    this.edges[0] = e1;\n    this.edges[1] = e2;\n    this.edges[2] = e3;\n  }\n}\n\n// -------------------------------------------------------------------------\n// Delaunay class declaration & implementation\n// -------------------------------------------------------------------------\n\nexport class Delaunay {\n  private readonly allVertices: Vertex2[] = [];\n  private readonly allEdges: Edge[] = [];\n  private readonly allTriangles: Triangle[] = [];\n  private readonly pendingDelaunayStack: Edge[] = [];\n  private readonly horzEdgeStack: Edge[] = [];\n  private readonly locMinStack: Vertex2[] = [];\n  private readonly useDelaunay: boolean;\n  private firstActive: Edge | null = null;\n  private lowermostVertex: Vertex2 | null = null;\n  private fastMath: boolean = false;\n  private readonly _edgesA: (Edge | null)[] = [null, null, null];\n  private readonly _edgesB: (Edge | null)[] = [null, null, null];\n\n  constructor(delaunay: boolean = true) {\n    this.useDelaunay = delaunay;\n  }\n\n  private updateFastMath(paths: Paths64): void {\n    let hasPoint = false;\n    let minX = 0;\n    let maxX = 0;\n    let minY = 0;\n    let maxY = 0;\n    let safe = true;\n\n    for (const path of paths) {\n      for (const pt of path) {\n        if (!Number.isSafeInteger(pt.x) || !Number.isSafeInteger(pt.y)) {\n          safe = false;\n          break;\n        }\n        if (!hasPoint) {\n          hasPoint = true;\n          minX = pt.x;\n          maxX = pt.x;\n          minY = pt.y;\n          maxY = pt.y;\n        } else {\n          if (pt.x < minX) minX = pt.x;\n          if (pt.x > maxX) maxX = pt.x;\n          if (pt.y < minY) minY = pt.y;\n          if (pt.y > maxY) maxY = pt.y;\n        }\n      }\n      if (!safe) break;\n    }\n\n    if (!safe || !hasPoint) {\n      this.fastMath = false;\n      return;\n    }\n\n    const maxDeltaX = maxX - minX;\n    const maxDeltaY = maxY - minY;\n    this.fastMath = Math.max(maxDeltaX, maxDeltaY) <= Delaunay.maxSafeDelta;\n  }\n\n  private addPath(path: Path64): void {\n    const len = path.length;\n    if (len === 0) return;\n\n    let i0 = 0;\n    let iPrev: number;\n    let iNext: number;\n\n    i0 = Delaunay.findLocMinIdx(path, len, i0);\n    if (i0 < 0) return;\n\n    iPrev = Delaunay.prev(i0, len);\n    while (path[iPrev].x === path[i0].x && path[iPrev].y === path[i0].y)\n      iPrev = Delaunay.prev(iPrev, len);\n\n    iNext = Delaunay.next(i0, len);\n\n    let i = i0;\n    while (this.crossProductSign(path[iPrev], path[i], path[iNext]) === 0) {\n      i = Delaunay.findLocMinIdx(path, len, i);\n      if (i < 0) return;\n      iPrev = Delaunay.prev(i, len);\n      while (path[iPrev].x === path[i].x && path[iPrev].y === path[i].y)\n        iPrev = Delaunay.prev(iPrev, len);\n      iNext = Delaunay.next(i, len);\n    }\n\n    const vert_cnt = this.allVertices.length;\n    const v0 = new Vertex2(path[i]);\n    this.allVertices.push(v0);\n\n    if (this.leftTurning(path[iPrev], path[i], path[iNext]))\n      v0.innerLM = true;\n\n    let vPrev = v0;\n    i = iNext;\n\n    for (; ;) {\n      iNext = Delaunay.next(i, len);\n      if (this.crossProductSign(vPrev.pt, path[i], path[iNext]) === 0) {\n        i = iNext;\n        continue;\n      }\n\n      // vPrev is a locMin here\n      this.locMinStack.push(vPrev);\n      if (this.lowermostVertex === null ||\n        vPrev.pt.y > this.lowermostVertex.pt.y ||\n        (vPrev.pt.y === this.lowermostVertex.pt.y &&\n          vPrev.pt.x < this.lowermostVertex.pt.x))\n        this.lowermostVertex = vPrev;\n\n      // ascend up next bound to LocMax\n      while (path[i].y <= vPrev.pt.y) {\n        const v = new Vertex2(path[i]);\n        this.allVertices.push(v);\n        this.createEdge(vPrev, v, EdgeKind.ascend);\n        vPrev = v;\n        i = iNext;\n        iNext = Delaunay.next(i, len);\n\n        while (this.crossProductSign(vPrev.pt, path[i], path[iNext]) === 0) {\n          i = iNext;\n          iNext = Delaunay.next(i, len);\n        }\n      }\n\n      // Now at a locMax, so descend to next locMin\n      const vPrevPrev = vPrev;\n      while (i !== i0 && path[i].y >= vPrev.pt.y) {\n        const v = new Vertex2(path[i]);\n        this.allVertices.push(v);\n        this.createEdge(v, vPrev, EdgeKind.descend);\n        vPrev = v;\n        i = iNext;\n        iNext = Delaunay.next(i, len);\n\n        while (this.crossProductSign(vPrev.pt, path[i], path[iNext]) === 0) {\n          i = iNext;\n          iNext = Delaunay.next(i, len);\n        }\n      }\n\n      // now at the next locMin\n      if (i === i0) break;\n      if (this.leftTurning(vPrevPrev.pt, vPrev.pt, path[i]))\n        vPrev.innerLM = true;\n    }\n\n    this.createEdge(v0, vPrev, EdgeKind.descend);\n\n    // finally, ignore this path if is not a polygon or too small\n    const pathLen = this.allVertices.length - vert_cnt;\n    const idx = vert_cnt;\n    if (pathLen < 3 || (pathLen === 3 &&\n      ((this.distanceSqr(this.allVertices[idx].pt, this.allVertices[idx + 1].pt) <= 1) ||\n        (this.distanceSqr(this.allVertices[idx + 1].pt, this.allVertices[idx + 2].pt) <= 1) ||\n        (this.distanceSqr(this.allVertices[idx + 2].pt, this.allVertices[idx].pt) <= 1)))) {\n      for (let j = vert_cnt; j < this.allVertices.length; ++j)\n        this.allVertices[j].edges = []; // flag to ignore\n    }\n  }\n\n  private addPaths(paths: Paths64): boolean {\n    let totalVertexCount = 0;\n    for (const path of paths)\n      totalVertexCount += path.length;\n    if (totalVertexCount === 0) return false;\n\n    for (const path of paths)\n      this.addPath(path);\n\n    return this.allVertices.length > 2;\n  }\n\n  private cleanUp(): void {\n    this.allVertices.length = 0;\n    this.allEdges.length = 0;\n    this.allTriangles.length = 0;\n    this.pendingDelaunayStack.length = 0;\n    this.horzEdgeStack.length = 0;\n    this.locMinStack.length = 0;\n\n    this.firstActive = null;\n    this.lowermostVertex = null;\n  }\n\n  private fixupEdgeIntersects(): boolean {\n    // precondition - edgeList must be sorted - ascending on edge.vL.pt.x\n    for (let i1 = 0; i1 < this.allEdges.length; ++i1) {\n      const e1 = this.allEdges[i1];\n      const e1vR = e1.vR.pt.x;\n      const e1vB = e1.vB.pt.y;\n      const e1vT = e1.vT.pt.y;\n      for (let i2 = i1 + 1; i2 < this.allEdges.length; ++i2) {\n        const e2 = this.allEdges[i2];\n        if (e2.vL.pt.x >= e1vR)\n          break;\n\n        if (e2.vT.pt.y < e1vB && e2.vB.pt.y > e1vT &&\n          this.segsIntersect(e2.vL.pt, e2.vR.pt, e1.vL.pt, e1.vR.pt) === IntersectKind.intersect) {\n          if (!this.removeIntersection(e2, e1))\n            return false;\n        }\n      }\n    }\n    return true;\n  }\n\n  private mergeDupOrCollinearVertices(): void {\n    if (this.allVertices.length < 2) return;\n\n    let v1Index = 0;\n    for (let v2Index = 1; v2Index < this.allVertices.length; ++v2Index) {\n      const v1 = this.allVertices[v1Index];\n      const v2 = this.allVertices[v2Index];\n\n      if (!(v1.pt.x === v2.pt.x && v1.pt.y === v2.pt.y)) {\n        v1Index = v2Index;\n        continue;\n      }\n\n      // merge v1 & v2\n      if (!v1.innerLM || !v2.innerLM)\n        v1.innerLM = false;\n\n      for (const e of v2.edges) {\n        if (e.vB === v2) e.vB = v1; else e.vT = v1;\n        if (e.vL === v2) e.vL = v1; else e.vR = v1;\n      }\n\n      v1.edges.push(...v2.edges);\n      v2.edges = [];\n\n      // excluding horizontals, if pv.edges contains two edges\n      // that are collinear and share the same bottom coords\n      // but have different lengths, split the longer edge at\n      // the top of the shorter edge ...\n      for (let iE = 0; iE < v1.edges.length; ++iE) {\n        const e1 = v1.edges[iE];\n        if (Delaunay.isHorizontal(e1) || e1.vB !== v1) continue;\n\n        for (let iE2 = iE + 1; iE2 < v1.edges.length; ++iE2) {\n          const e2 = v1.edges[iE2];\n          if (e2.vB !== v1 || e1.vT.pt.y === e2.vT.pt.y ||\n            this.crossProductSign(e1.vT.pt, v1.pt, e2.vT.pt) !== 0)\n            continue;\n\n          // parallel edges from v1 up\n          if (e1.vT.pt.y < e2.vT.pt.y) this.splitEdge(e1, e2);\n          else this.splitEdge(e2, e1);\n          break; // only two can be collinear\n        }\n      }\n    }\n  }\n\n  private splitEdge(longE: Edge, shortE: Edge): void {\n    const oldT = longE.vT;\n    const newT = shortE.vT;\n\n    Delaunay.removeEdgeFromVertex(oldT, longE);\n\n    longE.vT = newT;\n    if (longE.vL === oldT) longE.vL = newT; else longE.vR = newT;\n\n    newT.edges.push(longE);\n\n    this.createEdge(newT, oldT, longE.kind);\n  }\n\n  private removeIntersection(e1: Edge, e2: Edge): boolean {\n    let v = e1.vL;\n    let tmpE = e2;\n\n    let d = this.shortestDistFromSegment(e1.vL.pt, e2.vL.pt, e2.vR.pt);\n    let d2 = this.shortestDistFromSegment(e1.vR.pt, e2.vL.pt, e2.vR.pt);\n    if (d2 < d) { d = d2; v = e1.vR; }\n\n    d2 = this.shortestDistFromSegment(e2.vL.pt, e1.vL.pt, e1.vR.pt);\n    if (d2 < d) { d = d2; tmpE = e1; v = e2.vL; }\n\n    d2 = this.shortestDistFromSegment(e2.vR.pt, e1.vL.pt, e1.vR.pt);\n    if (d2 < d) { d = d2; tmpE = e1; v = e2.vR; }\n\n    if (d > 1.0)\n      return false; // not a simple rounding intersection\n\n    const v2 = tmpE.vT;\n    Delaunay.removeEdgeFromVertex(v2, tmpE);\n\n    if (tmpE.vL === v2) tmpE.vL = v; else tmpE.vR = v;\n    tmpE.vT = v;\n    v.edges.push(tmpE);\n    v.innerLM = false;\n\n    if (tmpE.vB.innerLM && Delaunay.getLocMinAngle(tmpE.vB) <= 0)\n      tmpE.vB.innerLM = false;\n\n    this.createEdge(v, v2, tmpE.kind);\n    return true;\n  }\n\n  private createEdge(v1: Vertex2, v2: Vertex2, k: EdgeKind): Edge {\n    const res = new Edge();\n    this.allEdges.push(res);\n\n    if (v1.pt.y === v2.pt.y) {\n      res.vB = v1;\n      res.vT = v2;\n    } else if (v1.pt.y < v2.pt.y) {\n      res.vB = v2;\n      res.vT = v1;\n    } else {\n      res.vB = v1;\n      res.vT = v2;\n    }\n\n    if (v1.pt.x <= v2.pt.x) {\n      res.vL = v1;\n      res.vR = v2;\n    } else {\n      res.vL = v2;\n      res.vR = v1;\n    }\n\n    res.kind = k;\n    v1.edges.push(res);\n    v2.edges.push(res);\n\n    if (k === EdgeKind.loose) {\n      this.queuePendingDelaunay(res);\n      this.addEdgeToActives(res);\n    }\n\n    return res;\n  }\n\n  private createTriangle(e1: Edge, e2: Edge, e3: Edge): Triangle {\n    const tri = new Triangle(e1, e2, e3);\n    this.allTriangles.push(tri);\n\n    for (let i = 0; i < 3; ++i) {\n      const e = tri.edges[i];\n      if (e.triA !== null) {\n        e.triB = tri;\n        this.removeEdgeFromActives(e);\n      } else {\n        e.triA = tri;\n        if (!Delaunay.isLooseEdge(e))\n          this.removeEdgeFromActives(e);\n      }\n    }\n\n    return tri;\n  }\n\n  private forceLegal(edge: Edge): void {\n    if (edge.triA === null || edge.triB === null) return;\n\n    let vertA: Vertex2 | null = null;\n    let vertB: Vertex2 | null = null;\n\n    const edgesA = this._edgesA;\n    const edgesB = this._edgesB;\n    edgesA[0] = edgesA[1] = edgesA[2] = null;\n    edgesB[0] = edgesB[1] = edgesB[2] = null;\n\n    for (let i = 0; i < 3; ++i) {\n      if (edge.triA!.edges[i] === edge) continue;\n      const e = edge.triA!.edges[i];\n      const containsResult = Delaunay.edgeContains(e, edge.vL);\n      if (containsResult === EdgeContainsResult.left) {\n        edgesA[1] = e;\n        vertA = e.vR;\n      } else if (containsResult === EdgeContainsResult.right) {\n        edgesA[1] = e;\n        vertA = e.vL;\n      } else {\n        edgesB[1] = e;\n      }\n    }\n\n    for (let i = 0; i < 3; ++i) {\n      if (edge.triB!.edges[i] === edge) continue;\n      const e = edge.triB!.edges[i];\n      const containsResult = Delaunay.edgeContains(e, edge.vL);\n      if (containsResult === EdgeContainsResult.left) {\n        edgesA[2] = e;\n        vertB = e.vR;\n      } else if (containsResult === EdgeContainsResult.right) {\n        edgesA[2] = e;\n        vertB = e.vL;\n      } else {\n        edgesB[2] = e;\n      }\n    }\n\n    if (vertA === null || vertB === null) return;\n\n    const cpsA = this.crossProductSign(vertA.pt, edge.vL.pt, edge.vR.pt);\n    if (cpsA === 0)\n      return;\n\n    const cpsB = this.crossProductSign(vertB.pt, edge.vL.pt, edge.vR.pt);\n    if (cpsB === 0 || cpsA === cpsB)\n      return;\n\n    const ictResult = this.inCircleTest(vertA.pt, edge.vL.pt, edge.vR.pt, vertB.pt);\n    if (ictResult === 0 ||\n      (this.rightTurning(vertA.pt, edge.vL.pt, edge.vR.pt) === (ictResult < 0)))\n      return;\n\n    edge.vL = vertA;\n    edge.vR = vertB;\n\n    edge.triA!.edges[0] = edge;\n    for (let i = 1; i < 3; ++i) {\n      const eAi = edgesA[i]!;\n      edge.triA!.edges[i] = eAi;\n      if (Delaunay.isLooseEdge(eAi))\n        this.queuePendingDelaunay(eAi);\n\n      if (eAi.triA === edge.triA || eAi.triB === edge.triA) continue;\n\n      if (eAi.triA === edge.triB)\n        eAi.triA = edge.triA;\n      else if (eAi.triB === edge.triB)\n        eAi.triB = edge.triA;\n      else\n        throw new Error('Triangulation internal error');\n    }\n\n    edge.triB!.edges[0] = edge;\n    for (let i = 1; i < 3; ++i) {\n      const eBi = edgesB[i]!;\n      edge.triB!.edges[i] = eBi;\n      if (Delaunay.isLooseEdge(eBi))\n        this.queuePendingDelaunay(eBi);\n\n      if (eBi.triA === edge.triB || eBi.triB === edge.triB) continue;\n\n      if (eBi.triA === edge.triA)\n        eBi.triA = edge.triB;\n      else if (eBi.triB === edge.triA)\n        eBi.triB = edge.triB;\n      else\n        throw new Error('Triangulation internal error');\n    }\n  }\n\n  private createInnerLocMinLooseEdge(vAbove: Vertex2): Edge | null {\n    if (this.firstActive === null) return null;\n\n    const xAbove = vAbove.pt.x;\n    const yAbove = vAbove.pt.y;\n\n    let e: Edge | null = this.firstActive;\n    let eBelow: Edge | null = null;\n    let bestD = -1.0;\n\n    while (e !== null) {\n      if (e.vL.pt.x <= xAbove && e.vR.pt.x >= xAbove &&\n        e.vB.pt.y >= yAbove && e.vB !== vAbove && e.vT !== vAbove &&\n        !this.leftTurning(e.vL.pt, vAbove.pt, e.vR.pt)) {\n        const d = this.shortestDistFromSegment(vAbove.pt, e.vL.pt, e.vR.pt);\n        if (eBelow === null || d < bestD) {\n          eBelow = e;\n          bestD = d;\n        }\n      }\n      e = e.nextE;\n    }\n\n    if (eBelow === null) return null;\n\n    let vBest = (eBelow.vT.pt.y <= yAbove) ? eBelow.vB : eBelow.vT;\n\n    // Iterate until no blocking edge is found for the current bridge vBest->vAbove.\n    // We must restart the search whenever vBest changes because edges checked earlier\n    // might now intersect the new bridge.\n    let changed = true;\n    while (changed) {\n      changed = false;\n      e = this.firstActive;\n      while (e !== null) {\n        // Skip edges that share a vertex with the bridge (not a true intersection)\n        if (e.vB !== vBest && e.vT !== vBest && e.vB !== vAbove && e.vT !== vAbove) {\n          if (this.segsIntersect(e.vB.pt, e.vT.pt, vBest.pt, vAbove.pt) === IntersectKind.intersect) {\n            // Found a blocking edge - use the vertex closer to yAbove as new vBest\n            vBest = (e.vT.pt.y > yAbove) ? e.vT : e.vB;\n            changed = true;\n            break; // restart search with new vBest\n          }\n        }\n        e = e.nextE;\n      }\n    }\n\n    return this.createEdge(vBest, vAbove, EdgeKind.loose);\n  }\n\n\n  private doTriangulateLeft(edge: Edge, pivot: Vertex2, minY: number, limitFan = false): void {\n    let vAlt: Vertex2 | null = null;\n    let eAlt: Edge | null = null;\n\n    const v = (edge.vB === pivot) ? edge.vT : edge.vB;\n\n    for (const e of pivot.edges) {\n      if (e === edge || !e.isActive) continue;\n\n      const vX = (e.vT === pivot) ? e.vB : e.vT;\n      if (vX === v) continue;\n\n    const cps = this.crossProductSign(v.pt, pivot.pt, vX.pt);\n      if (cps === 0) {\n        if ((v.pt.x > pivot.pt.x) === (pivot.pt.x > vX.pt.x)) continue;\n      } else if (cps > 0 || (vAlt !== null && !this.leftTurning(vX.pt, pivot.pt, vAlt.pt)))\n        continue;\n\n      vAlt = vX;\n      eAlt = e;\n    }\n\n    if (vAlt === null || vAlt.pt.y < minY || eAlt === null) return;\n\n    // Domiter & Zalik 2008, §3.2: stop fan extension when angle at pivot > pi/2\n    if (limitFan) {\n      const dvx = v.pt.x - pivot.pt.x, dvy = v.pt.y - pivot.pt.y;\n      const dax = vAlt.pt.x - pivot.pt.x, day = vAlt.pt.y - pivot.pt.y;\n      if (dvx * dax + dvy * day < 0) return;\n    }\n\n    if (vAlt.pt.y < pivot.pt.y) {\n      if (Delaunay.isLeftEdge(eAlt)) return;\n    } else if (vAlt.pt.y > pivot.pt.y) {\n      if (Delaunay.isRightEdge(eAlt)) return;\n    }\n\n    let eX = Delaunay.findLinkingEdge(vAlt, v, (vAlt.pt.y < v.pt.y));\n    if (eX === null) {\n      eX = this.createEdge(vAlt, v, EdgeKind.loose);\n    }\n\n    this.createTriangle(edge, eAlt, eX);\n\n    if (!Delaunay.edgeCompleted(eX))\n      this.doTriangulateLeft(eX, vAlt, minY, true);\n  }\n\n  private doTriangulateRight(edge: Edge, pivot: Vertex2, minY: number, limitFan = false): void {\n    let vAlt: Vertex2 | null = null;\n    let eAlt: Edge | null = null;\n\n    const v = (edge.vB === pivot) ? edge.vT : edge.vB;\n\n    for (const e of pivot.edges) {\n      if (e === edge || !e.isActive) continue;\n\n      const vX = (e.vT === pivot) ? e.vB : e.vT;\n      if (vX === v) continue;\n\n    const cps = this.crossProductSign(v.pt, pivot.pt, vX.pt);\n      if (cps === 0) {\n        if ((v.pt.x > pivot.pt.x) === (pivot.pt.x > vX.pt.x)) continue;\n      } else if (cps < 0 || (vAlt !== null && !this.rightTurning(vX.pt, pivot.pt, vAlt.pt)))\n        continue;\n\n      vAlt = vX;\n      eAlt = e;\n    }\n\n    if (vAlt === null || vAlt.pt.y < minY || eAlt === null) return;\n\n    // Domiter & Zalik 2008, §3.2: stop fan extension when angle at pivot > pi/2\n    if (limitFan) {\n      const dvx = v.pt.x - pivot.pt.x, dvy = v.pt.y - pivot.pt.y;\n      const dax = vAlt.pt.x - pivot.pt.x, day = vAlt.pt.y - pivot.pt.y;\n      if (dvx * dax + dvy * day < 0) return;\n    }\n\n    if (vAlt.pt.y < pivot.pt.y) {\n      if (Delaunay.isRightEdge(eAlt)) return;\n    } else if (vAlt.pt.y > pivot.pt.y) {\n      if (Delaunay.isLeftEdge(eAlt)) return;\n    }\n\n    let eX = Delaunay.findLinkingEdge(vAlt, v, (vAlt.pt.y > v.pt.y));\n    if (eX === null) {\n      eX = this.createEdge(vAlt, v, EdgeKind.loose);\n    }\n\n    this.createTriangle(edge, eX, eAlt);\n\n    if (!Delaunay.edgeCompleted(eX))\n      this.doTriangulateRight(eX, vAlt, minY, true);\n  }\n\n  private addEdgeToActives(edge: Edge): void {\n    if (edge.isActive) return;\n\n    edge.prevE = null;\n    edge.nextE = this.firstActive;\n    edge.isActive = true;\n\n    if (this.firstActive !== null)\n      this.firstActive.prevE = edge;\n\n    this.firstActive = edge;\n  }\n\n  private queuePendingDelaunay(edge: Edge): void {\n    if (edge.pendingDelaunay) return;\n    edge.pendingDelaunay = true;\n    this.pendingDelaunayStack.push(edge);\n  }\n\n  private removeEdgeFromActives(edge: Edge): void {\n    Delaunay.removeEdgeFromVertex(edge.vB, edge);\n    Delaunay.removeEdgeFromVertex(edge.vT, edge);\n\n    const prev = edge.prevE;\n    const next = edge.nextE;\n\n    if (next !== null) next.prevE = prev;\n    if (prev !== null) prev.nextE = next;\n\n    edge.isActive = false;\n    if (this.firstActive === edge) this.firstActive = next;\n  }\n\n  execute(paths: Paths64): { result: TriangulateResult, solution: Paths64 } {\n    const sol: Paths64 = [];\n\n    this.updateFastMath(paths);\n\n    if (!this.addPaths(paths)) {\n      return { result: TriangulateResult.noPolygons, solution: sol };\n    }\n\n    // if necessary fix path orientation because the algorithm \n    // expects clockwise outer paths and counter-clockwise inner paths\n    if (this.lowermostVertex!.innerLM) {\n      // the orientation of added paths must be wrong, so\n      // 1. reverse innerLM flags ...\n      while (this.locMinStack.length > 0) {\n        const lm = this.locMinStack.pop()!;\n        lm.innerLM = !lm.innerLM;\n      }\n      // 2. swap edge kinds\n      for (const e of this.allEdges) {\n        if (e.kind === EdgeKind.ascend)\n          e.kind = EdgeKind.descend;\n        else if (e.kind === EdgeKind.descend)\n          e.kind = EdgeKind.ascend;\n      }\n    } else {\n      // path orientation is fine so ...\n      this.locMinStack.length = 0;\n    }\n\n    this.allEdges.sort((a, b) => {\n      if (a.vL.pt.x < b.vL.pt.x) return -1;\n      if (a.vL.pt.x > b.vL.pt.x) return 1;\n      return 0;\n    });\n\n    if (!this.fixupEdgeIntersects()) {\n      this.cleanUp();\n      return { result: TriangulateResult.pathsIntersect, solution: sol };\n    }\n\n    this.allVertices.sort((a, b) => {\n      if (a.pt.y === b.pt.y) {\n        if (a.pt.x < b.pt.x) return -1;\n        if (a.pt.x > b.pt.x) return 1;\n        return 0;\n      }\n      if (b.pt.y < a.pt.y) return -1;\n      return 1;\n    });\n\n    this.mergeDupOrCollinearVertices();\n\n    let currY = this.allVertices[0].pt.y;\n\n    for (const v of this.allVertices) {\n      if (v.edges.length === 0) continue;\n\n      if (v.pt.y !== currY) {\n        while (this.locMinStack.length > 0) {\n          const lm = this.locMinStack.pop()!;\n          const e = this.createInnerLocMinLooseEdge(lm);\n          if (e === null) {\n            this.cleanUp();\n            return { result: TriangulateResult.fail, solution: sol };\n          }\n\n          if (Delaunay.isHorizontal(e)) {\n            if (e.vL === e.vB)\n              this.doTriangulateLeft(e, e.vB, currY);\n            else\n              this.doTriangulateRight(e, e.vB, currY);\n          } else {\n            this.doTriangulateLeft(e, e.vB, currY);\n            if (!Delaunay.edgeCompleted(e))\n              this.doTriangulateRight(e, e.vB, currY);\n          }\n\n          this.addEdgeToActives(lm.edges[0]);\n          this.addEdgeToActives(lm.edges[1]);\n        }\n\n        while (this.horzEdgeStack.length > 0) {\n          const e = this.horzEdgeStack.pop()!;\n          if (Delaunay.edgeCompleted(e)) continue;\n\n          if (e.vB === e.vL) {\n            if (Delaunay.isLeftEdge(e))\n              this.doTriangulateLeft(e, e.vB, currY);\n          } else {\n            if (Delaunay.isRightEdge(e))\n              this.doTriangulateRight(e, e.vB, currY);\n          }\n        }\n\n        currY = v.pt.y;\n      }\n\n      for (let i = v.edges.length - 1; i >= 0; --i) {\n        if (i >= v.edges.length) continue;\n\n        const e = v.edges[i];\n        if (Delaunay.edgeCompleted(e) || Delaunay.isLooseEdge(e)) continue;\n\n        if (v === e.vB) {\n          if (Delaunay.isHorizontal(e))\n            this.horzEdgeStack.push(e);\n\n          if (!v.innerLM)\n            this.addEdgeToActives(e);\n        } else {\n          if (Delaunay.isHorizontal(e))\n            this.horzEdgeStack.push(e);\n          else if (Delaunay.isLeftEdge(e))\n            this.doTriangulateLeft(e, e.vB, v.pt.y);\n          else\n            this.doTriangulateRight(e, e.vB, v.pt.y);\n        }\n      }\n\n      if (v.innerLM)\n        this.locMinStack.push(v);\n    }\n\n    while (this.horzEdgeStack.length > 0) {\n      const e = this.horzEdgeStack.pop()!;\n      if (!Delaunay.edgeCompleted(e) && e.vB === e.vL)\n        this.doTriangulateLeft(e, e.vB, currY);\n    }\n\n    if (this.useDelaunay) {\n      while (this.pendingDelaunayStack.length > 0) {\n        const e = this.pendingDelaunayStack.pop()!;\n        e.pendingDelaunay = false;\n        this.forceLegal(e);\n      }\n    }\n\n    for (const tri of this.allTriangles) {\n      const p = Delaunay.pathFromTriangle(tri);\n      const cps = this.crossProductSign(p[0], p[1], p[2]);\n      if (cps === 0) continue;\n      if (cps < 0) p.reverse();\n      sol.push(p);\n    }\n\n    this.cleanUp();\n    return { result: TriangulateResult.success, solution: sol };\n  }\n\n  private crossProductSign(p1: Point64, p2: Point64, p3: Point64): number {\n    if (this.fastMath) {\n      const prod1 = (p2.x - p1.x) * (p3.y - p2.y);\n      const prod2 = (p2.y - p1.y) * (p3.x - p2.x);\n      return (prod1 > prod2) ? 1 : (prod1 < prod2) ? -1 : 0;\n    }\n    return -adaptiveOrient2dSign(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);\n  }\n\n  private distanceSqr(a: Point64, b: Point64): number {\n    if (!this.fastMath)\n      return Delaunay.distanceSqr(a, b);\n\n    const dx = a.x - b.x;\n    const dy = a.y - b.y;\n    return dx * dx + dy * dy;\n  }\n\n  private shortestDistFromSegment(pt: Point64, segPt1: Point64, segPt2: Point64): number {\n    if (!this.fastMath)\n      return Delaunay.shortestDistFromSegment(pt, segPt1, segPt2);\n\n    const dx = segPt2.x - segPt1.x;\n    const dy = segPt2.y - segPt1.y;\n    const ax = pt.x - segPt1.x;\n    const ay = pt.y - segPt1.y;\n    const qNum = ax * dx + ay * dy;\n    const denom = dx * dx + dy * dy;\n\n    if (qNum < 0) return this.distanceSqr(pt, segPt1);\n    if (qNum > denom) return this.distanceSqr(pt, segPt2);\n\n    const cross = ax * dy - dx * ay;\n    return (cross * cross) / denom;\n  }\n\n  private segsIntersect(s1a: Point64, s1b: Point64, s2a: Point64, s2b: Point64): IntersectKind {\n    if (!this.fastMath)\n      return Delaunay.segsIntersect(s1a, s1b, s2a, s2b);\n\n    // ignore segments sharing an end-point\n    if ((s1a.x === s2a.x && s1a.y === s2a.y) ||\n        (s1a.x === s2b.x && s1a.y === s2b.y) ||\n        (s1b.x === s2b.x && s1b.y === s2b.y)) return IntersectKind.none;\n\n    const dy1 = s1b.y - s1a.y;\n    const dx1 = s1b.x - s1a.x;\n    const dy2 = s2b.y - s2a.y;\n    const dx2 = s2b.x - s2a.x;\n    const dxs = s1a.x - s2a.x;\n    const dys = s1a.y - s2a.y;\n\n    const cp = dy1 * dx2 - dy2 * dx1;\n    if (cp === 0) return IntersectKind.collinear;\n\n    let t = dxs * dy2 - dys * dx2;\n\n    // nb: testing for t === 0 is unreliable due to float imprecision\n    if (t >= 0) {\n      if (cp < 0 || t >= cp) return IntersectKind.none;\n    } else {\n      if (cp > 0 || t <= cp) return IntersectKind.none;\n    }\n\n    t = dxs * dy1 - dys * dx1;\n\n    if (t >= 0) {\n      if (cp > 0 && t < cp) return IntersectKind.intersect;\n    } else {\n      if (cp < 0 && t > cp) return IntersectKind.intersect;\n    }\n\n    return IntersectKind.none;\n  }\n\n  private inCircleTest(ptA: Point64, ptB: Point64, ptC: Point64, ptD: Point64): number {\n    if (this.fastMath) {\n      const ax = ptA.x - ptD.x, ay = ptA.y - ptD.y;\n      const bx = ptB.x - ptD.x, by = ptB.y - ptD.y;\n      const cx = ptC.x - ptD.x, cy = ptC.y - ptD.y;\n      const det = (ax * ax + ay * ay) * (bx * cy - cx * by) +\n                  (bx * bx + by * by) * (cx * ay - ax * cy) +\n                  (cx * cx + cy * cy) * (ax * by - bx * ay);\n      return det > 0 ? 1 : det < 0 ? -1 : 0;\n    }\n    return adaptiveIncircleSign(ptA.x, ptA.y, ptB.x, ptB.y, ptC.x, ptC.y, ptD.x, ptD.y);\n  }\n\n  // ---------------------------------------------------------------------\n  // Static / helper functions\n  // ---------------------------------------------------------------------\n\n  private static isLooseEdge(e: Edge): boolean {\n    return e.kind === EdgeKind.loose;\n  }\n\n  private static isLeftEdge(e: Edge): boolean {\n    return e.kind === EdgeKind.ascend;\n  }\n\n  private static isRightEdge(e: Edge): boolean {\n    return e.kind === EdgeKind.descend;\n  }\n\n  private static isHorizontal(e: Edge): boolean {\n    return e.vB.pt.y === e.vT.pt.y;\n  }\n\n  private leftTurning(p1: Point64, p2: Point64, p3: Point64): boolean {\n    return this.crossProductSign(p1, p2, p3) < 0;\n  }\n\n  private rightTurning(p1: Point64, p2: Point64, p3: Point64): boolean {\n    return this.crossProductSign(p1, p2, p3) > 0;\n  }\n\n  private static edgeCompleted(edge: Edge): boolean {\n    if (edge.triA === null) return false;\n    if (edge.triB !== null) return true;\n    return edge.kind !== EdgeKind.loose;\n  }\n\n  private static edgeContains(edge: Edge, v: Vertex2): EdgeContainsResult {\n    if (edge.vL === v) return EdgeContainsResult.left;\n    if (edge.vR === v) return EdgeContainsResult.right;\n    return EdgeContainsResult.neither;\n  }\n\n  private static getAngle(a: Point64, b: Point64, c: Point64): number {\n    const abx = Number(b.x - a.x);\n    const aby = Number(b.y - a.y);\n    const bcx = Number(b.x - c.x);\n    const bcy = Number(b.y - c.y);\n    const dp = abx * bcx + aby * bcy;\n    const cp = abx * bcy - aby * bcx;\n    return Math.atan2(cp, dp);\n  }\n\n  private static getLocMinAngle(v: Vertex2): number {\n    let asc: number;\n    let des: number;\n    if (v.edges[0].kind === EdgeKind.ascend) {\n      asc = 0;\n      des = 1;\n    } else {\n      des = 0;\n      asc = 1;\n    }\n    return Delaunay.getAngle(v.edges[des].vT.pt, v.pt, v.edges[asc].vT.pt);\n  }\n\n  private static removeEdgeFromVertex(vert: Vertex2, edge: Edge): void {\n    const idx = vert.edges.indexOf(edge);\n    if (idx < 0) throw new Error('Edge not found in vertex');\n    // Swap-with-last-and-pop: O(1) instead of O(n) splice.\n    // Edge order in the array doesn't matter.\n    const last = vert.edges.length - 1;\n    if (idx !== last) vert.edges[idx] = vert.edges[last];\n    vert.edges.pop();\n  }\n\n  private static findLocMinIdx(path: Path64, len: number, idx: number): number {\n    if (len < 3) return -1;\n    const i0 = idx;\n    let n = (idx + 1) % len;\n\n    while (path[n].y <= path[idx].y) {\n      idx = n;\n      n = (n + 1) % len;\n      if (idx === i0) return -1;\n    }\n\n    while (path[n].y >= path[idx].y) {\n      idx = n;\n      n = (n + 1) % len;\n    }\n\n    return idx;\n  }\n\n  private static prev(idx: number, len: number): number {\n    if (idx === 0) return len - 1;\n    return idx - 1;\n  }\n\n  private static next(idx: number, len: number): number {\n    return (idx + 1) % len;\n  }\n\n  private static findLinkingEdge(vert1: Vertex2, vert2: Vertex2, preferAscending: boolean): Edge | null {\n    let res: Edge | null = null;\n    for (const e of vert1.edges) {\n      if (e.vL === vert2 || e.vR === vert2) {\n        if (e.kind === EdgeKind.loose ||\n          ((e.kind === EdgeKind.ascend) === preferAscending))\n          return e;\n        res = e;\n      }\n    }\n    return res;\n  }\n\n  private static pathFromTriangle(tri: Triangle): Path64 {\n    const res: Path64 = [\n      tri.edges[0].vL.pt,\n      tri.edges[0].vR.pt\n    ];\n    const e = tri.edges[1];\n    if ((e.vL.pt.x === res[0].x && e.vL.pt.y === res[0].y) ||\n      (e.vL.pt.x === res[1].x && e.vL.pt.y === res[1].y))\n      res.push(e.vR.pt);\n    else\n      res.push(e.vL.pt);\n    return res;\n  }\n\n  private static readonly maxSafeDelta = Math.floor(Math.sqrt(Number.MAX_SAFE_INTEGER / 2));\n\n  private static shortestDistFromSegment(pt: Point64, segPt1: Point64, segPt2: Point64): number {\n    const dx = segPt2.x - segPt1.x;\n    const dy = segPt2.y - segPt1.y;\n    const ax = pt.x - segPt1.x;\n    const ay = pt.y - segPt1.y;\n\n    const msd = Delaunay.maxSafeDelta;\n    if (Math.abs(dx) <= msd && Math.abs(dy) <= msd && Math.abs(ax) <= msd && Math.abs(ay) <= msd) {\n      const qNum = ax * dx + ay * dy;\n      const denom = dx * dx + dy * dy;\n      if (qNum < 0) return Delaunay.distanceSqr(pt, segPt1);\n      if (qNum > denom) return Delaunay.distanceSqr(pt, segPt2);\n      return (ax * dy - dx * ay) * (ax * dy - dx * ay) / denom;\n    }\n\n    const dxB = BigInt(segPt2.x) - BigInt(segPt1.x);\n    const dyB = BigInt(segPt2.y) - BigInt(segPt1.y);\n    const axB = BigInt(pt.x) - BigInt(segPt1.x);\n    const ayB = BigInt(pt.y) - BigInt(segPt1.y);\n    const qNum = axB * dxB + ayB * dyB;\n    const denom = dxB * dxB + dyB * dyB;\n    const B0 = BigInt(0);\n\n    if (qNum < B0) return Delaunay.distanceSqr(pt, segPt1);\n    if (qNum > denom) return Delaunay.distanceSqr(pt, segPt2);\n\n    const cross = axB * dyB - dxB * ayB;\n    return Number(cross * cross) / Number(denom);\n  }\n\n  private static segsIntersect(s1a: Point64, s1b: Point64, s2a: Point64, s2b: Point64): IntersectKind {\n    if ((s1a.x === s2a.x && s1a.y === s2a.y) ||\n        (s1a.x === s2b.x && s1a.y === s2b.y) ||\n        (s1b.x === s2b.x && s1b.y === s2b.y)) return IntersectKind.none;\n\n    const d1 = adaptiveOrient2dSign(s2a.x, s2a.y, s2b.x, s2b.y, s1a.x, s1a.y);\n    const d2 = adaptiveOrient2dSign(s2a.x, s2a.y, s2b.x, s2b.y, s1b.x, s1b.y);\n\n    if (d1 === 0 && d2 === 0) return IntersectKind.collinear;\n    if (d1 === 0 || d2 === 0 || d1 === d2) return IntersectKind.none;\n\n    const d3 = adaptiveOrient2dSign(s1a.x, s1a.y, s1b.x, s1b.y, s2a.x, s2a.y);\n    const d4 = adaptiveOrient2dSign(s1a.x, s1a.y, s1b.x, s1b.y, s2b.x, s2b.y);\n\n    if (d3 === 0 || d4 === 0 || d3 === d4) return IntersectKind.none;\n\n    return IntersectKind.intersect;\n  }\n\n  private static distanceSqr(a: Point64, b: Point64): number {\n    const dx = a.x - b.x;\n    const dy = a.y - b.y;\n\n    const msd = Delaunay.maxSafeDelta;\n    if (Math.abs(dx) <= msd && Math.abs(dy) <= msd) {\n      const dist = dx * dx + dy * dy;\n      if (dist <= Number.MAX_SAFE_INTEGER) return dist;\n    }\n\n    const dxB = BigInt(a.x) - BigInt(b.x);\n    const dyB = BigInt(a.y) - BigInt(b.y);\n    return Number(dxB * dxB + dyB * dyB);\n  }\n}\n","/*******************************************************************************\n* Author    :  Angus Johnson                                                   *\n* Date      :  5 March 2025                                                    *\n* Website   :  https://www.angusj.com                                          *\n* Copyright :  Angus Johnson 2010-2025                                         *\n* Purpose   :  This module contains simple functions that will likely cover    *\n*              most polygon boolean and offsetting needs, while also avoiding  *\n*              the inherent complexities of the other modules.                 *\n* License   :  https://www.boost.org/LICENSE_1_0.txt                           *\n*******************************************************************************/\n\nimport {\n  Point64, PointD, Path64, PathD, Paths64, PathsD, Rect64, RectD,\n  ClipType, PathType, FillRule, PointInPolygonResult,\n  InternalClipper, Point64Utils, PointDUtils, Rect64Utils, RectDUtils,\n  InvalidRect64, InvalidRectD\n} from './Core.js';\nimport { Clipper64, ClipperD, PolyTree64, PolyTreeD, PolyPathD } from './Engine.js';\nimport { ClipperOffset, JoinType, EndType } from './Offset.js';\nimport { RectClip64, RectClipLines64 } from './RectClip.js';\nimport { Minkowski } from './Minkowski.js';\nimport { Delaunay, TriangulateResult } from './Triangulation.js';\n\n// BigInt constant — avoid BigInt literal syntax (0n) to sidestep\n// terser BigInt constant-folding issues in some consuming build setups.\nconst B2 = BigInt(2);\n\n// Constants\nexport const invalidRect64 = InvalidRect64;\nexport const invalidRectD = InvalidRectD;\n\n// Boolean operations\nexport function intersect(subject: Paths64, clip: Paths64, fillRule: FillRule): Paths64 {\n  return booleanOp(ClipType.Intersection, subject, clip, fillRule);\n}\n\nexport function intersectD(subject: PathsD, clip: PathsD, fillRule: FillRule, precision: number = 2): PathsD {\n  return booleanOpD(ClipType.Intersection, subject, clip, fillRule, precision);\n}\n\nexport function union(subject: Paths64, fillRule: FillRule): Paths64;\nexport function union(subject: Paths64, clip: Paths64, fillRule: FillRule): Paths64;\nexport function union(subject: Paths64, clipOrFillRule: Paths64 | FillRule, fillRule?: FillRule): Paths64 {\n  if (typeof clipOrFillRule === 'number') {\n    // First overload: union(subject, fillRule)\n    return booleanOp(ClipType.Union, subject, null, clipOrFillRule);\n  } else {\n    // Second overload: union(subject, clip, fillRule)\n    return booleanOp(ClipType.Union, subject, clipOrFillRule, fillRule!);\n  }\n}\n\nexport function unionD(subject: PathsD, fillRule: FillRule): PathsD;\nexport function unionD(subject: PathsD, clip: PathsD, fillRule: FillRule, precision?: number): PathsD;\nexport function unionD(subject: PathsD, clipOrFillRule: PathsD | FillRule, fillRuleOrPrecision?: FillRule | number, precision?: number): PathsD {\n  if (typeof clipOrFillRule === 'number') {\n    // First overload: unionD(subject, fillRule)\n    return booleanOpD(ClipType.Union, subject, null, clipOrFillRule);\n  } else {\n    // Second overload: unionD(subject, clip, fillRule, precision)\n    return booleanOpD(ClipType.Union, subject, clipOrFillRule, fillRuleOrPrecision as FillRule, precision || 2);\n  }\n}\n\nexport function difference(subject: Paths64, clip: Paths64, fillRule: FillRule): Paths64 {\n  return booleanOp(ClipType.Difference, subject, clip, fillRule);\n}\n\nexport function differenceD(subject: PathsD, clip: PathsD, fillRule: FillRule, precision: number = 2): PathsD {\n  return booleanOpD(ClipType.Difference, subject, clip, fillRule, precision);\n}\n\nexport function xor(subject: Paths64, clip: Paths64, fillRule: FillRule): Paths64 {\n  return booleanOp(ClipType.Xor, subject, clip, fillRule);\n}\n\nexport function xorD(subject: PathsD, clip: PathsD, fillRule: FillRule, precision: number = 2): PathsD {\n  return booleanOpD(ClipType.Xor, subject, clip, fillRule, precision);\n}\n\nexport function booleanOp(clipType: ClipType, subject: Paths64 | null, clip: Paths64 | null, fillRule: FillRule): Paths64 {\n  const solution: Paths64 = [];\n  if (subject === null) return solution;\n  const c = new Clipper64();\n  c.addPaths(subject, PathType.Subject);\n  if (clip !== null) {\n    c.addPaths(clip, PathType.Clip);\n  }\n  c.execute(clipType, fillRule, solution);\n  return solution;\n}\n\nexport function booleanOpWithPolyTree(clipType: ClipType, subject: Paths64 | null, clip: Paths64 | null, polytree: PolyTree64, fillRule: FillRule): void {\n  if (subject === null) return;\n  const c = new Clipper64();\n  c.addPaths(subject, PathType.Subject);\n  if (clip !== null) {\n    c.addPaths(clip, PathType.Clip);\n  }\n  c.execute(clipType, fillRule, polytree);\n}\n\nexport function booleanOpD(clipType: ClipType, subject: PathsD, clip: PathsD | null, fillRule: FillRule, precision: number = 2): PathsD {\n  const solution: PathsD = [];\n  const c = new ClipperD(precision);\n  c.addSubjectPaths(subject);\n  if (clip !== null) {\n    c.addClipPaths(clip);\n  }\n  c.execute(clipType, fillRule, solution);\n  return solution;\n}\n\nexport function booleanOpDWithPolyTree(\n  clipType: ClipType,\n  subject: PathsD | null,\n  clip: PathsD | null,\n  polytree: PolyTreeD,\n  fillRule: FillRule,\n  precision: number = 2\n): void {\n  if (subject === null) return;\n  const c = new ClipperD(precision);\n  c.addSubjectPaths(subject);\n  if (clip !== null) {\n    c.addClipPaths(clip);\n  }\n  c.execute(clipType, fillRule, polytree);\n}\n\nexport function inflatePaths(paths: Paths64, delta: number, joinType: JoinType, endType: EndType, miterLimit: number = 2.0, arcTolerance: number = 0.0): Paths64 {\n  const co = new ClipperOffset(miterLimit, arcTolerance);\n  co.addPaths(paths, joinType, endType);\n  const solution: Paths64 = [];\n  co.execute(delta, solution);\n  return solution;\n}\n\nexport function inflatePathsD(paths: PathsD, delta: number, joinType: JoinType, endType: EndType, miterLimit: number = 2.0, precision: number = 2, arcTolerance: number = 0.0): PathsD {\n  InternalClipper.checkPrecision(precision);\n  const scale = Math.pow(10, precision);\n  const tmp = scalePaths64(paths, scale);\n  const co = new ClipperOffset(miterLimit, scale * arcTolerance);\n  co.addPaths(tmp, joinType, endType);\n  const solution: Paths64 = [];\n  co.execute(delta * scale, solution); // reuse solution to receive (scaled) solution\n  return scalePathsD(solution, 1 / scale);\n}\n\nexport function rectClip(rect: Rect64, paths: Paths64): Paths64;\nexport function rectClip(rect: Rect64, path: Path64): Paths64;\nexport function rectClip(rect: RectD, paths: PathsD, precision?: number): PathsD;\nexport function rectClip(rect: RectD, path: PathD, precision?: number): PathsD;\nexport function rectClip(rect: Rect64 | RectD, pathsOrPath: Paths64 | Path64 | PathsD | PathD, precision?: number): Paths64 | PathsD {\n  if ('left' in rect && typeof rect.left === 'number' && Number.isInteger(rect.left)) {\n    // Rect64 case\n    const rect64 = rect as Rect64;\n    if (Rect64Utils.isEmpty(rect64)) return [];\n    \n    if (Array.isArray(pathsOrPath[0])) {\n      // Paths64\n      const paths = pathsOrPath as Paths64;\n      if (paths.length === 0) return [];\n      const rc = new RectClip64(rect64);\n      return rc.execute(paths);\n    } else {\n      // Path64\n      const path = pathsOrPath as Path64;\n      if (path.length === 0) return [];\n      const tmp: Paths64 = [path];\n      return rectClip(rect64, tmp);\n    }\n  } else {\n    // RectD case\n    const rectD = rect as RectD;\n    const prec = precision || 2;\n    InternalClipper.checkPrecision(prec);\n    if (RectDUtils.isEmpty(rectD)) return [];\n    \n    const scale = Math.pow(10, prec);\n    const r = scaleRect(rectD, scale);\n    \n    if (Array.isArray(pathsOrPath[0])) {\n      // PathsD\n      const paths = pathsOrPath as PathsD;\n      if (paths.length === 0) return [];\n      const tmpPath = scalePaths64(paths, scale);\n      const rc = new RectClip64(r);\n      const result = rc.execute(tmpPath);\n      return scalePathsD(result, 1 / scale);\n    } else {\n      // PathD\n      const path = pathsOrPath as PathD;\n      if (path.length === 0) return [];\n      const tmp: PathsD = [path];\n      return rectClip(rectD, tmp, prec);\n    }\n  }\n}\n\nexport function rectClipLines(rect: Rect64, paths: Paths64): Paths64;\nexport function rectClipLines(rect: Rect64, path: Path64): Paths64;\nexport function rectClipLines(rect: RectD, paths: PathsD, precision?: number): PathsD;\nexport function rectClipLines(rect: RectD, path: PathD, precision?: number): PathsD;\nexport function rectClipLines(rect: Rect64 | RectD, pathsOrPath: Paths64 | Path64 | PathsD | PathD, precision?: number): Paths64 | PathsD {\n  if ('left' in rect && typeof rect.left === 'number' && Number.isInteger(rect.left)) {\n    // Rect64 case\n    const rect64 = rect as Rect64;\n    if (Rect64Utils.isEmpty(rect64)) return [];\n    \n    if (Array.isArray(pathsOrPath[0])) {\n      // Paths64\n      const paths = pathsOrPath as Paths64;\n      if (paths.length === 0) return [];\n      const rc = new RectClipLines64(rect64);\n      return rc.execute(paths);\n    } else {\n      // Path64\n      const path = pathsOrPath as Path64;\n      if (path.length === 0) return [];\n      const tmp: Paths64 = [path];\n      return rectClipLines(rect64, tmp);\n    }\n  } else {\n    // RectD case\n    const rectD = rect as RectD;\n    const prec = precision || 2;\n    InternalClipper.checkPrecision(prec);\n    if (RectDUtils.isEmpty(rectD)) return [];\n    \n    const scale = Math.pow(10, prec);\n    const r = scaleRect(rectD, scale);\n    \n    if (Array.isArray(pathsOrPath[0])) {\n      // PathsD\n      const paths = pathsOrPath as PathsD;\n      if (paths.length === 0) return [];\n      const tmpPath = scalePaths64(paths, scale);\n      const rc = new RectClipLines64(r);\n      const result = rc.execute(tmpPath);\n      return scalePathsD(result, 1 / scale);\n    } else {\n      // PathD\n      const path = pathsOrPath as PathD;\n      if (path.length === 0) return [];\n      const tmp: PathsD = [path];\n      return rectClipLines(rectD, tmp, prec);\n    }\n  }\n}\n\nexport function minkowskiSum(pattern: Path64, path: Path64, isClosed: boolean): Paths64 {\n  return Minkowski.sum(pattern, path, isClosed);\n}\n\nexport function minkowskiSumD(pattern: PathD, path: PathD, isClosed: boolean): PathsD {\n  return Minkowski.sumD(pattern, path, isClosed);\n}\n\nexport function minkowskiDiff(pattern: Path64, path: Path64, isClosed: boolean): Paths64 {\n  return Minkowski.diff(pattern, path, isClosed);\n}\n\nexport function minkowskiDiffD(pattern: PathD, path: PathD, isClosed: boolean): PathsD {\n  return Minkowski.diffD(pattern, path, isClosed);\n}\n\nexport function area(path: Path64): number {\n  return InternalClipper.area(path);\n}\n\nexport function areaPaths(paths: Paths64): number {\n  let a = 0.0;\n  for (const path of paths) {\n    a += area(path);\n  }\n  return a;\n}\n\nexport function areaD(path: PathD): number {\n  let a = 0.0;\n  const cnt = path.length;\n  if (cnt < 3) return 0.0;\n  let prevPt = path[cnt - 1];\n  for (const pt of path) {\n    a += (prevPt.y + pt.y) * (prevPt.x - pt.x);\n    prevPt = pt;\n  }\n  return a * 0.5;\n}\n\nexport function areaPathsD(paths: PathsD): number {\n  let a = 0.0;\n  for (const path of paths) {\n    a += areaD(path);\n  }\n  return a;\n}\n\nexport function isPositive(poly: Path64): boolean {\n  return area(poly) >= 0;\n}\n\nexport function isPositiveD(poly: PathD): boolean {\n  return areaD(poly) >= 0;\n}\n\nexport function path64ToString(path: Path64): string {\n  let result = \"\";\n  for (const pt of path) {\n    result += Point64Utils.toString(pt);\n  }\n  return result + '\\n';\n}\n\nexport function paths64ToString(paths: Paths64): string {\n  let result = \"\";\n  for (const path of paths) {\n    result += path64ToString(path);\n  }\n  return result;\n}\n\nexport function pathDToString(path: PathD, precision: number = 2): string {\n  let result = \"\";\n  for (const pt of path) {\n    result += PointDUtils.toString(pt, precision);\n  }\n  return result + '\\n';\n}\n\nexport function pathsDToString(paths: PathsD, precision: number = 2): string {\n  let result = \"\";\n  for (const path of paths) {\n    result += pathDToString(path, precision);\n  }\n  return result;\n}\n\nexport function offsetPath(path: Path64, dx: number, dy: number): Path64 {\n  const result: Path64 = [];\n  for (const pt of path) {\n    result.push({ x: pt.x + dx, y: pt.y + dy });\n  }\n  return result;\n}\n\nexport function scalePoint64(pt: Point64, scale: number): Point64 {\n  return {\n    x: Math.round(pt.x * scale),\n    y: Math.round(pt.y * scale)\n  };\n}\n\nexport function scalePointD(pt: Point64, scale: number): PointD {\n  return {\n    x: pt.x * scale,\n    y: pt.y * scale\n  };\n}\n\nexport function scaleRect(rec: RectD, scale: number): Rect64 {\n  const maxAbs = InternalClipper.maxSafeCoordinateForScale(scale);\n  InternalClipper.checkSafeScaleValue(rec.left, maxAbs, \"scaleRect\");\n  InternalClipper.checkSafeScaleValue(rec.top, maxAbs, \"scaleRect\");\n  InternalClipper.checkSafeScaleValue(rec.right, maxAbs, \"scaleRect\");\n  InternalClipper.checkSafeScaleValue(rec.bottom, maxAbs, \"scaleRect\");\n  return {\n    left: Math.round(rec.left * scale),\n    top: Math.round(rec.top * scale),\n    right: Math.round(rec.right * scale),\n    bottom: Math.round(rec.bottom * scale)\n  };\n}\n\nexport function scalePath(path: Path64, scale: number): Path64 {\n  if (InternalClipper.isAlmostZero(scale - 1)) return path;\n  const result: Path64 = [];\n  for (const pt of path) {\n    result.push({\n      x: Math.round(pt.x * scale),\n      y: Math.round(pt.y * scale)\n    });\n  }\n  return result;\n}\n\nexport function scalePaths(paths: Paths64, scale: number): Paths64 {\n  if (InternalClipper.isAlmostZero(scale - 1)) return paths;\n  const result: Paths64 = [];\n  for (const path of paths) {\n    result.push(scalePath(path, scale));\n  }\n  return result;\n}\n\nexport function scalePathD(path: PathD, scale: number): PathD {\n  if (InternalClipper.isAlmostZero(scale - 1)) return path;\n  const result: PathD = [];\n  for (const pt of path) {\n    result.push(PointDUtils.scale(pt, scale));\n  }\n  return result;\n}\n\nexport function scalePathsD(paths: PathsD, scale: number): PathsD {\n  if (InternalClipper.isAlmostZero(scale - 1)) return paths;\n  const result: PathsD = [];\n  for (const path of paths) {\n    result.push(scalePathD(path, scale));\n  }\n  return result;\n}\n\n// Unlike ScalePath, both ScalePath64 & ScalePathD also involve type conversion\nexport function scalePath64(path: PathD, scale: number): Path64 {\n  const maxAbs = InternalClipper.maxSafeCoordinateForScale(scale);\n  const result: Path64 = [];\n  for (const pt of path) {\n    InternalClipper.checkSafeScaleValue(pt.x, maxAbs, \"scalePath64\");\n    InternalClipper.checkSafeScaleValue(pt.y, maxAbs, \"scalePath64\");\n    result.push({\n      x: Math.round(pt.x * scale),\n      y: Math.round(pt.y * scale)\n    });\n  }\n  return result;\n}\n\nexport function scalePaths64(paths: PathsD, scale: number): Paths64 {\n  const result: Paths64 = [];\n  for (const path of paths) {\n    result.push(scalePath64(path, scale));\n  }\n  return result;\n}\n\nexport function scalePathDFromInt(path: Path64, scale: number): PathD {\n  const result: PathD = [];\n  for (const pt of path) {\n    result.push({\n      x: pt.x * scale,\n      y: pt.y * scale\n    });\n  }\n  return result;\n}\n\nexport function scalePathsDFromInt(paths: Paths64, scale: number): PathsD {\n  const result: PathsD = [];\n  for (const path of paths) {\n    result.push(scalePathDFromInt(path, scale));\n  }\n  return result;\n}\n\n// The static functions Path64 and PathD convert path types without scaling\nexport function path64FromD(path: PathD): Path64 {\n  const result: Path64 = [];\n  for (const pt of path) {\n    result.push(Point64Utils.fromPointD(pt));\n  }\n  return result;\n}\n\nexport function paths64FromD(paths: PathsD): Paths64 {\n  const result: Paths64 = [];\n  for (const path of paths) {\n    result.push(path64FromD(path));\n  }\n  return result;\n}\n\nexport function pathsD(paths: Paths64): PathsD {\n  const result: PathsD = [];\n  for (const path of paths) {\n    result.push(pathD(path));\n  }\n  return result;\n}\n\nexport function pathD(path: Path64): PathD {\n  const result: PathD = [];\n  for (const pt of path) {\n    result.push(PointDUtils.fromPoint64(pt));\n  }\n  return result;\n}\n\nexport function translatePath(path: Path64, dx: number, dy: number): Path64 {\n  const result: Path64 = [];\n  for (const pt of path) {\n    result.push({ x: pt.x + dx, y: pt.y + dy });\n  }\n  return result;\n}\n\nexport function translatePaths(paths: Paths64, dx: number, dy: number): Paths64 {\n  const result: Paths64 = [];\n  for (const path of paths) {\n    result.push(offsetPath(path, dx, dy));\n  }\n  return result;\n}\n\nexport function translatePathD(path: PathD, dx: number, dy: number): PathD {\n  const result: PathD = [];\n  for (const pt of path) {\n    result.push({ x: pt.x + dx, y: pt.y + dy });\n  }\n  return result;\n}\n\nexport function translatePathsD(paths: PathsD, dx: number, dy: number): PathsD {\n  const result: PathsD = [];\n  for (const path of paths) {\n    result.push(translatePathD(path, dx, dy));\n  }\n  return result;\n}\n\nexport function reversePath(path: Path64): Path64 {\n  return [...path].reverse();\n}\n\nexport function reversePathD(path: PathD): PathD {\n  return [...path].reverse();\n}\n\nexport function reversePaths(paths: Paths64): Paths64 {\n  const result: Paths64 = [];\n  for (const path of paths) {\n    result.push(reversePath(path));\n  }\n  return result;\n}\n\nexport function reversePathsD(paths: PathsD): PathsD {\n  const result: PathsD = [];\n  for (const path of paths) {\n    result.push(reversePathD(path));\n  }\n  return result;\n}\n\nexport function getBounds(path: Path64): Rect64 {\n  return InternalClipper.getBounds(path);\n}\n\nexport function getBoundsPaths(paths: Paths64): Rect64 {\n  const result = Rect64Utils.createInvalid();\n  for (const path of paths) {\n    for (const pt of path) {\n      if (pt.x < result.left) result.left = pt.x;\n      if (pt.x > result.right) result.right = pt.x;\n      if (pt.y < result.top) result.top = pt.y;\n      if (pt.y > result.bottom) result.bottom = pt.y;\n    }\n  }\n  return result.left === Number.MAX_SAFE_INTEGER ? { left: 0, top: 0, right: 0, bottom: 0 } : result;\n}\n\nexport function getBoundsD(path: PathD): RectD {\n  const result = RectDUtils.createInvalid();\n  for (const pt of path) {\n    if (pt.x < result.left) result.left = pt.x;\n    if (pt.x > result.right) result.right = pt.x;\n    if (pt.y < result.top) result.top = pt.y;\n    if (pt.y > result.bottom) result.bottom = pt.y;\n  }\n  return Math.abs(result.left - Number.MAX_VALUE) < InternalClipper.floatingPointTolerance ? \n    { left: 0, top: 0, right: 0, bottom: 0 } : result;\n}\n\nexport function getBoundsPathsD(paths: PathsD): RectD {\n  const result = RectDUtils.createInvalid();\n  for (const path of paths) {\n    for (const pt of path) {\n      if (pt.x < result.left) result.left = pt.x;\n      if (pt.x > result.right) result.right = pt.x;\n      if (pt.y < result.top) result.top = pt.y;\n      if (pt.y > result.bottom) result.bottom = pt.y;\n    }\n  }\n  return Math.abs(result.left - Number.MAX_VALUE) < InternalClipper.floatingPointTolerance ? \n    { left: 0, top: 0, right: 0, bottom: 0 } : result;\n}\n\nexport function makePath(arr: number[]): Path64 {\n  const len = Math.floor(arr.length / 2);\n  const p: Path64 = [];\n  for (let i = 0; i < len; i++) {\n    p.push({ x: arr[i * 2], y: arr[i * 2 + 1], z: 0 });\n  }\n  return p;\n}\n\nexport function makePathD(arr: number[]): PathD {\n  const len = Math.floor(arr.length / 2);\n  const p: PathD = [];\n  for (let i = 0; i < len; i++) {\n    p.push({ x: arr[i * 2], y: arr[i * 2 + 1], z: 0 });\n  }\n  return p;\n}\n\nexport function sqr(val: number): number {\n  return val * val;\n}\n\nexport function distanceSqr(pt1: Point64, pt2: Point64): number {\n  const dx = pt1.x - pt2.x;\n  const dy = pt1.y - pt2.y;\n  \n  if (Number.isSafeInteger(dx) && Number.isSafeInteger(dy)) {\n    const dxAbs = Math.abs(dx);\n    const dyAbs = Math.abs(dy);\n    const maxDelta = InternalClipper.maxCoordForSafeAreaProduct * 2; // maxDeltaForSafeProduct\n    if (dxAbs <= maxDelta && dyAbs <= maxDelta) {\n      const dist = dx * dx + dy * dy;\n      if (dist <= Number.MAX_SAFE_INTEGER) return dist;\n    }\n    const dxSq = BigInt(dx) * BigInt(dx);\n    const dySq = BigInt(dy) * BigInt(dy);\n    return Number(dxSq + dySq);\n  }\n  return sqr(dx) + sqr(dy);\n}\n\nexport function midPoint(pt1: Point64, pt2: Point64): Point64 {\n  if (Number.isSafeInteger(pt1.x) && Number.isSafeInteger(pt2.x) &&\n      Number.isSafeInteger(pt1.y) && Number.isSafeInteger(pt2.y) &&\n      (Math.abs(pt1.x) + Math.abs(pt2.x) > Number.MAX_SAFE_INTEGER ||\n       Math.abs(pt1.y) + Math.abs(pt2.y) > Number.MAX_SAFE_INTEGER)) {\n    return { \n      x: Number((BigInt(pt1.x) + BigInt(pt2.x)) / B2),\n      y: Number((BigInt(pt1.y) + BigInt(pt2.y)) / B2)\n    };\n  }\n  return { x: Math.round((pt1.x + pt2.x) / 2), y: Math.round((pt1.y + pt2.y) / 2) };\n}\n\nexport function midPointD(pt1: PointD, pt2: PointD): PointD {\n  return { x: (pt1.x + pt2.x) / 2, y: (pt1.y + pt2.y) / 2 };\n}\n\nexport function inflateRect(rec: Rect64, dx: number, dy: number): void {\n  rec.left -= dx;\n  rec.right += dx;\n  rec.top -= dy;\n  rec.bottom += dy;\n}\n\nexport function inflateRectD(rec: RectD, dx: number, dy: number): void {\n  rec.left -= dx;\n  rec.right += dx;\n  rec.top -= dy;\n  rec.bottom += dy;\n}\n\nexport function pointsNearEqual(pt1: PointD, pt2: PointD, distanceSqrd: number): boolean {\n  return sqr(pt1.x - pt2.x) + sqr(pt1.y - pt2.y) < distanceSqrd;\n}\n\nexport function stripNearDuplicates(path: PathD, minEdgeLenSqrd: number, isClosedPath: boolean): PathD {\n  const cnt = path.length;\n  const result: PathD = [];\n  if (cnt === 0) return result;\n  \n  let lastPt = path[0];\n  result.push(lastPt);\n  for (let i = 1; i < cnt; i++) {\n    if (!pointsNearEqual(lastPt, path[i], minEdgeLenSqrd)) {\n      lastPt = path[i];\n      result.push(lastPt);\n    }\n  }\n\n  if (isClosedPath && pointsNearEqual(lastPt, result[0], minEdgeLenSqrd)) {\n    result.pop();\n  }\n\n  return result;\n}\n\nexport function stripDuplicates(path: Path64, isClosedPath: boolean): Path64 {\n  const cnt = path.length;\n  const result: Path64 = [];\n  if (cnt === 0) return result;\n  \n  let lastPt = path[0];\n  result.push(lastPt);\n  for (let i = 1; i < cnt; i++) {\n    if (!Point64Utils.equals(lastPt, path[i])) {\n      lastPt = path[i];\n      result.push(lastPt);\n    }\n  }\n  if (isClosedPath && Point64Utils.equals(lastPt, result[0])) {\n    result.pop();\n  }\n  return result;\n}\n\nfunction addPolyNodeToPaths(polyPath: PolyTree64, paths: Paths64): void {\n  if (polyPath.poly && polyPath.poly.length > 0) {\n    paths.push(polyPath.poly);\n  }\n  for (let i = 0; i < polyPath.count; i++) {\n    addPolyNodeToPaths(polyPath.child(i), paths);\n  }\n}\n\nexport function polyTreeToPaths64(polyTree: PolyTree64): Paths64 {\n  const result: Paths64 = [];\n  for (let i = 0; i < polyTree.count; i++) {\n    addPolyNodeToPaths(polyTree.child(i), result);\n  }\n  return result;\n}\n\nexport function addPolyNodeToPathsD(polyPath: PolyPathD, paths: PathsD): void {\n  if (polyPath.poly && polyPath.poly.length > 0) {\n    paths.push(polyPath.poly);\n  }\n  for (let i = 0; i < polyPath.count; i++) {\n    addPolyNodeToPathsD(polyPath.child(i), paths);\n  }\n}\n\nexport function polyTreeToPathsD(polyTree: PolyTreeD): PathsD {\n  const result: PathsD = [];\n  for (let i = 0; i < polyTree.count; i++) {\n    addPolyNodeToPathsD(polyTree.child(i), result);\n  }\n  return result;\n}\n\nexport function perpendicDistFromLineSqrd(pt: PointD, line1: PointD, line2: PointD): number {\n  const a = pt.x - line1.x;\n  const b = pt.y - line1.y;\n  const c = line2.x - line1.x;\n  const d = line2.y - line1.y;\n  if (c === 0 && d === 0) return 0;\n  return sqr(a * d - c * b) / (c * c + d * d);\n}\n\nexport function perpendicDistFromLineSqrd64(pt: Point64, line1: Point64, line2: Point64): number {\n  const a = pt.x - line1.x;\n  const b = pt.y - line1.y;\n  const c = line2.x - line1.x;\n  const d = line2.y - line1.y;\n  if (c === 0 && d === 0) return 0;\n  \n  if (Number.isSafeInteger(a) && Number.isSafeInteger(b) &&\n      Number.isSafeInteger(c) && Number.isSafeInteger(d)) {\n    const cross = (BigInt(a) * BigInt(d)) - (BigInt(c) * BigInt(b));\n    const crossSq = cross * cross;\n    const denom = (BigInt(c) * BigInt(c)) + (BigInt(d) * BigInt(d));\n    return Number(crossSq) / Number(denom);\n  }\n\n  const cross = InternalClipper.crossProduct(line1, pt, line2);\n  return sqr(cross) / (c * c + d * d);\n}\n\nfunction rdp(path: Path64, begin: number, end: number, epsSqrd: number, flags: boolean[]): void {\n  while (true) {\n    let idx = 0;\n    let maxD = 0;\n    while (end > begin && Point64Utils.equals(path[begin], path[end])) flags[end--] = false;\n    for (let i = begin + 1; i < end; ++i) {\n      // PerpendicDistFromLineSqrd - avoids expensive Sqrt()\n      const d = perpendicDistFromLineSqrd64(path[i], path[begin], path[end]);\n      if (d <= maxD) continue;\n      maxD = d;\n      idx = i;\n    }\n\n    if (maxD <= epsSqrd) return;\n    flags[idx] = true;\n    if (idx > begin + 1) rdp(path, begin, idx, epsSqrd, flags);\n    if (idx < end - 1) {\n      begin = idx;\n      continue;\n    }\n    break;\n  }\n}\n\nexport function ramerDouglasPeucker(path: Path64, epsilon: number): Path64 {\n  const len = path.length;\n  if (len < 5) return path;\n  const flags = new Array(len).fill(false);\n  flags[0] = true;\n  flags[len - 1] = true;\n  rdp(path, 0, len - 1, sqr(epsilon), flags);\n  const result: Path64 = [];\n  for (let i = 0; i < len; ++i) {\n    if (flags[i]) result.push(path[i]);\n  }\n  return result;\n}\n\nexport function ramerDouglasPeuckerPaths(paths: Paths64, epsilon: number): Paths64 {\n  const result: Paths64 = [];\n  for (const path of paths) {\n    result.push(ramerDouglasPeucker(path, epsilon));\n  }\n  return result;\n}\n\nfunction rdpD(path: PathD, begin: number, end: number, epsSqrd: number, flags: boolean[]): void {\n  while (true) {\n    let idx = 0;\n    let maxD = 0;\n    while (end > begin && PointDUtils.equals(path[begin], path[end])) flags[end--] = false;\n    for (let i = begin + 1; i < end; ++i) {\n      // PerpendicDistFromLineSqrd - avoids expensive Sqrt()\n      const d = perpendicDistFromLineSqrd(path[i], path[begin], path[end]);\n      if (d <= maxD) continue;\n      maxD = d;\n      idx = i;\n    }\n\n    if (maxD <= epsSqrd) return;\n    flags[idx] = true;\n    if (idx > begin + 1) rdpD(path, begin, idx, epsSqrd, flags);\n    if (idx < end - 1) {\n      begin = idx;\n      continue;\n    }\n    break;\n  }\n}\n\nexport function ramerDouglasPeuckerD(path: PathD, epsilon: number): PathD {\n  const len = path.length;\n  if (len < 5) return path;\n  const flags = new Array(len).fill(false);\n  flags[0] = true;\n  flags[len - 1] = true;\n  rdpD(path, 0, len - 1, sqr(epsilon), flags);\n  const result: PathD = [];\n  for (let i = 0; i < len; ++i) {\n    if (flags[i]) result.push(path[i]);\n  }\n  return result;\n}\n\nexport function ramerDouglasPeuckerPathsD(paths: PathsD, epsilon: number): PathsD {\n  const result: PathsD = [];\n  for (const path of paths) {\n    result.push(ramerDouglasPeuckerD(path, epsilon));\n  }\n  return result;\n}\n\nfunction getNext(current: number, high: number, flags: boolean[]): number {\n  ++current;\n  while (current <= high && flags[current]) ++current;\n  if (current <= high) return current;\n  current = 0;\n  while (flags[current]) ++current;\n  return current;\n}\n\nfunction getPrior(current: number, high: number, flags: boolean[]): number {\n  if (current === 0) current = high;\n  else --current;\n  while (current > 0 && flags[current]) --current;\n  if (!flags[current]) return current;\n  current = high;\n  while (flags[current]) --current;\n  return current;\n}\n\nexport function simplifyPath(path: Path64, epsilon: number, isClosedPath: boolean = true): Path64 {\n  const len = path.length;\n  const high = len - 1;\n  const epsSqr = sqr(epsilon);\n  if (len < 4) return path;\n\n  const flags = new Array(len).fill(false);\n  const dsq = new Array(len).fill(0);\n  let curr = 0;\n\n  if (isClosedPath) {\n    dsq[0] = perpendicDistFromLineSqrd64(path[0], path[high], path[1]);\n    dsq[high] = perpendicDistFromLineSqrd64(path[high], path[0], path[high - 1]);\n  } else {\n    dsq[0] = Number.MAX_VALUE;\n    dsq[high] = Number.MAX_VALUE;\n  }\n\n  for (let i = 1; i < high; ++i) {\n    dsq[i] = perpendicDistFromLineSqrd64(path[i], path[i - 1], path[i + 1]);\n  }\n\n  while (true) {\n    if (dsq[curr] > epsSqr) {\n      const start = curr;\n      do {\n        curr = getNext(curr, high, flags);\n      } while (curr !== start && dsq[curr] > epsSqr);\n      if (curr === start) break;\n    }\n\n    const prev = getPrior(curr, high, flags);\n    const next = getNext(curr, high, flags);\n    if (next === prev) break;\n\n    let prior2: number;\n    if (dsq[next] < dsq[curr]) {\n      prior2 = prev;\n      const newPrev = curr;\n      curr = next;\n      const newNext = getNext(next, high, flags);\n      flags[curr] = true;\n      curr = newNext;\n      const nextNext = getNext(newNext, high, flags);\n      if (isClosedPath || ((curr !== high) && (curr !== 0))) {\n        dsq[curr] = perpendicDistFromLineSqrd64(path[curr], path[newPrev], path[nextNext]);\n      }\n      if (isClosedPath || ((newPrev !== 0) && (newPrev !== high))) {\n        dsq[newPrev] = perpendicDistFromLineSqrd64(path[newPrev], path[prior2], path[curr]);\n      }\n    } else {\n      prior2 = getPrior(prev, high, flags);\n      flags[curr] = true;\n      curr = next;\n      const nextNext = getNext(next, high, flags);\n      if (isClosedPath || ((curr !== high) && (curr !== 0))) {\n        dsq[curr] = perpendicDistFromLineSqrd64(path[curr], path[prev], path[nextNext]);\n      }\n      if (isClosedPath || ((prev !== 0) && (prev !== high))) {\n        dsq[prev] = perpendicDistFromLineSqrd64(path[prev], path[prior2], path[curr]);\n      }\n    }\n  }\n  const result: Path64 = [];\n  for (let i = 0; i < len; i++) {\n    if (!flags[i]) result.push(path[i]);\n  }\n  return result;\n}\n\nexport function simplifyPaths(paths: Paths64, epsilon: number, isClosedPaths: boolean = true): Paths64 {\n  const result: Paths64 = [];\n  for (const path of paths) {\n    result.push(simplifyPath(path, epsilon, isClosedPaths));\n  }\n  return result;\n}\n\nexport function simplifyPathD(path: PathD, epsilon: number, isClosedPath: boolean = true): PathD {\n  const len = path.length;\n  const high = len - 1;\n  const epsSqr = sqr(epsilon);\n  if (len < 4) return path;\n\n  const flags = new Array(len).fill(false);\n  const dsq = new Array(len).fill(0);\n  let curr = 0;\n  \n  if (isClosedPath) {\n    dsq[0] = perpendicDistFromLineSqrd(path[0], path[high], path[1]);\n    dsq[high] = perpendicDistFromLineSqrd(path[high], path[0], path[high - 1]);\n  } else {\n    dsq[0] = Number.MAX_VALUE;\n    dsq[high] = Number.MAX_VALUE;\n  }\n  \n  for (let i = 1; i < high; ++i) {\n    dsq[i] = perpendicDistFromLineSqrd(path[i], path[i - 1], path[i + 1]);\n  }\n\n  while (true) {\n    if (dsq[curr] > epsSqr) {\n      const start = curr;\n      do {\n        curr = getNext(curr, high, flags);\n      } while (curr !== start && dsq[curr] > epsSqr);\n      if (curr === start) break;\n    }\n\n    const prev = getPrior(curr, high, flags);\n    const next = getNext(curr, high, flags);\n    if (next === prev) break;\n\n    let prior2: number;\n    if (dsq[next] < dsq[curr]) {\n      prior2 = prev;\n      const newPrev = curr;\n      curr = next;\n      const newNext = getNext(next, high, flags);\n      flags[curr] = true;\n      curr = newNext;\n      const nextNext = getNext(newNext, high, flags);\n      if (isClosedPath || ((curr !== high) && (curr !== 0))) {\n        dsq[curr] = perpendicDistFromLineSqrd(path[curr], path[newPrev], path[nextNext]);\n      }\n      if (isClosedPath || ((newPrev !== 0) && (newPrev !== high))) {\n        dsq[newPrev] = perpendicDistFromLineSqrd(path[newPrev], path[prior2], path[curr]);\n      }\n    } else {\n      prior2 = getPrior(prev, high, flags);\n      flags[curr] = true;\n      curr = next;\n      const nextNext = getNext(next, high, flags);\n      if (isClosedPath || ((curr !== high) && (curr !== 0))) {\n        dsq[curr] = perpendicDistFromLineSqrd(path[curr], path[prev], path[nextNext]);\n      }\n      if (isClosedPath || ((prev !== 0) && (prev !== high))) {\n        dsq[prev] = perpendicDistFromLineSqrd(path[prev], path[prior2], path[curr]);\n      }\n    }\n  }\n  const result: PathD = [];\n  for (let i = 0; i < len; i++) {\n    if (!flags[i]) result.push(path[i]);\n  }\n  return result;\n}\n\nexport function simplifyPathsD(paths: PathsD, epsilon: number, isClosedPath: boolean = true): PathsD {\n  const result: PathsD = [];\n  for (const path of paths) {\n    result.push(simplifyPathD(path, epsilon, isClosedPath));\n  }\n  return result;\n}\n\nexport function trimCollinear(path: Path64, isOpen: boolean = false): Path64 {\n  let len = path.length;\n  let i = 0;\n  if (!isOpen) {\n    while (i < len - 1 && InternalClipper.isCollinear(path[len - 1], path[i], path[i + 1])) i++;\n    while (i < len - 1 && InternalClipper.isCollinear(path[len - 2], path[len - 1], path[i])) len--;\n  }\n\n  if (len - i < 3) {\n    if (!isOpen || len < 2 || Point64Utils.equals(path[0], path[1])) {\n      return [];\n    }\n    return path;\n  }\n\n  const result: Path64 = [];\n  let last = path[i];\n  result.push(last);\n  for (i++; i < len - 1; i++) {\n    if (InternalClipper.isCollinear(last, path[i], path[i + 1])) continue;\n    last = path[i];\n    result.push(last);\n  }\n\n  if (isOpen) {\n    result.push(path[len - 1]);\n  } else if (!InternalClipper.isCollinear(last, path[len - 1], result[0])) {\n    result.push(path[len - 1]);\n  } else {\n    while (result.length > 2 && InternalClipper.isCollinear(\n      result[result.length - 1], result[result.length - 2], result[0])) {\n      result.pop();\n    }\n    if (result.length < 3) {\n      result.length = 0;\n    }\n  }\n  return result;\n}\n\nexport function trimCollinearD(path: PathD, precision: number, isOpen: boolean = false): PathD {\n  InternalClipper.checkPrecision(precision);\n  const scale = Math.pow(10, precision);\n  let p = scalePath64(path, scale);\n  p = trimCollinear(p, isOpen);\n  return scalePathDFromInt(p, 1 / scale);\n}\n\nexport function pointInPolygon(pt: Point64, polygon: Path64): PointInPolygonResult {\n  return InternalClipper.pointInPolygon(pt, polygon);\n}\n\nexport function pointInPolygonD(pt: PointD, polygon: PathD, precision: number = 2): PointInPolygonResult {\n  InternalClipper.checkPrecision(precision);\n  const scale = Math.pow(10, precision);\n  const maxAbs = InternalClipper.maxSafeCoordinateForScale(scale);\n  InternalClipper.checkSafeScaleValue(pt.x, maxAbs, \"pointInPolygonD\");\n  InternalClipper.checkSafeScaleValue(pt.y, maxAbs, \"pointInPolygonD\");\n  const p = Point64Utils.fromPointD(PointDUtils.scale(pt, scale));\n  const pathScaled = scalePath64(polygon, scale);\n  return InternalClipper.pointInPolygon(p, pathScaled);\n}\n\nexport function ellipse(center: Point64, radiusX: number, radiusY: number = 0, steps: number = 0): Path64 {\n  if (radiusX <= 0) return [];\n  if (radiusY <= 0) radiusY = radiusX;\n  if (steps <= 2) {\n    steps = Math.ceil(Math.PI * Math.sqrt((radiusX + radiusY) / 2));\n  }\n\n  const si = Math.sin(2 * Math.PI / steps);\n  const co = Math.cos(2 * Math.PI / steps);\n  let dx = co;\n  let dy = si;\n  const result: Path64 = [{ x: Math.round(center.x + radiusX), y: center.y }];\n  \n  for (let i = 1; i < steps; ++i) {\n    result.push({\n      x: Math.round(center.x + radiusX * dx),\n      y: Math.round(center.y + radiusY * dy)\n    });\n    const x = dx * co - dy * si;\n    dy = dy * co + dx * si;\n    dx = x;\n  }\n  return result;\n}\n\nexport function ellipseD(center: PointD, radiusX: number, radiusY: number = 0, steps: number = 0): PathD {\n  if (radiusX <= 0) return [];\n  if (radiusY <= 0) radiusY = radiusX;\n  if (steps <= 2) {\n    steps = Math.ceil(Math.PI * Math.sqrt((radiusX + radiusY) / 2));\n  }\n\n  const si = Math.sin(2 * Math.PI / steps);\n  const co = Math.cos(2 * Math.PI / steps);\n  let dx = co;\n  let dy = si;\n  const result: PathD = [{ x: center.x + radiusX, y: center.y }];\n  \n  for (let i = 1; i < steps; ++i) {\n    result.push({\n      x: center.x + radiusX * dx,\n      y: center.y + radiusY * dy\n    });\n    const x = dx * co - dy * si;\n    dy = dy * co + dx * si;\n    dx = x;\n  }\n  return result;\n}\n\n// Triangulation\nexport function triangulate(pp: Paths64, useDelaunay: boolean = true): { result: TriangulateResult, solution: Paths64 } {\n  const d = new Delaunay(useDelaunay);\n  return d.execute(pp);\n}\n\nexport function triangulateD(pp: PathsD, decPlaces: number, useDelaunay: boolean = true): { result: TriangulateResult, solution: PathsD } {\n  let scale: number;\n  if (decPlaces <= 0) scale = 1.0;\n  else if (decPlaces > 8) scale = Math.pow(10.0, 8.0);\n  else scale = Math.pow(10.0, decPlaces);\n\n  const pp64 = scalePaths64(pp, scale);\n\n  const d = new Delaunay(useDelaunay);\n  const { result, solution: sol64 } = d.execute(pp64);\n\n  let solution: PathsD;\n  if (result === TriangulateResult.success) {\n    solution = scalePathsD(sol64, 1.0 / scale);\n  } else {\n    solution = [];\n  }\n  return { result, solution };\n}\n\n/**\n * @deprecated Use named exports or \\`import * as Clipper\\` instead\n * Compatibility alias for direct imports from Clipper.js\n */\nexport const Clipper = {\n  invalidRect64,\n  invalidRectD,\n  intersect,\n  intersectD,\n  union,\n  unionD,\n  difference,\n  differenceD,\n  xor,\n  xorD,\n  booleanOp,\n  booleanOpWithPolyTree,\n  booleanOpD,\n  booleanOpDWithPolyTree,\n  inflatePaths,\n  inflatePathsD,\n  rectClip,\n  rectClipLines,\n  minkowskiSum,\n  minkowskiSumD,\n  minkowskiDiff,\n  minkowskiDiffD,\n  area,\n  areaPaths,\n  areaD,\n  areaPathsD,\n  isPositive,\n  isPositiveD,\n  path64ToString,\n  paths64ToString,\n  pathDToString,\n  pathsDToString,\n  offsetPath,\n  scalePoint64,\n  scalePointD,\n  scaleRect,\n  scalePath,\n  scalePaths,\n  scalePathD,\n  scalePathsD,\n  scalePath64,\n  scalePaths64,\n  scalePathDFromInt,\n  scalePathsDFromInt,\n  path64FromD,\n  paths64FromD,\n  pathsD,\n  pathD,\n  translatePath,\n  translatePaths,\n  translatePathD,\n  translatePathsD,\n  reversePath,\n  reversePathD,\n  reversePaths,\n  reversePathsD,\n  getBounds,\n  getBoundsPaths,\n  getBoundsD,\n  getBoundsPathsD,\n  makePath,\n  makePathD,\n  sqr,\n  distanceSqr,\n  midPoint,\n  midPointD,\n  inflateRect,\n  inflateRectD,\n  pointsNearEqual,\n  stripNearDuplicates,\n  stripDuplicates,\n  polyTreeToPaths64,\n  addPolyNodeToPathsD,\n  polyTreeToPathsD,\n  perpendicDistFromLineSqrd,\n  perpendicDistFromLineSqrd64,\n  ramerDouglasPeucker,\n  ramerDouglasPeuckerPaths,\n  ramerDouglasPeuckerD,\n  ramerDouglasPeuckerPathsD,\n  simplifyPath,\n  simplifyPaths,\n  simplifyPathD,\n  simplifyPathsD,\n  trimCollinear,\n  trimCollinearD,\n  pointInPolygon,\n  pointInPolygonD,\n  ellipse,\n  ellipseD,\n  triangulate,\n  triangulateD\n};\n"],"mappings":"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"}