@jokerized/decksmith 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +794 -0
- package/dist/cli.js +8906 -0
- package/dist/deck-runtime.js +55 -0
- package/dist/index.js +8590 -0
- package/dist/mcp.js +7809 -0
- package/dist/server/errors.js +73 -0
- package/dist/server/http.js +504 -0
- package/dist/server/main.js +91 -0
- package/dist/server/options.js +198 -0
- package/dist/server/pipeline.js +356 -0
- package/dist/server/queue.js +195 -0
- package/dist/server/ui.js +1614 -0
- package/dist/server/upload.js +232 -0
- package/dist/types/cli.d.ts +1 -0
- package/dist/types/deck/runtime.d.ts +59 -0
- package/dist/types/deck/subtitles.d.ts +101 -0
- package/dist/types/emit/archetypes/annotated-figure.d.ts +103 -0
- package/dist/types/emit/archetypes/bar-compare.d.ts +30 -0
- package/dist/types/emit/archetypes/callout.d.ts +7 -0
- package/dist/types/emit/archetypes/claim-figure.d.ts +9 -0
- package/dist/types/emit/archetypes/data-table.d.ts +21 -0
- package/dist/types/emit/archetypes/equation-walk.d.ts +2 -0
- package/dist/types/emit/archetypes/grid.d.ts +16 -0
- package/dist/types/emit/archetypes/index.d.ts +19 -0
- package/dist/types/emit/archetypes/line-chart.d.ts +22 -0
- package/dist/types/emit/archetypes/pipeline.d.ts +81 -0
- package/dist/types/emit/archetypes/split-compare.d.ts +2 -0
- package/dist/types/emit/archetypes/stack.d.ts +93 -0
- package/dist/types/emit/archetypes/title.d.ts +188 -0
- package/dist/types/emit/camera.d.ts +397 -0
- package/dist/types/emit/composition.d.ts +191 -0
- package/dist/types/emit/island.d.ts +19 -0
- package/dist/types/emit/kit.d.ts +256 -0
- package/dist/types/emit/svg.d.ts +177 -0
- package/dist/types/emit/theme.d.ts +65 -0
- package/dist/types/emit/themes/index.d.ts +40 -0
- package/dist/types/emit/themes/ink.d.ts +12 -0
- package/dist/types/emit/themes/mono.d.ts +20 -0
- package/dist/types/emit/themes/paper.d.ts +18 -0
- package/dist/types/index.d.ts +200 -0
- package/dist/types/mcp/main.d.ts +2 -0
- package/dist/types/mcp/prereqs.d.ts +22 -0
- package/dist/types/mcp/tools.d.ts +212 -0
- package/dist/types/narrate/narrate.d.ts +87 -0
- package/dist/types/narrate/tts.d.ts +134 -0
- package/dist/types/narrate/voices.d.ts +29 -0
- package/dist/types/pack/media.d.ts +61 -0
- package/dist/types/pack/pack.d.ts +16 -0
- package/dist/types/plan/codex.d.ts +24 -0
- package/dist/types/plan/duration.d.ts +394 -0
- package/dist/types/plan/prompt.d.ts +47 -0
- package/dist/types/plan/refs.d.ts +22 -0
- package/dist/types/plan/select.d.ts +116 -0
- package/dist/types/prefs.d.ts +43 -0
- package/dist/types/render/captions.d.ts +108 -0
- package/dist/types/render/ffmpeg.d.ts +129 -0
- package/dist/types/render/render.d.ts +123 -0
- package/dist/types/render/timing.d.ts +290 -0
- package/dist/types/server/errors.d.ts +11 -0
- package/dist/types/server/http.d.ts +57 -0
- package/dist/types/server/main.d.ts +1 -0
- package/dist/types/server/options.d.ts +90 -0
- package/dist/types/server/pipeline.d.ts +21 -0
- package/dist/types/server/queue.d.ts +105 -0
- package/dist/types/server/ui.d.ts +9 -0
- package/dist/types/server/upload.d.ts +107 -0
- package/dist/types/source/assets.d.ts +11 -0
- package/dist/types/source/fonts.d.ts +15 -0
- package/dist/types/source/markdown.d.ts +8 -0
- package/dist/types/types.d.ts +1992 -0
- package/dist/types/verify/budget.d.ts +41 -0
- package/dist/types/verify/check.d.ts +78 -0
- package/dist/types/verify/drift.d.ts +158 -0
- package/dist/types/verify/fidelity.d.ts +247 -0
- package/dist/types/verify/index.d.ts +207 -0
- package/dist/types/verify/overprint.d.ts +133 -0
- package/dist/types/verify/typefloor.d.ts +50 -0
- package/package.json +84 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The architecture overview, redrawn as motion.
|
|
3
|
+
*
|
|
4
|
+
* Every paper has this figure and every paper renders it as a flat PNG the
|
|
5
|
+
* reader has to decode all at once. Drawn here instead, one stage at a time with
|
|
6
|
+
* its connector arriving first, the viewer watches the method assemble in the
|
|
7
|
+
* order it actually runs — which is the only reading order a static diagram
|
|
8
|
+
* cannot impose.
|
|
9
|
+
*
|
|
10
|
+
* Two decisions carry the whole archetype:
|
|
11
|
+
*
|
|
12
|
+
* Boxes are all one width, solved from the widest label (`pipeLayout`). Boxes
|
|
13
|
+
* sized individually to their own text is what a generator produces; a row of
|
|
14
|
+
* equal boxes on a shared centreline is what a designer draws. When the labels
|
|
15
|
+
* genuinely do not fit on one line the answer is more lines, not smaller type —
|
|
16
|
+
* type stops at `MIN_FONT` and the box grows downwards, because a stage nobody
|
|
17
|
+
* in the third row can read is not a stage.
|
|
18
|
+
*
|
|
19
|
+
* The two connector reveals are different on purpose. A stage-to-stage arrow is
|
|
20
|
+
* ~120px, so it fades in as one object and its head is never orphaned. The
|
|
21
|
+
* feedback loop is a ~1000px elbow, and something that long has to be watched
|
|
22
|
+
* travelling: it is revealed by a clip sweeping against the flow, so the path
|
|
23
|
+
* appears in the direction it runs and its arrowhead lands last, on the stage it
|
|
24
|
+
* returns to.
|
|
25
|
+
*
|
|
26
|
+
* A row is a landscape idea. In portrait the same four stages get 860px to share
|
|
27
|
+
* and come out as columns — the demo's "Window" broke to "Windo/w" and "DQ-CTM"
|
|
28
|
+
* to "DQ-CT/M", which is a diagram that has stopped being one. So portrait turns
|
|
29
|
+
* the flow ninety degrees and runs it down the page instead: full-width boxes,
|
|
30
|
+
* arrows pointing down, and the return path up a channel on the right. See
|
|
31
|
+
* `columnLayout` — the two arrangements share their type, their reveal and their
|
|
32
|
+
* furniture, and nothing else.
|
|
33
|
+
*/
|
|
34
|
+
import type { BeatOf } from "../../types.js";
|
|
35
|
+
import type { Emitter } from "../kit.js";
|
|
36
|
+
import { type Track } from "../svg.js";
|
|
37
|
+
type Stage = BeatOf<"pipeline">["params"]["stages"][number];
|
|
38
|
+
type Loop = {
|
|
39
|
+
from: number;
|
|
40
|
+
to: number;
|
|
41
|
+
label: string;
|
|
42
|
+
};
|
|
43
|
+
export interface PipeLayout {
|
|
44
|
+
/** Label type size. Never below `MIN_FONT`, whatever the labels cost. */
|
|
45
|
+
size: number;
|
|
46
|
+
/**
|
|
47
|
+
* Position and extent along the flow axis: `x`/`w` read as x/width across a
|
|
48
|
+
* row, and as y/height down a column. One field rather than two so the emitter
|
|
49
|
+
* paints both arrangements with one expression — a second `rows` array is how
|
|
50
|
+
* the landscape and portrait geometries drift apart.
|
|
51
|
+
*/
|
|
52
|
+
boxes: Track[];
|
|
53
|
+
/** The cross-axis extent every box shares: its height in a row, its width in a column. */
|
|
54
|
+
boxH: number;
|
|
55
|
+
boxX: number;
|
|
56
|
+
boxW: number;
|
|
57
|
+
/** True when the flow runs down the page. Decides every axis below it. */
|
|
58
|
+
vertical: boolean;
|
|
59
|
+
/** Width available to text inside a box — what every `wrap` here is given. */
|
|
60
|
+
innerW: number;
|
|
61
|
+
/** Wrapped lines per stage. The box height is derived from these, not guessed. */
|
|
62
|
+
labelLines: string[][];
|
|
63
|
+
noteLines: string[][];
|
|
64
|
+
/** Box bottom to the feedback leg. Zero when there is no loop. */
|
|
65
|
+
loopDrop: number;
|
|
66
|
+
loopLines: string[];
|
|
67
|
+
/** The loop's label column, and where it starts. Portrait only. */
|
|
68
|
+
loopX: number;
|
|
69
|
+
loopW: number;
|
|
70
|
+
svgH: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* All the geometry, with no SVG in sight.
|
|
74
|
+
*
|
|
75
|
+
* Exported because "the text stays inside the box" is the one thing this
|
|
76
|
+
* archetype must never get wrong, and asserting it against numbers beats
|
|
77
|
+
* asserting it against a rendered string.
|
|
78
|
+
*/
|
|
79
|
+
export declare function pipeLayout(stageW: number, stages: readonly Stage[], loop?: Loop): PipeLayout;
|
|
80
|
+
export declare const pipeline: Emitter<"pipeline">;
|
|
81
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A stack, drawn as a stack.
|
|
3
|
+
*
|
|
4
|
+
* An encoder stack, a feature pyramid, a protocol layering: the source states
|
|
5
|
+
* these as a list and leaves the reader to hold the ordering in their head.
|
|
6
|
+
* Drawing them as offset planes receding up-right puts the ordering on the
|
|
7
|
+
* screen — and the build order *is* the explanation, so each plane arrives on
|
|
8
|
+
* its own beat instead of the pile fading in whole.
|
|
9
|
+
*
|
|
10
|
+
* Two decisions are worth knowing before changing anything here.
|
|
11
|
+
*
|
|
12
|
+
* The labels sit on a fixed right-hand spine, one per plane, so they read as a
|
|
13
|
+
* column rather than as seven captions scattered across a slanted pile. That
|
|
14
|
+
* spine is what makes the slide legible with the headline covered.
|
|
15
|
+
*
|
|
16
|
+
* The pile grows upward, so the top plane and its label are where this
|
|
17
|
+
* overflows — and the overflow is not a rounding error, it is structural: seven
|
|
18
|
+
* layers each carrying a note is more text than 1080px has room for once the
|
|
19
|
+
* chrome and the slide note have taken their share. So the rise is *solved*
|
|
20
|
+
* from the height that is actually left rather than assumed and hoped for, and
|
|
21
|
+
* the solve reserves the largest plane it might later choose so that clamping
|
|
22
|
+
* `sy` can never push the pile back out of the box.
|
|
23
|
+
*/
|
|
24
|
+
import type { BeatOf, Format } from "../../types.js";
|
|
25
|
+
import type { Emitter } from "../kit.js";
|
|
26
|
+
type Params = BeatOf<"stack">["params"];
|
|
27
|
+
export interface StackLayout {
|
|
28
|
+
/**
|
|
29
|
+
* False when the rise the canvas allows is shorter than the tallest label
|
|
30
|
+
* block — i.e. adjacent labels would overlap. `stackLayout` re-composes rather
|
|
31
|
+
* than shipping that, so a returned layout is only `!fits` when no composition
|
|
32
|
+
* fitted and the caller is looking at the least-bad one.
|
|
33
|
+
*/
|
|
34
|
+
fits: boolean;
|
|
35
|
+
/** Notes set beside their label rather than beneath it. See `stackLayout`. */
|
|
36
|
+
inline: boolean;
|
|
37
|
+
/** The svg's own box. `width` is the full content column. */
|
|
38
|
+
width: number;
|
|
39
|
+
height: number;
|
|
40
|
+
/** Vertical room the svg was allowed, after chrome, its margin and the note. */
|
|
41
|
+
avail: number;
|
|
42
|
+
chromeH: number;
|
|
43
|
+
noteH: number;
|
|
44
|
+
/** Distance between adjacent planes' front edges. */
|
|
45
|
+
rise: number;
|
|
46
|
+
/** The recede vector, and the slab's thickness. */
|
|
47
|
+
sx: number;
|
|
48
|
+
sy: number;
|
|
49
|
+
t: number;
|
|
50
|
+
/** Plane geometry: left edge of the front face, and its width. */
|
|
51
|
+
x0: number;
|
|
52
|
+
w: number;
|
|
53
|
+
/** Label spine: left edge and width of the label column. */
|
|
54
|
+
labelX: number;
|
|
55
|
+
colW: number;
|
|
56
|
+
labelSize: number;
|
|
57
|
+
/** Tallest label+note block. Adjacent labels collide once `rise` drops below it. */
|
|
58
|
+
blockH: number;
|
|
59
|
+
/** Half `blockH`, floored — the outermost labels overhang the pile by this. */
|
|
60
|
+
pad: number;
|
|
61
|
+
/** Front-face y of the bottom plane. Layer `i` sits `i * rise` above it. */
|
|
62
|
+
yBase: number;
|
|
63
|
+
/**
|
|
64
|
+
* Per-layer wrapped text and the width each ran against, so the emitter and
|
|
65
|
+
* the fit test cannot disagree about how many lines a label took.
|
|
66
|
+
*/
|
|
67
|
+
lines: {
|
|
68
|
+
label: string[];
|
|
69
|
+
note: string[];
|
|
70
|
+
noteW: number;
|
|
71
|
+
labelMaxW: number;
|
|
72
|
+
}[];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Solve the whole composition before a byte of SVG exists.
|
|
76
|
+
*
|
|
77
|
+
* Exported because every way this archetype can fail is a number in here: the
|
|
78
|
+
* pile leaving the canvas, a label set below `MIN_FONT`, a label column narrower
|
|
79
|
+
* than its longest label. Asserting those against rendered markup means parsing
|
|
80
|
+
* text extents back out of SVG, which is a second implementation of the metrics
|
|
81
|
+
* and would agree with the first right up until it mattered.
|
|
82
|
+
*
|
|
83
|
+
* The hard case is seven layers that each carry a note. Two lines of audience
|
|
84
|
+
* type per layer is ~106px, seven of those want 740px of rise, and after an
|
|
85
|
+
* eyebrow, a headline and a slide note there are barely 580px left — the
|
|
86
|
+
* stacked label simply does not fit, and clamping the rise to make it fit is
|
|
87
|
+
* how notes end up printed through the label below. So when it does not fit the
|
|
88
|
+
* composition changes rather than the type: the note moves beside its label, on
|
|
89
|
+
* the same line, right-aligned against the spine.
|
|
90
|
+
*/
|
|
91
|
+
export declare function stackLayout(p: Params, format: Format): StackLayout;
|
|
92
|
+
export declare const stack: Emitter<"stack">;
|
|
93
|
+
export {};
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The opening beat — and the slide chrome the other five archetypes reuse.
|
|
3
|
+
*
|
|
4
|
+
* A title slide is that chrome, enlarged and centred, so the eyebrow/headline
|
|
5
|
+
* block and its theme-derived CSS live here rather than being written out five
|
|
6
|
+
* more times. `kit.ts` owns the seam between shell and vocabulary; it does not
|
|
7
|
+
* own the vocabulary's typography.
|
|
8
|
+
*/
|
|
9
|
+
import type { Format } from "../../types.js";
|
|
10
|
+
import type { Emitter, Theme, Tween, Vars } from "../kit.js";
|
|
11
|
+
/**
|
|
12
|
+
* Whether this format's content box is taller than it is wide.
|
|
13
|
+
*
|
|
14
|
+
* The one question an archetype has to ask before it lays anything out. At
|
|
15
|
+
* `short-9x16` the box is 860x1752 against 16:9's 1700x912 — half as wide and
|
|
16
|
+
* nearly twice as tall — so a two-column comparison wants to become two stacked
|
|
17
|
+
* rows and a chart wants its readout underneath rather than beside it. Clamping
|
|
18
|
+
* a wide arrangement to the narrower width fits and still looks wrong.
|
|
19
|
+
*
|
|
20
|
+
* Read off the format rather than off `contentW`/`contentH` so `post-1x1`
|
|
21
|
+
* (1080x1080, box 860x912) stays on the landscape branch: it is square, and the
|
|
22
|
+
* landscape arrangements are the ones that survive a square box.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isPortrait(format: Format): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* The chrome's type scale, and the line boxes that fall out of it.
|
|
27
|
+
*
|
|
28
|
+
* These are exported because every archetype that draws a diagram has to know
|
|
29
|
+
* how much room the chrome took before it can decide how big the diagram is. A
|
|
30
|
+
* duplicated `const HEADLINE_H = 76` in five files is a type scale that can only
|
|
31
|
+
* ever be changed in one of them, and the other four then overflow or leave a
|
|
32
|
+
* band — both silent.
|
|
33
|
+
*
|
|
34
|
+
* 76/42, not 66/40. The floor is 40 and most of the deck was sitting on it, so
|
|
35
|
+
* the whole slide read as body text with one slightly larger line. Growing type
|
|
36
|
+
* is the safe direction (invariant 5 is a minimum), and the budget arithmetic
|
|
37
|
+
* below is what keeps the extra height from pushing a scene off both edges.
|
|
38
|
+
*/
|
|
39
|
+
export declare const EYEBROW_SIZE = 42;
|
|
40
|
+
export declare const EYEBROW_LH = 1.2;
|
|
41
|
+
/** One line box. The block is this per line, plus `margin-bottom` once. */
|
|
42
|
+
export declare const EYEBROW_LINE: number;
|
|
43
|
+
export declare const EYEBROW_GAP = 22;
|
|
44
|
+
/** One line box plus `margin-bottom` — the one-line case, which is the common one. */
|
|
45
|
+
export declare const EYEBROW_H: number;
|
|
46
|
+
/**
|
|
47
|
+
* The eyebrow is drawn UPPERCASE at `.14em` of tracking, and the headline at
|
|
48
|
+
* `-.015em`. Neither is decoration to the arithmetic below: measured against the
|
|
49
|
+
* browser, a 60-character eyebrow sets on two lines where an untracked
|
|
50
|
+
* lowercase measurement predicts one, and a 138-character headline sets on three
|
|
51
|
+
* where an untracked one predicts four.
|
|
52
|
+
*/
|
|
53
|
+
export declare const EYEBROW_TRACKING = 0.14;
|
|
54
|
+
export declare const HEADLINE_TRACKING = -0.015;
|
|
55
|
+
export declare const HEADLINE_SIZE = 76;
|
|
56
|
+
export declare const HEADLINE_LH = 1.15;
|
|
57
|
+
export declare const HEADLINE_H: number;
|
|
58
|
+
/** Body copy — notes, captions, claims. One notch off the floor, deliberately. */
|
|
59
|
+
export declare const BODY_SIZE = 44;
|
|
60
|
+
export declare const BODY_LH = 1.45;
|
|
61
|
+
/**
|
|
62
|
+
* Bind the tail of a headline so it cannot break to a one- or two-word last line.
|
|
63
|
+
*
|
|
64
|
+
* Gluing the final words with U+00A0 pulls one more word down with the orphan:
|
|
65
|
+
* "…the carrier is read / through" becomes "…the carrier is / read through". The
|
|
66
|
+
* line count does not change — greedy wrapping only ever moves words forward — so
|
|
67
|
+
* `chromeHeight` needs no adjustment and keeps measuring the raw string. (`wrap`
|
|
68
|
+
* splits on `\s`, which U+00A0 is, so it would not see the binding anyway; the
|
|
69
|
+
* width guard below is what keeps the browser's line count in step.)
|
|
70
|
+
*
|
|
71
|
+
* The run bound is the WIDEST that fits the measure, from `tail + 1` words down
|
|
72
|
+
* to two, rather than `tail + 1` alone. `wrap` errs wide by construction, so its
|
|
73
|
+
* last line is not the browser's: it broke "…reports three / different numbers"
|
|
74
|
+
* where the browser broke "…reports three different / numbers", and the three
|
|
75
|
+
* words it asked for were both too wide for the measure and aimed at an orphan
|
|
76
|
+
* that was not the one on screen. Any run that fits protects the same seam, and
|
|
77
|
+
* binding words that already sit together costs nothing.
|
|
78
|
+
*
|
|
79
|
+
* A candidate is REJECTED if it would leave some earlier line raggeder than the
|
|
80
|
+
* orphan it removes. Binding "dense output" in the demo's title pushed the run
|
|
81
|
+
* off line three and stranded "with" there by itself — a one-word line in the
|
|
82
|
+
* MIDDLE of a headline, which is worse than the one at the end. So each candidate
|
|
83
|
+
* is re-wrapped with the bound run held together as a single token, and kept only
|
|
84
|
+
* if the shortest line does not get shorter and no line is added.
|
|
85
|
+
*
|
|
86
|
+
* Two cases are left alone rather than forced: a headline that IS the orphan
|
|
87
|
+
* (nothing to borrow from), and one where every candidate is wider than the
|
|
88
|
+
* measure — the browser would break that anyway, and then in mid-word.
|
|
89
|
+
*/
|
|
90
|
+
export declare function unwidow(text: string, width: number, size: number, weight?: number): string;
|
|
91
|
+
/**
|
|
92
|
+
* Height the chrome will actually occupy, headline wrapping included.
|
|
93
|
+
*
|
|
94
|
+
* `wrap` errs wide, so this over-counts lines rather than under-counting them.
|
|
95
|
+
* That is the safe direction: an under-count overflows the canvas, and `.scene`
|
|
96
|
+
* is centred so it overflows off *both* edges at once.
|
|
97
|
+
*/
|
|
98
|
+
export declare function chromeHeight(eyebrow: string | undefined, headline: string, width: number): number;
|
|
99
|
+
/**
|
|
100
|
+
* What is left for the body once the chrome, the body's own top margin, and
|
|
101
|
+
* anything below it (a note, a caption band) have been paid for.
|
|
102
|
+
*
|
|
103
|
+
* `floor` IS A LAST RESORT, NOT A BUDGET, and the difference has already cost a
|
|
104
|
+
* defect. `claim-figure` asked for the space left under a 216-character claim,
|
|
105
|
+
* was told 320 when the true remainder was 163, sized the figure to fit 320, and
|
|
106
|
+
* drew the caption 7px below the canvas — with every gate green, because the
|
|
107
|
+
* gate was sampling nine midpoints and never looked at that hold. A caller that
|
|
108
|
+
* is LAST in the queue for space has to be able to hear "there is almost none",
|
|
109
|
+
* so it can pass its own floor and act on the answer.
|
|
110
|
+
*/
|
|
111
|
+
export declare function bodyBudget(format: Format, eyebrow: string | undefined, headline: string, below?: number, top?: number, floor?: number): number;
|
|
112
|
+
/**
|
|
113
|
+
* The largest size at which `text` sets in `width` lines of `maxLines`, capped
|
|
114
|
+
* both ends. Used where a headline should grow to meet its box instead of
|
|
115
|
+
* sitting at one authored size with 600px of air beside it.
|
|
116
|
+
*
|
|
117
|
+
* The division solves for perfect packing — every line filled to the last pixel —
|
|
118
|
+
* which no real line break achieves. At 1700 the slack is a few percent and the
|
|
119
|
+
* answer holds; at 860 it is not, because one long word is a fifth of the
|
|
120
|
+
* measure. The demo's title came back at 116px, set on FOUR lines against a cap
|
|
121
|
+
* of three, and the extra line was a stranded "with". So the quotient is an
|
|
122
|
+
* upper bound, and `wrap` is asked whether it is true.
|
|
123
|
+
*
|
|
124
|
+
* Stepping down rather than bisecting: the answer is within a few px of the
|
|
125
|
+
* bound in every case that matters, and a monotone scan cannot pick a size that
|
|
126
|
+
* a bisection's midpoint happened to skip. `lo` is a floor, not a target — a
|
|
127
|
+
* string that will not set in `maxLines` at `lo` simply lands there, as before.
|
|
128
|
+
*/
|
|
129
|
+
export declare function fitText(text: string, width: number, maxLines: number, lo: number, hi: number, weight?: number): number;
|
|
130
|
+
/**
|
|
131
|
+
* The vocabulary's own constructor: a `fromTo` at a rounded position.
|
|
132
|
+
*
|
|
133
|
+
* `kit.fromTo` is the bare structure; this is what an archetype calls, and the
|
|
134
|
+
* only thing it adds is invariant 10. Every archetype's positions are sums of
|
|
135
|
+
* authored beat times, so they accumulate float tails — `7.199999999999999` —
|
|
136
|
+
* and a position that prints differently between two builds of one storyboard
|
|
137
|
+
* moves a byte in the composition. Rounded HERE rather than in the serialiser
|
|
138
|
+
* because `camera.ts` rounds its own positions to three places against a clock
|
|
139
|
+
* the shell owns, and a second rounding on the way out would quietly truncate
|
|
140
|
+
* them.
|
|
141
|
+
*
|
|
142
|
+
* Every tween is `fromTo` — `from()` captures its end state when the timeline
|
|
143
|
+
* is constructed, which is wrong the moment the deck seeks somewhere else, and
|
|
144
|
+
* seeking is all deck navigation does. That is now the `Tween` type's doing
|
|
145
|
+
* rather than this comment's: there is no shape here that omits `from`.
|
|
146
|
+
*/
|
|
147
|
+
export declare function tween(target: string, from: Vars, to: Vars, at: number): Tween;
|
|
148
|
+
/**
|
|
149
|
+
* Hold points become absolute island fragment times and must land inside the
|
|
150
|
+
* slide's window, so a beat planned shorter than its own reveal schedule gets
|
|
151
|
+
* its holds clamped rather than silently pushed into the next slide.
|
|
152
|
+
*/
|
|
153
|
+
export declare function holdsWithin(times: number[], seconds: number): number[];
|
|
154
|
+
/**
|
|
155
|
+
* The eyebrow + headline block. Ids are scoped by `sid`, as every selector must be.
|
|
156
|
+
*
|
|
157
|
+
* `width` is the measure the headline will set in — always `contentW(ctx.format)`,
|
|
158
|
+
* since `.headline` is a block child of `.scene` and so spans the content box.
|
|
159
|
+
*
|
|
160
|
+
* Required, not optional. It was optional for one round while eleven emitters
|
|
161
|
+
* were being changed by different hands, and the six that never got the argument
|
|
162
|
+
* were exactly the six still printing one-word last lines ("…is read / through",
|
|
163
|
+
* "…not the / smallest"). A defaulted measure is indistinguishable at the call
|
|
164
|
+
* site from a deliberate one, so the next archetype would inherit the same
|
|
165
|
+
* silent opt-out; requiring it makes the omission a type error instead.
|
|
166
|
+
*/
|
|
167
|
+
export declare function chrome(sid: string, eyebrow: string | undefined, headline: string, width: number): string;
|
|
168
|
+
/** Reveals the chrome. Finishes at 0.9s, which is where archetype bodies pick up. */
|
|
169
|
+
export declare function chromeIn(sid: string, eyebrow: boolean): Tween[];
|
|
170
|
+
export declare function chromeCss(t: Theme): string;
|
|
171
|
+
/**
|
|
172
|
+
* The note that closes a slide. Eight archetypes each declared their own copy of
|
|
173
|
+
* this at 40px with a different class name; the sizes then drifted apart by
|
|
174
|
+
* archetype, which is a hierarchy nobody chose.
|
|
175
|
+
*/
|
|
176
|
+
export declare function noteCss(cls: string, t: Theme, top?: number): string;
|
|
177
|
+
/** The column a `.<cls>` note actually sets in: the cap, or the box if that is narrower. */
|
|
178
|
+
export declare function noteWidth(format: Format): number;
|
|
179
|
+
/**
|
|
180
|
+
* One `.<cls>` line box, wrapping included — what `bodyBudget`'s `below` wants.
|
|
181
|
+
*
|
|
182
|
+
* `width` is the caller's because two archetypes set their note in a column of
|
|
183
|
+
* their own rather than across the box. Everyone else passes `noteWidth(format)`;
|
|
184
|
+
* measuring against the bare 1600 cap at 9:16 under-counts the lines by half and
|
|
185
|
+
* hands the body a budget the note then overruns.
|
|
186
|
+
*/
|
|
187
|
+
export declare function noteHeight(note: string | undefined, width: number, top?: number): number;
|
|
188
|
+
export declare const title: Emitter<"title">;
|