chat-layout 1.0.2 → 1.1.0-1
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 +2 -1
- package/index.d.mts +5 -5
- package/index.mjs +80 -136
- package/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -49,7 +49,8 @@ See [example/chat.ts](./example/chat.ts) for a full chat example.
|
|
|
49
49
|
- `Place` is the simplest way to align a single bubble left, center, or right.
|
|
50
50
|
- `MultilineText.align` uses logical values: `start`, `center`, `end`.
|
|
51
51
|
- `MultilineText.physicalAlign` uses physical values: `left`, `center`, `right`.
|
|
52
|
-
- `Text` and `MultilineText`
|
|
52
|
+
- `Text` and `MultilineText` default to `whiteSpace: "normal"`, matching pretext and CSS-style collapsible whitespace.
|
|
53
|
+
- Use `whiteSpace: "pre-wrap"` when blank lines, hard breaks, or edge spaces must stay visible.
|
|
53
54
|
- `Text` and `MultilineText` default to `overflowWrap: "break-word"`, which preserves compatibility-first min-content sizing for shrink layouts.
|
|
54
55
|
- Use `overflowWrap: "anywhere"` when long unspaced strings should contribute grapheme-level breakpoints to min-content sizing.
|
|
55
56
|
- `Text` supports `overflow: "ellipsis"` with `ellipsisPosition: "start" | "end" | "middle"` when measured under a finite `maxWidth`.
|
package/index.d.mts
CHANGED
|
@@ -45,9 +45,9 @@ type TextAlign = "start" | "center" | "end";
|
|
|
45
45
|
*/
|
|
46
46
|
type PhysicalTextAlign = "left" | "center" | "right";
|
|
47
47
|
/**
|
|
48
|
-
* Whitespace
|
|
48
|
+
* Whitespace handling mode for text measurement and layout.
|
|
49
49
|
*/
|
|
50
|
-
type
|
|
50
|
+
type TextWhiteSpaceMode = "normal" | "pre-wrap";
|
|
51
51
|
/**
|
|
52
52
|
* Text overflow behavior when content exceeds a finite width constraint.
|
|
53
53
|
*/
|
|
@@ -70,8 +70,8 @@ interface TextStyleOptions<C extends CanvasRenderingContext2D> {
|
|
|
70
70
|
font: string;
|
|
71
71
|
/** Fill style or resolver used when drawing the text. */
|
|
72
72
|
style: DynValue<C, string>;
|
|
73
|
-
/** Default:
|
|
74
|
-
|
|
73
|
+
/** Default: normal; matches pretext and CSS-style collapsible whitespace behavior. */
|
|
74
|
+
whiteSpace?: TextWhiteSpaceMode;
|
|
75
75
|
/** Default: break-word; use anywhere when min-content should honor grapheme break opportunities. */
|
|
76
76
|
overflowWrap?: TextOverflowWrapMode;
|
|
77
77
|
}
|
|
@@ -612,5 +612,5 @@ declare class TimelineRenderer<C extends CanvasRenderingContext2D, T extends {}>
|
|
|
612
612
|
hittest(test: HitTest): boolean;
|
|
613
613
|
}
|
|
614
614
|
//#endregion
|
|
615
|
-
export { Axis, BaseRenderer, Box, ChatRenderer, ChildLayoutResult, Context, CrossAxisAlignment, DebugRenderer, DynValue, Fixed, Flex, FlexContainerOptions, FlexItem, FlexItemOptions, FlexLayoutResult, Group, HitTest, JumpToOptions, LayoutConstraints, LayoutRect, ListState, MainAxisAlignment, MainAxisSize, MultilineText, MultilineTextOptions, Node, PaddingBox, PhysicalTextAlign, Place, RenderFeedback, RendererOptions, Text, TextAlign, TextEllipsisPosition, TextOptions, TextOverflowMode, TextOverflowWrapMode, TextStyleOptions,
|
|
615
|
+
export { Axis, BaseRenderer, Box, ChatRenderer, ChildLayoutResult, Context, CrossAxisAlignment, DebugRenderer, DynValue, Fixed, Flex, FlexContainerOptions, FlexItem, FlexItemOptions, FlexLayoutResult, Group, HitTest, JumpToOptions, LayoutConstraints, LayoutRect, ListState, MainAxisAlignment, MainAxisSize, MultilineText, MultilineTextOptions, Node, PaddingBox, PhysicalTextAlign, Place, RenderFeedback, RendererOptions, Text, TextAlign, TextEllipsisPosition, TextOptions, TextOverflowMode, TextOverflowWrapMode, TextStyleOptions, TextWhiteSpaceMode, TimelineRenderer, VirtualizedRenderer, Wrapper, memoRenderItem, memoRenderItemBy };
|
|
616
616
|
//# sourceMappingURL=index.d.mts.map
|
package/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { layoutNextLine, layoutWithLines,
|
|
1
|
+
import { layoutNextLine, layoutWithLines, measureLineStats, measureNaturalWidth, prepareWithSegments } from "@chenglou/pretext";
|
|
2
2
|
//#region src/internal/node-registry.ts
|
|
3
3
|
const registry = /* @__PURE__ */ new WeakMap();
|
|
4
4
|
const revisions = /* @__PURE__ */ new WeakMap();
|
|
@@ -819,7 +819,8 @@ var Place = class extends Wrapper {
|
|
|
819
819
|
//#region src/text.ts
|
|
820
820
|
const FONT_SHIFT_PROBE = "M";
|
|
821
821
|
const ELLIPSIS_GLYPH = "…";
|
|
822
|
-
const
|
|
822
|
+
const INTRINSIC_MAX_WIDTH = Number.POSITIVE_INFINITY;
|
|
823
|
+
const PREPARED_TEXT_CACHE_CAPACITY = 512;
|
|
823
824
|
const FONT_SHIFT_CACHE_CAPACITY = 64;
|
|
824
825
|
const ELLIPSIS_WIDTH_CACHE_CAPACITY = 64;
|
|
825
826
|
const LINE_START_CURSOR = {
|
|
@@ -827,16 +828,11 @@ const LINE_START_CURSOR = {
|
|
|
827
828
|
graphemeIndex: 0
|
|
828
829
|
};
|
|
829
830
|
const MIN_CONTENT_WIDTH_EPSILON = .001;
|
|
830
|
-
const
|
|
831
|
+
const preparedTextCache = /* @__PURE__ */ new Map();
|
|
831
832
|
const fontShiftCache = /* @__PURE__ */ new Map();
|
|
832
833
|
const ellipsisWidthCache = /* @__PURE__ */ new Map();
|
|
833
834
|
const preparedUnitCache = /* @__PURE__ */ new WeakMap();
|
|
834
835
|
let sharedGraphemeSegmenter;
|
|
835
|
-
function preprocessSegments(text, whitespace = "preserve") {
|
|
836
|
-
const segments = text.split("\n");
|
|
837
|
-
if (whitespace === "trim-and-collapse") return segments.map((line) => line.trim()).filter((line) => line.length > 0);
|
|
838
|
-
return segments;
|
|
839
|
-
}
|
|
840
836
|
function readLruValue(cache, key) {
|
|
841
837
|
const cached = cache.get(key);
|
|
842
838
|
if (cached == null) return;
|
|
@@ -853,14 +849,22 @@ function writeLruValue(cache, key, value, capacity) {
|
|
|
853
849
|
cache.set(key, value);
|
|
854
850
|
return value;
|
|
855
851
|
}
|
|
856
|
-
function
|
|
857
|
-
return `${font}\u0000${
|
|
852
|
+
function getPreparedTextCacheKey(text, font, whiteSpace) {
|
|
853
|
+
return `${font}\u0000${whiteSpace}\u0000${text}`;
|
|
858
854
|
}
|
|
859
|
-
function
|
|
860
|
-
const key =
|
|
861
|
-
const cached = readLruValue(
|
|
855
|
+
function readPreparedText(text, font, whiteSpace) {
|
|
856
|
+
const key = getPreparedTextCacheKey(text, font, whiteSpace);
|
|
857
|
+
const cached = readLruValue(preparedTextCache, key);
|
|
862
858
|
if (cached != null) return cached;
|
|
863
|
-
return writeLruValue(
|
|
859
|
+
return writeLruValue(preparedTextCache, key, prepareWithSegments(text, font, { whiteSpace }), PREPARED_TEXT_CACHE_CAPACITY);
|
|
860
|
+
}
|
|
861
|
+
function readPreparedFirstLine(ctx, text, whiteSpace) {
|
|
862
|
+
const line = layoutNextLine(readPreparedText(text, ctx.graphics.font, whiteSpace), LINE_START_CURSOR, INTRINSIC_MAX_WIDTH);
|
|
863
|
+
if (line == null) return;
|
|
864
|
+
return {
|
|
865
|
+
text: line.text,
|
|
866
|
+
prepared: readPreparedText(line.text, ctx.graphics.font, whiteSpace)
|
|
867
|
+
};
|
|
864
868
|
}
|
|
865
869
|
function measureFontShift(ctx) {
|
|
866
870
|
const font = ctx.graphics.font;
|
|
@@ -877,18 +881,13 @@ function measurePreparedMinContentWidth(prepared, overflowWrap = "break-word") {
|
|
|
877
881
|
maxAnyWidth = Math.max(maxAnyWidth, segmentWidth);
|
|
878
882
|
const segment = prepared.segments[i];
|
|
879
883
|
if (segment != null && segment.trim().length > 0) {
|
|
880
|
-
const breakableWidths = prepared.
|
|
884
|
+
const breakableWidths = prepared.breakableFitAdvances[i];
|
|
881
885
|
const minContentWidth = overflowWrap === "anywhere" && breakableWidths != null && breakableWidths.length > 0 ? breakableWidths.reduce((widest, width) => Math.max(widest, width), 0) : segmentWidth;
|
|
882
886
|
maxWidth = Math.max(maxWidth, minContentWidth);
|
|
883
887
|
}
|
|
884
888
|
}
|
|
885
889
|
return maxWidth > 0 ? maxWidth : maxAnyWidth;
|
|
886
890
|
}
|
|
887
|
-
function measurePreparedWidth(prepared) {
|
|
888
|
-
let width = 0;
|
|
889
|
-
for (const segmentWidth of prepared.widths) width += segmentWidth ?? 0;
|
|
890
|
-
return width;
|
|
891
|
-
}
|
|
892
891
|
function getGraphemeSegmenter() {
|
|
893
892
|
if (sharedGraphemeSegmenter !== void 0) return sharedGraphemeSegmenter;
|
|
894
893
|
sharedGraphemeSegmenter = typeof Intl.Segmenter === "function" ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
|
|
@@ -908,7 +907,7 @@ function getPreparedUnits(prepared) {
|
|
|
908
907
|
for (let i = 0; i < prepared.segments.length; i += 1) {
|
|
909
908
|
const segment = prepared.segments[i] ?? "";
|
|
910
909
|
const segmentWidth = prepared.widths[i] ?? 0;
|
|
911
|
-
const breakableWidths = prepared.
|
|
910
|
+
const breakableWidths = prepared.breakableFitAdvances[i];
|
|
912
911
|
if (breakableWidths != null && segment.length > 0) {
|
|
913
912
|
const graphemes = splitGraphemes(segment);
|
|
914
913
|
if (graphemes.length === breakableWidths.length) {
|
|
@@ -982,7 +981,7 @@ function createEllipsisOnlyLayout(ctx, maxWidth, shift) {
|
|
|
982
981
|
};
|
|
983
982
|
}
|
|
984
983
|
function layoutPreparedEllipsis(ctx, prepared, text, maxWidth, shift, position, forceEllipsis = false) {
|
|
985
|
-
const intrinsicWidth =
|
|
984
|
+
const intrinsicWidth = measureNaturalWidth(prepared);
|
|
986
985
|
if (!forceEllipsis && intrinsicWidth <= maxWidth) return {
|
|
987
986
|
width: intrinsicWidth,
|
|
988
987
|
text,
|
|
@@ -1046,71 +1045,57 @@ function normalizeMaxLines(maxLines) {
|
|
|
1046
1045
|
if (maxLines == null || !Number.isFinite(maxLines)) return;
|
|
1047
1046
|
return Math.max(1, Math.trunc(maxLines));
|
|
1048
1047
|
}
|
|
1049
|
-
function layoutFirstLineIntrinsic(ctx, text,
|
|
1050
|
-
const
|
|
1051
|
-
if (
|
|
1048
|
+
function layoutFirstLineIntrinsic(ctx, text, whiteSpace = "normal") {
|
|
1049
|
+
const firstLine = readPreparedFirstLine(ctx, text, whiteSpace);
|
|
1050
|
+
if (firstLine == null) return {
|
|
1052
1051
|
width: 0,
|
|
1053
1052
|
text: "",
|
|
1054
1053
|
shift: 0
|
|
1055
1054
|
};
|
|
1056
1055
|
const shift = measureFontShift(ctx);
|
|
1057
1056
|
return {
|
|
1058
|
-
width:
|
|
1059
|
-
text:
|
|
1057
|
+
width: measureNaturalWidth(firstLine.prepared),
|
|
1058
|
+
text: firstLine.text,
|
|
1060
1059
|
shift
|
|
1061
1060
|
};
|
|
1062
1061
|
}
|
|
1063
|
-
function measureTextIntrinsic(ctx, text,
|
|
1064
|
-
const
|
|
1065
|
-
if (
|
|
1062
|
+
function measureTextIntrinsic(ctx, text, whiteSpace = "normal") {
|
|
1063
|
+
const { maxLineWidth: width, lineCount } = measureLineStats(readPreparedText(text, ctx.graphics.font, whiteSpace), INTRINSIC_MAX_WIDTH);
|
|
1064
|
+
if (lineCount === 0) return {
|
|
1066
1065
|
width: 0,
|
|
1067
1066
|
lineCount: 0
|
|
1068
1067
|
};
|
|
1069
|
-
let width = 0;
|
|
1070
|
-
for (const segment of segments) width = Math.max(width, ctx.graphics.measureText(segment).width);
|
|
1071
1068
|
return {
|
|
1072
1069
|
width,
|
|
1073
|
-
lineCount
|
|
1070
|
+
lineCount
|
|
1074
1071
|
};
|
|
1075
1072
|
}
|
|
1076
|
-
function layoutTextIntrinsic(ctx, text,
|
|
1077
|
-
const
|
|
1078
|
-
if (
|
|
1073
|
+
function layoutTextIntrinsic(ctx, text, whiteSpace = "normal") {
|
|
1074
|
+
const intrinsic = layoutWithLines(readPreparedText(text, ctx.graphics.font, whiteSpace), INTRINSIC_MAX_WIDTH, 0);
|
|
1075
|
+
if (intrinsic.lines.length === 0) return {
|
|
1079
1076
|
width: 0,
|
|
1080
1077
|
lines: []
|
|
1081
1078
|
};
|
|
1082
1079
|
const shift = measureFontShift(ctx);
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
lines.push({
|
|
1089
|
-
width: measuredWidth,
|
|
1090
|
-
text: segment,
|
|
1091
|
-
shift
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1080
|
+
const lines = intrinsic.lines.map((line) => ({
|
|
1081
|
+
width: line.width,
|
|
1082
|
+
text: line.text,
|
|
1083
|
+
shift
|
|
1084
|
+
}));
|
|
1094
1085
|
return {
|
|
1095
|
-
width,
|
|
1086
|
+
width: lines.reduce((maxLineWidth, line) => Math.max(maxLineWidth, line.width), 0),
|
|
1096
1087
|
lines
|
|
1097
1088
|
};
|
|
1098
1089
|
}
|
|
1099
|
-
function layoutFirstLine(ctx, text, maxWidth,
|
|
1090
|
+
function layoutFirstLine(ctx, text, maxWidth, whiteSpace = "normal") {
|
|
1100
1091
|
if (maxWidth < 0) maxWidth = 0;
|
|
1101
|
-
const segment = preprocessSegments(text, whitespace)[0];
|
|
1102
|
-
if (!segment) return {
|
|
1103
|
-
width: 0,
|
|
1104
|
-
text: "",
|
|
1105
|
-
shift: 0
|
|
1106
|
-
};
|
|
1107
1092
|
const shift = measureFontShift(ctx);
|
|
1108
1093
|
if (maxWidth === 0) return {
|
|
1109
1094
|
width: 0,
|
|
1110
1095
|
text: "",
|
|
1111
1096
|
shift
|
|
1112
1097
|
};
|
|
1113
|
-
const line = layoutNextLine(
|
|
1098
|
+
const line = layoutNextLine(readPreparedText(text, ctx.graphics.font, whiteSpace), LINE_START_CURSOR, maxWidth);
|
|
1114
1099
|
if (line == null) return {
|
|
1115
1100
|
width: 0,
|
|
1116
1101
|
text: "",
|
|
@@ -1122,10 +1107,10 @@ function layoutFirstLine(ctx, text, maxWidth, whitespace = "preserve") {
|
|
|
1122
1107
|
shift
|
|
1123
1108
|
};
|
|
1124
1109
|
}
|
|
1125
|
-
function layoutEllipsizedFirstLine(ctx, text, maxWidth, ellipsisPosition = "end",
|
|
1110
|
+
function layoutEllipsizedFirstLine(ctx, text, maxWidth, ellipsisPosition = "end", whiteSpace = "normal") {
|
|
1126
1111
|
if (maxWidth < 0) maxWidth = 0;
|
|
1127
|
-
const
|
|
1128
|
-
if (
|
|
1112
|
+
const firstLine = readPreparedFirstLine(ctx, text, whiteSpace);
|
|
1113
|
+
if (firstLine == null) return {
|
|
1129
1114
|
width: 0,
|
|
1130
1115
|
text: "",
|
|
1131
1116
|
shift: 0,
|
|
@@ -1138,105 +1123,64 @@ function layoutEllipsizedFirstLine(ctx, text, maxWidth, ellipsisPosition = "end"
|
|
|
1138
1123
|
shift,
|
|
1139
1124
|
overflowed: true
|
|
1140
1125
|
};
|
|
1141
|
-
return layoutPreparedEllipsis(ctx,
|
|
1126
|
+
return layoutPreparedEllipsis(ctx, firstLine.prepared, firstLine.text, maxWidth, shift, ellipsisPosition);
|
|
1142
1127
|
}
|
|
1143
|
-
function layoutForcedEllipsizedLine(ctx, text, maxWidth, shift) {
|
|
1128
|
+
function layoutForcedEllipsizedLine(ctx, text, maxWidth, shift, whiteSpace = "normal") {
|
|
1144
1129
|
if (text.length === 0) return createEllipsisOnlyLayout(ctx, maxWidth, shift);
|
|
1145
|
-
return layoutPreparedEllipsis(ctx,
|
|
1130
|
+
return layoutPreparedEllipsis(ctx, readPreparedText(text, ctx.graphics.font, whiteSpace), text, maxWidth, shift, "end", true);
|
|
1146
1131
|
}
|
|
1147
|
-
function measureText(ctx, text, maxWidth,
|
|
1132
|
+
function measureText(ctx, text, maxWidth, whiteSpace = "normal") {
|
|
1148
1133
|
if (maxWidth < 0) maxWidth = 0;
|
|
1149
|
-
|
|
1150
|
-
if (segments.length === 0 || maxWidth === 0) return {
|
|
1134
|
+
if (maxWidth === 0) return {
|
|
1151
1135
|
width: 0,
|
|
1152
1136
|
lineCount: 0
|
|
1153
1137
|
};
|
|
1154
|
-
const
|
|
1155
|
-
let width = 0;
|
|
1156
|
-
let lineCount = 0;
|
|
1157
|
-
for (const segment of segments) {
|
|
1158
|
-
if (segment.length === 0) {
|
|
1159
|
-
lineCount += 1;
|
|
1160
|
-
continue;
|
|
1161
|
-
}
|
|
1162
|
-
const prepared = readPreparedSegment(segment, font);
|
|
1163
|
-
lineCount += walkLineRanges(prepared, maxWidth, (line) => {
|
|
1164
|
-
width = Math.max(width, line.width);
|
|
1165
|
-
});
|
|
1166
|
-
}
|
|
1138
|
+
const { maxLineWidth: width, lineCount } = measureLineStats(readPreparedText(text, ctx.graphics.font, whiteSpace), maxWidth);
|
|
1167
1139
|
return {
|
|
1168
1140
|
width,
|
|
1169
1141
|
lineCount
|
|
1170
1142
|
};
|
|
1171
1143
|
}
|
|
1172
|
-
function measureTextMinContent(ctx, text,
|
|
1173
|
-
const
|
|
1174
|
-
if (
|
|
1144
|
+
function measureTextMinContent(ctx, text, whiteSpace = "normal", overflowWrap = "break-word") {
|
|
1145
|
+
const prepared = readPreparedText(text, ctx.graphics.font, whiteSpace);
|
|
1146
|
+
if (prepared.widths.length === 0) return {
|
|
1175
1147
|
width: 0,
|
|
1176
1148
|
lineCount: 0
|
|
1177
1149
|
};
|
|
1178
|
-
const
|
|
1179
|
-
|
|
1180
|
-
for (const segment of segments) {
|
|
1181
|
-
if (segment.length === 0) continue;
|
|
1182
|
-
const prepared = readPreparedSegment(segment, font);
|
|
1183
|
-
width = Math.max(width, measurePreparedMinContentWidth(prepared, overflowWrap));
|
|
1184
|
-
}
|
|
1185
|
-
let lineCount = 0;
|
|
1186
|
-
const lineMaxWidth = Math.max(width, MIN_CONTENT_WIDTH_EPSILON);
|
|
1187
|
-
for (const segment of segments) {
|
|
1188
|
-
if (segment.length === 0) {
|
|
1189
|
-
lineCount += 1;
|
|
1190
|
-
continue;
|
|
1191
|
-
}
|
|
1192
|
-
const prepared = readPreparedSegment(segment, font);
|
|
1193
|
-
lineCount += walkLineRanges(prepared, lineMaxWidth, () => {});
|
|
1194
|
-
}
|
|
1150
|
+
const width = measurePreparedMinContentWidth(prepared, overflowWrap);
|
|
1151
|
+
const { lineCount } = measureLineStats(prepared, Math.max(width, MIN_CONTENT_WIDTH_EPSILON));
|
|
1195
1152
|
return {
|
|
1196
1153
|
width,
|
|
1197
1154
|
lineCount
|
|
1198
1155
|
};
|
|
1199
1156
|
}
|
|
1200
|
-
function layoutText(ctx, text, maxWidth,
|
|
1157
|
+
function layoutText(ctx, text, maxWidth, whiteSpace = "normal") {
|
|
1201
1158
|
if (maxWidth < 0) maxWidth = 0;
|
|
1202
|
-
|
|
1203
|
-
|
|
1159
|
+
if (maxWidth === 0) return {
|
|
1160
|
+
width: 0,
|
|
1161
|
+
lines: []
|
|
1162
|
+
};
|
|
1163
|
+
const layout = layoutWithLines(readPreparedText(text, ctx.graphics.font, whiteSpace), maxWidth, 0);
|
|
1164
|
+
if (layout.lines.length === 0) return {
|
|
1204
1165
|
width: 0,
|
|
1205
1166
|
lines: []
|
|
1206
1167
|
};
|
|
1207
|
-
const font = ctx.graphics.font;
|
|
1208
1168
|
const shift = measureFontShift(ctx);
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
width: 0,
|
|
1215
|
-
text: "",
|
|
1216
|
-
shift
|
|
1217
|
-
});
|
|
1218
|
-
continue;
|
|
1219
|
-
}
|
|
1220
|
-
const { lines: segLines } = layoutWithLines(readPreparedSegment(segment, font), maxWidth, 0);
|
|
1221
|
-
for (const segLine of segLines) {
|
|
1222
|
-
width = Math.max(width, segLine.width);
|
|
1223
|
-
lines.push({
|
|
1224
|
-
width: segLine.width,
|
|
1225
|
-
text: segLine.text,
|
|
1226
|
-
shift
|
|
1227
|
-
});
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1169
|
+
const lines = layout.lines.map((line) => ({
|
|
1170
|
+
width: line.width,
|
|
1171
|
+
text: line.text,
|
|
1172
|
+
shift
|
|
1173
|
+
}));
|
|
1230
1174
|
return {
|
|
1231
|
-
width,
|
|
1175
|
+
width: lines.reduce((maxLineWidth, line) => Math.max(maxLineWidth, line.width), 0),
|
|
1232
1176
|
lines
|
|
1233
1177
|
};
|
|
1234
1178
|
}
|
|
1235
1179
|
function layoutTextWithOverflow(ctx, text, maxWidth, options = {}) {
|
|
1236
|
-
const
|
|
1180
|
+
const whiteSpace = options.whiteSpace ?? "normal";
|
|
1237
1181
|
const overflow = options.overflow ?? "clip";
|
|
1238
1182
|
const normalizedMaxLines = normalizeMaxLines(options.maxLines);
|
|
1239
|
-
const layout = layoutText(ctx, text, maxWidth,
|
|
1183
|
+
const layout = layoutText(ctx, text, maxWidth, whiteSpace);
|
|
1240
1184
|
if (normalizedMaxLines == null || layout.lines.length <= normalizedMaxLines) return {
|
|
1241
1185
|
width: layout.width,
|
|
1242
1186
|
lines: layout.lines.map((line) => ({
|
|
@@ -1256,7 +1200,7 @@ function layoutTextWithOverflow(ctx, text, maxWidth, options = {}) {
|
|
|
1256
1200
|
};
|
|
1257
1201
|
const shift = visibleLines[visibleLines.length - 1]?.shift ?? measureFontShift(ctx);
|
|
1258
1202
|
const lastVisibleLine = visibleLines[visibleLines.length - 1];
|
|
1259
|
-
const ellipsizedLastLine = lastVisibleLine == null || lastVisibleLine.text.length === 0 ? createEllipsisOnlyLayout(ctx, Math.max(0, maxWidth), shift) : layoutForcedEllipsizedLine(ctx, lastVisibleLine.text, maxWidth, shift);
|
|
1203
|
+
const ellipsizedLastLine = lastVisibleLine == null || lastVisibleLine.text.length === 0 ? createEllipsisOnlyLayout(ctx, Math.max(0, maxWidth), shift) : layoutForcedEllipsizedLine(ctx, lastVisibleLine.text, maxWidth, shift, whiteSpace);
|
|
1260
1204
|
const lines = [...visibleLines.slice(0, -1).map((line) => ({
|
|
1261
1205
|
...line,
|
|
1262
1206
|
overflowed: false
|
|
@@ -1319,12 +1263,12 @@ function getMultiLineMinContentLayoutKey() {
|
|
|
1319
1263
|
}
|
|
1320
1264
|
function getSingleLineLayout(node, ctx, text, options) {
|
|
1321
1265
|
const maxWidth = normalizeTextMaxWidth(ctx.constraints?.maxWidth);
|
|
1322
|
-
return readCachedTextLayout(node, ctx, getSingleLineLayoutKey(maxWidth), () => maxWidth == null ? layoutFirstLineIntrinsic(ctx, text, options.
|
|
1266
|
+
return readCachedTextLayout(node, ctx, getSingleLineLayoutKey(maxWidth), () => maxWidth == null ? layoutFirstLineIntrinsic(ctx, text, options.whiteSpace) : options.overflow === "ellipsis" ? layoutEllipsizedFirstLine(ctx, text, maxWidth, options.ellipsisPosition ?? "end", options.whiteSpace) : layoutFirstLine(ctx, text, maxWidth, options.whiteSpace));
|
|
1323
1267
|
}
|
|
1324
1268
|
function getMultiLineOverflowLayout(node, ctx, text, options) {
|
|
1325
1269
|
const maxWidth = normalizeTextMaxWidth(ctx.constraints?.maxWidth);
|
|
1326
1270
|
return readCachedTextLayout(node, ctx, getMultiLineOverflowLayoutKey(maxWidth), () => layoutTextWithOverflow(ctx, text, maxWidth ?? 0, {
|
|
1327
|
-
|
|
1271
|
+
whiteSpace: options.whiteSpace,
|
|
1328
1272
|
overflow: options.overflow,
|
|
1329
1273
|
maxLines: options.maxLines
|
|
1330
1274
|
}));
|
|
@@ -1338,17 +1282,17 @@ function getMultiLineMeasureLayout(node, ctx, text, options) {
|
|
|
1338
1282
|
lineCount: layout.lines.length
|
|
1339
1283
|
};
|
|
1340
1284
|
}
|
|
1341
|
-
return readCachedTextLayout(node, ctx, getMultiLineMeasureLayoutKey(maxWidth), () => maxWidth == null ? measureTextIntrinsic(ctx, text, options.
|
|
1285
|
+
return readCachedTextLayout(node, ctx, getMultiLineMeasureLayoutKey(maxWidth), () => maxWidth == null ? measureTextIntrinsic(ctx, text, options.whiteSpace) : measureText(ctx, text, maxWidth, options.whiteSpace));
|
|
1342
1286
|
}
|
|
1343
1287
|
function getMultiLineDrawLayout(node, ctx, text, options) {
|
|
1344
1288
|
const maxWidth = normalizeTextMaxWidth(ctx.constraints?.maxWidth);
|
|
1345
1289
|
if (maxWidth != null && shouldUseMultilineOverflowLayout(options)) return getMultiLineOverflowLayout(node, ctx, text, options);
|
|
1346
|
-
return readCachedTextLayout(node, ctx, getMultiLineDrawLayoutKey(maxWidth), () => maxWidth == null ? layoutTextIntrinsic(ctx, text, options.
|
|
1290
|
+
return readCachedTextLayout(node, ctx, getMultiLineDrawLayoutKey(maxWidth), () => maxWidth == null ? layoutTextIntrinsic(ctx, text, options.whiteSpace) : layoutText(ctx, text, maxWidth, options.whiteSpace));
|
|
1347
1291
|
}
|
|
1348
1292
|
function getSingleLineMinContentLayout(node, ctx, text, options) {
|
|
1349
1293
|
return readCachedTextLayout(node, ctx, getSingleLineMinContentLayoutKey(), () => {
|
|
1350
|
-
const measurement = measureTextMinContent(ctx, text, options.
|
|
1351
|
-
const { shift } = layoutFirstLineIntrinsic(ctx, text, options.
|
|
1294
|
+
const measurement = measureTextMinContent(ctx, text, options.whiteSpace, options.overflowWrap);
|
|
1295
|
+
const { shift } = layoutFirstLineIntrinsic(ctx, text, options.whiteSpace);
|
|
1352
1296
|
return {
|
|
1353
1297
|
width: measurement.width,
|
|
1354
1298
|
text,
|
|
@@ -1356,8 +1300,8 @@ function getSingleLineMinContentLayout(node, ctx, text, options) {
|
|
|
1356
1300
|
};
|
|
1357
1301
|
});
|
|
1358
1302
|
}
|
|
1359
|
-
function getMultiLineMinContentLayout(node, ctx, text,
|
|
1360
|
-
return readCachedTextLayout(node, ctx, getMultiLineMinContentLayoutKey(), () => measureTextMinContent(ctx, text,
|
|
1303
|
+
function getMultiLineMinContentLayout(node, ctx, text, whiteSpace, overflowWrap) {
|
|
1304
|
+
return readCachedTextLayout(node, ctx, getMultiLineMinContentLayoutKey(), () => measureTextMinContent(ctx, text, whiteSpace, overflowWrap));
|
|
1361
1305
|
}
|
|
1362
1306
|
/**
|
|
1363
1307
|
* Draws wrapped text using the configured line height and alignment.
|
|
@@ -1384,7 +1328,7 @@ var MultilineText = class {
|
|
|
1384
1328
|
measureMinContent(ctx) {
|
|
1385
1329
|
return ctx.with((g) => {
|
|
1386
1330
|
g.font = this.options.font;
|
|
1387
|
-
const { width, lineCount } = getMultiLineMinContentLayout(this, ctx, this.text, this.options.
|
|
1331
|
+
const { width, lineCount } = getMultiLineMinContentLayout(this, ctx, this.text, this.options.whiteSpace, this.options.overflowWrap);
|
|
1388
1332
|
return {
|
|
1389
1333
|
width,
|
|
1390
1334
|
height: lineCount * this.options.lineHeight
|
package/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["#children","#inner","clampToConstraints","#top","#bottom","#left","#right","#ctx","#lastWidth","#cache","#layoutCache","#textLayoutCache","#clearAllCaches","#syncCachesToViewportWidth","clamp","#cancelJumpAnimation","#jumpAnimation","#controlledState","clamp","clamp","#resolveVisibleWindow","#resolveVisibleWindow"],"sources":["../src/internal/node-registry.ts","../src/utils.ts","../src/nodes/base.ts","../src/layout.ts","../src/nodes/shared.ts","../src/nodes/box.ts","../src/nodes/flex.ts","../src/nodes/place.ts","../src/text.ts","../src/nodes/text.ts","../src/renderer/base.ts","../src/renderer/list-state.ts","../src/renderer/memo.ts","../src/renderer/virtualized/base.ts","../src/renderer/virtualized/solver.ts","../src/renderer/virtualized/chat.ts","../src/renderer/virtualized/timeline.ts"],"sourcesContent":["import type { Node } from \"../types\";\n\nconst registry = new WeakMap<Node<any>, Node<any>>();\nconst revisions = new WeakMap<Node<any>, number>();\n\nfunction getOwnershipError(): Error {\n return new Error(\"A node can only be attached to one parent. Shared nodes are not supported.\");\n}\n\nfunction getDetachOwnershipError(): Error {\n return new Error(\"Cannot detach or replace a node from a parent that does not own it.\");\n}\n\nfunction bumpRevision(node: Node<any>): void {\n revisions.set(node, (revisions.get(node) ?? 0) + 1);\n}\n\nexport function getNodeRevision<C extends CanvasRenderingContext2D>(node: Node<C>): number {\n return revisions.get(node) ?? 0;\n}\n\nexport function attachNodeToParent<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n parent: Node<C>,\n): void {\n if (registry.has(node)) {\n throw getOwnershipError();\n }\n registry.set(node, parent);\n bumpRevision(parent);\n}\n\nexport function attachNodesToParent<C extends CanvasRenderingContext2D>(\n nodes: Iterable<Node<C>>,\n parent: Node<C>,\n): void {\n for (const node of nodes) {\n attachNodeToParent(node, parent);\n }\n}\n\nexport function detachNodeFromParent<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n parent?: Node<C>,\n): void {\n const currentParent = registry.get(node);\n if (currentParent == null) {\n return;\n }\n if (parent != null && currentParent !== parent) {\n throw getDetachOwnershipError();\n }\n registry.delete(node);\n bumpRevision(currentParent);\n}\n\nexport function replaceNodeParent<C extends CanvasRenderingContext2D>(\n previousNode: Node<C>,\n nextNode: Node<C>,\n parent: Node<C>,\n): void {\n if (previousNode === nextNode) {\n return;\n }\n const currentParent = registry.get(previousNode);\n if (currentParent !== parent) {\n throw getDetachOwnershipError();\n }\n if (registry.has(nextNode)) {\n throw getOwnershipError();\n }\n registry.delete(previousNode);\n registry.set(nextNode, parent);\n bumpRevision(parent);\n}\n\nexport function replaceNodesParent<C extends CanvasRenderingContext2D>(\n previousNodes: Iterable<Node<C>>,\n nextNodes: Iterable<Node<C>>,\n parent: Node<C>,\n): void {\n const previousSnapshot = Array.from(previousNodes);\n const nextSnapshot = Array.from(nextNodes);\n if (\n previousSnapshot.length === nextSnapshot.length &&\n previousSnapshot.every((node, index) => node === nextSnapshot[index])\n ) {\n return;\n }\n\n const previousSet = new Set(previousSnapshot);\n const nextSet = new Set<Node<C>>();\n for (const node of nextSnapshot) {\n if (nextSet.has(node)) {\n throw getOwnershipError();\n }\n nextSet.add(node);\n const currentParent = registry.get(node);\n if (currentParent != null && currentParent !== parent) {\n throw getOwnershipError();\n }\n }\n\n for (const node of previousSnapshot) {\n if (!nextSet.has(node)) {\n const currentParent = registry.get(node);\n if (currentParent !== parent) {\n throw getDetachOwnershipError();\n }\n registry.delete(node);\n }\n }\n\n for (const node of nextSnapshot) {\n if (!previousSet.has(node)) {\n registry.set(node, parent);\n }\n }\n\n bumpRevision(parent);\n}\n\nexport function forEachNodeAncestor<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n visitor: (ancestor: Node<C>) => void,\n): void {\n let current: Node<C> | undefined = node;\n while ((current = registry.get(current))) {\n visitor(current);\n }\n}\n\nexport function registerNodeParent<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n parent: Node<C>,\n): void {\n attachNodeToParent(node, parent);\n}\n\nexport function unregisterNodeParent<C extends CanvasRenderingContext2D>(node: Node<C>, parent?: Node<C>): void {\n detachNodeFromParent(node, parent);\n}\n\nexport function getNodeParent<C extends CanvasRenderingContext2D>(node: Node<C>): Node<C> | undefined {\n return registry.get(node);\n}\n","export function shallow<T extends object>(object: T): T {\n return Object.create(object) as T;\n}\n","import { attachNodeToParent, replaceNodeParent, replaceNodesParent } from \"../internal/node-registry\";\nimport type { Box, Context, HitTest, LayoutConstraints, Node } from \"../types\";\nimport { shallow } from \"../utils\";\n\nexport function withNodeConstraints<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n constraints: LayoutConstraints | undefined,\n): Context<C> {\n if (constraints === ctx.constraints) {\n return ctx;\n }\n const next = shallow(ctx);\n next.constraints = constraints;\n return next;\n}\n\nexport function measureNodeMinContent<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n node: Node<C>,\n constraints: LayoutConstraints | undefined = ctx.constraints,\n): Box {\n const nextCtx = withNodeConstraints(ctx, constraints);\n if (node.measureMinContent != null) {\n return node.measureMinContent(nextCtx);\n }\n return node.measure(nextCtx);\n}\n\n/**\n * A node that owns an ordered list of child nodes.\n */\nexport abstract class Group<C extends CanvasRenderingContext2D> implements Node<C> {\n #children: Node<C>[];\n\n /**\n * @param children Initial child nodes, in layout order.\n */\n constructor(children: Node<C>[]) {\n this.#children = [...children];\n replaceNodesParent([], this.#children, this);\n }\n\n /** Child nodes managed by this group. */\n get children(): readonly Node<C>[] {\n return this.#children;\n }\n\n /**\n * Replaces the full child list while updating parent links.\n */\n replaceChildren(nextChildren: Node<C>[]): void {\n const nextSnapshot = [...nextChildren];\n replaceNodesParent(this.#children, nextSnapshot, this);\n this.#children = nextSnapshot;\n }\n\n abstract measure(ctx: Context<C>): Box;\n abstract draw(ctx: Context<C>, x: number, y: number): boolean;\n abstract hittest(ctx: Context<C>, test: HitTest): boolean;\n}\n\n/**\n * A node that forwards layout and drawing to a single inner node.\n */\nexport class Wrapper<C extends CanvasRenderingContext2D> implements Node<C> {\n #inner: Node<C>;\n\n /**\n * @param inner Wrapped child node.\n */\n constructor(inner: Node<C>) {\n this.#inner = inner;\n attachNodeToParent(this.#inner, this);\n }\n\n /** The wrapped child node. */\n get inner(): Node<C> {\n return this.#inner;\n }\n\n /** Replaces the wrapped child node. */\n set inner(newNode: Node<C>) {\n if (newNode === this.#inner) {\n return;\n }\n replaceNodeParent(this.#inner, newNode, this);\n this.#inner = newNode;\n }\n\n measure(ctx: Context<C>): Box {\n return this.inner.measure(ctx);\n }\n\n measureMinContent(ctx: Context<C>): Box {\n return measureNodeMinContent(ctx, this.inner);\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return this.inner.draw(ctx, x, y);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n return this.inner.hittest(ctx, test);\n }\n}\n","import type { Box, ChildLayoutResult, FlexLayoutResult, LayoutConstraints, LayoutRect } from \"./types\";\n\n/**\n * 创建 LayoutRect 的辅助函数\n */\nexport function createRect(x: number, y: number, width: number, height: number): LayoutRect {\n return { x, y, width, height };\n}\n\n/**\n * 合并多个 rect 得到包含所有 rect 的最小外接矩形\n */\nexport function mergeRects(rects: LayoutRect[]): LayoutRect {\n if (rects.length === 0) {\n return createRect(0, 0, 0, 0);\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const rect of rects) {\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.width);\n maxY = Math.max(maxY, rect.y + rect.height);\n }\n\n return createRect(minX, minY, maxX - minX, maxY - minY);\n}\n\n/**\n * 从子节点布局结果计算容器的 contentBox\n */\nexport function computeContentBox<C extends CanvasRenderingContext2D>(\n children: ChildLayoutResult<C>[],\n): LayoutRect {\n return mergeRects(children.map((child) => child.contentBox));\n}\n\n/**\n * 根据约束和实际内容计算最终的 containerBox\n */\nexport function computeContainerBox(\n contentBox: LayoutRect,\n constraints?: LayoutConstraints,\n): LayoutRect {\n let width = contentBox.width;\n let height = contentBox.height;\n\n if (constraints?.minWidth != null) {\n width = Math.max(width, constraints.minWidth);\n }\n if (constraints?.maxWidth != null) {\n width = Math.min(width, constraints.maxWidth);\n }\n if (constraints?.minHeight != null) {\n height = Math.max(height, constraints.minHeight);\n }\n if (constraints?.maxHeight != null) {\n height = Math.min(height, constraints.maxHeight);\n }\n\n return createRect(contentBox.x, contentBox.y, width, height);\n}\n\n/**\n * 将 Box 转换为 LayoutRect(位置为 0,0)\n */\nexport function boxToRect(box: Box): LayoutRect {\n return createRect(0, 0, box.width, box.height);\n}\n\n/**\n * 检查点是否在 rect 内\n */\nexport function pointInRect(x: number, y: number, rect: LayoutRect): boolean {\n return x >= rect.x && x < rect.x + rect.width && y >= rect.y && y < rect.y + rect.height;\n}\n\n/**\n * 平移 rect 的位置\n */\nexport function offsetRect(rect: LayoutRect, dx: number, dy: number): LayoutRect {\n return createRect(rect.x + dx, rect.y + dy, rect.width, rect.height);\n}\n\n/**\n * 读取单子节点布局结果中的唯一 child。\n */\nexport function getSingleChildLayout<C extends CanvasRenderingContext2D>(\n layout: FlexLayoutResult<C>,\n): ChildLayoutResult<C> | undefined {\n return layout.children[0];\n}\n\n/**\n * 在布局结果中按指定盒模型查找命中的 child,并返回局部坐标。\n */\nexport function findChildAtPoint<C extends CanvasRenderingContext2D>(\n children: ChildLayoutResult<C>[],\n x: number,\n y: number,\n box: \"rect\" | \"contentBox\" = \"contentBox\",\n):\n | {\n child: ChildLayoutResult<C>;\n localX: number;\n localY: number;\n }\n | undefined {\n for (let i = children.length - 1; i >= 0; i -= 1) {\n const child = children[i]!;\n const target = box === \"rect\" ? child.rect : child.contentBox;\n if (!pointInRect(x, y, target)) {\n continue;\n }\n return {\n child,\n localX: x - target.x,\n localY: y - target.y,\n };\n }\n return undefined;\n}\n","import { findChildAtPoint } from \"../layout\";\nimport type { Context, FlexLayoutResult, HitTest, LayoutConstraints, Node } from \"../types\";\nimport { shallow } from \"../utils\";\n\ntype LayoutCacheAccess<C extends CanvasRenderingContext2D> = {\n getLayoutResult(node: Node<C>, constraints?: LayoutConstraints): FlexLayoutResult<C> | undefined;\n setLayoutResult(node: Node<C>, result: FlexLayoutResult<C>, constraints?: LayoutConstraints): void;\n};\n\ntype LayoutContext<C extends CanvasRenderingContext2D> = Context<C> & LayoutCacheAccess<C>;\n\nexport function withConstraints<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n constraints: LayoutConstraints | undefined,\n): Context<C> {\n const next = shallow(ctx);\n next.constraints = constraints;\n return next;\n}\n\nfunction getLayoutContext<C extends CanvasRenderingContext2D>(ctx: Context<C>): LayoutContext<C> {\n return ctx as LayoutContext<C>;\n}\n\nexport function readLayoutResult<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n): FlexLayoutResult<C> | undefined {\n return getLayoutContext(ctx).getLayoutResult(node, ctx.constraints);\n}\n\nexport function writeLayoutResult<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n result: FlexLayoutResult<C>,\n): void {\n getLayoutContext(ctx).setLayoutResult(node, result, ctx.constraints);\n}\n\nfunction ensureLayoutResult<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n): FlexLayoutResult<C> | undefined {\n return readLayoutResult(node, ctx);\n}\n\nexport function drawLayoutChildren<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n x: number,\n y: number,\n): boolean {\n const layoutResult = ensureLayoutResult(node, ctx);\n if (!layoutResult) {\n return false;\n }\n\n let result = false;\n for (const childResult of layoutResult.children) {\n const childDrawn = childResult.node.draw(\n withConstraints(ctx, childResult.constraints),\n x + childResult.contentBox.x,\n y + childResult.contentBox.y,\n );\n result = childDrawn || result;\n }\n return result;\n}\n\nexport function hittestLayoutChildren<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n test: HitTest,\n box: \"rect\" | \"contentBox\" = \"contentBox\",\n): boolean {\n const layoutResult = ensureLayoutResult(node, ctx);\n if (!layoutResult) {\n return false;\n }\n\n const hit = findChildAtPoint(layoutResult.children, test.x, test.y, box);\n if (!hit) {\n return false;\n }\n\n return hit.child.node.hittest(\n withConstraints(ctx, hit.child.constraints),\n {\n ...test,\n x: hit.localX,\n y: hit.localY,\n },\n );\n}\n","import { createRect, findChildAtPoint, getSingleChildLayout } from \"../layout\";\nimport type { Box, Context, HitTest, Node } from \"../types\";\nimport { measureNodeMinContent } from \"./base\";\nimport { Wrapper } from \"./base\";\nimport { readLayoutResult, withConstraints, writeLayoutResult } from \"./shared\";\n\nfunction clampToConstraints(value: number, min?: number, max?: number): number {\n let result = value;\n if (min != null) {\n result = Math.max(result, min);\n }\n if (max != null) {\n result = Math.min(result, max);\n }\n return result;\n}\n\nfunction shrinkConstraint(value: number | undefined, padding: number): number | undefined {\n if (value == null) {\n return undefined;\n }\n return Math.max(0, value - padding);\n}\n\n/**\n * Adds padding around a single child node.\n */\nexport class PaddingBox<C extends CanvasRenderingContext2D> extends Wrapper<C> {\n /**\n * @param inner Wrapped child node.\n * @param padding Padding in CSS pixels on each side.\n */\n constructor(\n inner: Node<C>,\n readonly padding: {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n } = {},\n ) {\n super(inner);\n }\n\n get #top(): number {\n return this.padding.top ?? 0;\n }\n\n get #bottom(): number {\n return this.padding.bottom ?? 0;\n }\n\n get #left(): number {\n return this.padding.left ?? 0;\n }\n\n get #right(): number {\n return this.padding.right ?? 0;\n }\n\n measure(ctx: Context<C>): Box {\n const paddingLeft = this.#left;\n const paddingRight = this.#right;\n const paddingTop = this.#top;\n const paddingBottom = this.#bottom;\n const horizontalPadding = paddingLeft + paddingRight;\n const verticalPadding = paddingTop + paddingBottom;\n const childConstraints = ctx.constraints\n ? {\n ...ctx.constraints,\n minWidth: shrinkConstraint(ctx.constraints.minWidth, horizontalPadding),\n maxWidth: shrinkConstraint(ctx.constraints.maxWidth, horizontalPadding),\n minHeight: shrinkConstraint(ctx.constraints.minHeight, verticalPadding),\n maxHeight: shrinkConstraint(ctx.constraints.maxHeight, verticalPadding),\n }\n : undefined;\n const { width, height } = ctx.measureNode(this.inner, childConstraints);\n const containerBox = createRect(\n 0,\n 0,\n clampToConstraints(width + horizontalPadding, ctx.constraints?.minWidth, ctx.constraints?.maxWidth),\n clampToConstraints(height + verticalPadding, ctx.constraints?.minHeight, ctx.constraints?.maxHeight),\n );\n const childRect = createRect(paddingLeft, paddingTop, width, height);\n writeLayoutResult(this, ctx, {\n containerBox,\n contentBox: childRect,\n children: [\n {\n node: this.inner,\n rect: childRect,\n contentBox: childRect,\n constraints: childConstraints,\n },\n ],\n constraints: ctx.constraints,\n });\n return {\n width: containerBox.width,\n height: containerBox.height,\n };\n }\n\n measureMinContent(ctx: Context<C>): Box {\n const paddingLeft = this.#left;\n const paddingRight = this.#right;\n const paddingTop = this.#top;\n const paddingBottom = this.#bottom;\n const horizontalPadding = paddingLeft + paddingRight;\n const verticalPadding = paddingTop + paddingBottom;\n const childConstraints = ctx.constraints\n ? {\n ...ctx.constraints,\n minWidth: shrinkConstraint(ctx.constraints.minWidth, horizontalPadding),\n maxWidth: shrinkConstraint(ctx.constraints.maxWidth, horizontalPadding),\n minHeight: shrinkConstraint(ctx.constraints.minHeight, verticalPadding),\n maxHeight: shrinkConstraint(ctx.constraints.maxHeight, verticalPadding),\n }\n : undefined;\n const { width, height } = measureNodeMinContent(ctx, this.inner, childConstraints);\n return {\n width: width + horizontalPadding,\n height: height + verticalPadding,\n };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n const layoutResult = readLayoutResult(this, ctx);\n if (!layoutResult) {\n return this.inner.draw(ctx, x + this.#left, y + this.#top);\n }\n\n const childResult = getSingleChildLayout(layoutResult);\n if (!childResult) {\n return false;\n }\n\n return childResult.node.draw(\n withConstraints(ctx, childResult.constraints),\n x + childResult.rect.x,\n y + childResult.rect.y,\n );\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n const layoutResult = readLayoutResult(this, ctx);\n if (!layoutResult) {\n return false;\n }\n\n const hit = findChildAtPoint(layoutResult.children, test.x, test.y, \"rect\");\n if (!hit) {\n return false;\n }\n\n return hit.child.node.hittest(\n withConstraints(ctx, hit.child.constraints),\n {\n ...test,\n x: hit.localX,\n y: hit.localY,\n },\n );\n }\n}\n\n/**\n * A leaf node with a fixed size and no drawing behavior.\n */\nexport class Fixed<C extends CanvasRenderingContext2D> implements Node<C> {\n /**\n * @param width Fixed width in CSS pixels.\n * @param height Fixed height in CSS pixels.\n */\n constructor(\n readonly width: number,\n readonly height: number,\n ) {}\n\n measure(_ctx: Context<C>): Box {\n return { width: this.width, height: this.height };\n }\n\n measureMinContent(_ctx: Context<C>): Box {\n return { width: this.width, height: this.height };\n }\n\n draw(_ctx: Context<C>, _x: number, _y: number): boolean {\n return false;\n }\n\n hittest(_ctx: Context<C>, _test: HitTest): boolean {\n return false;\n }\n}\n","import { computeContentBox, createRect } from \"../layout\";\nimport type {\n Axis,\n Box,\n ChildLayoutResult,\n Context,\n CrossAxisAlignment,\n FlexContainerOptions,\n FlexItemOptions,\n HitTest,\n LayoutConstraints,\n Node,\n} from \"../types\";\nimport { Group, measureNodeMinContent, Wrapper } from \"./base\";\nimport { drawLayoutChildren, hittestLayoutChildren, writeLayoutResult } from \"./shared\";\n\nfunction getMainSize(axis: Axis, box: Box): number {\n return axis === \"row\" ? box.width : box.height;\n}\n\nfunction getCrossSize(axis: Axis, box: Box): number {\n return axis === \"row\" ? box.height : box.width;\n}\n\nfunction getMinMain(axis: Axis, constraints?: LayoutConstraints): number | undefined {\n return axis === \"row\" ? constraints?.minWidth : constraints?.minHeight;\n}\n\nfunction getMaxMain(axis: Axis, constraints?: LayoutConstraints): number | undefined {\n return axis === \"row\" ? constraints?.maxWidth : constraints?.maxHeight;\n}\n\nfunction getMinCross(axis: Axis, constraints?: LayoutConstraints): number | undefined {\n return axis === \"row\" ? constraints?.minHeight : constraints?.minWidth;\n}\n\nfunction getMaxCross(axis: Axis, constraints?: LayoutConstraints): number | undefined {\n return axis === \"row\" ? constraints?.maxHeight : constraints?.maxWidth;\n}\n\nfunction createAxisConstraints(\n axis: Axis,\n constraints: LayoutConstraints | undefined,\n main: { min?: number; max?: number },\n cross: { min?: number; max?: number } = {},\n): LayoutConstraints | undefined {\n if (\n constraints == null &&\n main.min == null &&\n main.max == null &&\n cross.min == null &&\n cross.max == null\n ) {\n return undefined;\n }\n\n const next: LayoutConstraints = {\n ...constraints,\n };\n if (axis === \"row\") {\n next.minWidth = main.min;\n next.maxWidth = main.max;\n next.minHeight = cross.min;\n next.maxHeight = cross.max;\n } else {\n next.minHeight = main.min;\n next.maxHeight = main.max;\n next.minWidth = cross.min;\n next.maxWidth = cross.max;\n }\n return next;\n}\n\nfunction clampToConstraints(value: number, min?: number, max?: number): number {\n let result = value;\n if (min != null) {\n result = Math.max(result, min);\n }\n if (max != null) {\n result = Math.min(result, max);\n }\n return result;\n}\n\nfunction constraintsEqual(left: LayoutConstraints | undefined, right: LayoutConstraints | undefined): boolean {\n if (left === right) {\n return true;\n }\n if (left == null || right == null) {\n return left == null && right == null;\n }\n return left.minWidth === right.minWidth\n && left.maxWidth === right.maxWidth\n && left.minHeight === right.minHeight\n && left.maxHeight === right.maxHeight;\n}\n\nfunction getCrossAlignment(alignSelf: CrossAxisAlignment | \"auto\" | undefined, alignItems: CrossAxisAlignment): CrossAxisAlignment {\n if (alignSelf == null || alignSelf === \"auto\") {\n return alignItems;\n }\n return alignSelf;\n}\n\nfunction getJustifySpacing(\n justifyContent: NonNullable<FlexContainerOptions[\"justifyContent\"]>,\n freeSpace: number,\n itemCount: number,\n gap: number,\n): { leading: number; between: number } {\n switch (justifyContent) {\n case \"center\":\n return { leading: freeSpace / 2, between: gap };\n case \"end\":\n return { leading: freeSpace, between: gap };\n case \"space-between\":\n return {\n leading: 0,\n between: itemCount > 1 ? gap + freeSpace / (itemCount - 1) : gap,\n };\n case \"space-around\":\n return {\n leading: itemCount > 0 ? freeSpace / itemCount / 2 : 0,\n between: itemCount > 0 ? gap + freeSpace / itemCount : gap,\n };\n case \"space-evenly\":\n return {\n leading: itemCount > 0 ? freeSpace / (itemCount + 1) : 0,\n between: itemCount > 0 ? gap + freeSpace / (itemCount + 1) : gap,\n };\n case \"start\":\n default:\n return { leading: 0, between: gap };\n }\n}\n\nfunction getCrossOffset(align: CrossAxisAlignment, frameCross: number, contentCross: number): number {\n switch (align) {\n case \"center\":\n return (frameCross - contentCross) / 2;\n case \"end\":\n return frameCross - contentCross;\n case \"stretch\":\n case \"start\":\n default:\n return 0;\n }\n}\n\nfunction createRectFromAxis(axis: Axis, main: number, cross: number, mainSize: number, crossSize: number) {\n return axis === \"row\"\n ? createRect(main, cross, mainSize, crossSize)\n : createRect(cross, main, crossSize, mainSize);\n}\n\nconst SHRINK_EPSILON = 1e-6;\n\ntype FlexMeasurement<C extends CanvasRenderingContext2D> = {\n child: Node<C>;\n item: FlexItemOptions;\n basisMeasured: Box;\n measured: Box;\n basisConstraints?: LayoutConstraints;\n initialConstraints?: LayoutConstraints;\n finalConstraints?: LayoutConstraints;\n allocatedMain?: number;\n grow: number;\n shrink: number;\n effectiveAlign: CrossAxisAlignment;\n stretch: boolean;\n basis: number;\n minContentMain: number;\n finalMain: number;\n frozen: boolean;\n frameMain: number;\n frameCross: number;\n};\n\ntype MeasuredLayout<C extends CanvasRenderingContext2D> = {\n box: Box;\n layout: {\n containerBox: ChildLayoutResult<C>[\"rect\"];\n contentBox: ChildLayoutResult<C>[\"contentBox\"];\n children: ChildLayoutResult<C>[];\n constraints?: LayoutConstraints;\n };\n};\n\nfunction readFlexItemOptions<C extends CanvasRenderingContext2D>(child: Node<C>): FlexItemOptions {\n if (child instanceof FlexItem) {\n return child.item;\n }\n return {};\n}\n\nexport function computeFlexLayout<C extends CanvasRenderingContext2D>(\n children: readonly Node<C>[],\n options: FlexContainerOptions,\n constraints: LayoutConstraints | undefined,\n measureChild: (node: Node<C>, constraints?: LayoutConstraints) => Box,\n measureChildMinContent: (node: Node<C>, constraints?: LayoutConstraints) => Box,\n): MeasuredLayout<C> {\n const axis = options.direction ?? \"row\";\n const gap = options.gap ?? 0;\n const justifyContent = options.justifyContent ?? \"start\";\n const alignItems = options.alignItems ?? \"start\";\n const reverse = options.reverse ?? false;\n const mainAxisSize = options.mainAxisSize ?? \"fill\";\n const orderedChildren = reverse ? [...children].reverse() : children;\n const maxMain = getMaxMain(axis, constraints);\n const minMain = getMinMain(axis, constraints);\n const maxCross = getMaxCross(axis, constraints);\n const minCross = getMinCross(axis, constraints);\n const gapTotal = orderedChildren.length > 1 ? gap * (orderedChildren.length - 1) : 0;\n const finiteMain = maxMain != null;\n const finiteCross = maxCross != null;\n const availableMain = finiteMain ? Math.max(0, maxMain - gapTotal) : undefined;\n let totalGrow = 0;\n let totalBasis = 0;\n let nonGrowBasis = 0;\n const measurements = new Map<Node<C>, FlexMeasurement<C>>();\n const basisConstraints = createAxisConstraints(\n axis,\n constraints,\n {\n min: undefined,\n max: undefined,\n },\n {\n min: undefined,\n max: maxCross,\n },\n );\n\n for (const child of orderedChildren) {\n const item = readFlexItemOptions(child);\n const grow = item.grow ?? 0;\n const shrink = item.shrink ?? 0;\n totalGrow += grow;\n const effectiveAlign = getCrossAlignment(item.alignSelf, alignItems);\n const stretch = effectiveAlign === \"stretch\";\n const basisMeasured = measureChild(child, basisConstraints);\n const basis = getMainSize(axis, basisMeasured);\n\n totalBasis += basis;\n if (grow <= 0) {\n nonGrowBasis += basis;\n }\n\n measurements.set(child, {\n child,\n item,\n basisMeasured,\n measured: basisMeasured,\n basisConstraints,\n initialConstraints: basisConstraints,\n finalConstraints: basisConstraints,\n allocatedMain: undefined,\n grow,\n shrink,\n effectiveAlign,\n stretch,\n basis,\n minContentMain: basis,\n finalMain: basis,\n frozen: false,\n frameMain: basis,\n frameCross: getCrossSize(axis, basisMeasured),\n });\n }\n\n const entersShrinkPath = finiteMain && availableMain != null && totalBasis - availableMain > SHRINK_EPSILON;\n\n if (entersShrinkPath) {\n const totalDeficit = totalBasis - availableMain!;\n let remainingDeficit = totalDeficit;\n\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n const minContentMeasured = measureChildMinContent(child, measurement.basisConstraints);\n measurement.minContentMain = Math.min(measurement.basis, getMainSize(axis, minContentMeasured));\n measurement.finalMain = measurement.basis;\n measurement.frozen = measurement.shrink <= 0 || measurement.basis - measurement.minContentMain <= SHRINK_EPSILON;\n }\n\n while (remainingDeficit > SHRINK_EPSILON) {\n const active = orderedChildren\n .map((child) => measurements.get(child)!)\n .filter((measurement) => !measurement.frozen && measurement.shrink > 0);\n const totalScaled = active.reduce((sum, measurement) => sum + measurement.shrink * measurement.basis, 0);\n\n if (active.length === 0 || totalScaled <= SHRINK_EPSILON) {\n break;\n }\n\n let frozeAny = false;\n for (const measurement of active) {\n const tentative = measurement.basis - remainingDeficit * ((measurement.shrink * measurement.basis) / totalScaled);\n if (tentative <= measurement.minContentMain + SHRINK_EPSILON) {\n measurement.finalMain = measurement.minContentMain;\n measurement.frozen = true;\n frozeAny = true;\n } else {\n measurement.finalMain = tentative;\n }\n }\n\n if (!frozeAny) {\n remainingDeficit = 0;\n break;\n }\n\n let absorbedDeficit = 0;\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n if (measurement.frozen) {\n absorbedDeficit += Math.max(0, measurement.basis - measurement.finalMain);\n }\n }\n remainingDeficit = Math.max(0, totalDeficit - absorbedDeficit);\n }\n\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n measurement.measured = measurement.basisMeasured;\n measurement.initialConstraints = measurement.basisConstraints;\n measurement.finalConstraints = createAxisConstraints(\n axis,\n constraints,\n {\n min: undefined,\n max: measurement.finalMain,\n },\n {\n min: undefined,\n max: maxCross,\n },\n );\n measurement.allocatedMain = undefined;\n measurement.frameMain = measurement.finalMain;\n measurement.frameCross = getCrossSize(axis, measurement.measured);\n }\n } else {\n const remainingMain = finiteMain && availableMain != null ? Math.max(0, availableMain - nonGrowBasis) : undefined;\n\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n if (!(measurement.grow > 0 && finiteMain && remainingMain != null && totalGrow > 0)) {\n measurement.measured = measurement.basisMeasured;\n measurement.initialConstraints = measurement.basisConstraints;\n measurement.finalConstraints = finiteMain\n ? createAxisConstraints(\n axis,\n constraints,\n {\n min: undefined,\n max: measurement.finalMain,\n },\n {\n min: undefined,\n max: maxCross,\n },\n )\n : measurement.basisConstraints;\n measurement.allocatedMain = undefined;\n measurement.finalMain = measurement.basis;\n measurement.frameMain = measurement.basis;\n measurement.frameCross = getCrossSize(axis, measurement.measured);\n continue;\n }\n\n const allocatedMain = (remainingMain * measurement.grow) / totalGrow;\n const childConstraints = createAxisConstraints(\n axis,\n constraints,\n {\n max: allocatedMain,\n },\n {\n min: undefined,\n max: maxCross,\n },\n );\n const measured = measureChild(child, childConstraints);\n measurement.measured = measured;\n measurement.initialConstraints = childConstraints;\n measurement.finalConstraints = childConstraints;\n measurement.allocatedMain = allocatedMain;\n measurement.finalMain = allocatedMain;\n measurement.frameMain = allocatedMain;\n measurement.frameCross = getCrossSize(axis, measured);\n }\n }\n\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n if (!constraintsEqual(measurement.initialConstraints, measurement.finalConstraints)) {\n measurement.measured = measureChild(child, measurement.finalConstraints);\n }\n measurement.frameMain = measurement.finalMain;\n measurement.frameCross = getCrossSize(axis, measurement.measured);\n }\n\n let contentMain = gapTotal;\n let contentCross = 0;\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n contentMain += measurement.frameMain;\n contentCross = Math.max(contentCross, measurement.frameCross);\n }\n\n const containerMain = finiteMain && mainAxisSize === \"fill\"\n ? Math.max(maxMain!, contentMain)\n : clampToConstraints(contentMain, minMain, maxMain);\n const containerCross = clampToConstraints(contentCross, minCross, maxCross);\n if (finiteCross) {\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n if (!measurement.stretch) {\n continue;\n }\n\n const finalConstraints = createAxisConstraints(\n axis,\n measurement.finalConstraints,\n {\n min: getMinMain(axis, measurement.finalConstraints),\n max: getMaxMain(axis, measurement.finalConstraints),\n },\n {\n min: containerCross,\n max: containerCross,\n },\n );\n const remeasured = measureChild(child, finalConstraints);\n measurement.measured = remeasured;\n measurement.finalConstraints = finalConstraints;\n measurement.frameCross = containerCross;\n measurement.frameMain = measurement.allocatedMain ?? getMainSize(axis, remeasured);\n }\n\n contentMain = gapTotal;\n contentCross = 0;\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n contentMain += measurement.frameMain;\n contentCross = Math.max(contentCross, getCrossSize(axis, measurement.measured));\n }\n }\n\n const finalContainerMain = finiteMain && mainAxisSize === \"fill\"\n ? Math.max(maxMain!, contentMain)\n : clampToConstraints(contentMain, minMain, maxMain);\n const freeSpace = Math.max(0, finalContainerMain - contentMain);\n const spacing = getJustifySpacing(justifyContent, freeSpace, orderedChildren.length, gap);\n const childResults: ChildLayoutResult<C>[] = [];\n let cursor = spacing.leading;\n\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n const frameCross = measurement.stretch && finiteCross ? containerCross : measurement.frameCross;\n const contentMainSize = getMainSize(axis, measurement.measured);\n const contentCrossSize = getCrossSize(axis, measurement.measured);\n const rectCross = measurement.stretch ? 0 : getCrossOffset(measurement.effectiveAlign, containerCross, frameCross);\n const contentCrossOffset = rectCross + getCrossOffset(measurement.effectiveAlign, frameCross, contentCrossSize);\n const rect = createRectFromAxis(axis, cursor, rectCross, measurement.frameMain, frameCross);\n const contentBox = createRectFromAxis(axis, cursor, contentCrossOffset, contentMainSize, contentCrossSize);\n\n childResults.push({\n node: child,\n rect,\n contentBox,\n constraints: measurement.finalConstraints,\n });\n cursor += measurement.frameMain + spacing.between;\n }\n\n const containerBox = axis === \"row\"\n ? createRect(0, 0, finalContainerMain, containerCross)\n : createRect(0, 0, containerCross, finalContainerMain);\n const finalContentBox = childResults.length > 0\n ? computeContentBox(childResults)\n : createRect(0, 0, 0, 0);\n\n return {\n box: {\n width: containerBox.width,\n height: containerBox.height,\n },\n layout: {\n containerBox,\n contentBox: finalContentBox,\n children: childResults,\n constraints,\n },\n };\n}\n\n/**\n * Wraps a child node with per-item flex options.\n */\nexport class FlexItem<C extends CanvasRenderingContext2D> extends Wrapper<C> {\n /**\n * @param inner Wrapped child node.\n * @param item Flex behavior overrides for the child.\n */\n constructor(\n inner: Node<C>,\n readonly item: FlexItemOptions = {},\n ) {\n super(inner);\n }\n}\n\n/**\n * Lays out children in a single flex row or column.\n */\nexport class Flex<C extends CanvasRenderingContext2D> extends Group<C> {\n /**\n * @param children Child nodes in visual order.\n * @param options Flex container configuration.\n */\n constructor(\n children: Node<C>[],\n readonly options: FlexContainerOptions = {},\n ) {\n super(children);\n }\n\n measure(ctx: Context<C>): Box {\n const result = computeFlexLayout(\n this.children,\n this.options,\n ctx.constraints,\n (node, constraints) => ctx.measureNode(node, constraints),\n (node, constraints) => measureNodeMinContent(ctx, node, constraints),\n );\n writeLayoutResult(this, ctx, result.layout);\n return result.box;\n }\n\n measureMinContent(ctx: Context<C>): Box {\n const axis = this.options.direction ?? \"row\";\n const gap = this.options.gap ?? 0;\n const orderedChildren = this.options.reverse ? [...this.children].reverse() : this.children;\n const gapTotal = orderedChildren.length > 1 ? gap * (orderedChildren.length - 1) : 0;\n const childConstraints = createAxisConstraints(\n axis,\n ctx.constraints,\n {\n min: undefined,\n max: undefined,\n },\n {\n min: undefined,\n max: getMaxCross(axis, ctx.constraints),\n },\n );\n\n let width = axis === \"row\" ? gapTotal : 0;\n let height = axis === \"column\" ? gapTotal : 0;\n\n for (const child of orderedChildren) {\n const measured = measureNodeMinContent(ctx, child, childConstraints);\n if (axis === \"row\") {\n width += measured.width;\n height = Math.max(height, measured.height);\n } else {\n width = Math.max(width, measured.width);\n height += measured.height;\n }\n }\n\n return { width, height };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return drawLayoutChildren(this, ctx, x, y);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n return hittestLayoutChildren(this, ctx, test, \"contentBox\");\n }\n}\n","import { createRect, findChildAtPoint, getSingleChildLayout } from \"../layout\";\nimport type { Box, Context, HitTest, Node, TextAlign } from \"../types\";\nimport { measureNodeMinContent, Wrapper } from \"./base\";\nimport { readLayoutResult, withConstraints, writeLayoutResult } from \"./shared\";\n\nfunction resolveHorizontalOffset(align: TextAlign, availableWidth: number, childWidth: number): number {\n switch (align) {\n case \"center\":\n return (availableWidth - childWidth) / 2;\n case \"end\":\n return availableWidth - childWidth;\n case \"start\":\n return 0;\n }\n}\n\n/**\n * Aligns a single child horizontally within the available width.\n */\nexport class Place<C extends CanvasRenderingContext2D> extends Wrapper<C> {\n /**\n * @param inner Wrapped child node.\n * @param options Alignment behavior for the child.\n */\n constructor(\n inner: Node<C>,\n readonly options: {\n align?: TextAlign;\n expand?: boolean;\n } = {},\n ) {\n super(inner);\n }\n\n measure(ctx: Context<C>): Box {\n const availableWidth = ctx.constraints?.maxWidth;\n const expand = this.options.expand ?? true;\n const childConstraints = ctx.constraints\n ? {\n ...ctx.constraints,\n }\n : undefined;\n const childBox = ctx.measureNode(this.inner, childConstraints);\n let width = expand && availableWidth != null ? availableWidth : childBox.width;\n if (ctx.constraints?.minWidth != null) {\n width = Math.max(width, ctx.constraints.minWidth);\n }\n if (ctx.constraints?.maxWidth != null) {\n width = Math.min(width, ctx.constraints.maxWidth);\n }\n\n const align = this.options.align ?? \"start\";\n const childRect = createRect(resolveHorizontalOffset(align, width, childBox.width), 0, childBox.width, childBox.height);\n\n writeLayoutResult(this, ctx, {\n containerBox: createRect(0, 0, width, childBox.height),\n contentBox: childRect,\n children: [\n {\n node: this.inner,\n rect: childRect,\n contentBox: createRect(0, 0, childBox.width, childBox.height),\n constraints: childConstraints,\n },\n ],\n constraints: ctx.constraints,\n });\n\n return {\n width,\n height: childBox.height,\n };\n }\n\n measureMinContent(ctx: Context<C>): Box {\n return measureNodeMinContent(ctx, this.inner);\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n const layoutResult = readLayoutResult(this, ctx);\n if (!layoutResult) {\n return this.inner.draw(ctx, x, y);\n }\n\n const childResult = getSingleChildLayout(layoutResult);\n if (!childResult) {\n return false;\n }\n const childCtx = withConstraints(ctx, childResult.constraints);\n return childResult.node.draw(childCtx, x + childResult.rect.x, y + childResult.rect.y);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n const layoutResult = readLayoutResult(this, ctx);\n if (!layoutResult) {\n return false;\n }\n\n const hit = findChildAtPoint(layoutResult.children, test.x, test.y, \"rect\");\n if (!hit) {\n return false;\n }\n\n return hit.child.node.hittest(\n withConstraints(ctx, hit.child.constraints),\n {\n ...test,\n x: hit.localX,\n y: hit.localY,\n },\n );\n }\n}\n","import {\n layoutNextLine,\n layoutWithLines,\n prepareWithSegments,\n walkLineRanges,\n type PreparedTextWithSegments,\n} from \"@chenglou/pretext\";\nimport type {\n Context,\n TextEllipsisPosition,\n TextOverflowMode,\n TextOverflowWrapMode,\n TextWhitespaceMode,\n} from \"./types\";\n\nexport interface TextLayout {\n width: number;\n text: string;\n shift: number;\n}\n\nexport interface TextMeasurement {\n width: number;\n lineCount: number;\n}\n\nexport interface OverflowTextLayout extends TextLayout {\n overflowed: boolean;\n}\n\nexport interface OverflowTextBlockLayout {\n width: number;\n lines: OverflowTextLayout[];\n overflowed: boolean;\n}\n\n// `fontBoundingBox*` depends on the active font, so one fixed probe is enough.\nconst FONT_SHIFT_PROBE = \"M\";\nconst ELLIPSIS_GLYPH = \"…\";\nconst PREPARED_SEGMENT_CACHE_CAPACITY = 512;\nconst FONT_SHIFT_CACHE_CAPACITY = 64;\nconst ELLIPSIS_WIDTH_CACHE_CAPACITY = 64;\nconst LINE_START_CURSOR = { segmentIndex: 0, graphemeIndex: 0 } as const;\nconst MIN_CONTENT_WIDTH_EPSILON = 0.001;\n\nconst preparedSegmentCache = new Map<string, PreparedTextWithSegments>();\nconst fontShiftCache = new Map<string, number>();\nconst ellipsisWidthCache = new Map<string, number>();\nconst preparedUnitCache = new WeakMap<PreparedTextWithSegments, PreparedTextUnit[]>();\n\ntype PreparedTextUnit = {\n text: string;\n width: number;\n};\n\nlet sharedGraphemeSegmenter: Intl.Segmenter | null | undefined;\n\nfunction preprocessSegments(text: string, whitespace: TextWhitespaceMode = \"preserve\"): string[] {\n const segments = text.split(\"\\n\");\n if (whitespace === \"trim-and-collapse\") {\n return segments\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n }\n return segments;\n}\n\nfunction readLruValue<T>(cache: Map<string, T>, key: string): T | undefined {\n const cached = cache.get(key);\n if (cached == null) {\n return undefined;\n }\n cache.delete(key);\n cache.set(key, cached);\n return cached;\n}\n\nfunction writeLruValue<T>(cache: Map<string, T>, key: string, value: T, capacity: number): T {\n if (cache.has(key)) {\n cache.delete(key);\n } else if (cache.size >= capacity) {\n const firstKey = cache.keys().next().value;\n if (firstKey != null) {\n cache.delete(firstKey);\n }\n }\n cache.set(key, value);\n return value;\n}\n\nfunction getPreparedSegmentCacheKey(segment: string, font: string): string {\n return `${font}\\u0000${segment}`;\n}\n\nfunction readPreparedSegment(segment: string, font: string): PreparedTextWithSegments {\n const key = getPreparedSegmentCacheKey(segment, font);\n const cached = readLruValue(preparedSegmentCache, key);\n if (cached != null) {\n return cached;\n }\n return writeLruValue(preparedSegmentCache, key, prepareWithSegments(segment, font), PREPARED_SEGMENT_CACHE_CAPACITY);\n}\n\nfunction measureFontShift<C extends CanvasRenderingContext2D>(ctx: Context<C>): number {\n const font = ctx.graphics.font;\n const cached = readLruValue(fontShiftCache, font);\n if (cached != null) {\n return cached;\n }\n const {\n fontBoundingBoxAscent: ascent = 0,\n fontBoundingBoxDescent: descent = 0,\n } = ctx.graphics.measureText(FONT_SHIFT_PROBE);\n return writeLruValue(fontShiftCache, font, ascent - descent, FONT_SHIFT_CACHE_CAPACITY);\n}\n\nfunction measurePreparedMinContentWidth(\n prepared: PreparedTextWithSegments,\n overflowWrap: TextOverflowWrapMode = \"break-word\",\n): number {\n let maxWidth = 0;\n let maxAnyWidth = 0;\n for (let i = 0; i < prepared.widths.length; i += 1) {\n const segmentWidth = prepared.widths[i] ?? 0;\n maxAnyWidth = Math.max(maxAnyWidth, segmentWidth);\n const segment = prepared.segments[i];\n if (segment != null && segment.trim().length > 0) {\n const breakableWidths = prepared.breakableWidths[i];\n const minContentWidth = overflowWrap === \"anywhere\" && breakableWidths != null && breakableWidths.length > 0\n ? breakableWidths.reduce((widest, width) => Math.max(widest, width), 0)\n : segmentWidth;\n maxWidth = Math.max(maxWidth, minContentWidth);\n }\n }\n return maxWidth > 0 ? maxWidth : maxAnyWidth;\n}\n\nfunction measurePreparedWidth(prepared: PreparedTextWithSegments): number {\n let width = 0;\n for (const segmentWidth of prepared.widths) {\n width += segmentWidth ?? 0;\n }\n return width;\n}\n\nfunction getGraphemeSegmenter(): Intl.Segmenter | null {\n if (sharedGraphemeSegmenter !== undefined) {\n return sharedGraphemeSegmenter;\n }\n sharedGraphemeSegmenter = typeof Intl.Segmenter === \"function\"\n ? new Intl.Segmenter(undefined, { granularity: \"grapheme\" })\n : null;\n return sharedGraphemeSegmenter;\n}\n\nfunction splitGraphemes(text: string): string[] {\n const segmenter = getGraphemeSegmenter();\n if (segmenter == null) {\n return Array.from(text);\n }\n const graphemes: string[] = [];\n for (const part of segmenter.segment(text)) {\n graphemes.push(part.segment);\n }\n return graphemes;\n}\n\nfunction getPreparedUnits(prepared: PreparedTextWithSegments): PreparedTextUnit[] {\n const cached = preparedUnitCache.get(prepared);\n if (cached != null) {\n return cached;\n }\n\n const units: PreparedTextUnit[] = [];\n for (let i = 0; i < prepared.segments.length; i += 1) {\n const segment = prepared.segments[i] ?? \"\";\n const segmentWidth = prepared.widths[i] ?? 0;\n const breakableWidths = prepared.breakableWidths[i];\n if (breakableWidths != null && segment.length > 0) {\n const graphemes = splitGraphemes(segment);\n if (graphemes.length === breakableWidths.length) {\n for (let j = 0; j < graphemes.length; j += 1) {\n units.push({ text: graphemes[j] ?? \"\", width: breakableWidths[j] ?? 0 });\n }\n continue;\n }\n }\n\n if (segment.length > 0 || segmentWidth > 0) {\n units.push({ text: segment, width: segmentWidth });\n }\n }\n\n preparedUnitCache.set(prepared, units);\n return units;\n}\n\nfunction buildUnitPrefixWidths(units: PreparedTextUnit[]): number[] {\n const widths = [0];\n let total = 0;\n for (const unit of units) {\n total += unit.width;\n widths.push(total);\n }\n return widths;\n}\n\nfunction buildUnitSuffixWidths(units: PreparedTextUnit[]): number[] {\n const widths = [0];\n let total = 0;\n for (let i = units.length - 1; i >= 0; i -= 1) {\n total += units[i]?.width ?? 0;\n widths.push(total);\n }\n return widths;\n}\n\nfunction findMaxFittingCount(cumulativeWidths: number[], maxWidth: number): number {\n if (maxWidth <= 0) {\n return 0;\n }\n let low = 0;\n let high = cumulativeWidths.length - 1;\n while (low < high) {\n const mid = Math.floor((low + high + 1) / 2);\n if ((cumulativeWidths[mid] ?? 0) <= maxWidth) {\n low = mid;\n } else {\n high = mid - 1;\n }\n }\n return low;\n}\n\nfunction joinUnitText(units: PreparedTextUnit[], start: number, end: number): string {\n if (start >= end) {\n return \"\";\n }\n return units.slice(start, end).map((unit) => unit.text).join(\"\");\n}\n\nfunction measureEllipsisWidth<C extends CanvasRenderingContext2D>(ctx: Context<C>): number {\n const font = ctx.graphics.font;\n const cached = readLruValue(ellipsisWidthCache, font);\n if (cached != null) {\n return cached;\n }\n return writeLruValue(\n ellipsisWidthCache,\n font,\n ctx.graphics.measureText(ELLIPSIS_GLYPH).width,\n ELLIPSIS_WIDTH_CACHE_CAPACITY,\n );\n}\n\nfunction createEllipsisOnlyLayout<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n maxWidth: number,\n shift: number,\n): OverflowTextLayout {\n const ellipsisWidth = measureEllipsisWidth(ctx);\n if (ellipsisWidth > maxWidth) {\n return { width: 0, text: \"\", shift, overflowed: true };\n }\n return { width: ellipsisWidth, text: ELLIPSIS_GLYPH, shift, overflowed: true };\n}\n\nfunction layoutPreparedEllipsis<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n prepared: PreparedTextWithSegments,\n text: string,\n maxWidth: number,\n shift: number,\n position: TextEllipsisPosition,\n forceEllipsis = false,\n): OverflowTextLayout {\n const intrinsicWidth = measurePreparedWidth(prepared);\n if (!forceEllipsis && intrinsicWidth <= maxWidth) {\n return { width: intrinsicWidth, text, shift, overflowed: false };\n }\n\n const ellipsisWidth = measureEllipsisWidth(ctx);\n if (ellipsisWidth > maxWidth) {\n return { width: 0, text: \"\", shift, overflowed: true };\n }\n\n const units = getPreparedUnits(prepared);\n if (units.length === 0) {\n return createEllipsisOnlyLayout(ctx, maxWidth, shift);\n }\n\n const availableWidth = Math.max(0, maxWidth - ellipsisWidth);\n const prefixWidths = buildUnitPrefixWidths(units);\n const suffixWidths = buildUnitSuffixWidths(units);\n\n let prefixCount = 0;\n let suffixCount = 0;\n switch (position) {\n case \"start\":\n suffixCount = Math.min(units.length, findMaxFittingCount(suffixWidths, availableWidth));\n break;\n case \"middle\": {\n let bestVisibleUnits = -1;\n let bestBalanceScore = Number.NEGATIVE_INFINITY;\n for (let nextPrefixCount = 0; nextPrefixCount <= units.length; nextPrefixCount += 1) {\n const prefixWidth = prefixWidths[nextPrefixCount] ?? 0;\n if (prefixWidth > availableWidth) {\n break;\n }\n const remainingWidth = availableWidth - prefixWidth;\n const maxSuffixCount = units.length - nextPrefixCount;\n const nextSuffixCount = Math.min(maxSuffixCount, findMaxFittingCount(suffixWidths, remainingWidth));\n const visibleUnits = nextPrefixCount + nextSuffixCount;\n const balanceScore = -Math.abs(nextPrefixCount - nextSuffixCount);\n if (\n visibleUnits > bestVisibleUnits ||\n (visibleUnits === bestVisibleUnits && balanceScore > bestBalanceScore) ||\n (visibleUnits === bestVisibleUnits && balanceScore === bestBalanceScore && nextPrefixCount > prefixCount)\n ) {\n prefixCount = nextPrefixCount;\n suffixCount = nextSuffixCount;\n bestVisibleUnits = visibleUnits;\n bestBalanceScore = balanceScore;\n }\n }\n break;\n }\n case \"end\":\n prefixCount = Math.min(units.length, findMaxFittingCount(prefixWidths, availableWidth));\n break;\n }\n\n const prefixWidth = prefixWidths[prefixCount] ?? 0;\n const suffixWidth = suffixWidths[suffixCount] ?? 0;\n const prefixText = joinUnitText(units, 0, prefixCount);\n const suffixText = joinUnitText(units, units.length - suffixCount, units.length);\n\n return {\n width: prefixWidth + ellipsisWidth + suffixWidth,\n text: `${prefixText}${ELLIPSIS_GLYPH}${suffixText}`,\n shift,\n overflowed: true,\n };\n}\n\nfunction normalizeMaxLines(maxLines: number | undefined): number | undefined {\n if (maxLines == null || !Number.isFinite(maxLines)) {\n return undefined;\n }\n return Math.max(1, Math.trunc(maxLines));\n}\n\nexport function layoutFirstLineIntrinsic<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n whitespace: TextWhitespaceMode = \"preserve\",\n): TextLayout {\n const segments = preprocessSegments(text, whitespace);\n const segment = segments[0];\n if (!segment) {\n return { width: 0, text: \"\", shift: 0 };\n }\n const shift = measureFontShift(ctx);\n return {\n width: ctx.graphics.measureText(segment).width,\n text: segment,\n shift,\n };\n}\n\nexport function measureTextIntrinsic<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n whitespace: TextWhitespaceMode = \"preserve\",\n): TextMeasurement {\n const segments = preprocessSegments(text, whitespace);\n if (segments.length === 0) {\n return { width: 0, lineCount: 0 };\n }\n\n let width = 0;\n for (const segment of segments) {\n width = Math.max(width, ctx.graphics.measureText(segment).width);\n }\n\n return { width, lineCount: segments.length };\n}\n\nexport function layoutTextIntrinsic<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n whitespace: TextWhitespaceMode = \"preserve\",\n): { width: number; lines: TextLayout[] } {\n const segments = preprocessSegments(text, whitespace);\n if (segments.length === 0) {\n return { width: 0, lines: [] };\n }\n\n const shift = measureFontShift(ctx);\n let width = 0;\n const lines: TextLayout[] = [];\n for (const segment of segments) {\n const measuredWidth = ctx.graphics.measureText(segment).width;\n width = Math.max(width, measuredWidth);\n lines.push({\n width: measuredWidth,\n text: segment,\n shift,\n });\n }\n\n return { width, lines };\n}\n\nexport function layoutFirstLine<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n whitespace: TextWhitespaceMode = \"preserve\",\n): TextLayout {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n const segments = preprocessSegments(text, whitespace);\n const segment = segments[0];\n if (!segment) {\n return { width: 0, text: \"\", shift: 0 };\n }\n const shift = measureFontShift(ctx);\n if (maxWidth === 0) {\n return { width: 0, text: \"\", shift };\n }\n const prepared = readPreparedSegment(segment, ctx.graphics.font);\n const line = layoutNextLine(prepared, LINE_START_CURSOR, maxWidth);\n if (line == null) {\n return { width: 0, text: \"\", shift };\n }\n return { width: line.width, text: line.text, shift };\n}\n\nexport function layoutEllipsizedFirstLine<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n ellipsisPosition: TextEllipsisPosition = \"end\",\n whitespace: TextWhitespaceMode = \"preserve\",\n): OverflowTextLayout {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n const segments = preprocessSegments(text, whitespace);\n const segment = segments[0];\n if (!segment) {\n return { width: 0, text: \"\", shift: 0, overflowed: false };\n }\n const shift = measureFontShift(ctx);\n if (maxWidth === 0) {\n return { width: 0, text: \"\", shift, overflowed: true };\n }\n const prepared = readPreparedSegment(segment, ctx.graphics.font);\n return layoutPreparedEllipsis(ctx, prepared, segment, maxWidth, shift, ellipsisPosition);\n}\n\nfunction layoutForcedEllipsizedLine<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n shift: number,\n): OverflowTextLayout {\n if (text.length === 0) {\n return createEllipsisOnlyLayout(ctx, maxWidth, shift);\n }\n const prepared = readPreparedSegment(text, ctx.graphics.font);\n return layoutPreparedEllipsis(ctx, prepared, text, maxWidth, shift, \"end\", true);\n}\n\nexport function measureText<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n whitespace: TextWhitespaceMode = \"preserve\",\n): TextMeasurement {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n\n const segments = preprocessSegments(text, whitespace);\n if (segments.length === 0 || maxWidth === 0) {\n return { width: 0, lineCount: 0 };\n }\n\n const font = ctx.graphics.font;\n let width = 0;\n let lineCount = 0;\n\n for (const segment of segments) {\n if (segment.length === 0) {\n lineCount += 1;\n continue;\n }\n const prepared = readPreparedSegment(segment, font);\n lineCount += walkLineRanges(prepared, maxWidth, (line) => {\n width = Math.max(width, line.width);\n });\n }\n\n return { width, lineCount };\n}\n\nexport function measureTextMinContent<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n whitespace: TextWhitespaceMode = \"preserve\",\n overflowWrap: TextOverflowWrapMode = \"break-word\",\n): TextMeasurement {\n const segments = preprocessSegments(text, whitespace);\n if (segments.length === 0) {\n return { width: 0, lineCount: 0 };\n }\n\n const font = ctx.graphics.font;\n let width = 0;\n\n for (const segment of segments) {\n if (segment.length === 0) {\n continue;\n }\n const prepared = readPreparedSegment(segment, font);\n width = Math.max(width, measurePreparedMinContentWidth(prepared, overflowWrap));\n }\n\n let lineCount = 0;\n const lineMaxWidth = Math.max(width, MIN_CONTENT_WIDTH_EPSILON);\n for (const segment of segments) {\n if (segment.length === 0) {\n lineCount += 1;\n continue;\n }\n const prepared = readPreparedSegment(segment, font);\n lineCount += walkLineRanges(prepared, lineMaxWidth, () => {});\n }\n\n return { width, lineCount };\n}\n\nexport function layoutText<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n whitespace: TextWhitespaceMode = \"preserve\",\n): { width: number; lines: TextLayout[] } {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n\n const segments = preprocessSegments(text, whitespace);\n if (segments.length === 0 || maxWidth === 0) {\n return { width: 0, lines: [] };\n }\n\n const font = ctx.graphics.font;\n const shift = measureFontShift(ctx);\n let width = 0;\n const lines: TextLayout[] = [];\n\n for (const segment of segments) {\n if (segment.length === 0) {\n lines.push({ width: 0, text: \"\", shift });\n continue;\n }\n const prepared = readPreparedSegment(segment, font);\n const { lines: segLines } = layoutWithLines(prepared, maxWidth, 0);\n for (const segLine of segLines) {\n width = Math.max(width, segLine.width);\n lines.push({ width: segLine.width, text: segLine.text, shift });\n }\n }\n\n return { width, lines };\n}\n\nexport function layoutTextWithOverflow<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n options: {\n whitespace?: TextWhitespaceMode;\n overflow?: TextOverflowMode;\n maxLines?: number;\n } = {},\n): OverflowTextBlockLayout {\n const whitespace = options.whitespace ?? \"preserve\";\n const overflow = options.overflow ?? \"clip\";\n const normalizedMaxLines = normalizeMaxLines(options.maxLines);\n\n const layout = layoutText(ctx, text, maxWidth, whitespace);\n if (normalizedMaxLines == null || layout.lines.length <= normalizedMaxLines) {\n return {\n width: layout.width,\n lines: layout.lines.map((line) => ({ ...line, overflowed: false })),\n overflowed: false,\n };\n }\n\n const visibleLines = layout.lines.slice(0, normalizedMaxLines);\n if (overflow !== \"ellipsis\") {\n return {\n width: visibleLines.reduce((lineWidth, line) => Math.max(lineWidth, line.width), 0),\n lines: visibleLines.map((line) => ({ ...line, overflowed: false })),\n overflowed: true,\n };\n }\n\n const shift = visibleLines[visibleLines.length - 1]?.shift ?? measureFontShift(ctx);\n const lastVisibleLine = visibleLines[visibleLines.length - 1];\n const ellipsizedLastLine = lastVisibleLine == null || lastVisibleLine.text.length === 0\n ? createEllipsisOnlyLayout(ctx, Math.max(0, maxWidth), shift)\n : layoutForcedEllipsizedLine(ctx, lastVisibleLine.text, maxWidth, shift);\n\n const lines = [\n ...visibleLines.slice(0, -1).map((line) => ({ ...line, overflowed: false })),\n { ...ellipsizedLastLine, shift },\n ];\n return {\n width: lines.reduce((lineWidth, line) => Math.max(lineWidth, line.width), 0),\n lines,\n overflowed: true,\n };\n}\n","import {\n layoutEllipsizedFirstLine,\n layoutFirstLine,\n layoutFirstLineIntrinsic,\n layoutText,\n layoutTextIntrinsic,\n layoutTextWithOverflow,\n measureText,\n measureTextMinContent,\n measureTextIntrinsic,\n type TextLayout,\n type TextMeasurement,\n} from \"../text\";\nimport type { Box, Context, MultilineTextOptions, Node, PhysicalTextAlign, TextOptions } from \"../types\";\n\ntype SingleLineLayout = TextLayout;\ntype MultiLineDrawLayout = {\n width: number;\n lines: TextLayout[];\n};\ntype MultiLineMeasureLayout = TextMeasurement;\n\ntype TextLayoutCacheAccess<C extends CanvasRenderingContext2D> = {\n getTextLayout<T>(node: Node<C>, key: string): T | undefined;\n setTextLayout<T>(node: Node<C>, key: string, layout: T): void;\n};\n\nfunction resolvePhysicalTextAlign(\n options: Pick<MultilineTextOptions<any>, \"align\" | \"physicalAlign\">,\n): PhysicalTextAlign {\n if (options.physicalAlign != null) {\n return options.physicalAlign;\n }\n if (options.align != null) {\n switch (options.align) {\n case \"start\":\n return \"left\";\n case \"center\":\n return \"center\";\n case \"end\":\n return \"right\";\n }\n }\n return \"left\";\n}\n\nfunction normalizeTextMaxWidth(maxWidth: number | undefined): number | undefined {\n if (maxWidth == null) {\n return undefined;\n }\n return Math.max(0, maxWidth);\n}\n\nfunction getTextLayoutContext<C extends CanvasRenderingContext2D>(ctx: Context<C>): Context<C> & TextLayoutCacheAccess<C> {\n return ctx as Context<C> & TextLayoutCacheAccess<C>;\n}\n\nfunction readCachedTextLayout<C extends CanvasRenderingContext2D, T>(\n node: Node<C>,\n ctx: Context<C>,\n key: string,\n compute: () => T,\n): T {\n const textCtx = getTextLayoutContext(ctx);\n const cached = textCtx.getTextLayout<T>(node, key);\n if (cached != null) {\n return cached;\n }\n const layout = compute();\n textCtx.setTextLayout(node, key, layout);\n return layout;\n}\n\nfunction getSingleLineLayoutKey(maxWidth: number | undefined): string {\n return maxWidth == null ? \"single:intrinsic\" : `single:${maxWidth}`;\n}\n\nfunction getMultiLineMeasureLayoutKey(maxWidth: number | undefined): string {\n return maxWidth == null ? \"multi:measure:intrinsic\" : `multi:measure:${maxWidth}`;\n}\n\nfunction getMultiLineDrawLayoutKey(maxWidth: number | undefined): string {\n return maxWidth == null ? \"multi:draw:intrinsic\" : `multi:draw:${maxWidth}`;\n}\n\nfunction getMultiLineOverflowLayoutKey(maxWidth: number | undefined): string {\n return maxWidth == null ? \"multi:overflow:intrinsic\" : `multi:overflow:${maxWidth}`;\n}\n\nfunction shouldUseMultilineOverflowLayout(options: Pick<MultilineTextOptions<any>, \"maxLines\">): boolean {\n return options.maxLines != null;\n}\n\nfunction getSingleLineMinContentLayoutKey(): string {\n return \"single:min-content\";\n}\n\nfunction getMultiLineMinContentLayoutKey(): string {\n return \"multi:min-content\";\n}\n\nfunction getSingleLineLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n options: TextOptions<C>,\n): SingleLineLayout {\n const maxWidth = normalizeTextMaxWidth(ctx.constraints?.maxWidth);\n return readCachedTextLayout(node, ctx, getSingleLineLayoutKey(maxWidth), () =>\n maxWidth == null\n ? layoutFirstLineIntrinsic(ctx, text, options.whitespace)\n : options.overflow === \"ellipsis\"\n ? layoutEllipsizedFirstLine(ctx, text, maxWidth, options.ellipsisPosition ?? \"end\", options.whitespace)\n : layoutFirstLine(ctx, text, maxWidth, options.whitespace)\n );\n}\n\nfunction getMultiLineOverflowLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n options: MultilineTextOptions<C>,\n): MultiLineDrawLayout {\n const maxWidth = normalizeTextMaxWidth(ctx.constraints?.maxWidth);\n return readCachedTextLayout(node, ctx, getMultiLineOverflowLayoutKey(maxWidth), () =>\n layoutTextWithOverflow(ctx, text, maxWidth ?? 0, {\n whitespace: options.whitespace,\n overflow: options.overflow,\n maxLines: options.maxLines,\n })\n );\n}\n\nfunction getMultiLineMeasureLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n options: MultilineTextOptions<C>,\n): MultiLineMeasureLayout {\n const maxWidth = normalizeTextMaxWidth(ctx.constraints?.maxWidth);\n if (maxWidth != null && shouldUseMultilineOverflowLayout(options)) {\n const layout = getMultiLineOverflowLayout(node, ctx, text, options);\n return { width: layout.width, lineCount: layout.lines.length };\n }\n return readCachedTextLayout(node, ctx, getMultiLineMeasureLayoutKey(maxWidth), () =>\n maxWidth == null ? measureTextIntrinsic(ctx, text, options.whitespace) : measureText(ctx, text, maxWidth, options.whitespace)\n );\n}\n\nfunction getMultiLineDrawLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n options: MultilineTextOptions<C>,\n): MultiLineDrawLayout {\n const maxWidth = normalizeTextMaxWidth(ctx.constraints?.maxWidth);\n if (maxWidth != null && shouldUseMultilineOverflowLayout(options)) {\n return getMultiLineOverflowLayout(node, ctx, text, options);\n }\n return readCachedTextLayout(node, ctx, getMultiLineDrawLayoutKey(maxWidth), () =>\n maxWidth == null ? layoutTextIntrinsic(ctx, text, options.whitespace) : layoutText(ctx, text, maxWidth, options.whitespace)\n );\n}\n\nfunction getSingleLineMinContentLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n options: TextOptions<C>,\n): SingleLineLayout {\n return readCachedTextLayout(node, ctx, getSingleLineMinContentLayoutKey(), () => {\n const measurement = measureTextMinContent(ctx, text, options.whitespace, options.overflowWrap);\n const { shift } = layoutFirstLineIntrinsic(ctx, text, options.whitespace);\n return {\n width: measurement.width,\n text,\n shift,\n };\n });\n}\n\nfunction getMultiLineMinContentLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n whitespace: MultilineTextOptions<C>[\"whitespace\"],\n overflowWrap: MultilineTextOptions<C>[\"overflowWrap\"],\n): MultiLineMeasureLayout {\n return readCachedTextLayout(node, ctx, getMultiLineMinContentLayoutKey(), () =>\n measureTextMinContent(ctx, text, whitespace, overflowWrap)\n );\n}\n\n/**\n * Draws wrapped text using the configured line height and alignment.\n */\nexport class MultilineText<C extends CanvasRenderingContext2D> implements Node<C> {\n /**\n * @param text Source text to measure and draw.\n * @param options Text layout and drawing options.\n */\n constructor(\n readonly text: string,\n readonly options: MultilineTextOptions<C>,\n ) {}\n\n measure(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width, lineCount } = getMultiLineMeasureLayout(this, ctx, this.text, this.options);\n return { width, height: lineCount * this.options.lineHeight };\n });\n }\n\n measureMinContent(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width, lineCount } = getMultiLineMinContentLayout(\n this,\n ctx,\n this.text,\n this.options.whitespace,\n this.options.overflowWrap,\n );\n return { width, height: lineCount * this.options.lineHeight };\n });\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return ctx.with((g) => {\n g.font = this.options.font;\n g.fillStyle = ctx.resolveDynValue(this.options.style);\n const { width, lines } = getMultiLineDrawLayout(this, ctx, this.text, this.options);\n switch (resolvePhysicalTextAlign(this.options)) {\n case \"left\":\n for (const { text, shift } of lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n case \"right\": {\n x += width;\n g.textAlign = \"right\";\n for (const { text, shift } of lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n }\n case \"center\": {\n x += width / 2;\n g.textAlign = \"center\";\n for (const { text, shift } of lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n }\n }\n return false;\n });\n }\n\n hittest(_ctx: Context<C>, _test: { x: number; y: number; type: \"click\" | \"auxclick\" | \"hover\" }): boolean {\n return false;\n }\n}\n\n/**\n * Draws a single line of text, clipped logically by measurement width.\n */\nexport class Text<C extends CanvasRenderingContext2D> implements Node<C> {\n /**\n * @param text Source text to measure and draw.\n * @param options Text layout and drawing options.\n */\n constructor(\n readonly text: string,\n readonly options: TextOptions<C>,\n ) {}\n\n measure(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width } = getSingleLineLayout(this, ctx, this.text, this.options);\n return { width, height: this.options.lineHeight };\n });\n }\n\n measureMinContent(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width } = getSingleLineMinContentLayout(this, ctx, this.text, this.options);\n return { width, height: this.options.lineHeight };\n });\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return ctx.with((g) => {\n g.font = this.options.font;\n g.fillStyle = ctx.resolveDynValue(this.options.style);\n const { text, shift } = getSingleLineLayout(this, ctx, this.text, this.options);\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n return false;\n });\n }\n\n hittest(_ctx: Context<C>, _test: { x: number; y: number; type: \"click\" | \"auxclick\" | \"hover\" }): boolean {\n return false;\n }\n}\n","import { forEachNodeAncestor, getNodeRevision } from \"../internal/node-registry\";\nimport type {\n Box,\n Context,\n DynValue,\n FlexLayoutResult,\n HitTest,\n LayoutConstraints,\n Node,\n RendererOptions,\n} from \"../types\";\nimport { shallow } from \"../utils\";\n\nconst MAX_CONSTRAINT_VARIANTS = 8;\n\ntype LayoutCacheAccess<C extends CanvasRenderingContext2D> = {\n getLayoutResult(node: Node<C>, constraints?: LayoutConstraints): FlexLayoutResult<C> | undefined;\n setLayoutResult(node: Node<C>, result: FlexLayoutResult<C>, constraints?: LayoutConstraints): void;\n};\n\ntype TextLayoutCacheAccess<C extends CanvasRenderingContext2D> = {\n getTextLayout<T>(node: Node<C>, key: string): T | undefined;\n setTextLayout<T>(node: Node<C>, key: string, layout: T): void;\n};\n\ntype BoxCacheEntry = {\n revision: number;\n box: Box;\n};\n\ntype LayoutCacheEntry<C extends CanvasRenderingContext2D> = {\n revision: number;\n layout: FlexLayoutResult<C>;\n};\n\ntype TextLayoutCacheEntry = {\n revision: number;\n layout: unknown;\n};\n\ntype RendererContext<C extends CanvasRenderingContext2D> = Context<C> & LayoutCacheAccess<C> & TextLayoutCacheAccess<C>;\n\nfunction constraintKey(constraints: LayoutConstraints | undefined): string {\n if (constraints == null) return \"\";\n return `${constraints.minWidth ?? \"\"},${constraints.maxWidth ?? \"\"},${constraints.minHeight ?? \"\"},${constraints.maxHeight ?? \"\"}`;\n}\n\n/**\n * Base renderer that provides measurement, layout caching, and drawing helpers.\n */\nexport class BaseRenderer<C extends CanvasRenderingContext2D, O extends {} = {}> {\n /** Canvas rendering context used by this renderer. */\n graphics: C;\n #ctx: RendererContext<C>;\n #lastWidth: number;\n #cache = new WeakMap<Node<C>, Map<string, BoxCacheEntry>>();\n #layoutCache = new WeakMap<Node<C>, Map<string, LayoutCacheEntry<C>>>();\n #textLayoutCache = new WeakMap<Node<C>, Map<string, TextLayoutCacheEntry>>();\n\n protected get context(): Context<C> {\n return shallow(this.#ctx);\n }\n\n /**\n * @param graphics Canvas rendering context used for all layout and drawing.\n * @param options Renderer-specific options.\n */\n constructor(\n graphics: C,\n readonly options: RendererOptions & O,\n ) {\n this.graphics = graphics;\n this.graphics.textRendering = \"optimizeLegibility\";\n const self = this;\n this.#ctx = {\n graphics: this.graphics,\n measureNode(node: Node<C>, constraints?: LayoutConstraints) {\n return self.measureNode(node, constraints);\n },\n getLayoutResult(node: Node<C>, constraints?: LayoutConstraints) {\n return self.getLayoutResult(node, constraints);\n },\n setLayoutResult(node: Node<C>, result: FlexLayoutResult<C>, constraints?: LayoutConstraints) {\n self.setLayoutResult(node, result, constraints);\n },\n getTextLayout<T>(node: Node<C>, key: string) {\n return self.getTextLayout<T>(node, key);\n },\n setTextLayout<T>(node: Node<C>, key: string, layout: T) {\n self.setTextLayout(node, key, layout);\n },\n invalidateNode: this.invalidateNode.bind(this),\n resolveDynValue<T>(value: DynValue<C, T>): T {\n if (typeof value === \"function\") {\n return value(this.graphics);\n }\n return value as T;\n },\n with<T>(cb: (g: C) => T): T {\n this.graphics.save();\n try {\n return cb(this.graphics);\n } finally {\n this.graphics.restore();\n }\n },\n };\n this.#lastWidth = this.graphics.canvas.clientWidth;\n }\n\n #clearAllCaches(): void {\n this.#cache = new WeakMap<Node<C>, Map<string, BoxCacheEntry>>();\n this.#layoutCache = new WeakMap<Node<C>, Map<string, LayoutCacheEntry<C>>>();\n this.#textLayoutCache = new WeakMap<Node<C>, Map<string, TextLayoutCacheEntry>>();\n }\n\n #syncCachesToViewportWidth(): void {\n const width = this.graphics.canvas.clientWidth;\n if (this.#lastWidth === width) {\n return;\n }\n this.#clearAllCaches();\n this.#lastWidth = width;\n }\n\n protected getRootConstraints(): LayoutConstraints {\n return {\n maxWidth: this.graphics.canvas.clientWidth,\n };\n }\n\n protected getRootContext(): Context<C> {\n const ctx = this.context;\n ctx.constraints = this.getRootConstraints();\n return ctx;\n }\n\n protected measureRootNode(node: Node<C>): Box {\n return this.measureNode(node, this.getRootConstraints());\n }\n\n protected drawRootNode(node: Node<C>, x = 0, y = 0): boolean {\n this.measureRootNode(node);\n return node.draw(this.getRootContext(), x, y);\n }\n\n protected hittestRootNode(node: Node<C>, test: HitTest): boolean {\n this.measureRootNode(node);\n return node.hittest(this.getRootContext(), test);\n }\n\n /**\n * Drops cached measurements for a node and every ancestor that depends on it.\n */\n invalidateNode(node: Node<C>): void {\n this.#syncCachesToViewportWidth();\n this.#cache.delete(node);\n this.#layoutCache.delete(node);\n this.#textLayoutCache.delete(node);\n forEachNodeAncestor(node, (ancestor) => {\n this.#cache.delete(ancestor);\n this.#layoutCache.delete(ancestor);\n this.#textLayoutCache.delete(ancestor);\n });\n }\n\n /**\n * Returns the cached layout result for a node under the given constraints, if available.\n */\n getLayoutResult(node: Node<C>, constraints?: LayoutConstraints): FlexLayoutResult<C> | undefined {\n this.#syncCachesToViewportWidth();\n const nodeCache = this.#layoutCache.get(node);\n if (nodeCache == null) {\n return undefined;\n }\n const key = constraintKey(constraints);\n const cached = nodeCache.get(key);\n if (cached == null) {\n return undefined;\n }\n if (cached.revision !== getNodeRevision(node)) {\n nodeCache.delete(key);\n return undefined;\n }\n return cached.layout;\n }\n\n /**\n * Stores a layout result for later draw and hit-test passes.\n */\n setLayoutResult(node: Node<C>, result: FlexLayoutResult<C>, constraints?: LayoutConstraints): void {\n this.#syncCachesToViewportWidth();\n let nodeCache = this.#layoutCache.get(node);\n if (nodeCache == null) {\n nodeCache = new Map();\n this.#layoutCache.set(node, nodeCache);\n } else if (nodeCache.size >= MAX_CONSTRAINT_VARIANTS) {\n const firstKey = nodeCache.keys().next().value!;\n nodeCache.delete(firstKey);\n }\n nodeCache.set(constraintKey(constraints), {\n revision: getNodeRevision(node),\n layout: result,\n });\n }\n\n protected getTextLayout<T>(node: Node<C>, key: string): T | undefined {\n this.#syncCachesToViewportWidth();\n const nodeCache = this.#textLayoutCache.get(node);\n if (nodeCache == null) {\n return undefined;\n }\n const cached = nodeCache.get(key);\n if (cached == null) {\n return undefined;\n }\n if (cached.revision !== getNodeRevision(node)) {\n nodeCache.delete(key);\n return undefined;\n }\n return cached.layout as T;\n }\n\n protected setTextLayout<T>(node: Node<C>, key: string, layout: T): void {\n this.#syncCachesToViewportWidth();\n let nodeCache = this.#textLayoutCache.get(node);\n if (nodeCache == null) {\n nodeCache = new Map();\n this.#textLayoutCache.set(node, nodeCache);\n } else if (nodeCache.size >= MAX_CONSTRAINT_VARIANTS) {\n const firstKey = nodeCache.keys().next().value!;\n nodeCache.delete(firstKey);\n }\n nodeCache.set(key, {\n revision: getNodeRevision(node),\n layout,\n });\n }\n\n /**\n * Measures a node under optional constraints, using cached results when possible.\n */\n measureNode(node: Node<C>, constraints?: LayoutConstraints): Box {\n this.#syncCachesToViewportWidth();\n {\n const nodeCache = this.#cache.get(node);\n if (nodeCache != null) {\n const key = constraintKey(constraints);\n const cached = nodeCache.get(key);\n if (cached != null) {\n if (cached.revision === getNodeRevision(node)) {\n return cached.box;\n }\n nodeCache.delete(key);\n }\n }\n }\n const ctx = this.context;\n if (constraints != null) {\n ctx.constraints = constraints;\n }\n const result = node.measure(ctx);\n const key = constraintKey(constraints);\n let nodeCache = this.#cache.get(node);\n if (nodeCache == null) {\n nodeCache = new Map();\n this.#cache.set(node, nodeCache);\n } else if (nodeCache.size >= MAX_CONSTRAINT_VARIANTS) {\n const firstKey = nodeCache.keys().next().value!;\n nodeCache.delete(firstKey);\n }\n nodeCache.set(key, {\n revision: getNodeRevision(node),\n box: result,\n });\n return result;\n }\n}\n\n/**\n * Immediate-mode renderer for a single root node.\n */\nexport class DebugRenderer<C extends CanvasRenderingContext2D> extends BaseRenderer<C> {\n /**\n * Clears the viewport and draws the provided root node.\n */\n draw(node: Node<C>): boolean {\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n return this.drawRootNode(node);\n }\n\n /**\n * Hit-tests the provided root node using viewport-relative coordinates.\n */\n hittest(node: Node<C>, test: HitTest): boolean {\n return this.hittestRootNode(node, test);\n }\n}\n","/**\n * Mutable list state shared with virtualized renderers.\n */\nexport class ListState<T extends {}> {\n /** Pixel offset from the anchored item edge. */\n offset = 0;\n /** Anchor item index, or `undefined` to use the renderer default. */\n position: number | undefined;\n /** Items currently managed by the renderer. */\n items: T[] = [];\n\n /**\n * @param items Initial list items.\n */\n constructor(items: T[] = []) {\n this.items = [...items];\n }\n\n /** Prepends one or more items. */\n unshift(...items: T[]): void {\n this.unshiftAll(items);\n }\n\n /** Prepends an array of items. */\n unshiftAll(items: T[]): void {\n if (this.position != null) {\n this.position += items.length;\n }\n this.items = items.concat(this.items);\n }\n\n /** Appends one or more items. */\n push(...items: T[]): void {\n this.pushAll(items);\n }\n\n /** Appends an array of items. */\n pushAll(items: T[]): void {\n this.items.push(...items);\n }\n\n /**\n * Sets the current anchor item and pixel offset.\n */\n setAnchor(position: number, offset = 0): void {\n this.position = Number.isFinite(position) ? Math.trunc(position) : undefined;\n this.offset = Number.isFinite(offset) ? offset : 0;\n }\n\n /**\n * Replaces all items and clears scroll state.\n */\n reset(items: T[] = []): void {\n this.items = [...items];\n this.offset = 0;\n this.position = undefined;\n }\n\n /** Clears the current scroll anchor while keeping the items. */\n resetScroll(): void {\n this.offset = 0;\n this.position = undefined;\n }\n\n /** Applies a relative pixel scroll delta. */\n applyScroll(delta: number): void {\n this.offset += delta;\n }\n}\n","import type { Node } from \"../types\";\n\nfunction isWeakMapKey(value: unknown): value is object {\n return (typeof value === \"object\" && value !== null) || typeof value === \"function\";\n}\n\n/**\n * Memoizes `renderItem` by object identity.\n */\nexport function memoRenderItem<C extends CanvasRenderingContext2D, T extends object>(\n renderItem: (item: T) => Node<C>,\n): ((item: T) => Node<C>) & { reset: (key: T) => boolean } {\n const cache = new WeakMap<object, Node<C>>();\n\n function fn(item: T): Node<C> {\n if (!isWeakMapKey(item)) {\n throw new TypeError(\"memoRenderItem() only supports object items. Use memoRenderItemBy() for primitive keys.\");\n }\n const key = item as unknown as object;\n const cached = cache.get(key);\n if (cached != null) {\n return cached;\n }\n const result = renderItem(item);\n cache.set(key, result);\n return result;\n }\n\n return Object.assign(fn, {\n reset: (key: T) => cache.delete(key as unknown as object),\n });\n}\n\n/**\n * Memoizes `renderItem` by a caller-provided cache key.\n */\nexport function memoRenderItemBy<C extends CanvasRenderingContext2D, T, K>(\n keyOf: (item: T) => K,\n renderItem: (item: T) => Node<C>,\n): ((item: T) => Node<C>) & { reset: (item: T) => boolean; resetKey: (key: K) => boolean } {\n const cache = new Map<K, Node<C>>();\n\n function fn(item: T): Node<C> {\n const key = keyOf(item);\n const cached = cache.get(key);\n if (cached != null) {\n return cached;\n }\n const result = renderItem(item);\n cache.set(key, result);\n return result;\n }\n\n return Object.assign(fn, {\n reset: (item: T) => cache.delete(keyOf(item)),\n resetKey: (key: K) => cache.delete(key),\n });\n}\n","import type { Node, RenderFeedback } from \"../../types\";\nimport { BaseRenderer } from \"../base\";\nimport { ListState } from \"../list-state\";\nimport type { NormalizedListState, VisibleListState, VisibleWindow } from \"./solver\";\n\n/**\n * Options for programmatic scrolling to a target item.\n */\nexport interface JumpToOptions {\n /** Whether to animate the jump. Defaults to `true`. */\n animated?: boolean;\n /** Which edge of the item should align with the viewport. */\n block?: \"start\" | \"center\" | \"end\";\n /** Animation duration in milliseconds. */\n duration?: number;\n /** Called after the jump completes or finishes animating. */\n onComplete?: () => void;\n}\n\ntype ControlledState = {\n position?: number;\n offset: number;\n};\n\ntype JumpAnimation = {\n startAnchor: number;\n targetAnchor: number;\n startTime: number;\n duration: number;\n needsMoreFrames: boolean;\n onComplete: (() => void) | undefined;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction sameState(state: ControlledState, position: number | undefined, offset: number): boolean {\n return Object.is(state.position, position) && Object.is(state.offset, offset);\n}\n\nfunction smoothstep(value: number): number {\n return value * value * (3 - 2 * value);\n}\n\nfunction getNow(): number {\n return globalThis.performance?.now() ?? Date.now();\n}\n\n/**\n * Shared base class for virtualized list renderers.\n */\nexport abstract class VirtualizedRenderer<C extends CanvasRenderingContext2D, T extends {}> extends BaseRenderer<\n C,\n {\n renderItem: (item: T) => Node<C>;\n list: ListState<T>;\n }\n> {\n static readonly MIN_JUMP_DURATION = 160;\n static readonly MAX_JUMP_DURATION = 420;\n static readonly JUMP_DURATION_PER_ITEM = 28;\n\n #controlledState: ControlledState | undefined;\n #jumpAnimation: JumpAnimation | undefined;\n\n /** Current anchor item index. */\n get position(): number | undefined {\n return this.options.list.position;\n }\n\n /** Updates the current anchor item index. */\n set position(value: number | undefined) {\n this.options.list.position = value;\n }\n\n /** Pixel offset from the anchored item edge. */\n get offset(): number {\n return this.options.list.offset;\n }\n\n /** Updates the pixel offset from the anchored item edge. */\n set offset(value: number) {\n this.options.list.offset = value;\n }\n\n /** Items currently available to the renderer. */\n get items(): T[] {\n return this.options.list.items;\n }\n\n /** Replaces the current item collection. */\n set items(value: T[]) {\n this.options.list.items = value;\n }\n\n /** Renders the current visible window. */\n abstract render(feedback?: RenderFeedback): boolean;\n /** Hit-tests the current visible window. */\n abstract hittest(test: { x: number; y: number; type: \"click\" | \"auxclick\" | \"hover\" }): boolean;\n\n protected _readListState(): VisibleListState {\n return {\n position: this.position,\n offset: this.offset,\n };\n }\n\n protected _commitListState(state: NormalizedListState): void {\n this.position = state.position;\n this.offset = state.offset;\n }\n\n /**\n * Scrolls the viewport to the requested item index.\n */\n jumpTo(index: number, options: JumpToOptions = {}): void {\n if (this.items.length === 0) {\n this.#cancelJumpAnimation();\n return;\n }\n\n const targetIndex = this._clampItemIndex(index);\n const currentState = this._normalizeListState(this._readListState());\n const targetBlock = options.block ?? this._getDefaultJumpBlock();\n const targetAnchor = this._getTargetAnchor(targetIndex, targetBlock);\n\n const animated = options.animated ?? true;\n if (!animated) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n options.onComplete?.();\n return;\n }\n\n const startAnchor = this._readAnchor(currentState);\n if (!Number.isFinite(startAnchor)) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n options.onComplete?.();\n return;\n }\n\n const duration = clamp(\n options.duration ??\n VirtualizedRenderer.MIN_JUMP_DURATION +\n Math.abs(targetAnchor - startAnchor) * VirtualizedRenderer.JUMP_DURATION_PER_ITEM,\n 0,\n VirtualizedRenderer.MAX_JUMP_DURATION,\n );\n\n if (duration <= 0 || Math.abs(targetAnchor - startAnchor) <= Number.EPSILON) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n options.onComplete?.();\n return;\n }\n\n this.#jumpAnimation = {\n startAnchor,\n targetAnchor,\n startTime: getNow(),\n duration,\n needsMoreFrames: true,\n onComplete: options.onComplete,\n };\n this.#controlledState = this._readListState();\n }\n\n protected _resetRenderFeedback(feedback?: RenderFeedback): void {\n if (feedback == null) {\n return;\n }\n feedback.minIdx = Number.NaN;\n feedback.maxIdx = Number.NaN;\n feedback.min = Number.NaN;\n feedback.max = Number.NaN;\n }\n\n protected _accumulateRenderFeedback(feedback: RenderFeedback, idx: number, top: number, height: number): void {\n if (!Number.isFinite(top) || !Number.isFinite(height) || height <= 0) {\n return;\n }\n\n const viewportHeight = this.graphics.canvas.clientHeight;\n const visibleTop = clamp(-top, 0, height);\n const visibleBottom = clamp(viewportHeight - top, 0, height);\n if (visibleBottom <= visibleTop) {\n return;\n }\n\n const itemMin = idx + visibleTop / height;\n const itemMax = idx + visibleBottom / height;\n feedback.minIdx = Number.isNaN(feedback.minIdx) ? idx : Math.min(idx, feedback.minIdx);\n feedback.maxIdx = Number.isNaN(feedback.maxIdx) ? idx : Math.max(idx, feedback.maxIdx);\n feedback.min = Number.isNaN(feedback.min) ? itemMin : Math.min(itemMin, feedback.min);\n feedback.max = Number.isNaN(feedback.max) ? itemMax : Math.max(itemMax, feedback.max);\n }\n\n protected _renderDrawList(list: VisibleWindow<Node<C>>[\"drawList\"], shift: number, feedback?: RenderFeedback): boolean {\n let result = false;\n const viewportHeight = this.graphics.canvas.clientHeight;\n\n for (const { idx, value: node, offset, height } of list) {\n const y = offset + shift;\n if (feedback != null) {\n this._accumulateRenderFeedback(feedback, idx, y, height);\n }\n if (y + height < 0 || y > viewportHeight) {\n continue;\n }\n if (this.drawRootNode(node, 0, y)) {\n result = true;\n }\n }\n\n return result;\n }\n\n protected _renderVisibleWindow(window: VisibleWindow<Node<C>>, feedback?: RenderFeedback): boolean {\n this._resetRenderFeedback(feedback);\n return this._renderDrawList(window.drawList, window.shift, feedback);\n }\n\n protected _hittestVisibleWindow(window: VisibleWindow<Node<C>>, test: { x: number; y: number; type: \"click\" | \"auxclick\" | \"hover\" }): boolean {\n for (const { value: node, offset, height } of window.drawList) {\n const y = offset + window.shift;\n if (test.y < y || test.y >= y + height) {\n continue;\n }\n return node.hittest(\n this.getRootContext(),\n {\n ...test,\n y: test.y - y,\n },\n );\n }\n return false;\n }\n\n protected _prepareRender(): boolean {\n const animation = this.#jumpAnimation;\n if (animation == null) {\n return false;\n }\n if (this.items.length === 0) {\n this.#cancelJumpAnimation();\n return false;\n }\n if (this.#controlledState != null && !sameState(this.#controlledState, this.position, this.offset)) {\n this.#cancelJumpAnimation();\n return false;\n }\n\n const progress = clamp((getNow() - animation.startTime) / animation.duration, 0, 1);\n const eased = progress >= 1 ? 1 : smoothstep(progress);\n const anchor = animation.startAnchor + (animation.targetAnchor - animation.startAnchor) * eased;\n this._applyAnchor(anchor);\n animation.needsMoreFrames = progress < 1;\n return animation.needsMoreFrames;\n }\n\n protected _finishRender(requestRedraw: boolean): boolean {\n const animation = this.#jumpAnimation;\n if (animation == null) {\n return requestRedraw;\n }\n\n if (animation.needsMoreFrames) {\n this.#controlledState = this._readListState();\n return true;\n }\n\n const onComplete = animation.onComplete;\n this.#cancelJumpAnimation();\n onComplete?.();\n return requestRedraw || this.#jumpAnimation != null;\n }\n\n protected _clampItemIndex(index: number): number {\n return clamp(Number.isFinite(index) ? Math.trunc(index) : 0, 0, this.items.length - 1);\n }\n\n protected _getItemHeight(index: number): number {\n const item = this.items[index];\n const node = this.options.renderItem(item);\n return this.measureRootNode(node).height;\n }\n\n protected _getAnchorAtOffset(index: number, offset: number): number {\n if (this.items.length === 0) {\n return 0;\n }\n\n let currentIndex = this._clampItemIndex(index);\n let remaining = Number.isFinite(offset) ? offset : 0;\n while (true) {\n if (remaining < 0) {\n if (currentIndex === 0) {\n return 0;\n }\n currentIndex -= 1;\n const height = this._getItemHeight(currentIndex);\n if (height > 0) {\n remaining += height;\n }\n continue;\n }\n\n const height = this._getItemHeight(currentIndex);\n if (height > 0) {\n if (remaining <= height) {\n return currentIndex + remaining / height;\n }\n remaining -= height;\n } else if (remaining === 0) {\n return currentIndex;\n }\n\n if (currentIndex === this.items.length - 1) {\n return this.items.length;\n }\n currentIndex += 1;\n }\n }\n\n protected abstract _normalizeListState(state: VisibleListState): NormalizedListState;\n protected abstract _readAnchor(state: NormalizedListState): number;\n protected abstract _applyAnchor(anchor: number): void;\n protected abstract _getDefaultJumpBlock(): NonNullable<JumpToOptions[\"block\"]>;\n protected abstract _getTargetAnchor(index: number, block: NonNullable<JumpToOptions[\"block\"]>): number;\n\n #cancelJumpAnimation(): void {\n this.#jumpAnimation = undefined;\n this.#controlledState = undefined;\n }\n}\n","export interface VisibleListState {\n position?: number;\n offset: number;\n}\n\nexport interface NormalizedListState {\n position: number;\n offset: number;\n}\n\nexport interface VisibleWindowEntry<T> {\n idx: number;\n value: T;\n offset: number;\n height: number;\n}\n\nexport interface VisibleWindow<T> {\n drawList: VisibleWindowEntry<T>[];\n shift: number;\n}\n\nexport interface VisibleWindowResult<T> {\n normalizedState: NormalizedListState;\n window: VisibleWindow<T>;\n}\n\ntype ResolvedItem<T> = {\n value: T;\n height: number;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction normalizeOffset(offset: number): number {\n return Number.isFinite(offset) ? offset : 0;\n}\n\nexport function normalizeTimelineState(itemCount: number, state: VisibleListState): NormalizedListState {\n if (itemCount <= 0) {\n return { position: 0, offset: 0 };\n }\n\n const position = state.position;\n if (typeof position !== \"number\" || !Number.isFinite(position)) {\n return {\n position: 0,\n offset: normalizeOffset(state.offset),\n };\n }\n\n return {\n position: clamp(Math.trunc(position), 0, itemCount - 1),\n offset: normalizeOffset(state.offset),\n };\n}\n\nexport function normalizeChatState(itemCount: number, state: VisibleListState): NormalizedListState {\n if (itemCount <= 0) {\n return { position: 0, offset: 0 };\n }\n\n const position = state.position;\n if (typeof position !== \"number\" || !Number.isFinite(position)) {\n return {\n position: itemCount - 1,\n offset: normalizeOffset(state.offset),\n };\n }\n\n return {\n position: clamp(Math.trunc(position), 0, itemCount - 1),\n offset: normalizeOffset(state.offset),\n };\n}\n\nexport function resolveTimelineVisibleWindow<T, V>(\n items: readonly T[],\n state: VisibleListState,\n viewportHeight: number,\n resolveItem: (item: T, idx: number) => ResolvedItem<V>,\n): VisibleWindowResult<V> {\n const normalizedState = normalizeTimelineState(items.length, state);\n if (items.length === 0) {\n return {\n normalizedState,\n window: { drawList: [], shift: 0 },\n };\n }\n\n let { position, offset } = normalizedState;\n let drawLength = 0;\n\n if (offset > 0) {\n if (position === 0) {\n offset = 0;\n } else {\n for (let i = position - 1; i >= 0; i -= 1) {\n const { height } = resolveItem(items[i]!, i);\n position = i;\n offset -= height;\n if (offset <= 0) {\n break;\n }\n }\n if (position === 0 && offset > 0) {\n offset = 0;\n }\n }\n }\n\n let y = offset;\n const drawList: VisibleWindowEntry<V>[] = [];\n for (let i = position; i < items.length; i += 1) {\n const { value, height } = resolveItem(items[i]!, i);\n if (y + height > 0) {\n drawList.push({ idx: i, value, offset: y, height });\n drawLength += height;\n } else {\n offset += height;\n position = i + 1;\n }\n y += height;\n if (y >= viewportHeight) {\n break;\n }\n }\n\n let shift = 0;\n if (y < viewportHeight) {\n if (position === 0 && drawLength < viewportHeight) {\n shift = -offset;\n offset = 0;\n } else {\n shift = viewportHeight - y;\n y = (offset += shift);\n let lastIdx = -1;\n for (let i = position - 1; i >= 0; i -= 1) {\n const { value, height } = resolveItem(items[i]!, i);\n drawLength += height;\n y -= height;\n drawList.push({ idx: i, value, offset: y - shift, height });\n lastIdx = i;\n if (y < 0) {\n break;\n }\n }\n if (lastIdx === 0 && drawLength < viewportHeight) {\n shift = drawList.at(-1)?.offset == null ? 0 : -drawList.at(-1)!.offset;\n position = 0;\n offset = 0;\n }\n }\n }\n\n return {\n normalizedState: { position, offset },\n window: { drawList, shift },\n };\n}\n\nexport function resolveChatVisibleWindow<T, V>(\n items: readonly T[],\n state: VisibleListState,\n viewportHeight: number,\n resolveItem: (item: T, idx: number) => ResolvedItem<V>,\n): VisibleWindowResult<V> {\n const normalizedState = normalizeChatState(items.length, state);\n if (items.length === 0) {\n return {\n normalizedState,\n window: { drawList: [], shift: 0 },\n };\n }\n\n let { position, offset } = normalizedState;\n let drawLength = 0;\n\n if (offset < 0) {\n if (position === items.length - 1) {\n offset = 0;\n } else {\n for (let i = position + 1; i < items.length; i += 1) {\n const { height } = resolveItem(items[i]!, i);\n position = i;\n offset += height;\n if (offset > 0) {\n break;\n }\n }\n }\n }\n\n let y = viewportHeight + offset;\n const drawList: VisibleWindowEntry<V>[] = [];\n for (let i = position; i >= 0; i -= 1) {\n const { value, height } = resolveItem(items[i]!, i);\n y -= height;\n if (y <= viewportHeight) {\n drawList.push({ idx: i, value, offset: y, height });\n drawLength += height;\n } else {\n offset -= height;\n position = i - 1;\n }\n if (y < 0) {\n break;\n }\n }\n\n let shift = 0;\n if (y > 0) {\n shift = -y;\n if (drawLength < viewportHeight) {\n y = drawLength;\n for (let i = position + 1; i < items.length; i += 1) {\n const { value, height } = resolveItem(items[i]!, i);\n drawList.push({ idx: i, value, offset: y - shift, height });\n y = (drawLength += height);\n position = i;\n if (y >= viewportHeight) {\n break;\n }\n }\n offset = drawLength < viewportHeight ? 0 : drawLength - viewportHeight;\n } else {\n offset = drawLength - viewportHeight;\n }\n }\n\n return {\n normalizedState: { position, offset },\n window: { drawList, shift },\n };\n}\n","import type { HitTest, Node, RenderFeedback } from \"../../types\";\nimport { VirtualizedRenderer } from \"./base\";\nimport type { JumpToOptions } from \"./base\";\nimport {\n normalizeChatState,\n resolveChatVisibleWindow,\n type NormalizedListState,\n type VisibleListState,\n type VisibleWindowResult,\n} from \"./solver\";\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Virtualized renderer anchored to the bottom, suitable for chat-style UIs.\n */\nexport class ChatRenderer<C extends CanvasRenderingContext2D, T extends {}> extends VirtualizedRenderer<C, T> {\n #resolveVisibleWindow(): VisibleWindowResult<Node<C>> {\n return resolveChatVisibleWindow(\n this.items,\n this._readListState(),\n this.graphics.canvas.clientHeight,\n (item) => {\n const node = this.options.renderItem(item);\n return {\n value: node,\n height: this.measureRootNode(node).height,\n };\n },\n );\n }\n\n protected _getDefaultJumpBlock(): NonNullable<JumpToOptions[\"block\"]> {\n return \"end\";\n }\n\n protected _normalizeListState(state: VisibleListState): NormalizedListState {\n return normalizeChatState(this.items.length, state);\n }\n\n protected _readAnchor(state: NormalizedListState): number {\n if (this.items.length === 0) {\n return 0;\n }\n const height = this._getItemHeight(state.position);\n return height > 0 ? state.position + 1 - state.offset / height : state.position + 1;\n }\n\n protected _applyAnchor(anchor: number): void {\n if (this.items.length === 0) {\n return;\n }\n const clampedAnchor = clamp(anchor, 0, this.items.length);\n const position = clamp(Math.ceil(clampedAnchor) - 1, 0, this.items.length - 1);\n const height = this._getItemHeight(position);\n const offset = height > 0 ? (position + 1 - clampedAnchor) * height : 0;\n this._commitListState({\n position,\n offset: Object.is(offset, -0) ? 0 : offset,\n });\n }\n\n protected _getTargetAnchor(index: number, block: NonNullable<JumpToOptions[\"block\"]>): number {\n const height = this._getItemHeight(index);\n const viewportHeight = this.graphics.canvas.clientHeight;\n\n switch (block) {\n case \"start\":\n return this._getAnchorAtOffset(index, viewportHeight);\n case \"center\":\n return this._getAnchorAtOffset(index, height / 2 + viewportHeight / 2);\n case \"end\":\n return this._getAnchorAtOffset(index, height);\n }\n }\n\n render(feedback?: RenderFeedback): boolean {\n const keepAnimating = this._prepareRender();\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n const solution = this.#resolveVisibleWindow();\n const requestRedraw = this._renderVisibleWindow(solution.window, feedback);\n this._commitListState(solution.normalizedState);\n return this._finishRender(keepAnimating || requestRedraw);\n }\n\n hittest(test: HitTest): boolean {\n return this._hittestVisibleWindow(this.#resolveVisibleWindow().window, test);\n }\n}\n","import type { HitTest, Node, RenderFeedback } from \"../../types\";\nimport { VirtualizedRenderer } from \"./base\";\nimport type { JumpToOptions } from \"./base\";\nimport {\n normalizeTimelineState,\n resolveTimelineVisibleWindow,\n type NormalizedListState,\n type VisibleListState,\n type VisibleWindowResult,\n} from \"./solver\";\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Virtualized renderer anchored to the top, suitable for timeline-style UIs.\n */\nexport class TimelineRenderer<C extends CanvasRenderingContext2D, T extends {}> extends VirtualizedRenderer<C, T> {\n #resolveVisibleWindow(): VisibleWindowResult<Node<C>> {\n return resolveTimelineVisibleWindow(\n this.items,\n this._readListState(),\n this.graphics.canvas.clientHeight,\n (item) => {\n const node = this.options.renderItem(item);\n return {\n value: node,\n height: this.measureRootNode(node).height,\n };\n },\n );\n }\n\n protected _getDefaultJumpBlock(): NonNullable<JumpToOptions[\"block\"]> {\n return \"start\";\n }\n\n protected _normalizeListState(state: VisibleListState): NormalizedListState {\n return normalizeTimelineState(this.items.length, state);\n }\n\n protected _readAnchor(state: NormalizedListState): number {\n if (this.items.length === 0) {\n return 0;\n }\n const height = this._getItemHeight(state.position);\n return height > 0 ? state.position - state.offset / height : state.position;\n }\n\n protected _applyAnchor(anchor: number): void {\n if (this.items.length === 0) {\n return;\n }\n const clampedAnchor = clamp(anchor, 0, this.items.length);\n const position = clamp(Math.floor(clampedAnchor), 0, this.items.length - 1);\n const height = this._getItemHeight(position);\n const offset = height > 0 ? -(clampedAnchor - position) * height : 0;\n this._commitListState({\n position,\n offset: Object.is(offset, -0) ? 0 : offset,\n });\n }\n\n protected _getTargetAnchor(index: number, block: NonNullable<JumpToOptions[\"block\"]>): number {\n const height = this._getItemHeight(index);\n const viewportHeight = this.graphics.canvas.clientHeight;\n\n switch (block) {\n case \"start\":\n return this._getAnchorAtOffset(index, 0);\n case \"center\":\n return this._getAnchorAtOffset(index, height / 2 - viewportHeight / 2);\n case \"end\":\n return this._getAnchorAtOffset(index, height - viewportHeight);\n }\n }\n\n render(feedback?: RenderFeedback): boolean {\n const keepAnimating = this._prepareRender();\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n const solution = this.#resolveVisibleWindow();\n const requestRedraw = this._renderVisibleWindow(solution.window, feedback);\n this._commitListState(solution.normalizedState);\n return this._finishRender(keepAnimating || requestRedraw);\n }\n\n hittest(test: HitTest): boolean {\n return this._hittestVisibleWindow(this.#resolveVisibleWindow().window, test);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["#children","#inner","clampToConstraints","#top","#bottom","#left","#right","#ctx","#lastWidth","#cache","#layoutCache","#textLayoutCache","#clearAllCaches","#syncCachesToViewportWidth","clamp","#cancelJumpAnimation","#jumpAnimation","#controlledState","clamp","clamp","#resolveVisibleWindow","#resolveVisibleWindow"],"sources":["../src/internal/node-registry.ts","../src/utils.ts","../src/nodes/base.ts","../src/layout.ts","../src/nodes/shared.ts","../src/nodes/box.ts","../src/nodes/flex.ts","../src/nodes/place.ts","../src/text.ts","../src/nodes/text.ts","../src/renderer/base.ts","../src/renderer/list-state.ts","../src/renderer/memo.ts","../src/renderer/virtualized/base.ts","../src/renderer/virtualized/solver.ts","../src/renderer/virtualized/chat.ts","../src/renderer/virtualized/timeline.ts"],"sourcesContent":["import type { Node } from \"../types\";\n\nconst registry = new WeakMap<Node<any>, Node<any>>();\nconst revisions = new WeakMap<Node<any>, number>();\n\nfunction getOwnershipError(): Error {\n return new Error(\"A node can only be attached to one parent. Shared nodes are not supported.\");\n}\n\nfunction getDetachOwnershipError(): Error {\n return new Error(\"Cannot detach or replace a node from a parent that does not own it.\");\n}\n\nfunction bumpRevision(node: Node<any>): void {\n revisions.set(node, (revisions.get(node) ?? 0) + 1);\n}\n\nexport function getNodeRevision<C extends CanvasRenderingContext2D>(node: Node<C>): number {\n return revisions.get(node) ?? 0;\n}\n\nexport function attachNodeToParent<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n parent: Node<C>,\n): void {\n if (registry.has(node)) {\n throw getOwnershipError();\n }\n registry.set(node, parent);\n bumpRevision(parent);\n}\n\nexport function attachNodesToParent<C extends CanvasRenderingContext2D>(\n nodes: Iterable<Node<C>>,\n parent: Node<C>,\n): void {\n for (const node of nodes) {\n attachNodeToParent(node, parent);\n }\n}\n\nexport function detachNodeFromParent<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n parent?: Node<C>,\n): void {\n const currentParent = registry.get(node);\n if (currentParent == null) {\n return;\n }\n if (parent != null && currentParent !== parent) {\n throw getDetachOwnershipError();\n }\n registry.delete(node);\n bumpRevision(currentParent);\n}\n\nexport function replaceNodeParent<C extends CanvasRenderingContext2D>(\n previousNode: Node<C>,\n nextNode: Node<C>,\n parent: Node<C>,\n): void {\n if (previousNode === nextNode) {\n return;\n }\n const currentParent = registry.get(previousNode);\n if (currentParent !== parent) {\n throw getDetachOwnershipError();\n }\n if (registry.has(nextNode)) {\n throw getOwnershipError();\n }\n registry.delete(previousNode);\n registry.set(nextNode, parent);\n bumpRevision(parent);\n}\n\nexport function replaceNodesParent<C extends CanvasRenderingContext2D>(\n previousNodes: Iterable<Node<C>>,\n nextNodes: Iterable<Node<C>>,\n parent: Node<C>,\n): void {\n const previousSnapshot = Array.from(previousNodes);\n const nextSnapshot = Array.from(nextNodes);\n if (\n previousSnapshot.length === nextSnapshot.length &&\n previousSnapshot.every((node, index) => node === nextSnapshot[index])\n ) {\n return;\n }\n\n const previousSet = new Set(previousSnapshot);\n const nextSet = new Set<Node<C>>();\n for (const node of nextSnapshot) {\n if (nextSet.has(node)) {\n throw getOwnershipError();\n }\n nextSet.add(node);\n const currentParent = registry.get(node);\n if (currentParent != null && currentParent !== parent) {\n throw getOwnershipError();\n }\n }\n\n for (const node of previousSnapshot) {\n if (!nextSet.has(node)) {\n const currentParent = registry.get(node);\n if (currentParent !== parent) {\n throw getDetachOwnershipError();\n }\n registry.delete(node);\n }\n }\n\n for (const node of nextSnapshot) {\n if (!previousSet.has(node)) {\n registry.set(node, parent);\n }\n }\n\n bumpRevision(parent);\n}\n\nexport function forEachNodeAncestor<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n visitor: (ancestor: Node<C>) => void,\n): void {\n let current: Node<C> | undefined = node;\n while ((current = registry.get(current))) {\n visitor(current);\n }\n}\n\nexport function registerNodeParent<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n parent: Node<C>,\n): void {\n attachNodeToParent(node, parent);\n}\n\nexport function unregisterNodeParent<C extends CanvasRenderingContext2D>(node: Node<C>, parent?: Node<C>): void {\n detachNodeFromParent(node, parent);\n}\n\nexport function getNodeParent<C extends CanvasRenderingContext2D>(node: Node<C>): Node<C> | undefined {\n return registry.get(node);\n}\n","export function shallow<T extends object>(object: T): T {\n return Object.create(object) as T;\n}\n","import { attachNodeToParent, replaceNodeParent, replaceNodesParent } from \"../internal/node-registry\";\nimport type { Box, Context, HitTest, LayoutConstraints, Node } from \"../types\";\nimport { shallow } from \"../utils\";\n\nexport function withNodeConstraints<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n constraints: LayoutConstraints | undefined,\n): Context<C> {\n if (constraints === ctx.constraints) {\n return ctx;\n }\n const next = shallow(ctx);\n next.constraints = constraints;\n return next;\n}\n\nexport function measureNodeMinContent<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n node: Node<C>,\n constraints: LayoutConstraints | undefined = ctx.constraints,\n): Box {\n const nextCtx = withNodeConstraints(ctx, constraints);\n if (node.measureMinContent != null) {\n return node.measureMinContent(nextCtx);\n }\n return node.measure(nextCtx);\n}\n\n/**\n * A node that owns an ordered list of child nodes.\n */\nexport abstract class Group<C extends CanvasRenderingContext2D> implements Node<C> {\n #children: Node<C>[];\n\n /**\n * @param children Initial child nodes, in layout order.\n */\n constructor(children: Node<C>[]) {\n this.#children = [...children];\n replaceNodesParent([], this.#children, this);\n }\n\n /** Child nodes managed by this group. */\n get children(): readonly Node<C>[] {\n return this.#children;\n }\n\n /**\n * Replaces the full child list while updating parent links.\n */\n replaceChildren(nextChildren: Node<C>[]): void {\n const nextSnapshot = [...nextChildren];\n replaceNodesParent(this.#children, nextSnapshot, this);\n this.#children = nextSnapshot;\n }\n\n abstract measure(ctx: Context<C>): Box;\n abstract draw(ctx: Context<C>, x: number, y: number): boolean;\n abstract hittest(ctx: Context<C>, test: HitTest): boolean;\n}\n\n/**\n * A node that forwards layout and drawing to a single inner node.\n */\nexport class Wrapper<C extends CanvasRenderingContext2D> implements Node<C> {\n #inner: Node<C>;\n\n /**\n * @param inner Wrapped child node.\n */\n constructor(inner: Node<C>) {\n this.#inner = inner;\n attachNodeToParent(this.#inner, this);\n }\n\n /** The wrapped child node. */\n get inner(): Node<C> {\n return this.#inner;\n }\n\n /** Replaces the wrapped child node. */\n set inner(newNode: Node<C>) {\n if (newNode === this.#inner) {\n return;\n }\n replaceNodeParent(this.#inner, newNode, this);\n this.#inner = newNode;\n }\n\n measure(ctx: Context<C>): Box {\n return this.inner.measure(ctx);\n }\n\n measureMinContent(ctx: Context<C>): Box {\n return measureNodeMinContent(ctx, this.inner);\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return this.inner.draw(ctx, x, y);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n return this.inner.hittest(ctx, test);\n }\n}\n","import type { Box, ChildLayoutResult, FlexLayoutResult, LayoutConstraints, LayoutRect } from \"./types\";\n\n/**\n * 创建 LayoutRect 的辅助函数\n */\nexport function createRect(x: number, y: number, width: number, height: number): LayoutRect {\n return { x, y, width, height };\n}\n\n/**\n * 合并多个 rect 得到包含所有 rect 的最小外接矩形\n */\nexport function mergeRects(rects: LayoutRect[]): LayoutRect {\n if (rects.length === 0) {\n return createRect(0, 0, 0, 0);\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const rect of rects) {\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.width);\n maxY = Math.max(maxY, rect.y + rect.height);\n }\n\n return createRect(minX, minY, maxX - minX, maxY - minY);\n}\n\n/**\n * 从子节点布局结果计算容器的 contentBox\n */\nexport function computeContentBox<C extends CanvasRenderingContext2D>(\n children: ChildLayoutResult<C>[],\n): LayoutRect {\n return mergeRects(children.map((child) => child.contentBox));\n}\n\n/**\n * 根据约束和实际内容计算最终的 containerBox\n */\nexport function computeContainerBox(\n contentBox: LayoutRect,\n constraints?: LayoutConstraints,\n): LayoutRect {\n let width = contentBox.width;\n let height = contentBox.height;\n\n if (constraints?.minWidth != null) {\n width = Math.max(width, constraints.minWidth);\n }\n if (constraints?.maxWidth != null) {\n width = Math.min(width, constraints.maxWidth);\n }\n if (constraints?.minHeight != null) {\n height = Math.max(height, constraints.minHeight);\n }\n if (constraints?.maxHeight != null) {\n height = Math.min(height, constraints.maxHeight);\n }\n\n return createRect(contentBox.x, contentBox.y, width, height);\n}\n\n/**\n * 将 Box 转换为 LayoutRect(位置为 0,0)\n */\nexport function boxToRect(box: Box): LayoutRect {\n return createRect(0, 0, box.width, box.height);\n}\n\n/**\n * 检查点是否在 rect 内\n */\nexport function pointInRect(x: number, y: number, rect: LayoutRect): boolean {\n return x >= rect.x && x < rect.x + rect.width && y >= rect.y && y < rect.y + rect.height;\n}\n\n/**\n * 平移 rect 的位置\n */\nexport function offsetRect(rect: LayoutRect, dx: number, dy: number): LayoutRect {\n return createRect(rect.x + dx, rect.y + dy, rect.width, rect.height);\n}\n\n/**\n * 读取单子节点布局结果中的唯一 child。\n */\nexport function getSingleChildLayout<C extends CanvasRenderingContext2D>(\n layout: FlexLayoutResult<C>,\n): ChildLayoutResult<C> | undefined {\n return layout.children[0];\n}\n\n/**\n * 在布局结果中按指定盒模型查找命中的 child,并返回局部坐标。\n */\nexport function findChildAtPoint<C extends CanvasRenderingContext2D>(\n children: ChildLayoutResult<C>[],\n x: number,\n y: number,\n box: \"rect\" | \"contentBox\" = \"contentBox\",\n):\n | {\n child: ChildLayoutResult<C>;\n localX: number;\n localY: number;\n }\n | undefined {\n for (let i = children.length - 1; i >= 0; i -= 1) {\n const child = children[i]!;\n const target = box === \"rect\" ? child.rect : child.contentBox;\n if (!pointInRect(x, y, target)) {\n continue;\n }\n return {\n child,\n localX: x - target.x,\n localY: y - target.y,\n };\n }\n return undefined;\n}\n","import { findChildAtPoint } from \"../layout\";\nimport type { Context, FlexLayoutResult, HitTest, LayoutConstraints, Node } from \"../types\";\nimport { shallow } from \"../utils\";\n\ntype LayoutCacheAccess<C extends CanvasRenderingContext2D> = {\n getLayoutResult(node: Node<C>, constraints?: LayoutConstraints): FlexLayoutResult<C> | undefined;\n setLayoutResult(node: Node<C>, result: FlexLayoutResult<C>, constraints?: LayoutConstraints): void;\n};\n\ntype LayoutContext<C extends CanvasRenderingContext2D> = Context<C> & LayoutCacheAccess<C>;\n\nexport function withConstraints<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n constraints: LayoutConstraints | undefined,\n): Context<C> {\n const next = shallow(ctx);\n next.constraints = constraints;\n return next;\n}\n\nfunction getLayoutContext<C extends CanvasRenderingContext2D>(ctx: Context<C>): LayoutContext<C> {\n return ctx as LayoutContext<C>;\n}\n\nexport function readLayoutResult<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n): FlexLayoutResult<C> | undefined {\n return getLayoutContext(ctx).getLayoutResult(node, ctx.constraints);\n}\n\nexport function writeLayoutResult<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n result: FlexLayoutResult<C>,\n): void {\n getLayoutContext(ctx).setLayoutResult(node, result, ctx.constraints);\n}\n\nfunction ensureLayoutResult<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n): FlexLayoutResult<C> | undefined {\n return readLayoutResult(node, ctx);\n}\n\nexport function drawLayoutChildren<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n x: number,\n y: number,\n): boolean {\n const layoutResult = ensureLayoutResult(node, ctx);\n if (!layoutResult) {\n return false;\n }\n\n let result = false;\n for (const childResult of layoutResult.children) {\n const childDrawn = childResult.node.draw(\n withConstraints(ctx, childResult.constraints),\n x + childResult.contentBox.x,\n y + childResult.contentBox.y,\n );\n result = childDrawn || result;\n }\n return result;\n}\n\nexport function hittestLayoutChildren<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n test: HitTest,\n box: \"rect\" | \"contentBox\" = \"contentBox\",\n): boolean {\n const layoutResult = ensureLayoutResult(node, ctx);\n if (!layoutResult) {\n return false;\n }\n\n const hit = findChildAtPoint(layoutResult.children, test.x, test.y, box);\n if (!hit) {\n return false;\n }\n\n return hit.child.node.hittest(\n withConstraints(ctx, hit.child.constraints),\n {\n ...test,\n x: hit.localX,\n y: hit.localY,\n },\n );\n}\n","import { createRect, findChildAtPoint, getSingleChildLayout } from \"../layout\";\nimport type { Box, Context, HitTest, Node } from \"../types\";\nimport { measureNodeMinContent } from \"./base\";\nimport { Wrapper } from \"./base\";\nimport { readLayoutResult, withConstraints, writeLayoutResult } from \"./shared\";\n\nfunction clampToConstraints(value: number, min?: number, max?: number): number {\n let result = value;\n if (min != null) {\n result = Math.max(result, min);\n }\n if (max != null) {\n result = Math.min(result, max);\n }\n return result;\n}\n\nfunction shrinkConstraint(value: number | undefined, padding: number): number | undefined {\n if (value == null) {\n return undefined;\n }\n return Math.max(0, value - padding);\n}\n\n/**\n * Adds padding around a single child node.\n */\nexport class PaddingBox<C extends CanvasRenderingContext2D> extends Wrapper<C> {\n /**\n * @param inner Wrapped child node.\n * @param padding Padding in CSS pixels on each side.\n */\n constructor(\n inner: Node<C>,\n readonly padding: {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n } = {},\n ) {\n super(inner);\n }\n\n get #top(): number {\n return this.padding.top ?? 0;\n }\n\n get #bottom(): number {\n return this.padding.bottom ?? 0;\n }\n\n get #left(): number {\n return this.padding.left ?? 0;\n }\n\n get #right(): number {\n return this.padding.right ?? 0;\n }\n\n measure(ctx: Context<C>): Box {\n const paddingLeft = this.#left;\n const paddingRight = this.#right;\n const paddingTop = this.#top;\n const paddingBottom = this.#bottom;\n const horizontalPadding = paddingLeft + paddingRight;\n const verticalPadding = paddingTop + paddingBottom;\n const childConstraints = ctx.constraints\n ? {\n ...ctx.constraints,\n minWidth: shrinkConstraint(ctx.constraints.minWidth, horizontalPadding),\n maxWidth: shrinkConstraint(ctx.constraints.maxWidth, horizontalPadding),\n minHeight: shrinkConstraint(ctx.constraints.minHeight, verticalPadding),\n maxHeight: shrinkConstraint(ctx.constraints.maxHeight, verticalPadding),\n }\n : undefined;\n const { width, height } = ctx.measureNode(this.inner, childConstraints);\n const containerBox = createRect(\n 0,\n 0,\n clampToConstraints(width + horizontalPadding, ctx.constraints?.minWidth, ctx.constraints?.maxWidth),\n clampToConstraints(height + verticalPadding, ctx.constraints?.minHeight, ctx.constraints?.maxHeight),\n );\n const childRect = createRect(paddingLeft, paddingTop, width, height);\n writeLayoutResult(this, ctx, {\n containerBox,\n contentBox: childRect,\n children: [\n {\n node: this.inner,\n rect: childRect,\n contentBox: childRect,\n constraints: childConstraints,\n },\n ],\n constraints: ctx.constraints,\n });\n return {\n width: containerBox.width,\n height: containerBox.height,\n };\n }\n\n measureMinContent(ctx: Context<C>): Box {\n const paddingLeft = this.#left;\n const paddingRight = this.#right;\n const paddingTop = this.#top;\n const paddingBottom = this.#bottom;\n const horizontalPadding = paddingLeft + paddingRight;\n const verticalPadding = paddingTop + paddingBottom;\n const childConstraints = ctx.constraints\n ? {\n ...ctx.constraints,\n minWidth: shrinkConstraint(ctx.constraints.minWidth, horizontalPadding),\n maxWidth: shrinkConstraint(ctx.constraints.maxWidth, horizontalPadding),\n minHeight: shrinkConstraint(ctx.constraints.minHeight, verticalPadding),\n maxHeight: shrinkConstraint(ctx.constraints.maxHeight, verticalPadding),\n }\n : undefined;\n const { width, height } = measureNodeMinContent(ctx, this.inner, childConstraints);\n return {\n width: width + horizontalPadding,\n height: height + verticalPadding,\n };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n const layoutResult = readLayoutResult(this, ctx);\n if (!layoutResult) {\n return this.inner.draw(ctx, x + this.#left, y + this.#top);\n }\n\n const childResult = getSingleChildLayout(layoutResult);\n if (!childResult) {\n return false;\n }\n\n return childResult.node.draw(\n withConstraints(ctx, childResult.constraints),\n x + childResult.rect.x,\n y + childResult.rect.y,\n );\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n const layoutResult = readLayoutResult(this, ctx);\n if (!layoutResult) {\n return false;\n }\n\n const hit = findChildAtPoint(layoutResult.children, test.x, test.y, \"rect\");\n if (!hit) {\n return false;\n }\n\n return hit.child.node.hittest(\n withConstraints(ctx, hit.child.constraints),\n {\n ...test,\n x: hit.localX,\n y: hit.localY,\n },\n );\n }\n}\n\n/**\n * A leaf node with a fixed size and no drawing behavior.\n */\nexport class Fixed<C extends CanvasRenderingContext2D> implements Node<C> {\n /**\n * @param width Fixed width in CSS pixels.\n * @param height Fixed height in CSS pixels.\n */\n constructor(\n readonly width: number,\n readonly height: number,\n ) {}\n\n measure(_ctx: Context<C>): Box {\n return { width: this.width, height: this.height };\n }\n\n measureMinContent(_ctx: Context<C>): Box {\n return { width: this.width, height: this.height };\n }\n\n draw(_ctx: Context<C>, _x: number, _y: number): boolean {\n return false;\n }\n\n hittest(_ctx: Context<C>, _test: HitTest): boolean {\n return false;\n }\n}\n","import { computeContentBox, createRect } from \"../layout\";\nimport type {\n Axis,\n Box,\n ChildLayoutResult,\n Context,\n CrossAxisAlignment,\n FlexContainerOptions,\n FlexItemOptions,\n HitTest,\n LayoutConstraints,\n Node,\n} from \"../types\";\nimport { Group, measureNodeMinContent, Wrapper } from \"./base\";\nimport { drawLayoutChildren, hittestLayoutChildren, writeLayoutResult } from \"./shared\";\n\nfunction getMainSize(axis: Axis, box: Box): number {\n return axis === \"row\" ? box.width : box.height;\n}\n\nfunction getCrossSize(axis: Axis, box: Box): number {\n return axis === \"row\" ? box.height : box.width;\n}\n\nfunction getMinMain(axis: Axis, constraints?: LayoutConstraints): number | undefined {\n return axis === \"row\" ? constraints?.minWidth : constraints?.minHeight;\n}\n\nfunction getMaxMain(axis: Axis, constraints?: LayoutConstraints): number | undefined {\n return axis === \"row\" ? constraints?.maxWidth : constraints?.maxHeight;\n}\n\nfunction getMinCross(axis: Axis, constraints?: LayoutConstraints): number | undefined {\n return axis === \"row\" ? constraints?.minHeight : constraints?.minWidth;\n}\n\nfunction getMaxCross(axis: Axis, constraints?: LayoutConstraints): number | undefined {\n return axis === \"row\" ? constraints?.maxHeight : constraints?.maxWidth;\n}\n\nfunction createAxisConstraints(\n axis: Axis,\n constraints: LayoutConstraints | undefined,\n main: { min?: number; max?: number },\n cross: { min?: number; max?: number } = {},\n): LayoutConstraints | undefined {\n if (\n constraints == null &&\n main.min == null &&\n main.max == null &&\n cross.min == null &&\n cross.max == null\n ) {\n return undefined;\n }\n\n const next: LayoutConstraints = {\n ...constraints,\n };\n if (axis === \"row\") {\n next.minWidth = main.min;\n next.maxWidth = main.max;\n next.minHeight = cross.min;\n next.maxHeight = cross.max;\n } else {\n next.minHeight = main.min;\n next.maxHeight = main.max;\n next.minWidth = cross.min;\n next.maxWidth = cross.max;\n }\n return next;\n}\n\nfunction clampToConstraints(value: number, min?: number, max?: number): number {\n let result = value;\n if (min != null) {\n result = Math.max(result, min);\n }\n if (max != null) {\n result = Math.min(result, max);\n }\n return result;\n}\n\nfunction constraintsEqual(left: LayoutConstraints | undefined, right: LayoutConstraints | undefined): boolean {\n if (left === right) {\n return true;\n }\n if (left == null || right == null) {\n return left == null && right == null;\n }\n return left.minWidth === right.minWidth\n && left.maxWidth === right.maxWidth\n && left.minHeight === right.minHeight\n && left.maxHeight === right.maxHeight;\n}\n\nfunction getCrossAlignment(alignSelf: CrossAxisAlignment | \"auto\" | undefined, alignItems: CrossAxisAlignment): CrossAxisAlignment {\n if (alignSelf == null || alignSelf === \"auto\") {\n return alignItems;\n }\n return alignSelf;\n}\n\nfunction getJustifySpacing(\n justifyContent: NonNullable<FlexContainerOptions[\"justifyContent\"]>,\n freeSpace: number,\n itemCount: number,\n gap: number,\n): { leading: number; between: number } {\n switch (justifyContent) {\n case \"center\":\n return { leading: freeSpace / 2, between: gap };\n case \"end\":\n return { leading: freeSpace, between: gap };\n case \"space-between\":\n return {\n leading: 0,\n between: itemCount > 1 ? gap + freeSpace / (itemCount - 1) : gap,\n };\n case \"space-around\":\n return {\n leading: itemCount > 0 ? freeSpace / itemCount / 2 : 0,\n between: itemCount > 0 ? gap + freeSpace / itemCount : gap,\n };\n case \"space-evenly\":\n return {\n leading: itemCount > 0 ? freeSpace / (itemCount + 1) : 0,\n between: itemCount > 0 ? gap + freeSpace / (itemCount + 1) : gap,\n };\n case \"start\":\n default:\n return { leading: 0, between: gap };\n }\n}\n\nfunction getCrossOffset(align: CrossAxisAlignment, frameCross: number, contentCross: number): number {\n switch (align) {\n case \"center\":\n return (frameCross - contentCross) / 2;\n case \"end\":\n return frameCross - contentCross;\n case \"stretch\":\n case \"start\":\n default:\n return 0;\n }\n}\n\nfunction createRectFromAxis(axis: Axis, main: number, cross: number, mainSize: number, crossSize: number) {\n return axis === \"row\"\n ? createRect(main, cross, mainSize, crossSize)\n : createRect(cross, main, crossSize, mainSize);\n}\n\nconst SHRINK_EPSILON = 1e-6;\n\ntype FlexMeasurement<C extends CanvasRenderingContext2D> = {\n child: Node<C>;\n item: FlexItemOptions;\n basisMeasured: Box;\n measured: Box;\n basisConstraints?: LayoutConstraints;\n initialConstraints?: LayoutConstraints;\n finalConstraints?: LayoutConstraints;\n allocatedMain?: number;\n grow: number;\n shrink: number;\n effectiveAlign: CrossAxisAlignment;\n stretch: boolean;\n basis: number;\n minContentMain: number;\n finalMain: number;\n frozen: boolean;\n frameMain: number;\n frameCross: number;\n};\n\ntype MeasuredLayout<C extends CanvasRenderingContext2D> = {\n box: Box;\n layout: {\n containerBox: ChildLayoutResult<C>[\"rect\"];\n contentBox: ChildLayoutResult<C>[\"contentBox\"];\n children: ChildLayoutResult<C>[];\n constraints?: LayoutConstraints;\n };\n};\n\nfunction readFlexItemOptions<C extends CanvasRenderingContext2D>(child: Node<C>): FlexItemOptions {\n if (child instanceof FlexItem) {\n return child.item;\n }\n return {};\n}\n\nexport function computeFlexLayout<C extends CanvasRenderingContext2D>(\n children: readonly Node<C>[],\n options: FlexContainerOptions,\n constraints: LayoutConstraints | undefined,\n measureChild: (node: Node<C>, constraints?: LayoutConstraints) => Box,\n measureChildMinContent: (node: Node<C>, constraints?: LayoutConstraints) => Box,\n): MeasuredLayout<C> {\n const axis = options.direction ?? \"row\";\n const gap = options.gap ?? 0;\n const justifyContent = options.justifyContent ?? \"start\";\n const alignItems = options.alignItems ?? \"start\";\n const reverse = options.reverse ?? false;\n const mainAxisSize = options.mainAxisSize ?? \"fill\";\n const orderedChildren = reverse ? [...children].reverse() : children;\n const maxMain = getMaxMain(axis, constraints);\n const minMain = getMinMain(axis, constraints);\n const maxCross = getMaxCross(axis, constraints);\n const minCross = getMinCross(axis, constraints);\n const gapTotal = orderedChildren.length > 1 ? gap * (orderedChildren.length - 1) : 0;\n const finiteMain = maxMain != null;\n const finiteCross = maxCross != null;\n const availableMain = finiteMain ? Math.max(0, maxMain - gapTotal) : undefined;\n let totalGrow = 0;\n let totalBasis = 0;\n let nonGrowBasis = 0;\n const measurements = new Map<Node<C>, FlexMeasurement<C>>();\n const basisConstraints = createAxisConstraints(\n axis,\n constraints,\n {\n min: undefined,\n max: undefined,\n },\n {\n min: undefined,\n max: maxCross,\n },\n );\n\n for (const child of orderedChildren) {\n const item = readFlexItemOptions(child);\n const grow = item.grow ?? 0;\n const shrink = item.shrink ?? 0;\n totalGrow += grow;\n const effectiveAlign = getCrossAlignment(item.alignSelf, alignItems);\n const stretch = effectiveAlign === \"stretch\";\n const basisMeasured = measureChild(child, basisConstraints);\n const basis = getMainSize(axis, basisMeasured);\n\n totalBasis += basis;\n if (grow <= 0) {\n nonGrowBasis += basis;\n }\n\n measurements.set(child, {\n child,\n item,\n basisMeasured,\n measured: basisMeasured,\n basisConstraints,\n initialConstraints: basisConstraints,\n finalConstraints: basisConstraints,\n allocatedMain: undefined,\n grow,\n shrink,\n effectiveAlign,\n stretch,\n basis,\n minContentMain: basis,\n finalMain: basis,\n frozen: false,\n frameMain: basis,\n frameCross: getCrossSize(axis, basisMeasured),\n });\n }\n\n const entersShrinkPath = finiteMain && availableMain != null && totalBasis - availableMain > SHRINK_EPSILON;\n\n if (entersShrinkPath) {\n const totalDeficit = totalBasis - availableMain!;\n let remainingDeficit = totalDeficit;\n\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n const minContentMeasured = measureChildMinContent(child, measurement.basisConstraints);\n measurement.minContentMain = Math.min(measurement.basis, getMainSize(axis, minContentMeasured));\n measurement.finalMain = measurement.basis;\n measurement.frozen = measurement.shrink <= 0 || measurement.basis - measurement.minContentMain <= SHRINK_EPSILON;\n }\n\n while (remainingDeficit > SHRINK_EPSILON) {\n const active = orderedChildren\n .map((child) => measurements.get(child)!)\n .filter((measurement) => !measurement.frozen && measurement.shrink > 0);\n const totalScaled = active.reduce((sum, measurement) => sum + measurement.shrink * measurement.basis, 0);\n\n if (active.length === 0 || totalScaled <= SHRINK_EPSILON) {\n break;\n }\n\n let frozeAny = false;\n for (const measurement of active) {\n const tentative = measurement.basis - remainingDeficit * ((measurement.shrink * measurement.basis) / totalScaled);\n if (tentative <= measurement.minContentMain + SHRINK_EPSILON) {\n measurement.finalMain = measurement.minContentMain;\n measurement.frozen = true;\n frozeAny = true;\n } else {\n measurement.finalMain = tentative;\n }\n }\n\n if (!frozeAny) {\n remainingDeficit = 0;\n break;\n }\n\n let absorbedDeficit = 0;\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n if (measurement.frozen) {\n absorbedDeficit += Math.max(0, measurement.basis - measurement.finalMain);\n }\n }\n remainingDeficit = Math.max(0, totalDeficit - absorbedDeficit);\n }\n\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n measurement.measured = measurement.basisMeasured;\n measurement.initialConstraints = measurement.basisConstraints;\n measurement.finalConstraints = createAxisConstraints(\n axis,\n constraints,\n {\n min: undefined,\n max: measurement.finalMain,\n },\n {\n min: undefined,\n max: maxCross,\n },\n );\n measurement.allocatedMain = undefined;\n measurement.frameMain = measurement.finalMain;\n measurement.frameCross = getCrossSize(axis, measurement.measured);\n }\n } else {\n const remainingMain = finiteMain && availableMain != null ? Math.max(0, availableMain - nonGrowBasis) : undefined;\n\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n if (!(measurement.grow > 0 && finiteMain && remainingMain != null && totalGrow > 0)) {\n measurement.measured = measurement.basisMeasured;\n measurement.initialConstraints = measurement.basisConstraints;\n measurement.finalConstraints = finiteMain\n ? createAxisConstraints(\n axis,\n constraints,\n {\n min: undefined,\n max: measurement.finalMain,\n },\n {\n min: undefined,\n max: maxCross,\n },\n )\n : measurement.basisConstraints;\n measurement.allocatedMain = undefined;\n measurement.finalMain = measurement.basis;\n measurement.frameMain = measurement.basis;\n measurement.frameCross = getCrossSize(axis, measurement.measured);\n continue;\n }\n\n const allocatedMain = (remainingMain * measurement.grow) / totalGrow;\n const childConstraints = createAxisConstraints(\n axis,\n constraints,\n {\n max: allocatedMain,\n },\n {\n min: undefined,\n max: maxCross,\n },\n );\n const measured = measureChild(child, childConstraints);\n measurement.measured = measured;\n measurement.initialConstraints = childConstraints;\n measurement.finalConstraints = childConstraints;\n measurement.allocatedMain = allocatedMain;\n measurement.finalMain = allocatedMain;\n measurement.frameMain = allocatedMain;\n measurement.frameCross = getCrossSize(axis, measured);\n }\n }\n\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n if (!constraintsEqual(measurement.initialConstraints, measurement.finalConstraints)) {\n measurement.measured = measureChild(child, measurement.finalConstraints);\n }\n measurement.frameMain = measurement.finalMain;\n measurement.frameCross = getCrossSize(axis, measurement.measured);\n }\n\n let contentMain = gapTotal;\n let contentCross = 0;\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n contentMain += measurement.frameMain;\n contentCross = Math.max(contentCross, measurement.frameCross);\n }\n\n const containerMain = finiteMain && mainAxisSize === \"fill\"\n ? Math.max(maxMain!, contentMain)\n : clampToConstraints(contentMain, minMain, maxMain);\n const containerCross = clampToConstraints(contentCross, minCross, maxCross);\n if (finiteCross) {\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n if (!measurement.stretch) {\n continue;\n }\n\n const finalConstraints = createAxisConstraints(\n axis,\n measurement.finalConstraints,\n {\n min: getMinMain(axis, measurement.finalConstraints),\n max: getMaxMain(axis, measurement.finalConstraints),\n },\n {\n min: containerCross,\n max: containerCross,\n },\n );\n const remeasured = measureChild(child, finalConstraints);\n measurement.measured = remeasured;\n measurement.finalConstraints = finalConstraints;\n measurement.frameCross = containerCross;\n measurement.frameMain = measurement.allocatedMain ?? getMainSize(axis, remeasured);\n }\n\n contentMain = gapTotal;\n contentCross = 0;\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n contentMain += measurement.frameMain;\n contentCross = Math.max(contentCross, getCrossSize(axis, measurement.measured));\n }\n }\n\n const finalContainerMain = finiteMain && mainAxisSize === \"fill\"\n ? Math.max(maxMain!, contentMain)\n : clampToConstraints(contentMain, minMain, maxMain);\n const freeSpace = Math.max(0, finalContainerMain - contentMain);\n const spacing = getJustifySpacing(justifyContent, freeSpace, orderedChildren.length, gap);\n const childResults: ChildLayoutResult<C>[] = [];\n let cursor = spacing.leading;\n\n for (const child of orderedChildren) {\n const measurement = measurements.get(child)!;\n const frameCross = measurement.stretch && finiteCross ? containerCross : measurement.frameCross;\n const contentMainSize = getMainSize(axis, measurement.measured);\n const contentCrossSize = getCrossSize(axis, measurement.measured);\n const rectCross = measurement.stretch ? 0 : getCrossOffset(measurement.effectiveAlign, containerCross, frameCross);\n const contentCrossOffset = rectCross + getCrossOffset(measurement.effectiveAlign, frameCross, contentCrossSize);\n const rect = createRectFromAxis(axis, cursor, rectCross, measurement.frameMain, frameCross);\n const contentBox = createRectFromAxis(axis, cursor, contentCrossOffset, contentMainSize, contentCrossSize);\n\n childResults.push({\n node: child,\n rect,\n contentBox,\n constraints: measurement.finalConstraints,\n });\n cursor += measurement.frameMain + spacing.between;\n }\n\n const containerBox = axis === \"row\"\n ? createRect(0, 0, finalContainerMain, containerCross)\n : createRect(0, 0, containerCross, finalContainerMain);\n const finalContentBox = childResults.length > 0\n ? computeContentBox(childResults)\n : createRect(0, 0, 0, 0);\n\n return {\n box: {\n width: containerBox.width,\n height: containerBox.height,\n },\n layout: {\n containerBox,\n contentBox: finalContentBox,\n children: childResults,\n constraints,\n },\n };\n}\n\n/**\n * Wraps a child node with per-item flex options.\n */\nexport class FlexItem<C extends CanvasRenderingContext2D> extends Wrapper<C> {\n /**\n * @param inner Wrapped child node.\n * @param item Flex behavior overrides for the child.\n */\n constructor(\n inner: Node<C>,\n readonly item: FlexItemOptions = {},\n ) {\n super(inner);\n }\n}\n\n/**\n * Lays out children in a single flex row or column.\n */\nexport class Flex<C extends CanvasRenderingContext2D> extends Group<C> {\n /**\n * @param children Child nodes in visual order.\n * @param options Flex container configuration.\n */\n constructor(\n children: Node<C>[],\n readonly options: FlexContainerOptions = {},\n ) {\n super(children);\n }\n\n measure(ctx: Context<C>): Box {\n const result = computeFlexLayout(\n this.children,\n this.options,\n ctx.constraints,\n (node, constraints) => ctx.measureNode(node, constraints),\n (node, constraints) => measureNodeMinContent(ctx, node, constraints),\n );\n writeLayoutResult(this, ctx, result.layout);\n return result.box;\n }\n\n measureMinContent(ctx: Context<C>): Box {\n const axis = this.options.direction ?? \"row\";\n const gap = this.options.gap ?? 0;\n const orderedChildren = this.options.reverse ? [...this.children].reverse() : this.children;\n const gapTotal = orderedChildren.length > 1 ? gap * (orderedChildren.length - 1) : 0;\n const childConstraints = createAxisConstraints(\n axis,\n ctx.constraints,\n {\n min: undefined,\n max: undefined,\n },\n {\n min: undefined,\n max: getMaxCross(axis, ctx.constraints),\n },\n );\n\n let width = axis === \"row\" ? gapTotal : 0;\n let height = axis === \"column\" ? gapTotal : 0;\n\n for (const child of orderedChildren) {\n const measured = measureNodeMinContent(ctx, child, childConstraints);\n if (axis === \"row\") {\n width += measured.width;\n height = Math.max(height, measured.height);\n } else {\n width = Math.max(width, measured.width);\n height += measured.height;\n }\n }\n\n return { width, height };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return drawLayoutChildren(this, ctx, x, y);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n return hittestLayoutChildren(this, ctx, test, \"contentBox\");\n }\n}\n","import { createRect, findChildAtPoint, getSingleChildLayout } from \"../layout\";\nimport type { Box, Context, HitTest, Node, TextAlign } from \"../types\";\nimport { measureNodeMinContent, Wrapper } from \"./base\";\nimport { readLayoutResult, withConstraints, writeLayoutResult } from \"./shared\";\n\nfunction resolveHorizontalOffset(align: TextAlign, availableWidth: number, childWidth: number): number {\n switch (align) {\n case \"center\":\n return (availableWidth - childWidth) / 2;\n case \"end\":\n return availableWidth - childWidth;\n case \"start\":\n return 0;\n }\n}\n\n/**\n * Aligns a single child horizontally within the available width.\n */\nexport class Place<C extends CanvasRenderingContext2D> extends Wrapper<C> {\n /**\n * @param inner Wrapped child node.\n * @param options Alignment behavior for the child.\n */\n constructor(\n inner: Node<C>,\n readonly options: {\n align?: TextAlign;\n expand?: boolean;\n } = {},\n ) {\n super(inner);\n }\n\n measure(ctx: Context<C>): Box {\n const availableWidth = ctx.constraints?.maxWidth;\n const expand = this.options.expand ?? true;\n const childConstraints = ctx.constraints\n ? {\n ...ctx.constraints,\n }\n : undefined;\n const childBox = ctx.measureNode(this.inner, childConstraints);\n let width = expand && availableWidth != null ? availableWidth : childBox.width;\n if (ctx.constraints?.minWidth != null) {\n width = Math.max(width, ctx.constraints.minWidth);\n }\n if (ctx.constraints?.maxWidth != null) {\n width = Math.min(width, ctx.constraints.maxWidth);\n }\n\n const align = this.options.align ?? \"start\";\n const childRect = createRect(resolveHorizontalOffset(align, width, childBox.width), 0, childBox.width, childBox.height);\n\n writeLayoutResult(this, ctx, {\n containerBox: createRect(0, 0, width, childBox.height),\n contentBox: childRect,\n children: [\n {\n node: this.inner,\n rect: childRect,\n contentBox: createRect(0, 0, childBox.width, childBox.height),\n constraints: childConstraints,\n },\n ],\n constraints: ctx.constraints,\n });\n\n return {\n width,\n height: childBox.height,\n };\n }\n\n measureMinContent(ctx: Context<C>): Box {\n return measureNodeMinContent(ctx, this.inner);\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n const layoutResult = readLayoutResult(this, ctx);\n if (!layoutResult) {\n return this.inner.draw(ctx, x, y);\n }\n\n const childResult = getSingleChildLayout(layoutResult);\n if (!childResult) {\n return false;\n }\n const childCtx = withConstraints(ctx, childResult.constraints);\n return childResult.node.draw(childCtx, x + childResult.rect.x, y + childResult.rect.y);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n const layoutResult = readLayoutResult(this, ctx);\n if (!layoutResult) {\n return false;\n }\n\n const hit = findChildAtPoint(layoutResult.children, test.x, test.y, \"rect\");\n if (!hit) {\n return false;\n }\n\n return hit.child.node.hittest(\n withConstraints(ctx, hit.child.constraints),\n {\n ...test,\n x: hit.localX,\n y: hit.localY,\n },\n );\n }\n}\n","import {\n layoutNextLine,\n layoutWithLines,\n measureLineStats,\n measureNaturalWidth,\n prepareWithSegments,\n type PreparedTextWithSegments,\n} from \"@chenglou/pretext\";\nimport type {\n Context,\n TextEllipsisPosition,\n TextOverflowMode,\n TextOverflowWrapMode,\n TextWhiteSpaceMode,\n} from \"./types\";\n\nexport interface TextLayout {\n width: number;\n text: string;\n shift: number;\n}\n\nexport interface TextMeasurement {\n width: number;\n lineCount: number;\n}\n\nexport interface OverflowTextLayout extends TextLayout {\n overflowed: boolean;\n}\n\nexport interface OverflowTextBlockLayout {\n width: number;\n lines: OverflowTextLayout[];\n overflowed: boolean;\n}\n\n// `fontBoundingBox*` depends on the active font, so one fixed probe is enough.\nconst FONT_SHIFT_PROBE = \"M\";\nconst ELLIPSIS_GLYPH = \"…\";\nconst INTRINSIC_MAX_WIDTH = Number.POSITIVE_INFINITY;\nconst PREPARED_TEXT_CACHE_CAPACITY = 512;\nconst FONT_SHIFT_CACHE_CAPACITY = 64;\nconst ELLIPSIS_WIDTH_CACHE_CAPACITY = 64;\nconst LINE_START_CURSOR = { segmentIndex: 0, graphemeIndex: 0 } as const;\nconst MIN_CONTENT_WIDTH_EPSILON = 0.001;\n\nconst preparedTextCache = new Map<string, PreparedTextWithSegments>();\nconst fontShiftCache = new Map<string, number>();\nconst ellipsisWidthCache = new Map<string, number>();\nconst preparedUnitCache = new WeakMap<PreparedTextWithSegments, PreparedTextUnit[]>();\n\ntype PreparedTextUnit = {\n text: string;\n width: number;\n};\n\nlet sharedGraphemeSegmenter: Intl.Segmenter | null | undefined;\n\nfunction readLruValue<T>(cache: Map<string, T>, key: string): T | undefined {\n const cached = cache.get(key);\n if (cached == null) {\n return undefined;\n }\n cache.delete(key);\n cache.set(key, cached);\n return cached;\n}\n\nfunction writeLruValue<T>(cache: Map<string, T>, key: string, value: T, capacity: number): T {\n if (cache.has(key)) {\n cache.delete(key);\n } else if (cache.size >= capacity) {\n const firstKey = cache.keys().next().value;\n if (firstKey != null) {\n cache.delete(firstKey);\n }\n }\n cache.set(key, value);\n return value;\n}\n\nfunction getPreparedTextCacheKey(text: string, font: string, whiteSpace: TextWhiteSpaceMode): string {\n return `${font}\\u0000${whiteSpace}\\u0000${text}`;\n}\n\nfunction readPreparedText(text: string, font: string, whiteSpace: TextWhiteSpaceMode): PreparedTextWithSegments {\n const key = getPreparedTextCacheKey(text, font, whiteSpace);\n const cached = readLruValue(preparedTextCache, key);\n if (cached != null) {\n return cached;\n }\n return writeLruValue(\n preparedTextCache,\n key,\n prepareWithSegments(text, font, { whiteSpace }),\n PREPARED_TEXT_CACHE_CAPACITY,\n );\n}\n\nfunction readPreparedFirstLine<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n whiteSpace: TextWhiteSpaceMode,\n): { text: string; prepared: PreparedTextWithSegments } | undefined {\n const prepared = readPreparedText(text, ctx.graphics.font, whiteSpace);\n const line = layoutNextLine(prepared, LINE_START_CURSOR, INTRINSIC_MAX_WIDTH);\n if (line == null) {\n return undefined;\n }\n return {\n text: line.text,\n prepared: readPreparedText(line.text, ctx.graphics.font, whiteSpace),\n };\n}\n\nfunction measureFontShift<C extends CanvasRenderingContext2D>(ctx: Context<C>): number {\n const font = ctx.graphics.font;\n const cached = readLruValue(fontShiftCache, font);\n if (cached != null) {\n return cached;\n }\n const {\n fontBoundingBoxAscent: ascent = 0,\n fontBoundingBoxDescent: descent = 0,\n } = ctx.graphics.measureText(FONT_SHIFT_PROBE);\n return writeLruValue(fontShiftCache, font, ascent - descent, FONT_SHIFT_CACHE_CAPACITY);\n}\n\nfunction measurePreparedMinContentWidth(\n prepared: PreparedTextWithSegments,\n overflowWrap: TextOverflowWrapMode = \"break-word\",\n): number {\n let maxWidth = 0;\n let maxAnyWidth = 0;\n for (let i = 0; i < prepared.widths.length; i += 1) {\n const segmentWidth = prepared.widths[i] ?? 0;\n maxAnyWidth = Math.max(maxAnyWidth, segmentWidth);\n const segment = prepared.segments[i];\n if (segment != null && segment.trim().length > 0) {\n const breakableWidths = prepared.breakableFitAdvances[i];\n const minContentWidth = overflowWrap === \"anywhere\" && breakableWidths != null && breakableWidths.length > 0\n ? breakableWidths.reduce((widest, width) => Math.max(widest, width), 0)\n : segmentWidth;\n maxWidth = Math.max(maxWidth, minContentWidth);\n }\n }\n return maxWidth > 0 ? maxWidth : maxAnyWidth;\n}\n\nfunction getGraphemeSegmenter(): Intl.Segmenter | null {\n if (sharedGraphemeSegmenter !== undefined) {\n return sharedGraphemeSegmenter;\n }\n sharedGraphemeSegmenter = typeof Intl.Segmenter === \"function\"\n ? new Intl.Segmenter(undefined, { granularity: \"grapheme\" })\n : null;\n return sharedGraphemeSegmenter;\n}\n\nfunction splitGraphemes(text: string): string[] {\n const segmenter = getGraphemeSegmenter();\n if (segmenter == null) {\n return Array.from(text);\n }\n const graphemes: string[] = [];\n for (const part of segmenter.segment(text)) {\n graphemes.push(part.segment);\n }\n return graphemes;\n}\n\nfunction getPreparedUnits(prepared: PreparedTextWithSegments): PreparedTextUnit[] {\n const cached = preparedUnitCache.get(prepared);\n if (cached != null) {\n return cached;\n }\n\n const units: PreparedTextUnit[] = [];\n for (let i = 0; i < prepared.segments.length; i += 1) {\n const segment = prepared.segments[i] ?? \"\";\n const segmentWidth = prepared.widths[i] ?? 0;\n const breakableWidths = prepared.breakableFitAdvances[i];\n if (breakableWidths != null && segment.length > 0) {\n const graphemes = splitGraphemes(segment);\n if (graphemes.length === breakableWidths.length) {\n for (let j = 0; j < graphemes.length; j += 1) {\n units.push({ text: graphemes[j] ?? \"\", width: breakableWidths[j] ?? 0 });\n }\n continue;\n }\n }\n\n if (segment.length > 0 || segmentWidth > 0) {\n units.push({ text: segment, width: segmentWidth });\n }\n }\n\n preparedUnitCache.set(prepared, units);\n return units;\n}\n\nfunction buildUnitPrefixWidths(units: PreparedTextUnit[]): number[] {\n const widths = [0];\n let total = 0;\n for (const unit of units) {\n total += unit.width;\n widths.push(total);\n }\n return widths;\n}\n\nfunction buildUnitSuffixWidths(units: PreparedTextUnit[]): number[] {\n const widths = [0];\n let total = 0;\n for (let i = units.length - 1; i >= 0; i -= 1) {\n total += units[i]?.width ?? 0;\n widths.push(total);\n }\n return widths;\n}\n\nfunction findMaxFittingCount(cumulativeWidths: number[], maxWidth: number): number {\n if (maxWidth <= 0) {\n return 0;\n }\n let low = 0;\n let high = cumulativeWidths.length - 1;\n while (low < high) {\n const mid = Math.floor((low + high + 1) / 2);\n if ((cumulativeWidths[mid] ?? 0) <= maxWidth) {\n low = mid;\n } else {\n high = mid - 1;\n }\n }\n return low;\n}\n\nfunction joinUnitText(units: PreparedTextUnit[], start: number, end: number): string {\n if (start >= end) {\n return \"\";\n }\n return units.slice(start, end).map((unit) => unit.text).join(\"\");\n}\n\nfunction measureEllipsisWidth<C extends CanvasRenderingContext2D>(ctx: Context<C>): number {\n const font = ctx.graphics.font;\n const cached = readLruValue(ellipsisWidthCache, font);\n if (cached != null) {\n return cached;\n }\n return writeLruValue(\n ellipsisWidthCache,\n font,\n ctx.graphics.measureText(ELLIPSIS_GLYPH).width,\n ELLIPSIS_WIDTH_CACHE_CAPACITY,\n );\n}\n\nfunction createEllipsisOnlyLayout<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n maxWidth: number,\n shift: number,\n): OverflowTextLayout {\n const ellipsisWidth = measureEllipsisWidth(ctx);\n if (ellipsisWidth > maxWidth) {\n return { width: 0, text: \"\", shift, overflowed: true };\n }\n return { width: ellipsisWidth, text: ELLIPSIS_GLYPH, shift, overflowed: true };\n}\n\nfunction layoutPreparedEllipsis<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n prepared: PreparedTextWithSegments,\n text: string,\n maxWidth: number,\n shift: number,\n position: TextEllipsisPosition,\n forceEllipsis = false,\n): OverflowTextLayout {\n const intrinsicWidth = measureNaturalWidth(prepared);\n if (!forceEllipsis && intrinsicWidth <= maxWidth) {\n return { width: intrinsicWidth, text, shift, overflowed: false };\n }\n\n const ellipsisWidth = measureEllipsisWidth(ctx);\n if (ellipsisWidth > maxWidth) {\n return { width: 0, text: \"\", shift, overflowed: true };\n }\n\n const units = getPreparedUnits(prepared);\n if (units.length === 0) {\n return createEllipsisOnlyLayout(ctx, maxWidth, shift);\n }\n\n const availableWidth = Math.max(0, maxWidth - ellipsisWidth);\n const prefixWidths = buildUnitPrefixWidths(units);\n const suffixWidths = buildUnitSuffixWidths(units);\n\n let prefixCount = 0;\n let suffixCount = 0;\n switch (position) {\n case \"start\":\n suffixCount = Math.min(units.length, findMaxFittingCount(suffixWidths, availableWidth));\n break;\n case \"middle\": {\n let bestVisibleUnits = -1;\n let bestBalanceScore = Number.NEGATIVE_INFINITY;\n for (let nextPrefixCount = 0; nextPrefixCount <= units.length; nextPrefixCount += 1) {\n const prefixWidth = prefixWidths[nextPrefixCount] ?? 0;\n if (prefixWidth > availableWidth) {\n break;\n }\n const remainingWidth = availableWidth - prefixWidth;\n const maxSuffixCount = units.length - nextPrefixCount;\n const nextSuffixCount = Math.min(maxSuffixCount, findMaxFittingCount(suffixWidths, remainingWidth));\n const visibleUnits = nextPrefixCount + nextSuffixCount;\n const balanceScore = -Math.abs(nextPrefixCount - nextSuffixCount);\n if (\n visibleUnits > bestVisibleUnits ||\n (visibleUnits === bestVisibleUnits && balanceScore > bestBalanceScore) ||\n (visibleUnits === bestVisibleUnits && balanceScore === bestBalanceScore && nextPrefixCount > prefixCount)\n ) {\n prefixCount = nextPrefixCount;\n suffixCount = nextSuffixCount;\n bestVisibleUnits = visibleUnits;\n bestBalanceScore = balanceScore;\n }\n }\n break;\n }\n case \"end\":\n prefixCount = Math.min(units.length, findMaxFittingCount(prefixWidths, availableWidth));\n break;\n }\n\n const prefixWidth = prefixWidths[prefixCount] ?? 0;\n const suffixWidth = suffixWidths[suffixCount] ?? 0;\n const prefixText = joinUnitText(units, 0, prefixCount);\n const suffixText = joinUnitText(units, units.length - suffixCount, units.length);\n\n return {\n width: prefixWidth + ellipsisWidth + suffixWidth,\n text: `${prefixText}${ELLIPSIS_GLYPH}${suffixText}`,\n shift,\n overflowed: true,\n };\n}\n\nfunction normalizeMaxLines(maxLines: number | undefined): number | undefined {\n if (maxLines == null || !Number.isFinite(maxLines)) {\n return undefined;\n }\n return Math.max(1, Math.trunc(maxLines));\n}\n\nexport function layoutFirstLineIntrinsic<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n whiteSpace: TextWhiteSpaceMode = \"normal\",\n): TextLayout {\n const firstLine = readPreparedFirstLine(ctx, text, whiteSpace);\n if (firstLine == null) {\n return { width: 0, text: \"\", shift: 0 };\n }\n const shift = measureFontShift(ctx);\n return {\n width: measureNaturalWidth(firstLine.prepared),\n text: firstLine.text,\n shift,\n };\n}\n\nexport function measureTextIntrinsic<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n whiteSpace: TextWhiteSpaceMode = \"normal\",\n): TextMeasurement {\n const prepared = readPreparedText(text, ctx.graphics.font, whiteSpace);\n const { maxLineWidth: width, lineCount } = measureLineStats(prepared, INTRINSIC_MAX_WIDTH);\n if (lineCount === 0) {\n return { width: 0, lineCount: 0 };\n }\n return { width, lineCount };\n}\n\nexport function layoutTextIntrinsic<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n whiteSpace: TextWhiteSpaceMode = \"normal\",\n): { width: number; lines: TextLayout[] } {\n const intrinsic = layoutWithLines(readPreparedText(text, ctx.graphics.font, whiteSpace), INTRINSIC_MAX_WIDTH, 0);\n if (intrinsic.lines.length === 0) {\n return { width: 0, lines: [] };\n }\n\n const shift = measureFontShift(ctx);\n const lines = intrinsic.lines.map((line) => ({ width: line.width, text: line.text, shift }));\n const width = lines.reduce((maxLineWidth, line) => Math.max(maxLineWidth, line.width), 0);\n\n return { width, lines };\n}\n\nexport function layoutFirstLine<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n whiteSpace: TextWhiteSpaceMode = \"normal\",\n): TextLayout {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n const shift = measureFontShift(ctx);\n if (maxWidth === 0) {\n return { width: 0, text: \"\", shift };\n }\n const prepared = readPreparedText(text, ctx.graphics.font, whiteSpace);\n const line = layoutNextLine(prepared, LINE_START_CURSOR, maxWidth);\n if (line == null) {\n return { width: 0, text: \"\", shift };\n }\n return { width: line.width, text: line.text, shift };\n}\n\nexport function layoutEllipsizedFirstLine<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n ellipsisPosition: TextEllipsisPosition = \"end\",\n whiteSpace: TextWhiteSpaceMode = \"normal\",\n): OverflowTextLayout {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n const firstLine = readPreparedFirstLine(ctx, text, whiteSpace);\n if (firstLine == null) {\n return { width: 0, text: \"\", shift: 0, overflowed: false };\n }\n const shift = measureFontShift(ctx);\n if (maxWidth === 0) {\n return { width: 0, text: \"\", shift, overflowed: true };\n }\n return layoutPreparedEllipsis(ctx, firstLine.prepared, firstLine.text, maxWidth, shift, ellipsisPosition);\n}\n\nfunction layoutForcedEllipsizedLine<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n shift: number,\n whiteSpace: TextWhiteSpaceMode = \"normal\",\n): OverflowTextLayout {\n if (text.length === 0) {\n return createEllipsisOnlyLayout(ctx, maxWidth, shift);\n }\n const prepared = readPreparedText(text, ctx.graphics.font, whiteSpace);\n return layoutPreparedEllipsis(ctx, prepared, text, maxWidth, shift, \"end\", true);\n}\n\nexport function measureText<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n whiteSpace: TextWhiteSpaceMode = \"normal\",\n): TextMeasurement {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n if (maxWidth === 0) {\n return { width: 0, lineCount: 0 };\n }\n\n const prepared = readPreparedText(text, ctx.graphics.font, whiteSpace);\n const { maxLineWidth: width, lineCount } = measureLineStats(prepared, maxWidth);\n\n return { width, lineCount };\n}\n\nexport function measureTextMinContent<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n whiteSpace: TextWhiteSpaceMode = \"normal\",\n overflowWrap: TextOverflowWrapMode = \"break-word\",\n): TextMeasurement {\n const prepared = readPreparedText(text, ctx.graphics.font, whiteSpace);\n if (prepared.widths.length === 0) {\n return { width: 0, lineCount: 0 };\n }\n\n const width = measurePreparedMinContentWidth(prepared, overflowWrap);\n const lineMaxWidth = Math.max(width, MIN_CONTENT_WIDTH_EPSILON);\n const { lineCount } = measureLineStats(prepared, lineMaxWidth);\n\n return { width, lineCount };\n}\n\nexport function layoutText<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n whiteSpace: TextWhiteSpaceMode = \"normal\",\n): { width: number; lines: TextLayout[] } {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n if (maxWidth === 0) {\n return { width: 0, lines: [] };\n }\n\n const layout = layoutWithLines(readPreparedText(text, ctx.graphics.font, whiteSpace), maxWidth, 0);\n if (layout.lines.length === 0) {\n return { width: 0, lines: [] };\n }\n\n const shift = measureFontShift(ctx);\n const lines = layout.lines.map((line) => ({ width: line.width, text: line.text, shift }));\n const width = lines.reduce((maxLineWidth, line) => Math.max(maxLineWidth, line.width), 0);\n\n return { width, lines };\n}\n\nexport function layoutTextWithOverflow<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n options: {\n whiteSpace?: TextWhiteSpaceMode;\n overflow?: TextOverflowMode;\n maxLines?: number;\n } = {},\n): OverflowTextBlockLayout {\n const whiteSpace = options.whiteSpace ?? \"normal\";\n const overflow = options.overflow ?? \"clip\";\n const normalizedMaxLines = normalizeMaxLines(options.maxLines);\n\n const layout = layoutText(ctx, text, maxWidth, whiteSpace);\n if (normalizedMaxLines == null || layout.lines.length <= normalizedMaxLines) {\n return {\n width: layout.width,\n lines: layout.lines.map((line) => ({ ...line, overflowed: false })),\n overflowed: false,\n };\n }\n\n const visibleLines = layout.lines.slice(0, normalizedMaxLines);\n if (overflow !== \"ellipsis\") {\n return {\n width: visibleLines.reduce((lineWidth, line) => Math.max(lineWidth, line.width), 0),\n lines: visibleLines.map((line) => ({ ...line, overflowed: false })),\n overflowed: true,\n };\n }\n\n const shift = visibleLines[visibleLines.length - 1]?.shift ?? measureFontShift(ctx);\n const lastVisibleLine = visibleLines[visibleLines.length - 1];\n const ellipsizedLastLine = lastVisibleLine == null || lastVisibleLine.text.length === 0\n ? createEllipsisOnlyLayout(ctx, Math.max(0, maxWidth), shift)\n : layoutForcedEllipsizedLine(ctx, lastVisibleLine.text, maxWidth, shift, whiteSpace);\n\n const lines = [\n ...visibleLines.slice(0, -1).map((line) => ({ ...line, overflowed: false })),\n { ...ellipsizedLastLine, shift },\n ];\n return {\n width: lines.reduce((lineWidth, line) => Math.max(lineWidth, line.width), 0),\n lines,\n overflowed: true,\n };\n}\n","import {\n layoutEllipsizedFirstLine,\n layoutFirstLine,\n layoutFirstLineIntrinsic,\n layoutText,\n layoutTextIntrinsic,\n layoutTextWithOverflow,\n measureText,\n measureTextMinContent,\n measureTextIntrinsic,\n type TextLayout,\n type TextMeasurement,\n} from \"../text\";\nimport type { Box, Context, MultilineTextOptions, Node, PhysicalTextAlign, TextOptions } from \"../types\";\n\ntype SingleLineLayout = TextLayout;\ntype MultiLineDrawLayout = {\n width: number;\n lines: TextLayout[];\n};\ntype MultiLineMeasureLayout = TextMeasurement;\n\ntype TextLayoutCacheAccess<C extends CanvasRenderingContext2D> = {\n getTextLayout<T>(node: Node<C>, key: string): T | undefined;\n setTextLayout<T>(node: Node<C>, key: string, layout: T): void;\n};\n\nfunction resolvePhysicalTextAlign(\n options: Pick<MultilineTextOptions<any>, \"align\" | \"physicalAlign\">,\n): PhysicalTextAlign {\n if (options.physicalAlign != null) {\n return options.physicalAlign;\n }\n if (options.align != null) {\n switch (options.align) {\n case \"start\":\n return \"left\";\n case \"center\":\n return \"center\";\n case \"end\":\n return \"right\";\n }\n }\n return \"left\";\n}\n\nfunction normalizeTextMaxWidth(maxWidth: number | undefined): number | undefined {\n if (maxWidth == null) {\n return undefined;\n }\n return Math.max(0, maxWidth);\n}\n\nfunction getTextLayoutContext<C extends CanvasRenderingContext2D>(ctx: Context<C>): Context<C> & TextLayoutCacheAccess<C> {\n return ctx as Context<C> & TextLayoutCacheAccess<C>;\n}\n\nfunction readCachedTextLayout<C extends CanvasRenderingContext2D, T>(\n node: Node<C>,\n ctx: Context<C>,\n key: string,\n compute: () => T,\n): T {\n const textCtx = getTextLayoutContext(ctx);\n const cached = textCtx.getTextLayout<T>(node, key);\n if (cached != null) {\n return cached;\n }\n const layout = compute();\n textCtx.setTextLayout(node, key, layout);\n return layout;\n}\n\nfunction getSingleLineLayoutKey(maxWidth: number | undefined): string {\n return maxWidth == null ? \"single:intrinsic\" : `single:${maxWidth}`;\n}\n\nfunction getMultiLineMeasureLayoutKey(maxWidth: number | undefined): string {\n return maxWidth == null ? \"multi:measure:intrinsic\" : `multi:measure:${maxWidth}`;\n}\n\nfunction getMultiLineDrawLayoutKey(maxWidth: number | undefined): string {\n return maxWidth == null ? \"multi:draw:intrinsic\" : `multi:draw:${maxWidth}`;\n}\n\nfunction getMultiLineOverflowLayoutKey(maxWidth: number | undefined): string {\n return maxWidth == null ? \"multi:overflow:intrinsic\" : `multi:overflow:${maxWidth}`;\n}\n\nfunction shouldUseMultilineOverflowLayout(options: Pick<MultilineTextOptions<any>, \"maxLines\">): boolean {\n return options.maxLines != null;\n}\n\nfunction getSingleLineMinContentLayoutKey(): string {\n return \"single:min-content\";\n}\n\nfunction getMultiLineMinContentLayoutKey(): string {\n return \"multi:min-content\";\n}\n\nfunction getSingleLineLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n options: TextOptions<C>,\n): SingleLineLayout {\n const maxWidth = normalizeTextMaxWidth(ctx.constraints?.maxWidth);\n return readCachedTextLayout(node, ctx, getSingleLineLayoutKey(maxWidth), () =>\n maxWidth == null\n ? layoutFirstLineIntrinsic(ctx, text, options.whiteSpace)\n : options.overflow === \"ellipsis\"\n ? layoutEllipsizedFirstLine(ctx, text, maxWidth, options.ellipsisPosition ?? \"end\", options.whiteSpace)\n : layoutFirstLine(ctx, text, maxWidth, options.whiteSpace)\n );\n}\n\nfunction getMultiLineOverflowLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n options: MultilineTextOptions<C>,\n): MultiLineDrawLayout {\n const maxWidth = normalizeTextMaxWidth(ctx.constraints?.maxWidth);\n return readCachedTextLayout(node, ctx, getMultiLineOverflowLayoutKey(maxWidth), () =>\n layoutTextWithOverflow(ctx, text, maxWidth ?? 0, {\n whiteSpace: options.whiteSpace,\n overflow: options.overflow,\n maxLines: options.maxLines,\n })\n );\n}\n\nfunction getMultiLineMeasureLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n options: MultilineTextOptions<C>,\n): MultiLineMeasureLayout {\n const maxWidth = normalizeTextMaxWidth(ctx.constraints?.maxWidth);\n if (maxWidth != null && shouldUseMultilineOverflowLayout(options)) {\n const layout = getMultiLineOverflowLayout(node, ctx, text, options);\n return { width: layout.width, lineCount: layout.lines.length };\n }\n return readCachedTextLayout(node, ctx, getMultiLineMeasureLayoutKey(maxWidth), () =>\n maxWidth == null ? measureTextIntrinsic(ctx, text, options.whiteSpace) : measureText(ctx, text, maxWidth, options.whiteSpace)\n );\n}\n\nfunction getMultiLineDrawLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n options: MultilineTextOptions<C>,\n): MultiLineDrawLayout {\n const maxWidth = normalizeTextMaxWidth(ctx.constraints?.maxWidth);\n if (maxWidth != null && shouldUseMultilineOverflowLayout(options)) {\n return getMultiLineOverflowLayout(node, ctx, text, options);\n }\n return readCachedTextLayout(node, ctx, getMultiLineDrawLayoutKey(maxWidth), () =>\n maxWidth == null ? layoutTextIntrinsic(ctx, text, options.whiteSpace) : layoutText(ctx, text, maxWidth, options.whiteSpace)\n );\n}\n\nfunction getSingleLineMinContentLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n options: TextOptions<C>,\n): SingleLineLayout {\n return readCachedTextLayout(node, ctx, getSingleLineMinContentLayoutKey(), () => {\n const measurement = measureTextMinContent(ctx, text, options.whiteSpace, options.overflowWrap);\n const { shift } = layoutFirstLineIntrinsic(ctx, text, options.whiteSpace);\n return {\n width: measurement.width,\n text,\n shift,\n };\n });\n}\n\nfunction getMultiLineMinContentLayout<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n ctx: Context<C>,\n text: string,\n whiteSpace: MultilineTextOptions<C>[\"whiteSpace\"],\n overflowWrap: MultilineTextOptions<C>[\"overflowWrap\"],\n): MultiLineMeasureLayout {\n return readCachedTextLayout(node, ctx, getMultiLineMinContentLayoutKey(), () =>\n measureTextMinContent(ctx, text, whiteSpace, overflowWrap)\n );\n}\n\n/**\n * Draws wrapped text using the configured line height and alignment.\n */\nexport class MultilineText<C extends CanvasRenderingContext2D> implements Node<C> {\n /**\n * @param text Source text to measure and draw.\n * @param options Text layout and drawing options.\n */\n constructor(\n readonly text: string,\n readonly options: MultilineTextOptions<C>,\n ) {}\n\n measure(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width, lineCount } = getMultiLineMeasureLayout(this, ctx, this.text, this.options);\n return { width, height: lineCount * this.options.lineHeight };\n });\n }\n\n measureMinContent(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width, lineCount } = getMultiLineMinContentLayout(\n this,\n ctx,\n this.text,\n this.options.whiteSpace,\n this.options.overflowWrap,\n );\n return { width, height: lineCount * this.options.lineHeight };\n });\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return ctx.with((g) => {\n g.font = this.options.font;\n g.fillStyle = ctx.resolveDynValue(this.options.style);\n const { width, lines } = getMultiLineDrawLayout(this, ctx, this.text, this.options);\n switch (resolvePhysicalTextAlign(this.options)) {\n case \"left\":\n for (const { text, shift } of lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n case \"right\": {\n x += width;\n g.textAlign = \"right\";\n for (const { text, shift } of lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n }\n case \"center\": {\n x += width / 2;\n g.textAlign = \"center\";\n for (const { text, shift } of lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n }\n }\n return false;\n });\n }\n\n hittest(_ctx: Context<C>, _test: { x: number; y: number; type: \"click\" | \"auxclick\" | \"hover\" }): boolean {\n return false;\n }\n}\n\n/**\n * Draws a single line of text, clipped logically by measurement width.\n */\nexport class Text<C extends CanvasRenderingContext2D> implements Node<C> {\n /**\n * @param text Source text to measure and draw.\n * @param options Text layout and drawing options.\n */\n constructor(\n readonly text: string,\n readonly options: TextOptions<C>,\n ) {}\n\n measure(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width } = getSingleLineLayout(this, ctx, this.text, this.options);\n return { width, height: this.options.lineHeight };\n });\n }\n\n measureMinContent(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width } = getSingleLineMinContentLayout(this, ctx, this.text, this.options);\n return { width, height: this.options.lineHeight };\n });\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return ctx.with((g) => {\n g.font = this.options.font;\n g.fillStyle = ctx.resolveDynValue(this.options.style);\n const { text, shift } = getSingleLineLayout(this, ctx, this.text, this.options);\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n return false;\n });\n }\n\n hittest(_ctx: Context<C>, _test: { x: number; y: number; type: \"click\" | \"auxclick\" | \"hover\" }): boolean {\n return false;\n }\n}\n","import { forEachNodeAncestor, getNodeRevision } from \"../internal/node-registry\";\nimport type {\n Box,\n Context,\n DynValue,\n FlexLayoutResult,\n HitTest,\n LayoutConstraints,\n Node,\n RendererOptions,\n} from \"../types\";\nimport { shallow } from \"../utils\";\n\nconst MAX_CONSTRAINT_VARIANTS = 8;\n\ntype LayoutCacheAccess<C extends CanvasRenderingContext2D> = {\n getLayoutResult(node: Node<C>, constraints?: LayoutConstraints): FlexLayoutResult<C> | undefined;\n setLayoutResult(node: Node<C>, result: FlexLayoutResult<C>, constraints?: LayoutConstraints): void;\n};\n\ntype TextLayoutCacheAccess<C extends CanvasRenderingContext2D> = {\n getTextLayout<T>(node: Node<C>, key: string): T | undefined;\n setTextLayout<T>(node: Node<C>, key: string, layout: T): void;\n};\n\ntype BoxCacheEntry = {\n revision: number;\n box: Box;\n};\n\ntype LayoutCacheEntry<C extends CanvasRenderingContext2D> = {\n revision: number;\n layout: FlexLayoutResult<C>;\n};\n\ntype TextLayoutCacheEntry = {\n revision: number;\n layout: unknown;\n};\n\ntype RendererContext<C extends CanvasRenderingContext2D> = Context<C> & LayoutCacheAccess<C> & TextLayoutCacheAccess<C>;\n\nfunction constraintKey(constraints: LayoutConstraints | undefined): string {\n if (constraints == null) return \"\";\n return `${constraints.minWidth ?? \"\"},${constraints.maxWidth ?? \"\"},${constraints.minHeight ?? \"\"},${constraints.maxHeight ?? \"\"}`;\n}\n\n/**\n * Base renderer that provides measurement, layout caching, and drawing helpers.\n */\nexport class BaseRenderer<C extends CanvasRenderingContext2D, O extends {} = {}> {\n /** Canvas rendering context used by this renderer. */\n graphics: C;\n #ctx: RendererContext<C>;\n #lastWidth: number;\n #cache = new WeakMap<Node<C>, Map<string, BoxCacheEntry>>();\n #layoutCache = new WeakMap<Node<C>, Map<string, LayoutCacheEntry<C>>>();\n #textLayoutCache = new WeakMap<Node<C>, Map<string, TextLayoutCacheEntry>>();\n\n protected get context(): Context<C> {\n return shallow(this.#ctx);\n }\n\n /**\n * @param graphics Canvas rendering context used for all layout and drawing.\n * @param options Renderer-specific options.\n */\n constructor(\n graphics: C,\n readonly options: RendererOptions & O,\n ) {\n this.graphics = graphics;\n this.graphics.textRendering = \"optimizeLegibility\";\n const self = this;\n this.#ctx = {\n graphics: this.graphics,\n measureNode(node: Node<C>, constraints?: LayoutConstraints) {\n return self.measureNode(node, constraints);\n },\n getLayoutResult(node: Node<C>, constraints?: LayoutConstraints) {\n return self.getLayoutResult(node, constraints);\n },\n setLayoutResult(node: Node<C>, result: FlexLayoutResult<C>, constraints?: LayoutConstraints) {\n self.setLayoutResult(node, result, constraints);\n },\n getTextLayout<T>(node: Node<C>, key: string) {\n return self.getTextLayout<T>(node, key);\n },\n setTextLayout<T>(node: Node<C>, key: string, layout: T) {\n self.setTextLayout(node, key, layout);\n },\n invalidateNode: this.invalidateNode.bind(this),\n resolveDynValue<T>(value: DynValue<C, T>): T {\n if (typeof value === \"function\") {\n return value(this.graphics);\n }\n return value as T;\n },\n with<T>(cb: (g: C) => T): T {\n this.graphics.save();\n try {\n return cb(this.graphics);\n } finally {\n this.graphics.restore();\n }\n },\n };\n this.#lastWidth = this.graphics.canvas.clientWidth;\n }\n\n #clearAllCaches(): void {\n this.#cache = new WeakMap<Node<C>, Map<string, BoxCacheEntry>>();\n this.#layoutCache = new WeakMap<Node<C>, Map<string, LayoutCacheEntry<C>>>();\n this.#textLayoutCache = new WeakMap<Node<C>, Map<string, TextLayoutCacheEntry>>();\n }\n\n #syncCachesToViewportWidth(): void {\n const width = this.graphics.canvas.clientWidth;\n if (this.#lastWidth === width) {\n return;\n }\n this.#clearAllCaches();\n this.#lastWidth = width;\n }\n\n protected getRootConstraints(): LayoutConstraints {\n return {\n maxWidth: this.graphics.canvas.clientWidth,\n };\n }\n\n protected getRootContext(): Context<C> {\n const ctx = this.context;\n ctx.constraints = this.getRootConstraints();\n return ctx;\n }\n\n protected measureRootNode(node: Node<C>): Box {\n return this.measureNode(node, this.getRootConstraints());\n }\n\n protected drawRootNode(node: Node<C>, x = 0, y = 0): boolean {\n this.measureRootNode(node);\n return node.draw(this.getRootContext(), x, y);\n }\n\n protected hittestRootNode(node: Node<C>, test: HitTest): boolean {\n this.measureRootNode(node);\n return node.hittest(this.getRootContext(), test);\n }\n\n /**\n * Drops cached measurements for a node and every ancestor that depends on it.\n */\n invalidateNode(node: Node<C>): void {\n this.#syncCachesToViewportWidth();\n this.#cache.delete(node);\n this.#layoutCache.delete(node);\n this.#textLayoutCache.delete(node);\n forEachNodeAncestor(node, (ancestor) => {\n this.#cache.delete(ancestor);\n this.#layoutCache.delete(ancestor);\n this.#textLayoutCache.delete(ancestor);\n });\n }\n\n /**\n * Returns the cached layout result for a node under the given constraints, if available.\n */\n getLayoutResult(node: Node<C>, constraints?: LayoutConstraints): FlexLayoutResult<C> | undefined {\n this.#syncCachesToViewportWidth();\n const nodeCache = this.#layoutCache.get(node);\n if (nodeCache == null) {\n return undefined;\n }\n const key = constraintKey(constraints);\n const cached = nodeCache.get(key);\n if (cached == null) {\n return undefined;\n }\n if (cached.revision !== getNodeRevision(node)) {\n nodeCache.delete(key);\n return undefined;\n }\n return cached.layout;\n }\n\n /**\n * Stores a layout result for later draw and hit-test passes.\n */\n setLayoutResult(node: Node<C>, result: FlexLayoutResult<C>, constraints?: LayoutConstraints): void {\n this.#syncCachesToViewportWidth();\n let nodeCache = this.#layoutCache.get(node);\n if (nodeCache == null) {\n nodeCache = new Map();\n this.#layoutCache.set(node, nodeCache);\n } else if (nodeCache.size >= MAX_CONSTRAINT_VARIANTS) {\n const firstKey = nodeCache.keys().next().value!;\n nodeCache.delete(firstKey);\n }\n nodeCache.set(constraintKey(constraints), {\n revision: getNodeRevision(node),\n layout: result,\n });\n }\n\n protected getTextLayout<T>(node: Node<C>, key: string): T | undefined {\n this.#syncCachesToViewportWidth();\n const nodeCache = this.#textLayoutCache.get(node);\n if (nodeCache == null) {\n return undefined;\n }\n const cached = nodeCache.get(key);\n if (cached == null) {\n return undefined;\n }\n if (cached.revision !== getNodeRevision(node)) {\n nodeCache.delete(key);\n return undefined;\n }\n return cached.layout as T;\n }\n\n protected setTextLayout<T>(node: Node<C>, key: string, layout: T): void {\n this.#syncCachesToViewportWidth();\n let nodeCache = this.#textLayoutCache.get(node);\n if (nodeCache == null) {\n nodeCache = new Map();\n this.#textLayoutCache.set(node, nodeCache);\n } else if (nodeCache.size >= MAX_CONSTRAINT_VARIANTS) {\n const firstKey = nodeCache.keys().next().value!;\n nodeCache.delete(firstKey);\n }\n nodeCache.set(key, {\n revision: getNodeRevision(node),\n layout,\n });\n }\n\n /**\n * Measures a node under optional constraints, using cached results when possible.\n */\n measureNode(node: Node<C>, constraints?: LayoutConstraints): Box {\n this.#syncCachesToViewportWidth();\n {\n const nodeCache = this.#cache.get(node);\n if (nodeCache != null) {\n const key = constraintKey(constraints);\n const cached = nodeCache.get(key);\n if (cached != null) {\n if (cached.revision === getNodeRevision(node)) {\n return cached.box;\n }\n nodeCache.delete(key);\n }\n }\n }\n const ctx = this.context;\n if (constraints != null) {\n ctx.constraints = constraints;\n }\n const result = node.measure(ctx);\n const key = constraintKey(constraints);\n let nodeCache = this.#cache.get(node);\n if (nodeCache == null) {\n nodeCache = new Map();\n this.#cache.set(node, nodeCache);\n } else if (nodeCache.size >= MAX_CONSTRAINT_VARIANTS) {\n const firstKey = nodeCache.keys().next().value!;\n nodeCache.delete(firstKey);\n }\n nodeCache.set(key, {\n revision: getNodeRevision(node),\n box: result,\n });\n return result;\n }\n}\n\n/**\n * Immediate-mode renderer for a single root node.\n */\nexport class DebugRenderer<C extends CanvasRenderingContext2D> extends BaseRenderer<C> {\n /**\n * Clears the viewport and draws the provided root node.\n */\n draw(node: Node<C>): boolean {\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n return this.drawRootNode(node);\n }\n\n /**\n * Hit-tests the provided root node using viewport-relative coordinates.\n */\n hittest(node: Node<C>, test: HitTest): boolean {\n return this.hittestRootNode(node, test);\n }\n}\n","/**\n * Mutable list state shared with virtualized renderers.\n */\nexport class ListState<T extends {}> {\n /** Pixel offset from the anchored item edge. */\n offset = 0;\n /** Anchor item index, or `undefined` to use the renderer default. */\n position: number | undefined;\n /** Items currently managed by the renderer. */\n items: T[] = [];\n\n /**\n * @param items Initial list items.\n */\n constructor(items: T[] = []) {\n this.items = [...items];\n }\n\n /** Prepends one or more items. */\n unshift(...items: T[]): void {\n this.unshiftAll(items);\n }\n\n /** Prepends an array of items. */\n unshiftAll(items: T[]): void {\n if (this.position != null) {\n this.position += items.length;\n }\n this.items = items.concat(this.items);\n }\n\n /** Appends one or more items. */\n push(...items: T[]): void {\n this.pushAll(items);\n }\n\n /** Appends an array of items. */\n pushAll(items: T[]): void {\n this.items.push(...items);\n }\n\n /**\n * Sets the current anchor item and pixel offset.\n */\n setAnchor(position: number, offset = 0): void {\n this.position = Number.isFinite(position) ? Math.trunc(position) : undefined;\n this.offset = Number.isFinite(offset) ? offset : 0;\n }\n\n /**\n * Replaces all items and clears scroll state.\n */\n reset(items: T[] = []): void {\n this.items = [...items];\n this.offset = 0;\n this.position = undefined;\n }\n\n /** Clears the current scroll anchor while keeping the items. */\n resetScroll(): void {\n this.offset = 0;\n this.position = undefined;\n }\n\n /** Applies a relative pixel scroll delta. */\n applyScroll(delta: number): void {\n this.offset += delta;\n }\n}\n","import type { Node } from \"../types\";\n\nfunction isWeakMapKey(value: unknown): value is object {\n return (typeof value === \"object\" && value !== null) || typeof value === \"function\";\n}\n\n/**\n * Memoizes `renderItem` by object identity.\n */\nexport function memoRenderItem<C extends CanvasRenderingContext2D, T extends object>(\n renderItem: (item: T) => Node<C>,\n): ((item: T) => Node<C>) & { reset: (key: T) => boolean } {\n const cache = new WeakMap<object, Node<C>>();\n\n function fn(item: T): Node<C> {\n if (!isWeakMapKey(item)) {\n throw new TypeError(\"memoRenderItem() only supports object items. Use memoRenderItemBy() for primitive keys.\");\n }\n const key = item as unknown as object;\n const cached = cache.get(key);\n if (cached != null) {\n return cached;\n }\n const result = renderItem(item);\n cache.set(key, result);\n return result;\n }\n\n return Object.assign(fn, {\n reset: (key: T) => cache.delete(key as unknown as object),\n });\n}\n\n/**\n * Memoizes `renderItem` by a caller-provided cache key.\n */\nexport function memoRenderItemBy<C extends CanvasRenderingContext2D, T, K>(\n keyOf: (item: T) => K,\n renderItem: (item: T) => Node<C>,\n): ((item: T) => Node<C>) & { reset: (item: T) => boolean; resetKey: (key: K) => boolean } {\n const cache = new Map<K, Node<C>>();\n\n function fn(item: T): Node<C> {\n const key = keyOf(item);\n const cached = cache.get(key);\n if (cached != null) {\n return cached;\n }\n const result = renderItem(item);\n cache.set(key, result);\n return result;\n }\n\n return Object.assign(fn, {\n reset: (item: T) => cache.delete(keyOf(item)),\n resetKey: (key: K) => cache.delete(key),\n });\n}\n","import type { Node, RenderFeedback } from \"../../types\";\nimport { BaseRenderer } from \"../base\";\nimport { ListState } from \"../list-state\";\nimport type { NormalizedListState, VisibleListState, VisibleWindow } from \"./solver\";\n\n/**\n * Options for programmatic scrolling to a target item.\n */\nexport interface JumpToOptions {\n /** Whether to animate the jump. Defaults to `true`. */\n animated?: boolean;\n /** Which edge of the item should align with the viewport. */\n block?: \"start\" | \"center\" | \"end\";\n /** Animation duration in milliseconds. */\n duration?: number;\n /** Called after the jump completes or finishes animating. */\n onComplete?: () => void;\n}\n\ntype ControlledState = {\n position?: number;\n offset: number;\n};\n\ntype JumpAnimation = {\n startAnchor: number;\n targetAnchor: number;\n startTime: number;\n duration: number;\n needsMoreFrames: boolean;\n onComplete: (() => void) | undefined;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction sameState(state: ControlledState, position: number | undefined, offset: number): boolean {\n return Object.is(state.position, position) && Object.is(state.offset, offset);\n}\n\nfunction smoothstep(value: number): number {\n return value * value * (3 - 2 * value);\n}\n\nfunction getNow(): number {\n return globalThis.performance?.now() ?? Date.now();\n}\n\n/**\n * Shared base class for virtualized list renderers.\n */\nexport abstract class VirtualizedRenderer<C extends CanvasRenderingContext2D, T extends {}> extends BaseRenderer<\n C,\n {\n renderItem: (item: T) => Node<C>;\n list: ListState<T>;\n }\n> {\n static readonly MIN_JUMP_DURATION = 160;\n static readonly MAX_JUMP_DURATION = 420;\n static readonly JUMP_DURATION_PER_ITEM = 28;\n\n #controlledState: ControlledState | undefined;\n #jumpAnimation: JumpAnimation | undefined;\n\n /** Current anchor item index. */\n get position(): number | undefined {\n return this.options.list.position;\n }\n\n /** Updates the current anchor item index. */\n set position(value: number | undefined) {\n this.options.list.position = value;\n }\n\n /** Pixel offset from the anchored item edge. */\n get offset(): number {\n return this.options.list.offset;\n }\n\n /** Updates the pixel offset from the anchored item edge. */\n set offset(value: number) {\n this.options.list.offset = value;\n }\n\n /** Items currently available to the renderer. */\n get items(): T[] {\n return this.options.list.items;\n }\n\n /** Replaces the current item collection. */\n set items(value: T[]) {\n this.options.list.items = value;\n }\n\n /** Renders the current visible window. */\n abstract render(feedback?: RenderFeedback): boolean;\n /** Hit-tests the current visible window. */\n abstract hittest(test: { x: number; y: number; type: \"click\" | \"auxclick\" | \"hover\" }): boolean;\n\n protected _readListState(): VisibleListState {\n return {\n position: this.position,\n offset: this.offset,\n };\n }\n\n protected _commitListState(state: NormalizedListState): void {\n this.position = state.position;\n this.offset = state.offset;\n }\n\n /**\n * Scrolls the viewport to the requested item index.\n */\n jumpTo(index: number, options: JumpToOptions = {}): void {\n if (this.items.length === 0) {\n this.#cancelJumpAnimation();\n return;\n }\n\n const targetIndex = this._clampItemIndex(index);\n const currentState = this._normalizeListState(this._readListState());\n const targetBlock = options.block ?? this._getDefaultJumpBlock();\n const targetAnchor = this._getTargetAnchor(targetIndex, targetBlock);\n\n const animated = options.animated ?? true;\n if (!animated) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n options.onComplete?.();\n return;\n }\n\n const startAnchor = this._readAnchor(currentState);\n if (!Number.isFinite(startAnchor)) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n options.onComplete?.();\n return;\n }\n\n const duration = clamp(\n options.duration ??\n VirtualizedRenderer.MIN_JUMP_DURATION +\n Math.abs(targetAnchor - startAnchor) * VirtualizedRenderer.JUMP_DURATION_PER_ITEM,\n 0,\n VirtualizedRenderer.MAX_JUMP_DURATION,\n );\n\n if (duration <= 0 || Math.abs(targetAnchor - startAnchor) <= Number.EPSILON) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n options.onComplete?.();\n return;\n }\n\n this.#jumpAnimation = {\n startAnchor,\n targetAnchor,\n startTime: getNow(),\n duration,\n needsMoreFrames: true,\n onComplete: options.onComplete,\n };\n this.#controlledState = this._readListState();\n }\n\n protected _resetRenderFeedback(feedback?: RenderFeedback): void {\n if (feedback == null) {\n return;\n }\n feedback.minIdx = Number.NaN;\n feedback.maxIdx = Number.NaN;\n feedback.min = Number.NaN;\n feedback.max = Number.NaN;\n }\n\n protected _accumulateRenderFeedback(feedback: RenderFeedback, idx: number, top: number, height: number): void {\n if (!Number.isFinite(top) || !Number.isFinite(height) || height <= 0) {\n return;\n }\n\n const viewportHeight = this.graphics.canvas.clientHeight;\n const visibleTop = clamp(-top, 0, height);\n const visibleBottom = clamp(viewportHeight - top, 0, height);\n if (visibleBottom <= visibleTop) {\n return;\n }\n\n const itemMin = idx + visibleTop / height;\n const itemMax = idx + visibleBottom / height;\n feedback.minIdx = Number.isNaN(feedback.minIdx) ? idx : Math.min(idx, feedback.minIdx);\n feedback.maxIdx = Number.isNaN(feedback.maxIdx) ? idx : Math.max(idx, feedback.maxIdx);\n feedback.min = Number.isNaN(feedback.min) ? itemMin : Math.min(itemMin, feedback.min);\n feedback.max = Number.isNaN(feedback.max) ? itemMax : Math.max(itemMax, feedback.max);\n }\n\n protected _renderDrawList(list: VisibleWindow<Node<C>>[\"drawList\"], shift: number, feedback?: RenderFeedback): boolean {\n let result = false;\n const viewportHeight = this.graphics.canvas.clientHeight;\n\n for (const { idx, value: node, offset, height } of list) {\n const y = offset + shift;\n if (feedback != null) {\n this._accumulateRenderFeedback(feedback, idx, y, height);\n }\n if (y + height < 0 || y > viewportHeight) {\n continue;\n }\n if (this.drawRootNode(node, 0, y)) {\n result = true;\n }\n }\n\n return result;\n }\n\n protected _renderVisibleWindow(window: VisibleWindow<Node<C>>, feedback?: RenderFeedback): boolean {\n this._resetRenderFeedback(feedback);\n return this._renderDrawList(window.drawList, window.shift, feedback);\n }\n\n protected _hittestVisibleWindow(window: VisibleWindow<Node<C>>, test: { x: number; y: number; type: \"click\" | \"auxclick\" | \"hover\" }): boolean {\n for (const { value: node, offset, height } of window.drawList) {\n const y = offset + window.shift;\n if (test.y < y || test.y >= y + height) {\n continue;\n }\n return node.hittest(\n this.getRootContext(),\n {\n ...test,\n y: test.y - y,\n },\n );\n }\n return false;\n }\n\n protected _prepareRender(): boolean {\n const animation = this.#jumpAnimation;\n if (animation == null) {\n return false;\n }\n if (this.items.length === 0) {\n this.#cancelJumpAnimation();\n return false;\n }\n if (this.#controlledState != null && !sameState(this.#controlledState, this.position, this.offset)) {\n this.#cancelJumpAnimation();\n return false;\n }\n\n const progress = clamp((getNow() - animation.startTime) / animation.duration, 0, 1);\n const eased = progress >= 1 ? 1 : smoothstep(progress);\n const anchor = animation.startAnchor + (animation.targetAnchor - animation.startAnchor) * eased;\n this._applyAnchor(anchor);\n animation.needsMoreFrames = progress < 1;\n return animation.needsMoreFrames;\n }\n\n protected _finishRender(requestRedraw: boolean): boolean {\n const animation = this.#jumpAnimation;\n if (animation == null) {\n return requestRedraw;\n }\n\n if (animation.needsMoreFrames) {\n this.#controlledState = this._readListState();\n return true;\n }\n\n const onComplete = animation.onComplete;\n this.#cancelJumpAnimation();\n onComplete?.();\n return requestRedraw || this.#jumpAnimation != null;\n }\n\n protected _clampItemIndex(index: number): number {\n return clamp(Number.isFinite(index) ? Math.trunc(index) : 0, 0, this.items.length - 1);\n }\n\n protected _getItemHeight(index: number): number {\n const item = this.items[index];\n const node = this.options.renderItem(item);\n return this.measureRootNode(node).height;\n }\n\n protected _getAnchorAtOffset(index: number, offset: number): number {\n if (this.items.length === 0) {\n return 0;\n }\n\n let currentIndex = this._clampItemIndex(index);\n let remaining = Number.isFinite(offset) ? offset : 0;\n while (true) {\n if (remaining < 0) {\n if (currentIndex === 0) {\n return 0;\n }\n currentIndex -= 1;\n const height = this._getItemHeight(currentIndex);\n if (height > 0) {\n remaining += height;\n }\n continue;\n }\n\n const height = this._getItemHeight(currentIndex);\n if (height > 0) {\n if (remaining <= height) {\n return currentIndex + remaining / height;\n }\n remaining -= height;\n } else if (remaining === 0) {\n return currentIndex;\n }\n\n if (currentIndex === this.items.length - 1) {\n return this.items.length;\n }\n currentIndex += 1;\n }\n }\n\n protected abstract _normalizeListState(state: VisibleListState): NormalizedListState;\n protected abstract _readAnchor(state: NormalizedListState): number;\n protected abstract _applyAnchor(anchor: number): void;\n protected abstract _getDefaultJumpBlock(): NonNullable<JumpToOptions[\"block\"]>;\n protected abstract _getTargetAnchor(index: number, block: NonNullable<JumpToOptions[\"block\"]>): number;\n\n #cancelJumpAnimation(): void {\n this.#jumpAnimation = undefined;\n this.#controlledState = undefined;\n }\n}\n","export interface VisibleListState {\n position?: number;\n offset: number;\n}\n\nexport interface NormalizedListState {\n position: number;\n offset: number;\n}\n\nexport interface VisibleWindowEntry<T> {\n idx: number;\n value: T;\n offset: number;\n height: number;\n}\n\nexport interface VisibleWindow<T> {\n drawList: VisibleWindowEntry<T>[];\n shift: number;\n}\n\nexport interface VisibleWindowResult<T> {\n normalizedState: NormalizedListState;\n window: VisibleWindow<T>;\n}\n\ntype ResolvedItem<T> = {\n value: T;\n height: number;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction normalizeOffset(offset: number): number {\n return Number.isFinite(offset) ? offset : 0;\n}\n\nexport function normalizeTimelineState(itemCount: number, state: VisibleListState): NormalizedListState {\n if (itemCount <= 0) {\n return { position: 0, offset: 0 };\n }\n\n const position = state.position;\n if (typeof position !== \"number\" || !Number.isFinite(position)) {\n return {\n position: 0,\n offset: normalizeOffset(state.offset),\n };\n }\n\n return {\n position: clamp(Math.trunc(position), 0, itemCount - 1),\n offset: normalizeOffset(state.offset),\n };\n}\n\nexport function normalizeChatState(itemCount: number, state: VisibleListState): NormalizedListState {\n if (itemCount <= 0) {\n return { position: 0, offset: 0 };\n }\n\n const position = state.position;\n if (typeof position !== \"number\" || !Number.isFinite(position)) {\n return {\n position: itemCount - 1,\n offset: normalizeOffset(state.offset),\n };\n }\n\n return {\n position: clamp(Math.trunc(position), 0, itemCount - 1),\n offset: normalizeOffset(state.offset),\n };\n}\n\nexport function resolveTimelineVisibleWindow<T, V>(\n items: readonly T[],\n state: VisibleListState,\n viewportHeight: number,\n resolveItem: (item: T, idx: number) => ResolvedItem<V>,\n): VisibleWindowResult<V> {\n const normalizedState = normalizeTimelineState(items.length, state);\n if (items.length === 0) {\n return {\n normalizedState,\n window: { drawList: [], shift: 0 },\n };\n }\n\n let { position, offset } = normalizedState;\n let drawLength = 0;\n\n if (offset > 0) {\n if (position === 0) {\n offset = 0;\n } else {\n for (let i = position - 1; i >= 0; i -= 1) {\n const { height } = resolveItem(items[i]!, i);\n position = i;\n offset -= height;\n if (offset <= 0) {\n break;\n }\n }\n if (position === 0 && offset > 0) {\n offset = 0;\n }\n }\n }\n\n let y = offset;\n const drawList: VisibleWindowEntry<V>[] = [];\n for (let i = position; i < items.length; i += 1) {\n const { value, height } = resolveItem(items[i]!, i);\n if (y + height > 0) {\n drawList.push({ idx: i, value, offset: y, height });\n drawLength += height;\n } else {\n offset += height;\n position = i + 1;\n }\n y += height;\n if (y >= viewportHeight) {\n break;\n }\n }\n\n let shift = 0;\n if (y < viewportHeight) {\n if (position === 0 && drawLength < viewportHeight) {\n shift = -offset;\n offset = 0;\n } else {\n shift = viewportHeight - y;\n y = (offset += shift);\n let lastIdx = -1;\n for (let i = position - 1; i >= 0; i -= 1) {\n const { value, height } = resolveItem(items[i]!, i);\n drawLength += height;\n y -= height;\n drawList.push({ idx: i, value, offset: y - shift, height });\n lastIdx = i;\n if (y < 0) {\n break;\n }\n }\n if (lastIdx === 0 && drawLength < viewportHeight) {\n shift = drawList.at(-1)?.offset == null ? 0 : -drawList.at(-1)!.offset;\n position = 0;\n offset = 0;\n }\n }\n }\n\n return {\n normalizedState: { position, offset },\n window: { drawList, shift },\n };\n}\n\nexport function resolveChatVisibleWindow<T, V>(\n items: readonly T[],\n state: VisibleListState,\n viewportHeight: number,\n resolveItem: (item: T, idx: number) => ResolvedItem<V>,\n): VisibleWindowResult<V> {\n const normalizedState = normalizeChatState(items.length, state);\n if (items.length === 0) {\n return {\n normalizedState,\n window: { drawList: [], shift: 0 },\n };\n }\n\n let { position, offset } = normalizedState;\n let drawLength = 0;\n\n if (offset < 0) {\n if (position === items.length - 1) {\n offset = 0;\n } else {\n for (let i = position + 1; i < items.length; i += 1) {\n const { height } = resolveItem(items[i]!, i);\n position = i;\n offset += height;\n if (offset > 0) {\n break;\n }\n }\n }\n }\n\n let y = viewportHeight + offset;\n const drawList: VisibleWindowEntry<V>[] = [];\n for (let i = position; i >= 0; i -= 1) {\n const { value, height } = resolveItem(items[i]!, i);\n y -= height;\n if (y <= viewportHeight) {\n drawList.push({ idx: i, value, offset: y, height });\n drawLength += height;\n } else {\n offset -= height;\n position = i - 1;\n }\n if (y < 0) {\n break;\n }\n }\n\n let shift = 0;\n if (y > 0) {\n shift = -y;\n if (drawLength < viewportHeight) {\n y = drawLength;\n for (let i = position + 1; i < items.length; i += 1) {\n const { value, height } = resolveItem(items[i]!, i);\n drawList.push({ idx: i, value, offset: y - shift, height });\n y = (drawLength += height);\n position = i;\n if (y >= viewportHeight) {\n break;\n }\n }\n offset = drawLength < viewportHeight ? 0 : drawLength - viewportHeight;\n } else {\n offset = drawLength - viewportHeight;\n }\n }\n\n return {\n normalizedState: { position, offset },\n window: { drawList, shift },\n };\n}\n","import type { HitTest, Node, RenderFeedback } from \"../../types\";\nimport { VirtualizedRenderer } from \"./base\";\nimport type { JumpToOptions } from \"./base\";\nimport {\n normalizeChatState,\n resolveChatVisibleWindow,\n type NormalizedListState,\n type VisibleListState,\n type VisibleWindowResult,\n} from \"./solver\";\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Virtualized renderer anchored to the bottom, suitable for chat-style UIs.\n */\nexport class ChatRenderer<C extends CanvasRenderingContext2D, T extends {}> extends VirtualizedRenderer<C, T> {\n #resolveVisibleWindow(): VisibleWindowResult<Node<C>> {\n return resolveChatVisibleWindow(\n this.items,\n this._readListState(),\n this.graphics.canvas.clientHeight,\n (item) => {\n const node = this.options.renderItem(item);\n return {\n value: node,\n height: this.measureRootNode(node).height,\n };\n },\n );\n }\n\n protected _getDefaultJumpBlock(): NonNullable<JumpToOptions[\"block\"]> {\n return \"end\";\n }\n\n protected _normalizeListState(state: VisibleListState): NormalizedListState {\n return normalizeChatState(this.items.length, state);\n }\n\n protected _readAnchor(state: NormalizedListState): number {\n if (this.items.length === 0) {\n return 0;\n }\n const height = this._getItemHeight(state.position);\n return height > 0 ? state.position + 1 - state.offset / height : state.position + 1;\n }\n\n protected _applyAnchor(anchor: number): void {\n if (this.items.length === 0) {\n return;\n }\n const clampedAnchor = clamp(anchor, 0, this.items.length);\n const position = clamp(Math.ceil(clampedAnchor) - 1, 0, this.items.length - 1);\n const height = this._getItemHeight(position);\n const offset = height > 0 ? (position + 1 - clampedAnchor) * height : 0;\n this._commitListState({\n position,\n offset: Object.is(offset, -0) ? 0 : offset,\n });\n }\n\n protected _getTargetAnchor(index: number, block: NonNullable<JumpToOptions[\"block\"]>): number {\n const height = this._getItemHeight(index);\n const viewportHeight = this.graphics.canvas.clientHeight;\n\n switch (block) {\n case \"start\":\n return this._getAnchorAtOffset(index, viewportHeight);\n case \"center\":\n return this._getAnchorAtOffset(index, height / 2 + viewportHeight / 2);\n case \"end\":\n return this._getAnchorAtOffset(index, height);\n }\n }\n\n render(feedback?: RenderFeedback): boolean {\n const keepAnimating = this._prepareRender();\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n const solution = this.#resolveVisibleWindow();\n const requestRedraw = this._renderVisibleWindow(solution.window, feedback);\n this._commitListState(solution.normalizedState);\n return this._finishRender(keepAnimating || requestRedraw);\n }\n\n hittest(test: HitTest): boolean {\n return this._hittestVisibleWindow(this.#resolveVisibleWindow().window, test);\n }\n}\n","import type { HitTest, Node, RenderFeedback } from \"../../types\";\nimport { VirtualizedRenderer } from \"./base\";\nimport type { JumpToOptions } from \"./base\";\nimport {\n normalizeTimelineState,\n resolveTimelineVisibleWindow,\n type NormalizedListState,\n type VisibleListState,\n type VisibleWindowResult,\n} from \"./solver\";\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Virtualized renderer anchored to the top, suitable for timeline-style UIs.\n */\nexport class TimelineRenderer<C extends CanvasRenderingContext2D, T extends {}> extends VirtualizedRenderer<C, T> {\n #resolveVisibleWindow(): VisibleWindowResult<Node<C>> {\n return resolveTimelineVisibleWindow(\n this.items,\n this._readListState(),\n this.graphics.canvas.clientHeight,\n (item) => {\n const node = this.options.renderItem(item);\n return {\n value: node,\n height: this.measureRootNode(node).height,\n };\n },\n );\n }\n\n protected _getDefaultJumpBlock(): NonNullable<JumpToOptions[\"block\"]> {\n return \"start\";\n }\n\n protected _normalizeListState(state: VisibleListState): NormalizedListState {\n return normalizeTimelineState(this.items.length, state);\n }\n\n protected _readAnchor(state: NormalizedListState): number {\n if (this.items.length === 0) {\n return 0;\n }\n const height = this._getItemHeight(state.position);\n return height > 0 ? state.position - state.offset / height : state.position;\n }\n\n protected _applyAnchor(anchor: number): void {\n if (this.items.length === 0) {\n return;\n }\n const clampedAnchor = clamp(anchor, 0, this.items.length);\n const position = clamp(Math.floor(clampedAnchor), 0, this.items.length - 1);\n const height = this._getItemHeight(position);\n const offset = height > 0 ? -(clampedAnchor - position) * height : 0;\n this._commitListState({\n position,\n offset: Object.is(offset, -0) ? 0 : offset,\n });\n }\n\n protected _getTargetAnchor(index: number, block: NonNullable<JumpToOptions[\"block\"]>): number {\n const height = this._getItemHeight(index);\n const viewportHeight = this.graphics.canvas.clientHeight;\n\n switch (block) {\n case \"start\":\n return this._getAnchorAtOffset(index, 0);\n case \"center\":\n return this._getAnchorAtOffset(index, height / 2 - viewportHeight / 2);\n case \"end\":\n return this._getAnchorAtOffset(index, height - viewportHeight);\n }\n }\n\n render(feedback?: RenderFeedback): boolean {\n const keepAnimating = this._prepareRender();\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n const solution = this.#resolveVisibleWindow();\n const requestRedraw = this._renderVisibleWindow(solution.window, feedback);\n this._commitListState(solution.normalizedState);\n return this._finishRender(keepAnimating || requestRedraw);\n }\n\n hittest(test: HitTest): boolean {\n return this._hittestVisibleWindow(this.#resolveVisibleWindow().window, test);\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"module": "./index.mjs",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@chenglou/pretext": "0.0.
|
|
6
|
+
"@chenglou/pretext": "0.0.5"
|
|
7
7
|
},
|
|
8
8
|
"repository": {
|
|
9
9
|
"url": "https://github.com/codehz/chat-layout.git"
|
|
10
10
|
},
|
|
11
|
-
"version": "1.0
|
|
11
|
+
"version": "1.1.0-1",
|
|
12
12
|
"main": "./index.mjs",
|
|
13
13
|
"types": "./index.d.mts",
|
|
14
14
|
"exports": {
|