@ue-too/curve 0.9.5 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js.map CHANGED
@@ -2,12 +2,12 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/b-curve.ts", "../src/line.ts", "../src/composite-curve.ts", "../src/path.ts"],
4
4
  "sourcesContent": [
5
- "import { PointCal } from \"@ue-too/math\";\nimport { Line } from \"./line\";\n\nconst T = [\n -0.0640568928626056260850430826247450385909,\n 0.0640568928626056260850430826247450385909,\n -0.1911188674736163091586398207570696318404,\n 0.1911188674736163091586398207570696318404,\n -0.3150426796961633743867932913198102407864,\n 0.3150426796961633743867932913198102407864,\n -0.4337935076260451384870842319133497124524,\n 0.4337935076260451384870842319133497124524,\n -0.5454214713888395356583756172183723700107,\n 0.5454214713888395356583756172183723700107,\n -0.6480936519369755692524957869107476266696,\n 0.6480936519369755692524957869107476266696,\n -0.7401241915785543642438281030999784255232,\n 0.7401241915785543642438281030999784255232,\n -0.8200019859739029219539498726697452080761,\n 0.8200019859739029219539498726697452080761,\n -0.8864155270044010342131543419821967550873,\n 0.8864155270044010342131543419821967550873,\n -0.9382745520027327585236490017087214496548,\n 0.9382745520027327585236490017087214496548,\n -0.9747285559713094981983919930081690617411,\n 0.9747285559713094981983919930081690617411,\n -0.9951872199970213601799974097007368118745,\n 0.9951872199970213601799974097007368118745,\n];\n\nconst C = [\n 0.1279381953467521569740561652246953718517,\n 0.1279381953467521569740561652246953718517,\n 0.1258374563468282961213753825111836887264,\n 0.1258374563468282961213753825111836887264,\n 0.121670472927803391204463153476262425607,\n 0.121670472927803391204463153476262425607,\n 0.1155056680537256013533444839067835598622,\n 0.1155056680537256013533444839067835598622,\n 0.1074442701159656347825773424466062227946,\n 0.1074442701159656347825773424466062227946,\n 0.0976186521041138882698806644642471544279,\n 0.0976186521041138882698806644642471544279,\n 0.086190161531953275917185202983742667185,\n 0.086190161531953275917185202983742667185,\n 0.0733464814110803057340336152531165181193,\n 0.0733464814110803057340336152531165181193,\n 0.0592985849154367807463677585001085845412,\n 0.0592985849154367807463677585001085845412,\n 0.0442774388174198061686027482113382288593,\n 0.0442774388174198061686027482113382288593,\n 0.0285313886289336631813078159518782864491,\n 0.0285313886289336631813078159518782864491,\n 0.0123412297999871995468056670700372915759,\n 0.0123412297999871995468056670700372915759,\n];\n\ntype ArcLengthLUT = {\n controlPoints: Point[];\n arcLengthLUT: {tVal: number, length: number}[];\n}\n\ntype AdvanceAtTWithLengthWithinCurveRes = {\n type: \"withinCurve\";\n tVal: number;\n point: Point;\n}\n\ntype AdvanceAtWithLengthBeforeCurveRes = {\n type: \"beforeCurve\";\n remainLength: number;\n}\n\ntype AdvanceAtWithLengthAfterCurveRes = {\n type: \"afterCurve\";\n remainLength: number;\n}\n\ntype AdvanceAtTWithLengthOutofCurveRes = AdvanceAtWithLengthBeforeCurveRes | AdvanceAtWithLengthAfterCurveRes;\n\ntype AdvanceAtTWithLengthRes = AdvanceAtTWithLengthWithinCurveRes | AdvanceAtTWithLengthOutofCurveRes;\n\nexport class BCurve{\n\n private controlPoints: Point[];\n private dControlPoints: Point[] = [];\n private arcLengthLUT: ArcLengthLUT = {controlPoints: [], arcLengthLUT: []};\n private _fullLength: number;\n private lengthCache: Map<number, number> = new Map(); // Cache for lengthAtT results\n\n /**\n * Gets cache statistics for performance monitoring\n * @returns Object containing cache size and hit rate information\n */\n public getCacheStats(): {size: number, hitRate: number} {\n return {\n size: this.lengthCache.size,\n hitRate: 0 // This would need to be tracked separately if needed\n };\n }\n\n /**\n * Pre-warms the cache with commonly used t values for better performance\n * @param steps Number of steps to pre-cache (default: 100)\n */\n public preWarmCache(steps: number = 100): void {\n const tSteps = 1 / steps;\n for (let tVal = 0; tVal <= 1; tVal += tSteps) {\n this.lengthAtT(tVal);\n }\n }\n\n private clearCache(): void {\n this.lengthCache.clear();\n }\n\n constructor(controlPoints: Point[]){\n this.controlPoints = controlPoints;\n this.dControlPoints = this.getDerivativeControlPoints(this.controlPoints);\n this._fullLength = this.calculateFullLength();\n // Make arc length LUT lazy - only compute when needed\n this.arcLengthLUT = { controlPoints: [], arcLengthLUT: [] };\n this.clearCache(); // Clear cache on initialization\n }\n\n public getPointbyPercentage(percentage: number){ // this is the percentage of the curve length, not the t value\n // this leaves room for optimization\n let controlPointsChangedSinceLastArcLengthLUT = this.arcLengthLUT.controlPoints.length != this.controlPoints.length;\n controlPointsChangedSinceLastArcLengthLUT = controlPointsChangedSinceLastArcLengthLUT || this.arcLengthLUT.controlPoints.reduce((prevVal, curVal, index)=>{\n return prevVal || !PointCal.isEqual(curVal, this.controlPoints[index]);\n }, false);\n let points: number[] = [];\n if (controlPointsChangedSinceLastArcLengthLUT){\n this.arcLengthLUT = this.getArcLengthLUT(1000);\n }\n points = [...this.arcLengthLUT.arcLengthLUT.map((item)=>item.length)];\n let targetLength = percentage * this.fullLength;\n let low = 0;\n let high = points.length - 1;\n while (low <= high){\n let mid = Math.floor((low + high) / 2);\n if (points[mid] == targetLength){\n return this.get((mid + 1) / points.length);\n } else if (points[mid] < targetLength){\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n return low >= points.length ? this.get(1) : this.get((low + 1) / points.length);\n }\n\n public getDerivativeControlPoints(controlPoints: Point[]): Point[]{\n const derivativeControlPoints: Point[] = [];\n for(let index = 1; index < controlPoints.length; index++){\n derivativeControlPoints.push(PointCal.multiplyVectorByScalar(PointCal.subVector(controlPoints[index], controlPoints[index - 1]), controlPoints.length - 1));\n }\n return derivativeControlPoints;\n }\n\n private validateTVal(tVal: number){\n if (tVal > 1 || tVal < 0){\n throw new TValOutofBoundError(\"tVal is greater than 1 or less than 0\");\n }\n }\n\n public getControlPoints(): Point[]{\n return this.controlPoints;\n }\n\n setControlPoints(controlPoints: Point[]){\n this.controlPoints = controlPoints;\n this.dControlPoints = this.getDerivativeControlPoints(this.controlPoints);\n this._fullLength = this.calculateFullLength();\n // Reset LUT to trigger lazy computation when needed\n this.arcLengthLUT = { controlPoints: [], arcLengthLUT: [] };\n this.clearCache(); // Clear cache on control point change\n }\n\n setControlPointAtIndex(index: number, newPoint: Point): boolean{\n if (index < 0 || index >= this.controlPoints.length){\n return false;\n }\n this.controlPoints[index] = newPoint;\n this.dControlPoints = this.getDerivativeControlPoints(this.controlPoints);\n this._fullLength = this.calculateFullLength();\n // Reset LUT to trigger lazy computation when needed\n this.arcLengthLUT = { controlPoints: [], arcLengthLUT: [] };\n this.clearCache(); // Clear cache on control point change\n return true;\n }\n\n public compute(tVal: number): Point{\n this.validateTVal(tVal);\n let points = this.controlPoints;\n while (points.length > 1) {\n let lowerLevelPoints = points.slice(1);\n for(let index = 0; index < lowerLevelPoints.length; index++){\n lowerLevelPoints[index] = PointCal.addVector(PointCal.multiplyVectorByScalar(points[index], (1 - tVal)), PointCal.multiplyVectorByScalar(points[index + 1], tVal));\n }\n points = lowerLevelPoints;\n }\n return points[0];\n }\n\n public get(tVal: number): Point {\n this.validateTVal(tVal);\n if (this.controlPoints.length == 3) {\n let firstTerm = PointCal.multiplyVectorByScalar(this.controlPoints[0], (1 - tVal) * (1 - tVal));\n let secondTerm = PointCal.multiplyVectorByScalar(this.controlPoints[1], 2 * (1 - tVal) * tVal);\n let thirdTerm = PointCal.multiplyVectorByScalar(this.controlPoints[2], tVal * tVal);\n let res = PointCal.addVector(PointCal.addVector(firstTerm, secondTerm), thirdTerm);\n return res;\n }\n if (this.controlPoints.length == 4){\n let firstTerm = PointCal.multiplyVectorByScalar(this.controlPoints[0], (1 - tVal) * (1 - tVal) * (1 - tVal));\n let secondTerm = PointCal.multiplyVectorByScalar(this.controlPoints[1], 3 * (1 - tVal) * (1 - tVal) * tVal);\n let thirdTerm = PointCal.multiplyVectorByScalar(this.controlPoints[2], 3 * (1 - tVal) * tVal * tVal);\n let forthTerm = PointCal.multiplyVectorByScalar(this.controlPoints[3], tVal * tVal * tVal);\n let res = PointCal.addVector(PointCal.addVector(firstTerm, secondTerm), PointCal.addVector(thirdTerm, forthTerm));\n return res;\n }\n return this.compute(tVal);\n }\n\n public getLUT(steps: number = 100){\n const stepSpan = 1 / steps;\n const res: Point[] = [];\n let tVal = 0;\n res.push(this.get(tVal));\n for(let index = 0; index < steps; index += 1){\n tVal += stepSpan;\n if((tVal > 1 && tVal - stepSpan < 1) || index == steps - 1){\n tVal = 1;\n }\n res.push(this.get(tVal));\n }\n return res\n }\n\n public getLUTWithTVal(steps?: number){\n if (steps == undefined){\n steps = 100;\n }\n const stepSpan = 1 / steps;\n const res: {point: Point, tVal: number}[] = [];\n let tVal = 0;\n res.push({point: this.get(tVal), tVal: tVal});\n for(let index = 0; index < steps; index += 1){\n tVal += stepSpan;\n if((tVal > 1 && tVal - stepSpan < 1) || index == steps - 1){\n tVal = 1;\n }\n res.push({point: this.get(tVal), tVal: tVal});\n }\n return res\n }\n\n get fullLength(): number{\n return this._fullLength;\n }\n\n private calculateFullLength(): number{\n return this.lengthAtT(1);\n }\n\n public lengthAtT(tVal: number): number{\n this.validateTVal(tVal);\n \n // Check cache first\n const cacheKey = Math.round(tVal * 1000000) / 1000000; // Round to 6 decimal places for cache key\n if (this.lengthCache.has(cacheKey)) {\n return this.lengthCache.get(cacheKey)!;\n }\n \n const z = tVal / 2, len = T.length;\n let sum = 0;\n for (let i = 0, t: number; i < len; i++) {\n t = z * T[i] + z;\n sum += C[i] * PointCal.magnitude(this.derivative(t));\n }\n const result = z * sum;\n \n // Cache the result\n this.lengthCache.set(cacheKey, result);\n \n return result;\n }\n\n public derivative(tVal: number): Point{\n return computeWithControlPoints(tVal, this.dControlPoints);\n }\n\n public derivativeNormalized(tVal: number): Point{\n return PointCal.unitVector(computeWithControlPoints(tVal, this.dControlPoints));\n }\n\n public getArcLengthLUT(steps: number = 50): {controlPoints: Point[], arcLengthLUT: {tVal: number, length: number}[]}{\n // Check if we need to recompute the LUT\n const controlPointsChanged = this.arcLengthLUT.controlPoints.length !== this.controlPoints.length ||\n this.arcLengthLUT.controlPoints.some((cp, index) => !PointCal.isEqual(cp, this.controlPoints[index]));\n \n if (controlPointsChanged || this.arcLengthLUT.arcLengthLUT.length === 0) {\n // Clear cache when regenerating LUT to ensure consistency\n this.clearCache();\n \n let res = [];\n let tSteps = 1 / steps;\n for(let tVal = 0; tVal <= 1; tVal += tSteps){\n res.push({tVal: tVal, length: this.lengthAtT(tVal)});\n }\n this.arcLengthLUT = {controlPoints: [...this.controlPoints], arcLengthLUT: res};\n }\n \n return this.arcLengthLUT;\n }\n\n splitIntoCurves(tVal: number): [BCurve, BCurve]{\n const res = this.split(tVal);\n return [new BCurve(res[0]), new BCurve(res[1])];\n }\n\n public split(tVal: number): [Point[], Point[]]{\n this.validateTVal(tVal);\n if (this.controlPoints.length == 3){\n let newControlPoint1 = this.controlPoints[0];\n let newControlPoint2 = PointCal.subVector(PointCal.multiplyVectorByScalar(this.controlPoints[1], tVal), PointCal.multiplyVectorByScalar(this.controlPoints[0], tVal - 1));\n let newControlPoint3 = PointCal.subVector(PointCal.multiplyVectorByScalar(this.controlPoints[2], tVal * tVal), PointCal.multiplyVectorByScalar(this.controlPoints[1], 2 * tVal * (tVal - 1)));\n newControlPoint3 = PointCal.addVector(newControlPoint3, PointCal.multiplyVectorByScalar(this.controlPoints[0], (tVal - 1) * (tVal - 1)));\n let newControlPoint4 = PointCal.subVector(PointCal.multiplyVectorByScalar(this.controlPoints[2], tVal), PointCal.multiplyVectorByScalar(this.controlPoints[1], tVal - 1));\n let newControlPoint5 = this.controlPoints[2];\n return [[newControlPoint1, newControlPoint2, newControlPoint3], [newControlPoint3, newControlPoint4, newControlPoint5]];\n }\n let newControlPoint1 = this.controlPoints[0];\n let newControlPoint2 = PointCal.subVector(PointCal.multiplyVectorByScalar(this.controlPoints[1], tVal), PointCal.multiplyVectorByScalar(this.controlPoints[0], (tVal - 1)));\n let newControlPoint3 = PointCal.addVector(PointCal.multiplyVectorByScalar(this.controlPoints[2], tVal * tVal), PointCal.addVector(PointCal.multiplyVectorByScalar(this.controlPoints[1], -(2 * tVal * (tVal - 1))), PointCal.multiplyVectorByScalar(this.controlPoints[0], (tVal - 1) * (tVal - 1))));\n let term1 = PointCal.multiplyVectorByScalar(this.controlPoints[3], tVal * tVal * tVal);\n let term2 = PointCal.multiplyVectorByScalar(this.controlPoints[2], -(3 * tVal * tVal * (tVal - 1)));\n let term3 = PointCal.multiplyVectorByScalar(this.controlPoints[1], 3 * tVal * (tVal - 1) * (tVal - 1));\n let term4 = PointCal.multiplyVectorByScalar(this.controlPoints[0], -((tVal - 1) * (tVal - 1) * (tVal - 1)));\n let newControlPoint4 = PointCal.addVector(term4, PointCal.addVector(term3, PointCal.addVector(term1, term2)));\n let newControlPoint5 = PointCal.addVector(PointCal.addVector(PointCal.multiplyVectorByScalar(this.controlPoints[3], tVal * tVal), PointCal.multiplyVectorByScalar(this.controlPoints[2], -(2 * tVal * (tVal - 1)))), PointCal.multiplyVectorByScalar(this.controlPoints[1], (tVal - 1) * (tVal - 1)));\n let newControlPoint6 = PointCal.addVector(PointCal.multiplyVectorByScalar(this.controlPoints[3], tVal), PointCal.multiplyVectorByScalar(this.controlPoints[2], -(tVal - 1)));\n let newControlPoint7 = this.controlPoints[3];\n\n return [[newControlPoint1, newControlPoint2, newControlPoint3, newControlPoint4], [newControlPoint4, newControlPoint5, newControlPoint6, newControlPoint7]];\n }\n\n splitIn3WithControlPoints(tVal: number, tVal2: number): [Point[], Point[], Point[]]{\n if(tVal2 < tVal){\n console.warn(\"tVal2 is less than tVal, swapping them\");\n [tVal, tVal2] = [tVal2, tVal];\n }\n\n const firstSplit = this.split(tVal);\n\n const secondHalf = new BCurve(firstSplit[1]);\n\n const mappedTVal2 = map(tVal2, tVal, 1, 0, 1);\n \n const secondSplit = secondHalf.split(mappedTVal2);\n\n return [firstSplit[0], secondSplit[0], secondSplit[1]];\n }\n\n splitIn3Curves(tVal: number, tVal2: number): [BCurve, BCurve, BCurve]{\n if(tVal2 < tVal){\n console.warn(\"tVal2 is less than tVal, swapping them\");\n [tVal, tVal2] = [tVal2, tVal];\n }\n\n const firstSplit = this.split(tVal);\n\n const secondHalf = new BCurve(firstSplit[1]);\n \n const mappedTVal2 = map(tVal2, tVal, 1, 0, 1);\n const secondSplit = secondHalf.split(mappedTVal2);\n\n return [new BCurve(firstSplit[0]), new BCurve(secondSplit[0]), new BCurve(secondSplit[1])];\n }\n\n splitAndTakeMidCurve(tVal: number, tVal2: number): BCurve{\n const [firstSplit, secondSplit, thirdSplit] = this.splitIn3Curves(tVal, tVal2);\n return secondSplit;\n }\n\n getProjection(point: Point){\n const threshold = 0.00001;\n let distance = Number.MAX_VALUE;\n let preliminaryProjectionTVal: number = 0;\n let preliminaryProjectionPoint: Point = this.get(0);\n let preliminaryProjectionIndex: number = 0;\n const LUT = this.getLUTWithTVal(500);\n LUT.forEach((curvePoint, index)=>{\n const curDistance = PointCal.distanceBetweenPoints(curvePoint.point, point);\n if(curDistance < distance){\n distance = curDistance;\n preliminaryProjectionPoint = {...curvePoint.point};\n preliminaryProjectionTVal = curvePoint.tVal;\n preliminaryProjectionIndex = index;\n }\n });\n // console.log(preliminaryProjectionIndex, preliminaryProjectionPoint, preliminaryProjectionTVal);\n let low = LUT[preliminaryProjectionIndex].tVal;\n let high = LUT[preliminaryProjectionIndex].tVal;\n if (preliminaryProjectionIndex < LUT.length - 1){\n high = LUT[preliminaryProjectionIndex + 1].tVal;\n }\n if (preliminaryProjectionIndex > 0){\n low = LUT[preliminaryProjectionIndex - 1].tVal;\n }\n while(low < high && high - low > threshold){\n let mid = low + (high - low) / 2;\n let halfSpan = mid - low;\n let lowMidMid = mid + halfSpan / 2;\n let highMidMid = mid + halfSpan / 2;\n let prevDist = distance;\n\n \n if(lowMidMid <= 1 && lowMidMid >= 0){\n let curDist = PointCal.distanceBetweenPoints(this.get(lowMidMid), point);\n if (curDist < distance){\n distance = curDist;\n preliminaryProjectionPoint = this.get(lowMidMid);\n preliminaryProjectionTVal = lowMidMid;\n high = lowMidMid + halfSpan / 2;\n low = lowMidMid - halfSpan / 2;\n }\n }\n if(highMidMid <= 1 && highMidMid >= 0){\n let curDist = PointCal.distanceBetweenPoints(this.get(highMidMid), point);\n if (curDist < distance){\n distance = curDist;\n preliminaryProjectionPoint = this.get(highMidMid);\n preliminaryProjectionTVal = highMidMid;\n high = highMidMid + halfSpan / 2;\n low = highMidMid - halfSpan / 2;\n }\n }\n if (prevDist == distance){\n break;\n }\n }\n return {projection: preliminaryProjectionPoint, tVal: preliminaryProjectionTVal};\n }\n\n public findArcs(errorThreshold: number){\n let low = 0;\n const res: {center: Point, radius: number, startPoint: Point, startT: number, endPoint: Point, endT: number}[] = [];\n\n while (low < 1){\n let loopRes = this.findArcStartingAt(errorThreshold, low);\n if (loopRes == null || loopRes.arc == undefined) {\n break;\n }\n res.push(loopRes.arc);\n low = loopRes.arc.endT;\n if(low >= 1){\n break;\n }\n }\n return res;\n }\n\n public findArcStartingAt(errorThreshold: number, low: number){\n let high = 1;\n let mid = low + (high - low) / 2;\n let prevArc:{good: boolean, arc?: {center: Point, radius: number, startPoint: Point, endPoint: Point, startT: number, endT: number}} = {good: false};\n let count = 0;\n while(true){\n count++;\n mid = low + (high - low) / 2;\n if (high > 1 || mid > 1){\n if (prevArc.good){\n return prevArc;\n } else {\n return null;\n }\n \n }\n const lowPoint = this.get(low);\n const highPoint = this.get(high);\n const midPoint = this.get(mid);\n const fitArcRes = this.fitArc(lowPoint, highPoint, midPoint);\n if (!fitArcRes.exists || fitArcRes.center == null || fitArcRes.radius == null){\n return null;\n }\n const n = high - mid;\n const e1 = mid - n / 2;\n const e2 = mid + n / 2;\n const checkPoint1 = this.get(e1);\n const checkPoint2 = this.get(e2);\n const checkRadius = PointCal.distanceBetweenPoints(checkPoint1, fitArcRes.center);\n const checkRadius2 = PointCal.distanceBetweenPoints(checkPoint2, fitArcRes.center);\n if (Math.abs(checkRadius - fitArcRes.radius) > errorThreshold || Math.abs(checkRadius2 - fitArcRes.radius) > errorThreshold){\n // arc is bad\n if (prevArc.good == true){\n return prevArc;\n }\n prevArc.good = false;\n high = mid\n } else {\n prevArc.good = true;\n if (fitArcRes.startPoint !== undefined && fitArcRes.endPoint !== undefined){\n prevArc.arc = { center: fitArcRes.center, radius: fitArcRes.radius, startPoint: fitArcRes.startPoint, endPoint: fitArcRes.endPoint, startT: low, endT: high};\n }\n high = high + (mid - low);\n }\n }\n }\n\n public fitArc(startPoint: Point, endPoint: Point, midPoint: Point): {exists: boolean, center?: Point, radius?: number, startPoint?: Point, endPoint?: Point}{\n const M11 = [[startPoint.x, startPoint.y, 1], [midPoint.x, midPoint.y, 1], [endPoint.x, endPoint.y, 1]];\n if (this.determinant3by3(M11) == 0) {\n // three points lie on a line no circle\n return {exists: false};\n }\n const M12 = [[startPoint.x * startPoint.x + startPoint.y * startPoint.y, startPoint.y, 1], \n [midPoint.x * midPoint.x + midPoint.y * midPoint.y, midPoint.y, 1],\n [endPoint.x * endPoint.x + endPoint.y * endPoint.y, endPoint.y, 1]];\n const M13 = [[startPoint.x * startPoint.x + startPoint.y * startPoint.y, startPoint.x, 1],\n [midPoint.x * midPoint.x + midPoint.y * midPoint.y, midPoint.x, 1],\n [endPoint.x * endPoint.x + endPoint.y * endPoint.y, endPoint.x, 1]];\n const M14 = [[startPoint.x * startPoint.x + startPoint.y * startPoint.y, startPoint.x, startPoint.y],\n [midPoint.x * midPoint.x + midPoint.y * midPoint.y, midPoint.x, midPoint.y],\n [endPoint.x * endPoint.x + endPoint.y * endPoint.y, endPoint.x, endPoint.y]]\n const centerX = (1 / 2) * (this.determinant3by3(M12) / this.determinant3by3(M11));\n const centerY = (-1 / 2) * (this.determinant3by3(M13) / this.determinant3by3(M11));\n const radius = Math.sqrt(centerX * centerX + centerY * centerY + (this.determinant3by3(M14) / this.determinant3by3(M11)))\n return {exists: true, center: {x: centerX, y:centerY}, radius: radius, startPoint: startPoint, endPoint: endPoint};\n }\n\n public determinant3by3(matrix: number[][]): number{\n const a = matrix[0][0];\n const b = matrix[0][1];\n const c = matrix[0][2];\n const d = matrix[1][0];\n const e = matrix[1][1];\n const f = matrix[1][2];\n const g = matrix[2][0];\n const h = matrix[2][1];\n const i = matrix[2][2];\n return a * (e * i - f * h) - b * (d * i - g * f) + c * (d * h - e * g);\n }\n\n public curvature(tVal: number): number{\n const derivative = computeWithControlPoints(tVal, this.dControlPoints);\n const secondDerivative = computeWithControlPoints(tVal, this.getDerivativeControlPoints(this.dControlPoints));\n const numerator = derivative.x * secondDerivative.y - secondDerivative.x * derivative.y;\n const denominator = Math.pow(derivative.x * derivative.x + derivative.y * derivative.y, 3 / 2);\n if (denominator == 0) return NaN;\n return numerator / denominator;\n }\n\n secondDerivative(tVal: number): Point{\n return computeWithControlPoints(tVal, this.getDerivativeControlPoints(this.dControlPoints));\n }\n\n public getCoefficientOfTTerms(): Point[]{\n return this.getCoefficientOfTTermsWithControlPoints(this.controlPoints);\n }\n\n public getDerivativeCoefficients(): Point[]{\n return this.getCoefficientOfTTermsWithControlPoints(this.dControlPoints);\n }\n\n public getCoefficientOfTTermsWithControlPoints(controlPoints: Point[]): Point[]{\n const terms: Point[] = [];\n let matrix: number[][] = [];\n if(controlPoints.length == 3){\n matrix = [[1, 0, 0], [-2, 2, 0], [1, -2, 1]];\n } else if (controlPoints.length == 4){\n matrix = [[1, 0, 0, 0], [-3, 3, 0, 0], [3, -6, 3, 0], [-1, 3, -3, 1]];\n } else if(controlPoints.length == 2){\n matrix = [[1, 0], [-1, 1]];\n } \n else {\n throw new Error(\"number of control points is wrong\");\n }\n for(let index = 0; index < controlPoints.length; index++){\n terms.push(controlPoints.reduce((prevVal, curVal, jindex)=>{\n return {x: prevVal.x + matrix[index][jindex] * curVal.x, y: prevVal.y + matrix[index][jindex] * curVal.y};\n }, {x: 0, y: 0}));\n }\n return terms;\n }\n\n getControlPointsAlignedWithXAxis(){\n const alignedAxis = PointCal.unitVectorFromA2B(this.controlPoints[0], this.controlPoints[this.controlPoints.length - 1]);\n const angle = PointCal.angleFromA2B({x:1, y:0}, alignedAxis);\n const startingPoint = this.controlPoints[0];\n const res = [{x: 0, y: 0}];\n for(let index = 1; index < this.controlPoints.length; index++){\n const vector = PointCal.subVector(this.controlPoints[index], startingPoint);\n const rotatedVector = PointCal.rotatePoint(vector, -angle);\n res.push(rotatedVector);\n }\n return res;\n }\n\n getExtrema():{x: number[], y: number[]}{\n const res: {x: number[], y: number[]} = {x: [], y: []};\n const derivativeCoefficients = this.getDerivativeCoefficients();\n let xCoefficients = [0, 0, 0, 0];\n let yCoefficients = [0, 0, 0, 0];\n derivativeCoefficients.forEach((coefficient, index)=>{\n xCoefficients[3 - index] = coefficient.x;\n yCoefficients[3 - index] = coefficient.y;\n });\n\n const xRoots = solveCubic(xCoefficients[0], xCoefficients[1], xCoefficients[2], xCoefficients[3]);\n const yRoots = solveCubic(yCoefficients[0], yCoefficients[1], yCoefficients[2], yCoefficients[3]);\n xRoots.forEach((root)=>{\n if(root >= 0 && root <= 1){\n res.x.push(root);\n }\n });\n yRoots.forEach((root)=>{\n if(root >= 0 && root <= 1){\n res.y.push(root);\n }\n });\n \n if(derivativeCoefficients.length >= 3){\n xCoefficients = [0, 0, 0, 0];\n yCoefficients = [0, 0, 0, 0];\n const secondDerivativeCoefficients = this.getCoefficientOfTTermsWithControlPoints(this.getDerivativeControlPoints(this.dControlPoints));\n secondDerivativeCoefficients.forEach((coefficient, index)=>{\n xCoefficients[3 - index] = coefficient.x;\n yCoefficients[3 - index] = coefficient.y;\n })\n const secondXRoots = solveCubic(xCoefficients[0], xCoefficients[1], xCoefficients[2], xCoefficients[3]);\n const secondYRoots = solveCubic(yCoefficients[0], yCoefficients[1], yCoefficients[2], yCoefficients[3]);\n secondXRoots.forEach((root)=>{\n if(root >= 0 && root <= 1){\n res.x.push(root);\n }\n });\n secondYRoots.forEach((root)=>{\n if(root >= 0 && root <= 1){\n res.y.push(root);\n }\n });\n\n }\n return res; \n }\n\n translateRotateControlPoints(translation: Point, rotationAngle: number){\n // rotation is in radians\n const res: Point[] = [];\n for(let index = 0; index < this.controlPoints.length; index++){\n res.push(PointCal.rotatePoint(PointCal.addVector(this.controlPoints[index], translation), rotationAngle));\n }\n return res;\n }\n\n getLineIntersections(line: Line): number[]{\n const translationRotation = line.getTranslationRotationToAlginXAxis();\n const res: number[] = [];\n const alignedControlPoints = this.translateRotateControlPoints(translationRotation.translation, translationRotation.rotationAngle);\n const coefficients = this.getCoefficientOfTTermsWithControlPoints(alignedControlPoints);\n let yCoefficients = [0, 0, 0, 0];\n coefficients.forEach((coefficient, index)=>{\n yCoefficients[3 - index] = coefficient.y;\n });\n\n const yRoots = solveCubic(yCoefficients[0], yCoefficients[1], yCoefficients[2], yCoefficients[3]);\n yRoots.forEach((root)=>{\n if(root >= 0 && root <= 1){\n if(line.pointInLine(this.get(root))){\n res.push(root);\n }\n }\n });\n\n return res;\n }\n\n getSelfIntersections(): {selfT: number, otherT: number}[]{\n const [subCurveControlPoints1, subCurveControlPoints2] = this.split(0.5);\n const subCurve1 = new BCurve(subCurveControlPoints1);\n const subCurve2 = new BCurve(subCurveControlPoints2);\n let initialRes = getIntersectionsBetweenCurves(subCurve1, subCurve2);\n initialRes.forEach((intersection)=>{\n intersection.selfT = intersection.selfT * 0.5;\n intersection.otherT = intersection.otherT * 0.5 + 0.5;\n });\n initialRes.shift();\n return initialRes;\n }\n\n getCircleIntersections(circleCenter: Point, circleRadius: number): {intersection: Point, tVal: number}[]{\n const LUT = this.getLUTWithTVal(500);\n let distanceError = Number.MAX_VALUE;\n let preliminaryIntersectionIndex = 0;\n let preliminaryIntersectionPoint: Point = LUT[0].point;\n let preliminaryIntersectionTVal = LUT[0].tVal;\n LUT.forEach((curvePoint, index)=>{\n let curDistanceError = Math.abs(PointCal.distanceBetweenPoints(circleCenter, curvePoint.point));\n if (curDistanceError < distanceError){\n distanceError = curDistanceError;\n preliminaryIntersectionIndex = index;\n }\n });\n const LUTD = LUT.map((curvePoint, index)=>{\n return {...curvePoint, distance: 0};\n })\n distanceError = Number.MAX_VALUE;\n let start = 0;\n let count = 0;\n let indices: number[] = [];\n while(++count < 25){\n let i = this.findClosest(circleCenter.x, circleCenter.y, LUTD, circleRadius, 5, LUTD[start - 2]?.distance, LUTD[start - 1]?.distance);\n if (i < start) break;\n if (i > 0 && i == start) break;\n indices.push(i);\n start = i + 2;\n }\n const finalList: {intersection: Point, tVal: number}[] = [];\n indices.forEach((index)=>{\n let res = this.refineBinary(this, circleCenter.x, circleCenter.y, LUTD, index, circleRadius);\n if (res != undefined){\n finalList.push({intersection: res.point, tVal: res.tVal});\n }\n })\n return finalList;\n }\n\n advanceAtTWithLength(tVal: number, length: number): AdvanceAtTWithLengthRes{\n const currentLength = this.lengthAtT(tVal);\n const targetLength = currentLength + length;\n \n // Handle edge cases first\n if(tVal === 0 && length < 0){\n return {type: \"beforeCurve\", remainLength: -length};\n }\n if(tVal === 1 && length > 0){\n return {type: \"afterCurve\", remainLength: length};\n }\n if(targetLength > this.fullLength){\n return {type: \"afterCurve\", remainLength: targetLength - this.fullLength};\n } else if(targetLength < 0){\n return {type: \"beforeCurve\", remainLength: -targetLength};\n }\n\n // Use LUT for binary search\n if(this.arcLengthLUT.arcLengthLUT.length === 0){\n this.arcLengthLUT = this.getArcLengthLUT(1000);\n }\n const points = this.arcLengthLUT.arcLengthLUT;\n let low = 0;\n let high = points.length - 1;\n \n // Binary search to find the interval containing targetLength\n while (low <= high){\n const mid = Math.floor((low + high) / 2);\n const midLength = points[mid].length;\n \n if (approximately(midLength, targetLength, 0.01)) {\n // Found exact match\n const resultTVal = points[mid].tVal;\n const point = this.get(resultTVal);\n return {type: \"withinCurve\", tVal: resultTVal, point: point};\n } else if (midLength < targetLength){\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n \n // After binary search, 'high' points to the largest index with length < targetLength\n // and 'low' points to the smallest index with length >= targetLength\n \n // Handle edge cases\n if (high < 0) {\n // targetLength is smaller than the first point's length\n high = 1;\n low = 0;\n }\n \n if (low >= points.length) {\n // targetLength is larger than the last point's length\n high = points.length - 1;\n low = points.length - 2;\n }\n \n // Interpolate between points[high] and points[low]\n const p1 = points[high];\n const p2 = points[low];\n \n // Linear interpolation\n const lengthRange = p2.length - p1.length;\n const tRange = p2.tVal - p1.tVal;\n \n if (lengthRange === 0) {\n // Both points have the same length, use the first one\n const point = this.get(p1.tVal);\n return {type: \"withinCurve\", tVal: p1.tVal, point: point};\n }\n \n const ratio = (targetLength - p1.length) / lengthRange;\n const interpolatedT = p1.tVal + ratio * tRange;\n \n // Clamp to valid range\n const clampedT = Math.max(0, Math.min(1, interpolatedT));\n const point = this.get(clampedT);\n \n return {type: \"withinCurve\", tVal: clampedT, point: point};\n }\n\n advanceByDistance(startT: number, distance: number): AdvanceAtTWithLengthRes {\n let currentT = startT;\n let remainingDistance = distance;\n const stepSize = 0.01; // Adjust for precision vs performance\n\n if(distance > this.fullLength){\n return {type: \"afterCurve\", remainLength: distance - this.fullLength};\n } else if(distance < 0){\n return {type: \"beforeCurve\", remainLength: -distance};\n }\n \n while (remainingDistance > 0 && currentT < 1) {\n const currentPoint = this.get(currentT);\n const nextT = Math.min(currentT + stepSize, 1);\n const nextPoint = this.get(nextT);\n \n const segmentLength = Math.sqrt(\n Math.pow(nextPoint.x - currentPoint.x, 2) + \n Math.pow(nextPoint.y - currentPoint.y, 2)\n );\n \n if (segmentLength >= remainingDistance) {\n // Interpolate within this segment\n const ratio = remainingDistance / segmentLength;\n return {type: \"withinCurve\", tVal: currentT + ratio * (nextT - currentT), point: this.get(currentT + ratio * (nextT - currentT))};\n }\n \n remainingDistance -= segmentLength;\n currentT = nextT;\n }\n \n return {type: \"withinCurve\", tVal: currentT, point: this.get(currentT)};\n }\n\n refineBinary(curve: BCurve, x: number, y: number, LUT: {point: Point, tVal: number, distance: number}[], i: number, targetDistance=0, epsilon=0.01) {\n let q: {point: Point, tVal: number, distance: number} | undefined = LUT[i],\n count = 1,\n distance = Number.MAX_SAFE_INTEGER;\n \n do {\n let i1 = i === 0 ? 0 : i - 1,\n i2 = i === LUT.length - 1 ? LUT.length - 1 : i + 1,\n t1 = LUT[i1].tVal,\n t2 = LUT[i2].tVal,\n lut: {point: Point, tVal: number, distance: number}[] = [],\n step = (t2 - t1) / 4;\n \n if (step < 0.001) break;\n \n lut.push(LUT[i1]);\n for (let j = 1; j <= 3; j++) {\n let n = curve.get(t1 + j * step);\n let nDistance = Math.abs(PointCal.distanceBetweenPoints(n, {x: x, y: y}) - targetDistance);\n if (nDistance < distance) {\n distance = nDistance;\n q = {point: n, tVal: t1 + j * step, distance: nDistance};\n i = j;\n }\n lut.push({point: n, tVal: t1 + j * step, distance: nDistance});\n }\n lut.push(LUT[i2]);\n \n // update the LUT to be our new five point LUT, and run again.\n LUT = lut;\n \n // The \"count\" test is mostly a safety measure: it will\n // never kick in, but something that _will_ terminate is\n // always better than while(true). Never use while(true)\n } while (count++ < 25);\n \n // If we're trying to hit a target, discard the result if\n // it is not close enough to the target.\n if (targetDistance && distance > epsilon) {\n q = undefined;\n }\n \n return q;\n }\n\n findClosest(x: number, y: number, LUT: {point: Point, tVal: number, distance: number}[], circleRadius: number, distanceEpsilon = 5, pd2?: number, pd1?: number) {\n let distance = Number.MAX_SAFE_INTEGER,\n prevDistance2 = pd2 || distance,\n prevDistance1 = pd1 || distance,\n i = -1;\n \n for (let index=0, e=LUT.length; index<e; index++){\n let p = LUT[index].point;\n LUT[index].distance = Math.abs(PointCal.distanceBetweenPoints({x:x, y:y}, p) - circleRadius);\n \n // Realistically, there's only going to be an intersection if\n // the distance to the circle center is already approximately\n // the circle's radius.\n if (prevDistance1 < distanceEpsilon && prevDistance2 > prevDistance1 && prevDistance1 < LUT[index].distance) {\n i = index - 1;\n break;\n }\n \n if (LUT[index].distance < distance) {\n distance = LUT[index].distance;\n }\n \n prevDistance2 = prevDistance1;\n prevDistance1 = LUT[index].distance;\n }\n \n return i;\n }\n\n getCurveIntersections(curve: BCurve, deduplicationTolerance?: number): {selfT: number, otherT: number}[]{\n return getIntersectionsBetweenCurves(this, curve, deduplicationTolerance);\n }\n\n get AABB():{min: Point, max: Point}{\n const extrema = this.getExtrema();\n const tVals = [0, 1];\n let min: Point = {x: Number.MAX_VALUE, y: Number.MAX_VALUE};\n let max: Point = {x: -Number.MAX_VALUE, y: -Number.MAX_VALUE};\n extrema.x.forEach((tVal)=>{\n tVals.push(tVal);\n });\n extrema.y.forEach((tVal)=>{\n tVals.push(tVal);\n });\n tVals.forEach((tVal)=>{\n const curPoint = this.get(tVal);\n min.x = Math.min(min.x, curPoint.x);\n min.y = Math.min(min.y, curPoint.y);\n max.x = Math.max(max.x, curPoint.x);\n max.y = Math.max(max.y, curPoint.y);\n });\n\n return {min:min, max:max};\n }\n\n normal(tVal: number): {tVal: number, direction: Point} {\n const d = this.derivative(tVal);\n const q = Math.sqrt(d.x * d.x + d.y * d.y);\n return {tVal, direction: {x: -d.y / q, y: d.x / q}};\n }\n}\n\nexport function reduce(curve: BCurve) {\n let i: number,\n t1 = 0,\n t2 = 0,\n step = 0.01,\n segment: BCurve,\n pass1: BCurve[] = [],\n pass2: BCurve[] = [];\n \n // first pass: split on extrema\n let extrema = curve.getExtrema().x;\n if (extrema.indexOf(0) === -1) {\n extrema = [0].concat(extrema);\n }\n if (extrema.indexOf(1) === -1) {\n extrema.push(1);\n }\n for (t1 = extrema[0], i = 1; i < extrema.length; i++) {\n t2 = extrema[i];\n segment = curve.splitAndTakeMidCurve(t1, t2);\n pass1.push(segment);\n t1 = t2;\n }\n \n // second pass: further reduce these segments to simple segments\n pass1.forEach(p1 => {\n t1 = 0;\n t2 = 0;\n while (t2 <= 1) {\n for (t2 = t1 + step; t2 <= 1 + step; t2 += step) {\n // Clamp t2 to valid range\n const clampedT2 = Math.min(t2, 1);\n segment = p1.splitAndTakeMidCurve(t1, clampedT2);\n if (!curveIsSimple(segment)) {\n t2 -= step;\n if (Math.abs(t1 - t2) < step) {\n // we can never form a reduction\n return [];\n }\n const finalT2 = Math.min(t2, 1);\n segment = p1.splitAndTakeMidCurve(t1, finalT2);\n pass2.push(segment);\n t1 = finalT2;\n break;\n }\n }\n }\n if (t1 < 1) {\n segment = p1.splitAndTakeMidCurve(t1, 1);\n pass2.push(segment);\n }\n });\n \n return pass2;\n}\n\nfunction raiseCurveOrder(curve: BCurve): BCurve {\n const p = curve.getControlPoints(),\n np = [p[0]],\n k = p.length;\n for (let i = 1; i < k; i++) {\n const pi = p[i];\n const pim = p[i - 1];\n np[i] = {\n x: ((k - i) / k) * pi.x + (i / k) * pim.x,\n y: ((k - i) / k) * pi.y + (i / k) * pim.y,\n };\n }\n np[k] = p[k - 1];\n return new BCurve(np);\n}\n\n// Function overloads for different return types\nexport function offset(curve: BCurve, t: number): BCurve[];\nexport function offset(curve: BCurve, t: number, d: number): {c: Point, n: Point, x: number, y: number};\nexport function offset(curve: BCurve, t: number, d?: number | undefined) {\n if (d !== undefined) {\n const c = curve.get(t),\n n = curve.normal(t).direction;\n const ret = {\n c: c,\n n: n,\n x: c.x + n.x * d,\n y: c.y + n.y * d,\n };\n // if (this._3d) {\n // ret.z = c.z + n.z * d;\n // }\n return ret;\n }\n\n // Native offset implementation based on bezier-js algorithm\n const points = curve.getControlPoints();\n const linear = curveIsLinear(curve);\n\n if (linear) {\n const nv = curve.normal(0).direction,\n coords = points.map(function (p) {\n const ret = {\n x: p.x + t * nv.x,\n y: p.y + t * nv.y,\n };\n return ret;\n });\n return [new BCurve(coords)];\n }\n\n // For non-linear curves, reduce to simple segments and scale each\n return reduce(curve).map(function (s) {\n if (curveIsLinear(s)) {\n return offset(s, t)[0];\n }\n return scaleCurve(s, t);\n });\n}\n\nexport function offset2(curve: BCurve, d: number): Point[]{\n const lut = curve.getLUTWithTVal(100);\n\n const res = lut.map((item)=>{\n const derivative = PointCal.unitVector(curve.derivative(item.tVal));\n const normal = {x: -derivative.y, y: derivative.x};\n const offsetPoint = {x: item.point.x + normal.x * d, y: item.point.y + normal.y * d};\n return offsetPoint;\n });\n\n return res;\n}\n\n// Helper function for line-line intersection (ported from bezier-js utils)\nfunction lli4(p1: Point, p2: Point, p3: Point, p4: Point): Point | false {\n const x1 = p1.x, y1 = p1.y,\n x2 = p2.x, y2 = p2.y,\n x3 = p3.x, y3 = p3.y,\n x4 = p4.x, y4 = p4.y;\n return lli8(x1, y1, x2, y2, x3, y3, x4, y4);\n}\n\nfunction lli8(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number): Point | false {\n const nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4);\n const ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4);\n const d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);\n if (d == 0) {\n return false;\n }\n return { x: nx / d, y: ny / d };\n}\n\nfunction curveIsLinear(curve: BCurve): boolean{\n const order = curve.getControlPoints().length - 1;\n const points = curve.getControlPoints();\n const alignedPoints = alignPointsToLine(points, {p1: points[0], p2: points[order]});\n const baseLength = PointCal.distanceBetweenPoints(points[0], points[order]);\n\n // Sum of distances from the line (y coordinates in aligned space)\n const linear = alignedPoints.reduce((t, p) => t + Math.abs(p.y), 0) < baseLength / 50;\n\n return linear;\n}\n\n\nfunction scaleCurve(curve: BCurve, d: number | ((t: number) => number)): BCurve {\n const order = curve.getControlPoints().length - 1;\n let distanceFn: ((t: number) => number) | undefined = undefined;\n\n if (typeof d === \"function\") {\n distanceFn = d;\n }\n\n if (distanceFn && order === 2) {\n return scaleCurve(raiseCurveOrder(curve), distanceFn);\n }\n\n const points = curve.getControlPoints();\n\n // Check if curve is linear\n if (curveIsLinear(curve)) {\n return translate(\n curve,\n curve.normal(0).direction,\n distanceFn ? distanceFn(0) : d as number,\n distanceFn ? distanceFn(1) : d as number\n );\n }\n\n const r1 = distanceFn ? distanceFn(0) : d as number;\n const r2 = distanceFn ? distanceFn(1) : d as number;\n \n // Get offset points at endpoints to find the scaling origin\n const v = [offset(curve, 0, 10), offset(curve, 1, 10)];\n const np: Point[] = [];\n const o = lli4(v[0] as any, (v[0] as any).c, v[1] as any, (v[1] as any).c);\n\n if (!o) {\n // Fallback: use simple translation for problematic curves\n return translate(\n curve,\n curve.normal(0).direction,\n r1,\n r2\n );\n }\n\n // Move endpoint control points by distance along normal\n [0, 1].forEach(function (t) {\n const p = JSON.parse(JSON.stringify(points[t * order]));\n const vt = v[t] as any;\n p.x += (t ? r2 : r1) * vt.n.x;\n p.y += (t ? r2 : r1) * vt.n.y;\n np[t * order] = p;\n });\n\n if (!distanceFn) {\n // Move control points to lie on the intersection of the offset\n // derivative vector, and the origin-through-control vector\n [0, 1].forEach((t) => {\n if (order === 2 && !!t) return;\n const p = np[t * order];\n const derivativeAtT = curve.derivative(t);\n const p2 = { x: p.x + derivativeAtT.x, y: p.y + derivativeAtT.y };\n const intersection = lli4(p, p2, o, points[t + 1]);\n if (intersection) {\n np[t + 1] = intersection;\n } else {\n // Fallback: use original control point with simple offset\n const originalPoint = points[t + 1];\n const normal = curve.normal((t + 1) / order).direction;\n np[t + 1] = {\n x: originalPoint.x + (t ? r2 : r1) * normal.x,\n y: originalPoint.y + (t ? r2 : r1) * normal.y\n };\n }\n });\n return new BCurve(np);\n }\n\n // For function-based distances, move control points by distance\n // to ensure correct tangent at endpoints\n [0, 1].forEach(function (t) {\n if (order === 2 && !!t) return;\n const p = points[t + 1];\n const ov = {\n x: p.x - o.x,\n y: p.y - o.y,\n };\n let rc = distanceFn!((t + 1) / order);\n const m = Math.sqrt(ov.x * ov.x + ov.y * ov.y);\n ov.x /= m;\n ov.y /= m;\n np[t + 1] = {\n x: p.x + rc * ov.x,\n y: p.y + rc * ov.y,\n };\n });\n return new BCurve(np);\n}\n\nfunction alignPointsToLine(points: Point[], line: {p1: Point, p2: Point}) {\n const tx = line.p1.x,\n ty = line.p1.y,\n a = -Math.atan2(line.p2.y - ty, line.p2.x - tx),\n d = function (v: Point) {\n return {\n x: (v.x - tx) * Math.cos(a) - (v.y - ty) * Math.sin(a),\n y: (v.x - tx) * Math.sin(a) + (v.y - ty) * Math.cos(a),\n };\n };\n return points.map(d);\n};\n\nfunction map(v: number, ds: number, de: number, ts: number, te: number): number {\n const d1 = de - ds, // source range size\n d2 = te - ts, // target range size \n v2 = v - ds, // offset from source start\n r = v2 / d1; // ratio within source range\n return ts + d2 * r; // mapped value in target range\n}\n\nexport class TValOutofBoundError extends Error{\n constructor(message: string){\n super(message);\n }\n}\n\nexport type Point = {\n x: number;\n y: number;\n z?: number;\n}\n\nexport function AABBIntersects(AABB1: {min: Point, max: Point}, AABB2: {min: Point, max: Point}): boolean{\n if ((AABB1.min.x <= AABB2.max.x && AABB2.min.x <= AABB1.max.x) && (AABB1.min.y <= AABB2.max.y && AABB2.min.y <= AABB1.max.y)){\n return true;\n }\n return false;\n}\n\nexport function approximately (a: number, b: number, precision?: number) {\n const epsilon = 0.000001\n return Math.abs(a - b) <= (precision || epsilon);\n}\n\nexport function cuberoot2(v:number) {\n if(v<0) return -Math.pow(-v,1/3);\n return Math.pow(v,1/3);\n}\n\nexport function accept(t: number) {\n return 0 <= t && t <=1;\n}\n\nexport function getCubicRoots(pa: number, pb: number, pc: number, pd: number) {\n let a = (3*pa - 6*pb + 3*pc),\n b = (-3*pa + 3*pb),\n c = pa,\n d = (-pa + 3*pb - 3*pc + pd);\n\n // do a check to see whether we even need cubic solving:\n if (approximately(d,0)) {\n // this is not a cubic curve.\n if (approximately(a,0)) {\n // in fact, this is not a quadratic curve either.\n if (approximately(b,0)) {\n // in fact in fact, there are no solutions.\n return [];\n }\n // linear solution\n return [-c / b].filter(accept);\n }\n // quadratic solution\n let q = Math.sqrt(b*b - 4*a*c), a2 = 2*a;\n return [(q-b)/a2, (-b-q)/a2].filter(accept)\n }\n\n // at this point, we know we need a cubic solution.\n\n a /= d;\n b /= d;\n c /= d;\n\n let p = (3*b - a*a)/3,\n p3 = p/3,\n q = (2*a*a*a - 9*a*b + 27*c)/27,\n q2 = q/2,\n discriminant = q2*q2 + p3*p3*p3;\n\n // and some variables we're going to use later on:\n let u1, v1, root1, root2, root3;\n\n // three possible real roots:\n if (discriminant < 0) {\n let mp3 = -p/3,\n mp33 = mp3*mp3*mp3,\n r = Math.sqrt( mp33 ),\n t = -q / (2*r),\n cosphi = t<-1 ? -1 : t>1 ? 1 : t,\n phi = Math.acos(cosphi),\n crtr = cuberoot2(r),\n t1 = 2*crtr;\n root1 = t1 * Math.cos(phi/3) - a/3;\n root2 = t1 * Math.cos((phi+2*Math.PI)/3) - a/3;\n root3 = t1 * Math.cos((phi+4*Math.PI)/3) - a/3;\n return [root1, root2, root3].filter(accept);\n }\n\n // three real roots, but two of them are equal:\n if(discriminant === 0) {\n u1 = q2 < 0 ? cuberoot2(-q2) : -cuberoot2(q2);\n root1 = 2*u1 - a/3;\n root2 = -u1 - a/3;\n return [root1, root2].filter(accept);\n }\n\n // one real root, two complex roots\n var sd = Math.sqrt(discriminant);\n u1 = cuberoot2(sd - q2);\n v1 = cuberoot2(sd + q2);\n root1 = u1 - v1 - a/3;\n return [root1].filter(accept);\n}\n\nexport function getIntersectionsBetweenCurves(curve: BCurve, curve2: BCurve, deduplicationTolerance: number = 0.01): {selfT: number, otherT: number}[]{\n const threshold = 0.5;\n let pairs: {curve1: {curve: BCurve, startTVal: number, endTVal: number}, curve2: {curve: BCurve, startTVal: number, endTVal: number}}[] = [{curve1: {curve: curve, startTVal: 0, endTVal: 1}, curve2: {curve: curve2, startTVal: 0, endTVal: 1}}];\n const finalRes = [];\n while (pairs.length > 0){\n let curLength = pairs.length;\n for(let index = 0; index < curLength; index++){\n let pair = pairs.shift();\n if (pair == undefined){\n break;\n }\n let aabb1 = pair.curve1.curve.AABB;\n let aabb2 = pair.curve2.curve.AABB;\n let intersects = AABBIntersects(aabb1, aabb2);\n if(pair.curve1.curve.fullLength < threshold && pair.curve2.curve.fullLength < threshold){\n finalRes.push({intersection: pair.curve1.curve.get(0.5), tVal1: (pair.curve1.startTVal + pair.curve1.endTVal) * 0.5, tVal2: (pair.curve2.startTVal + pair.curve2.endTVal) * 0.5});\n continue;\n }\n if (intersects){\n let [subCurveControlPoints1, subCurveControlPoints2] = pair.curve1.curve.split(0.5);\n let [subCurveControlPoints3, subCurveControlPoints4] = pair.curve2.curve.split(0.5);\n pairs.push({\n curve1: {\n curve: new BCurve(subCurveControlPoints1), \n startTVal: pair.curve1.startTVal, \n endTVal: pair.curve1.startTVal + (pair.curve1.endTVal - pair.curve1.startTVal) * 0.5\n }, curve2: {\n curve: new BCurve(subCurveControlPoints3),\n startTVal: pair.curve2.startTVal,\n endTVal: pair.curve2.startTVal + (pair.curve2.endTVal - pair.curve2.startTVal) * 0.5\n }});\n\n pairs.push({\n curve1: {\n curve: new BCurve(subCurveControlPoints1), \n startTVal: pair.curve1.startTVal, \n endTVal: pair.curve1.startTVal + (pair.curve1.endTVal - pair.curve1.startTVal) * 0.5\n }, curve2: {\n curve: new BCurve(subCurveControlPoints4),\n startTVal: pair.curve2.startTVal + (pair.curve2.endTVal - pair.curve2.startTVal) * 0.5,\n endTVal: pair.curve2.endTVal\n }});\n\n pairs.push({\n curve1: {\n curve: new BCurve(subCurveControlPoints2), \n startTVal: pair.curve1.startTVal + (pair.curve1.endTVal - pair.curve1.startTVal) * 0.5 ,\n endTVal: pair.curve1.endTVal \n }, curve2: {\n curve: new BCurve(subCurveControlPoints3),\n startTVal: pair.curve2.startTVal,\n endTVal: pair.curve2.startTVal + (pair.curve2.endTVal - pair.curve2.startTVal) * 0.5\n }});\n\n pairs.push({\n curve1: {\n curve: new BCurve(subCurveControlPoints2), \n startTVal: pair.curve1.startTVal + (pair.curve1.endTVal - pair.curve1.startTVal) * 0.5 ,\n endTVal: pair.curve1.endTVal \n }, curve2: {\n curve: new BCurve(subCurveControlPoints4),\n startTVal: pair.curve2.startTVal + (pair.curve2.endTVal - pair.curve2.startTVal) * 0.5,\n endTVal: pair.curve2.endTVal\n }});\n }\n\n }\n }\n\n // Improved deduplication logic that handles close tvals on both curves\n const tVals: {selfT: number, otherT: number}[] = [];\n \n // Sort intersections by tVal1 for more predictable deduplication\n finalRes.sort((a, b) => a.tVal1 - b.tVal1);\n \n for (const intersection of finalRes) {\n let isDuplicate = false;\n \n // Check against all existing intersections\n for (const existing of tVals) {\n // Check if this intersection is close to an existing one on either curve\n const selfTClose = approximately(intersection.tVal1, existing.selfT, deduplicationTolerance);\n const otherTClose = approximately(intersection.tVal2, existing.otherT, deduplicationTolerance);\n \n // Consider it a duplicate if both t-values are close\n if (selfTClose && otherTClose) {\n isDuplicate = true;\n break;\n }\n \n // Also check for cases where intersections might be very close on the same curve\n // This handles cases where curves are nearly tangent or have very close intersections\n const selfTVeryClose = approximately(intersection.tVal1, existing.selfT, deduplicationTolerance * 10);\n const otherTVeryClose = approximately(intersection.tVal2, existing.otherT, deduplicationTolerance * 10);\n \n if (selfTVeryClose || otherTVeryClose) {\n // Additional check: if the intersection points are very close spatially\n const point1 = curve.get(intersection.tVal1);\n const point2 = curve2.get(intersection.tVal2);\n const existingPoint1 = curve.get(existing.selfT);\n const existingPoint2 = curve2.get(existing.otherT);\n \n const distance1 = PointCal.distanceBetweenPoints(point1, existingPoint1);\n const distance2 = PointCal.distanceBetweenPoints(point2, existingPoint2);\n \n // If both intersection points are spatially very close, consider it a duplicate\n if (distance1 < deduplicationTolerance * 100 && distance2 < deduplicationTolerance * 100) {\n isDuplicate = true;\n break;\n }\n }\n }\n \n if (!isDuplicate) {\n tVals.push({selfT: intersection.tVal1, otherT: intersection.tVal2});\n }\n }\n \n return tVals;\n}\n\nexport function solveCubic(a: number, b: number, c: number, d: number) {\n if (Math.abs(a) < 1e-8) { // Quadratic case, ax^2+bx+c=0\n a = b; b = c; c = d;\n if (Math.abs(a) < 1e-8) { // Linear case, ax+b=0\n a = b; b = c;\n if (Math.abs(a) < 1e-8) // Degenerate case\n return [];\n return [-b/a];\n }\n\n let D = b*b - 4*a*c;\n if (Math.abs(D) < 1e-8)\n return [-b/(2*a)];\n else if (D > 0)\n return [(-b+Math.sqrt(D))/(2*a), (-b-Math.sqrt(D))/(2*a)];\n return [];\n }\n\n // Convert to depressed cubic t^3+pt+q = 0 (subst x = t - b/3a)\n let p = (3*a*c - b*b)/(3*a*a);\n let q = (2*b*b*b - 9*a*b*c + 27*a*a*d)/(27*a*a*a);\n let roots: number[];\n\n if (Math.abs(p) < 1e-8) { // p = 0 -> t^3 = -q -> t = -q^1/3\n roots = [cuberoot(-q)];\n } else if (Math.abs(q) < 1e-8) { // q = 0 -> t^3 + pt = 0 -> t(t^2+p)=0\n roots = [0].concat(p < 0 ? [Math.sqrt(-p), -Math.sqrt(-p)] : []);\n } else {\n let D = q*q/4 + p*p*p/27;\n if (Math.abs(D) < 1e-8) { // D = 0 -> two roots\n roots = [-1.5*q/p, 3*q/p];\n } else if (D > 0) { // Only one real root and two complex roots\n let u = cuberoot(-q/2 - Math.sqrt(D));\n let v = cuberoot(-q/2 + Math.sqrt(D));\n //console.log(\"Complext Root 1 real:\", -(u+v)/2.0 - a / 3.0, \"imaginary:\", Math.sqrt(3) / 2.0 * (v - u));\n //console.log(\"Complext Root 2 real:\", -(u+v)/2.0 - a / 3.0, \"imaginary:\",-1 * Math.sqrt(3) / 2.0 * (v - u));\n\n roots = [u - p/(3*u)];\n } else { // D < 0, three roots, but needs to use complex numbers/trigonometric solution\n let u = 2*Math.sqrt(-p/3);\n let t = Math.acos(3*q/p/u)/3; // D < 0 implies p < 0 and acos argument in [-1..1]\n let k = 2*Math.PI/3;\n roots = [u*Math.cos(t), u*Math.cos(t-k), u*Math.cos(t-2*k)];\n }\n }\n\n // Convert back from depressed cubic\n for (let i = 0; i < roots.length; i++)\n roots[i] -= b/(3*a);\n\n return roots;\n}\n\nexport function cuberoot(x: number) {\n var y = Math.pow(Math.abs(x), 1/3);\n return x < 0 ? -y : y;\n}\n\nexport function computeWithControlPoints(tVal: number, controlPoints: Point[]): Point{\n let points = [...controlPoints];\n while (points.length > 1) {\n let lowerLevelPoints = points.slice(1);\n for(let index = 0; index < lowerLevelPoints.length; index++){\n lowerLevelPoints[index] = PointCal.addVector(PointCal.multiplyVectorByScalar(points[index], (1 - tVal)), PointCal.multiplyVectorByScalar(points[index + 1], tVal));\n }\n points = lowerLevelPoints;\n }\n return points[0];\n}\n\nfunction curveIsSimple(curve: BCurve): boolean {\n if (curve.getControlPoints().length === 4) {\n const points = curve.getControlPoints();\n const p0ToP3Vector = PointCal.subVector(points[3], points[0]);\n const p0ToP1Vector = PointCal.subVector(points[1], points[0]);\n const p0ToP2Vector = PointCal.subVector(points[2], points[0]);\n \n const a1 = PointCal.angleFromA2B(p0ToP3Vector, p0ToP1Vector);\n const a2 = PointCal.angleFromA2B(p0ToP3Vector, p0ToP2Vector);\n if ((a1 > 0 && a2 < 0) || (a1 < 0 && a2 > 0)) return false;\n }\n const n1 = curve.normal(0).direction;\n const n2 = curve.normal(1).direction;\n let s = n1.x * n2.x + n1.y * n2.y;\n // if (this._3d) {\n // s += n1.z * n2.z;\n // }\n return Math.abs(Math.acos(s)) < Math.PI / 3;\n }\n\n\n\nfunction translate(curve: BCurve, vector: Point, d1: number, d2: number){\n const order = curve.getControlPoints().length - 1;\n const points = curve.getControlPoints();\n const d = points.map((_, i: number) => (1 - i / order) * d1 + (i / order) * d2);\n return new BCurve(points.map((p, i) => ({x: p.x + d[i] * vector.x, y: p.y + d[i] * vector.y})));\n}\n",
6
- "import { PointCal, Point } from \"@ue-too/math\";\n\nexport class Line {\n private startPoint: Point;\n private endPoint: Point;\n\n constructor(startPoint: Point, endPoint: Point){\n this.startPoint = startPoint;\n this.endPoint = endPoint;\n }\n\n getStartPoint(): Point{\n return this.startPoint;\n }\n\n getEndPoint(): Point{\n return this.endPoint;\n }\n\n intersectionWithAnotherLine(lineToIntersect: Line){\n return getLineIntersection(this.startPoint, this.endPoint, lineToIntersect.getStartPoint(), lineToIntersect.getEndPoint());\n }\n\n projectPoint(point: Point){\n return projectPointOntoLine(point, this.getStartPoint(), this.getEndPoint());\n }\n\n length(): number{\n return PointCal.distanceBetweenPoints(this.startPoint, this.endPoint);\n }\n \n getTranslationRotationToAlginXAxis(){\n const translation = PointCal.subVector({x: 0, y: 0}, this.startPoint);\n const rotationAngle = PointCal.angleFromA2B(PointCal.subVector(this.endPoint, this.startPoint), {x: 1, y: 0});\n\n return {translation, rotationAngle};\n }\n\n pointInLine(point: Point): boolean{\n const baseVector = PointCal.unitVectorFromA2B(this.startPoint, this.endPoint);\n const start2PointVector = PointCal.subVector(point, this.startPoint);\n const length = PointCal.dotProduct(start2PointVector, baseVector);\n const start2PointUnitVector = PointCal.unitVector(start2PointVector);\n const errorThreshold = PointCal.distanceBetweenPoints(this.startPoint, this.endPoint) * 0.0001;\n return length <= PointCal.distanceBetweenPoints(this.startPoint, this.endPoint) && length >= 0 && Math.abs(start2PointUnitVector.x - baseVector.x) < 0.0001 && Math.abs(start2PointUnitVector.y - baseVector.y) < 0.0001;\n }\n\n lerp(ratio: number): Point {\n return PointCal.linearInterpolation(this.startPoint, this.endPoint, ratio);\n }\n}\n\nexport function getLineIntersection(startPoint: Point, endPoint: Point, startPoint2: Point, endPoint2: Point):{\n intersects: boolean,\n intersection?: Point,\n offset?: number\n}{\n const numerator = (endPoint2.x - startPoint2.x) * (startPoint.y - startPoint2.y) - (endPoint2.y - startPoint2.y) * (startPoint.x - startPoint2.x);\n const denominator = (endPoint2.y - startPoint2.y) * (endPoint.x - startPoint.x) - (endPoint2.x - startPoint2.x) * (endPoint.y - startPoint.y);\n \n if (denominator === 0){\n return {intersects: false};\n }\n const t = numerator / denominator;\n if (t >= 0 && t <= 1){\n return {\n intersects: true, \n intersection: PointCal.linearInterpolation(startPoint, endPoint, t),\n offset: t\n }\n } else {\n return {\n intersects: false,\n }\n }\n\n}\n\nexport function projectPointOntoLine(point: Point, lineStartPoint: Point, lineEndPoint: Point): {\n within: boolean,\n projectionPoint?: Point,\n offset?: number\n}{\n const baseVector = PointCal.unitVector(PointCal.subVector(lineEndPoint, lineStartPoint));\n const vectorToPoint = PointCal.subVector(point, lineStartPoint);\n const res = PointCal.dotProduct(vectorToPoint, baseVector);\n if (res < 0 || res > PointCal.magnitude(PointCal.subVector(lineEndPoint, lineStartPoint))){\n return {\n within: false,\n };\n }\n return {\n within: true,\n projectionPoint: PointCal.addVector(lineStartPoint, PointCal.multiplyVectorByScalar(baseVector, res)),\n offset: res / PointCal.magnitude(PointCal.subVector(lineEndPoint, lineStartPoint))\n };\n\n}\n",
7
- "import { Point, PointCal } from \"@ue-too/math\";\n\nexport type HandleType = \"ALIGNED\" | \"VECTOR\" | \"FREE\";\n\nexport type HandlePoint = {\n position: Point;\n type: HandleType;\n}\n\nexport class ControlPoint {\n\n private position: Point;\n private leftHandle: HandlePoint;\n private rightHandle: HandlePoint;\n\n constructor(position: Point, leftHandle: HandlePoint, rightHandle: HandlePoint){\n this.position = position;\n this.leftHandle = leftHandle;\n this.rightHandle = rightHandle;\n }\n\n setPosition(destinationPosition: Point, prevControlPoint: ControlPoint | undefined, nextControlPoint: ControlPoint | undefined){\n let diff = PointCal.subVector(destinationPosition, this.position);\n this.position = destinationPosition;\n this.leftHandle.position = PointCal.addVector(this.leftHandle.position, diff);\n this.rightHandle.position = PointCal.addVector(this.rightHandle.position, diff);\n if(this.leftHandle.type == \"VECTOR\" && prevControlPoint){\n let relativeVector = PointCal.subVector(prevControlPoint.getPosition(), this.position);\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n this.leftHandle.position = PointCal.addVector(this.position, relativeVector);\n if(this.rightHandle.type == \"ALIGNED\"){\n let relativeVector = PointCal.subVector(this.rightHandle.position, this.position);\n let mag = PointCal.magnitude(relativeVector);\n let direction = PointCal.unitVectorFromA2B(this.leftHandle.position, this.position);\n this.rightHandle.position = PointCal.addVector(this.position, PointCal.multiplyVectorByScalar(direction, mag));\n }\n }\n if(this.rightHandle.type == \"VECTOR\" && nextControlPoint){\n let relativeVector = PointCal.subVector(nextControlPoint.getPosition(), this.position);\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n this.rightHandle.position = PointCal.addVector(this.position, relativeVector);\n if(this.leftHandle.type == \"ALIGNED\"){\n let mag = PointCal.distanceBetweenPoints(this.leftHandle.position, this.position);\n let direction = PointCal.subVector(this.position, this.rightHandle.position);\n this.leftHandle.position = PointCal.addVector(this.position, PointCal.multiplyVectorByScalar(direction, mag));\n }\n }\n if(prevControlPoint !== undefined && prevControlPoint.getRightHandle().type == \"VECTOR\"){\n let relativeVector = PointCal.subVector(this.position, prevControlPoint.getPosition());\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n prevControlPoint.setRightHandlePosition(PointCal.addVector(prevControlPoint.getPosition(), relativeVector));\n }\n if(nextControlPoint !== undefined && nextControlPoint.getLeftHandle().type == \"VECTOR\"){\n let relativeVector = PointCal.subVector(this.position, nextControlPoint.getPosition());\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n nextControlPoint.setLeftHandlePosition(PointCal.addVector(nextControlPoint.getPosition(), relativeVector));\n }\n }\n\n getPosition(): Point{\n return this.position;\n }\n\n setLeftHandleTypeVector(prevControlPoint: ControlPoint | undefined){\n if(this.rightHandle.type != \"VECTOR\"){\n this.rightHandle.type = \"FREE\";\n }\n let relativeVector: Point;\n if(prevControlPoint == undefined){\n relativeVector = PointCal.subVector(this.leftHandle.position, this.position);\n } else {\n relativeVector = PointCal.subVector(prevControlPoint.getPosition(), this.position);\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n }\n this.leftHandle.position = PointCal.addVector(this.position, relativeVector);\n }\n\n setLeftHandleTypeAligned(){\n this.leftHandle.type = \"ALIGNED\";\n if(this.rightHandle.type == \"VECTOR\"){\n let direction = PointCal.unitVectorFromA2B(this.rightHandle.position, this.position);\n let mag = PointCal.distanceBetweenPoints(this.position, this.leftHandle.position);\n this.leftHandle.position = PointCal.addVector(this.position, PointCal.multiplyVectorByScalar(direction, mag));\n }\n }\n\n setLeftHandleTypeFree(){\n this.leftHandle.type = \"FREE\";\n }\n\n setRightHandleTypeVector(nextControlPoint: ControlPoint | undefined) {\n if(this.leftHandle.type != \"VECTOR\"){\n this.leftHandle.type = \"FREE\";\n }\n let relativeVector: Point;\n if(nextControlPoint == undefined){\n relativeVector = PointCal.subVector(this.rightHandle.position, this.position);\n } else {\n relativeVector = PointCal.subVector(nextControlPoint.getPosition(), this.position);\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n }\n this.rightHandle.position = PointCal.addVector(this.position, relativeVector);\n }\n\n setRightHandleTypeAligned(){\n this.rightHandle.type = \"ALIGNED\";\n if(this.leftHandle.type == \"VECTOR\") {\n let direciton = PointCal.unitVectorFromA2B(this.leftHandle.position, this.position);\n let mag = PointCal.distanceBetweenPoints(this.position, this.rightHandle.position);\n this.rightHandle.position = PointCal.addVector(this.position, PointCal.multiplyVectorByScalar(direciton, mag));\n } \n }\n\n setRightHandleTypeFree(){\n this.rightHandle.type = \"FREE\";\n }\n\n setLeftHandlePosition(destPos: Point){\n let leftHandleType = this.leftHandle.type;\n switch(leftHandleType){\n case \"ALIGNED\":\n if(this.rightHandle.type == \"VECTOR\"){\n let diff = PointCal.subVector(destPos, this.position);\n let rightHandleDiff = PointCal.unitVectorFromA2B(this.rightHandle.position, this.position);\n let resMag = PointCal.dotProduct(diff, rightHandleDiff);\n let res = PointCal.multiplyVectorByScalar(rightHandleDiff, resMag);\n this.leftHandle.position = PointCal.addVector(this.position, res);\n } else if (this.rightHandle.type == \"ALIGNED\"){\n this.leftHandle.position = destPos;\n let mag = PointCal.distanceBetweenPoints(this.rightHandle.position, this.position);\n let direction = PointCal.unitVectorFromA2B(this.leftHandle.position, this.position);\n let res = PointCal.multiplyVectorByScalar(direction, mag);\n this.rightHandle.position = PointCal.addVector(res, this.position);\n } else {\n this.leftHandle.position = destPos;\n }\n break;\n case \"FREE\":\n this.leftHandle.position = destPos;\n break;\n case \"VECTOR\":\n break;\n default:\n throw new Error(`Unknown left handle type for control point`);\n }\n }\n\n setRightHandlePosition(destPos: Point){\n let rightHandleType = this.rightHandle.type;\n switch(rightHandleType){\n case \"ALIGNED\":\n if(this.leftHandle.type == \"VECTOR\"){\n let diff = PointCal.subVector(destPos, this.position);\n let leftHandleDiff = PointCal.unitVectorFromA2B(this.leftHandle.position, this.position);\n let resMag = PointCal.dotProduct(diff, leftHandleDiff);\n let res = PointCal.multiplyVectorByScalar(leftHandleDiff, resMag);\n this.rightHandle.position = PointCal.addVector(this.position, res);\n } else if (this.rightHandle.type == \"ALIGNED\"){\n this.rightHandle.position = destPos;\n let mag = PointCal.distanceBetweenPoints(this.leftHandle.position, this.position);\n let direction = PointCal.unitVectorFromA2B(this.rightHandle.position, this.position);\n let res = PointCal.multiplyVectorByScalar(direction, mag);\n this.leftHandle.position = PointCal.addVector(res, this.position);\n } else {\n this.rightHandle.position = destPos;\n }\n break;\n case \"FREE\":\n this.rightHandle.position = destPos;\n break;\n case \"VECTOR\":\n break;\n default:\n throw new Error(`Unknown left handle type for control point`);\n }\n }\n\n getLeftHandle(): HandlePoint{\n return this.leftHandle;\n }\n\n getRightHandle(): HandlePoint{\n return this.rightHandle;\n }\n}\n\nexport class CompositeBCurve{\n\n private controlPoints: ControlPoint[];\n\n constructor(controlPoints: ControlPoint[] = []){\n this.controlPoints = controlPoints;\n }\n\n getControlPoints(): ControlPoint[]{\n return this.controlPoints;\n }\n\n appendControlPoint(position: Point){\n let leftHandlePosition = PointCal.addVector(position, {x: -100, y: 0});\n let rightHandlePosition = PointCal.addVector(position, {x: 100, y: 0});\n let leftHandlePoint: HandlePoint = {\n position: leftHandlePosition,\n type: \"FREE\"\n }\n let rightHandlePoint: HandlePoint = {\n position: rightHandlePosition,\n type: \"FREE\"\n }\n\n let newControlPoint = new ControlPoint(position, leftHandlePoint, rightHandlePoint);\n this.controlPoints.push(newControlPoint);\n }\n\n setLeftHandlePositionOfControlPoint(controlPointIndex: number, destPos: Point){\n if(controlPointIndex >= this.controlPoints.length || controlPointIndex < 0){\n return;\n }\n this.controlPoints[controlPointIndex].setLeftHandlePosition(destPos);\n }\n\n setRightHandlePositionOfControlPoint(controlPointIndex: number, destPos: Point){\n if(controlPointIndex >= this.controlPoints.length || controlPointIndex < 0){\n return;\n }\n this.controlPoints[controlPointIndex].setRightHandlePosition(destPos);\n }\n \n setPositionOfControlPoint(controlPointIndex: number, destPos: Point){\n if(controlPointIndex >= this.controlPoints.length || controlPointIndex < 0){\n return;\n }\n let prevControlPoint = undefined;\n let nextControlPoint = undefined;\n if(controlPointIndex + 1 < this.controlPoints.length){\n nextControlPoint = this.controlPoints[controlPointIndex + 1];\n }\n if(controlPointIndex - 1 >= 0){\n prevControlPoint = this.controlPoints[controlPointIndex - 1];\n }\n this.controlPoints[controlPointIndex].setPosition(destPos, prevControlPoint, nextControlPoint);\n }\n}\n",
8
- "import { Line } from \"./line\";\nimport { Point } from \"@ue-too/math\";\n\ntype AdvanceAtTWithLengthWithinCurveRes = {\n type: \"withinCurve\";\n tVal: number;\n point: Point;\n}\n\ntype AdvanceAtWithLengthBeforeCurveRes = {\n type: \"beforeCurve\";\n remainLength: number;\n}\n\ntype AdvanceAtWithLengthAfterCurveRes = {\n type: \"afterCurve\";\n remainLength: number;\n}\n\ntype AdvanceAtTWithLengthOutofCurveRes = AdvanceAtWithLengthBeforeCurveRes | AdvanceAtWithLengthAfterCurveRes;\n\ntype AdvanceAtTWithLengthRes = AdvanceAtTWithLengthWithinCurveRes | AdvanceAtTWithLengthOutofCurveRes;\nexport class Path {\n\n private lines: Line[];\n\n constructor(lines: Line[]){\n this.lines = lines;\n }\n\n append(line: Line): void{\n this.lines.push(line);\n }\n\n clear(): void{\n this.lines = [];\n }\n\n prepend(line: Line): void{\n this.lines.unshift(line);\n }\n\n getLines(): Line[]{\n return this.lines;\n }\n\n getLength(): number{\n let res = 0;\n this.lines.forEach((line)=>{\n res += line.length();\n });\n return res;\n }\n\n // advanceByDistancAtPercentage(percentage: number, distance: number): {destination: Point}\n\n getPercentages(): {start: number, end: number}[]{\n const length = this.getLength();\n let currentCurvePercentage = 0;\n const res: {start: number, end: number}[] = [];\n this.lines.forEach((line)=>{\n const lineLength = line.length();\n const linePercentage = lineLength / length;\n let start = currentCurvePercentage;\n currentCurvePercentage += linePercentage;\n let end = currentCurvePercentage;\n res.push({start, end});\n });\n res[res.length - 1].end = 1;\n return res;\n }\n\n getPointByPercentage(percentage: number): Point | never{\n if (percentage < 0 || percentage > 1){\n throw new Error(\"Percentage must be between 0 and 1\");\n }\n const percentages = this.getPercentages();\n let left = 0;\n let right = percentages.length - 1;\n while (left <= right){\n const mid = Math.floor((left + right) / 2);\n if (percentage < percentages[mid].end){\n right = mid - 1;\n } else if (percentage > percentages[mid].end){\n left = mid + 1;\n } else {\n left = mid;\n break;\n }\n }\n const line = this.lines[left];\n const linePercentage = percentages[left];\n const ratio = (percentage - linePercentage.start) / (linePercentage.end - linePercentage.start);\n return line.lerp(ratio);\n }\n}\n"
5
+ "import { PointCal } from \"@ue-too/math\";\nimport { Line } from \"./line\";\n\nconst T = [\n -0.0640568928626056260850430826247450385909,\n 0.0640568928626056260850430826247450385909,\n -0.1911188674736163091586398207570696318404,\n 0.1911188674736163091586398207570696318404,\n -0.3150426796961633743867932913198102407864,\n 0.3150426796961633743867932913198102407864,\n -0.4337935076260451384870842319133497124524,\n 0.4337935076260451384870842319133497124524,\n -0.5454214713888395356583756172183723700107,\n 0.5454214713888395356583756172183723700107,\n -0.6480936519369755692524957869107476266696,\n 0.6480936519369755692524957869107476266696,\n -0.7401241915785543642438281030999784255232,\n 0.7401241915785543642438281030999784255232,\n -0.8200019859739029219539498726697452080761,\n 0.8200019859739029219539498726697452080761,\n -0.8864155270044010342131543419821967550873,\n 0.8864155270044010342131543419821967550873,\n -0.9382745520027327585236490017087214496548,\n 0.9382745520027327585236490017087214496548,\n -0.9747285559713094981983919930081690617411,\n 0.9747285559713094981983919930081690617411,\n -0.9951872199970213601799974097007368118745,\n 0.9951872199970213601799974097007368118745,\n];\n\nconst C = [\n 0.1279381953467521569740561652246953718517,\n 0.1279381953467521569740561652246953718517,\n 0.1258374563468282961213753825111836887264,\n 0.1258374563468282961213753825111836887264,\n 0.121670472927803391204463153476262425607,\n 0.121670472927803391204463153476262425607,\n 0.1155056680537256013533444839067835598622,\n 0.1155056680537256013533444839067835598622,\n 0.1074442701159656347825773424466062227946,\n 0.1074442701159656347825773424466062227946,\n 0.0976186521041138882698806644642471544279,\n 0.0976186521041138882698806644642471544279,\n 0.086190161531953275917185202983742667185,\n 0.086190161531953275917185202983742667185,\n 0.0733464814110803057340336152531165181193,\n 0.0733464814110803057340336152531165181193,\n 0.0592985849154367807463677585001085845412,\n 0.0592985849154367807463677585001085845412,\n 0.0442774388174198061686027482113382288593,\n 0.0442774388174198061686027482113382288593,\n 0.0285313886289336631813078159518782864491,\n 0.0285313886289336631813078159518782864491,\n 0.0123412297999871995468056670700372915759,\n 0.0123412297999871995468056670700372915759,\n];\n\ntype ArcLengthLUT = {\n controlPoints: Point[];\n arcLengthLUT: {tVal: number, length: number}[];\n}\n\ntype AdvanceAtTWithLengthWithinCurveRes = {\n type: \"withinCurve\";\n tVal: number;\n point: Point;\n}\n\ntype AdvanceAtWithLengthBeforeCurveRes = {\n type: \"beforeCurve\";\n remainLength: number;\n}\n\ntype AdvanceAtWithLengthAfterCurveRes = {\n type: \"afterCurve\";\n remainLength: number;\n}\n\ntype AdvanceAtTWithLengthOutofCurveRes = AdvanceAtWithLengthBeforeCurveRes | AdvanceAtWithLengthAfterCurveRes;\n\ntype AdvanceAtTWithLengthRes = AdvanceAtTWithLengthWithinCurveRes | AdvanceAtTWithLengthOutofCurveRes;\n\n/**\n * Bezier curve class supporting quadratic (3 points) and cubic (4 points) curves.\n *\n * @remarks\n * BCurve provides a comprehensive implementation of Bezier curves with:\n * - Curve evaluation at any parameter t (0 to 1)\n * - Arc-length calculation with caching for performance\n * - Curve splitting and subdivision\n * - Geometric queries (projection, intersection, extrema)\n * - Advanced operations (offset, arc fitting, curvature)\n *\n * ## Performance Optimizations\n * - Optimized formulas for quadratic and cubic curves\n * - Arc-length caching to avoid recomputation\n * - Lazy computation of lookup tables (LUT)\n * - Gauss-Legendre quadrature for arc-length calculation\n *\n * ## Coordinate System\n * - Parameter t ranges from 0 (start) to 1 (end)\n * - Points use {x, y} coordinates\n * - Supports 2D curves (z-coordinate optional but not used)\n *\n * @example\n * Create and evaluate a cubic Bezier curve\n * ```typescript\n * const curve = new BCurve([\n * { x: 0, y: 0 }, // Start point\n * { x: 33, y: 100 }, // Control point 1\n * { x: 66, y: 100 }, // Control point 2\n * { x: 100, y: 0 } // End point\n * ]);\n *\n * // Evaluate at different positions\n * const start = curve.get(0); // { x: 0, y: 0 }\n * const mid = curve.get(0.5); // Midpoint\n * const end = curve.get(1); // { x: 100, y: 0 }\n *\n * // Get curve length\n * console.log('Length:', curve.fullLength);\n *\n * // Get derivative (tangent vector)\n * const tangent = curve.derivative(0.5);\n * ```\n *\n * @category Core\n */\nexport class BCurve{\n\n private controlPoints: Point[];\n private dControlPoints: Point[] = [];\n private arcLengthLUT: ArcLengthLUT = {controlPoints: [], arcLengthLUT: []};\n private _fullLength: number;\n private lengthCache: Map<number, number> = new Map(); // Cache for lengthAtT results\n\n /**\n * Gets cache statistics for performance monitoring\n * @returns Object containing cache size and hit rate information\n */\n public getCacheStats(): {size: number, hitRate: number} {\n return {\n size: this.lengthCache.size,\n hitRate: 0 // This would need to be tracked separately if needed\n };\n }\n\n /**\n * Pre-warms the cache with commonly used t values for better performance\n * @param steps Number of steps to pre-cache (default: 100)\n */\n public preWarmCache(steps: number = 100): void {\n const tSteps = 1 / steps;\n for (let tVal = 0; tVal <= 1; tVal += tSteps) {\n this.lengthAtT(tVal);\n }\n }\n\n private clearCache(): void {\n this.lengthCache.clear();\n }\n\n constructor(controlPoints: Point[]){\n this.controlPoints = controlPoints;\n this.dControlPoints = this.getDerivativeControlPoints(this.controlPoints);\n this._fullLength = this.calculateFullLength();\n // Make arc length LUT lazy - only compute when needed\n this.arcLengthLUT = { controlPoints: [], arcLengthLUT: [] };\n this.clearCache(); // Clear cache on initialization\n }\n\n public getPointbyPercentage(percentage: number){ // this is the percentage of the curve length, not the t value\n // this leaves room for optimization\n let controlPointsChangedSinceLastArcLengthLUT = this.arcLengthLUT.controlPoints.length != this.controlPoints.length;\n controlPointsChangedSinceLastArcLengthLUT = controlPointsChangedSinceLastArcLengthLUT || this.arcLengthLUT.controlPoints.reduce((prevVal, curVal, index)=>{\n return prevVal || !PointCal.isEqual(curVal, this.controlPoints[index]);\n }, false);\n let points: number[] = [];\n if (controlPointsChangedSinceLastArcLengthLUT){\n this.arcLengthLUT = this.getArcLengthLUT(1000);\n }\n points = [...this.arcLengthLUT.arcLengthLUT.map((item)=>item.length)];\n let targetLength = percentage * this.fullLength;\n let low = 0;\n let high = points.length - 1;\n while (low <= high){\n let mid = Math.floor((low + high) / 2);\n if (points[mid] == targetLength){\n return this.get((mid + 1) / points.length);\n } else if (points[mid] < targetLength){\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n return low >= points.length ? this.get(1) : this.get((low + 1) / points.length);\n }\n\n public getDerivativeControlPoints(controlPoints: Point[]): Point[]{\n const derivativeControlPoints: Point[] = [];\n for(let index = 1; index < controlPoints.length; index++){\n derivativeControlPoints.push(PointCal.multiplyVectorByScalar(PointCal.subVector(controlPoints[index], controlPoints[index - 1]), controlPoints.length - 1));\n }\n return derivativeControlPoints;\n }\n\n private validateTVal(tVal: number){\n if (tVal > 1 || tVal < 0){\n throw new TValOutofBoundError(\"tVal is greater than 1 or less than 0\");\n }\n }\n\n public getControlPoints(): Point[]{\n return this.controlPoints;\n }\n\n setControlPoints(controlPoints: Point[]){\n this.controlPoints = controlPoints;\n this.dControlPoints = this.getDerivativeControlPoints(this.controlPoints);\n this._fullLength = this.calculateFullLength();\n // Reset LUT to trigger lazy computation when needed\n this.arcLengthLUT = { controlPoints: [], arcLengthLUT: [] };\n this.clearCache(); // Clear cache on control point change\n }\n\n setControlPointAtIndex(index: number, newPoint: Point): boolean{\n if (index < 0 || index >= this.controlPoints.length){\n return false;\n }\n this.controlPoints[index] = newPoint;\n this.dControlPoints = this.getDerivativeControlPoints(this.controlPoints);\n this._fullLength = this.calculateFullLength();\n // Reset LUT to trigger lazy computation when needed\n this.arcLengthLUT = { controlPoints: [], arcLengthLUT: [] };\n this.clearCache(); // Clear cache on control point change\n return true;\n }\n\n public compute(tVal: number): Point{\n this.validateTVal(tVal);\n let points = this.controlPoints;\n while (points.length > 1) {\n let lowerLevelPoints = points.slice(1);\n for(let index = 0; index < lowerLevelPoints.length; index++){\n lowerLevelPoints[index] = PointCal.addVector(PointCal.multiplyVectorByScalar(points[index], (1 - tVal)), PointCal.multiplyVectorByScalar(points[index + 1], tVal));\n }\n points = lowerLevelPoints;\n }\n return points[0];\n }\n\n public get(tVal: number): Point {\n this.validateTVal(tVal);\n if (this.controlPoints.length == 3) {\n let firstTerm = PointCal.multiplyVectorByScalar(this.controlPoints[0], (1 - tVal) * (1 - tVal));\n let secondTerm = PointCal.multiplyVectorByScalar(this.controlPoints[1], 2 * (1 - tVal) * tVal);\n let thirdTerm = PointCal.multiplyVectorByScalar(this.controlPoints[2], tVal * tVal);\n let res = PointCal.addVector(PointCal.addVector(firstTerm, secondTerm), thirdTerm);\n return res;\n }\n if (this.controlPoints.length == 4){\n let firstTerm = PointCal.multiplyVectorByScalar(this.controlPoints[0], (1 - tVal) * (1 - tVal) * (1 - tVal));\n let secondTerm = PointCal.multiplyVectorByScalar(this.controlPoints[1], 3 * (1 - tVal) * (1 - tVal) * tVal);\n let thirdTerm = PointCal.multiplyVectorByScalar(this.controlPoints[2], 3 * (1 - tVal) * tVal * tVal);\n let forthTerm = PointCal.multiplyVectorByScalar(this.controlPoints[3], tVal * tVal * tVal);\n let res = PointCal.addVector(PointCal.addVector(firstTerm, secondTerm), PointCal.addVector(thirdTerm, forthTerm));\n return res;\n }\n return this.compute(tVal);\n }\n\n public getLUT(steps: number = 100){\n const stepSpan = 1 / steps;\n const res: Point[] = [];\n let tVal = 0;\n res.push(this.get(tVal));\n for(let index = 0; index < steps; index += 1){\n tVal += stepSpan;\n if((tVal > 1 && tVal - stepSpan < 1) || index == steps - 1){\n tVal = 1;\n }\n res.push(this.get(tVal));\n }\n return res\n }\n\n public getLUTWithTVal(steps?: number){\n if (steps == undefined){\n steps = 100;\n }\n const stepSpan = 1 / steps;\n const res: {point: Point, tVal: number}[] = [];\n let tVal = 0;\n res.push({point: this.get(tVal), tVal: tVal});\n for(let index = 0; index < steps; index += 1){\n tVal += stepSpan;\n if((tVal > 1 && tVal - stepSpan < 1) || index == steps - 1){\n tVal = 1;\n }\n res.push({point: this.get(tVal), tVal: tVal});\n }\n return res\n }\n\n get fullLength(): number{\n return this._fullLength;\n }\n\n private calculateFullLength(): number{\n return this.lengthAtT(1);\n }\n\n public lengthAtT(tVal: number): number{\n this.validateTVal(tVal);\n \n // Check cache first\n const cacheKey = Math.round(tVal * 1000000) / 1000000; // Round to 6 decimal places for cache key\n if (this.lengthCache.has(cacheKey)) {\n return this.lengthCache.get(cacheKey)!;\n }\n \n const z = tVal / 2, len = T.length;\n let sum = 0;\n for (let i = 0, t: number; i < len; i++) {\n t = z * T[i] + z;\n sum += C[i] * PointCal.magnitude(this.derivative(t));\n }\n const result = z * sum;\n \n // Cache the result\n this.lengthCache.set(cacheKey, result);\n \n return result;\n }\n\n public derivative(tVal: number): Point{\n return computeWithControlPoints(tVal, this.dControlPoints);\n }\n\n public derivativeNormalized(tVal: number): Point{\n return PointCal.unitVector(computeWithControlPoints(tVal, this.dControlPoints));\n }\n\n public getArcLengthLUT(steps: number = 50): {controlPoints: Point[], arcLengthLUT: {tVal: number, length: number}[]}{\n // Check if we need to recompute the LUT\n const controlPointsChanged = this.arcLengthLUT.controlPoints.length !== this.controlPoints.length ||\n this.arcLengthLUT.controlPoints.some((cp, index) => !PointCal.isEqual(cp, this.controlPoints[index]));\n \n if (controlPointsChanged || this.arcLengthLUT.arcLengthLUT.length === 0) {\n // Clear cache when regenerating LUT to ensure consistency\n this.clearCache();\n \n let res = [];\n let tSteps = 1 / steps;\n for(let tVal = 0; tVal <= 1; tVal += tSteps){\n res.push({tVal: tVal, length: this.lengthAtT(tVal)});\n }\n this.arcLengthLUT = {controlPoints: [...this.controlPoints], arcLengthLUT: res};\n }\n \n return this.arcLengthLUT;\n }\n\n splitIntoCurves(tVal: number): [BCurve, BCurve]{\n const res = this.split(tVal);\n return [new BCurve(res[0]), new BCurve(res[1])];\n }\n\n public split(tVal: number): [Point[], Point[]]{\n this.validateTVal(tVal);\n if (this.controlPoints.length == 3){\n let newControlPoint1 = this.controlPoints[0];\n let newControlPoint2 = PointCal.subVector(PointCal.multiplyVectorByScalar(this.controlPoints[1], tVal), PointCal.multiplyVectorByScalar(this.controlPoints[0], tVal - 1));\n let newControlPoint3 = PointCal.subVector(PointCal.multiplyVectorByScalar(this.controlPoints[2], tVal * tVal), PointCal.multiplyVectorByScalar(this.controlPoints[1], 2 * tVal * (tVal - 1)));\n newControlPoint3 = PointCal.addVector(newControlPoint3, PointCal.multiplyVectorByScalar(this.controlPoints[0], (tVal - 1) * (tVal - 1)));\n let newControlPoint4 = PointCal.subVector(PointCal.multiplyVectorByScalar(this.controlPoints[2], tVal), PointCal.multiplyVectorByScalar(this.controlPoints[1], tVal - 1));\n let newControlPoint5 = this.controlPoints[2];\n return [[newControlPoint1, newControlPoint2, newControlPoint3], [newControlPoint3, newControlPoint4, newControlPoint5]];\n }\n let newControlPoint1 = this.controlPoints[0];\n let newControlPoint2 = PointCal.subVector(PointCal.multiplyVectorByScalar(this.controlPoints[1], tVal), PointCal.multiplyVectorByScalar(this.controlPoints[0], (tVal - 1)));\n let newControlPoint3 = PointCal.addVector(PointCal.multiplyVectorByScalar(this.controlPoints[2], tVal * tVal), PointCal.addVector(PointCal.multiplyVectorByScalar(this.controlPoints[1], -(2 * tVal * (tVal - 1))), PointCal.multiplyVectorByScalar(this.controlPoints[0], (tVal - 1) * (tVal - 1))));\n let term1 = PointCal.multiplyVectorByScalar(this.controlPoints[3], tVal * tVal * tVal);\n let term2 = PointCal.multiplyVectorByScalar(this.controlPoints[2], -(3 * tVal * tVal * (tVal - 1)));\n let term3 = PointCal.multiplyVectorByScalar(this.controlPoints[1], 3 * tVal * (tVal - 1) * (tVal - 1));\n let term4 = PointCal.multiplyVectorByScalar(this.controlPoints[0], -((tVal - 1) * (tVal - 1) * (tVal - 1)));\n let newControlPoint4 = PointCal.addVector(term4, PointCal.addVector(term3, PointCal.addVector(term1, term2)));\n let newControlPoint5 = PointCal.addVector(PointCal.addVector(PointCal.multiplyVectorByScalar(this.controlPoints[3], tVal * tVal), PointCal.multiplyVectorByScalar(this.controlPoints[2], -(2 * tVal * (tVal - 1)))), PointCal.multiplyVectorByScalar(this.controlPoints[1], (tVal - 1) * (tVal - 1)));\n let newControlPoint6 = PointCal.addVector(PointCal.multiplyVectorByScalar(this.controlPoints[3], tVal), PointCal.multiplyVectorByScalar(this.controlPoints[2], -(tVal - 1)));\n let newControlPoint7 = this.controlPoints[3];\n\n return [[newControlPoint1, newControlPoint2, newControlPoint3, newControlPoint4], [newControlPoint4, newControlPoint5, newControlPoint6, newControlPoint7]];\n }\n\n splitIn3WithControlPoints(tVal: number, tVal2: number): [Point[], Point[], Point[]]{\n if(tVal2 < tVal){\n console.warn(\"tVal2 is less than tVal, swapping them\");\n [tVal, tVal2] = [tVal2, tVal];\n }\n\n const firstSplit = this.split(tVal);\n\n const secondHalf = new BCurve(firstSplit[1]);\n\n const mappedTVal2 = map(tVal2, tVal, 1, 0, 1);\n \n const secondSplit = secondHalf.split(mappedTVal2);\n\n return [firstSplit[0], secondSplit[0], secondSplit[1]];\n }\n\n splitIn3Curves(tVal: number, tVal2: number): [BCurve, BCurve, BCurve]{\n if(tVal2 < tVal){\n console.warn(\"tVal2 is less than tVal, swapping them\");\n [tVal, tVal2] = [tVal2, tVal];\n }\n\n const firstSplit = this.split(tVal);\n\n const secondHalf = new BCurve(firstSplit[1]);\n \n const mappedTVal2 = map(tVal2, tVal, 1, 0, 1);\n const secondSplit = secondHalf.split(mappedTVal2);\n\n return [new BCurve(firstSplit[0]), new BCurve(secondSplit[0]), new BCurve(secondSplit[1])];\n }\n\n splitAndTakeMidCurve(tVal: number, tVal2: number): BCurve{\n const [firstSplit, secondSplit, thirdSplit] = this.splitIn3Curves(tVal, tVal2);\n return secondSplit;\n }\n\n getProjection(point: Point){\n const threshold = 0.00001;\n let distance = Number.MAX_VALUE;\n let preliminaryProjectionTVal: number = 0;\n let preliminaryProjectionPoint: Point = this.get(0);\n let preliminaryProjectionIndex: number = 0;\n const LUT = this.getLUTWithTVal(500);\n LUT.forEach((curvePoint, index)=>{\n const curDistance = PointCal.distanceBetweenPoints(curvePoint.point, point);\n if(curDistance < distance){\n distance = curDistance;\n preliminaryProjectionPoint = {...curvePoint.point};\n preliminaryProjectionTVal = curvePoint.tVal;\n preliminaryProjectionIndex = index;\n }\n });\n // console.log(preliminaryProjectionIndex, preliminaryProjectionPoint, preliminaryProjectionTVal);\n let low = LUT[preliminaryProjectionIndex].tVal;\n let high = LUT[preliminaryProjectionIndex].tVal;\n if (preliminaryProjectionIndex < LUT.length - 1){\n high = LUT[preliminaryProjectionIndex + 1].tVal;\n }\n if (preliminaryProjectionIndex > 0){\n low = LUT[preliminaryProjectionIndex - 1].tVal;\n }\n while(low < high && high - low > threshold){\n let mid = low + (high - low) / 2;\n let halfSpan = mid - low;\n let lowMidMid = mid + halfSpan / 2;\n let highMidMid = mid + halfSpan / 2;\n let prevDist = distance;\n\n \n if(lowMidMid <= 1 && lowMidMid >= 0){\n let curDist = PointCal.distanceBetweenPoints(this.get(lowMidMid), point);\n if (curDist < distance){\n distance = curDist;\n preliminaryProjectionPoint = this.get(lowMidMid);\n preliminaryProjectionTVal = lowMidMid;\n high = lowMidMid + halfSpan / 2;\n low = lowMidMid - halfSpan / 2;\n }\n }\n if(highMidMid <= 1 && highMidMid >= 0){\n let curDist = PointCal.distanceBetweenPoints(this.get(highMidMid), point);\n if (curDist < distance){\n distance = curDist;\n preliminaryProjectionPoint = this.get(highMidMid);\n preliminaryProjectionTVal = highMidMid;\n high = highMidMid + halfSpan / 2;\n low = highMidMid - halfSpan / 2;\n }\n }\n if (prevDist == distance){\n break;\n }\n }\n return {projection: preliminaryProjectionPoint, tVal: preliminaryProjectionTVal};\n }\n\n public findArcs(errorThreshold: number){\n let low = 0;\n const res: {center: Point, radius: number, startPoint: Point, startT: number, endPoint: Point, endT: number}[] = [];\n\n while (low < 1){\n let loopRes = this.findArcStartingAt(errorThreshold, low);\n if (loopRes == null || loopRes.arc == undefined) {\n break;\n }\n res.push(loopRes.arc);\n low = loopRes.arc.endT;\n if(low >= 1){\n break;\n }\n }\n return res;\n }\n\n public findArcStartingAt(errorThreshold: number, low: number){\n let high = 1;\n let mid = low + (high - low) / 2;\n let prevArc:{good: boolean, arc?: {center: Point, radius: number, startPoint: Point, endPoint: Point, startT: number, endT: number}} = {good: false};\n let count = 0;\n while(true){\n count++;\n mid = low + (high - low) / 2;\n if (high > 1 || mid > 1){\n if (prevArc.good){\n return prevArc;\n } else {\n return null;\n }\n \n }\n const lowPoint = this.get(low);\n const highPoint = this.get(high);\n const midPoint = this.get(mid);\n const fitArcRes = this.fitArc(lowPoint, highPoint, midPoint);\n if (!fitArcRes.exists || fitArcRes.center == null || fitArcRes.radius == null){\n return null;\n }\n const n = high - mid;\n const e1 = mid - n / 2;\n const e2 = mid + n / 2;\n const checkPoint1 = this.get(e1);\n const checkPoint2 = this.get(e2);\n const checkRadius = PointCal.distanceBetweenPoints(checkPoint1, fitArcRes.center);\n const checkRadius2 = PointCal.distanceBetweenPoints(checkPoint2, fitArcRes.center);\n if (Math.abs(checkRadius - fitArcRes.radius) > errorThreshold || Math.abs(checkRadius2 - fitArcRes.radius) > errorThreshold){\n // arc is bad\n if (prevArc.good == true){\n return prevArc;\n }\n prevArc.good = false;\n high = mid\n } else {\n prevArc.good = true;\n if (fitArcRes.startPoint !== undefined && fitArcRes.endPoint !== undefined){\n prevArc.arc = { center: fitArcRes.center, radius: fitArcRes.radius, startPoint: fitArcRes.startPoint, endPoint: fitArcRes.endPoint, startT: low, endT: high};\n }\n high = high + (mid - low);\n }\n }\n }\n\n public fitArc(startPoint: Point, endPoint: Point, midPoint: Point): {exists: boolean, center?: Point, radius?: number, startPoint?: Point, endPoint?: Point}{\n const M11 = [[startPoint.x, startPoint.y, 1], [midPoint.x, midPoint.y, 1], [endPoint.x, endPoint.y, 1]];\n if (this.determinant3by3(M11) == 0) {\n // three points lie on a line no circle\n return {exists: false};\n }\n const M12 = [[startPoint.x * startPoint.x + startPoint.y * startPoint.y, startPoint.y, 1], \n [midPoint.x * midPoint.x + midPoint.y * midPoint.y, midPoint.y, 1],\n [endPoint.x * endPoint.x + endPoint.y * endPoint.y, endPoint.y, 1]];\n const M13 = [[startPoint.x * startPoint.x + startPoint.y * startPoint.y, startPoint.x, 1],\n [midPoint.x * midPoint.x + midPoint.y * midPoint.y, midPoint.x, 1],\n [endPoint.x * endPoint.x + endPoint.y * endPoint.y, endPoint.x, 1]];\n const M14 = [[startPoint.x * startPoint.x + startPoint.y * startPoint.y, startPoint.x, startPoint.y],\n [midPoint.x * midPoint.x + midPoint.y * midPoint.y, midPoint.x, midPoint.y],\n [endPoint.x * endPoint.x + endPoint.y * endPoint.y, endPoint.x, endPoint.y]]\n const centerX = (1 / 2) * (this.determinant3by3(M12) / this.determinant3by3(M11));\n const centerY = (-1 / 2) * (this.determinant3by3(M13) / this.determinant3by3(M11));\n const radius = Math.sqrt(centerX * centerX + centerY * centerY + (this.determinant3by3(M14) / this.determinant3by3(M11)))\n return {exists: true, center: {x: centerX, y:centerY}, radius: radius, startPoint: startPoint, endPoint: endPoint};\n }\n\n public determinant3by3(matrix: number[][]): number{\n const a = matrix[0][0];\n const b = matrix[0][1];\n const c = matrix[0][2];\n const d = matrix[1][0];\n const e = matrix[1][1];\n const f = matrix[1][2];\n const g = matrix[2][0];\n const h = matrix[2][1];\n const i = matrix[2][2];\n return a * (e * i - f * h) - b * (d * i - g * f) + c * (d * h - e * g);\n }\n\n public curvature(tVal: number): number{\n const derivative = computeWithControlPoints(tVal, this.dControlPoints);\n const secondDerivative = computeWithControlPoints(tVal, this.getDerivativeControlPoints(this.dControlPoints));\n const numerator = derivative.x * secondDerivative.y - secondDerivative.x * derivative.y;\n const denominator = Math.pow(derivative.x * derivative.x + derivative.y * derivative.y, 3 / 2);\n if (denominator == 0) return NaN;\n return numerator / denominator;\n }\n\n secondDerivative(tVal: number): Point{\n return computeWithControlPoints(tVal, this.getDerivativeControlPoints(this.dControlPoints));\n }\n\n public getCoefficientOfTTerms(): Point[]{\n return this.getCoefficientOfTTermsWithControlPoints(this.controlPoints);\n }\n\n public getDerivativeCoefficients(): Point[]{\n return this.getCoefficientOfTTermsWithControlPoints(this.dControlPoints);\n }\n\n public getCoefficientOfTTermsWithControlPoints(controlPoints: Point[]): Point[]{\n const terms: Point[] = [];\n let matrix: number[][] = [];\n if(controlPoints.length == 3){\n matrix = [[1, 0, 0], [-2, 2, 0], [1, -2, 1]];\n } else if (controlPoints.length == 4){\n matrix = [[1, 0, 0, 0], [-3, 3, 0, 0], [3, -6, 3, 0], [-1, 3, -3, 1]];\n } else if(controlPoints.length == 2){\n matrix = [[1, 0], [-1, 1]];\n } \n else {\n throw new Error(\"number of control points is wrong\");\n }\n for(let index = 0; index < controlPoints.length; index++){\n terms.push(controlPoints.reduce((prevVal, curVal, jindex)=>{\n return {x: prevVal.x + matrix[index][jindex] * curVal.x, y: prevVal.y + matrix[index][jindex] * curVal.y};\n }, {x: 0, y: 0}));\n }\n return terms;\n }\n\n getControlPointsAlignedWithXAxis(){\n const alignedAxis = PointCal.unitVectorFromA2B(this.controlPoints[0], this.controlPoints[this.controlPoints.length - 1]);\n const angle = PointCal.angleFromA2B({x:1, y:0}, alignedAxis);\n const startingPoint = this.controlPoints[0];\n const res = [{x: 0, y: 0}];\n for(let index = 1; index < this.controlPoints.length; index++){\n const vector = PointCal.subVector(this.controlPoints[index], startingPoint);\n const rotatedVector = PointCal.rotatePoint(vector, -angle);\n res.push(rotatedVector);\n }\n return res;\n }\n\n getExtrema():{x: number[], y: number[]}{\n const res: {x: number[], y: number[]} = {x: [], y: []};\n const derivativeCoefficients = this.getDerivativeCoefficients();\n let xCoefficients = [0, 0, 0, 0];\n let yCoefficients = [0, 0, 0, 0];\n derivativeCoefficients.forEach((coefficient, index)=>{\n xCoefficients[3 - index] = coefficient.x;\n yCoefficients[3 - index] = coefficient.y;\n });\n\n const xRoots = solveCubic(xCoefficients[0], xCoefficients[1], xCoefficients[2], xCoefficients[3]);\n const yRoots = solveCubic(yCoefficients[0], yCoefficients[1], yCoefficients[2], yCoefficients[3]);\n xRoots.forEach((root)=>{\n if(root >= 0 && root <= 1){\n res.x.push(root);\n }\n });\n yRoots.forEach((root)=>{\n if(root >= 0 && root <= 1){\n res.y.push(root);\n }\n });\n \n if(derivativeCoefficients.length >= 3){\n xCoefficients = [0, 0, 0, 0];\n yCoefficients = [0, 0, 0, 0];\n const secondDerivativeCoefficients = this.getCoefficientOfTTermsWithControlPoints(this.getDerivativeControlPoints(this.dControlPoints));\n secondDerivativeCoefficients.forEach((coefficient, index)=>{\n xCoefficients[3 - index] = coefficient.x;\n yCoefficients[3 - index] = coefficient.y;\n })\n const secondXRoots = solveCubic(xCoefficients[0], xCoefficients[1], xCoefficients[2], xCoefficients[3]);\n const secondYRoots = solveCubic(yCoefficients[0], yCoefficients[1], yCoefficients[2], yCoefficients[3]);\n secondXRoots.forEach((root)=>{\n if(root >= 0 && root <= 1){\n res.x.push(root);\n }\n });\n secondYRoots.forEach((root)=>{\n if(root >= 0 && root <= 1){\n res.y.push(root);\n }\n });\n\n }\n return res; \n }\n\n translateRotateControlPoints(translation: Point, rotationAngle: number){\n // rotation is in radians\n const res: Point[] = [];\n for(let index = 0; index < this.controlPoints.length; index++){\n res.push(PointCal.rotatePoint(PointCal.addVector(this.controlPoints[index], translation), rotationAngle));\n }\n return res;\n }\n\n getLineIntersections(line: Line): number[]{\n const translationRotation = line.getTranslationRotationToAlginXAxis();\n const res: number[] = [];\n const alignedControlPoints = this.translateRotateControlPoints(translationRotation.translation, translationRotation.rotationAngle);\n const coefficients = this.getCoefficientOfTTermsWithControlPoints(alignedControlPoints);\n let yCoefficients = [0, 0, 0, 0];\n coefficients.forEach((coefficient, index)=>{\n yCoefficients[3 - index] = coefficient.y;\n });\n\n const yRoots = solveCubic(yCoefficients[0], yCoefficients[1], yCoefficients[2], yCoefficients[3]);\n yRoots.forEach((root)=>{\n if(root >= 0 && root <= 1){\n if(line.pointInLine(this.get(root))){\n res.push(root);\n }\n }\n });\n\n return res;\n }\n\n getSelfIntersections(): {selfT: number, otherT: number}[]{\n const [subCurveControlPoints1, subCurveControlPoints2] = this.split(0.5);\n const subCurve1 = new BCurve(subCurveControlPoints1);\n const subCurve2 = new BCurve(subCurveControlPoints2);\n let initialRes = getIntersectionsBetweenCurves(subCurve1, subCurve2);\n initialRes.forEach((intersection)=>{\n intersection.selfT = intersection.selfT * 0.5;\n intersection.otherT = intersection.otherT * 0.5 + 0.5;\n });\n initialRes.shift();\n return initialRes;\n }\n\n getCircleIntersections(circleCenter: Point, circleRadius: number): {intersection: Point, tVal: number}[]{\n const LUT = this.getLUTWithTVal(500);\n let distanceError = Number.MAX_VALUE;\n let preliminaryIntersectionIndex = 0;\n let preliminaryIntersectionPoint: Point = LUT[0].point;\n let preliminaryIntersectionTVal = LUT[0].tVal;\n LUT.forEach((curvePoint, index)=>{\n let curDistanceError = Math.abs(PointCal.distanceBetweenPoints(circleCenter, curvePoint.point));\n if (curDistanceError < distanceError){\n distanceError = curDistanceError;\n preliminaryIntersectionIndex = index;\n }\n });\n const LUTD = LUT.map((curvePoint, index)=>{\n return {...curvePoint, distance: 0};\n })\n distanceError = Number.MAX_VALUE;\n let start = 0;\n let count = 0;\n let indices: number[] = [];\n while(++count < 25){\n let i = this.findClosest(circleCenter.x, circleCenter.y, LUTD, circleRadius, 5, LUTD[start - 2]?.distance, LUTD[start - 1]?.distance);\n if (i < start) break;\n if (i > 0 && i == start) break;\n indices.push(i);\n start = i + 2;\n }\n const finalList: {intersection: Point, tVal: number}[] = [];\n indices.forEach((index)=>{\n let res = this.refineBinary(this, circleCenter.x, circleCenter.y, LUTD, index, circleRadius);\n if (res != undefined){\n finalList.push({intersection: res.point, tVal: res.tVal});\n }\n })\n return finalList;\n }\n\n advanceAtTWithLength(tVal: number, length: number): AdvanceAtTWithLengthRes{\n const currentLength = this.lengthAtT(tVal);\n const targetLength = currentLength + length;\n \n // Handle edge cases first\n if(tVal === 0 && length < 0){\n return {type: \"beforeCurve\", remainLength: -length};\n }\n if(tVal === 1 && length > 0){\n return {type: \"afterCurve\", remainLength: length};\n }\n if(targetLength > this.fullLength){\n return {type: \"afterCurve\", remainLength: targetLength - this.fullLength};\n } else if(targetLength < 0){\n return {type: \"beforeCurve\", remainLength: -targetLength};\n }\n\n // Use LUT for binary search\n if(this.arcLengthLUT.arcLengthLUT.length === 0){\n this.arcLengthLUT = this.getArcLengthLUT(1000);\n }\n const points = this.arcLengthLUT.arcLengthLUT;\n let low = 0;\n let high = points.length - 1;\n \n // Binary search to find the interval containing targetLength\n while (low <= high){\n const mid = Math.floor((low + high) / 2);\n const midLength = points[mid].length;\n \n if (approximately(midLength, targetLength, 0.01)) {\n // Found exact match\n const resultTVal = points[mid].tVal;\n const point = this.get(resultTVal);\n return {type: \"withinCurve\", tVal: resultTVal, point: point};\n } else if (midLength < targetLength){\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n \n // After binary search, 'high' points to the largest index with length < targetLength\n // and 'low' points to the smallest index with length >= targetLength\n \n // Handle edge cases\n if (high < 0) {\n // targetLength is smaller than the first point's length\n high = 1;\n low = 0;\n }\n \n if (low >= points.length) {\n // targetLength is larger than the last point's length\n high = points.length - 1;\n low = points.length - 2;\n }\n \n // Interpolate between points[high] and points[low]\n const p1 = points[high];\n const p2 = points[low];\n \n // Linear interpolation\n const lengthRange = p2.length - p1.length;\n const tRange = p2.tVal - p1.tVal;\n \n if (lengthRange === 0) {\n // Both points have the same length, use the first one\n const point = this.get(p1.tVal);\n return {type: \"withinCurve\", tVal: p1.tVal, point: point};\n }\n \n const ratio = (targetLength - p1.length) / lengthRange;\n const interpolatedT = p1.tVal + ratio * tRange;\n \n // Clamp to valid range\n const clampedT = Math.max(0, Math.min(1, interpolatedT));\n const point = this.get(clampedT);\n \n return {type: \"withinCurve\", tVal: clampedT, point: point};\n }\n\n advanceByDistance(startT: number, distance: number): AdvanceAtTWithLengthRes {\n let currentT = startT;\n let remainingDistance = distance;\n const stepSize = 0.01; // Adjust for precision vs performance\n\n if(distance > this.fullLength){\n return {type: \"afterCurve\", remainLength: distance - this.fullLength};\n } else if(distance < 0){\n return {type: \"beforeCurve\", remainLength: -distance};\n }\n \n while (remainingDistance > 0 && currentT < 1) {\n const currentPoint = this.get(currentT);\n const nextT = Math.min(currentT + stepSize, 1);\n const nextPoint = this.get(nextT);\n \n const segmentLength = Math.sqrt(\n Math.pow(nextPoint.x - currentPoint.x, 2) + \n Math.pow(nextPoint.y - currentPoint.y, 2)\n );\n \n if (segmentLength >= remainingDistance) {\n // Interpolate within this segment\n const ratio = remainingDistance / segmentLength;\n return {type: \"withinCurve\", tVal: currentT + ratio * (nextT - currentT), point: this.get(currentT + ratio * (nextT - currentT))};\n }\n \n remainingDistance -= segmentLength;\n currentT = nextT;\n }\n \n return {type: \"withinCurve\", tVal: currentT, point: this.get(currentT)};\n }\n\n refineBinary(curve: BCurve, x: number, y: number, LUT: {point: Point, tVal: number, distance: number}[], i: number, targetDistance=0, epsilon=0.01) {\n let q: {point: Point, tVal: number, distance: number} | undefined = LUT[i],\n count = 1,\n distance = Number.MAX_SAFE_INTEGER;\n \n do {\n let i1 = i === 0 ? 0 : i - 1,\n i2 = i === LUT.length - 1 ? LUT.length - 1 : i + 1,\n t1 = LUT[i1].tVal,\n t2 = LUT[i2].tVal,\n lut: {point: Point, tVal: number, distance: number}[] = [],\n step = (t2 - t1) / 4;\n \n if (step < 0.001) break;\n \n lut.push(LUT[i1]);\n for (let j = 1; j <= 3; j++) {\n let n = curve.get(t1 + j * step);\n let nDistance = Math.abs(PointCal.distanceBetweenPoints(n, {x: x, y: y}) - targetDistance);\n if (nDistance < distance) {\n distance = nDistance;\n q = {point: n, tVal: t1 + j * step, distance: nDistance};\n i = j;\n }\n lut.push({point: n, tVal: t1 + j * step, distance: nDistance});\n }\n lut.push(LUT[i2]);\n \n // update the LUT to be our new five point LUT, and run again.\n LUT = lut;\n \n // The \"count\" test is mostly a safety measure: it will\n // never kick in, but something that _will_ terminate is\n // always better than while(true). Never use while(true)\n } while (count++ < 25);\n \n // If we're trying to hit a target, discard the result if\n // it is not close enough to the target.\n if (targetDistance && distance > epsilon) {\n q = undefined;\n }\n \n return q;\n }\n\n findClosest(x: number, y: number, LUT: {point: Point, tVal: number, distance: number}[], circleRadius: number, distanceEpsilon = 5, pd2?: number, pd1?: number) {\n let distance = Number.MAX_SAFE_INTEGER,\n prevDistance2 = pd2 || distance,\n prevDistance1 = pd1 || distance,\n i = -1;\n \n for (let index=0, e=LUT.length; index<e; index++){\n let p = LUT[index].point;\n LUT[index].distance = Math.abs(PointCal.distanceBetweenPoints({x:x, y:y}, p) - circleRadius);\n \n // Realistically, there's only going to be an intersection if\n // the distance to the circle center is already approximately\n // the circle's radius.\n if (prevDistance1 < distanceEpsilon && prevDistance2 > prevDistance1 && prevDistance1 < LUT[index].distance) {\n i = index - 1;\n break;\n }\n \n if (LUT[index].distance < distance) {\n distance = LUT[index].distance;\n }\n \n prevDistance2 = prevDistance1;\n prevDistance1 = LUT[index].distance;\n }\n \n return i;\n }\n\n getCurveIntersections(curve: BCurve, deduplicationTolerance?: number): {selfT: number, otherT: number}[]{\n return getIntersectionsBetweenCurves(this, curve, deduplicationTolerance);\n }\n\n get AABB():{min: Point, max: Point}{\n const extrema = this.getExtrema();\n const tVals = [0, 1];\n let min: Point = {x: Number.MAX_VALUE, y: Number.MAX_VALUE};\n let max: Point = {x: -Number.MAX_VALUE, y: -Number.MAX_VALUE};\n extrema.x.forEach((tVal)=>{\n tVals.push(tVal);\n });\n extrema.y.forEach((tVal)=>{\n tVals.push(tVal);\n });\n tVals.forEach((tVal)=>{\n const curPoint = this.get(tVal);\n min.x = Math.min(min.x, curPoint.x);\n min.y = Math.min(min.y, curPoint.y);\n max.x = Math.max(max.x, curPoint.x);\n max.y = Math.max(max.y, curPoint.y);\n });\n\n return {min:min, max:max};\n }\n\n normal(tVal: number): {tVal: number, direction: Point} {\n const d = this.derivative(tVal);\n const q = Math.sqrt(d.x * d.x + d.y * d.y);\n return {tVal, direction: {x: -d.y / q, y: d.x / q}};\n }\n}\n\n/**\n * Reduces a Bezier curve into simpler segments.\n * @category Utilities\n */\nexport function reduce(curve: BCurve) {\n let i: number,\n t1 = 0,\n t2 = 0,\n step = 0.01,\n segment: BCurve,\n pass1: BCurve[] = [],\n pass2: BCurve[] = [];\n \n // first pass: split on extrema\n let extrema = curve.getExtrema().x;\n if (extrema.indexOf(0) === -1) {\n extrema = [0].concat(extrema);\n }\n if (extrema.indexOf(1) === -1) {\n extrema.push(1);\n }\n for (t1 = extrema[0], i = 1; i < extrema.length; i++) {\n t2 = extrema[i];\n segment = curve.splitAndTakeMidCurve(t1, t2);\n pass1.push(segment);\n t1 = t2;\n }\n \n // second pass: further reduce these segments to simple segments\n pass1.forEach(p1 => {\n t1 = 0;\n t2 = 0;\n while (t2 <= 1) {\n for (t2 = t1 + step; t2 <= 1 + step; t2 += step) {\n // Clamp t2 to valid range\n const clampedT2 = Math.min(t2, 1);\n segment = p1.splitAndTakeMidCurve(t1, clampedT2);\n if (!curveIsSimple(segment)) {\n t2 -= step;\n if (Math.abs(t1 - t2) < step) {\n // we can never form a reduction\n return [];\n }\n const finalT2 = Math.min(t2, 1);\n segment = p1.splitAndTakeMidCurve(t1, finalT2);\n pass2.push(segment);\n t1 = finalT2;\n break;\n }\n }\n }\n if (t1 < 1) {\n segment = p1.splitAndTakeMidCurve(t1, 1);\n pass2.push(segment);\n }\n });\n \n return pass2;\n}\n\nfunction raiseCurveOrder(curve: BCurve): BCurve {\n const p = curve.getControlPoints(),\n np = [p[0]],\n k = p.length;\n for (let i = 1; i < k; i++) {\n const pi = p[i];\n const pim = p[i - 1];\n np[i] = {\n x: ((k - i) / k) * pi.x + (i / k) * pim.x,\n y: ((k - i) / k) * pi.y + (i / k) * pim.y,\n };\n }\n np[k] = p[k - 1];\n return new BCurve(np);\n}\n\n/**\n * Creates offset curves at a specified distance from the original curve.\n * @category Utilities\n */\n// Function overloads for different return types\nexport function offset(curve: BCurve, t: number): BCurve[];\nexport function offset(curve: BCurve, t: number, d: number): {c: Point, n: Point, x: number, y: number};\nexport function offset(curve: BCurve, t: number, d?: number | undefined) {\n if (d !== undefined) {\n const c = curve.get(t),\n n = curve.normal(t).direction;\n const ret = {\n c: c,\n n: n,\n x: c.x + n.x * d,\n y: c.y + n.y * d,\n };\n // if (this._3d) {\n // ret.z = c.z + n.z * d;\n // }\n return ret;\n }\n\n // Native offset implementation based on bezier-js algorithm\n const points = curve.getControlPoints();\n const linear = curveIsLinear(curve);\n\n if (linear) {\n const nv = curve.normal(0).direction,\n coords = points.map(function (p) {\n const ret = {\n x: p.x + t * nv.x,\n y: p.y + t * nv.y,\n };\n return ret;\n });\n return [new BCurve(coords)];\n }\n\n // For non-linear curves, reduce to simple segments and scale each\n return reduce(curve).map(function (s) {\n if (curveIsLinear(s)) {\n return offset(s, t)[0];\n }\n return scaleCurve(s, t);\n });\n}\n\n/**\n * Alternative offset implementation using LUT-based approach.\n * @category Utilities\n */\nexport function offset2(curve: BCurve, d: number): Point[]{\n const lut = curve.getLUTWithTVal(100);\n\n const res = lut.map((item)=>{\n const derivative = PointCal.unitVector(curve.derivative(item.tVal));\n const normal = {x: -derivative.y, y: derivative.x};\n const offsetPoint = {x: item.point.x + normal.x * d, y: item.point.y + normal.y * d};\n return offsetPoint;\n });\n\n return res;\n}\n\n// Helper function for line-line intersection (ported from bezier-js utils)\nfunction lli4(p1: Point, p2: Point, p3: Point, p4: Point): Point | false {\n const x1 = p1.x, y1 = p1.y,\n x2 = p2.x, y2 = p2.y,\n x3 = p3.x, y3 = p3.y,\n x4 = p4.x, y4 = p4.y;\n return lli8(x1, y1, x2, y2, x3, y3, x4, y4);\n}\n\nfunction lli8(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number): Point | false {\n const nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4);\n const ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4);\n const d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);\n if (d == 0) {\n return false;\n }\n return { x: nx / d, y: ny / d };\n}\n\nfunction curveIsLinear(curve: BCurve): boolean{\n const order = curve.getControlPoints().length - 1;\n const points = curve.getControlPoints();\n const alignedPoints = alignPointsToLine(points, {p1: points[0], p2: points[order]});\n const baseLength = PointCal.distanceBetweenPoints(points[0], points[order]);\n\n // Sum of distances from the line (y coordinates in aligned space)\n const linear = alignedPoints.reduce((t, p) => t + Math.abs(p.y), 0) < baseLength / 50;\n\n return linear;\n}\n\n\nfunction scaleCurve(curve: BCurve, d: number | ((t: number) => number)): BCurve {\n const order = curve.getControlPoints().length - 1;\n let distanceFn: ((t: number) => number) | undefined = undefined;\n\n if (typeof d === \"function\") {\n distanceFn = d;\n }\n\n if (distanceFn && order === 2) {\n return scaleCurve(raiseCurveOrder(curve), distanceFn);\n }\n\n const points = curve.getControlPoints();\n\n // Check if curve is linear\n if (curveIsLinear(curve)) {\n return translate(\n curve,\n curve.normal(0).direction,\n distanceFn ? distanceFn(0) : d as number,\n distanceFn ? distanceFn(1) : d as number\n );\n }\n\n const r1 = distanceFn ? distanceFn(0) : d as number;\n const r2 = distanceFn ? distanceFn(1) : d as number;\n \n // Get offset points at endpoints to find the scaling origin\n const v = [offset(curve, 0, 10), offset(curve, 1, 10)];\n const np: Point[] = [];\n const o = lli4(v[0] as any, (v[0] as any).c, v[1] as any, (v[1] as any).c);\n\n if (!o) {\n // Fallback: use simple translation for problematic curves\n return translate(\n curve,\n curve.normal(0).direction,\n r1,\n r2\n );\n }\n\n // Move endpoint control points by distance along normal\n [0, 1].forEach(function (t) {\n const p = JSON.parse(JSON.stringify(points[t * order]));\n const vt = v[t] as any;\n p.x += (t ? r2 : r1) * vt.n.x;\n p.y += (t ? r2 : r1) * vt.n.y;\n np[t * order] = p;\n });\n\n if (!distanceFn) {\n // Move control points to lie on the intersection of the offset\n // derivative vector, and the origin-through-control vector\n [0, 1].forEach((t) => {\n if (order === 2 && !!t) return;\n const p = np[t * order];\n const derivativeAtT = curve.derivative(t);\n const p2 = { x: p.x + derivativeAtT.x, y: p.y + derivativeAtT.y };\n const intersection = lli4(p, p2, o, points[t + 1]);\n if (intersection) {\n np[t + 1] = intersection;\n } else {\n // Fallback: use original control point with simple offset\n const originalPoint = points[t + 1];\n const normal = curve.normal((t + 1) / order).direction;\n np[t + 1] = {\n x: originalPoint.x + (t ? r2 : r1) * normal.x,\n y: originalPoint.y + (t ? r2 : r1) * normal.y\n };\n }\n });\n return new BCurve(np);\n }\n\n // For function-based distances, move control points by distance\n // to ensure correct tangent at endpoints\n [0, 1].forEach(function (t) {\n if (order === 2 && !!t) return;\n const p = points[t + 1];\n const ov = {\n x: p.x - o.x,\n y: p.y - o.y,\n };\n let rc = distanceFn!((t + 1) / order);\n const m = Math.sqrt(ov.x * ov.x + ov.y * ov.y);\n ov.x /= m;\n ov.y /= m;\n np[t + 1] = {\n x: p.x + rc * ov.x,\n y: p.y + rc * ov.y,\n };\n });\n return new BCurve(np);\n}\n\nfunction alignPointsToLine(points: Point[], line: {p1: Point, p2: Point}) {\n const tx = line.p1.x,\n ty = line.p1.y,\n a = -Math.atan2(line.p2.y - ty, line.p2.x - tx),\n d = function (v: Point) {\n return {\n x: (v.x - tx) * Math.cos(a) - (v.y - ty) * Math.sin(a),\n y: (v.x - tx) * Math.sin(a) + (v.y - ty) * Math.cos(a),\n };\n };\n return points.map(d);\n};\n\nfunction map(v: number, ds: number, de: number, ts: number, te: number): number {\n const d1 = de - ds, // source range size\n d2 = te - ts, // target range size \n v2 = v - ds, // offset from source start\n r = v2 / d1; // ratio within source range\n return ts + d2 * r; // mapped value in target range\n}\n\n/**\n * Error thrown when t-value is out of valid range [0, 1].\n * @category Types\n */\nexport class TValOutofBoundError extends Error{\n constructor(message: string){\n super(message);\n }\n}\n\n/**\n * 2D/3D point type.\n * @category Types\n */\nexport type Point = {\n x: number;\n y: number;\n z?: number;\n}\n\n/**\n * Tests if two axis-aligned bounding boxes intersect.\n * @category Utilities\n */\nexport function AABBIntersects(AABB1: {min: Point, max: Point}, AABB2: {min: Point, max: Point}): boolean{\n if ((AABB1.min.x <= AABB2.max.x && AABB2.min.x <= AABB1.max.x) && (AABB1.min.y <= AABB2.max.y && AABB2.min.y <= AABB1.max.y)){\n return true;\n }\n return false;\n}\n\n/**\n * Checks if two numbers are approximately equal within a precision threshold.\n * @category Utilities\n */\nexport function approximately (a: number, b: number, precision?: number) {\n const epsilon = 0.000001\n return Math.abs(a - b) <= (precision || epsilon);\n}\n\nexport function cuberoot2(v:number) {\n if(v<0) return -Math.pow(-v,1/3);\n return Math.pow(v,1/3);\n}\n\nexport function accept(t: number) {\n return 0 <= t && t <=1;\n}\n\nexport function getCubicRoots(pa: number, pb: number, pc: number, pd: number) {\n let a = (3*pa - 6*pb + 3*pc),\n b = (-3*pa + 3*pb),\n c = pa,\n d = (-pa + 3*pb - 3*pc + pd);\n\n // do a check to see whether we even need cubic solving:\n if (approximately(d,0)) {\n // this is not a cubic curve.\n if (approximately(a,0)) {\n // in fact, this is not a quadratic curve either.\n if (approximately(b,0)) {\n // in fact in fact, there are no solutions.\n return [];\n }\n // linear solution\n return [-c / b].filter(accept);\n }\n // quadratic solution\n let q = Math.sqrt(b*b - 4*a*c), a2 = 2*a;\n return [(q-b)/a2, (-b-q)/a2].filter(accept)\n }\n\n // at this point, we know we need a cubic solution.\n\n a /= d;\n b /= d;\n c /= d;\n\n let p = (3*b - a*a)/3,\n p3 = p/3,\n q = (2*a*a*a - 9*a*b + 27*c)/27,\n q2 = q/2,\n discriminant = q2*q2 + p3*p3*p3;\n\n // and some variables we're going to use later on:\n let u1, v1, root1, root2, root3;\n\n // three possible real roots:\n if (discriminant < 0) {\n let mp3 = -p/3,\n mp33 = mp3*mp3*mp3,\n r = Math.sqrt( mp33 ),\n t = -q / (2*r),\n cosphi = t<-1 ? -1 : t>1 ? 1 : t,\n phi = Math.acos(cosphi),\n crtr = cuberoot2(r),\n t1 = 2*crtr;\n root1 = t1 * Math.cos(phi/3) - a/3;\n root2 = t1 * Math.cos((phi+2*Math.PI)/3) - a/3;\n root3 = t1 * Math.cos((phi+4*Math.PI)/3) - a/3;\n return [root1, root2, root3].filter(accept);\n }\n\n // three real roots, but two of them are equal:\n if(discriminant === 0) {\n u1 = q2 < 0 ? cuberoot2(-q2) : -cuberoot2(q2);\n root1 = 2*u1 - a/3;\n root2 = -u1 - a/3;\n return [root1, root2].filter(accept);\n }\n\n // one real root, two complex roots\n var sd = Math.sqrt(discriminant);\n u1 = cuberoot2(sd - q2);\n v1 = cuberoot2(sd + q2);\n root1 = u1 - v1 - a/3;\n return [root1].filter(accept);\n}\n\n/**\n * Finds all intersection points between two Bezier curves.\n * @category Utilities\n */\nexport function getIntersectionsBetweenCurves(curve: BCurve, curve2: BCurve, deduplicationTolerance: number = 0.01): {selfT: number, otherT: number}[]{\n const threshold = 0.5;\n let pairs: {curve1: {curve: BCurve, startTVal: number, endTVal: number}, curve2: {curve: BCurve, startTVal: number, endTVal: number}}[] = [{curve1: {curve: curve, startTVal: 0, endTVal: 1}, curve2: {curve: curve2, startTVal: 0, endTVal: 1}}];\n const finalRes = [];\n while (pairs.length > 0){\n let curLength = pairs.length;\n for(let index = 0; index < curLength; index++){\n let pair = pairs.shift();\n if (pair == undefined){\n break;\n }\n let aabb1 = pair.curve1.curve.AABB;\n let aabb2 = pair.curve2.curve.AABB;\n let intersects = AABBIntersects(aabb1, aabb2);\n if(pair.curve1.curve.fullLength < threshold && pair.curve2.curve.fullLength < threshold){\n finalRes.push({intersection: pair.curve1.curve.get(0.5), tVal1: (pair.curve1.startTVal + pair.curve1.endTVal) * 0.5, tVal2: (pair.curve2.startTVal + pair.curve2.endTVal) * 0.5});\n continue;\n }\n if (intersects){\n let [subCurveControlPoints1, subCurveControlPoints2] = pair.curve1.curve.split(0.5);\n let [subCurveControlPoints3, subCurveControlPoints4] = pair.curve2.curve.split(0.5);\n pairs.push({\n curve1: {\n curve: new BCurve(subCurveControlPoints1), \n startTVal: pair.curve1.startTVal, \n endTVal: pair.curve1.startTVal + (pair.curve1.endTVal - pair.curve1.startTVal) * 0.5\n }, curve2: {\n curve: new BCurve(subCurveControlPoints3),\n startTVal: pair.curve2.startTVal,\n endTVal: pair.curve2.startTVal + (pair.curve2.endTVal - pair.curve2.startTVal) * 0.5\n }});\n\n pairs.push({\n curve1: {\n curve: new BCurve(subCurveControlPoints1), \n startTVal: pair.curve1.startTVal, \n endTVal: pair.curve1.startTVal + (pair.curve1.endTVal - pair.curve1.startTVal) * 0.5\n }, curve2: {\n curve: new BCurve(subCurveControlPoints4),\n startTVal: pair.curve2.startTVal + (pair.curve2.endTVal - pair.curve2.startTVal) * 0.5,\n endTVal: pair.curve2.endTVal\n }});\n\n pairs.push({\n curve1: {\n curve: new BCurve(subCurveControlPoints2), \n startTVal: pair.curve1.startTVal + (pair.curve1.endTVal - pair.curve1.startTVal) * 0.5 ,\n endTVal: pair.curve1.endTVal \n }, curve2: {\n curve: new BCurve(subCurveControlPoints3),\n startTVal: pair.curve2.startTVal,\n endTVal: pair.curve2.startTVal + (pair.curve2.endTVal - pair.curve2.startTVal) * 0.5\n }});\n\n pairs.push({\n curve1: {\n curve: new BCurve(subCurveControlPoints2), \n startTVal: pair.curve1.startTVal + (pair.curve1.endTVal - pair.curve1.startTVal) * 0.5 ,\n endTVal: pair.curve1.endTVal \n }, curve2: {\n curve: new BCurve(subCurveControlPoints4),\n startTVal: pair.curve2.startTVal + (pair.curve2.endTVal - pair.curve2.startTVal) * 0.5,\n endTVal: pair.curve2.endTVal\n }});\n }\n\n }\n }\n\n // Improved deduplication logic that handles close tvals on both curves\n const tVals: {selfT: number, otherT: number}[] = [];\n \n // Sort intersections by tVal1 for more predictable deduplication\n finalRes.sort((a, b) => a.tVal1 - b.tVal1);\n \n for (const intersection of finalRes) {\n let isDuplicate = false;\n \n // Check against all existing intersections\n for (const existing of tVals) {\n // Check if this intersection is close to an existing one on either curve\n const selfTClose = approximately(intersection.tVal1, existing.selfT, deduplicationTolerance);\n const otherTClose = approximately(intersection.tVal2, existing.otherT, deduplicationTolerance);\n \n // Consider it a duplicate if both t-values are close\n if (selfTClose && otherTClose) {\n isDuplicate = true;\n break;\n }\n \n // Also check for cases where intersections might be very close on the same curve\n // This handles cases where curves are nearly tangent or have very close intersections\n const selfTVeryClose = approximately(intersection.tVal1, existing.selfT, deduplicationTolerance * 10);\n const otherTVeryClose = approximately(intersection.tVal2, existing.otherT, deduplicationTolerance * 10);\n \n if (selfTVeryClose || otherTVeryClose) {\n // Additional check: if the intersection points are very close spatially\n const point1 = curve.get(intersection.tVal1);\n const point2 = curve2.get(intersection.tVal2);\n const existingPoint1 = curve.get(existing.selfT);\n const existingPoint2 = curve2.get(existing.otherT);\n \n const distance1 = PointCal.distanceBetweenPoints(point1, existingPoint1);\n const distance2 = PointCal.distanceBetweenPoints(point2, existingPoint2);\n \n // If both intersection points are spatially very close, consider it a duplicate\n if (distance1 < deduplicationTolerance * 100 && distance2 < deduplicationTolerance * 100) {\n isDuplicate = true;\n break;\n }\n }\n }\n \n if (!isDuplicate) {\n tVals.push({selfT: intersection.tVal1, otherT: intersection.tVal2});\n }\n }\n \n return tVals;\n}\n\n/**\n * Solves cubic equations.\n * @category Utilities\n */\nexport function solveCubic(a: number, b: number, c: number, d: number) {\n if (Math.abs(a) < 1e-8) { // Quadratic case, ax^2+bx+c=0\n a = b; b = c; c = d;\n if (Math.abs(a) < 1e-8) { // Linear case, ax+b=0\n a = b; b = c;\n if (Math.abs(a) < 1e-8) // Degenerate case\n return [];\n return [-b/a];\n }\n\n let D = b*b - 4*a*c;\n if (Math.abs(D) < 1e-8)\n return [-b/(2*a)];\n else if (D > 0)\n return [(-b+Math.sqrt(D))/(2*a), (-b-Math.sqrt(D))/(2*a)];\n return [];\n }\n\n // Convert to depressed cubic t^3+pt+q = 0 (subst x = t - b/3a)\n let p = (3*a*c - b*b)/(3*a*a);\n let q = (2*b*b*b - 9*a*b*c + 27*a*a*d)/(27*a*a*a);\n let roots: number[];\n\n if (Math.abs(p) < 1e-8) { // p = 0 -> t^3 = -q -> t = -q^1/3\n roots = [cuberoot(-q)];\n } else if (Math.abs(q) < 1e-8) { // q = 0 -> t^3 + pt = 0 -> t(t^2+p)=0\n roots = [0].concat(p < 0 ? [Math.sqrt(-p), -Math.sqrt(-p)] : []);\n } else {\n let D = q*q/4 + p*p*p/27;\n if (Math.abs(D) < 1e-8) { // D = 0 -> two roots\n roots = [-1.5*q/p, 3*q/p];\n } else if (D > 0) { // Only one real root and two complex roots\n let u = cuberoot(-q/2 - Math.sqrt(D));\n let v = cuberoot(-q/2 + Math.sqrt(D));\n //console.log(\"Complext Root 1 real:\", -(u+v)/2.0 - a / 3.0, \"imaginary:\", Math.sqrt(3) / 2.0 * (v - u));\n //console.log(\"Complext Root 2 real:\", -(u+v)/2.0 - a / 3.0, \"imaginary:\",-1 * Math.sqrt(3) / 2.0 * (v - u));\n\n roots = [u - p/(3*u)];\n } else { // D < 0, three roots, but needs to use complex numbers/trigonometric solution\n let u = 2*Math.sqrt(-p/3);\n let t = Math.acos(3*q/p/u)/3; // D < 0 implies p < 0 and acos argument in [-1..1]\n let k = 2*Math.PI/3;\n roots = [u*Math.cos(t), u*Math.cos(t-k), u*Math.cos(t-2*k)];\n }\n }\n\n // Convert back from depressed cubic\n for (let i = 0; i < roots.length; i++)\n roots[i] -= b/(3*a);\n\n return roots;\n}\n\nexport function cuberoot(x: number) {\n var y = Math.pow(Math.abs(x), 1/3);\n return x < 0 ? -y : y;\n}\n\n/**\n * Computes point on curve using De Casteljau's algorithm.\n * @category Utilities\n */\nexport function computeWithControlPoints(tVal: number, controlPoints: Point[]): Point{\n let points = [...controlPoints];\n while (points.length > 1) {\n let lowerLevelPoints = points.slice(1);\n for(let index = 0; index < lowerLevelPoints.length; index++){\n lowerLevelPoints[index] = PointCal.addVector(PointCal.multiplyVectorByScalar(points[index], (1 - tVal)), PointCal.multiplyVectorByScalar(points[index + 1], tVal));\n }\n points = lowerLevelPoints;\n }\n return points[0];\n}\n\nfunction curveIsSimple(curve: BCurve): boolean {\n if (curve.getControlPoints().length === 4) {\n const points = curve.getControlPoints();\n const p0ToP3Vector = PointCal.subVector(points[3], points[0]);\n const p0ToP1Vector = PointCal.subVector(points[1], points[0]);\n const p0ToP2Vector = PointCal.subVector(points[2], points[0]);\n \n const a1 = PointCal.angleFromA2B(p0ToP3Vector, p0ToP1Vector);\n const a2 = PointCal.angleFromA2B(p0ToP3Vector, p0ToP2Vector);\n if ((a1 > 0 && a2 < 0) || (a1 < 0 && a2 > 0)) return false;\n }\n const n1 = curve.normal(0).direction;\n const n2 = curve.normal(1).direction;\n let s = n1.x * n2.x + n1.y * n2.y;\n // if (this._3d) {\n // s += n1.z * n2.z;\n // }\n return Math.abs(Math.acos(s)) < Math.PI / 3;\n }\n\n\n\nfunction translate(curve: BCurve, vector: Point, d1: number, d2: number){\n const order = curve.getControlPoints().length - 1;\n const points = curve.getControlPoints();\n const d = points.map((_, i: number) => (1 - i / order) * d1 + (i / order) * d2);\n return new BCurve(points.map((p, i) => ({x: p.x + d[i] * vector.x, y: p.y + d[i] * vector.y})));\n}\n",
6
+ "import { PointCal, Point } from \"@ue-too/math\";\n\n/**\n * Line segment class with geometric utilities.\n *\n * @remarks\n * Represents a straight line segment between two points with operations for:\n * - Line-line intersection\n * - Point projection onto line\n * - Point-in-line testing\n * - Linear interpolation (lerp)\n *\n * @example\n * ```typescript\n * const line = new Line({ x: 0, y: 0 }, { x: 100, y: 100 });\n *\n * // Get length\n * console.log('Length:', line.length());\n *\n * // Interpolate at midpoint\n * const mid = line.lerp(0.5); // { x: 50, y: 50 }\n *\n * // Project a point onto the line\n * const result = line.projectPoint({ x: 50, y: 0 });\n * if (result.within) {\n * console.log('Projection:', result.projectionPoint);\n * }\n * ```\n *\n * @category Core\n */\nexport class Line {\n private startPoint: Point;\n private endPoint: Point;\n\n constructor(startPoint: Point, endPoint: Point){\n this.startPoint = startPoint;\n this.endPoint = endPoint;\n }\n\n getStartPoint(): Point{\n return this.startPoint;\n }\n\n getEndPoint(): Point{\n return this.endPoint;\n }\n\n intersectionWithAnotherLine(lineToIntersect: Line){\n return getLineIntersection(this.startPoint, this.endPoint, lineToIntersect.getStartPoint(), lineToIntersect.getEndPoint());\n }\n\n projectPoint(point: Point){\n return projectPointOntoLine(point, this.getStartPoint(), this.getEndPoint());\n }\n\n length(): number{\n return PointCal.distanceBetweenPoints(this.startPoint, this.endPoint);\n }\n \n getTranslationRotationToAlginXAxis(){\n const translation = PointCal.subVector({x: 0, y: 0}, this.startPoint);\n const rotationAngle = PointCal.angleFromA2B(PointCal.subVector(this.endPoint, this.startPoint), {x: 1, y: 0});\n\n return {translation, rotationAngle};\n }\n\n pointInLine(point: Point): boolean{\n const baseVector = PointCal.unitVectorFromA2B(this.startPoint, this.endPoint);\n const start2PointVector = PointCal.subVector(point, this.startPoint);\n const length = PointCal.dotProduct(start2PointVector, baseVector);\n const start2PointUnitVector = PointCal.unitVector(start2PointVector);\n const errorThreshold = PointCal.distanceBetweenPoints(this.startPoint, this.endPoint) * 0.0001;\n return length <= PointCal.distanceBetweenPoints(this.startPoint, this.endPoint) && length >= 0 && Math.abs(start2PointUnitVector.x - baseVector.x) < 0.0001 && Math.abs(start2PointUnitVector.y - baseVector.y) < 0.0001;\n }\n\n lerp(ratio: number): Point {\n return PointCal.linearInterpolation(this.startPoint, this.endPoint, ratio);\n }\n}\n\nexport function getLineIntersection(startPoint: Point, endPoint: Point, startPoint2: Point, endPoint2: Point):{\n intersects: boolean,\n intersection?: Point,\n offset?: number\n}{\n const numerator = (endPoint2.x - startPoint2.x) * (startPoint.y - startPoint2.y) - (endPoint2.y - startPoint2.y) * (startPoint.x - startPoint2.x);\n const denominator = (endPoint2.y - startPoint2.y) * (endPoint.x - startPoint.x) - (endPoint2.x - startPoint2.x) * (endPoint.y - startPoint.y);\n \n if (denominator === 0){\n return {intersects: false};\n }\n const t = numerator / denominator;\n if (t >= 0 && t <= 1){\n return {\n intersects: true, \n intersection: PointCal.linearInterpolation(startPoint, endPoint, t),\n offset: t\n }\n } else {\n return {\n intersects: false,\n }\n }\n\n}\n\nexport function projectPointOntoLine(point: Point, lineStartPoint: Point, lineEndPoint: Point): {\n within: boolean,\n projectionPoint?: Point,\n offset?: number\n}{\n const baseVector = PointCal.unitVector(PointCal.subVector(lineEndPoint, lineStartPoint));\n const vectorToPoint = PointCal.subVector(point, lineStartPoint);\n const res = PointCal.dotProduct(vectorToPoint, baseVector);\n if (res < 0 || res > PointCal.magnitude(PointCal.subVector(lineEndPoint, lineStartPoint))){\n return {\n within: false,\n };\n }\n return {\n within: true,\n projectionPoint: PointCal.addVector(lineStartPoint, PointCal.multiplyVectorByScalar(baseVector, res)),\n offset: res / PointCal.magnitude(PointCal.subVector(lineEndPoint, lineStartPoint))\n };\n\n}\n",
7
+ "import { Point, PointCal } from \"@ue-too/math\";\n\n/**\n * Handle type for Bezier curve control points.\n * @category Types\n */\nexport type HandleType = \"ALIGNED\" | \"VECTOR\" | \"FREE\";\n\n/**\n * Handle point with position and type.\n * @category Types\n */\nexport type HandlePoint = {\n position: Point;\n type: HandleType;\n}\n\n/**\n * Control point with left and right handles for composite Bezier curves.\n * @category Core\n */\nexport class ControlPoint {\n\n private position: Point;\n private leftHandle: HandlePoint;\n private rightHandle: HandlePoint;\n\n constructor(position: Point, leftHandle: HandlePoint, rightHandle: HandlePoint){\n this.position = position;\n this.leftHandle = leftHandle;\n this.rightHandle = rightHandle;\n }\n\n setPosition(destinationPosition: Point, prevControlPoint: ControlPoint | undefined, nextControlPoint: ControlPoint | undefined){\n let diff = PointCal.subVector(destinationPosition, this.position);\n this.position = destinationPosition;\n this.leftHandle.position = PointCal.addVector(this.leftHandle.position, diff);\n this.rightHandle.position = PointCal.addVector(this.rightHandle.position, diff);\n if(this.leftHandle.type == \"VECTOR\" && prevControlPoint){\n let relativeVector = PointCal.subVector(prevControlPoint.getPosition(), this.position);\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n this.leftHandle.position = PointCal.addVector(this.position, relativeVector);\n if(this.rightHandle.type == \"ALIGNED\"){\n let relativeVector = PointCal.subVector(this.rightHandle.position, this.position);\n let mag = PointCal.magnitude(relativeVector);\n let direction = PointCal.unitVectorFromA2B(this.leftHandle.position, this.position);\n this.rightHandle.position = PointCal.addVector(this.position, PointCal.multiplyVectorByScalar(direction, mag));\n }\n }\n if(this.rightHandle.type == \"VECTOR\" && nextControlPoint){\n let relativeVector = PointCal.subVector(nextControlPoint.getPosition(), this.position);\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n this.rightHandle.position = PointCal.addVector(this.position, relativeVector);\n if(this.leftHandle.type == \"ALIGNED\"){\n let mag = PointCal.distanceBetweenPoints(this.leftHandle.position, this.position);\n let direction = PointCal.subVector(this.position, this.rightHandle.position);\n this.leftHandle.position = PointCal.addVector(this.position, PointCal.multiplyVectorByScalar(direction, mag));\n }\n }\n if(prevControlPoint !== undefined && prevControlPoint.getRightHandle().type == \"VECTOR\"){\n let relativeVector = PointCal.subVector(this.position, prevControlPoint.getPosition());\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n prevControlPoint.setRightHandlePosition(PointCal.addVector(prevControlPoint.getPosition(), relativeVector));\n }\n if(nextControlPoint !== undefined && nextControlPoint.getLeftHandle().type == \"VECTOR\"){\n let relativeVector = PointCal.subVector(this.position, nextControlPoint.getPosition());\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n nextControlPoint.setLeftHandlePosition(PointCal.addVector(nextControlPoint.getPosition(), relativeVector));\n }\n }\n\n getPosition(): Point{\n return this.position;\n }\n\n setLeftHandleTypeVector(prevControlPoint: ControlPoint | undefined){\n if(this.rightHandle.type != \"VECTOR\"){\n this.rightHandle.type = \"FREE\";\n }\n let relativeVector: Point;\n if(prevControlPoint == undefined){\n relativeVector = PointCal.subVector(this.leftHandle.position, this.position);\n } else {\n relativeVector = PointCal.subVector(prevControlPoint.getPosition(), this.position);\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n }\n this.leftHandle.position = PointCal.addVector(this.position, relativeVector);\n }\n\n setLeftHandleTypeAligned(){\n this.leftHandle.type = \"ALIGNED\";\n if(this.rightHandle.type == \"VECTOR\"){\n let direction = PointCal.unitVectorFromA2B(this.rightHandle.position, this.position);\n let mag = PointCal.distanceBetweenPoints(this.position, this.leftHandle.position);\n this.leftHandle.position = PointCal.addVector(this.position, PointCal.multiplyVectorByScalar(direction, mag));\n }\n }\n\n setLeftHandleTypeFree(){\n this.leftHandle.type = \"FREE\";\n }\n\n setRightHandleTypeVector(nextControlPoint: ControlPoint | undefined) {\n if(this.leftHandle.type != \"VECTOR\"){\n this.leftHandle.type = \"FREE\";\n }\n let relativeVector: Point;\n if(nextControlPoint == undefined){\n relativeVector = PointCal.subVector(this.rightHandle.position, this.position);\n } else {\n relativeVector = PointCal.subVector(nextControlPoint.getPosition(), this.position);\n relativeVector = PointCal.multiplyVectorByScalar(relativeVector, 1 / 3);\n }\n this.rightHandle.position = PointCal.addVector(this.position, relativeVector);\n }\n\n setRightHandleTypeAligned(){\n this.rightHandle.type = \"ALIGNED\";\n if(this.leftHandle.type == \"VECTOR\") {\n let direciton = PointCal.unitVectorFromA2B(this.leftHandle.position, this.position);\n let mag = PointCal.distanceBetweenPoints(this.position, this.rightHandle.position);\n this.rightHandle.position = PointCal.addVector(this.position, PointCal.multiplyVectorByScalar(direciton, mag));\n } \n }\n\n setRightHandleTypeFree(){\n this.rightHandle.type = \"FREE\";\n }\n\n setLeftHandlePosition(destPos: Point){\n let leftHandleType = this.leftHandle.type;\n switch(leftHandleType){\n case \"ALIGNED\":\n if(this.rightHandle.type == \"VECTOR\"){\n let diff = PointCal.subVector(destPos, this.position);\n let rightHandleDiff = PointCal.unitVectorFromA2B(this.rightHandle.position, this.position);\n let resMag = PointCal.dotProduct(diff, rightHandleDiff);\n let res = PointCal.multiplyVectorByScalar(rightHandleDiff, resMag);\n this.leftHandle.position = PointCal.addVector(this.position, res);\n } else if (this.rightHandle.type == \"ALIGNED\"){\n this.leftHandle.position = destPos;\n let mag = PointCal.distanceBetweenPoints(this.rightHandle.position, this.position);\n let direction = PointCal.unitVectorFromA2B(this.leftHandle.position, this.position);\n let res = PointCal.multiplyVectorByScalar(direction, mag);\n this.rightHandle.position = PointCal.addVector(res, this.position);\n } else {\n this.leftHandle.position = destPos;\n }\n break;\n case \"FREE\":\n this.leftHandle.position = destPos;\n break;\n case \"VECTOR\":\n break;\n default:\n throw new Error(`Unknown left handle type for control point`);\n }\n }\n\n setRightHandlePosition(destPos: Point){\n let rightHandleType = this.rightHandle.type;\n switch(rightHandleType){\n case \"ALIGNED\":\n if(this.leftHandle.type == \"VECTOR\"){\n let diff = PointCal.subVector(destPos, this.position);\n let leftHandleDiff = PointCal.unitVectorFromA2B(this.leftHandle.position, this.position);\n let resMag = PointCal.dotProduct(diff, leftHandleDiff);\n let res = PointCal.multiplyVectorByScalar(leftHandleDiff, resMag);\n this.rightHandle.position = PointCal.addVector(this.position, res);\n } else if (this.rightHandle.type == \"ALIGNED\"){\n this.rightHandle.position = destPos;\n let mag = PointCal.distanceBetweenPoints(this.leftHandle.position, this.position);\n let direction = PointCal.unitVectorFromA2B(this.rightHandle.position, this.position);\n let res = PointCal.multiplyVectorByScalar(direction, mag);\n this.leftHandle.position = PointCal.addVector(res, this.position);\n } else {\n this.rightHandle.position = destPos;\n }\n break;\n case \"FREE\":\n this.rightHandle.position = destPos;\n break;\n case \"VECTOR\":\n break;\n default:\n throw new Error(`Unknown left handle type for control point`);\n }\n }\n\n getLeftHandle(): HandlePoint{\n return this.leftHandle;\n }\n\n getRightHandle(): HandlePoint{\n return this.rightHandle;\n }\n}\n\n/**\n * Composite Bezier curve made of multiple control points with handles.\n * @category Core\n */\nexport class CompositeBCurve{\n\n private controlPoints: ControlPoint[];\n\n constructor(controlPoints: ControlPoint[] = []){\n this.controlPoints = controlPoints;\n }\n\n getControlPoints(): ControlPoint[]{\n return this.controlPoints;\n }\n\n appendControlPoint(position: Point){\n let leftHandlePosition = PointCal.addVector(position, {x: -100, y: 0});\n let rightHandlePosition = PointCal.addVector(position, {x: 100, y: 0});\n let leftHandlePoint: HandlePoint = {\n position: leftHandlePosition,\n type: \"FREE\"\n }\n let rightHandlePoint: HandlePoint = {\n position: rightHandlePosition,\n type: \"FREE\"\n }\n\n let newControlPoint = new ControlPoint(position, leftHandlePoint, rightHandlePoint);\n this.controlPoints.push(newControlPoint);\n }\n\n setLeftHandlePositionOfControlPoint(controlPointIndex: number, destPos: Point){\n if(controlPointIndex >= this.controlPoints.length || controlPointIndex < 0){\n return;\n }\n this.controlPoints[controlPointIndex].setLeftHandlePosition(destPos);\n }\n\n setRightHandlePositionOfControlPoint(controlPointIndex: number, destPos: Point){\n if(controlPointIndex >= this.controlPoints.length || controlPointIndex < 0){\n return;\n }\n this.controlPoints[controlPointIndex].setRightHandlePosition(destPos);\n }\n \n setPositionOfControlPoint(controlPointIndex: number, destPos: Point){\n if(controlPointIndex >= this.controlPoints.length || controlPointIndex < 0){\n return;\n }\n let prevControlPoint = undefined;\n let nextControlPoint = undefined;\n if(controlPointIndex + 1 < this.controlPoints.length){\n nextControlPoint = this.controlPoints[controlPointIndex + 1];\n }\n if(controlPointIndex - 1 >= 0){\n prevControlPoint = this.controlPoints[controlPointIndex - 1];\n }\n this.controlPoints[controlPointIndex].setPosition(destPos, prevControlPoint, nextControlPoint);\n }\n}\n",
8
+ "import { Line } from \"./line\";\nimport { Point } from \"@ue-too/math\";\n\n/**\n * Result type for advancing within curve bounds.\n * @category Types\n */\ntype AdvanceAtTWithLengthWithinCurveRes = {\n type: \"withinCurve\";\n tVal: number;\n point: Point;\n}\n\n/**\n * Result type for advancing before curve start.\n * @category Types\n */\ntype AdvanceAtWithLengthBeforeCurveRes = {\n type: \"beforeCurve\";\n remainLength: number;\n}\n\n/**\n * Result type for advancing after curve end.\n * @category Types\n */\ntype AdvanceAtWithLengthAfterCurveRes = {\n type: \"afterCurve\";\n remainLength: number;\n}\n\n/**\n * Combined result type for advancing outside curve bounds.\n * @category Types\n */\ntype AdvanceAtTWithLengthOutofCurveRes = AdvanceAtWithLengthBeforeCurveRes | AdvanceAtWithLengthAfterCurveRes;\n\n/**\n * Result type for advancing along curve.\n * @category Types\n */\ntype AdvanceAtTWithLengthRes = AdvanceAtTWithLengthWithinCurveRes | AdvanceAtTWithLengthOutofCurveRes;\n\n/**\n * Path made of sequential line segments.\n * @category Core\n */\nexport class Path {\n\n private lines: Line[];\n\n constructor(lines: Line[]){\n this.lines = lines;\n }\n\n append(line: Line): void{\n this.lines.push(line);\n }\n\n clear(): void{\n this.lines = [];\n }\n\n prepend(line: Line): void{\n this.lines.unshift(line);\n }\n\n getLines(): Line[]{\n return this.lines;\n }\n\n getLength(): number{\n let res = 0;\n this.lines.forEach((line)=>{\n res += line.length();\n });\n return res;\n }\n\n // advanceByDistancAtPercentage(percentage: number, distance: number): {destination: Point}\n\n getPercentages(): {start: number, end: number}[]{\n const length = this.getLength();\n let currentCurvePercentage = 0;\n const res: {start: number, end: number}[] = [];\n this.lines.forEach((line)=>{\n const lineLength = line.length();\n const linePercentage = lineLength / length;\n let start = currentCurvePercentage;\n currentCurvePercentage += linePercentage;\n let end = currentCurvePercentage;\n res.push({start, end});\n });\n res[res.length - 1].end = 1;\n return res;\n }\n\n getPointByPercentage(percentage: number): Point | never{\n if (percentage < 0 || percentage > 1){\n throw new Error(\"Percentage must be between 0 and 1\");\n }\n const percentages = this.getPercentages();\n let left = 0;\n let right = percentages.length - 1;\n while (left <= right){\n const mid = Math.floor((left + right) / 2);\n if (percentage < percentages[mid].end){\n right = mid - 1;\n } else if (percentage > percentages[mid].end){\n left = mid + 1;\n } else {\n left = mid;\n break;\n }\n }\n const line = this.lines[left];\n const linePercentage = percentages[left];\n const ratio = (percentage - linePercentage.start) / (linePercentage.end - linePercentage.start);\n return line.lerp(ratio);\n }\n}\n"
9
9
  ],
