pa_font 0.2.0 → 0.2.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"paFont.cjs","names":["sharedWordSegmenter","sharedGraphemeSegmenter","getMeasureContext","getSharedGraphemeSegmenter","sharedGraphemeSegmenter"],"sources":["../src/paFont/geometry.js","../src/paFont/core.js","../src/paFont/shape.js","../node_modules/@chenglou/pretext/dist/bidi.js","../node_modules/@chenglou/pretext/dist/analysis.js","../node_modules/@chenglou/pretext/dist/measurement.js","../node_modules/@chenglou/pretext/dist/line-break.js","../node_modules/@chenglou/pretext/dist/layout.js","../src/paFont/paragraphLayout.js","../src/paFont/paragraph.js","../src/paFont/paFont.js"],"sourcesContent":["export function toScreenPoint(point, scale) {\n return [point.x * scale, -point.y * scale];\n}\n\nexport function cloneRawPoint(point) {\n return { x: point.x, y: point.y };\n}\n\nexport function pushUniquePoint(points, point) {\n if (points.length === 0 || !pointsEqual2D(points[points.length - 1], point)) {\n points.push(point);\n }\n}\n\nexport function flattenQuadratic(p0, p1, p2, tolerance, out, depth = 0) {\n if (depth >= 12 || quadFlatness(p0, p1, p2) <= tolerance) {\n pushUniquePoint(out, p2);\n return;\n }\n\n const p01 = midpoint(p0, p1);\n const p12 = midpoint(p1, p2);\n const p012 = midpoint(p01, p12);\n\n flattenQuadratic(p0, p01, p012, tolerance, out, depth + 1);\n flattenQuadratic(p012, p12, p2, tolerance, out, depth + 1);\n}\n\nexport function flattenCubic(p0, p1, p2, p3, tolerance, out, depth = 0) {\n if (depth >= 12 || cubicFlatness(p0, p1, p2, p3) <= tolerance) {\n pushUniquePoint(out, p3);\n return;\n }\n\n const p01 = midpoint(p0, p1);\n const p12 = midpoint(p1, p2);\n const p23 = midpoint(p2, p3);\n const p012 = midpoint(p01, p12);\n const p123 = midpoint(p12, p23);\n const p0123 = midpoint(p012, p123);\n\n flattenCubic(p0, p01, p012, p0123, tolerance, out, depth + 1);\n flattenCubic(p0123, p123, p23, p3, tolerance, out, depth + 1);\n}\n\nfunction quadFlatness(p0, p1, p2) {\n return pointToLineDistance(p1, p0, p2);\n}\n\nfunction cubicFlatness(p0, p1, p2, p3) {\n return Math.max(\n pointToLineDistance(p1, p0, p3),\n pointToLineDistance(p2, p0, p3)\n );\n}\n\nfunction pointToLineDistance(point, lineStart, lineEnd) {\n const dx = lineEnd[0] - lineStart[0];\n const dy = lineEnd[1] - lineStart[1];\n const lengthSq = dx * dx + dy * dy;\n\n if (lengthSq === 0) {\n return distance(point, lineStart);\n }\n\n const area = Math.abs(\n dx * (lineStart[1] - point[1]) - (lineStart[0] - point[0]) * dy\n );\n\n return area / Math.sqrt(lengthSq);\n}\n\nexport function midpoint(a, b) {\n return [(a[0] + b[0]) * 0.5, (a[1] + b[1]) * 0.5];\n}\n\nexport function signedArea(ring) {\n let area = 0;\n\n for (let index = 0; index < ring.length; index += 1) {\n const current = ring[index];\n const next = ring[(index + 1) % ring.length];\n area += current[0] * next[1] - next[0] * current[1];\n }\n\n return area * 0.5;\n}\n\nexport function pointInRing(point, ring) {\n let inside = false;\n\n for (let i = 0, j = ring.length - 1; i < ring.length; j = i, i += 1) {\n const xi = ring[i][0];\n const yi = ring[i][1];\n const xj = ring[j][0];\n const yj = ring[j][1];\n const intersects =\n yi > point[1] !== yj > point[1] &&\n point[0] < ((xj - xi) * (point[1] - yi)) / (yj - yi || 1e-9) + xi;\n\n if (intersects) {\n inside = !inside;\n }\n }\n\n return inside;\n}\n\nexport function hitPart(point, part, epsilon) {\n if (!rectContainsPoint(part.bbox, point, epsilon)) {\n return \"outside\";\n }\n\n if (isPointOnRingEdge(point, part.outer, epsilon)) {\n return \"edge\";\n }\n\n if (!pointInRing(point, part.outer)) {\n return \"outside\";\n }\n\n for (const hole of part.holes) {\n if (isPointOnRingEdge(point, hole, epsilon)) {\n return \"edge\";\n }\n\n if (pointInRing(point, hole)) {\n return \"hole\";\n }\n }\n\n return \"fill\";\n}\n\nfunction isPointOnRingEdge(point, ring, epsilon) {\n for (let index = 0; index < ring.length; index += 1) {\n const a = ring[index];\n const b = ring[(index + 1) % ring.length];\n\n if (distancePointToSegment(point, a, b) <= epsilon) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction distancePointToSegment(point, a, b) {\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const lengthSq = dx * dx + dy * dy;\n\n if (lengthSq === 0) {\n return distance(point, a);\n }\n\n let t = ((point[0] - a[0]) * dx + (point[1] - a[1]) * dy) / lengthSq;\n t = Math.max(0, Math.min(1, t));\n\n const projection = [a[0] + dx * t, a[1] + dy * t];\n return distance(point, projection);\n}\n\nexport function distance(a, b) {\n const dx = a[0] - b[0];\n const dy = a[1] - b[1];\n return Math.sqrt(dx * dx + dy * dy);\n}\n\nexport function sampleRing(ring, step, callback) {\n for (let index = 0; index < ring.length; index += 1) {\n const a = ring[index];\n const b = ring[(index + 1) % ring.length];\n const segmentLength = distance(a, b);\n const divisions = Math.max(1, Math.ceil(segmentLength / step));\n\n for (let offset = 0; offset < divisions; offset += 1) {\n if (index > 0 || offset > 0) {\n const t = offset / divisions;\n callback([\n a[0] + (b[0] - a[0]) * t,\n a[1] + (b[1] - a[1]) * t,\n ]);\n } else {\n callback([a[0], a[1]]);\n }\n }\n }\n}\n\nexport function ringBounds(ring) {\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n\n ring.forEach((point) => {\n minX = Math.min(minX, point[0]);\n minY = Math.min(minY, point[1]);\n maxX = Math.max(maxX, point[0]);\n maxY = Math.max(maxY, point[1]);\n });\n\n return {\n x: minX,\n y: minY,\n w: maxX - minX,\n h: maxY - minY,\n };\n}\n\nexport function translateRing(ring, tx, ty) {\n return ring.map((point) => [point[0] + tx, point[1] + ty]);\n}\n\nexport function translateRect(rect, tx, ty) {\n return {\n x: rect.x + tx,\n y: rect.y + ty,\n w: rect.w,\n h: rect.h,\n };\n}\n\nexport function copyRing(ring) {\n return ring.map((point) => [point[0], point[1]]);\n}\n\nexport function combineRects(rects) {\n if (rects.length === 0) {\n return null;\n }\n\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n\n rects.forEach((rect) => {\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.w);\n maxY = Math.max(maxY, rect.y + rect.h);\n });\n\n return {\n x: minX,\n y: minY,\n w: maxX - minX,\n h: maxY - minY,\n };\n}\n\nexport function rectContainsRect(outer, inner, epsilon = 1e-6) {\n return (\n inner.x >= outer.x - epsilon &&\n inner.y >= outer.y - epsilon &&\n inner.x + inner.w <= outer.x + outer.w + epsilon &&\n inner.y + inner.h <= outer.y + outer.h + epsilon\n );\n}\n\nexport function rectContainsPoint(rect, point, epsilon = 0) {\n return (\n point[0] >= rect.x - epsilon &&\n point[0] <= rect.x + rect.w + epsilon &&\n point[1] >= rect.y - epsilon &&\n point[1] <= rect.y + rect.h + epsilon\n );\n}\n\nexport function emptyRect() {\n return { x: 0, y: 0, w: 0, h: 0 };\n}\n\nexport function normalizeNumber(value, fallback) {\n return Number.isFinite(value) ? value : fallback;\n}\n\nexport function normalizePositive(value, fallback) {\n return Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\nexport function samePoint(a, b) {\n return a.x === b.x && a.y === b.y;\n}\n\nexport function pointsEqual2D(a, b) {\n return a[0] === b[0] && a[1] === b[1];\n}\n\nexport function pointsAlmostEqual2D(a, b, epsilon = 1e-6) {\n return Math.abs(a[0] - b[0]) <= epsilon && Math.abs(a[1] - b[1]) <= epsilon;\n}\n\nexport function ringPerimeter(ring) {\n let total = 0;\n\n for (let index = 0; index < ring.length; index += 1) {\n total += distance(ring[index], ring[(index + 1) % ring.length]);\n }\n\n return total;\n}\n\nexport function polylineLength(path) {\n let total = 0;\n\n for (let index = 0; index < path.length - 1; index += 1) {\n total += distance(path[index], path[index + 1]);\n }\n\n return total;\n}\n\nexport function pointAtClosedPathDistance(ring, distanceAlong) {\n const perimeter = ringPerimeter(ring);\n\n if (perimeter <= 1e-9) {\n return [ring[0][0], ring[0][1]];\n }\n\n let remaining = mod(distanceAlong, perimeter);\n\n for (let index = 0; index < ring.length; index += 1) {\n const start = ring[index];\n const end = ring[(index + 1) % ring.length];\n const segmentLength = distance(start, end);\n\n if (segmentLength <= 1e-9) {\n continue;\n }\n\n if (remaining <= segmentLength) {\n const t = remaining / segmentLength;\n return [\n start[0] + (end[0] - start[0]) * t,\n start[1] + (end[1] - start[1]) * t,\n ];\n }\n\n remaining -= segmentLength;\n }\n\n return [ring[ring.length - 1][0], ring[ring.length - 1][1]];\n}\n\nexport function pointAtOpenPathDistance(path, distanceAlong) {\n if (distanceAlong <= 0) {\n return [path[0][0], path[0][1]];\n }\n\n let remaining = distanceAlong;\n\n for (let index = 0; index < path.length - 1; index += 1) {\n const start = path[index];\n const end = path[index + 1];\n const segmentLength = distance(start, end);\n\n if (segmentLength <= 1e-9) {\n continue;\n }\n\n if (remaining <= segmentLength) {\n const t = remaining / segmentLength;\n return [\n start[0] + (end[0] - start[0]) * t,\n start[1] + (end[1] - start[1]) * t,\n ];\n }\n\n remaining -= segmentLength;\n }\n\n return [path[path.length - 1][0], path[path.length - 1][1]];\n}\n\nexport function segmentIntersectsRing(a, b, ring, ignoredEdges, epsilon) {\n for (let index = 0; index < ring.length; index += 1) {\n if (ignoredEdges.has(index)) {\n continue;\n }\n\n const c = ring[index];\n const d = ring[(index + 1) % ring.length];\n\n if (segmentsIntersect(a, b, c, d, epsilon)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction segmentsIntersect(a, b, c, d, epsilon) {\n const o1 = orientation(a, b, c);\n const o2 = orientation(a, b, d);\n const o3 = orientation(c, d, a);\n const o4 = orientation(c, d, b);\n\n if (\n ((o1 > epsilon && o2 < -epsilon) || (o1 < -epsilon && o2 > epsilon)) &&\n ((o3 > epsilon && o4 < -epsilon) || (o3 < -epsilon && o4 > epsilon))\n ) {\n return true;\n }\n\n if (Math.abs(o1) <= epsilon && pointOnSegment(c, a, b, epsilon)) {\n return true;\n }\n\n if (Math.abs(o2) <= epsilon && pointOnSegment(d, a, b, epsilon)) {\n return true;\n }\n\n if (Math.abs(o3) <= epsilon && pointOnSegment(a, c, d, epsilon)) {\n return true;\n }\n\n if (Math.abs(o4) <= epsilon && pointOnSegment(b, c, d, epsilon)) {\n return true;\n }\n\n return false;\n}\n\nfunction orientation(a, b, c) {\n return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);\n}\n\nfunction pointOnSegment(point, start, end, epsilon) {\n return (\n point[0] >= Math.min(start[0], end[0]) - epsilon &&\n point[0] <= Math.max(start[0], end[0]) + epsilon &&\n point[1] >= Math.min(start[1], end[1]) - epsilon &&\n point[1] <= Math.max(start[1], end[1]) + epsilon\n );\n}\n\nexport function mod(value, divisor) {\n return ((value % divisor) + divisor) % divisor;\n}\n","import {\n cloneRawPoint,\n combineRects,\n copyRing,\n emptyRect,\n flattenCubic,\n flattenQuadratic,\n normalizeNumber,\n normalizePositive,\n pointInRing,\n pointsEqual2D,\n pushUniquePoint,\n rectContainsRect,\n ringBounds,\n samePoint,\n signedArea,\n toScreenPoint,\n translateRect,\n translateRing,\n} from \"./geometry.js\";\n\nexport function layoutGlyphs(font, value, opts) {\n const glyphs = [];\n const renderOptions = toRenderOptions(opts);\n const endX = font.forEachGlyph(\n value,\n opts.x,\n opts.y,\n opts.size,\n renderOptions,\n (glyph, x, y, size) => {\n glyphs.push({\n glyph,\n x,\n y,\n size,\n index: glyphs.length,\n });\n }\n );\n\n return {\n text: value,\n glyphs,\n metrics: {\n width: endX - opts.x,\n x: opts.x,\n y: opts.y,\n size: opts.size,\n },\n };\n}\n\nexport function measureText(font, value, opts) {\n const renderOptions = toRenderOptions(opts);\n const path = font.getPath(value, opts.x, opts.y, opts.size, renderOptions);\n const box = path.getBoundingBox();\n\n return {\n width: measureAdvanceWidth(font, value, opts),\n bbox: {\n x: box.x1,\n y: box.y1,\n w: box.x2 - box.x1,\n h: box.y2 - box.y1,\n },\n };\n}\n\nexport function measureAdvanceWidth(font, value, opts) {\n return font.getAdvanceWidth(value, opts.size, toRenderOptions(opts));\n}\n\nexport function buildGlyphTopology(glyph, fallbackUnitsPerEm) {\n const commands = glyph.path?.commands ?? [];\n const contours = [];\n let contourId = 0;\n let current = null;\n\n const finishCurrentContour = () => {\n if (!current || current.segments.length === 0) {\n current = null;\n return;\n }\n\n if (!samePoint(current.cursor, current.start)) {\n current.segments.push({\n type: \"L\",\n from: cloneRawPoint(current.cursor),\n to: cloneRawPoint(current.start),\n });\n current.cursor = cloneRawPoint(current.start);\n }\n\n contours.push({\n id: contourId++,\n start: cloneRawPoint(current.start),\n segments: current.segments,\n });\n current = null;\n };\n\n commands.forEach((cmd) => {\n if (cmd.type === \"M\") {\n finishCurrentContour();\n current = {\n start: { x: cmd.x, y: cmd.y },\n cursor: { x: cmd.x, y: cmd.y },\n segments: [],\n };\n return;\n }\n\n if (!current) {\n return;\n }\n\n if (cmd.type === \"L\") {\n const to = { x: cmd.x, y: cmd.y };\n current.segments.push({\n type: \"L\",\n from: cloneRawPoint(current.cursor),\n to,\n });\n current.cursor = cloneRawPoint(to);\n return;\n }\n\n if (cmd.type === \"Q\") {\n const to = { x: cmd.x, y: cmd.y };\n current.segments.push({\n type: \"Q\",\n from: cloneRawPoint(current.cursor),\n c1: { x: cmd.x1, y: cmd.y1 },\n to,\n });\n current.cursor = cloneRawPoint(to);\n return;\n }\n\n if (cmd.type === \"C\") {\n const to = { x: cmd.x, y: cmd.y };\n current.segments.push({\n type: \"C\",\n from: cloneRawPoint(current.cursor),\n c1: { x: cmd.x1, y: cmd.y1 },\n c2: { x: cmd.x2, y: cmd.y2 },\n to,\n });\n current.cursor = cloneRawPoint(to);\n return;\n }\n\n if (cmd.type === \"Z\") {\n finishCurrentContour();\n }\n });\n\n finishCurrentContour();\n\n return {\n glyphIndex: glyph.index,\n advanceWidth: glyph.advanceWidth ?? 0,\n unitsPerEm: glyph.path?.unitsPerEm ?? fallbackUnitsPerEm ?? 1000,\n contours,\n };\n}\n\nexport function flattenGlyphTopology(topology, options) {\n const scale = options.size / topology.unitsPerEm;\n const contours = topology.contours\n .map((contour) => flattenContour(contour, scale, options.flatten))\n .filter(Boolean);\n const classifiedContours = classifyContours(contours);\n const parts = buildParts(classifiedContours);\n const bbox = combineRects(parts.map((part) => part.bbox)) ?? emptyRect();\n\n return {\n glyphIndex: topology.glyphIndex,\n advanceWidth: topology.advanceWidth * scale,\n contours: classifiedContours,\n parts,\n bbox,\n };\n}\n\nfunction flattenContour(contour, scale, tolerance) {\n const ring = [];\n const start = toScreenPoint(contour.start, scale);\n pushUniquePoint(ring, start);\n\n contour.segments.forEach((segment) => {\n if (segment.type === \"L\") {\n pushUniquePoint(ring, toScreenPoint(segment.to, scale));\n return;\n }\n\n if (segment.type === \"Q\") {\n flattenQuadratic(\n toScreenPoint(segment.from, scale),\n toScreenPoint(segment.c1, scale),\n toScreenPoint(segment.to, scale),\n tolerance,\n ring\n );\n return;\n }\n\n if (segment.type === \"C\") {\n flattenCubic(\n toScreenPoint(segment.from, scale),\n toScreenPoint(segment.c1, scale),\n toScreenPoint(segment.c2, scale),\n toScreenPoint(segment.to, scale),\n tolerance,\n ring\n );\n }\n });\n\n if (ring.length > 1 && pointsEqual2D(ring[0], ring[ring.length - 1])) {\n ring.pop();\n }\n\n if (ring.length < 3) {\n return null;\n }\n\n const bbox = ringBounds(ring);\n const area = signedArea(ring);\n\n return {\n id: contour.id,\n ring,\n bbox,\n area,\n };\n}\n\nfunction classifyContours(contours) {\n const result = contours.map((contour) => ({\n ...contour,\n parentId: null,\n depth: 0,\n role: \"outer\",\n }));\n\n result.forEach((child) => {\n let parent = null;\n let parentArea = Number.POSITIVE_INFINITY;\n\n result.forEach((candidate) => {\n if (candidate.id === child.id) {\n return;\n }\n\n if (Math.abs(candidate.area) <= Math.abs(child.area)) {\n return;\n }\n\n if (!rectContainsRect(candidate.bbox, child.bbox)) {\n return;\n }\n\n if (!pointInRing(child.ring[0], candidate.ring)) {\n return;\n }\n\n const candidateArea = Math.abs(candidate.area);\n if (candidateArea < parentArea) {\n parent = candidate;\n parentArea = candidateArea;\n }\n });\n\n if (parent) {\n child.parentId = parent.id;\n }\n });\n\n const byId = new Map(result.map((contour) => [contour.id, contour]));\n\n const resolveDepth = (contour) => {\n if (contour.parentId == null) {\n return 0;\n }\n\n const parent = byId.get(contour.parentId);\n return resolveDepth(parent) + 1;\n };\n\n result.forEach((contour) => {\n contour.depth = resolveDepth(contour);\n contour.role = contour.depth % 2 === 0 ? \"outer\" : \"hole\";\n });\n\n return result;\n}\n\nfunction buildParts(contours) {\n return contours\n .filter((contour) => contour.role === \"outer\")\n .map((outer) => {\n const holeContours = contours.filter(\n (contour) => contour.parentId === outer.id && contour.role === \"hole\"\n );\n\n return {\n outer: copyRing(outer.ring),\n holes: holeContours.map((hole) => copyRing(hole.ring)),\n bbox: { ...outer.bbox },\n area:\n Math.abs(outer.area) -\n holeContours.reduce((sum, hole) => sum + Math.abs(hole.area), 0),\n };\n });\n}\n\nexport function translateGlyphGeometry(geometry, tx, ty, glyphPosition) {\n const parts = geometry.parts.map((part, partIndex) => ({\n outer: translateRing(part.outer, tx, ty),\n holes: part.holes.map((hole) => translateRing(hole, tx, ty)),\n bbox: translateRect(part.bbox, tx, ty),\n area: part.area,\n glyphPosition,\n partIndex,\n }));\n\n const contours = geometry.contours.map((contour) => ({\n id: `${glyphPosition}:${contour.id}`,\n sourceId: contour.id,\n glyphPosition,\n parentId:\n contour.parentId == null ? null : `${glyphPosition}:${contour.parentId}`,\n depth: contour.depth,\n role: contour.role,\n area: contour.area,\n bbox: translateRect(contour.bbox, tx, ty),\n ring: translateRing(contour.ring, tx, ty),\n }));\n\n return {\n parts,\n contours,\n bbox: translateRect(geometry.bbox, tx, ty),\n };\n}\n\nexport function normalizeTextOptions(options = {}) {\n const size = normalizePositive(options.size, 72);\n\n return {\n x: normalizeNumber(options.x, 0),\n y: normalizeNumber(options.y, 0),\n size,\n flatten: normalizePositive(options.flatten, 1.25),\n edgeEpsilon:\n options.edgeEpsilon == null\n ? defaultEdgeEpsilon(size)\n : normalizePositive(options.edgeEpsilon, defaultEdgeEpsilon(size)),\n kerning: options.kerning !== false,\n letterSpacing:\n options.letterSpacing == null\n ? undefined\n : normalizeNumber(options.letterSpacing, 0),\n tracking:\n options.tracking == null\n ? undefined\n : normalizeNumber(options.tracking, 0),\n script: options.script,\n language: options.language,\n features: options.features,\n };\n}\n\nfunction defaultEdgeEpsilon(size) {\n return Math.min(1, Math.max(0.01, size * 0.0025));\n}\n\nfunction toRenderOptions(opts) {\n const renderOptions = {\n kerning: opts.kerning,\n };\n\n if (opts.letterSpacing != null) {\n renderOptions.letterSpacing = opts.letterSpacing;\n }\n\n if (opts.tracking != null) {\n renderOptions.tracking = opts.tracking;\n }\n\n if (opts.script) {\n renderOptions.script = opts.script;\n }\n\n if (opts.language) {\n renderOptions.language = opts.language;\n }\n\n if (opts.features) {\n renderOptions.features = opts.features;\n }\n\n return renderOptions;\n}\n\nexport function toArrayBuffer(value) {\n if (value instanceof ArrayBuffer) {\n return value;\n }\n\n if (ArrayBuffer.isView(value)) {\n return value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength);\n }\n\n return value;\n}\n","import {\n combineRects,\n copyRing,\n distance,\n emptyRect,\n hitPart,\n midpoint,\n mod,\n normalizeNumber,\n normalizePositive,\n pointAtClosedPathDistance,\n pointAtOpenPathDistance,\n pointInRing,\n pointsAlmostEqual2D,\n polylineLength,\n rectContainsPoint,\n ringBounds,\n ringPerimeter,\n sampleRing,\n segmentIntersectsRing,\n signedArea,\n} from \"./geometry.js\";\nimport { translateGlyphGeometry } from \"./core.js\";\n\nexport class PAShape {\n constructor({ text, parts, contours, glyphs, bbox, metrics, edgeEpsilon }) {\n this.text = text;\n this.parts = parts;\n this.bbox = bbox;\n this.metrics = metrics;\n this.edgeEpsilon = edgeEpsilon;\n this.raw = {\n contours,\n glyphs,\n };\n this._cache = {\n glyphs: null,\n openHoles: new Map(),\n resample: new Map(),\n shapes: new Map(),\n regionViews: null,\n };\n }\n\n get polygons() {\n return this.parts.map((part) => [part.outer, ...part.holes]);\n }\n\n [Symbol.iterator]() {\n return this._getRegionViews()[Symbol.iterator]();\n }\n\n glyphs() {\n if (this._cache.glyphs) {\n return this._cache.glyphs;\n }\n\n if (!Array.isArray(this.raw.glyphs) || this.raw.glyphs.length <= 1) {\n this._cache.glyphs = [this];\n return this._cache.glyphs;\n }\n\n this._cache.glyphs = this.raw.glyphs.map((_, glyphPosition) =>\n createGlyphShape(this, glyphPosition)\n );\n\n return this._cache.glyphs;\n }\n\n toShape(options = {}) {\n return resolveShapeVariant(this, options);\n }\n\n toRegions(options = {}) {\n const shape = this.toShape(options);\n return createRegionCollection(shape);\n }\n\n openHoles(width) {\n const slitWidth = normalizePositive(width, 0);\n\n if (slitWidth <= 0 || !this.parts.some((part) => part.holes.length > 0)) {\n return this;\n }\n\n const cacheKey = toCacheKey(slitWidth);\n const cached = this._cache.openHoles.get(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const geometryEpsilon = resolveGeometryEpsilon(slitWidth);\n\n const shape = createDerivedShape(\n this,\n this.parts.map((part) => openPartWithSlit(part, slitWidth, geometryEpsilon))\n );\n\n this._cache.openHoles.set(cacheKey, shape);\n return shape;\n }\n\n resample(step) {\n const spacing = normalizePositive(step, 0);\n\n if (spacing <= 0) {\n return this;\n }\n\n const cacheKey = toCacheKey(spacing);\n const cached = this._cache.resample.get(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const shape = createDerivedShape(\n this,\n this.parts.map((part) => resamplePart(part, spacing))\n );\n\n this._cache.resample.set(cacheKey, shape);\n return shape;\n }\n\n hit(x, y, epsilon = this.edgeEpsilon) {\n const point = [x, y];\n\n if (!rectContainsPoint(this.bbox, point, epsilon)) {\n return \"outside\";\n }\n\n let holeHit = false;\n\n for (const part of this.parts) {\n const result = hitPart(point, part, epsilon);\n\n if (result === \"edge\" || result === \"fill\") {\n return result;\n }\n\n if (result === \"hole\") {\n holeHit = true;\n }\n }\n\n return holeHit ? \"hole\" : \"outside\";\n }\n\n contains(x, y, epsilon = this.edgeEpsilon) {\n return this.hit(x, y, epsilon) === \"fill\";\n }\n\n toPoints(options = {}) {\n const opts = normalizePointOptions(options);\n const shape =\n opts.openWidth > 0 ? this.toShape({ openWidth: opts.openWidth }) : this;\n const step = opts.step;\n const includeHoles = opts.includeHoles;\n const sampled = [];\n\n shape.parts.forEach((part, partIndex) => {\n sampleRing(part.outer, step, (point) => {\n sampled.push({\n x: point[0],\n y: point[1],\n partIndex,\n hole: false,\n });\n });\n\n if (!includeHoles) {\n return;\n }\n\n part.holes.forEach((hole, holeIndex) => {\n sampleRing(hole, step, (point) => {\n sampled.push({\n x: point[0],\n y: point[1],\n partIndex,\n hole: true,\n holeIndex,\n });\n });\n });\n });\n\n return sampled;\n }\n\n _getRegionViews() {\n if (!this._cache.regionViews) {\n this._cache.regionViews = this.parts.map((part) =>\n Object.freeze({\n outer: part.outer,\n holes: part.holes,\n bbox: part.bbox,\n })\n );\n }\n\n return this._cache.regionViews;\n }\n}\n\nexport function createTextShape(layout, opts, fontInstance) {\n const parts = [];\n const contours = [];\n const glyphs = [];\n\n layout.glyphs.forEach((item, glyphPosition) => {\n const localGeometry = fontInstance._getFlattenedGlyph(item.glyph, opts);\n const translated = translateGlyphGeometry(\n localGeometry,\n item.x,\n item.y,\n glyphPosition\n );\n\n parts.push(...translated.parts);\n contours.push(...translated.contours);\n glyphs.push({\n position: glyphPosition,\n glyphIndex: item.glyph.index,\n x: item.x,\n y: item.y,\n size: item.size,\n bbox: translated.bbox,\n partCount: translated.parts.length,\n });\n });\n\n const bbox = combineRects(parts.map((part) => part.bbox)) ?? emptyRect();\n\n return new PAShape({\n text: layout.text,\n parts,\n contours,\n glyphs,\n bbox,\n metrics: {\n ...layout.metrics,\n bbox,\n },\n edgeEpsilon: opts.edgeEpsilon,\n });\n}\n\nexport function mergeShapes(shapes, options = {}) {\n if (!Array.isArray(shapes) || shapes.length === 0) {\n const bbox = emptyRect();\n\n return new PAShape({\n text: String(options.text ?? \"\"),\n parts: [],\n contours: [],\n glyphs: [],\n bbox,\n metrics: {\n x: normalizeNumber(options.x, 0),\n y: normalizeNumber(options.y, 0),\n size: normalizePositive(options.size, 0),\n width: normalizeNumber(options.width, 0),\n bbox,\n },\n edgeEpsilon: normalizePositive(options.edgeEpsilon, 0.01),\n });\n }\n\n const parts = [];\n const contours = [];\n const glyphs = [];\n let glyphOffset = 0;\n\n shapes.forEach((shape, shapeIndex) => {\n const copiedParts = copyParts(shape.parts).map((part) => ({\n ...part,\n glyphPosition:\n typeof part.glyphPosition === \"number\"\n ? part.glyphPosition + glyphOffset\n : part.glyphPosition,\n }));\n\n parts.push(...copiedParts);\n\n const copiedContours = copyContours(shape.raw.contours ?? []).map((contour) => ({\n ...contour,\n id: `${shapeIndex}:${contour.id}`,\n parentId:\n contour.parentId == null ? null : `${shapeIndex}:${contour.parentId}`,\n glyphPosition:\n typeof contour.glyphPosition === \"number\"\n ? contour.glyphPosition + glyphOffset\n : contour.glyphPosition,\n }));\n\n contours.push(...copiedContours);\n\n const copiedGlyphs = (shape.raw.glyphs ?? []).map((glyph, glyphIndex) => ({\n ...glyph,\n position: glyphOffset + glyphIndex,\n bbox: glyph.bbox ? { ...glyph.bbox } : emptyRect(),\n }));\n\n glyphs.push(...copiedGlyphs);\n glyphOffset += shape.raw.glyphs?.length ?? 0;\n });\n\n const bbox =\n combineRects(parts.map((part) => part.bbox)) ??\n combineRects(glyphs.map((glyph) => glyph.bbox)) ??\n emptyRect();\n const firstShape = shapes[0];\n\n return new PAShape({\n text: String(options.text ?? shapes.map((shape) => shape.text).join(\"\")),\n parts,\n contours,\n glyphs,\n bbox,\n metrics: {\n x: normalizeNumber(options.x, firstShape?.metrics?.x ?? 0),\n y: normalizeNumber(options.y, firstShape?.metrics?.y ?? 0),\n size: normalizePositive(options.size, firstShape?.metrics?.size ?? 0),\n width: normalizeNumber(options.width, bbox.w),\n bbox,\n },\n edgeEpsilon: normalizePositive(\n options.edgeEpsilon,\n firstShape?.edgeEpsilon ?? 0.01,\n ),\n });\n}\n\nfunction createGlyphShape(shape, glyphPosition) {\n const glyphMeta = shape.raw.glyphs?.[glyphPosition] ?? null;\n const parts = copyParts(\n shape.parts.filter((part) => part.glyphPosition === glyphPosition)\n );\n const contours = copyContours(\n (shape.raw.contours ?? []).filter(\n (contour) => contour.glyphPosition === glyphPosition\n )\n );\n const bbox =\n combineRects(parts.map((part) => part.bbox)) ??\n (glyphMeta?.bbox ? { ...glyphMeta.bbox } : emptyRect());\n\n return new PAShape({\n text: extractGlyphText(shape.text, glyphPosition, shape.raw.glyphs?.length ?? 0),\n parts,\n contours,\n glyphs: glyphMeta ? [{ ...glyphMeta, bbox, partCount: parts.length }] : [],\n bbox,\n metrics: {\n x: glyphMeta?.x ?? shape.metrics?.x ?? 0,\n y: glyphMeta?.y ?? shape.metrics?.y ?? 0,\n size: glyphMeta?.size ?? shape.metrics?.size ?? 0,\n width: bbox.w,\n bbox,\n },\n edgeEpsilon: shape.edgeEpsilon,\n });\n}\n\nfunction createDerivedShape(shape, parts) {\n const copiedParts = copyParts(parts);\n const bbox = combineRects(copiedParts.map((part) => part.bbox)) ?? emptyRect();\n const glyphs = (shape.raw.glyphs ?? []).map((glyph, glyphPosition) => {\n const glyphParts = copiedParts.filter(\n (part) => part.glyphPosition === glyphPosition\n );\n\n return {\n ...glyph,\n bbox:\n combineRects(glyphParts.map((part) => part.bbox)) ??\n (glyph.bbox ? { ...glyph.bbox } : emptyRect()),\n partCount: glyphParts.length,\n };\n });\n\n return new PAShape({\n text: shape.text,\n parts: copiedParts,\n contours: [],\n glyphs,\n bbox,\n metrics: {\n ...shape.metrics,\n bbox,\n },\n edgeEpsilon: shape.edgeEpsilon,\n });\n}\n\nfunction createRegionCollection(shape) {\n return shape.parts.map((part) => ({\n outer: copyRing(part.outer),\n holes: part.holes.map((hole) => copyRing(hole)),\n bbox: { ...part.bbox },\n }));\n}\n\nfunction copyParts(parts) {\n return parts.map((part) => copyPart(part));\n}\n\nfunction copyPart(part) {\n return {\n ...part,\n outer: copyRing(part.outer),\n holes: part.holes.map((hole) => copyRing(hole)),\n anchors: part.anchors ? part.anchors.map((point) => [point[0], point[1]]) : undefined,\n bbox: { ...part.bbox },\n };\n}\n\nfunction copyContours(contours) {\n return contours.map((contour) => ({\n ...contour,\n bbox: { ...contour.bbox },\n ring: copyRing(contour.ring),\n }));\n}\n\nfunction extractGlyphText(text, glyphPosition, glyphCount) {\n if (glyphCount <= 1) {\n return text;\n }\n\n const glyphText = Array.from(text ?? \"\")[glyphPosition];\n return glyphText ?? \"\";\n}\n\nfunction normalizePointOptions(options = {}) {\n if (options == null) {\n return {\n step: 8,\n openWidth: 0,\n includeHoles: true,\n };\n }\n\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(\"toPoints() expects an options object.\");\n }\n\n return {\n step: normalizePositive(options.step, 8),\n openWidth: normalizePositive(options.openWidth, 0),\n includeHoles: options.includeHoles !== false,\n };\n}\n\nfunction normalizeShapeOptions(options = {}) {\n if (options == null) {\n return {\n step: 0,\n openWidth: 0,\n };\n }\n\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(\n \"toShape() and toRegions() expect an options object.\",\n );\n }\n\n return {\n step: normalizePositive(options.step, 0),\n openWidth: normalizePositive(options.openWidth, 0),\n };\n}\n\nfunction resolveShapeVariant(shape, options = {}) {\n const normalized = normalizeShapeOptions(options);\n\n if (normalized.step <= 0 && normalized.openWidth <= 0) {\n return shape;\n }\n\n const cacheKey = `${toCacheKey(normalized.step)}:${toCacheKey(normalized.openWidth)}`;\n const cached = shape._cache.shapes.get(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n let next = shape;\n\n if (normalized.openWidth > 0) {\n next = next.openHoles(normalized.openWidth);\n }\n\n if (normalized.step > 0) {\n next = next.resample(normalized.step);\n }\n\n shape._cache.shapes.set(cacheKey, next);\n return next;\n}\n\nfunction toCacheKey(value) {\n return normalizePositive(value, 0).toFixed(6);\n}\n\nfunction resolveGeometryEpsilon(width) {\n return Math.max(1e-4, normalizePositive(width, 1) * 1e-3);\n}\n\nfunction openPartWithSlit(part, width, epsilon) {\n if (!part.holes || part.holes.length === 0) {\n return copyPart(part);\n }\n\n let outer = copyRing(part.outer);\n const holes = part.holes.map((hole) => copyRing(hole));\n const anchors = [];\n\n while (holes.length > 0) {\n let selectedHoleIndex = -1;\n let selectedBridge = null;\n\n holes.forEach((hole, holeIndex) => {\n const blockers = holes.filter((_, index) => index !== holeIndex);\n const candidate = findBestHoleBridge(outer, hole, blockers, epsilon);\n\n if (\n candidate &&\n (!selectedBridge || candidate.distance < selectedBridge.distance)\n ) {\n selectedBridge = candidate;\n selectedHoleIndex = holeIndex;\n }\n });\n\n if (!selectedBridge || selectedHoleIndex === -1) {\n break;\n }\n\n const [hole] = holes.splice(selectedHoleIndex, 1);\n const merged = mergeHoleIntoOuter(outer, hole, selectedBridge, width, epsilon);\n outer = merged.ring;\n anchors.push(...merged.anchors);\n }\n\n return {\n ...part,\n outer,\n holes,\n anchors,\n bbox: ringBounds(outer),\n area:\n Math.abs(signedArea(outer)) -\n holes.reduce((sum, hole) => sum + Math.abs(signedArea(hole)), 0),\n };\n}\n\nfunction resamplePart(part, step) {\n const outer = resampleRing(part.outer, step, part.anchors ?? []);\n const holes = part.holes.map((hole) => resampleRing(hole, step));\n\n return {\n ...part,\n outer,\n holes,\n anchors: part.anchors ? part.anchors.map((point) => [point[0], point[1]]) : undefined,\n bbox: ringBounds(outer),\n area:\n Math.abs(signedArea(outer)) -\n holes.reduce((sum, hole) => sum + Math.abs(signedArea(hole)), 0),\n };\n}\n\nfunction findBestHoleBridge(outer, hole, blockers, epsilon) {\n let best = null;\n\n outer.forEach((outerPoint, outerIndex) => {\n hole.forEach((holePoint, holeIndex) => {\n if (\n !isVisibleBridge(\n outer,\n hole,\n blockers,\n outerPoint,\n holePoint,\n outerIndex,\n holeIndex,\n epsilon\n )\n ) {\n return;\n }\n\n const candidate = {\n outerIndex,\n holeIndex,\n distance: distance(outerPoint, holePoint),\n };\n\n if (!best || candidate.distance < best.distance) {\n best = candidate;\n }\n });\n });\n\n if (best) {\n return best;\n }\n\n return findNearestBridge(outer, hole);\n}\n\nfunction findNearestBridge(outer, hole) {\n let best = null;\n\n outer.forEach((outerPoint, outerIndex) => {\n hole.forEach((holePoint, holeIndex) => {\n const candidate = {\n outerIndex,\n holeIndex,\n distance: distance(outerPoint, holePoint),\n };\n\n if (!best || candidate.distance < best.distance) {\n best = candidate;\n }\n });\n });\n\n return best;\n}\n\nfunction isVisibleBridge(\n outer,\n hole,\n blockers,\n outerPoint,\n holePoint,\n outerIndex,\n holeIndex,\n epsilon\n) {\n if (distance(outerPoint, holePoint) <= epsilon) {\n return false;\n }\n\n const bridgeMidpoint = midpoint(outerPoint, holePoint);\n\n if (!pointInRing(bridgeMidpoint, outer) || pointInRing(bridgeMidpoint, hole)) {\n return false;\n }\n\n if (blockers.some((blocker) => pointInRing(bridgeMidpoint, blocker))) {\n return false;\n }\n\n if (\n segmentIntersectsRing(\n outerPoint,\n holePoint,\n outer,\n new Set([outerIndex, mod(outerIndex - 1, outer.length)]),\n epsilon\n )\n ) {\n return false;\n }\n\n if (\n segmentIntersectsRing(\n outerPoint,\n holePoint,\n hole,\n new Set([holeIndex, mod(holeIndex - 1, hole.length)]),\n epsilon\n )\n ) {\n return false;\n }\n\n return !blockers.some((blocker) =>\n segmentIntersectsRing(outerPoint, holePoint, blocker, new Set(), epsilon)\n );\n}\n\nfunction mergeHoleIntoOuter(outer, hole, bridge, width, epsilon) {\n const slitWidth = clampSlitWidth(width, outer, hole, epsilon);\n const outerCut = createRingCut(outer, bridge.outerIndex, slitWidth, epsilon);\n const holeCut = createRingCut(hole, bridge.holeIndex, slitWidth, epsilon);\n const outerPath = ringPath(\n outerCut.ring,\n outerCut.afterIndex,\n outerCut.beforeIndex\n );\n const holePath = ringPath(\n holeCut.ring,\n holeCut.afterIndex,\n holeCut.beforeIndex\n );\n const merged = [];\n\n appendPath(merged, outerPath, epsilon);\n appendPath(merged, holePath, epsilon);\n\n if (\n merged.length > 1 &&\n pointsAlmostEqual2D(merged[0], merged[merged.length - 1], epsilon)\n ) {\n merged.pop();\n }\n\n return {\n ring: merged,\n anchors: [\n outerCut.ring[outerCut.beforeIndex],\n holeCut.ring[holeCut.beforeIndex],\n holeCut.ring[holeCut.afterIndex],\n outerCut.ring[outerCut.afterIndex],\n ].map((point) => [point[0], point[1]]),\n };\n}\n\nfunction clampSlitWidth(width, outer, hole, epsilon) {\n const minPerimeter = Math.min(ringPerimeter(outer), ringPerimeter(hole));\n return Math.max(\n epsilon * 2,\n Math.min(width, Math.max(minPerimeter * 0.24, epsilon * 2))\n );\n}\n\nfunction createRingCut(ring, anchorIndex, width, epsilon) {\n const beforeCut = moveAlongRing(ring, anchorIndex, -width * 0.5, epsilon);\n const afterCut = moveAlongRing(ring, anchorIndex, width * 0.5, epsilon);\n\n return insertRingCutPoints(ring, beforeCut, afterCut, epsilon);\n}\n\nfunction moveAlongRing(ring, anchorIndex, offset, epsilon) {\n if (!Number.isFinite(offset) || Math.abs(offset) <= epsilon) {\n return {\n point: [ring[anchorIndex][0], ring[anchorIndex][1]],\n vertexIndex: anchorIndex,\n t: 0,\n };\n }\n\n let remaining = Math.abs(offset);\n let currentIndex = anchorIndex;\n const direction = offset > 0 ? 1 : -1;\n\n while (remaining > epsilon) {\n const nextIndex =\n direction > 0 ? (currentIndex + 1) % ring.length : mod(currentIndex - 1, ring.length);\n const segmentIndex = direction > 0 ? currentIndex : nextIndex;\n const segmentStart = ring[segmentIndex];\n const segmentEnd = ring[(segmentIndex + 1) % ring.length];\n const segmentLength = distance(segmentStart, segmentEnd);\n\n if (segmentLength <= epsilon) {\n currentIndex = direction > 0 ? nextIndex : segmentIndex;\n continue;\n }\n\n if (remaining < segmentLength - epsilon) {\n const t = remaining / segmentLength;\n const ratio = direction > 0 ? t : 1 - t;\n return {\n point: [\n segmentStart[0] + (segmentEnd[0] - segmentStart[0]) * ratio,\n segmentStart[1] + (segmentEnd[1] - segmentStart[1]) * ratio,\n ],\n segmentIndex,\n t: ratio,\n };\n }\n\n remaining -= segmentLength;\n currentIndex = direction > 0 ? nextIndex : segmentIndex;\n }\n\n return {\n point: [ring[currentIndex][0], ring[currentIndex][1]],\n vertexIndex: currentIndex,\n t: 0,\n };\n}\n\nfunction insertRingCutPoints(ring, beforeCut, afterCut, epsilon) {\n const cuts = [\n normalizeCutLocation(\"before\", ring, beforeCut, epsilon),\n normalizeCutLocation(\"after\", ring, afterCut, epsilon),\n ];\n const insertsBySegment = new Map();\n const cutIndices = {};\n const augmented = [];\n\n cuts.forEach((cut) => {\n if (cut.vertexIndex != null) {\n return;\n }\n\n const existing = insertsBySegment.get(cut.segmentIndex) ?? [];\n existing.push(cut);\n insertsBySegment.set(cut.segmentIndex, existing);\n });\n\n for (let index = 0; index < ring.length; index += 1) {\n augmented.push([ring[index][0], ring[index][1]]);\n\n cuts.forEach((cut) => {\n if (cut.vertexIndex === index) {\n cutIndices[cut.name] = augmented.length - 1;\n }\n });\n\n const segmentCuts = (insertsBySegment.get(index) ?? []).sort(\n (a, b) => a.t - b.t\n );\n\n segmentCuts.forEach((cut) => {\n augmented.push([cut.point[0], cut.point[1]]);\n cutIndices[cut.name] = augmented.length - 1;\n });\n }\n\n return {\n ring: augmented,\n beforeIndex: cutIndices.before,\n afterIndex: cutIndices.after,\n };\n}\n\nfunction normalizeCutLocation(name, ring, cut, epsilon) {\n if (cut.vertexIndex != null) {\n return {\n ...cut,\n name,\n };\n }\n\n const segmentStart = ring[cut.segmentIndex];\n const segmentEnd = ring[(cut.segmentIndex + 1) % ring.length];\n\n if (distance(cut.point, segmentStart) <= epsilon) {\n return {\n point: [segmentStart[0], segmentStart[1]],\n vertexIndex: cut.segmentIndex,\n t: 0,\n name,\n };\n }\n\n if (distance(cut.point, segmentEnd) <= epsilon) {\n return {\n point: [segmentEnd[0], segmentEnd[1]],\n vertexIndex: (cut.segmentIndex + 1) % ring.length,\n t: 1,\n name,\n };\n }\n\n return {\n ...cut,\n name,\n };\n}\n\nfunction ringPath(ring, startIndex, endIndex) {\n if (startIndex == null || endIndex == null) {\n return copyRing(ring);\n }\n\n const path = [ring[startIndex]];\n let cursor = startIndex;\n\n while (cursor !== endIndex) {\n cursor = (cursor + 1) % ring.length;\n path.push(ring[cursor]);\n }\n\n return path;\n}\n\nfunction appendPath(target, path, epsilon) {\n path.forEach((point) => {\n if (\n target.length === 0 ||\n !pointsAlmostEqual2D(target[target.length - 1], point, epsilon)\n ) {\n target.push([point[0], point[1]]);\n }\n });\n}\n\nfunction resampleRing(ring, step, anchors = []) {\n if (ring.length < 3) {\n return copyRing(ring);\n }\n\n const normalizedAnchors = normalizeAnchorPoints(ring, anchors);\n\n if (normalizedAnchors.length >= 2) {\n return resampleRingWithAnchors(ring, step, normalizedAnchors);\n }\n\n return resampleClosedPath(ring, step);\n}\n\nfunction normalizeAnchorPoints(ring, anchors) {\n const indices = anchors\n .map((anchor) => findRingPointIndex(ring, anchor))\n .filter((index) => index >= 0)\n .sort((a, b) => a - b);\n\n return indices.filter((index, position) => index !== indices[position - 1]);\n}\n\nfunction findRingPointIndex(ring, point, epsilon = 1e-6) {\n for (let index = 0; index < ring.length; index += 1) {\n if (pointsAlmostEqual2D(ring[index], point, epsilon)) {\n return index;\n }\n }\n\n return -1;\n}\n\nfunction resampleRingWithAnchors(ring, step, anchorIndices) {\n const result = [];\n\n for (let index = 0; index < anchorIndices.length; index += 1) {\n const startIndex = anchorIndices[index];\n const endIndex = anchorIndices[(index + 1) % anchorIndices.length];\n const path = ringPath(ring, startIndex, endIndex);\n const sampled = resampleOpenPath(path, step);\n\n appendPath(result, sampled, 1e-6);\n }\n\n if (\n result.length > 1 &&\n pointsAlmostEqual2D(result[0], result[result.length - 1], 1e-6)\n ) {\n result.pop();\n }\n\n if (result.length < 3 || result.length >= ring.length) {\n return copyRing(ring);\n }\n\n return result;\n}\n\nfunction resampleClosedPath(ring, step) {\n const perimeter = ringPerimeter(ring);\n\n if (perimeter <= 1e-9) {\n return copyRing(ring);\n }\n\n const pointCount = Math.max(3, Math.round(perimeter / step));\n\n if (pointCount >= ring.length) {\n return copyRing(ring);\n }\n\n const sampled = [];\n\n for (let index = 0; index < pointCount; index += 1) {\n const point = pointAtClosedPathDistance(ring, (perimeter * index) / pointCount);\n\n if (\n sampled.length === 0 ||\n !pointsAlmostEqual2D(sampled[sampled.length - 1], point, 1e-6)\n ) {\n sampled.push(point);\n }\n }\n\n if (sampled.length < 3 || sampled.length >= ring.length) {\n return copyRing(ring);\n }\n\n return sampled;\n}\n\nfunction resampleOpenPath(path, step) {\n if (path.length <= 2) {\n return path.map((point) => [point[0], point[1]]);\n }\n\n const length = polylineLength(path);\n\n if (length <= step) {\n return [\n [path[0][0], path[0][1]],\n [path[path.length - 1][0], path[path.length - 1][1]],\n ];\n }\n\n const divisionCount = Math.max(1, Math.round(length / step));\n const sampled = [];\n\n for (let index = 0; index <= divisionCount; index += 1) {\n const point = pointAtOpenPathDistance(path, (length * index) / divisionCount);\n\n if (\n sampled.length === 0 ||\n !pointsAlmostEqual2D(sampled[sampled.length - 1], point, 1e-6)\n ) {\n sampled.push(point);\n }\n }\n\n return sampled;\n}\n","// Simplified bidi metadata helper for the rich prepareWithSegments() path,\n// forked from pdf.js via Sebastian's text-layout. It classifies characters\n// into bidi types, computes embedding levels, and maps them onto prepared\n// segments for custom rendering. The line-breaking engine does not consume\n// these levels.\nconst baseTypes = [\n 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'S', 'B', 'S', 'WS',\n 'B', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',\n 'BN', 'BN', 'B', 'B', 'B', 'S', 'WS', 'ON', 'ON', 'ET', 'ET', 'ET', 'ON',\n 'ON', 'ON', 'ON', 'ON', 'ON', 'CS', 'ON', 'CS', 'ON', 'EN', 'EN', 'EN',\n 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'ON', 'ON', 'ON', 'ON', 'ON',\n 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'ON', 'ON',\n 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'ON', 'ON', 'ON', 'ON', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'B', 'BN',\n 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',\n 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',\n 'BN', 'CS', 'ON', 'ET', 'ET', 'ET', 'ET', 'ON', 'ON', 'ON', 'ON', 'L', 'ON',\n 'ON', 'ON', 'ON', 'ON', 'ET', 'ET', 'EN', 'EN', 'ON', 'L', 'ON', 'ON', 'ON',\n 'EN', 'L', 'ON', 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'L', 'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L'\n];\nconst arabicTypes = [\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'CS', 'AL', 'ON', 'ON', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM',\n 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN',\n 'AN', 'ET', 'AN', 'AN', 'AL', 'AL', 'AL', 'NSM', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM',\n 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'ON', 'NSM',\n 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL'\n];\nfunction classifyChar(charCode) {\n if (charCode <= 0x00ff)\n return baseTypes[charCode];\n if (0x0590 <= charCode && charCode <= 0x05f4)\n return 'R';\n if (0x0600 <= charCode && charCode <= 0x06ff)\n return arabicTypes[charCode & 0xff];\n if (0x0700 <= charCode && charCode <= 0x08AC)\n return 'AL';\n return 'L';\n}\nfunction computeBidiLevels(str) {\n const len = str.length;\n if (len === 0)\n return null;\n // eslint-disable-next-line unicorn/no-new-array\n const types = new Array(len);\n let numBidi = 0;\n for (let i = 0; i < len; i++) {\n const t = classifyChar(str.charCodeAt(i));\n if (t === 'R' || t === 'AL' || t === 'AN')\n numBidi++;\n types[i] = t;\n }\n if (numBidi === 0)\n return null;\n const startLevel = (len / numBidi) < 0.3 ? 0 : 1;\n const levels = new Int8Array(len);\n for (let i = 0; i < len; i++)\n levels[i] = startLevel;\n const e = (startLevel & 1) ? 'R' : 'L';\n const sor = e;\n // W1-W7\n let lastType = sor;\n for (let i = 0; i < len; i++) {\n if (types[i] === 'NSM')\n types[i] = lastType;\n else\n lastType = types[i];\n }\n lastType = sor;\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if (t === 'EN')\n types[i] = lastType === 'AL' ? 'AN' : 'EN';\n else if (t === 'R' || t === 'L' || t === 'AL')\n lastType = t;\n }\n for (let i = 0; i < len; i++) {\n if (types[i] === 'AL')\n types[i] = 'R';\n }\n for (let i = 1; i < len - 1; i++) {\n if (types[i] === 'ES' && types[i - 1] === 'EN' && types[i + 1] === 'EN') {\n types[i] = 'EN';\n }\n if (types[i] === 'CS' &&\n (types[i - 1] === 'EN' || types[i - 1] === 'AN') &&\n types[i + 1] === types[i - 1]) {\n types[i] = types[i - 1];\n }\n }\n for (let i = 0; i < len; i++) {\n if (types[i] !== 'EN')\n continue;\n let j;\n for (j = i - 1; j >= 0 && types[j] === 'ET'; j--)\n types[j] = 'EN';\n for (j = i + 1; j < len && types[j] === 'ET'; j++)\n types[j] = 'EN';\n }\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if (t === 'WS' || t === 'ES' || t === 'ET' || t === 'CS')\n types[i] = 'ON';\n }\n lastType = sor;\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if (t === 'EN')\n types[i] = lastType === 'L' ? 'L' : 'EN';\n else if (t === 'R' || t === 'L')\n lastType = t;\n }\n // N1-N2\n for (let i = 0; i < len; i++) {\n if (types[i] !== 'ON')\n continue;\n let end = i + 1;\n while (end < len && types[end] === 'ON')\n end++;\n const before = i > 0 ? types[i - 1] : sor;\n const after = end < len ? types[end] : sor;\n const bDir = before !== 'L' ? 'R' : 'L';\n const aDir = after !== 'L' ? 'R' : 'L';\n if (bDir === aDir) {\n for (let j = i; j < end; j++)\n types[j] = bDir;\n }\n i = end - 1;\n }\n for (let i = 0; i < len; i++) {\n if (types[i] === 'ON')\n types[i] = e;\n }\n // I1-I2\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if ((levels[i] & 1) === 0) {\n if (t === 'R')\n levels[i]++;\n else if (t === 'AN' || t === 'EN')\n levels[i] += 2;\n }\n else if (t === 'L' || t === 'AN' || t === 'EN') {\n levels[i]++;\n }\n }\n return levels;\n}\nexport function computeSegmentLevels(normalized, segStarts) {\n const bidiLevels = computeBidiLevels(normalized);\n if (bidiLevels === null)\n return null;\n const segLevels = new Int8Array(segStarts.length);\n for (let i = 0; i < segStarts.length; i++) {\n segLevels[i] = bidiLevels[segStarts[i]];\n }\n return segLevels;\n}\n","const collapsibleWhitespaceRunRe = /[ \\t\\n\\r\\f]+/g;\nconst needsWhitespaceNormalizationRe = /[\\t\\n\\r\\f]| {2,}|^ | $/;\nfunction getWhiteSpaceProfile(whiteSpace) {\n const mode = whiteSpace ?? 'normal';\n return mode === 'pre-wrap'\n ? { mode, preserveOrdinarySpaces: true, preserveHardBreaks: true }\n : { mode, preserveOrdinarySpaces: false, preserveHardBreaks: false };\n}\nexport function normalizeWhitespaceNormal(text) {\n if (!needsWhitespaceNormalizationRe.test(text))\n return text;\n let normalized = text.replace(collapsibleWhitespaceRunRe, ' ');\n if (normalized.charCodeAt(0) === 0x20) {\n normalized = normalized.slice(1);\n }\n if (normalized.length > 0 && normalized.charCodeAt(normalized.length - 1) === 0x20) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\nfunction normalizeWhitespacePreWrap(text) {\n if (!/[\\r\\f]/.test(text))\n return text.replace(/\\r\\n/g, '\\n');\n return text\n .replace(/\\r\\n/g, '\\n')\n .replace(/[\\r\\f]/g, '\\n');\n}\nlet sharedWordSegmenter = null;\nlet segmenterLocale;\nfunction getSharedWordSegmenter() {\n if (sharedWordSegmenter === null) {\n sharedWordSegmenter = new Intl.Segmenter(segmenterLocale, { granularity: 'word' });\n }\n return sharedWordSegmenter;\n}\nexport function clearAnalysisCaches() {\n sharedWordSegmenter = null;\n}\nexport function setAnalysisLocale(locale) {\n const nextLocale = locale && locale.length > 0 ? locale : undefined;\n if (segmenterLocale === nextLocale)\n return;\n segmenterLocale = nextLocale;\n sharedWordSegmenter = null;\n}\nconst arabicScriptRe = /\\p{Script=Arabic}/u;\nconst combiningMarkRe = /\\p{M}/u;\nconst decimalDigitRe = /\\p{Nd}/u;\nfunction containsArabicScript(text) {\n return arabicScriptRe.test(text);\n}\nexport function isCJK(s) {\n for (const ch of s) {\n const c = ch.codePointAt(0);\n if ((c >= 0x4E00 && c <= 0x9FFF) ||\n (c >= 0x3400 && c <= 0x4DBF) ||\n (c >= 0x20000 && c <= 0x2A6DF) ||\n (c >= 0x2A700 && c <= 0x2B73F) ||\n (c >= 0x2B740 && c <= 0x2B81F) ||\n (c >= 0x2B820 && c <= 0x2CEAF) ||\n (c >= 0x2CEB0 && c <= 0x2EBEF) ||\n (c >= 0x30000 && c <= 0x3134F) ||\n (c >= 0xF900 && c <= 0xFAFF) ||\n (c >= 0x2F800 && c <= 0x2FA1F) ||\n (c >= 0x3000 && c <= 0x303F) ||\n (c >= 0x3040 && c <= 0x309F) ||\n (c >= 0x30A0 && c <= 0x30FF) ||\n (c >= 0xAC00 && c <= 0xD7AF) ||\n (c >= 0xFF00 && c <= 0xFFEF)) {\n return true;\n }\n }\n return false;\n}\nexport const kinsokuStart = new Set([\n '\\uFF0C',\n '\\uFF0E',\n '\\uFF01',\n '\\uFF1A',\n '\\uFF1B',\n '\\uFF1F',\n '\\u3001',\n '\\u3002',\n '\\u30FB',\n '\\uFF09',\n '\\u3015',\n '\\u3009',\n '\\u300B',\n '\\u300D',\n '\\u300F',\n '\\u3011',\n '\\u3017',\n '\\u3019',\n '\\u301B',\n '\\u30FC',\n '\\u3005',\n '\\u303B',\n '\\u309D',\n '\\u309E',\n '\\u30FD',\n '\\u30FE',\n]);\nexport const kinsokuEnd = new Set([\n '\"',\n '(', '[', '{',\n '“', '‘', '«', '‹',\n '\\uFF08',\n '\\u3014',\n '\\u3008',\n '\\u300A',\n '\\u300C',\n '\\u300E',\n '\\u3010',\n '\\u3016',\n '\\u3018',\n '\\u301A',\n]);\nconst forwardStickyGlue = new Set([\n \"'\", '’',\n]);\nexport const leftStickyPunctuation = new Set([\n '.', ',', '!', '?', ':', ';',\n '\\u060C',\n '\\u061B',\n '\\u061F',\n '\\u0964',\n '\\u0965',\n '\\u104A',\n '\\u104B',\n '\\u104C',\n '\\u104D',\n '\\u104F',\n ')', ']', '}',\n '%',\n '\"',\n '”', '’', '»', '›',\n '…',\n]);\nconst arabicNoSpaceTrailingPunctuation = new Set([\n ':',\n '.',\n '\\u060C',\n '\\u061B',\n]);\nconst myanmarMedialGlue = new Set([\n '\\u104F',\n]);\nconst closingQuoteChars = new Set([\n '”', '’', '»', '›',\n '\\u300D',\n '\\u300F',\n '\\u3011',\n '\\u300B',\n '\\u3009',\n '\\u3015',\n '\\uFF09',\n]);\nfunction isLeftStickyPunctuationSegment(segment) {\n if (isEscapedQuoteClusterSegment(segment))\n return true;\n let sawPunctuation = false;\n for (const ch of segment) {\n if (leftStickyPunctuation.has(ch)) {\n sawPunctuation = true;\n continue;\n }\n if (sawPunctuation && combiningMarkRe.test(ch))\n continue;\n return false;\n }\n return sawPunctuation;\n}\nfunction isCJKLineStartProhibitedSegment(segment) {\n for (const ch of segment) {\n if (!kinsokuStart.has(ch) && !leftStickyPunctuation.has(ch))\n return false;\n }\n return segment.length > 0;\n}\nfunction isForwardStickyClusterSegment(segment) {\n if (isEscapedQuoteClusterSegment(segment))\n return true;\n for (const ch of segment) {\n if (!kinsokuEnd.has(ch) && !forwardStickyGlue.has(ch) && !combiningMarkRe.test(ch))\n return false;\n }\n return segment.length > 0;\n}\nfunction isEscapedQuoteClusterSegment(segment) {\n let sawQuote = false;\n for (const ch of segment) {\n if (ch === '\\\\' || combiningMarkRe.test(ch))\n continue;\n if (kinsokuEnd.has(ch) || leftStickyPunctuation.has(ch) || forwardStickyGlue.has(ch)) {\n sawQuote = true;\n continue;\n }\n return false;\n }\n return sawQuote;\n}\nfunction splitTrailingForwardStickyCluster(text) {\n const chars = Array.from(text);\n let splitIndex = chars.length;\n while (splitIndex > 0) {\n const ch = chars[splitIndex - 1];\n if (combiningMarkRe.test(ch)) {\n splitIndex--;\n continue;\n }\n if (kinsokuEnd.has(ch) || forwardStickyGlue.has(ch)) {\n splitIndex--;\n continue;\n }\n break;\n }\n if (splitIndex <= 0 || splitIndex === chars.length)\n return null;\n return {\n head: chars.slice(0, splitIndex).join(''),\n tail: chars.slice(splitIndex).join(''),\n };\n}\nfunction isRepeatedSingleCharRun(segment, ch) {\n if (segment.length === 0)\n return false;\n for (const part of segment) {\n if (part !== ch)\n return false;\n }\n return true;\n}\nfunction endsWithArabicNoSpacePunctuation(segment) {\n if (!containsArabicScript(segment) || segment.length === 0)\n return false;\n return arabicNoSpaceTrailingPunctuation.has(segment[segment.length - 1]);\n}\nfunction endsWithMyanmarMedialGlue(segment) {\n if (segment.length === 0)\n return false;\n return myanmarMedialGlue.has(segment[segment.length - 1]);\n}\nfunction splitLeadingSpaceAndMarks(segment) {\n if (segment.length < 2 || segment[0] !== ' ')\n return null;\n const marks = segment.slice(1);\n if (/^\\p{M}+$/u.test(marks)) {\n return { space: ' ', marks };\n }\n return null;\n}\nexport function endsWithClosingQuote(text) {\n for (let i = text.length - 1; i >= 0; i--) {\n const ch = text[i];\n if (closingQuoteChars.has(ch))\n return true;\n if (!leftStickyPunctuation.has(ch))\n return false;\n }\n return false;\n}\nfunction classifySegmentBreakChar(ch, whiteSpaceProfile) {\n if (whiteSpaceProfile.preserveOrdinarySpaces || whiteSpaceProfile.preserveHardBreaks) {\n if (ch === ' ')\n return 'preserved-space';\n if (ch === '\\t')\n return 'tab';\n if (whiteSpaceProfile.preserveHardBreaks && ch === '\\n')\n return 'hard-break';\n }\n if (ch === ' ')\n return 'space';\n if (ch === '\\u00A0' || ch === '\\u202F' || ch === '\\u2060' || ch === '\\uFEFF') {\n return 'glue';\n }\n if (ch === '\\u200B')\n return 'zero-width-break';\n if (ch === '\\u00AD')\n return 'soft-hyphen';\n return 'text';\n}\nfunction joinTextParts(parts) {\n return parts.length === 1 ? parts[0] : parts.join('');\n}\nfunction splitSegmentByBreakKind(segment, isWordLike, start, whiteSpaceProfile) {\n const pieces = [];\n let currentKind = null;\n let currentTextParts = [];\n let currentStart = start;\n let currentWordLike = false;\n let offset = 0;\n for (const ch of segment) {\n const kind = classifySegmentBreakChar(ch, whiteSpaceProfile);\n const wordLike = kind === 'text' && isWordLike;\n if (currentKind !== null && kind === currentKind && wordLike === currentWordLike) {\n currentTextParts.push(ch);\n offset += ch.length;\n continue;\n }\n if (currentKind !== null) {\n pieces.push({\n text: joinTextParts(currentTextParts),\n isWordLike: currentWordLike,\n kind: currentKind,\n start: currentStart,\n });\n }\n currentKind = kind;\n currentTextParts = [ch];\n currentStart = start + offset;\n currentWordLike = wordLike;\n offset += ch.length;\n }\n if (currentKind !== null) {\n pieces.push({\n text: joinTextParts(currentTextParts),\n isWordLike: currentWordLike,\n kind: currentKind,\n start: currentStart,\n });\n }\n return pieces;\n}\nfunction isTextRunBoundary(kind) {\n return (kind === 'space' ||\n kind === 'preserved-space' ||\n kind === 'zero-width-break' ||\n kind === 'hard-break');\n}\nconst urlSchemeSegmentRe = /^[A-Za-z][A-Za-z0-9+.-]*:$/;\nfunction isUrlLikeRunStart(segmentation, index) {\n const text = segmentation.texts[index];\n if (text.startsWith('www.'))\n return true;\n return (urlSchemeSegmentRe.test(text) &&\n index + 1 < segmentation.len &&\n segmentation.kinds[index + 1] === 'text' &&\n segmentation.texts[index + 1] === '//');\n}\nfunction isUrlQueryBoundarySegment(text) {\n return text.includes('?') && (text.includes('://') || text.startsWith('www.'));\n}\nfunction mergeUrlLikeRuns(segmentation) {\n const texts = segmentation.texts.slice();\n const isWordLike = segmentation.isWordLike.slice();\n const kinds = segmentation.kinds.slice();\n const starts = segmentation.starts.slice();\n for (let i = 0; i < segmentation.len; i++) {\n if (kinds[i] !== 'text' || !isUrlLikeRunStart(segmentation, i))\n continue;\n const mergedParts = [texts[i]];\n let j = i + 1;\n while (j < segmentation.len && !isTextRunBoundary(kinds[j])) {\n mergedParts.push(texts[j]);\n isWordLike[i] = true;\n const endsQueryPrefix = texts[j].includes('?');\n kinds[j] = 'text';\n texts[j] = '';\n j++;\n if (endsQueryPrefix)\n break;\n }\n texts[i] = joinTextParts(mergedParts);\n }\n let compactLen = 0;\n for (let read = 0; read < texts.length; read++) {\n const text = texts[read];\n if (text.length === 0)\n continue;\n if (compactLen !== read) {\n texts[compactLen] = text;\n isWordLike[compactLen] = isWordLike[read];\n kinds[compactLen] = kinds[read];\n starts[compactLen] = starts[read];\n }\n compactLen++;\n }\n texts.length = compactLen;\n isWordLike.length = compactLen;\n kinds.length = compactLen;\n starts.length = compactLen;\n return {\n len: compactLen,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction mergeUrlQueryRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n texts.push(text);\n isWordLike.push(segmentation.isWordLike[i]);\n kinds.push(segmentation.kinds[i]);\n starts.push(segmentation.starts[i]);\n if (!isUrlQueryBoundarySegment(text))\n continue;\n const nextIndex = i + 1;\n if (nextIndex >= segmentation.len ||\n isTextRunBoundary(segmentation.kinds[nextIndex])) {\n continue;\n }\n const queryParts = [];\n const queryStart = segmentation.starts[nextIndex];\n let j = nextIndex;\n while (j < segmentation.len && !isTextRunBoundary(segmentation.kinds[j])) {\n queryParts.push(segmentation.texts[j]);\n j++;\n }\n if (queryParts.length > 0) {\n texts.push(joinTextParts(queryParts));\n isWordLike.push(true);\n kinds.push('text');\n starts.push(queryStart);\n i = j - 1;\n }\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nconst numericJoinerChars = new Set([\n ':', '-', '/', '×', ',', '.', '+',\n '\\u2013',\n '\\u2014',\n]);\nconst asciiPunctuationChainSegmentRe = /^[A-Za-z0-9_]+[,:;]*$/;\nconst asciiPunctuationChainTrailingJoinersRe = /[,:;]+$/;\nfunction segmentContainsDecimalDigit(text) {\n for (const ch of text) {\n if (decimalDigitRe.test(ch))\n return true;\n }\n return false;\n}\nfunction isNumericRunSegment(text) {\n if (text.length === 0)\n return false;\n for (const ch of text) {\n if (decimalDigitRe.test(ch) || numericJoinerChars.has(ch))\n continue;\n return false;\n }\n return true;\n}\nfunction mergeNumericRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n const kind = segmentation.kinds[i];\n if (kind === 'text' && isNumericRunSegment(text) && segmentContainsDecimalDigit(text)) {\n const mergedParts = [text];\n let j = i + 1;\n while (j < segmentation.len &&\n segmentation.kinds[j] === 'text' &&\n isNumericRunSegment(segmentation.texts[j])) {\n mergedParts.push(segmentation.texts[j]);\n j++;\n }\n texts.push(joinTextParts(mergedParts));\n isWordLike.push(true);\n kinds.push('text');\n starts.push(segmentation.starts[i]);\n i = j - 1;\n continue;\n }\n texts.push(text);\n isWordLike.push(segmentation.isWordLike[i]);\n kinds.push(kind);\n starts.push(segmentation.starts[i]);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction mergeAsciiPunctuationChains(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n const kind = segmentation.kinds[i];\n const wordLike = segmentation.isWordLike[i];\n if (kind === 'text' && wordLike && asciiPunctuationChainSegmentRe.test(text)) {\n const mergedParts = [text];\n let endsWithJoiners = asciiPunctuationChainTrailingJoinersRe.test(text);\n let j = i + 1;\n while (endsWithJoiners &&\n j < segmentation.len &&\n segmentation.kinds[j] === 'text' &&\n segmentation.isWordLike[j] &&\n asciiPunctuationChainSegmentRe.test(segmentation.texts[j])) {\n const nextText = segmentation.texts[j];\n mergedParts.push(nextText);\n endsWithJoiners = asciiPunctuationChainTrailingJoinersRe.test(nextText);\n j++;\n }\n texts.push(joinTextParts(mergedParts));\n isWordLike.push(true);\n kinds.push('text');\n starts.push(segmentation.starts[i]);\n i = j - 1;\n continue;\n }\n texts.push(text);\n isWordLike.push(wordLike);\n kinds.push(kind);\n starts.push(segmentation.starts[i]);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction splitHyphenatedNumericRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n if (segmentation.kinds[i] === 'text' && text.includes('-')) {\n const parts = text.split('-');\n let shouldSplit = parts.length > 1;\n for (let j = 0; j < parts.length; j++) {\n const part = parts[j];\n if (!shouldSplit)\n break;\n if (part.length === 0 ||\n !segmentContainsDecimalDigit(part) ||\n !isNumericRunSegment(part)) {\n shouldSplit = false;\n }\n }\n if (shouldSplit) {\n let offset = 0;\n for (let j = 0; j < parts.length; j++) {\n const part = parts[j];\n const splitText = j < parts.length - 1 ? `${part}-` : part;\n texts.push(splitText);\n isWordLike.push(true);\n kinds.push('text');\n starts.push(segmentation.starts[i] + offset);\n offset += splitText.length;\n }\n continue;\n }\n }\n texts.push(text);\n isWordLike.push(segmentation.isWordLike[i]);\n kinds.push(segmentation.kinds[i]);\n starts.push(segmentation.starts[i]);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction mergeGlueConnectedTextRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n let read = 0;\n while (read < segmentation.len) {\n const textParts = [segmentation.texts[read]];\n let wordLike = segmentation.isWordLike[read];\n let kind = segmentation.kinds[read];\n let start = segmentation.starts[read];\n if (kind === 'glue') {\n const glueParts = [textParts[0]];\n const glueStart = start;\n read++;\n while (read < segmentation.len && segmentation.kinds[read] === 'glue') {\n glueParts.push(segmentation.texts[read]);\n read++;\n }\n const glueText = joinTextParts(glueParts);\n if (read < segmentation.len && segmentation.kinds[read] === 'text') {\n textParts[0] = glueText;\n textParts.push(segmentation.texts[read]);\n wordLike = segmentation.isWordLike[read];\n kind = 'text';\n start = glueStart;\n read++;\n }\n else {\n texts.push(glueText);\n isWordLike.push(false);\n kinds.push('glue');\n starts.push(glueStart);\n continue;\n }\n }\n else {\n read++;\n }\n if (kind === 'text') {\n while (read < segmentation.len && segmentation.kinds[read] === 'glue') {\n const glueParts = [];\n while (read < segmentation.len && segmentation.kinds[read] === 'glue') {\n glueParts.push(segmentation.texts[read]);\n read++;\n }\n const glueText = joinTextParts(glueParts);\n if (read < segmentation.len && segmentation.kinds[read] === 'text') {\n textParts.push(glueText, segmentation.texts[read]);\n wordLike = wordLike || segmentation.isWordLike[read];\n read++;\n continue;\n }\n textParts.push(glueText);\n }\n }\n texts.push(joinTextParts(textParts));\n isWordLike.push(wordLike);\n kinds.push(kind);\n starts.push(start);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction carryTrailingForwardStickyAcrossCJKBoundary(segmentation) {\n const texts = segmentation.texts.slice();\n const isWordLike = segmentation.isWordLike.slice();\n const kinds = segmentation.kinds.slice();\n const starts = segmentation.starts.slice();\n for (let i = 0; i < texts.length - 1; i++) {\n if (kinds[i] !== 'text' || kinds[i + 1] !== 'text')\n continue;\n if (!isCJK(texts[i]) || !isCJK(texts[i + 1]))\n continue;\n const split = splitTrailingForwardStickyCluster(texts[i]);\n if (split === null)\n continue;\n texts[i] = split.head;\n texts[i + 1] = split.tail + texts[i + 1];\n starts[i + 1] = starts[i] + split.head.length;\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction buildMergedSegmentation(normalized, profile, whiteSpaceProfile) {\n const wordSegmenter = getSharedWordSegmenter();\n let mergedLen = 0;\n const mergedTexts = [];\n const mergedWordLike = [];\n const mergedKinds = [];\n const mergedStarts = [];\n for (const s of wordSegmenter.segment(normalized)) {\n for (const piece of splitSegmentByBreakKind(s.segment, s.isWordLike ?? false, s.index, whiteSpaceProfile)) {\n const isText = piece.kind === 'text';\n if (profile.carryCJKAfterClosingQuote &&\n isText &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n isCJK(piece.text) &&\n isCJK(mergedTexts[mergedLen - 1]) &&\n endsWithClosingQuote(mergedTexts[mergedLen - 1])) {\n mergedTexts[mergedLen - 1] += piece.text;\n mergedWordLike[mergedLen - 1] = mergedWordLike[mergedLen - 1] || piece.isWordLike;\n }\n else if (isText &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n isCJKLineStartProhibitedSegment(piece.text) &&\n isCJK(mergedTexts[mergedLen - 1])) {\n mergedTexts[mergedLen - 1] += piece.text;\n mergedWordLike[mergedLen - 1] = mergedWordLike[mergedLen - 1] || piece.isWordLike;\n }\n else if (isText &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n endsWithMyanmarMedialGlue(mergedTexts[mergedLen - 1])) {\n mergedTexts[mergedLen - 1] += piece.text;\n mergedWordLike[mergedLen - 1] = mergedWordLike[mergedLen - 1] || piece.isWordLike;\n }\n else if (isText &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n piece.isWordLike &&\n containsArabicScript(piece.text) &&\n endsWithArabicNoSpacePunctuation(mergedTexts[mergedLen - 1])) {\n mergedTexts[mergedLen - 1] += piece.text;\n mergedWordLike[mergedLen - 1] = true;\n }\n else if (isText &&\n !piece.isWordLike &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n piece.text.length === 1 &&\n piece.text !== '-' &&\n piece.text !== '—' &&\n isRepeatedSingleCharRun(mergedTexts[mergedLen - 1], piece.text)) {\n mergedTexts[mergedLen - 1] += piece.text;\n }\n else if (isText &&\n !piece.isWordLike &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n (isLeftStickyPunctuationSegment(piece.text) ||\n (piece.text === '-' && mergedWordLike[mergedLen - 1]))) {\n mergedTexts[mergedLen - 1] += piece.text;\n }\n else {\n mergedTexts[mergedLen] = piece.text;\n mergedWordLike[mergedLen] = piece.isWordLike;\n mergedKinds[mergedLen] = piece.kind;\n mergedStarts[mergedLen] = piece.start;\n mergedLen++;\n }\n }\n }\n for (let i = 1; i < mergedLen; i++) {\n if (mergedKinds[i] === 'text' &&\n !mergedWordLike[i] &&\n isEscapedQuoteClusterSegment(mergedTexts[i]) &&\n mergedKinds[i - 1] === 'text') {\n mergedTexts[i - 1] += mergedTexts[i];\n mergedWordLike[i - 1] = mergedWordLike[i - 1] || mergedWordLike[i];\n mergedTexts[i] = '';\n }\n }\n for (let i = mergedLen - 2; i >= 0; i--) {\n if (mergedKinds[i] === 'text' && !mergedWordLike[i] && isForwardStickyClusterSegment(mergedTexts[i])) {\n let j = i + 1;\n while (j < mergedLen && mergedTexts[j] === '')\n j++;\n if (j < mergedLen && mergedKinds[j] === 'text') {\n mergedTexts[j] = mergedTexts[i] + mergedTexts[j];\n mergedStarts[j] = mergedStarts[i];\n mergedTexts[i] = '';\n }\n }\n }\n let compactLen = 0;\n for (let read = 0; read < mergedLen; read++) {\n const text = mergedTexts[read];\n if (text.length === 0)\n continue;\n if (compactLen !== read) {\n mergedTexts[compactLen] = text;\n mergedWordLike[compactLen] = mergedWordLike[read];\n mergedKinds[compactLen] = mergedKinds[read];\n mergedStarts[compactLen] = mergedStarts[read];\n }\n compactLen++;\n }\n mergedTexts.length = compactLen;\n mergedWordLike.length = compactLen;\n mergedKinds.length = compactLen;\n mergedStarts.length = compactLen;\n const compacted = mergeGlueConnectedTextRuns({\n len: compactLen,\n texts: mergedTexts,\n isWordLike: mergedWordLike,\n kinds: mergedKinds,\n starts: mergedStarts,\n });\n const withMergedUrls = carryTrailingForwardStickyAcrossCJKBoundary(mergeAsciiPunctuationChains(splitHyphenatedNumericRuns(mergeNumericRuns(mergeUrlQueryRuns(mergeUrlLikeRuns(compacted))))));\n for (let i = 0; i < withMergedUrls.len - 1; i++) {\n const split = splitLeadingSpaceAndMarks(withMergedUrls.texts[i]);\n if (split === null)\n continue;\n if ((withMergedUrls.kinds[i] !== 'space' && withMergedUrls.kinds[i] !== 'preserved-space') ||\n withMergedUrls.kinds[i + 1] !== 'text' ||\n !containsArabicScript(withMergedUrls.texts[i + 1])) {\n continue;\n }\n withMergedUrls.texts[i] = split.space;\n withMergedUrls.isWordLike[i] = false;\n withMergedUrls.kinds[i] = withMergedUrls.kinds[i] === 'preserved-space' ? 'preserved-space' : 'space';\n withMergedUrls.texts[i + 1] = split.marks + withMergedUrls.texts[i + 1];\n withMergedUrls.starts[i + 1] = withMergedUrls.starts[i] + split.space.length;\n }\n return withMergedUrls;\n}\nfunction compileAnalysisChunks(segmentation, whiteSpaceProfile) {\n if (segmentation.len === 0)\n return [];\n if (!whiteSpaceProfile.preserveHardBreaks) {\n return [{\n startSegmentIndex: 0,\n endSegmentIndex: segmentation.len,\n consumedEndSegmentIndex: segmentation.len,\n }];\n }\n const chunks = [];\n let startSegmentIndex = 0;\n for (let i = 0; i < segmentation.len; i++) {\n if (segmentation.kinds[i] !== 'hard-break')\n continue;\n chunks.push({\n startSegmentIndex,\n endSegmentIndex: i,\n consumedEndSegmentIndex: i + 1,\n });\n startSegmentIndex = i + 1;\n }\n if (startSegmentIndex < segmentation.len) {\n chunks.push({\n startSegmentIndex,\n endSegmentIndex: segmentation.len,\n consumedEndSegmentIndex: segmentation.len,\n });\n }\n return chunks;\n}\nexport function analyzeText(text, profile, whiteSpace = 'normal') {\n const whiteSpaceProfile = getWhiteSpaceProfile(whiteSpace);\n const normalized = whiteSpaceProfile.mode === 'pre-wrap'\n ? normalizeWhitespacePreWrap(text)\n : normalizeWhitespaceNormal(text);\n if (normalized.length === 0) {\n return {\n normalized,\n chunks: [],\n len: 0,\n texts: [],\n isWordLike: [],\n kinds: [],\n starts: [],\n };\n }\n const segmentation = buildMergedSegmentation(normalized, profile, whiteSpaceProfile);\n return {\n normalized,\n chunks: compileAnalysisChunks(segmentation, whiteSpaceProfile),\n ...segmentation,\n };\n}\n","import { isCJK } from './analysis.js';\nlet measureContext = null;\nconst segmentMetricCaches = new Map();\nlet cachedEngineProfile = null;\nconst emojiPresentationRe = /\\p{Emoji_Presentation}/u;\nconst maybeEmojiRe = /[\\p{Emoji_Presentation}\\p{Extended_Pictographic}\\p{Regional_Indicator}\\uFE0F\\u20E3]/u;\nlet sharedGraphemeSegmenter = null;\nconst emojiCorrectionCache = new Map();\nexport function getMeasureContext() {\n if (measureContext !== null)\n return measureContext;\n if (typeof OffscreenCanvas !== 'undefined') {\n measureContext = new OffscreenCanvas(1, 1).getContext('2d');\n return measureContext;\n }\n if (typeof document !== 'undefined') {\n measureContext = document.createElement('canvas').getContext('2d');\n return measureContext;\n }\n throw new Error('Text measurement requires OffscreenCanvas or a DOM canvas context.');\n}\nexport function getSegmentMetricCache(font) {\n let cache = segmentMetricCaches.get(font);\n if (!cache) {\n cache = new Map();\n segmentMetricCaches.set(font, cache);\n }\n return cache;\n}\nexport function getSegmentMetrics(seg, cache) {\n let metrics = cache.get(seg);\n if (metrics === undefined) {\n const ctx = getMeasureContext();\n metrics = {\n width: ctx.measureText(seg).width,\n containsCJK: isCJK(seg),\n };\n cache.set(seg, metrics);\n }\n return metrics;\n}\nexport function getEngineProfile() {\n if (cachedEngineProfile !== null)\n return cachedEngineProfile;\n if (typeof navigator === 'undefined') {\n cachedEngineProfile = {\n lineFitEpsilon: 0.005,\n carryCJKAfterClosingQuote: false,\n preferPrefixWidthsForBreakableRuns: false,\n preferEarlySoftHyphenBreak: false,\n };\n return cachedEngineProfile;\n }\n const ua = navigator.userAgent;\n const vendor = navigator.vendor;\n const isSafari = vendor === 'Apple Computer, Inc.' &&\n ua.includes('Safari/') &&\n !ua.includes('Chrome/') &&\n !ua.includes('Chromium/') &&\n !ua.includes('CriOS/') &&\n !ua.includes('FxiOS/') &&\n !ua.includes('EdgiOS/');\n const isChromium = ua.includes('Chrome/') ||\n ua.includes('Chromium/') ||\n ua.includes('CriOS/') ||\n ua.includes('Edg/');\n cachedEngineProfile = {\n lineFitEpsilon: isSafari ? 1 / 64 : 0.005,\n carryCJKAfterClosingQuote: isChromium,\n preferPrefixWidthsForBreakableRuns: isSafari,\n preferEarlySoftHyphenBreak: isSafari,\n };\n return cachedEngineProfile;\n}\nexport function parseFontSize(font) {\n const m = font.match(/(\\d+(?:\\.\\d+)?)\\s*px/);\n return m ? parseFloat(m[1]) : 16;\n}\nfunction getSharedGraphemeSegmenter() {\n if (sharedGraphemeSegmenter === null) {\n sharedGraphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\n }\n return sharedGraphemeSegmenter;\n}\nfunction isEmojiGrapheme(g) {\n return emojiPresentationRe.test(g) || g.includes('\\uFE0F');\n}\nexport function textMayContainEmoji(text) {\n return maybeEmojiRe.test(text);\n}\nfunction getEmojiCorrection(font, fontSize) {\n let correction = emojiCorrectionCache.get(font);\n if (correction !== undefined)\n return correction;\n const ctx = getMeasureContext();\n ctx.font = font;\n const canvasW = ctx.measureText('\\u{1F600}').width;\n correction = 0;\n if (canvasW > fontSize + 0.5 &&\n typeof document !== 'undefined' &&\n document.body !== null) {\n const span = document.createElement('span');\n span.style.font = font;\n span.style.display = 'inline-block';\n span.style.visibility = 'hidden';\n span.style.position = 'absolute';\n span.textContent = '\\u{1F600}';\n document.body.appendChild(span);\n const domW = span.getBoundingClientRect().width;\n document.body.removeChild(span);\n if (canvasW - domW > 0.5) {\n correction = canvasW - domW;\n }\n }\n emojiCorrectionCache.set(font, correction);\n return correction;\n}\nfunction countEmojiGraphemes(text) {\n let count = 0;\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n for (const g of graphemeSegmenter.segment(text)) {\n if (isEmojiGrapheme(g.segment))\n count++;\n }\n return count;\n}\nfunction getEmojiCount(seg, metrics) {\n if (metrics.emojiCount === undefined) {\n metrics.emojiCount = countEmojiGraphemes(seg);\n }\n return metrics.emojiCount;\n}\nexport function getCorrectedSegmentWidth(seg, metrics, emojiCorrection) {\n if (emojiCorrection === 0)\n return metrics.width;\n return metrics.width - getEmojiCount(seg, metrics) * emojiCorrection;\n}\nexport function getSegmentGraphemeWidths(seg, metrics, cache, emojiCorrection) {\n if (metrics.graphemeWidths !== undefined)\n return metrics.graphemeWidths;\n const widths = [];\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n for (const gs of graphemeSegmenter.segment(seg)) {\n const graphemeMetrics = getSegmentMetrics(gs.segment, cache);\n widths.push(getCorrectedSegmentWidth(gs.segment, graphemeMetrics, emojiCorrection));\n }\n metrics.graphemeWidths = widths.length > 1 ? widths : null;\n return metrics.graphemeWidths;\n}\nexport function getSegmentGraphemePrefixWidths(seg, metrics, cache, emojiCorrection) {\n if (metrics.graphemePrefixWidths !== undefined)\n return metrics.graphemePrefixWidths;\n const prefixWidths = [];\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n let prefix = '';\n for (const gs of graphemeSegmenter.segment(seg)) {\n prefix += gs.segment;\n const prefixMetrics = getSegmentMetrics(prefix, cache);\n prefixWidths.push(getCorrectedSegmentWidth(prefix, prefixMetrics, emojiCorrection));\n }\n metrics.graphemePrefixWidths = prefixWidths.length > 1 ? prefixWidths : null;\n return metrics.graphemePrefixWidths;\n}\nexport function getFontMeasurementState(font, needsEmojiCorrection) {\n const ctx = getMeasureContext();\n ctx.font = font;\n const cache = getSegmentMetricCache(font);\n const fontSize = parseFontSize(font);\n const emojiCorrection = needsEmojiCorrection ? getEmojiCorrection(font, fontSize) : 0;\n return { cache, fontSize, emojiCorrection };\n}\nexport function clearMeasurementCaches() {\n segmentMetricCaches.clear();\n emojiCorrectionCache.clear();\n sharedGraphemeSegmenter = null;\n}\n","import { getEngineProfile } from './measurement.js';\nfunction canBreakAfter(kind) {\n return (kind === 'space' ||\n kind === 'preserved-space' ||\n kind === 'tab' ||\n kind === 'zero-width-break' ||\n kind === 'soft-hyphen');\n}\nfunction normalizeSimpleLineStartSegmentIndex(prepared, segmentIndex) {\n while (segmentIndex < prepared.widths.length) {\n const kind = prepared.kinds[segmentIndex];\n if (kind !== 'space' && kind !== 'zero-width-break' && kind !== 'soft-hyphen')\n break;\n segmentIndex++;\n }\n return segmentIndex;\n}\nfunction getTabAdvance(lineWidth, tabStopAdvance) {\n if (tabStopAdvance <= 0)\n return 0;\n const remainder = lineWidth % tabStopAdvance;\n if (Math.abs(remainder) <= 1e-6)\n return tabStopAdvance;\n return tabStopAdvance - remainder;\n}\nfunction getBreakableAdvance(graphemeWidths, graphemePrefixWidths, graphemeIndex, preferPrefixWidths) {\n if (!preferPrefixWidths || graphemePrefixWidths === null) {\n return graphemeWidths[graphemeIndex];\n }\n return graphemePrefixWidths[graphemeIndex] - (graphemeIndex > 0 ? graphemePrefixWidths[graphemeIndex - 1] : 0);\n}\nfunction fitSoftHyphenBreak(graphemeWidths, initialWidth, maxWidth, lineFitEpsilon, discretionaryHyphenWidth, cumulativeWidths) {\n let fitCount = 0;\n let fittedWidth = initialWidth;\n while (fitCount < graphemeWidths.length) {\n const nextWidth = cumulativeWidths\n ? initialWidth + graphemeWidths[fitCount]\n : fittedWidth + graphemeWidths[fitCount];\n const nextLineWidth = fitCount + 1 < graphemeWidths.length\n ? nextWidth + discretionaryHyphenWidth\n : nextWidth;\n if (nextLineWidth > maxWidth + lineFitEpsilon)\n break;\n fittedWidth = nextWidth;\n fitCount++;\n }\n return { fitCount, fittedWidth };\n}\nfunction findChunkIndexForStart(prepared, segmentIndex) {\n let lo = 0;\n let hi = prepared.chunks.length;\n while (lo < hi) {\n const mid = Math.floor((lo + hi) / 2);\n if (segmentIndex < prepared.chunks[mid].consumedEndSegmentIndex) {\n hi = mid;\n }\n else {\n lo = mid + 1;\n }\n }\n return lo < prepared.chunks.length ? lo : -1;\n}\nfunction normalizeLineStartWithChunk(prepared, start) {\n let segmentIndex = start.segmentIndex;\n const graphemeIndex = start.graphemeIndex;\n if (segmentIndex >= prepared.widths.length)\n return null;\n const chunkIndex = findChunkIndexForStart(prepared, segmentIndex);\n if (chunkIndex < 0)\n return null;\n if (graphemeIndex > 0) {\n return { cursor: start, chunkIndex };\n }\n const chunk = prepared.chunks[chunkIndex];\n if (chunk.startSegmentIndex === chunk.endSegmentIndex && segmentIndex === chunk.startSegmentIndex) {\n return { cursor: { segmentIndex, graphemeIndex: 0 }, chunkIndex };\n }\n if (segmentIndex < chunk.startSegmentIndex)\n segmentIndex = chunk.startSegmentIndex;\n while (segmentIndex < chunk.endSegmentIndex) {\n const kind = prepared.kinds[segmentIndex];\n if (kind !== 'space' && kind !== 'zero-width-break' && kind !== 'soft-hyphen') {\n return { cursor: { segmentIndex, graphemeIndex: 0 }, chunkIndex };\n }\n segmentIndex++;\n }\n if (chunk.consumedEndSegmentIndex >= prepared.widths.length)\n return null;\n return {\n cursor: { segmentIndex: chunk.consumedEndSegmentIndex, graphemeIndex: 0 },\n chunkIndex: chunkIndex + 1,\n };\n}\nexport function normalizeLineStart(prepared, start) {\n return normalizeLineStartWithChunk(prepared, start)?.cursor ?? null;\n}\nexport function countPreparedLines(prepared, maxWidth) {\n if (prepared.simpleLineWalkFastPath) {\n return countPreparedLinesSimple(prepared, maxWidth);\n }\n return walkPreparedLines(prepared, maxWidth);\n}\nfunction countPreparedLinesSimple(prepared, maxWidth) {\n return walkPreparedLinesSimple(prepared, maxWidth);\n}\nfunction walkPreparedLinesSimple(prepared, maxWidth, onLine) {\n const { widths, kinds, breakableWidths, breakablePrefixWidths } = prepared;\n if (widths.length === 0)\n return 0;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n let lineCount = 0;\n let lineW = 0;\n let hasContent = false;\n let lineStartSegmentIndex = 0;\n let lineStartGraphemeIndex = 0;\n let lineEndSegmentIndex = 0;\n let lineEndGraphemeIndex = 0;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakPaintWidth = 0;\n function clearPendingBreak() {\n pendingBreakSegmentIndex = -1;\n pendingBreakPaintWidth = 0;\n }\n function emitCurrentLine(endSegmentIndex = lineEndSegmentIndex, endGraphemeIndex = lineEndGraphemeIndex, width = lineW) {\n lineCount++;\n onLine?.({\n startSegmentIndex: lineStartSegmentIndex,\n startGraphemeIndex: lineStartGraphemeIndex,\n endSegmentIndex,\n endGraphemeIndex,\n width,\n });\n lineW = 0;\n hasContent = false;\n clearPendingBreak();\n }\n function startLineAtSegment(segmentIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = 0;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n lineW = width;\n }\n function startLineAtGrapheme(segmentIndex, graphemeIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = graphemeIndex;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = graphemeIndex + 1;\n lineW = width;\n }\n function appendWholeSegment(segmentIndex, width) {\n if (!hasContent) {\n startLineAtSegment(segmentIndex, width);\n return;\n }\n lineW += width;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n function updatePendingBreak(segmentIndex, segmentWidth) {\n if (!canBreakAfter(kinds[segmentIndex]))\n return;\n pendingBreakSegmentIndex = segmentIndex + 1;\n pendingBreakPaintWidth = lineW - segmentWidth;\n }\n function appendBreakableSegment(segmentIndex) {\n appendBreakableSegmentFrom(segmentIndex, 0);\n }\n function appendBreakableSegmentFrom(segmentIndex, startGraphemeIndex) {\n const gWidths = breakableWidths[segmentIndex];\n const gPrefixWidths = breakablePrefixWidths[segmentIndex] ?? null;\n for (let g = startGraphemeIndex; g < gWidths.length; g++) {\n const gw = getBreakableAdvance(gWidths, gPrefixWidths, g, engineProfile.preferPrefixWidthsForBreakableRuns);\n if (!hasContent) {\n startLineAtGrapheme(segmentIndex, g, gw);\n continue;\n }\n if (lineW + gw > maxWidth + lineFitEpsilon) {\n emitCurrentLine();\n startLineAtGrapheme(segmentIndex, g, gw);\n }\n else {\n lineW += gw;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = g + 1;\n }\n }\n if (hasContent && lineEndSegmentIndex === segmentIndex && lineEndGraphemeIndex === gWidths.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n }\n let i = 0;\n while (i < widths.length) {\n if (!hasContent) {\n i = normalizeSimpleLineStartSegmentIndex(prepared, i);\n if (i >= widths.length)\n break;\n }\n const w = widths[i];\n const kind = kinds[i];\n if (!hasContent) {\n if (w > maxWidth && breakableWidths[i] !== null) {\n appendBreakableSegment(i);\n }\n else {\n startLineAtSegment(i, w);\n }\n updatePendingBreak(i, w);\n i++;\n continue;\n }\n const newW = lineW + w;\n if (newW > maxWidth + lineFitEpsilon) {\n if (canBreakAfter(kind)) {\n appendWholeSegment(i, w);\n emitCurrentLine(i + 1, 0, lineW - w);\n i++;\n continue;\n }\n if (pendingBreakSegmentIndex >= 0) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n emitCurrentLine();\n continue;\n }\n emitCurrentLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n continue;\n }\n if (w > maxWidth && breakableWidths[i] !== null) {\n emitCurrentLine();\n appendBreakableSegment(i);\n i++;\n continue;\n }\n emitCurrentLine();\n continue;\n }\n appendWholeSegment(i, w);\n updatePendingBreak(i, w);\n i++;\n }\n if (hasContent)\n emitCurrentLine();\n return lineCount;\n}\nexport function walkPreparedLines(prepared, maxWidth, onLine) {\n if (prepared.simpleLineWalkFastPath) {\n return walkPreparedLinesSimple(prepared, maxWidth, onLine);\n }\n const { widths, lineEndFitAdvances, lineEndPaintAdvances, kinds, breakableWidths, breakablePrefixWidths, discretionaryHyphenWidth, tabStopAdvance, chunks, } = prepared;\n if (widths.length === 0 || chunks.length === 0)\n return 0;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n let lineCount = 0;\n let lineW = 0;\n let hasContent = false;\n let lineStartSegmentIndex = 0;\n let lineStartGraphemeIndex = 0;\n let lineEndSegmentIndex = 0;\n let lineEndGraphemeIndex = 0;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakFitWidth = 0;\n let pendingBreakPaintWidth = 0;\n let pendingBreakKind = null;\n function clearPendingBreak() {\n pendingBreakSegmentIndex = -1;\n pendingBreakFitWidth = 0;\n pendingBreakPaintWidth = 0;\n pendingBreakKind = null;\n }\n function emitCurrentLine(endSegmentIndex = lineEndSegmentIndex, endGraphemeIndex = lineEndGraphemeIndex, width = lineW) {\n lineCount++;\n onLine?.({\n startSegmentIndex: lineStartSegmentIndex,\n startGraphemeIndex: lineStartGraphemeIndex,\n endSegmentIndex,\n endGraphemeIndex,\n width,\n });\n lineW = 0;\n hasContent = false;\n clearPendingBreak();\n }\n function startLineAtSegment(segmentIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = 0;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n lineW = width;\n }\n function startLineAtGrapheme(segmentIndex, graphemeIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = graphemeIndex;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = graphemeIndex + 1;\n lineW = width;\n }\n function appendWholeSegment(segmentIndex, width) {\n if (!hasContent) {\n startLineAtSegment(segmentIndex, width);\n return;\n }\n lineW += width;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n function updatePendingBreakForWholeSegment(segmentIndex, segmentWidth) {\n if (!canBreakAfter(kinds[segmentIndex]))\n return;\n const fitAdvance = kinds[segmentIndex] === 'tab' ? 0 : lineEndFitAdvances[segmentIndex];\n const paintAdvance = kinds[segmentIndex] === 'tab' ? segmentWidth : lineEndPaintAdvances[segmentIndex];\n pendingBreakSegmentIndex = segmentIndex + 1;\n pendingBreakFitWidth = lineW - segmentWidth + fitAdvance;\n pendingBreakPaintWidth = lineW - segmentWidth + paintAdvance;\n pendingBreakKind = kinds[segmentIndex];\n }\n function appendBreakableSegment(segmentIndex) {\n appendBreakableSegmentFrom(segmentIndex, 0);\n }\n function appendBreakableSegmentFrom(segmentIndex, startGraphemeIndex) {\n const gWidths = breakableWidths[segmentIndex];\n const gPrefixWidths = breakablePrefixWidths[segmentIndex] ?? null;\n for (let g = startGraphemeIndex; g < gWidths.length; g++) {\n const gw = getBreakableAdvance(gWidths, gPrefixWidths, g, engineProfile.preferPrefixWidthsForBreakableRuns);\n if (!hasContent) {\n startLineAtGrapheme(segmentIndex, g, gw);\n continue;\n }\n if (lineW + gw > maxWidth + lineFitEpsilon) {\n emitCurrentLine();\n startLineAtGrapheme(segmentIndex, g, gw);\n }\n else {\n lineW += gw;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = g + 1;\n }\n }\n if (hasContent && lineEndSegmentIndex === segmentIndex && lineEndGraphemeIndex === gWidths.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n }\n function continueSoftHyphenBreakableSegment(segmentIndex) {\n if (pendingBreakKind !== 'soft-hyphen')\n return false;\n const gWidths = breakableWidths[segmentIndex];\n if (gWidths === null)\n return false;\n const fitWidths = engineProfile.preferPrefixWidthsForBreakableRuns\n ? breakablePrefixWidths[segmentIndex] ?? gWidths\n : gWidths;\n const usesPrefixWidths = fitWidths !== gWidths;\n const { fitCount, fittedWidth } = fitSoftHyphenBreak(fitWidths, lineW, maxWidth, lineFitEpsilon, discretionaryHyphenWidth, usesPrefixWidths);\n if (fitCount === 0)\n return false;\n lineW = fittedWidth;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = fitCount;\n clearPendingBreak();\n if (fitCount === gWidths.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n return true;\n }\n emitCurrentLine(segmentIndex, fitCount, fittedWidth + discretionaryHyphenWidth);\n appendBreakableSegmentFrom(segmentIndex, fitCount);\n return true;\n }\n function emitEmptyChunk(chunk) {\n lineCount++;\n onLine?.({\n startSegmentIndex: chunk.startSegmentIndex,\n startGraphemeIndex: 0,\n endSegmentIndex: chunk.consumedEndSegmentIndex,\n endGraphemeIndex: 0,\n width: 0,\n });\n clearPendingBreak();\n }\n for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {\n const chunk = chunks[chunkIndex];\n if (chunk.startSegmentIndex === chunk.endSegmentIndex) {\n emitEmptyChunk(chunk);\n continue;\n }\n hasContent = false;\n lineW = 0;\n lineStartSegmentIndex = chunk.startSegmentIndex;\n lineStartGraphemeIndex = 0;\n lineEndSegmentIndex = chunk.startSegmentIndex;\n lineEndGraphemeIndex = 0;\n clearPendingBreak();\n let i = chunk.startSegmentIndex;\n while (i < chunk.endSegmentIndex) {\n const kind = kinds[i];\n const w = kind === 'tab' ? getTabAdvance(lineW, tabStopAdvance) : widths[i];\n if (kind === 'soft-hyphen') {\n if (hasContent) {\n lineEndSegmentIndex = i + 1;\n lineEndGraphemeIndex = 0;\n pendingBreakSegmentIndex = i + 1;\n pendingBreakFitWidth = lineW + discretionaryHyphenWidth;\n pendingBreakPaintWidth = lineW + discretionaryHyphenWidth;\n pendingBreakKind = kind;\n }\n i++;\n continue;\n }\n if (!hasContent) {\n if (w > maxWidth && breakableWidths[i] !== null) {\n appendBreakableSegment(i);\n }\n else {\n startLineAtSegment(i, w);\n }\n updatePendingBreakForWholeSegment(i, w);\n i++;\n continue;\n }\n const newW = lineW + w;\n if (newW > maxWidth + lineFitEpsilon) {\n const currentBreakFitWidth = lineW + (kind === 'tab' ? 0 : lineEndFitAdvances[i]);\n const currentBreakPaintWidth = lineW + (kind === 'tab' ? w : lineEndPaintAdvances[i]);\n if (pendingBreakKind === 'soft-hyphen' &&\n engineProfile.preferEarlySoftHyphenBreak &&\n pendingBreakFitWidth <= maxWidth + lineFitEpsilon) {\n emitCurrentLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n continue;\n }\n if (pendingBreakKind === 'soft-hyphen' && continueSoftHyphenBreakableSegment(i)) {\n i++;\n continue;\n }\n if (canBreakAfter(kind) && currentBreakFitWidth <= maxWidth + lineFitEpsilon) {\n appendWholeSegment(i, w);\n emitCurrentLine(i + 1, 0, currentBreakPaintWidth);\n i++;\n continue;\n }\n if (pendingBreakSegmentIndex >= 0 && pendingBreakFitWidth <= maxWidth + lineFitEpsilon) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n emitCurrentLine();\n continue;\n }\n const nextSegmentIndex = pendingBreakSegmentIndex;\n emitCurrentLine(nextSegmentIndex, 0, pendingBreakPaintWidth);\n i = nextSegmentIndex;\n continue;\n }\n if (w > maxWidth && breakableWidths[i] !== null) {\n emitCurrentLine();\n appendBreakableSegment(i);\n i++;\n continue;\n }\n emitCurrentLine();\n continue;\n }\n appendWholeSegment(i, w);\n updatePendingBreakForWholeSegment(i, w);\n i++;\n }\n if (hasContent) {\n const finalPaintWidth = pendingBreakSegmentIndex === chunk.consumedEndSegmentIndex\n ? pendingBreakPaintWidth\n : lineW;\n emitCurrentLine(chunk.consumedEndSegmentIndex, 0, finalPaintWidth);\n }\n }\n return lineCount;\n}\nexport function layoutNextLineRange(prepared, start, maxWidth) {\n const normalized = normalizeLineStartWithChunk(prepared, start);\n if (normalized === null)\n return null;\n if (prepared.simpleLineWalkFastPath) {\n return layoutNextLineRangeSimple(prepared, normalized.cursor, maxWidth);\n }\n const chunk = prepared.chunks[normalized.chunkIndex];\n if (chunk.startSegmentIndex === chunk.endSegmentIndex) {\n return {\n startSegmentIndex: chunk.startSegmentIndex,\n startGraphemeIndex: 0,\n endSegmentIndex: chunk.consumedEndSegmentIndex,\n endGraphemeIndex: 0,\n width: 0,\n };\n }\n const { widths, lineEndFitAdvances, lineEndPaintAdvances, kinds, breakableWidths, breakablePrefixWidths, discretionaryHyphenWidth, tabStopAdvance, } = prepared;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n let lineW = 0;\n let hasContent = false;\n const lineStartSegmentIndex = normalized.cursor.segmentIndex;\n const lineStartGraphemeIndex = normalized.cursor.graphemeIndex;\n let lineEndSegmentIndex = lineStartSegmentIndex;\n let lineEndGraphemeIndex = lineStartGraphemeIndex;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakFitWidth = 0;\n let pendingBreakPaintWidth = 0;\n let pendingBreakKind = null;\n function clearPendingBreak() {\n pendingBreakSegmentIndex = -1;\n pendingBreakFitWidth = 0;\n pendingBreakPaintWidth = 0;\n pendingBreakKind = null;\n }\n function finishLine(endSegmentIndex = lineEndSegmentIndex, endGraphemeIndex = lineEndGraphemeIndex, width = lineW) {\n if (!hasContent)\n return null;\n return {\n startSegmentIndex: lineStartSegmentIndex,\n startGraphemeIndex: lineStartGraphemeIndex,\n endSegmentIndex,\n endGraphemeIndex,\n width,\n };\n }\n function startLineAtSegment(segmentIndex, width) {\n hasContent = true;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n lineW = width;\n }\n function startLineAtGrapheme(segmentIndex, graphemeIndex, width) {\n hasContent = true;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = graphemeIndex + 1;\n lineW = width;\n }\n function appendWholeSegment(segmentIndex, width) {\n if (!hasContent) {\n startLineAtSegment(segmentIndex, width);\n return;\n }\n lineW += width;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n function updatePendingBreakForWholeSegment(segmentIndex, segmentWidth) {\n if (!canBreakAfter(kinds[segmentIndex]))\n return;\n const fitAdvance = kinds[segmentIndex] === 'tab' ? 0 : lineEndFitAdvances[segmentIndex];\n const paintAdvance = kinds[segmentIndex] === 'tab' ? segmentWidth : lineEndPaintAdvances[segmentIndex];\n pendingBreakSegmentIndex = segmentIndex + 1;\n pendingBreakFitWidth = lineW - segmentWidth + fitAdvance;\n pendingBreakPaintWidth = lineW - segmentWidth + paintAdvance;\n pendingBreakKind = kinds[segmentIndex];\n }\n function appendBreakableSegmentFrom(segmentIndex, startGraphemeIndex) {\n const gWidths = breakableWidths[segmentIndex];\n const gPrefixWidths = breakablePrefixWidths[segmentIndex] ?? null;\n for (let g = startGraphemeIndex; g < gWidths.length; g++) {\n const gw = getBreakableAdvance(gWidths, gPrefixWidths, g, engineProfile.preferPrefixWidthsForBreakableRuns);\n if (!hasContent) {\n startLineAtGrapheme(segmentIndex, g, gw);\n continue;\n }\n if (lineW + gw > maxWidth + lineFitEpsilon) {\n return finishLine();\n }\n lineW += gw;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = g + 1;\n }\n if (hasContent && lineEndSegmentIndex === segmentIndex && lineEndGraphemeIndex === gWidths.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n return null;\n }\n function maybeFinishAtSoftHyphen(segmentIndex) {\n if (pendingBreakKind !== 'soft-hyphen' || pendingBreakSegmentIndex < 0)\n return null;\n const gWidths = breakableWidths[segmentIndex] ?? null;\n if (gWidths !== null) {\n const fitWidths = engineProfile.preferPrefixWidthsForBreakableRuns\n ? breakablePrefixWidths[segmentIndex] ?? gWidths\n : gWidths;\n const usesPrefixWidths = fitWidths !== gWidths;\n const { fitCount, fittedWidth } = fitSoftHyphenBreak(fitWidths, lineW, maxWidth, lineFitEpsilon, discretionaryHyphenWidth, usesPrefixWidths);\n if (fitCount === gWidths.length) {\n lineW = fittedWidth;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n clearPendingBreak();\n return null;\n }\n if (fitCount > 0) {\n return finishLine(segmentIndex, fitCount, fittedWidth + discretionaryHyphenWidth);\n }\n }\n if (pendingBreakFitWidth <= maxWidth + lineFitEpsilon) {\n return finishLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n }\n return null;\n }\n for (let i = normalized.cursor.segmentIndex; i < chunk.endSegmentIndex; i++) {\n const kind = kinds[i];\n const startGraphemeIndex = i === normalized.cursor.segmentIndex ? normalized.cursor.graphemeIndex : 0;\n const w = kind === 'tab' ? getTabAdvance(lineW, tabStopAdvance) : widths[i];\n if (kind === 'soft-hyphen' && startGraphemeIndex === 0) {\n if (hasContent) {\n lineEndSegmentIndex = i + 1;\n lineEndGraphemeIndex = 0;\n pendingBreakSegmentIndex = i + 1;\n pendingBreakFitWidth = lineW + discretionaryHyphenWidth;\n pendingBreakPaintWidth = lineW + discretionaryHyphenWidth;\n pendingBreakKind = kind;\n }\n continue;\n }\n if (!hasContent) {\n if (startGraphemeIndex > 0) {\n const line = appendBreakableSegmentFrom(i, startGraphemeIndex);\n if (line !== null)\n return line;\n }\n else if (w > maxWidth && breakableWidths[i] !== null) {\n const line = appendBreakableSegmentFrom(i, 0);\n if (line !== null)\n return line;\n }\n else {\n startLineAtSegment(i, w);\n }\n updatePendingBreakForWholeSegment(i, w);\n continue;\n }\n const newW = lineW + w;\n if (newW > maxWidth + lineFitEpsilon) {\n const currentBreakFitWidth = lineW + (kind === 'tab' ? 0 : lineEndFitAdvances[i]);\n const currentBreakPaintWidth = lineW + (kind === 'tab' ? w : lineEndPaintAdvances[i]);\n if (pendingBreakKind === 'soft-hyphen' &&\n engineProfile.preferEarlySoftHyphenBreak &&\n pendingBreakFitWidth <= maxWidth + lineFitEpsilon) {\n return finishLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n }\n const softBreakLine = maybeFinishAtSoftHyphen(i);\n if (softBreakLine !== null)\n return softBreakLine;\n if (canBreakAfter(kind) && currentBreakFitWidth <= maxWidth + lineFitEpsilon) {\n appendWholeSegment(i, w);\n return finishLine(i + 1, 0, currentBreakPaintWidth);\n }\n if (pendingBreakSegmentIndex >= 0 && pendingBreakFitWidth <= maxWidth + lineFitEpsilon) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n return finishLine();\n }\n return finishLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n }\n if (w > maxWidth && breakableWidths[i] !== null) {\n const currentLine = finishLine();\n if (currentLine !== null)\n return currentLine;\n const line = appendBreakableSegmentFrom(i, 0);\n if (line !== null)\n return line;\n }\n return finishLine();\n }\n appendWholeSegment(i, w);\n updatePendingBreakForWholeSegment(i, w);\n }\n if (pendingBreakSegmentIndex === chunk.consumedEndSegmentIndex && lineEndGraphemeIndex === 0) {\n return finishLine(chunk.consumedEndSegmentIndex, 0, pendingBreakPaintWidth);\n }\n return finishLine(chunk.consumedEndSegmentIndex, 0, lineW);\n}\nfunction layoutNextLineRangeSimple(prepared, normalizedStart, maxWidth) {\n const { widths, kinds, breakableWidths, breakablePrefixWidths } = prepared;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n let lineW = 0;\n let hasContent = false;\n const lineStartSegmentIndex = normalizedStart.segmentIndex;\n const lineStartGraphemeIndex = normalizedStart.graphemeIndex;\n let lineEndSegmentIndex = lineStartSegmentIndex;\n let lineEndGraphemeIndex = lineStartGraphemeIndex;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakPaintWidth = 0;\n function finishLine(endSegmentIndex = lineEndSegmentIndex, endGraphemeIndex = lineEndGraphemeIndex, width = lineW) {\n if (!hasContent)\n return null;\n return {\n startSegmentIndex: lineStartSegmentIndex,\n startGraphemeIndex: lineStartGraphemeIndex,\n endSegmentIndex,\n endGraphemeIndex,\n width,\n };\n }\n function startLineAtSegment(segmentIndex, width) {\n hasContent = true;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n lineW = width;\n }\n function startLineAtGrapheme(segmentIndex, graphemeIndex, width) {\n hasContent = true;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = graphemeIndex + 1;\n lineW = width;\n }\n function appendWholeSegment(segmentIndex, width) {\n if (!hasContent) {\n startLineAtSegment(segmentIndex, width);\n return;\n }\n lineW += width;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n function updatePendingBreak(segmentIndex, segmentWidth) {\n if (!canBreakAfter(kinds[segmentIndex]))\n return;\n pendingBreakSegmentIndex = segmentIndex + 1;\n pendingBreakPaintWidth = lineW - segmentWidth;\n }\n function appendBreakableSegmentFrom(segmentIndex, startGraphemeIndex) {\n const gWidths = breakableWidths[segmentIndex];\n const gPrefixWidths = breakablePrefixWidths[segmentIndex] ?? null;\n for (let g = startGraphemeIndex; g < gWidths.length; g++) {\n const gw = getBreakableAdvance(gWidths, gPrefixWidths, g, engineProfile.preferPrefixWidthsForBreakableRuns);\n if (!hasContent) {\n startLineAtGrapheme(segmentIndex, g, gw);\n continue;\n }\n if (lineW + gw > maxWidth + lineFitEpsilon) {\n return finishLine();\n }\n lineW += gw;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = g + 1;\n }\n if (hasContent && lineEndSegmentIndex === segmentIndex && lineEndGraphemeIndex === gWidths.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n return null;\n }\n for (let i = normalizedStart.segmentIndex; i < widths.length; i++) {\n const w = widths[i];\n const kind = kinds[i];\n const startGraphemeIndex = i === normalizedStart.segmentIndex ? normalizedStart.graphemeIndex : 0;\n if (!hasContent) {\n if (startGraphemeIndex > 0) {\n const line = appendBreakableSegmentFrom(i, startGraphemeIndex);\n if (line !== null)\n return line;\n }\n else if (w > maxWidth && breakableWidths[i] !== null) {\n const line = appendBreakableSegmentFrom(i, 0);\n if (line !== null)\n return line;\n }\n else {\n startLineAtSegment(i, w);\n }\n updatePendingBreak(i, w);\n continue;\n }\n const newW = lineW + w;\n if (newW > maxWidth + lineFitEpsilon) {\n if (canBreakAfter(kind)) {\n appendWholeSegment(i, w);\n return finishLine(i + 1, 0, lineW - w);\n }\n if (pendingBreakSegmentIndex >= 0) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n return finishLine();\n }\n return finishLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n }\n if (w > maxWidth && breakableWidths[i] !== null) {\n const currentLine = finishLine();\n if (currentLine !== null)\n return currentLine;\n const line = appendBreakableSegmentFrom(i, 0);\n if (line !== null)\n return line;\n }\n return finishLine();\n }\n appendWholeSegment(i, w);\n updatePendingBreak(i, w);\n }\n return finishLine();\n}\n","// Text measurement for browser environments using canvas measureText.\n//\n// Problem: DOM-based text measurement (getBoundingClientRect, offsetHeight)\n// forces synchronous layout reflow. When components independently measure text,\n// each measurement triggers a reflow of the entire document. This creates\n// read/write interleaving that can cost 30ms+ per frame for 500 text blocks.\n//\n// Solution: two-phase measurement centered around canvas measureText.\n// prepare(text, font) — segments text via Intl.Segmenter, measures each word\n// via canvas, caches widths, and does one cached DOM calibration read per\n// font when emoji correction is needed. Call once when text first appears.\n// layout(prepared, maxWidth, lineHeight) — walks cached word widths with pure\n// arithmetic to count lines and compute height. Call on every resize.\n// ~0.0002ms per text.\n//\n// i18n: Intl.Segmenter handles CJK (per-character breaking), Thai, Arabic, etc.\n// Bidi: simplified rich-path metadata for mixed LTR/RTL custom rendering.\n// Punctuation merging: \"better.\" measured as one unit (matches CSS behavior).\n// Trailing whitespace: hangs past line edge without triggering breaks (CSS behavior).\n// overflow-wrap: pre-measured grapheme widths enable character-level word breaking.\n//\n// Emoji correction: Chrome/Firefox canvas measures emoji wider than DOM at font\n// sizes <24px on macOS (Apple Color Emoji). The inflation is constant per emoji\n// grapheme at a given size, font-independent. Auto-detected by comparing canvas\n// vs actual DOM emoji width (one cached DOM read per font). Safari canvas and\n// DOM agree (both wider than fontSize), so correction = 0 there.\n//\n// Limitations:\n// - system-ui font: canvas resolves to different optical variants than DOM on macOS.\n// Use named fonts (Helvetica, Inter, etc.) for guaranteed accuracy.\n// See RESEARCH.md \"Discovery: system-ui font resolution mismatch\".\n//\n// Based on Sebastian Markbage's text-layout research (github.com/chenglou/text-layout).\nimport { computeSegmentLevels } from './bidi.js';\nimport { analyzeText, clearAnalysisCaches, endsWithClosingQuote, isCJK, kinsokuEnd, kinsokuStart, leftStickyPunctuation, setAnalysisLocale, } from './analysis.js';\nimport { clearMeasurementCaches, getCorrectedSegmentWidth, getEngineProfile, getFontMeasurementState, getSegmentGraphemePrefixWidths, getSegmentGraphemeWidths, getSegmentMetrics, textMayContainEmoji, } from './measurement.js';\nimport { countPreparedLines, layoutNextLineRange as stepPreparedLineRange, walkPreparedLines, } from './line-break.js';\nlet sharedGraphemeSegmenter = null;\n// Rich-path only. Reuses grapheme splits while materializing multiple lines\n// from the same prepared handle, without pushing that cache into the API.\nlet sharedLineTextCaches = new WeakMap();\nfunction getSharedGraphemeSegmenter() {\n if (sharedGraphemeSegmenter === null) {\n sharedGraphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\n }\n return sharedGraphemeSegmenter;\n}\n// --- Public API ---\nfunction createEmptyPrepared(includeSegments) {\n if (includeSegments) {\n return {\n widths: [],\n lineEndFitAdvances: [],\n lineEndPaintAdvances: [],\n kinds: [],\n simpleLineWalkFastPath: true,\n segLevels: null,\n breakableWidths: [],\n breakablePrefixWidths: [],\n discretionaryHyphenWidth: 0,\n tabStopAdvance: 0,\n chunks: [],\n segments: [],\n };\n }\n return {\n widths: [],\n lineEndFitAdvances: [],\n lineEndPaintAdvances: [],\n kinds: [],\n simpleLineWalkFastPath: true,\n segLevels: null,\n breakableWidths: [],\n breakablePrefixWidths: [],\n discretionaryHyphenWidth: 0,\n tabStopAdvance: 0,\n chunks: [],\n };\n}\nfunction measureAnalysis(analysis, font, includeSegments) {\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n const engineProfile = getEngineProfile();\n const { cache, emojiCorrection } = getFontMeasurementState(font, textMayContainEmoji(analysis.normalized));\n const discretionaryHyphenWidth = getCorrectedSegmentWidth('-', getSegmentMetrics('-', cache), emojiCorrection);\n const spaceWidth = getCorrectedSegmentWidth(' ', getSegmentMetrics(' ', cache), emojiCorrection);\n const tabStopAdvance = spaceWidth * 8;\n if (analysis.len === 0)\n return createEmptyPrepared(includeSegments);\n const widths = [];\n const lineEndFitAdvances = [];\n const lineEndPaintAdvances = [];\n const kinds = [];\n let simpleLineWalkFastPath = analysis.chunks.length <= 1;\n const segStarts = includeSegments ? [] : null;\n const breakableWidths = [];\n const breakablePrefixWidths = [];\n const segments = includeSegments ? [] : null;\n const preparedStartByAnalysisIndex = Array.from({ length: analysis.len });\n const preparedEndByAnalysisIndex = Array.from({ length: analysis.len });\n function pushMeasuredSegment(text, width, lineEndFitAdvance, lineEndPaintAdvance, kind, start, breakable, breakablePrefix) {\n if (kind !== 'text' && kind !== 'space' && kind !== 'zero-width-break') {\n simpleLineWalkFastPath = false;\n }\n widths.push(width);\n lineEndFitAdvances.push(lineEndFitAdvance);\n lineEndPaintAdvances.push(lineEndPaintAdvance);\n kinds.push(kind);\n segStarts?.push(start);\n breakableWidths.push(breakable);\n breakablePrefixWidths.push(breakablePrefix);\n if (segments !== null)\n segments.push(text);\n }\n for (let mi = 0; mi < analysis.len; mi++) {\n preparedStartByAnalysisIndex[mi] = widths.length;\n const segText = analysis.texts[mi];\n const segWordLike = analysis.isWordLike[mi];\n const segKind = analysis.kinds[mi];\n const segStart = analysis.starts[mi];\n if (segKind === 'soft-hyphen') {\n pushMeasuredSegment(segText, 0, discretionaryHyphenWidth, discretionaryHyphenWidth, segKind, segStart, null, null);\n preparedEndByAnalysisIndex[mi] = widths.length;\n continue;\n }\n if (segKind === 'hard-break') {\n pushMeasuredSegment(segText, 0, 0, 0, segKind, segStart, null, null);\n preparedEndByAnalysisIndex[mi] = widths.length;\n continue;\n }\n if (segKind === 'tab') {\n pushMeasuredSegment(segText, 0, 0, 0, segKind, segStart, null, null);\n preparedEndByAnalysisIndex[mi] = widths.length;\n continue;\n }\n const segMetrics = getSegmentMetrics(segText, cache);\n if (segKind === 'text' && segMetrics.containsCJK) {\n let unitText = '';\n let unitStart = 0;\n for (const gs of graphemeSegmenter.segment(segText)) {\n const grapheme = gs.segment;\n if (unitText.length === 0) {\n unitText = grapheme;\n unitStart = gs.index;\n continue;\n }\n if (kinsokuEnd.has(unitText) ||\n kinsokuStart.has(grapheme) ||\n leftStickyPunctuation.has(grapheme) ||\n (engineProfile.carryCJKAfterClosingQuote &&\n isCJK(grapheme) &&\n endsWithClosingQuote(unitText))) {\n unitText += grapheme;\n continue;\n }\n const unitMetrics = getSegmentMetrics(unitText, cache);\n const w = getCorrectedSegmentWidth(unitText, unitMetrics, emojiCorrection);\n pushMeasuredSegment(unitText, w, w, w, 'text', segStart + unitStart, null, null);\n unitText = grapheme;\n unitStart = gs.index;\n }\n if (unitText.length > 0) {\n const unitMetrics = getSegmentMetrics(unitText, cache);\n const w = getCorrectedSegmentWidth(unitText, unitMetrics, emojiCorrection);\n pushMeasuredSegment(unitText, w, w, w, 'text', segStart + unitStart, null, null);\n }\n preparedEndByAnalysisIndex[mi] = widths.length;\n continue;\n }\n const w = getCorrectedSegmentWidth(segText, segMetrics, emojiCorrection);\n const lineEndFitAdvance = segKind === 'space' || segKind === 'preserved-space' || segKind === 'zero-width-break'\n ? 0\n : w;\n const lineEndPaintAdvance = segKind === 'space' || segKind === 'zero-width-break'\n ? 0\n : w;\n if (segWordLike && segText.length > 1) {\n const graphemeWidths = getSegmentGraphemeWidths(segText, segMetrics, cache, emojiCorrection);\n const graphemePrefixWidths = engineProfile.preferPrefixWidthsForBreakableRuns\n ? getSegmentGraphemePrefixWidths(segText, segMetrics, cache, emojiCorrection)\n : null;\n pushMeasuredSegment(segText, w, lineEndFitAdvance, lineEndPaintAdvance, segKind, segStart, graphemeWidths, graphemePrefixWidths);\n }\n else {\n pushMeasuredSegment(segText, w, lineEndFitAdvance, lineEndPaintAdvance, segKind, segStart, null, null);\n }\n preparedEndByAnalysisIndex[mi] = widths.length;\n }\n const chunks = mapAnalysisChunksToPreparedChunks(analysis.chunks, preparedStartByAnalysisIndex, preparedEndByAnalysisIndex);\n const segLevels = segStarts === null ? null : computeSegmentLevels(analysis.normalized, segStarts);\n if (segments !== null) {\n return {\n widths,\n lineEndFitAdvances,\n lineEndPaintAdvances,\n kinds,\n simpleLineWalkFastPath,\n segLevels,\n breakableWidths,\n breakablePrefixWidths,\n discretionaryHyphenWidth,\n tabStopAdvance,\n chunks,\n segments,\n };\n }\n return {\n widths,\n lineEndFitAdvances,\n lineEndPaintAdvances,\n kinds,\n simpleLineWalkFastPath,\n segLevels,\n breakableWidths,\n breakablePrefixWidths,\n discretionaryHyphenWidth,\n tabStopAdvance,\n chunks,\n };\n}\nfunction mapAnalysisChunksToPreparedChunks(chunks, preparedStartByAnalysisIndex, preparedEndByAnalysisIndex) {\n const preparedChunks = [];\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n const startSegmentIndex = chunk.startSegmentIndex < preparedStartByAnalysisIndex.length\n ? preparedStartByAnalysisIndex[chunk.startSegmentIndex]\n : preparedEndByAnalysisIndex[preparedEndByAnalysisIndex.length - 1] ?? 0;\n const endSegmentIndex = chunk.endSegmentIndex < preparedStartByAnalysisIndex.length\n ? preparedStartByAnalysisIndex[chunk.endSegmentIndex]\n : preparedEndByAnalysisIndex[preparedEndByAnalysisIndex.length - 1] ?? 0;\n const consumedEndSegmentIndex = chunk.consumedEndSegmentIndex < preparedStartByAnalysisIndex.length\n ? preparedStartByAnalysisIndex[chunk.consumedEndSegmentIndex]\n : preparedEndByAnalysisIndex[preparedEndByAnalysisIndex.length - 1] ?? 0;\n preparedChunks.push({\n startSegmentIndex,\n endSegmentIndex,\n consumedEndSegmentIndex,\n });\n }\n return preparedChunks;\n}\nfunction prepareInternal(text, font, includeSegments, options) {\n const analysis = analyzeText(text, getEngineProfile(), options?.whiteSpace);\n return measureAnalysis(analysis, font, includeSegments);\n}\n// Diagnostic-only helper used by the browser benchmark harness to separate the\n// text-analysis and measurement phases without duplicating the prepare logic.\nexport function profilePrepare(text, font, options) {\n const t0 = performance.now();\n const analysis = analyzeText(text, getEngineProfile(), options?.whiteSpace);\n const t1 = performance.now();\n const prepared = measureAnalysis(analysis, font, false);\n const t2 = performance.now();\n let breakableSegments = 0;\n for (const widths of prepared.breakableWidths) {\n if (widths !== null)\n breakableSegments++;\n }\n return {\n analysisMs: t1 - t0,\n measureMs: t2 - t1,\n totalMs: t2 - t0,\n analysisSegments: analysis.len,\n preparedSegments: prepared.widths.length,\n breakableSegments,\n };\n}\n// Prepare text for layout. Segments the text, measures each segment via canvas,\n// and stores the widths for fast relayout at any width. Call once per text block\n// (e.g. when a comment first appears). The result is width-independent — the\n// same PreparedText can be laid out at any maxWidth and lineHeight via layout().\n//\n// Steps:\n// 1. Normalize collapsible whitespace (CSS white-space: normal behavior)\n// 2. Segment via Intl.Segmenter (handles CJK, Thai, etc.)\n// 3. Merge punctuation into preceding word (\"better.\" as one unit)\n// 4. Split CJK words into individual graphemes (per-character line breaks)\n// 5. Measure each segment via canvas measureText, cache by (segment, font)\n// 6. Pre-measure graphemes of long words (for overflow-wrap: break-word)\n// 7. Correct emoji canvas inflation (auto-detected per font size)\n// 8. Optionally compute rich-path bidi metadata for custom renderers\nexport function prepare(text, font, options) {\n return prepareInternal(text, font, false, options);\n}\n// Rich variant used by callers that need enough information to render the\n// laid-out lines themselves.\nexport function prepareWithSegments(text, font, options) {\n return prepareInternal(text, font, true, options);\n}\nfunction getInternalPrepared(prepared) {\n return prepared;\n}\n// Layout prepared text at a given max width and caller-provided lineHeight.\n// Pure arithmetic on cached widths — no canvas calls, no DOM reads, no string\n// operations, no allocations.\n// ~0.0002ms per text block. Call on every resize.\n//\n// Line breaking rules (matching CSS white-space: normal + overflow-wrap: break-word):\n// - Break before any non-space segment that would overflow the line\n// - Trailing whitespace hangs past the line edge (doesn't trigger breaks)\n// - Segments wider than maxWidth are broken at grapheme boundaries\nexport function layout(prepared, maxWidth, lineHeight) {\n // Keep the resize hot path specialized. `layoutWithLines()` shares the same\n // break semantics but also tracks line ranges; the extra bookkeeping is too\n // expensive to pay on every hot-path `layout()` call.\n const lineCount = countPreparedLines(getInternalPrepared(prepared), maxWidth);\n return { lineCount, height: lineCount * lineHeight };\n}\nfunction getSegmentGraphemes(segmentIndex, segments, cache) {\n let graphemes = cache.get(segmentIndex);\n if (graphemes !== undefined)\n return graphemes;\n graphemes = [];\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n for (const gs of graphemeSegmenter.segment(segments[segmentIndex])) {\n graphemes.push(gs.segment);\n }\n cache.set(segmentIndex, graphemes);\n return graphemes;\n}\nfunction getLineTextCache(prepared) {\n let cache = sharedLineTextCaches.get(prepared);\n if (cache !== undefined)\n return cache;\n cache = new Map();\n sharedLineTextCaches.set(prepared, cache);\n return cache;\n}\nfunction lineHasDiscretionaryHyphen(kinds, startSegmentIndex, startGraphemeIndex, endSegmentIndex) {\n return (endSegmentIndex > 0 &&\n kinds[endSegmentIndex - 1] === 'soft-hyphen' &&\n !(startSegmentIndex === endSegmentIndex && startGraphemeIndex > 0));\n}\nfunction buildLineTextFromRange(segments, kinds, cache, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) {\n let text = '';\n const endsWithDiscretionaryHyphen = lineHasDiscretionaryHyphen(kinds, startSegmentIndex, startGraphemeIndex, endSegmentIndex);\n for (let i = startSegmentIndex; i < endSegmentIndex; i++) {\n if (kinds[i] === 'soft-hyphen' || kinds[i] === 'hard-break')\n continue;\n if (i === startSegmentIndex && startGraphemeIndex > 0) {\n text += getSegmentGraphemes(i, segments, cache).slice(startGraphemeIndex).join('');\n }\n else {\n text += segments[i];\n }\n }\n if (endGraphemeIndex > 0) {\n if (endsWithDiscretionaryHyphen)\n text += '-';\n text += getSegmentGraphemes(endSegmentIndex, segments, cache).slice(startSegmentIndex === endSegmentIndex ? startGraphemeIndex : 0, endGraphemeIndex).join('');\n }\n else if (endsWithDiscretionaryHyphen) {\n text += '-';\n }\n return text;\n}\nfunction createLayoutLine(prepared, cache, width, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) {\n return {\n text: buildLineTextFromRange(prepared.segments, prepared.kinds, cache, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex),\n width,\n start: {\n segmentIndex: startSegmentIndex,\n graphemeIndex: startGraphemeIndex,\n },\n end: {\n segmentIndex: endSegmentIndex,\n graphemeIndex: endGraphemeIndex,\n },\n };\n}\nfunction materializeLayoutLine(prepared, cache, line) {\n return createLayoutLine(prepared, cache, line.width, line.startSegmentIndex, line.startGraphemeIndex, line.endSegmentIndex, line.endGraphemeIndex);\n}\nfunction toLayoutLineRange(line) {\n return {\n width: line.width,\n start: {\n segmentIndex: line.startSegmentIndex,\n graphemeIndex: line.startGraphemeIndex,\n },\n end: {\n segmentIndex: line.endSegmentIndex,\n graphemeIndex: line.endGraphemeIndex,\n },\n };\n}\nfunction stepLineRange(prepared, start, maxWidth) {\n const line = stepPreparedLineRange(prepared, start, maxWidth);\n if (line === null)\n return null;\n return toLayoutLineRange(line);\n}\nfunction materializeLine(prepared, line) {\n return createLayoutLine(prepared, getLineTextCache(prepared), line.width, line.start.segmentIndex, line.start.graphemeIndex, line.end.segmentIndex, line.end.graphemeIndex);\n}\n// Batch low-level line geometry pass. This is the non-materializing counterpart\n// to layoutWithLines(), useful for shrinkwrap and other aggregate geometry work.\nexport function walkLineRanges(prepared, maxWidth, onLine) {\n if (prepared.widths.length === 0)\n return 0;\n return walkPreparedLines(getInternalPrepared(prepared), maxWidth, line => {\n onLine(toLayoutLineRange(line));\n });\n}\nexport function layoutNextLine(prepared, start, maxWidth) {\n const line = stepLineRange(prepared, start, maxWidth);\n if (line === null)\n return null;\n return materializeLine(prepared, line);\n}\n// Rich layout API for callers that want the actual line contents and widths.\n// Caller still supplies lineHeight at layout time. Mirrors layout()'s break\n// decisions, but keeps extra per-line bookkeeping so it should stay off the\n// resize hot path.\nexport function layoutWithLines(prepared, maxWidth, lineHeight) {\n const lines = [];\n if (prepared.widths.length === 0)\n return { lineCount: 0, height: 0, lines };\n const graphemeCache = getLineTextCache(prepared);\n const lineCount = walkPreparedLines(getInternalPrepared(prepared), maxWidth, line => {\n lines.push(materializeLayoutLine(prepared, graphemeCache, line));\n });\n return { lineCount, height: lineCount * lineHeight, lines };\n}\nexport function clearCache() {\n clearAnalysisCaches();\n sharedGraphemeSegmenter = null;\n sharedLineTextCaches = new WeakMap();\n clearMeasurementCaches();\n}\nexport function setLocale(locale) {\n setAnalysisLocale(locale);\n clearCache();\n}\n","import { layoutWithLines, prepareWithSegments } from \"@chenglou/pretext\";\nimport { measureAdvanceWidth, normalizeTextOptions } from \"./core.js\";\nimport { combineRects, emptyRect, normalizeNumber, normalizePositive } from \"./geometry.js\";\n\nconst DEFAULT_LINE_HEIGHT_RATIO = 1.2;\nconst HUGE_LAYOUT_WIDTH = 1e9;\nconst JUSTIFY_EPSILON = 1e-6;\nconst QUOTE_RE = /\"/g;\n\nlet sharedMeasureContext = null;\nlet sharedWordSegmenter = null;\nlet sharedGraphemeSegmenter = null;\n\nexport function layoutParagraph(fontInstance, text, options = {}, state = {}) {\n const normalized = normalizeParagraphOptions(fontInstance, options);\n const textValue = String(text ?? \"\");\n const canUsePretext =\n normalized.engine === \"pretext\" && normalized.overflowWrap !== \"normal\";\n const layoutState = canUsePretext\n ? layoutWithPretext(fontInstance, textValue, normalized, state)\n : layoutWithNative(fontInstance, textValue, normalized);\n\n const measuredLines = applyMaxLines(\n layoutState.lines,\n normalized,\n createTextMeasurer(fontInstance, normalized),\n );\n const lines = positionLines(fontInstance, measuredLines, normalized);\n const bbox = combineRects(lines.map((line) => line.bbox)) ?? emptyRect();\n const width = lines.reduce((max, line) => Math.max(max, line.width), 0);\n\n return {\n options: normalized,\n lines,\n metrics: {\n x: normalized.x,\n y: normalized.y,\n width,\n height: lines.length * normalized.lineHeight,\n lineCount: lines.length,\n bbox,\n },\n prepared: layoutState.prepared ?? null,\n preparedWhiteSpace: layoutState.preparedWhiteSpace ?? null,\n layoutEngine: layoutState.layoutEngine,\n };\n}\n\nexport function normalizeParagraphOptions(fontInstance, options = {}) {\n if (options == null || typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(\"font.paragraph() options must be an object.\");\n }\n\n const textOptions = normalizeTextOptions(options);\n const width = normalizePositive(options.width, 0);\n\n if (width <= 0) {\n throw new TypeError('font.paragraph() option \"width\" must be a positive number.');\n }\n\n const font = resolveCanvasFont(fontInstance, textOptions.size, options);\n const lineHeight = resolveLineHeight(options.lineHeight, textOptions.size);\n const align = normalizeEnum(options.align, [\"left\", \"center\", \"right\", \"justify\"], \"left\");\n const whiteSpace = normalizeEnum(\n options.whiteSpace,\n [\"normal\", \"pre-wrap\", \"nowrap\"],\n \"normal\",\n );\n const overflowWrap = normalizeEnum(\n options.overflowWrap,\n [\"normal\", \"break-word\", \"anywhere\"],\n \"break-word\",\n );\n const engine = normalizeEnum(options.engine, [\"pretext\", \"native\"], \"pretext\");\n const maxLines = normalizeMaxLines(options.maxLines);\n const ellipsis = normalizeEllipsis(options.ellipsis);\n\n return {\n ...textOptions,\n width,\n lineHeight,\n align,\n whiteSpace,\n overflowWrap,\n maxLines,\n ellipsis,\n fontStyle: normalizeEnum(options.fontStyle, [\"normal\", \"italic\", \"oblique\"], \"normal\"),\n fontWeight:\n typeof options.fontWeight === \"string\" || Number.isFinite(options.fontWeight)\n ? options.fontWeight\n : 400,\n fontFamily: resolveFontFamily(fontInstance, options.fontFamily),\n font,\n engine,\n };\n}\n\nexport function resolveCanvasFont(fontInstance, size, options = {}) {\n if (typeof options.font === \"string\" && options.font.trim().length > 0) {\n return options.font.trim();\n }\n\n const style = normalizeEnum(options.fontStyle, [\"normal\", \"italic\", \"oblique\"], \"normal\");\n const weight =\n typeof options.fontWeight === \"string\" || Number.isFinite(options.fontWeight)\n ? String(options.fontWeight)\n : \"400\";\n const family = formatFontFamily(resolveFontFamily(fontInstance, options.fontFamily));\n\n return `${style} ${weight} ${size}px ${family}`;\n}\n\nexport function canReusePreparedParagraphState(previousState, previousOptions, nextOptions) {\n return (\n previousState?.prepared != null &&\n previousState.preparedWhiteSpace === resolvePretextWhiteSpace(nextOptions.whiteSpace) &&\n previousOptions?.font === nextOptions.font\n );\n}\n\nfunction layoutWithPretext(fontInstance, text, options, state) {\n const preparedWhiteSpace = resolvePretextWhiteSpace(options.whiteSpace);\n const prepared =\n state.prepared != null &&\n state.preparedWhiteSpace === preparedWhiteSpace &&\n state.font === options.font\n ? state.prepared\n : prepareWithSegments(text, options.font, { whiteSpace: preparedWhiteSpace });\n const maxWidth = options.whiteSpace === \"nowrap\" ? HUGE_LAYOUT_WIDTH : options.width;\n const layout = layoutWithLines(prepared, maxWidth, options.lineHeight);\n const lines = layout.lines.map((line) => ({\n text: line.text,\n width: line.width,\n start: null,\n end: null,\n hardBreak: isHardBreak(prepared, line),\n }));\n\n return {\n lines,\n prepared,\n preparedWhiteSpace,\n layoutEngine: \"pretext\",\n fontInstance,\n };\n}\n\nfunction layoutWithNative(fontInstance, text, options) {\n const measuredWidth = createOpenTypeMeasurer(fontInstance, options);\n const source = normalizeNativeText(text, options.whiteSpace);\n\n if (source.length === 0) {\n return {\n lines: [],\n prepared: null,\n preparedWhiteSpace: null,\n layoutEngine: \"native\",\n };\n }\n\n if (options.whiteSpace === \"nowrap\") {\n return {\n lines: [\n {\n text: source,\n width: measuredWidth(source),\n start: 0,\n end: source.length,\n hardBreak: false,\n },\n ],\n prepared: null,\n preparedWhiteSpace: null,\n layoutEngine: \"native\",\n };\n }\n\n const tokens = tokenizeNativeText(source, options.whiteSpace, measuredWidth);\n const lines = [];\n let currentText = \"\";\n let currentWidth = 0;\n let currentStart = null;\n let currentEnd = null;\n\n const pushCurrentLine = (hardBreak, fallbackOffset) => {\n const textValue =\n options.whiteSpace === \"pre-wrap\"\n ? currentText\n : currentText.replace(/\\s+$/u, \"\");\n const widthValue =\n textValue === currentText ? currentWidth : measuredWidth(textValue);\n\n lines.push({\n text: textValue,\n width: widthValue,\n start: currentStart ?? fallbackOffset,\n end: currentEnd ?? fallbackOffset,\n hardBreak,\n });\n currentText = \"\";\n currentWidth = 0;\n currentStart = null;\n currentEnd = null;\n };\n\n const appendPiece = (piece) => {\n currentText += piece.text;\n currentWidth += piece.width;\n currentStart = currentStart == null ? piece.start : currentStart;\n currentEnd = piece.end;\n };\n\n const appendWrappedToken = (token) => {\n if (options.overflowWrap === \"normal\") {\n appendPiece(token);\n return;\n }\n\n const pieces = splitIntoGraphemePieces(token, measuredWidth);\n\n pieces.forEach((piece) => {\n if (\n currentText.length > 0 &&\n currentWidth + piece.width > options.width + JUSTIFY_EPSILON\n ) {\n pushCurrentLine(false, piece.start);\n }\n\n appendPiece(piece);\n });\n };\n\n tokens.forEach((token) => {\n if (token.type === \"hardBreak\") {\n pushCurrentLine(true, token.start);\n return;\n }\n\n if (token.type === \"space\" && currentText.length === 0 && options.whiteSpace !== \"pre-wrap\") {\n return;\n }\n\n if (\n currentText.length === 0 ||\n currentWidth + token.width <= options.width + JUSTIFY_EPSILON\n ) {\n appendPiece(token);\n return;\n }\n\n if (token.type === \"space\") {\n pushCurrentLine(false, token.start);\n\n if (options.whiteSpace === \"pre-wrap\") {\n appendWrappedToken(token);\n }\n\n return;\n }\n\n pushCurrentLine(false, token.start);\n appendWrappedToken(token);\n });\n\n if (currentText.length > 0 || lines.length === 0) {\n pushCurrentLine(false, source.length);\n }\n\n return {\n lines,\n prepared: null,\n preparedWhiteSpace: null,\n layoutEngine: \"native\",\n };\n}\n\nfunction splitIntoGraphemePieces(token, measureWidth) {\n const pieces = [];\n const segmenter = getGraphemeSegmenter();\n\n for (const part of segmenter.segment(token.text)) {\n const text = part.segment;\n const start = token.start + part.index;\n const end = start + text.length;\n\n pieces.push({\n text,\n type: token.type,\n start,\n end,\n width: measureWidth(text),\n });\n }\n\n return pieces.length > 0 ? pieces : [token];\n}\n\nfunction applyMaxLines(lines, options, measureWidth) {\n if (options.maxLines == null || lines.length <= options.maxLines) {\n return lines;\n }\n\n const clipped = lines.slice(0, options.maxLines).map((line) => ({ ...line }));\n\n if (options.ellipsis !== false && clipped.length > 0) {\n const lastLine = clipped[clipped.length - 1];\n const suffix = options.ellipsis;\n const suffixWidth = measureWidth(suffix);\n const trimmed = trimTrailingWhitespace(lastLine.text);\n\n if (suffixWidth > options.width + JUSTIFY_EPSILON) {\n lastLine.text = \"\";\n lastLine.width = 0;\n } else {\n let nextText = trimmed;\n\n while (nextText.length > 0 && measureWidth(`${nextText}${suffix}`) > options.width + JUSTIFY_EPSILON) {\n nextText = trimLastGrapheme(nextText);\n }\n\n lastLine.text = `${nextText}${suffix}`;\n lastLine.width = measureWidth(lastLine.text);\n }\n\n lastLine.hardBreak = false;\n }\n\n return clipped;\n}\n\nfunction positionLines(fontInstance, lines, options) {\n const ascent = getFontAscender(fontInstance, options.size);\n const lineBoxHeight = options.lineHeight;\n const measureWidth = createTextMeasurer(fontInstance, options);\n let cursor = 0;\n\n return lines.map((line, index) => {\n const justified = shouldJustifyLine(line, index, lines.length, options);\n const offsetX = justified ? 0 : resolveAlignOffset(options.align, line.width, options.width);\n const x = options.x + offsetX;\n const y = options.y + index * lineBoxHeight;\n const baseline = y + ascent;\n const fragments = justified\n ? buildJustifiedFragments(line, options, measureWidth)\n : [\n {\n text: line.text,\n x,\n width: line.width,\n isWhitespace: false,\n },\n ];\n const width = justified ? options.width : line.width;\n const bbox = {\n x,\n y,\n w: width,\n h: lineBoxHeight,\n };\n const positioned = {\n index,\n text: line.text,\n start: line.start ?? cursor,\n end: line.end ?? cursor + line.text.length,\n x,\n y,\n width,\n baseline,\n height: lineBoxHeight,\n bbox,\n hardBreak: line.hardBreak,\n fragments,\n };\n\n cursor = positioned.end + (line.hardBreak ? 1 : 0);\n return positioned;\n });\n}\n\nfunction buildJustifiedFragments(line, options, measureWidth) {\n const tokens = splitPreservingWhitespace(line.text);\n const expandable = tokens.reduce((count, token, index) => {\n if (\n index > 0 &&\n index < tokens.length - 1 &&\n /\\s/u.test(token)\n ) {\n return count + 1;\n }\n\n return count;\n }, 0);\n\n if (expandable === 0) {\n return [\n {\n text: line.text,\n x: options.x,\n width: line.width,\n isWhitespace: false,\n },\n ];\n }\n\n const extraPerGap = Math.max(0, options.width - line.width) / expandable;\n const fragments = [];\n let cursorX = options.x;\n\n tokens.forEach((token, index) => {\n const isWhitespace = /\\s/u.test(token);\n const isExpandable = isWhitespace && index > 0 && index < tokens.length - 1;\n const baseWidth = measureWidth(token);\n const width = baseWidth + (isExpandable ? extraPerGap : 0);\n\n fragments.push({\n text: token,\n x: cursorX,\n width,\n isWhitespace,\n });\n\n cursorX += width;\n });\n\n return fragments;\n}\n\nfunction shouldJustifyLine(line, index, lineCount, options) {\n return (\n options.align === \"justify\" &&\n index < lineCount - 1 &&\n !line.hardBreak &&\n /\\S\\s+\\S/u.test(line.text)\n );\n}\n\nfunction resolveAlignOffset(align, lineWidth, maxWidth) {\n if (align === \"center\") {\n return (maxWidth - lineWidth) * 0.5;\n }\n\n if (align === \"right\") {\n return maxWidth - lineWidth;\n }\n\n return 0;\n}\n\nfunction resolveLineHeight(value, size) {\n if (!Number.isFinite(value) || value <= 0) {\n return size * DEFAULT_LINE_HEIGHT_RATIO;\n }\n\n if (value <= 10) {\n return size * value;\n }\n\n return value;\n}\n\nfunction normalizeEnum(value, supported, fallback) {\n return typeof value === \"string\" && supported.includes(value) ? value : fallback;\n}\n\nfunction normalizeEllipsis(value) {\n if (value === false || value == null) {\n return false;\n }\n\n return typeof value === \"string\" ? value : \"…\";\n}\n\nfunction normalizeMaxLines(value) {\n if (!Number.isFinite(value)) {\n return null;\n }\n\n const rounded = Math.floor(value);\n return rounded > 0 ? rounded : null;\n}\n\nfunction resolveFontFamily(fontInstance, fontFamily) {\n if (typeof fontFamily === \"string\" && fontFamily.trim().length > 0) {\n return fontFamily.trim();\n }\n\n const preferred =\n fontInstance?.font?.names?.fullName?.en ??\n fontInstance?.font?.names?.fontFamily?.en ??\n fontInstance?.font?.familyName;\n\n return typeof preferred === \"string\" && preferred.trim().length > 0\n ? preferred.trim()\n : \"sans-serif\";\n}\n\nfunction formatFontFamily(value) {\n if (value.includes(\",\") || value.includes('\"') || value.includes(\"'\")) {\n return value;\n }\n\n return /\\s/u.test(value) ? `\"${value.replace(QUOTE_RE, '\\\\\"')}\"` : value;\n}\n\nfunction resolvePretextWhiteSpace(whiteSpace) {\n return whiteSpace === \"pre-wrap\" ? \"pre-wrap\" : \"normal\";\n}\n\nfunction isHardBreak(prepared, line) {\n return prepared.kinds?.[line.end.segmentIndex] === \"hard-break\";\n}\n\nfunction normalizeNativeText(text, whiteSpace) {\n if (whiteSpace === \"pre-wrap\") {\n return String(text ?? \"\").replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n }\n\n const collapsed = String(text ?? \"\")\n .replace(/\\s+/gu, \" \")\n .trim();\n\n return collapsed;\n}\n\nfunction tokenizeNativeText(text, whiteSpace, measureWidth) {\n const tokens = [];\n let index = 0;\n\n while (index < text.length) {\n const char = text[index];\n\n if (char === \"\\n\") {\n tokens.push({\n text: \"\\n\",\n type: \"hardBreak\",\n start: index,\n end: index + 1,\n width: 0,\n });\n index += 1;\n continue;\n }\n\n if ((char === \" \" || char === \"\\t\") && whiteSpace === \"pre-wrap\") {\n const start = index;\n\n while (index < text.length && (text[index] === \" \" || text[index] === \"\\t\")) {\n index += 1;\n }\n\n tokens.push({\n text: text.slice(start, index),\n type: \"space\",\n start,\n end: index,\n width: measureWidth(text.slice(start, index)),\n });\n continue;\n }\n\n if (char === \" \") {\n tokens.push({\n text: \" \",\n type: \"space\",\n start: index,\n end: index + 1,\n width: measureWidth(\" \"),\n });\n index += 1;\n continue;\n }\n\n const nextStop = findNextStop(text, index, whiteSpace);\n const chunk = text.slice(index, nextStop);\n\n for (const piece of segmentWords(chunk, index, measureWidth)) {\n tokens.push(piece);\n }\n\n index = nextStop;\n }\n\n return tokens;\n}\n\nfunction findNextStop(text, start, whiteSpace) {\n let index = start;\n\n while (index < text.length) {\n const char = text[index];\n\n if (char === \"\\n\") {\n break;\n }\n\n if (char === \" \" || (whiteSpace === \"pre-wrap\" && char === \"\\t\")) {\n break;\n }\n\n index += 1;\n }\n\n return index;\n}\n\nfunction segmentWords(text, baseOffset, measureWidth) {\n const pieces = [];\n const segmenter = getWordSegmenter();\n\n for (const part of segmenter.segment(text)) {\n const value = part.segment;\n\n if (value.length === 0) {\n continue;\n }\n\n pieces.push({\n text: value,\n type: /\\s/u.test(value) ? \"space\" : \"text\",\n start: baseOffset + part.index,\n end: baseOffset + part.index + value.length,\n width: measureWidth(value),\n });\n }\n\n return pieces.length > 0\n ? pieces\n : [\n {\n text,\n type: \"text\",\n start: baseOffset,\n end: baseOffset + text.length,\n width: measureWidth(text),\n },\n ];\n}\n\nfunction createTextMeasurer(fontInstance, options) {\n const cache = new Map();\n const openTypeMeasurer = createOpenTypeMeasurer(fontInstance, options);\n const context = getMeasureContext();\n\n return (value) => {\n if (value.length === 0) {\n return 0;\n }\n\n if (cache.has(value)) {\n return cache.get(value);\n }\n\n let width;\n\n if (context) {\n context.font = options.font;\n width = context.measureText(value).width;\n } else {\n width = openTypeMeasurer(value);\n }\n\n cache.set(value, width);\n return width;\n };\n}\n\nfunction createOpenTypeMeasurer(fontInstance, options) {\n const cache = new Map();\n const widthOptions = {\n x: 0,\n y: 0,\n size: options.size,\n flatten: options.flatten,\n edgeEpsilon: options.edgeEpsilon,\n kerning: options.kerning,\n letterSpacing: options.letterSpacing,\n tracking: options.tracking,\n script: options.script,\n language: options.language,\n features: options.features,\n };\n\n return (value) => {\n if (value.length === 0) {\n return 0;\n }\n\n if (cache.has(value)) {\n return cache.get(value);\n }\n\n const width = measureAdvanceWidth(fontInstance.font, value, widthOptions);\n\n cache.set(value, width);\n return width;\n };\n}\n\nfunction getMeasureContext() {\n if (sharedMeasureContext) {\n return sharedMeasureContext;\n }\n\n if (typeof OffscreenCanvas !== \"undefined\") {\n sharedMeasureContext = new OffscreenCanvas(1, 1).getContext(\"2d\");\n return sharedMeasureContext;\n }\n\n if (typeof document !== \"undefined\") {\n sharedMeasureContext = document.createElement(\"canvas\").getContext(\"2d\");\n return sharedMeasureContext;\n }\n\n return null;\n}\n\nfunction getWordSegmenter() {\n if (sharedWordSegmenter == null) {\n sharedWordSegmenter = new Intl.Segmenter(undefined, { granularity: \"word\" });\n }\n\n return sharedWordSegmenter;\n}\n\nfunction getGraphemeSegmenter() {\n if (sharedGraphemeSegmenter == null) {\n sharedGraphemeSegmenter = new Intl.Segmenter(undefined, {\n granularity: \"grapheme\",\n });\n }\n\n return sharedGraphemeSegmenter;\n}\n\nfunction trimTrailingWhitespace(value) {\n return value.replace(/\\s+$/u, \"\");\n}\n\nfunction trimLastGrapheme(value) {\n const segmenter = getGraphemeSegmenter();\n const graphemes = Array.from(segmenter.segment(value), (segment) => segment.segment);\n\n graphemes.pop();\n return graphemes.join(\"\");\n}\n\nfunction splitPreservingWhitespace(value) {\n return value.split(/(\\s+)/u).filter((token) => token.length > 0);\n}\n\nfunction getFontAscender(fontInstance, size) {\n const ascender = normalizeNumber(fontInstance?.font?.ascender, fontInstance?.unitsPerEm ?? 1000);\n const unitsPerEm = normalizePositive(fontInstance?.unitsPerEm, 1000);\n return (ascender / unitsPerEm) * size;\n}\n","import { createTextShape } from \"./shape.js\";\nimport {\n canReusePreparedParagraphState,\n layoutParagraph,\n normalizeParagraphOptions,\n resolveCanvasFont,\n} from \"./paragraphLayout.js\";\n\nexport class paParagraph {\n constructor(fontInstance, text, options, state) {\n this._font = fontInstance;\n this._state = state;\n this.text = text;\n this.options = options;\n this.lines = state.lines.map((line) => ({\n index: line.index,\n text: line.text,\n start: line.start,\n end: line.end,\n x: line.x,\n y: line.y,\n width: line.width,\n baseline: line.baseline,\n height: line.height,\n bbox: { ...line.bbox },\n }));\n this.metrics = {\n ...state.metrics,\n bbox: { ...state.metrics.bbox },\n };\n this._cache = {\n baseShapes: new Map(),\n layoutParagraphs: new Map(),\n };\n }\n\n relayout(next = {}) {\n const normalized = normalizeParagraphOptions(this._font, {\n ...this.options,\n ...next,\n });\n const state = layoutParagraph(this._font, this.text, normalized, {\n prepared: canReusePreparedParagraphState(this._state, this.options, normalized)\n ? this._state.prepared\n : null,\n preparedWhiteSpace: this._state.preparedWhiteSpace,\n font: this.options.font,\n });\n\n return new paParagraph(this._font, this.text, normalized, state);\n }\n\n line(index) {\n return this.lines[index];\n }\n\n drawText(ctx, options = {}) {\n if (!ctx || typeof ctx.fillText !== \"function\") {\n throw new TypeError(\"drawText() expects a CanvasRenderingContext2D.\");\n }\n\n const fill = options.fill !== false;\n const stroke = options.stroke === true;\n\n if (!fill && !stroke) {\n return;\n }\n\n ctx.save();\n ctx.font = resolveCanvasFont(this._font, this.options.size, this.options);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"alphabetic\";\n\n if (options.fillStyle != null) {\n ctx.fillStyle = options.fillStyle;\n }\n\n if (options.strokeStyle != null) {\n ctx.strokeStyle = options.strokeStyle;\n }\n\n this._state.lines.forEach((line) => {\n line.fragments.forEach((fragment) => {\n if (fill) {\n ctx.fillText(fragment.text, fragment.x, line.baseline);\n }\n\n if (stroke) {\n ctx.strokeText(fragment.text, fragment.x, line.baseline);\n }\n });\n });\n\n ctx.restore();\n }\n\n toShape(options = {}) {\n const { layout = \"current\", ...shapeOptions } = normalizeParagraphShapeOptions(\n options,\n \"toShape()\",\n );\n return this._getBaseShape(layout).toShape(shapeOptions);\n }\n\n toRegions(options = {}) {\n const { layout = \"current\", ...shapeOptions } = normalizeParagraphShapeOptions(\n options,\n \"toRegions()\",\n );\n return this._getBaseShape(layout).toRegions(shapeOptions);\n }\n\n toPoints(options = {}) {\n const normalized = normalizeParagraphPointOptions(options);\n const { layout = \"current\", ...pointOptions } = normalized;\n return this._getBaseShape(layout).toPoints(pointOptions);\n }\n\n _getBaseShape(layout) {\n const paragraph = this._resolveParagraph(layout);\n\n if (paragraph._cache.baseShapes.has(\"base\")) {\n return paragraph._cache.baseShapes.get(\"base\");\n }\n\n const baseShape = createTextShape(\n buildParagraphGlyphLayout(paragraph),\n paragraph.options,\n paragraph._font,\n );\n\n paragraph._cache.baseShapes.set(\"base\", baseShape);\n return baseShape;\n }\n\n _resolveParagraph(layout) {\n if (layout === \"current\") {\n return this;\n }\n\n if (layout === \"native\") {\n return this._getLayoutParagraph(\"native\");\n }\n\n if (layout === \"pretext\") {\n return this._getLayoutParagraph(\"pretext\");\n }\n\n throw new TypeError(\n 'Paragraph layout must be \"current\", \"pretext\", or \"native\".',\n );\n }\n\n _getLayoutParagraph(engine) {\n if (this.options.engine === engine) {\n return this;\n }\n\n if (this._cache.layoutParagraphs.has(engine)) {\n return this._cache.layoutParagraphs.get(engine);\n }\n\n const paragraph = this.relayout({ engine });\n this._cache.layoutParagraphs.set(engine, paragraph);\n return paragraph;\n }\n}\n\nexport function createParagraph(fontInstance, text, options = {}, state = {}) {\n const normalized = normalizeParagraphOptions(fontInstance, options);\n const layoutState = layoutParagraph(fontInstance, text, normalized, state);\n return new paParagraph(fontInstance, text, normalized, layoutState);\n}\n\nfunction buildParagraphGlyphLayout(paragraph) {\n const glyphs = [];\n const glyphOptions = {\n x: 0,\n y: 0,\n size: paragraph.options.size,\n flatten: paragraph.options.flatten,\n edgeEpsilon: paragraph.options.edgeEpsilon,\n kerning: paragraph.options.kerning,\n letterSpacing: paragraph.options.letterSpacing,\n tracking: paragraph.options.tracking,\n script: paragraph.options.script,\n language: paragraph.options.language,\n features: paragraph.options.features,\n };\n\n paragraph._state.lines.forEach((line) => {\n line.fragments.forEach((fragment) => {\n if (fragment.text.length === 0) {\n return;\n }\n\n const layout = paragraph._font._layoutText(fragment.text, {\n ...glyphOptions,\n x: fragment.x,\n y: line.baseline,\n });\n\n glyphs.push(...layout.glyphs);\n });\n });\n\n return {\n text: paragraph.text,\n glyphs,\n metrics: {\n x: paragraph.metrics.x,\n y: paragraph.metrics.y,\n size: paragraph.options.size,\n width: paragraph.metrics.width,\n },\n };\n}\n\nfunction normalizeParagraphShapeOptions(options = {}, callerName) {\n if (options == null) {\n return { layout: \"current\" };\n }\n\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(`${callerName} expects an options object.`);\n }\n\n return {\n ...options,\n layout: options.layout ?? \"current\",\n };\n}\n\nfunction normalizeParagraphPointOptions(options = {}) {\n if (options == null) {\n return { layout: \"current\" };\n }\n\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(\"toPoints() expects an options object.\");\n }\n\n return {\n ...options,\n layout: options.layout ?? \"current\",\n };\n}\n","import { load as loadFont, parse as parseFont } from \"opentype.js\";\nimport {\n buildGlyphTopology,\n flattenGlyphTopology,\n layoutGlyphs,\n measureText,\n normalizeTextOptions,\n toArrayBuffer,\n} from \"./core.js\";\nimport { createParagraph } from \"./paragraph.js\";\nimport { createTextShape } from \"./shape.js\";\n\nexport class paFont {\n constructor(font) {\n this.font = font;\n this.unitsPerEm = font.unitsPerEm ?? 1000;\n this._glyphTopologyCache = new Map();\n this._glyphFlatCache = new Map();\n }\n\n static async load(source, options = {}) {\n const opts = normalizeLoadOptions(options);\n\n if (source instanceof ArrayBuffer || ArrayBuffer.isView(source)) {\n return new paFont(parseFont(toArrayBuffer(source)));\n }\n\n if (typeof window !== \"undefined\") {\n const requestUrl = resolveBrowserFontSource(source, opts.base);\n const bytes = await fetchFontBytes(requestUrl);\n return new paFont(parseFont(bytes));\n }\n\n const { target, loadOptions } = await resolveNodeFontSource(\n source,\n opts.base,\n );\n const font = await loadFont(target, undefined, loadOptions);\n return new paFont(font);\n }\n\n text(value, options = {}) {\n const opts = normalizeTextOptions(options);\n const layout = this._layoutText(String(value ?? \"\"), opts);\n return createTextShape(layout, opts, this);\n }\n\n glyph(value, options = {}) {\n const opts = normalizeTextOptions(options);\n const glyph = this.font.charToGlyph(String(value ?? \"\"));\n const layout = {\n text: String(value ?? \"\"),\n glyphs: [\n {\n glyph,\n x: opts.x,\n y: opts.y,\n size: opts.size,\n index: 0,\n },\n ],\n metrics: {\n width: (glyph.advanceWidth ?? 0) * (opts.size / this.unitsPerEm),\n x: opts.x,\n y: opts.y,\n size: opts.size,\n },\n };\n\n return createTextShape(layout, opts, this);\n }\n\n metrics(value, options = {}) {\n const opts = normalizeTextOptions(options);\n return measureText(this.font, String(value ?? \"\"), opts);\n }\n\n paragraph(value, options = {}) {\n return createParagraph(this, String(value ?? \"\"), options);\n }\n\n _getGlyphTopology(glyph) {\n const key = String(glyph.index);\n\n if (!this._glyphTopologyCache.has(key)) {\n this._glyphTopologyCache.set(\n key,\n buildGlyphTopology(glyph, this.unitsPerEm),\n );\n }\n\n return this._glyphTopologyCache.get(key);\n }\n\n _getFlattenedGlyph(glyph, opts) {\n const key = `${glyph.index}:${opts.size}:${opts.flatten}`;\n\n if (!this._glyphFlatCache.has(key)) {\n const topology = this._getGlyphTopology(glyph);\n this._glyphFlatCache.set(\n key,\n flattenGlyphTopology(topology, {\n size: opts.size,\n flatten: opts.flatten,\n }),\n );\n }\n\n return this._glyphFlatCache.get(key);\n }\n\n _layoutText(value, opts) {\n return layoutGlyphs(this.font, value, opts);\n }\n}\n\nasync function fetchFontBytes(source) {\n const response = await fetch(source);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load font from ${source}: ${response.status} ${response.statusText}`,\n );\n }\n\n const bytes = await response.arrayBuffer();\n const signature = readSignature(bytes);\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"text/html\") || isHtmlSignature(signature)) {\n throw new Error(\n `Font URL returned HTML instead of font data: ${source}. Use a public font URL like \"/assets/font.otf\", or pass { base: import.meta.url } when loading a module-relative string path. Plain string paths in the browser are resolved from the current page URL.`,\n );\n }\n\n return bytes;\n}\n\nfunction normalizeLoadOptions(options = {}) {\n if (options == null) {\n return {};\n }\n\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(\"paFont.load() options must be an object.\");\n }\n\n return options;\n}\n\nfunction resolveBrowserFontSource(source, base) {\n if (source instanceof URL) {\n return source.href;\n }\n\n if (typeof source !== \"string\") {\n throw new TypeError(\n \"paFont.load() expects a string, URL, ArrayBuffer, or ArrayBufferView.\",\n );\n }\n\n if (base == null) {\n return source;\n }\n\n return new URL(source, normalizeBase(base)).href;\n}\n\nasync function resolveNodeFontSource(source, base) {\n if (source instanceof URL) {\n return toNodeLoadTarget(source);\n }\n\n if (typeof source !== \"string\") {\n throw new TypeError(\n \"paFont.load() expects a string, URL, ArrayBuffer, or ArrayBufferView.\",\n );\n }\n\n if (base == null) {\n if (isLoadableUrlString(source)) {\n return toNodeLoadTarget(new URL(source));\n }\n\n return {\n target: source,\n loadOptions: undefined,\n };\n }\n\n return toNodeLoadTarget(new URL(source, normalizeBase(base)));\n}\n\nfunction normalizeBase(base) {\n if (base instanceof URL) {\n return base;\n }\n\n if (typeof base === \"string\") {\n return base;\n }\n\n throw new TypeError('paFont.load() option \"base\" must be a string or URL.');\n}\n\nasync function toNodeLoadTarget(url) {\n if (url.protocol === \"file:\") {\n return {\n target: fileUrlToPath(url),\n loadOptions: undefined,\n };\n }\n\n return {\n target: url.href,\n loadOptions: {\n isUrl: true,\n },\n };\n}\n\nfunction fileUrlToPath(url) {\n const pathname = decodeURIComponent(url.pathname);\n\n if (/^\\/[a-zA-Z]:/.test(pathname)) {\n return pathname.slice(1);\n }\n\n if (url.hostname) {\n return `//${url.hostname}${pathname}`;\n }\n\n return pathname;\n}\n\nfunction isLoadableUrlString(value) {\n return (\n value.startsWith(\"http://\") ||\n value.startsWith(\"https://\") ||\n value.startsWith(\"file://\")\n );\n}\n\nfunction readSignature(bytes) {\n const view = new Uint8Array(bytes, 0, Math.min(4, bytes.byteLength));\n let signature = \"\";\n\n for (const value of view) {\n signature += String.fromCharCode(value);\n }\n\n return signature.toLowerCase();\n}\n\nfunction isHtmlSignature(signature) {\n return signature === \"<!do\" || signature === \"<htm\";\n}\n\nexport default paFont;\n"],"x_google_ignoreList":[3,4,5,6,7],"mappings":"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;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAClE;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAM;CAAM;CAAM;CACnE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAO;CAAM;CAAM;CAAM;CACnE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CACrE;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAM;CACrE;CAAO;CAAO;CAAO;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CACrE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CACnD;AACD,SAA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"}
1
+ {"version":3,"file":"paFont.cjs","names":["sharedWordSegmenter","sharedGraphemeSegmenter","getMeasureContext","getSharedGraphemeSegmenter","sharedGraphemeSegmenter"],"sources":["../src/paFont/geometry.js","../src/paFont/core.js","../src/paFont/shape.js","../node_modules/@chenglou/pretext/dist/bidi.js","../node_modules/@chenglou/pretext/dist/analysis.js","../node_modules/@chenglou/pretext/dist/measurement.js","../node_modules/@chenglou/pretext/dist/line-break.js","../node_modules/@chenglou/pretext/dist/layout.js","../src/paFont/paragraphLayout.js","../src/paFont/paragraph.js","../src/paFont/paFont.js"],"sourcesContent":["export function toScreenPoint(point, scale) {\n return [point.x * scale, -point.y * scale];\n}\n\nexport function cloneRawPoint(point) {\n return { x: point.x, y: point.y };\n}\n\nexport function pushUniquePoint(points, point) {\n if (points.length === 0 || !pointsEqual2D(points[points.length - 1], point)) {\n points.push(point);\n }\n}\n\nexport function flattenQuadratic(p0, p1, p2, tolerance, out, depth = 0) {\n if (depth >= 12 || quadFlatness(p0, p1, p2) <= tolerance) {\n pushUniquePoint(out, p2);\n return;\n }\n\n const p01 = midpoint(p0, p1);\n const p12 = midpoint(p1, p2);\n const p012 = midpoint(p01, p12);\n\n flattenQuadratic(p0, p01, p012, tolerance, out, depth + 1);\n flattenQuadratic(p012, p12, p2, tolerance, out, depth + 1);\n}\n\nexport function flattenCubic(p0, p1, p2, p3, tolerance, out, depth = 0) {\n if (depth >= 12 || cubicFlatness(p0, p1, p2, p3) <= tolerance) {\n pushUniquePoint(out, p3);\n return;\n }\n\n const p01 = midpoint(p0, p1);\n const p12 = midpoint(p1, p2);\n const p23 = midpoint(p2, p3);\n const p012 = midpoint(p01, p12);\n const p123 = midpoint(p12, p23);\n const p0123 = midpoint(p012, p123);\n\n flattenCubic(p0, p01, p012, p0123, tolerance, out, depth + 1);\n flattenCubic(p0123, p123, p23, p3, tolerance, out, depth + 1);\n}\n\nfunction quadFlatness(p0, p1, p2) {\n return pointToLineDistance(p1, p0, p2);\n}\n\nfunction cubicFlatness(p0, p1, p2, p3) {\n return Math.max(\n pointToLineDistance(p1, p0, p3),\n pointToLineDistance(p2, p0, p3)\n );\n}\n\nfunction pointToLineDistance(point, lineStart, lineEnd) {\n const dx = lineEnd[0] - lineStart[0];\n const dy = lineEnd[1] - lineStart[1];\n const lengthSq = dx * dx + dy * dy;\n\n if (lengthSq === 0) {\n return distance(point, lineStart);\n }\n\n const area = Math.abs(\n dx * (lineStart[1] - point[1]) - (lineStart[0] - point[0]) * dy\n );\n\n return area / Math.sqrt(lengthSq);\n}\n\nexport function midpoint(a, b) {\n return [(a[0] + b[0]) * 0.5, (a[1] + b[1]) * 0.5];\n}\n\nexport function signedArea(ring) {\n let area = 0;\n\n for (let index = 0; index < ring.length; index += 1) {\n const current = ring[index];\n const next = ring[(index + 1) % ring.length];\n area += current[0] * next[1] - next[0] * current[1];\n }\n\n return area * 0.5;\n}\n\nexport function pointInRing(point, ring) {\n let inside = false;\n\n for (let i = 0, j = ring.length - 1; i < ring.length; j = i, i += 1) {\n const xi = ring[i][0];\n const yi = ring[i][1];\n const xj = ring[j][0];\n const yj = ring[j][1];\n const intersects =\n yi > point[1] !== yj > point[1] &&\n point[0] < ((xj - xi) * (point[1] - yi)) / (yj - yi || 1e-9) + xi;\n\n if (intersects) {\n inside = !inside;\n }\n }\n\n return inside;\n}\n\nexport function hitPart(point, part, epsilon) {\n if (!rectContainsPoint(part.bbox, point, epsilon)) {\n return \"outside\";\n }\n\n if (isPointOnRingEdge(point, part.outer, epsilon)) {\n return \"edge\";\n }\n\n if (!pointInRing(point, part.outer)) {\n return \"outside\";\n }\n\n for (const hole of part.holes) {\n if (isPointOnRingEdge(point, hole, epsilon)) {\n return \"edge\";\n }\n\n if (pointInRing(point, hole)) {\n return \"hole\";\n }\n }\n\n return \"fill\";\n}\n\nfunction isPointOnRingEdge(point, ring, epsilon) {\n for (let index = 0; index < ring.length; index += 1) {\n const a = ring[index];\n const b = ring[(index + 1) % ring.length];\n\n if (distancePointToSegment(point, a, b) <= epsilon) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction distancePointToSegment(point, a, b) {\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const lengthSq = dx * dx + dy * dy;\n\n if (lengthSq === 0) {\n return distance(point, a);\n }\n\n let t = ((point[0] - a[0]) * dx + (point[1] - a[1]) * dy) / lengthSq;\n t = Math.max(0, Math.min(1, t));\n\n const projection = [a[0] + dx * t, a[1] + dy * t];\n return distance(point, projection);\n}\n\nexport function distance(a, b) {\n const dx = a[0] - b[0];\n const dy = a[1] - b[1];\n return Math.sqrt(dx * dx + dy * dy);\n}\n\nexport function sampleRing(ring, step, callback) {\n for (let index = 0; index < ring.length; index += 1) {\n const a = ring[index];\n const b = ring[(index + 1) % ring.length];\n const segmentLength = distance(a, b);\n const divisions = Math.max(1, Math.ceil(segmentLength / step));\n\n for (let offset = 0; offset < divisions; offset += 1) {\n if (index > 0 || offset > 0) {\n const t = offset / divisions;\n callback([\n a[0] + (b[0] - a[0]) * t,\n a[1] + (b[1] - a[1]) * t,\n ]);\n } else {\n callback([a[0], a[1]]);\n }\n }\n }\n}\n\nexport function ringBounds(ring) {\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n\n ring.forEach((point) => {\n minX = Math.min(minX, point[0]);\n minY = Math.min(minY, point[1]);\n maxX = Math.max(maxX, point[0]);\n maxY = Math.max(maxY, point[1]);\n });\n\n return {\n x: minX,\n y: minY,\n w: maxX - minX,\n h: maxY - minY,\n };\n}\n\nexport function translateRing(ring, tx, ty) {\n return ring.map((point) => [point[0] + tx, point[1] + ty]);\n}\n\nexport function translateRect(rect, tx, ty) {\n return {\n x: rect.x + tx,\n y: rect.y + ty,\n w: rect.w,\n h: rect.h,\n };\n}\n\nexport function copyRing(ring) {\n return ring.map((point) => [point[0], point[1]]);\n}\n\nexport function combineRects(rects) {\n if (rects.length === 0) {\n return null;\n }\n\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n\n rects.forEach((rect) => {\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.w);\n maxY = Math.max(maxY, rect.y + rect.h);\n });\n\n return {\n x: minX,\n y: minY,\n w: maxX - minX,\n h: maxY - minY,\n };\n}\n\nexport function rectContainsRect(outer, inner, epsilon = 1e-6) {\n return (\n inner.x >= outer.x - epsilon &&\n inner.y >= outer.y - epsilon &&\n inner.x + inner.w <= outer.x + outer.w + epsilon &&\n inner.y + inner.h <= outer.y + outer.h + epsilon\n );\n}\n\nexport function rectContainsPoint(rect, point, epsilon = 0) {\n return (\n point[0] >= rect.x - epsilon &&\n point[0] <= rect.x + rect.w + epsilon &&\n point[1] >= rect.y - epsilon &&\n point[1] <= rect.y + rect.h + epsilon\n );\n}\n\nexport function emptyRect() {\n return { x: 0, y: 0, w: 0, h: 0 };\n}\n\nexport function normalizeNumber(value, fallback) {\n return Number.isFinite(value) ? value : fallback;\n}\n\nexport function normalizePositive(value, fallback) {\n return Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\nexport function samePoint(a, b) {\n return a.x === b.x && a.y === b.y;\n}\n\nexport function pointsEqual2D(a, b) {\n return a[0] === b[0] && a[1] === b[1];\n}\n\nexport function pointsAlmostEqual2D(a, b, epsilon = 1e-6) {\n return Math.abs(a[0] - b[0]) <= epsilon && Math.abs(a[1] - b[1]) <= epsilon;\n}\n\nexport function ringPerimeter(ring) {\n let total = 0;\n\n for (let index = 0; index < ring.length; index += 1) {\n total += distance(ring[index], ring[(index + 1) % ring.length]);\n }\n\n return total;\n}\n\nexport function polylineLength(path) {\n let total = 0;\n\n for (let index = 0; index < path.length - 1; index += 1) {\n total += distance(path[index], path[index + 1]);\n }\n\n return total;\n}\n\nexport function pointAtClosedPathDistance(ring, distanceAlong) {\n const perimeter = ringPerimeter(ring);\n\n if (perimeter <= 1e-9) {\n return [ring[0][0], ring[0][1]];\n }\n\n let remaining = mod(distanceAlong, perimeter);\n\n for (let index = 0; index < ring.length; index += 1) {\n const start = ring[index];\n const end = ring[(index + 1) % ring.length];\n const segmentLength = distance(start, end);\n\n if (segmentLength <= 1e-9) {\n continue;\n }\n\n if (remaining <= segmentLength) {\n const t = remaining / segmentLength;\n return [\n start[0] + (end[0] - start[0]) * t,\n start[1] + (end[1] - start[1]) * t,\n ];\n }\n\n remaining -= segmentLength;\n }\n\n return [ring[ring.length - 1][0], ring[ring.length - 1][1]];\n}\n\nexport function pointAtOpenPathDistance(path, distanceAlong) {\n if (distanceAlong <= 0) {\n return [path[0][0], path[0][1]];\n }\n\n let remaining = distanceAlong;\n\n for (let index = 0; index < path.length - 1; index += 1) {\n const start = path[index];\n const end = path[index + 1];\n const segmentLength = distance(start, end);\n\n if (segmentLength <= 1e-9) {\n continue;\n }\n\n if (remaining <= segmentLength) {\n const t = remaining / segmentLength;\n return [\n start[0] + (end[0] - start[0]) * t,\n start[1] + (end[1] - start[1]) * t,\n ];\n }\n\n remaining -= segmentLength;\n }\n\n return [path[path.length - 1][0], path[path.length - 1][1]];\n}\n\nexport function segmentIntersectsRing(a, b, ring, ignoredEdges, epsilon) {\n for (let index = 0; index < ring.length; index += 1) {\n if (ignoredEdges.has(index)) {\n continue;\n }\n\n const c = ring[index];\n const d = ring[(index + 1) % ring.length];\n\n if (segmentsIntersect(a, b, c, d, epsilon)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction segmentsIntersect(a, b, c, d, epsilon) {\n const o1 = orientation(a, b, c);\n const o2 = orientation(a, b, d);\n const o3 = orientation(c, d, a);\n const o4 = orientation(c, d, b);\n\n if (\n ((o1 > epsilon && o2 < -epsilon) || (o1 < -epsilon && o2 > epsilon)) &&\n ((o3 > epsilon && o4 < -epsilon) || (o3 < -epsilon && o4 > epsilon))\n ) {\n return true;\n }\n\n if (Math.abs(o1) <= epsilon && pointOnSegment(c, a, b, epsilon)) {\n return true;\n }\n\n if (Math.abs(o2) <= epsilon && pointOnSegment(d, a, b, epsilon)) {\n return true;\n }\n\n if (Math.abs(o3) <= epsilon && pointOnSegment(a, c, d, epsilon)) {\n return true;\n }\n\n if (Math.abs(o4) <= epsilon && pointOnSegment(b, c, d, epsilon)) {\n return true;\n }\n\n return false;\n}\n\nfunction orientation(a, b, c) {\n return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);\n}\n\nfunction pointOnSegment(point, start, end, epsilon) {\n return (\n point[0] >= Math.min(start[0], end[0]) - epsilon &&\n point[0] <= Math.max(start[0], end[0]) + epsilon &&\n point[1] >= Math.min(start[1], end[1]) - epsilon &&\n point[1] <= Math.max(start[1], end[1]) + epsilon\n );\n}\n\nexport function mod(value, divisor) {\n return ((value % divisor) + divisor) % divisor;\n}\n","import {\n cloneRawPoint,\n combineRects,\n copyRing,\n emptyRect,\n flattenCubic,\n flattenQuadratic,\n normalizeNumber,\n normalizePositive,\n pointInRing,\n pointsEqual2D,\n pushUniquePoint,\n rectContainsRect,\n ringBounds,\n samePoint,\n signedArea,\n toScreenPoint,\n translateRect,\n translateRing,\n} from \"./geometry.js\";\n\nexport function layoutGlyphs(font, value, opts) {\n const glyphs = [];\n const renderOptions = toRenderOptions(opts);\n const endX = font.forEachGlyph(\n value,\n opts.x,\n opts.y,\n opts.size,\n renderOptions,\n (glyph, x, y, size) => {\n glyphs.push({\n glyph,\n x,\n y,\n size,\n index: glyphs.length,\n });\n }\n );\n\n return {\n text: value,\n glyphs,\n metrics: {\n width: endX - opts.x,\n x: opts.x,\n y: opts.y,\n size: opts.size,\n },\n };\n}\n\nexport function measureText(font, value, opts) {\n const renderOptions = toRenderOptions(opts);\n const path = font.getPath(value, opts.x, opts.y, opts.size, renderOptions);\n const box = path.getBoundingBox();\n\n return {\n width: measureAdvanceWidth(font, value, opts),\n bbox: {\n x: box.x1,\n y: box.y1,\n w: box.x2 - box.x1,\n h: box.y2 - box.y1,\n },\n };\n}\n\nexport function measureAdvanceWidth(font, value, opts) {\n return font.getAdvanceWidth(value, opts.size, toRenderOptions(opts));\n}\n\nexport function buildGlyphTopology(glyph, fallbackUnitsPerEm) {\n const commands = glyph.path?.commands ?? [];\n const contours = [];\n let contourId = 0;\n let current = null;\n\n const finishCurrentContour = () => {\n if (!current || current.segments.length === 0) {\n current = null;\n return;\n }\n\n if (!samePoint(current.cursor, current.start)) {\n current.segments.push({\n type: \"L\",\n from: cloneRawPoint(current.cursor),\n to: cloneRawPoint(current.start),\n });\n current.cursor = cloneRawPoint(current.start);\n }\n\n contours.push({\n id: contourId++,\n start: cloneRawPoint(current.start),\n segments: current.segments,\n });\n current = null;\n };\n\n commands.forEach((cmd) => {\n if (cmd.type === \"M\") {\n finishCurrentContour();\n current = {\n start: { x: cmd.x, y: cmd.y },\n cursor: { x: cmd.x, y: cmd.y },\n segments: [],\n };\n return;\n }\n\n if (!current) {\n return;\n }\n\n if (cmd.type === \"L\") {\n const to = { x: cmd.x, y: cmd.y };\n current.segments.push({\n type: \"L\",\n from: cloneRawPoint(current.cursor),\n to,\n });\n current.cursor = cloneRawPoint(to);\n return;\n }\n\n if (cmd.type === \"Q\") {\n const to = { x: cmd.x, y: cmd.y };\n current.segments.push({\n type: \"Q\",\n from: cloneRawPoint(current.cursor),\n c1: { x: cmd.x1, y: cmd.y1 },\n to,\n });\n current.cursor = cloneRawPoint(to);\n return;\n }\n\n if (cmd.type === \"C\") {\n const to = { x: cmd.x, y: cmd.y };\n current.segments.push({\n type: \"C\",\n from: cloneRawPoint(current.cursor),\n c1: { x: cmd.x1, y: cmd.y1 },\n c2: { x: cmd.x2, y: cmd.y2 },\n to,\n });\n current.cursor = cloneRawPoint(to);\n return;\n }\n\n if (cmd.type === \"Z\") {\n finishCurrentContour();\n }\n });\n\n finishCurrentContour();\n\n return {\n glyphIndex: glyph.index,\n advanceWidth: glyph.advanceWidth ?? 0,\n unitsPerEm: glyph.path?.unitsPerEm ?? fallbackUnitsPerEm ?? 1000,\n contours,\n };\n}\n\nexport function flattenGlyphTopology(topology, options) {\n const scale = options.size / topology.unitsPerEm;\n const contours = topology.contours\n .map((contour) => flattenContour(contour, scale, options.flatten))\n .filter(Boolean);\n const classifiedContours = classifyContours(contours);\n const parts = buildParts(classifiedContours);\n const bbox = combineRects(parts.map((part) => part.bbox)) ?? emptyRect();\n\n return {\n glyphIndex: topology.glyphIndex,\n advanceWidth: topology.advanceWidth * scale,\n contours: classifiedContours,\n parts,\n bbox,\n };\n}\n\nfunction flattenContour(contour, scale, tolerance) {\n const ring = [];\n const start = toScreenPoint(contour.start, scale);\n pushUniquePoint(ring, start);\n\n contour.segments.forEach((segment) => {\n if (segment.type === \"L\") {\n pushUniquePoint(ring, toScreenPoint(segment.to, scale));\n return;\n }\n\n if (segment.type === \"Q\") {\n flattenQuadratic(\n toScreenPoint(segment.from, scale),\n toScreenPoint(segment.c1, scale),\n toScreenPoint(segment.to, scale),\n tolerance,\n ring\n );\n return;\n }\n\n if (segment.type === \"C\") {\n flattenCubic(\n toScreenPoint(segment.from, scale),\n toScreenPoint(segment.c1, scale),\n toScreenPoint(segment.c2, scale),\n toScreenPoint(segment.to, scale),\n tolerance,\n ring\n );\n }\n });\n\n if (ring.length > 1 && pointsEqual2D(ring[0], ring[ring.length - 1])) {\n ring.pop();\n }\n\n if (ring.length < 3) {\n return null;\n }\n\n const bbox = ringBounds(ring);\n const area = signedArea(ring);\n\n return {\n id: contour.id,\n ring,\n bbox,\n area,\n };\n}\n\nfunction classifyContours(contours) {\n const result = contours.map((contour) => ({\n ...contour,\n parentId: null,\n depth: 0,\n role: \"outer\",\n }));\n\n result.forEach((child) => {\n let parent = null;\n let parentArea = Number.POSITIVE_INFINITY;\n\n result.forEach((candidate) => {\n if (candidate.id === child.id) {\n return;\n }\n\n if (Math.abs(candidate.area) <= Math.abs(child.area)) {\n return;\n }\n\n if (!rectContainsRect(candidate.bbox, child.bbox)) {\n return;\n }\n\n if (!pointInRing(child.ring[0], candidate.ring)) {\n return;\n }\n\n const candidateArea = Math.abs(candidate.area);\n if (candidateArea < parentArea) {\n parent = candidate;\n parentArea = candidateArea;\n }\n });\n\n if (parent) {\n child.parentId = parent.id;\n }\n });\n\n const byId = new Map(result.map((contour) => [contour.id, contour]));\n\n const resolveDepth = (contour) => {\n if (contour.parentId == null) {\n return 0;\n }\n\n const parent = byId.get(contour.parentId);\n return resolveDepth(parent) + 1;\n };\n\n result.forEach((contour) => {\n contour.depth = resolveDepth(contour);\n contour.role = contour.depth % 2 === 0 ? \"outer\" : \"hole\";\n });\n\n return result;\n}\n\nfunction buildParts(contours) {\n return contours\n .filter((contour) => contour.role === \"outer\")\n .map((outer) => {\n const holeContours = contours.filter(\n (contour) => contour.parentId === outer.id && contour.role === \"hole\"\n );\n\n return {\n outer: copyRing(outer.ring),\n holes: holeContours.map((hole) => copyRing(hole.ring)),\n bbox: { ...outer.bbox },\n area:\n Math.abs(outer.area) -\n holeContours.reduce((sum, hole) => sum + Math.abs(hole.area), 0),\n };\n });\n}\n\nexport function translateGlyphGeometry(geometry, tx, ty, glyphPosition) {\n const parts = geometry.parts.map((part, partIndex) => ({\n outer: translateRing(part.outer, tx, ty),\n holes: part.holes.map((hole) => translateRing(hole, tx, ty)),\n bbox: translateRect(part.bbox, tx, ty),\n area: part.area,\n glyphPosition,\n partIndex,\n }));\n\n const contours = geometry.contours.map((contour) => ({\n id: `${glyphPosition}:${contour.id}`,\n sourceId: contour.id,\n glyphPosition,\n parentId:\n contour.parentId == null ? null : `${glyphPosition}:${contour.parentId}`,\n depth: contour.depth,\n role: contour.role,\n area: contour.area,\n bbox: translateRect(contour.bbox, tx, ty),\n ring: translateRing(contour.ring, tx, ty),\n }));\n\n return {\n parts,\n contours,\n bbox: translateRect(geometry.bbox, tx, ty),\n };\n}\n\nexport function normalizeTextOptions(options = {}) {\n const size = normalizePositive(options.size, 72);\n\n return {\n x: normalizeNumber(options.x, 0),\n y: normalizeNumber(options.y, 0),\n size,\n flatten: normalizePositive(options.flatten, 1.25),\n edgeEpsilon:\n options.edgeEpsilon == null\n ? defaultEdgeEpsilon(size)\n : normalizePositive(options.edgeEpsilon, defaultEdgeEpsilon(size)),\n kerning: options.kerning !== false,\n letterSpacing:\n options.letterSpacing == null\n ? undefined\n : normalizeNumber(options.letterSpacing, 0),\n tracking:\n options.tracking == null\n ? undefined\n : normalizeNumber(options.tracking, 0),\n script: options.script,\n language: options.language,\n features: options.features,\n };\n}\n\nfunction defaultEdgeEpsilon(size) {\n return Math.min(1, Math.max(0.01, size * 0.0025));\n}\n\nfunction toRenderOptions(opts) {\n const renderOptions = {\n kerning: opts.kerning,\n };\n\n if (opts.letterSpacing != null) {\n renderOptions.letterSpacing = opts.letterSpacing;\n }\n\n if (opts.tracking != null) {\n renderOptions.tracking = opts.tracking;\n }\n\n if (opts.script) {\n renderOptions.script = opts.script;\n }\n\n if (opts.language) {\n renderOptions.language = opts.language;\n }\n\n if (opts.features) {\n renderOptions.features = opts.features;\n }\n\n return renderOptions;\n}\n\nexport function toArrayBuffer(value) {\n if (value instanceof ArrayBuffer) {\n return value;\n }\n\n if (ArrayBuffer.isView(value)) {\n return value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength);\n }\n\n return value;\n}\n","import {\n combineRects,\n copyRing,\n distance,\n emptyRect,\n hitPart,\n midpoint,\n mod,\n normalizeNumber,\n normalizePositive,\n pointAtClosedPathDistance,\n pointAtOpenPathDistance,\n pointInRing,\n pointsAlmostEqual2D,\n polylineLength,\n rectContainsPoint,\n ringBounds,\n ringPerimeter,\n sampleRing,\n segmentIntersectsRing,\n signedArea,\n} from \"./geometry.js\";\nimport { translateGlyphGeometry } from \"./core.js\";\n\nexport class PAShape {\n constructor({ text, parts, contours, glyphs, bbox, metrics, edgeEpsilon }) {\n this.text = text;\n this.parts = parts;\n this.bbox = bbox;\n this.metrics = metrics;\n this.edgeEpsilon = edgeEpsilon;\n this.raw = {\n contours,\n glyphs,\n };\n this._cache = {\n glyphs: null,\n openHoles: new Map(),\n resample: new Map(),\n shapes: new Map(),\n regionViews: null,\n };\n }\n\n get polygons() {\n return this.parts.map((part) => [part.outer, ...part.holes]);\n }\n\n [Symbol.iterator]() {\n return this._getRegionViews()[Symbol.iterator]();\n }\n\n glyphs() {\n if (this._cache.glyphs) {\n return this._cache.glyphs;\n }\n\n if (!Array.isArray(this.raw.glyphs) || this.raw.glyphs.length <= 1) {\n this._cache.glyphs = [this];\n return this._cache.glyphs;\n }\n\n this._cache.glyphs = this.raw.glyphs.map((_, glyphPosition) =>\n createGlyphShape(this, glyphPosition)\n );\n\n return this._cache.glyphs;\n }\n\n toShape(options = {}) {\n return resolveShapeVariant(this, options);\n }\n\n toRegions(options = {}) {\n const shape = this.toShape(options);\n return createRegionCollection(shape);\n }\n\n openHoles(width) {\n const slitWidth = normalizePositive(width, 0);\n\n if (slitWidth <= 0 || !this.parts.some((part) => part.holes.length > 0)) {\n return this;\n }\n\n const cacheKey = toCacheKey(slitWidth);\n const cached = this._cache.openHoles.get(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const geometryEpsilon = resolveGeometryEpsilon(slitWidth);\n\n const shape = createDerivedShape(\n this,\n this.parts.map((part) => openPartWithSlit(part, slitWidth, geometryEpsilon))\n );\n\n this._cache.openHoles.set(cacheKey, shape);\n return shape;\n }\n\n resample(step) {\n const spacing = normalizePositive(step, 0);\n\n if (spacing <= 0) {\n return this;\n }\n\n const cacheKey = toCacheKey(spacing);\n const cached = this._cache.resample.get(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const shape = createDerivedShape(\n this,\n this.parts.map((part) => resamplePart(part, spacing))\n );\n\n this._cache.resample.set(cacheKey, shape);\n return shape;\n }\n\n hit(x, y, epsilon = this.edgeEpsilon) {\n const point = [x, y];\n\n if (!rectContainsPoint(this.bbox, point, epsilon)) {\n return \"outside\";\n }\n\n let holeHit = false;\n\n for (const part of this.parts) {\n const result = hitPart(point, part, epsilon);\n\n if (result === \"edge\" || result === \"fill\") {\n return result;\n }\n\n if (result === \"hole\") {\n holeHit = true;\n }\n }\n\n return holeHit ? \"hole\" : \"outside\";\n }\n\n contains(x, y, epsilon = this.edgeEpsilon) {\n return this.hit(x, y, epsilon) === \"fill\";\n }\n\n toPoints(options = {}) {\n const opts = normalizePointOptions(options);\n const shape =\n opts.openWidth > 0 ? this.toShape({ openWidth: opts.openWidth }) : this;\n const step = opts.step;\n const includeHoles = opts.includeHoles;\n const sampled = [];\n\n shape.parts.forEach((part, partIndex) => {\n sampleRing(part.outer, step, (point) => {\n sampled.push({\n x: point[0],\n y: point[1],\n partIndex,\n hole: false,\n });\n });\n\n if (!includeHoles) {\n return;\n }\n\n part.holes.forEach((hole, holeIndex) => {\n sampleRing(hole, step, (point) => {\n sampled.push({\n x: point[0],\n y: point[1],\n partIndex,\n hole: true,\n holeIndex,\n });\n });\n });\n });\n\n return sampled;\n }\n\n _getRegionViews() {\n if (!this._cache.regionViews) {\n this._cache.regionViews = this.parts.map((part) =>\n Object.freeze({\n outer: part.outer,\n holes: part.holes,\n bbox: part.bbox,\n })\n );\n }\n\n return this._cache.regionViews;\n }\n}\n\nexport function createTextShape(layout, opts, fontInstance) {\n const parts = [];\n const contours = [];\n const glyphs = [];\n\n layout.glyphs.forEach((item, glyphPosition) => {\n const localGeometry = fontInstance._getFlattenedGlyph(item.glyph, opts);\n const translated = translateGlyphGeometry(\n localGeometry,\n item.x,\n item.y,\n glyphPosition\n );\n\n parts.push(...translated.parts);\n contours.push(...translated.contours);\n glyphs.push({\n position: glyphPosition,\n glyphIndex: item.glyph.index,\n x: item.x,\n y: item.y,\n size: item.size,\n bbox: translated.bbox,\n partCount: translated.parts.length,\n });\n });\n\n const bbox = combineRects(parts.map((part) => part.bbox)) ?? emptyRect();\n\n return new PAShape({\n text: layout.text,\n parts,\n contours,\n glyphs,\n bbox,\n metrics: {\n ...layout.metrics,\n bbox,\n },\n edgeEpsilon: opts.edgeEpsilon,\n });\n}\n\nexport function mergeShapes(shapes, options = {}) {\n if (!Array.isArray(shapes) || shapes.length === 0) {\n const bbox = emptyRect();\n\n return new PAShape({\n text: String(options.text ?? \"\"),\n parts: [],\n contours: [],\n glyphs: [],\n bbox,\n metrics: {\n x: normalizeNumber(options.x, 0),\n y: normalizeNumber(options.y, 0),\n size: normalizePositive(options.size, 0),\n width: normalizeNumber(options.width, 0),\n bbox,\n },\n edgeEpsilon: normalizePositive(options.edgeEpsilon, 0.01),\n });\n }\n\n const parts = [];\n const contours = [];\n const glyphs = [];\n let glyphOffset = 0;\n\n shapes.forEach((shape, shapeIndex) => {\n const copiedParts = copyParts(shape.parts).map((part) => ({\n ...part,\n glyphPosition:\n typeof part.glyphPosition === \"number\"\n ? part.glyphPosition + glyphOffset\n : part.glyphPosition,\n }));\n\n parts.push(...copiedParts);\n\n const copiedContours = copyContours(shape.raw.contours ?? []).map((contour) => ({\n ...contour,\n id: `${shapeIndex}:${contour.id}`,\n parentId:\n contour.parentId == null ? null : `${shapeIndex}:${contour.parentId}`,\n glyphPosition:\n typeof contour.glyphPosition === \"number\"\n ? contour.glyphPosition + glyphOffset\n : contour.glyphPosition,\n }));\n\n contours.push(...copiedContours);\n\n const copiedGlyphs = (shape.raw.glyphs ?? []).map((glyph, glyphIndex) => ({\n ...glyph,\n position: glyphOffset + glyphIndex,\n bbox: glyph.bbox ? { ...glyph.bbox } : emptyRect(),\n }));\n\n glyphs.push(...copiedGlyphs);\n glyphOffset += shape.raw.glyphs?.length ?? 0;\n });\n\n const bbox =\n combineRects(parts.map((part) => part.bbox)) ??\n combineRects(glyphs.map((glyph) => glyph.bbox)) ??\n emptyRect();\n const firstShape = shapes[0];\n\n return new PAShape({\n text: String(options.text ?? shapes.map((shape) => shape.text).join(\"\")),\n parts,\n contours,\n glyphs,\n bbox,\n metrics: {\n x: normalizeNumber(options.x, firstShape?.metrics?.x ?? 0),\n y: normalizeNumber(options.y, firstShape?.metrics?.y ?? 0),\n size: normalizePositive(options.size, firstShape?.metrics?.size ?? 0),\n width: normalizeNumber(options.width, bbox.w),\n bbox,\n },\n edgeEpsilon: normalizePositive(\n options.edgeEpsilon,\n firstShape?.edgeEpsilon ?? 0.01,\n ),\n });\n}\n\nfunction createGlyphShape(shape, glyphPosition) {\n const glyphMeta = shape.raw.glyphs?.[glyphPosition] ?? null;\n const parts = copyParts(\n shape.parts.filter((part) => part.glyphPosition === glyphPosition)\n );\n const contours = copyContours(\n (shape.raw.contours ?? []).filter(\n (contour) => contour.glyphPosition === glyphPosition\n )\n );\n const bbox =\n combineRects(parts.map((part) => part.bbox)) ??\n (glyphMeta?.bbox ? { ...glyphMeta.bbox } : emptyRect());\n\n return new PAShape({\n text: extractGlyphText(shape.text, glyphPosition, shape.raw.glyphs?.length ?? 0),\n parts,\n contours,\n glyphs: glyphMeta ? [{ ...glyphMeta, bbox, partCount: parts.length }] : [],\n bbox,\n metrics: {\n x: glyphMeta?.x ?? shape.metrics?.x ?? 0,\n y: glyphMeta?.y ?? shape.metrics?.y ?? 0,\n size: glyphMeta?.size ?? shape.metrics?.size ?? 0,\n width: bbox.w,\n bbox,\n },\n edgeEpsilon: shape.edgeEpsilon,\n });\n}\n\nfunction createDerivedShape(shape, parts) {\n const copiedParts = copyParts(parts);\n const bbox = combineRects(copiedParts.map((part) => part.bbox)) ?? emptyRect();\n const glyphs = (shape.raw.glyphs ?? []).map((glyph, glyphPosition) => {\n const glyphParts = copiedParts.filter(\n (part) => part.glyphPosition === glyphPosition\n );\n\n return {\n ...glyph,\n bbox:\n combineRects(glyphParts.map((part) => part.bbox)) ??\n (glyph.bbox ? { ...glyph.bbox } : emptyRect()),\n partCount: glyphParts.length,\n };\n });\n\n return new PAShape({\n text: shape.text,\n parts: copiedParts,\n contours: [],\n glyphs,\n bbox,\n metrics: {\n ...shape.metrics,\n bbox,\n },\n edgeEpsilon: shape.edgeEpsilon,\n });\n}\n\nfunction createRegionCollection(shape) {\n return shape.parts.map((part) => ({\n outer: copyRing(part.outer),\n holes: part.holes.map((hole) => copyRing(hole)),\n bbox: { ...part.bbox },\n }));\n}\n\nfunction copyParts(parts) {\n return parts.map((part) => copyPart(part));\n}\n\nfunction copyPart(part) {\n return {\n ...part,\n outer: copyRing(part.outer),\n holes: part.holes.map((hole) => copyRing(hole)),\n anchors: part.anchors ? part.anchors.map((point) => [point[0], point[1]]) : undefined,\n bbox: { ...part.bbox },\n };\n}\n\nfunction copyContours(contours) {\n return contours.map((contour) => ({\n ...contour,\n bbox: { ...contour.bbox },\n ring: copyRing(contour.ring),\n }));\n}\n\nfunction extractGlyphText(text, glyphPosition, glyphCount) {\n if (glyphCount <= 1) {\n return text;\n }\n\n const glyphText = Array.from(text ?? \"\")[glyphPosition];\n return glyphText ?? \"\";\n}\n\nfunction normalizePointOptions(options = {}) {\n if (options == null) {\n return {\n step: 8,\n openWidth: 0,\n includeHoles: true,\n };\n }\n\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(\"toPoints() expects an options object.\");\n }\n\n return {\n step: normalizePositive(options.step, 8),\n openWidth: normalizePositive(options.openWidth, 0),\n includeHoles: options.includeHoles !== false,\n };\n}\n\nfunction normalizeShapeOptions(options = {}) {\n if (options == null) {\n return {\n step: 0,\n openWidth: 0,\n };\n }\n\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(\n \"toShape() and toRegions() expect an options object.\",\n );\n }\n\n return {\n step: normalizePositive(options.step, 0),\n openWidth: normalizePositive(options.openWidth, 0),\n };\n}\n\nfunction resolveShapeVariant(shape, options = {}) {\n const normalized = normalizeShapeOptions(options);\n\n if (normalized.step <= 0 && normalized.openWidth <= 0) {\n return shape;\n }\n\n const cacheKey = `${toCacheKey(normalized.step)}:${toCacheKey(normalized.openWidth)}`;\n const cached = shape._cache.shapes.get(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n let next = shape;\n\n if (normalized.openWidth > 0) {\n next = next.openHoles(normalized.openWidth);\n }\n\n if (normalized.step > 0) {\n next = next.resample(normalized.step);\n }\n\n shape._cache.shapes.set(cacheKey, next);\n return next;\n}\n\nfunction toCacheKey(value) {\n return normalizePositive(value, 0).toFixed(6);\n}\n\nfunction resolveGeometryEpsilon(width) {\n return Math.max(1e-4, normalizePositive(width, 1) * 1e-3);\n}\n\nfunction openPartWithSlit(part, width, epsilon) {\n if (!part.holes || part.holes.length === 0) {\n return copyPart(part);\n }\n\n let outer = copyRing(part.outer);\n const holes = part.holes.map((hole) => copyRing(hole));\n const anchors = [];\n\n while (holes.length > 0) {\n let selectedHoleIndex = -1;\n let selectedBridge = null;\n\n holes.forEach((hole, holeIndex) => {\n const blockers = holes.filter((_, index) => index !== holeIndex);\n const candidate = findBestHoleBridge(outer, hole, blockers, epsilon);\n\n if (\n candidate &&\n (!selectedBridge || candidate.distance < selectedBridge.distance)\n ) {\n selectedBridge = candidate;\n selectedHoleIndex = holeIndex;\n }\n });\n\n if (!selectedBridge || selectedHoleIndex === -1) {\n break;\n }\n\n const [hole] = holes.splice(selectedHoleIndex, 1);\n const merged = mergeHoleIntoOuter(outer, hole, selectedBridge, width, epsilon);\n outer = merged.ring;\n anchors.push(...merged.anchors);\n }\n\n return {\n ...part,\n outer,\n holes,\n anchors,\n bbox: ringBounds(outer),\n area:\n Math.abs(signedArea(outer)) -\n holes.reduce((sum, hole) => sum + Math.abs(signedArea(hole)), 0),\n };\n}\n\nfunction resamplePart(part, step) {\n const outer = resampleRing(part.outer, step, part.anchors ?? []);\n const holes = part.holes.map((hole) => resampleRing(hole, step));\n\n return {\n ...part,\n outer,\n holes,\n anchors: part.anchors ? part.anchors.map((point) => [point[0], point[1]]) : undefined,\n bbox: ringBounds(outer),\n area:\n Math.abs(signedArea(outer)) -\n holes.reduce((sum, hole) => sum + Math.abs(signedArea(hole)), 0),\n };\n}\n\nfunction findBestHoleBridge(outer, hole, blockers, epsilon) {\n let best = null;\n\n outer.forEach((outerPoint, outerIndex) => {\n hole.forEach((holePoint, holeIndex) => {\n if (\n !isVisibleBridge(\n outer,\n hole,\n blockers,\n outerPoint,\n holePoint,\n outerIndex,\n holeIndex,\n epsilon\n )\n ) {\n return;\n }\n\n const candidate = {\n outerIndex,\n holeIndex,\n distance: distance(outerPoint, holePoint),\n };\n\n if (!best || candidate.distance < best.distance) {\n best = candidate;\n }\n });\n });\n\n if (best) {\n return best;\n }\n\n return findNearestBridge(outer, hole);\n}\n\nfunction findNearestBridge(outer, hole) {\n let best = null;\n\n outer.forEach((outerPoint, outerIndex) => {\n hole.forEach((holePoint, holeIndex) => {\n const candidate = {\n outerIndex,\n holeIndex,\n distance: distance(outerPoint, holePoint),\n };\n\n if (!best || candidate.distance < best.distance) {\n best = candidate;\n }\n });\n });\n\n return best;\n}\n\nfunction isVisibleBridge(\n outer,\n hole,\n blockers,\n outerPoint,\n holePoint,\n outerIndex,\n holeIndex,\n epsilon\n) {\n if (distance(outerPoint, holePoint) <= epsilon) {\n return false;\n }\n\n const bridgeMidpoint = midpoint(outerPoint, holePoint);\n\n if (!pointInRing(bridgeMidpoint, outer) || pointInRing(bridgeMidpoint, hole)) {\n return false;\n }\n\n if (blockers.some((blocker) => pointInRing(bridgeMidpoint, blocker))) {\n return false;\n }\n\n if (\n segmentIntersectsRing(\n outerPoint,\n holePoint,\n outer,\n new Set([outerIndex, mod(outerIndex - 1, outer.length)]),\n epsilon\n )\n ) {\n return false;\n }\n\n if (\n segmentIntersectsRing(\n outerPoint,\n holePoint,\n hole,\n new Set([holeIndex, mod(holeIndex - 1, hole.length)]),\n epsilon\n )\n ) {\n return false;\n }\n\n return !blockers.some((blocker) =>\n segmentIntersectsRing(outerPoint, holePoint, blocker, new Set(), epsilon)\n );\n}\n\nfunction mergeHoleIntoOuter(outer, hole, bridge, width, epsilon) {\n const slitWidth = clampSlitWidth(width, outer, hole, epsilon);\n const outerCut = createRingCut(outer, bridge.outerIndex, slitWidth, epsilon);\n const holeCut = createRingCut(hole, bridge.holeIndex, slitWidth, epsilon);\n const outerPath = ringPath(\n outerCut.ring,\n outerCut.afterIndex,\n outerCut.beforeIndex\n );\n const holePath = ringPath(\n holeCut.ring,\n holeCut.afterIndex,\n holeCut.beforeIndex\n );\n const merged = [];\n\n appendPath(merged, outerPath, epsilon);\n appendPath(merged, holePath, epsilon);\n\n if (\n merged.length > 1 &&\n pointsAlmostEqual2D(merged[0], merged[merged.length - 1], epsilon)\n ) {\n merged.pop();\n }\n\n return {\n ring: merged,\n anchors: [\n outerCut.ring[outerCut.beforeIndex],\n holeCut.ring[holeCut.beforeIndex],\n holeCut.ring[holeCut.afterIndex],\n outerCut.ring[outerCut.afterIndex],\n ].map((point) => [point[0], point[1]]),\n };\n}\n\nfunction clampSlitWidth(width, outer, hole, epsilon) {\n const minPerimeter = Math.min(ringPerimeter(outer), ringPerimeter(hole));\n return Math.max(\n epsilon * 2,\n Math.min(width, Math.max(minPerimeter * 0.24, epsilon * 2))\n );\n}\n\nfunction createRingCut(ring, anchorIndex, width, epsilon) {\n const beforeCut = moveAlongRing(ring, anchorIndex, -width * 0.5, epsilon);\n const afterCut = moveAlongRing(ring, anchorIndex, width * 0.5, epsilon);\n\n return insertRingCutPoints(ring, beforeCut, afterCut, epsilon);\n}\n\nfunction moveAlongRing(ring, anchorIndex, offset, epsilon) {\n if (!Number.isFinite(offset) || Math.abs(offset) <= epsilon) {\n return {\n point: [ring[anchorIndex][0], ring[anchorIndex][1]],\n vertexIndex: anchorIndex,\n t: 0,\n };\n }\n\n let remaining = Math.abs(offset);\n let currentIndex = anchorIndex;\n const direction = offset > 0 ? 1 : -1;\n\n while (remaining > epsilon) {\n const nextIndex =\n direction > 0 ? (currentIndex + 1) % ring.length : mod(currentIndex - 1, ring.length);\n const segmentIndex = direction > 0 ? currentIndex : nextIndex;\n const segmentStart = ring[segmentIndex];\n const segmentEnd = ring[(segmentIndex + 1) % ring.length];\n const segmentLength = distance(segmentStart, segmentEnd);\n\n if (segmentLength <= epsilon) {\n currentIndex = direction > 0 ? nextIndex : segmentIndex;\n continue;\n }\n\n if (remaining < segmentLength - epsilon) {\n const t = remaining / segmentLength;\n const ratio = direction > 0 ? t : 1 - t;\n return {\n point: [\n segmentStart[0] + (segmentEnd[0] - segmentStart[0]) * ratio,\n segmentStart[1] + (segmentEnd[1] - segmentStart[1]) * ratio,\n ],\n segmentIndex,\n t: ratio,\n };\n }\n\n remaining -= segmentLength;\n currentIndex = direction > 0 ? nextIndex : segmentIndex;\n }\n\n return {\n point: [ring[currentIndex][0], ring[currentIndex][1]],\n vertexIndex: currentIndex,\n t: 0,\n };\n}\n\nfunction insertRingCutPoints(ring, beforeCut, afterCut, epsilon) {\n const cuts = [\n normalizeCutLocation(\"before\", ring, beforeCut, epsilon),\n normalizeCutLocation(\"after\", ring, afterCut, epsilon),\n ];\n const insertsBySegment = new Map();\n const cutIndices = {};\n const augmented = [];\n\n cuts.forEach((cut) => {\n if (cut.vertexIndex != null) {\n return;\n }\n\n const existing = insertsBySegment.get(cut.segmentIndex) ?? [];\n existing.push(cut);\n insertsBySegment.set(cut.segmentIndex, existing);\n });\n\n for (let index = 0; index < ring.length; index += 1) {\n augmented.push([ring[index][0], ring[index][1]]);\n\n cuts.forEach((cut) => {\n if (cut.vertexIndex === index) {\n cutIndices[cut.name] = augmented.length - 1;\n }\n });\n\n const segmentCuts = (insertsBySegment.get(index) ?? []).sort(\n (a, b) => a.t - b.t\n );\n\n segmentCuts.forEach((cut) => {\n augmented.push([cut.point[0], cut.point[1]]);\n cutIndices[cut.name] = augmented.length - 1;\n });\n }\n\n return {\n ring: augmented,\n beforeIndex: cutIndices.before,\n afterIndex: cutIndices.after,\n };\n}\n\nfunction normalizeCutLocation(name, ring, cut, epsilon) {\n if (cut.vertexIndex != null) {\n return {\n ...cut,\n name,\n };\n }\n\n const segmentStart = ring[cut.segmentIndex];\n const segmentEnd = ring[(cut.segmentIndex + 1) % ring.length];\n\n if (distance(cut.point, segmentStart) <= epsilon) {\n return {\n point: [segmentStart[0], segmentStart[1]],\n vertexIndex: cut.segmentIndex,\n t: 0,\n name,\n };\n }\n\n if (distance(cut.point, segmentEnd) <= epsilon) {\n return {\n point: [segmentEnd[0], segmentEnd[1]],\n vertexIndex: (cut.segmentIndex + 1) % ring.length,\n t: 1,\n name,\n };\n }\n\n return {\n ...cut,\n name,\n };\n}\n\nfunction ringPath(ring, startIndex, endIndex) {\n if (startIndex == null || endIndex == null) {\n return copyRing(ring);\n }\n\n const path = [ring[startIndex]];\n let cursor = startIndex;\n\n while (cursor !== endIndex) {\n cursor = (cursor + 1) % ring.length;\n path.push(ring[cursor]);\n }\n\n return path;\n}\n\nfunction appendPath(target, path, epsilon) {\n path.forEach((point) => {\n if (\n target.length === 0 ||\n !pointsAlmostEqual2D(target[target.length - 1], point, epsilon)\n ) {\n target.push([point[0], point[1]]);\n }\n });\n}\n\nfunction resampleRing(ring, step, anchors = []) {\n if (ring.length < 3) {\n return copyRing(ring);\n }\n\n const normalizedAnchors = normalizeAnchorPoints(ring, anchors);\n\n if (normalizedAnchors.length >= 2) {\n return resampleRingWithAnchors(ring, step, normalizedAnchors);\n }\n\n return resampleClosedPath(ring, step);\n}\n\nfunction normalizeAnchorPoints(ring, anchors) {\n const indices = anchors\n .map((anchor) => findRingPointIndex(ring, anchor))\n .filter((index) => index >= 0)\n .sort((a, b) => a - b);\n\n return indices.filter((index, position) => index !== indices[position - 1]);\n}\n\nfunction findRingPointIndex(ring, point, epsilon = 1e-6) {\n for (let index = 0; index < ring.length; index += 1) {\n if (pointsAlmostEqual2D(ring[index], point, epsilon)) {\n return index;\n }\n }\n\n return -1;\n}\n\nfunction resampleRingWithAnchors(ring, step, anchorIndices) {\n const result = [];\n\n for (let index = 0; index < anchorIndices.length; index += 1) {\n const startIndex = anchorIndices[index];\n const endIndex = anchorIndices[(index + 1) % anchorIndices.length];\n const path = ringPath(ring, startIndex, endIndex);\n const sampled = resampleOpenPath(path, step);\n\n appendPath(result, sampled, 1e-6);\n }\n\n if (\n result.length > 1 &&\n pointsAlmostEqual2D(result[0], result[result.length - 1], 1e-6)\n ) {\n result.pop();\n }\n\n if (result.length < 3 || result.length >= ring.length) {\n return copyRing(ring);\n }\n\n return result;\n}\n\nfunction resampleClosedPath(ring, step) {\n const perimeter = ringPerimeter(ring);\n\n if (perimeter <= 1e-9) {\n return copyRing(ring);\n }\n\n const pointCount = Math.max(3, Math.round(perimeter / step));\n\n if (pointCount >= ring.length) {\n return copyRing(ring);\n }\n\n const sampled = [];\n\n for (let index = 0; index < pointCount; index += 1) {\n const point = pointAtClosedPathDistance(ring, (perimeter * index) / pointCount);\n\n if (\n sampled.length === 0 ||\n !pointsAlmostEqual2D(sampled[sampled.length - 1], point, 1e-6)\n ) {\n sampled.push(point);\n }\n }\n\n if (sampled.length < 3 || sampled.length >= ring.length) {\n return copyRing(ring);\n }\n\n return sampled;\n}\n\nfunction resampleOpenPath(path, step) {\n if (path.length <= 2) {\n return path.map((point) => [point[0], point[1]]);\n }\n\n const length = polylineLength(path);\n\n if (length <= step) {\n return [\n [path[0][0], path[0][1]],\n [path[path.length - 1][0], path[path.length - 1][1]],\n ];\n }\n\n const divisionCount = Math.max(1, Math.round(length / step));\n const sampled = [];\n\n for (let index = 0; index <= divisionCount; index += 1) {\n const point = pointAtOpenPathDistance(path, (length * index) / divisionCount);\n\n if (\n sampled.length === 0 ||\n !pointsAlmostEqual2D(sampled[sampled.length - 1], point, 1e-6)\n ) {\n sampled.push(point);\n }\n }\n\n return sampled;\n}\n","// Simplified bidi metadata helper for the rich prepareWithSegments() path,\n// forked from pdf.js via Sebastian's text-layout. It classifies characters\n// into bidi types, computes embedding levels, and maps them onto prepared\n// segments for custom rendering. The line-breaking engine does not consume\n// these levels.\nconst baseTypes = [\n 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'S', 'B', 'S', 'WS',\n 'B', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',\n 'BN', 'BN', 'B', 'B', 'B', 'S', 'WS', 'ON', 'ON', 'ET', 'ET', 'ET', 'ON',\n 'ON', 'ON', 'ON', 'ON', 'ON', 'CS', 'ON', 'CS', 'ON', 'EN', 'EN', 'EN',\n 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'ON', 'ON', 'ON', 'ON', 'ON',\n 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'ON', 'ON',\n 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'ON', 'ON', 'ON', 'ON', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'B', 'BN',\n 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',\n 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',\n 'BN', 'CS', 'ON', 'ET', 'ET', 'ET', 'ET', 'ON', 'ON', 'ON', 'ON', 'L', 'ON',\n 'ON', 'ON', 'ON', 'ON', 'ET', 'ET', 'EN', 'EN', 'ON', 'L', 'ON', 'ON', 'ON',\n 'EN', 'L', 'ON', 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',\n 'L', 'L', 'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L'\n];\nconst arabicTypes = [\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'CS', 'AL', 'ON', 'ON', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM',\n 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN',\n 'AN', 'ET', 'AN', 'AN', 'AL', 'AL', 'AL', 'NSM', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM',\n 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'ON', 'NSM',\n 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',\n 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL'\n];\nfunction classifyChar(charCode) {\n if (charCode <= 0x00ff)\n return baseTypes[charCode];\n if (0x0590 <= charCode && charCode <= 0x05f4)\n return 'R';\n if (0x0600 <= charCode && charCode <= 0x06ff)\n return arabicTypes[charCode & 0xff];\n if (0x0700 <= charCode && charCode <= 0x08AC)\n return 'AL';\n return 'L';\n}\nfunction computeBidiLevels(str) {\n const len = str.length;\n if (len === 0)\n return null;\n // eslint-disable-next-line unicorn/no-new-array\n const types = new Array(len);\n let numBidi = 0;\n for (let i = 0; i < len; i++) {\n const t = classifyChar(str.charCodeAt(i));\n if (t === 'R' || t === 'AL' || t === 'AN')\n numBidi++;\n types[i] = t;\n }\n if (numBidi === 0)\n return null;\n const startLevel = (len / numBidi) < 0.3 ? 0 : 1;\n const levels = new Int8Array(len);\n for (let i = 0; i < len; i++)\n levels[i] = startLevel;\n const e = (startLevel & 1) ? 'R' : 'L';\n const sor = e;\n // W1-W7\n let lastType = sor;\n for (let i = 0; i < len; i++) {\n if (types[i] === 'NSM')\n types[i] = lastType;\n else\n lastType = types[i];\n }\n lastType = sor;\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if (t === 'EN')\n types[i] = lastType === 'AL' ? 'AN' : 'EN';\n else if (t === 'R' || t === 'L' || t === 'AL')\n lastType = t;\n }\n for (let i = 0; i < len; i++) {\n if (types[i] === 'AL')\n types[i] = 'R';\n }\n for (let i = 1; i < len - 1; i++) {\n if (types[i] === 'ES' && types[i - 1] === 'EN' && types[i + 1] === 'EN') {\n types[i] = 'EN';\n }\n if (types[i] === 'CS' &&\n (types[i - 1] === 'EN' || types[i - 1] === 'AN') &&\n types[i + 1] === types[i - 1]) {\n types[i] = types[i - 1];\n }\n }\n for (let i = 0; i < len; i++) {\n if (types[i] !== 'EN')\n continue;\n let j;\n for (j = i - 1; j >= 0 && types[j] === 'ET'; j--)\n types[j] = 'EN';\n for (j = i + 1; j < len && types[j] === 'ET'; j++)\n types[j] = 'EN';\n }\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if (t === 'WS' || t === 'ES' || t === 'ET' || t === 'CS')\n types[i] = 'ON';\n }\n lastType = sor;\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if (t === 'EN')\n types[i] = lastType === 'L' ? 'L' : 'EN';\n else if (t === 'R' || t === 'L')\n lastType = t;\n }\n // N1-N2\n for (let i = 0; i < len; i++) {\n if (types[i] !== 'ON')\n continue;\n let end = i + 1;\n while (end < len && types[end] === 'ON')\n end++;\n const before = i > 0 ? types[i - 1] : sor;\n const after = end < len ? types[end] : sor;\n const bDir = before !== 'L' ? 'R' : 'L';\n const aDir = after !== 'L' ? 'R' : 'L';\n if (bDir === aDir) {\n for (let j = i; j < end; j++)\n types[j] = bDir;\n }\n i = end - 1;\n }\n for (let i = 0; i < len; i++) {\n if (types[i] === 'ON')\n types[i] = e;\n }\n // I1-I2\n for (let i = 0; i < len; i++) {\n const t = types[i];\n if ((levels[i] & 1) === 0) {\n if (t === 'R')\n levels[i]++;\n else if (t === 'AN' || t === 'EN')\n levels[i] += 2;\n }\n else if (t === 'L' || t === 'AN' || t === 'EN') {\n levels[i]++;\n }\n }\n return levels;\n}\nexport function computeSegmentLevels(normalized, segStarts) {\n const bidiLevels = computeBidiLevels(normalized);\n if (bidiLevels === null)\n return null;\n const segLevels = new Int8Array(segStarts.length);\n for (let i = 0; i < segStarts.length; i++) {\n segLevels[i] = bidiLevels[segStarts[i]];\n }\n return segLevels;\n}\n","const collapsibleWhitespaceRunRe = /[ \\t\\n\\r\\f]+/g;\nconst needsWhitespaceNormalizationRe = /[\\t\\n\\r\\f]| {2,}|^ | $/;\nfunction getWhiteSpaceProfile(whiteSpace) {\n const mode = whiteSpace ?? 'normal';\n return mode === 'pre-wrap'\n ? { mode, preserveOrdinarySpaces: true, preserveHardBreaks: true }\n : { mode, preserveOrdinarySpaces: false, preserveHardBreaks: false };\n}\nexport function normalizeWhitespaceNormal(text) {\n if (!needsWhitespaceNormalizationRe.test(text))\n return text;\n let normalized = text.replace(collapsibleWhitespaceRunRe, ' ');\n if (normalized.charCodeAt(0) === 0x20) {\n normalized = normalized.slice(1);\n }\n if (normalized.length > 0 && normalized.charCodeAt(normalized.length - 1) === 0x20) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\nfunction normalizeWhitespacePreWrap(text) {\n if (!/[\\r\\f]/.test(text))\n return text.replace(/\\r\\n/g, '\\n');\n return text\n .replace(/\\r\\n/g, '\\n')\n .replace(/[\\r\\f]/g, '\\n');\n}\nlet sharedWordSegmenter = null;\nlet segmenterLocale;\nfunction getSharedWordSegmenter() {\n if (sharedWordSegmenter === null) {\n sharedWordSegmenter = new Intl.Segmenter(segmenterLocale, { granularity: 'word' });\n }\n return sharedWordSegmenter;\n}\nexport function clearAnalysisCaches() {\n sharedWordSegmenter = null;\n}\nexport function setAnalysisLocale(locale) {\n const nextLocale = locale && locale.length > 0 ? locale : undefined;\n if (segmenterLocale === nextLocale)\n return;\n segmenterLocale = nextLocale;\n sharedWordSegmenter = null;\n}\nconst arabicScriptRe = /\\p{Script=Arabic}/u;\nconst combiningMarkRe = /\\p{M}/u;\nconst decimalDigitRe = /\\p{Nd}/u;\nfunction containsArabicScript(text) {\n return arabicScriptRe.test(text);\n}\nexport function isCJK(s) {\n for (const ch of s) {\n const c = ch.codePointAt(0);\n if ((c >= 0x4E00 && c <= 0x9FFF) ||\n (c >= 0x3400 && c <= 0x4DBF) ||\n (c >= 0x20000 && c <= 0x2A6DF) ||\n (c >= 0x2A700 && c <= 0x2B73F) ||\n (c >= 0x2B740 && c <= 0x2B81F) ||\n (c >= 0x2B820 && c <= 0x2CEAF) ||\n (c >= 0x2CEB0 && c <= 0x2EBEF) ||\n (c >= 0x30000 && c <= 0x3134F) ||\n (c >= 0xF900 && c <= 0xFAFF) ||\n (c >= 0x2F800 && c <= 0x2FA1F) ||\n (c >= 0x3000 && c <= 0x303F) ||\n (c >= 0x3040 && c <= 0x309F) ||\n (c >= 0x30A0 && c <= 0x30FF) ||\n (c >= 0xAC00 && c <= 0xD7AF) ||\n (c >= 0xFF00 && c <= 0xFFEF)) {\n return true;\n }\n }\n return false;\n}\nexport const kinsokuStart = new Set([\n '\\uFF0C',\n '\\uFF0E',\n '\\uFF01',\n '\\uFF1A',\n '\\uFF1B',\n '\\uFF1F',\n '\\u3001',\n '\\u3002',\n '\\u30FB',\n '\\uFF09',\n '\\u3015',\n '\\u3009',\n '\\u300B',\n '\\u300D',\n '\\u300F',\n '\\u3011',\n '\\u3017',\n '\\u3019',\n '\\u301B',\n '\\u30FC',\n '\\u3005',\n '\\u303B',\n '\\u309D',\n '\\u309E',\n '\\u30FD',\n '\\u30FE',\n]);\nexport const kinsokuEnd = new Set([\n '\"',\n '(', '[', '{',\n '“', '‘', '«', '‹',\n '\\uFF08',\n '\\u3014',\n '\\u3008',\n '\\u300A',\n '\\u300C',\n '\\u300E',\n '\\u3010',\n '\\u3016',\n '\\u3018',\n '\\u301A',\n]);\nconst forwardStickyGlue = new Set([\n \"'\", '’',\n]);\nexport const leftStickyPunctuation = new Set([\n '.', ',', '!', '?', ':', ';',\n '\\u060C',\n '\\u061B',\n '\\u061F',\n '\\u0964',\n '\\u0965',\n '\\u104A',\n '\\u104B',\n '\\u104C',\n '\\u104D',\n '\\u104F',\n ')', ']', '}',\n '%',\n '\"',\n '”', '’', '»', '›',\n '…',\n]);\nconst arabicNoSpaceTrailingPunctuation = new Set([\n ':',\n '.',\n '\\u060C',\n '\\u061B',\n]);\nconst myanmarMedialGlue = new Set([\n '\\u104F',\n]);\nconst closingQuoteChars = new Set([\n '”', '’', '»', '›',\n '\\u300D',\n '\\u300F',\n '\\u3011',\n '\\u300B',\n '\\u3009',\n '\\u3015',\n '\\uFF09',\n]);\nfunction isLeftStickyPunctuationSegment(segment) {\n if (isEscapedQuoteClusterSegment(segment))\n return true;\n let sawPunctuation = false;\n for (const ch of segment) {\n if (leftStickyPunctuation.has(ch)) {\n sawPunctuation = true;\n continue;\n }\n if (sawPunctuation && combiningMarkRe.test(ch))\n continue;\n return false;\n }\n return sawPunctuation;\n}\nfunction isCJKLineStartProhibitedSegment(segment) {\n for (const ch of segment) {\n if (!kinsokuStart.has(ch) && !leftStickyPunctuation.has(ch))\n return false;\n }\n return segment.length > 0;\n}\nfunction isForwardStickyClusterSegment(segment) {\n if (isEscapedQuoteClusterSegment(segment))\n return true;\n for (const ch of segment) {\n if (!kinsokuEnd.has(ch) && !forwardStickyGlue.has(ch) && !combiningMarkRe.test(ch))\n return false;\n }\n return segment.length > 0;\n}\nfunction isEscapedQuoteClusterSegment(segment) {\n let sawQuote = false;\n for (const ch of segment) {\n if (ch === '\\\\' || combiningMarkRe.test(ch))\n continue;\n if (kinsokuEnd.has(ch) || leftStickyPunctuation.has(ch) || forwardStickyGlue.has(ch)) {\n sawQuote = true;\n continue;\n }\n return false;\n }\n return sawQuote;\n}\nfunction splitTrailingForwardStickyCluster(text) {\n const chars = Array.from(text);\n let splitIndex = chars.length;\n while (splitIndex > 0) {\n const ch = chars[splitIndex - 1];\n if (combiningMarkRe.test(ch)) {\n splitIndex--;\n continue;\n }\n if (kinsokuEnd.has(ch) || forwardStickyGlue.has(ch)) {\n splitIndex--;\n continue;\n }\n break;\n }\n if (splitIndex <= 0 || splitIndex === chars.length)\n return null;\n return {\n head: chars.slice(0, splitIndex).join(''),\n tail: chars.slice(splitIndex).join(''),\n };\n}\nfunction isRepeatedSingleCharRun(segment, ch) {\n if (segment.length === 0)\n return false;\n for (const part of segment) {\n if (part !== ch)\n return false;\n }\n return true;\n}\nfunction endsWithArabicNoSpacePunctuation(segment) {\n if (!containsArabicScript(segment) || segment.length === 0)\n return false;\n return arabicNoSpaceTrailingPunctuation.has(segment[segment.length - 1]);\n}\nfunction endsWithMyanmarMedialGlue(segment) {\n if (segment.length === 0)\n return false;\n return myanmarMedialGlue.has(segment[segment.length - 1]);\n}\nfunction splitLeadingSpaceAndMarks(segment) {\n if (segment.length < 2 || segment[0] !== ' ')\n return null;\n const marks = segment.slice(1);\n if (/^\\p{M}+$/u.test(marks)) {\n return { space: ' ', marks };\n }\n return null;\n}\nexport function endsWithClosingQuote(text) {\n for (let i = text.length - 1; i >= 0; i--) {\n const ch = text[i];\n if (closingQuoteChars.has(ch))\n return true;\n if (!leftStickyPunctuation.has(ch))\n return false;\n }\n return false;\n}\nfunction classifySegmentBreakChar(ch, whiteSpaceProfile) {\n if (whiteSpaceProfile.preserveOrdinarySpaces || whiteSpaceProfile.preserveHardBreaks) {\n if (ch === ' ')\n return 'preserved-space';\n if (ch === '\\t')\n return 'tab';\n if (whiteSpaceProfile.preserveHardBreaks && ch === '\\n')\n return 'hard-break';\n }\n if (ch === ' ')\n return 'space';\n if (ch === '\\u00A0' || ch === '\\u202F' || ch === '\\u2060' || ch === '\\uFEFF') {\n return 'glue';\n }\n if (ch === '\\u200B')\n return 'zero-width-break';\n if (ch === '\\u00AD')\n return 'soft-hyphen';\n return 'text';\n}\nfunction joinTextParts(parts) {\n return parts.length === 1 ? parts[0] : parts.join('');\n}\nfunction splitSegmentByBreakKind(segment, isWordLike, start, whiteSpaceProfile) {\n const pieces = [];\n let currentKind = null;\n let currentTextParts = [];\n let currentStart = start;\n let currentWordLike = false;\n let offset = 0;\n for (const ch of segment) {\n const kind = classifySegmentBreakChar(ch, whiteSpaceProfile);\n const wordLike = kind === 'text' && isWordLike;\n if (currentKind !== null && kind === currentKind && wordLike === currentWordLike) {\n currentTextParts.push(ch);\n offset += ch.length;\n continue;\n }\n if (currentKind !== null) {\n pieces.push({\n text: joinTextParts(currentTextParts),\n isWordLike: currentWordLike,\n kind: currentKind,\n start: currentStart,\n });\n }\n currentKind = kind;\n currentTextParts = [ch];\n currentStart = start + offset;\n currentWordLike = wordLike;\n offset += ch.length;\n }\n if (currentKind !== null) {\n pieces.push({\n text: joinTextParts(currentTextParts),\n isWordLike: currentWordLike,\n kind: currentKind,\n start: currentStart,\n });\n }\n return pieces;\n}\nfunction isTextRunBoundary(kind) {\n return (kind === 'space' ||\n kind === 'preserved-space' ||\n kind === 'zero-width-break' ||\n kind === 'hard-break');\n}\nconst urlSchemeSegmentRe = /^[A-Za-z][A-Za-z0-9+.-]*:$/;\nfunction isUrlLikeRunStart(segmentation, index) {\n const text = segmentation.texts[index];\n if (text.startsWith('www.'))\n return true;\n return (urlSchemeSegmentRe.test(text) &&\n index + 1 < segmentation.len &&\n segmentation.kinds[index + 1] === 'text' &&\n segmentation.texts[index + 1] === '//');\n}\nfunction isUrlQueryBoundarySegment(text) {\n return text.includes('?') && (text.includes('://') || text.startsWith('www.'));\n}\nfunction mergeUrlLikeRuns(segmentation) {\n const texts = segmentation.texts.slice();\n const isWordLike = segmentation.isWordLike.slice();\n const kinds = segmentation.kinds.slice();\n const starts = segmentation.starts.slice();\n for (let i = 0; i < segmentation.len; i++) {\n if (kinds[i] !== 'text' || !isUrlLikeRunStart(segmentation, i))\n continue;\n const mergedParts = [texts[i]];\n let j = i + 1;\n while (j < segmentation.len && !isTextRunBoundary(kinds[j])) {\n mergedParts.push(texts[j]);\n isWordLike[i] = true;\n const endsQueryPrefix = texts[j].includes('?');\n kinds[j] = 'text';\n texts[j] = '';\n j++;\n if (endsQueryPrefix)\n break;\n }\n texts[i] = joinTextParts(mergedParts);\n }\n let compactLen = 0;\n for (let read = 0; read < texts.length; read++) {\n const text = texts[read];\n if (text.length === 0)\n continue;\n if (compactLen !== read) {\n texts[compactLen] = text;\n isWordLike[compactLen] = isWordLike[read];\n kinds[compactLen] = kinds[read];\n starts[compactLen] = starts[read];\n }\n compactLen++;\n }\n texts.length = compactLen;\n isWordLike.length = compactLen;\n kinds.length = compactLen;\n starts.length = compactLen;\n return {\n len: compactLen,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction mergeUrlQueryRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n texts.push(text);\n isWordLike.push(segmentation.isWordLike[i]);\n kinds.push(segmentation.kinds[i]);\n starts.push(segmentation.starts[i]);\n if (!isUrlQueryBoundarySegment(text))\n continue;\n const nextIndex = i + 1;\n if (nextIndex >= segmentation.len ||\n isTextRunBoundary(segmentation.kinds[nextIndex])) {\n continue;\n }\n const queryParts = [];\n const queryStart = segmentation.starts[nextIndex];\n let j = nextIndex;\n while (j < segmentation.len && !isTextRunBoundary(segmentation.kinds[j])) {\n queryParts.push(segmentation.texts[j]);\n j++;\n }\n if (queryParts.length > 0) {\n texts.push(joinTextParts(queryParts));\n isWordLike.push(true);\n kinds.push('text');\n starts.push(queryStart);\n i = j - 1;\n }\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nconst numericJoinerChars = new Set([\n ':', '-', '/', '×', ',', '.', '+',\n '\\u2013',\n '\\u2014',\n]);\nconst asciiPunctuationChainSegmentRe = /^[A-Za-z0-9_]+[,:;]*$/;\nconst asciiPunctuationChainTrailingJoinersRe = /[,:;]+$/;\nfunction segmentContainsDecimalDigit(text) {\n for (const ch of text) {\n if (decimalDigitRe.test(ch))\n return true;\n }\n return false;\n}\nfunction isNumericRunSegment(text) {\n if (text.length === 0)\n return false;\n for (const ch of text) {\n if (decimalDigitRe.test(ch) || numericJoinerChars.has(ch))\n continue;\n return false;\n }\n return true;\n}\nfunction mergeNumericRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n const kind = segmentation.kinds[i];\n if (kind === 'text' && isNumericRunSegment(text) && segmentContainsDecimalDigit(text)) {\n const mergedParts = [text];\n let j = i + 1;\n while (j < segmentation.len &&\n segmentation.kinds[j] === 'text' &&\n isNumericRunSegment(segmentation.texts[j])) {\n mergedParts.push(segmentation.texts[j]);\n j++;\n }\n texts.push(joinTextParts(mergedParts));\n isWordLike.push(true);\n kinds.push('text');\n starts.push(segmentation.starts[i]);\n i = j - 1;\n continue;\n }\n texts.push(text);\n isWordLike.push(segmentation.isWordLike[i]);\n kinds.push(kind);\n starts.push(segmentation.starts[i]);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction mergeAsciiPunctuationChains(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n const kind = segmentation.kinds[i];\n const wordLike = segmentation.isWordLike[i];\n if (kind === 'text' && wordLike && asciiPunctuationChainSegmentRe.test(text)) {\n const mergedParts = [text];\n let endsWithJoiners = asciiPunctuationChainTrailingJoinersRe.test(text);\n let j = i + 1;\n while (endsWithJoiners &&\n j < segmentation.len &&\n segmentation.kinds[j] === 'text' &&\n segmentation.isWordLike[j] &&\n asciiPunctuationChainSegmentRe.test(segmentation.texts[j])) {\n const nextText = segmentation.texts[j];\n mergedParts.push(nextText);\n endsWithJoiners = asciiPunctuationChainTrailingJoinersRe.test(nextText);\n j++;\n }\n texts.push(joinTextParts(mergedParts));\n isWordLike.push(true);\n kinds.push('text');\n starts.push(segmentation.starts[i]);\n i = j - 1;\n continue;\n }\n texts.push(text);\n isWordLike.push(wordLike);\n kinds.push(kind);\n starts.push(segmentation.starts[i]);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction splitHyphenatedNumericRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n for (let i = 0; i < segmentation.len; i++) {\n const text = segmentation.texts[i];\n if (segmentation.kinds[i] === 'text' && text.includes('-')) {\n const parts = text.split('-');\n let shouldSplit = parts.length > 1;\n for (let j = 0; j < parts.length; j++) {\n const part = parts[j];\n if (!shouldSplit)\n break;\n if (part.length === 0 ||\n !segmentContainsDecimalDigit(part) ||\n !isNumericRunSegment(part)) {\n shouldSplit = false;\n }\n }\n if (shouldSplit) {\n let offset = 0;\n for (let j = 0; j < parts.length; j++) {\n const part = parts[j];\n const splitText = j < parts.length - 1 ? `${part}-` : part;\n texts.push(splitText);\n isWordLike.push(true);\n kinds.push('text');\n starts.push(segmentation.starts[i] + offset);\n offset += splitText.length;\n }\n continue;\n }\n }\n texts.push(text);\n isWordLike.push(segmentation.isWordLike[i]);\n kinds.push(segmentation.kinds[i]);\n starts.push(segmentation.starts[i]);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction mergeGlueConnectedTextRuns(segmentation) {\n const texts = [];\n const isWordLike = [];\n const kinds = [];\n const starts = [];\n let read = 0;\n while (read < segmentation.len) {\n const textParts = [segmentation.texts[read]];\n let wordLike = segmentation.isWordLike[read];\n let kind = segmentation.kinds[read];\n let start = segmentation.starts[read];\n if (kind === 'glue') {\n const glueParts = [textParts[0]];\n const glueStart = start;\n read++;\n while (read < segmentation.len && segmentation.kinds[read] === 'glue') {\n glueParts.push(segmentation.texts[read]);\n read++;\n }\n const glueText = joinTextParts(glueParts);\n if (read < segmentation.len && segmentation.kinds[read] === 'text') {\n textParts[0] = glueText;\n textParts.push(segmentation.texts[read]);\n wordLike = segmentation.isWordLike[read];\n kind = 'text';\n start = glueStart;\n read++;\n }\n else {\n texts.push(glueText);\n isWordLike.push(false);\n kinds.push('glue');\n starts.push(glueStart);\n continue;\n }\n }\n else {\n read++;\n }\n if (kind === 'text') {\n while (read < segmentation.len && segmentation.kinds[read] === 'glue') {\n const glueParts = [];\n while (read < segmentation.len && segmentation.kinds[read] === 'glue') {\n glueParts.push(segmentation.texts[read]);\n read++;\n }\n const glueText = joinTextParts(glueParts);\n if (read < segmentation.len && segmentation.kinds[read] === 'text') {\n textParts.push(glueText, segmentation.texts[read]);\n wordLike = wordLike || segmentation.isWordLike[read];\n read++;\n continue;\n }\n textParts.push(glueText);\n }\n }\n texts.push(joinTextParts(textParts));\n isWordLike.push(wordLike);\n kinds.push(kind);\n starts.push(start);\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction carryTrailingForwardStickyAcrossCJKBoundary(segmentation) {\n const texts = segmentation.texts.slice();\n const isWordLike = segmentation.isWordLike.slice();\n const kinds = segmentation.kinds.slice();\n const starts = segmentation.starts.slice();\n for (let i = 0; i < texts.length - 1; i++) {\n if (kinds[i] !== 'text' || kinds[i + 1] !== 'text')\n continue;\n if (!isCJK(texts[i]) || !isCJK(texts[i + 1]))\n continue;\n const split = splitTrailingForwardStickyCluster(texts[i]);\n if (split === null)\n continue;\n texts[i] = split.head;\n texts[i + 1] = split.tail + texts[i + 1];\n starts[i + 1] = starts[i] + split.head.length;\n }\n return {\n len: texts.length,\n texts,\n isWordLike,\n kinds,\n starts,\n };\n}\nfunction buildMergedSegmentation(normalized, profile, whiteSpaceProfile) {\n const wordSegmenter = getSharedWordSegmenter();\n let mergedLen = 0;\n const mergedTexts = [];\n const mergedWordLike = [];\n const mergedKinds = [];\n const mergedStarts = [];\n for (const s of wordSegmenter.segment(normalized)) {\n for (const piece of splitSegmentByBreakKind(s.segment, s.isWordLike ?? false, s.index, whiteSpaceProfile)) {\n const isText = piece.kind === 'text';\n if (profile.carryCJKAfterClosingQuote &&\n isText &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n isCJK(piece.text) &&\n isCJK(mergedTexts[mergedLen - 1]) &&\n endsWithClosingQuote(mergedTexts[mergedLen - 1])) {\n mergedTexts[mergedLen - 1] += piece.text;\n mergedWordLike[mergedLen - 1] = mergedWordLike[mergedLen - 1] || piece.isWordLike;\n }\n else if (isText &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n isCJKLineStartProhibitedSegment(piece.text) &&\n isCJK(mergedTexts[mergedLen - 1])) {\n mergedTexts[mergedLen - 1] += piece.text;\n mergedWordLike[mergedLen - 1] = mergedWordLike[mergedLen - 1] || piece.isWordLike;\n }\n else if (isText &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n endsWithMyanmarMedialGlue(mergedTexts[mergedLen - 1])) {\n mergedTexts[mergedLen - 1] += piece.text;\n mergedWordLike[mergedLen - 1] = mergedWordLike[mergedLen - 1] || piece.isWordLike;\n }\n else if (isText &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n piece.isWordLike &&\n containsArabicScript(piece.text) &&\n endsWithArabicNoSpacePunctuation(mergedTexts[mergedLen - 1])) {\n mergedTexts[mergedLen - 1] += piece.text;\n mergedWordLike[mergedLen - 1] = true;\n }\n else if (isText &&\n !piece.isWordLike &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n piece.text.length === 1 &&\n piece.text !== '-' &&\n piece.text !== '—' &&\n isRepeatedSingleCharRun(mergedTexts[mergedLen - 1], piece.text)) {\n mergedTexts[mergedLen - 1] += piece.text;\n }\n else if (isText &&\n !piece.isWordLike &&\n mergedLen > 0 &&\n mergedKinds[mergedLen - 1] === 'text' &&\n (isLeftStickyPunctuationSegment(piece.text) ||\n (piece.text === '-' && mergedWordLike[mergedLen - 1]))) {\n mergedTexts[mergedLen - 1] += piece.text;\n }\n else {\n mergedTexts[mergedLen] = piece.text;\n mergedWordLike[mergedLen] = piece.isWordLike;\n mergedKinds[mergedLen] = piece.kind;\n mergedStarts[mergedLen] = piece.start;\n mergedLen++;\n }\n }\n }\n for (let i = 1; i < mergedLen; i++) {\n if (mergedKinds[i] === 'text' &&\n !mergedWordLike[i] &&\n isEscapedQuoteClusterSegment(mergedTexts[i]) &&\n mergedKinds[i - 1] === 'text') {\n mergedTexts[i - 1] += mergedTexts[i];\n mergedWordLike[i - 1] = mergedWordLike[i - 1] || mergedWordLike[i];\n mergedTexts[i] = '';\n }\n }\n for (let i = mergedLen - 2; i >= 0; i--) {\n if (mergedKinds[i] === 'text' && !mergedWordLike[i] && isForwardStickyClusterSegment(mergedTexts[i])) {\n let j = i + 1;\n while (j < mergedLen && mergedTexts[j] === '')\n j++;\n if (j < mergedLen && mergedKinds[j] === 'text') {\n mergedTexts[j] = mergedTexts[i] + mergedTexts[j];\n mergedStarts[j] = mergedStarts[i];\n mergedTexts[i] = '';\n }\n }\n }\n let compactLen = 0;\n for (let read = 0; read < mergedLen; read++) {\n const text = mergedTexts[read];\n if (text.length === 0)\n continue;\n if (compactLen !== read) {\n mergedTexts[compactLen] = text;\n mergedWordLike[compactLen] = mergedWordLike[read];\n mergedKinds[compactLen] = mergedKinds[read];\n mergedStarts[compactLen] = mergedStarts[read];\n }\n compactLen++;\n }\n mergedTexts.length = compactLen;\n mergedWordLike.length = compactLen;\n mergedKinds.length = compactLen;\n mergedStarts.length = compactLen;\n const compacted = mergeGlueConnectedTextRuns({\n len: compactLen,\n texts: mergedTexts,\n isWordLike: mergedWordLike,\n kinds: mergedKinds,\n starts: mergedStarts,\n });\n const withMergedUrls = carryTrailingForwardStickyAcrossCJKBoundary(mergeAsciiPunctuationChains(splitHyphenatedNumericRuns(mergeNumericRuns(mergeUrlQueryRuns(mergeUrlLikeRuns(compacted))))));\n for (let i = 0; i < withMergedUrls.len - 1; i++) {\n const split = splitLeadingSpaceAndMarks(withMergedUrls.texts[i]);\n if (split === null)\n continue;\n if ((withMergedUrls.kinds[i] !== 'space' && withMergedUrls.kinds[i] !== 'preserved-space') ||\n withMergedUrls.kinds[i + 1] !== 'text' ||\n !containsArabicScript(withMergedUrls.texts[i + 1])) {\n continue;\n }\n withMergedUrls.texts[i] = split.space;\n withMergedUrls.isWordLike[i] = false;\n withMergedUrls.kinds[i] = withMergedUrls.kinds[i] === 'preserved-space' ? 'preserved-space' : 'space';\n withMergedUrls.texts[i + 1] = split.marks + withMergedUrls.texts[i + 1];\n withMergedUrls.starts[i + 1] = withMergedUrls.starts[i] + split.space.length;\n }\n return withMergedUrls;\n}\nfunction compileAnalysisChunks(segmentation, whiteSpaceProfile) {\n if (segmentation.len === 0)\n return [];\n if (!whiteSpaceProfile.preserveHardBreaks) {\n return [{\n startSegmentIndex: 0,\n endSegmentIndex: segmentation.len,\n consumedEndSegmentIndex: segmentation.len,\n }];\n }\n const chunks = [];\n let startSegmentIndex = 0;\n for (let i = 0; i < segmentation.len; i++) {\n if (segmentation.kinds[i] !== 'hard-break')\n continue;\n chunks.push({\n startSegmentIndex,\n endSegmentIndex: i,\n consumedEndSegmentIndex: i + 1,\n });\n startSegmentIndex = i + 1;\n }\n if (startSegmentIndex < segmentation.len) {\n chunks.push({\n startSegmentIndex,\n endSegmentIndex: segmentation.len,\n consumedEndSegmentIndex: segmentation.len,\n });\n }\n return chunks;\n}\nexport function analyzeText(text, profile, whiteSpace = 'normal') {\n const whiteSpaceProfile = getWhiteSpaceProfile(whiteSpace);\n const normalized = whiteSpaceProfile.mode === 'pre-wrap'\n ? normalizeWhitespacePreWrap(text)\n : normalizeWhitespaceNormal(text);\n if (normalized.length === 0) {\n return {\n normalized,\n chunks: [],\n len: 0,\n texts: [],\n isWordLike: [],\n kinds: [],\n starts: [],\n };\n }\n const segmentation = buildMergedSegmentation(normalized, profile, whiteSpaceProfile);\n return {\n normalized,\n chunks: compileAnalysisChunks(segmentation, whiteSpaceProfile),\n ...segmentation,\n };\n}\n","import { isCJK } from './analysis.js';\nlet measureContext = null;\nconst segmentMetricCaches = new Map();\nlet cachedEngineProfile = null;\nconst emojiPresentationRe = /\\p{Emoji_Presentation}/u;\nconst maybeEmojiRe = /[\\p{Emoji_Presentation}\\p{Extended_Pictographic}\\p{Regional_Indicator}\\uFE0F\\u20E3]/u;\nlet sharedGraphemeSegmenter = null;\nconst emojiCorrectionCache = new Map();\nexport function getMeasureContext() {\n if (measureContext !== null)\n return measureContext;\n if (typeof OffscreenCanvas !== 'undefined') {\n measureContext = new OffscreenCanvas(1, 1).getContext('2d');\n return measureContext;\n }\n if (typeof document !== 'undefined') {\n measureContext = document.createElement('canvas').getContext('2d');\n return measureContext;\n }\n throw new Error('Text measurement requires OffscreenCanvas or a DOM canvas context.');\n}\nexport function getSegmentMetricCache(font) {\n let cache = segmentMetricCaches.get(font);\n if (!cache) {\n cache = new Map();\n segmentMetricCaches.set(font, cache);\n }\n return cache;\n}\nexport function getSegmentMetrics(seg, cache) {\n let metrics = cache.get(seg);\n if (metrics === undefined) {\n const ctx = getMeasureContext();\n metrics = {\n width: ctx.measureText(seg).width,\n containsCJK: isCJK(seg),\n };\n cache.set(seg, metrics);\n }\n return metrics;\n}\nexport function getEngineProfile() {\n if (cachedEngineProfile !== null)\n return cachedEngineProfile;\n if (typeof navigator === 'undefined') {\n cachedEngineProfile = {\n lineFitEpsilon: 0.005,\n carryCJKAfterClosingQuote: false,\n preferPrefixWidthsForBreakableRuns: false,\n preferEarlySoftHyphenBreak: false,\n };\n return cachedEngineProfile;\n }\n const ua = navigator.userAgent;\n const vendor = navigator.vendor;\n const isSafari = vendor === 'Apple Computer, Inc.' &&\n ua.includes('Safari/') &&\n !ua.includes('Chrome/') &&\n !ua.includes('Chromium/') &&\n !ua.includes('CriOS/') &&\n !ua.includes('FxiOS/') &&\n !ua.includes('EdgiOS/');\n const isChromium = ua.includes('Chrome/') ||\n ua.includes('Chromium/') ||\n ua.includes('CriOS/') ||\n ua.includes('Edg/');\n cachedEngineProfile = {\n lineFitEpsilon: isSafari ? 1 / 64 : 0.005,\n carryCJKAfterClosingQuote: isChromium,\n preferPrefixWidthsForBreakableRuns: isSafari,\n preferEarlySoftHyphenBreak: isSafari,\n };\n return cachedEngineProfile;\n}\nexport function parseFontSize(font) {\n const m = font.match(/(\\d+(?:\\.\\d+)?)\\s*px/);\n return m ? parseFloat(m[1]) : 16;\n}\nfunction getSharedGraphemeSegmenter() {\n if (sharedGraphemeSegmenter === null) {\n sharedGraphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\n }\n return sharedGraphemeSegmenter;\n}\nfunction isEmojiGrapheme(g) {\n return emojiPresentationRe.test(g) || g.includes('\\uFE0F');\n}\nexport function textMayContainEmoji(text) {\n return maybeEmojiRe.test(text);\n}\nfunction getEmojiCorrection(font, fontSize) {\n let correction = emojiCorrectionCache.get(font);\n if (correction !== undefined)\n return correction;\n const ctx = getMeasureContext();\n ctx.font = font;\n const canvasW = ctx.measureText('\\u{1F600}').width;\n correction = 0;\n if (canvasW > fontSize + 0.5 &&\n typeof document !== 'undefined' &&\n document.body !== null) {\n const span = document.createElement('span');\n span.style.font = font;\n span.style.display = 'inline-block';\n span.style.visibility = 'hidden';\n span.style.position = 'absolute';\n span.textContent = '\\u{1F600}';\n document.body.appendChild(span);\n const domW = span.getBoundingClientRect().width;\n document.body.removeChild(span);\n if (canvasW - domW > 0.5) {\n correction = canvasW - domW;\n }\n }\n emojiCorrectionCache.set(font, correction);\n return correction;\n}\nfunction countEmojiGraphemes(text) {\n let count = 0;\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n for (const g of graphemeSegmenter.segment(text)) {\n if (isEmojiGrapheme(g.segment))\n count++;\n }\n return count;\n}\nfunction getEmojiCount(seg, metrics) {\n if (metrics.emojiCount === undefined) {\n metrics.emojiCount = countEmojiGraphemes(seg);\n }\n return metrics.emojiCount;\n}\nexport function getCorrectedSegmentWidth(seg, metrics, emojiCorrection) {\n if (emojiCorrection === 0)\n return metrics.width;\n return metrics.width - getEmojiCount(seg, metrics) * emojiCorrection;\n}\nexport function getSegmentGraphemeWidths(seg, metrics, cache, emojiCorrection) {\n if (metrics.graphemeWidths !== undefined)\n return metrics.graphemeWidths;\n const widths = [];\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n for (const gs of graphemeSegmenter.segment(seg)) {\n const graphemeMetrics = getSegmentMetrics(gs.segment, cache);\n widths.push(getCorrectedSegmentWidth(gs.segment, graphemeMetrics, emojiCorrection));\n }\n metrics.graphemeWidths = widths.length > 1 ? widths : null;\n return metrics.graphemeWidths;\n}\nexport function getSegmentGraphemePrefixWidths(seg, metrics, cache, emojiCorrection) {\n if (metrics.graphemePrefixWidths !== undefined)\n return metrics.graphemePrefixWidths;\n const prefixWidths = [];\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n let prefix = '';\n for (const gs of graphemeSegmenter.segment(seg)) {\n prefix += gs.segment;\n const prefixMetrics = getSegmentMetrics(prefix, cache);\n prefixWidths.push(getCorrectedSegmentWidth(prefix, prefixMetrics, emojiCorrection));\n }\n metrics.graphemePrefixWidths = prefixWidths.length > 1 ? prefixWidths : null;\n return metrics.graphemePrefixWidths;\n}\nexport function getFontMeasurementState(font, needsEmojiCorrection) {\n const ctx = getMeasureContext();\n ctx.font = font;\n const cache = getSegmentMetricCache(font);\n const fontSize = parseFontSize(font);\n const emojiCorrection = needsEmojiCorrection ? getEmojiCorrection(font, fontSize) : 0;\n return { cache, fontSize, emojiCorrection };\n}\nexport function clearMeasurementCaches() {\n segmentMetricCaches.clear();\n emojiCorrectionCache.clear();\n sharedGraphemeSegmenter = null;\n}\n","import { getEngineProfile } from './measurement.js';\nfunction canBreakAfter(kind) {\n return (kind === 'space' ||\n kind === 'preserved-space' ||\n kind === 'tab' ||\n kind === 'zero-width-break' ||\n kind === 'soft-hyphen');\n}\nfunction normalizeSimpleLineStartSegmentIndex(prepared, segmentIndex) {\n while (segmentIndex < prepared.widths.length) {\n const kind = prepared.kinds[segmentIndex];\n if (kind !== 'space' && kind !== 'zero-width-break' && kind !== 'soft-hyphen')\n break;\n segmentIndex++;\n }\n return segmentIndex;\n}\nfunction getTabAdvance(lineWidth, tabStopAdvance) {\n if (tabStopAdvance <= 0)\n return 0;\n const remainder = lineWidth % tabStopAdvance;\n if (Math.abs(remainder) <= 1e-6)\n return tabStopAdvance;\n return tabStopAdvance - remainder;\n}\nfunction getBreakableAdvance(graphemeWidths, graphemePrefixWidths, graphemeIndex, preferPrefixWidths) {\n if (!preferPrefixWidths || graphemePrefixWidths === null) {\n return graphemeWidths[graphemeIndex];\n }\n return graphemePrefixWidths[graphemeIndex] - (graphemeIndex > 0 ? graphemePrefixWidths[graphemeIndex - 1] : 0);\n}\nfunction fitSoftHyphenBreak(graphemeWidths, initialWidth, maxWidth, lineFitEpsilon, discretionaryHyphenWidth, cumulativeWidths) {\n let fitCount = 0;\n let fittedWidth = initialWidth;\n while (fitCount < graphemeWidths.length) {\n const nextWidth = cumulativeWidths\n ? initialWidth + graphemeWidths[fitCount]\n : fittedWidth + graphemeWidths[fitCount];\n const nextLineWidth = fitCount + 1 < graphemeWidths.length\n ? nextWidth + discretionaryHyphenWidth\n : nextWidth;\n if (nextLineWidth > maxWidth + lineFitEpsilon)\n break;\n fittedWidth = nextWidth;\n fitCount++;\n }\n return { fitCount, fittedWidth };\n}\nfunction findChunkIndexForStart(prepared, segmentIndex) {\n let lo = 0;\n let hi = prepared.chunks.length;\n while (lo < hi) {\n const mid = Math.floor((lo + hi) / 2);\n if (segmentIndex < prepared.chunks[mid].consumedEndSegmentIndex) {\n hi = mid;\n }\n else {\n lo = mid + 1;\n }\n }\n return lo < prepared.chunks.length ? lo : -1;\n}\nfunction normalizeLineStartWithChunk(prepared, start) {\n let segmentIndex = start.segmentIndex;\n const graphemeIndex = start.graphemeIndex;\n if (segmentIndex >= prepared.widths.length)\n return null;\n const chunkIndex = findChunkIndexForStart(prepared, segmentIndex);\n if (chunkIndex < 0)\n return null;\n if (graphemeIndex > 0) {\n return { cursor: start, chunkIndex };\n }\n const chunk = prepared.chunks[chunkIndex];\n if (chunk.startSegmentIndex === chunk.endSegmentIndex && segmentIndex === chunk.startSegmentIndex) {\n return { cursor: { segmentIndex, graphemeIndex: 0 }, chunkIndex };\n }\n if (segmentIndex < chunk.startSegmentIndex)\n segmentIndex = chunk.startSegmentIndex;\n while (segmentIndex < chunk.endSegmentIndex) {\n const kind = prepared.kinds[segmentIndex];\n if (kind !== 'space' && kind !== 'zero-width-break' && kind !== 'soft-hyphen') {\n return { cursor: { segmentIndex, graphemeIndex: 0 }, chunkIndex };\n }\n segmentIndex++;\n }\n if (chunk.consumedEndSegmentIndex >= prepared.widths.length)\n return null;\n return {\n cursor: { segmentIndex: chunk.consumedEndSegmentIndex, graphemeIndex: 0 },\n chunkIndex: chunkIndex + 1,\n };\n}\nexport function normalizeLineStart(prepared, start) {\n return normalizeLineStartWithChunk(prepared, start)?.cursor ?? null;\n}\nexport function countPreparedLines(prepared, maxWidth) {\n if (prepared.simpleLineWalkFastPath) {\n return countPreparedLinesSimple(prepared, maxWidth);\n }\n return walkPreparedLines(prepared, maxWidth);\n}\nfunction countPreparedLinesSimple(prepared, maxWidth) {\n return walkPreparedLinesSimple(prepared, maxWidth);\n}\nfunction walkPreparedLinesSimple(prepared, maxWidth, onLine) {\n const { widths, kinds, breakableWidths, breakablePrefixWidths } = prepared;\n if (widths.length === 0)\n return 0;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n let lineCount = 0;\n let lineW = 0;\n let hasContent = false;\n let lineStartSegmentIndex = 0;\n let lineStartGraphemeIndex = 0;\n let lineEndSegmentIndex = 0;\n let lineEndGraphemeIndex = 0;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakPaintWidth = 0;\n function clearPendingBreak() {\n pendingBreakSegmentIndex = -1;\n pendingBreakPaintWidth = 0;\n }\n function emitCurrentLine(endSegmentIndex = lineEndSegmentIndex, endGraphemeIndex = lineEndGraphemeIndex, width = lineW) {\n lineCount++;\n onLine?.({\n startSegmentIndex: lineStartSegmentIndex,\n startGraphemeIndex: lineStartGraphemeIndex,\n endSegmentIndex,\n endGraphemeIndex,\n width,\n });\n lineW = 0;\n hasContent = false;\n clearPendingBreak();\n }\n function startLineAtSegment(segmentIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = 0;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n lineW = width;\n }\n function startLineAtGrapheme(segmentIndex, graphemeIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = graphemeIndex;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = graphemeIndex + 1;\n lineW = width;\n }\n function appendWholeSegment(segmentIndex, width) {\n if (!hasContent) {\n startLineAtSegment(segmentIndex, width);\n return;\n }\n lineW += width;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n function updatePendingBreak(segmentIndex, segmentWidth) {\n if (!canBreakAfter(kinds[segmentIndex]))\n return;\n pendingBreakSegmentIndex = segmentIndex + 1;\n pendingBreakPaintWidth = lineW - segmentWidth;\n }\n function appendBreakableSegment(segmentIndex) {\n appendBreakableSegmentFrom(segmentIndex, 0);\n }\n function appendBreakableSegmentFrom(segmentIndex, startGraphemeIndex) {\n const gWidths = breakableWidths[segmentIndex];\n const gPrefixWidths = breakablePrefixWidths[segmentIndex] ?? null;\n for (let g = startGraphemeIndex; g < gWidths.length; g++) {\n const gw = getBreakableAdvance(gWidths, gPrefixWidths, g, engineProfile.preferPrefixWidthsForBreakableRuns);\n if (!hasContent) {\n startLineAtGrapheme(segmentIndex, g, gw);\n continue;\n }\n if (lineW + gw > maxWidth + lineFitEpsilon) {\n emitCurrentLine();\n startLineAtGrapheme(segmentIndex, g, gw);\n }\n else {\n lineW += gw;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = g + 1;\n }\n }\n if (hasContent && lineEndSegmentIndex === segmentIndex && lineEndGraphemeIndex === gWidths.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n }\n let i = 0;\n while (i < widths.length) {\n if (!hasContent) {\n i = normalizeSimpleLineStartSegmentIndex(prepared, i);\n if (i >= widths.length)\n break;\n }\n const w = widths[i];\n const kind = kinds[i];\n if (!hasContent) {\n if (w > maxWidth && breakableWidths[i] !== null) {\n appendBreakableSegment(i);\n }\n else {\n startLineAtSegment(i, w);\n }\n updatePendingBreak(i, w);\n i++;\n continue;\n }\n const newW = lineW + w;\n if (newW > maxWidth + lineFitEpsilon) {\n if (canBreakAfter(kind)) {\n appendWholeSegment(i, w);\n emitCurrentLine(i + 1, 0, lineW - w);\n i++;\n continue;\n }\n if (pendingBreakSegmentIndex >= 0) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n emitCurrentLine();\n continue;\n }\n emitCurrentLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n continue;\n }\n if (w > maxWidth && breakableWidths[i] !== null) {\n emitCurrentLine();\n appendBreakableSegment(i);\n i++;\n continue;\n }\n emitCurrentLine();\n continue;\n }\n appendWholeSegment(i, w);\n updatePendingBreak(i, w);\n i++;\n }\n if (hasContent)\n emitCurrentLine();\n return lineCount;\n}\nexport function walkPreparedLines(prepared, maxWidth, onLine) {\n if (prepared.simpleLineWalkFastPath) {\n return walkPreparedLinesSimple(prepared, maxWidth, onLine);\n }\n const { widths, lineEndFitAdvances, lineEndPaintAdvances, kinds, breakableWidths, breakablePrefixWidths, discretionaryHyphenWidth, tabStopAdvance, chunks, } = prepared;\n if (widths.length === 0 || chunks.length === 0)\n return 0;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n let lineCount = 0;\n let lineW = 0;\n let hasContent = false;\n let lineStartSegmentIndex = 0;\n let lineStartGraphemeIndex = 0;\n let lineEndSegmentIndex = 0;\n let lineEndGraphemeIndex = 0;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakFitWidth = 0;\n let pendingBreakPaintWidth = 0;\n let pendingBreakKind = null;\n function clearPendingBreak() {\n pendingBreakSegmentIndex = -1;\n pendingBreakFitWidth = 0;\n pendingBreakPaintWidth = 0;\n pendingBreakKind = null;\n }\n function emitCurrentLine(endSegmentIndex = lineEndSegmentIndex, endGraphemeIndex = lineEndGraphemeIndex, width = lineW) {\n lineCount++;\n onLine?.({\n startSegmentIndex: lineStartSegmentIndex,\n startGraphemeIndex: lineStartGraphemeIndex,\n endSegmentIndex,\n endGraphemeIndex,\n width,\n });\n lineW = 0;\n hasContent = false;\n clearPendingBreak();\n }\n function startLineAtSegment(segmentIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = 0;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n lineW = width;\n }\n function startLineAtGrapheme(segmentIndex, graphemeIndex, width) {\n hasContent = true;\n lineStartSegmentIndex = segmentIndex;\n lineStartGraphemeIndex = graphemeIndex;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = graphemeIndex + 1;\n lineW = width;\n }\n function appendWholeSegment(segmentIndex, width) {\n if (!hasContent) {\n startLineAtSegment(segmentIndex, width);\n return;\n }\n lineW += width;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n function updatePendingBreakForWholeSegment(segmentIndex, segmentWidth) {\n if (!canBreakAfter(kinds[segmentIndex]))\n return;\n const fitAdvance = kinds[segmentIndex] === 'tab' ? 0 : lineEndFitAdvances[segmentIndex];\n const paintAdvance = kinds[segmentIndex] === 'tab' ? segmentWidth : lineEndPaintAdvances[segmentIndex];\n pendingBreakSegmentIndex = segmentIndex + 1;\n pendingBreakFitWidth = lineW - segmentWidth + fitAdvance;\n pendingBreakPaintWidth = lineW - segmentWidth + paintAdvance;\n pendingBreakKind = kinds[segmentIndex];\n }\n function appendBreakableSegment(segmentIndex) {\n appendBreakableSegmentFrom(segmentIndex, 0);\n }\n function appendBreakableSegmentFrom(segmentIndex, startGraphemeIndex) {\n const gWidths = breakableWidths[segmentIndex];\n const gPrefixWidths = breakablePrefixWidths[segmentIndex] ?? null;\n for (let g = startGraphemeIndex; g < gWidths.length; g++) {\n const gw = getBreakableAdvance(gWidths, gPrefixWidths, g, engineProfile.preferPrefixWidthsForBreakableRuns);\n if (!hasContent) {\n startLineAtGrapheme(segmentIndex, g, gw);\n continue;\n }\n if (lineW + gw > maxWidth + lineFitEpsilon) {\n emitCurrentLine();\n startLineAtGrapheme(segmentIndex, g, gw);\n }\n else {\n lineW += gw;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = g + 1;\n }\n }\n if (hasContent && lineEndSegmentIndex === segmentIndex && lineEndGraphemeIndex === gWidths.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n }\n function continueSoftHyphenBreakableSegment(segmentIndex) {\n if (pendingBreakKind !== 'soft-hyphen')\n return false;\n const gWidths = breakableWidths[segmentIndex];\n if (gWidths === null)\n return false;\n const fitWidths = engineProfile.preferPrefixWidthsForBreakableRuns\n ? breakablePrefixWidths[segmentIndex] ?? gWidths\n : gWidths;\n const usesPrefixWidths = fitWidths !== gWidths;\n const { fitCount, fittedWidth } = fitSoftHyphenBreak(fitWidths, lineW, maxWidth, lineFitEpsilon, discretionaryHyphenWidth, usesPrefixWidths);\n if (fitCount === 0)\n return false;\n lineW = fittedWidth;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = fitCount;\n clearPendingBreak();\n if (fitCount === gWidths.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n return true;\n }\n emitCurrentLine(segmentIndex, fitCount, fittedWidth + discretionaryHyphenWidth);\n appendBreakableSegmentFrom(segmentIndex, fitCount);\n return true;\n }\n function emitEmptyChunk(chunk) {\n lineCount++;\n onLine?.({\n startSegmentIndex: chunk.startSegmentIndex,\n startGraphemeIndex: 0,\n endSegmentIndex: chunk.consumedEndSegmentIndex,\n endGraphemeIndex: 0,\n width: 0,\n });\n clearPendingBreak();\n }\n for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {\n const chunk = chunks[chunkIndex];\n if (chunk.startSegmentIndex === chunk.endSegmentIndex) {\n emitEmptyChunk(chunk);\n continue;\n }\n hasContent = false;\n lineW = 0;\n lineStartSegmentIndex = chunk.startSegmentIndex;\n lineStartGraphemeIndex = 0;\n lineEndSegmentIndex = chunk.startSegmentIndex;\n lineEndGraphemeIndex = 0;\n clearPendingBreak();\n let i = chunk.startSegmentIndex;\n while (i < chunk.endSegmentIndex) {\n const kind = kinds[i];\n const w = kind === 'tab' ? getTabAdvance(lineW, tabStopAdvance) : widths[i];\n if (kind === 'soft-hyphen') {\n if (hasContent) {\n lineEndSegmentIndex = i + 1;\n lineEndGraphemeIndex = 0;\n pendingBreakSegmentIndex = i + 1;\n pendingBreakFitWidth = lineW + discretionaryHyphenWidth;\n pendingBreakPaintWidth = lineW + discretionaryHyphenWidth;\n pendingBreakKind = kind;\n }\n i++;\n continue;\n }\n if (!hasContent) {\n if (w > maxWidth && breakableWidths[i] !== null) {\n appendBreakableSegment(i);\n }\n else {\n startLineAtSegment(i, w);\n }\n updatePendingBreakForWholeSegment(i, w);\n i++;\n continue;\n }\n const newW = lineW + w;\n if (newW > maxWidth + lineFitEpsilon) {\n const currentBreakFitWidth = lineW + (kind === 'tab' ? 0 : lineEndFitAdvances[i]);\n const currentBreakPaintWidth = lineW + (kind === 'tab' ? w : lineEndPaintAdvances[i]);\n if (pendingBreakKind === 'soft-hyphen' &&\n engineProfile.preferEarlySoftHyphenBreak &&\n pendingBreakFitWidth <= maxWidth + lineFitEpsilon) {\n emitCurrentLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n continue;\n }\n if (pendingBreakKind === 'soft-hyphen' && continueSoftHyphenBreakableSegment(i)) {\n i++;\n continue;\n }\n if (canBreakAfter(kind) && currentBreakFitWidth <= maxWidth + lineFitEpsilon) {\n appendWholeSegment(i, w);\n emitCurrentLine(i + 1, 0, currentBreakPaintWidth);\n i++;\n continue;\n }\n if (pendingBreakSegmentIndex >= 0 && pendingBreakFitWidth <= maxWidth + lineFitEpsilon) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n emitCurrentLine();\n continue;\n }\n const nextSegmentIndex = pendingBreakSegmentIndex;\n emitCurrentLine(nextSegmentIndex, 0, pendingBreakPaintWidth);\n i = nextSegmentIndex;\n continue;\n }\n if (w > maxWidth && breakableWidths[i] !== null) {\n emitCurrentLine();\n appendBreakableSegment(i);\n i++;\n continue;\n }\n emitCurrentLine();\n continue;\n }\n appendWholeSegment(i, w);\n updatePendingBreakForWholeSegment(i, w);\n i++;\n }\n if (hasContent) {\n const finalPaintWidth = pendingBreakSegmentIndex === chunk.consumedEndSegmentIndex\n ? pendingBreakPaintWidth\n : lineW;\n emitCurrentLine(chunk.consumedEndSegmentIndex, 0, finalPaintWidth);\n }\n }\n return lineCount;\n}\nexport function layoutNextLineRange(prepared, start, maxWidth) {\n const normalized = normalizeLineStartWithChunk(prepared, start);\n if (normalized === null)\n return null;\n if (prepared.simpleLineWalkFastPath) {\n return layoutNextLineRangeSimple(prepared, normalized.cursor, maxWidth);\n }\n const chunk = prepared.chunks[normalized.chunkIndex];\n if (chunk.startSegmentIndex === chunk.endSegmentIndex) {\n return {\n startSegmentIndex: chunk.startSegmentIndex,\n startGraphemeIndex: 0,\n endSegmentIndex: chunk.consumedEndSegmentIndex,\n endGraphemeIndex: 0,\n width: 0,\n };\n }\n const { widths, lineEndFitAdvances, lineEndPaintAdvances, kinds, breakableWidths, breakablePrefixWidths, discretionaryHyphenWidth, tabStopAdvance, } = prepared;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n let lineW = 0;\n let hasContent = false;\n const lineStartSegmentIndex = normalized.cursor.segmentIndex;\n const lineStartGraphemeIndex = normalized.cursor.graphemeIndex;\n let lineEndSegmentIndex = lineStartSegmentIndex;\n let lineEndGraphemeIndex = lineStartGraphemeIndex;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakFitWidth = 0;\n let pendingBreakPaintWidth = 0;\n let pendingBreakKind = null;\n function clearPendingBreak() {\n pendingBreakSegmentIndex = -1;\n pendingBreakFitWidth = 0;\n pendingBreakPaintWidth = 0;\n pendingBreakKind = null;\n }\n function finishLine(endSegmentIndex = lineEndSegmentIndex, endGraphemeIndex = lineEndGraphemeIndex, width = lineW) {\n if (!hasContent)\n return null;\n return {\n startSegmentIndex: lineStartSegmentIndex,\n startGraphemeIndex: lineStartGraphemeIndex,\n endSegmentIndex,\n endGraphemeIndex,\n width,\n };\n }\n function startLineAtSegment(segmentIndex, width) {\n hasContent = true;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n lineW = width;\n }\n function startLineAtGrapheme(segmentIndex, graphemeIndex, width) {\n hasContent = true;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = graphemeIndex + 1;\n lineW = width;\n }\n function appendWholeSegment(segmentIndex, width) {\n if (!hasContent) {\n startLineAtSegment(segmentIndex, width);\n return;\n }\n lineW += width;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n function updatePendingBreakForWholeSegment(segmentIndex, segmentWidth) {\n if (!canBreakAfter(kinds[segmentIndex]))\n return;\n const fitAdvance = kinds[segmentIndex] === 'tab' ? 0 : lineEndFitAdvances[segmentIndex];\n const paintAdvance = kinds[segmentIndex] === 'tab' ? segmentWidth : lineEndPaintAdvances[segmentIndex];\n pendingBreakSegmentIndex = segmentIndex + 1;\n pendingBreakFitWidth = lineW - segmentWidth + fitAdvance;\n pendingBreakPaintWidth = lineW - segmentWidth + paintAdvance;\n pendingBreakKind = kinds[segmentIndex];\n }\n function appendBreakableSegmentFrom(segmentIndex, startGraphemeIndex) {\n const gWidths = breakableWidths[segmentIndex];\n const gPrefixWidths = breakablePrefixWidths[segmentIndex] ?? null;\n for (let g = startGraphemeIndex; g < gWidths.length; g++) {\n const gw = getBreakableAdvance(gWidths, gPrefixWidths, g, engineProfile.preferPrefixWidthsForBreakableRuns);\n if (!hasContent) {\n startLineAtGrapheme(segmentIndex, g, gw);\n continue;\n }\n if (lineW + gw > maxWidth + lineFitEpsilon) {\n return finishLine();\n }\n lineW += gw;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = g + 1;\n }\n if (hasContent && lineEndSegmentIndex === segmentIndex && lineEndGraphemeIndex === gWidths.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n return null;\n }\n function maybeFinishAtSoftHyphen(segmentIndex) {\n if (pendingBreakKind !== 'soft-hyphen' || pendingBreakSegmentIndex < 0)\n return null;\n const gWidths = breakableWidths[segmentIndex] ?? null;\n if (gWidths !== null) {\n const fitWidths = engineProfile.preferPrefixWidthsForBreakableRuns\n ? breakablePrefixWidths[segmentIndex] ?? gWidths\n : gWidths;\n const usesPrefixWidths = fitWidths !== gWidths;\n const { fitCount, fittedWidth } = fitSoftHyphenBreak(fitWidths, lineW, maxWidth, lineFitEpsilon, discretionaryHyphenWidth, usesPrefixWidths);\n if (fitCount === gWidths.length) {\n lineW = fittedWidth;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n clearPendingBreak();\n return null;\n }\n if (fitCount > 0) {\n return finishLine(segmentIndex, fitCount, fittedWidth + discretionaryHyphenWidth);\n }\n }\n if (pendingBreakFitWidth <= maxWidth + lineFitEpsilon) {\n return finishLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n }\n return null;\n }\n for (let i = normalized.cursor.segmentIndex; i < chunk.endSegmentIndex; i++) {\n const kind = kinds[i];\n const startGraphemeIndex = i === normalized.cursor.segmentIndex ? normalized.cursor.graphemeIndex : 0;\n const w = kind === 'tab' ? getTabAdvance(lineW, tabStopAdvance) : widths[i];\n if (kind === 'soft-hyphen' && startGraphemeIndex === 0) {\n if (hasContent) {\n lineEndSegmentIndex = i + 1;\n lineEndGraphemeIndex = 0;\n pendingBreakSegmentIndex = i + 1;\n pendingBreakFitWidth = lineW + discretionaryHyphenWidth;\n pendingBreakPaintWidth = lineW + discretionaryHyphenWidth;\n pendingBreakKind = kind;\n }\n continue;\n }\n if (!hasContent) {\n if (startGraphemeIndex > 0) {\n const line = appendBreakableSegmentFrom(i, startGraphemeIndex);\n if (line !== null)\n return line;\n }\n else if (w > maxWidth && breakableWidths[i] !== null) {\n const line = appendBreakableSegmentFrom(i, 0);\n if (line !== null)\n return line;\n }\n else {\n startLineAtSegment(i, w);\n }\n updatePendingBreakForWholeSegment(i, w);\n continue;\n }\n const newW = lineW + w;\n if (newW > maxWidth + lineFitEpsilon) {\n const currentBreakFitWidth = lineW + (kind === 'tab' ? 0 : lineEndFitAdvances[i]);\n const currentBreakPaintWidth = lineW + (kind === 'tab' ? w : lineEndPaintAdvances[i]);\n if (pendingBreakKind === 'soft-hyphen' &&\n engineProfile.preferEarlySoftHyphenBreak &&\n pendingBreakFitWidth <= maxWidth + lineFitEpsilon) {\n return finishLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n }\n const softBreakLine = maybeFinishAtSoftHyphen(i);\n if (softBreakLine !== null)\n return softBreakLine;\n if (canBreakAfter(kind) && currentBreakFitWidth <= maxWidth + lineFitEpsilon) {\n appendWholeSegment(i, w);\n return finishLine(i + 1, 0, currentBreakPaintWidth);\n }\n if (pendingBreakSegmentIndex >= 0 && pendingBreakFitWidth <= maxWidth + lineFitEpsilon) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n return finishLine();\n }\n return finishLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n }\n if (w > maxWidth && breakableWidths[i] !== null) {\n const currentLine = finishLine();\n if (currentLine !== null)\n return currentLine;\n const line = appendBreakableSegmentFrom(i, 0);\n if (line !== null)\n return line;\n }\n return finishLine();\n }\n appendWholeSegment(i, w);\n updatePendingBreakForWholeSegment(i, w);\n }\n if (pendingBreakSegmentIndex === chunk.consumedEndSegmentIndex && lineEndGraphemeIndex === 0) {\n return finishLine(chunk.consumedEndSegmentIndex, 0, pendingBreakPaintWidth);\n }\n return finishLine(chunk.consumedEndSegmentIndex, 0, lineW);\n}\nfunction layoutNextLineRangeSimple(prepared, normalizedStart, maxWidth) {\n const { widths, kinds, breakableWidths, breakablePrefixWidths } = prepared;\n const engineProfile = getEngineProfile();\n const lineFitEpsilon = engineProfile.lineFitEpsilon;\n let lineW = 0;\n let hasContent = false;\n const lineStartSegmentIndex = normalizedStart.segmentIndex;\n const lineStartGraphemeIndex = normalizedStart.graphemeIndex;\n let lineEndSegmentIndex = lineStartSegmentIndex;\n let lineEndGraphemeIndex = lineStartGraphemeIndex;\n let pendingBreakSegmentIndex = -1;\n let pendingBreakPaintWidth = 0;\n function finishLine(endSegmentIndex = lineEndSegmentIndex, endGraphemeIndex = lineEndGraphemeIndex, width = lineW) {\n if (!hasContent)\n return null;\n return {\n startSegmentIndex: lineStartSegmentIndex,\n startGraphemeIndex: lineStartGraphemeIndex,\n endSegmentIndex,\n endGraphemeIndex,\n width,\n };\n }\n function startLineAtSegment(segmentIndex, width) {\n hasContent = true;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n lineW = width;\n }\n function startLineAtGrapheme(segmentIndex, graphemeIndex, width) {\n hasContent = true;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = graphemeIndex + 1;\n lineW = width;\n }\n function appendWholeSegment(segmentIndex, width) {\n if (!hasContent) {\n startLineAtSegment(segmentIndex, width);\n return;\n }\n lineW += width;\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n function updatePendingBreak(segmentIndex, segmentWidth) {\n if (!canBreakAfter(kinds[segmentIndex]))\n return;\n pendingBreakSegmentIndex = segmentIndex + 1;\n pendingBreakPaintWidth = lineW - segmentWidth;\n }\n function appendBreakableSegmentFrom(segmentIndex, startGraphemeIndex) {\n const gWidths = breakableWidths[segmentIndex];\n const gPrefixWidths = breakablePrefixWidths[segmentIndex] ?? null;\n for (let g = startGraphemeIndex; g < gWidths.length; g++) {\n const gw = getBreakableAdvance(gWidths, gPrefixWidths, g, engineProfile.preferPrefixWidthsForBreakableRuns);\n if (!hasContent) {\n startLineAtGrapheme(segmentIndex, g, gw);\n continue;\n }\n if (lineW + gw > maxWidth + lineFitEpsilon) {\n return finishLine();\n }\n lineW += gw;\n lineEndSegmentIndex = segmentIndex;\n lineEndGraphemeIndex = g + 1;\n }\n if (hasContent && lineEndSegmentIndex === segmentIndex && lineEndGraphemeIndex === gWidths.length) {\n lineEndSegmentIndex = segmentIndex + 1;\n lineEndGraphemeIndex = 0;\n }\n return null;\n }\n for (let i = normalizedStart.segmentIndex; i < widths.length; i++) {\n const w = widths[i];\n const kind = kinds[i];\n const startGraphemeIndex = i === normalizedStart.segmentIndex ? normalizedStart.graphemeIndex : 0;\n if (!hasContent) {\n if (startGraphemeIndex > 0) {\n const line = appendBreakableSegmentFrom(i, startGraphemeIndex);\n if (line !== null)\n return line;\n }\n else if (w > maxWidth && breakableWidths[i] !== null) {\n const line = appendBreakableSegmentFrom(i, 0);\n if (line !== null)\n return line;\n }\n else {\n startLineAtSegment(i, w);\n }\n updatePendingBreak(i, w);\n continue;\n }\n const newW = lineW + w;\n if (newW > maxWidth + lineFitEpsilon) {\n if (canBreakAfter(kind)) {\n appendWholeSegment(i, w);\n return finishLine(i + 1, 0, lineW - w);\n }\n if (pendingBreakSegmentIndex >= 0) {\n if (lineEndSegmentIndex > pendingBreakSegmentIndex ||\n (lineEndSegmentIndex === pendingBreakSegmentIndex && lineEndGraphemeIndex > 0)) {\n return finishLine();\n }\n return finishLine(pendingBreakSegmentIndex, 0, pendingBreakPaintWidth);\n }\n if (w > maxWidth && breakableWidths[i] !== null) {\n const currentLine = finishLine();\n if (currentLine !== null)\n return currentLine;\n const line = appendBreakableSegmentFrom(i, 0);\n if (line !== null)\n return line;\n }\n return finishLine();\n }\n appendWholeSegment(i, w);\n updatePendingBreak(i, w);\n }\n return finishLine();\n}\n","// Text measurement for browser environments using canvas measureText.\n//\n// Problem: DOM-based text measurement (getBoundingClientRect, offsetHeight)\n// forces synchronous layout reflow. When components independently measure text,\n// each measurement triggers a reflow of the entire document. This creates\n// read/write interleaving that can cost 30ms+ per frame for 500 text blocks.\n//\n// Solution: two-phase measurement centered around canvas measureText.\n// prepare(text, font) — segments text via Intl.Segmenter, measures each word\n// via canvas, caches widths, and does one cached DOM calibration read per\n// font when emoji correction is needed. Call once when text first appears.\n// layout(prepared, maxWidth, lineHeight) — walks cached word widths with pure\n// arithmetic to count lines and compute height. Call on every resize.\n// ~0.0002ms per text.\n//\n// i18n: Intl.Segmenter handles CJK (per-character breaking), Thai, Arabic, etc.\n// Bidi: simplified rich-path metadata for mixed LTR/RTL custom rendering.\n// Punctuation merging: \"better.\" measured as one unit (matches CSS behavior).\n// Trailing whitespace: hangs past line edge without triggering breaks (CSS behavior).\n// overflow-wrap: pre-measured grapheme widths enable character-level word breaking.\n//\n// Emoji correction: Chrome/Firefox canvas measures emoji wider than DOM at font\n// sizes <24px on macOS (Apple Color Emoji). The inflation is constant per emoji\n// grapheme at a given size, font-independent. Auto-detected by comparing canvas\n// vs actual DOM emoji width (one cached DOM read per font). Safari canvas and\n// DOM agree (both wider than fontSize), so correction = 0 there.\n//\n// Limitations:\n// - system-ui font: canvas resolves to different optical variants than DOM on macOS.\n// Use named fonts (Helvetica, Inter, etc.) for guaranteed accuracy.\n// See RESEARCH.md \"Discovery: system-ui font resolution mismatch\".\n//\n// Based on Sebastian Markbage's text-layout research (github.com/chenglou/text-layout).\nimport { computeSegmentLevels } from './bidi.js';\nimport { analyzeText, clearAnalysisCaches, endsWithClosingQuote, isCJK, kinsokuEnd, kinsokuStart, leftStickyPunctuation, setAnalysisLocale, } from './analysis.js';\nimport { clearMeasurementCaches, getCorrectedSegmentWidth, getEngineProfile, getFontMeasurementState, getSegmentGraphemePrefixWidths, getSegmentGraphemeWidths, getSegmentMetrics, textMayContainEmoji, } from './measurement.js';\nimport { countPreparedLines, layoutNextLineRange as stepPreparedLineRange, walkPreparedLines, } from './line-break.js';\nlet sharedGraphemeSegmenter = null;\n// Rich-path only. Reuses grapheme splits while materializing multiple lines\n// from the same prepared handle, without pushing that cache into the API.\nlet sharedLineTextCaches = new WeakMap();\nfunction getSharedGraphemeSegmenter() {\n if (sharedGraphemeSegmenter === null) {\n sharedGraphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });\n }\n return sharedGraphemeSegmenter;\n}\n// --- Public API ---\nfunction createEmptyPrepared(includeSegments) {\n if (includeSegments) {\n return {\n widths: [],\n lineEndFitAdvances: [],\n lineEndPaintAdvances: [],\n kinds: [],\n simpleLineWalkFastPath: true,\n segLevels: null,\n breakableWidths: [],\n breakablePrefixWidths: [],\n discretionaryHyphenWidth: 0,\n tabStopAdvance: 0,\n chunks: [],\n segments: [],\n };\n }\n return {\n widths: [],\n lineEndFitAdvances: [],\n lineEndPaintAdvances: [],\n kinds: [],\n simpleLineWalkFastPath: true,\n segLevels: null,\n breakableWidths: [],\n breakablePrefixWidths: [],\n discretionaryHyphenWidth: 0,\n tabStopAdvance: 0,\n chunks: [],\n };\n}\nfunction measureAnalysis(analysis, font, includeSegments) {\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n const engineProfile = getEngineProfile();\n const { cache, emojiCorrection } = getFontMeasurementState(font, textMayContainEmoji(analysis.normalized));\n const discretionaryHyphenWidth = getCorrectedSegmentWidth('-', getSegmentMetrics('-', cache), emojiCorrection);\n const spaceWidth = getCorrectedSegmentWidth(' ', getSegmentMetrics(' ', cache), emojiCorrection);\n const tabStopAdvance = spaceWidth * 8;\n if (analysis.len === 0)\n return createEmptyPrepared(includeSegments);\n const widths = [];\n const lineEndFitAdvances = [];\n const lineEndPaintAdvances = [];\n const kinds = [];\n let simpleLineWalkFastPath = analysis.chunks.length <= 1;\n const segStarts = includeSegments ? [] : null;\n const breakableWidths = [];\n const breakablePrefixWidths = [];\n const segments = includeSegments ? [] : null;\n const preparedStartByAnalysisIndex = Array.from({ length: analysis.len });\n const preparedEndByAnalysisIndex = Array.from({ length: analysis.len });\n function pushMeasuredSegment(text, width, lineEndFitAdvance, lineEndPaintAdvance, kind, start, breakable, breakablePrefix) {\n if (kind !== 'text' && kind !== 'space' && kind !== 'zero-width-break') {\n simpleLineWalkFastPath = false;\n }\n widths.push(width);\n lineEndFitAdvances.push(lineEndFitAdvance);\n lineEndPaintAdvances.push(lineEndPaintAdvance);\n kinds.push(kind);\n segStarts?.push(start);\n breakableWidths.push(breakable);\n breakablePrefixWidths.push(breakablePrefix);\n if (segments !== null)\n segments.push(text);\n }\n for (let mi = 0; mi < analysis.len; mi++) {\n preparedStartByAnalysisIndex[mi] = widths.length;\n const segText = analysis.texts[mi];\n const segWordLike = analysis.isWordLike[mi];\n const segKind = analysis.kinds[mi];\n const segStart = analysis.starts[mi];\n if (segKind === 'soft-hyphen') {\n pushMeasuredSegment(segText, 0, discretionaryHyphenWidth, discretionaryHyphenWidth, segKind, segStart, null, null);\n preparedEndByAnalysisIndex[mi] = widths.length;\n continue;\n }\n if (segKind === 'hard-break') {\n pushMeasuredSegment(segText, 0, 0, 0, segKind, segStart, null, null);\n preparedEndByAnalysisIndex[mi] = widths.length;\n continue;\n }\n if (segKind === 'tab') {\n pushMeasuredSegment(segText, 0, 0, 0, segKind, segStart, null, null);\n preparedEndByAnalysisIndex[mi] = widths.length;\n continue;\n }\n const segMetrics = getSegmentMetrics(segText, cache);\n if (segKind === 'text' && segMetrics.containsCJK) {\n let unitText = '';\n let unitStart = 0;\n for (const gs of graphemeSegmenter.segment(segText)) {\n const grapheme = gs.segment;\n if (unitText.length === 0) {\n unitText = grapheme;\n unitStart = gs.index;\n continue;\n }\n if (kinsokuEnd.has(unitText) ||\n kinsokuStart.has(grapheme) ||\n leftStickyPunctuation.has(grapheme) ||\n (engineProfile.carryCJKAfterClosingQuote &&\n isCJK(grapheme) &&\n endsWithClosingQuote(unitText))) {\n unitText += grapheme;\n continue;\n }\n const unitMetrics = getSegmentMetrics(unitText, cache);\n const w = getCorrectedSegmentWidth(unitText, unitMetrics, emojiCorrection);\n pushMeasuredSegment(unitText, w, w, w, 'text', segStart + unitStart, null, null);\n unitText = grapheme;\n unitStart = gs.index;\n }\n if (unitText.length > 0) {\n const unitMetrics = getSegmentMetrics(unitText, cache);\n const w = getCorrectedSegmentWidth(unitText, unitMetrics, emojiCorrection);\n pushMeasuredSegment(unitText, w, w, w, 'text', segStart + unitStart, null, null);\n }\n preparedEndByAnalysisIndex[mi] = widths.length;\n continue;\n }\n const w = getCorrectedSegmentWidth(segText, segMetrics, emojiCorrection);\n const lineEndFitAdvance = segKind === 'space' || segKind === 'preserved-space' || segKind === 'zero-width-break'\n ? 0\n : w;\n const lineEndPaintAdvance = segKind === 'space' || segKind === 'zero-width-break'\n ? 0\n : w;\n if (segWordLike && segText.length > 1) {\n const graphemeWidths = getSegmentGraphemeWidths(segText, segMetrics, cache, emojiCorrection);\n const graphemePrefixWidths = engineProfile.preferPrefixWidthsForBreakableRuns\n ? getSegmentGraphemePrefixWidths(segText, segMetrics, cache, emojiCorrection)\n : null;\n pushMeasuredSegment(segText, w, lineEndFitAdvance, lineEndPaintAdvance, segKind, segStart, graphemeWidths, graphemePrefixWidths);\n }\n else {\n pushMeasuredSegment(segText, w, lineEndFitAdvance, lineEndPaintAdvance, segKind, segStart, null, null);\n }\n preparedEndByAnalysisIndex[mi] = widths.length;\n }\n const chunks = mapAnalysisChunksToPreparedChunks(analysis.chunks, preparedStartByAnalysisIndex, preparedEndByAnalysisIndex);\n const segLevels = segStarts === null ? null : computeSegmentLevels(analysis.normalized, segStarts);\n if (segments !== null) {\n return {\n widths,\n lineEndFitAdvances,\n lineEndPaintAdvances,\n kinds,\n simpleLineWalkFastPath,\n segLevels,\n breakableWidths,\n breakablePrefixWidths,\n discretionaryHyphenWidth,\n tabStopAdvance,\n chunks,\n segments,\n };\n }\n return {\n widths,\n lineEndFitAdvances,\n lineEndPaintAdvances,\n kinds,\n simpleLineWalkFastPath,\n segLevels,\n breakableWidths,\n breakablePrefixWidths,\n discretionaryHyphenWidth,\n tabStopAdvance,\n chunks,\n };\n}\nfunction mapAnalysisChunksToPreparedChunks(chunks, preparedStartByAnalysisIndex, preparedEndByAnalysisIndex) {\n const preparedChunks = [];\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n const startSegmentIndex = chunk.startSegmentIndex < preparedStartByAnalysisIndex.length\n ? preparedStartByAnalysisIndex[chunk.startSegmentIndex]\n : preparedEndByAnalysisIndex[preparedEndByAnalysisIndex.length - 1] ?? 0;\n const endSegmentIndex = chunk.endSegmentIndex < preparedStartByAnalysisIndex.length\n ? preparedStartByAnalysisIndex[chunk.endSegmentIndex]\n : preparedEndByAnalysisIndex[preparedEndByAnalysisIndex.length - 1] ?? 0;\n const consumedEndSegmentIndex = chunk.consumedEndSegmentIndex < preparedStartByAnalysisIndex.length\n ? preparedStartByAnalysisIndex[chunk.consumedEndSegmentIndex]\n : preparedEndByAnalysisIndex[preparedEndByAnalysisIndex.length - 1] ?? 0;\n preparedChunks.push({\n startSegmentIndex,\n endSegmentIndex,\n consumedEndSegmentIndex,\n });\n }\n return preparedChunks;\n}\nfunction prepareInternal(text, font, includeSegments, options) {\n const analysis = analyzeText(text, getEngineProfile(), options?.whiteSpace);\n return measureAnalysis(analysis, font, includeSegments);\n}\n// Diagnostic-only helper used by the browser benchmark harness to separate the\n// text-analysis and measurement phases without duplicating the prepare logic.\nexport function profilePrepare(text, font, options) {\n const t0 = performance.now();\n const analysis = analyzeText(text, getEngineProfile(), options?.whiteSpace);\n const t1 = performance.now();\n const prepared = measureAnalysis(analysis, font, false);\n const t2 = performance.now();\n let breakableSegments = 0;\n for (const widths of prepared.breakableWidths) {\n if (widths !== null)\n breakableSegments++;\n }\n return {\n analysisMs: t1 - t0,\n measureMs: t2 - t1,\n totalMs: t2 - t0,\n analysisSegments: analysis.len,\n preparedSegments: prepared.widths.length,\n breakableSegments,\n };\n}\n// Prepare text for layout. Segments the text, measures each segment via canvas,\n// and stores the widths for fast relayout at any width. Call once per text block\n// (e.g. when a comment first appears). The result is width-independent — the\n// same PreparedText can be laid out at any maxWidth and lineHeight via layout().\n//\n// Steps:\n// 1. Normalize collapsible whitespace (CSS white-space: normal behavior)\n// 2. Segment via Intl.Segmenter (handles CJK, Thai, etc.)\n// 3. Merge punctuation into preceding word (\"better.\" as one unit)\n// 4. Split CJK words into individual graphemes (per-character line breaks)\n// 5. Measure each segment via canvas measureText, cache by (segment, font)\n// 6. Pre-measure graphemes of long words (for overflow-wrap: break-word)\n// 7. Correct emoji canvas inflation (auto-detected per font size)\n// 8. Optionally compute rich-path bidi metadata for custom renderers\nexport function prepare(text, font, options) {\n return prepareInternal(text, font, false, options);\n}\n// Rich variant used by callers that need enough information to render the\n// laid-out lines themselves.\nexport function prepareWithSegments(text, font, options) {\n return prepareInternal(text, font, true, options);\n}\nfunction getInternalPrepared(prepared) {\n return prepared;\n}\n// Layout prepared text at a given max width and caller-provided lineHeight.\n// Pure arithmetic on cached widths — no canvas calls, no DOM reads, no string\n// operations, no allocations.\n// ~0.0002ms per text block. Call on every resize.\n//\n// Line breaking rules (matching CSS white-space: normal + overflow-wrap: break-word):\n// - Break before any non-space segment that would overflow the line\n// - Trailing whitespace hangs past the line edge (doesn't trigger breaks)\n// - Segments wider than maxWidth are broken at grapheme boundaries\nexport function layout(prepared, maxWidth, lineHeight) {\n // Keep the resize hot path specialized. `layoutWithLines()` shares the same\n // break semantics but also tracks line ranges; the extra bookkeeping is too\n // expensive to pay on every hot-path `layout()` call.\n const lineCount = countPreparedLines(getInternalPrepared(prepared), maxWidth);\n return { lineCount, height: lineCount * lineHeight };\n}\nfunction getSegmentGraphemes(segmentIndex, segments, cache) {\n let graphemes = cache.get(segmentIndex);\n if (graphemes !== undefined)\n return graphemes;\n graphemes = [];\n const graphemeSegmenter = getSharedGraphemeSegmenter();\n for (const gs of graphemeSegmenter.segment(segments[segmentIndex])) {\n graphemes.push(gs.segment);\n }\n cache.set(segmentIndex, graphemes);\n return graphemes;\n}\nfunction getLineTextCache(prepared) {\n let cache = sharedLineTextCaches.get(prepared);\n if (cache !== undefined)\n return cache;\n cache = new Map();\n sharedLineTextCaches.set(prepared, cache);\n return cache;\n}\nfunction lineHasDiscretionaryHyphen(kinds, startSegmentIndex, startGraphemeIndex, endSegmentIndex) {\n return (endSegmentIndex > 0 &&\n kinds[endSegmentIndex - 1] === 'soft-hyphen' &&\n !(startSegmentIndex === endSegmentIndex && startGraphemeIndex > 0));\n}\nfunction buildLineTextFromRange(segments, kinds, cache, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) {\n let text = '';\n const endsWithDiscretionaryHyphen = lineHasDiscretionaryHyphen(kinds, startSegmentIndex, startGraphemeIndex, endSegmentIndex);\n for (let i = startSegmentIndex; i < endSegmentIndex; i++) {\n if (kinds[i] === 'soft-hyphen' || kinds[i] === 'hard-break')\n continue;\n if (i === startSegmentIndex && startGraphemeIndex > 0) {\n text += getSegmentGraphemes(i, segments, cache).slice(startGraphemeIndex).join('');\n }\n else {\n text += segments[i];\n }\n }\n if (endGraphemeIndex > 0) {\n if (endsWithDiscretionaryHyphen)\n text += '-';\n text += getSegmentGraphemes(endSegmentIndex, segments, cache).slice(startSegmentIndex === endSegmentIndex ? startGraphemeIndex : 0, endGraphemeIndex).join('');\n }\n else if (endsWithDiscretionaryHyphen) {\n text += '-';\n }\n return text;\n}\nfunction createLayoutLine(prepared, cache, width, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) {\n return {\n text: buildLineTextFromRange(prepared.segments, prepared.kinds, cache, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex),\n width,\n start: {\n segmentIndex: startSegmentIndex,\n graphemeIndex: startGraphemeIndex,\n },\n end: {\n segmentIndex: endSegmentIndex,\n graphemeIndex: endGraphemeIndex,\n },\n };\n}\nfunction materializeLayoutLine(prepared, cache, line) {\n return createLayoutLine(prepared, cache, line.width, line.startSegmentIndex, line.startGraphemeIndex, line.endSegmentIndex, line.endGraphemeIndex);\n}\nfunction toLayoutLineRange(line) {\n return {\n width: line.width,\n start: {\n segmentIndex: line.startSegmentIndex,\n graphemeIndex: line.startGraphemeIndex,\n },\n end: {\n segmentIndex: line.endSegmentIndex,\n graphemeIndex: line.endGraphemeIndex,\n },\n };\n}\nfunction stepLineRange(prepared, start, maxWidth) {\n const line = stepPreparedLineRange(prepared, start, maxWidth);\n if (line === null)\n return null;\n return toLayoutLineRange(line);\n}\nfunction materializeLine(prepared, line) {\n return createLayoutLine(prepared, getLineTextCache(prepared), line.width, line.start.segmentIndex, line.start.graphemeIndex, line.end.segmentIndex, line.end.graphemeIndex);\n}\n// Batch low-level line geometry pass. This is the non-materializing counterpart\n// to layoutWithLines(), useful for shrinkwrap and other aggregate geometry work.\nexport function walkLineRanges(prepared, maxWidth, onLine) {\n if (prepared.widths.length === 0)\n return 0;\n return walkPreparedLines(getInternalPrepared(prepared), maxWidth, line => {\n onLine(toLayoutLineRange(line));\n });\n}\nexport function layoutNextLine(prepared, start, maxWidth) {\n const line = stepLineRange(prepared, start, maxWidth);\n if (line === null)\n return null;\n return materializeLine(prepared, line);\n}\n// Rich layout API for callers that want the actual line contents and widths.\n// Caller still supplies lineHeight at layout time. Mirrors layout()'s break\n// decisions, but keeps extra per-line bookkeeping so it should stay off the\n// resize hot path.\nexport function layoutWithLines(prepared, maxWidth, lineHeight) {\n const lines = [];\n if (prepared.widths.length === 0)\n return { lineCount: 0, height: 0, lines };\n const graphemeCache = getLineTextCache(prepared);\n const lineCount = walkPreparedLines(getInternalPrepared(prepared), maxWidth, line => {\n lines.push(materializeLayoutLine(prepared, graphemeCache, line));\n });\n return { lineCount, height: lineCount * lineHeight, lines };\n}\nexport function clearCache() {\n clearAnalysisCaches();\n sharedGraphemeSegmenter = null;\n sharedLineTextCaches = new WeakMap();\n clearMeasurementCaches();\n}\nexport function setLocale(locale) {\n setAnalysisLocale(locale);\n clearCache();\n}\n","import { layoutWithLines, prepareWithSegments } from \"@chenglou/pretext\";\nimport { measureAdvanceWidth, normalizeTextOptions } from \"./core.js\";\nimport {\n combineRects,\n emptyRect,\n normalizeNumber,\n normalizePositive,\n} from \"./geometry.js\";\n\nconst DEFAULT_LINE_HEIGHT_RATIO = 1.2;\nconst HUGE_LAYOUT_WIDTH = 1e9;\nconst JUSTIFY_EPSILON = 1e-6;\nconst QUOTE_RE = /\"/g;\n\nlet sharedMeasureContext = null;\nlet sharedWordSegmenter = null;\nlet sharedGraphemeSegmenter = null;\n\nexport function layoutParagraph(fontInstance, text, options = {}, state = {}) {\n const normalized = normalizeParagraphOptions(fontInstance, options);\n const textValue = String(text ?? \"\");\n const layoutBox = resolveLayoutBox(normalized, state);\n const retainedPreparedState = resolveRetainedPreparedState(state, normalized);\n const pretextState = shouldAttemptPretextLayout(normalized)\n ? layoutWithPretext(textValue, normalized, retainedPreparedState, layoutBox)\n : null;\n const layoutState =\n pretextState != null && canUsePretextLayout(pretextState, normalized)\n ? pretextState\n : layoutWithNative(fontInstance, textValue, normalized, layoutBox);\n const measureWidth = createLazyTextMeasurer(fontInstance, normalized);\n const measuredLines = applyOverflowClamping(\n layoutState.lines,\n normalized,\n layoutBox,\n measureWidth,\n );\n const lines = positionLines(\n fontInstance,\n measuredLines,\n normalized,\n layoutBox,\n measureWidth,\n );\n const textBBox = combineRects(lines.map((line) => line.bbox)) ?? emptyRect();\n const textWidth = lines.reduce((max, line) => Math.max(max, line.width), 0);\n const textHeight = lines.length * normalized.lineHeight;\n const finalLayoutBox = finalizeLayoutBox(layoutBox, normalized, textHeight);\n const cachedPrepared = pretextState?.prepared ?? retainedPreparedState.prepared ?? null;\n const cachedPreparedWhiteSpace =\n pretextState?.preparedWhiteSpace ?? retainedPreparedState.preparedWhiteSpace ?? null;\n\n return {\n options: normalized,\n lines,\n metrics: {\n x: finalLayoutBox.contentBox.x,\n y: finalLayoutBox.contentBox.y,\n width: textWidth,\n height: textHeight,\n lineCount: lines.length,\n bbox: textBBox,\n contentBox: { ...finalLayoutBox.contentBox },\n paddingBox: { ...finalLayoutBox.paddingBox },\n marginBox: { ...finalLayoutBox.marginBox },\n clipBox: { ...finalLayoutBox.clipBox },\n },\n prepared: cachedPrepared,\n preparedWhiteSpace: cachedPreparedWhiteSpace,\n layoutEngine: layoutState.layoutEngine,\n layoutBox: finalLayoutBox,\n containerWidth: layoutBox.containerWidth,\n containerHeight: layoutBox.containerHeight,\n };\n}\n\nexport function normalizeParagraphOptions(fontInstance, options = {}) {\n if (options == null || typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(\"font.paragraph() options must be an object.\");\n }\n\n const textOptions = normalizeTextOptions(options);\n const wrap = normalizeNullableEnum(options.wrap, [\"word\", \"char\", \"keep\"], null);\n const wrapDefaults = resolveWrapDefaults(wrap);\n const width = normalizeDimension(options.width);\n const height = normalizeDimension(options.height);\n\n if (options.width != null && width == null) {\n throw new TypeError('font.paragraph() option \"width\" must be a positive number.');\n }\n\n if (options.height != null && height == null) {\n throw new TypeError('font.paragraph() option \"height\" must be a positive number.');\n }\n\n const font = resolveCanvasFont(fontInstance, textOptions.size, options);\n\n return {\n ...textOptions,\n wrap: resolveWrapPreset(\n normalizeEnum(\n options.wordBreak,\n [\"normal\", \"break-all\", \"keep-all\"],\n wrapDefaults.wordBreak,\n ),\n normalizeEnum(\n options.overflowWrap,\n [\"normal\", \"break-word\", \"anywhere\"],\n wrapDefaults.overflowWrap,\n ),\n ),\n width,\n height,\n lineHeight: resolveLineHeight(options.lineHeight, textOptions.size),\n align: normalizeEnum(options.align, [\"left\", \"center\", \"right\", \"justify\"], \"left\"),\n whiteSpace: normalizeEnum(\n options.whiteSpace,\n [\"normal\", \"pre-wrap\", \"nowrap\"],\n \"normal\",\n ),\n overflowWrap: normalizeEnum(\n options.overflowWrap,\n [\"normal\", \"break-word\", \"anywhere\"],\n wrapDefaults.overflowWrap,\n ),\n wordBreak: normalizeEnum(\n options.wordBreak,\n [\"normal\", \"break-all\", \"keep-all\"],\n wrapDefaults.wordBreak,\n ),\n overflow: normalizeEnum(options.overflow, [\"visible\", \"hidden\"], \"visible\"),\n textOverflow: normalizeNullableEnum(\n options.textOverflow,\n [\"clip\", \"ellipsis\"],\n null,\n ),\n maxLines: normalizeMaxLines(options.maxLines),\n ellipsis: normalizeEllipsis(options.ellipsis),\n margin: normalizeSpacing(options.margin),\n padding: normalizeSpacing(options.padding),\n fontStyle: normalizeEnum(\n options.fontStyle,\n [\"normal\", \"italic\", \"oblique\"],\n \"normal\",\n ),\n fontWeight:\n typeof options.fontWeight === \"string\" || Number.isFinite(options.fontWeight)\n ? options.fontWeight\n : 400,\n fontFamily: resolveFontFamily(fontInstance, options.fontFamily),\n font,\n engine: normalizeEnum(options.engine, [\"pretext\", \"native\"], \"pretext\"),\n };\n}\n\nexport function resolveCanvasFont(fontInstance, size, options = {}) {\n if (typeof options.font === \"string\" && options.font.trim().length > 0) {\n return options.font.trim();\n }\n\n const style = normalizeEnum(\n options.fontStyle,\n [\"normal\", \"italic\", \"oblique\"],\n \"normal\",\n );\n const weight =\n typeof options.fontWeight === \"string\" || Number.isFinite(options.fontWeight)\n ? String(options.fontWeight)\n : \"400\";\n const family = formatFontFamily(resolveFontFamily(fontInstance, options.fontFamily));\n\n return `${style} ${weight} ${size}px ${family}`;\n}\n\nexport function canReusePreparedParagraphState(previousState, previousOptions, nextOptions) {\n return (\n previousState?.prepared != null &&\n previousState.preparedWhiteSpace === resolvePretextWhiteSpace(nextOptions.whiteSpace) &&\n previousOptions?.font === nextOptions.font\n );\n}\n\nfunction layoutWithPretext(text, options, state, layoutBox) {\n const preparedWhiteSpace = resolvePretextWhiteSpace(options.whiteSpace);\n const prepared =\n state.prepared != null &&\n state.preparedWhiteSpace === preparedWhiteSpace &&\n state.font === options.font\n ? state.prepared\n : prepareWithSegments(text, options.font, { whiteSpace: preparedWhiteSpace });\n const maxWidth =\n options.whiteSpace === \"nowrap\" ? HUGE_LAYOUT_WIDTH : layoutBox.contentWidth;\n const layout = layoutWithLines(prepared, maxWidth, options.lineHeight);\n const lines = layout.lines.map((line) => ({\n text: line.text,\n width: line.width,\n start: null,\n end: null,\n hardBreak: isHardBreak(prepared, line),\n }));\n\n return {\n lines,\n prepared,\n preparedWhiteSpace,\n layoutEngine: \"pretext\",\n usedOverflowWrapFallbackBreaks: layout.lines.some(\n (line) => line.end.graphemeIndex > 0,\n ),\n };\n}\n\nfunction layoutWithNative(fontInstance, text, options, layoutBox) {\n const measuredWidth = createOpenTypeMeasurer(fontInstance, options);\n const source = normalizeNativeText(text, options.whiteSpace);\n\n if (source.length === 0) {\n return {\n lines: [],\n prepared: null,\n preparedWhiteSpace: null,\n layoutEngine: \"native\",\n };\n }\n\n if (options.whiteSpace === \"nowrap\") {\n return {\n lines: [\n {\n text: source,\n width: measuredWidth(source),\n start: 0,\n end: source.length,\n hardBreak: false,\n },\n ],\n prepared: null,\n preparedWhiteSpace: null,\n layoutEngine: \"native\",\n };\n }\n\n const tokens = tokenizeNativeText(\n source,\n options.whiteSpace,\n measuredWidth,\n options.wordBreak,\n );\n const lines = [];\n let currentText = \"\";\n let currentWidth = 0;\n let currentStart = null;\n let currentEnd = null;\n\n const pushCurrentLine = (hardBreak, fallbackOffset) => {\n const textValue =\n options.whiteSpace === \"pre-wrap\"\n ? currentText\n : currentText.replace(/\\s+$/u, \"\");\n const widthValue =\n textValue === currentText ? currentWidth : measuredWidth(textValue);\n\n lines.push({\n text: textValue,\n width: widthValue,\n start: currentStart ?? fallbackOffset,\n end: currentEnd ?? fallbackOffset,\n hardBreak,\n });\n currentText = \"\";\n currentWidth = 0;\n currentStart = null;\n currentEnd = null;\n };\n\n const appendPiece = (piece) => {\n currentText += piece.text;\n currentWidth += piece.width;\n currentStart = currentStart == null ? piece.start : currentStart;\n currentEnd = piece.end;\n };\n\n const appendWrappedToken = (token) => {\n if (options.overflowWrap === \"normal\" && options.wordBreak !== \"break-all\") {\n appendPiece(token);\n return;\n }\n\n const pieces = splitIntoGraphemePieces(token, measuredWidth);\n\n pieces.forEach((piece) => {\n if (\n currentText.length > 0 &&\n currentWidth + piece.width > layoutBox.contentWidth + JUSTIFY_EPSILON\n ) {\n pushCurrentLine(false, piece.start);\n }\n\n appendPiece(piece);\n });\n };\n\n tokens.forEach((token) => {\n if (token.type === \"hardBreak\") {\n pushCurrentLine(true, token.start);\n return;\n }\n\n if (\n token.type === \"space\" &&\n currentText.length === 0 &&\n options.whiteSpace !== \"pre-wrap\"\n ) {\n return;\n }\n\n if (\n currentText.length === 0 ||\n currentWidth + token.width <= layoutBox.contentWidth + JUSTIFY_EPSILON\n ) {\n appendPiece(token);\n return;\n }\n\n if (token.type === \"space\") {\n pushCurrentLine(false, token.start);\n\n if (options.whiteSpace === \"pre-wrap\") {\n appendWrappedToken(token);\n }\n\n return;\n }\n\n pushCurrentLine(false, token.start);\n appendWrappedToken(token);\n });\n\n if (currentText.length > 0 || lines.length === 0) {\n pushCurrentLine(false, source.length);\n }\n\n return {\n lines,\n prepared: null,\n preparedWhiteSpace: null,\n layoutEngine: \"native\",\n };\n}\n\nfunction splitIntoGraphemePieces(token, measureWidth) {\n const pieces = [];\n const segmenter = getGraphemeSegmenter();\n\n for (const part of segmenter.segment(token.text)) {\n const text = part.segment;\n const start = token.start + part.index;\n const end = start + text.length;\n\n pieces.push({\n text,\n type: token.type,\n start,\n end,\n width: measureWidth(text),\n });\n }\n\n return pieces.length > 0 ? pieces : [token];\n}\n\nfunction applyOverflowClamping(lines, options, layoutBox, measureWidth) {\n const contentWidth = layoutBox.contentWidth;\n const result = lines.map((line) => ({ ...line }));\n let lineLimit = options.maxLines;\n\n if (options.overflow === \"hidden\" && layoutBox.clipContentHeight != null) {\n const visibleLineCount = Math.max(\n 0,\n Math.floor((layoutBox.clipContentHeight + JUSTIFY_EPSILON) / options.lineHeight),\n );\n lineLimit = lineLimit == null ? visibleLineCount : Math.min(lineLimit, visibleLineCount);\n }\n\n let clippedByCount = false;\n\n if (lineLimit != null) {\n if (lineLimit <= 0) {\n return [];\n }\n\n if (result.length > lineLimit) {\n result.length = lineLimit;\n clippedByCount = true;\n }\n }\n\n if (result.length === 0) {\n return result;\n }\n\n if (\n options.overflow === \"hidden\" &&\n options.whiteSpace === \"nowrap\" &&\n result[0].width > contentWidth + JUSTIFY_EPSILON\n ) {\n result[0] = truncateLineToWidth(\n result[0],\n contentWidth,\n measureWidth,\n options.textOverflow === \"ellipsis\" ? options.ellipsis : false,\n );\n } else if (clippedByCount && shouldEllipsizeClampedLines(options)) {\n const lastIndex = result.length - 1;\n result[lastIndex] = truncateLineToWidth(\n result[lastIndex],\n contentWidth,\n measureWidth,\n options.ellipsis,\n );\n result[lastIndex].hardBreak = false;\n }\n\n return result;\n}\n\nfunction truncateLineToWidth(line, maxWidth, measureWidth, suffix) {\n const suffixText = suffix === false ? \"\" : suffix;\n const suffixWidth = suffixText.length > 0 ? measureWidth(suffixText) : 0;\n\n if (suffixWidth > maxWidth + JUSTIFY_EPSILON) {\n return {\n ...line,\n text: \"\",\n width: 0,\n hardBreak: false,\n };\n }\n\n let nextText = trimTrailingWhitespace(line.text);\n\n while (\n nextText.length > 0 &&\n measureWidth(`${nextText}${suffixText}`) > maxWidth + JUSTIFY_EPSILON\n ) {\n nextText = trimLastGrapheme(nextText);\n }\n\n const text = `${nextText}${suffixText}`;\n\n return {\n ...line,\n text,\n width: measureWidth(text),\n hardBreak: false,\n };\n}\n\nfunction shouldEllipsizeClampedLines(options) {\n return (\n options.textOverflow === \"ellipsis\" ||\n (options.textOverflow == null &&\n options.maxLines != null &&\n options.ellipsis !== false)\n );\n}\n\nfunction positionLines(fontInstance, lines, options, layoutBox, measureWidth) {\n const ascent = getFontAscender(fontInstance, options.size);\n const lineBoxHeight = options.lineHeight;\n let cursor = 0;\n\n return lines.map((line, index) => {\n const justified = shouldJustifyLine(line, index, lines.length, options);\n const offsetX = justified\n ? 0\n : resolveAlignOffset(options.align, line.width, layoutBox.contentWidth);\n const x = layoutBox.contentX + offsetX;\n const y = layoutBox.contentY + index * lineBoxHeight;\n const baseline = y + ascent;\n const fragments = justified\n ? buildJustifiedFragments(line, layoutBox.contentX, layoutBox.contentWidth, measureWidth)\n : [\n {\n text: line.text,\n x,\n width: line.width,\n isWhitespace: false,\n },\n ];\n const width = justified ? layoutBox.contentWidth : line.width;\n const bbox = {\n x,\n y,\n w: width,\n h: lineBoxHeight,\n };\n const positioned = {\n index,\n text: line.text,\n start: line.start ?? cursor,\n end: line.end ?? cursor + line.text.length,\n x,\n y,\n width,\n baseline,\n height: lineBoxHeight,\n bbox,\n hardBreak: line.hardBreak,\n fragments,\n };\n\n cursor = positioned.end + (line.hardBreak ? 1 : 0);\n return positioned;\n });\n}\n\nfunction buildJustifiedFragments(line, contentX, contentWidth, measureWidth) {\n const tokens = splitPreservingWhitespace(line.text);\n const expandable = tokens.reduce((count, token, index) => {\n if (index > 0 && index < tokens.length - 1 && /\\s/u.test(token)) {\n return count + 1;\n }\n\n return count;\n }, 0);\n\n if (expandable === 0) {\n return [\n {\n text: line.text,\n x: contentX,\n width: line.width,\n isWhitespace: false,\n },\n ];\n }\n\n const extraPerGap = Math.max(0, contentWidth - line.width) / expandable;\n const fragments = [];\n let cursorX = contentX;\n\n tokens.forEach((token, index) => {\n const isWhitespace = /\\s/u.test(token);\n const isExpandable = isWhitespace && index > 0 && index < tokens.length - 1;\n const baseWidth = measureWidth(token);\n const width = baseWidth + (isExpandable ? extraPerGap : 0);\n\n fragments.push({\n text: token,\n x: cursorX,\n width,\n isWhitespace,\n });\n\n cursorX += width;\n });\n\n return fragments;\n}\n\nfunction shouldJustifyLine(line, index, lineCount, options) {\n return (\n options.align === \"justify\" &&\n index < lineCount - 1 &&\n !line.hardBreak &&\n /\\S\\s+\\S/u.test(line.text)\n );\n}\n\nfunction resolveAlignOffset(align, lineWidth, maxWidth) {\n if (align === \"center\") {\n return (maxWidth - lineWidth) * 0.5;\n }\n\n if (align === \"right\") {\n return maxWidth - lineWidth;\n }\n\n return 0;\n}\n\nfunction resolveLineHeight(value, size) {\n if (!Number.isFinite(value) || value <= 0) {\n return size * DEFAULT_LINE_HEIGHT_RATIO;\n }\n\n if (value <= 10) {\n return size * value;\n }\n\n return value;\n}\n\nfunction resolveLayoutBox(options, state = {}) {\n const margin = options.margin;\n const padding = options.padding;\n const containerWidth = resolveContainerDimension(\n state.containerWidth,\n typeof window !== \"undefined\" ? window.innerWidth : null,\n );\n const containerHeight = resolveContainerDimension(\n state.containerHeight,\n typeof window !== \"undefined\" ? window.innerHeight : null,\n );\n const contentWidth =\n options.width ??\n Math.max(\n 1,\n (containerWidth ?? 0) -\n options.x -\n margin.left -\n margin.right -\n padding.left -\n padding.right,\n );\n const contentX = options.x + margin.left + padding.left;\n const contentY = options.y + margin.top + padding.top;\n\n return {\n containerWidth,\n containerHeight,\n contentWidth,\n clipContentHeight: options.height,\n contentX,\n contentY,\n margin,\n padding,\n contentBox: {\n x: contentX,\n y: contentY,\n w: contentWidth,\n h: options.height ?? 0,\n },\n paddingBox: {\n x: options.x + margin.left,\n y: options.y + margin.top,\n w: contentWidth + padding.left + padding.right,\n h: (options.height ?? 0) + padding.top + padding.bottom,\n },\n marginBox: {\n x: options.x,\n y: options.y,\n w:\n contentWidth +\n padding.left +\n padding.right +\n margin.left +\n margin.right,\n h:\n (options.height ?? 0) +\n padding.top +\n padding.bottom +\n margin.top +\n margin.bottom,\n },\n clipBox: {\n x: contentX,\n y: contentY,\n w: contentWidth,\n h: options.height ?? 0,\n },\n };\n}\n\nfunction finalizeLayoutBox(layoutBox, options, textHeight) {\n const contentHeight = options.height ?? textHeight;\n\n return {\n ...layoutBox,\n contentBox: {\n x: layoutBox.contentX,\n y: layoutBox.contentY,\n w: layoutBox.contentWidth,\n h: contentHeight,\n },\n paddingBox: {\n x: layoutBox.paddingBox.x,\n y: layoutBox.paddingBox.y,\n w: layoutBox.paddingBox.w,\n h: contentHeight + layoutBox.padding.top + layoutBox.padding.bottom,\n },\n marginBox: {\n x: layoutBox.marginBox.x,\n y: layoutBox.marginBox.y,\n w: layoutBox.marginBox.w,\n h:\n contentHeight +\n layoutBox.padding.top +\n layoutBox.padding.bottom +\n layoutBox.margin.top +\n layoutBox.margin.bottom,\n },\n clipBox: {\n x: layoutBox.contentX,\n y: layoutBox.contentY,\n w: layoutBox.contentWidth,\n h: options.overflow === \"hidden\" ? contentHeight : textHeight,\n },\n };\n}\n\nfunction resolveContainerDimension(explicit, fallback) {\n if (Number.isFinite(explicit) && explicit > 0) {\n return explicit;\n }\n\n if (Number.isFinite(fallback) && fallback > 0) {\n return fallback;\n }\n\n return null;\n}\n\nfunction normalizeEnum(value, supported, fallback) {\n return typeof value === \"string\" && supported.includes(value) ? value : fallback;\n}\n\nfunction normalizeNullableEnum(value, supported, fallback) {\n if (value == null) {\n return fallback;\n }\n\n return typeof value === \"string\" && supported.includes(value) ? value : fallback;\n}\n\nfunction normalizeEllipsis(value) {\n if (value === false) {\n return false;\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n return \"…\";\n}\n\nfunction normalizeMaxLines(value) {\n if (!Number.isFinite(value)) {\n return null;\n }\n\n const rounded = Math.floor(value);\n return rounded > 0 ? rounded : null;\n}\n\nfunction normalizeDimension(value) {\n return Number.isFinite(value) && value > 0 ? value : null;\n}\n\nfunction normalizeSpacing(value) {\n if (value == null) {\n return zeroSpacing();\n }\n\n if (Number.isFinite(value)) {\n const next = Number(value);\n return { top: next, right: next, bottom: next, left: next };\n }\n\n if (Array.isArray(value)) {\n const numbers = value.map((entry) =>\n Number.isFinite(entry) ? Number(entry) : 0,\n );\n\n if (numbers.length === 2) {\n return {\n top: numbers[0],\n right: numbers[1],\n bottom: numbers[0],\n left: numbers[1],\n };\n }\n\n if (numbers.length === 3) {\n return {\n top: numbers[0],\n right: numbers[1],\n bottom: numbers[2],\n left: numbers[1],\n };\n }\n\n if (numbers.length === 4) {\n return {\n top: numbers[0],\n right: numbers[1],\n bottom: numbers[2],\n left: numbers[3],\n };\n }\n\n if (numbers.length === 1) {\n return {\n top: numbers[0],\n right: numbers[0],\n bottom: numbers[0],\n left: numbers[0],\n };\n }\n }\n\n if (typeof value === \"string\") {\n const tokens = parseSpacingString(value);\n if (tokens != null) {\n return normalizeSpacing(tokens);\n }\n }\n\n if (typeof value === \"object\") {\n const horizontal = normalizeNumber(value.x, 0);\n const vertical = normalizeNumber(value.y, 0);\n return {\n top: normalizeNumber(value.top, vertical),\n right: normalizeNumber(value.right, horizontal),\n bottom: normalizeNumber(value.bottom, vertical),\n left: normalizeNumber(value.left, horizontal),\n };\n }\n\n return zeroSpacing();\n}\n\nfunction zeroSpacing() {\n return { top: 0, right: 0, bottom: 0, left: 0 };\n}\n\nfunction resolveFontFamily(fontInstance, fontFamily) {\n if (typeof fontFamily === \"string\" && fontFamily.trim().length > 0) {\n return fontFamily.trim();\n }\n\n if (\n typeof fontInstance?.canvasFamily === \"string\" &&\n fontInstance.canvasFamily.trim().length > 0\n ) {\n return fontInstance.canvasFamily.trim();\n }\n\n const preferred =\n fontInstance?.font?.names?.fullName?.en ??\n fontInstance?.font?.names?.fontFamily?.en ??\n fontInstance?.font?.familyName;\n\n return typeof preferred === \"string\" && preferred.trim().length > 0\n ? preferred.trim()\n : \"sans-serif\";\n}\n\nfunction formatFontFamily(value) {\n if (value.includes(\",\") || value.includes('\"') || value.includes(\"'\")) {\n return value;\n }\n\n return /\\s/u.test(value) ? `\"${value.replace(QUOTE_RE, '\\\\\"')}\"` : value;\n}\n\nfunction resolvePretextWhiteSpace(whiteSpace) {\n return whiteSpace === \"pre-wrap\" ? \"pre-wrap\" : \"normal\";\n}\n\nfunction resolveWrapDefaults(wrap) {\n if (wrap === \"char\") {\n return {\n overflowWrap: \"break-word\",\n wordBreak: \"break-all\",\n };\n }\n\n if (wrap === \"keep\") {\n return {\n overflowWrap: \"normal\",\n wordBreak: \"keep-all\",\n };\n }\n\n return {\n overflowWrap: \"break-word\",\n wordBreak: \"normal\",\n };\n}\n\nfunction resolveWrapPreset(wordBreak, overflowWrap) {\n if (wordBreak === \"break-all\") {\n return \"char\";\n }\n\n if (wordBreak === \"keep-all\" && overflowWrap === \"normal\") {\n return \"keep\";\n }\n\n if (wordBreak === \"normal\" && overflowWrap === \"break-word\") {\n return \"word\";\n }\n\n return null;\n}\n\nfunction shouldAttemptPretextLayout(options) {\n return options.engine === \"pretext\" && options.wordBreak === \"normal\";\n}\n\nfunction canUsePretextLayout(layoutState, options) {\n return !(\n options.overflowWrap === \"normal\" && layoutState.usedOverflowWrapFallbackBreaks\n );\n}\n\nfunction resolveRetainedPreparedState(state, options) {\n if (\n state.prepared != null &&\n state.preparedWhiteSpace === resolvePretextWhiteSpace(options.whiteSpace) &&\n state.font === options.font\n ) {\n return {\n prepared: state.prepared,\n preparedWhiteSpace: state.preparedWhiteSpace,\n };\n }\n\n return {\n prepared: null,\n preparedWhiteSpace: null,\n };\n}\n\nfunction isHardBreak(prepared, line) {\n return prepared.kinds?.[line.end.segmentIndex] === \"hard-break\";\n}\n\nfunction normalizeNativeText(text, whiteSpace) {\n if (whiteSpace === \"pre-wrap\") {\n return String(text ?? \"\").replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n }\n\n return String(text ?? \"\").replace(/\\s+/gu, \" \").trim();\n}\n\nfunction tokenizeNativeText(text, whiteSpace, measureWidth, wordBreak) {\n const tokens = [];\n let index = 0;\n\n while (index < text.length) {\n const char = text[index];\n\n if (char === \"\\n\") {\n tokens.push({\n text: \"\\n\",\n type: \"hardBreak\",\n start: index,\n end: index + 1,\n width: 0,\n });\n index += 1;\n continue;\n }\n\n if ((char === \" \" || char === \"\\t\") && whiteSpace === \"pre-wrap\") {\n const start = index;\n\n while (index < text.length && (text[index] === \" \" || text[index] === \"\\t\")) {\n index += 1;\n }\n\n const segment = text.slice(start, index);\n\n tokens.push({\n text: segment,\n type: \"space\",\n start,\n end: index,\n width: measureWidth(segment),\n });\n continue;\n }\n\n if (char === \" \") {\n tokens.push({\n text: \" \",\n type: \"space\",\n start: index,\n end: index + 1,\n width: measureWidth(\" \"),\n });\n index += 1;\n continue;\n }\n\n const nextStop = findNextStop(text, index, whiteSpace);\n const chunk = text.slice(index, nextStop);\n\n tokens.push(...segmentChunk(chunk, index, measureWidth, wordBreak));\n index = nextStop;\n }\n\n return tokens;\n}\n\nfunction findNextStop(text, start, whiteSpace) {\n let index = start;\n\n while (index < text.length) {\n const char = text[index];\n\n if (char === \"\\n\") {\n break;\n }\n\n if (char === \" \" || (whiteSpace === \"pre-wrap\" && char === \"\\t\")) {\n break;\n }\n\n index += 1;\n }\n\n return index;\n}\n\nfunction segmentChunk(text, baseOffset, measureWidth, wordBreak) {\n if (text.length === 0) {\n return [];\n }\n\n if (wordBreak === \"keep-all\") {\n return [\n {\n text,\n type: \"text\",\n start: baseOffset,\n end: baseOffset + text.length,\n width: measureWidth(text),\n },\n ];\n }\n\n if (wordBreak === \"break-all\") {\n return splitIntoGraphemePieces(\n {\n text,\n type: \"text\",\n start: baseOffset,\n end: baseOffset + text.length,\n width: measureWidth(text),\n },\n measureWidth,\n );\n }\n\n return segmentWords(text, baseOffset, measureWidth);\n}\n\nfunction segmentWords(text, baseOffset, measureWidth) {\n const pieces = [];\n const segmenter = getWordSegmenter();\n\n for (const part of segmenter.segment(text)) {\n const value = part.segment;\n\n if (value.length === 0) {\n continue;\n }\n\n pieces.push({\n text: value,\n type: /\\s/u.test(value) ? \"space\" : \"text\",\n start: baseOffset + part.index,\n end: baseOffset + part.index + value.length,\n width: measureWidth(value),\n });\n }\n\n return pieces.length > 0\n ? pieces\n : [\n {\n text,\n type: \"text\",\n start: baseOffset,\n end: baseOffset + text.length,\n width: measureWidth(text),\n },\n ];\n}\n\nfunction createTextMeasurer(fontInstance, options) {\n const cache = new Map();\n const openTypeMeasurer = createOpenTypeMeasurer(fontInstance, options);\n const context = getMeasureContext();\n\n return (value) => {\n if (value.length === 0) {\n return 0;\n }\n\n if (cache.has(value)) {\n return cache.get(value);\n }\n\n let width;\n\n if (context) {\n context.font = options.font;\n width = context.measureText(value).width;\n } else {\n width = openTypeMeasurer(value);\n }\n\n cache.set(value, width);\n return width;\n };\n}\n\nfunction createLazyTextMeasurer(fontInstance, options) {\n let measureWidth = null;\n\n return (value) => {\n if (measureWidth == null) {\n measureWidth = createTextMeasurer(fontInstance, options);\n }\n\n return measureWidth(value);\n };\n}\n\nfunction createOpenTypeMeasurer(fontInstance, options) {\n const cache = new Map();\n const widthOptions = {\n x: 0,\n y: 0,\n size: options.size,\n flatten: options.flatten,\n edgeEpsilon: options.edgeEpsilon,\n kerning: options.kerning,\n letterSpacing: options.letterSpacing,\n tracking: options.tracking,\n script: options.script,\n language: options.language,\n features: options.features,\n };\n\n return (value) => {\n if (value.length === 0) {\n return 0;\n }\n\n if (cache.has(value)) {\n return cache.get(value);\n }\n\n const width = measureAdvanceWidth(fontInstance.font, value, widthOptions);\n\n cache.set(value, width);\n return width;\n };\n}\n\nfunction getMeasureContext() {\n if (sharedMeasureContext) {\n return sharedMeasureContext;\n }\n\n if (typeof OffscreenCanvas !== \"undefined\") {\n sharedMeasureContext = new OffscreenCanvas(1, 1).getContext(\"2d\");\n return sharedMeasureContext;\n }\n\n if (typeof document !== \"undefined\") {\n sharedMeasureContext = document.createElement(\"canvas\").getContext(\"2d\");\n return sharedMeasureContext;\n }\n\n return null;\n}\n\nfunction getWordSegmenter() {\n if (sharedWordSegmenter == null) {\n sharedWordSegmenter = new Intl.Segmenter(undefined, { granularity: \"word\" });\n }\n\n return sharedWordSegmenter;\n}\n\nfunction getGraphemeSegmenter() {\n if (sharedGraphemeSegmenter == null) {\n sharedGraphemeSegmenter = new Intl.Segmenter(undefined, {\n granularity: \"grapheme\",\n });\n }\n\n return sharedGraphemeSegmenter;\n}\n\nfunction trimTrailingWhitespace(value) {\n return value.replace(/\\s+$/u, \"\");\n}\n\nfunction trimLastGrapheme(value) {\n const segmenter = getGraphemeSegmenter();\n const graphemes = Array.from(segmenter.segment(value), (segment) => segment.segment);\n\n graphemes.pop();\n return graphemes.join(\"\");\n}\n\nfunction splitPreservingWhitespace(value) {\n return value.split(/(\\s+)/u).filter((token) => token.length > 0);\n}\n\nfunction parseSpacingString(value) {\n const tokens = value\n .trim()\n .split(/[\\s,]+/u)\n .filter(Boolean)\n .map(parseSpacingToken);\n\n if (tokens.length >= 1 && tokens.length <= 4 && tokens.every(Number.isFinite)) {\n return tokens;\n }\n\n return null;\n}\n\nfunction parseSpacingToken(value) {\n const match = value.match(/^(-?\\d+(?:\\.\\d+)?)(px)?$/u);\n return match ? Number(match[1]) : Number.NaN;\n}\n\nfunction getFontAscender(fontInstance, size) {\n const ascender = normalizeNumber(\n fontInstance?.font?.ascender,\n fontInstance?.unitsPerEm ?? 1000,\n );\n const unitsPerEm = normalizePositive(fontInstance?.unitsPerEm, 1000);\n return (ascender / unitsPerEm) * size;\n}\n","import { createTextShape } from \"./shape.js\";\nimport {\n canReusePreparedParagraphState,\n layoutParagraph,\n normalizeParagraphOptions,\n resolveCanvasFont,\n} from \"./paragraphLayout.js\";\n\nexport class paParagraph {\n constructor(fontInstance, text, options, state) {\n this._font = fontInstance;\n this.text = text;\n this._cache = {\n baseShapes: new Map(),\n layoutParagraphs: new Map(),\n };\n this._applySnapshot(options, state);\n }\n\n relayout(next = {}) {\n const normalized = normalizeParagraphOptions(this._font, {\n ...this.options,\n ...next,\n });\n const state = layoutParagraph(this._font, this.text, normalized, {\n prepared: canReusePreparedParagraphState(this._state, this.options, normalized)\n ? this._state.prepared\n : null,\n preparedWhiteSpace: this._state.preparedWhiteSpace,\n font: this.options.font,\n containerWidth: this._state.containerWidth,\n containerHeight: this._state.containerHeight,\n });\n\n return new paParagraph(this._font, this.text, normalized, state);\n }\n\n line(index) {\n return this.lines[index];\n }\n\n drawText(ctx, options = {}) {\n if (!ctx || typeof ctx.fillText !== \"function\") {\n throw new TypeError(\"drawText() expects a CanvasRenderingContext2D.\");\n }\n\n const fill = options.fill !== false;\n const stroke = options.stroke === true;\n\n if (!fill && !stroke) {\n return;\n }\n\n this._syncLayoutWithContext(ctx);\n\n ctx.save();\n ctx.font = resolveCanvasFont(this._font, this.options.size, this.options);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"alphabetic\";\n\n if (options.fillStyle != null) {\n ctx.fillStyle = options.fillStyle;\n }\n\n if (options.strokeStyle != null) {\n ctx.strokeStyle = options.strokeStyle;\n }\n\n if (this.options.overflow === \"hidden\" && this._state.layoutBox?.clipBox) {\n const clipBox = this._state.layoutBox.clipBox;\n ctx.beginPath();\n ctx.rect(clipBox.x, clipBox.y, clipBox.w, clipBox.h);\n ctx.clip();\n }\n\n this._state.lines.forEach((line) => {\n line.fragments.forEach((fragment) => {\n if (fill) {\n ctx.fillText(fragment.text, fragment.x, line.baseline);\n }\n\n if (stroke) {\n ctx.strokeText(fragment.text, fragment.x, line.baseline);\n }\n });\n });\n\n ctx.restore();\n }\n\n toShape(options = {}) {\n const { layout = \"current\", ...shapeOptions } = normalizeParagraphShapeOptions(\n options,\n \"toShape()\",\n );\n return this._getBaseShape(layout).toShape(shapeOptions);\n }\n\n toRegions(options = {}) {\n const { layout = \"current\", ...shapeOptions } = normalizeParagraphShapeOptions(\n options,\n \"toRegions()\",\n );\n return this._getBaseShape(layout).toRegions(shapeOptions);\n }\n\n toPoints(options = {}) {\n const normalized = normalizeParagraphPointOptions(options);\n const { layout = \"current\", ...pointOptions } = normalized;\n return this._getBaseShape(layout).toPoints(pointOptions);\n }\n\n _getBaseShape(layout) {\n const paragraph = this._resolveParagraph(layout);\n\n if (paragraph._cache.baseShapes.has(\"base\")) {\n return paragraph._cache.baseShapes.get(\"base\");\n }\n\n const baseShape = createTextShape(\n buildParagraphGlyphLayout(paragraph),\n paragraph.options,\n paragraph._font,\n );\n\n paragraph._cache.baseShapes.set(\"base\", baseShape);\n return baseShape;\n }\n\n _applySnapshot(options, state) {\n this.options = options;\n this.layoutEngine = state.layoutEngine;\n this._state = state;\n this.lines = state.lines.map((line) => ({\n index: line.index,\n text: line.text,\n start: line.start,\n end: line.end,\n x: line.x,\n y: line.y,\n width: line.width,\n baseline: line.baseline,\n height: line.height,\n bbox: { ...line.bbox },\n }));\n this.metrics = {\n ...state.metrics,\n bbox: { ...state.metrics.bbox },\n contentBox: state.metrics.contentBox ? { ...state.metrics.contentBox } : undefined,\n paddingBox: state.metrics.paddingBox ? { ...state.metrics.paddingBox } : undefined,\n marginBox: state.metrics.marginBox ? { ...state.metrics.marginBox } : undefined,\n clipBox: state.metrics.clipBox ? { ...state.metrics.clipBox } : undefined,\n };\n this._cache.baseShapes.clear();\n this._cache.layoutParagraphs.clear();\n }\n\n _syncLayoutWithContext(ctx) {\n const canvas = ctx?.canvas;\n\n if (!canvas || this.options.width != null) {\n return;\n }\n\n const containerWidth = Number.isFinite(canvas.width) ? canvas.width : null;\n const containerHeight = Number.isFinite(canvas.height) ? canvas.height : null;\n\n if (\n containerWidth === this._state.containerWidth &&\n containerHeight === this._state.containerHeight\n ) {\n return;\n }\n\n const state = layoutParagraph(this._font, this.text, this.options, {\n prepared: canReusePreparedParagraphState(this._state, this.options, this.options)\n ? this._state.prepared\n : null,\n preparedWhiteSpace: this._state.preparedWhiteSpace,\n font: this.options.font,\n containerWidth,\n containerHeight,\n });\n\n this._applySnapshot(this.options, state);\n }\n\n _resolveParagraph(layout) {\n if (layout === \"current\") {\n return this;\n }\n\n if (layout === \"native\") {\n return this._getLayoutParagraph(\"native\");\n }\n\n if (layout === \"pretext\") {\n return this._getLayoutParagraph(\"pretext\");\n }\n\n throw new TypeError(\n 'Paragraph layout must be \"current\", \"pretext\", or \"native\".',\n );\n }\n\n _getLayoutParagraph(engine) {\n if (this.options.engine === engine) {\n return this;\n }\n\n if (this._cache.layoutParagraphs.has(engine)) {\n return this._cache.layoutParagraphs.get(engine);\n }\n\n const paragraph = this.relayout({ engine });\n this._cache.layoutParagraphs.set(engine, paragraph);\n return paragraph;\n }\n}\n\nexport function createParagraph(fontInstance, text, options = {}, state = {}) {\n const normalized = normalizeParagraphOptions(fontInstance, options);\n const layoutState = layoutParagraph(fontInstance, text, normalized, state);\n return new paParagraph(fontInstance, text, normalized, layoutState);\n}\n\nfunction buildParagraphGlyphLayout(paragraph) {\n const glyphs = [];\n const glyphOptions = {\n x: 0,\n y: 0,\n size: paragraph.options.size,\n flatten: paragraph.options.flatten,\n edgeEpsilon: paragraph.options.edgeEpsilon,\n kerning: paragraph.options.kerning,\n letterSpacing: paragraph.options.letterSpacing,\n tracking: paragraph.options.tracking,\n script: paragraph.options.script,\n language: paragraph.options.language,\n features: paragraph.options.features,\n };\n\n paragraph._state.lines.forEach((line) => {\n line.fragments.forEach((fragment) => {\n if (fragment.text.length === 0) {\n return;\n }\n\n const layout = paragraph._font._layoutText(fragment.text, {\n ...glyphOptions,\n x: fragment.x,\n y: line.baseline,\n });\n\n glyphs.push(...layout.glyphs);\n });\n });\n\n return {\n text: paragraph.text,\n glyphs,\n metrics: {\n x: paragraph.metrics.x,\n y: paragraph.metrics.y,\n size: paragraph.options.size,\n width: paragraph.metrics.width,\n },\n };\n}\n\nfunction normalizeParagraphShapeOptions(options = {}, callerName) {\n if (options == null) {\n return { layout: \"current\" };\n }\n\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(`${callerName} expects an options object.`);\n }\n\n return {\n ...options,\n layout: options.layout ?? \"current\",\n };\n}\n\nfunction normalizeParagraphPointOptions(options = {}) {\n if (options == null) {\n return { layout: \"current\" };\n }\n\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(\"toPoints() expects an options object.\");\n }\n\n return {\n ...options,\n layout: options.layout ?? \"current\",\n };\n}\n","import { load as loadFont, parse as parseFont } from \"opentype.js\";\nimport {\n buildGlyphTopology,\n flattenGlyphTopology,\n layoutGlyphs,\n measureText,\n normalizeTextOptions,\n toArrayBuffer,\n} from \"./core.js\";\nimport { createParagraph } from \"./paragraph.js\";\nimport { createTextShape } from \"./shape.js\";\n\nlet browserFontRegistrationId = 0;\n\nexport class paFont {\n constructor(font) {\n this.font = font;\n this.unitsPerEm = font.unitsPerEm ?? 1000;\n this.family = resolveLoadedFontFamily(font);\n this.canvasFamily = this.family;\n this._glyphTopologyCache = new Map();\n this._glyphFlatCache = new Map();\n }\n\n static async load(source, options = {}) {\n const opts = normalizeLoadOptions(options);\n\n if (source instanceof ArrayBuffer || ArrayBuffer.isView(source)) {\n const bytes = toArrayBuffer(source);\n const instance = new paFont(parseFont(bytes));\n await instance._registerBrowserFont(bytes);\n return instance;\n }\n\n if (typeof window !== \"undefined\") {\n const requestUrl = resolveBrowserFontSource(source, opts.base);\n const bytes = await fetchFontBytes(requestUrl);\n const instance = new paFont(parseFont(bytes));\n await instance._registerBrowserFont(bytes);\n return instance;\n }\n\n const { target, loadOptions } = await resolveNodeFontSource(\n source,\n opts.base,\n );\n const font = await loadFont(target, undefined, loadOptions);\n return new paFont(font);\n }\n\n text(value, options = {}) {\n const opts = normalizeTextOptions(options);\n const layout = this._layoutText(String(value ?? \"\"), opts);\n return createTextShape(layout, opts, this);\n }\n\n glyph(value, options = {}) {\n const opts = normalizeTextOptions(options);\n const glyph = this.font.charToGlyph(String(value ?? \"\"));\n const layout = {\n text: String(value ?? \"\"),\n glyphs: [\n {\n glyph,\n x: opts.x,\n y: opts.y,\n size: opts.size,\n index: 0,\n },\n ],\n metrics: {\n width: (glyph.advanceWidth ?? 0) * (opts.size / this.unitsPerEm),\n x: opts.x,\n y: opts.y,\n size: opts.size,\n },\n };\n\n return createTextShape(layout, opts, this);\n }\n\n metrics(value, options = {}) {\n const opts = normalizeTextOptions(options);\n return measureText(this.font, String(value ?? \"\"), opts);\n }\n\n paragraph(value, options = {}) {\n return createParagraph(this, String(value ?? \"\"), options);\n }\n\n async _registerBrowserFont(source) {\n if (\n typeof window === \"undefined\" ||\n typeof FontFace === \"undefined\" ||\n typeof document === \"undefined\" ||\n document.fonts == null\n ) {\n return;\n }\n\n try {\n const family = createBrowserFontFamily(this.family);\n const face = new FontFace(family, source);\n\n await face.load();\n document.fonts.add(face);\n this.canvasFamily = family;\n } catch {\n this.canvasFamily = this.family;\n }\n }\n\n _getGlyphTopology(glyph) {\n const key = String(glyph.index);\n\n if (!this._glyphTopologyCache.has(key)) {\n this._glyphTopologyCache.set(\n key,\n buildGlyphTopology(glyph, this.unitsPerEm),\n );\n }\n\n return this._glyphTopologyCache.get(key);\n }\n\n _getFlattenedGlyph(glyph, opts) {\n const key = `${glyph.index}:${opts.size}:${opts.flatten}`;\n\n if (!this._glyphFlatCache.has(key)) {\n const topology = this._getGlyphTopology(glyph);\n this._glyphFlatCache.set(\n key,\n flattenGlyphTopology(topology, {\n size: opts.size,\n flatten: opts.flatten,\n }),\n );\n }\n\n return this._glyphFlatCache.get(key);\n }\n\n _layoutText(value, opts) {\n return layoutGlyphs(this.font, value, opts);\n }\n}\n\nasync function fetchFontBytes(source) {\n const response = await fetch(source);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load font from ${source}: ${response.status} ${response.statusText}`,\n );\n }\n\n const bytes = await response.arrayBuffer();\n const signature = readSignature(bytes);\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"text/html\") || isHtmlSignature(signature)) {\n throw new Error(\n `Font URL returned HTML instead of font data: ${source}. Use a public font URL like \"/assets/font.otf\", or pass { base: import.meta.url } when loading a module-relative string path. Plain string paths in the browser are resolved from the current page URL.`,\n );\n }\n\n return bytes;\n}\n\nfunction normalizeLoadOptions(options = {}) {\n if (options == null) {\n return {};\n }\n\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new TypeError(\"paFont.load() options must be an object.\");\n }\n\n return options;\n}\n\nfunction resolveBrowserFontSource(source, base) {\n if (source instanceof URL) {\n return source.href;\n }\n\n if (typeof source !== \"string\") {\n throw new TypeError(\n \"paFont.load() expects a string, URL, ArrayBuffer, or ArrayBufferView.\",\n );\n }\n\n if (base == null) {\n return source;\n }\n\n return new URL(source, normalizeBase(base)).href;\n}\n\nasync function resolveNodeFontSource(source, base) {\n if (source instanceof URL) {\n return toNodeLoadTarget(source);\n }\n\n if (typeof source !== \"string\") {\n throw new TypeError(\n \"paFont.load() expects a string, URL, ArrayBuffer, or ArrayBufferView.\",\n );\n }\n\n if (base == null) {\n if (isLoadableUrlString(source)) {\n return toNodeLoadTarget(new URL(source));\n }\n\n return {\n target: source,\n loadOptions: undefined,\n };\n }\n\n return toNodeLoadTarget(new URL(source, normalizeBase(base)));\n}\n\nfunction normalizeBase(base) {\n if (base instanceof URL) {\n return base;\n }\n\n if (typeof base === \"string\") {\n return base;\n }\n\n throw new TypeError('paFont.load() option \"base\" must be a string or URL.');\n}\n\nasync function toNodeLoadTarget(url) {\n if (url.protocol === \"file:\") {\n return {\n target: fileUrlToPath(url),\n loadOptions: undefined,\n };\n }\n\n return {\n target: url.href,\n loadOptions: {\n isUrl: true,\n },\n };\n}\n\nfunction fileUrlToPath(url) {\n const pathname = decodeURIComponent(url.pathname);\n\n if (/^\\/[a-zA-Z]:/.test(pathname)) {\n return pathname.slice(1);\n }\n\n if (url.hostname) {\n return `//${url.hostname}${pathname}`;\n }\n\n return pathname;\n}\n\nfunction isLoadableUrlString(value) {\n return (\n value.startsWith(\"http://\") ||\n value.startsWith(\"https://\") ||\n value.startsWith(\"file://\")\n );\n}\n\nfunction readSignature(bytes) {\n const view = new Uint8Array(bytes, 0, Math.min(4, bytes.byteLength));\n let signature = \"\";\n\n for (const value of view) {\n signature += String.fromCharCode(value);\n }\n\n return signature.toLowerCase();\n}\n\nfunction isHtmlSignature(signature) {\n return signature === \"<!do\" || signature === \"<htm\";\n}\n\nexport default paFont;\n\nfunction resolveLoadedFontFamily(font) {\n return (\n font?.names?.fontFamily?.en ??\n font?.names?.preferredFamily?.en ??\n font?.names?.fullName?.en ??\n font?.familyName ??\n \"paFont\"\n );\n}\n\nfunction createBrowserFontFamily(family) {\n browserFontRegistrationId += 1;\n const normalized = String(family ?? \"paFont\")\n .trim()\n .replace(/\\s+/g, \" \")\n .replace(/[^a-zA-Z0-9 _-]/g, \"\");\n\n return `${normalized || \"paFont\"}__pa_${browserFontRegistrationId}`;\n}\n"],"x_google_ignoreList":[3,4,5,6,7],"mappings":"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;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAClE;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAM;CAAM;CAAM;CACnE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAO;CAAM;CAAM;CAAM;CACnE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAClE;CAAM;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CACrE;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;CAAM;CACrE;CAAO;CAAO;CAAO;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CACrE;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;CACnD;AACD,SAA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"}