@selimssevgi/cube-design-angular 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +118 -4
- package/fesm2022/selimssevgi-cube-design-angular.mjs +1159 -63
- package/fesm2022/selimssevgi-cube-design-angular.mjs.map +1 -1
- package/package.json +1 -1
- package/tokens/dark.css +11 -1
- package/tokens/light.css +11 -1
- package/types/selimssevgi-cube-design-angular.d.ts +473 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selimssevgi-cube-design-angular.mjs","names":[],"sources":["../../../projects/cube-design-angular/src/lib/drawing/cube-drawing.ts","../../../projects/cube-design-angular/src/lib/cube-picture/cube-picture.ts","../../../projects/cube-design-angular/src/lib/hold/cube-hold.ts","../../../projects/cube-design-angular/src/lib/icon/cube-icon.ts","../../../projects/cube-design-angular/src/lib/context-cube/context-cube.ts","../../../projects/cube-design-angular/src/lib/context-cube/arrange.ts","../../../projects/cube-design-angular/src/lib/context-cube/levels.ts","../../../projects/cube-design-angular/src/lib/square/turning-rows.ts","../../../projects/cube-design-angular/src/lib/square/cube-square.ts","../../../projects/cube-design-angular/src/lib/context-cube/cube-context.ts"],"sourcesContent":["/**\n * drawing a cube of small cubes in isometric view: the left, right and top faces, each split into\n * n × n stickers. a sticker is coloured by a piece, or pale while nothing is known for it.\n *\n * the same projection anlat, mosaic and cubes drew by hand before this package (cube design,\n * `07-visual.md`). pure functions, no angular: they can be used anywhere.\n */\n\n/** The side of the smallest cube that holds this many pieces, up to 7 × 7 × 7. */\nexport function sizeFor(count: number): number {\n let s = 1;\n while (s * s * s < count && s < 7) s++;\n return s;\n}\n\nexport type Face = 'top' | 'left' | 'right';\n\nexport interface Sticker {\n face: Face;\n /** The sticker's square, as SVG points. */\n outer: string;\n /** The coloured inset inside it. */\n inner: string;\n colour: string | null;\n}\n\nexport interface Drawing {\n width: number;\n height: number;\n viewBox: string;\n /** The faint bigger cube it can grow into, as dashed outlines. */\n hint: string[];\n stickers: Sticker[];\n}\n\nexport interface DrawOptions {\n /** Show the next size as a faint cube behind (only while it is small). */\n hint?: boolean;\n /** A value: one colour on every sticker. */\n whole?: boolean;\n /** How many times it has been turned: shifts the colours round the stickers. */\n rot?: number;\n}\n\nconst C30 = Math.cos(Math.PI / 6);\ntype Point = [number, number];\n\nfunction poly(pts: Point[], k: number): string {\n const cx = pts.reduce((a, q) => a + q[0], 0) / pts.length;\n const cy = pts.reduce((a, q) => a + q[1], 0) / pts.length;\n return pts\n .map(([x, y]) => `${(cx + (x - cx) * k).toFixed(1)},${(cy + (y - cy) * k).toFixed(1)}`)\n .join(' ');\n}\n\nfunction squares(n: number, s: number, shift: Point): { face: Face; pts: Point[] }[] {\n const ox = n * s * C30;\n const oy = n * s;\n const p = (x: number, y: number, z: number): Point => [\n shift[0] + ox + (x - y) * C30 * s,\n shift[1] + oy + (x + y) * 0.5 * s - z * s,\n ];\n const out: { face: Face; pts: Point[] }[] = [];\n for (let a = 0; a < n; a++)\n for (let b = n - 1; b >= 0; b--)\n out.push({\n face: 'left',\n pts: [p(a, n, b + 1), p(a + 1, n, b + 1), p(a + 1, n, b), p(a, n, b)],\n });\n for (let a = 0; a < n; a++)\n for (let b = n - 1; b >= 0; b--)\n out.push({\n face: 'right',\n pts: [p(n, a, b + 1), p(n, a + 1, b + 1), p(n, a + 1, b), p(n, a, b)],\n });\n for (let a = 0; a < n; a++)\n for (let b = 0; b < n; b++)\n out.push({\n face: 'top',\n pts: [p(a, b, n), p(a + 1, b, n), p(a + 1, b + 1, n), p(a, b + 1, n)],\n });\n return out;\n}\n\n/** A cube for `count` pieces, `width` wide, coloured by `colours` in sticker order. */\nexport function drawCube(\n count: number,\n colours: (string | null)[],\n width: number,\n options: DrawOptions = {},\n): Drawing {\n const n = sizeFor(Math.max(1, count));\n const hinted = !!options.hint && count < 9;\n const big = hinted ? n + 1 : n;\n const s = width / (2 * big * C30);\n const hint = hinted ? squares(big, s, [0, 0]).map((q) => poly(q.pts, 0.86)) : [];\n const shift: Point = hinted ? [(big - n) * s * C30, (big - n) * s * 2] : [0, 0];\n const k = colours.length ? (options.rot ?? 0) % colours.length : 0;\n const turned = colours.slice(k).concat(colours.slice(0, k));\n const stickers = squares(n, s, shift).map((q, i) => ({\n face: q.face,\n outer: poly(q.pts, 1),\n inner: poly(q.pts, 0.86),\n colour: options.whole ? (colours[0] ?? null) : (turned[i] ?? null),\n }));\n const height = 2 * big * s;\n return {\n width,\n height: Math.round(height),\n viewBox: `-2 -2 ${(width + 4).toFixed(1)} ${(height + 4).toFixed(1)}`,\n hint,\n stickers,\n };\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { drawCube } from '../drawing/cube-drawing';\n\n/**\n * a cube of small cubes, one per piece: coloured where something is known, pale where not.\n *\n * its look comes from css variables, so each app keeps its own dialect (the light one of cubes and\n * anlat, the dark one of mosaic). every variable has a light fallback, so it draws without any;\n * `tokens/light.css` and `tokens/dark.css` set them all.\n */\n@Component({\n selector: 'cube-picture',\n template: `\n @let d = drawing();\n <svg\n [attr.viewBox]=\"d.viewBox\"\n [attr.width]=\"d.width\"\n [attr.height]=\"d.height\"\n aria-hidden=\"true\"\n >\n @for (q of d.hint; track $index) {\n <polygon class=\"hint\" [attr.points]=\"q\" />\n }\n @for (q of d.stickers; track $index) {\n <polygon [attr.points]=\"q.outer\" [attr.class]=\"'side ' + q.face\" />\n }\n @for (q of d.stickers; track $index) {\n <polygon\n [attr.points]=\"q.inner\"\n [attr.class]=\"q.colour ? 'sticker' : 'sticker unknown'\"\n [attr.fill]=\"q.colour\"\n />\n }\n </svg>\n `,\n styles: `\n :host {\n display: inline-block;\n line-height: 0;\n }\n svg {\n overflow: visible;\n }\n .hint {\n fill: none;\n stroke: var(--cube-hint, #87938c);\n stroke-width: 1;\n stroke-dasharray: 3 3;\n opacity: var(--cube-hint-opacity, 0.5);\n }\n .side {\n stroke: var(--cube-edge, #cdd8d0);\n stroke-width: var(--cube-edge-width, 0.6);\n }\n .top {\n fill: var(--cube-top, #f9fbf8);\n }\n .left {\n fill: var(--cube-left, #e9eee9);\n }\n .right {\n fill: var(--cube-right, #dfe6e0);\n }\n .sticker {\n stroke: var(--cube-sticker-edge, rgba(31, 45, 39, 0.28));\n stroke-width: 1;\n }\n .unknown {\n fill: var(--cube-unknown, #e3e7e1);\n stroke: var(--cube-unknown-edge, none);\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CubePicture {\n /** how many pieces: the cube is the smallest n × n × n that holds them. */\n readonly count = input(1);\n /** the stickers' colours in order; null is a sticker not known yet. */\n readonly colours = input<(string | null)[]>([]);\n /** the width in pixels. */\n readonly width = input(64);\n /** show the bigger cube it can grow into, faintly, while it is small. */\n readonly hint = input(false);\n /** one colour on every sticker (a value). */\n readonly whole = input(false);\n /** how many times it was turned: shifts the colours round the stickers. */\n readonly rot = input(0);\n\n protected readonly drawing = computed(() =>\n drawCube(this.count(), this.colours(), this.width(), {\n hint: this.hint(),\n whole: this.whole(),\n rot: this.rot(),\n }),\n );\n}\n","import { DestroyRef, Directive, ElementRef, inject, input, output } from '@angular/core';\n\n/** what a hold reports: how it came, on which element, and the event that ended it. */\nexport interface CubeHeld {\n /** `press`: a finger, pen or the main mouse button stayed put; `menu`: a contextmenu event. */\n via: 'press' | 'menu';\n /** the element holding the directive. */\n element: HTMLElement;\n /** the pointerdown that was held, or the contextmenu. */\n event: Event;\n}\n\n/** how long a press is held before it is a hold (cubes' value; each app may set its own). */\nexport const CUBE_HOLD_MS = 520;\n/** how far a finger may move while pressing before it is a drag, in pixels. */\nexport const CUBE_HOLD_SLOP = 10;\n\n/**\n * pressing and holding a piece (principle 31): a long press, a right click or the menu key raise\n * one `cubeHeld`. a second finger (a pinch) or a drag never does, and the click that follows a hold\n * is swallowed so the piece does not also open. what a hold opens is the app's.\n *\n * it only reports: it never stops or prevents the pointer events, so a swipe or a pinch on the same\n * element keeps working.\n */\n@Directive({\n selector: '[cubeHold]',\n host: {\n '[style.user-select]': 'cubeHoldDisabled() ? null : \"none\"',\n '[style.-webkit-user-select]': 'cubeHoldDisabled() ? null : \"none\"',\n '[style.-webkit-touch-callout]': 'cubeHoldDisabled() ? null : \"none\"',\n '(pointerdown)': 'press($event)',\n '(pointermove)': 'moved($event)',\n '(pointerup)': 'lift($event)',\n '(pointercancel)': 'lift($event)',\n '(pointerleave)': 'lift($event)',\n '(contextmenu)': 'menu($event)',\n '(keydown)': 'pressFired = false; swallow = false',\n },\n})\nexport class CubeHold {\n /** no hold at all: the listeners do nothing and the browser's own menu stays. */\n readonly cubeHoldDisabled = input(false);\n /** how long a press is held before it is a hold, in milliseconds. */\n readonly cubeHoldMs = input(CUBE_HOLD_MS);\n /** how far the press may move before it is a drag instead, in pixels. */\n readonly cubeHoldSlop = input(CUBE_HOLD_SLOP);\n /** a short buzz (`navigator.vibrate(12)`) when it holds, where the device can. */\n readonly cubeHoldBuzz = input(true);\n\n /** the piece was held. */\n readonly cubeHeld = output<CubeHeld>();\n\n private readonly element = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private timer: ReturnType<typeof setTimeout> | undefined;\n /** where the press started; null while nothing may become a hold. */\n private start: { x: number; y: number } | null = null;\n /** the pointers down on the element: two or more are a pinch. */\n private readonly pointers = new Set<number>();\n /** this press already held, so the phone's own contextmenu after it is not a second hold. */\n protected pressFired = false;\n /** a hold swallows the one click that follows it. */\n protected swallow = false;\n\n constructor() {\n // caught first, before the element's own (click), so a hold never also opens the piece.\n const swallow = (e: Event) => {\n if (!this.swallow) return;\n this.swallow = false;\n e.preventDefault();\n e.stopImmediatePropagation();\n };\n this.element.addEventListener('click', swallow, true);\n inject(DestroyRef).onDestroy(() => {\n clearTimeout(this.timer);\n this.element.removeEventListener('click', swallow, true);\n });\n }\n\n protected press(e: PointerEvent): void {\n this.pointers.add(e.pointerId);\n this.cancel();\n this.pressFired = false;\n this.swallow = false;\n // a second finger is a pinch, and only the main button holds.\n if (this.cubeHoldDisabled() || this.pointers.size > 1 || e.button > 0) return;\n this.start = { x: e.clientX, y: e.clientY };\n this.timer = setTimeout(() => this.fire('press', e), this.cubeHoldMs());\n }\n\n protected moved(e: PointerEvent): void {\n if (!this.start) return;\n if (Math.hypot(e.clientX - this.start.x, e.clientY - this.start.y) > this.cubeHoldSlop()) {\n this.cancel();\n }\n }\n\n protected lift(e: PointerEvent): void {\n this.pointers.delete(e.pointerId);\n this.cancel();\n }\n\n /** a right click, a phone's own long press, the menu key or shift+f10. */\n protected menu(e: Event): void {\n if (this.cubeHoldDisabled()) return;\n e.preventDefault();\n if (this.pressFired) return;\n this.fire('menu', e);\n }\n\n private fire(via: CubeHeld['via'], event: Event): void {\n this.cancel();\n if (this.cubeHoldDisabled()) return;\n this.pressFired = via === 'press';\n this.swallow = true;\n if (this.cubeHoldBuzz()) globalThis.navigator?.vibrate?.(12);\n this.cubeHeld.emit({ via, element: this.element, event });\n }\n\n private cancel(): void {\n clearTimeout(this.timer);\n this.timer = undefined;\n this.start = null;\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\n\n/** the views a cube can be shown in, each drawn as its own shape. */\nexport type CubeIconView = 'square' | 'one' | 'two' | 'three' | 'four' | 'grid-4x5' | 'grid-3x6';\n\n/** what a tile of a cube the app keeps is about (a context cube's parts and their choices). */\nexport type CubeIconName =\n | 'names'\n | 'name'\n | 'change'\n | 'move'\n | 'place'\n | 'whose'\n | 'library'\n | 'mine'\n | 'shown'\n | 'hidden'\n | 'view'\n | 'sort'\n | 'kept'\n | 'face'\n | 'added'\n | 'up'\n | 'down'\n | 'plus'\n | CubeIconView;\n\n/** every icon, in the order above. */\nexport const CUBE_ICON_NAMES: readonly CubeIconName[] = [\n 'names',\n 'name',\n 'change',\n 'move',\n 'place',\n 'whose',\n 'library',\n 'mine',\n 'shown',\n 'hidden',\n 'view',\n 'sort',\n 'kept',\n 'face',\n 'added',\n 'up',\n 'down',\n 'plus',\n 'square',\n 'one',\n 'two',\n 'three',\n 'four',\n 'grid-4x5',\n 'grid-3x6',\n];\n\n/** a view's icon is its own shape: the cells of one, two… across, a fixed grid, the square. */\nconst SHAPES: Record<CubeIconView, { cols: number; rows: number }> = {\n square: { cols: 3, rows: 3 },\n one: { cols: 1, rows: 3 },\n two: { cols: 2, rows: 3 },\n three: { cols: 3, rows: 3 },\n four: { cols: 4, rows: 3 },\n 'grid-4x5': { cols: 4, rows: 5 },\n 'grid-3x6': { cols: 3, rows: 6 },\n};\n\nexport interface CubeIconCell {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/**\n * the cells a view's icon draws in its 24 × 24 box, or null when the icon is not a view. one across\n * is a list, so its cells are rows.\n */\nexport function cubeIconCells(icon: CubeIconName): CubeIconCell[] | null {\n const shape = SHAPES[icon as CubeIconView];\n if (!shape) return null;\n const { cols, rows } = shape;\n const gap = 1.6;\n const size = Math.min((17 - gap * (cols - 1)) / cols, (17 - gap * (rows - 1)) / rows);\n const w = cols * size + gap * (cols - 1);\n const h = rows * size + gap * (rows - 1);\n const out: CubeIconCell[] = [];\n for (let r = 0; r < rows; r++)\n for (let c = 0; c < cols; c++)\n out.push({\n x: cols === 1 ? 3.5 : 12 - w / 2 + c * (size + gap),\n y: 12 - h / 2 + r * (size + gap),\n w: cols === 1 ? 17 : size,\n h: size,\n });\n return out;\n}\n\n/**\n * an icon on a tile of a cube the app keeps (a context cube and its parts), in place of a small\n * cube: such cubes hold no pieces, so their tiles show what they are about.\n *\n * its look comes from css variables (`--cube-icon-*`), each with a light fallback; `tokens/light.css`\n * and `tokens/dark.css` set them all. it says nothing: the tile's words come from the app.\n */\n@Component({\n selector: 'cube-icon',\n template: `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n @if (cells(); as cs) {\n @for (c of cs; track $index) {\n <rect\n class=\"cell\"\n [attr.x]=\"c.x\"\n [attr.y]=\"c.y\"\n [attr.width]=\"c.w\"\n [attr.height]=\"c.h\"\n rx=\"0.8\"\n />\n }\n }\n @switch (icon()) {\n @case ('view') {\n <rect x=\"4\" y=\"4\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13\" y=\"4\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"4\" y=\"13\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13\" y=\"13\" width=\"7\" height=\"7\" rx=\"1.5\" />\n }\n @case ('sort') {\n <path d=\"M8 19V5M4.5 8.5 8 5l3.5 3.5M16 5v14M12.5 15.5 16 19l3.5-3.5\" />\n }\n @case ('kept') {\n <path d=\"M5 7h14M5 12h14M5 17h9\" />\n }\n @case ('face') {\n <path d=\"M12 3.5 20 8v8l-8 4.5L4 16V8Z\" />\n <path d=\"M4 8l8 4.5L20 8M12 12.5v8\" />\n }\n @case ('added') {\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n <path d=\"M12 7.5V12l3 2\" />\n }\n @case ('up') {\n <path d=\"M12 19V5M6.5 10.5 12 5l5.5 5.5\" />\n }\n @case ('plus') {\n <path d=\"M12 5v14M5 12h14\" />\n }\n @case ('down') {\n <path d=\"M12 5v14M6.5 13.5 12 19l5.5-5.5\" />\n }\n @case ('names') {\n <path d=\"M3.5 12.5 11 5h8v8l-7.5 7.5a1.5 1.5 0 0 1-2.1 0L3.5 14.6a1.5 1.5 0 0 1 0-2.1Z\" />\n <circle cx=\"15.2\" cy=\"8.8\" r=\"1.4\" />\n }\n @case ('name') {\n <path d=\"M5 18 9.5 6h1L15 18M6.6 14h6.8\" />\n <path\n d=\"M17 11.5c1.6-1.2 3.5-.5 3.5 1.4V18M20.5 14.6c-2.6-.3-4 .4-4 1.8 0 1.9 2.7 2 4 .3\"\n />\n }\n @case ('change') {\n <path d=\"M4 20h4L19 9a2.8 2.8 0 0 0-4-4L4 16v4Z\" />\n <path d=\"M13.5 6.5l4 4\" />\n }\n @case ('move') {\n <path\n d=\"M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-1\"\n />\n <path d=\"M2.5 13H12M9 10l3 3-3 3\" />\n }\n @case ('place') {\n <path\n d=\"M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8Z\"\n />\n }\n @case ('whose') {\n <circle cx=\"9\" cy=\"8\" r=\"3.2\" />\n <path d=\"M3 19c.6-3.4 3-5.2 6-5.2s5.4 1.8 6 5.2\" />\n <path d=\"M16 5.5a3 3 0 0 1 0 5.6M18.5 14.4c1.4.8 2.3 2.4 2.5 4.6\" />\n }\n @case ('library') {\n <path d=\"M4 5h4v15H4zM10 5h4v15h-4z\" />\n <path d=\"m16 6 3.6-1 3 14.4-3.6 1z\" />\n }\n @case ('mine') {\n <circle cx=\"12\" cy=\"8\" r=\"3.4\" />\n <path d=\"M5 20c.7-4 3.5-6 7-6s6.3 2 7 6\" />\n }\n @case ('shown') {\n <path d=\"M3 12s3.2-6 9-6 9 6 9 6-3.2 6-9 6-9-6-9-6Z\" />\n <circle cx=\"12\" cy=\"12\" r=\"2.6\" />\n }\n @case ('hidden') {\n <path d=\"M3 12s3.2-6 9-6c1.6 0 3 .45 4.2 1.1M21 12s-3.2 6-9 6c-1.6 0-3-.45-4.2-1.1\" />\n <path d=\"M4.5 19.5 19.5 4.5\" />\n }\n }\n </svg>\n `,\n styles: `\n :host {\n display: inline-block;\n width: var(--cube-icon-size, 34px);\n height: var(--cube-icon-size, 34px);\n line-height: 0;\n }\n svg {\n width: 100%;\n height: 100%;\n fill: none;\n stroke: var(--cube-icon-stroke, #1f2a26);\n stroke-width: var(--cube-icon-stroke-width, 1.7);\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n .cell {\n fill: var(--cube-icon-stroke, #1f2a26);\n stroke: none;\n opacity: var(--cube-icon-cell-opacity, 0.8);\n }\n :host(.in-use) svg {\n stroke: var(--cube-icon-in-use, #3b5a4c);\n }\n :host(.in-use) .cell {\n fill: var(--cube-icon-in-use, #3b5a4c);\n }\n `,\n host: { '[class.in-use]': 'inUse()' },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CubeIcon {\n /** what the tile is about. */\n readonly icon = input.required<CubeIconName>();\n /** the one in use among its siblings: drawn in the in-use colour. */\n readonly inUse = input(false);\n\n protected readonly cells = computed(() => cubeIconCells(this.icon()));\n}\n","import { InjectionToken } from '@angular/core';\nimport { Direction, ViewKey } from './arrange';\n\n/*\n * the context cube: behind every piece sits a second cube, the app's, where it keeps how the piece\n * is named, shown and kept. pressing and holding a piece walks into it (principle 31; cubes calls it\n * the own cube, decisions 39 and 40). this is its shape only: each app fills it from its own data\n * through a `ContextCubeSource`, and gives every word through `ContextWords`.\n */\n\n/**\n * the parts a context cube can have. the seven are the ones cubes found; an app may add its own,\n * any string, and they come after the known ones.\n */\nexport type ContextPartKey =\n 'names' | 'change' | 'view' | 'sort' | 'move' | 'whose' | 'hide' | (string & {});\n\n/** cubes' rows: how it is called (names, change), how it is shown (view, sort), what i do with it. */\nexport const CONTEXT_PART_ORDER: readonly ContextPartKey[] = [\n 'names',\n 'change',\n 'view',\n 'sort',\n 'move',\n 'whose',\n 'hide',\n];\n\n/** the parts in their rows; parts an app added come last, in the order it gave them. twice is once. */\nexport function orderParts(parts: readonly ContextPartKey[]): ContextPartKey[] {\n const unique = [...new Set(parts)];\n const known = CONTEXT_PART_ORDER.filter((p) => unique.includes(p));\n return [...known, ...unique.filter((p) => !CONTEXT_PART_ORDER.includes(p))];\n}\n\n/** one tile of a level. its title and line always come from the app. */\nexport interface ContextTile<D = unknown> {\n /** unique among its level. */\n key: string;\n title: string;\n line?: string | null;\n /** the icon's name: a part, a view key, a direction, or one of the app's. */\n icon: string;\n /** the one in use among its siblings (the name in use, shown or hidden, the view). */\n inUse?: boolean;\n /** drawn quietly: something that can be read but not used. */\n pale?: boolean;\n /** the plus: keeps something new beside the others, always last. */\n adds?: boolean;\n /** what the tile stands for, for the app's own `pick`. */\n data?: D;\n}\n\n/** where in the context cube one is: [] is its top (its parts), ['names'] a part, ['sort', by] deeper. */\nexport type ContextPath = readonly string[];\n\n/** what a pick does: walk into a deeper level, end the journey, step one level out, or nothing. */\nexport type ContextPick =\n { kind: 'enter'; path: string[] } | { kind: 'done' } | { kind: 'out' } | { kind: 'stay' };\n\n/** what an app gives for its own held type `T`: a piece, a cube, a to-do, a level. */\nexport interface ContextCubeSource<T = unknown> {\n /** the parts this held thing has, in any order (`orderParts` puts them in rows). */\n parts(held: T): ContextPartKey[];\n /** the tiles of one level, or null when that path does not exist for it. */\n level(held: T, path: ContextPath): ContextTile[] | null;\n /** a tile was tapped at that path. */\n pick(held: T, path: ContextPath, tile: ContextTile): ContextPick | Promise<ContextPick>;\n}\n\n/** a title and its line, in the app's language. */\nexport interface ContextWord {\n title: string;\n line?: string | null;\n}\n\n/** a name a piece has had, as the names level lists it. */\nexport interface ContextName {\n name: string;\n /** the one in use. */\n current: boolean;\n /** the day it was given, as the app keeps it. */\n on?: string | null;\n /** whose hands gave it. */\n by?: string | null;\n /** whether it was ever in use, or only kept beside. */\n used?: boolean;\n}\n\n/** every word the context cube shows. the package ships none. */\nexport interface ContextWords {\n /** each part's title and line; a part with no word has an empty title. */\n parts: Partial<Record<ContextPartKey, ContextWord>>;\n /** each view's name. */\n views: Partial<Record<ViewKey, ContextWord>>;\n /** the two directions of a sort, when a sort option has none of its own. */\n directions: Record<Direction, ContextWord>;\n /** the two pieces of hide. */\n hide: { shown: ContextWord; hidden: ContextWord };\n /** the plus among the names, and the line under each name (its day and hands). */\n names: { another: ContextWord; line?: (name: ContextName) => string | null };\n /** said on the one in use, when the app wants it said. */\n inUse?: string;\n}\n\n/** the app's source of context cubes. */\nexport const CONTEXT_CUBE_SOURCE = new InjectionToken<ContextCubeSource<any>>(\n 'CONTEXT_CUBE_SOURCE',\n);\n\n/** the app's words for the context cube. */\nexport const CONTEXT_CUBE_WORDS = new InjectionToken<ContextWords>('CONTEXT_CUBE_WORDS');\n\n/** what the top level shows of a part now: the view in use, the name, shown or hidden. */\nexport interface PartNow {\n line?: string | null;\n icon?: string;\n}\n\n/**\n * the icon a part's tile shows when the app gives none of what it holds now. most parts are drawn\n * by their own name; hide has no icon of its own and shows shown (the eye), since a piece is in\n * sight until it is hidden. an app passes `now.hide.icon` (`shown` or `hidden`) to say which.\n */\nexport const PART_ICONS: Partial<Record<ContextPartKey, string>> = { hide: 'shown' };\n\n/** the top of a context cube: its parts in rows, each with its word and, when given, what it holds now. */\nexport function partsLevel(\n parts: readonly ContextPartKey[],\n words: ContextWords,\n now: Partial<Record<ContextPartKey, PartNow>> = {},\n): ContextTile<ContextPartKey>[] {\n return orderParts(parts).map((p) => ({\n key: p,\n title: words.parts[p]?.title ?? '',\n line: now[p]?.line !== undefined ? now[p]?.line : (words.parts[p]?.line ?? null),\n icon: now[p]?.icon ?? PART_ICONS[p] ?? p,\n data: p,\n }));\n}\n","/*\n * how a cube's pieces are laid out and in what order they come, moved from cubes\n * (`core/world/arrange.ts`, design decision 40). both change the view only, never the cube. the\n * words for each view and each direction come from the app (`ContextWords`).\n */\n\n/** the ways a cube's square can be laid out: the square first (cubes decision 23), then the rest. */\nexport type ViewKey = 'square' | 'one' | 'two' | 'three' | 'four' | 'grid-4x5' | 'grid-3x6';\n\n/** every view, in the order they are offered. */\nexport const VIEW_KEYS: readonly ViewKey[] = [\n 'square',\n 'one',\n 'two',\n 'three',\n 'four',\n 'grid-4x5',\n 'grid-3x6',\n];\n\nexport const isView = (v: unknown): v is ViewKey => VIEW_KEYS.includes(v as ViewKey);\n\n/** columns and rows of a layout holding this many; every row is full, open places outlined. */\nexport interface Grid {\n cols: number;\n rows: number;\n}\n\nexport function gridFor(view: ViewKey, count: number): Grid {\n const n = Math.max(1, count);\n switch (view) {\n case 'square': {\n const side = Math.max(1, Math.ceil(Math.sqrt(n)));\n return { cols: side, rows: side };\n }\n case 'one':\n case 'two':\n case 'three':\n case 'four': {\n const cols = { one: 1, two: 2, three: 3, four: 4 }[view];\n return { cols, rows: Math.ceil(n / cols) };\n }\n case 'grid-4x5':\n case 'grid-3x6': {\n const [cols, rows] = view === 'grid-4x5' ? [4, 5] : [3, 6];\n return { cols, rows: rows * Math.ceil(n / (cols * rows)) };\n }\n }\n}\n\n/** up is the face's own order (a to z, oldest first, its first colour first); down the other way. */\nexport type Direction = 'up' | 'down';\n\n/** what an item is sorted by: text, a number, or nothing found (not known yet). */\nexport type SortValue = string | number | null | undefined;\n\n/**\n * items in the order a sort asks for. `by` reads what each item is sorted by; text is compared as\n * a person reads it, numbers as numbers. an item with nothing found is not known yet and comes last\n * in both directions (empty is the point, never hidden). ties keep the items' own order.\n */\nexport function sortItems<T>(items: readonly T[], by: (item: T) => SortValue, dir: Direction): T[] {\n const sign = dir === 'down' ? -1 : 1;\n const known = (v: SortValue): v is string | number => v !== null && v !== undefined && v !== '';\n return items\n .map((item, at) => ({ item, at, value: by(item) }))\n .sort((a, b) => {\n const ka = known(a.value);\n const kb = known(b.value);\n if (!ka || !kb) return Number(!ka) - Number(!kb) || a.at - b.at;\n return sign * compare(a.value as string | number, b.value as string | number) || a.at - b.at;\n })\n .map((x) => x.item);\n}\n\nfunction compare(a: string | number, b: string | number): number {\n if (typeof a === 'number' && typeof b === 'number') return a - b;\n return String(a).localeCompare(String(b));\n}\n","import { Direction, VIEW_KEYS, ViewKey } from './arrange';\nimport { ContextName, ContextTile, ContextWord, ContextWords } from './context-cube';\n\n/*\n * the levels every app's context cube shares, as pure functions: names, hide, view and sort. each\n * returns the tiles of one level; what a tap does stays with the app (its `pick`), read from the\n * tile's `data`.\n */\n\n/** what a names tile holds: a name, or the plus. */\nexport type NamesData = { name: ContextName } | { another: true };\n\n/**\n * every name it has had: the one in use first, then the rest newest first (the names come oldest\n * first, as they were given). when the app allows it, a plus keeps a new one beside it without\n * using it.\n */\nexport function namesLevel(\n names: readonly ContextName[],\n words: ContextWords,\n opts: { canAdd?: boolean } = {},\n): ContextTile<NamesData>[] {\n const listed = [...names.filter((n) => n.current), ...names.filter((n) => !n.current).reverse()];\n const tiles: ContextTile<NamesData>[] = listed.map((n, i) => ({\n key: `name:${i}:${n.name}`,\n title: n.name,\n line: words.names.line?.(n) ?? null,\n icon: 'name',\n inUse: n.current,\n data: { name: n },\n }));\n if (opts.canAdd)\n tiles.push({\n key: 'name:+',\n title: words.names.another.title,\n line: words.names.another.line ?? null,\n icon: 'plus',\n adds: true,\n data: { another: true },\n });\n return tiles;\n}\n\n/** hide: a cube of two pieces, shown and hidden, one in use; `data` is whether it hides. */\nexport function hideLevel(hidden: boolean, words: ContextWords): ContextTile<boolean>[] {\n return [\n {\n key: 'hide:shown',\n title: words.hide.shown.title,\n line: words.hide.shown.line ?? null,\n icon: 'shown',\n inUse: !hidden,\n data: false,\n },\n {\n key: 'hide:hidden',\n title: words.hide.hidden.title,\n line: words.hide.hidden.line ?? null,\n icon: 'hidden',\n inUse: hidden,\n data: true,\n },\n ];\n}\n\n/**\n * view: every way to lay the cube out, its icon its own shape. the one in use says so in place of\n * its line, so both fit a small tile.\n */\nexport function viewLevel(\n now: ViewKey,\n words: ContextWords,\n views: readonly ViewKey[] = VIEW_KEYS,\n): ContextTile<ViewKey>[] {\n return views.map((v) => ({\n key: 'view:' + v,\n title: words.views[v]?.title ?? '',\n line: v === now ? null : (words.views[v]?.line ?? null),\n icon: v,\n inUse: v === now,\n data: v,\n }));\n}\n\n/** what a cube can be sorted by, given by the app: as kept, names, when added, each face. */\nexport interface SortOption {\n /** the app's own key: `kept`, `names`, `added`, a face's id. */\n by: string;\n title: string;\n line?: string | null;\n icon: string;\n /** false for an order with no two ways (as kept): picking it uses it at once. */\n directed?: boolean;\n /** this option's two directions in its own words (a to z, oldest first, small first). */\n up?: ContextWord;\n down?: ContextWord;\n}\n\n/** a sort in use. */\nexport interface SortNow {\n by: string;\n dir: Direction;\n}\n\n/** the two directions of an option, in its own words or else the app's general ones. */\nexport function directionWords(\n option: SortOption,\n words: ContextWords,\n): Record<Direction, ContextWord> {\n return {\n up: option.up ?? words.directions.up,\n down: option.down ?? words.directions.down,\n };\n}\n\n/**\n * sort: the options, the one in use marked; a directed option in use says its direction in place\n * of its line. picking a directed option walks into its two directions (`sortDirectionsLevel`).\n */\nexport function sortLevel(\n options: readonly SortOption[],\n now: SortNow,\n words: ContextWords,\n): ContextTile<SortOption>[] {\n return options.map((o) => {\n const inUse = now.by === o.by;\n const directed = o.directed !== false;\n return {\n key: 'sort:' + o.by,\n title: o.title,\n line: inUse && directed ? directionWords(o, words)[now.dir].title : (o.line ?? null),\n icon: o.icon,\n inUse,\n data: o,\n };\n });\n}\n\n/**\n * inside one sort option: its two directions, up first. whatever direction, an item with nothing\n * found is not known yet and comes last (`sortItems`); the words say so in their lines.\n */\nexport function sortDirectionsLevel(\n option: SortOption,\n now: SortNow,\n words: ContextWords,\n): ContextTile<Direction>[] {\n const w = directionWords(option, words);\n return (['up', 'down'] as const).map((dir) => ({\n key: 'dir:' + dir,\n title: w[dir].title,\n line: w[dir].line ?? null,\n icon: dir,\n inUse: now.by === option.by && now.dir === dir,\n data: dir,\n }));\n}\n","/**\n * turning rows (selim: row rotation), first tried in mosaic's todarch cube: a square of more\n * pieces than its front holds keeps its front full and turns its rows like the layers of a puzzle\n * cube. each row is a band of four sides; the pieces past the front fill the first row's other\n * sides, then the second row's, and so on, so the open places gather at the very end and a row\n * with nothing behind its front does not turn.\n *\n * this is only the layout, pure and without angular: which piece sits on which side of which row.\n * the front is cols × rows (3 × 3 as mosaic draws it, 4 × 5 and 3 × 6 for cubes' fixed grids).\n * when four sides a row are still not enough, rows are added below, as mosaic does.\n */\nexport interface TurningRows<T> {\n /** rows × 4 sides × cols places; null is an open place. side 0 is the front. */\n rows: (T | null)[][][];\n /** how many sides of each row hold something (1: only its front, it does not turn). */\n sides: number[];\n}\n\n/** the sides of one row: its front and the three behind it. */\nexport const TURNING_SIDES = 4;\n\nexport function turningRows<T>(\n pieces: readonly T[],\n own: T | null,\n cols = 3,\n rows = cols,\n): TurningRows<T> {\n const across = Math.max(1, Math.floor(cols));\n const down = Math.max(1, Math.floor(rows));\n const count = pieces.length + (own !== null ? 1 : 0);\n const perRow = across * TURNING_SIDES;\n const rowCount = Math.max(down, Math.ceil(count / perRow));\n const grid: (T | null)[][][] = Array.from({ length: rowCount }, () =>\n Array.from({ length: TURNING_SIDES }, () =>\n Array.from<T | null>({ length: across }).fill(null),\n ),\n );\n const front: [number, number][] = [];\n for (let r = 0; r < rowCount; r++) for (let c = 0; c < across; c++) front.push([r, c]);\n // the own box keeps the front's last place, so it is always seen\n const frontForPieces = own !== null ? front.slice(0, -1) : front;\n if (own !== null) grid[rowCount - 1][0][across - 1] = own;\n let next = 0;\n for (const [r, c] of frontForPieces) {\n if (next >= pieces.length) break;\n grid[r][0][c] = pieces[next++];\n }\n for (let r = 0; r < rowCount && next < pieces.length; r++)\n for (let s = 1; s < TURNING_SIDES && next < pieces.length; s++)\n for (let c = 0; c < across && next < pieces.length; c++) grid[r][s][c] = pieces[next++];\n const sides = grid.map(\n (row) => 1 + row.slice(1).filter((side) => side.some((t) => t !== null)).length,\n );\n return { rows: grid, sides };\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n Directive,\n ElementRef,\n TemplateRef,\n afterNextRender,\n computed,\n contentChild,\n effect,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ViewKey, gridFor } from '../context-cube/arrange';\nimport { TURNING_SIDES, turningRows } from './turning-rows';\n\n/*\n * the square: the complete grid of tiles every face of a cube is drawn with (cube design decision\n * 23, cubes decision 40). mosaic (`app-square-tiles`), cubes (`app-tiles`) and the context cube each\n * wrote it; this is the one they share. it only places the tiles an app gives: each app keeps\n * drawing its own tile through a template. turning rows ride on it (`turning`, off by default).\n */\n\n/** how close a square's places are: from one big tile (0) to only its icon or small cube (4). */\nexport type SquareLevel = 0 | 1 | 2 | 3 | 4;\n\n/** cubes' steps (`levelFor`), by a cell's side in px: a tile says less as the square fills. */\nexport function squareLevelFor(cell: number): SquareLevel {\n return cell >= 280 ? 0 : cell >= 150 ? 1 : cell >= 100 ? 2 : cell >= 70 ? 3 : 4;\n}\n\n/** places still open keep their outline; the fuller the square, the closer its places. */\nexport function squareGap(n: number): number {\n return n <= 2 ? 12 : n === 3 ? 10 : n === 4 ? 8 : 5;\n}\n\n/** the room a square may take: the width it is given, and the window's height for the square. */\nexport interface SquareRoom {\n width: number;\n /** the window's height less a head (48 px); only the square view is held to it, so it is seen whole. */\n tall: number;\n}\n\n/** one square laid out: its columns and rows, its size, and how much each tile says. */\nexport interface SquareLayout {\n cols: number;\n rows: number;\n /** the square's width and height, in px. */\n width: number;\n height: number;\n gap: number;\n /** a cell's width, in px. */\n cell: number;\n /** a row's height: the cell, or a list row's own height in one across. */\n rowHeight: number;\n level: SquareLevel;\n /** one across is a list: each row as tall as a tile with its name and line, not a square. */\n list: boolean;\n /** places not filled, outlined; they only ever finish the last row. */\n open: number;\n}\n\n/** the largest side a square takes on a wide screen, in px (cubes', mosaic's). */\nexport const SQUARE_MAX_SIDE = 880;\n/** a row's height in one across, the list (cubes'). */\nexport const SQUARE_LIST_ROW = 76;\n\n/**\n * how this many tiles are laid out in a view, in this much room. the square view is the smallest\n * n × n that holds them, as wide as the room and the window's height allow; the other views are as\n * long as they need and scroll. open places only finish the last row, so a view never draws a whole\n * empty row (decision of 2026-11-01): three pieces in 4 × 5 are one row of four. the square keeps\n * its own rule, its size coming from the pieces.\n */\nexport function squareLayout(\n view: ViewKey,\n count: number,\n room: SquareRoom,\n opts: { maxSide?: number; listRow?: number } = {},\n): SquareLayout {\n const n = Math.max(0, count);\n const grid = gridFor(view, n);\n const cols = grid.cols;\n const rows = view === 'square' ? grid.rows : Math.max(1, Math.ceil(n / cols));\n const width = Math.max(\n 0,\n Math.min(\n view === 'square' ? Math.min(room.width, room.tall) : room.width,\n opts.maxSide ?? SQUARE_MAX_SIDE,\n ),\n );\n const list = view === 'one';\n const gap = list ? 8 : squareGap(Math.max(cols, Math.min(rows, 5)));\n const cell = Math.max(0, (width - gap * (cols - 1)) / cols);\n const rowHeight = list ? (opts.listRow ?? SQUARE_LIST_ROW) : cell;\n return {\n cols,\n rows,\n width,\n height: rows * rowHeight + gap * (rows - 1),\n gap,\n cell,\n rowHeight,\n level: list ? 1 : squareLevelFor(cell),\n list,\n open: cols * rows - n,\n };\n}\n\n/** what a tile's template is given. */\nexport interface CubeSquareTileContext<T> {\n /** the tile, as the app gave it. */\n $implicit: T;\n index: number;\n /** how much it says (0 everything … 4 only its icon or small cube). */\n level: SquareLevel;\n /** its cell's width and height, in px, for a picture sized to it. */\n cell: number;\n rowHeight: number;\n /** one across: a list row, not a square cell. */\n list: boolean;\n}\n\n/**\n * `<ng-template cubeSquareTile let-tile let-level=\"level\">`: how the app draws one tile inside a\n * `<cube-square>`. the square only places it; the template fills its cell.\n */\n@Directive({ selector: 'ng-template[cubeSquareTile]' })\nexport class CubeSquareTile<T> {\n readonly template = inject<TemplateRef<CubeSquareTileContext<T>>>(TemplateRef);\n /** the tiles' type, for the template's checks: `[cubeSquareTile]=\"tiles()\"`. */\n readonly cubeSquareTile = input<readonly T[] | '' | undefined>();\n\n static ngTemplateContextGuard<T>(\n _dir: CubeSquareTile<T>,\n ctx: unknown,\n ): ctx is CubeSquareTileContext<T> {\n return true;\n }\n}\n\n/** the front a view keeps when its rows turn: the square's `across` × `across`, a fixed grid's page. */\nexport function turningFront(view: ViewKey, across = 3): { cols: number; rows: number } | null {\n if (view === 'square') return { cols: across, rows: across };\n if (view === 'grid-4x5') return { cols: 4, rows: 5 };\n if (view === 'grid-3x6') return { cols: 3, rows: 6 };\n return null;\n}\n\n/** narrower than this (a phone), a full square turns its rows, when `turning` is on. */\nexport const TURNING_BELOW = 640;\n/** turns after which a row with more stops nudging when the square opens. */\nexport const TURNING_NUDGE_UNTIL = 3;\n\n/** turns counted on this page when the app gives no key to keep them on the phone. */\nlet turnedHere = 0;\nconst readTurned = (key: string | null): number => {\n if (!key) return turnedHere;\n try {\n return Number(localStorage.getItem(key)) || 0;\n } catch {\n return turnedHere;\n }\n};\nconst noteTurned = (key: string | null): void => {\n turnedHere++;\n if (!key) return;\n try {\n localStorage.setItem(key, String(readTurned(key) + 1));\n } catch {\n // a phone that keeps nothing keeps nudging, which is fine\n }\n};\n\nconst reducedMotion = () =>\n typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;\n\n/**\n * `<cube-square [tiles] [view]>`: the tiles an app gives, laid out as a complete square or another\n * view, each drawn by the app's `cubeSquareTile` template and told its level. it measures its own\n * width (up to the window's height for the square, at most `maxSide`), outlines its open places and\n * zooms a step when it has to hold more. it says no word and draws no tile. its look is css\n * variables (`--cube-square-*`), set in both token files.\n */\n@Component({\n selector: 'cube-square',\n imports: [NgTemplateOutlet],\n template: `\n @let sq = layout();\n @if (rings(); as r) {\n <div\n class=\"cs-turning\"\n [class]=\"'cs-turning cs-l' + sq.level\"\n [class.cs-dashed]=\"dashed()\"\n [attr.data-level]=\"sq.level\"\n [style.width.px]=\"sq.width\"\n [style.--cs-gap.px]=\"sq.gap\"\n >\n @for (row of r.rows; track ri; let ri = $index) {\n <div\n class=\"cs-row\"\n [class.cs-turns]=\"r.sides[ri] > 1\"\n [attr.data-row]=\"ri\"\n [style.height.px]=\"sq.rowHeight\"\n (pointerdown)=\"down(ri, $event)\"\n (pointermove)=\"move(ri, $event)\"\n (pointerup)=\"up(ri, $event)\"\n (pointercancel)=\"up(ri, $event)\"\n (keydown)=\"key(ri, $event)\"\n >\n @if (r.sides[ri] > 1) {\n <span class=\"cs-edge\" aria-hidden=\"true\"></span>\n }\n <div\n class=\"cs-band\"\n [class.cs-still]=\"dragging() === ri || still()\"\n [class.cs-nudging]=\"nudging()\"\n [style.transform]=\"\n 'translateZ(' + -sq.width / 2 + 'px) rotateY(' + angle(ri) + 'deg)'\n \"\n >\n @for (side of row; track si; let si = $index) {\n <div\n class=\"cs-side\"\n [attr.data-side]=\"si\"\n [style.grid-template-columns]=\"'repeat(' + sq.cols + ', minmax(0, 1fr))'\"\n [style.transform]=\"\n 'rotateY(' + si * 90 + 'deg) translateZ(' + sq.width / 2 + 'px)'\n \"\n [attr.aria-hidden]=\"sideOf(ri) === si ? null : 'true'\"\n [attr.inert]=\"sideOf(ri) === si ? null : ''\"\n >\n @for (t of side; track ci; let ci = $index) {\n @if (t !== null) {\n <div class=\"cs-cell\">\n @if (tile(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: t,\n index: indexOf(t),\n level: sq.level,\n cell: sq.cell,\n rowHeight: sq.rowHeight,\n list: false,\n }\"\n />\n }\n </div>\n } @else if (si < r.sides[ri]) {\n <div class=\"cs-place\" aria-hidden=\"true\"></div>\n }\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div\n #grid\n [class]=\"'cs-square cs-l' + sq.level\"\n [class.cs-list]=\"sq.list\"\n [class.cs-dashed]=\"dashed()\"\n [attr.data-level]=\"sq.level\"\n [style.width.px]=\"sq.width\"\n [style.height.px]=\"sq.height\"\n [style.--cs-gap.px]=\"sq.gap\"\n [style.grid-template-columns]=\"'repeat(' + sq.cols + ', minmax(0, 1fr))'\"\n [style.grid-template-rows]=\"'repeat(' + sq.rows + ', minmax(0, 1fr))'\"\n >\n @for (t of tiles(); track keyOf()(t, $index); let i = $index) {\n <div class=\"cs-cell\">\n @if (tile(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: t,\n index: i,\n level: sq.level,\n cell: sq.cell,\n rowHeight: sq.rowHeight,\n list: sq.list,\n }\"\n />\n }\n </div>\n }\n @for (i of openPlaces(); track i) {\n <div class=\"cs-place\" aria-hidden=\"true\"></div>\n }\n </div>\n }\n `,\n // every class is cs-prefixed: an app's global .tile, .square or .place rules would reach inside,\n // since emulated encapsulation only keeps the component's rules in.\n styles: `\n :host {\n display: block;\n }\n .cs-square {\n display: grid;\n gap: calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));\n --cs-radius: var(--cube-square-radius, 20px);\n }\n .cs-cell {\n display: grid;\n min-width: 0;\n min-height: 0;\n }\n .cs-place {\n box-sizing: border-box;\n border: var(--cube-square-place-width, 1.5px) solid\n var(--cube-square-place, color-mix(in srgb, #dae0d9 55%, transparent));\n border-radius: var(--cs-radius);\n }\n /* something could come here (a cube of mine, a level with a plus): its open places are dashed. */\n .cs-dashed .cs-place {\n border-style: dashed;\n border-color: var(--cube-square-place-dashed, #dae0d9);\n }\n .cs-l0 {\n --cs-radius: 28px;\n }\n .cs-l2 {\n --cs-radius: 16px;\n }\n .cs-l3 {\n --cs-radius: 12px;\n }\n .cs-l4 {\n --cs-radius: 9px;\n }\n .cs-l4 .cs-place {\n border-width: 1px;\n }\n /* turning rows: each row a band of four sides, turned like a puzzle cube's layer. */\n .cs-turning {\n display: flex;\n flex-direction: column;\n gap: calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));\n --cs-radius: var(--cube-square-radius, 20px);\n }\n .cs-row {\n position: relative;\n perspective: 1400px;\n touch-action: pan-y;\n user-select: none;\n -webkit-user-select: none;\n outline: none;\n }\n .cs-row:focus-visible {\n outline: 2px solid var(--cube-square-focus, #5f9a80);\n outline-offset: 3px;\n border-radius: var(--cs-radius);\n }\n .cs-band {\n position: absolute;\n inset: 0;\n transform-style: preserve-3d;\n transition: transform 380ms cubic-bezier(0.2, 0.8, 0.2, 1);\n }\n .cs-band.cs-nudging {\n transition: transform 520ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n .cs-band.cs-still {\n transition: none;\n }\n .cs-side {\n position: absolute;\n inset: 0;\n display: grid;\n gap: calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));\n backface-visibility: hidden;\n }\n /* the hint: the edge of the next side, on a row that has more. */\n .cs-edge {\n pointer-events: none;\n position: absolute;\n top: 18%;\n bottom: 18%;\n right: calc(-1 * max(4px, var(--cs-gap) - 2px));\n z-index: 1;\n width: 3px;\n border-radius: 999px;\n background: var(--cube-square-edge, color-mix(in srgb, #5f9a80 45%, transparent));\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CubeSquare<T> {\n /** the tiles, in the order they are placed. */\n readonly tiles = input.required<readonly T[]>();\n /** how they are laid out: the square (the default), one to four across, 4 × 5, 3 × 6. */\n readonly view = input<ViewKey>('square');\n /** the largest side the square takes on a wide screen, in px. */\n readonly maxSide = input(SQUARE_MAX_SIDE);\n /** a row's height in one across, in px. */\n readonly listRow = input(SQUARE_LIST_ROW);\n /** open places dashed, where something could come (a cube of mine, a level with a plus). */\n readonly dashed = input(false);\n /** what keeps a tile the same tile across changes, so it is not drawn anew; its place by default. */\n readonly keyOf = input<(tile: T, index: number) => unknown>((_, i) => i);\n /**\n * turning rows (selim: row rotation, first in mosaic's todarch cube), off unless the app turns\n * them on: on a phone, a square or fixed grid holding more than its front keeps its size, and each\n * row becomes a band of four sides that a finger (or the arrow keys on a focused row) turns, bringing\n * in the pieces past the front (`turningRows`).\n */\n readonly turning = input(false);\n /** rows turn only on a screen narrower than this, in px; a wide screen shows the whole square. */\n readonly turnBelow = input(TURNING_BELOW);\n /** the square's front when its rows turn: `across` × `across` (3 × 3). */\n readonly across = input(3);\n /** which tile is my own box: it keeps the front's last place while the rows turn. */\n readonly isOwn = input<((tile: T) => boolean) | null>(null);\n /** where the turns are counted on this phone (localStorage), so the nudge stops after a few. */\n readonly nudgeKey = input<string | null>(null);\n\n protected readonly tile = contentChild<CubeSquareTile<T>>(CubeSquareTile);\n private readonly grid = viewChild<ElementRef<HTMLElement>>('grid');\n /** the host's width and the window's height, followed as either changes. */\n private readonly room = signal<SquareRoom>({ width: 0, tall: 0 });\n\n /** the layout now: columns, rows, size, gap, level and open places. */\n /** the front kept while the rows turn, or null when they do not (off, a wide screen, all fit). */\n readonly front = computed(() => {\n if (!this.turning()) return null;\n if ((this.room().width || 354) >= this.turnBelow()) return null;\n const front = turningFront(this.view(), Math.max(1, Math.floor(this.across())));\n return front && this.tiles().length > front.cols * front.rows ? front : null;\n });\n\n /** the layout now: columns, rows, size, gap, level and open places. */\n readonly layout = computed(() => {\n const r = this.room();\n const width = r.width || 354;\n const room = { width, tall: r.tall || width };\n const opts = { maxSide: this.maxSide(), listRow: this.listRow() };\n const front = this.front();\n if (!front) return squareLayout(this.view(), this.tiles().length, room, opts);\n // turning: laid out as its full front, then as many rows as the turning rows need\n const view = this.view();\n const full = squareLayout(view, front.cols * front.rows, room, opts);\n const rows = this.rings()?.rows.length ?? front.rows;\n return {\n ...full,\n rows,\n height: rows * full.rowHeight + full.gap * (rows - 1),\n open: 0,\n };\n });\n\n /** the turning rows: rows × four sides × cols, and how many sides of each hold something. */\n protected readonly rings = computed(() => {\n const front = this.front();\n if (!front) return null;\n const isOwn = this.isOwn();\n const tiles = this.tiles();\n const own = isOwn ? (tiles.find((t) => isOwn(t)) ?? null) : null;\n const pieces = own === null ? tiles : tiles.filter((t) => t !== own);\n return turningRows(pieces, own, front.cols, front.rows);\n });\n\n private readonly indexes = computed(() => new Map(this.tiles().map((t, i) => [t, i])));\n protected indexOf(t: T): number {\n return this.indexes().get(t) ?? 0;\n }\n protected readonly openPlaces = computed(() =>\n Array.from({ length: this.layout().open }, (_, i) => i),\n );\n\n /** each row's turn in degrees, and the row a finger is turning now. */\n private readonly angles = signal<Record<number, number>>({});\n protected readonly dragging = signal<number | null>(null);\n /** turns that should not animate (reduced motion). */\n protected readonly still = signal(reducedMotion());\n protected readonly nudging = signal(false);\n private drag: {\n row: number;\n id: number;\n x: number;\n y: number;\n base: number;\n moved: boolean;\n } | null = null;\n /** fingers on the square now: a second one is a pinch, never a turn. */\n private readonly fingers = new Set<number>();\n private suppressClick = false;\n private nudged = false;\n private readonly timers: ReturnType<typeof setTimeout>[] = [];\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n protected angle(row: number): number {\n return this.angles()[row] ?? 0;\n }\n\n /** the side of a row facing me (0 to 3). */\n protected sideOf(row: number): number {\n const sides = TURNING_SIDES;\n return ((Math.round(-this.angle(row) / 90) % sides) + sides) % sides;\n }\n\n private filled(row: number): number {\n return this.rings()?.sides[row] ?? 1;\n }\n\n protected down(row: number, e: PointerEvent): void {\n this.fingers.add(e.pointerId);\n if (this.fingers.size > 1) {\n // a pinch: let the turn go, the row settles where it was\n this.cancelDrag();\n return;\n }\n if (this.filled(row) <= 1) return;\n this.drag = {\n row,\n id: e.pointerId,\n x: e.clientX,\n y: e.clientY,\n base: this.angle(row),\n moved: false,\n };\n }\n\n protected move(row: number, e: PointerEvent): void {\n const drag = this.drag;\n if (!drag || drag.row !== row || drag.id !== e.pointerId) return;\n const dx = e.clientX - drag.x;\n const dy = e.clientY - drag.y;\n if (!drag.moved) {\n // only a sideways drag turns; up and down is the page scrolling\n if (Math.abs(dx) < 8 || Math.abs(dx) < Math.abs(dy)) return;\n drag.moved = true;\n this.dragging.set(row);\n (e.currentTarget as HTMLElement | null)?.setPointerCapture?.(e.pointerId);\n }\n const width = this.layout().width || 354;\n this.angles.update((a) => ({ ...a, [row]: drag.base + (dx / width) * 90 }));\n }\n\n protected up(row: number, e: PointerEvent): void {\n this.fingers.delete(e.pointerId);\n const drag = this.drag;\n if (!drag || drag.row !== row || drag.id !== e.pointerId) return;\n this.drag = null;\n if (!drag.moved) return;\n this.dragging.set(null);\n this.suppressClick = true;\n setTimeout(() => (this.suppressClick = false));\n // a short swipe is enough to turn one side; it settles on a side, never between two\n const moved = this.angle(row) - drag.base;\n const steps =\n Math.abs(moved) > 12 ? Math.sign(moved) * Math.max(1, Math.round(Math.abs(moved) / 90)) : 0;\n this.settle(row, drag.base, steps);\n }\n\n private cancelDrag(): void {\n const drag = this.drag;\n this.drag = null;\n if (!drag?.moved) return;\n this.dragging.set(null);\n this.angles.update((a) => ({ ...a, [drag.row]: drag.base }));\n }\n\n /** turns a row `steps` sides from `base`, passing the sides with nothing on them. */\n private settle(row: number, base: number, steps: number): void {\n const filled = this.filled(row);\n const sideAt = (s: number) =>\n ((Math.round(-(base + s * 90) / 90) % TURNING_SIDES) + TURNING_SIDES) % TURNING_SIDES;\n let n = steps;\n while (n !== 0 && sideAt(n) >= filled) n += Math.sign(n);\n this.angles.update((a) => ({ ...a, [row]: base + n * 90 }));\n if (n !== 0) noteTurned(this.nudgeKey());\n }\n\n /** the arrow keys on a focused row turn it, so a keyboard reaches every piece too. */\n protected key(row: number, e: KeyboardEvent): void {\n if (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft') return;\n if (this.filled(row) <= 1) return;\n e.preventDefault();\n const col = this.focusedColumn(e.target as HTMLElement | null);\n // the next side comes in from the right, as a swipe to the left brings it\n this.settle(row, this.angle(row), e.key === 'ArrowRight' ? -1 : 1);\n setTimeout(() => this.focusSide(row, col));\n }\n\n private focusedColumn(target: HTMLElement | null): number {\n const cell = target?.closest('.cs-cell, .cs-place');\n const side = cell?.parentElement;\n return cell && side ? Array.from(side.children).indexOf(cell) : 0;\n }\n\n /** after a turn by the keys, focus goes to the same place on the side now facing me. */\n private focusSide(row: number, col: number): void {\n const side = this.host.querySelector<HTMLElement>(\n `.cs-row[data-row=\"${row}\"] .cs-side[data-side=\"${this.sideOf(row)}\"]`,\n );\n if (!side) return;\n const cells = Array.from(side.children) as HTMLElement[];\n const order = [cells[col], ...cells].filter(Boolean);\n const focusable = 'button, a[href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n for (const cell of order) {\n const el = cell.matches(focusable) ? cell : cell.querySelector<HTMLElement>(focusable);\n if (el) {\n el.focus();\n return;\n }\n }\n side.closest<HTMLElement>('.cs-row')?.focus();\n }\n\n /** the nudge: rows with more turn a little and back, one after another, until i turned a few. */\n private nudge(): void {\n const rings = this.rings();\n if (this.nudged || !rings || reducedMotion()) return;\n if (readTurned(this.nudgeKey()) >= TURNING_NUDGE_UNTIL) return;\n const rows = rings.sides.flatMap((s, i) => (s > 1 ? [i] : []));\n if (!rows.length) return;\n this.nudged = true;\n this.nudging.set(true);\n const set = (row: number, angle: number) => {\n if (this.drag || this.dragging() !== null) return;\n this.angles.update((a) => ({ ...a, [row]: angle }));\n };\n rows.forEach((row, i) => {\n this.timers.push(\n setTimeout(() => set(row, -22), 500 + i * 180),\n setTimeout(() => set(row, 0), 1020 + i * 180),\n );\n });\n this.timers.push(setTimeout(() => this.nudging.set(false), 1600 + rows.length * 180));\n }\n\n constructor() {\n const host = this.host;\n const destroy = inject(DestroyRef);\n // the tap that ends a turn is not a tap on a tile\n const swallow = (e: Event) => {\n if (!this.suppressClick) return;\n e.stopPropagation();\n e.preventDefault();\n };\n host.addEventListener('click', swallow, true);\n destroy.onDestroy(() => {\n host.removeEventListener('click', swallow, true);\n this.timers.forEach(clearTimeout);\n });\n effect(() => {\n if (this.rings()) untracked(() => this.timers.push(setTimeout(() => this.nudge())));\n });\n afterNextRender(() => {\n const measure = () =>\n this.room.set({ width: host.clientWidth, tall: Math.max(320, window.innerHeight - 48) });\n measure();\n const watch = typeof ResizeObserver === 'function' ? new ResizeObserver(measure) : null;\n watch?.observe(host);\n window.addEventListener('resize', measure);\n destroy.onDestroy(() => {\n watch?.disconnect();\n window.removeEventListener('resize', measure);\n });\n });\n // a square that has to hold more zooms out a step (and in when it holds fewer); the other views\n // only grow longer.\n let before = 0;\n let beforeView: ViewKey | null = null;\n effect(() => {\n const { cols, list } = this.layout();\n const view = this.view();\n const el = this.grid()?.nativeElement;\n if (\n el &&\n before &&\n cols !== before &&\n view === beforeView &&\n !list &&\n !reducedMotion() &&\n typeof el.animate === 'function'\n ) {\n el.animate([{ transform: `scale(${cols / before})` }, { transform: 'none' }], {\n duration: 420,\n easing: 'cubic-bezier(.2,.7,.2,1)',\n });\n }\n before = cols;\n beforeView = view;\n });\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n untracked,\n} from '@angular/core';\nimport { CUBE_ICON_NAMES, CubeIcon, CubeIconName } from '../icon/cube-icon';\nimport {\n CubeSquare,\n CubeSquareTile,\n SquareLevel,\n squareGap,\n squareLevelFor,\n} from '../square/cube-square';\nimport { gridFor } from './arrange';\nimport {\n CONTEXT_CUBE_SOURCE,\n CONTEXT_CUBE_WORDS,\n ContextCubeSource,\n ContextPath,\n ContextTile,\n ContextWords,\n} from './context-cube';\n\n/*\n * the square that draws one level of a context cube: the tiles an app's `ContextCubeSource` gives\n * for the held thing at a path, as a complete square (cube design decision 23, cubes decisions 39\n * and 40). it never routes, zooms, draws a head or says a word of its own: each app hosts it in its\n * own route under its own head, and walks the path it reports.\n */\n\n/** how close a square's places are: from one big tile (0) to only its icon (4). */\nexport type ContextLevel = SquareLevel;\n\n/** cubes' steps, now the square's (`squareLevelFor`); kept under its first name. */\nexport const contextLevelFor: (cell: number) => ContextLevel = squareLevelFor;\n\n/** a level's square: n × n places, how far apart, and how much each tile says. */\nexport interface ContextSquare {\n /** places on a side. */\n n: number;\n /** the square's side, in px. */\n side: number;\n gap: number;\n level: ContextLevel;\n /** the places not filled, outlined so the square stays whole. */\n open: number;\n}\n\n/**\n * the square for this many tiles in this much room: the smallest n × n that holds them all\n * (`gridFor('square', count)`), as wide as the room, at most `maxSide`.\n */\nexport function contextSquare(count: number, room: number, maxSide = 880): ContextSquare {\n const { cols: n, rows } = gridFor('square', count);\n const side = Math.max(0, Math.min(room, maxSide));\n const gap = squareGap(n);\n const cell = (side - gap * (n - 1)) / n;\n return { n, side, gap, level: contextLevelFor(cell), open: n * rows - Math.max(0, count) };\n}\n\n/**\n * the icon a tile is drawn with: its own when `cube-icon` draws it, shown for `hide` (it has no icon\n * of its own), the plus for a tile that adds, and else a face (an app's own part with an icon the\n * package does not have).\n */\nexport function contextIcon(tile: Pick<ContextTile, 'icon' | 'adds'>): CubeIconName {\n if ((CUBE_ICON_NAMES as readonly string[]).includes(tile.icon)) return tile.icon as CubeIconName;\n if (tile.adds) return 'plus';\n if (tile.icon === 'hide') return 'shown';\n return 'face';\n}\n\n/** a tapped tile and the element it is drawn in. */\nexport interface ContextTapped {\n tile: ContextTile;\n element: HTMLElement;\n}\n\n/**\n * `<cube-context [held] [path]>`: one level of the held thing's context cube, as a complete square\n * of icon tiles. a tap asks the source's `pick`, and the answer comes out as `enter` (a deeper\n * path), `done` (the journey ends: a name, a view, shown or hidden was used) or `out` (one level\n * up); `stay` redraws the level where it is. a level the source does not have (null) is `out` too.\n *\n * the source and the words come from `CONTEXT_CUBE_SOURCE` and `CONTEXT_CUBE_WORDS`, or from the\n * `source` and `words` inputs when one screen holds a different one. its look is css variables\n * (`--cube-context-*`, `--cube-icon-*`), set in both token files.\n */\n@Component({\n selector: 'cube-context',\n imports: [CubeIcon, CubeSquare, CubeSquareTile],\n template: `\n <cube-square\n [tiles]=\"tiles()\"\n [dashed]=\"adds()\"\n [maxSide]=\"maxSide()\"\n [keyOf]=\"keyOf\"\n [class.cc-adds]=\"adds()\"\n >\n <ng-template [cubeSquareTile]=\"tiles()\" let-t let-level=\"level\">\n <button\n type=\"button\"\n [class]=\"'cc-tile cc-l' + level\"\n [class.cc-in-use]=\"!!t.inUse\"\n [class.cc-pale]=\"!!t.pale\"\n [class.cc-adds]=\"!!t.adds\"\n [class.cc-busy]=\"busy() === t.key\"\n [disabled]=\"busy() !== null\"\n [attr.aria-label]=\"level >= 4 ? t.title : null\"\n [attr.aria-current]=\"t.inUse ? 'true' : null\"\n [attr.title]=\"level >= 3 ? t.title : null\"\n (click)=\"tap(t, $any($event.currentTarget))\"\n >\n <span class=\"cc-icon\"><cube-icon [icon]=\"iconOf(t)\" [inUse]=\"!!t.inUse\" /></span>\n @if (level < 4) {\n <span class=\"cc-t\">{{ t.title }}</span>\n }\n @if (t.line && level < 3) {\n <span class=\"cc-m\">{{ t.line }}</span>\n }\n @if (t.inUse && inUseWord() && level < 3) {\n <span class=\"cc-tick\">{{ inUseWord() }}</span>\n }\n </button>\n </ng-template>\n </cube-square>\n `,\n // every class is cc-prefixed: an app's own .tile, .square or .place rules (cubes has them) are\n // global and would reach inside, since emulated encapsulation only keeps the component's rules in.\n styles: `\n :host {\n display: block;\n font: inherit;\n color: var(--cube-context-ink, #1f2a26);\n /* the square's open places in the context cube's own look */\n --cube-square-place: color-mix(in srgb, var(--cube-context-line, #dae0d9) 55%, transparent);\n --cube-square-place-dashed: var(--cube-context-line, #dae0d9);\n --cube-square-radius: var(--cube-context-radius, 20px);\n }\n .cc-tile {\n all: unset;\n cursor: pointer;\n box-sizing: border-box;\n min-width: 0;\n min-height: 0;\n height: 100%;\n overflow: hidden;\n display: grid;\n justify-items: center;\n align-content: center;\n gap: 6px;\n padding: 14px 10px 12px;\n text-align: center;\n background: var(--cube-context-tile, #ffffff);\n border: 1px solid var(--cube-context-line, #dae0d9);\n border-radius: var(--cube-context-radius, 20px);\n user-select: none;\n -webkit-user-select: none;\n -webkit-touch-callout: none;\n transition: transform 160ms;\n }\n .cc-tile:active:not(:disabled) {\n transform: scale(0.97);\n }\n .cc-tile:focus-visible {\n outline: 3px solid var(--cube-context-focus, #5f9a80);\n outline-offset: 2px;\n }\n .cc-tile.cc-in-use {\n border: 2px solid var(--cube-context-in-use, #3b5a4c);\n }\n .cc-tile.cc-pale {\n background: transparent;\n border: 2px dashed var(--cube-context-line, #dae0d9);\n color: var(--cube-context-quiet, #5d6a64);\n }\n .cc-tile.cc-adds {\n border: 2px solid var(--cube-context-adds, #c8693f);\n }\n .cc-tile.cc-busy {\n opacity: 0.6;\n cursor: progress;\n }\n .cc-tile:disabled:not(.cc-busy) {\n cursor: default;\n }\n .cc-icon {\n display: grid;\n place-items: center;\n line-height: 0;\n }\n .cc-tile.cc-adds .cc-icon {\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: var(--cube-context-adds-bg, #f3e3d6);\n --cube-icon-stroke: var(--cube-context-adds-ink, #7a4a2b);\n --cube-icon-size: 26px;\n }\n .cc-t,\n .cc-m {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n }\n .cc-t {\n -webkit-line-clamp: var(--cube-context-title-lines, 2);\n line-clamp: var(--cube-context-title-lines, 2);\n }\n .cc-m {\n -webkit-line-clamp: var(--cube-context-line-lines, 2);\n line-clamp: var(--cube-context-line-lines, 2);\n }\n .cc-t {\n font-size: var(--cube-context-title-size, 17px);\n font-weight: 700;\n line-height: 1.2;\n }\n .cc-m {\n font-size: var(--cube-context-line-size, 13px);\n line-height: 1.3;\n color: var(--cube-context-quiet, #5d6a64);\n }\n .cc-tick {\n font-size: var(--cube-context-line-size, 13px);\n font-weight: 800;\n color: var(--cube-context-in-use, #3b5a4c);\n }\n .cc-tile.cc-l0 {\n border-radius: 28px;\n padding: 24px;\n gap: 10px;\n }\n .cc-l0 .cc-t {\n font-size: calc(var(--cube-context-title-size, 17px) * 26 / 17);\n }\n .cc-l0 .cc-m {\n font-size: calc(var(--cube-context-line-size, 13px) * 16 / 13);\n }\n .cc-l0 .cc-icon {\n --cube-icon-size: 64px;\n }\n .cc-tile.cc-l0.cc-adds .cc-icon {\n width: 96px;\n height: 96px;\n --cube-icon-size: 40px;\n }\n .cc-tile.cc-l2 {\n border-radius: 16px;\n padding: 10px 6px;\n gap: 5px;\n }\n .cc-l2 .cc-t {\n font-size: calc(var(--cube-context-title-size, 17px) * 14 / 17);\n }\n .cc-l2 .cc-m {\n font-size: calc(var(--cube-context-line-size, 13px) * 12 / 13);\n }\n .cc-tile.cc-l3 {\n border-radius: 12px;\n padding: 6px 4px;\n gap: 3px;\n }\n .cc-l3 .cc-t {\n font-size: calc(var(--cube-context-title-size, 17px) * 12 / 17);\n }\n .cc-tile.cc-l4 {\n border-radius: 9px;\n padding: 2px;\n gap: 0;\n }\n .cc-l3 .cc-icon,\n .cc-l4 .cc-icon {\n --cube-icon-size: 24px;\n }\n .cc-tile.cc-l3.cc-adds .cc-icon,\n .cc-tile.cc-l4.cc-adds .cc-icon {\n width: 30px;\n height: 30px;\n --cube-icon-size: 18px;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CubeContext {\n /** what was held: a piece, a cube, a to-do, a level, as the app's source knows it. */\n readonly held = input.required<unknown>();\n /** where in its context cube: [] is its top (the parts), ['names'] a part, ['sort', by] deeper. */\n readonly path = input<ContextPath>([]);\n /** a source for this screen alone; else `CONTEXT_CUBE_SOURCE`. */\n readonly source = input<ContextCubeSource<any> | null>(null);\n /** words for this screen alone; else `CONTEXT_CUBE_WORDS`. */\n readonly words = input<ContextWords | null>(null);\n /** the largest side the square takes on a wide screen, in px. */\n readonly maxSide = input(880);\n\n /** walk into a deeper level: the app puts this path in its own route. */\n readonly enter = output<string[]>();\n /** step one level out (or out of the context cube, from its top). */\n readonly out = output<void>();\n /** the journey ends: the tile that was used. */\n readonly done = output<ContextTile>();\n /**\n * a tile was tapped, before the source answers: the tile and its element, so the app can grow the\n * next level (or whatever the pick opens) out of the tile, as it zooms into any other piece.\n */\n readonly tapped = output<ContextTapped>();\n\n private readonly given = inject(CONTEXT_CUBE_SOURCE, { optional: true });\n private readonly givenWords = inject(CONTEXT_CUBE_WORDS, { optional: true });\n\n /** the tile whose pick is still being answered; every tile waits meanwhile. */\n protected readonly busy = signal<string | null>(null);\n /** bumped after a pick, so a source that keeps its data outside signals is read again. */\n private readonly again = signal(0);\n\n private readonly from = computed(() => {\n const s = this.source() ?? this.given;\n if (!s) throw new Error('cube-context: provide CONTEXT_CUBE_SOURCE or pass [source]');\n return s;\n });\n /** the path as one key, so the same path given anew is the same level. */\n private readonly where = computed(() => this.path().join('\\u0000'));\n private readonly level = computed(() => {\n this.again();\n return this.from().level(this.held(), this.path());\n });\n protected readonly tiles = computed(() => this.level() ?? []);\n protected readonly adds = computed(() => this.tiles().some((t) => !!t.adds));\n /** a tile stays the same tile across levels by its key. */\n protected readonly keyOf = (t: ContextTile) => t.key;\n protected readonly inUseWord = computed(() => (this.words() ?? this.givenWords)?.inUse ?? null);\n protected readonly iconOf = contextIcon;\n\n constructor() {\n // a path the source does not have (a part that went away) steps out.\n effect(() => {\n if (this.level() === null) untracked(() => this.out.emit());\n });\n // a new path is a new level: nothing is waiting any more.\n effect(() => {\n this.where();\n this.held();\n untracked(() => this.busy.set(null));\n });\n }\n\n protected async tap(tile: ContextTile, element?: HTMLElement): Promise<void> {\n if (this.busy() !== null) return;\n if (element) this.tapped.emit({ tile, element });\n const held = this.held();\n const path = this.path();\n const where = this.where();\n const here = () => this.held() === held && this.where() === where;\n this.busy.set(tile.key);\n try {\n const picked = await this.from().pick(held, path, tile);\n // the person walked elsewhere while it was answered: the answer is for a level gone.\n if (!here()) return;\n switch (picked.kind) {\n case 'enter':\n this.enter.emit(picked.path);\n break;\n case 'done':\n this.done.emit(tile);\n break;\n case 'out':\n this.out.emit();\n break;\n case 'stay':\n break;\n }\n } finally {\n if (here()) this.busy.set(null);\n this.again.update((n) => n + 1);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"selimssevgi-cube-design-angular.mjs","names":["reducedMotion"],"sources":["../../../projects/cube-design-angular/src/lib/drawing/cube-drawing.ts","../../../projects/cube-design-angular/src/lib/cube-picture/cube-picture.ts","../../../projects/cube-design-angular/src/lib/hold/cube-hold.ts","../../../projects/cube-design-angular/src/lib/pinch/cube-pinch.ts","../../../projects/cube-design-angular/src/lib/carry/cube-carry.ts","../../../projects/cube-design-angular/src/lib/icon/cube-icon.ts","../../../projects/cube-design-angular/src/lib/context-cube/context-cube.ts","../../../projects/cube-design-angular/src/lib/context-cube/arrange.ts","../../../projects/cube-design-angular/src/lib/context-cube/levels.ts","../../../projects/cube-design-angular/src/lib/context-cube/where.ts","../../../projects/cube-design-angular/src/lib/square/turning-rows.ts","../../../projects/cube-design-angular/src/lib/square/cube-square.ts","../../../projects/cube-design-angular/src/lib/context-cube/cube-context.ts","../../../projects/cube-design-angular/src/lib/loading/cube-loading.ts"],"sourcesContent":["/**\n * drawing a cube of small cubes in isometric view: the left, right and top faces, each split into\n * n × n stickers. a sticker is coloured by a piece, or pale while nothing is known for it.\n *\n * the same projection anlat, mosaic and cubes drew by hand before this package (cube design,\n * `04-screens.md`). pure functions, no angular: they can be used anywhere.\n */\n\n/** The side of the smallest cube that holds this many pieces, up to 7 × 7 × 7. */\nexport function sizeFor(count: number): number {\n let s = 1;\n while (s * s * s < count && s < 7) s++;\n return s;\n}\n\nexport type Face = 'top' | 'left' | 'right';\n\nexport interface Sticker {\n face: Face;\n /** The sticker's square, as SVG points. */\n outer: string;\n /** The coloured inset inside it. */\n inner: string;\n colour: string | null;\n}\n\nexport interface Drawing {\n width: number;\n height: number;\n viewBox: string;\n /** The faint bigger cube it can grow into, as dashed outlines. */\n hint: string[];\n stickers: Sticker[];\n}\n\nexport interface DrawOptions {\n /** Show the next size as a faint cube behind (only while it is small). */\n hint?: boolean;\n /** A value: one colour on every sticker. */\n whole?: boolean;\n /** How many times it has been turned: shifts the colours round the stickers. */\n rot?: number;\n}\n\nconst C30 = Math.cos(Math.PI / 6);\ntype Point = [number, number];\n\nfunction poly(pts: Point[], k: number): string {\n const cx = pts.reduce((a, q) => a + q[0], 0) / pts.length;\n const cy = pts.reduce((a, q) => a + q[1], 0) / pts.length;\n return pts\n .map(([x, y]) => `${(cx + (x - cx) * k).toFixed(1)},${(cy + (y - cy) * k).toFixed(1)}`)\n .join(' ');\n}\n\nfunction squares(n: number, s: number, shift: Point): { face: Face; pts: Point[] }[] {\n const ox = n * s * C30;\n const oy = n * s;\n const p = (x: number, y: number, z: number): Point => [\n shift[0] + ox + (x - y) * C30 * s,\n shift[1] + oy + (x + y) * 0.5 * s - z * s,\n ];\n const out: { face: Face; pts: Point[] }[] = [];\n for (let a = 0; a < n; a++)\n for (let b = n - 1; b >= 0; b--)\n out.push({\n face: 'left',\n pts: [p(a, n, b + 1), p(a + 1, n, b + 1), p(a + 1, n, b), p(a, n, b)],\n });\n for (let a = 0; a < n; a++)\n for (let b = n - 1; b >= 0; b--)\n out.push({\n face: 'right',\n pts: [p(n, a, b + 1), p(n, a + 1, b + 1), p(n, a + 1, b), p(n, a, b)],\n });\n for (let a = 0; a < n; a++)\n for (let b = 0; b < n; b++)\n out.push({\n face: 'top',\n pts: [p(a, b, n), p(a + 1, b, n), p(a + 1, b + 1, n), p(a, b + 1, n)],\n });\n return out;\n}\n\n/** A cube for `count` pieces, `width` wide, coloured by `colours` in sticker order. */\nexport function drawCube(\n count: number,\n colours: (string | null)[],\n width: number,\n options: DrawOptions = {},\n): Drawing {\n const n = sizeFor(Math.max(1, count));\n const hinted = !!options.hint && count < 9;\n const big = hinted ? n + 1 : n;\n const s = width / (2 * big * C30);\n const hint = hinted ? squares(big, s, [0, 0]).map((q) => poly(q.pts, 0.86)) : [];\n const shift: Point = hinted ? [(big - n) * s * C30, (big - n) * s * 2] : [0, 0];\n const k = colours.length ? (options.rot ?? 0) % colours.length : 0;\n const turned = colours.slice(k).concat(colours.slice(0, k));\n const stickers = squares(n, s, shift).map((q, i) => ({\n face: q.face,\n outer: poly(q.pts, 1),\n inner: poly(q.pts, 0.86),\n colour: options.whole ? (colours[0] ?? null) : (turned[i] ?? null),\n }));\n const height = 2 * big * s;\n return {\n width,\n height: Math.round(height),\n viewBox: `-2 -2 ${(width + 4).toFixed(1)} ${(height + 4).toFixed(1)}`,\n hint,\n stickers,\n };\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { drawCube } from '../drawing/cube-drawing';\n\n/**\n * a cube of small cubes, one per piece: coloured where something is known, pale where not.\n *\n * its look comes from css variables, so each app keeps its own dialect (the light one of cubes and\n * anlat, the dark one of mosaic). every variable has a light fallback, so it draws without any;\n * `tokens/light.css` and `tokens/dark.css` set them all.\n */\n@Component({\n selector: 'cube-picture',\n template: `\n @let d = drawing();\n <svg\n [attr.viewBox]=\"d.viewBox\"\n [attr.width]=\"d.width\"\n [attr.height]=\"d.height\"\n aria-hidden=\"true\"\n >\n @for (q of d.hint; track $index) {\n <polygon class=\"hint\" [attr.points]=\"q\" />\n }\n @for (q of d.stickers; track $index) {\n <polygon [attr.points]=\"q.outer\" [attr.class]=\"'side ' + q.face\" />\n }\n @for (q of d.stickers; track $index) {\n <polygon\n [attr.points]=\"q.inner\"\n [attr.class]=\"q.colour ? 'sticker' : 'sticker unknown'\"\n [attr.fill]=\"q.colour\"\n />\n }\n </svg>\n `,\n styles: `\n :host {\n display: inline-block;\n line-height: 0;\n }\n svg {\n overflow: visible;\n }\n .hint {\n fill: none;\n stroke: var(--cube-hint, #87938c);\n stroke-width: 1;\n stroke-dasharray: 3 3;\n opacity: var(--cube-hint-opacity, 0.5);\n }\n .side {\n stroke: var(--cube-edge, #cdd8d0);\n stroke-width: var(--cube-edge-width, 0.6);\n }\n .top {\n fill: var(--cube-top, #f9fbf8);\n }\n .left {\n fill: var(--cube-left, #e9eee9);\n }\n .right {\n fill: var(--cube-right, #dfe6e0);\n }\n .sticker {\n stroke: var(--cube-sticker-edge, rgba(31, 45, 39, 0.28));\n stroke-width: 1;\n }\n .unknown {\n fill: var(--cube-unknown, #e3e7e1);\n stroke: var(--cube-unknown-edge, none);\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CubePicture {\n /** how many pieces: the cube is the smallest n × n × n that holds them. */\n readonly count = input(1);\n /** the stickers' colours in order; null is a sticker not known yet. */\n readonly colours = input<(string | null)[]>([]);\n /** the width in pixels. */\n readonly width = input(64);\n /** show the bigger cube it can grow into, faintly, while it is small. */\n readonly hint = input(false);\n /** one colour on every sticker (a value). */\n readonly whole = input(false);\n /** how many times it was turned: shifts the colours round the stickers. */\n readonly rot = input(0);\n\n protected readonly drawing = computed(() =>\n drawCube(this.count(), this.colours(), this.width(), {\n hint: this.hint(),\n whole: this.whole(),\n rot: this.rot(),\n }),\n );\n}\n","import { DestroyRef, Directive, ElementRef, inject, input, output } from '@angular/core';\n\n/** what a hold reports: how it came, on which element, and the event that ended it. */\nexport interface CubeHeld {\n /** `press`: a finger, pen or the main mouse button stayed put; `menu`: a contextmenu event. */\n via: 'press' | 'menu';\n /** the element holding the directive. */\n element: HTMLElement;\n /** the pointerdown that was held, or the contextmenu. */\n event: Event;\n}\n\n/** how long a press is held before it is a hold (cubes' value; each app may set its own). */\nexport const CUBE_HOLD_MS = 520;\n/** how far a finger may move while pressing before it is a drag, in pixels. */\nexport const CUBE_HOLD_SLOP = 10;\n\n/**\n * pressing and holding a piece (principle 31): a long press, a right click or the menu key raise\n * one `cubeHeld`. a second finger (a pinch) or a drag never does, and the click that follows a hold\n * is swallowed so the piece does not also open. what a hold opens is the app's.\n *\n * it only reports: it never stops or prevents the pointer events, so a swipe or a pinch on the same\n * element keeps working.\n */\n@Directive({\n selector: '[cubeHold]',\n host: {\n '[style.user-select]': 'cubeHoldDisabled() ? null : \"none\"',\n '[style.-webkit-user-select]': 'cubeHoldDisabled() ? null : \"none\"',\n '[style.-webkit-touch-callout]': 'cubeHoldDisabled() ? null : \"none\"',\n '(pointerdown)': 'press($event)',\n '(pointermove)': 'moved($event)',\n '(pointerup)': 'lift($event)',\n '(pointercancel)': 'lift($event)',\n '(pointerleave)': 'lift($event)',\n '(contextmenu)': 'menu($event)',\n '(keydown)': 'pressFired = false; swallow = false',\n },\n})\nexport class CubeHold {\n /** no hold at all: the listeners do nothing and the browser's own menu stays. */\n readonly cubeHoldDisabled = input(false);\n /** how long a press is held before it is a hold, in milliseconds. */\n readonly cubeHoldMs = input(CUBE_HOLD_MS);\n /** how far the press may move before it is a drag instead, in pixels. */\n readonly cubeHoldSlop = input(CUBE_HOLD_SLOP);\n /** a short buzz (`navigator.vibrate(12)`) when it holds, where the device can. */\n readonly cubeHoldBuzz = input(true);\n\n /** the piece was held. */\n readonly cubeHeld = output<CubeHeld>();\n\n private readonly element = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private timer: ReturnType<typeof setTimeout> | undefined;\n /** where the press started; null while nothing may become a hold. */\n private start: { x: number; y: number } | null = null;\n /** the pointers down on the element: two or more are a pinch. */\n private readonly pointers = new Set<number>();\n /** this press already held, so the phone's own contextmenu after it is not a second hold. */\n protected pressFired = false;\n /** a hold swallows the one click that follows it. */\n protected swallow = false;\n\n constructor() {\n // caught first, before the element's own (click), so a hold never also opens the piece.\n const swallow = (e: Event) => {\n if (!this.swallow) return;\n this.swallow = false;\n e.preventDefault();\n e.stopImmediatePropagation();\n };\n this.element.addEventListener('click', swallow, true);\n inject(DestroyRef).onDestroy(() => {\n clearTimeout(this.timer);\n this.element.removeEventListener('click', swallow, true);\n });\n }\n\n protected press(e: PointerEvent): void {\n this.pointers.add(e.pointerId);\n this.cancel();\n this.pressFired = false;\n this.swallow = false;\n // a second finger is a pinch, and only the main button holds.\n if (this.cubeHoldDisabled() || this.pointers.size > 1 || e.button > 0) return;\n this.start = { x: e.clientX, y: e.clientY };\n this.timer = setTimeout(() => this.fire('press', e), this.cubeHoldMs());\n }\n\n protected moved(e: PointerEvent): void {\n if (!this.start) return;\n if (Math.hypot(e.clientX - this.start.x, e.clientY - this.start.y) > this.cubeHoldSlop()) {\n this.cancel();\n }\n }\n\n protected lift(e: PointerEvent): void {\n this.pointers.delete(e.pointerId);\n this.cancel();\n }\n\n /** a right click, a phone's own long press, the menu key or shift+f10. */\n protected menu(e: Event): void {\n if (this.cubeHoldDisabled()) return;\n e.preventDefault();\n if (this.pressFired) return;\n this.fire('menu', e);\n }\n\n private fire(via: CubeHeld['via'], event: Event): void {\n this.cancel();\n if (this.cubeHoldDisabled()) return;\n this.pressFired = via === 'press';\n this.swallow = true;\n if (this.cubeHoldBuzz()) globalThis.navigator?.vibrate?.(12);\n this.cubeHeld.emit({ via, element: this.element, event });\n }\n\n private cancel(): void {\n clearTimeout(this.timer);\n this.timer = undefined;\n this.start = null;\n }\n}\n","import { Directive, input, output } from '@angular/core';\n\n/** what a pinch reports: which way the fingers went, where, how it came and the event that ended it. */\nexport interface CubePinched {\n /** `in`: fingers apart, going into the piece under them; `out`: fingers together, one level out. */\n way: 'in' | 'out';\n /** the element under the pinch (between two fingers, under the pointer); null when none. */\n at: Element | null;\n /**\n * `touch`: two fingers on a screen; `wheel`: ctrl and the wheel, which is how chrome, edge and\n * firefox send a trackpad's pinch; `gesture`: safari's own gesture events for a trackpad's pinch.\n */\n via: 'touch' | 'wheel' | 'gesture';\n /** the event that decided it: the `pointerup`, the first `wheel` of the stream, the `gestureend`. */\n event: Event;\n}\n\n/** two fingers this much further apart than they started is a pinch in (cubes', mosaic's, anlat's). */\nexport const CUBE_PINCH_APART = 1.25;\n/** two fingers this much closer than they started is a pinch out. */\nexport const CUBE_PINCH_TOGETHER = 0.8;\n/**\n * a trackpad's pinch is a stream of ctrl + wheel events for as long as the fingers move; the stream\n * is one gesture until the wheel has been quiet this long, in milliseconds (mosaic's, 3 nov 2026).\n */\nexport const CUBE_WHEEL_QUIET_MS = 250;\n\n/**\n * whether a ctrl + wheel event at `now` starts a new gesture, given when the last one of the stream\n * came (`-Infinity` for never). pure, so an app with a wheel of its own (a puzzle, a canvas) keeps\n * the same rule.\n */\nexport function startsWheelGesture(lastAt: number, now: number, quietMs = CUBE_WHEEL_QUIET_MS): boolean {\n return now - lastAt >= quietMs;\n}\n\n/**\n * the stream a trackpad's pinch is, kept for the whole page and not per directive: the level a\n * pinch steps to is a new screen with a directive of its own, and the rest of the same pinch must\n * not step it again (two levels out for one pinch on a mac, found in mosaic on 3 nov 2026).\n */\nconst stream = {\n wheelAt: -Infinity,\n gestureAt: -Infinity,\n /** the wheel event the page heard last, and when the one before it came. */\n heard: null as Event | null,\n heardAfter: -Infinity,\n /** until when the page's ctrl and wheel belong to a pinch a `cubePinch` took. */\n ownedUntil: -Infinity,\n};\n\n/**\n * the page hears every ctrl and wheel, not only the ones that reach a `cubePinch`: while the screen\n * a pinch stepped to is coming in (a view transition, an animation), the events land on the root,\n * outside any directive. heard here, they keep the stream going, so the rest of that pinch is no\n * second step, and they keep the browser's page zoom away. found adopting 0.3.0 in anlat, whose\n * levels come in through view transitions: one long pinch out stepped three levels.\n */\nlet listening = false;\nfunction listenToThePage(quietMs: number): void {\n const w = globalThis.window;\n if (listening || !w?.addEventListener) return;\n listening = true;\n w.addEventListener(\n 'wheel',\n (e: WheelEvent) => {\n if (!e.ctrlKey) return;\n const now = performance.now();\n stream.heard = e;\n stream.heardAfter = stream.wheelAt;\n stream.wheelAt = now;\n if (now - stream.heardAfter < quietMs && now < stream.ownedUntil + quietMs) {\n stream.ownedUntil = now;\n e.preventDefault();\n }\n },\n { capture: true, passive: false },\n );\n}\n\n/**\n * the pinch (principle 25, two fingers together is one level out): fingers apart on a piece raise\n * one `cubePinched` with `way: 'in'`, fingers together one with `way: 'out'`. on a computer a\n * trackpad's pinch or ctrl and the wheel do the same, one level for one pinch however long it lasts.\n *\n * it only reports. it never routes or zooms: what `in` opens (most often a tap on the tile at `at`)\n * and where `out` goes (the way i came) stay in the app. it keeps the browser's own page zoom away\n * from a ctrl + wheel and a safari gesture on its element, and lets every other event through.\n */\n@Directive({\n selector: '[cubePinch]',\n host: {\n '(pointerdown)': 'down($event)',\n '(pointermove)': 'move($event)',\n '(pointerup)': 'up($event)',\n '(pointercancel)': 'cancel($event)',\n '(wheel)': 'wheel($event)',\n '(gesturestart)': 'gestureStart($event)',\n '(gesturechange)': 'gestureChange($event)',\n '(gestureend)': 'gestureEnd($event)',\n },\n})\nexport class CubePinch {\n /** no pinch at all: the listeners do nothing and the browser zooms the page again. */\n readonly cubePinchDisabled = input(false);\n /** how quiet the wheel must be before a new pinch starts, in milliseconds. */\n readonly cubePinchQuietMs = input(CUBE_WHEEL_QUIET_MS);\n\n /** the fingers went apart (`in`) or together (`out`): once a pinch. */\n readonly cubePinched = output<CubePinched>();\n\n constructor() {\n listenToThePage(CUBE_WHEEL_QUIET_MS);\n }\n\n /** the pointers down on the element, by id, with where each is now. */\n private readonly pointers = new Map<number, { x: number; y: number }>();\n /** a two-finger pinch under way: how far apart the fingers started and what was between them. */\n private pinch: { distance: number; at: Element | null } | null = null;\n\n protected down(e: PointerEvent): void {\n if (this.cubePinchDisabled()) return;\n this.pointers.set(e.pointerId, { x: e.clientX, y: e.clientY });\n if (this.pointers.size !== 2) {\n // a third finger is no pinch\n this.pinch = null;\n return;\n }\n const [a, b] = [...this.pointers.values()];\n this.pinch = {\n distance: Math.max(1, Math.hypot(a.x - b.x, a.y - b.y)),\n at: pointAt((a.x + b.x) / 2, (a.y + b.y) / 2),\n };\n }\n\n protected move(e: PointerEvent): void {\n if (this.pointers.has(e.pointerId)) this.pointers.set(e.pointerId, { x: e.clientX, y: e.clientY });\n }\n\n /** the first finger to lift decides; the second has nothing left to say. */\n protected up(e: PointerEvent): void {\n if (this.pinch && this.pointers.size === 2 && this.pointers.has(e.pointerId)) {\n this.pointers.set(e.pointerId, { x: e.clientX, y: e.clientY });\n const [a, b] = [...this.pointers.values()];\n const ratio = Math.hypot(a.x - b.x, a.y - b.y) / this.pinch.distance;\n const at = this.pinch.at;\n this.pinch = null;\n if (ratio > CUBE_PINCH_APART) this.emit('in', at, 'touch', e);\n else if (ratio < CUBE_PINCH_TOGETHER) this.emit('out', at, 'touch', e);\n }\n this.pointers.delete(e.pointerId);\n }\n\n protected cancel(e: PointerEvent): void {\n this.pinch = null;\n this.pointers.delete(e.pointerId);\n }\n\n protected wheel(e: WheelEvent): void {\n if (this.cubePinchDisabled() || !e.ctrlKey) return;\n e.preventDefault();\n const now = performance.now();\n // the page heard it first (and moved the stream's end); else it is heard only here\n const lastAt = stream.heard === e ? stream.heardAfter : stream.wheelAt;\n const starts = startsWheelGesture(lastAt, now, this.cubePinchQuietMs());\n // every event of the stream moves its end, so a slow pinch stays one gesture\n stream.wheelAt = now;\n stream.ownedUntil = now;\n if (!starts || e.deltaY === 0) return;\n if (e.deltaY < 0) this.emit('in', pointAt(e.clientX, e.clientY), 'wheel', e);\n else this.emit('out', pointAt(e.clientX, e.clientY), 'wheel', e);\n }\n\n protected gestureStart(e: Event): void {\n if (this.cubePinchDisabled()) return;\n e.preventDefault();\n }\n\n protected gestureChange(e: Event): void {\n if (this.cubePinchDisabled()) return;\n e.preventDefault();\n }\n\n /** safari decides at the end of its gesture; a wheel stream that already decided wins. */\n protected gestureEnd(e: Event): void {\n if (this.cubePinchDisabled()) return;\n e.preventDefault();\n const now = performance.now();\n if (!startsWheelGesture(stream.wheelAt, now, this.cubePinchQuietMs())) return;\n if (!startsWheelGesture(stream.gestureAt, now, this.cubePinchQuietMs())) return;\n const g = e as Event & { scale?: number; clientX?: number; clientY?: number };\n const scale = g.scale ?? 1;\n const at = g.clientX === undefined || g.clientY === undefined ? null : pointAt(g.clientX, g.clientY);\n if (scale > CUBE_PINCH_APART) this.emit('in', at, 'gesture', e);\n else if (scale < CUBE_PINCH_TOGETHER) this.emit('out', at, 'gesture', e);\n else return;\n stream.gestureAt = now;\n }\n\n private emit(way: CubePinched['way'], at: Element | null, via: CubePinched['via'], event: Event): void {\n this.cubePinched.emit({ way, at, via, event });\n }\n}\n\nconst pointAt = (x: number, y: number): Element | null => globalThis.document?.elementFromPoint?.(x, y) ?? null;\n","import { DestroyRef, Directive, ElementRef, inject, input, output } from '@angular/core';\nimport { CUBE_HOLD_MS, CUBE_HOLD_SLOP, CubeHeld } from '../hold/cube-hold';\n\n/** the `data-drop` value of the element that means out: one level up (the app's ‹). */\nexport const CUBE_DROP_OUT = 'out';\n/** how far a lifted piece must travel before letting go is a drop, not a hold, in pixels. */\nexport const CUBE_CARRY_MOVE = 12;\n\n/** a piece lifted: the press was held, and it may now be carried. */\nexport interface CubeLifted {\n /** the carried piece, as `[cubeCarry]` names it. */\n piece: string;\n /** the element holding the directive (the tile left behind, faded). */\n element: HTMLElement;\n /** the ghost following the finger: a copy of the element, on `document.body`. */\n ghost: HTMLElement;\n}\n\n/** what the carried piece is over now: a `[data-drop]` element, or nothing. */\nexport interface CubeCarriedOver {\n piece: string;\n /** its `data-drop`, `'out'` for the ‹; null when over nothing a piece may land on. */\n onto: string | null;\n /** the `[data-drop]` element it is over, marked meanwhile; null over nothing. */\n target: HTMLElement | null;\n}\n\n/** a carried piece let go over a `[data-drop]` element. */\nexport interface CubeDropped {\n piece: string;\n /** the target's `data-drop`: a piece's key, or `'out'` (`CUBE_DROP_OUT`) for the ‹. */\n onto: string;\n /** the element it was let go over. */\n target: HTMLElement;\n}\n\n/**\n * how a carry ended: `dropped` (on a target), `held` (let go without moving: a hold), `nowhere`\n * (let go over nothing a piece lands on: it goes back), `cancelled` (two fingers, escape, a\n * cancelled touch, or the directive went away).\n */\nexport type CubeCarryEnd = 'dropped' | 'held' | 'nowhere' | 'cancelled';\n\n/** the classes and attributes the carry puts on the page while it carries; the app styles them. */\nexport const CUBE_CARRY_CLASSES = {\n /** on `document.body` while a piece is lifted. */\n carrying: 'cube-carrying',\n /** on the lifted piece's own element, which stays where it was. */\n lifted: 'cube-carry-lifted',\n /** on the ghost that follows the finger. */\n ghost: 'cube-carry-ghost',\n /** on the `[data-drop]` element the piece is over. */\n over: 'cube-carry-over',\n} as const;\n\n/** a touch that came this recently makes the mouse events and the phone's own menu after it echoes. */\nconst TOUCH_ECHO_MS = 800;\n\ninterface Press {\n x: number;\n y: number;\n touch: boolean;\n event: Event;\n timer?: ReturnType<typeof setTimeout>;\n lifted: boolean;\n moved: boolean;\n /** moved past the slop before the hold: a scroll or a swipe, never a hold. */\n scrolled: boolean;\n ghost?: HTMLElement;\n dx: number;\n dy: number;\n target: HTMLElement | null;\n /** the element's own opacity before it faded, put back after. */\n opacity?: string;\n}\n\n/**\n * carry and drop (selim, 3 november 2026, the grouping prototype's round 2): press and hold a piece,\n * and it lifts; carry it onto another piece and let go, and the app asks what the drop means (drop\n * it in, make them one). a hold that does not move is still a hold (`cubeHeld`, the context cube),\n * a tap stays a tap, and two fingers (a pinch) cancel.\n *\n * it holds as `cubeHold` does (`cubeHeld`, the same `CubeHeld`), so it replaces `cubeHold` on a\n * piece that can be carried: put one of the two on an element, never both. what it adds: at the\n * hold time (520 ms) the piece lifts, and a ghost of it follows the finger; the `[data-drop]`\n * element under the finger is marked; letting go there emits `cubeDropped` with `{ piece, onto }`,\n * where `onto` is that element's `data-drop` (`'out'` for the app's ‹). letting go without moving\n * the piece is the hold, said then. with `[cubeCarry]` empty (null or '') nothing lifts and it is\n * `cubeHold`: the hold is said at the hold time.\n *\n * mouse and touch both: touch events on a phone, as the prototype (pointer events lose the finger\n * to the page's scroll), the mouse's own events elsewhere. it says no words and draws only the\n * ghost; the hint, the sheet and the marks' look are the app's.\n */\n@Directive({\n selector: '[cubeCarry]',\n host: {\n '[style.user-select]': 'cubeCarryDisabled() ? null : \"none\"',\n '[style.-webkit-user-select]': 'cubeCarryDisabled() ? null : \"none\"',\n '[style.-webkit-touch-callout]': 'cubeCarryDisabled() ? null : \"none\"',\n '(touchstart)': 'touchStart($event)',\n '(mousedown)': 'mouseDown($event)',\n '(contextmenu)': 'menu($event)',\n '(dragstart)': 'noDrag($event)',\n '(keydown)': 'swallow = false',\n },\n})\nexport class CubeCarry {\n /** the piece this element carries (its key, as the app's `data-drop` names pieces); empty: none. */\n readonly cubeCarry = input<string | null | undefined>(null);\n /** no hold and no carry: the listeners do nothing and the browser's own menu stays. */\n readonly cubeCarryDisabled = input(false);\n /** how long a press is held before it lifts (or holds), in milliseconds. */\n readonly cubeHoldMs = input(CUBE_HOLD_MS);\n /** how far the press may move before the hold time and still hold, in pixels. */\n readonly cubeHoldSlop = input(CUBE_HOLD_SLOP);\n /** a short buzz when it lifts or holds, where the device can. */\n readonly cubeHoldBuzz = input(true);\n\n /** a hold: let go without moving after the hold time, a right click or the menu key. */\n readonly cubeHeld = output<CubeHeld>();\n /** the piece lifted at the hold time; the app shows its hint and names its ‹ the way out. */\n readonly cubeLifted = output<CubeLifted>();\n /** the piece is over another `[data-drop]` element now, or over none. */\n readonly cubeCarriedOver = output<CubeCarriedOver>();\n /** the piece was let go over a `[data-drop]` element. */\n readonly cubeDropped = output<CubeDropped>();\n /** a lift ended, however it ended: the app takes its hint away. after `cubeDropped` or `cubeHeld`. */\n readonly cubeCarryEnd = output<CubeCarryEnd>();\n\n private readonly element = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n private press: Press | null = null;\n private lastTouch = 0;\n /** the click after a hold or a carry is swallowed, so the piece does not also open. */\n protected swallow = false;\n private readonly doc = this.element.ownerDocument;\n private readonly listening: [string, EventListener, AddEventListenerOptions][] = [];\n\n constructor() {\n const swallow = (e: Event) => {\n if (!this.swallow) return;\n this.swallow = false;\n e.preventDefault();\n e.stopImmediatePropagation();\n };\n this.element.addEventListener('click', swallow, true);\n inject(DestroyRef).onDestroy(() => {\n this.cancel();\n this.element.removeEventListener('click', swallow, true);\n });\n }\n\n /** whether a piece is being carried (lifted) by this element now. */\n get carrying(): boolean {\n return !!this.press?.lifted;\n }\n\n protected touchStart(e: TouchEvent): void {\n this.lastTouch = Date.now();\n if (this.cubeCarryDisabled()) return;\n if (e.touches.length !== 1) {\n this.cancel();\n return;\n }\n const t = e.touches[0];\n this.begin(t.clientX, t.clientY, true, e);\n }\n\n protected mouseDown(e: MouseEvent): void {\n if (this.cubeCarryDisabled() || e.button !== 0) return;\n if (Date.now() - this.lastTouch < TOUCH_ECHO_MS) return;\n this.begin(e.clientX, e.clientY, false, e);\n }\n\n /** a right click, the menu key or shift+f10 hold at once; a phone's own long press is ours. */\n protected menu(e: Event): void {\n if (this.cubeCarryDisabled()) return;\n e.preventDefault();\n if (Date.now() - this.lastTouch < TOUCH_ECHO_MS || this.press) return;\n this.fireHeld('menu', e);\n }\n\n /** the browser's own drag of a link or a picture would take the mouse away from the carry. */\n protected noDrag(e: Event): void {\n if (!this.cubeCarryDisabled()) e.preventDefault();\n }\n\n private begin(x: number, y: number, touch: boolean, event: Event): void {\n this.cancel();\n this.swallow = false;\n const p: Press = {\n x,\n y,\n touch,\n event,\n lifted: false,\n moved: false,\n scrolled: false,\n dx: 0,\n dy: 0,\n target: null,\n };\n this.press = p;\n p.timer = setTimeout(() => this.lift(), this.cubeHoldMs());\n if (touch) {\n this.listen('touchmove', (ev) => this.touchMove(ev as TouchEvent), { passive: false });\n this.listen('touchend', (ev) => this.touchEnd(ev as TouchEvent), { passive: false });\n this.listen('touchcancel', () => this.cancel(), {});\n // a second finger anywhere is a pinch\n this.listen('touchstart', (ev) => (ev as TouchEvent).touches.length > 1 && this.cancel(), {\n passive: true,\n });\n } else {\n this.listen(\n 'mousemove',\n (ev) => this.moveTo((ev as MouseEvent).clientX, (ev as MouseEvent).clientY),\n {},\n );\n this.listen('mouseup', () => this.end(), {});\n }\n // escape while a piece is lifted puts it back, and does nothing else (not the app's way out)\n this.listen(\n 'keydown',\n (ev) => {\n if ((ev as KeyboardEvent).key !== 'Escape' || !this.press) return;\n if (this.press.lifted) ev.stopPropagation();\n this.cancel();\n },\n { capture: true },\n );\n }\n\n private touchMove(e: TouchEvent): void {\n if (!this.press) return;\n if (e.touches.length > 1) {\n this.cancel();\n return;\n }\n if (this.press.lifted && e.cancelable) e.preventDefault();\n const t = e.touches[0];\n if (t) this.moveTo(t.clientX, t.clientY);\n }\n\n private touchEnd(e: TouchEvent): void {\n if (!this.press || e.touches.length > 0) return;\n // a lifted piece let go is never also a tap on what is under it\n if (this.press.lifted && e.cancelable) e.preventDefault();\n this.end();\n }\n\n private lift(): void {\n const p = this.press;\n if (!p) return;\n p.timer = undefined;\n const piece = this.cubeCarry();\n if (!piece) {\n // nothing to carry: this is cubeHold, and the hold is said now\n this.forget();\n this.fireHeld('press', p.event);\n return;\n }\n p.lifted = true;\n this.swallow = true;\n if (this.cubeHoldBuzz()) globalThis.navigator?.vibrate?.(12);\n const r = this.element.getBoundingClientRect();\n const ghost = this.element.cloneNode(true) as HTMLElement;\n ghost.removeAttribute('data-drop');\n ghost.removeAttribute('id');\n ghost.querySelectorAll('[id],[data-drop]').forEach((el) => {\n el.removeAttribute('id');\n el.removeAttribute('data-drop');\n });\n ghost.classList.add(CUBE_CARRY_CLASSES.ghost);\n ghost.setAttribute('aria-hidden', 'true');\n Object.assign(ghost.style, {\n position: 'fixed',\n zIndex: 'var(--cube-carry-ghost-z, 1000)',\n pointerEvents: 'none',\n margin: '0',\n boxSizing: 'border-box',\n width: r.width + 'px',\n height: r.height + 'px',\n left: r.left + 'px',\n top: r.top + 'px',\n transform: 'var(--cube-carry-ghost-transform, scale(1.08) rotate(-2deg))',\n boxShadow: 'var(--cube-carry-ghost-shadow, 0 14px 32px rgb(0 0 0 / 0.28))',\n opacity: 'var(--cube-carry-ghost-opacity, 0.95)',\n } satisfies Partial<CSSStyleDeclaration>);\n p.dx = p.x - r.left;\n p.dy = p.y - r.top;\n p.ghost = ghost;\n this.doc.body.appendChild(ghost);\n this.element.classList.add(CUBE_CARRY_CLASSES.lifted);\n p.opacity = this.element.style.opacity;\n this.element.style.opacity = 'var(--cube-carry-lifted-opacity, 0.3)';\n this.doc.body.classList.add(CUBE_CARRY_CLASSES.carrying);\n this.cubeLifted.emit({ piece, element: this.element, ghost });\n }\n\n private moveTo(x: number, y: number): void {\n const p = this.press;\n if (!p) return;\n if (!p.lifted) {\n // moving before the hold time is a scroll or a swipe: never a hold, and the tap stays a tap\n if (Math.hypot(x - p.x, y - p.y) > this.cubeHoldSlop()) {\n clearTimeout(p.timer);\n p.timer = undefined;\n p.scrolled = true;\n }\n return;\n }\n if (!p.ghost) return;\n if (Math.hypot(x - p.x, y - p.y) > CUBE_CARRY_MOVE) p.moved = true;\n p.ghost.style.left = x - p.dx + 'px';\n p.ghost.style.top = y - p.dy + 'px';\n const under = this.doc.elementFromPoint?.(x, y) ?? null;\n let target = (under?.closest('[data-drop]') as HTMLElement | null) ?? null;\n if (target && (target === this.element || this.element.contains(target))) target = null;\n if (target !== p.target) {\n p.target?.classList.remove(CUBE_CARRY_CLASSES.over);\n p.target = target;\n target?.classList.add(CUBE_CARRY_CLASSES.over);\n this.cubeCarriedOver.emit({\n piece: this.cubeCarry() ?? '',\n onto: target?.dataset['drop'] ?? null,\n target,\n });\n }\n }\n\n private end(): void {\n const p = this.press;\n if (!p) return;\n this.forget();\n if (!p.lifted) return; // a tap (its click comes on its own) or a scroll\n const piece = this.cubeCarry() ?? '';\n this.clean(p);\n if (!p.moved) {\n this.fireHeld('press', p.event, false);\n this.cubeCarryEnd.emit('held');\n return;\n }\n if (!p.target) {\n this.cubeCarryEnd.emit('nowhere');\n return;\n }\n this.cubeDropped.emit({ piece, onto: p.target.dataset['drop'] ?? '', target: p.target });\n this.cubeCarryEnd.emit('dropped');\n }\n\n /** two fingers, escape, a cancelled touch: whatever was lifted goes back, nothing is said but the end. */\n cancel(): void {\n const p = this.press;\n if (!p) return;\n this.forget();\n if (p.lifted) {\n this.clean(p);\n this.cubeCarryEnd.emit('cancelled');\n }\n }\n\n private clean(p: Press): void {\n p.ghost?.remove();\n p.target?.classList.remove(CUBE_CARRY_CLASSES.over);\n this.element.classList.remove(CUBE_CARRY_CLASSES.lifted);\n if (p.opacity !== undefined) this.element.style.opacity = p.opacity;\n this.doc.body.classList.remove(CUBE_CARRY_CLASSES.carrying);\n }\n\n /** the press is over: its timer and the page's listeners go. */\n private forget(): void {\n if (this.press) clearTimeout(this.press.timer);\n this.press = null;\n for (const [type, fn, opts] of this.listening.splice(0))\n this.doc.removeEventListener(type, fn, opts);\n }\n\n private listen(type: string, fn: EventListener, opts: AddEventListenerOptions): void {\n this.doc.addEventListener(type, fn, opts);\n this.listening.push([type, fn, opts]);\n }\n\n private fireHeld(via: CubeHeld['via'], event: Event, buzz = true): void {\n this.swallow = true;\n if (buzz && this.cubeHoldBuzz()) globalThis.navigator?.vibrate?.(12);\n this.cubeHeld.emit({ via, element: this.element, event });\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\n\n/** the views a cube can be shown in, each drawn as its own shape. */\nexport type CubeIconView = 'square' | 'one' | 'two' | 'three' | 'four' | 'grid-4x5' | 'grid-3x6';\n\n/** what a tile of a cube the app keeps is about (a context cube's parts and their choices). */\nexport type CubeIconName =\n | 'names'\n | 'name'\n | 'change'\n | 'move'\n | 'place'\n | 'whose'\n | 'library'\n | 'mine'\n | 'shown'\n | 'hidden'\n | 'view'\n | 'sort'\n | 'kept'\n | 'face'\n | 'added'\n | 'up'\n | 'down'\n | 'plus'\n | CubeIconView;\n\n/** every icon, in the order above. */\nexport const CUBE_ICON_NAMES: readonly CubeIconName[] = [\n 'names',\n 'name',\n 'change',\n 'move',\n 'place',\n 'whose',\n 'library',\n 'mine',\n 'shown',\n 'hidden',\n 'view',\n 'sort',\n 'kept',\n 'face',\n 'added',\n 'up',\n 'down',\n 'plus',\n 'square',\n 'one',\n 'two',\n 'three',\n 'four',\n 'grid-4x5',\n 'grid-3x6',\n];\n\n/** a view's icon is its own shape: the cells of one, two… across, a fixed grid, the square. */\nconst SHAPES: Record<CubeIconView, { cols: number; rows: number }> = {\n square: { cols: 3, rows: 3 },\n one: { cols: 1, rows: 3 },\n two: { cols: 2, rows: 3 },\n three: { cols: 3, rows: 3 },\n four: { cols: 4, rows: 3 },\n 'grid-4x5': { cols: 4, rows: 5 },\n 'grid-3x6': { cols: 3, rows: 6 },\n};\n\nexport interface CubeIconCell {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/**\n * the cells a view's icon draws in its 24 × 24 box, or null when the icon is not a view. one across\n * is a list, so its cells are rows.\n */\nexport function cubeIconCells(icon: CubeIconName): CubeIconCell[] | null {\n const shape = SHAPES[icon as CubeIconView];\n if (!shape) return null;\n const { cols, rows } = shape;\n const gap = 1.6;\n const size = Math.min((17 - gap * (cols - 1)) / cols, (17 - gap * (rows - 1)) / rows);\n const w = cols * size + gap * (cols - 1);\n const h = rows * size + gap * (rows - 1);\n const out: CubeIconCell[] = [];\n for (let r = 0; r < rows; r++)\n for (let c = 0; c < cols; c++)\n out.push({\n x: cols === 1 ? 3.5 : 12 - w / 2 + c * (size + gap),\n y: 12 - h / 2 + r * (size + gap),\n w: cols === 1 ? 17 : size,\n h: size,\n });\n return out;\n}\n\n/**\n * an icon on a tile of a cube the app keeps (a context cube and its parts), in place of a small\n * cube: such cubes hold no pieces, so their tiles show what they are about.\n *\n * its look comes from css variables (`--cube-icon-*`), each with a light fallback; `tokens/light.css`\n * and `tokens/dark.css` set them all. it says nothing: the tile's words come from the app.\n */\n@Component({\n selector: 'cube-icon',\n template: `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n @if (cells(); as cs) {\n @for (c of cs; track $index) {\n <rect\n class=\"cell\"\n [attr.x]=\"c.x\"\n [attr.y]=\"c.y\"\n [attr.width]=\"c.w\"\n [attr.height]=\"c.h\"\n rx=\"0.8\"\n />\n }\n }\n @switch (icon()) {\n @case ('view') {\n <rect x=\"4\" y=\"4\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13\" y=\"4\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"4\" y=\"13\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13\" y=\"13\" width=\"7\" height=\"7\" rx=\"1.5\" />\n }\n @case ('sort') {\n <path d=\"M8 19V5M4.5 8.5 8 5l3.5 3.5M16 5v14M12.5 15.5 16 19l3.5-3.5\" />\n }\n @case ('kept') {\n <path d=\"M5 7h14M5 12h14M5 17h9\" />\n }\n @case ('face') {\n <path d=\"M12 3.5 20 8v8l-8 4.5L4 16V8Z\" />\n <path d=\"M4 8l8 4.5L20 8M12 12.5v8\" />\n }\n @case ('added') {\n <circle cx=\"12\" cy=\"12\" r=\"8\" />\n <path d=\"M12 7.5V12l3 2\" />\n }\n @case ('up') {\n <path d=\"M12 19V5M6.5 10.5 12 5l5.5 5.5\" />\n }\n @case ('plus') {\n <path d=\"M12 5v14M5 12h14\" />\n }\n @case ('down') {\n <path d=\"M12 5v14M6.5 13.5 12 19l5.5-5.5\" />\n }\n @case ('names') {\n <path d=\"M3.5 12.5 11 5h8v8l-7.5 7.5a1.5 1.5 0 0 1-2.1 0L3.5 14.6a1.5 1.5 0 0 1 0-2.1Z\" />\n <circle cx=\"15.2\" cy=\"8.8\" r=\"1.4\" />\n }\n @case ('name') {\n <path d=\"M5 18 9.5 6h1L15 18M6.6 14h6.8\" />\n <path\n d=\"M17 11.5c1.6-1.2 3.5-.5 3.5 1.4V18M20.5 14.6c-2.6-.3-4 .4-4 1.8 0 1.9 2.7 2 4 .3\"\n />\n }\n @case ('change') {\n <path d=\"M4 20h4L19 9a2.8 2.8 0 0 0-4-4L4 16v4Z\" />\n <path d=\"M13.5 6.5l4 4\" />\n }\n @case ('move') {\n <path\n d=\"M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-1\"\n />\n <path d=\"M2.5 13H12M9 10l3 3-3 3\" />\n }\n @case ('place') {\n <path\n d=\"M4 8V6a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8Z\"\n />\n }\n @case ('whose') {\n <circle cx=\"9\" cy=\"8\" r=\"3.2\" />\n <path d=\"M3 19c.6-3.4 3-5.2 6-5.2s5.4 1.8 6 5.2\" />\n <path d=\"M16 5.5a3 3 0 0 1 0 5.6M18.5 14.4c1.4.8 2.3 2.4 2.5 4.6\" />\n }\n @case ('library') {\n <path d=\"M4 5h4v15H4zM10 5h4v15h-4z\" />\n <path d=\"m16 6 3.6-1 3 14.4-3.6 1z\" />\n }\n @case ('mine') {\n <circle cx=\"12\" cy=\"8\" r=\"3.4\" />\n <path d=\"M5 20c.7-4 3.5-6 7-6s6.3 2 7 6\" />\n }\n @case ('shown') {\n <path d=\"M3 12s3.2-6 9-6 9 6 9 6-3.2 6-9 6-9-6-9-6Z\" />\n <circle cx=\"12\" cy=\"12\" r=\"2.6\" />\n }\n @case ('hidden') {\n <path d=\"M3 12s3.2-6 9-6c1.6 0 3 .45 4.2 1.1M21 12s-3.2 6-9 6c-1.6 0-3-.45-4.2-1.1\" />\n <path d=\"M4.5 19.5 19.5 4.5\" />\n }\n }\n </svg>\n `,\n styles: `\n :host {\n display: inline-block;\n width: var(--cube-icon-size, 34px);\n height: var(--cube-icon-size, 34px);\n line-height: 0;\n }\n svg {\n width: 100%;\n height: 100%;\n fill: none;\n stroke: var(--cube-icon-stroke, #1f2a26);\n stroke-width: var(--cube-icon-stroke-width, 1.7);\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n .cell {\n fill: var(--cube-icon-stroke, #1f2a26);\n stroke: none;\n opacity: var(--cube-icon-cell-opacity, 0.8);\n }\n :host(.in-use) svg {\n stroke: var(--cube-icon-in-use, #3b5a4c);\n }\n :host(.in-use) .cell {\n fill: var(--cube-icon-in-use, #3b5a4c);\n }\n `,\n host: { '[class.in-use]': 'inUse()' },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CubeIcon {\n /** what the tile is about. */\n readonly icon = input.required<CubeIconName>();\n /** the one in use among its siblings: drawn in the in-use colour. */\n readonly inUse = input(false);\n\n protected readonly cells = computed(() => cubeIconCells(this.icon()));\n}\n","import { InjectionToken } from '@angular/core';\nimport { Direction, ViewKey } from './arrange';\nimport type { WhereWords } from './where';\n\n/*\n * the context cube: behind every piece sits a second cube, the app's, where it keeps how the piece\n * is named, shown and kept. pressing and holding a piece walks into it (principle 31; cubes calls it\n * the own cube, decisions 39 and 40). this is its shape only: each app fills it from its own data\n * through a `ContextCubeSource`, and gives every word through `ContextWords`.\n */\n\n/**\n * the parts a context cube can have. the seven are the ones cubes found, and where (one piece in\n * many places, 0.3.0); an app may add its own, any string, and they come after the known ones.\n */\nexport type ContextPartKey =\n 'names' | 'change' | 'view' | 'sort' | 'move' | 'where' | 'whose' | 'hide' | (string & {});\n\n/**\n * cubes' rows: how it is called (names, change), how it is shown (view, sort), what i do with it\n * (move, where, whose, hide).\n */\nexport const CONTEXT_PART_ORDER: readonly ContextPartKey[] = [\n 'names',\n 'change',\n 'view',\n 'sort',\n 'move',\n 'where',\n 'whose',\n 'hide',\n];\n\n/** the parts in their rows; parts an app added come last, in the order it gave them. twice is once. */\nexport function orderParts(parts: readonly ContextPartKey[]): ContextPartKey[] {\n const unique = [...new Set(parts)];\n const known = CONTEXT_PART_ORDER.filter((p) => unique.includes(p));\n return [...known, ...unique.filter((p) => !CONTEXT_PART_ORDER.includes(p))];\n}\n\n/** one tile of a level. its title and line always come from the app. */\nexport interface ContextTile<D = unknown> {\n /** unique among its level. */\n key: string;\n title: string;\n line?: string | null;\n /** the icon's name: a part, a view key, a direction, or one of the app's. */\n icon: string;\n /** the one in use among its siblings (the name in use, shown or hidden, the view). */\n inUse?: boolean;\n /** drawn quietly: something that can be read but not used. */\n pale?: boolean;\n /** the plus: keeps something new beside the others, always last. */\n adds?: boolean;\n /** what the tile stands for, for the app's own `pick`. */\n data?: D;\n /**\n * a way inside it beside the tap (›): the path `<cube-context>` enters when the › is pressed,\n * while a tap on the tile still asks the source's `pick` (where: a tap stands it there, › looks\n * inside). none by default.\n */\n zoom?: string[] | null;\n /** the ›'s label for a screen reader, the app's words; the tile's title by default. */\n zoomLabel?: string | null;\n}\n\n/** where in the context cube one is: [] is its top (its parts), ['names'] a part, ['sort', by] deeper. */\nexport type ContextPath = readonly string[];\n\n/** what a pick does: walk into a deeper level, end the journey, step one level out, or nothing. */\nexport type ContextPick =\n { kind: 'enter'; path: string[] } | { kind: 'done' } | { kind: 'out' } | { kind: 'stay' };\n\n/** what an app gives for its own held type `T`: a piece, a cube, a to-do, a level. */\nexport interface ContextCubeSource<T = unknown> {\n /** the parts this held thing has, in any order (`orderParts` puts them in rows). */\n parts(held: T): ContextPartKey[];\n /** the tiles of one level, or null when that path does not exist for it. */\n level(held: T, path: ContextPath): ContextTile[] | null;\n /** a tile was tapped at that path. */\n pick(held: T, path: ContextPath, tile: ContextTile): ContextPick | Promise<ContextPick>;\n}\n\n/** a title and its line, in the app's language. */\nexport interface ContextWord {\n title: string;\n line?: string | null;\n}\n\n/** a name a piece has had, as the names level lists it. */\nexport interface ContextName {\n name: string;\n /** the one in use. */\n current: boolean;\n /** the day it was given, as the app keeps it. */\n on?: string | null;\n /** whose hands gave it. */\n by?: string | null;\n /** whether it was ever in use, or only kept beside. */\n used?: boolean;\n}\n\n/** every word the context cube shows. the package ships none. */\nexport interface ContextWords {\n /** each part's title and line; a part with no word has an empty title. */\n parts: Partial<Record<ContextPartKey, ContextWord>>;\n /** each view's name. */\n views: Partial<Record<ViewKey, ContextWord>>;\n /** the two directions of a sort, when a sort option has none of its own. */\n directions: Record<Direction, ContextWord>;\n /** the two pieces of hide. */\n hide: { shown: ContextWord; hidden: ContextWord };\n /** the plus among the names, and the line under each name (its day and hands). */\n names: { another: ContextWord; line?: (name: ContextName) => string | null };\n /** said on the one in use, when the app wants it said. */\n inUse?: string;\n /** where's title and line for each place (`whereLevel`); the place's name and no line without. */\n where?: WhereWords;\n}\n\n/** the app's source of context cubes. */\nexport const CONTEXT_CUBE_SOURCE = new InjectionToken<ContextCubeSource<any>>(\n 'CONTEXT_CUBE_SOURCE',\n);\n\n/** the app's words for the context cube. */\nexport const CONTEXT_CUBE_WORDS = new InjectionToken<ContextWords>('CONTEXT_CUBE_WORDS');\n\n/** what the top level shows of a part now: the view in use, the name, shown or hidden. */\nexport interface PartNow {\n line?: string | null;\n icon?: string;\n}\n\n/**\n * the icon a part's tile shows when the app gives none of what it holds now. most parts are drawn\n * by their own name; hide has no icon of its own and shows shown (the eye), since a piece is in\n * sight until it is hidden. an app passes `now.hide.icon` (`shown` or `hidden`) to say which. where\n * is drawn as a place.\n */\nexport const PART_ICONS: Partial<Record<ContextPartKey, string>> = {\n hide: 'shown',\n where: 'place',\n};\n\n/** the top of a context cube: its parts in rows, each with its word and, when given, what it holds now. */\nexport function partsLevel(\n parts: readonly ContextPartKey[],\n words: ContextWords,\n now: Partial<Record<ContextPartKey, PartNow>> = {},\n): ContextTile<ContextPartKey>[] {\n return orderParts(parts).map((p) => ({\n key: p,\n title: words.parts[p]?.title ?? '',\n line: now[p]?.line !== undefined ? now[p]?.line : (words.parts[p]?.line ?? null),\n icon: now[p]?.icon ?? PART_ICONS[p] ?? p,\n data: p,\n }));\n}\n","/*\n * how a cube's pieces are laid out and in what order they come, moved from cubes\n * (`core/world/arrange.ts`, design decision 40). both change the view only, never the cube. the\n * words for each view and each direction come from the app (`ContextWords`).\n */\n\n/** the ways a cube's square can be laid out: the square first (cubes decision 23), then the rest. */\nexport type ViewKey = 'square' | 'one' | 'two' | 'three' | 'four' | 'grid-4x5' | 'grid-3x6';\n\n/** every view, in the order they are offered. */\nexport const VIEW_KEYS: readonly ViewKey[] = [\n 'square',\n 'one',\n 'two',\n 'three',\n 'four',\n 'grid-4x5',\n 'grid-3x6',\n];\n\nexport const isView = (v: unknown): v is ViewKey => VIEW_KEYS.includes(v as ViewKey);\n\n/** columns and rows of a layout holding this many; every row is full, open places outlined. */\nexport interface Grid {\n cols: number;\n rows: number;\n}\n\nexport function gridFor(view: ViewKey, count: number): Grid {\n const n = Math.max(1, count);\n switch (view) {\n case 'square': {\n const side = Math.max(1, Math.ceil(Math.sqrt(n)));\n return { cols: side, rows: side };\n }\n case 'one':\n case 'two':\n case 'three':\n case 'four': {\n const cols = { one: 1, two: 2, three: 3, four: 4 }[view];\n return { cols, rows: Math.ceil(n / cols) };\n }\n case 'grid-4x5':\n case 'grid-3x6': {\n const [cols, rows] = view === 'grid-4x5' ? [4, 5] : [3, 6];\n return { cols, rows: rows * Math.ceil(n / (cols * rows)) };\n }\n }\n}\n\n/** up is the face's own order (a to z, oldest first, its first colour first); down the other way. */\nexport type Direction = 'up' | 'down';\n\n/** what an item is sorted by: text, a number, or nothing found (not known yet). */\nexport type SortValue = string | number | null | undefined;\n\n/**\n * how text is compared: `natural` reads numbers inside text as numbers (`moment 2` before\n * `moment 10`), as a person reads them; `plain` compares letter by letter (`moment 10` first).\n * both are kept: natural is the default, an app may offer plain (decision of 2026-11-02).\n */\nexport type TextOrder = 'natural' | 'plain';\n\n/** the ways text can be compared, the default first. */\nexport const TEXT_ORDERS: readonly TextOrder[] = ['natural', 'plain'];\n\n/**\n * items in the order a sort asks for. `by` reads what each item is sorted by; numbers are compared\n * as numbers, text in the reader's language, numbers inside it as numbers (`text`, natural by\n * default; `plain` compares letter by letter). an item with nothing found (empty text, `NaN`) is\n * not known yet and comes last in both directions (empty is the point, never hidden). ties keep\n * the items' own order.\n */\nexport function sortItems<T>(\n items: readonly T[],\n by: (item: T) => SortValue,\n dir: Direction,\n text: TextOrder = 'natural',\n): T[] {\n const sign = dir === 'down' ? -1 : 1;\n const known = (v: SortValue): v is string | number =>\n v !== null && v !== undefined && v !== '' && !(typeof v === 'number' && Number.isNaN(v));\n const collator = new Intl.Collator(undefined, { numeric: text === 'natural' });\n const compare = (a: string | number, b: string | number): number =>\n typeof a === 'number' && typeof b === 'number' ? a - b : collator.compare(String(a), String(b));\n return items\n .map((item, at) => ({ item, at, value: by(item) }))\n .sort((a, b) => {\n const ka = known(a.value);\n const kb = known(b.value);\n if (!ka || !kb) return Number(!ka) - Number(!kb) || a.at - b.at;\n return sign * compare(a.value as string | number, b.value as string | number) || a.at - b.at;\n })\n .map((x) => x.item);\n}\n","import { Direction, VIEW_KEYS, ViewKey } from './arrange';\nimport { ContextName, ContextTile, ContextWord, ContextWords } from './context-cube';\n\n/*\n * the levels every app's context cube shares, as pure functions: names, hide, view and sort. each\n * returns the tiles of one level; what a tap does stays with the app (its `pick`), read from the\n * tile's `data`.\n */\n\n/** what a names tile holds: a name, or the plus. */\nexport type NamesData = { name: ContextName } | { another: true };\n\n/**\n * every name it has had: the one in use first, then the rest newest first (the names come oldest\n * first, as they were given). when the app allows it, a plus keeps a new one beside it without\n * using it.\n */\nexport function namesLevel(\n names: readonly ContextName[],\n words: ContextWords,\n opts: { canAdd?: boolean } = {},\n): ContextTile<NamesData>[] {\n const listed = [...names.filter((n) => n.current), ...names.filter((n) => !n.current).reverse()];\n const tiles: ContextTile<NamesData>[] = listed.map((n, i) => ({\n key: `name:${i}:${n.name}`,\n title: n.name,\n line: words.names.line?.(n) ?? null,\n icon: 'name',\n inUse: n.current,\n data: { name: n },\n }));\n if (opts.canAdd)\n tiles.push({\n key: 'name:+',\n title: words.names.another.title,\n line: words.names.another.line ?? null,\n icon: 'plus',\n adds: true,\n data: { another: true },\n });\n return tiles;\n}\n\n/** hide: a cube of two pieces, shown and hidden, one in use; `data` is whether it hides. */\nexport function hideLevel(hidden: boolean, words: ContextWords): ContextTile<boolean>[] {\n return [\n {\n key: 'hide:shown',\n title: words.hide.shown.title,\n line: words.hide.shown.line ?? null,\n icon: 'shown',\n inUse: !hidden,\n data: false,\n },\n {\n key: 'hide:hidden',\n title: words.hide.hidden.title,\n line: words.hide.hidden.line ?? null,\n icon: 'hidden',\n inUse: hidden,\n data: true,\n },\n ];\n}\n\n/**\n * view: every way to lay the cube out, its icon its own shape. the one in use says so in place of\n * its line, so both fit a small tile.\n */\nexport function viewLevel(\n now: ViewKey,\n words: ContextWords,\n views: readonly ViewKey[] = VIEW_KEYS,\n): ContextTile<ViewKey>[] {\n return views.map((v) => ({\n key: 'view:' + v,\n title: words.views[v]?.title ?? '',\n line: v === now ? null : (words.views[v]?.line ?? null),\n icon: v,\n inUse: v === now,\n data: v,\n }));\n}\n\n/** what a cube can be sorted by, given by the app: as kept, names, when added, each face. */\nexport interface SortOption {\n /** the app's own key: `kept`, `names`, `added`, a face's id. */\n by: string;\n title: string;\n line?: string | null;\n icon: string;\n /** false for an order with no two ways (as kept): picking it uses it at once. */\n directed?: boolean;\n /** this option's two directions in its own words (a to z, oldest first, small first). */\n up?: ContextWord;\n down?: ContextWord;\n}\n\n/** a sort in use. */\nexport interface SortNow {\n by: string;\n dir: Direction;\n}\n\n/** the two directions of an option, in its own words or else the app's general ones. */\nexport function directionWords(\n option: SortOption,\n words: ContextWords,\n): Record<Direction, ContextWord> {\n return {\n up: option.up ?? words.directions.up,\n down: option.down ?? words.directions.down,\n };\n}\n\n/**\n * sort: the options, the one in use marked; a directed option in use says its direction in place\n * of its line. picking a directed option walks into its two directions (`sortDirectionsLevel`).\n */\nexport function sortLevel(\n options: readonly SortOption[],\n now: SortNow,\n words: ContextWords,\n): ContextTile<SortOption>[] {\n return options.map((o) => {\n const inUse = now.by === o.by;\n const directed = o.directed !== false;\n return {\n key: 'sort:' + o.by,\n title: o.title,\n line: inUse && directed ? directionWords(o, words)[now.dir].title : (o.line ?? null),\n icon: o.icon,\n inUse,\n data: o,\n };\n });\n}\n\n/**\n * inside one sort option: its two directions, up first. whatever direction, an item with nothing\n * found is not known yet and comes last (`sortItems`); the words say so in their lines.\n */\nexport function sortDirectionsLevel(\n option: SortOption,\n now: SortNow,\n words: ContextWords,\n): ContextTile<Direction>[] {\n const w = directionWords(option, words);\n return (['up', 'down'] as const).map((dir) => ({\n key: 'dir:' + dir,\n title: w[dir].title,\n line: w[dir].line ?? null,\n icon: dir,\n inUse: now.by === option.by && now.dir === dir,\n data: dir,\n }));\n}\n","import { ContextTile } from './context-cube';\n\n/*\n * where: one piece standing in many places at once, never copied (cube design study\n * `studies/one-piece-many-places-once.md`, principle 1). a level of the context cube beside names\n * and hide: every place the held piece could stand in, ticked where it stands. pure functions over\n * a `WhereSource` the app fills from its own world; the package keeps no data and says no words.\n *\n * taken from three that were written by hand: cubes' `placesFor` (`core/world/own.ts`), mosaic's\n * todarch cube (`placesFor` and `whereLevel`) and the grouping prototype's `whereLevel`\n * (`uat/use-cases/prototypes/my-own-groups.html`), whose shape this is: a level looks inside one\n * place, and a place with places inside it is looked into (›) instead of one long list.\n */\n\n/** what an app gives for where: its places and how they hold each other, from its own world. */\nexport interface WhereSource {\n /** the place everything stands in at last: the top (mine, mosaic, my to-dos). */\n readonly top: string;\n /** what stands in a place, in its order, hidden ones too (they still count for loops). */\n partsOf(place: string): readonly string[];\n /** every place a piece stands in now (its live rows). */\n placesOf(piece: string): readonly string[];\n /** a place's name as the app shows it (data, not a word of the package). */\n nameOf(place: string): string;\n /** the place the app put it in, which it never leaves; none by default. */\n givenPlaceOf?(piece: string): string | null;\n /** left out of a level (hidden there); nothing by default. */\n hidden?(id: string): boolean;\n /**\n * why the piece may not stand in the place, by the app's own rules (a screen that holds nothing,\n * a given piece into another given one), as the app's refusal key; null when it may. the package\n * checks \"inside itself\" on its own first.\n */\n refuses?(piece: string, place: string): string | null;\n}\n\n/** the refusals the package finds by itself; every other one is the app's (`WhereSource.refuses`). */\nexport type WhereRefusal = 'inside-itself' | 'given-place' | 'last-place' | (string & {});\n\n/** one place, as a where level shows it. the words for it are the app's. */\nexport interface CubePlace {\n /** the place's key, as the app's source knows it. */\n key: string;\n /** its name, from the source's `nameOf`. */\n title: string;\n /** the place this level looks inside, listed first (\"mosaic, the top\", \"kitchen itself\"). */\n at: boolean;\n /** the top, the place everything stands in at last. */\n top: boolean;\n /** the held piece stands here (ticked). */\n in: boolean;\n /** here is its only place: it never leaves it. */\n last: boolean;\n /** the app put it here: it never leaves it. */\n given: boolean;\n /** the held piece itself, listed pale where it stands among the others. */\n self: boolean;\n /** a place inside the held piece, listed pale: standing there would put it inside itself. */\n inside: boolean;\n /** what a tap asks for: stand it here too, or take it out of here; null for itself or inside it. */\n tap: 'stand' | 'take-out' | null;\n /** why that tap would be refused, or null when it would be done. */\n refused: WhereRefusal | null;\n /** what is shown in it now, the held piece left out, in order: for the app's line. */\n holds: string[];\n /** nothing shown in it yet but the held piece. */\n empty: boolean;\n /** inside it are places worth looking into (›): it can stand somewhere in there. */\n deeper: boolean;\n}\n\n/** how `placesOf` lists: one level, as the prototype (the default), or every place at once. */\nexport interface PlacesOptions {\n /** the place to look inside; the source's top by default. */\n at?: string;\n /**\n * every place it could stand in or stands in, under `at`, as one list (cubes' and the todarch\n * cube's flat list): no ›, and itself and what is inside it are left out instead of pale.\n */\n flat?: boolean;\n}\n\n/** everything standing inside a piece, at any depth and through every place (never the piece). */\nexport function insideOf(source: WhereSource, piece: string): Set<string> {\n const seen = new Set<string>();\n const walk = [...source.partsOf(piece)];\n while (walk.length) {\n const p = walk.pop()!;\n if (p === piece || seen.has(p)) continue;\n seen.add(p);\n walk.push(...source.partsOf(p));\n }\n return seen;\n}\n\n/** standing the piece in the place would put it inside itself (the place is it, or inside it). */\nexport function wouldLoop(source: WhereSource, piece: string, place: string): boolean {\n return piece === place || insideOf(source, piece).has(place);\n}\n\n/**\n * why the piece may not stand in the place: `inside-itself`, or the app's own refusal; null when\n * it may. a place it already stands in is never refused.\n */\nexport function refusalOf(source: WhereSource, piece: string, place: string): WhereRefusal | null {\n if (source.placesOf(piece).includes(place)) return null;\n if (wouldLoop(source, piece, place)) return 'inside-itself';\n return source.refuses?.(piece, place) ?? null;\n}\n\n/**\n * the places the held piece could stand in, as one level of where: the place looked inside (`at`,\n * the top by default) first when it may stand there, then what stands in it, in its order, each\n * place it could stand in or stands in, or that has such places deeper inside (`deeper`, ›); the\n * held piece and what is inside it come pale (`self`, `inside`). with `flat`, every such place under\n * `at` at once, breadth first, with no › and nothing pale.\n *\n * a tap on a place it stands in takes it out, refused on its given place and on its last; a tap on\n * one it does not stand in stands it there too, refused when inside itself or by the app's rules.\n */\nexport function placesOf(source: WhereSource, held: string, opts: PlacesOptions = {}): CubePlace[] {\n const at = opts.at ?? source.top;\n const inside = insideOf(source, held);\n const where = new Set(source.placesOf(held));\n const given = source.givenPlaceOf?.(held) ?? null;\n const hidden = (id: string) => !!source.hidden?.(id);\n const shown = (place: string) => source.partsOf(place).filter((p) => !hidden(p));\n const refused = (place: string) => refusalOf(source, held, place);\n const usable = (q: string) => q !== held && !inside.has(q) && (where.has(q) || !refused(q));\n\n // a place reaches deeper when something shown inside it is usable, or reaches further (a dag:\n // the loops are refused, and the walk never visits a place twice).\n const reached = new Map<string, boolean>();\n const reaches = (q: string, trail = new Set<string>()): boolean => {\n if (reached.has(q)) return reached.get(q)!;\n if (trail.has(q)) return false;\n trail.add(q);\n const r = shown(q).some(\n (p) => p !== held && !inside.has(p) && (usable(p) || reaches(p, trail)),\n );\n reached.set(q, r);\n return r;\n };\n\n const place = (key: string, isAt: boolean, deeper: boolean): CubePlace => {\n const stands = where.has(key);\n const holds = shown(key).filter((p) => p !== held);\n const tap = stands ? 'take-out' : 'stand';\n return {\n key,\n title: source.nameOf(key),\n at: isAt,\n top: key === source.top,\n in: stands,\n last: stands && where.size === 1,\n given: given === key,\n self: false,\n inside: false,\n tap,\n refused: stands\n ? given === key\n ? 'given-place'\n : where.size === 1\n ? 'last-place'\n : null\n : refused(key),\n holds,\n empty: holds.length === 0,\n deeper,\n };\n };\n const pale = (key: string, self: boolean): CubePlace => {\n const holds = shown(key).filter((p) => p !== held);\n return {\n key,\n title: source.nameOf(key),\n at: false,\n top: key === source.top,\n in: false,\n last: false,\n given: false,\n self,\n inside: !self,\n tap: null,\n refused: 'inside-itself',\n holds,\n empty: holds.length === 0,\n deeper: false,\n };\n };\n\n if (opts.flat) {\n const out: CubePlace[] = [];\n const seen = new Set<string>();\n const queue = [at];\n while (queue.length) {\n const q = queue.shift()!;\n if (seen.has(q) || q === held || inside.has(q)) continue;\n seen.add(q);\n if (usable(q) || (q === at && q === source.top)) out.push(place(q, q === at, false));\n queue.push(...shown(q));\n }\n return out;\n }\n\n const out: CubePlace[] = [];\n if (at !== held && !inside.has(at) && (usable(at) || at === source.top))\n out.push(place(at, true, false));\n for (const p of shown(at)) {\n if (p === at) continue;\n if (p === held || inside.has(p)) {\n out.push(pale(p, p === held));\n continue;\n }\n const deeper = reaches(p);\n if (usable(p) || deeper) out.push(place(p, false, deeper));\n }\n return out;\n}\n\n/** the words of where, the app's: a place's title and line (both from the place). */\nexport interface WhereWords {\n /** its title; the place's name by default (the app says \"mosaic, the top\", \"kitchen itself\"). */\n title?(place: CubePlace): string;\n /** the line under it: where the app put it, what it holds, itself, inside it. */\n line?(place: CubePlace): string | null;\n}\n\n/**\n * where as context tiles: every place, ticked (`inUse`) where it stands; pale where a tap can do\n * nothing (itself, inside it, a place it may not stand in). each tile's `data` is its `CubePlace`,\n * so the app's `pick` reads `tap` and `refused`, and a place with `deeper` gets `zoom`, the path that\n * looks inside it (`['where', key]` by default), which `<cube-context>` draws as a ›. the words are\n * the app's: `ContextWords.where`.\n */\nexport function whereLevel(\n places: readonly CubePlace[],\n words: WhereWords = {},\n opts: { pathOf?: (place: CubePlace) => string[] } = {},\n): ContextTile<CubePlace>[] {\n const pathOf = opts.pathOf ?? ((p: CubePlace) => ['where', p.key]);\n return places.map((p) => ({\n key: 'where:' + p.key,\n title: words.title?.(p) ?? p.title,\n line: words.line?.(p) ?? null,\n icon: 'place',\n inUse: p.in,\n pale: p.tap === null || (!p.in && p.refused !== null),\n zoom: p.deeper ? pathOf(p) : null,\n data: p,\n }));\n}\n","/**\n * turning rows (selim: row rotation), first tried in mosaic's todarch cube: a square of more\n * pieces than its front holds keeps its front full and turns its rows like the layers of a puzzle\n * cube. each row is a band of four sides; the pieces past the front fill the first row's other\n * sides, then the second row's, and so on, so the open places gather at the very end and a row\n * with nothing behind its front does not turn.\n *\n * this is only the layout, pure and without angular: which piece sits on which side of which row.\n * the front is cols × rows (3 × 3 as mosaic draws it, 4 × 5 and 3 × 6 for cubes' fixed grids).\n * when four sides a row are still not enough, rows are added below, as mosaic does.\n */\nexport interface TurningRows<T> {\n /** rows × 4 sides × cols places; null is an open place. side 0 is the front. */\n rows: (T | null)[][][];\n /** how many sides of each row hold something (1: only its front, it does not turn). */\n sides: number[];\n}\n\n/** the sides of one row: its front and the three behind it. */\nexport const TURNING_SIDES = 4;\n\nexport function turningRows<T>(\n pieces: readonly T[],\n own: T | null,\n cols = 3,\n rows = cols,\n): TurningRows<T> {\n const across = Math.max(1, Math.floor(cols));\n const down = Math.max(1, Math.floor(rows));\n const count = pieces.length + (own !== null ? 1 : 0);\n const perRow = across * TURNING_SIDES;\n const rowCount = Math.max(down, Math.ceil(count / perRow));\n const grid: (T | null)[][][] = Array.from({ length: rowCount }, () =>\n Array.from({ length: TURNING_SIDES }, () =>\n Array.from<T | null>({ length: across }).fill(null),\n ),\n );\n const front: [number, number][] = [];\n for (let r = 0; r < rowCount; r++) for (let c = 0; c < across; c++) front.push([r, c]);\n // the own box keeps the front's last place, so it is always seen\n const frontForPieces = own !== null ? front.slice(0, -1) : front;\n if (own !== null) grid[rowCount - 1][0][across - 1] = own;\n let next = 0;\n for (const [r, c] of frontForPieces) {\n if (next >= pieces.length) break;\n grid[r][0][c] = pieces[next++];\n }\n for (let r = 0; r < rowCount && next < pieces.length; r++)\n for (let s = 1; s < TURNING_SIDES && next < pieces.length; s++)\n for (let c = 0; c < across && next < pieces.length; c++) grid[r][s][c] = pieces[next++];\n const sides = grid.map(\n (row) => 1 + row.slice(1).filter((side) => side.some((t) => t !== null)).length,\n );\n return { rows: grid, sides };\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n Directive,\n ElementRef,\n TemplateRef,\n afterNextRender,\n computed,\n contentChild,\n effect,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ViewKey, gridFor } from '../context-cube/arrange';\nimport { TURNING_SIDES, turningRows } from './turning-rows';\n\n/*\n * the square: the complete grid of tiles every face of a cube is drawn with (cube design decision\n * 23, cubes decision 40). mosaic (`app-square-tiles`), cubes (`app-tiles`) and the context cube each\n * wrote it; this is the one they share. it only places the tiles an app gives: each app keeps\n * drawing its own tile through a template. turning rows ride on it (`turning`, off by default).\n */\n\n/** how close a square's places are: from one big tile (0) to only its icon or small cube (4). */\nexport type SquareLevel = 0 | 1 | 2 | 3 | 4;\n\n/** cubes' steps (`levelFor`), by a cell's side in px: a tile says less as the square fills. */\nexport function squareLevelFor(cell: number): SquareLevel {\n return cell >= 280 ? 0 : cell >= 150 ? 1 : cell >= 100 ? 2 : cell >= 70 ? 3 : 4;\n}\n\n/** places still open keep their outline; the fuller the square, the closer its places. */\nexport function squareGap(n: number): number {\n return n <= 2 ? 12 : n === 3 ? 10 : n === 4 ? 8 : 5;\n}\n\n/** the room a square may take: the width it is given, and the window's height for the square. */\nexport interface SquareRoom {\n width: number;\n /** the window's height less a head (48 px); only the square view is held to it, so it is seen whole. */\n tall: number;\n}\n\n/** one square laid out: its columns and rows, its size, and how much each tile says. */\nexport interface SquareLayout {\n cols: number;\n rows: number;\n /** the square's width and height, in px. */\n width: number;\n height: number;\n gap: number;\n /** a cell's width, in px. */\n cell: number;\n /** a row's height: the cell, or a list row's own height in one across. */\n rowHeight: number;\n level: SquareLevel;\n /** one across is a list: each row as tall as a tile with its name and line, not a square. */\n list: boolean;\n /** places not filled, outlined; they only ever finish the last row. */\n open: number;\n}\n\n/** the largest side a square takes on a wide screen, in px (cubes', mosaic's). */\nexport const SQUARE_MAX_SIDE = 880;\n/** a row's height in one across, the list (cubes'). */\nexport const SQUARE_LIST_ROW = 76;\n\n/**\n * how this many tiles are laid out in a view, in this much room. the square view is the smallest\n * n × n that holds them, as wide as the room and the window's height allow; the other views are as\n * long as they need and scroll. open places only finish the last row, so a view never draws a whole\n * empty row (decision of 2026-11-01): three pieces in 4 × 5 are one row of four. the square keeps\n * its own rule, its size coming from the pieces.\n */\nexport function squareLayout(\n view: ViewKey,\n count: number,\n room: SquareRoom,\n opts: { maxSide?: number; listRow?: number } = {},\n): SquareLayout {\n const n = Math.max(0, count);\n const grid = gridFor(view, n);\n const cols = grid.cols;\n const rows = view === 'square' ? grid.rows : Math.max(1, Math.ceil(n / cols));\n const width = Math.max(\n 0,\n Math.min(\n view === 'square' ? Math.min(room.width, room.tall) : room.width,\n opts.maxSide ?? SQUARE_MAX_SIDE,\n ),\n );\n const list = view === 'one';\n const gap = list ? 8 : squareGap(Math.max(cols, Math.min(rows, 5)));\n const cell = Math.max(0, (width - gap * (cols - 1)) / cols);\n const rowHeight = list ? (opts.listRow ?? SQUARE_LIST_ROW) : cell;\n return {\n cols,\n rows,\n width,\n height: rows * rowHeight + gap * (rows - 1),\n gap,\n cell,\n rowHeight,\n level: list ? 1 : squareLevelFor(cell),\n list,\n open: cols * rows - n,\n };\n}\n\n/** what a tile's template is given. */\nexport interface CubeSquareTileContext<T> {\n /** the tile, as the app gave it. */\n $implicit: T;\n index: number;\n /** how much it says (0 everything … 4 only its icon or small cube). */\n level: SquareLevel;\n /** its cell's width and height, in px, for a picture sized to it. */\n cell: number;\n rowHeight: number;\n /** one across: a list row, not a square cell. */\n list: boolean;\n}\n\n/**\n * `<ng-template cubeSquareTile let-tile let-level=\"level\">`: how the app draws one tile inside a\n * `<cube-square>`. the square only places it; the template fills its cell.\n */\n@Directive({ selector: 'ng-template[cubeSquareTile]' })\nexport class CubeSquareTile<T> {\n readonly template = inject<TemplateRef<CubeSquareTileContext<T>>>(TemplateRef);\n /** the tiles' type, for the template's checks: `[cubeSquareTile]=\"tiles()\"`. */\n readonly cubeSquareTile = input<readonly T[] | '' | undefined>();\n\n static ngTemplateContextGuard<T>(\n _dir: CubeSquareTile<T>,\n ctx: unknown,\n ): ctx is CubeSquareTileContext<T> {\n return true;\n }\n}\n\n/** the front a view keeps when its rows turn: the square's `across` × `across`, a fixed grid's page. */\nexport function turningFront(view: ViewKey, across = 3): { cols: number; rows: number } | null {\n if (view === 'square') return { cols: across, rows: across };\n if (view === 'grid-4x5') return { cols: 4, rows: 5 };\n if (view === 'grid-3x6') return { cols: 3, rows: 6 };\n return null;\n}\n\n/** narrower than this (a phone), a full square turns its rows, when `turning` is on. */\nexport const TURNING_BELOW = 640;\n/** turns after which a row with more stops nudging when the square opens. */\nexport const TURNING_NUDGE_UNTIL = 3;\n\n/** turns counted on this page when the app gives no key to keep them on the phone. */\nlet turnedHere = 0;\nconst readTurned = (key: string | null): number => {\n if (!key) return turnedHere;\n try {\n return Number(localStorage.getItem(key)) || 0;\n } catch {\n return turnedHere;\n }\n};\nconst noteTurned = (key: string | null): void => {\n turnedHere++;\n if (!key) return;\n try {\n localStorage.setItem(key, String(readTurned(key) + 1));\n } catch {\n // a phone that keeps nothing keeps nudging, which is fine\n }\n};\n\nconst reducedMotion = () =>\n typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;\n\n/**\n * `<cube-square [tiles] [view]>`: the tiles an app gives, laid out as a complete square or another\n * view, each drawn by the app's `cubeSquareTile` template and told its level. it measures its own\n * width (up to the window's height for the square, at most `maxSide`), outlines its open places and\n * zooms a step when it has to hold more. it says no word and draws no tile. its look is css\n * variables (`--cube-square-*`), set in both token files.\n */\n@Component({\n selector: 'cube-square',\n imports: [NgTemplateOutlet],\n template: `\n @let sq = layout();\n @if (rings(); as r) {\n <div\n class=\"cs-turning\"\n [class]=\"'cs-turning cs-l' + sq.level\"\n [class.cs-dashed]=\"dashed()\"\n [attr.data-level]=\"sq.level\"\n [style.width.px]=\"sq.width\"\n [style.--cs-gap.px]=\"sq.gap\"\n >\n @for (row of r.rows; track ri; let ri = $index) {\n <div\n class=\"cs-row\"\n [class.cs-turns]=\"r.sides[ri] > 1\"\n [attr.data-row]=\"ri\"\n [style.height.px]=\"sq.rowHeight\"\n (pointerdown)=\"down(ri, $event)\"\n (pointermove)=\"move(ri, $event)\"\n (pointerup)=\"up(ri, $event)\"\n (pointercancel)=\"up(ri, $event)\"\n (keydown)=\"key(ri, $event)\"\n >\n @if (r.sides[ri] > 1) {\n <span class=\"cs-edge\" aria-hidden=\"true\"></span>\n }\n <div\n class=\"cs-band\"\n [class.cs-still]=\"dragging() === ri || still()\"\n [class.cs-nudging]=\"nudging()\"\n [style.transform]=\"\n 'translateZ(' + -sq.width / 2 + 'px) rotateY(' + angle(ri) + 'deg)'\n \"\n >\n @for (side of row; track si; let si = $index) {\n <div\n class=\"cs-side\"\n [attr.data-side]=\"si\"\n [style.grid-template-columns]=\"'repeat(' + sq.cols + ', minmax(0, 1fr))'\"\n [style.transform]=\"\n 'rotateY(' + si * 90 + 'deg) translateZ(' + sq.width / 2 + 'px)'\n \"\n [attr.aria-hidden]=\"sideOf(ri) === si ? null : 'true'\"\n [attr.inert]=\"sideOf(ri) === si ? null : ''\"\n >\n @for (t of side; track ci; let ci = $index) {\n @if (t !== null) {\n <div class=\"cs-cell\">\n @if (tile(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: t,\n index: indexOf(t),\n level: sq.level,\n cell: sq.cell,\n rowHeight: sq.rowHeight,\n list: false,\n }\"\n />\n }\n </div>\n } @else if (si < r.sides[ri]) {\n <div class=\"cs-place\" aria-hidden=\"true\"></div>\n }\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div\n #grid\n [class]=\"'cs-square cs-l' + sq.level\"\n [class.cs-list]=\"sq.list\"\n [class.cs-dashed]=\"dashed()\"\n [attr.data-level]=\"sq.level\"\n [style.width.px]=\"sq.width\"\n [style.height.px]=\"sq.height\"\n [style.--cs-gap.px]=\"sq.gap\"\n [style.grid-template-columns]=\"'repeat(' + sq.cols + ', minmax(0, 1fr))'\"\n [style.grid-template-rows]=\"'repeat(' + sq.rows + ', minmax(0, 1fr))'\"\n >\n @for (t of tiles(); track keyOf()(t, $index); let i = $index) {\n <div class=\"cs-cell\">\n @if (tile(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: t,\n index: i,\n level: sq.level,\n cell: sq.cell,\n rowHeight: sq.rowHeight,\n list: sq.list,\n }\"\n />\n }\n </div>\n }\n @for (i of openPlaces(); track i) {\n <div class=\"cs-place\" aria-hidden=\"true\"></div>\n }\n </div>\n }\n `,\n // every class is cs-prefixed: an app's global .tile, .square or .place rules would reach inside,\n // since emulated encapsulation only keeps the component's rules in.\n styles: `\n :host {\n display: block;\n }\n .cs-square {\n display: grid;\n gap: calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));\n --cs-radius: var(--cube-square-radius, 20px);\n }\n .cs-cell {\n display: grid;\n min-width: 0;\n min-height: 0;\n }\n .cs-place {\n box-sizing: border-box;\n border: var(--cube-square-place-width, 1.5px) solid\n var(--cube-square-place, color-mix(in srgb, #dae0d9 55%, transparent));\n border-radius: var(--cs-radius);\n }\n /* something could come here (a cube of mine, a level with a plus): its open places are dashed. */\n .cs-dashed .cs-place {\n border-style: dashed;\n border-color: var(--cube-square-place-dashed, #dae0d9);\n }\n .cs-l0 {\n --cs-radius: 28px;\n }\n .cs-l2 {\n --cs-radius: 16px;\n }\n .cs-l3 {\n --cs-radius: 12px;\n }\n .cs-l4 {\n --cs-radius: 9px;\n }\n .cs-l4 .cs-place {\n border-width: 1px;\n }\n /* turning rows: each row a band of four sides, turned like a puzzle cube's layer. */\n .cs-turning {\n display: flex;\n flex-direction: column;\n gap: calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));\n --cs-radius: var(--cube-square-radius, 20px);\n }\n .cs-row {\n position: relative;\n perspective: 1400px;\n touch-action: pan-y;\n user-select: none;\n -webkit-user-select: none;\n outline: none;\n }\n .cs-row:focus-visible {\n outline: 2px solid var(--cube-square-focus, #5f9a80);\n outline-offset: 3px;\n border-radius: var(--cs-radius);\n }\n .cs-band {\n position: absolute;\n inset: 0;\n transform-style: preserve-3d;\n transition: transform 380ms cubic-bezier(0.2, 0.8, 0.2, 1);\n }\n .cs-band.cs-nudging {\n transition: transform 520ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n .cs-band.cs-still {\n transition: none;\n }\n .cs-side {\n position: absolute;\n inset: 0;\n display: grid;\n gap: calc(var(--cs-gap) * var(--cube-square-gap-scale, 1));\n backface-visibility: hidden;\n }\n /* the hint: the edge of the next side, on a row that has more. */\n .cs-edge {\n pointer-events: none;\n position: absolute;\n top: 18%;\n bottom: 18%;\n right: calc(-1 * max(4px, var(--cs-gap) - 2px));\n z-index: 1;\n width: 3px;\n border-radius: 999px;\n background: var(--cube-square-edge, color-mix(in srgb, #5f9a80 45%, transparent));\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CubeSquare<T> {\n /** the tiles, in the order they are placed. */\n readonly tiles = input.required<readonly T[]>();\n /** how they are laid out: the square (the default), one to four across, 4 × 5, 3 × 6. */\n readonly view = input<ViewKey>('square');\n /** the largest side the square takes on a wide screen, in px. */\n readonly maxSide = input(SQUARE_MAX_SIDE);\n /** a row's height in one across, in px. */\n readonly listRow = input(SQUARE_LIST_ROW);\n /** open places dashed, where something could come (a cube of mine, a level with a plus). */\n readonly dashed = input(false);\n /** what keeps a tile the same tile across changes, so it is not drawn anew; its place by default. */\n readonly keyOf = input<(tile: T, index: number) => unknown>((_, i) => i);\n /**\n * turning rows (selim: row rotation, first in mosaic's todarch cube), off unless the app turns\n * them on: on a phone, a square or fixed grid holding more than its front keeps its size, and each\n * row becomes a band of four sides that a finger (or the arrow keys on a focused row) turns, bringing\n * in the pieces past the front (`turningRows`).\n */\n readonly turning = input(false);\n /** rows turn only on a screen narrower than this, in px; a wide screen shows the whole square. */\n readonly turnBelow = input(TURNING_BELOW);\n /** the square's front when its rows turn: `across` × `across` (3 × 3). */\n readonly across = input(3);\n /** which tile is my own box: it keeps the front's last place while the rows turn. */\n readonly isOwn = input<((tile: T) => boolean) | null>(null);\n /** where the turns are counted on this phone (localStorage), so the nudge stops after a few. */\n readonly nudgeKey = input<string | null>(null);\n\n protected readonly tile = contentChild<CubeSquareTile<T>>(CubeSquareTile);\n private readonly grid = viewChild<ElementRef<HTMLElement>>('grid');\n /** the host's width and the window's height, followed as either changes. */\n private readonly room = signal<SquareRoom>({ width: 0, tall: 0 });\n\n /** the layout now: columns, rows, size, gap, level and open places. */\n /** the front kept while the rows turn, or null when they do not (off, a wide screen, all fit). */\n readonly front = computed(() => {\n if (!this.turning()) return null;\n if ((this.room().width || 354) >= this.turnBelow()) return null;\n const front = turningFront(this.view(), Math.max(1, Math.floor(this.across())));\n return front && this.tiles().length > front.cols * front.rows ? front : null;\n });\n\n /** the layout now: columns, rows, size, gap, level and open places. */\n readonly layout = computed(() => {\n const r = this.room();\n const width = r.width || 354;\n const room = { width, tall: r.tall || width };\n const opts = { maxSide: this.maxSide(), listRow: this.listRow() };\n const front = this.front();\n if (!front) return squareLayout(this.view(), this.tiles().length, room, opts);\n // turning: laid out as its full front, then as many rows as the turning rows need\n const view = this.view();\n const full = squareLayout(view, front.cols * front.rows, room, opts);\n const rows = this.rings()?.rows.length ?? front.rows;\n return {\n ...full,\n rows,\n height: rows * full.rowHeight + full.gap * (rows - 1),\n open: 0,\n };\n });\n\n /** the turning rows: rows × four sides × cols, and how many sides of each hold something. */\n protected readonly rings = computed(() => {\n const front = this.front();\n if (!front) return null;\n const isOwn = this.isOwn();\n const tiles = this.tiles();\n const own = isOwn ? (tiles.find((t) => isOwn(t)) ?? null) : null;\n const pieces = own === null ? tiles : tiles.filter((t) => t !== own);\n return turningRows(pieces, own, front.cols, front.rows);\n });\n\n private readonly indexes = computed(() => new Map(this.tiles().map((t, i) => [t, i])));\n protected indexOf(t: T): number {\n return this.indexes().get(t) ?? 0;\n }\n protected readonly openPlaces = computed(() =>\n Array.from({ length: this.layout().open }, (_, i) => i),\n );\n\n /** each row's turn in degrees, and the row a finger is turning now. */\n private readonly angles = signal<Record<number, number>>({});\n protected readonly dragging = signal<number | null>(null);\n /** turns that should not animate (reduced motion). */\n protected readonly still = signal(reducedMotion());\n protected readonly nudging = signal(false);\n private drag: {\n row: number;\n id: number;\n x: number;\n y: number;\n base: number;\n moved: boolean;\n } | null = null;\n /** fingers on the square now: a second one is a pinch, never a turn. */\n private readonly fingers = new Set<number>();\n private suppressClick = false;\n private nudged = false;\n private readonly timers: ReturnType<typeof setTimeout>[] = [];\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n protected angle(row: number): number {\n return this.angles()[row] ?? 0;\n }\n\n /** the side of a row facing me (0 to 3). */\n protected sideOf(row: number): number {\n const sides = TURNING_SIDES;\n return ((Math.round(-this.angle(row) / 90) % sides) + sides) % sides;\n }\n\n private filled(row: number): number {\n return this.rings()?.sides[row] ?? 1;\n }\n\n protected down(row: number, e: PointerEvent): void {\n this.fingers.add(e.pointerId);\n if (this.fingers.size > 1) {\n // a pinch: let the turn go, the row settles where it was\n this.cancelDrag();\n return;\n }\n if (this.filled(row) <= 1) return;\n this.drag = {\n row,\n id: e.pointerId,\n x: e.clientX,\n y: e.clientY,\n base: this.angle(row),\n moved: false,\n };\n }\n\n protected move(row: number, e: PointerEvent): void {\n const drag = this.drag;\n if (!drag || drag.row !== row || drag.id !== e.pointerId) return;\n const dx = e.clientX - drag.x;\n const dy = e.clientY - drag.y;\n if (!drag.moved) {\n // only a sideways drag turns; up and down is the page scrolling\n if (Math.abs(dx) < 8 || Math.abs(dx) < Math.abs(dy)) return;\n drag.moved = true;\n this.dragging.set(row);\n (e.currentTarget as HTMLElement | null)?.setPointerCapture?.(e.pointerId);\n }\n const width = this.layout().width || 354;\n this.angles.update((a) => ({ ...a, [row]: drag.base + (dx / width) * 90 }));\n }\n\n protected up(row: number, e: PointerEvent): void {\n this.fingers.delete(e.pointerId);\n const drag = this.drag;\n if (!drag || drag.row !== row || drag.id !== e.pointerId) return;\n this.drag = null;\n if (!drag.moved) return;\n this.dragging.set(null);\n this.suppressClick = true;\n setTimeout(() => (this.suppressClick = false));\n // a short swipe is enough to turn one side; it settles on a side, never between two\n const moved = this.angle(row) - drag.base;\n const steps =\n Math.abs(moved) > 12 ? Math.sign(moved) * Math.max(1, Math.round(Math.abs(moved) / 90)) : 0;\n this.settle(row, drag.base, steps);\n }\n\n private cancelDrag(): void {\n const drag = this.drag;\n this.drag = null;\n if (!drag?.moved) return;\n this.dragging.set(null);\n this.angles.update((a) => ({ ...a, [drag.row]: drag.base }));\n }\n\n /** turns a row `steps` sides from `base`, passing the sides with nothing on them. */\n private settle(row: number, base: number, steps: number): void {\n const filled = this.filled(row);\n const sideAt = (s: number) =>\n ((Math.round(-(base + s * 90) / 90) % TURNING_SIDES) + TURNING_SIDES) % TURNING_SIDES;\n let n = steps;\n while (n !== 0 && sideAt(n) >= filled) n += Math.sign(n);\n this.angles.update((a) => ({ ...a, [row]: base + n * 90 }));\n if (n !== 0) noteTurned(this.nudgeKey());\n }\n\n /** the arrow keys on a focused row turn it, so a keyboard reaches every piece too. */\n protected key(row: number, e: KeyboardEvent): void {\n if (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft') return;\n if (this.filled(row) <= 1) return;\n e.preventDefault();\n const col = this.focusedColumn(e.target as HTMLElement | null);\n // the next side comes in from the right, as a swipe to the left brings it\n this.settle(row, this.angle(row), e.key === 'ArrowRight' ? -1 : 1);\n setTimeout(() => this.focusSide(row, col));\n }\n\n private focusedColumn(target: HTMLElement | null): number {\n const cell = target?.closest('.cs-cell, .cs-place');\n const side = cell?.parentElement;\n return cell && side ? Array.from(side.children).indexOf(cell) : 0;\n }\n\n /** after a turn by the keys, focus goes to the same place on the side now facing me. */\n private focusSide(row: number, col: number): void {\n const side = this.host.querySelector<HTMLElement>(\n `.cs-row[data-row=\"${row}\"] .cs-side[data-side=\"${this.sideOf(row)}\"]`,\n );\n if (!side) return;\n const cells = Array.from(side.children) as HTMLElement[];\n const order = [cells[col], ...cells].filter(Boolean);\n const focusable = 'button, a[href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n for (const cell of order) {\n const el = cell.matches(focusable) ? cell : cell.querySelector<HTMLElement>(focusable);\n if (el) {\n el.focus();\n return;\n }\n }\n side.closest<HTMLElement>('.cs-row')?.focus();\n }\n\n /** the nudge: rows with more turn a little and back, one after another, until i turned a few. */\n private nudge(): void {\n const rings = this.rings();\n if (this.nudged || !rings || reducedMotion()) return;\n if (readTurned(this.nudgeKey()) >= TURNING_NUDGE_UNTIL) return;\n const rows = rings.sides.flatMap((s, i) => (s > 1 ? [i] : []));\n if (!rows.length) return;\n this.nudged = true;\n this.nudging.set(true);\n const set = (row: number, angle: number) => {\n if (this.drag || this.dragging() !== null) return;\n this.angles.update((a) => ({ ...a, [row]: angle }));\n };\n rows.forEach((row, i) => {\n this.timers.push(\n setTimeout(() => set(row, -22), 500 + i * 180),\n setTimeout(() => set(row, 0), 1020 + i * 180),\n );\n });\n this.timers.push(setTimeout(() => this.nudging.set(false), 1600 + rows.length * 180));\n }\n\n constructor() {\n const host = this.host;\n const destroy = inject(DestroyRef);\n // the tap that ends a turn is not a tap on a tile\n const swallow = (e: Event) => {\n if (!this.suppressClick) return;\n e.stopPropagation();\n e.preventDefault();\n };\n host.addEventListener('click', swallow, true);\n destroy.onDestroy(() => {\n host.removeEventListener('click', swallow, true);\n this.timers.forEach(clearTimeout);\n });\n effect(() => {\n if (this.rings()) untracked(() => this.timers.push(setTimeout(() => this.nudge())));\n });\n afterNextRender(() => {\n const measure = () =>\n this.room.set({ width: host.clientWidth, tall: Math.max(320, window.innerHeight - 48) });\n measure();\n const watch = typeof ResizeObserver === 'function' ? new ResizeObserver(measure) : null;\n watch?.observe(host);\n window.addEventListener('resize', measure);\n destroy.onDestroy(() => {\n watch?.disconnect();\n window.removeEventListener('resize', measure);\n });\n });\n // a square that has to hold more zooms out a step (and in when it holds fewer); the other views\n // only grow longer.\n let before = 0;\n let beforeView: ViewKey | null = null;\n effect(() => {\n const { cols, list } = this.layout();\n const view = this.view();\n const el = this.grid()?.nativeElement;\n if (\n el &&\n before &&\n cols !== before &&\n view === beforeView &&\n !list &&\n !reducedMotion() &&\n typeof el.animate === 'function'\n ) {\n el.animate([{ transform: `scale(${cols / before})` }, { transform: 'none' }], {\n duration: 420,\n easing: 'cubic-bezier(.2,.7,.2,1)',\n });\n }\n before = cols;\n beforeView = view;\n });\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n untracked,\n} from '@angular/core';\nimport { CUBE_ICON_NAMES, CubeIcon, CubeIconName } from '../icon/cube-icon';\nimport {\n CubeSquare,\n CubeSquareTile,\n SquareLevel,\n squareGap,\n squareLevelFor,\n} from '../square/cube-square';\nimport { gridFor } from './arrange';\nimport {\n CONTEXT_CUBE_SOURCE,\n CONTEXT_CUBE_WORDS,\n ContextCubeSource,\n ContextPath,\n ContextTile,\n ContextWords,\n} from './context-cube';\n\n/*\n * the square that draws one level of a context cube: the tiles an app's `ContextCubeSource` gives\n * for the held thing at a path, as a complete square (cube design decision 23, cubes decisions 39\n * and 40). it never routes, zooms, draws a head or says a word of its own: each app hosts it in its\n * own route under its own head, and walks the path it reports.\n */\n\n/** how close a square's places are: from one big tile (0) to only its icon (4). */\nexport type ContextLevel = SquareLevel;\n\n/** cubes' steps, now the square's (`squareLevelFor`); kept under its first name. */\nexport const contextLevelFor: (cell: number) => ContextLevel = squareLevelFor;\n\n/** a level's square: n × n places, how far apart, and how much each tile says. */\nexport interface ContextSquare {\n /** places on a side. */\n n: number;\n /** the square's side, in px. */\n side: number;\n gap: number;\n level: ContextLevel;\n /** the places not filled, outlined so the square stays whole. */\n open: number;\n}\n\n/**\n * the square for this many tiles in this much room: the smallest n × n that holds them all\n * (`gridFor('square', count)`), as wide as the room, at most `maxSide`.\n */\nexport function contextSquare(count: number, room: number, maxSide = 880): ContextSquare {\n const { cols: n, rows } = gridFor('square', count);\n const side = Math.max(0, Math.min(room, maxSide));\n const gap = squareGap(n);\n const cell = (side - gap * (n - 1)) / n;\n return { n, side, gap, level: contextLevelFor(cell), open: n * rows - Math.max(0, count) };\n}\n\n/**\n * the icon a tile is drawn with: its own when `cube-icon` draws it, shown for `hide` (it has no icon\n * of its own), the plus for a tile that adds, and else a face (an app's own part with an icon the\n * package does not have).\n */\nexport function contextIcon(tile: Pick<ContextTile, 'icon' | 'adds'>): CubeIconName {\n if ((CUBE_ICON_NAMES as readonly string[]).includes(tile.icon)) return tile.icon as CubeIconName;\n if (tile.adds) return 'plus';\n if (tile.icon === 'hide') return 'shown';\n return 'face';\n}\n\n/** a tapped tile and the element it is drawn in. */\nexport interface ContextTapped {\n tile: ContextTile;\n element: HTMLElement;\n}\n\n/**\n * `<cube-context [held] [path]>`: one level of the held thing's context cube, as a complete square\n * of icon tiles. a tap asks the source's `pick`, and the answer comes out as `enter` (a deeper\n * path), `done` (the journey ends: a name, a view, shown or hidden was used) or `out` (one level\n * up); `stay` redraws the level where it is. a level the source does not have (null) is `out` too.\n *\n * the source and the words come from `CONTEXT_CUBE_SOURCE` and `CONTEXT_CUBE_WORDS`, or from the\n * `source` and `words` inputs when one screen holds a different one. its look is css variables\n * (`--cube-context-*`, `--cube-icon-*`), set in both token files.\n */\n@Component({\n selector: 'cube-context',\n imports: [CubeIcon, CubeSquare, CubeSquareTile],\n template: `\n <cube-square\n [tiles]=\"tiles()\"\n [dashed]=\"adds()\"\n [maxSide]=\"maxSide()\"\n [keyOf]=\"keyOf\"\n [class.cc-adds]=\"adds()\"\n >\n <ng-template [cubeSquareTile]=\"tiles()\" let-t let-level=\"level\">\n <div class=\"cc-cell\">\n <button\n type=\"button\"\n [class]=\"'cc-tile cc-l' + level\"\n [class.cc-in-use]=\"!!t.inUse\"\n [class.cc-pale]=\"!!t.pale\"\n [class.cc-adds]=\"!!t.adds\"\n [class.cc-busy]=\"busy() === t.key\"\n [disabled]=\"busy() !== null\"\n [attr.aria-label]=\"level >= 4 ? t.title : null\"\n [attr.aria-current]=\"t.inUse ? 'true' : null\"\n [attr.title]=\"level >= 3 ? t.title : null\"\n (click)=\"tap(t, $any($event.currentTarget))\"\n >\n <span class=\"cc-icon\"><cube-icon [icon]=\"iconOf(t)\" [inUse]=\"!!t.inUse\" /></span>\n @if (level < 4) {\n <span class=\"cc-t\">{{ t.title }}</span>\n }\n @if (t.line && level < 3) {\n <span class=\"cc-m\">{{ t.line }}</span>\n }\n @if (t.inUse && inUseWord() && level < 3) {\n <span class=\"cc-tick\">{{ inUseWord() }}</span>\n }\n </button>\n @if (t.zoom?.length) {\n <button\n type=\"button\"\n class=\"cc-go\"\n [disabled]=\"busy() !== null\"\n [attr.aria-label]=\"t.zoomLabel || t.title\"\n (click)=\"zoomInto(t, $any($event.currentTarget))\"\n >\n <svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" aria-hidden=\"true\">\n <path\n d=\"M6 3l5 5-5 5\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n </div>\n </ng-template>\n </cube-square>\n `,\n // every class is cc-prefixed: an app's own .tile, .square or .place rules (cubes has them) are\n // global and would reach inside, since emulated encapsulation only keeps the component's rules in.\n styles: `\n :host {\n display: block;\n font: inherit;\n color: var(--cube-context-ink, #1f2a26);\n /* the square's open places in the context cube's own look */\n --cube-square-place: color-mix(in srgb, var(--cube-context-line, #dae0d9) 55%, transparent);\n --cube-square-place-dashed: var(--cube-context-line, #dae0d9);\n --cube-square-radius: var(--cube-context-radius, 20px);\n }\n .cc-cell {\n position: relative;\n height: 100%;\n min-width: 0;\n min-height: 0;\n display: grid;\n }\n .cc-go {\n all: unset;\n cursor: pointer;\n position: absolute;\n top: 6px;\n right: 6px;\n width: 32px;\n height: 32px;\n display: grid;\n place-items: center;\n border-radius: 50%;\n color: var(--cube-context-ink, #1f2a26);\n background: var(\n --cube-context-go,\n color-mix(in srgb, var(--cube-context-line, #dae0d9) 60%, transparent)\n );\n }\n .cc-go:focus-visible {\n outline: 3px solid var(--cube-context-focus, #5f9a80);\n outline-offset: 2px;\n }\n .cc-go:disabled {\n cursor: default;\n }\n .cc-tile {\n all: unset;\n cursor: pointer;\n box-sizing: border-box;\n min-width: 0;\n min-height: 0;\n height: 100%;\n overflow: hidden;\n display: grid;\n justify-items: center;\n align-content: center;\n gap: 6px;\n padding: 14px 10px 12px;\n text-align: center;\n background: var(--cube-context-tile, #ffffff);\n border: 1px solid var(--cube-context-line, #dae0d9);\n border-radius: var(--cube-context-radius, 20px);\n user-select: none;\n -webkit-user-select: none;\n -webkit-touch-callout: none;\n transition: transform 160ms;\n }\n .cc-tile:active:not(:disabled) {\n transform: scale(0.97);\n }\n .cc-tile:focus-visible {\n outline: 3px solid var(--cube-context-focus, #5f9a80);\n outline-offset: 2px;\n }\n .cc-tile.cc-in-use {\n border: 2px solid var(--cube-context-in-use, #3b5a4c);\n }\n .cc-tile.cc-pale {\n background: transparent;\n border: 2px dashed var(--cube-context-line, #dae0d9);\n color: var(--cube-context-quiet, #5d6a64);\n }\n .cc-tile.cc-adds {\n border: 2px solid var(--cube-context-adds, #c8693f);\n }\n .cc-tile.cc-busy {\n opacity: 0.6;\n cursor: progress;\n }\n .cc-tile:disabled:not(.cc-busy) {\n cursor: default;\n }\n .cc-icon {\n display: grid;\n place-items: center;\n line-height: 0;\n }\n .cc-tile.cc-adds .cc-icon {\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: var(--cube-context-adds-bg, #f3e3d6);\n --cube-icon-stroke: var(--cube-context-adds-ink, #7a4a2b);\n --cube-icon-size: 26px;\n }\n .cc-t,\n .cc-m {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n }\n .cc-t {\n -webkit-line-clamp: var(--cube-context-title-lines, 2);\n line-clamp: var(--cube-context-title-lines, 2);\n }\n .cc-m {\n -webkit-line-clamp: var(--cube-context-line-lines, 2);\n line-clamp: var(--cube-context-line-lines, 2);\n }\n .cc-t {\n font-size: var(--cube-context-title-size, 17px);\n font-weight: 700;\n line-height: 1.2;\n }\n .cc-m {\n font-size: var(--cube-context-line-size, 13px);\n line-height: 1.3;\n color: var(--cube-context-quiet, #5d6a64);\n }\n .cc-tick {\n font-size: var(--cube-context-line-size, 13px);\n font-weight: 800;\n color: var(--cube-context-in-use, #3b5a4c);\n }\n .cc-tile.cc-l0 {\n border-radius: 28px;\n padding: 24px;\n gap: 10px;\n }\n .cc-l0 .cc-t {\n font-size: calc(var(--cube-context-title-size, 17px) * 26 / 17);\n }\n .cc-l0 .cc-m {\n font-size: calc(var(--cube-context-line-size, 13px) * 16 / 13);\n }\n .cc-l0 .cc-icon {\n --cube-icon-size: 64px;\n }\n .cc-tile.cc-l0.cc-adds .cc-icon {\n width: 96px;\n height: 96px;\n --cube-icon-size: 40px;\n }\n .cc-tile.cc-l2 {\n border-radius: 16px;\n padding: 10px 6px;\n gap: 5px;\n }\n .cc-l2 .cc-t {\n font-size: calc(var(--cube-context-title-size, 17px) * 14 / 17);\n }\n .cc-l2 .cc-m {\n font-size: calc(var(--cube-context-line-size, 13px) * 12 / 13);\n }\n .cc-tile.cc-l3 {\n border-radius: 12px;\n padding: 6px 4px;\n gap: 3px;\n }\n .cc-l3 .cc-t {\n font-size: calc(var(--cube-context-title-size, 17px) * 12 / 17);\n }\n .cc-tile.cc-l4 {\n border-radius: 9px;\n padding: 2px;\n gap: 0;\n }\n .cc-l3 .cc-icon,\n .cc-l4 .cc-icon {\n --cube-icon-size: 24px;\n }\n .cc-tile.cc-l3.cc-adds .cc-icon,\n .cc-tile.cc-l4.cc-adds .cc-icon {\n width: 30px;\n height: 30px;\n --cube-icon-size: 18px;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CubeContext {\n /** what was held: a piece, a cube, a to-do, a level, as the app's source knows it. */\n readonly held = input.required<unknown>();\n /** where in its context cube: [] is its top (the parts), ['names'] a part, ['sort', by] deeper. */\n readonly path = input<ContextPath>([]);\n /** a source for this screen alone; else `CONTEXT_CUBE_SOURCE`. */\n readonly source = input<ContextCubeSource<any> | null>(null);\n /** words for this screen alone; else `CONTEXT_CUBE_WORDS`. */\n readonly words = input<ContextWords | null>(null);\n /** the largest side the square takes on a wide screen, in px. */\n readonly maxSide = input(880);\n /**\n * what keeps the held thing the same thing while a pick is answered (itself by default). an app\n * whose store gives a new object when the pick changes it (a rename, a hide) passes its id here, or\n * the answer would be dropped as if the person had walked to another thing.\n */\n readonly heldKey = input<(held: unknown) => unknown>((held) => held);\n\n /** walk into a deeper level: the app puts this path in its own route. */\n readonly enter = output<string[]>();\n /** step one level out (or out of the context cube, from its top). */\n readonly out = output<void>();\n /** the journey ends: the tile that was used. */\n readonly done = output<ContextTile>();\n /**\n * a tile was tapped, before the source answers: the tile and its element, so the app can grow the\n * next level (or whatever the pick opens) out of the tile, as it zooms into any other piece.\n */\n readonly tapped = output<ContextTapped>();\n\n private readonly given = inject(CONTEXT_CUBE_SOURCE, { optional: true });\n private readonly givenWords = inject(CONTEXT_CUBE_WORDS, { optional: true });\n\n /** the tile whose pick is still being answered; every tile waits meanwhile. */\n protected readonly busy = signal<string | null>(null);\n /** bumped after a pick, so a source that keeps its data outside signals is read again. */\n private readonly again = signal(0);\n\n private readonly from = computed(() => {\n const s = this.source() ?? this.given;\n if (!s) throw new Error('cube-context: provide CONTEXT_CUBE_SOURCE or pass [source]');\n return s;\n });\n /** the path as one key, so the same path given anew is the same level. */\n private readonly where = computed(() => this.path().join('\\u0000'));\n private readonly level = computed(() => {\n this.again();\n return this.from().level(this.held(), this.path());\n });\n protected readonly tiles = computed(() => this.level() ?? []);\n protected readonly adds = computed(() => this.tiles().some((t) => !!t.adds));\n /** a tile stays the same tile across levels by its key. */\n protected readonly keyOf = (t: ContextTile) => t.key;\n protected readonly inUseWord = computed(() => (this.words() ?? this.givenWords)?.inUse ?? null);\n protected readonly iconOf = contextIcon;\n\n constructor() {\n // a path the source does not have (a part that went away) steps out.\n effect(() => {\n if (this.level() === null) untracked(() => this.out.emit());\n });\n // a new path is a new level: nothing is waiting any more.\n effect(() => {\n this.where();\n this.held();\n untracked(() => this.busy.set(null));\n });\n }\n\n /** the › of a tile with a way inside: walks into its path, without asking the source. */\n protected zoomInto(tile: ContextTile, element?: HTMLElement): void {\n if (this.busy() !== null || !tile.zoom?.length) return;\n if (element) this.tapped.emit({ tile, element });\n this.enter.emit([...tile.zoom]);\n }\n\n protected async tap(tile: ContextTile, element?: HTMLElement): Promise<void> {\n if (this.busy() !== null) return;\n if (element) this.tapped.emit({ tile, element });\n const held = this.held();\n const path = this.path();\n const where = this.where();\n const key = this.heldKey();\n const here = () => key(this.held()) === key(held) && this.where() === where;\n this.busy.set(tile.key);\n try {\n const picked = await this.from().pick(held, path, tile);\n // the person walked elsewhere while it was answered: the answer is for a level gone.\n if (!here()) return;\n switch (picked.kind) {\n case 'enter':\n this.enter.emit(picked.path);\n break;\n case 'done':\n this.done.emit(tile);\n break;\n case 'out':\n this.out.emit();\n break;\n case 'stay':\n break;\n }\n } finally {\n if (here()) this.busy.set(null);\n this.again.update((n) => n + 1);\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n PLATFORM_ID,\n computed,\n effect,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { CubePicture } from '../cube-picture/cube-picture';\nimport { CubeSquare, CubeSquareTile } from '../square/cube-square';\n\n/**\n * something on its way, the cube design way: the cube picture's pale stickers take colour (a page,\n * a cube) or its colours turn round the stickers (a piece: a tile, a button saving). picked by selim\n * on 3 november 2026 (cube design's `08-decisions.md`, the study `studies/loading-pieces.md`), in\n * place of grey pulsing cards and primeng's ring. it says no word: the app's own line is projected.\n */\n\n/**\n * the ways something on its way is shown. `fill`: the picture's pale stickers take colour one by\n * one, then start again (a page or a cube). `turn`: the colours turn round the stickers, the way\n * `rot` turns a cube (a piece). the places wait and the cube grows (the study's b and d) are not in\n * yet: options to add when an app asks.\n */\nexport type CubeLoadingWay = 'fill' | 'turn';\nexport const CUBE_LOADING_WAYS: readonly CubeLoadingWay[] = ['fill', 'turn'];\n\n/**\n * how much is on its way. `page`: a whole screen, the picture over the line and the square's pale\n * places. `cube`: a part of a screen, the picture over the line. `piece`: a tile or a button, a small\n * cube beside the line, on one line with the words around it.\n */\nexport type CubeLoadingLevel = 'page' | 'cube' | 'piece';\nexport const CUBE_LOADING_LEVELS: readonly CubeLoadingLevel[] = ['page', 'cube', 'piece'];\n\n/** the way picked for each level (selim, 3 november 2026): a page or a cube fills, a piece turns. */\nexport function loadingWayFor(level: CubeLoadingLevel): CubeLoadingWay {\n return level === 'piece' ? 'turn' : 'fill';\n}\n\n/** how long one step lasts, in milliseconds: the prototype's pace. */\nexport const CUBE_LOADING_STEP_MS: Readonly<Record<CubeLoadingWay, number>> = { fill: 150, turn: 180 };\n\n/** the picture's width for each level, in pixels, when the app sets none. */\nexport const CUBE_LOADING_WIDTH: Readonly<Record<CubeLoadingLevel, number>> = {\n page: 96,\n cube: 64,\n piece: 20,\n};\n\n/** the colours the stickers take when the app gives none: cube design's sample palette. */\nexport const CUBE_LOADING_COLOURS: readonly string[] = ['#5f9a80', '#c8693f', '#e0b44c', '#4f7cac', '#9b6bb3'];\n\n/** the picture is a 2 × 2 × 2 cube: three faces of four stickers. */\nexport const CUBE_LOADING_STICKERS = 12;\n\n/**\n * the stickers' colours at a step of a way (null is pale). `fill`: the first `step` stickers are\n * coloured, all twelve, then none again. `turn`: every third sticker coloured, moved on one sticker\n * a step. with no palette every sticker is pale.\n */\nexport function loadingStickers(\n way: CubeLoadingWay,\n step: number,\n palette: readonly string[] = CUBE_LOADING_COLOURS,\n stickers = CUBE_LOADING_STICKERS,\n): (string | null)[] {\n const n = Math.max(1, Math.floor(stickers));\n const s = Math.max(0, Math.floor(step));\n const colour = (i: number) => (palette.length ? palette[i % palette.length] : null);\n if (way === 'fill') {\n const k = s % (n + 1);\n return Array.from({ length: n }, (_, i) => (i < k ? colour(i) : null));\n }\n const base = Array.from({ length: n }, (_, i) => (i % 3 === 0 ? colour(i / 3) : null));\n return Array.from({ length: n }, (_, i) => base[(((i - s) % n) + n) % n]);\n}\n\n/** the step drawn when nothing may move (reduced motion): half filled, or the turn at rest. */\nexport function stillStep(way: CubeLoadingWay, stickers = CUBE_LOADING_STICKERS): number {\n return way === 'fill' ? Math.floor(stickers / 2) : 0;\n}\n\nconst reducedMotion = (): MediaQueryList | null =>\n typeof matchMedia === 'function' ? matchMedia('(prefers-reduced-motion: reduce)') : null;\n\n/**\n * `<cube-loading>`: something on its way. the app projects its own line (\"bringing my recipes…\")\n * and, when it failed, its own retry (`[cubeLoadingRetry]`). it is never red: a failed load is the\n * picture at rest, pale, over the app's words.\n */\n@Component({\n selector: 'cube-loading',\n imports: [CubePicture, CubeSquare, CubeSquareTile],\n host: {\n '[class]': \"'cl-' + level()\",\n '[class.cl-failed]': 'failed()',\n '[attr.aria-busy]': 'failed() ? \"false\" : \"true\"',\n '[attr.data-way]': 'wayInUse()',\n },\n template: `\n <span class=\"cl-cube\">\n <cube-picture [count]=\"8\" [colours]=\"stickers()\" [width]=\"widthInUse()\" />\n </span>\n <span class=\"cl-line\" role=\"status\" aria-live=\"polite\"><ng-content /></span>\n @if (failed()) {\n <span class=\"cl-retry\"><ng-content select=\"[cubeLoadingRetry]\" /></span>\n } @else if (level() === 'page' && places().length) {\n <cube-square class=\"cl-square\" [tiles]=\"places()\">\n <ng-template [cubeSquareTile]=\"places()\"><span class=\"cl-place\"></span></ng-template>\n </cube-square>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--cube-loading-gap, 12px);\n text-align: center;\n color: var(--cube-loading-line, inherit);\n }\n :host(.cl-page) {\n width: 100%;\n }\n :host(.cl-piece) {\n display: inline-flex;\n flex-direction: row;\n gap: 0.5em;\n vertical-align: middle;\n }\n .cl-cube {\n display: inline-flex;\n line-height: 0;\n }\n .cl-line:empty,\n .cl-retry:empty {\n display: none;\n }\n .cl-square {\n display: block;\n width: 100%;\n margin-top: var(--cube-loading-gap, 12px);\n }\n .cl-place {\n display: block;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n /* the square's radius at its level (it zooms out as it holds more). */\n border-radius: var(--cs-radius, var(--cube-square-radius, 20px));\n background: var(--cube-loading-place, var(--cube-unknown, #e3e7e1));\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CubeLoading {\n /** how much is on its way: a page (the default), a cube or a piece. */\n readonly level = input<CubeLoadingLevel>('page');\n /** the way it is shown; null is the one picked for its level (`loadingWayFor`). */\n readonly way = input<CubeLoadingWay | null>(null);\n /** how many places the square on a page has: its pale places, a complete square. 0 draws none. */\n readonly count = input(9);\n /** it did not come: the picture rests, pale; the line is the app's and its retry is projected. */\n readonly failed = input(false);\n /** the colours the stickers take; cube design's sample palette when not set. */\n readonly colours = input<readonly string[]>(CUBE_LOADING_COLOURS);\n /** the picture's width in pixels; null is its level's (`CUBE_LOADING_WIDTH`). */\n readonly width = input<number | null>(null);\n\n protected readonly wayInUse = computed(() => this.way() ?? loadingWayFor(this.level()));\n protected readonly widthInUse = computed(() => this.width() ?? CUBE_LOADING_WIDTH[this.level()]);\n protected readonly places = computed(() =>\n Array.from({ length: Math.max(0, Math.floor(this.count())) }, (_, i) => i),\n );\n\n private readonly step = signal(0);\n private readonly still = signal(reducedMotion()?.matches ?? false);\n\n protected readonly stickers = computed(() => {\n if (this.failed()) return [];\n const way = this.wayInUse();\n return loadingStickers(way, this.still() ? stillStep(way) : this.step(), this.colours());\n });\n\n constructor() {\n if (!isPlatformBrowser(inject(PLATFORM_ID))) return;\n const mq = reducedMotion();\n const change = (e: MediaQueryListEvent) => this.still.set(e.matches);\n mq?.addEventListener?.('change', change);\n inject(DestroyRef).onDestroy(() => mq?.removeEventListener?.('change', change));\n effect((onCleanup) => {\n if (this.failed() || this.still()) return;\n const timer = setInterval(() => this.step.update((s) => s + 1), CUBE_LOADING_STEP_MS[this.wayInUse()]);\n onCleanup(() => clearInterval(timer));\n });\n }\n}\n"],"mappings":"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"}
|