@jokerized/decksmith 0.9.5 → 0.9.6
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/dist/cli.js +20780 -10104
- package/dist/deck-runtime.js +2 -2
- package/dist/index.js +11501 -1435
- package/dist/mcp.js +10775 -1087
- package/dist/types/bespoke/pipeline.d.ts +1 -1
- package/dist/types/bespoke/scene.d.ts +18 -2
- package/dist/types/emit/archetypes/index.d.ts +15 -0
- package/dist/types/emit/composition.d.ts +16 -1
- package/dist/types/emit/kit.d.ts +33 -0
- package/dist/types/emit/svg.d.ts +19 -0
- package/dist/types/emit/tex.d.ts +13 -0
- package/dist/types/literal/check.d.ts +45 -0
- package/dist/types/literal/formula.d.ts +78 -0
- package/dist/types/literal/index.d.ts +133 -0
- package/dist/types/literal/kind.d.ts +121 -0
- package/dist/types/literal/kinds/common.d.ts +280 -0
- package/dist/types/literal/kinds/evolve.d.ts +58 -0
- package/dist/types/literal/kinds/flow.d.ts +13 -0
- package/dist/types/literal/kinds/operate.d.ts +27 -0
- package/dist/types/literal/kinds/place-combos.d.ts +33 -0
- package/dist/types/literal/kinds/place-lengths.d.ts +36 -0
- package/dist/types/literal/kinds/place-margins.d.ts +44 -0
- package/dist/types/literal/kinds/place-sets.d.ts +31 -0
- package/dist/types/literal/kinds/place.d.ts +69 -0
- package/dist/types/literal/kinds/prior-work.d.ts +29 -0
- package/dist/types/literal/kinds/read.d.ts +33 -0
- package/dist/types/literal/kinds/recap.d.ts +16 -0
- package/dist/types/literal/kinds/region.d.ts +56 -0
- package/dist/types/literal/kinds/stage.d.ts +108 -0
- package/dist/types/literal/kinds/svg.d.ts +65 -0
- package/dist/types/literal/kinds/table.d.ts +19 -0
- package/dist/types/literal/kinds/tex.d.ts +6 -0
- package/dist/types/literal/kinds-shared.d.ts +15 -0
- package/dist/types/literal/kit.d.ts +86 -0
- package/dist/types/literal/ops.d.ts +56 -0
- package/dist/types/literal/registry.d.ts +20 -0
- package/dist/types/plan/codex.d.ts +15 -4
- package/dist/types/plan/coverage.d.ts +179 -0
- package/dist/types/plan/duration.d.ts +2 -0
- package/dist/types/plan/locate.d.ts +46 -0
- package/dist/types/plan/prompt.d.ts +14 -1
- package/dist/types/plan/variety.d.ts +23 -0
- package/dist/types/render/timing.d.ts +7 -1
- package/dist/types/source/harvest.d.ts +1 -0
- package/dist/types/types.d.ts +21451 -933
- package/dist/types/verify/fidelity.d.ts +7 -2
- package/dist/types/verify/fill.d.ts +70 -9
- package/dist/types/verify/overprint.d.ts +46 -0
- package/dist/types/verify/scenes.d.ts +61 -2
- package/package.json +1 -1
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the mechanism kinds share: the shape of their output, a seeded random
|
|
3
|
+
* source, and a few raster and layout helpers.
|
|
4
|
+
*
|
|
5
|
+
* A mechanism kind is a PURE function from typed inputs (a picture, a table of
|
|
6
|
+
* numbers, a graph) and the scene's region to a
|
|
7
|
+
* `MechanismResult`: rasters computed at build time, and frames of plain
|
|
8
|
+
* vector primitives in region pixels. The framework renders them (`svg.ts`
|
|
9
|
+
* draws one frame as SVG; an adapter turns rasters into files and frames into
|
|
10
|
+
* a fragment whose steps follow the narration).
|
|
11
|
+
*
|
|
12
|
+
* Determinism: no `Math.random`, no `Date`; every random draw comes from
|
|
13
|
+
* `mulberry32(seed)`. Same input, same bytes (`resultBytes` is what the tests
|
|
14
|
+
* hash).
|
|
15
|
+
*
|
|
16
|
+
* Words: a kind never writes language of its own. A text primitive carries
|
|
17
|
+
* either the input's own strings (tokens, item names, node labels) or a slot
|
|
18
|
+
* name plus the computed values the slot's text may name as `{var}`, exactly
|
|
19
|
+
* like the literal kinds' `slotText` (src/types.ts `LiteralSlot`).
|
|
20
|
+
*/
|
|
21
|
+
import type { LiteralSlot } from "../../types.js";
|
|
22
|
+
/** FNV-1a, the repo's one copy (src/emit/motion.ts): a deterministic bucket from text. */
|
|
23
|
+
export { fnv1a } from "../../emit/motion.js";
|
|
24
|
+
import type { Rgb } from "../kit.js";
|
|
25
|
+
export type { LiteralSlot, Rgb };
|
|
26
|
+
/** A scalar map, 0..1 unless a kind says otherwise, row-major. */
|
|
27
|
+
export interface Gray {
|
|
28
|
+
w: number;
|
|
29
|
+
h: number;
|
|
30
|
+
d: Float32Array;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A theme colour by name — the style pack's tokens and nothing else: ink (fg),
|
|
34
|
+
* muted, dim, rule, panel, accent and the four tones. The ground is the shell's;
|
|
35
|
+
* a kind never paints it.
|
|
36
|
+
*/
|
|
37
|
+
export type Role = "fg" | "muted" | "dim" | "rule" | "panel" | "accent" | "a" | "b" | "c" | "d";
|
|
38
|
+
/** A picture with straight alpha, 0..1 per channel, RGBA row-major: drawn over the deck's ground. */
|
|
39
|
+
export interface Rgba {
|
|
40
|
+
w: number;
|
|
41
|
+
h: number;
|
|
42
|
+
d: Float32Array;
|
|
43
|
+
}
|
|
44
|
+
/** A colour the data itself computes (a node's features), 0..1 per channel. */
|
|
45
|
+
export type DataRgb = readonly [number, number, number];
|
|
46
|
+
interface Paint {
|
|
47
|
+
/** Stable across frames, so the framework can tween one primitive from frame to frame. */
|
|
48
|
+
id?: string;
|
|
49
|
+
opacity?: number;
|
|
50
|
+
/**
|
|
51
|
+
* STAGING (src/literal/kinds/stage.ts). `at` ≥ 1: hidden when its frame
|
|
52
|
+
* opens, revealed as the frame's `at`-th sub-step, spread over the frame's
|
|
53
|
+
* sentence; `wipe`: revealed left to right by a clip, not a fade; `cam`: part
|
|
54
|
+
* of the frame's material the camera moves over once the reveals are done.
|
|
55
|
+
*/
|
|
56
|
+
at?: number;
|
|
57
|
+
wipe?: boolean;
|
|
58
|
+
cam?: boolean;
|
|
59
|
+
}
|
|
60
|
+
export type Prim = (Paint & {
|
|
61
|
+
p: "line";
|
|
62
|
+
x1: number;
|
|
63
|
+
y1: number;
|
|
64
|
+
x2: number;
|
|
65
|
+
y2: number;
|
|
66
|
+
role: Role;
|
|
67
|
+
/** Tone weights (see the circle's `mix`): the line carries a data colour instead of `role`. */
|
|
68
|
+
mix?: number[];
|
|
69
|
+
width: number;
|
|
70
|
+
arrow?: boolean;
|
|
71
|
+
dash?: boolean;
|
|
72
|
+
}) | (Paint & {
|
|
73
|
+
p: "path";
|
|
74
|
+
/** x0, y0, x1, y1, … */
|
|
75
|
+
pts: number[];
|
|
76
|
+
role: Role;
|
|
77
|
+
width: number;
|
|
78
|
+
closed?: boolean;
|
|
79
|
+
fill?: Role;
|
|
80
|
+
dash?: boolean;
|
|
81
|
+
}) | (Paint & {
|
|
82
|
+
p: "rect";
|
|
83
|
+
x: number;
|
|
84
|
+
y: number;
|
|
85
|
+
w: number;
|
|
86
|
+
h: number;
|
|
87
|
+
/** Stroke. */
|
|
88
|
+
role?: Role;
|
|
89
|
+
width?: number;
|
|
90
|
+
fill?: Role;
|
|
91
|
+
/** 0..1 on the theme's ramp (background → accent), instead of `fill`. */
|
|
92
|
+
heat?: number;
|
|
93
|
+
mix?: number[];
|
|
94
|
+
rgb?: DataRgb;
|
|
95
|
+
radius?: number;
|
|
96
|
+
}) | (Paint & {
|
|
97
|
+
p: "circle";
|
|
98
|
+
cx: number;
|
|
99
|
+
cy: number;
|
|
100
|
+
r: number;
|
|
101
|
+
role?: Role;
|
|
102
|
+
width?: number;
|
|
103
|
+
fill?: Role;
|
|
104
|
+
heat?: number;
|
|
105
|
+
/**
|
|
106
|
+
* Weights 0..1 on the tones a, b, c, d (in that order): the hue is their
|
|
107
|
+
* weighted mix, the strength their sum (capped at 1) over the panel.
|
|
108
|
+
*/
|
|
109
|
+
mix?: number[];
|
|
110
|
+
rgb?: DataRgb;
|
|
111
|
+
}) | (Paint & {
|
|
112
|
+
p: "ellipse";
|
|
113
|
+
cx: number;
|
|
114
|
+
cy: number;
|
|
115
|
+
rx: number;
|
|
116
|
+
ry: number;
|
|
117
|
+
/** Degrees, clockwise in screen space. */
|
|
118
|
+
angle: number;
|
|
119
|
+
role?: Role;
|
|
120
|
+
width?: number;
|
|
121
|
+
rgb?: DataRgb;
|
|
122
|
+
}) | (Paint & {
|
|
123
|
+
p: "text";
|
|
124
|
+
x: number;
|
|
125
|
+
y: number;
|
|
126
|
+
/** Baseline-free: `y` is the top of the line. */
|
|
127
|
+
size: number;
|
|
128
|
+
/** "auto": the theme's ink (fg) or its panel, whichever reads better on what is under the text. */
|
|
129
|
+
role: Role | "auto";
|
|
130
|
+
anchor: "start" | "middle" | "end";
|
|
131
|
+
weight?: number;
|
|
132
|
+
/** The input's own string … */
|
|
133
|
+
text?: string;
|
|
134
|
+
/** … or a slot, filled with `vars`. */
|
|
135
|
+
slot?: string;
|
|
136
|
+
vars?: Readonly<Record<string, string | number>>;
|
|
137
|
+
}) | (Paint & {
|
|
138
|
+
/**
|
|
139
|
+
* A formula, typeset in the page by the deck's KaTeX (`ds-tex`) in display
|
|
140
|
+
* style; `w`×`h` is its box as estimated at build (./tex.ts `texBox`).
|
|
141
|
+
*/
|
|
142
|
+
p: "tex";
|
|
143
|
+
x: number;
|
|
144
|
+
y: number;
|
|
145
|
+
w: number;
|
|
146
|
+
h: number;
|
|
147
|
+
size: number;
|
|
148
|
+
tex: string;
|
|
149
|
+
role: Role;
|
|
150
|
+
}) | (Paint & {
|
|
151
|
+
p: "image";
|
|
152
|
+
x: number;
|
|
153
|
+
y: number;
|
|
154
|
+
w: number;
|
|
155
|
+
h: number;
|
|
156
|
+
/** Key into `MechanismResult.rasters`. */
|
|
157
|
+
layer: string;
|
|
158
|
+
/** Nearest-neighbour upscaling (a patch grid stays a grid). */
|
|
159
|
+
pixelated?: boolean;
|
|
160
|
+
/** Keep the picture's own aspect inside the box (a figure, a layer of unknown size). */
|
|
161
|
+
fit?: boolean;
|
|
162
|
+
/** With `fit`, at the box's top rather than its middle (a picture under its title). */
|
|
163
|
+
top?: boolean;
|
|
164
|
+
});
|
|
165
|
+
/** A raster layer: a picture, or a scalar map drawn in a theme colour with alpha = value × `alpha`. */
|
|
166
|
+
export type Raster = {
|
|
167
|
+
rgb: Rgb;
|
|
168
|
+
} | {
|
|
169
|
+
rgba: Rgba;
|
|
170
|
+
} | {
|
|
171
|
+
heat: Gray;
|
|
172
|
+
role: Role;
|
|
173
|
+
alpha: number;
|
|
174
|
+
};
|
|
175
|
+
export interface Frame {
|
|
176
|
+
id: string;
|
|
177
|
+
prims: Prim[];
|
|
178
|
+
/**
|
|
179
|
+
* Room left around the camera's material for its push-in, px a side: the
|
|
180
|
+
* camera's clip is its material's box grown by this, so text at the edge of
|
|
181
|
+
* a plot is not cut while the camera leans in (`text_clipped`).
|
|
182
|
+
*/
|
|
183
|
+
pad?: {
|
|
184
|
+
x: number;
|
|
185
|
+
y: number;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* The frame's faded reveals stand at `PREVIEW` opacity from the frame's
|
|
189
|
+
* first moment and come to full when spoken, so every hold shows the whole
|
|
190
|
+
* diagram (the fill gate measures the content's box at EVERY hold). For a
|
|
191
|
+
* diagram whose parts are known up front — a chain's stages, a plane's points,
|
|
192
|
+
* a set's members — never for a computed result, which must not show before
|
|
193
|
+
* the op that makes it. Wipes are untouched.
|
|
194
|
+
*/
|
|
195
|
+
preview?: boolean;
|
|
196
|
+
/**
|
|
197
|
+
* Px the camera's material moves LEFT across the frame's time: a picture wider
|
|
198
|
+
* than the scene read along (a band of a figure), instead of a push-in.
|
|
199
|
+
*/
|
|
200
|
+
pan?: number;
|
|
201
|
+
/**
|
|
202
|
+
* The camera back at rest before the frame ends: frames that must line up
|
|
203
|
+
* across their crossfade (a trace's rows, the lit one walking down). Pushed in
|
|
204
|
+
* at its end, a frame would fade into the next at rest and every row jump.
|
|
205
|
+
*/
|
|
206
|
+
settle?: boolean;
|
|
207
|
+
/** Where the push leans in, in the frame's own coordinates: else its material's middle. */
|
|
208
|
+
focus?: {
|
|
209
|
+
x: number;
|
|
210
|
+
y: number;
|
|
211
|
+
};
|
|
212
|
+
/** The values this frame's slots may name. */
|
|
213
|
+
vars: Record<string, string | number>;
|
|
214
|
+
}
|
|
215
|
+
export interface MechanismResult {
|
|
216
|
+
rasters: Record<string, Raster>;
|
|
217
|
+
frames: Frame[];
|
|
218
|
+
/** The computed numbers, for tests and for a fragment that wants them. */
|
|
219
|
+
data: Record<string, unknown>;
|
|
220
|
+
/** Values the takeaway template names. */
|
|
221
|
+
vars: Record<string, string | number>;
|
|
222
|
+
/** What a later verb may take as input (src/literal/kit.ts `Material`). */
|
|
223
|
+
material?: import("../kit.js").Material;
|
|
224
|
+
}
|
|
225
|
+
export interface Region {
|
|
226
|
+
width: number;
|
|
227
|
+
height: number;
|
|
228
|
+
}
|
|
229
|
+
/** Text width in px; the adapter passes the deck's own measure (src/emit/svg.ts `textWidth`). */
|
|
230
|
+
export type Measure = (text: string, size: number) => number;
|
|
231
|
+
/** A conservative Latin estimate, for tests and previews. */
|
|
232
|
+
export declare const roughMeasure: Measure;
|
|
233
|
+
/**
|
|
234
|
+
* Han and kana: the scripts with no spaces between words, so a line breaks
|
|
235
|
+
* between any two characters — as the deck's own CSS lets Chinese and Japanese
|
|
236
|
+
* break (src/emit/composition.ts `cjkTypesetCss`). Hangul is not here: Korean
|
|
237
|
+
* breaks at spaces, and a Korean word stays whole (`keep-all`).
|
|
238
|
+
*/
|
|
239
|
+
export declare const BREAKS_ANYWHERE: RegExp;
|
|
240
|
+
/**
|
|
241
|
+
* Greedy wrap by a measure. Breaks at spaces and, inside Han or kana, between
|
|
242
|
+
* characters — without that a Chinese label is one unbreakable word (a
|
|
243
|
+
* 14-character item ran 621px into a 582px part). A lone separator ("·") never
|
|
244
|
+
* opens a line. A unit wider than the line keeps its own line; the caller decides
|
|
245
|
+
* whether that is an error. An empty text is no lines.
|
|
246
|
+
*/
|
|
247
|
+
export declare function wrapBy(text: string, size: number, maxW: number, measure: Measure): string[];
|
|
248
|
+
/** The deck's type, never below 40 px at 1920×1080 (invariant 5). */
|
|
249
|
+
export declare const TYPE: {
|
|
250
|
+
readonly headline: 56;
|
|
251
|
+
readonly body: 44;
|
|
252
|
+
readonly label: 40;
|
|
253
|
+
};
|
|
254
|
+
/** Mulberry32: a 32-bit seeded generator, uniform on [0, 1). */
|
|
255
|
+
export declare function mulberry32(seed: number): () => number;
|
|
256
|
+
/** `{name}` in a template, replaced by `vars[name]`; throws on a name it was not given. */
|
|
257
|
+
export declare function fillTemplate(template: string, vars: Readonly<Record<string, string | number>>): string;
|
|
258
|
+
/** A number as a plain value: `digits` decimals, no trailing noise, "-0" never shown. */
|
|
259
|
+
export declare function fmt(n: number, digits?: number): string;
|
|
260
|
+
/** Area-average resample of a picture to w×h (any ratio). */
|
|
261
|
+
export declare function resample(img: Rgb, w: number, h: number): Rgb;
|
|
262
|
+
/** The largest w×h box of the picture's aspect inside bw×bh, centred at (bx, by). */
|
|
263
|
+
export declare function fitBox(w: number, h: number, bx: number, by: number, bw: number, bh: number): {
|
|
264
|
+
x: number;
|
|
265
|
+
y: number;
|
|
266
|
+
w: number;
|
|
267
|
+
h: number;
|
|
268
|
+
};
|
|
269
|
+
/** A polyline as flat points, rounded to 2 decimals (bytes do not drift). */
|
|
270
|
+
export declare function flat(points: ReadonlyArray<readonly [number, number]>): number[];
|
|
271
|
+
/** Clamped to 0..1. */
|
|
272
|
+
export declare const clamp01: (n: number) => number;
|
|
273
|
+
export declare const r2: (n: number) => number;
|
|
274
|
+
/**
|
|
275
|
+
* Every byte a result carries, for determinism checks: each raster's floats and
|
|
276
|
+
* the frames and data as JSON (typed arrays as their bytes' hex).
|
|
277
|
+
*/
|
|
278
|
+
export declare function resultBytes(r: MechanismResult): Buffer;
|
|
279
|
+
/** `p` moved by (dx, dy). */
|
|
280
|
+
export declare function shiftPrim(p: Prim, dx: number, dy: number): Prim;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { MechanismResult, Raster } from "./common.js";
|
|
2
|
+
import { type Role } from "./common.js";
|
|
3
|
+
import { type VerbCtx } from "./stage.js";
|
|
4
|
+
type Ctx = VerbCtx<"evolve">;
|
|
5
|
+
export declare function evolve(c: Ctx): MechanismResult;
|
|
6
|
+
/**
|
|
7
|
+
* THE ROW LOOK (the approved evolve, .planning/designs/2026-10-12-verb-looks/
|
|
8
|
+
* 2-evolve.png): one row per step, its number, what it carries on from (muted)
|
|
9
|
+
* and its parts in their tags' tones; the legend and the source's note beside.
|
|
10
|
+
* One frame per step: the step's row is lit on a panel, its parts arriving run
|
|
11
|
+
* by run (a struck part is crossed out as it arrives), the rows before it stay
|
|
12
|
+
* at ROW_DONE, the rows after it show only their numbers. Frames crossfade, so
|
|
13
|
+
* the lit row walks down the trace; each frame's push leans in on the lit row
|
|
14
|
+
* and `settle`s back to rest before the next, or every row would jump between
|
|
15
|
+
* two frames and break that walk. Too many
|
|
16
|
+
* rows for the height: a window of them, the lit one second from the bottom. A
|
|
17
|
+
* short trace is spread down the scene, as a chain's column is: the deck's gate
|
|
18
|
+
* wants the content to span the region (src/verify/fill.ts).
|
|
19
|
+
*/
|
|
20
|
+
export interface RowTag {
|
|
21
|
+
tag: string;
|
|
22
|
+
label: string;
|
|
23
|
+
tone: Role;
|
|
24
|
+
strike?: boolean;
|
|
25
|
+
/** Not in the legend: words that name their own row (a lane's name, its total). */
|
|
26
|
+
hidden?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface Row {
|
|
29
|
+
lead?: string;
|
|
30
|
+
parts: ReadonlyArray<{
|
|
31
|
+
text: string;
|
|
32
|
+
tag: string;
|
|
33
|
+
}>;
|
|
34
|
+
/** A picture at the row's start: a raster layer. */
|
|
35
|
+
image?: string;
|
|
36
|
+
/** Bars after the words, each 0..1 of its rail in its tag's tone; a tick at `mark`; `dim` when frozen. */
|
|
37
|
+
bars?: ReadonlyArray<{
|
|
38
|
+
value: number;
|
|
39
|
+
tag: string;
|
|
40
|
+
mark?: {
|
|
41
|
+
at: number;
|
|
42
|
+
tag: string;
|
|
43
|
+
};
|
|
44
|
+
dim?: boolean;
|
|
45
|
+
}>;
|
|
46
|
+
/** A track of runs along the bar column: each from..to (0..1 of it) in `blocks` blocks. */
|
|
47
|
+
track?: ReadonlyArray<{
|
|
48
|
+
from: number;
|
|
49
|
+
to: number;
|
|
50
|
+
tag: string;
|
|
51
|
+
blocks: number;
|
|
52
|
+
}>;
|
|
53
|
+
}
|
|
54
|
+
export declare function rowsLook(c: Ctx, rows: readonly Row[], tags: readonly RowTag[], note: readonly string[], opts?: {
|
|
55
|
+
rasters?: Record<string, Raster>;
|
|
56
|
+
aspect?: number;
|
|
57
|
+
}): MechanismResult;
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { MechanismResult } from "./common.js";
|
|
2
|
+
import { type VerbCtx } from "./stage.js";
|
|
3
|
+
type Ctx = VerbCtx<"flow">;
|
|
4
|
+
export declare function flow(c: Ctx): MechanismResult;
|
|
5
|
+
/**
|
|
6
|
+
* A stage's `shape` as the tokens it counts, when it is a count the source
|
|
7
|
+
* states: a whole number (that many chips, unlabelled), or one symbol with an
|
|
8
|
+
* optional offset, alone or as the end of a run from 1 ("γ", "γ+1", "1…γ+1"),
|
|
9
|
+
* drawn as 1, 2, …, the symbol, so no value of the symbol is invented.
|
|
10
|
+
* Anything else ("H×W×C", "256×256") is not a count and stays words.
|
|
11
|
+
*/
|
|
12
|
+
export declare function tokenChips(shape: string): string[] | undefined;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* operate — the approved look (.planning/designs/2026-10-12-verb-looks/
|
|
3
|
+
* 1-operate.png): what the source states on top, as chips, then one CELL per
|
|
4
|
+
* computed stage joined in reading order, each revealed on its sentence. Two
|
|
5
|
+
* forms:
|
|
6
|
+
*
|
|
7
|
+
* TERMS: a stated formula evaluated term by term on the values the source gives
|
|
8
|
+
* — the equation above, a cell a term, the terms combined into the result beside
|
|
9
|
+
* the source's own reported number, which it must match.
|
|
10
|
+
*
|
|
11
|
+
* CHAIN: an input run through KNOWN operations (src/literal/ops.ts), every output
|
|
12
|
+
* computed for real at build time — the input, then each step's output, a cell
|
|
13
|
+
* each: a picture or a matrix as itself, vectors as bars over their bins on each
|
|
14
|
+
* cell's own scale; a `compare` adds the other side's cell.
|
|
15
|
+
*
|
|
16
|
+
* WHAT IS EXACT. The ops and terms, with the values the source states (the gate
|
|
17
|
+
* grounds each in its role, src/plan/coverage.ts). WHAT IS EXAMPLE. A chain's
|
|
18
|
+
* input when it is a picture (always: a picture is never the method's own
|
|
19
|
+
* intermediate) or a vector the source does not print, and any `condition`;
|
|
20
|
+
* the scene then carries the example tag, and prints no computed value. No
|
|
21
|
+
* cell invents a number: no ticks, no values on example data.
|
|
22
|
+
*/
|
|
23
|
+
import type { MechanismResult } from "./common.js";
|
|
24
|
+
import { type VerbCtx } from "./stage.js";
|
|
25
|
+
type Ctx = VerbCtx<"operate">;
|
|
26
|
+
export declare function operate(c: Ctx): MechanismResult;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ablation — the experiments a paper did not run, shown as the holes they
|
|
3
|
+
* leave. Every combination of its components (one or two) is a square of one
|
|
4
|
+
* small grid: the combinations the source reports are filled and their results
|
|
5
|
+
* stand under the grid, large; the rest are visibly empty, and one quiet mark
|
|
6
|
+
* says what an empty square means. Each setting the source fixes is its name and
|
|
7
|
+
* the ONE value tested, as words (no axis: the source states no range), and
|
|
8
|
+
* further comparisons it proposes are outlined.
|
|
9
|
+
*
|
|
10
|
+
* Nothing here is computed but the layout: the components, the reported
|
|
11
|
+
* results, the settings' values and the proposals are the plan's, held to the
|
|
12
|
+
* source by the truth gate. The empty cells are the point of the scene, not a
|
|
13
|
+
* placeholder: they are what the next experiment would fill.
|
|
14
|
+
*/
|
|
15
|
+
import { type KindImpl } from "../kind.js";
|
|
16
|
+
export interface AblationData {
|
|
17
|
+
components: string[];
|
|
18
|
+
reported: Array<{
|
|
19
|
+
with: string[];
|
|
20
|
+
result: string;
|
|
21
|
+
}>;
|
|
22
|
+
settings: Array<{
|
|
23
|
+
name: string;
|
|
24
|
+
value: string;
|
|
25
|
+
}>;
|
|
26
|
+
others: string[];
|
|
27
|
+
}
|
|
28
|
+
/** Every combination of the components, as the components each one keeps, in grid order. */
|
|
29
|
+
export declare function combinations(components: readonly string[]): string[][];
|
|
30
|
+
/** The reported result of one combination, or undefined when the source reports none. */
|
|
31
|
+
export declare function resultOf(d: AblationData, keep: readonly string[]): string | undefined;
|
|
32
|
+
/** place, form combos: the experiments a source did not run, as empty cells. */
|
|
33
|
+
export declare const combosForm: KindImpl;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* place, measure length — reported quantities as AREAS to scale. Never bars.
|
|
3
|
+
*
|
|
4
|
+
* Each item is a block whose area is its value on one shared scale, drawn whole
|
|
5
|
+
* and faded in; nothing grows (the brief bans growing bars, and r2's "97M vs 6M"
|
|
6
|
+
* drew two horizontal bars that read as a bar chart however they arrived). A
|
|
7
|
+
* group of whole counts no larger than `UNITS_MAX` is drawn as that many unit
|
|
8
|
+
* cells (35 tokens are 35 cells); any other group as squares whose sides go as
|
|
9
|
+
* √value. A group's blocks sit on one baseline across the region's width, so the
|
|
10
|
+
* scene fills its frame however unequal the values are, with each item's name
|
|
11
|
+
* and value under its block.
|
|
12
|
+
*
|
|
13
|
+
* Squares: the smallest block's outline then slides onto the largest, so the two
|
|
14
|
+
* are compared at one scale; with `tile` the quotient the source states is
|
|
15
|
+
* printed beside it (`tileRatio`, the number the truth gate checks).
|
|
16
|
+
*/
|
|
17
|
+
import { type KindImpl } from "../kind.js";
|
|
18
|
+
interface ScaleData {
|
|
19
|
+
groups: Array<{
|
|
20
|
+
label: string;
|
|
21
|
+
unit: string;
|
|
22
|
+
items: Array<{
|
|
23
|
+
label: string;
|
|
24
|
+
value: string;
|
|
25
|
+
}>;
|
|
26
|
+
}>;
|
|
27
|
+
tile: boolean;
|
|
28
|
+
}
|
|
29
|
+
/** A group of whole counts up to this is drawn as unit cells; larger values as squares. */
|
|
30
|
+
export declare const UNITS_MAX = 100;
|
|
31
|
+
type Group = ScaleData["groups"][number];
|
|
32
|
+
/** Whether a group is drawn as unit cells: every value a whole count, 1–UNITS_MAX. */
|
|
33
|
+
export declare const unitCells: (g: Group) => boolean;
|
|
34
|
+
/** place, measure length: reported quantities as areas to scale. */
|
|
35
|
+
export declare const lengthsForm: KindImpl;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* margins — results against the best OTHER method, as positions: each setting
|
|
3
|
+
* (a dataset, a split) placed by its margin on one metric (a strip) or two (a
|
|
4
|
+
* plane), zero being "level with the best other method". Where the method leads
|
|
5
|
+
* and where it trails is then a place on screen, not a cell to read.
|
|
6
|
+
*
|
|
7
|
+
* EXACT ARITHMETIC ON THE SOURCE'S NUMBERS. The plan gives, per setting and
|
|
8
|
+
* metric, the method's value, the best other method's value and its name, as
|
|
9
|
+
* the source states them (the truth gate holds every one to the source); the
|
|
10
|
+
* margin is their difference, signed so that positive is better, printed with
|
|
11
|
+
* as many decimals as the values carry. Each axis is scaled to its own largest
|
|
12
|
+
* margin, which the `scaled` slot says on screen. No dataset picture is drawn:
|
|
13
|
+
* a source without one has none to show, and none is made up.
|
|
14
|
+
*/
|
|
15
|
+
import { type KindImpl } from "../kind.js";
|
|
16
|
+
export interface MarginsData {
|
|
17
|
+
ours: string;
|
|
18
|
+
metrics: Array<{
|
|
19
|
+
name: string;
|
|
20
|
+
lowerIsBetter: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
settings: Array<{
|
|
23
|
+
name: string;
|
|
24
|
+
values: Array<{
|
|
25
|
+
ours: string;
|
|
26
|
+
best: string;
|
|
27
|
+
rival: string;
|
|
28
|
+
}>;
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
export interface Margin {
|
|
32
|
+
/** Positive: the method is better than the best other method on this metric. */
|
|
33
|
+
gap: number;
|
|
34
|
+
/** The gap as printed: signed, with the values' own decimals. */
|
|
35
|
+
text: string;
|
|
36
|
+
}
|
|
37
|
+
/** One margin: ours − best (best − ours when lower is better), at the values' precision. */
|
|
38
|
+
export declare function marginOf(ours: string, best: string, lowerIsBetter: boolean): Margin;
|
|
39
|
+
/** Every setting's margins, metric by metric; refuses a setting with the wrong number of values. */
|
|
40
|
+
export declare function marginsOf(d: MarginsData): Margin[][];
|
|
41
|
+
/** Each axis's half-range: its largest |margin|, with room so no point sits on the frame. */
|
|
42
|
+
export declare function axisSpan(margins: readonly Margin[][], m: number): number;
|
|
43
|
+
/** place, measure margin: results against the best other method, as positions. */
|
|
44
|
+
export declare const marginsForm: KindImpl;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type KindImpl } from "../kind.js";
|
|
2
|
+
export interface ScopeData {
|
|
3
|
+
rings: Array<{
|
|
4
|
+
label: string;
|
|
5
|
+
items: string[];
|
|
6
|
+
}>;
|
|
7
|
+
}
|
|
8
|
+
/** One part of the split: its column, its label's lines, its items' lines and where they sit. */
|
|
9
|
+
export interface ScopePart {
|
|
10
|
+
x: number;
|
|
11
|
+
w: number;
|
|
12
|
+
label: string[];
|
|
13
|
+
items: Array<{
|
|
14
|
+
lines: string[];
|
|
15
|
+
y: number;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
18
|
+
export interface ScopeLayout {
|
|
19
|
+
parts: ScopePart[];
|
|
20
|
+
/** Where the items start, under the rules and the labels. */
|
|
21
|
+
top: number;
|
|
22
|
+
captionY: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The split: 2–4 equal columns side by side, each its rule, its label and its
|
|
26
|
+
* items stacked down the column with the room shared out between them, so a
|
|
27
|
+
* short list still uses the height. Throws when a part cannot fit.
|
|
28
|
+
*/
|
|
29
|
+
export declare function scopeLayout(d: ScopeData, W: number, H: number, measure: (text: string, size: number) => number, captionH?: number): ScopeLayout;
|
|
30
|
+
/** place, form sets: what a claim rests on and what lies outside it. */
|
|
31
|
+
export declare const setsForm: KindImpl;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Literal } from "../../types.js";
|
|
2
|
+
import { type KindImpl } from "../kind.js";
|
|
3
|
+
import type { Frame, MechanismResult } from "./common.js";
|
|
4
|
+
import { type VerbCtx } from "./stage.js";
|
|
5
|
+
type Ctx = VerbCtx<"place">;
|
|
6
|
+
type PlaceLit = Extract<Literal, {
|
|
7
|
+
kind: "place";
|
|
8
|
+
}>;
|
|
9
|
+
/** The first number a value states ("88.84", "4.46 s", "3.4X"). */
|
|
10
|
+
export declare function numberIn(v: string, what: string): number;
|
|
11
|
+
/** Which renderer a place scene is drawn with. */
|
|
12
|
+
export declare function placeForm(lit: PlaceLit): "points" | "margins" | "lengths" | "combos" | "sets";
|
|
13
|
+
/**
|
|
14
|
+
* Points, inset for the camera's push (`withPushRoom`); with a `figure`, the
|
|
15
|
+
* plot takes the left of the scene and the source's own picture of what was
|
|
16
|
+
* measured stands at the right under its `scene` title (the approved look,
|
|
17
|
+
* .planning/designs/2026-10-12-verb-looks.md).
|
|
18
|
+
*/
|
|
19
|
+
export declare const points: (c: Ctx) => MechanismResult;
|
|
20
|
+
/** A plane names each point beside it up to this many; past it, a key (`KEYED`). */
|
|
21
|
+
export declare const NAMED_MAX = 8;
|
|
22
|
+
interface Box {
|
|
23
|
+
x0: number;
|
|
24
|
+
y0: number;
|
|
25
|
+
x1: number;
|
|
26
|
+
y1: number;
|
|
27
|
+
}
|
|
28
|
+
/** A polyline (x0, y0, x1, y1, …) as small boxes every 10px along it, `w` px thick: an obstacle to a label. */
|
|
29
|
+
export declare function segBoxes(pts: readonly number[], w: number): Box[];
|
|
30
|
+
/**
|
|
31
|
+
* Where a point's label goes, and the leader that ties it to its dot when it
|
|
32
|
+
* sits more than `LEADER_PX` away: the first box, nearest first, inside the
|
|
33
|
+
* plot, that covers no word, point or line (`taken`, `strokes`) AND whose
|
|
34
|
+
* leader crosses no word or point.
|
|
35
|
+
* Null when there is none: the caller names the points by a key instead of
|
|
36
|
+
* drawing a word over a point, a line or another word.
|
|
37
|
+
*
|
|
38
|
+
* A plane tries beside the point, right then left, stepping 48px up and down.
|
|
39
|
+
* A strip tries its own side of the line first (`side`), then the other, at
|
|
40
|
+
* every level from the line out to the plot's edge — starting from level
|
|
41
|
+
* `spreadFrom` (the item's index), so a short strip's labels use the height
|
|
42
|
+
* rather than all hugging the axis.
|
|
43
|
+
*/
|
|
44
|
+
export declare function placeLabel(px: number, py: number, w: number, h: number, side: "beside" | "above" | "below", plot: {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
w: number;
|
|
48
|
+
h: number;
|
|
49
|
+
}, taken: readonly Box[], strokes: readonly Box[], spreadFrom?: number, others?: ReadonlyArray<{
|
|
50
|
+
x: number;
|
|
51
|
+
y: number;
|
|
52
|
+
}>, crossNot?: readonly Box[]): {
|
|
53
|
+
box: Box;
|
|
54
|
+
leader: number[][];
|
|
55
|
+
} | null;
|
|
56
|
+
/** Past this many px from its dot, a label is joined to it by a leader line. */
|
|
57
|
+
export declare const LEADER_PX = 60;
|
|
58
|
+
/** A label never sits further than this from its dot; past it the points are keyed. */
|
|
59
|
+
export declare const LEADER_MAX = 150;
|
|
60
|
+
/**
|
|
61
|
+
* 3–6 round tick values inside `[lo, hi]` (an axis's drawn range, in log10 on a
|
|
62
|
+
* log axis, where only powers of ten are ticked), each with its text.
|
|
63
|
+
*/
|
|
64
|
+
export declare function ticksOf(r: readonly [number, number], log: boolean): Array<{
|
|
65
|
+
v: number;
|
|
66
|
+
text: string;
|
|
67
|
+
}>;
|
|
68
|
+
export declare const placeKind: KindImpl;
|
|
69
|
+
export type { Frame };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* prior-work — earlier approaches shown by what they do, family by family,
|
|
3
|
+
* side by side. A family is shown by what an earlier verb scene of this deck
|
|
4
|
+
* COMPUTED (`from`: that scene's layer, brought back), or, for a family of
|
|
5
|
+
* learned methods, only by the numbers the source reports for its members,
|
|
6
|
+
* each held to the source by the truth gate. A network the build does not have
|
|
7
|
+
* is never drawn working.
|
|
8
|
+
*
|
|
9
|
+
* Each lane carries the family, its members and where the source says it runs
|
|
10
|
+
* out (`gap`), all the plan's words in the deck's language.
|
|
11
|
+
*/
|
|
12
|
+
import { type KindImpl } from "../kind.js";
|
|
13
|
+
export interface PriorWorkData {
|
|
14
|
+
lanes: Array<{
|
|
15
|
+
family: string;
|
|
16
|
+
members: string;
|
|
17
|
+
numbers: Array<{
|
|
18
|
+
label: string;
|
|
19
|
+
value: string;
|
|
20
|
+
}>;
|
|
21
|
+
from?: string | undefined;
|
|
22
|
+
gap: string;
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
/** Whether a lane shows an earlier scene's computed layer. */
|
|
26
|
+
export declare const runsOnPicture: (l: PriorWorkData["lanes"][number]) => boolean;
|
|
27
|
+
/** Checks a plan's lanes before anything is drawn: the counts and what each lane needs. */
|
|
28
|
+
export declare function checkLanes(d: PriorWorkData): void;
|
|
29
|
+
export declare const priorWorkKind: KindImpl;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading a verb's plan into numbers and op steps: every number is written as
|
|
3
|
+
* the source writes it ("0.6", "1,024") and read here; a name an op does not
|
|
4
|
+
* take, a variant it does not have, a value that is not a number, is refused
|
|
5
|
+
* with the reason, at plan time (the verb's dry run) as at build time.
|
|
6
|
+
*/
|
|
7
|
+
import { type LiteralOpDoc, type LiteralOpName } from "../../types.js";
|
|
8
|
+
import type { OpStep } from "../ops.js";
|
|
9
|
+
/** A number as the source writes it. */
|
|
10
|
+
export declare function num(value: string, what: string): number;
|
|
11
|
+
export interface PlanParam {
|
|
12
|
+
name: string;
|
|
13
|
+
value: string;
|
|
14
|
+
symbol?: string | undefined;
|
|
15
|
+
}
|
|
16
|
+
/** A param list as numbers by name, against what the op (or rule) takes. */
|
|
17
|
+
export declare function paramRecord(params: readonly PlanParam[], doc: Pick<LiteralOpDoc, "params">, what: string, free?: boolean): Record<string, number>;
|
|
18
|
+
/** The schema's op step (src/types.ts `literalSchema` operate.chain). */
|
|
19
|
+
export interface PlanStep {
|
|
20
|
+
op: LiteralOpName;
|
|
21
|
+
how?: string | undefined;
|
|
22
|
+
stat?: "mean" | "var" | "std" | undefined;
|
|
23
|
+
over?: "all" | "channel" | "row" | undefined;
|
|
24
|
+
params: readonly PlanParam[];
|
|
25
|
+
weights: readonly (readonly number[])[];
|
|
26
|
+
of: readonly number[];
|
|
27
|
+
expr?: string | undefined;
|
|
28
|
+
label: string;
|
|
29
|
+
}
|
|
30
|
+
/** A chain step read against the library: its variant, enums and params checked. */
|
|
31
|
+
export declare function opStepOf(s: PlanStep, k: number): OpStep;
|
|
32
|
+
/** A computed value as words: up to 3 significant decimals, no float dust. */
|
|
33
|
+
export declare function plain(v: number): string;
|