{
  "version": 3,
  "sources": ["../../../../src/lib/shapes/arrow/arrowLabel.ts"],
  "sourcesContent": ["import {\n\tArc2d,\n\tBox,\n\tCircle2d,\n\tComputedCache,\n\tEdge2d,\n\tEditor,\n\tGeometry2d,\n\tPolygon2d,\n\tTLArrowShape,\n\tVec,\n\tVecLike,\n\tWeakCache,\n\tangleDistance,\n\tclamp,\n\tgetPointOnCircle,\n\tintersectCirclePolygon,\n\tintersectLineSegmentPolygon,\n} from '@tldraw/editor'\nimport {\n\tARROW_LABEL_FONT_SIZES,\n\tARROW_LABEL_PADDING,\n\tFONT_FAMILIES,\n\tLABEL_TO_ARROW_PADDING,\n\tSTROKE_SIZES,\n\tTEXT_PROPS,\n} from '../shared/default-shape-constants'\nimport { getArrowLength } from './ArrowShapeUtil'\nimport { TLArrowInfo } from './arrow-types'\nimport { getArrowInfo } from './shared'\n\nconst labelSizeCacheCache = new WeakCache<Editor, ComputedCache<Vec, TLArrowShape>>()\n\nfunction getLabelSizeCache(editor: Editor) {\n\treturn labelSizeCacheCache.get(editor, () => {\n\t\treturn editor.store.createComputedCache<Vec, TLArrowShape>('arrowLabelSize', (shape) => {\n\t\t\tconst info = getArrowInfo(editor, shape)!\n\t\t\tlet width = 0\n\t\t\tlet height = 0\n\n\t\t\tconst bodyGeom = info.isStraight\n\t\t\t\t? new Edge2d({\n\t\t\t\t\t\tstart: Vec.From(info.start.point),\n\t\t\t\t\t\tend: Vec.From(info.end.point),\n\t\t\t\t\t})\n\t\t\t\t: new Arc2d({\n\t\t\t\t\t\tcenter: Vec.Cast(info.handleArc.center),\n\t\t\t\t\t\tstart: Vec.Cast(info.start.point),\n\t\t\t\t\t\tend: Vec.Cast(info.end.point),\n\t\t\t\t\t\tsweepFlag: info.bodyArc.sweepFlag,\n\t\t\t\t\t\tlargeArcFlag: info.bodyArc.largeArcFlag,\n\t\t\t\t\t})\n\n\t\t\tif (shape.props.text.trim()) {\n\t\t\t\tconst bodyBounds = bodyGeom.bounds\n\n\t\t\t\tconst fontSize = getArrowLabelFontSize(shape)\n\n\t\t\t\t// First we measure the text with no constraints\n\t\t\t\tconst { w, h } = editor.textMeasure.measureText(shape.props.text, {\n\t\t\t\t\t...TEXT_PROPS,\n\t\t\t\t\tfontFamily: FONT_FAMILIES[shape.props.font],\n\t\t\t\t\tfontSize,\n\t\t\t\t\tmaxWidth: null,\n\t\t\t\t})\n\n\t\t\t\twidth = w\n\t\t\t\theight = h\n\n\t\t\t\tlet shouldSquish = false\n\n\t\t\t\t// If the text is wider than the body, we need to squish it\n\t\t\t\tif (bodyBounds.width > bodyBounds.height) {\n\t\t\t\t\twidth = Math.max(Math.min(w, 64), Math.min(bodyBounds.width - 64, w))\n\t\t\t\t\tshouldSquish = true\n\t\t\t\t} else if (width > 16 * fontSize) {\n\t\t\t\t\twidth = 16 * fontSize\n\t\t\t\t\tshouldSquish = true\n\t\t\t\t}\n\n\t\t\t\tif (shouldSquish) {\n\t\t\t\t\tconst { w: squishedWidth, h: squishedHeight } = editor.textMeasure.measureText(\n\t\t\t\t\t\tshape.props.text,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...TEXT_PROPS,\n\t\t\t\t\t\t\tfontFamily: FONT_FAMILIES[shape.props.font],\n\t\t\t\t\t\t\tfontSize,\n\t\t\t\t\t\t\tmaxWidth: width,\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\n\t\t\t\t\twidth = squishedWidth\n\t\t\t\t\theight = squishedHeight\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new Vec(width, height).addScalar(ARROW_LABEL_PADDING * 2 * shape.props.scale)\n\t\t})\n\t})\n}\n\nfunction getArrowLabelSize(editor: Editor, shape: TLArrowShape) {\n\tif (shape.props.text.trim() === '') {\n\t\treturn new Vec(0, 0).addScalar(ARROW_LABEL_PADDING * 2 * shape.props.scale)\n\t}\n\treturn getLabelSizeCache(editor).get(shape.id) ?? new Vec(0, 0)\n}\n\nfunction getLabelToArrowPadding(shape: TLArrowShape) {\n\tconst strokeWidth = STROKE_SIZES[shape.props.size]\n\tconst labelToArrowPadding =\n\t\t(LABEL_TO_ARROW_PADDING +\n\t\t\t(strokeWidth - STROKE_SIZES.s) * 2 +\n\t\t\t(strokeWidth === STROKE_SIZES.xl ? 20 : 0)) *\n\t\tshape.props.scale\n\n\treturn labelToArrowPadding\n}\n\n/**\n * Return the range of possible label positions for a straight arrow. The full possible range is 0\n * to 1, but as the label itself takes up space the usable range is smaller.\n */\nfunction getStraightArrowLabelRange(\n\teditor: Editor,\n\tshape: TLArrowShape,\n\tinfo: Extract<TLArrowInfo, { isStraight: true }>\n): { start: number; end: number } {\n\tconst labelSize = getArrowLabelSize(editor, shape)\n\tconst labelToArrowPadding = getLabelToArrowPadding(shape)\n\n\t// take the start and end points of the arrow, and nudge them in a bit to give some spare space:\n\tconst startOffset = Vec.Nudge(info.start.point, info.end.point, labelToArrowPadding)\n\tconst endOffset = Vec.Nudge(info.end.point, info.start.point, labelToArrowPadding)\n\n\t// assuming we just stick the label in the middle of the shape, where does the arrow intersect the label?\n\tconst intersectionPoints = intersectLineSegmentPolygon(\n\t\tstartOffset,\n\t\tendOffset,\n\t\tBox.FromCenter(info.middle, labelSize).corners\n\t)\n\tif (!intersectionPoints || intersectionPoints.length !== 2) {\n\t\treturn { start: 0.5, end: 0.5 }\n\t}\n\n\t// there should be two intersection points - one near the start, and one near the end\n\tlet [startIntersect, endIntersect] = intersectionPoints\n\tif (Vec.Dist2(startIntersect, startOffset) > Vec.Dist2(endIntersect, startOffset)) {\n\t\t;[endIntersect, startIntersect] = intersectionPoints\n\t}\n\n\t// take our nudged start and end points and scooch them in even further to give us the possible\n\t// range for the position of the _center_ of the label\n\tconst startConstrained = startOffset.add(Vec.Sub(info.middle, startIntersect))\n\tconst endConstrained = endOffset.add(Vec.Sub(info.middle, endIntersect))\n\n\t// now we can work out the range of possible label positions\n\tconst start = Vec.Dist(info.start.point, startConstrained) / info.length\n\tconst end = Vec.Dist(info.start.point, endConstrained) / info.length\n\treturn { start, end }\n}\n\n/**\n * Return the range of possible label positions for a curved arrow. The full possible range is 0\n * to 1, but as the label itself takes up space the usable range is smaller.\n */\nfunction getCurvedArrowLabelRange(\n\teditor: Editor,\n\tshape: TLArrowShape,\n\tinfo: Extract<TLArrowInfo, { isStraight: false }>\n): { start: number; end: number; dbg?: Geometry2d[] } {\n\tconst labelSize = getArrowLabelSize(editor, shape)\n\tconst labelToArrowPadding = getLabelToArrowPadding(shape)\n\tconst direction = Math.sign(shape.props.bend)\n\n\t// take the start and end points of the arrow, and nudge them in a bit to give some spare space:\n\tconst labelToArrowPaddingRad = (labelToArrowPadding / info.handleArc.radius) * direction\n\tconst startOffsetAngle = Vec.Angle(info.bodyArc.center, info.start.point) - labelToArrowPaddingRad\n\tconst endOffsetAngle = Vec.Angle(info.bodyArc.center, info.end.point) + labelToArrowPaddingRad\n\tconst startOffset = getPointOnCircle(info.bodyArc.center, info.bodyArc.radius, startOffsetAngle)\n\tconst endOffset = getPointOnCircle(info.bodyArc.center, info.bodyArc.radius, endOffsetAngle)\n\n\tconst dbg: Geometry2d[] = []\n\n\t// unlike the straight arrow, we can't just stick the label in the middle of the shape when\n\t// we're working out the range. this is because as the label moves along the curve, the place\n\t// where the arrow intersects with label changes. instead, we have to stick the label center on\n\t// the `startOffset` (the start-most place where it can go), then find where it intersects with\n\t// the arc. because of the symmetry of the label rectangle, we can move the label to that new\n\t// center and take that as the start-most possible point.\n\tconst startIntersections = intersectArcPolygon(\n\t\tinfo.bodyArc.center,\n\t\tinfo.bodyArc.radius,\n\t\tstartOffsetAngle,\n\t\tendOffsetAngle,\n\t\tdirection,\n\t\tBox.FromCenter(startOffset, labelSize).corners\n\t)\n\n\tdbg.push(\n\t\tnew Polygon2d({\n\t\t\tpoints: Box.FromCenter(startOffset, labelSize).corners,\n\t\t\tdebugColor: 'lime',\n\t\t\tisFilled: false,\n\t\t\tignore: true,\n\t\t})\n\t)\n\n\tconst endIntersections = intersectArcPolygon(\n\t\tinfo.bodyArc.center,\n\t\tinfo.bodyArc.radius,\n\t\tstartOffsetAngle,\n\t\tendOffsetAngle,\n\t\tdirection,\n\t\tBox.FromCenter(endOffset, labelSize).corners\n\t)\n\n\tdbg.push(\n\t\tnew Polygon2d({\n\t\t\tpoints: Box.FromCenter(endOffset, labelSize).corners,\n\t\t\tdebugColor: 'lime',\n\t\t\tisFilled: false,\n\t\t\tignore: true,\n\t\t})\n\t)\n\tfor (const pt of [\n\t\t...(startIntersections ?? []),\n\t\t...(endIntersections ?? []),\n\t\tstartOffset,\n\t\tendOffset,\n\t]) {\n\t\tdbg.push(\n\t\t\tnew Circle2d({\n\t\t\t\tx: pt.x - 3,\n\t\t\t\ty: pt.y - 3,\n\t\t\t\tradius: 3,\n\t\t\t\tisFilled: false,\n\t\t\t\tdebugColor: 'magenta',\n\t\t\t\tignore: true,\n\t\t\t})\n\t\t)\n\t}\n\n\t// if we have one or more intersections (we shouldn't have more than two) then the one we need\n\t// is the one furthest from the arrow terminal\n\tconst startConstrained =\n\t\t(startIntersections && furthest(info.start.point, startIntersections)) ?? info.middle\n\tconst endConstrained =\n\t\t(endIntersections && furthest(info.end.point, endIntersections)) ?? info.middle\n\n\tconst startAngle = Vec.Angle(info.bodyArc.center, info.start.point)\n\tconst endAngle = Vec.Angle(info.bodyArc.center, info.end.point)\n\tconst constrainedStartAngle = Vec.Angle(info.bodyArc.center, startConstrained)\n\tconst constrainedEndAngle = Vec.Angle(info.bodyArc.center, endConstrained)\n\n\t// if the arc is small enough that there's no room for the label to move, we constrain it to the middle.\n\tif (\n\t\tangleDistance(startAngle, constrainedStartAngle, direction) >\n\t\tangleDistance(startAngle, constrainedEndAngle, direction)\n\t) {\n\t\treturn { start: 0.5, end: 0.5, dbg }\n\t}\n\n\t// now we can work out the range of possible label positions\n\tconst fullDistance = angleDistance(startAngle, endAngle, direction)\n\tconst start = angleDistance(startAngle, constrainedStartAngle, direction) / fullDistance\n\tconst end = angleDistance(startAngle, constrainedEndAngle, direction) / fullDistance\n\treturn { start, end, dbg }\n}\ninterface ArrowheadInfo {\n\thasStartBinding: boolean\n\thasEndBinding: boolean\n\thasStartArrowhead: boolean\n\thasEndArrowhead: boolean\n}\nexport function getArrowLabelPosition(editor: Editor, shape: TLArrowShape) {\n\tlet labelCenter\n\tconst debugGeom: Geometry2d[] = []\n\tconst info = getArrowInfo(editor, shape)!\n\n\tconst arrowheadInfo: ArrowheadInfo = {\n\t\thasStartBinding: !!info.bindings.start,\n\t\thasEndBinding: !!info.bindings.end,\n\t\thasStartArrowhead: info.start.arrowhead !== 'none',\n\t\thasEndArrowhead: info.end.arrowhead !== 'none',\n\t}\n\tif (info.isStraight) {\n\t\tconst range = getStraightArrowLabelRange(editor, shape, info)\n\t\tconst clampedPosition = getClampedPosition(editor, shape, range, arrowheadInfo)\n\t\tlabelCenter = Vec.Lrp(info.start.point, info.end.point, clampedPosition)\n\t} else {\n\t\tconst range = getCurvedArrowLabelRange(editor, shape, info)\n\t\tif (range.dbg) debugGeom.push(...range.dbg)\n\t\tconst clampedPosition = getClampedPosition(editor, shape, range, arrowheadInfo)\n\t\tconst labelAngle = interpolateArcAngles(\n\t\t\tVec.Angle(info.bodyArc.center, info.start.point),\n\t\t\tVec.Angle(info.bodyArc.center, info.end.point),\n\t\t\tMath.sign(shape.props.bend),\n\t\t\tclampedPosition\n\t\t)\n\t\tlabelCenter = getPointOnCircle(info.bodyArc.center, info.bodyArc.radius, labelAngle)\n\t}\n\n\tconst labelSize = getArrowLabelSize(editor, shape)\n\n\treturn { box: Box.FromCenter(labelCenter, labelSize), debugGeom }\n}\n\nfunction getClampedPosition(\n\teditor: Editor,\n\tshape: TLArrowShape,\n\trange: { start: number; end: number },\n\tarrowheadInfo: ArrowheadInfo\n) {\n\tconst { hasEndArrowhead, hasEndBinding, hasStartBinding, hasStartArrowhead } = arrowheadInfo\n\tconst arrowLength = getArrowLength(editor, shape)\n\tlet clampedPosition = clamp(\n\t\tshape.props.labelPosition,\n\t\thasStartArrowhead || hasStartBinding ? range.start : 0,\n\t\thasEndArrowhead || hasEndBinding ? range.end : 1\n\t)\n\tconst snapDistance = Math.min(0.02, (500 / arrowLength) * 0.02)\n\n\tclampedPosition =\n\t\tclampedPosition >= 0.5 - snapDistance && clampedPosition <= 0.5 + snapDistance\n\t\t\t? 0.5\n\t\t\t: clampedPosition\n\n\treturn clampedPosition\n}\n\nfunction intersectArcPolygon(\n\tcenter: VecLike,\n\tradius: number,\n\tangleStart: number,\n\tangleEnd: number,\n\tdirection: number,\n\tpolygon: VecLike[]\n) {\n\tconst intersections = intersectCirclePolygon(center, radius, polygon)\n\n\t// filter the circle intersections to just the ones from the arc\n\tconst fullArcDistance = angleDistance(angleStart, angleEnd, direction)\n\treturn intersections?.filter((pt) => {\n\t\tconst pDistance = angleDistance(angleStart, Vec.Angle(center, pt), direction)\n\t\treturn pDistance >= 0 && pDistance <= fullArcDistance\n\t})\n}\n\nfunction furthest(from: VecLike, candidates: VecLike[]): VecLike | null {\n\tlet furthest: VecLike | null = null\n\tlet furthestDist = -Infinity\n\n\tfor (const candidate of candidates) {\n\t\tconst dist = Vec.Dist2(from, candidate)\n\t\tif (dist > furthestDist) {\n\t\t\tfurthest = candidate\n\t\t\tfurthestDist = dist\n\t\t}\n\t}\n\n\treturn furthest\n}\n\n/**\n *\n * @param angleStart - The angle of the start of the arc\n * @param angleEnd - The angle of the end of the arc\n * @param direction - The direction of the arc (1 = counter-clockwise, -1 = clockwise)\n * @param t - A number between 0 and 1 representing the position along the arc\n * @returns\n */\nfunction interpolateArcAngles(angleStart: number, angleEnd: number, direction: number, t: number) {\n\tconst dist = angleDistance(angleStart, angleEnd, direction)\n\treturn angleStart + dist * t * direction * -1\n}\n\nexport function getArrowLabelFontSize(shape: TLArrowShape) {\n\treturn ARROW_LABEL_FONT_SIZES[shape.props.size] * shape.props.scale\n}\n"],
  "mappings": "AAAA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EAGA;AAAA,EAEA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,sBAAsB;AAE/B,SAAS,oBAAoB;AAE7B,MAAM,sBAAsB,IAAI,UAAoD;AAEpF,SAAS,kBAAkB,QAAgB;AAC1C,SAAO,oBAAoB,IAAI,QAAQ,MAAM;AAC5C,WAAO,OAAO,MAAM,oBAAuC,kBAAkB,CAAC,UAAU;AACvF,YAAM,OAAO,aAAa,QAAQ,KAAK;AACvC,UAAI,QAAQ;AACZ,UAAI,SAAS;AAEb,YAAM,WAAW,KAAK,aACnB,IAAI,OAAO;AAAA,QACX,OAAO,IAAI,KAAK,KAAK,MAAM,KAAK;AAAA,QAChC,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK;AAAA,MAC7B,CAAC,IACA,IAAI,MAAM;AAAA,QACV,QAAQ,IAAI,KAAK,KAAK,UAAU,MAAM;AAAA,QACtC,OAAO,IAAI,KAAK,KAAK,MAAM,KAAK;AAAA,QAChC,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK;AAAA,QAC5B,WAAW,KAAK,QAAQ;AAAA,QACxB,cAAc,KAAK,QAAQ;AAAA,MAC5B,CAAC;AAEH,UAAI,MAAM,MAAM,KAAK,KAAK,GAAG;AAC5B,cAAM,aAAa,SAAS;AAE5B,cAAM,WAAW,sBAAsB,KAAK;AAG5C,cAAM,EAAE,GAAG,EAAE,IAAI,OAAO,YAAY,YAAY,MAAM,MAAM,MAAM;AAAA,UACjE,GAAG;AAAA,UACH,YAAY,cAAc,MAAM,MAAM,IAAI;AAAA,UAC1C;AAAA,UACA,UAAU;AAAA,QACX,CAAC;AAED,gBAAQ;AACR,iBAAS;AAET,YAAI,eAAe;AAGnB,YAAI,WAAW,QAAQ,WAAW,QAAQ;AACzC,kBAAQ,KAAK,IAAI,KAAK,IAAI,GAAG,EAAE,GAAG,KAAK,IAAI,WAAW,QAAQ,IAAI,CAAC,CAAC;AACpE,yBAAe;AAAA,QAChB,WAAW,QAAQ,KAAK,UAAU;AACjC,kBAAQ,KAAK;AACb,yBAAe;AAAA,QAChB;AAEA,YAAI,cAAc;AACjB,gBAAM,EAAE,GAAG,eAAe,GAAG,eAAe,IAAI,OAAO,YAAY;AAAA,YAClE,MAAM,MAAM;AAAA,YACZ;AAAA,cACC,GAAG;AAAA,cACH,YAAY,cAAc,MAAM,MAAM,IAAI;AAAA,cAC1C;AAAA,cACA,UAAU;AAAA,YACX;AAAA,UACD;AAEA,kBAAQ;AACR,mBAAS;AAAA,QACV;AAAA,MACD;AAEA,aAAO,IAAI,IAAI,OAAO,MAAM,EAAE,UAAU,sBAAsB,IAAI,MAAM,MAAM,KAAK;AAAA,IACpF,CAAC;AAAA,EACF,CAAC;AACF;AAEA,SAAS,kBAAkB,QAAgB,OAAqB;AAC/D,MAAI,MAAM,MAAM,KAAK,KAAK,MAAM,IAAI;AACnC,WAAO,IAAI,IAAI,GAAG,CAAC,EAAE,UAAU,sBAAsB,IAAI,MAAM,MAAM,KAAK;AAAA,EAC3E;AACA,SAAO,kBAAkB,MAAM,EAAE,IAAI,MAAM,EAAE,KAAK,IAAI,IAAI,GAAG,CAAC;AAC/D;AAEA,SAAS,uBAAuB,OAAqB;AACpD,QAAM,cAAc,aAAa,MAAM,MAAM,IAAI;AACjD,QAAM,uBACJ,0BACC,cAAc,aAAa,KAAK,KAChC,gBAAgB,aAAa,KAAK,KAAK,MACzC,MAAM,MAAM;AAEb,SAAO;AACR;AAMA,SAAS,2BACR,QACA,OACA,MACiC;AACjC,QAAM,YAAY,kBAAkB,QAAQ,KAAK;AACjD,QAAM,sBAAsB,uBAAuB,KAAK;AAGxD,QAAM,cAAc,IAAI,MAAM,KAAK,MAAM,OAAO,KAAK,IAAI,OAAO,mBAAmB;AACnF,QAAM,YAAY,IAAI,MAAM,KAAK,IAAI,OAAO,KAAK,MAAM,OAAO,mBAAmB;AAGjF,QAAM,qBAAqB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA,IAAI,WAAW,KAAK,QAAQ,SAAS,EAAE;AAAA,EACxC;AACA,MAAI,CAAC,sBAAsB,mBAAmB,WAAW,GAAG;AAC3D,WAAO,EAAE,OAAO,KAAK,KAAK,IAAI;AAAA,EAC/B;AAGA,MAAI,CAAC,gBAAgB,YAAY,IAAI;AACrC,MAAI,IAAI,MAAM,gBAAgB,WAAW,IAAI,IAAI,MAAM,cAAc,WAAW,GAAG;AAClF;AAAC,KAAC,cAAc,cAAc,IAAI;AAAA,EACnC;AAIA,QAAM,mBAAmB,YAAY,IAAI,IAAI,IAAI,KAAK,QAAQ,cAAc,CAAC;AAC7E,QAAM,iBAAiB,UAAU,IAAI,IAAI,IAAI,KAAK,QAAQ,YAAY,CAAC;AAGvE,QAAM,QAAQ,IAAI,KAAK,KAAK,MAAM,OAAO,gBAAgB,IAAI,KAAK;AAClE,QAAM,MAAM,IAAI,KAAK,KAAK,MAAM,OAAO,cAAc,IAAI,KAAK;AAC9D,SAAO,EAAE,OAAO,IAAI;AACrB;AAMA,SAAS,yBACR,QACA,OACA,MACqD;AACrD,QAAM,YAAY,kBAAkB,QAAQ,KAAK;AACjD,QAAM,sBAAsB,uBAAuB,KAAK;AACxD,QAAM,YAAY,KAAK,KAAK,MAAM,MAAM,IAAI;AAG5C,QAAM,yBAA0B,sBAAsB,KAAK,UAAU,SAAU;AAC/E,QAAM,mBAAmB,IAAI,MAAM,KAAK,QAAQ,QAAQ,KAAK,MAAM,KAAK,IAAI;AAC5E,QAAM,iBAAiB,IAAI,MAAM,KAAK,QAAQ,QAAQ,KAAK,IAAI,KAAK,IAAI;AACxE,QAAM,cAAc,iBAAiB,KAAK,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,gBAAgB;AAC/F,QAAM,YAAY,iBAAiB,KAAK,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,cAAc;AAE3F,QAAM,MAAoB,CAAC;AAQ3B,QAAM,qBAAqB;AAAA,IAC1B,KAAK,QAAQ;AAAA,IACb,KAAK,QAAQ;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI,WAAW,aAAa,SAAS,EAAE;AAAA,EACxC;AAEA,MAAI;AAAA,IACH,IAAI,UAAU;AAAA,MACb,QAAQ,IAAI,WAAW,aAAa,SAAS,EAAE;AAAA,MAC/C,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,QAAQ;AAAA,IACT,CAAC;AAAA,EACF;AAEA,QAAM,mBAAmB;AAAA,IACxB,KAAK,QAAQ;AAAA,IACb,KAAK,QAAQ;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI,WAAW,WAAW,SAAS,EAAE;AAAA,EACtC;AAEA,MAAI;AAAA,IACH,IAAI,UAAU;AAAA,MACb,QAAQ,IAAI,WAAW,WAAW,SAAS,EAAE;AAAA,MAC7C,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,QAAQ;AAAA,IACT,CAAC;AAAA,EACF;AACA,aAAW,MAAM;AAAA,IAChB,GAAI,sBAAsB,CAAC;AAAA,IAC3B,GAAI,oBAAoB,CAAC;AAAA,IACzB;AAAA,IACA;AAAA,EACD,GAAG;AACF,QAAI;AAAA,MACH,IAAI,SAAS;AAAA,QACZ,GAAG,GAAG,IAAI;AAAA,QACV,GAAG,GAAG,IAAI;AAAA,QACV,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,MACT,CAAC;AAAA,IACF;AAAA,EACD;AAIA,QAAM,oBACJ,sBAAsB,SAAS,KAAK,MAAM,OAAO,kBAAkB,MAAM,KAAK;AAChF,QAAM,kBACJ,oBAAoB,SAAS,KAAK,IAAI,OAAO,gBAAgB,MAAM,KAAK;AAE1E,QAAM,aAAa,IAAI,MAAM,KAAK,QAAQ,QAAQ,KAAK,MAAM,KAAK;AAClE,QAAM,WAAW,IAAI,MAAM,KAAK,QAAQ,QAAQ,KAAK,IAAI,KAAK;AAC9D,QAAM,wBAAwB,IAAI,MAAM,KAAK,QAAQ,QAAQ,gBAAgB;AAC7E,QAAM,sBAAsB,IAAI,MAAM,KAAK,QAAQ,QAAQ,cAAc;AAGzE,MACC,cAAc,YAAY,uBAAuB,SAAS,IAC1D,cAAc,YAAY,qBAAqB,SAAS,GACvD;AACD,WAAO,EAAE,OAAO,KAAK,KAAK,KAAK,IAAI;AAAA,EACpC;AAGA,QAAM,eAAe,cAAc,YAAY,UAAU,SAAS;AAClE,QAAM,QAAQ,cAAc,YAAY,uBAAuB,SAAS,IAAI;AAC5E,QAAM,MAAM,cAAc,YAAY,qBAAqB,SAAS,IAAI;AACxE,SAAO,EAAE,OAAO,KAAK,IAAI;AAC1B;AAOO,SAAS,sBAAsB,QAAgB,OAAqB;AAC1E,MAAI;AACJ,QAAM,YAA0B,CAAC;AACjC,QAAM,OAAO,aAAa,QAAQ,KAAK;AAEvC,QAAM,gBAA+B;AAAA,IACpC,iBAAiB,CAAC,CAAC,KAAK,SAAS;AAAA,IACjC,eAAe,CAAC,CAAC,KAAK,SAAS;AAAA,IAC/B,mBAAmB,KAAK,MAAM,cAAc;AAAA,IAC5C,iBAAiB,KAAK,IAAI,cAAc;AAAA,EACzC;AACA,MAAI,KAAK,YAAY;AACpB,UAAM,QAAQ,2BAA2B,QAAQ,OAAO,IAAI;AAC5D,UAAM,kBAAkB,mBAAmB,QAAQ,OAAO,OAAO,aAAa;AAC9E,kBAAc,IAAI,IAAI,KAAK,MAAM,OAAO,KAAK,IAAI,OAAO,eAAe;AAAA,EACxE,OAAO;AACN,UAAM,QAAQ,yBAAyB,QAAQ,OAAO,IAAI;AAC1D,QAAI,MAAM,IAAK,WAAU,KAAK,GAAG,MAAM,GAAG;AAC1C,UAAM,kBAAkB,mBAAmB,QAAQ,OAAO,OAAO,aAAa;AAC9E,UAAM,aAAa;AAAA,MAClB,IAAI,MAAM,KAAK,QAAQ,QAAQ,KAAK,MAAM,KAAK;AAAA,MAC/C,IAAI,MAAM,KAAK,QAAQ,QAAQ,KAAK,IAAI,KAAK;AAAA,MAC7C,KAAK,KAAK,MAAM,MAAM,IAAI;AAAA,MAC1B;AAAA,IACD;AACA,kBAAc,iBAAiB,KAAK,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,UAAU;AAAA,EACpF;AAEA,QAAM,YAAY,kBAAkB,QAAQ,KAAK;AAEjD,SAAO,EAAE,KAAK,IAAI,WAAW,aAAa,SAAS,GAAG,UAAU;AACjE;AAEA,SAAS,mBACR,QACA,OACA,OACA,eACC;AACD,QAAM,EAAE,iBAAiB,eAAe,iBAAiB,kBAAkB,IAAI;AAC/E,QAAM,cAAc,eAAe,QAAQ,KAAK;AAChD,MAAI,kBAAkB;AAAA,IACrB,MAAM,MAAM;AAAA,IACZ,qBAAqB,kBAAkB,MAAM,QAAQ;AAAA,IACrD,mBAAmB,gBAAgB,MAAM,MAAM;AAAA,EAChD;AACA,QAAM,eAAe,KAAK,IAAI,MAAO,MAAM,cAAe,IAAI;AAE9D,oBACC,mBAAmB,MAAM,gBAAgB,mBAAmB,MAAM,eAC/D,MACA;AAEJ,SAAO;AACR;AAEA,SAAS,oBACR,QACA,QACA,YACA,UACA,WACA,SACC;AACD,QAAM,gBAAgB,uBAAuB,QAAQ,QAAQ,OAAO;AAGpE,QAAM,kBAAkB,cAAc,YAAY,UAAU,SAAS;AACrE,SAAO,eAAe,OAAO,CAAC,OAAO;AACpC,UAAM,YAAY,cAAc,YAAY,IAAI,MAAM,QAAQ,EAAE,GAAG,SAAS;AAC5E,WAAO,aAAa,KAAK,aAAa;AAAA,EACvC,CAAC;AACF;AAEA,SAAS,SAAS,MAAe,YAAuC;AACvE,MAAIA,YAA2B;AAC/B,MAAI,eAAe;AAEnB,aAAW,aAAa,YAAY;AACnC,UAAM,OAAO,IAAI,MAAM,MAAM,SAAS;AACtC,QAAI,OAAO,cAAc;AACxB,MAAAA,YAAW;AACX,qBAAe;AAAA,IAChB;AAAA,EACD;AAEA,SAAOA;AACR;AAUA,SAAS,qBAAqB,YAAoB,UAAkB,WAAmB,GAAW;AACjG,QAAM,OAAO,cAAc,YAAY,UAAU,SAAS;AAC1D,SAAO,aAAa,OAAO,IAAI,YAAY;AAC5C;AAEO,SAAS,sBAAsB,OAAqB;AAC1D,SAAO,uBAAuB,MAAM,MAAM,IAAI,IAAI,MAAM,MAAM;AAC/D;",
  "names": ["furthest"]
}
