@promptctl/rich-js 0.28.0 → 0.29.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 +7 -7
- package/dist/core/animation.d.ts +37 -37
- package/dist/core/animation.js +61 -61
- package/dist/core/ansi.d.ts +4 -4
- package/dist/core/ansi.js +9 -9
- package/dist/core/bidi.js +6 -6
- package/dist/core/cells.d.ts +1 -1
- package/dist/core/cells.js +5 -5
- package/dist/core/clock.d.ts +1 -1
- package/dist/core/color.d.ts +50 -50
- package/dist/core/color.js +69 -69
- package/dist/core/console.d.ts +8 -8
- package/dist/core/console.js +5 -5
- package/dist/core/control-codes.d.ts +3 -3
- package/dist/core/control-codes.js +7 -7
- package/dist/core/easing.d.ts +40 -40
- package/dist/core/easing.js +40 -40
- package/dist/core/env.d.ts +1 -1
- package/dist/core/env.js +1 -1
- package/dist/core/export-html.js +1 -1
- package/dist/core/export-lines.d.ts +11 -11
- package/dist/core/export-lines.js +12 -12
- package/dist/core/export-svg.d.ts +3 -3
- package/dist/core/export-svg.js +4 -4
- package/dist/core/markup.js +1 -1
- package/dist/core/memo.d.ts +1 -1
- package/dist/core/memo.js +1 -1
- package/dist/core/oklch.d.ts +14 -14
- package/dist/core/oklch.js +10 -10
- package/dist/core/orient.d.ts +3 -3
- package/dist/core/orient.js +3 -3
- package/dist/core/paint.d.ts +9 -9
- package/dist/core/paint.js +3 -3
- package/dist/core/pretty.d.ts +1 -1
- package/dist/core/pretty.js +3 -3
- package/dist/core/protocol.d.ts +26 -26
- package/dist/core/protocol.js +22 -22
- package/dist/core/render.d.ts +11 -11
- package/dist/core/render.js +12 -12
- package/dist/core/segment.d.ts +3 -3
- package/dist/core/segment.js +5 -5
- package/dist/core/strip.d.ts +83 -83
- package/dist/core/strip.js +70 -70
- package/dist/core/style.d.ts +20 -20
- package/dist/core/style.js +55 -55
- package/dist/core/text.d.ts +2 -2
- package/dist/core/text.js +5 -5
- package/dist/core/timeline.d.ts +5 -5
- package/dist/core/timeline.js +9 -9
- package/dist/core/tween.d.ts +6 -6
- package/dist/core/tween.js +10 -10
- package/dist/core/view.d.ts +4 -4
- package/dist/core/view.js +12 -12
- package/dist/host/app.d.ts +9 -9
- package/dist/host/app.js +12 -12
- package/dist/host/host-environment.d.ts +2 -2
- package/dist/host/host-environment.js +2 -2
- package/dist/host/index.d.ts +2 -2
- package/dist/host/input.d.ts +7 -7
- package/dist/host/input.js +4 -4
- package/dist/host/terminal-colors.d.ts +2 -2
- package/dist/host/terminal-colors.js +4 -4
- package/dist/host/terminal-host.d.ts +2 -2
- package/dist/host/terminal-host.js +1 -1
- package/dist/index.d.ts +14 -14
- package/dist/index.js +10 -10
- package/dist/node/prompt.d.ts +1 -1
- package/dist/node/prompt.js +1 -1
- package/dist/node/terminal-host.d.ts +1 -1
- package/dist/node/traceback.js +2 -2
- package/dist/renderables/change.js +2 -2
- package/dist/renderables/effect.d.ts +39 -39
- package/dist/renderables/effect.js +45 -45
- package/dist/renderables/effects.d.ts +81 -81
- package/dist/renderables/effects.js +157 -157
- package/dist/renderables/embed.d.ts +1 -1
- package/dist/renderables/embed.js +2 -2
- package/dist/renderables/flexStrip.d.ts +7 -7
- package/dist/renderables/flexStrip.js +15 -15
- package/dist/renderables/frames.d.ts +6 -6
- package/dist/renderables/frames.js +11 -11
- package/dist/renderables/glyph-effect.d.ts +15 -15
- package/dist/renderables/glyph-effect.js +17 -17
- package/dist/renderables/glyph-effects.d.ts +7 -7
- package/dist/renderables/glyph-effects.js +16 -16
- package/dist/renderables/html-entities.d.ts +1 -1
- package/dist/renderables/html-entities.js +1 -1
- package/dist/renderables/lifecycle.d.ts +4 -4
- package/dist/renderables/lifecycle.js +12 -12
- package/dist/renderables/live.d.ts +2 -2
- package/dist/renderables/live.js +7 -7
- package/dist/renderables/markdown-parse.js +3 -3
- package/dist/renderables/panel.js +3 -3
- package/dist/renderables/progress.d.ts +1 -1
- package/dist/renderables/progress.js +1 -1
- package/dist/renderables/progressBar.d.ts +1 -1
- package/dist/renderables/progressBar.js +6 -6
- package/dist/renderables/prompt.d.ts +1 -1
- package/dist/renderables/scroll.d.ts +1 -1
- package/dist/renderables/scroll.js +3 -3
- package/dist/renderables/spinner.d.ts +4 -4
- package/dist/renderables/spinner.js +10 -10
- package/dist/renderables/syntax.d.ts +2 -2
- package/dist/renderables/syntax.js +2 -2
- package/dist/renderables/table.js +3 -3
- package/dist/renderables/traceback.d.ts +1 -1
- package/dist/renderables/traceback.js +1 -1
- package/dist/renderables/tree.js +3 -3
- package/dist/template-bindings/animation-funcs.d.ts +14 -14
- package/dist/template-bindings/animation-funcs.js +27 -27
- package/dist/template-bindings/color-funcs.d.ts +14 -14
- package/dist/template-bindings/color-funcs.js +25 -25
- package/dist/template-bindings/index.d.ts +9 -9
- package/dist/template-bindings/index.js +9 -9
- package/dist/template-bindings/palette-funcs.d.ts +1 -1
- package/dist/template-bindings/palette-funcs.js +3 -3
- package/dist/template-bindings/style-funcs.d.ts +5 -5
- package/dist/template-bindings/style-funcs.js +16 -16
- package/dist/themes/{transpose.d.ts → adjust.d.ts} +23 -23
- package/dist/themes/{transpose.js → adjust.js} +28 -28
- package/dist/themes/buildPalette.d.ts +3 -3
- package/dist/themes/buildPalette.js +20 -20
- package/dist/themes/colorMath.d.ts +16 -16
- package/dist/themes/colorMath.js +32 -32
- package/dist/themes/data/ansi-tables.d.ts +2 -2
- package/dist/themes/data/ansi-tables.js +2 -2
- package/dist/themes/data/types.d.ts +4 -4
- package/dist/themes/data/types.js +2 -2
- package/dist/themes/palette.d.ts +12 -12
- package/dist/themes/palette.js +16 -16
- package/dist/themes/ramp.d.ts +17 -17
- package/dist/themes/ramp.js +12 -12
- package/dist/themes/registry.js +4 -4
- package/dist/themes/terminalThemes.d.ts +1 -1
- package/dist/themes/terminalThemes.js +1 -1
- package/dist/widgets/button.d.ts +2 -2
- package/dist/widgets/button.js +4 -4
- package/dist/widgets/checkbox.d.ts +2 -2
- package/dist/widgets/checkbox.js +2 -2
- package/dist/widgets/dropdown.d.ts +2 -2
- package/dist/widgets/dropdown.js +3 -3
- package/dist/widgets/event-router.d.ts +6 -6
- package/dist/widgets/event-router.js +2 -2
- package/dist/widgets/focus-manager.d.ts +3 -3
- package/dist/widgets/focus-manager.js +3 -3
- package/dist/widgets/index.d.ts +2 -2
- package/dist/widgets/index.js +1 -1
- package/dist/widgets/ink.d.ts +3 -3
- package/dist/widgets/ink.js +4 -4
- package/dist/widgets/slider.d.ts +2 -2
- package/dist/widgets/static-item.d.ts +2 -2
- package/dist/widgets/text-input.d.ts +2 -2
- package/dist/widgets/text-input.js +5 -5
- package/dist/widgets/themed-widget.js +1 -1
- package/dist/widgets/toggle.d.ts +3 -3
- package/dist/widgets/toggle.js +3 -3
- package/dist/widgets/types.d.ts +6 -6
- package/dist/widgets/types.js +2 -2
- package/dist/widgets/widget-app.d.ts +10 -10
- package/dist/widgets/widget-app.js +8 -8
- package/dist/widgets/widget-base.d.ts +2 -2
- package/package.json +1 -1
|
@@ -107,7 +107,7 @@ export declare function cutLabel(text: RichText, width: number, marker: string):
|
|
|
107
107
|
* `Text` are not, and markup that styles nothing is — it reads as empty text,
|
|
108
108
|
* but the string that holds it is not empty.
|
|
109
109
|
*/
|
|
110
|
-
export declare function
|
|
110
|
+
export declare function mounted(content: string | RichText | undefined): content is string | RichText;
|
|
111
111
|
/**
|
|
112
112
|
* A label's text as one line of segments at its natural width, its own styles
|
|
113
113
|
* laid over `base`. The caller has already cut it to its room, so it leaves as
|
|
@@ -159,7 +159,7 @@ export function cutLabel(text, width, marker) {
|
|
|
159
159
|
* `Text` are not, and markup that styles nothing is — it reads as empty text,
|
|
160
160
|
* but the string that holds it is not empty.
|
|
161
161
|
*/
|
|
162
|
-
export function
|
|
162
|
+
export function mounted(content) {
|
|
163
163
|
// Asked of what the content is rather than of what it is not, so a `null`
|
|
164
164
|
// from untyped JS is no content, as Rich's `None` is.
|
|
165
165
|
return typeof content === "string" ? content !== "" : content instanceof RichText && content.plain !== "";
|
|
@@ -180,5 +180,5 @@ export function drawLabel(text, options, base) {
|
|
|
180
180
|
* label, which still opens a gap in the rule, as Rich's does.
|
|
181
181
|
*/
|
|
182
182
|
export function inlineLabel(content) {
|
|
183
|
-
return
|
|
183
|
+
return mounted(content) ? new InlineLabel(content) : undefined;
|
|
184
184
|
}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* FlexStrip — wrap-to-width horizontal layout for `StyledRenderable` items.
|
|
3
3
|
*
|
|
4
4
|
* Pack as many items as fit on a line, then break and continue. Each line is
|
|
5
|
-
* an independent sub-strip: optional `
|
|
5
|
+
* an independent sub-strip: optional `Separator` end-caps fire at every line
|
|
6
6
|
* boundary (not just the strip's first/last position), so a line break looks
|
|
7
|
-
* the same as an endpoint to the joiner. Composes with the Strip +
|
|
8
|
-
* primitive in `core/strip` — same `
|
|
7
|
+
* the same as an endpoint to the joiner. Composes with the Strip + Separator
|
|
8
|
+
* primitive in `core/strip` — same `Separator` protocol, no new join semantics.
|
|
9
9
|
*
|
|
10
10
|
* [LAW:dataflow-not-control-flow] The pack walk is the same shape every
|
|
11
11
|
* render: measure each item, render every joiner form (start-cap, end-cap,
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { Segment } from "../core/segment.js";
|
|
19
19
|
import type { Renderable, Measurable, RenderOptions } from "../core/protocol.js";
|
|
20
|
-
import { type
|
|
20
|
+
import { type Separator, type StyledRenderable } from "../core/strip.js";
|
|
21
21
|
export type FlexAlign = "left" | "center" | "right" | "justify";
|
|
22
22
|
export interface FlexStripOptions<T extends StyledRenderable> {
|
|
23
|
-
/**
|
|
24
|
-
|
|
23
|
+
/** Separator used between items within a line, and at line endpoints. */
|
|
24
|
+
separator?: Separator<T>;
|
|
25
25
|
/** Cells of horizontal space inserted on each side of an inter-item joiner (default 0). */
|
|
26
26
|
gap?: number;
|
|
27
27
|
/** Line alignment when packed items don't fill the available width (default "left"). */
|
|
@@ -29,7 +29,7 @@ export interface FlexStripOptions<T extends StyledRenderable> {
|
|
|
29
29
|
}
|
|
30
30
|
export declare class FlexStrip<T extends StyledRenderable = StyledRenderable> implements Renderable, Measurable {
|
|
31
31
|
readonly items: readonly T[];
|
|
32
|
-
readonly
|
|
32
|
+
readonly separator: Separator<T> | undefined;
|
|
33
33
|
readonly gap: number;
|
|
34
34
|
readonly align: FlexAlign;
|
|
35
35
|
constructor(items: readonly T[], options?: FlexStripOptions<T>);
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* FlexStrip — wrap-to-width horizontal layout for `StyledRenderable` items.
|
|
3
3
|
*
|
|
4
4
|
* Pack as many items as fit on a line, then break and continue. Each line is
|
|
5
|
-
* an independent sub-strip: optional `
|
|
5
|
+
* an independent sub-strip: optional `Separator` end-caps fire at every line
|
|
6
6
|
* boundary (not just the strip's first/last position), so a line break looks
|
|
7
|
-
* the same as an endpoint to the joiner. Composes with the Strip +
|
|
8
|
-
* primitive in `core/strip` — same `
|
|
7
|
+
* the same as an endpoint to the joiner. Composes with the Strip + Separator
|
|
8
|
+
* primitive in `core/strip` — same `Separator` protocol, no new join semantics.
|
|
9
9
|
*
|
|
10
10
|
* [LAW:dataflow-not-control-flow] The pack walk is the same shape every
|
|
11
11
|
* render: measure each item, render every joiner form (start-cap, end-cap,
|
|
@@ -47,12 +47,12 @@ function computeSlotFills(align, isFinalLine, spare, itemCount) {
|
|
|
47
47
|
}
|
|
48
48
|
export class FlexStrip {
|
|
49
49
|
items;
|
|
50
|
-
|
|
50
|
+
separator;
|
|
51
51
|
gap;
|
|
52
52
|
align;
|
|
53
53
|
constructor(items, options) {
|
|
54
54
|
this.items = items;
|
|
55
|
-
this.
|
|
55
|
+
this.separator = options?.separator;
|
|
56
56
|
this.gap = options?.gap ?? 0;
|
|
57
57
|
this.align = options?.align ?? "left";
|
|
58
58
|
}
|
|
@@ -62,7 +62,7 @@ export class FlexStrip {
|
|
|
62
62
|
return;
|
|
63
63
|
const maxWidth = Math.max(1, options.maxWidth);
|
|
64
64
|
const gap = this.gap;
|
|
65
|
-
const joiner = this.
|
|
65
|
+
const joiner = this.separator;
|
|
66
66
|
// Pre-render every item and every joiner form we might need. Doing this
|
|
67
67
|
// up-front turns packing into a pure data computation over widths.
|
|
68
68
|
const itemBlocks = items.map((it) => renderToBlock(drawItem(it), options));
|
|
@@ -178,24 +178,24 @@ export class FlexStrip {
|
|
|
178
178
|
let maximum = 0;
|
|
179
179
|
for (let i = 0; i < items.length; i++) {
|
|
180
180
|
const itemWidth = renderToBlock(items[i], options).width;
|
|
181
|
-
const sc = this.
|
|
182
|
-
? renderToBlock(drawJoin(this.
|
|
181
|
+
const sc = this.separator
|
|
182
|
+
? renderToBlock(drawJoin(this.separator, null, items[i], { index: i }), options).width
|
|
183
183
|
: 0;
|
|
184
|
-
const ec = this.
|
|
185
|
-
? renderToBlock(drawJoin(this.
|
|
184
|
+
const ec = this.separator
|
|
185
|
+
? renderToBlock(drawJoin(this.separator, items[i], null, { index: i + 1 }), options).width
|
|
186
186
|
: 0;
|
|
187
187
|
minimum = Math.max(minimum, itemWidth + sc + ec);
|
|
188
188
|
maximum += itemWidth;
|
|
189
189
|
if (i > 0) {
|
|
190
190
|
maximum += this.gap * 2;
|
|
191
|
-
if (this.
|
|
192
|
-
maximum += renderToBlock(drawJoin(this.
|
|
191
|
+
if (this.separator) {
|
|
192
|
+
maximum += renderToBlock(drawJoin(this.separator, items[i - 1], items[i], { index: i }), options).width;
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
-
if (this.
|
|
197
|
-
maximum += renderToBlock(drawJoin(this.
|
|
198
|
-
maximum += renderToBlock(drawJoin(this.
|
|
196
|
+
if (this.separator) {
|
|
197
|
+
maximum += renderToBlock(drawJoin(this.separator, null, items[0], { index: 0 }), options).width;
|
|
198
|
+
maximum += renderToBlock(drawJoin(this.separator, items[items.length - 1], null, { index: items.length }), options).width;
|
|
199
199
|
}
|
|
200
200
|
return { minimum, maximum };
|
|
201
201
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* for its own seconds and looping, drawn as the one in progress at a time
|
|
4
4
|
* the host hands in.
|
|
5
5
|
*
|
|
6
|
-
* An effect moves a cell's
|
|
6
|
+
* An effect moves a cell's colors and may never change a glyph
|
|
7
7
|
* (`./effect.ts`: "It changes how cells look, never which cells exist or who
|
|
8
8
|
* drew them"). A frame is the other kind of motion — what the element shows
|
|
9
9
|
* changes — so it is its own primitive and not a wider `Effect`, and the two
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* placed sequence stamps them with its hold (`Style.hold`,
|
|
31
31
|
* `placedRender` in `core/animation.ts`), which rides up
|
|
32
32
|
* through every container to whoever holds the composed frame
|
|
33
|
-
* (`Segment.
|
|
33
|
+
* (`Segment.validUntil`), so a host drawing at `t` knows when to draw again,
|
|
34
34
|
* and one drawing slower than the frames turn can see that it is skipping
|
|
35
35
|
* them. Nothing an animation's `at` returns carries a stamp of its own: the
|
|
36
36
|
* stamp is put on where the frame's time is known.
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
* children do.
|
|
46
46
|
*/
|
|
47
47
|
import { Animation } from "../core/animation.js";
|
|
48
|
-
import { type
|
|
48
|
+
import { type StepSequence } from "../core/easing.js";
|
|
49
49
|
import type { RenderOptions } from "../core/protocol.js";
|
|
50
50
|
import type { Segment } from "../core/segment.js";
|
|
51
51
|
import { RichText } from "../core/text.js";
|
|
@@ -57,7 +57,7 @@ export interface Frame {
|
|
|
57
57
|
/** A sequence of frames prepared to be drawn: built once, asked for the frame at a time. */
|
|
58
58
|
export declare class FrameSequence implements Animation<RichText> {
|
|
59
59
|
/** Which frame is in progress when: the holds are the frames' seconds, in order. */
|
|
60
|
-
readonly
|
|
60
|
+
readonly stepSequence: StepSequence;
|
|
61
61
|
/** The width every frame draws at: the widest frame's, in cells. */
|
|
62
62
|
readonly width: number;
|
|
63
63
|
private readonly _shown;
|
|
@@ -70,9 +70,9 @@ export declare class FrameSequence implements Animation<RichText> {
|
|
|
70
70
|
*/
|
|
71
71
|
at(t: number): RichText;
|
|
72
72
|
/** When the frame in progress at `t` gives way to the next: the beat's answer, its holds being the frames'. */
|
|
73
|
-
|
|
73
|
+
validUntil(t: number): number;
|
|
74
74
|
/** When the frame in progress at `t` began: the beat's answer. */
|
|
75
|
-
|
|
75
|
+
validFrom(t: number): number;
|
|
76
76
|
/** The frames with their motion taken out: the beat's first frame, held, a copy as `at`'s is. */
|
|
77
77
|
reduced(): Animation<RichText>;
|
|
78
78
|
render(options: RenderOptions): Iterable<Segment>;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* for its own seconds and looping, drawn as the one in progress at a time
|
|
4
4
|
* the host hands in.
|
|
5
5
|
*
|
|
6
|
-
* An effect moves a cell's
|
|
6
|
+
* An effect moves a cell's colors and may never change a glyph
|
|
7
7
|
* (`./effect.ts`: "It changes how cells look, never which cells exist or who
|
|
8
8
|
* drew them"). A frame is the other kind of motion — what the element shows
|
|
9
9
|
* changes — so it is its own primitive and not a wider `Effect`, and the two
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* placed sequence stamps them with its hold (`Style.hold`,
|
|
31
31
|
* `placedRender` in `core/animation.ts`), which rides up
|
|
32
32
|
* through every container to whoever holds the composed frame
|
|
33
|
-
* (`Segment.
|
|
33
|
+
* (`Segment.validUntil`), so a host drawing at `t` knows when to draw again,
|
|
34
34
|
* and one drawing slower than the frames turn can see that it is skipping
|
|
35
35
|
* them. Nothing an animation's `at` returns carries a stamp of its own: the
|
|
36
36
|
* stamp is put on where the frame's time is known.
|
|
@@ -45,18 +45,18 @@
|
|
|
45
45
|
* children do.
|
|
46
46
|
*/
|
|
47
47
|
import { Animation, placedRender } from "../core/animation.js";
|
|
48
|
-
import {
|
|
48
|
+
import { stepSequence } from "../core/easing.js";
|
|
49
49
|
import { setIntoLine } from "./embed.js";
|
|
50
50
|
/** A sequence of frames prepared to be drawn: built once, asked for the frame at a time. */
|
|
51
51
|
export class FrameSequence {
|
|
52
52
|
/** Which frame is in progress when: the holds are the frames' seconds, in order. */
|
|
53
|
-
|
|
53
|
+
stepSequence;
|
|
54
54
|
/** The width every frame draws at: the widest frame's, in cells. */
|
|
55
55
|
width;
|
|
56
56
|
// Each frame as it draws: a line fragment padded to `width`, made once.
|
|
57
57
|
_shown;
|
|
58
58
|
constructor(frames) {
|
|
59
|
-
this.
|
|
59
|
+
this.stepSequence = stepSequence(frames.map((frame) => frame.seconds));
|
|
60
60
|
const texts = frames.map((frame) => setIntoLine(frame.text.copy()));
|
|
61
61
|
const widths = texts.map((text) => text.cellLength);
|
|
62
62
|
this.width = Math.max(...widths);
|
|
@@ -75,19 +75,19 @@ export class FrameSequence {
|
|
|
75
75
|
* refuses a `t` that is not finite.
|
|
76
76
|
*/
|
|
77
77
|
at(t) {
|
|
78
|
-
return this._shown[this.
|
|
78
|
+
return this._shown[this.stepSequence.at(t)].copy();
|
|
79
79
|
}
|
|
80
80
|
/** When the frame in progress at `t` gives way to the next: the beat's answer, its holds being the frames'. */
|
|
81
|
-
|
|
82
|
-
return this.
|
|
81
|
+
validUntil(t) {
|
|
82
|
+
return this.stepSequence.validUntil(t);
|
|
83
83
|
}
|
|
84
84
|
/** When the frame in progress at `t` began: the beat's answer. */
|
|
85
|
-
|
|
86
|
-
return this.
|
|
85
|
+
validFrom(t) {
|
|
86
|
+
return this.stepSequence.validFrom(t);
|
|
87
87
|
}
|
|
88
88
|
/** The frames with their motion taken out: the beat's first frame, held, a copy as `at`'s is. */
|
|
89
89
|
reduced() {
|
|
90
|
-
return Animation.map(this.
|
|
90
|
+
return Animation.map(this.stepSequence.reduced(), (i) => this._shown[i].copy());
|
|
91
91
|
}
|
|
92
92
|
render(options) {
|
|
93
93
|
return placedRender(this, options);
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* glyph effect at a moment `t`: the glyph half of `Effected` (`./effect.ts`),
|
|
4
4
|
* built to its contract.
|
|
5
5
|
*
|
|
6
|
-
* A glyph effect is the
|
|
7
|
-
* the
|
|
6
|
+
* A glyph effect is the color effect's two-stage shape with a glyph where
|
|
7
|
+
* the colors were: for the cells an element draws in a frame, an
|
|
8
8
|
* `Animation` (`../core/animation.ts`) of what is done to them. The first
|
|
9
9
|
* stage is handed every cell once a frame (`GlyphCell`), blanks included —
|
|
10
10
|
* rain and stars live there — and whether the output draws ASCII alone
|
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
* scramble, a wave of case changes and particles on blank cells are all this
|
|
15
15
|
* one shape (`./glyph-effects.ts`) [LAW:one-type-per-behavior].
|
|
16
16
|
*
|
|
17
|
-
*
|
|
17
|
+
* Color and glyph are not two kinds of animation: each is an `Animation` of
|
|
18
18
|
* a per-cell map, and they differ only in what a cell is mapped to. The
|
|
19
|
-
* wrappers are two because the stages are handed different facts. A
|
|
20
|
-
* effect is settled against the depth, the terminal and the
|
|
21
|
-
* words (`Drawn`), and with no
|
|
19
|
+
* wrappers are two because the stages are handed different facts. A color
|
|
20
|
+
* effect is settled against the depth, the terminal and the colors of the
|
|
21
|
+
* words (`Drawn`), and with no color output there is nothing for it to
|
|
22
22
|
* change. A glyph effect needs none of that, and is written at every depth,
|
|
23
|
-
* with no
|
|
24
|
-
* `new Effected(new GlyphEffected(child, glyphs, …),
|
|
25
|
-
*
|
|
23
|
+
* with no color too. Over one element the two compose by nesting:
|
|
24
|
+
* `new Effected(new GlyphEffected(child, glyphs, …), colors, …)` moves the
|
|
25
|
+
* colors of the glyphs the glyph effect left, since each wrapper measures
|
|
26
26
|
* what its child drew.
|
|
27
27
|
*
|
|
28
28
|
* A `GlyphEffected` is the element under its glyph effect over time, an
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
* Positions are the child's own: row and column count from the top-left of
|
|
52
52
|
* what the child drew.
|
|
53
53
|
*/
|
|
54
|
-
import { Animation, type
|
|
54
|
+
import { Animation, type Reads } from "../core/animation.js";
|
|
55
55
|
import type { Measurable, Renderable, RenderOptions } from "../core/protocol.js";
|
|
56
56
|
import { Segment } from "../core/segment.js";
|
|
57
57
|
import { type RichText } from "../core/text.js";
|
|
@@ -85,7 +85,7 @@ export interface DrawnGlyphs {
|
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
87
|
* For an element drawing `drawn`, the animation of what is done to its
|
|
88
|
-
* glyphs. Its `
|
|
88
|
+
* glyphs. Its `validUntil` is when the frame next changes, as an `Effect`'s is.
|
|
89
89
|
*/
|
|
90
90
|
export type GlyphEffect = (drawn: DrawnGlyphs) => Animation<GlyphFrame>;
|
|
91
91
|
export interface GlyphEffectedOptions {
|
|
@@ -96,7 +96,7 @@ export interface GlyphEffectedOptions {
|
|
|
96
96
|
* A `GlyphEffected` at `t`, or an element through a glyph effect at a time an
|
|
97
97
|
* animation's `at` was handed: `renderable` with its cells' glyphs passed
|
|
98
98
|
* through `effect` at `t`, telling the hold it drew in as a `Recolored` does
|
|
99
|
-
* (`RenderOptions.
|
|
99
|
+
* (`RenderOptions.onReads`, `./effect.ts`). [LAW:one-type-per-behavior]
|
|
100
100
|
*/
|
|
101
101
|
export declare class Reglyphed implements Renderable, Measurable {
|
|
102
102
|
readonly renderable: Renderable;
|
|
@@ -117,7 +117,7 @@ export declare class Reglyphed implements Renderable, Measurable {
|
|
|
117
117
|
* as an `Effected` is (`./effect.ts`): with nothing drawn its answer is `t`,
|
|
118
118
|
* and placed, on its own or as a part of any combinator, it says the glyph
|
|
119
119
|
* effect's exact hold at that time and the output's `asciiOnly`, which the
|
|
120
|
-
* frame's drawing told (`
|
|
120
|
+
* frame's drawing told (`Reads`).
|
|
121
121
|
*/
|
|
122
122
|
export declare class GlyphEffected implements Animation<Renderable> {
|
|
123
123
|
readonly renderable: Renderable;
|
|
@@ -126,8 +126,8 @@ export declare class GlyphEffected implements Animation<Renderable> {
|
|
|
126
126
|
constructor(renderable: Renderable, effect: GlyphEffect, options: GlyphEffectedOptions);
|
|
127
127
|
/** The element through the glyph effect at `t`, unstamped. */
|
|
128
128
|
at(t: number): Reglyphed;
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
validUntil(t: number, moves?: Reads): number;
|
|
130
|
+
validFrom(t: number, moves?: Reads): number;
|
|
131
131
|
/** The element under the glyph effect with its motion taken out. */
|
|
132
132
|
reduced(): GlyphEffected;
|
|
133
133
|
/** Drawn at the frame's time, its cells stamped with the glyph effect's exact hold there. */
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* glyph effect at a moment `t`: the glyph half of `Effected` (`./effect.ts`),
|
|
4
4
|
* built to its contract.
|
|
5
5
|
*
|
|
6
|
-
* A glyph effect is the
|
|
7
|
-
* the
|
|
6
|
+
* A glyph effect is the color effect's two-stage shape with a glyph where
|
|
7
|
+
* the colors were: for the cells an element draws in a frame, an
|
|
8
8
|
* `Animation` (`../core/animation.ts`) of what is done to them. The first
|
|
9
9
|
* stage is handed every cell once a frame (`GlyphCell`), blanks included —
|
|
10
10
|
* rain and stars live there — and whether the output draws ASCII alone
|
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
* scramble, a wave of case changes and particles on blank cells are all this
|
|
15
15
|
* one shape (`./glyph-effects.ts`) [LAW:one-type-per-behavior].
|
|
16
16
|
*
|
|
17
|
-
*
|
|
17
|
+
* Color and glyph are not two kinds of animation: each is an `Animation` of
|
|
18
18
|
* a per-cell map, and they differ only in what a cell is mapped to. The
|
|
19
|
-
* wrappers are two because the stages are handed different facts. A
|
|
20
|
-
* effect is settled against the depth, the terminal and the
|
|
21
|
-
* words (`Drawn`), and with no
|
|
19
|
+
* wrappers are two because the stages are handed different facts. A color
|
|
20
|
+
* effect is settled against the depth, the terminal and the colors of the
|
|
21
|
+
* words (`Drawn`), and with no color output there is nothing for it to
|
|
22
22
|
* change. A glyph effect needs none of that, and is written at every depth,
|
|
23
|
-
* with no
|
|
24
|
-
* `new Effected(new GlyphEffected(child, glyphs, …),
|
|
25
|
-
*
|
|
23
|
+
* with no color too. Over one element the two compose by nesting:
|
|
24
|
+
* `new Effected(new GlyphEffected(child, glyphs, …), colors, …)` moves the
|
|
25
|
+
* colors of the glyphs the glyph effect left, since each wrapper measures
|
|
26
26
|
* what its child drew.
|
|
27
27
|
*
|
|
28
28
|
* A `GlyphEffected` is the element under its glyph effect over time, an
|
|
@@ -58,13 +58,13 @@ import { render } from "../core/protocol.js";
|
|
|
58
58
|
import { Segment } from "../core/segment.js";
|
|
59
59
|
import { finiteTime } from "../core/easing.js";
|
|
60
60
|
import { sanitized } from "../core/text.js";
|
|
61
|
-
import { cellSeed,
|
|
61
|
+
import { cellSeed, validityOver, walkGlyphs } from "./effect.js";
|
|
62
62
|
import { pattern } from "../core/pattern.js";
|
|
63
63
|
/**
|
|
64
64
|
* A `GlyphEffected` at `t`, or an element through a glyph effect at a time an
|
|
65
65
|
* animation's `at` was handed: `renderable` with its cells' glyphs passed
|
|
66
66
|
* through `effect` at `t`, telling the hold it drew in as a `Recolored` does
|
|
67
|
-
* (`RenderOptions.
|
|
67
|
+
* (`RenderOptions.onReads`, `./effect.ts`). [LAW:one-type-per-behavior]
|
|
68
68
|
*/
|
|
69
69
|
export class Reglyphed {
|
|
70
70
|
renderable;
|
|
@@ -83,7 +83,7 @@ export class Reglyphed {
|
|
|
83
83
|
const animation = this.effect({ cells, asciiOnly: options.asciiOnly === true });
|
|
84
84
|
const frame = shownAt(animation, this._t, options);
|
|
85
85
|
const shown = showGlyphs(placed, frame.value);
|
|
86
|
-
options.
|
|
86
|
+
options.onReads?.(this._t, this.key, validityOver(cells.length > 0, frame, this._t));
|
|
87
87
|
return segments.map((segment, i) => (shown[i].every((text, j) => text === placed[i][j].glyph) ? segment : new Segment(shown[i].join(""), segment.style)));
|
|
88
88
|
}
|
|
89
89
|
measure(options) {
|
|
@@ -95,7 +95,7 @@ export class Reglyphed {
|
|
|
95
95
|
* as an `Effected` is (`./effect.ts`): with nothing drawn its answer is `t`,
|
|
96
96
|
* and placed, on its own or as a part of any combinator, it says the glyph
|
|
97
97
|
* effect's exact hold at that time and the output's `asciiOnly`, which the
|
|
98
|
-
* frame's drawing told (`
|
|
98
|
+
* frame's drawing told (`Reads`).
|
|
99
99
|
*/
|
|
100
100
|
export class GlyphEffected {
|
|
101
101
|
renderable;
|
|
@@ -110,11 +110,11 @@ export class GlyphEffected {
|
|
|
110
110
|
at(t) {
|
|
111
111
|
return new Reglyphed(this.renderable, this.effect, { t, key: this.key });
|
|
112
112
|
}
|
|
113
|
-
|
|
114
|
-
return moves?.(t, this.key)?.
|
|
113
|
+
validUntil(t, moves) {
|
|
114
|
+
return moves?.(t, this.key)?.validUntil ?? t;
|
|
115
115
|
}
|
|
116
|
-
|
|
117
|
-
return moves?.(t, this.key)?.
|
|
116
|
+
validFrom(t, moves) {
|
|
117
|
+
return moves?.(t, this.key)?.validFrom ?? t;
|
|
118
118
|
}
|
|
119
119
|
/** The element under the glyph effect with its motion taken out. */
|
|
120
120
|
reduced() {
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
* are done, each with its way out for an element leaving (`backspace`,
|
|
4
4
|
* `scrambleOut`), and a wave of case changes, rain, stars and marching ants,
|
|
5
5
|
* which loop for as long as they are drawn. Each is a `GlyphEffect` for
|
|
6
|
-
* `GlyphEffected` (`./glyph-effect.ts`), built as the
|
|
6
|
+
* `GlyphEffected` (`./glyph-effect.ts`), built as the color catalogue's are
|
|
7
7
|
* (`./effects.ts`): one function each over the one shape, at the defaults in
|
|
8
8
|
* `GLYPH_DEFAULTS`. `GLYPH_EFFECT_CATALOGUE` makes by name those a template's
|
|
9
9
|
* `glyphs` takes.
|
|
10
10
|
*
|
|
11
|
-
* Where a
|
|
11
|
+
* Where a color loop glides, a glyph cannot: a cell shows one glyph or
|
|
12
12
|
* another, so every loop here moves in steps, on a `beat`, and says when its
|
|
13
13
|
* next step is. The transitions are `Transition`s by the one rule the
|
|
14
|
-
*
|
|
14
|
+
* color transitions follow (`transition`): they move every frame until
|
|
15
15
|
* their seconds are up, and never after.
|
|
16
16
|
*
|
|
17
17
|
* [LAW:no-ambient-temporal-coupling] No effect reads a clock, and what a cell
|
|
@@ -113,19 +113,19 @@ export type GlyphTransitionName = "typewriter" | "scramble" | "backspace" | "scr
|
|
|
113
113
|
export declare const GLYPH_DEFAULTS: {
|
|
114
114
|
readonly typewriter: {
|
|
115
115
|
readonly seconds: 2;
|
|
116
|
-
readonly ease: import("../core/easing.js").
|
|
116
|
+
readonly ease: import("../core/easing.js").Easing;
|
|
117
117
|
};
|
|
118
118
|
readonly scramble: {
|
|
119
119
|
readonly seconds: 2.5;
|
|
120
|
-
readonly ease: import("../core/easing.js").
|
|
120
|
+
readonly ease: import("../core/easing.js").Easing;
|
|
121
121
|
};
|
|
122
122
|
readonly backspace: {
|
|
123
123
|
readonly seconds: 1.5;
|
|
124
|
-
readonly ease: import("../core/easing.js").
|
|
124
|
+
readonly ease: import("../core/easing.js").Easing;
|
|
125
125
|
};
|
|
126
126
|
readonly scrambleOut: {
|
|
127
127
|
readonly seconds: 2.5;
|
|
128
|
-
readonly ease: import("../core/easing.js").
|
|
128
|
+
readonly ease: import("../core/easing.js").Easing;
|
|
129
129
|
};
|
|
130
130
|
readonly wave: {
|
|
131
131
|
readonly step: 0.06;
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
* are done, each with its way out for an element leaving (`backspace`,
|
|
4
4
|
* `scrambleOut`), and a wave of case changes, rain, stars and marching ants,
|
|
5
5
|
* which loop for as long as they are drawn. Each is a `GlyphEffect` for
|
|
6
|
-
* `GlyphEffected` (`./glyph-effect.ts`), built as the
|
|
6
|
+
* `GlyphEffected` (`./glyph-effect.ts`), built as the color catalogue's are
|
|
7
7
|
* (`./effects.ts`): one function each over the one shape, at the defaults in
|
|
8
8
|
* `GLYPH_DEFAULTS`. `GLYPH_EFFECT_CATALOGUE` makes by name those a template's
|
|
9
9
|
* `glyphs` takes.
|
|
10
10
|
*
|
|
11
|
-
* Where a
|
|
11
|
+
* Where a color loop glides, a glyph cannot: a cell shows one glyph or
|
|
12
12
|
* another, so every loop here moves in steps, on a `beat`, and says when its
|
|
13
13
|
* next step is. The transitions are `Transition`s by the one rule the
|
|
14
|
-
*
|
|
14
|
+
* color transitions follow (`transition`): they move every frame until
|
|
15
15
|
* their seconds are up, and never after.
|
|
16
16
|
*
|
|
17
17
|
* [LAW:no-ambient-temporal-coupling] No effect reads a clock, and what a cell
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import { Animation } from "../core/animation.js";
|
|
24
24
|
import { cellLen, graphemes } from "../core/cells.js";
|
|
25
|
-
import { EASES,
|
|
25
|
+
import { EASES, WrapMode, stepSequence, positiveSeconds, withSettlingTime } from "../core/easing.js";
|
|
26
26
|
import { hash } from "../core/noise.js";
|
|
27
27
|
import { drawable, isAscii } from "../core/protocol.js";
|
|
28
28
|
import { inked } from "./effect.js";
|
|
@@ -67,11 +67,11 @@ function arrived(n, p) {
|
|
|
67
67
|
* the change shows. The beat is made once, for every frame drawn on it.
|
|
68
68
|
*/
|
|
69
69
|
function stepped(seconds) {
|
|
70
|
-
const pace =
|
|
70
|
+
const pace = stepSequence([seconds]);
|
|
71
71
|
return (frame, still) => Animation.of({
|
|
72
|
-
at: (t) => frame(Math.round(pace.
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
at: (t) => frame(Math.round(pace.validFrom(t) / seconds)),
|
|
73
|
+
validUntil: (t) => pace.validUntil(t),
|
|
74
|
+
validFrom: (t) => pace.validFrom(t),
|
|
75
75
|
reduced: () => Animation.constant(still),
|
|
76
76
|
});
|
|
77
77
|
}
|
|
@@ -85,9 +85,9 @@ const AS_WRITTEN = (cell) => cell.glyph;
|
|
|
85
85
|
* with are not text, so no second is spent on them.
|
|
86
86
|
*/
|
|
87
87
|
export function typewriter(timing) {
|
|
88
|
-
const phase =
|
|
88
|
+
const phase = WrapMode.once(0, timing.seconds);
|
|
89
89
|
// Settled, so the last cell is typed at the seconds whatever ease was handed.
|
|
90
|
-
const ease =
|
|
90
|
+
const ease = withSettlingTime(timing.ease);
|
|
91
91
|
return transition(timing.seconds, ({ cells }) => {
|
|
92
92
|
const { length, place } = text(cells);
|
|
93
93
|
return Animation.continuous((t) => {
|
|
@@ -110,9 +110,9 @@ const FLICKER = 1 / 15;
|
|
|
110
110
|
*/
|
|
111
111
|
export function scramble(timing, z) {
|
|
112
112
|
requireZ("scramble", z);
|
|
113
|
-
const phase =
|
|
113
|
+
const phase = WrapMode.once(0, timing.seconds);
|
|
114
114
|
// Settled, so the last cell resolves at the seconds whatever ease was handed.
|
|
115
|
-
const ease =
|
|
115
|
+
const ease = withSettlingTime(timing.ease);
|
|
116
116
|
const flicker = stepped(FLICKER)((step) => step, 0);
|
|
117
117
|
return transition(timing.seconds, ({ cells }) => {
|
|
118
118
|
const { length, place } = text(cells);
|
|
@@ -134,9 +134,9 @@ function churned(cell, z, step) {
|
|
|
134
134
|
* element ends blank and nothing is left to vanish when it goes.
|
|
135
135
|
*/
|
|
136
136
|
export function backspace(timing) {
|
|
137
|
-
const phase =
|
|
137
|
+
const phase = WrapMode.once(0, timing.seconds);
|
|
138
138
|
// Settled, so the first cell is erased at the seconds whatever ease was handed.
|
|
139
|
-
const ease =
|
|
139
|
+
const ease = withSettlingTime(timing.ease);
|
|
140
140
|
return transition(timing.seconds, ({ cells }) => {
|
|
141
141
|
const { length, place } = text(cells);
|
|
142
142
|
return Animation.continuous((t) => {
|
|
@@ -156,9 +156,9 @@ const CHURN = 0.3;
|
|
|
156
156
|
*/
|
|
157
157
|
export function scrambleOut(timing, z) {
|
|
158
158
|
requireZ("scrambleOut", z);
|
|
159
|
-
const phase =
|
|
159
|
+
const phase = WrapMode.once(0, timing.seconds);
|
|
160
160
|
// Settled, so the last cell is blank at the seconds whatever ease was handed.
|
|
161
|
-
const ease =
|
|
161
|
+
const ease = withSettlingTime(timing.ease);
|
|
162
162
|
const flicker = stepped(FLICKER)((step) => step, 0);
|
|
163
163
|
return transition(timing.seconds, ({ cells }) => {
|
|
164
164
|
const { length, place } = text(cells);
|
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
* `html.entities.html5`; regenerate rather than edit.
|
|
6
6
|
*/
|
|
7
7
|
/** The characters `name`, a reference's name without its `&` and `;`, stands for, if it names any. */
|
|
8
|
-
export declare function
|
|
8
|
+
export declare function namedCharacterReference(name: string): string | undefined;
|
|
@@ -380,7 +380,7 @@ const NAMED_REFERENCES = {
|
|
|
380
380
|
zwnj: "\u200c",
|
|
381
381
|
};
|
|
382
382
|
/** The characters `name`, a reference's name without its `&` and `;`, stands for, if it names any. */
|
|
383
|
-
export function
|
|
383
|
+
export function namedCharacterReference(name) {
|
|
384
384
|
// An own key only: `constructor` names nothing here, whatever the prototype holds.
|
|
385
385
|
return Object.hasOwn(NAMED_REFERENCES, name) ? NAMED_REFERENCES[name] : undefined;
|
|
386
386
|
}
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
* them with its hold at the frame's time (`placedRender`). The exit is
|
|
24
24
|
* drawn over whatever the arrival draws, so an element told to leave while
|
|
25
25
|
* it is still arriving leaves from where it is, never shown whole first —
|
|
26
|
-
* though a
|
|
26
|
+
* though a color exit is spread over the cells each frame shows, so a cell
|
|
27
27
|
* the arrival adds can move one already leaving back toward whole
|
|
28
28
|
* (`ownChange`, `./effects.ts`). [LAW:dataflow-not-control-flow]
|
|
29
29
|
*
|
|
30
|
-
* A half draws the element through a
|
|
30
|
+
* A half draws the element through a color transition (`throughColors`, a
|
|
31
31
|
* `fadeIn`) or a glyph one (`throughGlyphs`, a `typewriter`): each binds its
|
|
32
32
|
* transition to the one wrapper that draws it, so nothing here asks which kind
|
|
33
33
|
* a half is, and a line can type itself in and dissolve out. A half
|
|
@@ -57,9 +57,9 @@ import type { GlyphTransition } from "./glyph-effects.js";
|
|
|
57
57
|
* `throughColors` and `throughGlyphs` lend one the transition's schedule.
|
|
58
58
|
*/
|
|
59
59
|
export type Half = (element: Renderable, key: string) => Animation<Renderable>;
|
|
60
|
-
/** `transition`'s
|
|
60
|
+
/** `transition`'s colors drawn over an element, arriving from and leaving to the ground of the terminal the frame is drawn on. */
|
|
61
61
|
export declare function throughColors(transition: Transition): Half;
|
|
62
|
-
/** `transition`'s glyphs drawn over an element, at every depth, with no
|
|
62
|
+
/** `transition`'s glyphs drawn over an element, at every depth, with no color too. */
|
|
63
63
|
export declare function throughGlyphs(transition: GlyphTransition): Half;
|
|
64
64
|
/** How an element arrives and leaves, and what it is named for their seeds. */
|
|
65
65
|
export interface LifecycleOptions {
|