10
- "mappings": "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",
11
- "debugId": "EABF32F5EF0F7EC864756E2164756E21",
10
+ "mappings": "AAAA,mBAAS,qBAGT,IAAM,EAAI,CACN,qBACA,oBACA,oBACA,mBACA,oBACA,mBACA,oBACA,mBACA,oBACA,mBACA,oBACA,mBACA,oBACA,mBACA,mBACA,kBACA,oBACA,mBACA,oBACA,mBACA,oBACA,mBACA,oBACA,kBACJ,EAEM,EAAI,CACN,oBACA,oBACA,mBACA,mBACA,oBACA,oBACA,mBACA,mBACA,oBACA,oBACA,oBACA,oBACA,oBACA,oBACA,mBACA,mBACA,oBACA,oBACA,oBACA,oBACA,qBACA,qBACA,mBACA,kBACJ,EAyEO,MAAM,CAAM,CAEP,cACA,eAA0B,CAAC,EAC3B,aAA6B,CAAC,cAAe,CAAC,EAAG,aAAc,CAAC,CAAC,EACjE,YACA,YAAmC,IAAI,IAMxC,aAAa,EAAoC,CACpD,MAAO,CACH,KAAM,KAAK,YAAY,KACvB,QAAS,CACb,EAOG,YAAY,CAAC,EAAgB,IAAW,CAC3C,IAAM,EAAS,EAAI,EACnB,QAAS,EAAO,EAAG,GAAQ,EAAG,GAAQ,EAClC,KAAK,UAAU,CAAI,EAInB,UAAU,EAAS,CACvB,KAAK,YAAY,MAAM,EAG3B,WAAW,CAAC,EAAuB,CAC/B,KAAK,cAAgB,EACrB,KAAK,eAAiB,KAAK,2BAA2B,KAAK,aAAa,EACxE,KAAK,YAAc,KAAK,oBAAoB,EAE5C,KAAK,aAAe,CAAE,cAAe,CAAC,EAAG,aAAc,CAAC,CAAE,EAC1D,KAAK,WAAW,EAGb,oBAAoB,CAAC,EAAmB,CAE3C,IAAI,EAA4C,KAAK,aAAa,cAAc,QAAU,KAAK,cAAc,OAC7G,EAA4C,GAA6C,KAAK,aAAa,cAAc,OAAO,CAAC,EAAS,EAAQ,IAAQ,CACtJ,OAAO,GAAW,CAAC,EAAS,QAAQ,EAAQ,KAAK,cAAc,EAAM,GACtE,EAAK,EACR,IAAI,EAAmB,CAAC,EACxB,GAAI,EACA,KAAK,aAAe,KAAK,gBAAgB,IAAI,EAEjD,EAAS,CAAC,GAAG,KAAK,aAAa,aAAa,IAAI,CAAC,IAAO,EAAK,MAAM,CAAC,EACpE,IAAI,EAAe,EAAa,KAAK,WACjC,EAAM,EACN,EAAO,EAAO,OAAS,EAC3B,MAAO,GAAO,EAAK,CACf,IAAI,EAAM,KAAK,OAAO,EAAM,GAAQ,CAAC,EACrC,GAAI,EAAO,IAAQ,EACf,OAAO,KAAK,KAAK,EAAM,GAAK,EAAO,MAAM,EACtC,QAAI,EAAO,GAAO,EACrB,EAAM,EAAM,EAEZ,OAAO,EAAM,EAGrB,OAAO,GAAO,EAAO,OAAS,KAAK,IAAI,CAAC,EAAI,KAAK,KAAK,EAAM,GAAK,EAAO,MAAM,EAG3E,0BAA0B,CAAC,EAAgC,CAC9D,IAAM,EAAmC,CAAC,EAC1C,QAAQ,EAAQ,EAAG,EAAQ,EAAc,OAAQ,IAC7C,EAAwB,KAAK,EAAS,uBAAuB,EAAS,UAAU,EAAc,GAAQ,EAAc,EAAQ,EAAE,EAAG,EAAc,OAAS,CAAC,CAAC,EAE9J,OAAO,EAGH,YAAY,CAAC,EAAa,CAC9B,GAAI,EAAO,GAAK,EAAO,EACnB,MAAM,IAAI,EAAoB,uCAAuC,EAItE,gBAAgB,EAAW,CAC9B,OAAO,KAAK,cAGhB,gBAAgB,CAAC,EAAuB,CACpC,KAAK,cAAgB,EACrB,KAAK,eAAiB,KAAK,2BAA2B,KAAK,aAAa,EACxE,KAAK,YAAc,KAAK,oBAAoB,EAE5C,KAAK,aAAe,CAAE,cAAe,CAAC,EAAG,aAAc,CAAC,CAAE,EAC1D,KAAK,WAAW,EAGpB,sBAAsB,CAAC,EAAe,EAAyB,CAC3D,GAAI,EAAQ,GAAK,GAAS,KAAK,cAAc,OACzC,MAAO,GAQX,OANA,KAAK,cAAc,GAAS,EAC5B,KAAK,eAAiB,KAAK,2BAA2B,KAAK,aAAa,EACxE,KAAK,YAAc,KAAK,oBAAoB,EAE5C,KAAK,aAAe,CAAE,cAAe,CAAC,EAAG,aAAc,CAAC,CAAE,EAC1D,KAAK,WAAW,EACT,GAGJ,OAAO,CAAC,EAAoB,CAC/B,KAAK,aAAa,CAAI,EACtB,IAAI,EAAS,KAAK,cAClB,MAAO,EAAO,OAAS,EAAG,CACtB,IAAI,EAAmB,EAAO,MAAM,CAAC,EACrC,QAAQ,EAAQ,EAAG,EAAQ,EAAiB,OAAQ,IAChD,EAAiB,GAAS,EAAS,UAAU,EAAS,uBAAuB,EAAO,GAAS,EAAI,CAAK,EAAG,EAAS,uBAAuB,EAAO,EAAQ,GAAI,CAAI,CAAC,EAErK,EAAS,EAEb,OAAO,EAAO,GAGX,GAAG,CAAC,EAAqB,CAE5B,GADA,KAAK,aAAa,CAAI,EAClB,KAAK,cAAc,QAAU,EAAG,CAChC,IAAI,EAAY,EAAS,uBAAuB,KAAK,cAAc,IAAK,EAAI,IAAS,EAAI,EAAK,EAC1F,EAAa,EAAS,uBAAuB,KAAK,cAAc,GAAI,GAAK,EAAI,GAAQ,CAAI,EACzF,EAAY,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAO,CAAI,EAElF,OADU,EAAS,UAAU,EAAS,UAAU,EAAW,CAAU,EAAG,CAAS,EAGrF,GAAI,KAAK,cAAc,QAAU,EAAE,CAC/B,IAAI,EAAY,EAAS,uBAAuB,KAAK,cAAc,IAAK,EAAI,IAAS,EAAI,IAAS,EAAI,EAAK,EACvG,EAAa,EAAS,uBAAuB,KAAK,cAAc,GAAI,GAAK,EAAI,IAAS,EAAI,GAAQ,CAAI,EACtG,EAAY,EAAS,uBAAuB,KAAK,cAAc,GAAI,GAAK,EAAI,GAAQ,EAAO,CAAI,EAC/F,EAAY,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAO,EAAO,CAAI,EAEzF,OADU,EAAS,UAAU,EAAS,UAAU,EAAW,CAAU,EAAG,EAAS,UAAU,EAAW,CAAS,CAAC,EAGpH,OAAO,KAAK,QAAQ,CAAI,EAGrB,MAAM,CAAC,EAAgB,IAAI,CAC9B,IAAM,EAAW,EAAI,EACf,EAAe,CAAC,EAClB,EAAO,EACX,EAAI,KAAK,KAAK,IAAI,CAAI,CAAC,EACvB,QAAQ,EAAQ,EAAG,EAAQ,EAAO,GAAS,EAAE,CAEzC,GADA,GAAQ,EACJ,EAAO,GAAK,EAAO,EAAW,GAAM,GAAS,EAAQ,EACrD,EAAO,EAEX,EAAI,KAAK,KAAK,IAAI,CAAI,CAAC,EAE3B,OAAO,EAGJ,cAAc,CAAC,EAAe,CACjC,GAAI,GAAS,KACT,EAAQ,IAEZ,IAAM,EAAW,EAAI,EACf,EAAsC,CAAC,EACzC,EAAO,EACX,EAAI,KAAK,CAAC,MAAO,KAAK,IAAI,CAAI,EAAG,KAAM,CAAI,CAAC,EAC5C,QAAQ,EAAQ,EAAG,EAAQ,EAAO,GAAS,EAAE,CAEzC,GADA,GAAQ,EACJ,EAAO,GAAK,EAAO,EAAW,GAAM,GAAS,EAAQ,EACrD,EAAO,EAEX,EAAI,KAAK,CAAC,MAAO,KAAK,IAAI,CAAI,EAAG,KAAM,CAAI,CAAC,EAEhD,OAAO,KAGP,WAAU,EAAU,CACpB,OAAO,KAAK,YAGR,mBAAmB,EAAU,CACjC,OAAO,KAAK,UAAU,CAAC,EAGpB,SAAS,CAAC,EAAqB,CAClC,KAAK,aAAa,CAAI,EAGtB,IAAM,EAAW,KAAK,MAAM,EAAO,GAAO,EAAI,IAC9C,GAAI,KAAK,YAAY,IAAI,CAAQ,EAC7B,OAAO,KAAK,YAAY,IAAI,CAAQ,EAGxC,IAAM,EAAI,EAAO,EAAG,EAAM,EAAE,OACxB,EAAM,EACV,QAAS,EAAI,EAAG,EAAW,EAAI,EAAK,IAChC,EAAI,EAAI,EAAE,GAAK,EACf,GAAO,EAAE,GAAK,EAAS,UAAU,KAAK,WAAW,CAAC,CAAC,EAEvD,IAAM,EAAS,EAAI,EAKnB,OAFA,KAAK,YAAY,IAAI,EAAU,CAAM,EAE9B,EAGJ,UAAU,CAAC,EAAoB,CAClC,OAAO,EAAyB,EAAM,KAAK,cAAc,EAGtD,oBAAoB,CAAC,EAAoB,CAC5C,OAAO,EAAS,WAAW,EAAyB,EAAM,KAAK,cAAc,CAAC,EAG3E,eAAe,CAAC,EAAgB,GAA6E,CAKhH,GAH6B,KAAK,aAAa,cAAc,SAAW,KAAK,cAAc,QACvF,KAAK,aAAa,cAAc,KAAK,CAAC,EAAI,IAAU,CAAC,EAAS,QAAQ,EAAI,KAAK,cAAc,EAAM,CAAC,GAE5E,KAAK,aAAa,aAAa,SAAW,EAAG,CAErE,KAAK,WAAW,EAEhB,IAAI,EAAM,CAAC,EACP,EAAS,EAAI,EACjB,QAAQ,EAAO,EAAG,GAAQ,EAAG,GAAQ,EACjC,EAAI,KAAK,CAAC,KAAM,EAAM,OAAQ,KAAK,UAAU,CAAI,CAAC,CAAC,EAEvD,KAAK,aAAe,CAAC,cAAe,CAAC,GAAG,KAAK,aAAa,EAAG,aAAc,CAAG,EAGlF,OAAO,KAAK,aAGhB,eAAe,CAAC,EAA+B,CAC3C,IAAM,EAAM,KAAK,MAAM,CAAI,EAC3B,MAAO,CAAC,IAAI,EAAO,EAAI,EAAE,EAAG,IAAI,EAAO,EAAI,EAAE,CAAC,EAG3C,KAAK,CAAC,EAAiC,CAE1C,GADA,KAAK,aAAa,CAAI,EAClB,KAAK,cAAc,QAAU,EAAE,CAC/B,IAAI,EAAmB,KAAK,cAAc,GACtC,EAAmB,EAAS,UAAU,EAAS,uBAAuB,KAAK,cAAc,GAAI,CAAI,EAAG,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAO,CAAC,CAAC,EACpK,EAAmB,EAAS,UAAU,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAO,CAAI,EAAG,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAI,GAAQ,EAAO,EAAE,CAAC,EAC5L,EAAmB,EAAS,UAAU,EAAkB,EAAS,uBAAuB,KAAK,cAAc,IAAK,EAAO,IAAM,EAAO,EAAE,CAAC,EACvI,IAAI,EAAmB,EAAS,UAAU,EAAS,uBAAuB,KAAK,cAAc,GAAI,CAAI,EAAG,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAO,CAAC,CAAC,EACpK,EAAmB,KAAK,cAAc,GAC1C,MAAO,CAAC,CAAC,EAAkB,EAAkB,CAAgB,EAAG,CAAC,EAAkB,EAAkB,CAAgB,CAAC,EAE1H,IAAI,EAAmB,KAAK,cAAc,GACtC,EAAmB,EAAS,UAAU,EAAS,uBAAuB,KAAK,cAAc,GAAI,CAAI,EAAG,EAAS,uBAAuB,KAAK,cAAc,GAAK,EAAO,CAAE,CAAC,EACtK,EAAmB,EAAS,UAAU,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAO,CAAI,EAAG,EAAS,UAAU,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAE,EAAI,GAAQ,EAAO,GAAG,EAAG,EAAS,uBAAuB,KAAK,cAAc,IAAK,EAAO,IAAM,EAAO,EAAE,CAAC,CAAC,EAChS,EAAQ,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAO,EAAO,CAAI,EACjF,EAAQ,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAE,EAAI,EAAO,GAAQ,EAAO,GAAG,EAC9F,EAAQ,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAI,GAAQ,EAAO,IAAM,EAAO,EAAE,EACjG,EAAQ,EAAS,uBAAuB,KAAK,cAAc,GAAI,GAAG,EAAO,IAAM,EAAO,IAAM,EAAO,GAAG,EACtG,EAAmB,EAAS,UAAU,EAAO,EAAS,UAAU,EAAO,EAAS,UAAU,EAAO,CAAK,CAAC,CAAC,EACxG,EAAmB,EAAS,UAAU,EAAS,UAAU,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAO,CAAI,EAAG,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAE,EAAK,GAAQ,EAAO,GAAG,CAAC,EAAG,EAAS,uBAAuB,KAAK,cAAc,IAAK,EAAO,IAAM,EAAO,EAAE,CAAC,EACjS,EAAmB,EAAS,UAAU,EAAS,uBAAuB,KAAK,cAAc,GAAI,CAAI,EAAG,EAAS,uBAAuB,KAAK,cAAc,GAAI,EAAE,EAAO,EAAE,CAAC,EACvK,EAAmB,KAAK,cAAc,GAE1C,MAAO,CAAC,CAAC,EAAkB,EAAkB,EAAkB,CAAgB,EAAG,CAAC,EAAkB,EAAkB,EAAkB,CAAgB,CAAC,EAG/J,yBAAyB,CAAC,EAAc,EAA2C,CAC9E,GAAG,EAAQ,EACP,QAAQ,KAAK,wCAAwC,EACrD,CAAC,EAAM,CAAK,EAAI,CAAC,EAAO,CAAI,EAGhC,IAAM,EAAa,KAAK,MAAM,CAAI,EAE5B,EAAa,IAAI,EAAO,EAAW,EAAE,EAErC,EAAc,EAAI,EAAO,EAAM,EAAG,EAAG,CAAC,EAEtC,EAAc,EAAW,MAAM,CAAW,EAEhD,MAAO,CAAC,EAAW,GAAI,EAAY,GAAI,EAAY,EAAE,EAG1D,cAAc,CAAC,EAAc,EAAwC,CAChE,GAAG,EAAQ,EACP,QAAQ,KAAK,wCAAwC,EACrD,CAAC,EAAM,CAAK,EAAI,CAAC,EAAO,CAAI,EAGhC,IAAM,EAAa,KAAK,MAAM,CAAI,EAE5B,EAAa,IAAI,EAAO,EAAW,EAAE,EAErC,EAAc,EAAI,EAAO,EAAM,EAAG,EAAG,CAAC,EACtC,EAAc,EAAW,MAAM,CAAW,EAEhD,MAAO,CAAC,IAAI,EAAO,EAAW,EAAE,EAAG,IAAI,EAAO,EAAY,EAAE,EAAG,IAAI,EAAO,EAAY,EAAE,CAAC,EAG7F,oBAAoB,CAAC,EAAc,EAAsB,CACrD,IAAO,EAAY,EAAa,GAAc,KAAK,eAAe,EAAM,CAAK,EAC7E,OAAO,EAGX,aAAa,CAAC,EAAa,CAEvB,IAAI,EAAW,OAAO,UAClB,EAAoC,EACpC,EAAoC,KAAK,IAAI,CAAC,EAC9C,EAAqC,EACnC,EAAM,KAAK,eAAe,GAAG,EACnC,EAAI,QAAQ,CAAC,EAAY,IAAQ,CAC7B,IAAM,EAAc,EAAS,sBAAsB,EAAW,MAAO,CAAK,EAC1E,GAAG,EAAc,EACb,EAAW,EACX,EAA6B,IAAI,EAAW,KAAK,EACjD,EAA4B,EAAW,KACvC,EAA6B,EAEpC,EAED,IAAI,EAAM,EAAI,GAA4B,KACtC,EAAO,EAAI,GAA4B,KAC3C,GAAI,EAA6B,EAAI,OAAS,EAC1C,EAAO,EAAI,EAA6B,GAAG,KAE/C,GAAI,EAA6B,EAC7B,EAAM,EAAI,EAA6B,GAAG,KAE9C,MAAM,EAAM,GAAQ,EAAO,EAxBT,QAwByB,CACvC,IAAI,EAAM,GAAO,EAAO,GAAO,EAC3B,EAAW,EAAM,EACjB,EAAY,EAAM,EAAW,EAC7B,EAAa,EAAM,EAAW,EAC9B,EAAW,EAGf,GAAG,GAAa,GAAK,GAAa,EAAE,CAChC,IAAI,EAAU,EAAS,sBAAsB,KAAK,IAAI,CAAS,EAAG,CAAK,EACvE,GAAI,EAAU,EACV,EAAW,EACX,EAA6B,KAAK,IAAI,CAAS,EAC/C,EAA4B,EAC5B,EAAO,EAAY,EAAW,EAC9B,EAAM,EAAY,EAAW,EAGrC,GAAG,GAAc,GAAK,GAAc,EAAE,CAClC,IAAI,EAAU,EAAS,sBAAsB,KAAK,IAAI,CAAU,EAAG,CAAK,EACxE,GAAI,EAAU,EACV,EAAW,EACX,EAA6B,KAAK,IAAI,CAAU,EAChD,EAA4B,EAC5B,EAAO,EAAa,EAAW,EAC/B,EAAM,EAAa,EAAW,EAGtC,GAAI,GAAY,EACZ,MAGR,MAAO,CAAC,WAAY,EAA4B,KAAM,CAAyB,EAG5E,QAAQ,CAAC,EAAuB,CACnC,IAAI,EAAM,EACJ,EAA2G,CAAC,EAElH,MAAO,EAAM,EAAE,CACX,IAAI,EAAU,KAAK,kBAAkB,EAAgB,CAAG,EACxD,GAAI,GAAW,MAAQ,EAAQ,KAAO,KAClC,MAIJ,GAFA,EAAI,KAAK,EAAQ,GAAG,EACpB,EAAM,EAAQ,IAAI,KACf,GAAO,EACN,MAGR,OAAO,EAGJ,iBAAiB,CAAC,EAAwB,EAAY,CACzD,IAAI,EAAO,EACP,EAAM,GAAO,EAAO,GAAO,EAC3B,EAAmI,CAAC,KAAM,EAAK,EAC/I,EAAQ,EACZ,MAAM,GAAK,CAGP,GAFA,IACA,EAAM,GAAO,EAAO,GAAO,EACvB,EAAO,GAAK,EAAM,EAClB,GAAI,EAAQ,KACR,OAAO,EAEP,YAAO,KAIf,IAAM,EAAW,KAAK,IAAI,CAAG,EACvB,EAAY,KAAK,IAAI,CAAI,EACzB,EAAW,KAAK,IAAI,CAAG,EACvB,EAAY,KAAK,OAAO,EAAU,EAAW,CAAQ,EAC3D,GAAI,CAAC,EAAU,QAAU,EAAU,QAAU,MAAQ,EAAU,QAAU,KACrE,OAAO,KAEX,IAAM,EAAI,EAAO,EACX,EAAK,EAAO,EAAI,EAChB,EAAK,EAAM,EAAI,EACf,EAAc,KAAK,IAAI,CAAE,EACzB,EAAc,KAAK,IAAI,CAAE,EACzB,EAAc,EAAS,sBAAsB,EAAa,EAAU,MAAM,EAC1E,EAAe,EAAS,sBAAsB,EAAa,EAAU,MAAM,EACjF,GAAI,KAAK,IAAI,EAAc,EAAU,MAAM,EAAI,GAAkB,KAAK,IAAI,EAAe,EAAU,MAAM,EAAI,EAAe,CAExH,GAAI,EAAQ,MAAQ,GAChB,OAAO,EAEX,EAAQ,KAAO,GACf,EAAO,EACJ,KAEH,GADA,EAAQ,KAAO,GACX,EAAU,aAAe,QAAa,EAAU,WAAa,OAC7D,EAAQ,IAAM,CAAE,OAAQ,EAAU,OAAQ,OAAQ,EAAU,OAAQ,WAAY,EAAU,WAAY,SAAU,EAAU,SAAU,OAAQ,EAAK,KAAM,CAAI,EAE/J,EAAO,GAAQ,EAAM,KAK1B,MAAM,CAAC,EAAmB,EAAiB,EAA0G,CACxJ,IAAM,EAAM,CAAC,CAAC,EAAW,EAAG,EAAW,EAAG,CAAC,EAAG,CAAC,EAAS,EAAG,EAAS,EAAG,CAAC,EAAG,CAAC,EAAS,EAAG,EAAS,EAAG,CAAC,CAAC,EACtG,GAAI,KAAK,gBAAgB,CAAG,GAAK,EAE7B,MAAO,CAAC,OAAQ,EAAK,EAEzB,IAAM,EAAM,CAAC,CAAC,EAAW,EAAI,EAAW,EAAI,EAAW,EAAI,EAAW,EAAG,EAAW,EAAG,CAAC,EAC3E,CAAC,EAAS,EAAI,EAAS,EAAI,EAAS,EAAI,EAAS,EAAG,EAAS,EAAG,CAAC,EACjE,CAAC,EAAS,EAAI,EAAS,EAAI,EAAS,EAAI,EAAS,EAAG,EAAS,EAAG,CAAC,CAAC,EACzE,EAAM,CAAC,CAAC,EAAW,EAAI,EAAW,EAAI,EAAW,EAAI,EAAW,EAAG,EAAW,EAAG,CAAC,EAC3E,CAAC,EAAS,EAAI,EAAS,EAAI,EAAS,EAAI,EAAS,EAAG,EAAS,EAAG,CAAC,EACjE,CAAC,EAAS,EAAI,EAAS,EAAI,EAAS,EAAI,EAAS,EAAG,EAAS,EAAG,CAAC,CAAC,EACzE,EAAM,CAAC,CAAC,EAAW,EAAI,EAAW,EAAI,EAAW,EAAI,EAAW,EAAG,EAAW,EAAG,EAAW,CAAC,EACtF,CAAC,EAAS,EAAI,EAAS,EAAI,EAAS,EAAI,EAAS,EAAG,EAAS,EAAG,EAAS,CAAC,EAC1E,CAAC,EAAS,EAAI,EAAS,EAAI,EAAS,EAAI,EAAS,EAAG,EAAS,EAAG,EAAS,CAAC,CAAC,EAClF,EAAW,KAAU,KAAK,gBAAgB,CAAG,EAAI,KAAK,gBAAgB,CAAG,GACzE,EAAW,MAAW,KAAK,gBAAgB,CAAG,EAAI,KAAK,gBAAgB,CAAG,GAC1E,EAAS,KAAK,KAAK,EAAU,EAAU,EAAU,EAAW,KAAK,gBAAgB,CAAG,EAAI,KAAK,gBAAgB,CAAG,CAAE,EACxH,MAAO,CAAC,OAAQ,GAAM,OAAQ,CAAC,EAAG,EAAS,EAAE,CAAO,EAAG,OAAQ,EAAQ,WAAY,EAAY,SAAU,CAAQ,EAG9G,eAAe,CAAC,EAA2B,CAC9C,IAAM,EAAI,EAAO,GAAG,GACd,EAAI,EAAO,GAAG,GACd,EAAI,EAAO,GAAG,GACd,EAAI,EAAO,GAAG,GACd,EAAI,EAAO,GAAG,GACd,EAAI,EAAO,GAAG,GACd,EAAI,EAAO,GAAG,GACd,EAAI,EAAO,GAAG,GACd,EAAI,EAAO,GAAG,GACpB,OAAO,GAAK,EAAI,EAAI,EAAI,GAAK,GAAK,EAAI,EAAI,EAAI,GAAK,GAAK,EAAI,EAAI,EAAI,GAGjE,SAAS,CAAC,EAAqB,CAClC,IAAM,EAAa,EAAyB,EAAM,KAAK,cAAc,EAC/D,EAAmB,EAAyB,EAAM,KAAK,2BAA2B,KAAK,cAAc,CAAC,EACtG,EAAY,EAAW,EAAI,EAAiB,EAAI,EAAiB,EAAI,EAAW,EAChF,EAAc,KAAK,IAAI,EAAW,EAAI,EAAW,EAAI,EAAW,EAAI,EAAW,EAAG,GAAK,EAC7F,GAAI,GAAe,EAAG,MAAO,KAC7B,OAAO,EAAY,EAGvB,gBAAgB,CAAC,EAAoB,CACjC,OAAO,EAAyB,EAAM,KAAK,2BAA2B,KAAK,cAAc,CAAC,EAGvF,sBAAsB,EAAW,CACpC,OAAO,KAAK,wCAAwC,KAAK,aAAa,EAGnE,yBAAyB,EAAW,CACvC,OAAO,KAAK,wCAAwC,KAAK,cAAc,EAGpE,uCAAuC,CAAC,EAAgC,CAC3E,IAAM,EAAiB,CAAC,EACpB,EAAqB,CAAC,EAC1B,GAAG,EAAc,QAAU,EACvB,EAAS,CAAC,CAAC,EAAG,EAAG,CAAC,EAAG,CAAC,GAAI,EAAG,CAAC,EAAG,CAAC,EAAG,GAAI,CAAC,CAAC,EACxC,QAAI,EAAc,QAAU,EAC/B,EAAS,CAAC,CAAC,EAAG,EAAG,EAAG,CAAC,EAAG,CAAC,GAAI,EAAG,EAAG,CAAC,EAAG,CAAC,EAAG,GAAI,EAAG,CAAC,EAAG,CAAC,GAAI,EAAG,GAAI,CAAC,CAAC,EACjE,QAAG,EAAc,QAAU,EAC9B,EAAS,CAAC,CAAC,EAAG,CAAC,EAAG,CAAC,GAAI,CAAC,CAAC,EAGzB,WAAU,MAAM,mCAAmC,EAEvD,QAAQ,EAAQ,EAAG,EAAQ,EAAc,OAAQ,IAC7C,EAAM,KAAK,EAAc,OAAO,CAAC,EAAS,EAAQ,IAAS,CACvD,MAAO,CAAC,EAAG,EAAQ,EAAI,EAAO,GAAO,GAAU,EAAO,EAAG,EAAG,EAAQ,EAAI,EAAO,GAAO,GAAU,EAAO,CAAC,GACzG,CAAC,EAAG,EAAG,EAAG,CAAC,CAAC,CAAC,EAEpB,OAAO,EAGX,gCAAgC,EAAE,CAC9B,IAAM,EAAc,EAAS,kBAAkB,KAAK,cAAc,GAAI,KAAK,cAAc,KAAK,cAAc,OAAS,EAAE,EACjH,EAAQ,EAAS,aAAa,CAAC,EAAE,EAAG,EAAE,CAAC,EAAG,CAAW,EACrD,EAAgB,KAAK,cAAc,GACnC,EAAM,CAAC,CAAC,EAAG,EAAG,EAAG,CAAC,CAAC,EACzB,QAAQ,EAAQ,EAAG,EAAQ,KAAK,cAAc,OAAQ,IAAQ,CAC1D,IAAM,EAAS,EAAS,UAAU,KAAK,cAAc,GAAQ,CAAa,EACpE,EAAgB,EAAS,YAAY,EAAQ,CAAC,CAAK,EACzD,EAAI,KAAK,CAAa,EAE1B,OAAO,EAGX,UAAU,EAA6B,CACnC,IAAM,EAAkC,CAAC,EAAG,CAAC,EAAG,EAAG,CAAC,CAAC,EAC/C,EAAyB,KAAK,0BAA0B,EAC1D,EAAgB,CAAC,EAAG,EAAG,EAAG,CAAC,EAC3B,EAAgB,CAAC,EAAG,EAAG,EAAG,CAAC,EAC/B,EAAuB,QAAQ,CAAC,EAAa,IAAQ,CACjD,EAAc,EAAI,GAAS,EAAY,EACvC,EAAc,EAAI,GAAS,EAAY,EAC1C,EAED,IAAM,EAAS,EAAW,EAAc,GAAI,EAAc,GAAI,EAAc,GAAI,EAAc,EAAE,EAC1F,EAAS,EAAW,EAAc,GAAI,EAAc,GAAI,EAAc,GAAI,EAAc,EAAE,EAYhG,GAXA,EAAO,QAAQ,CAAC,IAAO,CACnB,GAAG,GAAQ,GAAK,GAAQ,EACpB,EAAI,EAAE,KAAK,CAAI,EAEtB,EACD,EAAO,QAAQ,CAAC,IAAO,CACnB,GAAG,GAAQ,GAAK,GAAQ,EACpB,EAAI,EAAE,KAAK,CAAI,EAEtB,EAEE,EAAuB,QAAU,EAAE,CAClC,EAAgB,CAAC,EAAG,EAAG,EAAG,CAAC,EAC3B,EAAgB,CAAC,EAAG,EAAG,EAAG,CAAC,EACU,KAAK,wCAAwC,KAAK,2BAA2B,KAAK,cAAc,CAAC,EACzG,QAAQ,CAAC,EAAa,IAAQ,CACvD,EAAc,EAAI,GAAS,EAAY,EACvC,EAAc,EAAI,GAAS,EAAY,EAC1C,EACD,IAAM,EAAe,EAAW,EAAc,GAAI,EAAc,GAAI,EAAc,GAAI,EAAc,EAAE,EAChG,EAAe,EAAW,EAAc,GAAI,EAAc,GAAI,EAAc,GAAI,EAAc,EAAE,EACtG,EAAa,QAAQ,CAAC,IAAO,CACzB,GAAG,GAAQ,GAAK,GAAQ,EACpB,EAAI,EAAE,KAAK,CAAI,EAEtB,EACD,EAAa,QAAQ,CAAC,IAAO,CACzB,GAAG,GAAQ,GAAK,GAAQ,EACpB,EAAI,EAAE,KAAK,CAAI,EAEtB,EAGL,OAAO,EAGX,4BAA4B,CAAC,EAAoB,EAAsB,CAEnE,IAAM,EAAe,CAAC,EACtB,QAAQ,EAAQ,EAAG,EAAQ,KAAK,cAAc,OAAQ,IAClD,EAAI,KAAK,EAAS,YAAY,EAAS,UAAU,KAAK,cAAc,GAAQ,CAAW,EAAG,CAAa,CAAC,EAE5G,OAAO,EAGX,oBAAoB,CAAC,EAAqB,CACtC,IAAM,EAAsB,EAAK,mCAAmC,EAC9D,EAAgB,CAAC,EACjB,EAAuB,KAAK,6BAA6B,EAAoB,YAAa,EAAoB,aAAa,EAC3H,EAAe,KAAK,wCAAwC,CAAoB,EAClF,EAAgB,CAAC,EAAG,EAAG,EAAG,CAAC,EAc/B,OAbA,EAAa,QAAQ,CAAC,EAAa,IAAQ,CACvC,EAAc,EAAI,GAAS,EAAY,EAC1C,EAEc,EAAW,EAAc,GAAI,EAAc,GAAI,EAAc,GAAI,EAAc,EAAE,EACzF,QAAQ,CAAC,IAAO,CACnB,GAAG,GAAQ,GAAK,GAAQ,GACpB,GAAG,EAAK,YAAY,KAAK,IAAI,CAAI,CAAC,EAC9B,EAAI,KAAK,CAAI,GAGxB,EAEM,EAGX,oBAAoB,EAAqC,CACrD,IAAO,EAAwB,GAA0B,KAAK,MAAM,GAAG,EACjE,EAAY,IAAI,EAAO,CAAsB,EAC7C,EAAY,IAAI,EAAO,CAAsB,EAC/C,EAAa,EAA8B,EAAW,CAAS,EAMnE,OALA,EAAW,QAAQ,CAAC,IAAe,CAC/B,EAAa,MAAQ,EAAa,MAAQ,IAC1C,EAAa,OAAS,EAAa,OAAS,IAAM,IACrD,EACD,EAAW,MAAM,EACV,EAGX,sBAAsB,CAAC,EAAqB,EAA4D,CACpG,IAAM,EAAM,KAAK,eAAe,GAAG,EAC/B,EAAgB,OAAO,UACvB,EAA+B,EAC/B,EAAsC,EAAI,GAAG,MAC7C,EAA8B,EAAI,GAAG,KACzC,EAAI,QAAQ,CAAC,EAAY,IAAQ,CAC7B,IAAI,EAAmB,KAAK,IAAI,EAAS,sBAAsB,EAAc,EAAW,KAAK,CAAC,EAC9F,GAAI,EAAmB,EACnB,EAAgB,EAChB,EAA+B,EAEtC,EACD,IAAM,EAAO,EAAI,IAAI,CAAC,EAAY,IAAQ,CACtC,MAAO,IAAI,EAAY,SAAU,CAAC,EACrC,EACD,EAAgB,OAAO,UACvB,IAAI,EAAQ,EACR,EAAQ,EACR,EAAoB,CAAC,EACzB,MAAM,EAAE,EAAQ,GAAG,CACf,IAAI,EAAI,KAAK,YAAY,EAAa,EAAG,EAAa,EAAG,EAAM,EAAc,EAAG,EAAK,EAAQ,IAAI,SAAU,EAAK,EAAQ,IAAI,QAAQ,EACpI,GAAI,EAAI,EAAO,MACf,GAAI,EAAI,GAAK,GAAK,EAAO,MACzB,EAAQ,KAAK,CAAC,EACd,EAAQ,EAAI,EAEhB,IAAM,EAAmD,CAAC,EAO1D,OANA,EAAQ,QAAQ,CAAC,IAAQ,CACrB,IAAI,EAAM,KAAK,aAAa,KAAM,EAAa,EAAG,EAAa,EAAG,EAAM,EAAO,CAAY,EAC3F,GAAI,GAAO,KACP,EAAU,KAAK,CAAC,aAAc,EAAI,MAAO,KAAM,EAAI,IAAI,CAAC,EAE/D,EACM,EAGX,oBAAoB,CAAC,EAAc,EAAwC,CAEvE,IAAM,EADgB,KAAK,UAAU,CAAI,EACJ,EAGrC,GAAG,IAAS,GAAK,EAAS,EACtB,MAAO,CAAC,KAAM,cAAe,aAAc,CAAC,CAAM,EAEtD,GAAG,IAAS,GAAK,EAAS,EACtB,MAAO,CAAC,KAAM,aAAc,aAAc,CAAM,EAEpD,GAAG,EAAe,KAAK,WACnB,MAAO,CAAC,KAAM,aAAc,aAAc,EAAe,KAAK,UAAU,EACrE,QAAG,EAAe,EACrB,MAAO,CAAC,KAAM,cAAe,aAAc,CAAC,CAAY,EAI5D,GAAG,KAAK,aAAa,aAAa,SAAW,EACzC,KAAK,aAAe,KAAK,gBAAgB,IAAI,EAEjD,IAAM,EAAS,KAAK,aAAa,aAC7B,EAAM,EACN,EAAO,EAAO,OAAS,EAG3B,MAAO,GAAO,EAAK,CACf,IAAM,EAAM,KAAK,OAAO,EAAM,GAAQ,CAAC,EACjC,EAAY,EAAO,GAAK,OAE9B,GAAI,EAAc,EAAW,EAAc,IAAI,EAAG,CAE9C,IAAM,EAAa,EAAO,GAAK,KACzB,EAAQ,KAAK,IAAI,CAAU,EACjC,MAAO,CAAC,KAAM,cAAe,KAAM,EAAY,MAAO,CAAK,EACxD,QAAI,EAAY,EACnB,EAAM,EAAM,EAEZ,OAAO,EAAM,EAQrB,GAAI,EAAO,EAEP,EAAO,EACP,EAAM,EAGV,GAAI,GAAO,EAAO,OAEd,EAAO,EAAO,OAAS,EACvB,EAAM,EAAO,OAAS,EAI1B,IAAM,EAAK,EAAO,GACZ,EAAK,EAAO,GAGZ,EAAc,EAAG,OAAS,EAAG,OAC7B,EAAS,EAAG,KAAO,EAAG,KAE5B,GAAI,IAAgB,EAAG,CAEnB,IAAM,EAAQ,KAAK,IAAI,EAAG,IAAI,EAC9B,MAAO,CAAC,KAAM,cAAe,KAAM,EAAG,KAAM,MAAO,CAAK,EAG5D,IAAM,GAAS,EAAe,EAAG,QAAU,EACrC,EAAgB,EAAG,KAAO,EAAQ,EAGlC,EAAW,KAAK,IAAI,EAAG,KAAK,IAAI,EAAG,CAAa,CAAC,EACjD,EAAQ,KAAK,IAAI,CAAQ,EAE/B,MAAO,CAAC,KAAM,cAAe,KAAM,EAAU,MAAO,CAAK,EAG7D,iBAAiB,CAAC,EAAgB,EAA2C,CACzE,IAAI,EAAW,EACX,EAAoB,EAClB,EAAW,KAEjB,GAAG,EAAW,KAAK,WACf,MAAO,CAAC,KAAM,aAAc,aAAc,EAAW,KAAK,UAAU,EACjE,QAAG,EAAW,EACjB,MAAO,CAAC,KAAM,cAAe,aAAc,CAAC,CAAQ,EAGxD,MAAO,EAAoB,GAAK,EAAW,EAAG,CAC1C,IAAM,EAAe,KAAK,IAAI,CAAQ,EAChC,EAAQ,KAAK,IAAI,EAAW,EAAU,CAAC,EACvC,EAAY,KAAK,IAAI,CAAK,EAE1B,EAAgB,KAAK,KACvB,KAAK,IAAI,EAAU,EAAI,EAAa,EAAG,CAAC,EACxC,KAAK,IAAI,EAAU,EAAI,EAAa,EAAG,CAAC,CAC5C,EAEA,GAAI,GAAiB,EAAmB,CAEpC,IAAM,EAAQ,EAAoB,EAClC,MAAO,CAAC,KAAM,cAAe,KAAM,EAAW,GAAS,EAAQ,GAAW,MAAO,KAAK,IAAI,EAAW,GAAS,EAAQ,EAAS,CAAC,EAGpI,GAAqB,EACrB,EAAW,EAGf,MAAO,CAAC,KAAM,cAAe,KAAM,EAAU,MAAO,KAAK,IAAI,CAAQ,CAAC,EAG1E,YAAY,CAAC,EAAe,EAAW,EAAW,EAAuD,EAAW,EAAe,EAAG,EAAQ,KAAM,CAChJ,IAAI,EAAgE,EAAI,GACtE,EAAQ,EACR,EAAW,OAAO,iBAEpB,EAAG,CACD,IAAI,EAAK,IAAM,EAAI,EAAI,EAAI,EACvB,EAAK,IAAM,EAAI,OAAS,EAAI,EAAI,OAAS,EAAI,EAAI,EACjD,EAAK,EAAI,GAAI,KACb,EAAK,EAAI,GAAI,KACb,EAAwD,CAAC,EACzD,GAAQ,EAAK,GAAM,EAEvB,GAAI,EAAO,MAAO,MAElB,EAAI,KAAK,EAAI,EAAG,EAChB,QAAS,EAAI,EAAG,GAAK,EAAG,IAAK,CAC3B,IAAI,EAAI,EAAM,IAAI,EAAK,EAAI,CAAI,EAC3B,EAAY,KAAK,IAAI,EAAS,sBAAsB,EAAG,CAAC,EAAG,EAAG,EAAG,CAAC,CAAC,EAAI,CAAc,EACzF,GAAI,EAAY,EACd,EAAW,EACX,EAAI,CAAC,MAAO,EAAG,KAAM,EAAK,EAAI,EAAM,SAAU,CAAS,EACvD,EAAI,EAEN,EAAI,KAAK,CAAC,MAAO,EAAG,KAAM,EAAK,EAAI,EAAM,SAAU,CAAS,CAAC,EAE/D,EAAI,KAAK,EAAI,EAAG,EAGhB,EAAM,QAKC,IAAU,IAInB,GAAI,GAAkB,EAAW,EAC/B,EAAI,OAGN,OAAO,EAGX,WAAW,CAAC,EAAW,EAAW,EAAuD,EAAsB,EAAkB,EAAG,EAAc,EAAc,CAC5J,IAAI,EAAW,OAAO,iBACpB,EAAgB,GAAO,EACvB,EAAgB,GAAO,EACvB,EAAI,GAEN,QAAS,EAAM,EAAG,EAAE,EAAI,OAAQ,EAAM,EAAG,IAAQ,CAC/C,IAAI,EAAI,EAAI,GAAO,MAMnB,GALA,EAAI,GAAO,SAAW,KAAK,IAAI,EAAS,sBAAsB,CAAC,EAAE,EAAG,EAAE,CAAC,EAAG,CAAC,EAAI,CAAY,EAKvF,EAAgB,GAAmB,EAAgB,GAAiB,EAAgB,EAAI,GAAO,SAAU,CAC3G,EAAI,EAAQ,EACZ,MAGF,GAAI,EAAI,GAAO,SAAW,EACxB,EAAW,EAAI,GAAO,SAGxB,EAAgB,EAChB,EAAgB,EAAI,GAAO,SAG7B,OAAO,EAGX,qBAAqB,CAAC,EAAe,EAAmE,CACpG,OAAO,EAA8B,KAAM,EAAO,CAAsB,KAGxE,KAAI,EAA2B,CAC/B,IAAM,EAAU,KAAK,WAAW,EAC1B,EAAQ,CAAC,EAAG,CAAC,EACf,EAAa,CAAC,EAAG,OAAO,UAAW,EAAG,OAAO,SAAS,EACtD,EAAa,CAAC,EAAG,CAAC,OAAO,UAAW,EAAG,CAAC,OAAO,SAAS,EAe5D,OAdA,EAAQ,EAAE,QAAQ,CAAC,IAAO,CACtB,EAAM,KAAK,CAAI,EAClB,EACD,EAAQ,EAAE,QAAQ,CAAC,IAAO,CACtB,EAAM,KAAK,CAAI,EAClB,EACD,EAAM,QAAQ,CAAC,IAAO,CAClB,IAAM,EAAW,KAAK,IAAI,CAAI,EAC9B,EAAI,EAAI,KAAK,IAAI,EAAI,EAAG,EAAS,CAAC,EAClC,EAAI,EAAI,KAAK,IAAI,EAAI,EAAG,EAAS,CAAC,EAClC,EAAI,EAAI,KAAK,IAAI,EAAI,EAAG,EAAS,CAAC,EAClC,EAAI,EAAI,KAAK,IAAI,EAAI,EAAG,EAAS,CAAC,EACrC,EAEM,CAAC,IAAI,EAAK,IAAI,CAAG,EAG5B,MAAM,CAAC,EAAgD,CACnD,IAAM,EAAI,KAAK,WAAW,CAAI,EACxB,EAAI,KAAK,KAAK,EAAE,EAAI,EAAE,EAAI,EAAE,EAAI,EAAE,CAAC,EACzC,MAAO,CAAC,OAAM,UAAW,CAAC,EAAG,CAAC,EAAE,EAAI,EAAG,EAAG,EAAE,EAAI,CAAC,CAAC,EAE1D,CAMO,SAAS,CAAM,CAAC,EAAe,CAClC,IAAI,EACF,EAAK,EACL,EAAK,EACL,EAAO,KACP,EACA,EAAkB,CAAC,EACnB,EAAkB,CAAC,EAGjB,EAAU,EAAM,WAAW,EAAE,EACjC,GAAI,EAAQ,QAAQ,CAAC,IAAM,GACzB,EAAU,CAAC,CAAC,EAAE,OAAO,CAAO,EAE9B,GAAI,EAAQ,QAAQ,CAAC,IAAM,GACzB,EAAQ,KAAK,CAAC,EAEhB,IAAK,EAAK,EAAQ,GAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAC/C,EAAK,EAAQ,GACb,EAAU,EAAM,qBAAqB,EAAI,CAAE,EAC3C,EAAM,KAAK,CAAO,EAClB,EAAK,EAgCP,OA5BA,EAAM,QAAQ,KAAM,CAClB,EAAK,EACL,EAAK,EACL,MAAO,GAAM,EACX,IAAK,EAAK,EAAK,EAAM,GAAM,EAAI,EAAM,GAAM,EAAM,CAE/C,IAAM,EAAY,KAAK,IAAI,EAAI,CAAC,EAEhC,GADA,EAAU,EAAG,qBAAqB,EAAI,CAAS,EAC3C,CAAC,EAAc,CAAO,EAAG,CAE3B,GADA,GAAM,EACF,KAAK,IAAI,EAAK,CAAE,EAAI,EAEtB,MAAO,CAAC,EAEV,IAAM,EAAU,KAAK,IAAI,EAAI,CAAC,EAC9B,EAAU,EAAG,qBAAqB,EAAI,CAAO,EAC7C,EAAM,KAAK,CAAO,EAClB,EAAK,EACL,OAIN,GAAI,EAAK,EACP,EAAU,EAAG,qBAAqB,EAAI,CAAC,EACvC,EAAM,KAAK,CAAO,EAErB,EAEM,EAGX,SAAS,CAAe,CAAC,EAAuB,CAC5C,IAAM,EAAI,EAAM,iBAAiB,EAC7B,EAAK,CAAC,EAAE,EAAE,EACV,EAAI,EAAE,OACV,QAAS,EAAI,EAAG,EAAI,EAAG,IAAK,CACxB,IAAM,EAAK,EAAE,GACP,EAAM,EAAE,EAAI,GAClB,EAAG,GAAK,CACJ,GAAK,EAAI,GAAK,EAAK,EAAG,EAAK,EAAI,EAAK,EAAI,EACxC,GAAK,EAAI,GAAK,EAAK,EAAG,EAAK,EAAI,EAAK,EAAI,CAC5C,EAGJ,OADA,EAAG,GAAK,EAAE,EAAI,GACP,IAAI,EAAO,CAAE,EAUjB,SAAS,CAAM,CAAC,EAAe,EAAW,EAAwB,CACrE,GAAI,IAAM,OAAW,CACjB,IAAM,EAAI,EAAM,IAAI,CAAC,EACrB,EAAI,EAAM,OAAO,CAAC,EAAE,UAUpB,MATY,CACZ,EAAG,EACH,EAAG,EACH,EAAG,EAAE,EAAI,EAAE,EAAI,EACf,EAAG,EAAE,EAAI,EAAE,EAAI,CACf,EAQJ,IAAM,EAAS,EAAM,iBAAiB,EAGtC,GAFe,EAAc,CAAK,EAEtB,CACR,IAAM,EAAK,EAAM,OAAO,CAAC,EAAE,UAC3B,EAAS,EAAO,IAAI,QAAS,CAAC,EAAG,CAK7B,MAJY,CACZ,EAAG,EAAE,EAAI,EAAI,EAAG,EAChB,EAAG,EAAE,EAAI,EAAI,EAAG,CAChB,EAEH,EACD,MAAO,CAAC,IAAI,EAAO,CAAM,CAAC,EAI9B,OAAO,EAAO,CAAK,EAAE,IAAI,QAAS,CAAC,EAAG,CAClC,GAAI,EAAc,CAAC,EACf,OAAO,EAAO,EAAG,CAAC,EAAE,GAExB,OAAO,EAAW,EAAG,CAAC,EACzB,EAOE,SAAS,EAAO,CAAC,EAAe,EAAmB,CAUtD,OATY,EAAM,eAAe,GAAG,EAEpB,IAAI,CAAC,IAAO,CACxB,IAAM,EAAa,EAAS,WAAW,EAAM,WAAW,EAAK,IAAI,CAAC,EAC5D,EAAS,CAAC,EAAG,CAAC,EAAW,EAAG,EAAG,EAAW,CAAC,EAEjD,MADoB,CAAC,EAAG,EAAK,MAAM,EAAI,EAAO,EAAI,EAAG,EAAG,EAAK,MAAM,EAAI,EAAO,EAAI,CAAC,EAEtF,EAML,SAAS,CAAI,CAAC,EAAW,EAAW,EAAW,EAA0B,CACrE,IAAc,EAAR,EAAmB,EAAR,GAAK,EAChB,EAAK,EAAG,EAAG,EAAK,EAAG,EACnB,EAAK,EAAG,EAAG,EAAK,EAAG,EACnB,EAAK,EAAG,EAAG,EAAK,EAAG,EACzB,OAAO,EAAK,EAAI,EAAI,EAAI,EAAI,EAAI,EAAI,EAAI,CAAE,EAG9C,SAAS,CAAI,CAAC,EAAY,EAAY,EAAY,EAAY,EAAY,EAAY,EAAY,EAA2B,CACzH,IAAM,GAAM,EAAK,EAAK,EAAK,IAAO,EAAK,IAAO,EAAK,IAAO,EAAK,EAAK,EAAK,GACnE,GAAM,EAAK,EAAK,EAAK,IAAO,EAAK,IAAO,EAAK,IAAO,EAAK,EAAK,EAAK,GACnE,GAAK,EAAK,IAAO,EAAK,IAAO,EAAK,IAAO,EAAK,GACpD,GAAI,GAAK,EACL,MAAO,GAEX,MAAO,CAAE,EAAG,EAAK,EAAG,EAAG,EAAK,CAAE,EAGlC,SAAS,CAAa,CAAC,EAAuB,CAC1C,IAAM,EAAQ,EAAM,iBAAiB,EAAE,OAAS,EAC1C,EAAS,EAAM,iBAAiB,EAChC,EAAgB,EAAkB,EAAQ,CAAC,GAAI,EAAO,GAAI,GAAI,EAAO,EAAM,CAAC,EAC5E,EAAa,EAAS,sBAAsB,EAAO,GAAI,EAAO,EAAM,EAK1E,OAFe,EAAc,OAAO,CAAC,EAAG,IAAM,EAAI,KAAK,IAAI,EAAE,CAAC,EAAG,CAAC,EAAI,EAAa,GAMvF,SAAS,CAAU,CAAC,EAAe,EAA6C,CAC5E,IAAM,EAAQ,EAAM,iBAAiB,EAAE,OAAS,EAC5C,EAAkD,OAEtD,GAAI,OAAO,IAAM,WACb,EAAa,EAGjB,GAAI,GAAc,IAAU,EACxB,OAAO,EAAW,EAAgB,CAAK,EAAG,CAAU,EAGxD,IAAM,EAAS,EAAM,iBAAiB,EAGtC,GAAI,EAAc,CAAK,EACnB,OAAO,EACH,EACA,EAAM,OAAO,CAAC,EAAE,UAChB,EAAa,EAAW,CAAC,EAAI,EAC7B,EAAa,EAAW,CAAC,EAAI,CACjC,EAGJ,IAAM,EAAK,EAAa,EAAW,CAAC,EAAI,EAClC,EAAK,EAAa,EAAW,CAAC,EAAI,EAGlC,EAAI,CAAC,EAAO,EAAO,EAAG,EAAE,EAAG,EAAO,EAAO,EAAG,EAAE,CAAC,EAC/C,EAAc,CAAC,EACf,EAAI,EAAK,EAAE,GAAY,EAAE,GAAW,EAAG,EAAE,GAAY,EAAE,GAAW,CAAC,EAEzE,GAAI,CAAC,EAED,OAAO,EACH,EACA,EAAM,OAAO,CAAC,EAAE,UAChB,EACA,CACJ,EAYJ,GARA,CAAC,EAAG,CAAC,EAAE,QAAQ,QAAS,CAAC,EAAG,CACxB,IAAM,EAAI,KAAK,MAAM,KAAK,UAAU,EAAO,EAAI,EAAM,CAAC,EAChD,EAAK,EAAE,GACb,EAAE,IAAM,EAAI,EAAK,GAAM,EAAG,EAAE,EAC5B,EAAE,IAAM,EAAI,EAAK,GAAM,EAAG,EAAE,EAC5B,EAAG,EAAI,GAAS,EACnB,EAEG,CAAC,EAqBD,MAlBA,CAAC,EAAG,CAAC,EAAE,QAAQ,CAAC,IAAM,CAClB,GAAI,IAAU,GAAK,CAAC,CAAC,EAAG,OACxB,IAAM,EAAI,EAAG,EAAI,GACX,EAAgB,EAAM,WAAW,CAAC,EAClC,EAAK,CAAE,EAAG,EAAE,EAAI,EAAc,EAAG,EAAG,EAAE,EAAI,EAAc,CAAE,EAC1D,EAAe,EAAK,EAAG,EAAI,EAAG,EAAO,EAAI,EAAE,EACjD,GAAI,EACA,EAAG,EAAI,GAAK,EACT,KAEH,IAAM,EAAgB,EAAO,EAAI,GAC3B,EAAS,EAAM,QAAQ,EAAI,GAAK,CAAK,EAAE,UAC7C,EAAG,EAAI,GAAK,CACR,EAAG,EAAc,GAAK,EAAI,EAAK,GAAM,EAAO,EAC5C,EAAG,EAAc,GAAK,EAAI,EAAK,GAAM,EAAO,CAChD,GAEP,EACM,IAAI,EAAO,CAAE,EAqBxB,MAhBA,CAAC,EAAG,CAAC,EAAE,QAAQ,QAAS,CAAC,EAAG,CACxB,GAAI,IAAU,GAAK,CAAC,CAAC,EAAG,OACxB,IAAM,EAAI,EAAO,EAAI,GACf,EAAK,CACP,EAAG,EAAE,EAAI,EAAE,EACX,EAAG,EAAE,EAAI,EAAE,CACf,EACI,EAAK,GAAa,EAAI,GAAK,CAAK,EAC9B,EAAI,KAAK,KAAK,EAAG,EAAI,EAAG,EAAI,EAAG,EAAI,EAAG,CAAC,EAC7C,EAAG,GAAK,EACR,EAAG,GAAK,EACR,EAAG,EAAI,GAAK,CACR,EAAG,EAAE,EAAI,EAAK,EAAG,EACjB,EAAG,EAAE,EAAI,EAAK,EAAG,CACrB,EACH,EACM,IAAI,EAAO,CAAE,EAGxB,SAAS,CAAiB,CAAC,EAAiB,EAA8B,CACtE,IAAM,EAAK,EAAK,GAAG,EACjB,EAAK,EAAK,GAAG,EACb,EAAI,CAAC,KAAK,MAAM,EAAK,GAAG,EAAI,EAAI,EAAK,GAAG,EAAI,CAAE,EAC9C,EAAI,QAAS,CAAC,EAAU,CACtB,MAAO,CACL,GAAI,EAAE,EAAI,GAAM,KAAK,IAAI,CAAC,GAAK,EAAE,EAAI,GAAM,KAAK,IAAI,CAAC,EACrD,GAAI,EAAE,EAAI,GAAM,KAAK,IAAI,CAAC,GAAK,EAAE,EAAI,GAAM,KAAK,IAAI,CAAC,CACvD,GAEJ,OAAO,EAAO,IAAI,CAAC,EAGvB,SAAS,CAAG,CAAC,EAAW,EAAY,EAAY,EAAY,EAAoB,CAC5E,IAAM,EAAK,EAAK,EACd,EAAK,EAAK,EACV,EAAK,EAAI,EACT,EAAI,EAAK,EACX,OAAO,EAAK,EAAK,EAOd,MAAM,UAA4B,KAAK,CAC1C,WAAW,CAAC,EAAgB,CACxB,MAAM,CAAO,EAErB,CAgBO,SAAS,CAAc,CAAC,EAAiC,EAAyC,CACrG,GAAK,EAAM,IAAI,GAAK,EAAM,IAAI,GAAK,EAAM,IAAI,GAAK,EAAM,IAAI,IAAO,EAAM,IAAI,GAAK,EAAM,IAAI,GAAK,EAAM,IAAI,GAAK,EAAM,IAAI,GACtH,MAAO,GAEX,MAAO,GAOJ,SAAS,CAAc,CAAC,EAAW,EAAW,EAAoB,CAErE,OAAO,KAAK,IAAI,EAAI,CAAC,IAAM,GADX,UAIb,SAAS,CAAS,CAAC,EAAU,CAChC,GAAG,EAAE,EAAG,MAAO,CAAC,KAAK,IAAI,CAAC,EAAE,kBAAG,EAC/B,OAAO,KAAK,IAAI,EAAE,kBAAG,EAGlB,SAAS,CAAM,CAAC,EAAW,CAC9B,MAAO,IAAK,GAAK,GAAI,EAGlB,SAAS,EAAa,CAAC,EAAY,EAAY,EAAY,EAAY,CAC1E,IAAI,EAAK,EAAE,EAAK,EAAE,EAAK,EAAE,EACrB,EAAK,GAAG,EAAK,EAAE,EACf,EAAI,EACJ,EAAK,CAAC,EAAK,EAAE,EAAK,EAAE,EAAK,EAG7B,GAAI,EAAc,EAAE,CAAC,EAAG,CAEpB,GAAI,EAAc,EAAE,CAAC,EAAG,CAEpB,GAAI,EAAc,EAAE,CAAC,EAEjB,MAAO,CAAC,EAGZ,MAAO,CAAC,CAAC,EAAI,CAAC,EAAE,OAAO,CAAM,EAGjC,IAAI,EAAI,KAAK,KAAK,EAAE,EAAI,EAAE,EAAE,CAAC,EAAG,EAAK,EAAE,EACvC,MAAO,EAAE,EAAE,GAAG,GAAK,CAAC,EAAE,GAAG,CAAE,EAAE,OAAO,CAAM,EAK9C,GAAK,EACL,GAAK,EACL,GAAK,EAEL,IAAI,GAAK,EAAE,EAAI,EAAE,GAAG,EAChB,EAAK,EAAE,EACP,GAAK,EAAE,EAAE,EAAE,EAAI,EAAE,EAAE,EAAI,GAAG,GAAG,GAC7B,EAAK,EAAE,EACP,EAAe,EAAG,EAAK,EAAG,EAAG,EAG7B,EAAI,EAAI,EAAO,EAAO,EAG1B,GAAI,EAAe,EAAG,CAClB,IAAI,EAAO,CAAC,EAAE,EACd,EAAO,EAAI,EAAI,EACf,EAAO,KAAK,KAAM,CAAK,EACvB,EAAO,CAAC,GAAK,EAAE,GACf,EAAS,EAAE,GAAK,GAAK,EAAE,EAAI,EAAI,EAC/B,EAAO,KAAK,KAAK,CAAM,EACvB,EAAO,EAAU,CAAC,EAClB,EAAO,EAAE,EAIT,OAHA,EAAQ,EAAK,KAAK,IAAI,EAAI,CAAC,EAAI,EAAE,EACjC,EAAQ,EAAK,KAAK,KAAK,EAAI,EAAE,KAAK,IAAI,CAAC,EAAI,EAAE,EAC7C,EAAQ,EAAK,KAAK,KAAK,EAAI,EAAE,KAAK,IAAI,CAAC,EAAI,EAAE,EACtC,CAAC,EAAO,EAAO,CAAK,EAAE,OAAO,CAAM,EAI9C,GAAG,IAAiB,EAIhB,OAHA,EAAK,EAAK,EAAI,EAAU,CAAC,CAAE,EAAI,CAAC,EAAU,CAAE,EAC5C,EAAQ,EAAE,EAAK,EAAE,EACjB,EAAQ,CAAC,EAAK,EAAE,EACT,CAAC,EAAO,CAAK,EAAE,OAAO,CAAM,EAIvC,IAAI,EAAK,KAAK,KAAK,CAAY,EAI/B,OAHA,EAAK,EAAU,EAAK,CAAE,EACtB,EAAK,EAAU,EAAK,CAAE,EACtB,EAAQ,EAAK,EAAK,EAAE,EACb,CAAC,CAAK,EAAE,OAAO,CAAM,EAOzB,SAAS,CAA6B,CAAC,EAAe,EAAgB,EAAiC,KAAwC,CAElJ,IAAI,EAAsI,CAAC,CAAC,OAAQ,CAAC,MAAO,EAAO,UAAW,EAAG,QAAS,CAAC,EAAG,OAAQ,CAAC,MAAO,EAAQ,UAAW,EAAG,QAAS,CAAC,CAAC,CAAC,EAC1O,EAAW,CAAC,EAClB,MAAO,EAAM,OAAS,EAAE,CACpB,IAAI,EAAY,EAAM,OACtB,QAAQ,EAAQ,EAAG,EAAQ,EAAW,IAAQ,CAC1C,IAAI,EAAO,EAAM,MAAM,EACvB,GAAI,GAAQ,KACR,MAEJ,IAAI,EAAQ,EAAK,OAAO,MAAM,KAC1B,EAAQ,EAAK,OAAO,MAAM,KAC1B,EAAa,EAAe,EAAO,CAAK,EAC5C,GAAG,EAAK,OAAO,MAAM,WAbX,KAaqC,EAAK,OAAO,MAAM,WAbvD,IAa8E,CACpF,EAAS,KAAK,CAAC,aAAc,EAAK,OAAO,MAAM,IAAI,GAAG,EAAG,OAAQ,EAAK,OAAO,UAAY,EAAK,OAAO,SAAW,IAAK,OAAQ,EAAK,OAAO,UAAY,EAAK,OAAO,SAAW,GAAG,CAAC,EAChL,SAEJ,GAAI,EAAW,CACX,IAAK,EAAwB,GAA0B,EAAK,OAAO,MAAM,MAAM,GAAG,GAC7E,EAAwB,GAA0B,EAAK,OAAO,MAAM,MAAM,GAAG,EAClF,EAAM,KAAK,CACP,OAAQ,CACJ,MAAO,IAAI,EAAO,CAAsB,EACxC,UAAW,EAAK,OAAO,UACvB,QAAS,EAAK,OAAO,WAAa,EAAK,OAAO,QAAU,EAAK,OAAO,WAAa,GACzF,EAAG,OAAQ,CACH,MAAO,IAAI,EAAO,CAAsB,EACxC,UAAW,EAAK,OAAO,UACvB,QAAS,EAAK,OAAO,WAAa,EAAK,OAAO,QAAU,EAAK,OAAO,WAAa,GACzF,CAAC,CAAC,EAEF,EAAM,KAAK,CACP,OAAQ,CACJ,MAAO,IAAI,EAAO,CAAsB,EACxC,UAAW,EAAK,OAAO,UACvB,QAAS,EAAK,OAAO,WAAa,EAAK,OAAO,QAAU,EAAK,OAAO,WAAa,GACzF,EAAG,OAAQ,CACH,MAAO,IAAI,EAAO,CAAsB,EACxC,UAAW,EAAK,OAAO,WAAa,EAAK,OAAO,QAAU,EAAK,OAAO,WAAa,IACnF,QAAS,EAAK,OAAO,OAC7B,CAAC,CAAC,EAEF,EAAM,KAAK,CACP,OAAQ,CACJ,MAAO,IAAI,EAAO,CAAsB,EACxC,UAAW,EAAK,OAAO,WAAa,EAAK,OAAO,QAAU,EAAK,OAAO,WAAa,IACnF,QAAS,EAAK,OAAO,OAC7B,EAAG,OAAQ,CACH,MAAO,IAAI,EAAO,CAAsB,EACxC,UAAW,EAAK,OAAO,UACvB,QAAS,EAAK,OAAO,WAAa,EAAK,OAAO,QAAU,EAAK,OAAO,WAAa,GACzF,CAAC,CAAC,EAEF,EAAM,KAAK,CACP,OAAQ,CACJ,MAAO,IAAI,EAAO,CAAsB,EACxC,UAAW,EAAK,OAAO,WAAa,EAAK,OAAO,QAAU,EAAK,OAAO,WAAa,IACnF,QAAS,EAAK,OAAO,OAC7B,EAAG,OAAQ,CACH,MAAO,IAAI,EAAO,CAAsB,EACxC,UAAW,EAAK,OAAO,WAAa,EAAK,OAAO,QAAU,EAAK,OAAO,WAAa,IACnF,QAAS,EAAK,OAAO,OAC7B,CAAC,CAAC,IAOd,IAAM,EAA2C,CAAC,EAGlD,EAAS,KAAK,CAAC,EAAG,IAAM,EAAE,MAAQ,EAAE,KAAK,EAEzC,QAAW,KAAgB,EAAU,CACjC,IAAI,EAAc,GAGlB,QAAW,KAAY,EAAO,CAE1B,IAAM,EAAa,EAAc,EAAa,MAAO,EAAS,MAAO,CAAsB,EACrF,EAAc,EAAc,EAAa,MAAO,EAAS,OAAQ,CAAsB,EAG7F,GAAI,GAAc,EAAa,CAC3B,EAAc,GACd,MAKJ,IAAM,EAAiB,EAAc,EAAa,MAAO,EAAS,MAAO,EAAyB,EAAE,EAC9F,EAAkB,EAAc,EAAa,MAAO,EAAS,OAAQ,EAAyB,EAAE,EAEtG,GAAI,GAAkB,EAAiB,CAEnC,IAAM,EAAS,EAAM,IAAI,EAAa,KAAK,EACrC,EAAS,EAAO,IAAI,EAAa,KAAK,EACtC,EAAiB,EAAM,IAAI,EAAS,KAAK,EACzC,EAAiB,EAAO,IAAI,EAAS,MAAM,EAE3C,EAAY,EAAS,sBAAsB,EAAQ,CAAc,EACjE,EAAY,EAAS,sBAAsB,EAAQ,CAAc,EAGvE,GAAI,EAAY,EAAyB,KAAO,EAAY,EAAyB,IAAK,CACtF,EAAc,GACd,QAKZ,GAAI,CAAC,EACD,EAAM,KAAK,CAAC,MAAO,EAAa,MAAO,OAAQ,EAAa,KAAK,CAAC,EAI1E,OAAO,EAOJ,SAAS,CAAU,CAAC,EAAW,EAAW,EAAW,EAAW,CACnE,GAAI,KAAK,IAAI,CAAC,EAAI,WAAM,CAEpB,GADA,EAAI,EAAG,EAAI,EAAG,EAAI,EACd,KAAK,IAAI,CAAC,EAAI,WAAM,CAEpB,GADA,EAAI,EAAG,EAAI,EACP,KAAK,IAAI,CAAC,EAAI,WACd,MAAO,CAAC,EACZ,MAAO,CAAC,CAAC,EAAE,CAAC,EAGhB,IAAI,EAAI,EAAE,EAAI,EAAE,EAAE,EAClB,GAAI,KAAK,IAAI,CAAC,EAAI,WACd,MAAO,CAAC,CAAC,GAAG,EAAE,EAAE,EACf,QAAI,EAAI,EACT,MAAO,EAAE,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,EAAE,IAAK,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE,EAC5D,MAAO,CAAC,EAIZ,IAAI,GAAK,EAAE,EAAE,EAAI,EAAE,IAAI,EAAE,EAAE,GACvB,GAAK,EAAE,EAAE,EAAE,EAAI,EAAE,EAAE,EAAE,EAAI,GAAG,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,GAC3C,EAEJ,GAAI,KAAK,IAAI,CAAC,EAAI,WACd,EAAQ,CAAC,EAAS,CAAC,CAAC,CAAC,EAClB,QAAI,KAAK,IAAI,CAAC,EAAI,WACrB,EAAQ,CAAC,CAAC,EAAE,OAAO,EAAI,EAAI,CAAC,KAAK,KAAK,CAAC,CAAC,EAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAI,CAAC,CAAC,EAC5D,KACH,IAAI,EAAI,EAAE,EAAE,EAAI,EAAE,EAAE,EAAE,GACtB,GAAI,KAAK,IAAI,CAAC,EAAI,WACd,EAAQ,CAAC,KAAK,EAAE,EAAG,EAAE,EAAE,CAAC,EACrB,QAAI,EAAI,EAAG,CACd,IAAI,EAAI,EAAS,CAAC,EAAE,EAAI,KAAK,KAAK,CAAC,CAAC,EAChC,EAAI,EAAS,CAAC,EAAE,EAAI,KAAK,KAAK,CAAC,CAAC,EAIpC,EAAQ,CAAC,EAAI,GAAG,EAAE,EAAE,EACjB,KACH,IAAI,EAAI,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,EACpB,EAAI,KAAK,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,EACvB,EAAI,EAAE,KAAK,GAAG,EAClB,EAAQ,CAAC,EAAE,KAAK,IAAI,CAAC,EAAG,EAAE,KAAK,IAAI,EAAE,CAAC,EAAG,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,GAKlE,QAAS,EAAI,EAAG,EAAI,EAAM,OAAQ,IAC9B,EAAM,IAAM,GAAG,EAAE,GAErB,OAAO,EAGJ,SAAS,CAAQ,CAAC,EAAW,CAChC,IAAI,EAAI,KAAK,IAAI,KAAK,IAAI,CAAC,EAAG,kBAAG,EACjC,OAAO,EAAI,EAAI,CAAC,EAAI,EAOjB,SAAS,CAAwB,CAAC,EAAc,EAA8B,CACjF,IAAI,EAAS,CAAC,GAAG,CAAa,EAC9B,MAAO,EAAO,OAAS,EAAG,CACtB,IAAI,EAAmB,EAAO,MAAM,CAAC,EACrC,QAAQ,EAAQ,EAAG,EAAQ,EAAiB,OAAQ,IAChD,EAAiB,GAAS,EAAS,UAAU,EAAS,uBAAuB,EAAO,GAAS,EAAI,CAAK,EAAG,EAAS,uBAAuB,EAAO,EAAQ,GAAI,CAAI,CAAC,EAErK,EAAS,EAEb,OAAO,EAAO,GAGlB,SAAS,CAAa,CAAC,EAAwB,CAC3C,GAAI,EAAM,iBAAiB,EAAE,SAAW,EAAG,CACvC,IAAM,EAAS,EAAM,iBAAiB,EAChC,EAAe,EAAS,UAAU,EAAO,GAAI,EAAO,EAAE,EACtD,EAAe,EAAS,UAAU,EAAO,GAAI,EAAO,EAAE,EACtD,EAAe,EAAS,UAAU,EAAO,GAAI,EAAO,EAAE,EAEtD,EAAK,EAAS,aAAa,EAAc,CAAY,EACrD,EAAK,EAAS,aAAa,EAAc,CAAY,EAC3D,GAAK,EAAK,GAAK,EAAK,GAAO,EAAK,GAAK,EAAK,EAAI,MAAO,GAEzD,IAAM,EAAK,EAAM,OAAO,CAAC,EAAE,UACrB,EAAK,EAAM,OAAO,CAAC,EAAE,UACvB,EAAI,EAAG,EAAI,EAAG,EAAI,EAAG,EAAI,EAAG,EAIhC,OAAO,KAAK,IAAI,KAAK,KAAK,CAAC,CAAC,EAAI,KAAK,GAAK,EAK9C,SAAS,CAAS,CAAC,EAAe,EAAe,EAAY,EAAW,CACpE,IAAM,EAAQ,EAAM,iBAAiB,EAAE,OAAS,EAC1C,EAAS,EAAM,iBAAiB,EAChC,EAAI,EAAO,IAAI,CAAC,EAAG,KAAe,EAAI,EAAI,GAAS,EAAM,EAAI,EAAS,CAAE,EAC9E,OAAO,IAAI,EAAO,EAAO,IAAI,CAAC,EAAG,KAAO,CAAC,EAAG,EAAE,EAAI,EAAE,GAAK,EAAO,EAAG,EAAG,EAAE,EAAI,EAAE,GAAK,EAAO,CAAC,EAAE,CAAC,ECpmDlG,mBAAS,qBA+BF,MAAM,EAAK,CACN,WACA,SAER,WAAW,CAAC,EAAmB,EAAgB,CAC3C,KAAK,WAAa,EAClB,KAAK,SAAW,EAGpB,aAAa,EAAS,CAClB,OAAO,KAAK,WAGhB,WAAW,EAAS,CAChB,OAAO,KAAK,SAGhB,2BAA2B,CAAC,EAAsB,CAC9C,OAAO,GAAoB,KAAK,WAAY,KAAK,SAAU,EAAgB,cAAc,EAAG,EAAgB,YAAY,CAAC,EAG7H,YAAY,CAAC,EAAa,CACtB,OAAO,GAAqB,EAAO,KAAK,cAAc,EAAG,KAAK,YAAY,CAAC,EAG/E,MAAM,EAAU,CACZ,OAAO,EAAS,sBAAsB,KAAK,WAAY,KAAK,QAAQ,EAGxE,kCAAkC,EAAE,CAChC,IAAM,EAAc,EAAS,UAAU,CAAC,EAAG,EAAG,EAAG,CAAC,EAAG,KAAK,UAAU,EAC9D,EAAgB,EAAS,aAAa,EAAS,UAAU,KAAK,SAAU,KAAK,UAAU,EAAG,CAAC,EAAG,EAAG,EAAG,CAAC,CAAC,EAE5G,MAAO,CAAC,cAAa,eAAa,EAGtC,WAAW,CAAC,EAAsB,CAC9B,IAAM,EAAa,EAAS,kBAAkB,KAAK,WAAY,KAAK,QAAQ,EACtE,EAAoB,EAAS,UAAU,EAAO,KAAK,UAAU,EAC7D,EAAS,EAAS,WAAW,EAAmB,CAAU,EAC1D,EAAwB,EAAS,WAAW,CAAiB,EAC7D,EAAiB,EAAS,sBAAsB,KAAK,WAAY,KAAK,QAAQ,EAAI,OACxF,OAAO,GAAU,EAAS,sBAAsB,KAAK,WAAY,KAAK,QAAQ,GAAK,GAAU,GAAK,KAAK,IAAI,EAAsB,EAAI,EAAW,CAAC,EAAI,QAAU,KAAK,IAAI,EAAsB,EAAI,EAAW,CAAC,EAAI,OAGtN,IAAI,CAAC,EAAsB,CACvB,OAAO,EAAS,oBAAoB,KAAK,WAAY,KAAK,SAAU,CAAK,EAEjF,CAEO,SAAS,EAAmB,CAAC,EAAmB,EAAiB,EAAoB,EAI3F,CACG,IAAM,GAAa,EAAU,EAAI,EAAY,IAAM,EAAW,EAAI,EAAY,IAAM,EAAU,EAAI,EAAY,IAAM,EAAW,EAAI,EAAY,GACzI,GAAe,EAAU,EAAI,EAAY,IAAM,EAAS,EAAI,EAAW,IAAM,EAAU,EAAI,EAAY,IAAM,EAAS,EAAI,EAAW,GAE3I,GAAI,IAAgB,EAChB,MAAO,CAAC,WAAY,EAAK,EAE7B,IAAM,EAAI,EAAY,EACtB,GAAI,GAAK,GAAK,GAAK,EACf,MAAO,CACH,WAAY,GACZ,aAAc,EAAS,oBAAoB,EAAY,EAAU,CAAC,EAClE,OAAQ,CACZ,EAEA,WAAO,CACH,WAAY,EAChB,EAKD,SAAS,EAAoB,CAAC,EAAc,EAAuB,EAIzE,CACG,IAAM,EAAa,EAAS,WAAW,EAAS,UAAU,EAAc,CAAc,CAAC,EACjF,EAAgB,EAAS,UAAU,EAAO,CAAc,EACxD,EAAM,EAAS,WAAW,EAAe,CAAU,EACzD,GAAI,EAAM,GAAK,EAAM,EAAS,UAAU,EAAS,UAAU,EAAc,CAAc,CAAC,EACpF,MAAO,CACH,OAAQ,EACZ,EAEJ,MAAO,CACH,OAAQ,GACR,gBAAiB,EAAS,UAAU,EAAgB,EAAS,uBAAuB,EAAY,CAAG,CAAC,EACpG,OAAQ,EAAM,EAAS,UAAU,EAAS,UAAU,EAAc,CAAc,CAAC,CACrF,EC5HJ,mBAAgB,qBAqBT,MAAM,CAAa,CAEd,SACA,WACA,YAER,WAAW,CAAC,EAAiB,EAAyB,EAAyB,CAC3E,KAAK,SAAW,EAChB,KAAK,WAAa,EAClB,KAAK,YAAc,EAGvB,WAAW,CAAC,EAA4B,EAA4C,EAA2C,CAC3H,IAAI,EAAO,EAAS,UAAU,EAAqB,KAAK,QAAQ,EAIhE,GAHA,KAAK,SAAW,EAChB,KAAK,WAAW,SAAW,EAAS,UAAU,KAAK,WAAW,SAAU,CAAI,EAC5E,KAAK,YAAY,SAAW,EAAS,UAAU,KAAK,YAAY,SAAU,CAAI,EAC3E,KAAK,WAAW,MAAQ,UAAY,EAAiB,CACpD,IAAI,EAAiB,EAAS,UAAU,EAAiB,YAAY,EAAG,KAAK,QAAQ,EAGrF,GAFA,EAAiB,EAAS,uBAAuB,EAAgB,kBAAK,EACtE,KAAK,WAAW,SAAW,EAAS,UAAU,KAAK,SAAU,CAAc,EACxE,KAAK,YAAY,MAAQ,UAAU,CAClC,IAAI,EAAiB,EAAS,UAAU,KAAK,YAAY,SAAU,KAAK,QAAQ,EAC5E,EAAM,EAAS,UAAU,CAAc,EACvC,EAAY,EAAS,kBAAkB,KAAK,WAAW,SAAU,KAAK,QAAQ,EAClF,KAAK,YAAY,SAAW,EAAS,UAAU,KAAK,SAAU,EAAS,uBAAuB,EAAW,CAAG,CAAC,GAGrH,GAAG,KAAK,YAAY,MAAQ,UAAY,EAAiB,CACrD,IAAI,EAAiB,EAAS,UAAU,EAAiB,YAAY,EAAG,KAAK,QAAQ,EAGrF,GAFA,EAAiB,EAAS,uBAAuB,EAAgB,kBAAK,EACtE,KAAK,YAAY,SAAW,EAAS,UAAU,KAAK,SAAU,CAAc,EACzE,KAAK,WAAW,MAAQ,UAAU,CACjC,IAAI,EAAM,EAAS,sBAAsB,KAAK,WAAW,SAAU,KAAK,QAAQ,EAC5E,EAAY,EAAS,UAAU,KAAK,SAAU,KAAK,YAAY,QAAQ,EAC3E,KAAK,WAAW,SAAW,EAAS,UAAU,KAAK,SAAU,EAAS,uBAAuB,EAAW,CAAG,CAAC,GAGpH,GAAG,IAAqB,QAAa,EAAiB,eAAe,EAAE,MAAQ,SAAS,CACpF,IAAI,EAAiB,EAAS,UAAU,KAAK,SAAU,EAAiB,YAAY,CAAC,EACrF,EAAiB,EAAS,uBAAuB,EAAgB,kBAAK,EACtE,EAAiB,uBAAuB,EAAS,UAAU,EAAiB,YAAY,EAAG,CAAc,CAAC,EAE9G,GAAG,IAAqB,QAAa,EAAiB,cAAc,EAAE,MAAQ,SAAS,CACnF,IAAI,EAAiB,EAAS,UAAU,KAAK,SAAU,EAAiB,YAAY,CAAC,EACrF,EAAiB,EAAS,uBAAuB,EAAgB,kBAAK,EACtE,EAAiB,sBAAsB,EAAS,UAAU,EAAiB,YAAY,EAAG,CAAc,CAAC,GAIjH,WAAW,EAAS,CAChB,OAAO,KAAK,SAGhB,uBAAuB,CAAC,EAA2C,CAC/D,GAAG,KAAK,YAAY,MAAQ,SACxB,KAAK,YAAY,KAAO,OAE5B,IAAI,EACJ,GAAG,GAAoB,KACnB,EAAiB,EAAS,UAAU,KAAK,WAAW,SAAU,KAAK,QAAQ,EAE3E,OAAiB,EAAS,UAAU,EAAiB,YAAY,EAAG,KAAK,QAAQ,EACjF,EAAiB,EAAS,uBAAuB,EAAgB,kBAAK,EAE1E,KAAK,WAAW,SAAW,EAAS,UAAU,KAAK,SAAU,CAAc,EAG/E,wBAAwB,EAAE,CAEtB,GADA,KAAK,WAAW,KAAO,UACpB,KAAK,YAAY,MAAQ,SAAS,CACjC,IAAI,EAAY,EAAS,kBAAkB,KAAK,YAAY,SAAU,KAAK,QAAQ,EAC/E,EAAM,EAAS,sBAAsB,KAAK,SAAU,KAAK,WAAW,QAAQ,EAChF,KAAK,WAAW,SAAW,EAAS,UAAU,KAAK,SAAU,EAAS,uBAAuB,EAAW,CAAG,CAAC,GAIpH,qBAAqB,EAAE,CACnB,KAAK,WAAW,KAAO,OAG3B,wBAAwB,CAAC,EAA4C,CACjE,GAAG,KAAK,WAAW,MAAQ,SACvB,KAAK,WAAW,KAAO,OAE3B,IAAI,EACJ,GAAG,GAAoB,KACnB,EAAiB,EAAS,UAAU,KAAK,YAAY,SAAU,KAAK,QAAQ,EAE5E,OAAiB,EAAS,UAAU,EAAiB,YAAY,EAAG,KAAK,QAAQ,EACjF,EAAiB,EAAS,uBAAuB,EAAgB,kBAAK,EAE1E,KAAK,YAAY,SAAW,EAAS,UAAU,KAAK,SAAU,CAAc,EAGhF,yBAAyB,EAAE,CAEvB,GADA,KAAK,YAAY,KAAO,UACrB,KAAK,WAAW,MAAQ,SAAU,CACjC,IAAI,EAAY,EAAS,kBAAkB,KAAK,WAAW,SAAU,KAAK,QAAQ,EAC9E,EAAM,EAAS,sBAAsB,KAAK,SAAU,KAAK,YAAY,QAAQ,EACjF,KAAK,YAAY,SAAW,EAAS,UAAU,KAAK,SAAU,EAAS,uBAAuB,EAAW,CAAG,CAAC,GAIrH,sBAAsB,EAAE,CACpB,KAAK,YAAY,KAAO,OAG5B,qBAAqB,CAAC,EAAe,CAEjC,OADqB,KAAK,WAAW,UAE5B,UACD,GAAG,KAAK,YAAY,MAAQ,SAAS,CACjC,IAAI,EAAO,EAAS,UAAU,EAAS,KAAK,QAAQ,EAChD,EAAkB,EAAS,kBAAkB,KAAK,YAAY,SAAU,KAAK,QAAQ,EACrF,EAAS,EAAS,WAAW,EAAM,CAAe,EAClD,EAAM,EAAS,uBAAuB,EAAiB,CAAM,EACjE,KAAK,WAAW,SAAW,EAAS,UAAU,KAAK,SAAU,CAAG,EAC7D,QAAI,KAAK,YAAY,MAAQ,UAAU,CAC1C,KAAK,WAAW,SAAW,EAC3B,IAAI,EAAM,EAAS,sBAAsB,KAAK,YAAY,SAAU,KAAK,QAAQ,EAC7E,EAAY,EAAS,kBAAkB,KAAK,WAAW,SAAU,KAAK,QAAQ,EAC9E,EAAM,EAAS,uBAAuB,EAAW,CAAG,EACxD,KAAK,YAAY,SAAW,EAAS,UAAU,EAAK,KAAK,QAAQ,EAEjE,UAAK,WAAW,SAAW,EAE/B,UACC,OACD,KAAK,WAAW,SAAW,EAC3B,UACC,SACD,cAEA,MAAU,MAAM,4CAA4C,GAIxE,sBAAsB,CAAC,EAAe,CAElC,OADsB,KAAK,YAAY,UAE9B,UACD,GAAG,KAAK,WAAW,MAAQ,SAAS,CAChC,IAAI,EAAO,EAAS,UAAU,EAAS,KAAK,QAAQ,EAChD,EAAiB,EAAS,kBAAkB,KAAK,WAAW,SAAU,KAAK,QAAQ,EACnF,EAAS,EAAS,WAAW,EAAM,CAAc,EACjD,EAAM,EAAS,uBAAuB,EAAgB,CAAM,EAChE,KAAK,YAAY,SAAW,EAAS,UAAU,KAAK,SAAU,CAAG,EAC9D,QAAI,KAAK,YAAY,MAAQ,UAAU,CAC1C,KAAK,YAAY,SAAW,EAC5B,IAAI,EAAM,EAAS,sBAAsB,KAAK,WAAW,SAAU,KAAK,QAAQ,EAC5E,EAAY,EAAS,kBAAkB,KAAK,YAAY,SAAU,KAAK,QAAQ,EAC/E,EAAM,EAAS,uBAAuB,EAAW,CAAG,EACxD,KAAK,WAAW,SAAW,EAAS,UAAU,EAAK,KAAK,QAAQ,EAEhE,UAAK,YAAY,SAAW,EAEhC,UACC,OACD,KAAK,YAAY,SAAW,EAC5B,UACC,SACD,cAEA,MAAU,MAAM,4CAA4C,GAIxE,aAAa,EAAe,CACxB,OAAO,KAAK,WAGhB,cAAc,EAAe,CACzB,OAAO,KAAK,YAEpB,CAMO,MAAM,EAAe,CAEhB,cAER,WAAW,CAAC,EAAgC,CAAC,EAAE,CAC3C,KAAK,cAAgB,EAGzB,gBAAgB,EAAkB,CAC9B,OAAO,KAAK,cAGhB,kBAAkB,CAAC,EAAgB,CAC/B,IAAI,EAAqB,EAAS,UAAU,EAAU,CAAC,EAAG,KAAM,EAAG,CAAC,CAAC,EACjE,EAAsB,EAAS,UAAU,EAAU,CAAC,EAAG,IAAK,EAAG,CAAC,CAAC,EAUjE,EAAkB,IAAI,EAAa,EATJ,CAC/B,SAAU,EACV,KAAM,MACV,EACoC,CAChC,SAAU,EACV,KAAM,MACV,CAEkF,EAClF,KAAK,cAAc,KAAK,CAAe,EAG3C,mCAAmC,CAAC,EAA2B,EAAe,CAC1E,GAAG,GAAqB,KAAK,cAAc,QAAU,EAAoB,EACrE,OAEJ,KAAK,cAAc,GAAmB,sBAAsB,CAAO,EAGvE,oCAAoC,CAAC,EAA2B,EAAe,CAC3E,GAAG,GAAqB,KAAK,cAAc,QAAU,EAAoB,EACrE,OAEJ,KAAK,cAAc,GAAmB,uBAAuB,CAAO,EAGxE,yBAAyB,CAAC,EAA2B,EAAe,CAChE,GAAG,GAAqB,KAAK,cAAc,QAAU,EAAoB,EACrE,OAEJ,IAAI,EAAmB,OACnB,EAAmB,OACvB,GAAG,EAAoB,EAAI,KAAK,cAAc,OAC1C,EAAmB,KAAK,cAAc,EAAoB,GAE9D,GAAG,EAAoB,GAAK,EACxB,EAAmB,KAAK,cAAc,EAAoB,GAE9D,KAAK,cAAc,GAAmB,YAAY,EAAS,EAAkB,CAAgB,EAErG,CCnNO,MAAM,EAAK,CAEN,MAER,WAAW,CAAC,EAAc,CACtB,KAAK,MAAQ,EAGjB,MAAM,CAAC,EAAiB,CACpB,KAAK,MAAM,KAAK,CAAI,EAGxB,KAAK,EAAQ,CACT,KAAK,MAAQ,CAAC,EAGlB,OAAO,CAAC,EAAiB,CACrB,KAAK,MAAM,QAAQ,CAAI,EAG3B,QAAQ,EAAU,CACd,OAAO,KAAK,MAGhB,SAAS,EAAU,CACf,IAAI,EAAM,EAIV,OAHA,KAAK,MAAM,QAAQ,CAAC,IAAO,CACvB,GAAO,EAAK,OAAO,EACtB,EACM,EAKX,cAAc,EAAkC,CAC5C,IAAM,EAAS,KAAK,UAAU,EAC1B,EAAyB,EACvB,EAAsC,CAAC,EAU7C,OATA,KAAK,MAAM,QAAQ,CAAC,IAAO,CAEvB,IAAM,EADa,EAAK,OAAO,EACK,EAChC,EAAQ,EACZ,GAA0B,EAC1B,IAAI,EAAM,EACV,EAAI,KAAK,CAAC,QAAO,KAAG,CAAC,EACxB,EACD,EAAI,EAAI,OAAS,GAAG,IAAM,EACnB,EAGX,oBAAoB,CAAC,EAAkC,CACnD,GAAI,EAAa,GAAK,EAAa,EAC/B,MAAU,MAAM,oCAAoC,EAExD,IAAM,EAAc,KAAK,eAAe,EACpC,EAAO,EACP,EAAQ,EAAY,OAAS,EACjC,MAAO,GAAQ,EAAM,CACjB,IAAM,EAAM,KAAK,OAAO,EAAO,GAAS,CAAC,EACzC,GAAI,EAAa,EAAY,GAAK,IAC9B,EAAQ,EAAM,EACX,QAAI,EAAa,EAAY,GAAK,IACrC,EAAO,EAAM,EACV,KACH,EAAO,EACP,OAGR,IAAM,EAAO,KAAK,MAAM,GAClB,EAAiB,EAAY,GAC7B,GAAS,EAAa,EAAe,QAAU,EAAe,IAAM,EAAe,OACzF,OAAO,EAAK,KAAK,CAAK,EAE9B",
11
+ "debugId": "B487176DCF176FA664756E2164756E21",
12
12
  "names": []
13
13
  }