unfold-nav 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unfold-nav.js","names":["URL_LIKE","ICON_NAME","renderIcon","src","depth","resolve","page","t","img","resolved","glyph","monogram","el","label","svg","body","GRAPH_ICON","CLOSE_ICON","BACK_ICON","variants","s","TAU","DEG","LABEL_SPACING","distToRect","dx","r","p","dy","rectsTouch","a","b","pad","rectContains","inside","outer","grow","d","segDist","l2","polyDist","i","poly","segHitsRect","t0","t1","q","polyHitsRect","towards","to","from","l","dist","fmt","n","edgeShape","straight","e","style","horizontal","lane","corners","route","points","before","after","round","corner","enter","leave","j","u","parentAngle","len","c","LABEL_ANGLES","LABEL_RINGS","OPEN_LABEL_RINGS","rectAlong","ux","angle","uy","lo","hi","clear","w","h","x","y","labelCollides","ctx","own","rect","halo","freeSpots","size","sizes","extra","offset","node","placeLabels","placeLabel","it","run","out","items","missing","order","place","natural","best","spots","attempt","placeOne","DISTANCE_SCALES","k","RING_SCALES","DEVIATION_STEP","LABEL_CHECKS_PER_TIER","arcPoints","start","dir","step","o","rad","ringPoints","nodePenalty","f","base","edges","pts","min","ignoreBlocked","strict","fanLabels","nodes","rects","rule","bestEffort","originLabel","inEdge","origin","placeFan","chord","gap","fallback","pen","budget","res","needOrigin","radii","exact","preferredDev","wide","basePasses","passes","pass","minRad","fan","minStep","comfy","steps","candidates","stepCost","sign","dev","bestCount","tried","consider","labels","placedCount","clean","score","perfect","layoutGraph","placed","g","obstacles","reserved","released","center","level","parent","cache","toCenter","nearCenter","id","open","owner","edge","last","circles","frontier","crosses","redo","visible","rectOf","clearEdges","other","hitTest","bestD","slop","LIGHT","DARK","STYLES","DEFAULT_STRINGS","DEFAULT_OPTIONS","isIconSource","value","enums","normalizeOptions","patch","next","current","key","values","positive","off","offsets","v","buildTree","rootPage","pages","byId","root","ancestors","validate","path","visit","kids","trail","index","child","pathTo","ids","normalizePath","pathname","findCurrent","currentUrl","curPath","exactScore","prefix","prefixLen","tree","href","url","documents","updateInsets","registry","doc","name","entry","previous","navigationUrl","OPTION_KEYS","ATTRIBUTES","parseAttribute","SVG_NS","LEVEL_SEP","SUPPORTS_POPOVER","Base","ARROWS","toggleAttr","on","setParts","parts","state","states","UnfoldNav","shadow","$","sel","trigger","overlay","options","pagesChanged","wasOpen","hadFocus","focus","views","stagger","focusTrigger","script","error","oldValue","dockBar","layer","thickness","custom","slotted","mode","first","ov","modal","timer","active","cur","hub","view","cs","probe","inset","bounds","cx","cy","deg","m","levels","tn","onPath","withLabels","tabStop","entering","insertAfter","pl","lit","dimEdge","icon","backTo","scale","title","desc","narrow","box","variantsOf","els","go","delay","live","circleOf","shown","narrowed","compact","except","withEdges","tight","grown","fits","show","covers","activeView","attempts","measure","rings","isActive","moved","tapped","hit","vx","vy","along","across","target","focusId","now","via","keyboard","nodeEl","focused","walk","rtl","bestScore","sibs","newTab","char","pool","query","at","highlight","expanded","detail","proceed","type","ms","raw","TAG","define","tag","createUnfoldNav","container"],"sources":["../src/icons.ts","../src/layout.ts","../src/styles.ts","../src/options.ts","../src/tree.ts","../src/insets.ts","../src/navigation.ts","../src/element.ts","../src/index.ts"],"sourcesContent":["import type { IconSource, NavPage } from './types.js';\n\nexport type IconResolver = ((name: string, page?: NavPage) => Node | string | null | undefined) | undefined;\n\nconst URL_LIKE = /^(https?:|data:|blob:|\\/|\\.\\.?\\/)|\\.(svg|png|jpe?g|gif|webp|avif)(\\?.*)?$/i;\nconst ICON_NAME = /^[a-z][\\w-]{2,}$/i;\n\n/**\n * Turns an `IconSource` into DOM. Returns null when there is nothing to show (the caller falls back to a\n * monogram). Markup strings are inserted as-is, so only pass markup you trust.\n */\nexport function renderIcon(src: IconSource | undefined, resolve: IconResolver, page?: NavPage, depth = 0): Node | null {\n if (src == null || src === '' || depth > 3) return null;\n if (typeof src === 'function') return renderIcon(src(), resolve, page, depth + 1);\n if (typeof src !== 'string') return src.cloneNode(true);\n\n const s = src.trim();\n if (s.startsWith('<')) {\n const t = document.createElement('template');\n t.innerHTML = s;\n return t.content;\n }\n if (URL_LIKE.test(s)) {\n const img = document.createElement('img');\n img.src = s;\n img.alt = '';\n img.decoding = 'async';\n img.draggable = false;\n return img;\n }\n if (ICON_NAME.test(s)) {\n const resolved = resolve?.(s, page);\n return resolved == null || resolved === s ? null : renderIcon(resolved, undefined, page, depth + 1);\n }\n const glyph = document.createElement('span');\n glyph.className = 'glyph';\n glyph.textContent = s;\n return glyph;\n}\n\nexport function monogram(label: string): HTMLElement {\n const el = document.createElement('span');\n el.className = 'mono';\n el.textContent = Array.from(label.trim())[0]?.toUpperCase() ?? '•';\n return el;\n}\n\nconst svg = (body: string) =>\n `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${body}</svg>`;\n\n/** A small graph unfolding upwards; rotated towards wherever the graph will open. */\nexport const GRAPH_ICON = svg(\n '<path d=\"M12 17.5 6 8.6M12 17.5V6.2M12 17.5l6-8.9\"/>' +\n '<circle cx=\"12\" cy=\"18.2\" r=\"2.5\" fill=\"currentColor\" stroke=\"none\"/>' +\n '<circle cx=\"5.6\" cy=\"8\" r=\"2\" fill=\"currentColor\" stroke=\"none\"/>' +\n '<circle cx=\"12\" cy=\"5.4\" r=\"2\" fill=\"currentColor\" stroke=\"none\"/>' +\n '<circle cx=\"18.4\" cy=\"8\" r=\"2\" fill=\"currentColor\" stroke=\"none\"/>',\n);\nexport const CLOSE_ICON = svg('<path d=\"M6.5 6.5l11 11M17.5 6.5l-11 11\"/>');\nexport const BACK_ICON = svg('<path d=\"M19 12H5.5M11 6l-6 6 6 6\"/>');\n","/**\n * Pure geometry: where nodes go, where their labels go, and how edges are drawn.\n * Coordinates are viewport pixels (y grows downwards, angles are clockwise from +x).\n *\n * The guarantee this file is built around: nothing overlaps. Every node reserves room for its label at\n * the moment its fan is placed, a fan is only accepted when all of its nodes *and* labels fit clear of\n * everything already on screen (nodes, labels, edges, the viewport edge), and later fans have to keep\n * clear of what's reserved. When that's impossible (a tiny screen, a huge menu) labels that don't fit\n * are left out rather than drawn on top of something.\n */\n\nexport interface Vec {\n x: number;\n y: number;\n}\nexport interface Circle extends Vec {\n r: number;\n}\nexport interface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\nexport interface Size {\n w: number;\n h: number;\n}\n/** A label's possible sizes, preferred first (e.g. one line, then wrapped onto two). */\nexport type Sizes = Size | Size[];\nconst variants = (s: Sizes): Size[] => (Array.isArray(s) ? s : [s]);\nexport type EdgeKind = 'curved' | 'straight' | 'step' | 'none';\n\nconst TAU = Math.PI * 2;\nconst DEG = Math.PI / 180;\n/** Minimum space between two labels. */\nconst LABEL_SPACING = 4;\n\n/* ------------------------------------------------------------- primitives */\n\nexport function distToRect(p: Vec, r: Rect): number {\n const dx = Math.max(r.x - p.x, 0, p.x - (r.x + r.w));\n const dy = Math.max(r.y - p.y, 0, p.y - (r.y + r.h));\n return Math.hypot(dx, dy);\n}\n\nexport function rectsTouch(a: Rect, b: Rect, pad = 0): boolean {\n return a.x < b.x + b.w + pad && b.x < a.x + a.w + pad && a.y < b.y + b.h + pad && b.y < a.y + a.h + pad;\n}\n\nexport const rectContains = (r: Rect, p: Vec) => p.x >= r.x && p.x <= r.x + r.w && p.y >= r.y && p.y <= r.y + r.h;\n\nconst inside = (outer: Rect, r: Rect) =>\n r.x >= outer.x - 0.5 &&\n r.y >= outer.y - 0.5 &&\n r.x + r.w <= outer.x + outer.w + 0.5 &&\n r.y + r.h <= outer.y + outer.h + 0.5;\n\nconst grow = (r: Rect, d: number): Rect => ({ x: r.x - d, y: r.y - d, w: r.w + d * 2, h: r.h + d * 2 });\n\nfunction segDist(p: Vec, a: Vec, b: Vec): number {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const l2 = dx * dx + dy * dy;\n const t = l2 ? Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / l2)) : 0;\n return Math.hypot(p.x - (a.x + t * dx), p.y - (a.y + t * dy));\n}\n\n/** Distance from a point to a polyline. */\nexport function polyDist(p: Vec, poly: Vec[]): number {\n let d = Infinity;\n for (let i = 0; i < poly.length - 1; i++) d = Math.min(d, segDist(p, poly[i], poly[i + 1]));\n return d;\n}\n\n/** Liang–Barsky: does segment a→b pass through rect r? */\nfunction segHitsRect(a: Vec, b: Vec, r: Rect): boolean {\n let t0 = 0;\n let t1 = 1;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const p = [-dx, dx, -dy, dy];\n const q = [a.x - r.x, r.x + r.w - a.x, a.y - r.y, r.y + r.h - a.y];\n for (let i = 0; i < 4; i++) {\n if (p[i] === 0) {\n if (q[i] < 0) return false;\n } else {\n const t = q[i] / p[i];\n if (p[i] < 0) {\n if (t > t1) return false;\n if (t > t0) t0 = t;\n } else {\n if (t < t0) return false;\n if (t < t1) t1 = t;\n }\n }\n }\n return true;\n}\n\nexport function polyHitsRect(poly: Vec[], r: Rect): boolean {\n for (let i = 0; i < poly.length - 1; i++) if (segHitsRect(poly[i], poly[i + 1], r)) return true;\n return false;\n}\n\nfunction towards(from: Vec, to: Vec, dist: number): Vec {\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n const l = Math.hypot(dx, dy) || 1;\n return { x: from.x + (dx / l) * dist, y: from.y + (dy / l) * dist };\n}\n\n/* ------------------------------------------------------------------ edges */\n\nexport interface EdgeShape {\n /** SVG path data. */\n d: string;\n /** The same edge as a polyline, for overlap checks. */\n points: Vec[];\n}\n\nconst fmt = (n: number) => n.toFixed(1);\n\n/**\n * The edge from `a` to `b`, trimmed to both circles.\n * - `curved` edges leave the parent along the direction it was itself reached from, so deeper branches\n * read like a growing tree.\n * - `step` edges use separate radial ports and two rounded turns, like traces on a circuit board.\n * Siblings never share the long axis-aligned stem that a single elbow would create.\n */\nexport function edgeShape(a: Circle, b: Circle, style: EdgeKind, parentAngle: number | null): EdgeShape {\n const straight = (): EdgeShape => {\n const s = towards(a, b, a.r);\n const e = towards(b, a, b.r);\n return { d: `M${fmt(s.x)} ${fmt(s.y)}L${fmt(e.x)} ${fmt(e.y)}`, points: [s, e] };\n };\n\n if (style === 'step') {\n const s = towards(a, b, a.r);\n const e = towards(b, a, b.r);\n if (Math.min(Math.abs(e.x - s.x), Math.abs(e.y - s.y)) < 1 || Math.hypot(b.x - a.x, b.y - a.y) <= a.r + b.r) {\n return straight();\n }\n // The ports follow the direction to each child. This offsets sibling departures while keeping\n // every trace inside its endpoints' bounding box, including near viewport corners.\n const horizontal = Math.abs(b.x - a.x) >= Math.abs(b.y - a.y);\n const lane = horizontal ? (s.x + e.x) / 2 : (s.y + e.y) / 2;\n const corners = horizontal\n ? [\n { x: lane, y: s.y },\n { x: lane, y: e.y },\n ]\n : [\n { x: s.x, y: lane },\n { x: e.x, y: lane },\n ];\n const route = [s, ...corners, e];\n const points = [s];\n let d = `M${fmt(s.x)} ${fmt(s.y)}`;\n corners.forEach((corner, i) => {\n const before = route[i];\n const after = route[i + 2];\n const round = Math.min(\n 10,\n Math.hypot(corner.x - before.x, corner.y - before.y) / 2,\n Math.hypot(after.x - corner.x, after.y - corner.y) / 2,\n );\n const enter = towards(corner, before, round);\n const leave = towards(corner, after, round);\n d += `L${fmt(enter.x)} ${fmt(enter.y)}Q${fmt(corner.x)} ${fmt(corner.y)} ${fmt(leave.x)} ${fmt(leave.y)}`;\n points.push(enter);\n // Collision checks follow the rounded corners as well as the straight portions.\n for (let j = 1; j <= 4; j++) {\n const t = j / 4;\n const u = 1 - t;\n points.push({\n x: u * u * enter.x + 2 * u * t * corner.x + t * t * leave.x,\n y: u * u * enter.y + 2 * u * t * corner.y + t * t * leave.y,\n });\n }\n });\n points.push(e);\n return { d: `${d}L${fmt(e.x)} ${fmt(e.y)}`, points };\n }\n\n if (style !== 'curved' || parentAngle == null) return straight();\n const len = Math.hypot(b.x - a.x, b.y - a.y) || 1;\n const c = { x: a.x + Math.cos(parentAngle) * len * 0.5, y: a.y + Math.sin(parentAngle) * len * 0.5 };\n const s = towards(a, c, a.r);\n const e = towards(b, c, b.r);\n const points: Vec[] = [];\n for (let i = 0; i <= 6; i++) {\n const t = i / 6;\n const u = 1 - t;\n points.push({ x: u * u * s.x + 2 * u * t * c.x + t * t * e.x, y: u * u * s.y + 2 * u * t * c.y + t * t * e.y });\n }\n return { d: `M${fmt(s.x)} ${fmt(s.y)}Q${fmt(c.x)} ${fmt(c.y)} ${fmt(e.x)} ${fmt(e.y)}`, points };\n}\n\n/** SVG path data for an edge (see `edgeShape`). */\nexport const edgePath = (a: Circle, b: Circle, style: EdgeKind, parentAngle: number | null) =>\n edgeShape(a, b, style, parentAngle).d;\n\n/* ----------------------------------------------------------------- labels */\n\nexport interface LabelContext {\n bounds: Rect;\n /** Every node and the hub. */\n circles: Circle[];\n /** Labels already on screen or reserved. */\n taken: Rect[];\n /** Edge polylines a label must not cross (empty to allow crossing). */\n edges: Vec[][];\n /** Clearance between any node's rim and any label: room for hover growth, rings and halos. */\n pad: number;\n /**\n * Clearance from the label's own node, if different. Lets the highlighted label sit closer to the\n * other nodes: only the highlighted node grows, so the others need less room.\n */\n ownPad?: number;\n /** Extra distances from the node to try, nearest first (default `LABEL_RINGS`). */\n rings?: number[];\n}\n\n/** Preferred direction first, then alternating outwards in 22.5° steps. */\nconst LABEL_ANGLES = [0, ...Array.from({ length: 7 }, (_, i) => [(i + 1) * 22.5, -(i + 1) * 22.5]).flat(), 180].map(\n (d) => d * DEG,\n);\n/** Extra distance from the node, tried after every angle failed (never far: a label must read as its node's). */\nconst LABEL_RINGS = [0, 12, 28];\n/** An open branch's label may sit a little further out: its highlighted path ties it to the node. */\nconst OPEN_LABEL_RINGS = [0, 12, 28, 48];\n\n/** Rect of size w×h pushed from (x, y) along `angle` until it clears a circle of radius `clear`. */\nfunction rectAlong(x: number, y: number, w: number, h: number, angle: number, clear: number): Rect {\n const ux = Math.cos(angle);\n const uy = Math.sin(angle);\n let lo = 0;\n let hi = clear + w + h;\n for (let i = 0; i < 14; i++) {\n const t = (lo + hi) / 2;\n if (distToRect({ x, y }, { x: x + ux * t - w / 2, y: y + uy * t - h / 2, w, h }) >= clear) hi = t;\n else lo = t;\n }\n return { x: x + ux * hi - w / 2, y: y + uy * hi - h / 2, w, h };\n}\n\nfunction labelCollides(rect: Rect, own: Circle, ctx: LabelContext): boolean {\n for (const c of ctx.circles) {\n if (c === own) continue;\n if (distToRect(c, rect) < c.r + ctx.pad) return true;\n }\n for (const t of ctx.taken) if (rectsTouch(rect, t, LABEL_SPACING)) return true;\n if (ctx.edges.length) {\n const halo = grow(rect, 2);\n for (const e of ctx.edges) if (polyHitsRect(e, halo)) return true;\n }\n return false;\n}\n\n/** How many candidate spots around `node` are free: a measure of how constrained a label is. */\nfunction freeSpots(node: Circle, sizes: Sizes, angle: number, ctx: LabelContext): number {\n const size = variants(sizes)[0];\n let n = 0;\n for (const extra of LABEL_RINGS) {\n for (const offset of LABEL_ANGLES) {\n const rect = rectAlong(node.x, node.y, size.w, size.h, angle + offset, node.r + (ctx.ownPad ?? ctx.pad) + extra);\n if (inside(ctx.bounds, rect) && !labelCollides(rect, node, ctx)) n++;\n }\n }\n return n;\n}\n\n/**\n * Places several labels so that none of them overlap. Greedy in the given order first; if that leaves\n * one out, the most constrained label goes first, then the reverse order. Returns rects by index.\n */\nexport function placeLabels(\n items: { node: Circle; size: Sizes; angle: number }[],\n ctx: LabelContext,\n place: (item: { node: Circle; size: Sizes; angle: number }, ctx: LabelContext) => Rect | null = (it, c) =>\n placeLabel(it.node, it.size, it.angle, c),\n): (Rect | null)[] {\n const run = (order: number[]) => {\n const out: (Rect | null)[] = items.map(() => null);\n const c = { ...ctx, taken: [...ctx.taken] };\n let missing = 0;\n for (const i of order) {\n const rect = place(items[i], c);\n if (rect) c.taken.push(rect);\n else missing++;\n out[i] = rect;\n }\n return { out, missing };\n };\n const natural = items.map((_, i) => i);\n let best = run(natural);\n if (best.missing === 0 || items.length < 2) return best.out;\n const spots = items.map((it) => freeSpots(it.node, it.size, it.angle, ctx));\n for (const order of [[...natural].sort((a, b) => spots[a] - spots[b]), [...natural].reverse()]) {\n const attempt = run(order);\n if (attempt.missing < best.missing) best = attempt;\n if (best.missing === 0) break;\n }\n return best.out;\n}\n\n/**\n * Finds a spot for a label next to `node` that touches nothing in `ctx`, trying the preferred direction\n * first, and each size variant in turn (the full-width label before a wrapped one). `node` must be the\n * same object as its entry in `ctx.circles`. Null when nothing fits.\n */\nexport function placeLabel(node: Circle, sizes: Sizes, angle: number, ctx: LabelContext): Rect | null {\n for (const size of variants(sizes)) {\n const rect = placeOne(node, size, angle, ctx);\n if (rect) return rect;\n }\n return null;\n}\n\nfunction placeOne(node: Circle, size: Size, angle: number, ctx: LabelContext): Rect | null {\n for (const extra of ctx.rings ?? LABEL_RINGS) {\n for (const offset of LABEL_ANGLES) {\n const rect = rectAlong(node.x, node.y, size.w, size.h, angle + offset, node.r + (ctx.ownPad ?? ctx.pad) + extra);\n if (inside(ctx.bounds, rect) && !labelCollides(rect, node, ctx)) return rect;\n }\n }\n return null;\n}\n\n/* ------------------------------------------------------------------- fans */\n\nexport interface FanInput {\n /** The parent node, or the hub for the top level. */\n origin: Circle;\n /** Direction the origin itself was reached from (null for the hub). Shapes curved edges. */\n parentAngle: number | null;\n count: number;\n /** Preferred direction the fan opens towards (radians). */\n direction: number;\n /** Node radius. */\n radius: number;\n /** Preferred distance from origin to each node centre. */\n distance: number;\n /** Minimum free space between neighbouring nodes. */\n gap: number;\n /** Nodes and labels must stay inside. */\n bounds: Rect;\n /** Everything already placed, except the origin. */\n obstacles: Circle[];\n /** Label rects already reserved. */\n blocked?: Rect[];\n /** Edges already drawn. */\n edges?: Vec[][];\n edgeStyle?: EdgeKind;\n /** Label size(s) to reserve for each new node (null: no label). */\n labels?: (Sizes | null)[];\n /** Label size(s) to reserve for the origin itself (an unfolded branch keeps its name on screen). */\n originLabel?: Sizes | null;\n /** The edge leading into the origin (its label must not cross it). */\n parentEdge?: Vec[] | null;\n /** See `LabelContext.pad`. */\n labelPad?: number;\n /** Allow a full ring around the origin (for a free-floating button). */\n ring?: boolean;\n /** A comfortable angle between neighbours, used when there is room. */\n preferredStep?: number;\n /** Upper bound for the angle the whole fan covers. */\n maxSpread?: number;\n /** How far the fan may rotate away from `direction` before other directions are considered. */\n maxDeviation?: number;\n}\n\nexport interface Fan {\n points: Vec[];\n /** Reserved label rect per node; null where no label was asked for or none fits. */\n labels: (Rect | null)[];\n /** Reserved label rect for the origin (see `FanInput.originLabel`). */\n originLabel?: Rect | null;\n}\n\n/** Fan distances tried, as multiples of the preferred one. Fine-grained: on narrow screens only a narrow band fits. */\nconst DISTANCE_SCALES = Array.from({ length: 41 }, (_, k) => 1 + k * 0.06);\nconst RING_SCALES = [1, 1.15, 1.3, 1.5, 1.75, 2, 2.3];\nconst DEVIATION_STEP = 5 * DEG;\n/** Label checks are the expensive part; cap how many node-valid candidates per distance get one. */\nconst LABEL_CHECKS_PER_TIER = 200;\n\nfunction arcPoints(o: Vec, rad: number, n: number, dir: number, step: number): Vec[] {\n const start = dir - (step * (n - 1)) / 2;\n return Array.from({ length: n }, (_, i) => {\n const a = start + i * step;\n return { x: o.x + rad * Math.cos(a), y: o.y + rad * Math.sin(a) };\n });\n}\n\nfunction ringPoints(o: Vec, rad: number, n: number, dir: number): Vec[] {\n return Array.from({ length: n }, (_, i) => {\n const a = dir + (i * TAU) / n;\n return { x: o.x + rad * Math.cos(a), y: o.y + rad * Math.sin(a) };\n });\n}\n\n/**\n * `base`: overflow, and overlap with nodes or reserved labels. `edges`: nodes sitting on edges, or new\n * edges running through nodes. (New edges may pass *under* labels reserved by earlier levels: those belong\n * to pages that are dimmed while this branch is open, and labels are drawn above edges.)\n */\nfunction nodePenalty(pts: Vec[], f: FanInput, strict: boolean, ignoreBlocked = false): { base: number; edges: number } {\n const { bounds: b, radius: r } = f;\n const pad = f.labelPad ?? 8;\n let base = 0;\n let edges = 0;\n for (const q of pts) {\n base += Math.max(0, b.x + r - q.x) + Math.max(0, q.x + r - (b.x + b.w));\n base += Math.max(0, b.y + r - q.y) + Math.max(0, q.y + r - (b.y + b.h));\n for (const o of f.obstacles) {\n const min = r + o.r + f.gap * 0.75;\n const d = Math.hypot(q.x - o.x, q.y - o.y);\n if (d < min) base += min - d;\n }\n if (!ignoreBlocked) {\n for (const rect of f.blocked ?? []) {\n const d = distToRect(q, rect);\n if (d < r + pad) base += r + pad - d;\n }\n }\n }\n if (strict && f.edgeStyle !== 'none' && base === 0) {\n const style = f.edgeStyle ?? 'straight';\n for (const q of pts) {\n for (const e of f.edges ?? []) {\n const d = polyDist(q, e);\n if (d < r + 4) edges += r + 4 - d;\n }\n }\n pts.forEach((q, i) => {\n const e = edgeShape(f.origin, { ...q, r }, style, f.parentAngle).points;\n for (const o of f.obstacles) {\n const d = polyDist(o, e);\n if (d < o.r + 4) edges += o.r + 4 - d;\n }\n pts.forEach((p, j) => {\n if (j === i) return;\n const d = polyDist(p, e);\n if (d < r + 4) edges += r + 4 - d;\n });\n });\n }\n return { base, edges };\n}\n\ntype OriginRule = 'clean' | 'breadcrumb' | 'optional';\n\n/**\n * Reserves a label for every node of a candidate fan. Null when one doesn't fit (unless `bestEffort`).\n * `strict`: labels cross no edge. `relaxed`: they may cross earlier levels' edges, not this fan's.\n * `loose`: they may cross any edge but their own node's.\n */\nfunction fanLabels(\n pts: Vec[],\n f: FanInput,\n rule: 'strict' | 'relaxed' | 'loose',\n bestEffort: boolean,\n /** What the unfolded branch's own label must be: clean, clean-or-breadcrumb, or anything (even none). */\n origin: OriginRule = 'optional',\n): { labels: (Rect | null)[]; originLabel: Rect | null } | null {\n if (!f.labels?.some(Boolean) && !f.originLabel) return { labels: pts.map(() => null), originLabel: null };\n const r = f.radius;\n const style = f.edgeStyle ?? 'straight';\n const nodes = pts.map((p) => ({ x: p.x, y: p.y, r }));\n const own = style !== 'none' ? nodes.map((n) => edgeShape(f.origin, n, style, f.parentAngle).points) : [];\n const edges = style !== 'none' ? [...(f.edges ?? []), ...own] : [];\n const ctx: LabelContext = {\n bounds: f.bounds,\n circles: [...f.obstacles, f.origin, ...nodes],\n taken: [...(f.blocked ?? [])],\n edges,\n pad: f.labelPad ?? 8,\n };\n const wanted = nodes.map((node, i) => ({\n i,\n node,\n size: f.labels?.[i] ?? null,\n angle: Math.atan2(node.y - f.origin.y, node.x - f.origin.x),\n }));\n const items = wanted.filter((w): w is typeof w & { size: Sizes } => !!w.size);\n const rects = placeLabels(items, ctx, (it, c) => {\n const i = (it as (typeof items)[number]).i;\n return (\n placeLabel(it.node, it.size, it.angle, c) ??\n (rule === 'strict' ? null : placeLabel(it.node, it.size, it.angle, { ...c, edges: own })) ??\n (rule === 'loose' ? placeLabel(it.node, it.size, it.angle, { ...c, edges: own.length ? [own[i]] : [] }) : null)\n );\n });\n const out: (Rect | null)[] = nodes.map(() => null);\n items.forEach((it, k) => (out[it.i] = rects[k]));\n if (!bestEffort && items.some((_, k) => !rects[k])) return null;\n\n // The unfolded branch keeps its name too: clear of its children, their labels and their edges.\n let originLabel: Rect | null = null;\n if (f.originLabel) {\n const c = { ...ctx, taken: [...ctx.taken, ...out.filter((x): x is Rect => !!x)], rings: OPEN_LABEL_RINGS };\n const inEdge = f.parentEdge ? [f.parentEdge] : [];\n // Crossing nothing, or else sitting on its own (highlighted) incoming path like a breadcrumb. If there's\n // no such spot it's placed on demand instead.\n originLabel = placeLabel(f.origin, f.originLabel, f.direction, { ...c, edges: [...c.edges, ...inEdge] });\n if (!originLabel && origin !== 'clean') {\n originLabel = placeLabel(f.origin, f.originLabel, f.direction + Math.PI, {\n ...c,\n edges: c.edges.filter((e) => e !== f.parentEdge),\n });\n }\n if (!originLabel && origin !== 'optional' && !bestEffort) return null;\n }\n return { labels: out, originLabel };\n}\n\n/**\n * Places `count` nodes around `origin`, each with room for its label.\n *\n * Search order: the preferred distance first, growing until something fits; within a distance, the\n * candidate closest to the preferred direction. Passes, each more lenient: (1) strict, near the preferred\n * direction; (2) strict, any direction, wider fans; (3) as (2) but edges may cross labels and nodes;\n * (4) nodes still never overlap, but labels that don't fit are left out. Only if there's no room for the\n * nodes themselves is the least-bad placement used.\n */\nexport function placeFan(f: FanInput): Fan {\n const { origin, count: n, radius: r, gap } = f;\n if (n <= 0) return { points: [], labels: [] };\n const chord = 2 * r + gap;\n let fallback: { points: Vec[]; penalty: number } | null = null;\n\n const attempt = (pts: Vec[], strict: boolean, budget: { left: number }, needOrigin: OriginRule): Fan | null => {\n const pen = nodePenalty(pts, f, strict);\n if (!fallback || pen.base < fallback.penalty) fallback = { points: pts, penalty: pen.base };\n if (pen.base > 0 || (strict && pen.edges > 0) || budget.left <= 0) return null;\n budget.left--;\n const res = fanLabels(pts, f, strict ? 'strict' : 'relaxed', false, needOrigin);\n return res ? { points: pts, ...res } : null;\n };\n\n const radii = DISTANCE_SCALES.map((s) => f.distance * s);\n if (n > 1 && f.maxSpread != null) {\n // The distance at which the fan exactly fills `maxSpread`: often the only one that fits.\n const exact = chord / (2 * Math.sin(f.maxSpread / (2 * (n - 1)))) + 0.5;\n if (exact > f.distance) radii.push(exact);\n }\n radii.sort((a, b) => a - b);\n\n const preferredDev = Math.min(f.maxDeviation ?? Math.PI, Math.PI);\n const wide = f.maxSpread != null && !f.ring ? Math.min(f.maxSpread * 1.5, 1.4 * Math.PI) : f.maxSpread;\n // An unfolded branch would like to keep its own label on screen: every pass is tried with that first,\n // then without (the label is then placed on demand, when the branch is highlighted).\n const basePasses: { dev: number; strict: boolean; spread: number | undefined }[] = [\n { dev: preferredDev, strict: true, spread: f.maxSpread },\n { dev: Math.PI, strict: true, spread: wide },\n { dev: Math.PI, strict: false, spread: wide },\n ];\n const originRules: OriginRule[] = f.originLabel ? ['clean', 'breadcrumb', 'optional'] : ['optional'];\n const passes = originRules.flatMap((needOrigin) => basePasses.map((p) => ({ ...p, needOrigin })));\n\n for (const pass of passes) {\n if (f.ring && n >= 3) {\n const minRad = Math.max(f.distance, chord / (2 * Math.sin(Math.PI / n)));\n for (const s of RING_SCALES) {\n const fan = attempt(ringPoints(origin, minRad * s, n, f.direction), pass.strict, { left: 1 }, pass.needOrigin);\n if (fan) return fan;\n }\n }\n\n for (const rad of radii) {\n if (chord >= 2 * rad) continue;\n const minStep = 2 * Math.asin(chord / (2 * rad));\n const comfy = Math.max(minStep, f.preferredStep ?? 0);\n const steps = comfy > minStep + 1e-9 ? [comfy, minStep] : [minStep];\n\n // Every candidate at this distance, cheapest (closest to the preferred direction) first.\n const candidates: { dir: number; step: number; cost: number }[] = [];\n for (const step of steps) {\n if (n > 1 && pass.spread != null && step * (n - 1) > pass.spread + 1e-9) continue;\n const stepCost = step === comfy ? 0 : 0.15;\n for (let k = 0; k * DEVIATION_STEP <= pass.dev + 1e-9; k++) {\n for (const sign of k === 0 ? [0] : [1, -1]) {\n const dev = sign * k * DEVIATION_STEP;\n candidates.push({ dir: f.direction + dev, step, cost: Math.abs(dev) + stepCost });\n }\n }\n }\n candidates.sort((a, b) => a.cost - b.cost);\n const budget = { left: LABEL_CHECKS_PER_TIER };\n for (const c of candidates) {\n const fan = attempt(arcPoints(origin, rad, n, c.dir, c.step), pass.strict, budget, pass.needOrigin);\n if (fan) return fan;\n }\n }\n }\n\n // (4) Clean nodes, as many labels as fit: the best of the first few clean candidates. Nodes may take\n // room reserved for earlier labels here; `layoutGraph` drops those labels rather than overlap them.\n let best: Fan | null = null;\n let bestCount = -1;\n let tried = 0;\n const style = f.edgeStyle ?? 'straight';\n const consider = (pts: Vec[]) => {\n if (nodePenalty(pts, f, false, true).base > 0) return;\n tried++;\n const res = fanLabels(pts, f, 'loose', true)!;\n const labels = res.labels;\n // Most labels first, then most labels clear of every edge.\n const edges =\n style === 'none'\n ? []\n : [...(f.edges ?? []), ...pts.map((p) => edgeShape(f.origin, { ...p, r }, style, f.parentAngle).points)];\n const placedCount = labels.filter(Boolean).length + (res.originLabel ? 1 : 0);\n const clean = labels.filter((l) => l && !edges.some((e) => polyHitsRect(e, l))).length;\n const score = placedCount * (n + 2) + clean;\n if (score > bestCount) {\n best = { points: pts, ...res };\n bestCount = score;\n }\n };\n if (f.ring && n >= 3) {\n const minRad = Math.max(f.distance, chord / (2 * Math.sin(Math.PI / n)));\n for (const s of RING_SCALES) consider(ringPoints(origin, minRad * s, n, f.direction));\n }\n for (const rad of radii) {\n const perfect = (n + (f.originLabel ? 1 : 0)) * (n + 2) + n;\n if (tried >= 160 || bestCount === perfect || chord >= 2 * rad) continue;\n const step = 2 * Math.asin(chord / (2 * rad));\n for (let k = 0; k * DEVIATION_STEP <= Math.PI && tried < 160 && bestCount < perfect; k++) {\n for (const sign of k === 0 ? [0] : [1, -1])\n consider(arcPoints(origin, rad, n, f.direction + sign * k * DEVIATION_STEP, step));\n }\n }\n if (best) return best;\n\n const points =\n (fallback as { points: Vec[] } | null)?.points ?? arcPoints(origin, f.distance, n, f.direction, chord / f.distance);\n return { points, ...fanLabels(points, f, 'loose', true)! };\n}\n\n/* ------------------------------------------------------------------ graph */\n\nexport interface Level {\n /** Unique key for the level (the ids of the expanded path joined), used for caching. */\n key: string;\n /** `null` for the top level (children of the button). */\n parentId: string | null;\n childIds: string[];\n}\n\nexport interface PlacedNode extends Vec {\n /** Centre of the parent (the button for top-level pages). */\n from: Vec;\n /** Direction from the parent to this node. */\n angle: number;\n /** Direction the parent itself was reached from (null for top-level pages). */\n parentAngle: number | null;\n /** Room reserved for this node's label; null when labels are off or none fits. */\n label: Rect | null;\n /**\n * The label uses room reserved for a dimmed page's label (only for the level you're looking at, whose\n * labels are always shown). That dimmed label must then stay hidden while this one is visible.\n */\n borrowed?: boolean;\n /** The edge from the parent as a polyline. */\n edge: Vec[];\n /** Room reserved for this node's label while it is unfolded (see `GraphInput.branchLabelSize`). */\n pathLabel?: Rect | null;\n}\n\nexport interface GraphInput {\n hub: Circle;\n bounds: Rect;\n levels: Level[];\n nodeRadius: number;\n distance: number;\n gap: number;\n edgeStyle?: EdgeKind;\n /** Size(s) of each node's label, to reserve room for it. Omit to lay out without labels. */\n labelSize?: (id: string) => Sizes | null;\n /** Size(s) of an unfolded branch's label (it may carry an extra hint); defaults to `labelSize`. */\n branchLabelSize?: (id: string) => Sizes | null;\n /** See `LabelContext.pad`. */\n labelPad?: number;\n}\n\n/**\n * Lays out the visible part of the tree level by level. Each level only depends on the levels before it,\n * so a fan never moves when something deeper unfolds; fans are cached per level key.\n *\n * When a node unfolds, its own reserved label space is released (its children usually want that\n * direction); every other reserved label stays out of bounds for deeper levels.\n */\nexport function layoutGraph(g: GraphInput, cache = new Map<string, Fan>()): Map<string, PlacedNode> {\n const placed = new Map<string, PlacedNode>();\n const style = g.edgeStyle ?? 'straight';\n const r = g.nodeRadius;\n const obstacles: Circle[] = [g.hub];\n const edges: Vec[][] = [];\n const reserved: { id: string; rect: Rect }[] = [];\n const released = new Set<string>();\n const center = { x: g.bounds.x + g.bounds.w / 2, y: g.bounds.y + g.bounds.h / 2 };\n\n for (const level of g.levels) {\n const parent = level.parentId == null ? null : placed.get(level.parentId);\n if (level.parentId != null && !parent) continue;\n if (level.parentId != null) released.add(level.parentId);\n const origin: Circle = parent ? { x: parent.x, y: parent.y, r } : g.hub;\n\n let fan = cache.get(level.key);\n if (!fan || fan.points.length !== level.childIds.length) {\n const toCenter = Math.atan2(center.y - g.hub.y, center.x - g.hub.x);\n const nearCenter = Math.hypot(center.x - g.hub.x, center.y - g.hub.y) < 1;\n fan = placeFan({\n origin,\n parentAngle: parent ? parent.angle : null,\n count: level.childIds.length,\n direction: parent ? parent.angle : nearCenter ? -Math.PI / 2 : toCenter,\n radius: r,\n distance: g.distance,\n gap: g.gap,\n bounds: g.bounds,\n obstacles: obstacles.filter((o) => o.x !== origin.x || o.y !== origin.y),\n blocked: reserved.filter((x) => !released.has(x.id)).map((x) => x.rect),\n edges,\n edgeStyle: style,\n labels: level.childIds.map((id) => g.labelSize?.(id) ?? null),\n originLabel: parent && level.parentId ? ((g.branchLabelSize ?? g.labelSize)?.(level.parentId) ?? null) : null,\n parentEdge: parent ? parent.edge : null,\n labelPad: g.labelPad,\n ...(parent\n ? { maxSpread: 150 * DEG, maxDeviation: 110 * DEG }\n : { ring: true, preferredStep: 50 * DEG, maxSpread: Math.PI }),\n });\n cache.set(level.key, fan);\n }\n\n if (parent) {\n parent.pathLabel = fan.originLabel ?? null;\n // Deeper levels keep clear of it (it's never released).\n if (parent.pathLabel) reserved.push({ id: `${level.parentId}\\u0000open`, rect: parent.pathLabel });\n }\n\n // A fan that only fit as a last resort may cover reserved labels: drop those labels, never overlap.\n const pad = g.labelPad ?? 8;\n for (const res of reserved) {\n if (released.has(res.id)) continue;\n const covered = fan.points.some((p) => distToRect(p, res.rect) < r + pad - 0.5);\n if (!covered) continue;\n const [id, open] = res.id.split('\\u0000');\n const owner = placed.get(id);\n if (!owner) continue;\n if (open) owner.pathLabel = null;\n else owner.label = null;\n }\n\n level.childIds.forEach((id, i) => {\n const p = fan.points[i];\n const node = { x: p.x, y: p.y, r };\n const parentAngle = parent ? parent.angle : null;\n const edge = edgeShape(origin, node, style, parentAngle).points;\n placed.set(id, {\n x: p.x,\n y: p.y,\n from: { x: origin.x, y: origin.y },\n angle: Math.atan2(p.y - origin.y, p.x - origin.x),\n parentAngle,\n label: fan.labels[i] ?? null,\n edge,\n });\n obstacles.push(node);\n if (style !== 'none') edges.push(edge);\n const rect = fan.labels[i];\n if (rect) reserved.push({ id, rect });\n });\n }\n\n // Second chance for the level you're looking at: labels that found no room, or had to cross an edge,\n // may use space reserved for dimmed pages' labels, which are hidden while this level is open.\n const last = g.levels[g.levels.length - 1];\n if (last && g.labelSize) {\n const pad = g.labelPad ?? 8;\n const circles = new Map<string, Circle>();\n for (const [id, p] of placed) circles.set(id, { x: p.x, y: p.y, r });\n const frontier = last.childIds.filter((id) => placed.has(id));\n const crosses = (rect: Rect) => edges.some((e) => polyHitsRect(e, rect));\n const redo = frontier.filter((id) => {\n const rect = placed.get(id)!.label;\n return g.labelSize!(id) && (!rect || crosses(rect));\n });\n if (redo.length) {\n const ctx: LabelContext = {\n bounds: g.bounds,\n circles: [g.hub, ...circles.values()],\n taken: frontier\n .filter((id) => !redo.includes(id))\n .map((id) => placed.get(id)!.label)\n .filter((x): x is Rect => !!x),\n edges,\n pad,\n };\n const items = redo.map((id) => ({\n id,\n node: circles.get(id)!,\n size: g.labelSize!(id)!,\n angle: placed.get(id)!.angle,\n }));\n // Visible labels matter more than a clean line under them: as a last resort a label may cover\n // another edge (it's drawn above edges), but never its own.\n const rects = placeLabels(items, ctx, (it, c) => {\n const p = placed.get((it as (typeof items)[number]).id)!;\n return (\n placeLabel(it.node, it.size, it.angle, c) ??\n // A label that already had a (crossing) spot keeps it, and keeps others out of it.\n p.label ??\n placeLabel(it.node, it.size, it.angle, { ...c, edges: style === 'none' ? [] : [p.edge] })\n );\n });\n items.forEach((it, k) => {\n const p = placed.get(it.id)!;\n if (rects[k] && rects[k] !== p.label) {\n p.label = rects[k];\n p.borrowed = true;\n }\n });\n }\n }\n // Circuit doglegs can enter room reserved for an earlier open branch's name. Recheck the visible\n // labels against the complete graph, rather than retaining a crossing spot from a shallower fan.\n if (style === 'step' && last && g.labelSize) {\n const open = new Set(g.levels.flatMap((level) => (level.parentId == null ? [] : [level.parentId])));\n const visible = [...new Set([...open, ...last.childIds])].filter((id) => placed.has(id));\n const rectOf = (id: string) => (open.has(id) ? placed.get(id)!.pathLabel : placed.get(id)!.label);\n for (const id of visible) {\n const p = placed.get(id)!;\n const rect = rectOf(id);\n const clearEdges = open.has(id) ? edges.filter((e) => e !== p.edge) : edges;\n if (rect && !clearEdges.some((e) => polyHitsRect(e, rect))) continue;\n const size = (open.has(id) ? (g.branchLabelSize ?? g.labelSize) : g.labelSize)(id);\n if (!size) continue;\n const node = { x: p.x, y: p.y, r };\n const ctx: LabelContext = {\n bounds: g.bounds,\n circles: [g.hub, ...[...placed.values()].map((q) => ({ x: q.x, y: q.y, r }))],\n taken: visible\n .filter((other) => other !== id)\n .map(rectOf)\n .filter((q): q is Rect => !!q),\n edges: clearEdges,\n pad: g.labelPad ?? 8,\n rings: [...OPEN_LABEL_RINGS, 64, 80],\n };\n const clean = placeLabel(node, size, p.angle, ctx);\n if (open.has(id)) p.pathLabel = clean;\n else p.label = clean;\n // As with frontier labels, a relocated branch caption may borrow a dimmed sibling's room.\n if (clean) p.borrowed = true;\n }\n }\n return placed;\n}\n\n/** Index of the node under the pointer, or -1. Picks the nearest node within its radius + slop. */\nexport function hitTest(p: Vec, nodes: Circle[], slop: number): number {\n let best = -1;\n let bestD = Infinity;\n nodes.forEach((n, i) => {\n const d = Math.hypot(p.x - n.x, p.y - n.y);\n if (d <= n.r + slop && d < bestD) {\n best = i;\n bestD = d;\n }\n });\n return best;\n}\n","/**\n * Every public knob is a `--unfold-*` custom property (set it on the element or any ancestor). Internally\n * each one resolves into a private `--_*` variable that carries the light/dark default.\n */\nconst LIGHT = `\n --_fg: var(--unfold-fg, #17171c);\n --_muted: var(--unfold-muted, rgb(23 23 28 / .68));\n --_surface: var(--unfold-surface, rgb(255 255 255 / .78));\n --_surface-active: var(--unfold-surface-active, rgb(255 255 255 / .96));\n --_border: var(--unfold-border, rgb(255 255 255 / .7));\n --_outline: var(--unfold-outline, rgb(15 15 30 / .09));\n --_shadow: var(--unfold-shadow, 0 1px 2px rgb(15 15 30 / .08), 0 10px 28px -8px rgb(15 15 30 / .28));\n --_edge: var(--unfold-edge, rgb(23 23 28 / .2));\n --_label-bg: var(--unfold-label-bg, rgb(255 255 255 / .9));\n --_label-fg: var(--unfold-label-fg, var(--_fg));\n --_backdrop: var(--unfold-backdrop, rgb(244 244 248 / .42));\n`;\n\nconst DARK = `\n --_fg: var(--unfold-fg, #f3f3f6);\n --_muted: var(--unfold-muted, rgb(243 243 246 / .7));\n --_surface: var(--unfold-surface, rgb(38 38 44 / .72));\n --_surface-active: var(--unfold-surface-active, rgb(56 56 64 / .92));\n --_border: var(--unfold-border, rgb(255 255 255 / .12));\n --_outline: var(--unfold-outline, rgb(0 0 0 / .4));\n --_shadow: var(--unfold-shadow, 0 1px 2px rgb(0 0 0 / .3), 0 12px 30px -8px rgb(0 0 0 / .6));\n --_edge: var(--unfold-edge, rgb(243 243 246 / .22));\n --_label-bg: var(--unfold-label-bg, rgb(30 30 36 / .9));\n --_label-fg: var(--unfold-label-fg, var(--_fg));\n --_backdrop: var(--unfold-backdrop, rgb(8 8 12 / .45));\n`;\n\nexport const STYLES: string = `\n:host {\n display: inline-block;\n vertical-align: middle;\n}\n:host([hidden]) { display: none; }\n\n.root {\n --_accent: var(--unfold-accent, #5b5bf0);\n --_accent-fg: var(--unfold-accent-fg, #fff);\n --_blur: var(--unfold-blur, 18px);\n --_backdrop-blur: var(--unfold-backdrop-blur, 6px);\n --_edge-width: var(--unfold-edge-width, 1.5px);\n --_icon-size: var(--unfold-icon-size, 22px);\n --_dur: var(--unfold-duration, 340ms);\n --_spring: var(--unfold-easing, cubic-bezier(.22, 1.2, .36, 1));\n --_ease: cubic-bezier(.3, .7, .2, 1);\n --_z: var(--unfold-z-index, 2147483000);\n --_node-radius: var(--unfold-node-radius, 50%);\n --_trigger-radius: var(--unfold-trigger-radius, 50%);\n --_border-width: var(--unfold-border-width, 1px);\n --_active-scale: var(--unfold-active-scale, 1.14);\n --_dim-opacity: var(--unfold-dim-opacity, .7);\n --_dim-scale: var(--unfold-dim-scale, .86);\n --_label-radius: var(--unfold-label-radius, 9px);\n /* Follows the reader's font-size preference, never smaller than 13px. */\n --_label-size: var(--unfold-label-size, max(13px, .8125rem));\n --_desc-size: var(--unfold-description-size, max(12px, .75rem));\n --_dock-bg: var(--unfold-dock-bg, color-mix(in srgb, var(--_surface-active) 88%, transparent));\n --_dock-border: var(--unfold-dock-border, var(--_outline));\n --_dock-blur: var(--unfold-dock-blur, 16px);\n --_label-weight: var(--unfold-label-weight, 600);\n --_label-tracking: var(--unfold-label-tracking, normal);\n --_label-case: var(--unfold-label-case, none);\n ${LIGHT}\n /* Longhands on purpose: with no --unfold-font the family declaration is invalid and simply inherits the\n page's font, while size and weight stay ours. (A shorthand with an inherited part would be dropped.) */\n font-family: var(--unfold-font);\n font-size: 13px;\n font-weight: 500;\n line-height: 1.25;\n color: var(--_fg);\n}\n.root[data-theme=\"dark\"] { ${DARK} }\n@media (prefers-color-scheme: dark) {\n .root[data-theme=\"auto\"] { ${DARK} }\n}\n\n/* ---------------------------------------------------------------- button */\n\n/* dock=\"bar\": a strip along the button's edge, so page content never sits under the button. */\n.dock-bar {\n display: none;\n position: fixed;\n z-index: calc(var(--_z) - 1);\n background: var(--_dock-bg);\n border: 0 solid var(--_dock-border);\n -webkit-backdrop-filter: blur(var(--_dock-blur)) saturate(1.4);\n backdrop-filter: blur(var(--_dock-blur)) saturate(1.4);\n}\n.root[data-dock=\"bar\"] .dock-bar[data-edge] { display: block; }\n.dock-bar[data-edge=\"top\"], .dock-bar[data-edge=\"bottom\"] { left: 0; right: 0; }\n.dock-bar[data-edge=\"left\"], .dock-bar[data-edge=\"right\"] { top: 0; bottom: 0; }\n.dock-bar[data-edge=\"top\"] { top: 0; height: calc(var(--_trigger-size) + var(--_offset-y) * 2 + env(safe-area-inset-top, 0px)); border-bottom-width: 1px; }\n.dock-bar[data-edge=\"bottom\"] { bottom: 0; height: calc(var(--_trigger-size) + var(--_offset-y) * 2 + env(safe-area-inset-bottom, 0px)); border-top-width: 1px; }\n.dock-bar[data-edge=\"left\"] { left: 0; width: calc(var(--_trigger-size) + var(--_offset-x) * 2 + env(safe-area-inset-left, 0px)); border-right-width: 1px; }\n.dock-bar[data-edge=\"right\"] { right: 0; width: calc(var(--_trigger-size) + var(--_offset-x) * 2 + env(safe-area-inset-right, 0px)); border-left-width: 1px; }\n\n.dock {\n position: fixed;\n z-index: var(--_z);\n width: var(--_trigger-size);\n height: var(--_trigger-size);\n --_ox: calc(var(--_offset-x) + env(safe-area-inset-left, 0px));\n --_ox-r: calc(var(--_offset-x) + env(safe-area-inset-right, 0px));\n --_oy: calc(var(--_offset-y) + env(safe-area-inset-top, 0px));\n --_oy-b: calc(var(--_offset-y) + env(safe-area-inset-bottom, 0px));\n}\n.dock[data-position=\"inline\"] { position: relative; z-index: auto; }\n.dock[data-position^=\"top\"] { top: var(--_oy); }\n.dock[data-position^=\"bottom\"] { bottom: var(--_oy-b); }\n.dock[data-position$=\"left\"] { left: var(--_ox); }\n.dock[data-position$=\"right\"] { right: var(--_ox-r); }\n.dock[data-position=\"top\"], .dock[data-position=\"bottom\"], .dock[data-position=\"center\"] {\n left: calc(50% - var(--_trigger-size) / 2);\n}\n.dock[data-position=\"left\"], .dock[data-position=\"right\"], .dock[data-position=\"center\"] {\n top: calc(50% - var(--_trigger-size) / 2);\n}\n\n.trigger, .hub, .node {\n all: unset;\n box-sizing: border-box;\n display: grid;\n place-items: center;\n border-radius: var(--_node-radius);\n color: var(--_fg);\n background: var(--_surface);\n border: var(--_border-width) solid var(--_border);\n box-shadow: var(--_shadow), 0 0 0 .5px var(--_outline);\n -webkit-backdrop-filter: blur(var(--_blur)) saturate(1.8);\n backdrop-filter: blur(var(--_blur)) saturate(1.8);\n cursor: pointer;\n touch-action: none;\n user-select: none;\n -webkit-user-select: none;\n -webkit-touch-callout: none;\n -webkit-tap-highlight-color: transparent;\n}\n.trigger:focus-visible, .hub:focus-visible, .node:focus-visible {\n outline: 3px solid var(--_accent);\n outline-offset: 3px;\n}\n\n.trigger, .hub { border-radius: var(--_trigger-radius); }\n.trigger {\n position: relative;\n width: 100%;\n height: 100%;\n transition: scale 220ms var(--_ease), box-shadow 220ms;\n}\n.trigger:hover { box-shadow: var(--_shadow), 0 0 0 .5px var(--_outline), 0 0 0 6px color-mix(in srgb, var(--_accent) 10%, transparent); }\n.trigger[data-pressing] { scale: .92; }\n.trigger-icon, .hub-icon {\n display: grid;\n place-items: center;\n width: var(--_icon-size);\n height: var(--_icon-size);\n pointer-events: none;\n}\n.trigger-icon[data-default] { rotate: var(--_icon-rotate, 0deg); }\n.icon-own { display: contents; }\n.trigger-icon[data-slotted] .icon-own { display: none; }\n.icon-own > svg, .icon-own > img, .hub-icon > svg, .trigger-icon ::slotted(*) { width: 100%; height: 100%; display: block; }\n.icon-own > img { object-fit: contain; }\n\n.hold {\n position: absolute;\n inset: -5px;\n width: calc(100% + 10px);\n height: calc(100% + 10px);\n rotate: -90deg;\n pointer-events: none;\n overflow: visible;\n}\n.hold circle {\n fill: none;\n stroke: var(--_accent);\n stroke-width: 2.5;\n stroke-linecap: round;\n stroke-dasharray: 1 1;\n stroke-dashoffset: 1;\n opacity: 0;\n transition: opacity 120ms, stroke-dashoffset 120ms;\n}\n.trigger[data-pressing] .hold circle {\n opacity: 1;\n stroke-dashoffset: 0;\n transition: opacity 80ms, stroke-dashoffset var(--_hold) linear;\n}\n\n/* --------------------------------------------------------------- overlay */\n\n.overlay {\n position: fixed;\n inset: 0;\n width: 100%;\n height: 100%;\n max-width: none;\n max-height: none;\n margin: 0;\n padding: 0;\n border: 0;\n background: transparent;\n color: inherit;\n overflow: hidden;\n overscroll-behavior: none;\n z-index: var(--_z);\n touch-action: none;\n}\n.overlay:not([data-state]) { display: none; }\n.overlay::backdrop { background: transparent; }\n.overlay:focus { outline: none; }\n\n.backdrop {\n position: absolute;\n inset: 0;\n background: var(--_backdrop);\n -webkit-backdrop-filter: blur(var(--_backdrop-blur)) saturate(1.2);\n backdrop-filter: blur(var(--_backdrop-blur)) saturate(1.2);\n opacity: 0;\n transition: opacity var(--_dur) var(--_ease);\n}\n.root:not([data-backdrop]) .backdrop { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }\n.overlay[data-state=\"open\"] .backdrop { opacity: 1; }\n\n.edges {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n overflow: visible;\n pointer-events: none;\n}\n.edge {\n fill: none;\n stroke: var(--_edge);\n stroke-width: var(--_edge-width);\n stroke-linecap: round;\n stroke-dasharray: 1 1;\n stroke-dashoffset: 1;\n opacity: 0;\n transition: stroke-dashoffset var(--_dur) var(--_ease) var(--_delay, 0ms), opacity 160ms var(--_delay, 0ms), stroke 160ms, stroke-width 160ms;\n}\n.edge[data-shown] { stroke-dashoffset: 0; opacity: 1; }\n.edge[data-dim] { opacity: .45; }\n.edge[data-lit] { stroke: var(--_lit, var(--_accent)); stroke-width: calc(var(--_edge-width) + .5px); }\n\n.root[data-edges=\"none\"] .edges { display: none; }\n\n.layer, .labels { position: absolute; inset: 0; pointer-events: none; }\n\n/* ----------------------------------------------------------------- nodes */\n\n.hub {\n position: absolute;\n pointer-events: auto;\n transition: scale 220ms var(--_ease);\n}\n.hub[data-active] { scale: 1.08; }\n.hub-icon { transition: rotate var(--_dur) var(--_spring), opacity 160ms; }\n.overlay:not([data-state=\"open\"]) .hub-icon { rotate: -90deg; opacity: 0; }\n\n.node {\n position: absolute;\n left: 0;\n top: 0;\n width: var(--_node-size);\n height: var(--_node-size);\n margin: calc(var(--_node-size) / -2) 0 0 calc(var(--_node-size) / -2);\n pointer-events: auto;\n scale: 1;\n --_tint: var(--_node-accent, var(--_accent));\n transition:\n translate var(--_dur) var(--_spring) var(--_delay, 0ms),\n scale var(--_dur) var(--_spring) var(--_delay, 0ms),\n opacity calc(var(--_dur) * .6) var(--_ease) var(--_delay, 0ms),\n background-color 160ms, border-color 160ms, box-shadow 160ms, color 160ms;\n}\n.node[data-state=\"dim\"] { opacity: var(--_dim-opacity); scale: var(--_dim-scale); }\n.node[data-state=\"path\"] { border-color: color-mix(in srgb, var(--_tint) 55%, transparent); color: var(--_tint); }\n.node[data-active] {\n background: var(--_surface-active);\n color: var(--_tint);\n opacity: 1;\n scale: var(--_active-scale);\n box-shadow: var(--_shadow), 0 0 0 2px var(--_tint), 0 0 0 7px color-mix(in srgb, var(--_tint) 18%, transparent);\n}\n.node[data-current] { color: var(--_tint); }\n.node[data-current]::before {\n content: \"\";\n position: absolute;\n inset: -4px;\n border-radius: inherit;\n border: 1.5px dashed color-mix(in srgb, var(--_tint) 70%, transparent);\n pointer-events: none;\n}\n.node[aria-disabled=\"true\"] { opacity: .35; cursor: not-allowed; }\n.node[data-enter], .node[data-leave] { scale: .35; opacity: 0; }\n.node[data-leave] { pointer-events: none; transition-duration: calc(var(--_dur) * .7); }\n\n/* A knob on the rim, pointing where the children will unfold. */\n.node[data-branch]::after {\n content: \"\";\n position: absolute;\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--_surface-active);\n box-shadow: 0 0 0 1.5px var(--_muted);\n translate: calc(cos(var(--_a, 0deg)) * (var(--_node-size) / 2 - 1px)) calc(sin(var(--_a, 0deg)) * (var(--_node-size) / 2 - 1px));\n transition: background-color 160ms, box-shadow 160ms;\n}\n.node[data-branch][data-current-trail]::after,\n.node[data-branch][data-state=\"path\"]::after,\n.node[data-branch][data-active]::after { background: var(--_tint); box-shadow: 0 0 0 1.5px var(--_tint); }\n.node[data-state=\"path\"]::after { opacity: 0; }\n\n.icon {\n display: grid;\n place-items: center;\n width: var(--_icon-size);\n height: var(--_icon-size);\n pointer-events: none;\n}\n.icon > svg, .icon > img { width: 100%; height: 100%; display: block; }\n.icon > img { object-fit: contain; border-radius: 4px; }\n.glyph { font-size: calc(var(--_icon-size) * .92); line-height: 1; }\n.mono { font-weight: 650; font-size: calc(var(--_icon-size) * .8); line-height: 1; letter-spacing: -.01em; }\n\n/* ---------------------------------------------------------------- labels */\n\n.label {\n position: absolute;\n left: 0;\n top: 0;\n box-sizing: border-box;\n width: max-content;\n max-width: var(--unfold-label-max-width, 160px);\n padding: 5px 10px 6px;\n border-radius: var(--_label-radius);\n background: var(--_label-bg);\n color: var(--_label-fg);\n box-shadow: 0 1px 2px rgb(0 0 0 / .06), 0 4px 14px -4px rgb(0 0 0 / .18), 0 0 0 .5px var(--_outline);\n -webkit-backdrop-filter: blur(var(--_blur));\n backdrop-filter: blur(var(--_blur));\n overflow-wrap: anywhere;\n pointer-events: none;\n opacity: 0;\n /* Labels never slide: a sliding label could cross another one on its way. */\n transition: opacity 140ms var(--_ease);\n}\n.label[data-visible] { opacity: 1; transition-delay: var(--_label-delay, 0ms), 0ms; }\n.label[data-instant] { transition: none; }\n.label .title {\n display: block;\n text-wrap: balance;\n font-family: var(--unfold-label-font, var(--unfold-font));\n font-size: var(--_label-size);\n font-weight: var(--_label-weight);\n line-height: 1.25;\n letter-spacing: var(--_label-tracking);\n text-transform: var(--_label-case);\n}\n.label[data-go] .title::after { content: \" →\"; color: var(--_muted); font-weight: 500; }\n.label .desc { display: none; margin-top: 2px; font-weight: 450; font-size: var(--_desc-size); line-height: 1.35; color: var(--_muted); }\n.label[data-active] { max-width: var(--unfold-label-max-width-active, 240px); }\n/* The wrapped variant, used where a one-line label doesn't fit. Words stay whole (hyphenated if needed). */\n.label[data-narrow] {\n max-width: var(--unfold-label-narrow-width, 96px);\n min-width: min-content;\n overflow-wrap: normal;\n hyphens: auto;\n}\n.label[data-active]:not([data-compact]) .desc { display: block; }\n.labels .measure { position: absolute; left: 0; top: 0; visibility: hidden; }\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n.safe-probe {\n position: fixed;\n inset: 0;\n visibility: hidden;\n pointer-events: none;\n padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);\n}\n\n/* Right-to-left: \"back\" points the other way. */\n:host(:dir(rtl)) .hub[data-icon=\"back\"] .hub-icon { scale: -1 1; }\n\n@media (prefers-contrast: more) {\n .root {\n --_border-width: 2px;\n --_border: currentColor;\n --_muted: var(--_fg);\n --_surface: var(--_surface-active);\n --_label-bg: var(--_surface-active);\n --_edge: color-mix(in srgb, var(--_fg) 60%, transparent);\n --_dim-opacity: 1;\n --_blur: 0px;\n }\n .label { border: 1.5px solid currentColor; }\n}\n\n@media (prefers-reduced-transparency: reduce) {\n .root { --_surface: var(--_surface-active); --_label-bg: var(--_surface-active); --_blur: 0px; --_backdrop-blur: 0px; --_dock-blur: 0px; }\n}\n\n/* Windows High Contrast and other forced palettes: states move from colour/shadow to outlines. */\n@media (forced-colors: active) {\n .trigger, .hub, .node { border: 2px solid ButtonText; }\n .node[data-active], .hub[data-active] { outline: 3px solid Highlight; outline-offset: 2px; }\n .node[data-state=\"path\"] { border-color: Highlight; }\n .node[data-state=\"dim\"] { opacity: 1; }\n .node[data-current]::before { border-color: Highlight; }\n .node[data-branch]::after { background: ButtonText; box-shadow: none; }\n .edge { stroke: CanvasText; }\n .edge[data-lit] { stroke: Highlight; }\n .label { border: 1px solid CanvasText; }\n .backdrop { background: Canvas; opacity: .9; }\n .hold circle { stroke: Highlight; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .root { --_dur: 1ms; --_spring: linear; }\n .label { transition: opacity 120ms; }\n}\n`;\n","import type { IconSource, UnfoldNavOptions, UnfoldNavStrings } from './types.js';\n\nexport const DEFAULT_STRINGS: UnfoldNavStrings = Object.freeze({\n pages: 'Pages',\n close: 'Close navigation',\n backToTop: 'Back to all pages',\n back: 'Back to {label}',\n});\n\nexport const DEFAULT_OPTIONS: UnfoldNavOptions = Object.freeze({\n pages: Object.freeze([]) as unknown as UnfoldNavOptions['pages'],\n position: 'bottom-right',\n dock: 'float',\n offset: 24,\n holdDelay: 220,\n expandDelay: 140,\n openOnTap: true,\n nodeSize: 52,\n triggerSize: 60,\n spacing: 96,\n gap: 16,\n labels: 'auto',\n edges: 'curved',\n backdrop: true,\n haptics: true,\n theme: 'auto',\n current: undefined,\n label: 'Navigation',\n arrowKeys: 'tree',\n strings: Object.freeze({}),\n triggerIcon: undefined,\n iconResolver: undefined,\n navigate: undefined,\n});\n\nexport function isIconSource(value: unknown): value is IconSource {\n return (\n typeof value === 'string' ||\n typeof value === 'function' ||\n (typeof value === 'object' && value !== null && 'cloneNode' in value && typeof value.cloneNode === 'function')\n );\n}\n\nconst enums = {\n position: [\n 'top-left',\n 'top',\n 'top-right',\n 'left',\n 'center',\n 'right',\n 'bottom-left',\n 'bottom',\n 'bottom-right',\n 'inline',\n ],\n dock: ['float', 'bar'],\n labels: ['auto', 'always', 'hover', 'none'],\n edges: ['curved', 'straight', 'step', 'none'],\n theme: ['auto', 'light', 'dark'],\n arrowKeys: ['tree', 'spatial'],\n};\n\n/** Validate before applying changes, so an invalid update leaves a working navigation intact. */\nexport function normalizeOptions(current: UnfoldNavOptions, patch: Partial<UnfoldNavOptions>): UnfoldNavOptions {\n if (!patch || typeof patch !== 'object' || Array.isArray(patch))\n throw new TypeError('[unfold-nav] Options must be an object.');\n const next = { ...current };\n for (const [key, value] of Object.entries(patch)) {\n if (!Object.hasOwn(DEFAULT_OPTIONS, key)) continue;\n const k = key as keyof UnfoldNavOptions;\n (next as unknown as Record<string, unknown>)[k] = value === undefined ? DEFAULT_OPTIONS[k] : value;\n }\n for (const [key, values] of Object.entries(enums)) {\n if (!values.includes(next[key as keyof typeof enums]))\n throw new TypeError(`[unfold-nav] Invalid ${key}. Expected ${values.join(', ')}.`);\n }\n for (const key of ['nodeSize', 'triggerSize', 'spacing', 'gap', 'holdDelay', 'expandDelay'] as const) {\n const value = next[key];\n const positive = key === 'nodeSize' || key === 'triggerSize' || key === 'spacing';\n if (typeof value !== 'number' || !Number.isFinite(value) || (positive ? value <= 0 : value < 0)) {\n throw new RangeError(`[unfold-nav] ${key} must be a finite ${positive ? 'positive' : 'non-negative'} number.`);\n }\n }\n const off = next.offset;\n const offsets = typeof off === 'number' ? [off] : off && typeof off === 'object' ? [off.x, off.y] : [];\n if (!offsets.length || offsets.some((v) => typeof v !== 'number' || !Number.isFinite(v) || v < 0)) {\n throw new RangeError('[unfold-nav] offset must be a non-negative number or { x, y }.');\n }\n for (const key of ['openOnTap', 'backdrop', 'haptics'] as const) {\n if (typeof next[key] !== 'boolean') throw new TypeError(`[unfold-nav] ${key} must be a boolean.`);\n }\n if (typeof next.label !== 'string' || !next.label.trim())\n throw new TypeError('[unfold-nav] label must be a non-empty string.');\n if (next.current != null && typeof next.current !== 'string')\n throw new TypeError('[unfold-nav] current must be a URL string, null or undefined.');\n for (const key of ['navigate', 'iconResolver'] as const) {\n if (next[key] !== undefined && typeof next[key] !== 'function')\n throw new TypeError(`[unfold-nav] ${key} must be a function.`);\n }\n if (next.triggerIcon !== undefined && !isIconSource(next.triggerIcon))\n throw new TypeError('[unfold-nav] Invalid triggerIcon.');\n if (!next.strings || typeof next.strings !== 'object' || Array.isArray(next.strings))\n throw new TypeError('[unfold-nav] strings must be an object.');\n for (const key of Object.keys(DEFAULT_STRINGS) as (keyof UnfoldNavStrings)[]) {\n if (next.strings[key] !== undefined && typeof next.strings[key] !== 'string')\n throw new TypeError(`[unfold-nav] strings.${key} must be a string.`);\n }\n next.strings = Object.fromEntries(\n Object.entries(next.strings).filter(([key, value]) => Object.hasOwn(DEFAULT_STRINGS, key) && value !== undefined),\n );\n return next;\n}\n","import type { NavPage } from './types.js';\nimport { isIconSource } from './options.js';\n\nexport interface TreeNode {\n id: string;\n page: NavPage;\n parent: TreeNode | null;\n children: TreeNode[];\n /** 0 for the (possibly virtual) root, 1 for top-level pages. */\n depth: number;\n index: number;\n}\n\nexport interface Tree {\n root: TreeNode;\n byId: Map<string, TreeNode>;\n}\n\nexport function buildTree(pages: NavPage[] | NavPage | null | undefined): Tree {\n const rootPage: NavPage = Array.isArray(pages)\n ? { label: 'Navigation', children: pages }\n : (pages ?? { label: 'Navigation', children: [] });\n\n const byId = new Map<string, TreeNode>();\n const root: TreeNode = { id: '', page: rootPage, parent: null, children: [], depth: 0, index: 0 };\n const ancestors = new WeakSet<object>();\n\n const validate = (page: NavPage, path: string) => {\n if (!page || typeof page !== 'object' || Array.isArray(page))\n throw new TypeError(`[unfold-nav] ${path} must be a page object.`);\n if (typeof page.label !== 'string' || !page.label.trim())\n throw new TypeError(`[unfold-nav] ${path}.label must be a non-empty string.`);\n for (const key of ['id', 'href', 'target', 'description', 'color'] as const) {\n if (page[key] !== undefined && typeof page[key] !== 'string')\n throw new TypeError(`[unfold-nav] ${path}.${key} must be a string.`);\n }\n if (page.children !== undefined && !Array.isArray(page.children))\n throw new TypeError(`[unfold-nav] ${path}.children must be an array.`);\n if (page.disabled !== undefined && typeof page.disabled !== 'boolean')\n throw new TypeError(`[unfold-nav] ${path}.disabled must be a boolean.`);\n if (page.icon !== undefined && !isIconSource(page.icon))\n throw new TypeError(`[unfold-nav] ${path}.icon is invalid.`);\n if (ancestors.has(page)) throw new TypeError(`[unfold-nav] ${path} contains a cyclic page tree.`);\n };\n validate(rootPage, 'pages');\n ancestors.add(rootPage);\n\n const visit = (node: TreeNode, kids: NavPage[] | undefined, trail: number[]) => {\n (kids ?? []).forEach((page, index) => {\n const path = [...trail, index];\n validate(page, `pages[${path.join('].children[')}]`);\n let id = page.id != null && page.id !== '' ? String(page.id) : `n${path.join('.')}`;\n if (byId.has(id)) {\n let n = 2;\n while (byId.has(`${id}~${n}`)) n++;\n id = `${id}~${n}`;\n }\n const child: TreeNode = { id, page, parent: node, children: [], depth: node.depth + 1, index };\n byId.set(id, child);\n node.children.push(child);\n ancestors.add(page);\n visit(child, page.children, path);\n ancestors.delete(page);\n });\n };\n visit(root, rootPage.children, []);\n return { root, byId };\n}\n\n/** Ids from the top level down to `node` (inclusive). Empty for the root. */\nexport function pathTo(node: TreeNode | null | undefined): string[] {\n const ids: string[] = [];\n for (let n = node; n && n.depth > 0; n = n.parent) ids.unshift(n.id);\n return ids;\n}\n\nconst normalizePath = (pathname: string) => (pathname.length > 1 ? pathname.replace(/\\/+$/, '') : pathname);\n\n/**\n * The page matching `currentUrl`: an exact path (+ optional query/hash) match wins, otherwise the deepest page whose\n * path is a prefix of the current one (`/blog` for `/blog/some-post`). The site root `/` only matches exactly.\n */\nexport function findCurrent(tree: Tree, currentUrl: string, base: string): TreeNode | null {\n let current: URL;\n try {\n current = new URL(currentUrl, base);\n } catch {\n return null;\n }\n const curPath = normalizePath(current.pathname);\n let exact: TreeNode | null = null;\n let exactScore = -1;\n let prefix: TreeNode | null = null;\n let prefixLen = -1;\n\n for (const node of tree.byId.values()) {\n const href = node.page.href;\n if (!href) continue;\n let url: URL;\n try {\n url = new URL(href, base);\n } catch {\n continue;\n }\n if (url.origin !== current.origin) continue;\n if (url.search && url.search !== current.search) continue;\n if (url.hash && url.hash !== current.hash) continue;\n const path = normalizePath(url.pathname);\n if (path === curPath) {\n const score = (url.search ? 1 : 0) + (url.hash ? 1 : 0);\n if (!exact || score > exactScore || (score === exactScore && node.depth > exact.depth)) {\n exact = node;\n exactScore = score;\n }\n } else if (path !== '/' && curPath.startsWith(path + '/') && path.length > prefixLen) {\n prefix = node;\n prefixLen = path.length;\n }\n }\n return exact ?? prefix;\n}\n","type Edge = 'top' | 'right' | 'bottom' | 'left';\nconst edges: Edge[] = ['top', 'right', 'bottom', 'left'];\nconst documents = new WeakMap<\n Document,\n {\n owners: Map<object, { edge: Edge; size: number }>;\n previous: Map<Edge, { value: string; priority: string }>;\n }\n>();\n\n/** Multiple navigations share each edge; removing one restores the remaining inset or the host's value. */\nexport function updateInsets(owner: object, doc: Document, edge: Edge | null, size = 0): void {\n let registry = documents.get(doc);\n if (!registry && !edge) return;\n if (!registry) {\n registry = { owners: new Map(), previous: new Map() };\n documents.set(doc, registry);\n }\n if (edge) registry.owners.set(owner, { edge, size });\n else registry.owners.delete(owner);\n const style = doc.documentElement.style;\n for (const e of edges) {\n const name = `--unfold-inset-${e}`;\n const sizes = [...registry.owners.values()].filter((entry) => entry.edge === e).map((entry) => entry.size);\n if (sizes.length) {\n if (!registry.previous.has(e))\n registry.previous.set(e, { value: style.getPropertyValue(name), priority: style.getPropertyPriority(name) });\n style.setProperty(name, `calc(${Math.max(...sizes)}px + env(safe-area-inset-${e}, 0px))`);\n } else {\n const previous = registry.previous.get(e);\n if (previous) {\n if (previous.value) style.setProperty(name, previous.value, previous.priority);\n else style.removeProperty(name);\n registry.previous.delete(e);\n }\n }\n }\n if (!registry.owners.size) documents.delete(doc);\n}\n","/** Default browser navigation allows web links and common contact protocols. Custom routers own their URLs. */\nexport function navigationUrl(href: string, base: string): string | null {\n try {\n const url = new URL(href, base);\n return ['http:', 'https:', 'mailto:', 'tel:', 'sms:'].includes(url.protocol) ? url.href : null;\n } catch {\n return null;\n }\n}\n","import { BACK_ICON, CLOSE_ICON, GRAPH_ICON, monogram, renderIcon } from './icons.js';\nimport {\n hitTest,\n layoutGraph,\n placeLabel,\n rectContains,\n rectsTouch,\n edgeShape,\n type Circle,\n type Fan,\n type LabelContext,\n type Level,\n type PlacedNode,\n type Rect,\n type Size,\n type Sizes,\n type Vec,\n} from './layout.js';\nimport { STYLES } from './styles.js';\nimport { buildTree, findCurrent, pathTo, type Tree, type TreeNode } from './tree.js';\nimport type { NavPage, SelectDetail, UnfoldNavOptions, UnfoldNavStrings } from './types.js';\n\nimport { DEFAULT_OPTIONS, DEFAULT_STRINGS, normalizeOptions } from './options.js';\nimport { updateInsets } from './insets.js';\nimport { navigationUrl } from './navigation.js';\nexport { DEFAULT_OPTIONS, DEFAULT_STRINGS } from './options.js';\n\ntype OptionKey = keyof UnfoldNavOptions;\nconst OPTION_KEYS = Object.keys(DEFAULT_OPTIONS) as OptionKey[];\n\nconst ATTRIBUTES: Record<string, OptionKey> = {\n pages: 'pages',\n position: 'position',\n dock: 'dock',\n offset: 'offset',\n 'hold-delay': 'holdDelay',\n 'expand-delay': 'expandDelay',\n 'open-on-tap': 'openOnTap',\n 'node-size': 'nodeSize',\n 'trigger-size': 'triggerSize',\n spacing: 'spacing',\n gap: 'gap',\n labels: 'labels',\n edges: 'edges',\n backdrop: 'backdrop',\n haptics: 'haptics',\n theme: 'theme',\n current: 'current',\n label: 'label',\n 'arrow-keys': 'arrowKeys',\n 'trigger-icon': 'triggerIcon',\n};\n\nfunction parseAttribute(key: OptionKey, value: string | null): unknown {\n if (value === null) return DEFAULT_OPTIONS[key];\n if (key === 'offset') {\n const [x, y = x] = value\n .trim()\n .split(/[\\s,]+/)\n .map(Number);\n return { x, y };\n }\n if (key === 'pages') {\n return JSON.parse(value);\n }\n switch (typeof DEFAULT_OPTIONS[key]) {\n case 'number': {\n const n = Number(value);\n return n;\n }\n case 'boolean':\n return !/^(false|0|off|no)$/i.test(value.trim());\n }\n return value;\n}\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\nconst LEVEL_SEP = '\\u001f';\nconst INSET_EDGES = ['top', 'right', 'bottom', 'left'] as const;\nconst SUPPORTS_POPOVER = typeof HTMLElement !== 'undefined' && 'showPopover' in HTMLElement.prototype;\nconst Base: typeof HTMLElement =\n typeof HTMLElement === 'undefined' ? (class {} as unknown as typeof HTMLElement) : HTMLElement;\n\nconst ARROWS: Record<string, Vec> = {\n ArrowUp: { x: 0, y: -1 },\n ArrowDown: { x: 0, y: 1 },\n ArrowLeft: { x: -1, y: 0 },\n ArrowRight: { x: 1, y: 0 },\n};\n\nfunction toggleAttr(el: Element, name: string, on: boolean, value = '') {\n if (on) el.setAttribute(name, value);\n else el.removeAttribute(name);\n}\n\n/** `part=\"node node-active node-current\"`: states as part names, since `::part()` can't match attributes. */\nfunction setParts(el: Element, base: string, states: Record<string, boolean>) {\n const parts = [base];\n for (const [state, on] of Object.entries(states)) if (on) parts.push(`${base}-${state}`);\n const value = parts.join(' ');\n if (el.getAttribute('part') !== value) el.setAttribute('part', value);\n}\n\ninterface View {\n tree: TreeNode;\n node: HTMLButtonElement;\n label: HTMLDivElement;\n edge: SVGPathElement;\n /** Where the node grows from / folds back to. */\n from: Vec;\n leaveTimer: number;\n /** Where the label is shown, if it is. */\n shownAt: Rect | null;\n}\n\ntype Via = SelectDetail['via'];\ntype FocusMode = 'keyboard' | 'pointer' | 'none';\n\nexport interface UnfoldNav extends UnfoldNavOptions {}\n\n/**\n * `<unfold-nav>`: press and hold the button, the site map unfolds around it as a graph. Drag along the\n * graph and release on a page to go there, or tap to open it and tap your way through.\n *\n * While open for tapping or the keyboard it is a modal dialog: the rest of the page is inert, focus moves\n * into a tree of pages (standard tree keys), and returns to the button when it closes.\n *\n * Events (all bubble and cross shadow boundaries):\n * - `unfold-select` (cancelable) `detail: SelectDetail`: call `preventDefault()` to handle navigation yourself\n * - `unfold-open` `detail: { mode: 'drag' | 'tap' }`\n * - `unfold-close`\n * - `unfold-highlight` `detail: { page: NavPage | null }`\n */\nexport class UnfoldNav extends Base {\n static get observedAttributes() {\n return Object.keys(ATTRIBUTES);\n }\n\n private opts: UnfoldNavOptions = { ...DEFAULT_OPTIONS };\n private text: UnfoldNavStrings = DEFAULT_STRINGS;\n private tree: Tree = buildTree([]);\n private currentId: string | null = null;\n private currentTrail = new Set<string>();\n\n private state: 'closed' | 'open' | 'closing' = 'closed';\n private mode: 'drag' | 'tap' = 'tap';\n private path: string[] = [];\n private active: string | null = null;\n private focusId: string | null = null;\n private views = new Map<string, View>();\n private placed = new Map<string, PlacedNode>();\n private fanCache = new Map<string, Fan>();\n private labelSizes = new Map<string, Size>();\n /** Open branches with a page show a \"→\" hint: their label is measured with it. */\n private branchLabelSizes = new Map<string, Size>();\n /** Wrapped (narrower, taller) variants, for labels wider than the narrow width. Same keys as above. */\n private narrowSizes = new Map<string, Size>();\n private narrowBranchSizes = new Map<string, Size>();\n private hub: Circle = { x: 0, y: 0, r: 30 };\n private bounds: Rect = { x: 0, y: 0, w: 0, h: 0 };\n private animationTimers = new Set<number>();\n\n private pointerId: number | null = null;\n private pointerType = 'mouse';\n private downAt: Vec = { x: 0, y: 0 };\n private lastPoint: Vec = { x: 0, y: 0 };\n private leftHub = false;\n private holdTimer = 0;\n private dwellTimer = 0;\n private dwellTarget: string | null = null;\n private closeTimer = 0;\n private resizeFrame = 0;\n private openedAt = 0;\n private lastPointerUp = -Infinity;\n private typeahead = { text: '', at: 0 };\n private lastKeyActivation = -Infinity;\n\n private readonly els: {\n root: HTMLDivElement;\n dockBar: HTMLDivElement;\n dock: HTMLDivElement;\n trigger: HTMLButtonElement;\n triggerIcon: HTMLSpanElement;\n iconSlot: HTMLSlotElement;\n iconOwn: HTMLSpanElement;\n overlay: HTMLDialogElement;\n edges: SVGSVGElement;\n layer: HTMLDivElement;\n labels: HTMLDivElement;\n measure: HTMLDivElement;\n hub: HTMLButtonElement;\n hubIcon: HTMLSpanElement;\n probe: HTMLDivElement;\n };\n\n constructor() {\n if (typeof document === 'undefined')\n throw new Error('[unfold-nav] Create navigation elements in a browser after mounting.');\n super();\n const shadow = this.attachShadow({ mode: 'open' });\n shadow.innerHTML = `<style>${STYLES}</style>\n<div class=\"root\" part=\"root\">\n <div class=\"dock-bar\" part=\"dock-bar\" aria-hidden=\"true\"></div>\n <div class=\"dock\" part=\"dock\">\n <button class=\"trigger\" part=\"trigger\" type=\"button\" aria-haspopup=\"dialog\" aria-expanded=\"false\" aria-controls=\"graph\">\n <svg class=\"hold\" viewBox=\"0 0 100 100\" aria-hidden=\"true\"><circle cx=\"50\" cy=\"50\" r=\"47\" pathLength=\"1\"/></svg>\n <span class=\"trigger-icon\" part=\"trigger-icon\" aria-hidden=\"true\"><slot name=\"icon\"></slot><span class=\"icon-own\"></span></span>\n </button>\n </div>\n <dialog class=\"overlay\" part=\"overlay\" id=\"graph\">\n <div class=\"backdrop\" part=\"backdrop\" aria-hidden=\"true\"></div>\n <svg class=\"edges\" part=\"edges\" aria-hidden=\"true\"></svg>\n <div class=\"layer\" role=\"tree\"></div>\n <div class=\"labels\" aria-hidden=\"true\"><div class=\"measure\"></div></div>\n <button class=\"hub\" part=\"hub\" type=\"button\"><span class=\"hub-icon\" aria-hidden=\"true\"></span></button>\n </dialog>\n <div class=\"safe-probe\" aria-hidden=\"true\"></div>\n</div>`;\n const $ = <T extends Element>(sel: string) => shadow.querySelector(sel) as T;\n this.els = {\n root: $('.root'),\n dockBar: $('.dock-bar'),\n dock: $('.dock'),\n trigger: $('.trigger'),\n triggerIcon: $('.trigger-icon'),\n iconSlot: $('slot[name=\"icon\"]'),\n iconOwn: $('.icon-own'),\n overlay: $('.overlay'),\n edges: $('.edges'),\n layer: $('.layer'),\n labels: $('.labels'),\n measure: $('.measure'),\n hub: $('.hub'),\n hubIcon: $('.hub-icon'),\n probe: $('.safe-probe'),\n };\n // Drag mode shows the dialog as a (non-modal) top-layer popover; tapping and keyboard use showModal().\n if (SUPPORTS_POPOVER) this.els.overlay.setAttribute('popover', 'manual');\n // Only toggles attributes: touching the slot's own children would fire slotchange again.\n this.els.iconSlot.addEventListener('slotchange', () => this.syncSlotted());\n\n const { trigger, overlay } = this.els;\n trigger.addEventListener('pointerdown', this.onPointerDown);\n trigger.addEventListener('pointermove', this.onPointerMove);\n trigger.addEventListener('pointerup', this.onPointerUp);\n trigger.addEventListener('pointercancel', this.onPointerCancel);\n trigger.addEventListener('lostpointercapture', this.onLostCapture);\n trigger.addEventListener('click', this.onTriggerClick);\n trigger.addEventListener('keydown', this.onTriggerKey);\n trigger.addEventListener('contextmenu', (e) => e.preventDefault());\n overlay.addEventListener('click', this.onOverlayClick);\n overlay.addEventListener('pointermove', this.onOverlayHover);\n overlay.addEventListener('keydown', this.onOverlayKey);\n overlay.addEventListener('cancel', this.onCancel);\n overlay.addEventListener('close', this.onDialogClose);\n overlay.addEventListener('wheel', (e) => e.preventDefault(), { passive: false });\n overlay.addEventListener('touchmove', (e) => e.preventDefault(), { passive: false });\n overlay.addEventListener('contextmenu', (e) => e.preventDefault());\n this.applyOptions();\n }\n\n /* -------------------------------------------------------------- public API */\n\n /** Update several options at once. */\n configure(options: Partial<UnfoldNavOptions>): this {\n const next = normalizeOptions(this.opts, options);\n const pagesChanged = Object.hasOwn(options, 'pages');\n const tree = pagesChanged ? buildTree(next.pages) : this.tree;\n this.opts = next;\n this.tree = tree;\n if (pagesChanged && this.state !== 'closed') {\n const wasOpen = this.state === 'open';\n const hadFocus = this.focusInside();\n this.finishClose();\n if (hadFocus && this.isConnected) this.els.trigger.focus({ preventScroll: true });\n if (wasOpen) this.emit('unfold-close');\n }\n this.fanCache.clear();\n this.clearLabelSizes();\n this.applyOptions();\n if (this.state === 'open') {\n this.measure();\n this.render();\n }\n return this;\n }\n\n get isOpen(): boolean {\n return this.state === 'open';\n }\n\n /** Open for tapping. With `focus`, the first page shows keyboard focus. */\n open({ focus = false }: { focus?: boolean } = {}): void {\n this.show('tap', focus ? 'keyboard' : 'pointer');\n }\n\n close({ focusTrigger = false }: { focusTrigger?: boolean } = {}): void {\n if (this.state !== 'open') return;\n const hadFocus = this.focusInside();\n this.state = 'closing';\n window.clearTimeout(this.holdTimer);\n window.clearTimeout(this.dwellTimer);\n this.holdTimer = this.dwellTimer = 0;\n this.dwellTarget = null;\n this.pointerId = null;\n window.removeEventListener('keydown', this.onWindowKey, true);\n\n const { overlay, trigger, hub } = this.els;\n overlay.dataset.state = 'closing';\n overlay.setAttribute('aria-hidden', 'true');\n hub.tabIndex = -1;\n // Leave the modal state right away, so the page and the button are usable during the exit animation.\n if (overlay.open) {\n overlay.close();\n if (SUPPORTS_POPOVER) {\n try {\n overlay.showPopover();\n } catch {\n /* already showing */\n }\n }\n }\n trigger.setAttribute('aria-expanded', 'false');\n\n const views = [...this.views.values()].filter((v) => !v.leaveTimer).reverse();\n const stagger = this.reducedMotion ? 0 : Math.min(12, 120 / Math.max(1, views.length));\n views.forEach((v, i) => this.leave(v, this.hub, i * stagger));\n this.closeTimer = window.setTimeout(() => this.finishClose(), this.duration + views.length * stagger + 60);\n\n if (focusTrigger || hadFocus) trigger.focus({ preventScroll: true });\n this.emit('unfold-close');\n }\n\n toggle(): void {\n if (this.state === 'open') this.close();\n else this.open();\n }\n\n /* --------------------------------------------------------------- lifecycle */\n\n connectedCallback() {\n for (const key of OPTION_KEYS) this.upgradeProperty(key);\n if (!this.tree.root.children.length) {\n const script = this.querySelector('script[type=\"application/json\"]');\n if (script?.textContent?.trim()) {\n try {\n this.configure({ pages: JSON.parse(script.textContent) });\n } catch (error) {\n console.warn('[unfold-nav] Invalid inline pages:', error);\n }\n }\n }\n window.addEventListener('resize', this.onResize);\n document.fonts?.addEventListener('loadingdone', this.onFontsLoaded);\n this.publishInsets();\n this.onResize();\n }\n\n disconnectedCallback() {\n window.removeEventListener('resize', this.onResize);\n window.removeEventListener('keydown', this.onWindowKey, true);\n document.fonts?.removeEventListener('loadingdone', this.onFontsLoaded);\n window.clearTimeout(this.holdTimer);\n window.clearTimeout(this.dwellTimer);\n this.holdTimer = this.dwellTimer = 0;\n this.pointerId = null;\n this.els.trigger.removeAttribute('data-pressing');\n cancelAnimationFrame(this.resizeFrame);\n this.resizeFrame = 0;\n this.finishClose();\n this.publishInsets();\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, value: string | null) {\n if (oldValue === value) return;\n const key = ATTRIBUTES[name];\n if (!key) return;\n try {\n this.configure({ [key]: parseAttribute(key, value) });\n } catch (error) {\n console.warn(`[unfold-nav] Ignoring invalid ${name} attribute:`, error);\n }\n }\n\n /** Properties set before the element was defined shadow the accessors; re-apply them. */\n private upgradeProperty(key: OptionKey) {\n if (Object.prototype.hasOwnProperty.call(this, key)) {\n const value = (this as unknown as Record<string, unknown>)[key];\n delete (this as unknown as Record<string, unknown>)[key];\n this.configure({ [key]: value });\n }\n }\n\n private applyOptions() {\n const o = this.opts;\n const { root, dock, dockBar, trigger, layer, overlay } = this.els;\n this.text = { ...DEFAULT_STRINGS, ...o.strings };\n root.dataset.theme = o.theme;\n root.dataset.edges = o.edges;\n root.dataset.dock = o.dock;\n toggleAttr(root, 'data-backdrop', o.backdrop);\n dock.dataset.position = o.position;\n const edge = this.dockEdge();\n toggleAttr(dockBar, 'data-edge', !!edge, edge ?? '');\n const off = this.offsets;\n root.style.setProperty('--_offset-x', `${off.x}px`);\n root.style.setProperty('--_offset-y', `${off.y}px`);\n root.style.setProperty('--_trigger-size', `${o.triggerSize}px`);\n root.style.setProperty('--_node-size', `${o.nodeSize}px`);\n root.style.setProperty('--_hold', `${o.holdDelay}ms`);\n trigger.setAttribute('aria-label', o.label);\n overlay.setAttribute('aria-label', o.label);\n layer.setAttribute('aria-label', this.text.pages);\n\n this.syncIcon();\n this.publishInsets();\n }\n\n private get offsets(): Vec {\n const o = this.opts.offset;\n return typeof o === 'number' ? { x: o, y: o } : o;\n }\n\n /** The screen edge the button is docked to, if any. */\n private dockEdge(): (typeof INSET_EDGES)[number] | null {\n const p = this.opts.position;\n if (p === 'center' || p === 'inline') return null;\n if (p.startsWith('top')) return 'top';\n if (p.startsWith('bottom')) return 'bottom';\n return p as 'left' | 'right';\n }\n\n /**\n * Publishes the space the button takes as `--unfold-inset-{top,right,bottom,left}` on `<html>`, so a\n * page can keep its content clear: `body { padding-bottom: var(--unfold-inset-bottom, 0px) }`.\n */\n private publishInsets() {\n const edge = this.isConnected ? this.dockEdge() : null;\n const off = this.offsets;\n const thickness = this.opts.triggerSize + 2 * (edge === 'top' || edge === 'bottom' ? off.y : off.x);\n updateInsets(this, this.ownerDocument, edge, thickness);\n }\n\n private syncIcon() {\n const o = this.opts;\n const custom = renderIcon(o.triggerIcon ?? this.tree.root.page.icon, o.iconResolver);\n this.els.iconOwn.replaceChildren(custom ?? renderIcon(GRAPH_ICON, undefined)!);\n this.els.iconOwn.toggleAttribute('data-custom', !!custom);\n this.syncSlotted();\n }\n\n private syncSlotted() {\n const slotted = this.els.iconSlot.assignedNodes().length > 0;\n toggleAttr(this.els.triggerIcon, 'data-slotted', slotted);\n toggleAttr(this.els.triggerIcon, 'data-default', !slotted && !this.els.iconOwn.hasAttribute('data-custom'));\n if (this.isConnected) this.orientIcon();\n }\n\n /* --------------------------------------------------------- open & close */\n\n private show(mode: 'drag' | 'tap', focus: FocusMode) {\n if (this.state === 'open' || !this.isConnected) return;\n window.clearTimeout(this.closeTimer);\n this.state = 'open';\n this.mode = mode;\n this.path = [];\n this.active = null;\n this.focusId = null;\n this.dwellTarget = null;\n this.computeCurrent();\n\n const { overlay, trigger, hub } = this.els;\n overlay.dataset.state = 'open';\n overlay.dataset.mode = mode;\n overlay.removeAttribute('aria-hidden');\n hub.tabIndex = 0;\n this.present(mode === 'tap');\n trigger.setAttribute('aria-expanded', 'true');\n this.openedAt = performance.now();\n this.measure();\n this.render();\n this.haptic(10);\n if (mode === 'drag') window.addEventListener('keydown', this.onWindowKey, true);\n this.emit('unfold-open', { mode });\n\n if (mode === 'tap' && focus !== 'none') {\n const first = this.initialFocusId();\n if (first) this.focusNode(first, focus === 'keyboard');\n }\n }\n\n /** Modal (tap/keyboard) or a non-modal top-layer popover (drag, where the button keeps the pointer). */\n private present(modal: boolean) {\n const ov = this.els.overlay;\n try {\n if (modal) {\n if (SUPPORTS_POPOVER && ov.matches(':popover-open')) ov.hidePopover();\n if (!ov.open) ov.showModal();\n } else if (!ov.open && !(SUPPORTS_POPOVER && ov.matches(':popover-open'))) {\n if (SUPPORTS_POPOVER) ov.showPopover();\n else ov.show();\n }\n } catch {\n /* already in that state */\n }\n }\n\n private finishClose() {\n window.clearTimeout(this.closeTimer);\n this.state = 'closed';\n window.removeEventListener('keydown', this.onWindowKey, true);\n window.clearTimeout(this.holdTimer);\n window.clearTimeout(this.dwellTimer);\n this.holdTimer = this.dwellTimer = 0;\n this.dwellTarget = null;\n this.pointerId = null;\n this.els.trigger.removeAttribute('data-pressing');\n for (const timer of this.animationTimers) window.clearTimeout(timer);\n this.animationTimers.clear();\n for (const v of this.views.values()) {\n window.clearTimeout(v.leaveTimer);\n v.node.remove();\n v.label.remove();\n v.edge.remove();\n }\n this.views.clear();\n this.placed.clear();\n const { overlay } = this.els;\n try {\n if (overlay.open) overlay.close();\n if (SUPPORTS_POPOVER && overlay.matches(':popover-open')) overlay.hidePopover();\n } catch {\n /* not open */\n }\n overlay.removeAttribute('data-state');\n overlay.removeAttribute('aria-hidden');\n this.els.trigger.setAttribute('aria-expanded', 'false');\n }\n\n /** Escape, or the Android back gesture, on the modal dialog. */\n private onCancel = (e: Event) => {\n e.preventDefault();\n if (this.state !== 'open') return;\n if (this.path.length) this.goUp(true);\n else this.close({ focusTrigger: true });\n };\n\n /** The browser closed the dialog by itself (a close request without user activation). */\n private onDialogClose = () => {\n if (\n this.state === 'open' &&\n !this.els.overlay.open &&\n !(SUPPORTS_POPOVER && this.els.overlay.matches(':popover-open'))\n ) {\n this.finishClose();\n this.emit('unfold-close');\n this.els.trigger.focus({ preventScroll: true });\n }\n };\n\n /** Escape cancels a drag (the pointer is held, so focus is wherever it was). */\n private onWindowKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && this.state === 'open' && this.mode === 'drag') {\n e.preventDefault();\n this.close();\n }\n };\n\n private focusInside(): boolean {\n const active = this.shadowRoot?.activeElement;\n return !!active && this.els.overlay.contains(active);\n }\n\n private computeCurrent() {\n const cur = this.opts.current === undefined ? location.href : this.opts.current;\n const node = cur ? findCurrent(this.tree, cur, location.href) : null;\n this.currentId = node?.id ?? null;\n this.currentTrail = new Set(pathTo(node));\n }\n\n private initialFocusId(): string | null {\n const trail = this.currentId ? pathTo(this.tree.byId.get(this.currentId)) : [];\n return trail[0] ?? this.tree.root.children[0]?.id ?? null;\n }\n\n /** Reads the button position, the viewport and safe-area insets. */\n private measure() {\n const { trigger, hub, probe, overlay } = this.els;\n const rect = trigger.getBoundingClientRect();\n const r = trigger.offsetWidth / 2;\n const next = { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2, r };\n if (next.x !== this.hub.x || next.y !== this.hub.y || next.r !== this.hub.r) this.fanCache.clear();\n this.hub = next;\n Object.assign(hub.style, {\n left: `${next.x - r}px`,\n top: `${next.y - r}px`,\n width: `${r * 2}px`,\n height: `${r * 2}px`,\n });\n\n const view = overlay.getBoundingClientRect();\n const w = view.width || document.documentElement.clientWidth;\n const h = view.height || window.innerHeight;\n const cs = getComputedStyle(probe);\n const inset = {\n t: parseFloat(cs.paddingTop) || 0,\n r: parseFloat(cs.paddingRight) || 0,\n b: parseFloat(cs.paddingBottom) || 0,\n l: parseFloat(cs.paddingLeft) || 0,\n };\n const pad = 8;\n const bounds = {\n x: inset.l + pad,\n y: inset.t + pad,\n w: w - inset.l - inset.r - pad * 2,\n h: h - inset.t - inset.b - pad * 2,\n };\n if (bounds.w !== this.bounds.w || bounds.h !== this.bounds.h) this.fanCache.clear();\n this.bounds = bounds;\n }\n\n /** Points the default glyph towards where the graph will open. */\n private orientIcon() {\n const rect = this.els.trigger.getBoundingClientRect();\n const cx = rect.left + rect.width / 2;\n const cy = rect.top + rect.height / 2;\n const dx = document.documentElement.clientWidth / 2 - cx;\n const dy = window.innerHeight / 2 - cy;\n const deg = Math.hypot(dx, dy) < 2 ? 0 : (Math.atan2(dy, dx) * 180) / Math.PI + 90;\n this.els.root.style.setProperty('--_icon-rotate', `${deg.toFixed(1)}deg`);\n }\n\n private onResize = () => {\n cancelAnimationFrame(this.resizeFrame);\n this.resizeFrame = requestAnimationFrame(() => {\n this.resizeFrame = 0;\n if (!this.isConnected) return;\n this.orientIcon();\n if (this.state === 'open') {\n this.measure();\n this.render();\n }\n });\n };\n\n private clearLabelSizes() {\n for (const m of [this.labelSizes, this.branchLabelSizes, this.narrowSizes, this.narrowBranchSizes]) m.clear();\n }\n\n /** Web fonts change label sizes: measure again and re-plan. */\n private onFontsLoaded = () => {\n this.clearLabelSizes();\n this.fanCache.clear();\n if (this.state === 'open') this.render();\n };\n\n /* ------------------------------------------------------------- rendering */\n\n private render() {\n if (this.state !== 'open') return;\n const { root, byId } = this.tree;\n const r = this.opts.nodeSize / 2;\n\n const levels: Level[] = [{ key: '', parentId: null, childIds: root.children.map((c) => c.id) }];\n const path: string[] = [];\n for (const id of this.path) {\n const tn = byId.get(id);\n if (!tn || !tn.children.length || (tn.parent?.id ?? '') !== (path[path.length - 1] ?? '')) break;\n path.push(id);\n levels.push({ key: path.join(LEVEL_SEP), parentId: id, childIds: tn.children.map((c) => c.id) });\n }\n this.path = path;\n const onPath = new Set(path);\n const frontier = levels[levels.length - 1].parentId ?? '';\n\n const withLabels = this.opts.labels !== 'none';\n if (withLabels) this.measureLabels(levels.flatMap((l) => l.childIds));\n this.placed = layoutGraph(\n {\n hub: this.hub,\n bounds: this.bounds,\n levels,\n nodeRadius: r,\n distance: this.opts.spacing,\n gap: this.opts.gap,\n edgeStyle: this.opts.edges,\n labelSize: withLabels ? (id) => this.sizesOf(id, false) : undefined,\n branchLabelSize: withLabels ? (id) => this.sizesOf(id, true) : undefined,\n labelPad: this.labelPad,\n },\n this.fanCache,\n );\n\n for (const view of this.views.values()) {\n if (!this.placed.has(view.tree.id) && !view.leaveTimer) this.leave(view, view.from, 0);\n }\n\n const tabStop = this.focusId && this.placed.has(this.focusId) ? this.focusId : this.initialFocusId();\n const entering: View[] = [];\n for (const level of levels) {\n const parentView = level.parentId ? this.views.get(level.parentId) : null;\n let insertAfter: Element | null = parentView?.node ?? null;\n for (const id of level.childIds) {\n const pl = this.placed.get(id)!;\n let view = this.views.get(id);\n if (!view) {\n view = this.createView(byId.get(id)!, pl);\n this.views.set(id, view);\n if (insertAfter) insertAfter.after(view.node);\n else this.els.layer.append(view.node);\n entering.push(view);\n } else if (view.leaveTimer) {\n window.clearTimeout(view.leaveTimer);\n view.leaveTimer = 0;\n view.node.removeAttribute('data-leave');\n view.edge.setAttribute('data-shown', '');\n }\n insertAfter = view.node;\n view.from = pl.from;\n\n const { node, edge, tree: tn } = view;\n const state = onPath.has(id) ? 'path' : (tn.parent?.id ?? '') === frontier ? 'frontier' : 'dim';\n node.dataset.state = state;\n toggleAttr(node, 'data-active', id === this.active);\n toggleAttr(node, 'data-current', id === this.currentId);\n toggleAttr(node, 'data-current-trail', this.currentTrail.has(id) && id !== this.currentId);\n if (id === this.currentId) node.setAttribute('aria-current', 'page');\n else node.removeAttribute('aria-current');\n if (tn.children.length) node.setAttribute('aria-expanded', String(onPath.has(id)));\n node.tabIndex = id === tabStop ? 0 : -1;\n node.style.setProperty('--_a', `${pl.angle.toFixed(4)}rad`);\n if (!entering.includes(view)) node.style.translate = `${pl.x}px ${pl.y}px`;\n\n setParts(node, 'node', {\n active: id === this.active,\n current: id === this.currentId,\n trail: this.currentTrail.has(id) && id !== this.currentId,\n path: state === 'path',\n frontier: state === 'frontier',\n dim: state === 'dim',\n branch: tn.children.length > 0,\n disabled: !!tn.page.disabled,\n });\n\n const parent = level.parentId == null ? this.hub : { ...this.placed.get(level.parentId)!, r };\n const lit = onPath.has(id) || id === this.active;\n const dimEdge = state === 'dim' && id !== this.active;\n edge.setAttribute('d', edgeShape(parent, { x: pl.x, y: pl.y, r }, this.opts.edges, pl.parentAngle).d);\n toggleAttr(edge, 'data-lit', lit);\n toggleAttr(edge, 'data-dim', dimEdge);\n setParts(edge, 'edge', { lit, dim: dimEdge });\n }\n }\n\n if (entering.length) this.animateIn(entering);\n this.renderLabels();\n\n const hub = this.els.hub;\n const icon = path.length ? 'back' : 'close';\n if (hub.dataset.icon !== icon) {\n hub.dataset.icon = icon;\n this.els.hubIcon.innerHTML = path.length ? BACK_ICON : CLOSE_ICON;\n }\n const backTo = path.length > 1 ? byId.get(path[path.length - 2])!.page.label : null;\n hub.setAttribute(\n 'aria-label',\n !path.length ? this.text.close : backTo ? this.text.back.replace('{label}', backTo) : this.text.backToTop,\n );\n toggleAttr(hub, 'data-active', this.mode === 'drag' && this.dwellTarget === 'hub');\n setParts(hub, 'hub', { back: path.length > 0, active: hub.hasAttribute('data-active') });\n }\n\n /** Clearance between node rims and labels: room for the hover growth (`--unfold-active-scale`) and halo. */\n private get labelPad(): number {\n const scale = parseFloat(getComputedStyle(this.els.root).getPropertyValue('--_active-scale')) || 1.14;\n return (this.opts.nodeSize / 2) * Math.max(0, scale - 1) + 8;\n }\n\n private buildLabel(tn: TreeNode): HTMLDivElement {\n const label = document.createElement('div');\n label.className = 'label';\n label.setAttribute('part', 'label');\n const title = document.createElement('span');\n title.className = 'title';\n title.textContent = tn.page.label;\n label.append(title);\n if (tn.page.description) {\n const desc = document.createElement('span');\n desc.className = 'desc';\n desc.textContent = tn.page.description;\n label.append(desc);\n }\n return label;\n }\n\n /** Size variants of a label (one line first, then wrapped), at rest or as an open branch. */\n private sizesOf(id: string, open: boolean): Sizes | null {\n const wide = (open ? this.branchLabelSizes.get(id) : null) ?? this.labelSizes.get(id);\n if (!wide) return null;\n const narrow = (open ? this.narrowBranchSizes.get(id) : null) ?? this.narrowSizes.get(id);\n return narrow ? [wide, narrow] : wide;\n }\n\n /** Measures the resting size of labels not measured yet, in one batch (one layout). */\n private measureLabels(ids: string[]) {\n const missing = ids.filter((id) => !this.labelSizes.has(id));\n if (!missing.length) return;\n const box = this.els.measure;\n // Every label at rest; open branches with their \"→\"; and each of those wrapped narrow.\n const variantsOf = (tn: TreeNode) => (tn.children.length && tn.page.href ? [false, true] : [false]);\n const els = missing.flatMap((id) => {\n const tn = this.tree.byId.get(id)!;\n return variantsOf(tn).flatMap((go) =>\n [false, true].map((narrow) => {\n const el = this.buildLabel(tn);\n toggleAttr(el, 'data-go', go);\n toggleAttr(el, 'data-narrow', narrow);\n box.append(el);\n return { id, el, go, narrow };\n }),\n );\n });\n const size = (el: HTMLElement): Size => ({ w: Math.ceil(el.offsetWidth) + 1, h: Math.ceil(el.offsetHeight) + 1 });\n for (const { id, el, go, narrow } of els) {\n const target = narrow\n ? go\n ? this.narrowBranchSizes\n : this.narrowSizes\n : go\n ? this.branchLabelSizes\n : this.labelSizes;\n target.set(id, size(el));\n }\n // A narrow variant only counts if it is actually narrower.\n for (const [wide, narrow] of [\n [this.labelSizes, this.narrowSizes],\n [this.branchLabelSizes, this.narrowBranchSizes],\n ] as const) {\n for (const id of missing) {\n const n = narrow.get(id);\n if (n && n.w >= (wide.get(id)?.w ?? 0) - 1) narrow.delete(id);\n }\n }\n box.replaceChildren();\n }\n\n private createView(tn: TreeNode, pl: PlacedNode): View {\n const page = tn.page;\n const node = document.createElement('button');\n node.type = 'button';\n node.className = 'node';\n node.setAttribute('part', 'node');\n node.setAttribute('role', 'treeitem');\n node.setAttribute('aria-label', page.label);\n node.setAttribute('aria-level', String(tn.depth));\n node.setAttribute('aria-setsize', String(tn.parent?.children.length ?? 1));\n node.setAttribute('aria-posinset', String(tn.index + 1));\n if (page.description) node.setAttribute('aria-description', page.description);\n if (page.disabled) node.setAttribute('aria-disabled', 'true');\n if (tn.children.length) node.dataset.branch = '';\n if (page.color) node.style.setProperty('--_node-accent', page.color);\n node.dataset.id = tn.id;\n\n const icon = document.createElement('span');\n icon.className = 'icon';\n icon.setAttribute('part', 'icon');\n icon.setAttribute('aria-hidden', 'true');\n icon.append(renderIcon(page.icon, this.opts.iconResolver, page) ?? monogram(page.label));\n node.append(icon);\n\n const label = this.buildLabel(tn);\n this.els.labels.append(label);\n\n const edge = document.createElementNS(SVG_NS, 'path');\n edge.setAttribute('class', 'edge');\n edge.setAttribute('part', 'edge');\n edge.setAttribute('pathLength', '1');\n if (page.color) edge.style.setProperty('--_lit', page.color);\n this.els.edges.append(edge);\n\n return { tree: tn, node, label, edge, from: pl.from, leaveTimer: 0, shownAt: null };\n }\n\n /** New nodes grow out of their parent, staggered, with their edge drawing along. */\n private animateIn(views: View[]) {\n const stagger = this.reducedMotion ? 0 : 22;\n for (const v of views) {\n v.node.style.transition = 'none';\n v.node.style.translate = `${v.from.x}px ${v.from.y}px`;\n v.node.dataset.enter = '';\n }\n void this.els.layer.offsetWidth;\n views.forEach((v, i) => {\n const pl = this.placed.get(v.tree.id)!;\n const delay = i * stagger;\n v.node.style.transition = '';\n v.node.style.setProperty('--_delay', `${delay}ms`);\n v.edge.style.setProperty('--_delay', `${delay}ms`);\n // Labels appear once their node has (nearly) arrived, so nothing moves through them.\n v.label.style.setProperty('--_label-delay', `${delay + this.duration * 0.6}ms`);\n v.node.style.translate = `${pl.x}px ${pl.y}px`;\n v.node.removeAttribute('data-enter');\n v.edge.setAttribute('data-shown', '');\n const timer = window.setTimeout(() => {\n this.animationTimers.delete(timer);\n v.node.style.removeProperty('--_delay');\n v.edge.style.removeProperty('--_delay');\n v.label.style.removeProperty('--_label-delay');\n }, delay + this.duration);\n this.animationTimers.add(timer);\n });\n }\n\n private leave(view: View, to: Vec, delay: number) {\n const { node, edge, label } = view;\n // Don't let focus fall out of the dialog with the node: hand it to the parent (or the centre button).\n if (this.shadowRoot?.activeElement === node && this.state === 'open') {\n const parent = view.tree.parent ? this.views.get(view.tree.parent.id) : null;\n if (parent && !parent.leaveTimer) {\n this.focusId = parent.tree.id;\n parent.node.tabIndex = 0;\n parent.node.focus({ preventScroll: true });\n } else this.els.hub.focus({ preventScroll: true });\n }\n node.style.setProperty('--_delay', `${delay}ms`);\n edge.style.setProperty('--_delay', `${delay}ms`);\n node.style.translate = `${to.x}px ${to.y}px`;\n node.setAttribute('data-leave', '');\n node.removeAttribute('data-active');\n node.setAttribute('part', 'node node-leaving');\n edge.setAttribute('part', 'edge');\n label.setAttribute('part', 'label');\n node.tabIndex = -1;\n edge.removeAttribute('data-shown');\n label.removeAttribute('data-visible');\n view.shownAt = null;\n view.leaveTimer = window.setTimeout(\n () => {\n node.remove();\n label.remove();\n edge.remove();\n this.views.delete(view.tree.id);\n },\n delay + this.duration * 0.7 + 40,\n );\n }\n\n /**\n * Shows labels without ever overlapping anything:\n * 1. the level you're looking at (and, with `labels=\"always\"`, every other page) uses the room the\n * layout reserved for it, or on very crowded screens a spot found on demand;\n * 2. the highlighted page gets its description too, if that fits;\n * 3. open branches show their name in their reserved room, or wherever there's room.\n * A label that doesn't fit on one line may wrap onto two (`data-narrow`). Anything that still doesn't\n * fit stays hidden; the page's name is always on the node for assistive tech.\n */\n private renderLabels() {\n const mode = this.opts.labels;\n const r = this.opts.nodeSize / 2;\n const live = [...this.views.values()].filter((v) => !v.leaveTimer);\n const circleOf = new Map<string, Circle>();\n for (const v of live) {\n const pl = this.placed.get(v.tree.id)!;\n circleOf.set(v.tree.id, { x: pl.x, y: pl.y, r });\n }\n const edges = this.opts.edges === 'none' ? [] : live.map((v) => this.placed.get(v.tree.id)!.edge);\n const shown = new Map<string, Rect>();\n const narrowed = new Set<string>();\n const compact = new Set<string>();\n const pad = this.labelPad;\n const ctx = (except: string | null, withEdges: Vec[][] = edges): LabelContext => ({\n bounds: this.bounds,\n circles: [this.hub, ...circleOf.values()],\n taken: [...shown].filter(([id]) => id !== except).map(([, rect]) => rect),\n edges: withEdges,\n pad,\n });\n /**\n * Tighter spacing for labels placed on demand: other nodes only need a small gap, except the\n * highlighted one, which grows. The label's own node keeps the full clearance.\n */\n const tight = (except: string, withEdges: Vec[][] = edges): LabelContext => {\n const base = ctx(except, withEdges);\n const grown = this.active ? circleOf.get(this.active) : null;\n const own = circleOf.get(except);\n const circles = base.circles.map((c) => (c === grown && c !== own ? { ...c, r: c.r + pad - 6 } : c));\n return { ...base, circles, pad: 6, ownPad: pad };\n };\n const fits = (rect: Rect, except: string) =>\n ![...shown].some(([id, other]) => id !== except && rectsTouch(rect, other, 4));\n /** Shows `id` at `rect`; it's the wrapped variant if narrower than its one-line size. */\n const show = (id: string, rect: Rect, wide: Size) => {\n shown.set(id, rect);\n if (rect.w < wide.w - 1) narrowed.add(id);\n else narrowed.delete(id);\n };\n const covers = (rect: Rect | null | undefined, size: Size | undefined) =>\n !!rect && !!size && rect.w >= size.w - 1 && rect.h >= size.h - 1;\n\n // Settle every label's state before measuring anything (a leftover highlighted or wrapped state would\n // measure the wrong size).\n for (const v of live) {\n toggleAttr(v.label, 'data-go', this.mode === 'tap' && v.node.dataset.state === 'path' && !!v.tree.page.href);\n if (v.tree.id !== this.active) v.label.removeAttribute('data-active');\n v.label.removeAttribute('data-compact');\n v.label.removeAttribute('data-narrow');\n }\n\n // 1. Reserved labels: the visible level first (it may have borrowed room from dimmed pages).\n if (mode === 'auto' || mode === 'always') {\n const order = [...live].sort(\n (a, b) => Number(b.node.dataset.state === 'frontier') - Number(a.node.dataset.state === 'frontier'),\n );\n for (const v of order) {\n const id = v.tree.id;\n const state = v.node.dataset.state;\n const rect = this.placed.get(id)!.label;\n const wanted = state === 'frontier' || (state === 'dim' && mode === 'always');\n if (wanted && rect && fits(rect, id)) show(id, rect, this.labelSizes.get(id) ?? rect);\n }\n // 1b. A label of the visible level the layout found no room for (very crowded screens only): placed\n // on demand with tighter spacing, re-evaluated whenever the highlight changes.\n for (const v of live) {\n const id = v.tree.id;\n if (shown.has(id) || id === this.active || v.node.dataset.state !== 'frontier') continue;\n const pl = this.placed.get(id)!;\n const sizes = this.sizesOf(id, false);\n if (!sizes) continue;\n const node = circleOf.get(id)!;\n const c = tight(id);\n const rect =\n placeLabel(node, sizes, pl.angle, c) ?? placeLabel(node, sizes, pl.angle, { ...c, edges: [pl.edge] });\n if (rect) show(id, rect, this.labelSizes.get(id)!);\n }\n }\n\n // 2. The highlighted page: with its description if there's room, else just its name. Only this node\n // grows, so its label may come closer to the others than reserved labels do.\n const activeView = this.active ? this.views.get(this.active) : null;\n if (activeView && !activeView.leaveTimer && mode !== 'none') {\n const id = activeView.tree.id;\n const pl = this.placed.get(id)!;\n const node = circleOf.get(id)!;\n const label = activeView.label;\n const open = activeView.node.dataset.state === 'path';\n // Cleanest first: across no edge; then across other pages' edges; an open branch, whose own edge\n // is the highlighted path, may finally sit on that path like a breadcrumb.\n const attempts = (sizes: Sizes) => {\n const c = tight(id);\n return (\n placeLabel(node, sizes, pl.angle, c) ??\n placeLabel(node, sizes, pl.angle, { ...c, edges: [pl.edge] }) ??\n (open ? placeLabel(node, sizes, pl.angle, { ...c, edges: [] }) : null)\n );\n };\n const measure = (): Size => ({ w: label.offsetWidth + 1, h: label.offsetHeight + 1 });\n label.setAttribute('data-active', '');\n let wide = measure();\n let rect: Rect | null = activeView.tree.page.description ? attempts(wide) : null;\n if (!rect) {\n compact.add(id);\n label.setAttribute('data-compact', '');\n wide = measure();\n const narrow = (open ? this.narrowBranchSizes.get(id) : null) ?? this.narrowSizes.get(id);\n const sizes: Sizes = narrow ? [wide, narrow] : wide;\n const reserved = open ? pl.pathLabel : pl.label;\n const own = shown.get(id) ?? (reserved && fits(reserved, id) ? reserved : null);\n rect = own && (covers(own, wide) || covers(own, narrow)) ? own : attempts(sizes);\n // Crowded (small screens): show the name beside the centre button, like a caption; the lit path\n // connects the two.\n if (!rect) {\n const c = tight(id);\n const toCenter = Math.atan2(\n this.bounds.y + this.bounds.h / 2 - this.hub.y,\n this.bounds.x + this.bounds.w / 2 - this.hub.x,\n );\n rect = placeLabel(this.hub, sizes, toCenter, c) ?? placeLabel(this.hub, sizes, toCenter, { ...c, edges: [] });\n }\n }\n if (rect) show(id, rect, wide);\n else shown.delete(id);\n }\n\n // 3. Open branches: in the room the layout reserved for them, else wherever there's room.\n if (mode === 'auto' || mode === 'always') {\n for (const id of this.path) {\n if (id === this.active || shown.has(id)) continue;\n const v = this.views.get(id);\n if (!v || v.leaveTimer) continue;\n const pl = this.placed.get(id)!;\n const wide = { w: v.label.offsetWidth + 1, h: v.label.offsetHeight + 1 };\n const narrow = this.narrowBranchSizes.get(id) ?? this.narrowSizes.get(id);\n const sizes: Sizes = narrow ? [wide, narrow] : wide;\n const reserved =\n pl.pathLabel && (covers(pl.pathLabel, wide) || covers(pl.pathLabel, narrow)) && fits(pl.pathLabel, id)\n ? pl.pathLabel\n : null;\n const node = circleOf.get(id)!;\n const rings = [0, 12, 28, 48];\n const rect =\n reserved ??\n placeLabel(node, sizes, pl.angle, { ...tight(id), rings }) ??\n placeLabel(node, sizes, pl.angle + Math.PI, {\n ...tight(\n id,\n edges.filter((e) => e !== pl.edge),\n ),\n rings,\n });\n if (rect) show(id, rect, wide);\n }\n }\n\n for (const v of this.views.values()) {\n const id = v.tree.id;\n const rect = v.leaveTimer ? null : (shown.get(id) ?? null);\n const isActive = id === this.active && !!rect;\n toggleAttr(v.label, 'data-active', isActive);\n toggleAttr(v.label, 'data-narrow', !!rect && narrowed.has(id));\n if (!compact.has(id)) v.label.removeAttribute('data-compact');\n setParts(v.label, 'label', { active: isActive, path: v.node.dataset.state === 'path' });\n if (!rect) {\n v.label.removeAttribute('data-visible');\n v.shownAt = null;\n continue;\n }\n const moved = v.shownAt && (Math.abs(v.shownAt.x - rect.x) > 1 || Math.abs(v.shownAt.y - rect.y) > 1);\n v.label.style.translate = `${rect.x.toFixed(1)}px ${rect.y.toFixed(1)}px`;\n v.label.setAttribute('data-visible', '');\n // Never slide: reappear at the new spot instead.\n if (moved && !this.reducedMotion)\n v.label.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 160, easing: 'ease-out' });\n v.shownAt = rect;\n }\n }\n\n /* --------------------------------------------------------------- gestures */\n\n private onPointerDown = (e: PointerEvent) => {\n if (!e.isPrimary || (e.pointerType === 'mouse' && e.button !== 0)) return;\n if (this.state === 'open') return;\n e.preventDefault();\n const { trigger } = this.els;\n try {\n trigger.setPointerCapture(e.pointerId);\n } catch {\n /* synthetic events */\n }\n this.pointerId = e.pointerId;\n this.pointerType = e.pointerType;\n this.downAt = this.lastPoint = { x: e.clientX, y: e.clientY };\n this.leftHub = false;\n trigger.setAttribute('data-pressing', '');\n this.holdTimer = window.setTimeout(() => this.beginDrag(), this.opts.holdDelay);\n };\n\n private beginDrag() {\n window.clearTimeout(this.holdTimer);\n this.holdTimer = 0;\n this.els.trigger.removeAttribute('data-pressing');\n this.show('drag', 'none');\n }\n\n private onPointerMove = (e: PointerEvent) => {\n if (e.pointerId !== this.pointerId) return;\n const p = (this.lastPoint = { x: e.clientX, y: e.clientY });\n if (this.state !== 'open') {\n // Moving away early skips the wait: press-and-flick works too.\n if (this.holdTimer && Math.hypot(p.x - this.downAt.x, p.y - this.downAt.y) > 10) this.beginDrag();\n else return;\n }\n if (this.mode === 'drag') this.dragTo(p);\n };\n\n private onPointerUp = (e: PointerEvent) => {\n if (e.pointerId !== this.pointerId) return;\n this.pointerId = null;\n this.lastPointerUp = performance.now();\n const tapped = this.holdTimer !== 0;\n window.clearTimeout(this.holdTimer);\n this.holdTimer = 0;\n this.els.trigger.removeAttribute('data-pressing');\n if (this.state !== 'open') {\n if (tapped && this.opts.openOnTap) this.show('tap', 'pointer');\n return;\n }\n if (this.mode === 'drag') this.release({ x: e.clientX, y: e.clientY });\n };\n\n private onPointerCancel = (e: PointerEvent) => {\n if (e.pointerId !== this.pointerId) return;\n this.pointerId = null;\n window.clearTimeout(this.holdTimer);\n this.holdTimer = 0;\n this.els.trigger.removeAttribute('data-pressing');\n if (this.state === 'open' && this.mode === 'drag') this.close();\n };\n\n /** Capture lost without a pointerup (rare, browser-specific): treat it as a release where we last were. */\n private onLostCapture = (e: PointerEvent) => {\n if (e.pointerId !== this.pointerId) return;\n this.pointerId = null;\n window.clearTimeout(this.holdTimer);\n this.holdTimer = 0;\n this.els.trigger.removeAttribute('data-pressing');\n if (this.state === 'open' && this.mode === 'drag') this.release(this.lastPoint);\n };\n\n private onTriggerClick = (e: MouseEvent) => {\n // Pointer taps are handled above; this catches keyboard and assistive-technology activation.\n if (performance.now() - this.lastPointerUp < 700) return;\n if (this.state === 'open') this.close({ focusTrigger: true });\n else this.show('tap', e.detail === 0 ? 'keyboard' : 'pointer');\n };\n\n private onTriggerKey = (e: KeyboardEvent) => {\n if (this.state === 'closed' && (e.key === 'ArrowUp' || e.key === 'ArrowDown')) {\n e.preventDefault();\n this.show('tap', 'keyboard');\n }\n };\n\n /** Node, its visible label, or the centre button under a point. */\n private hitAt(p: Vec): string | null {\n const ids: string[] = [];\n const circles: Circle[] = [];\n const r = this.opts.nodeSize / 2;\n for (const [id, pl] of this.placed) {\n const v = this.views.get(id);\n if (!v || v.leaveTimer) continue;\n ids.push(id);\n circles.push({ x: pl.x, y: pl.y, r });\n }\n ids.push('hub');\n circles.push(this.hub);\n const i = hitTest(p, circles, this.pointerType === 'mouse' ? 6 : 14);\n if (i >= 0) return ids[i];\n // Labels are part of the target: pointing at a page's name counts as pointing at the page.\n for (const v of this.views.values()) if (!v.leaveTimer && v.shownAt && rectContains(v.shownAt, p)) return v.tree.id;\n return null;\n }\n\n private dragTo(p: Vec) {\n const hit = this.hitAt(p);\n if (hit === 'hub') {\n this.setActive(null);\n this.dwell(this.leftHub && this.path.length ? 'hub' : null);\n } else if (hit) {\n this.leftHub = true;\n this.setActive(hit);\n this.dwell(hit);\n } else {\n if (Math.hypot(p.x - this.hub.x, p.y - this.hub.y) > this.hub.r + 6) this.leftHub = true;\n this.setActive(null);\n // Overshooting a branch outwards keeps it unfolding instead of cancelling.\n const keep = this.dwellTarget && this.dwellTarget !== 'hub' && this.isBeyond(p, this.dwellTarget);\n if (!keep) this.dwell(null);\n }\n toggleAttr(this.els.hub, 'data-active', this.dwellTarget === 'hub');\n }\n\n private isBeyond(p: Vec, id: string): boolean {\n const pl = this.placed.get(id);\n if (!pl || !this.tree.byId.get(id)?.children.length) return false;\n const dx = pl.x - pl.from.x;\n const dy = pl.y - pl.from.y;\n const len = Math.hypot(dx, dy) || 1;\n const ux = dx / len;\n const uy = dy / len;\n const vx = p.x - pl.from.x;\n const vy = p.y - pl.from.y;\n const along = vx * ux + vy * uy;\n const across = Math.abs(vx * uy - vy * ux);\n return along > len && along < len + this.opts.spacing * 1.2 && across < this.opts.spacing * 0.55;\n }\n\n /** Hovering long enough unfolds a branch (or, for a leaf, folds away whatever its siblings had open). */\n private dwell(target: string | null) {\n if (target === this.dwellTarget) return;\n window.clearTimeout(this.dwellTimer);\n this.dwellTimer = 0;\n this.dwellTarget = target;\n if (!target) return;\n this.dwellTimer = window.setTimeout(() => {\n this.dwellTimer = 0;\n if (target === 'hub') return this.setPath([]);\n const tn = this.tree.byId.get(target);\n if (!tn || tn.page.disabled) return;\n this.setPath(pathTo(tn.children.length ? tn : tn.parent));\n }, this.opts.expandDelay);\n }\n\n private release(p: Vec) {\n window.clearTimeout(this.dwellTimer);\n this.dwellTimer = 0;\n this.dwellTarget = null;\n const hit = this.hitAt(p);\n if (hit && hit !== 'hub') {\n const tn = this.tree.byId.get(hit)!;\n if (!tn.page.disabled) {\n if (tn.page.href || !tn.children.length) return this.select(tn, 'release');\n this.path = pathTo(tn);\n }\n return this.toTapMode(hit);\n }\n // Held and let go without going anywhere: keep it open for tapping.\n if (!this.leftHub) return this.toTapMode(null);\n this.close();\n }\n\n /** From drag to tap: the dialog becomes modal and focus moves into it. */\n private toTapMode(focusId: string | null) {\n this.mode = 'tap';\n this.els.overlay.dataset.mode = 'tap';\n window.removeEventListener('keydown', this.onWindowKey, true);\n this.present(true);\n this.render();\n const id = focusId ?? this.initialFocusId();\n if (id) this.focusNode(id, false);\n }\n\n private onOverlayHover = (e: PointerEvent) => {\n if (this.state !== 'open' || this.mode !== 'tap' || e.pointerType !== 'mouse') return;\n const hit = this.hitAt({ x: e.clientX, y: e.clientY });\n this.setActive(hit === 'hub' ? null : hit);\n };\n\n private onOverlayClick = (e: MouseEvent) => {\n if (this.state !== 'open' || this.mode !== 'tap') return;\n const now = performance.now();\n if (now - this.openedAt < 250) return; // the click that finished the opening tap\n if (e.detail === 0 && now - this.lastKeyActivation < 500) return; // already handled on keydown\n const target = e.target as Element;\n if (target.closest('.hub')) return this.hubAction(e.detail === 0);\n const node = target.closest<HTMLElement>('.node');\n let id = node?.dataset.id ?? null;\n if (!id && e.detail !== 0) {\n const hit = this.hitAt({ x: e.clientX, y: e.clientY });\n id = hit === 'hub' ? null : hit;\n }\n const tn = id ? this.tree.byId.get(id) : null;\n if (!tn) return this.close();\n const via: Via = e.detail === 0 ? 'keyboard' : 'click';\n this.focusNode(tn.id, via === 'keyboard');\n this.activate(tn, via, e.metaKey || e.ctrlKey || e.button === 1);\n };\n\n private hubAction(keyboard: boolean) {\n if (this.path.length) this.goUp(keyboard);\n else this.close({ focusTrigger: true });\n }\n\n /* ---------------------------------------------------------------- keyboard */\n\n private onOverlayKey = (e: KeyboardEvent) => {\n if (this.state !== 'open') return;\n const key = e.key;\n if (key === 'Escape') {\n // Escape closes the whole dialog (Left / Backspace step back a level).\n e.preventDefault();\n this.close({ focusTrigger: true });\n return;\n }\n if (this.mode !== 'tap') return;\n const target = e.composedPath()[0] as Element | undefined;\n const nodeEl = target instanceof Element ? target.closest<HTMLElement>('.node') : null;\n // Keys on the centre button keep their native meaning (Enter/Space press it, Tab moves on).\n if (!nodeEl) {\n if (target === this.els.hub) return;\n if (key in ARROWS || key === 'Home' || key === 'End') {\n e.preventDefault();\n const id = this.focusId && this.placed.has(this.focusId) ? this.focusId : this.initialFocusId();\n if (id) this.focusNode(id);\n }\n return;\n }\n const focused = this.tree.byId.get(nodeEl.dataset.id!);\n if (!focused) return;\n if (this.focusId !== focused.id) this.focusId = focused.id;\n\n if (key === 'Enter' || key === ' ') {\n e.preventDefault();\n this.lastKeyActivation = performance.now();\n return this.activateKey(focused, e.metaKey || e.ctrlKey);\n }\n if (key === 'Backspace') {\n e.preventDefault();\n return this.stepBack(focused);\n }\n const handled = this.opts.arrowKeys === 'spatial' ? this.spatialKey(focused, key) : this.treeKey(focused, key);\n if (handled) {\n e.preventDefault();\n return;\n }\n if (key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey && key !== ' ') this.typeAhead(focused, key);\n };\n\n /** Pages in reading order: every top-level page, each open branch followed by its children. */\n private visibleOrder(): string[] {\n const out: string[] = [];\n const walk = (nodes: TreeNode[]) => {\n for (const n of nodes) {\n out.push(n.id);\n if (this.path.includes(n.id)) walk(n.children);\n }\n };\n walk(this.tree.root.children);\n return out;\n }\n\n /** WAI-ARIA tree keys (mirrored for right-to-left). */\n private treeKey(f: TreeNode, key: string): boolean {\n const rtl = getComputedStyle(this).direction === 'rtl';\n const order = this.visibleOrder();\n const i = order.indexOf(f.id);\n const open = this.path.includes(f.id);\n if (key === 'ArrowDown') {\n if (i < order.length - 1) this.focusNode(order[i + 1]);\n } else if (key === 'ArrowUp') {\n if (i > 0) this.focusNode(order[i - 1]);\n } else if (key === (rtl ? 'ArrowLeft' : 'ArrowRight')) {\n if (f.children.length && !f.page.disabled) {\n if (open) this.focusNode(f.children[0].id);\n else {\n this.path = pathTo(f);\n this.haptic(6);\n this.focusNode(f.id);\n }\n }\n } else if (key === (rtl ? 'ArrowRight' : 'ArrowLeft')) {\n if (open) {\n this.path = pathTo(f.parent);\n this.focusNode(f.id);\n } else if (f.parent && f.parent.depth > 0) this.focusNode(f.parent.id);\n } else if (key === 'Home') this.focusNode(order[0]);\n else if (key === 'End') this.focusNode(order[order.length - 1]);\n else return false;\n return true;\n }\n\n /** Arrows move to the nearest visible page in that direction, whatever the layout looks like. */\n private spatialKey(f: TreeNode, key: string): boolean {\n if (key in ARROWS) {\n const from = this.placed.get(f.id);\n if (!from) return true;\n const dir = ARROWS[key];\n let best: string | null = null;\n let bestScore = Infinity;\n for (const [id, pl] of this.placed) {\n if (id === f.id || this.views.get(id)?.leaveTimer) continue;\n const vx = pl.x - from.x;\n const vy = pl.y - from.y;\n const along = vx * dir.x + vy * dir.y;\n if (along <= 1) continue;\n const across = Math.abs(vx * dir.y - vy * dir.x);\n if (across > along * 2.2) continue;\n const score = along + across * 2;\n if (score < bestScore) {\n bestScore = score;\n best = id;\n }\n }\n if (best) this.focusNode(best);\n return true;\n }\n if (key === 'Home' || key === 'End') {\n const sibs = f.parent?.children ?? [];\n const target = key === 'Home' ? sibs[0] : sibs[sibs.length - 1];\n if (target) this.focusNode(target.id);\n return true;\n }\n return false;\n }\n\n /**\n * Enter / Space. Tree keys: a page with an address opens it; a group without one opens or closes.\n * Spatial keys: like tapping (first press unfolds a branch, the next opens its page).\n */\n private activateKey(f: TreeNode, newTab: boolean) {\n if (f.page.disabled) return;\n if (this.opts.arrowKeys === 'spatial') return this.activate(f, 'keyboard', newTab);\n if (f.page.href || !f.children.length) return this.select(f, 'keyboard', newTab);\n this.path = this.path.includes(f.id) ? pathTo(f.parent) : pathTo(f);\n this.haptic(6);\n this.focusNode(f.id);\n }\n\n /** Backspace: close the branch you're in and focus its page. */\n private stepBack(f: TreeNode) {\n if (f.parent && f.parent.depth > 0) {\n this.path = pathTo(f.parent.parent);\n this.focusNode(f.parent.id);\n } else if (this.path.length) {\n this.path = [];\n this.focusNode(f.id);\n }\n }\n\n private typeAhead(f: TreeNode, char: string) {\n const now = performance.now();\n this.typeahead.text = now - this.typeahead.at < 700 ? this.typeahead.text + char.toLowerCase() : char.toLowerCase();\n this.typeahead.at = now;\n const pool = this.opts.arrowKeys === 'spatial' ? (f.parent?.children ?? []).map((n) => n.id) : this.visibleOrder();\n const query = this.typeahead.text;\n const at = pool.indexOf(f.id);\n const start = query.length === 1 ? at + 1 : at;\n for (let i = 0; i < pool.length; i++) {\n const id = pool[(start + i) % pool.length];\n if (this.tree.byId.get(id)!.page.label.toLowerCase().startsWith(query)) return this.focusNode(id);\n }\n }\n\n private goUp(keyboard: boolean) {\n const last = this.path[this.path.length - 1];\n this.path = this.path.slice(0, -1);\n if (last) this.focusNode(last, keyboard);\n else this.render();\n }\n\n /** Moves focus (roving tabindex). `highlight` also shows it as the active page, label and all. */\n private focusNode(id: string, highlight = true) {\n this.focusId = id;\n if (highlight) this.active = id;\n this.render();\n this.views.get(id)?.node.focus({ preventScroll: true });\n if (highlight) this.emitHighlight();\n }\n\n /* -------------------------------------------------------------- selection */\n\n /** Tap (or Enter with spatial keys): unfold a closed branch; open a page; fold a branch that has no page. */\n private activate(tn: TreeNode, via: Via, newTab = false) {\n if (tn.page.disabled) return;\n if (newTab && tn.page.href) return this.select(tn, via, true);\n const expanded = this.path.includes(tn.id);\n if (tn.children.length && !expanded) {\n this.path = pathTo(tn);\n this.haptic(6);\n if (via === 'keyboard') this.focusNode(tn.children[0].id);\n else {\n this.active = tn.id;\n this.render();\n }\n return;\n }\n if (tn.children.length && !tn.page.href) {\n this.path = pathTo(tn.parent);\n if (via === 'keyboard') this.focusNode(tn.id);\n else this.render();\n return;\n }\n this.select(tn, via, newTab);\n }\n\n private select(tn: TreeNode, via: Via, newTab = false) {\n const detail: SelectDetail = {\n page: tn.page,\n trail: pathTo(tn).map((id) => this.tree.byId.get(id)!.page),\n via,\n };\n const proceed = this.emit('unfold-select', detail, true);\n this.haptic(12);\n this.close({ focusTrigger: via === 'keyboard' });\n if (!proceed) return;\n const { href, target } = tn.page;\n if (this.opts.navigate && !(href && (newTab || (target && target !== '_self')))) {\n this.opts.navigate(tn.page, detail);\n return;\n }\n if (!href) return;\n const url = navigationUrl(href, document.baseURI);\n if (!url) {\n console.warn('[unfold-nav] Refusing an unsupported navigation URL:', href);\n return;\n }\n if (newTab || (target && target !== '_self')) window.open(url, newTab ? '_blank' : target, 'noopener');\n else location.assign(url);\n }\n\n private setActive(id: string | null) {\n if (id === this.active) return;\n this.active = id;\n if (id && this.mode === 'drag') this.haptic(4);\n this.render();\n this.emitHighlight();\n }\n\n private setPath(path: string[]) {\n if (path.length === this.path.length && path.every((id, i) => id === this.path[i])) return;\n this.path = path;\n this.haptic(6);\n this.render();\n }\n\n /* ---------------------------------------------------------------- helpers */\n\n private emit(type: string, detail?: unknown, cancelable = false): boolean {\n return this.dispatchEvent(new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable }));\n }\n\n private emitHighlight() {\n const page = this.active ? (this.tree.byId.get(this.active)?.page ?? null) : null;\n this.emit('unfold-highlight', { page });\n }\n\n private haptic(ms: number) {\n if (!this.opts.haptics) return;\n try {\n navigator.vibrate?.(ms);\n } catch {\n /* unsupported */\n }\n }\n\n private get reducedMotion(): boolean {\n return matchMedia('(prefers-reduced-motion: reduce)').matches;\n }\n\n /** The `--unfold-duration` actually in effect, in ms. */\n private get duration(): number {\n const raw = getComputedStyle(this.els.root).getPropertyValue('--_dur').trim();\n const n = parseFloat(raw);\n if (!Number.isFinite(n)) return 340;\n return raw.endsWith('ms') ? n : raw.endsWith('s') ? n * 1000 : n;\n }\n}\n\n// Every option is also a property: `nav.position = 'top'`, `nav.pages = [...]`.\nif (typeof HTMLElement !== 'undefined') {\n for (const key of OPTION_KEYS) {\n Object.defineProperty(UnfoldNav.prototype, key, {\n configurable: true,\n enumerable: true,\n get(this: UnfoldNav) {\n return (this as unknown as { opts: UnfoldNavOptions }).opts[key];\n },\n set(this: UnfoldNav, value: unknown) {\n this.configure({ [key]: value } as Partial<UnfoldNavOptions>);\n },\n });\n }\n}\n\nexport type { NavPage };\n","import { UnfoldNav } from './element.js';\nimport type { SelectDetail, UnfoldNavOptions } from './types.js';\n\nexport { UnfoldNav, DEFAULT_OPTIONS, DEFAULT_STRINGS } from './element.js';\nexport { buildTree, findCurrent } from './tree.js';\nexport { placeFan, layoutGraph, placeLabel } from './layout.js';\nexport type * from './types.js';\n\nexport const TAG = 'unfold-nav';\n\n/** Registers `<unfold-nav>` (idempotent; importing this module already does it). */\nexport function define(tag = TAG): void {\n if (typeof customElements === 'undefined' || customElements.get(tag)) return;\n // A CustomElementRegistry cannot register the same constructor under two names.\n customElements.define(tag, tag === TAG ? UnfoldNav : class extends UnfoldNav {});\n}\ndefine();\n\n/**\n * Creates a navigation, appends it to `container` (default `document.body`) and returns the element.\n *\n * const nav = createUnfoldNav({ pages, position: 'bottom' });\n * nav.addEventListener('unfold-select', (e) => console.log(e.detail.page));\n * nav.remove(); // to tear it down\n */\nexport function createUnfoldNav(\n options: Partial<UnfoldNavOptions> & Pick<UnfoldNavOptions, 'pages'>,\n container?: Element | DocumentFragment,\n): UnfoldNav {\n if (typeof document === 'undefined')\n throw new Error('[unfold-nav] Call createUnfoldNav in a browser after mounting.');\n const parent = container ?? document.body;\n if (!parent) throw new Error('[unfold-nav] Wait for document.body or provide a container.');\n define();\n const el = document.createElement(TAG) as UnfoldNav;\n el.configure(options);\n parent.append(el);\n return el;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'unfold-nav': UnfoldNav;\n }\n interface HTMLElementEventMap {\n 'unfold-select': CustomEvent<SelectDetail>;\n 'unfold-open': CustomEvent<{ mode: 'drag' | 'tap' }>;\n 'unfold-close': CustomEvent<undefined>;\n 'unfold-highlight': CustomEvent<{ page: SelectDetail['page'] | null }>;\n }\n}\n"],"mappings":"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"}