tldraw
Version:
A tiny little drawing editor.
8 lines (7 loc) • 28.5 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../../src/lib/shapes/geo/geo-shape-helpers.ts"],
"sourcesContent": ["import {\n\tCubicBezier2d,\n\tEASINGS,\n\tHALF_PI,\n\tPI,\n\tPI2,\n\tTLDefaultSizeStyle,\n\tVec,\n\tVecModel,\n\tcenterOfCircleFromThreePoints,\n\tgetPointOnCircle,\n\tgetPointsOnArc,\n\tperimeterOfEllipse,\n\trng,\n\ttoDomPrecision,\n} from '@tldraw/editor'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\n\n/* ---------------------- Oval ---------------------- */\n\nexport function getOvalPerimeter(h: number, w: number) {\n\tif (h > w) return (PI * (w / 2) + (h - w)) * 2\n\telse return (PI * (h / 2) + (w - h)) * 2\n}\n\n/* ---------------------- Heart --------------------- */\n\nexport function getHeartPath(w: number, h: number) {\n\treturn (\n\t\tgetHeartParts(w, h)\n\t\t\t.map((c, i) => c.getSvgPathData(i === 0))\n\t\t\t.join(' ') + ' Z'\n\t)\n}\n\nexport function getDrawHeartPath(w: number, h: number, sw: number, id: string) {\n\tconst o = w / 4\n\tconst k = h / 4\n\tconst random = rng(id)\n\tconst mutDistance = sw * 0.75\n\tconst mut = (v: Vec) => v.addXY(random() * mutDistance, random() * mutDistance)\n\n\tconst A = new Vec(w / 2, h)\n\tconst B = new Vec(0, k * 1.2)\n\tconst C = new Vec(w / 2, k * 0.9)\n\tconst D = new Vec(w, k * 1.2)\n\n\tconst Am = mut(new Vec(w / 2, h))\n\tconst Bm = mut(new Vec(0, k * 1.2))\n\tconst Cm = mut(new Vec(w / 2, k * 0.9))\n\tconst Dm = mut(new Vec(w, k * 1.2))\n\n\tconst parts = [\n\t\tnew CubicBezier2d({\n\t\t\tstart: A,\n\t\t\tcp1: new Vec(o * 1.5, k * 3),\n\t\t\tcp2: new Vec(0, k * 2.5),\n\t\t\tend: B,\n\t\t}),\n\t\tnew CubicBezier2d({\n\t\t\tstart: B,\n\t\t\tcp1: new Vec(0, -k * 0.32),\n\t\t\tcp2: new Vec(o * 1.85, -k * 0.32),\n\t\t\tend: C,\n\t\t}),\n\t\tnew CubicBezier2d({\n\t\t\tstart: C,\n\t\t\tcp1: new Vec(o * 2.15, -k * 0.32),\n\t\t\tcp2: new Vec(w, -k * 0.32),\n\t\t\tend: D,\n\t\t}),\n\t\tnew CubicBezier2d({\n\t\t\tstart: D,\n\t\t\tcp1: new Vec(w, k * 2.5),\n\t\t\tcp2: new Vec(o * 2.5, k * 3),\n\t\t\tend: Am,\n\t\t}),\n\t\tnew CubicBezier2d({\n\t\t\tstart: Am,\n\t\t\tcp1: new Vec(o * 1.5, k * 3),\n\t\t\tcp2: new Vec(0, k * 2.5),\n\t\t\tend: Bm,\n\t\t}),\n\t\tnew CubicBezier2d({\n\t\t\tstart: Bm,\n\t\t\tcp1: new Vec(0, -k * 0.32),\n\t\t\tcp2: new Vec(o * 1.85, -k * 0.32),\n\t\t\tend: Cm,\n\t\t}),\n\t\tnew CubicBezier2d({\n\t\t\tstart: Cm,\n\t\t\tcp1: new Vec(o * 2.15, -k * 0.32),\n\t\t\tcp2: new Vec(w, -k * 0.32),\n\t\t\tend: Dm,\n\t\t}),\n\t\tnew CubicBezier2d({\n\t\t\tstart: Dm,\n\t\t\tcp1: new Vec(w, k * 2.5),\n\t\t\tcp2: new Vec(o * 2.5, k * 3),\n\t\t\tend: A,\n\t\t}),\n\t]\n\n\treturn parts.map((c, i) => c.getSvgPathData(i === 0)).join(' ') + ' Z'\n}\n\nexport function getHeartPoints(w: number, h: number) {\n\tconst points = [] as Vec[]\n\tconst curves = getHeartParts(w, h)\n\tfor (let i = 0; i < curves.length; i++) {\n\t\tfor (let j = 0; j < 20; j++) {\n\t\t\tpoints.push(CubicBezier2d.GetAtT(curves[i], j / 20))\n\t\t}\n\t\tif (i === curves.length - 1) {\n\t\t\tpoints.push(CubicBezier2d.GetAtT(curves[i], 1))\n\t\t}\n\t}\n}\n\nexport function getHeartParts(w: number, h: number) {\n\tconst o = w / 4\n\tconst k = h / 4\n\treturn [\n\t\tnew CubicBezier2d({\n\t\t\tstart: new Vec(w / 2, h),\n\t\t\tcp1: new Vec(o * 1.5, k * 3),\n\t\t\tcp2: new Vec(0, k * 2.5),\n\t\t\tend: new Vec(0, k * 1.2),\n\t\t}),\n\t\tnew CubicBezier2d({\n\t\t\tstart: new Vec(0, k * 1.2),\n\t\t\tcp1: new Vec(0, -k * 0.32),\n\t\t\tcp2: new Vec(o * 1.85, -k * 0.32),\n\t\t\tend: new Vec(w / 2, k * 0.9),\n\t\t}),\n\t\tnew CubicBezier2d({\n\t\t\tstart: new Vec(w / 2, k * 0.9),\n\t\t\tcp1: new Vec(o * 2.15, -k * 0.32),\n\t\t\tcp2: new Vec(w, -k * 0.32),\n\t\t\tend: new Vec(w, k * 1.2),\n\t\t}),\n\t\tnew CubicBezier2d({\n\t\t\tstart: new Vec(w, k * 1.2),\n\t\t\tcp1: new Vec(w, k * 2.5),\n\t\t\tcp2: new Vec(o * 2.5, k * 3),\n\t\t\tend: new Vec(w / 2, h),\n\t\t}),\n\t]\n}\n\n/* --------------------- Ellipse -------------------- */\n\nfunction getEllipseStrokeOptions(strokeWidth: number) {\n\treturn {\n\t\tsize: 1 + strokeWidth,\n\t\tthinning: 0.25,\n\t\tend: { taper: strokeWidth },\n\t\tstart: { taper: strokeWidth },\n\t\tstreamline: 0,\n\t\tsmoothing: 1,\n\t\tsimulatePressure: false,\n\t}\n}\n\nfunction getEllipseStrokePoints(id: string, width: number, height: number, strokeWidth: number) {\n\tconst getRandom = rng(id)\n\n\tconst rx = width / 2\n\tconst ry = height / 2\n\tconst perimeter = perimeterOfEllipse(rx, ry)\n\n\tconst points: Vec[] = []\n\n\tconst start = PI2 * getRandom()\n\tconst length = PI2 + HALF_PI / 2 + Math.abs(getRandom()) * HALF_PI\n\tconst count = Math.max(16, perimeter / 10)\n\n\tfor (let i = 0; i < count; i++) {\n\t\tconst t = i / (count - 1)\n\t\tconst r = start + t * length\n\t\tconst c = Math.cos(r)\n\t\tconst s = Math.sin(r)\n\t\tpoints.push(\n\t\t\tnew Vec(\n\t\t\t\trx * c + width * 0.5 + 0.05 * getRandom(),\n\t\t\t\try * s + height / 2 + 0.05 * getRandom(),\n\t\t\t\tMath.min(\n\t\t\t\t\t1,\n\t\t\t\t\t0.5 +\n\t\t\t\t\t\tMath.abs(0.5 - (getRandom() > 0 ? EASINGS.easeInOutSine(t) : EASINGS.easeInExpo(t))) / 2\n\t\t\t\t)\n\t\t\t)\n\t\t)\n\t}\n\n\treturn getStrokePoints(points, getEllipseStrokeOptions(strokeWidth))\n}\n\nexport function getEllipseDrawIndicatorPath(\n\tid: string,\n\twidth: number,\n\theight: number,\n\tstrokeWidth: number\n) {\n\treturn getSvgPathFromStrokePoints(getEllipseStrokePoints(id, width, height, strokeWidth))\n}\n\nexport function getEllipsePath(w: number, h: number) {\n\tconst cx = w / 2\n\tconst cy = h / 2\n\tconst rx = Math.max(0, cx)\n\tconst ry = Math.max(0, cy)\n\treturn `M${cx - rx},${cy}a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`\n}\n\n/* --------------------- Polygon -------------------- */\n\nimport { VecLike, precise } from '@tldraw/editor'\n\n/** @public */\nexport function getRoundedInkyPolygonPath(points: VecLike[]) {\n\tlet polylineA = `M`\n\n\tconst len = points.length\n\n\tlet p0: VecLike\n\tlet p1: VecLike\n\tlet p2: VecLike\n\n\tfor (let i = 0, n = len; i < n; i += 3) {\n\t\tp0 = points[i]\n\t\tp1 = points[i + 1]\n\t\tp2 = points[i + 2]\n\n\t\tpolylineA += `${precise(p0)}L${precise(p1)}Q${precise(p2)}`\n\t}\n\n\tpolylineA += `${precise(points[0])}`\n\n\treturn polylineA\n}\n\n/** @public */\nexport function getRoundedPolygonPoints(\n\tid: string,\n\toutline: VecLike[],\n\toffset: number,\n\troundness: number,\n\tpasses: number\n) {\n\tconst results: VecLike[] = []\n\n\tconst random = rng(id)\n\tlet p0 = outline[0]\n\tlet p1: VecLike\n\n\tconst len = outline.length\n\n\tfor (let i = 0, n = len * passes; i < n; i++) {\n\t\tp1 = Vec.AddXY(outline[(i + 1) % len], random() * offset, random() * offset)\n\n\t\tconst delta = Vec.Sub(p1, p0)\n\t\tconst distance = Vec.Len(delta)\n\t\tconst vector = Vec.Div(delta, distance).mul(Math.min(distance / 4, roundness))\n\t\tresults.push(Vec.Add(p0, vector), Vec.Add(p1, vector.neg()), p1)\n\n\t\tp0 = p1\n\t}\n\n\treturn results\n}\n\n/* ---------------------- Cloud --------------------- */\n\ntype PillSection =\n\t| {\n\t\t\ttype: 'straight'\n\t\t\tstart: VecModel\n\t\t\tdelta: VecModel\n\t }\n\t| {\n\t\t\ttype: 'arc'\n\t\t\tcenter: VecModel\n\t\t\tstartAngle: number\n\t }\n\nfunction getPillPoints(width: number, height: number, numPoints: number) {\n\tconst radius = Math.min(width, height) / 2\n\tconst longSide = Math.max(width, height) - radius * 2\n\tconst circumference = Math.PI * (radius * 2) + 2 * longSide\n\tconst spacing = circumference / numPoints\n\n\tconst sections: PillSection[] =\n\t\twidth > height\n\t\t\t? [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\tstart: new Vec(radius, 0),\n\t\t\t\t\t\tdelta: new Vec(1, 0),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'arc',\n\t\t\t\t\t\tcenter: new Vec(width - radius, radius),\n\t\t\t\t\t\tstartAngle: -PI / 2,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\tstart: new Vec(width - radius, height),\n\t\t\t\t\t\tdelta: new Vec(-1, 0),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'arc',\n\t\t\t\t\t\tcenter: new Vec(radius, radius),\n\t\t\t\t\t\tstartAngle: PI / 2,\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\tstart: new Vec(width, radius),\n\t\t\t\t\t\tdelta: new Vec(0, 1),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'arc',\n\t\t\t\t\t\tcenter: new Vec(radius, height - radius),\n\t\t\t\t\t\tstartAngle: 0,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\tstart: new Vec(0, height - radius),\n\t\t\t\t\t\tdelta: new Vec(0, -1),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'arc',\n\t\t\t\t\t\tcenter: new Vec(radius, radius),\n\t\t\t\t\t\tstartAngle: PI,\n\t\t\t\t\t},\n\t\t\t\t]\n\n\tlet sectionOffset = 0\n\n\tconst points: Vec[] = []\n\tfor (let i = 0; i < numPoints; i++) {\n\t\tconst section = sections[0]\n\t\tif (section.type === 'straight') {\n\t\t\tpoints.push(Vec.Add(section.start, Vec.Mul(section.delta, sectionOffset)))\n\t\t} else {\n\t\t\tpoints.push(\n\t\t\t\tgetPointOnCircle(section.center, radius, section.startAngle + sectionOffset / radius)\n\t\t\t)\n\t\t}\n\t\tsectionOffset += spacing\n\t\tlet sectionLength = section.type === 'straight' ? longSide : PI * radius\n\t\twhile (sectionOffset > sectionLength) {\n\t\t\tsectionOffset -= sectionLength\n\t\t\tsections.push(sections.shift()!)\n\t\t\tsectionLength = sections[0].type === 'straight' ? longSide : PI * radius\n\t\t}\n\t}\n\n\treturn points\n}\n\nconst SIZES: Record<TLDefaultSizeStyle, number> = {\n\ts: 50,\n\tm: 70,\n\tl: 100,\n\txl: 130,\n}\n\nconst BUMP_PROTRUSION = 0.2\n\nexport function getCloudArcs(\n\twidth: number,\n\theight: number,\n\tseed: string,\n\tsize: TLDefaultSizeStyle,\n\tscale: number\n) {\n\tconst getRandom = rng(seed)\n\tconst pillCircumference = getOvalPerimeter(width, height)\n\tconst numBumps = Math.max(\n\t\tMath.ceil(pillCircumference / SIZES[size]),\n\t\t6,\n\t\tMath.ceil(pillCircumference / Math.min(width, height))\n\t)\n\tconst targetBumpProtrusion = (pillCircumference / numBumps) * BUMP_PROTRUSION\n\n\t// if the aspect ratio is high, innerWidth should be smaller\n\tconst innerWidth = Math.max(width - targetBumpProtrusion * 2, 1)\n\tconst innerHeight = Math.max(height - targetBumpProtrusion * 2, 1)\n\tconst innerCircumference = getOvalPerimeter(innerWidth, innerHeight)\n\n\tconst distanceBetweenPointsOnPerimeter = innerCircumference / numBumps\n\n\tconst paddingX = (width - innerWidth) / 2\n\tconst paddingY = (height - innerHeight) / 2\n\tconst bumpPoints = getPillPoints(innerWidth, innerHeight, numBumps).map((p) => {\n\t\treturn p.addXY(paddingX, paddingY)\n\t})\n\tconst maxWiggleX = width < 20 ? 0 : targetBumpProtrusion * 0.3\n\tconst maxWiggleY = height < 20 ? 0 : targetBumpProtrusion * 0.3\n\n\t// wiggle the points from either end so that the bumps 'pop'\n\t// in at the bottom-right and the top-left looks relatively stable\n\t// note: it's important that we don't mutate here! these points are also the bump points\n\tconst wiggledPoints = bumpPoints.slice(0)\n\tfor (let i = 0; i < Math.floor(numBumps / 2); i++) {\n\t\twiggledPoints[i] = Vec.AddXY(\n\t\t\twiggledPoints[i],\n\t\t\tgetRandom() * maxWiggleX * scale,\n\t\t\tgetRandom() * maxWiggleY * scale\n\t\t)\n\t\twiggledPoints[numBumps - i - 1] = Vec.AddXY(\n\t\t\twiggledPoints[numBumps - i - 1],\n\t\t\tgetRandom() * maxWiggleX * scale,\n\t\t\tgetRandom() * maxWiggleY * scale\n\t\t)\n\t}\n\n\tconst arcs: Arc[] = []\n\n\tfor (let i = 0; i < wiggledPoints.length; i++) {\n\t\tconst j = i === wiggledPoints.length - 1 ? 0 : i + 1\n\t\tconst leftWigglePoint = wiggledPoints[i]\n\t\tconst rightWigglePoint = wiggledPoints[j]\n\t\tconst leftPoint = bumpPoints[i]\n\t\tconst rightPoint = bumpPoints[j]\n\n\t\t// when the points are on the curvy part of a pill, there is a natural arc that we need to extends past\n\t\t// otherwise it looks like the bumps get less bumpy on the curvy parts\n\t\tconst distanceBetweenOriginalPoints = Vec.Dist(leftPoint, rightPoint)\n\t\tconst curvatureOffset = distanceBetweenPointsOnPerimeter - distanceBetweenOriginalPoints\n\t\tconst distanceBetweenWigglePoints = Vec.Dist(leftWigglePoint, rightWigglePoint)\n\t\tconst relativeSize = distanceBetweenWigglePoints / distanceBetweenOriginalPoints\n\t\tconst finalDistance = (Math.max(paddingX, paddingY) + curvatureOffset) * relativeSize\n\n\t\tconst arcPoint = Vec.Lrp(leftPoint, rightPoint, 0.5).add(\n\t\t\tVec.Sub(rightPoint, leftPoint).uni().per().mul(finalDistance)\n\t\t)\n\t\tif (arcPoint.x < 0) {\n\t\t\tarcPoint.x = 0\n\t\t} else if (arcPoint.x > width) {\n\t\t\tarcPoint.x = width\n\t\t}\n\t\tif (arcPoint.y < 0) {\n\t\t\tarcPoint.y = 0\n\t\t} else if (arcPoint.y > height) {\n\t\t\tarcPoint.y = height\n\t\t}\n\n\t\tconst center = centerOfCircleFromThreePoints(leftWigglePoint, rightWigglePoint, arcPoint)\n\n\t\tconst radius = Vec.Dist(\n\t\t\tcenter ? center : Vec.Average([leftWigglePoint, rightWigglePoint]),\n\t\t\tleftWigglePoint\n\t\t)\n\n\t\t// todo: could use Arc2d here\n\n\t\tarcs.push({\n\t\t\tleftPoint: leftWigglePoint,\n\t\t\trightPoint: rightWigglePoint,\n\t\t\tarcPoint,\n\t\t\tcenter,\n\t\t\tradius,\n\t\t})\n\t}\n\n\treturn arcs\n}\n\ninterface Arc {\n\tleftPoint: Vec\n\trightPoint: Vec\n\tarcPoint: Vec\n\tcenter: Vec | null\n\tradius: number\n}\n\nexport function cloudOutline(\n\twidth: number,\n\theight: number,\n\tseed: string,\n\tsize: TLDefaultSizeStyle,\n\tscale: number\n) {\n\tconst path: Vec[] = []\n\n\tconst arcs = getCloudArcs(width, height, seed, size, scale)\n\n\tfor (const { center, radius, leftPoint, rightPoint } of arcs) {\n\t\tpath.push(...getPointsOnArc(leftPoint, rightPoint, center, radius, 10))\n\t}\n\n\treturn path\n}\n\nexport function getCloudPath(\n\twidth: number,\n\theight: number,\n\tseed: string,\n\tsize: TLDefaultSizeStyle,\n\tscale: number\n) {\n\t// const points = cloudOutline(width, height, seed, size)\n\t// {\n\t// \tlet path = `M${toDomPrecision(points[0].x)},${toDomPrecision(points[0].y)}`\n\t// \tfor (const point of points.slice(1)) {\n\t// \t\tpath += ` L${toDomPrecision(point.x)},${toDomPrecision(point.y)}`\n\t// \t}\n\t// \treturn path\n\t// }\n\n\tconst arcs = getCloudArcs(width, height, seed, size, scale)\n\tlet path = `M${arcs[0].leftPoint.toFixed()}`\n\n\t// now draw arcs for each circle, starting where it intersects the previous circle, and ending where it intersects the next circle\n\tfor (const { leftPoint, rightPoint, radius, center } of arcs) {\n\t\tif (center === null) {\n\t\t\t// draw a line to rightPoint instead\n\t\t\tpath += ` L${rightPoint.toFixed()}`\n\t\t\tcontinue\n\t\t}\n\t\t// use the large arc if the center of the circle is to the left of the line between the two points\n\t\tconst arc = Vec.Clockwise(leftPoint, rightPoint, center) ? '0' : '1'\n\t\tpath += ` A${toDomPrecision(radius)},${toDomPrecision(radius)} 0 ${arc},1 ${rightPoint.toFixed()}`\n\t}\n\n\tpath += ' Z'\n\treturn path\n}\n\nconst DRAW_OFFSETS: Record<TLDefaultSizeStyle, number> = {\n\ts: 0.5,\n\tm: 0.7,\n\tl: 0.9,\n\txl: 1.6,\n}\n\nexport function inkyCloudSvgPath(\n\twidth: number,\n\theight: number,\n\tseed: string,\n\tsize: TLDefaultSizeStyle,\n\tscale: number\n) {\n\tconst getRandom = rng(seed)\n\tconst mutMultiplier = DRAW_OFFSETS[size] * scale\n\tconst arcs = getCloudArcs(width, height, seed, size, scale)\n\tconst avgArcLengthSquared =\n\t\tarcs.reduce((sum, arc) => sum + Vec.Dist2(arc.leftPoint, arc.rightPoint), 0) / arcs.length\n\tconst shouldMutatePoints = avgArcLengthSquared > (mutMultiplier * 15) ** 2\n\tconst mutPoint = shouldMutatePoints\n\t\t? (p: Vec) => Vec.AddXY(p, getRandom() * mutMultiplier * 2, getRandom() * mutMultiplier * 2)\n\t\t: (p: Vec) => p\n\tlet pathA = `M${arcs[0].leftPoint.toFixed()}`\n\tlet leftMutPoint = mutPoint(arcs[0].leftPoint)\n\tlet pathB = `M${leftMutPoint.toFixed()}`\n\n\tfor (const { leftPoint, center, rightPoint, radius, arcPoint } of arcs) {\n\t\tif (center === null) {\n\t\t\t// draw a line to rightPoint instead\n\t\t\tpathA += ` L${rightPoint.toFixed()}`\n\t\t\tconst rightMutPoint = mutPoint(rightPoint)\n\t\t\tpathB += ` L${rightMutPoint.toFixed()}`\n\t\t\tleftMutPoint = rightMutPoint\n\t\t\tcontinue\n\t\t}\n\t\tconst arc = Vec.Clockwise(leftPoint, rightPoint, center) ? '0' : '1'\n\t\tpathA += ` A${toDomPrecision(radius)},${toDomPrecision(radius)} 0 ${arc},1 ${rightPoint.toFixed()}`\n\t\tconst rightMutPoint = mutPoint(rightPoint)\n\t\tconst mutArcPoint = mutPoint(arcPoint)\n\t\tconst mutCenter = centerOfCircleFromThreePoints(leftMutPoint, rightMutPoint, mutArcPoint)\n\n\t\t// handle situations where the points are colinear (this happens when the cloud is very small)\n\t\tif (!mutCenter) {\n\t\t\t// draw a line to rightMutPoint instead\n\t\t\tpathB += ` L${rightMutPoint.toFixed()}`\n\t\t\tleftMutPoint = rightMutPoint\n\t\t\tcontinue\n\t\t}\n\n\t\tconst mutRadius = Math.abs(Vec.Dist(mutCenter, leftMutPoint))\n\t\tpathB += ` A${toDomPrecision(mutRadius)},${toDomPrecision(\n\t\t\tmutRadius\n\t\t)} 0 ${arc},1 ${rightMutPoint.toFixed()}`\n\t\tleftMutPoint = rightMutPoint\n\t}\n\n\treturn pathA + pathB + ' Z'\n}\n"],
"mappings": "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",
"names": ["rightMutPoint"]
}