gesso-core 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as prepareInputSurface, $a as UiNodeType, $i as isTypographyRole, $n as offsetForVerticalMove, $r as isMinMaxTrack, $t as DEFAULT_FONT_FAMILY, A as accumulatedOffsetTo, Aa as writeDeclaredProperty, Ai as hasThemeExtension, An as linkOf, Ar as statesEqual, At as ELLIPSIS, B as parseFlexDirection, Ba as UiFocusEvent, Bi as defaultSpacing, Bn as isMultiline, Br as transform, Bt as drawText, C as describeLength, Ca as findEnvironmentKey, Ci as unknownContainerSize, Cn as isNodeInert, Cr as propertyValuesEqualByName, Ct as paragraphGeometry, D as formatNumber, Da as clearOverrideProperty, Di as withContrast, Dn as clearLinkHover, Dr as isUiRole, Dt as CharacterCountTextMeasurer, E as formatExplanation, Ea as DirtyNodeSet, Ei as themesEqual, En as resolveCursor, Er as UI_SEMANTIC_STATES, Et as wordRangeIn, F as constraintsEqual, Fa as visualState, Fi as contrastRatio, Fn as EDITOR_PROP, Fr as inputsEqual, Ft as isPrintable, G as MainAxisAlignment, Ga as UiPinchEvent, Gi as shadowsEqual, Gn as isVideoSurface, Gr as gradientsEqual, Gt as spanOf, H as sizeGridTracks, Ha as UiInputEvent, Hi as spacingEqual, Hn as nextCaretToggle, Hr as transformsEqual, Ht as layoutTextLines, I as tightenConstraints, Ia as visualStatesEqual, Ii as highContrastColors, In as caretVisibleAt, Ir as paintValuesEqual, It as EditableLayout, J as parseMainAxisAlignment, Ja as UiTextChangeEvent, Ji as boxShadowsEqual, Jn as lineIndexAtY, Jr as validateGradient, Jt as textRunDecorations, K as parseAlignContent, Ka as UiPointerEvent, Ki as boxShadow, Kn as videoFrameSize, Kr as linearGradient, Kt as textMeasureRequest, L as MAX_MEASURES_PER_CHILD, La as MOUSE_POINTER, Li as raiseContrast, Ln as editorFor, Lr as pathValuesEqual, Lt as applyCanvasTextStyle, M as LayoutRecord, Ma as UiVisualState, Mi as themeExtension, Mn as setLinkHover, Mr as validateStates, Mt as proportionalFontMetrics, N as Constraints, Na as defaultVisualState, Ni as themeExtensionsEqual, Nn as CARET_BLINK_MS, Nr as UI_SUBGRID_AXES, Nt as commandForKey, O as labelNode, Oa as overrideSources, Oi as withDensity, On as hasTextLinks, Or as isUiSemanticState, Ot as ParagraphTextMeasurer, P as clampSize, Pa as hasVisualState, Pi as withThemeExtension, Pn as CARET_WIDTH, Pr as validateSubgrid, Pt as detectEditingPlatform, Q as pointerDeviceOf, Qa as wheelDeltaYOf, Qi as defaultTypography, Qn as offsetAtX, Qr as isFrLength, Qt as registerFontStack, R as isLayoutProtocol, Ra as UiBeforeInputEvent, Ri as relativeLuminance, Rn as editorOf, Rr as UiTransforms, Rt as buildFontString, S as SCROLLBAR_LINGER_MS, Sa as createEnvironmentKey, Si as containerBands, Sn as isNodeHitTestable, Sr as propertyIsInherited, St as offsetAtPointIn, T as formatConstraints, Ta as UiNode, Ti as lightTheme, Tn as isNodeTabStop, Tr as UI_ROLES, Tt as selectionRectsIn, U as AlignContent, Ua as UiKeyboardEvent, Ui as spacingSteps, Un as syncEditorValue, Ur as MAX_GRADIENT_STOPS, Ut as runCanvasStyleInto, V as placeGridItems, Va as UiGestureEvent, Vi as scaleSpacing, Vn as isReadOnly, Vr as transformIsIdentity, Vt as fillTextRects, W as CrossAxisAlignment, Wa as UiPasteEvent, Wi as defaultShadows, Wn as resolveColorValue, Wr as gradientPaint, Wt as runFontString, X as UiPlatformAdapter, Xa as UiWheelEvent, Xi as isShapeName, Xn as lineLimit, Xr as fr, Xt as clearFontStacks, Y as CanvasPlatformSurface, Ya as UiWheelDeltaMode, Yi as defaultShapes, Yn as lineIndexForOffset, Yr as auto, Yt as bumpFontStack, Z as capturePointer, Za as noKeyModifiers, Zi as shapesEqual, Zn as offsetAtPoint, Zr as isAutoLength, Zt as fontStackFor, _ as LABEL_PADDING_X, _a as colorsEqual, _i as insetsEqual, _n as selectableTextNodes, _r as findPropertyDefinition, _t as scrollbarThumb, a as PaintPictureCache, aa as spanAtOffset, ai as UiBorderRadiuses, an as createPaintState, ar as nextGraphemeEnd, at as UiWheelController, b as LayoutEngine, ba as rgb8, bi as UiContainerSizeSource, bn as setSelectionRange, br as inheritedPropertyNames, bt as UiInputDispatcher, c as EMPTY_RECORDING, ca as textSpansEqual, ci as borderRadiusEqual, cn as normalizeVerticalAlign, cr as previousWordStart, ct as UiPointerController, d as tracePathData, da as darkColors, di as normalizeBorderRadius, dn as TEXT_MATCHES_PROP, dr as resolveNumber, dt as SCROLLBAR_HOVER_ZONE, ea as typographyEqual, ei as isPercentLength, en as DEFAULT_FONT_SIZE, eo as DirtyFlags, er as selectionRects, et as touchActionFor, f as ScaledImageCache, fa as lightColors, fi as uniformBorderRadius, fn as clearMatchRanges, fr as resolveProperty, ft as SCROLLBAR_INSET, g as paintsAfterChildren, ga as colorValuesEqual, gi as UiInsetRegistry, gn as clearSelectionRange, gr as closestPropertyName, gt as scrollRange, h as hasDecorationPhase, ha as colorToRgba, hi as UiEnvironmentKeys, hn as TEXT_SELECTION_PROP, hr as UiGraph, ht as scrollLeaderOf, i as traceRoundedRect, ia as resolvedSpansOf, ii as resolveLength, in as computeObjectFitRect, ir as lineStartAt, it as UiPinchRecognizer, j as contentOffset, ja as writeOverrideProperty, ji as noThemeExtensions, jn as linkRunAtPointIn, jr as validateRole, jt as layoutParagraph, k as withOverrideSource, ka as resetOverrideWarnings, ki as defineThemeExtension, kn as linkHoverOf, kr as normalizeStates, kt as spannedRunsFor, l as PaintRecorder, la as textStylesEqual, li as borderRadiusIsZero, ln as resolvePaintState, lr as wordRangeAt, lt as UiFocusManager, m as decorationRect, ma as colorToHex, mi as propertyValuesEqual, mn as setMatchRanges, mr as resolveString, mt as SCROLLBAR_THICKNESS, n as createCanvasSurface, na as editableSpansOf, ni as percent, nn as DEFAULT_TEXT_COLOR, nr as graphemeBoundaries, nt as UiTouchScroller, o as paintPictures, oa as spannedTextOf, oi as borderRadius, on as isPaintVisible, or as nextWordEnd, ot as isScrollContainer, p as decorationColor, pa as UiBasicColors, pi as defineProperty, pn as matchRangesOf, pr as resolvePropertyByName, pt as SCROLLBAR_MIN_THUMB, q as parseCrossAxisAlignment, qa as UiSelectionChangeEvent, qi as boxShadowArraysEqual, qn as caretRectFor, qr as radialGradient, qt as textRunBackgrounds, r as Canvas2DRenderer, ra as flattenTextSpans, ri as repeat, rn as colorToCss, rr as lineEndAt, rt as UiGestureRecognizer, s as PaintTarget, sa as textContentOf, si as borderRadiusCorners, sn as normalizeTextAlign, sr as previousGraphemeStart, st as UiKeyboardController, t as CanvasSurface, ta as defaultTextStyle, ti as minmax, tn as DEFAULT_FONT_WEIGHT, to as UiBinding, tr as EditableTextModel, tt as UiEditingController, u as replayPaint, ua as colorsEqualPalette, ui as borderRadiusValuesEqual, un as DEFAULT_LINE_HEIGHT_FACTOR, ur as resolveBoolean, ut as UiHitTester, v as drawOverlayShapes, va as normalizeColor, vi as noInsets, vn as selectableTextOf, vr as getPropertyNames, vt as scrollbarThumbs, w as describeOverrides, wa as UiEnvironment, wi as darkTheme, wn as isNodeSelectable, wr as UiProperties, wt as paragraphGeometryFrom, x as SCROLLBAR_FADE_MS, xa as rgba, xi as bandOf, xn as isNodeFocusable, xr as propertyEffects, xt as hasDrawnText, y as labelOrigin, ya as parseColor, yi as observeViewportInsets, yn as selectionRangeOf, yr as inheritedPropertyFlags, yt as scrollbarZoneAt, z as FlexDirection, za as UiEventType, zi as densityFactors, zn as isEditableNode, zr as parseTransform, zt as createCanvasTextStyle } from "./CanvasSurface-BMOmE_dD.js";
1
+ import { $ as pointerDeviceOf, $a as UiKeyboardEvent, $i as boxShadow, $n as caretRectFor, $r as radialGradient, $t as DEFAULT_FONT_SIZE, A as withOverrideSource, Aa as rgb8, Ai as darkTheme, An as linkRunAtPointIn, Ar as UiProperties, At as edgeField, B as FlexDirection, Ba as writeDeclaredProperty, Bi as withThemeExtension, Bn as isReadOnly, Br as validateSubgrid, Bt as fillTextRects, C as SCROLLBAR_LINGER_MS, Ca as UiBasicColors, Ci as insetsEqual, Cn as isNodeTabStop, Cr as findPropertyDefinition, Ct as offsetAtPointIn, D as formatExplanation, Da as colorsEqual, Di as bandOf, Dn as hasTextLinks, Dr as propertyEffects, Dt as wordRangeIn, E as formatConstraints, Ea as colorValuesEqual, Ei as UiContainerSizeSource, En as clearLinkHover, Er as inheritedPropertyNames, Et as selectionRectsIn, F as clampSize, Fa as UiNode, Fi as defineThemeExtension, Fn as caretVisibleAt, Fr as normalizeStates, Ft as EditableLayout, G as CrossAxisAlignment, Ga as visualState, Gi as densityFactors, Gn as videoFrameSize, Gr as parseTransform, Gt as textMeasureRequest, H as placeGridItems, Ha as UiVisualState, Hi as highContrastColors, Hn as syncEditorValue, Hr as paintValuesEqual, Ht as runCanvasStyleInto, I as constraintsEqual, Ia as DirtyNodeSet, Ii as hasThemeExtension, In as editorFor, Ir as statesEqual, It as applyCanvasTextStyle, J as parseCrossAxisAlignment, Ja as UiBeforeInputEvent, Ji as spacingEqual, Jn as spannedRunsFor, Jr as transformsEqual, Jt as bumpFontStack, K as MainAxisAlignment, Ka as visualStatesEqual, Ki as defaultSpacing, Kn as CharacterCountTextMeasurer, Kr as transform, Kt as textRunBackgrounds, L as tightenConstraints, La as clearOverrideProperty, Li as noThemeExtensions, Ln as editorOf, Lr as validateRole, Lt as buildFontString, M as contentOffset, Ma as createEnvironmentKey, Mi as themesEqual, Mn as CARET_BLINK_MS, Mr as UI_SEMANTIC_STATES, Mt as commandForKey, N as LayoutRecord, Na as findEnvironmentKey, Ni as withContrast, Nn as CARET_WIDTH, Nr as isUiRole, Nt as detectEditingPlatform, O as formatNumber, Oa as normalizeColor, Oi as containerBands, On as linkHoverOf, Or as propertyIsInherited, Ot as adjacentField, P as Constraints, Pa as UiEnvironment, Pi as withDensity, Pn as EDITOR_PROP, Pr as isUiSemanticState, Pt as isPrintable, Q as capturePointer, Qa as UiInputEvent, Qi as BOX_SHADOW_BLUR_REACH, Qn as DEFAULT_LINE_HEIGHT_FACTOR, Qr as linearGradient, Qt as DEFAULT_FONT_FAMILY, R as MAX_MEASURES_PER_CHILD, Ra as overrideSources, Ri as themeExtension, Rn as isEditableNode, Rr as validateStates, Rt as createCanvasTextStyle, S as SCROLLBAR_FADE_MS, Sa as lightColors, Si as UiInsetRegistry, Sn as isNodeSelectable, Sr as closestPropertyName, St as hasDrawnText, T as describeOverrides, Ta as colorToRgba, Ti as observeViewportInsets, Tn as resolveCursor, Tr as inheritedPropertyFlags, Tt as paragraphGeometryFrom, U as sizeGridTracks, Ua as defaultVisualState, Ui as raiseContrast, Un as resolveColorValue, Ur as pathValuesEqual, Ut as runFontString, V as parseFlexDirection, Va as writeOverrideProperty, Vi as contrastRatio, Vn as nextCaretToggle, Vr as inputsEqual, Vt as layoutTextLines, W as AlignContent, Wa as hasVisualState, Wi as relativeLuminance, Wn as isVideoSurface, Wr as UiTransforms, Wt as spanOf, X as CanvasPlatformSurface, Xa as UiFocusEvent, Xi as defaultShadows, Xn as layoutParagraph, Xr as gradientPaint, Xt as fontStackFor, Y as parseMainAxisAlignment, Ya as UiEventType, Yi as spacingSteps, Yn as ELLIPSIS, Yr as MAX_GRADIENT_STOPS, Yt as clearFontStacks, Z as UiPlatformAdapter, Za as UiGestureEvent, Zi as shadowsEqual, Zn as proportionalFontMetrics, Zr as gradientsEqual, Zt as registerFontStack, _ as LABEL_PADDING_X, _a as textContentOf, _i as normalizeBorderRadius, _n as selectionRangeOf, _r as resolveNumber, _t as scrollRange, a as PaintPictureCache, aa as isShapeName, ai as isMinMaxTrack, an as isPaintVisible, ao as UiWheelDeltaMode, ar as offsetForVerticalMove, at as UiPinchRecognizer, b as snapScroll, ba as colorsEqualPalette, bi as propertyValuesEqual, bn as isNodeHitTestable, br as resolveString, bt as scrollbarZoneAt, c as EMPTY_RECORDING, ca as isTypographyRole, ci as percent, cn as resolvePaintState, co as wheelDeltaYOf, cr as graphemeBoundaries, ct as UiKeyboardController, d as tracePathData, da as editableSpansOf, di as UiBorderRadiuses, dn as matchRangesOf, do as UiBinding, dr as nextGraphemeEnd, dt as UiHitTester, ea as boxShadowArraysEqual, ei as validateGradient, en as DEFAULT_FONT_WEIGHT, eo as UiPasteEvent, er as lineIndexAtY, et as prepareInputSurface, f as ScaledImageCache, fa as flattenTextSpans, fi as borderRadius, fn as setMatchRanges, fr as nextWordEnd, ft as SCROLLBAR_HOVER_ZONE, g as paintsAfterChildren, ga as spannedTextOf, gi as borderRadiusValuesEqual, gn as selectableTextOf, gr as resolveBoolean, gt as scrollLeaderOf, h as hasDecorationPhase, ha as spanAtOffset, hi as borderRadiusIsZero, hn as selectableTextNodes, hr as wordRangeAt, ht as SCROLLBAR_THICKNESS, i as traceRoundedRect, ia as defaultShapes, ii as isFrLength, in as createPaintState, io as UiTextChangeEvent, ir as offsetAtX, it as UiGestureRecognizer, j as accumulatedOffsetTo, ja as rgba, ji as lightTheme, jn as setLinkHover, jr as UI_ROLES, jt as editingGroupOf, k as labelNode, ka as parseColor, ki as unknownContainerSize, kn as linkOf, kr as propertyValuesEqualByName, kt as comparePositions, l as PaintRecorder, la as typographyEqual, li as repeat, ln as TEXT_MATCHES_PROP, lo as UiNodeType, lr as lineEndAt, lt as UiPointerController, m as decorationRect, ma as resolvedSpansOf, mi as borderRadiusEqual, mn as clearSelectionRange, mr as previousWordStart, mt as SCROLLBAR_MIN_THUMB, n as createCanvasSurface, na as boxShadowReach, ni as fr, nn as colorToCss, no as UiPointerEvent, nr as lineLimit, nt as UiEditingController, o as paintPictures, oa as shapesEqual, oi as isPercentLength, on as normalizeTextAlign, oo as UiWheelEvent, or as selectionRects, ot as UiWheelController, p as decorationColor, pa as hiddenRangesOf, pi as borderRadiusCorners, pn as TEXT_SELECTION_PROP, pr as previousGraphemeStart, pt as SCROLLBAR_INSET, q as parseAlignContent, qa as MOUSE_POINTER, qi as scaleSpacing, qn as ParagraphTextMeasurer, qr as transformIsIdentity, qt as textRunDecorations, r as Canvas2DRenderer, ra as boxShadowsEqual, ri as isAutoLength, rn as computeObjectFitRect, ro as UiSelectionChangeEvent, rr as offsetAtPoint, rt as UiTouchScroller, s as PaintTarget, sa as defaultTypography, si as minmax, sn as normalizeVerticalAlign, so as noKeyModifiers, sr as EditableTextModel, st as isScrollContainer, t as CanvasSurface, ta as boxShadowRadius, ti as auto, tn as DEFAULT_TEXT_COLOR, to as UiPinchEvent, tr as lineIndexForOffset, tt as touchActionFor, u as replayPaint, ua as defaultTextStyle, ui as resolveLength, un as clearMatchRanges, uo as DirtyFlags, ur as lineStartAt, ut as UiFocusManager, v as drawOverlayShapes, va as textSpansEqual, vi as uniformBorderRadius, vn as setSelectionRange, vr as resolveProperty, vt as scrollbarThumb, w as describeLength, wa as colorToHex, wi as noInsets, wn as isPressable, wr as getPropertyNames, wt as paragraphGeometry, x as LayoutEngine, xa as darkColors, xi as UiEnvironmentKeys, xn as isNodeInert, xr as UiGraph, xt as UiInputDispatcher, y as labelOrigin, ya as textStylesEqual, yi as defineProperty, yn as isNodeFocusable, yr as resolvePropertyByName, yt as scrollbarThumbs, z as isLayoutProtocol, za as resetOverrideWarnings, zi as themeExtensionsEqual, zn as isMultiline, zr as UI_SUBGRID_AXES, zt as drawText } from "./CanvasSurface-CDjWI3EH.js";
2
2
  import { BehaviorSubject, EMPTY, Subject, combineLatest, distinctUntilChanged, isObservable as isObservable$1, map, of } from "rxjs";
3
3
  //#region src/animation/UiEasing.ts
4
4
  /** Progress equals time. What a spinner and a sweep want. */
@@ -836,11 +836,12 @@ var UiSharedElements = class {
836
836
  * But it must not disappear *yet*. A claim happens during
837
837
  * reconciliation, and the arriving node has no box until the frame
838
838
  * lays out — so yielding here leaves a window in which neither
839
- * element is drawn. For a transform morph that window is closed
840
- * within the same frame; for a geometry morph, which cannot write a
841
- * box after layout has run, it is a whole frame long, and a whole
842
- * frame with neither the old card nor the new one is a flash of the
843
- * page behind them. It was exactly that visible.
839
+ * element is drawn. The window closes within the frame now, for a
840
+ * geometry morph as for a transform one, but only because the
841
+ * arriving element takes its place in that frame's layout pass; when
842
+ * a geometry morph's box waited for the next frame, a whole frame
843
+ * with neither the old card nor the new one was a flash of the page
844
+ * behind them, and it was exactly that visible.
844
845
  *
845
846
  * So the caller yields the previous holder at the moment it actually
846
847
  * takes its place. Until then both are on screen, in the same
@@ -1199,7 +1200,7 @@ const PRESS_ONLY = Object.freeze({
1199
1200
  hover: false,
1200
1201
  press: true
1201
1202
  });
1202
- const kind$4 = defineModifier({
1203
+ const kind$5 = defineModifier({
1203
1204
  name: "interactive",
1204
1205
  attach(host, options) {
1205
1206
  let hovered = false;
@@ -1246,15 +1247,15 @@ const kind$4 = defineModifier({
1246
1247
  });
1247
1248
  /** Hover and press. */
1248
1249
  function interactive(options = BOTH) {
1249
- return kind$4(options);
1250
+ return kind$5(options);
1250
1251
  }
1251
1252
  /** Hover only. */
1252
1253
  function hoverable() {
1253
- return kind$4(HOVER_ONLY);
1254
+ return kind$5(HOVER_ONLY);
1254
1255
  }
1255
1256
  /** Press only. */
1256
1257
  function pressable() {
1257
- return kind$4(PRESS_ONLY);
1258
+ return kind$5(PRESS_ONLY);
1258
1259
  }
1259
1260
  /**
1260
1261
  * What every Button carries. One shared value, so `sameArgs` matches it
@@ -1263,7 +1264,7 @@ function pressable() {
1263
1264
  * that genuinely differ do detach and re-attach it, losing the hover and
1264
1265
  * press state with them, which is the reason this one is a constant.
1265
1266
  */
1266
- const BUTTON_INTERACTION = kind$4(BOTH);
1267
+ const BUTTON_INTERACTION = kind$5(BOTH);
1267
1268
  function sameStates(a, b) {
1268
1269
  if (a.size !== b.size) return false;
1269
1270
  for (const state of b) if (!a.has(state)) return false;
@@ -1769,13 +1770,13 @@ var Host = class {
1769
1770
  }
1770
1771
  this.own(environment.onChange(this.node, listener));
1771
1772
  }
1772
- focus() {
1773
+ focus(options) {
1773
1774
  const focus = this.services.focus;
1774
1775
  if (focus === void 0) {
1775
1776
  warnMissing(this.name, "move focus", "focus");
1776
1777
  return;
1777
1778
  }
1778
- focus.focus(this.node);
1779
+ focus.focus(this.node, options);
1779
1780
  }
1780
1781
  isFocused() {
1781
1782
  return this.services.focus?.isFocused(this.node) ?? false;
@@ -2497,15 +2498,30 @@ var UiGraphBuilder = class {
2497
2498
  * instance is unchanged and torn down when a property stops
2498
2499
  * being reactive.
2499
2500
  */
2501
+ /**
2502
+ * The properties each node's element declared last time, so a render
2503
+ * that stops declaring one takes it off the node.
2504
+ *
2505
+ * Only bindings used to be torn down that way. A plain value stayed:
2506
+ * a conditional that swapped `<scrollview padding={20}>` for a
2507
+ * `<scrollview>` reused the node and kept the padding, and an editor
2508
+ * switching from its source view back to its document came back
2509
+ * twenty pixels narrower. Only what the builder declared is tracked,
2510
+ * so what modifiers and the runtime write on a node is left alone.
2511
+ */
2512
+ declaredProps = /* @__PURE__ */ new WeakMap();
2500
2513
  reconcileProps(node, props, parent) {
2501
2514
  this.reconcileTransitions(node, props[TRANSITION_PROP]);
2502
2515
  const present = /* @__PURE__ */ new Set();
2503
2516
  const presentEvents = /* @__PURE__ */ new Set();
2504
2517
  let declaredModifiers;
2518
+ let declaredRef;
2519
+ let hasRef = false;
2505
2520
  for (const [property, value] of Object.entries(props)) {
2506
2521
  if (property === KEY_PROP) continue;
2507
2522
  if (property === REF_PROP) {
2508
- this.reconcileRef(node, value);
2523
+ declaredRef = value;
2524
+ hasRef = true;
2509
2525
  continue;
2510
2526
  }
2511
2527
  if (property === MODIFIERS_PROP) {
@@ -2532,7 +2548,13 @@ var UiGraphBuilder = class {
2532
2548
  }
2533
2549
  for (const binding of this.graph.getBindingsForNode(node)) if (!present.has(binding.property)) this.graph.unbind(binding);
2534
2550
  for (const binding of this.graph.getEventBindingsForNode(node)) if (!presentEvents.has(binding.type)) this.graph.unbindEvent(node, binding);
2551
+ const previous = this.declaredProps.get(node);
2552
+ if (previous !== void 0) {
2553
+ for (const property of previous) if (!present.has(property)) this.graph.removeNodeProperty(node, property, propertyEffects(property));
2554
+ }
2555
+ this.declaredProps.set(node, present);
2535
2556
  if (node.environment === null && parent?.environment != null) node.environment = this.graph.buildNodeEnvironment(node, parent);
2557
+ if (hasRef) this.reconcileRef(node, declaredRef);
2536
2558
  this.reconcileModifiers(node, declaredModifiers);
2537
2559
  }
2538
2560
  /**
@@ -3183,6 +3205,9 @@ function lazyList(axis, props, renderItem, grid) {
3183
3205
  * padding, and a layout that switched arms at 600 px would otherwise
3184
3206
  * switch at 600 px of border box and lay itself out in 560.
3185
3207
  *
3208
+ * What a subtree builds from the size it reports is laid out on the
3209
+ * same frame, before anything paints; see `UiModifierHost.onLayout`.
3210
+ *
3186
3211
  * `Responsive` attaches this for you. Attach it by hand when the
3187
3212
  * source has to be reachable somewhere the helper's own children are
3188
3213
  * not, and put the same object on the node's `containerSize` prop.
@@ -3218,9 +3243,15 @@ const sizeContainer = defineModifier({
3218
3243
  * about it and the thing a media query cannot do: a card in a sidebar
3219
3244
  * asks how wide the card is, not how wide the window is.
3220
3245
  *
3221
- * Nothing is written until the node has been laid out once, so the
3222
- * first frame uses the element's own values. Give the element the
3223
- * narrowest band's values as its declared props if that matters.
3246
+ * Nothing is written until the node has been laid out once, but the
3247
+ * first frame is already right: the runtime lays out again before it
3248
+ * paints when a layout listener changes layout (see
3249
+ * `UiModifierHost.onLayout`), so the frame a node first appears on,
3250
+ * and the frame a resize crosses a width on, are drawn with the band's
3251
+ * values. The element's own values are what that first pass measures
3252
+ * with; give it the narrowest band's values as its declared props so a
3253
+ * layout nothing settles (a headless one, a spec driving layout by
3254
+ * hand) starts from the right band.
3224
3255
  */
3225
3256
  const breakpoint = defineModifier({
3226
3257
  name: "breakpoint",
@@ -3273,7 +3304,9 @@ const breakpoint = defineModifier({
3273
3304
  * The first build happens before any layout, when the size is zero, so
3274
3305
  * `build` must return something sensible for a container whose room is
3275
3306
  * not yet known. Zero picks the narrowest arm, which is the right
3276
- * guess and also what a phone gets.
3307
+ * guess and also what a phone gets. It is never what a wider container
3308
+ * paints: the first layout reports the real size, the arm for it is
3309
+ * built, and the runtime lays that out before the frame paints.
3277
3310
  */
3278
3311
  function Responsive(props, build) {
3279
3312
  const { at, as = "column", modifiers, ...rest } = props;
@@ -4375,6 +4408,12 @@ const MODIFIER_KEYS = /* @__PURE__ */ new Set([
4375
4408
  * Without that rule an application with a `n` for "new note" becomes an
4376
4409
  * application you cannot type the letter n into, which is the failure
4377
4410
  * every home-grown key handler eventually ships.
4411
+ *
4412
+ * ## Pressing is not a shortcut
4413
+ *
4414
+ * A bare Enter or Space is skipped while a button or link has focus,
4415
+ * unless the shortcut is that control's own: the control is focused, so
4416
+ * it has the key first, as it would in a browser.
4378
4417
  */
4379
4418
  var UiShortcutRegistry = class {
4380
4419
  bindings = [];
@@ -4390,10 +4429,11 @@ var UiShortcutRegistry = class {
4390
4429
  /** Adds a shortcut. The returned function removes it again. */
4391
4430
  register(shortcut) {
4392
4431
  const steps = parseShortcut(shortcut.keys);
4432
+ this.platform ??= detectEditingPlatform();
4393
4433
  const binding = {
4394
4434
  ...shortcut,
4395
4435
  steps,
4396
- display: formatShortcut(steps)
4436
+ display: formatShortcut(steps, this.platform)
4397
4437
  };
4398
4438
  this.bindings.push(binding);
4399
4439
  return () => {
@@ -4434,6 +4474,10 @@ var UiShortcutRegistry = class {
4434
4474
  */
4435
4475
  handleKey(key, modifiers, focused) {
4436
4476
  if (MODIFIER_KEYS.has(key)) return false;
4477
+ if (focused !== null && isTypingInto(focused) && this.isEditingKey(key, modifiers)) {
4478
+ this.pending = [];
4479
+ return false;
4480
+ }
4437
4481
  const step = stepFor(key, modifiers);
4438
4482
  const at = this.now();
4439
4483
  if (this.pending.length > 0 && at - this.pendingAt > this.chordTimeout) this.pending = [];
@@ -4456,6 +4500,13 @@ var UiShortcutRegistry = class {
4456
4500
  this.pending = [];
4457
4501
  return false;
4458
4502
  }
4503
+ platform = null;
4504
+ /** Whether a field would take this key as an edit of its own, rather than as text or as Enter. */
4505
+ isEditingKey(key, modifiers) {
4506
+ this.platform ??= detectEditingPlatform();
4507
+ const command = commandForKey(key, modifiers, this.platform, false);
4508
+ return command !== null && command.kind !== "newline" && command.kind !== "insert";
4509
+ }
4459
4510
  /** Forgets a half-typed chord, for a route change or a lost focus. */
4460
4511
  reset() {
4461
4512
  this.pending = [];
@@ -4463,17 +4514,20 @@ var UiShortcutRegistry = class {
4463
4514
  /**
4464
4515
  * Whether a binding would fire for a key going to `focused`.
4465
4516
  *
4466
- * Three things take a shortcut out: its scope does not contain the
4467
- * focused node, its own `when` says no, and, for a shortcut with no
4468
- * modifier at all, the focused node is somewhere text is being
4469
- * typed. The last is the rule that keeps a single-letter shortcut
4470
- * from making a text field unusable.
4517
+ * Four things take a shortcut out: its scope does not contain the
4518
+ * focused node, its own `when` says no, for a shortcut with no
4519
+ * modifier at all the focused node is somewhere text is being typed,
4520
+ * and for a bare Enter or Space the focused node is a button that
4521
+ * isn't the shortcut's own. The third keeps a single-letter shortcut
4522
+ * from making a text field unusable; the fourth keeps a list's Enter
4523
+ * from opening a row when the button focused inside it was pressed.
4471
4524
  */
4472
4525
  isLive(binding, focused) {
4473
4526
  const scope = binding.scope ?? null;
4474
4527
  if (scope !== null && (focused === null || !containsNode(scope, focused))) return false;
4475
4528
  if (binding.when !== void 0 && !binding.when()) return false;
4476
4529
  if (focused !== null && isTypingInto(focused) && binding.steps.every((step) => isBare(step))) return false;
4530
+ if (focused !== null && scope !== focused && isPressing(binding.steps) && isPressable(focused)) return false;
4477
4531
  return true;
4478
4532
  }
4479
4533
  };
@@ -4508,6 +4562,11 @@ function isTypingInto(node) {
4508
4562
  for (let current = node; current !== null; current = current.parent) if (current.type === "editable-text" && !isNodeInert(current)) return true;
4509
4563
  return false;
4510
4564
  }
4565
+ /** A bare Enter or Space on its own: what presses a focused button. */
4566
+ function isPressing(steps) {
4567
+ const [step] = steps;
4568
+ return steps.length === 1 && step !== void 0 && isBare(step) && !step.shift && (step.key === "Enter" || step.key === " ");
4569
+ }
4511
4570
  /** A press with no modifier at all: an ordinary character. */
4512
4571
  function isBare(step) {
4513
4572
  return !step.mod && !step.ctrl && !step.meta && !step.alt;
@@ -4569,10 +4628,24 @@ function parseStep(text) {
4569
4628
  * `'Mod+K'` and `'Mod+k'` are the same shortcut, and the browser
4570
4629
  * reports whichever the shift state produced. Anything longer than one
4571
4630
  * character is a named key (`'Enter'`, `'ArrowUp'`) and keeps its case.
4631
+ *
4632
+ * The space bar is the exception that has to be spelled out. The
4633
+ * platform reports it as `' '`, which a shortcut string cannot contain
4634
+ * because space separates the steps of a chord, so the name `Space`
4635
+ * stands for it. Before this, `'Space'` was kept as the literal name and
4636
+ * never matched a press: the board's keyboard drag in the issue tracker
4637
+ * was the first thing to need it.
4572
4638
  */
4573
4639
  function normalizeKey(key) {
4640
+ const named = NAMED_KEYS[key.toLowerCase()];
4641
+ if (named !== void 0) return named;
4574
4642
  return key.length === 1 ? key.toLowerCase() : key;
4575
4643
  }
4644
+ /** Key names a shortcut string uses for keys it cannot spell. */
4645
+ const NAMED_KEYS = {
4646
+ space: " ",
4647
+ spacebar: " "
4648
+ };
4576
4649
  /** Whether the presses so far could still complete this shortcut. */
4577
4650
  function matchesPrefix(steps, sequence) {
4578
4651
  if (sequence.length > steps.length) return false;
@@ -4595,15 +4668,29 @@ function stepFor(key, modifiers) {
4595
4668
  };
4596
4669
  }
4597
4670
  /**
4598
- * The shortcut as a palette should print it.
4599
- *
4600
- * `Mod` is printed as `Ctrl`, not as a platform glyph: the render
4601
- * worker cannot see the platform, and a wrong symbol is worse than a
4602
- * plain word. An application that knows what it is running on can
4603
- * format the `steps` itself.
4671
+ * The shortcut as a palette should print it, the way the platform
4672
+ * writes its own: `⇧⌘K` on a Mac, where `Mod` is Command, and
4673
+ * `Ctrl+Shift+K` elsewhere, where it is Control. The platform is the
4674
+ * one the editing keys follow (`detectEditingPlatform`, from the user
4675
+ * agent, which a worker can read too).
4604
4676
  */
4605
- function formatShortcut(steps) {
4606
- return steps.map(formatStep).join(" ");
4677
+ function formatShortcut(steps, platform = detectEditingPlatform()) {
4678
+ return steps.map((step) => platform === "mac" ? formatMacStep(step) : formatStep(step)).join(" ");
4679
+ }
4680
+ /** In the order the Mac's menus print them: Control, Option, Shift, Command. */
4681
+ function formatMacStep(step) {
4682
+ return `${step.ctrl ? "⌃" : ""}${step.alt ? "⌥" : ""}${step.shift ? "⇧" : ""}${step.mod || step.meta ? "⌘" : ""}${keyName(step.key)}`;
4683
+ }
4684
+ /** The arrows as arrows, which every keyboard prints them as. */
4685
+ const KEY_NAMES = {
4686
+ " ": "Space",
4687
+ ArrowUp: "↑",
4688
+ ArrowDown: "↓",
4689
+ ArrowLeft: "←",
4690
+ ArrowRight: "→"
4691
+ };
4692
+ function keyName(key) {
4693
+ return KEY_NAMES[key] ?? (key.length === 1 ? key.toUpperCase() : key);
4607
4694
  }
4608
4695
  function formatStep(step) {
4609
4696
  const parts = [];
@@ -4611,7 +4698,7 @@ function formatStep(step) {
4611
4698
  if (step.meta) parts.push("Meta");
4612
4699
  if (step.alt) parts.push("Alt");
4613
4700
  if (step.shift) parts.push("Shift");
4614
- parts.push(step.key.length === 1 ? step.key.toUpperCase() : step.key);
4701
+ parts.push(keyName(step.key));
4615
4702
  return parts.join("+");
4616
4703
  }
4617
4704
  function defaultClock() {
@@ -4656,6 +4743,8 @@ var UiDragSession = class {
4656
4743
  zones = [];
4657
4744
  current = null;
4658
4745
  inside = null;
4746
+ /** Every zone the point is in that would take the payload, winner or not. */
4747
+ hovering = /* @__PURE__ */ new Set();
4659
4748
  /** Registers a drop target. The returned function unregisters it. */
4660
4749
  addZone(zone) {
4661
4750
  this.zones.push(zone);
@@ -4719,6 +4808,7 @@ var UiDragSession = class {
4719
4808
  }
4720
4809
  const effect = zone.drop(state);
4721
4810
  zone.leave();
4811
+ this.unhover();
4722
4812
  return {
4723
4813
  node: zone.node,
4724
4814
  effect
@@ -4729,6 +4819,12 @@ var UiDragSession = class {
4729
4819
  this.inside?.leave();
4730
4820
  this.inside = null;
4731
4821
  this.current = null;
4822
+ this.unhover();
4823
+ }
4824
+ /** Tells every zone the drag was hovering over that it no longer is. */
4825
+ unhover() {
4826
+ for (const zone of this.hovering) zone.hover?.(null);
4827
+ this.hovering.clear();
4732
4828
  }
4733
4829
  /**
4734
4830
  * Turns a shell's file-drop message into an ordinary drag.
@@ -4779,10 +4875,12 @@ var UiDragSession = class {
4779
4875
  if (state === null) return;
4780
4876
  let best = null;
4781
4877
  let bestDepth = -1;
4878
+ const containing = /* @__PURE__ */ new Set();
4782
4879
  for (const zone of this.zones) {
4783
4880
  if (!zone.accepts(state.payload)) continue;
4784
4881
  const box = zone.boxOf();
4785
4882
  if (box === null || !contains$1(box, state.x, state.y)) continue;
4883
+ containing.add(zone);
4786
4884
  const depth = depthOf(zone.node);
4787
4885
  if (depth > bestDepth) {
4788
4886
  best = zone;
@@ -4793,9 +4891,10 @@ var UiDragSession = class {
4793
4891
  this.inside?.leave();
4794
4892
  this.inside = best;
4795
4893
  best?.enter(state);
4796
- return;
4797
- }
4798
- best?.over(state);
4894
+ } else best?.over(state);
4895
+ for (const zone of this.hovering) if (!containing.has(zone)) zone.hover?.(null);
4896
+ for (const zone of containing) zone.hover?.(state);
4897
+ this.hovering = containing;
4799
4898
  }
4800
4899
  };
4801
4900
  function contains$1(box, x, y) {
@@ -5007,7 +5106,7 @@ function ringShapes(options) {
5007
5106
  * costs nothing here because the options of a focus ring do not
5008
5107
  * change while it is attached.
5009
5108
  */
5010
- const kind$3 = defineModifier({
5109
+ const kind$4 = defineModifier({
5011
5110
  name: "focusRing",
5012
5111
  attach(host, options) {
5013
5112
  const shapes = ringShapes(options);
@@ -5018,7 +5117,7 @@ const kind$3 = defineModifier({
5018
5117
  host.onFocusChange(sync);
5019
5118
  }
5020
5119
  });
5021
- const DEFAULT_RING = kind$3(Object.freeze({}));
5120
+ const DEFAULT_RING = kind$4(Object.freeze({}));
5022
5121
  /**
5023
5122
  * The ring, with the theme's own colour and spacing.
5024
5123
  *
@@ -5029,7 +5128,7 @@ const DEFAULT_RING = kind$3(Object.freeze({}));
5029
5128
  * attachment.
5030
5129
  */
5031
5130
  function focusRing(options) {
5032
- return options === void 0 ? DEFAULT_RING : kind$3(options);
5131
+ return options === void 0 ? DEFAULT_RING : kind$4(options);
5033
5132
  }
5034
5133
  /**
5035
5134
  * A border per edge, as paint rather than as layout.
@@ -5138,24 +5237,62 @@ function borderShapes(options) {
5138
5237
  //#endregion
5139
5238
  //#region src/modifiers/focus.ts
5140
5239
  /**
5141
- * One shared instance, so the arguments keep their identity across
5142
- * renders and the modifier is never detached and re-attached (which
5143
- * would autofocus a second time).
5240
+ * Takes focus the first time the node is laid out.
5241
+ *
5242
+ * The one a dialog needs: an overlay that opens with the caret already
5243
+ * in its first field, without the component that opened it reaching
5244
+ * for a `ref` and a focus store.
5245
+ *
5246
+ * **Why the first layout and not the attach.** A modifier attaches
5247
+ * while its node is still being built, before the builder inserts it
5248
+ * into its parent, so at attach time the node has no parent and is not
5249
+ * under the focus manager's traversal root. `UiFocusManager.focus`
5250
+ * would accept it anyway (it asks whether the node is focusable, not
5251
+ * where it is), and the result would be a focused node that Tab cannot
5252
+ * reach and that no ancestor sees the focus event from. The first
5253
+ * layout is the first moment the node is demonstrably on screen, and
5254
+ * it is the same frame in every case that matters, because a node
5255
+ * mounted into a live tree is laid out on the frame that mounted it.
5256
+ *
5257
+ * It fires once. A node that is autofocused, loses focus to something
5258
+ * the person clicked, and is then laid out again does not steal the
5259
+ * focus back; that would make an autofocus a focus trap.
5260
+ *
5261
+ * A node that cannot take focus is left alone and no error is raised:
5262
+ * `focus()` refuses a node that is inert, not focusable, or outside an
5263
+ * active focus scope, which is exactly the set of cases where an
5264
+ * application would not want the focus moved either.
5144
5265
  */
5145
- const AUTO_FOCUS = defineModifier({
5266
+ const kind$3 = defineModifier({
5146
5267
  name: "autoFocus",
5147
- attach(host) {
5268
+ attach(host, options) {
5148
5269
  let done = false;
5149
5270
  host.onLayout(() => {
5150
5271
  if (done) return;
5151
5272
  done = true;
5152
- host.focus();
5273
+ host.focus(options);
5153
5274
  });
5154
5275
  }
5155
- })(void 0);
5156
- /** Takes focus the first time the node is laid out. */
5157
- function autoFocus() {
5158
- return AUTO_FOCUS;
5276
+ });
5277
+ /**
5278
+ * One shared instance of each, so the arguments keep their identity
5279
+ * across renders and the modifier is never detached and re-attached
5280
+ * (which would autofocus a second time).
5281
+ */
5282
+ const AUTO_FOCUS = kind$3({});
5283
+ const AUTO_FOCUS_IN_PLACE = kind$3({ preventScroll: true });
5284
+ /**
5285
+ * Takes focus the first time the node is laid out.
5286
+ *
5287
+ * The node is scrolled into view, as focus from code always is, once
5288
+ * the frame's layout has settled. Pass `{ preventScroll: true }` to
5289
+ * leave the page where it is, as `element.focus({ preventScroll: true })`
5290
+ * does: for a region focused when a page opens so a screen reader reads
5291
+ * it, where revealing it would scroll a tall region to a few pixels
5292
+ * short of its own top instead of leaving the page at its start.
5293
+ */
5294
+ function autoFocus(options = {}) {
5295
+ return options.preventScroll === true ? AUTO_FOCUS_IN_PLACE : AUTO_FOCUS;
5159
5296
  }
5160
5297
  //#endregion
5161
5298
  //#region src/modifiers/clickOutside.ts
@@ -5485,13 +5622,20 @@ var DropTarget = class {
5485
5622
  x: state.x,
5486
5623
  y: state.y
5487
5624
  });
5488
- this.updateAutoScroll(state);
5489
5625
  }
5490
5626
  leave() {
5491
5627
  for (const property of Object.keys(this.options.over ?? {})) this.host.clear(property);
5492
- this.stopScrolling();
5493
5628
  this.options.onLeave?.();
5494
5629
  }
5630
+ /**
5631
+ * Auto-scroll follows the point being inside this zone, not this zone
5632
+ * winning the drop: a list covered in row zones is never the winner,
5633
+ * and still has to scroll when a card is held at its edge.
5634
+ */
5635
+ hover(state) {
5636
+ if (state === null) this.stopScrolling();
5637
+ else this.updateAutoScroll(state);
5638
+ }
5495
5639
  drop(state) {
5496
5640
  return this.options.onDrop(state.payload, {
5497
5641
  x: state.x,
@@ -6780,15 +6924,15 @@ var SharedElementController = class {
6780
6924
  *
6781
6925
  * Held rather than called on arrival: see `UiSharedElements.claim`.
6782
6926
  * Between claiming a name and taking the departing element's place
6783
- * there is at least one layout, and for a geometry morph a whole
6784
- * frame — and hiding it up front makes that a frame with neither
6785
- * element on screen, which reads as a flash of the page behind them.
6927
+ * there is at least one layout pass — and hiding it up front, on a
6928
+ * frame painted between the two, would leave neither element on
6929
+ * screen, which reads as a flash of the page behind them.
6786
6930
  */
6787
6931
  yieldPrevious = null;
6788
6932
  yielded = false;
6789
6933
  /** Whether a morph is running, so `onMorph` is never told twice. */
6790
6934
  morphing = false;
6791
- /** Set for the one frame a geometry morph spends being measured. */
6935
+ /** Set between a geometry morph writing its first box and that box being laid out. */
6792
6936
  geometryTarget = null;
6793
6937
  constructor(host, args) {
6794
6938
  this.host = host;
@@ -8294,6 +8438,40 @@ function onDeviceLost(listener) {
8294
8438
  onDeviceLostListeners.delete(listener);
8295
8439
  };
8296
8440
  }
8441
+ //#endregion
8442
+ //#region src/rendering/webgpu/WebGPUShader.ts
8443
+ /**
8444
+ * WGSL sources for the two WebGPU pipelines.
8445
+ *
8446
+ * Both draw one unit quad per instance. An instance carries the
8447
+ * rectangle it covers in absolute layout coordinates and the affine
8448
+ * transform that maps those coordinates to logical screen pixels, so
8449
+ * every instance under one node shares the node's transform and the
8450
+ * rectangle is honest — a scrollbar thumb sits where its geometry says.
8451
+ *
8452
+ * Clipping is two-layered. The rectangular part is a scissor set per
8453
+ * draw command. The rounded part is a **clip chain**: a storage buffer
8454
+ * of clipping boxes with corner radii, each holding its parent's index
8455
+ * and the inverse of its own transform. An instance names its
8456
+ * innermost rounded clip; the fragment shader carries the pixel back
8457
+ * into each clip's space up the chain and multiplies their coverages,
8458
+ * so every rounded ancestor applies.
8459
+ *
8460
+ * Edges are anti-aliased by coverage rather than cut by `discard`: a
8461
+ * pixel's alpha is scaled by how far its centre sits inside the shape,
8462
+ * in physical pixels. A box on integer coordinates is still crisp —
8463
+ * every pixel centre is half a pixel from its edge — and rounded
8464
+ * corners match the anti-aliased paths Canvas2D draws.
8465
+ *
8466
+ * A box shadow is a primitive too, drawn analytically: the coverage of
8467
+ * a Gaussian-blurred rounded rectangle is integrated in closed form
8468
+ * across one axis (an error function) and sampled along the other, as
8469
+ * in Evan Wallace's "Fast rounded rectangle shadows". It is exact for
8470
+ * square corners and within a fraction of a percent for round ones,
8471
+ * which is closer than browsers' own blur gets to a Gaussian.
8472
+ */
8473
+ /** Mirrors `BOX_SHADOW_BLUR_REACH`: a shadow's quad reaches this many blur radii past its shape. */
8474
+ const SHADOW_REACH = BOX_SHADOW_BLUR_REACH;
8297
8475
  const SHARED = `
8298
8476
  // x: logical width, y: logical height, z: device pixel ratio.
8299
8477
  @group(0) @binding(0) var<uniform> uView: vec4f;
@@ -8438,6 +8616,86 @@ fn gradientColor(index: u32, local: vec2f) -> vec4f {
8438
8616
  return unpremultiply(previousColor);
8439
8617
  }
8440
8618
 
8619
+ // PrimitiveKind: 0 fill, 1 border, 2 shadow, 3 inset shadow.
8620
+ const KIND_BORDER = 1u;
8621
+ const KIND_SHADOW = 2u;
8622
+ const SHADOW_REACH = ${SHADOW_REACH};
8623
+
8624
+ // Abramowitz and Stegun's approximation, to about 5e-4, for two values.
8625
+ fn erf2(x: vec2f) -> vec2f {
8626
+ let s = sign(x);
8627
+ let a = abs(x);
8628
+ var t = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a;
8629
+ t = t * t;
8630
+ return s - s / (t * t);
8631
+ }
8632
+
8633
+ fn gaussian(x: f32, sigma: f32) -> f32 {
8634
+ return exp(-(x * x) / (2.0 * sigma * sigma)) / (2.5066283 * sigma);
8635
+ }
8636
+
8637
+ // The blurred shape's coverage along x at one height y, both relative
8638
+ // to its centre: an error function across the row the rounded corner
8639
+ // leaves at that height.
8640
+ fn shadowRow(x: f32, y: f32, sigma: f32, corner: f32, halfSize: vec2f) -> f32 {
8641
+ let delta = min(halfSize.y - corner - abs(y), 0.0);
8642
+ let curved = halfSize.x - corner + sqrt(max(0.0, corner * corner - delta * delta));
8643
+ let integral = 0.5 + 0.5 * erf2((x + vec2f(-curved, curved)) * (0.70710678 / sigma));
8644
+ return integral.y - integral.x;
8645
+ }
8646
+
8647
+ // Coverage at a point of a rounded rectangle blurred by a Gaussian of
8648
+ // the given standard deviation. The row integral is weighted by the
8649
+ // Gaussian over the three deviations either side that it reaches.
8650
+ fn blurredRoundedRect(point: vec2f, origin: vec2f, size: vec2f, radius: f32, sigma: f32, dpr: f32) -> f32 {
8651
+ if (size.x <= 0.0 || size.y <= 0.0) {
8652
+ return 0.0;
8653
+ }
8654
+ if (sigma * dpr < 0.25) {
8655
+ // Under a quarter of a device pixel: the sharp shape, anti-aliased.
8656
+ return coverage(roundedRectDistance(point, origin, size, radius), dpr);
8657
+ }
8658
+ let halfSize = size * 0.5;
8659
+ let corner = min(radius, min(halfSize.x, halfSize.y));
8660
+ let p = point - (origin + halfSize);
8661
+ let low = p.y - halfSize.y;
8662
+ let high = p.y + halfSize.y;
8663
+ let first = clamp(-3.0 * sigma, low, high);
8664
+ let last = clamp(3.0 * sigma, low, high);
8665
+ let stride = (last - first) / 4.0;
8666
+ var y = first + stride * 0.5;
8667
+ var value = 0.0;
8668
+ for (var i = 0; i < 4; i = i + 1) {
8669
+ value = value + shadowRow(p.x, p.y - y, sigma, corner, halfSize) * gaussian(y, sigma) * stride;
8670
+ y = y + stride;
8671
+ }
8672
+ return clamp(value, 0.0, 1.0);
8673
+ }
8674
+
8675
+ // A shadow's alpha at a point of its quad; see the instance layout in
8676
+ // WebGPURenderData.ts for what each field holds.
8677
+ fn shadowAlpha(kind: u32, local: vec2f, size: vec2f, radius: f32, blur: f32, shadow: vec4f, dpr: f32) -> f32 {
8678
+ let sigma = blur * 0.5;
8679
+ let offset = shadow.xy;
8680
+ let spread = shadow.z;
8681
+ if (kind == KIND_SHADOW) {
8682
+ // The quad is the blurred shape grown by the blur's reach; the box
8683
+ // sits back by the offset and in by the spread, and hides it.
8684
+ let reach = blur * SHADOW_REACH;
8685
+ let shapeOrigin = vec2f(reach, reach);
8686
+ let shapeSize = size - vec2f(reach, reach) * 2.0;
8687
+ let boxOrigin = shapeOrigin - offset + vec2f(spread, spread);
8688
+ let boxSize = shapeSize - vec2f(spread, spread) * 2.0;
8689
+ let blurred = blurredRoundedRect(local, shapeOrigin, shapeSize, radius, sigma, dpr);
8690
+ return blurred * (1.0 - coverage(roundedRectDistance(local, boxOrigin, boxSize, shadow.w), dpr));
8691
+ }
8692
+ // Inset: the quad is the box; everything but the blurred hole is shadow.
8693
+ let holeOrigin = offset + vec2f(spread, spread);
8694
+ let holeSize = size - vec2f(spread, spread) * 2.0;
8695
+ let inside = coverage(roundedRectDistance(local, vec2f(0.0, 0.0), size, radius), dpr);
8696
+ return inside * (1.0 - blurredRoundedRect(local, holeOrigin, holeSize, shadow.w, sigma, dpr));
8697
+ }
8698
+
8441
8699
  struct VertexOutput {
8442
8700
  @builtin(position) position: vec4f,
8443
8701
  @location(0) localPos: vec2f,
@@ -8447,6 +8705,7 @@ struct VertexOutput {
8447
8705
  @location(4) @interpolate(flat) kind: u32,
8448
8706
  @location(5) @interpolate(flat) clipIndex: f32,
8449
8707
  @location(6) @interpolate(flat) gradientIndex: f32,
8708
+ @location(7) @interpolate(flat) shadow: vec4f,
8450
8709
  };
8451
8710
 
8452
8711
  @vertex
@@ -8456,12 +8715,13 @@ fn vs(
8456
8715
  @location(2) instanceSize: vec2f,
8457
8716
  @location(3) instanceColor: vec4f,
8458
8717
  @location(4) radiusOpacityBorder: vec3f,
8459
- @location(5) instanceKind: u32,
8718
+ @location(5) instanceKind: f32,
8460
8719
  @location(6) transformA: vec2f,
8461
8720
  @location(7) transformB: vec2f,
8462
8721
  @location(8) transformC: vec2f,
8463
8722
  @location(9) clipIndex: f32,
8464
8723
  @location(10) gradientIndex: f32,
8724
+ @location(11) shadow: vec4f,
8465
8725
  ) -> VertexOutput {
8466
8726
  var out: VertexOutput;
8467
8727
  // The quad is inflated by one physical pixel on every side so the
@@ -8480,9 +8740,10 @@ fn vs(
8480
8740
  out.size = instanceSize;
8481
8741
  out.color = instanceColor;
8482
8742
  out.radiusOpacityBorder = radiusOpacityBorder;
8483
- out.kind = instanceKind;
8743
+ out.kind = u32(instanceKind + 0.5);
8484
8744
  out.clipIndex = clipIndex;
8485
8745
  out.gradientIndex = gradientIndex;
8746
+ out.shadow = shadow;
8486
8747
  return out;
8487
8748
  }
8488
8749
 
@@ -8492,7 +8753,17 @@ fn fs(in: VertexOutput) -> @location(0) vec4f {
8492
8753
  let dist = roundedRectDistance(in.localPos, vec2f(0.0, 0.0), in.size, in.radiusOpacityBorder.x);
8493
8754
 
8494
8755
  var shape = coverage(dist, dpr);
8495
- if (in.kind != 0u) {
8756
+ if (in.kind >= KIND_SHADOW) {
8757
+ shape = shadowAlpha(
8758
+ in.kind,
8759
+ in.localPos,
8760
+ in.size,
8761
+ in.radiusOpacityBorder.x,
8762
+ in.radiusOpacityBorder.z,
8763
+ in.shadow,
8764
+ dpr
8765
+ );
8766
+ } else if (in.kind == KIND_BORDER) {
8496
8767
  // Border: the band between the outer edge and the inner edge inset
8497
8768
  // by borderWidth.
8498
8769
  let bw = max(in.radiusOpacityBorder.z, 0.0);
@@ -9319,14 +9590,25 @@ function createWebGPUSurface(host) {
9319
9590
  * 2 size.xy
9320
9591
  * 4 color.rgba
9321
9592
  * 8 radius, opacity, borderWidth
9322
- * 11 kind (u32: PrimitiveKind)
9593
+ * 11 kind (PrimitiveKind, as a float)
9323
9594
  * 12 transform 3x2 affine, absolute layout → logical screen
9324
9595
  * 18 clipIndex index into the clip chain, -1 for none
9325
9596
  * 19 gradientIndex index into the frame's gradients, -1 for none
9326
- * 20 (end)
9327
- */
9328
- const INSTANCE_STRIDE_FLOATS = 20;
9329
- const INSTANCE_STRIDE_BYTES = 80;
9597
+ * 20 shadow offsetX, offsetY, spread, the other shape's radius
9598
+ * 24 (end)
9599
+ *
9600
+ * A shadow is two rounded rectangles, the blurred one and the box it
9601
+ * is cut by, and an instance describes the first. For an outer shadow
9602
+ * the rectangle is the blurred shape grown by the blur's reach
9603
+ * (`BOX_SHADOW_BLUR_REACH` × blur), `radius` its corners, `borderWidth`
9604
+ * the blur, and the box it must not show under is recovered from the
9605
+ * offset and spread, with the box's own radius last. An inset shadow's
9606
+ * rectangle is the box, and the hole it is cast from is the box moved
9607
+ * by the offset and shrunk by the spread, with the hole's radius last.
9608
+ * Every other instance writes zeros there.
9609
+ */
9610
+ const INSTANCE_STRIDE_FLOATS = 24;
9611
+ const INSTANCE_STRIDE_BYTES = 96;
9330
9612
  /**
9331
9613
  * Textured instance layout (glyphs and images), in floats:
9332
9614
  *
@@ -9362,6 +9644,10 @@ const NO_CLIP_INDEX = -1;
9362
9644
  let PrimitiveKind = /* @__PURE__ */ function(PrimitiveKind) {
9363
9645
  PrimitiveKind[PrimitiveKind["Fill"] = 0] = "Fill";
9364
9646
  PrimitiveKind[PrimitiveKind["Border"] = 1] = "Border";
9647
+ /** A `boxShadows` entry outside the box; see the instance layout. */
9648
+ PrimitiveKind[PrimitiveKind["Shadow"] = 2] = "Shadow";
9649
+ /** A `boxShadows` entry marked `inset`. */
9650
+ PrimitiveKind[PrimitiveKind["InsetShadow"] = 3] = "InsetShadow";
9365
9651
  return PrimitiveKind;
9366
9652
  }({});
9367
9653
  let CommandKind = /* @__PURE__ */ function(CommandKind) {
@@ -9435,7 +9721,7 @@ var FloatBuffer = class {
9435
9721
  return this.data.slice(0, this.length);
9436
9722
  }
9437
9723
  };
9438
- const instanceScratch = new FloatBuffer(10240);
9724
+ const instanceScratch = new FloatBuffer(12288);
9439
9725
  const texturedScratch = new FloatBuffer(32768);
9440
9726
  const clipScratch = new FloatBuffer(1024);
9441
9727
  const gradientScratch = new FloatBuffer(768);
@@ -9488,7 +9774,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
9488
9774
  /** The nodes asking for `lift`, met on the walk and drawn after it. */
9489
9775
  const liftedPass = [];
9490
9776
  function closePrimitives() {
9491
- const end = instanceData.length / 20;
9777
+ const end = instanceData.length / 24;
9492
9778
  if (end > openStart) commands.push({
9493
9779
  kind: 0,
9494
9780
  start: openStart,
@@ -9498,7 +9784,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
9498
9784
  openStart = end;
9499
9785
  }
9500
9786
  function beginPrimitives(scissor) {
9501
- if (openStart === instanceData.length / 20) {
9787
+ if (openStart === instanceData.length / 24) {
9502
9788
  openScissor = scissor;
9503
9789
  return;
9504
9790
  }
@@ -9612,7 +9898,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
9612
9898
  return;
9613
9899
  }
9614
9900
  const sticky = rec.stickyOffsetX !== 0 || rec.stickyOffsetY !== 0;
9615
- if (state.cull !== null && !intersectsCull(state.cull, rec.x + rec.stickyOffsetX, rec.y + rec.stickyOffsetY, rec.width, rec.height)) return;
9901
+ if (state.cull !== null && !intersectsCull(state.cull, rec.extentMinX + rec.stickyOffsetX, rec.extentMinY + rec.stickyOffsetY, rec.extentMaxX - rec.extentMinX, rec.extentMaxY - rec.extentMinY)) return;
9616
9902
  const paint = resolvePaintState(node, paintScratch);
9617
9903
  const effectiveOpacity = state.opacity * paint.opacity;
9618
9904
  const baseCtm = sticky ? translateTransform(state.ctm, rec.stickyOffsetX, rec.stickyOffsetY) : state.ctm;
@@ -9637,6 +9923,10 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
9637
9923
  }
9638
9924
  const contentScissor = nextClip;
9639
9925
  const contentRounded = nextRounded;
9926
+ if (paint.boxShadows.length > 0) {
9927
+ beginPrimitives(ownScissor);
9928
+ pushShadows(instanceData, rec, paint, effectiveOpacity, nodeCtm, ownRounded, false);
9929
+ }
9640
9930
  if (paint.backgroundColor !== void 0) {
9641
9931
  const color = parseColor$1(paint.backgroundColor);
9642
9932
  if (color !== void 0) {
@@ -9652,6 +9942,10 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
9652
9942
  pushInstance(instanceData, rec.x, rec.y, rec.width, rec.height, first, uniformBorderRadius(paint.borderRadius), effectiveOpacity, 0, 0, nodeCtm, ownRounded, index);
9653
9943
  }
9654
9944
  }
9945
+ if (paint.boxShadows.length > 0) {
9946
+ beginPrimitives(ownScissor);
9947
+ pushShadows(instanceData, rec, paint, effectiveOpacity, nodeCtm, ownRounded, true);
9948
+ }
9655
9949
  const textureSource = paint.video !== void 0 && paint.video.frame !== null ? paint.video : paint.image;
9656
9950
  if (textureSource !== void 0) {
9657
9951
  const sourceSize = paint.video !== void 0 && paint.video.frame !== null ? videoFrameSize(paint.video) : {
@@ -9766,7 +10060,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
9766
10060
  state.rounded = nextRounded;
9767
10061
  if (rec.clips && state.cull !== null) state.cull = pushCull(state.cull, rec);
9768
10062
  if (paint.hasTransform || sticky) state.cull = null;
9769
- if (rec.scrollable) state.ctm = translateTransform(state.ctm, -rec.scrollX, -rec.scrollY);
10063
+ if (rec.scrollable) state.ctm = translateTransform(state.ctm, -snapScroll(rec.scrollX, dpr), -snapScroll(rec.scrollY, dpr));
9770
10064
  liftedFrom = liftedPass.length;
9771
10065
  visitChildren(node, rec.paintOrder);
9772
10066
  state.opacity = saved.opacity;
@@ -9821,9 +10115,10 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
9821
10115
  const model = text.editor;
9822
10116
  const editable = new EditableLayout(model, contentBox, text, measurer);
9823
10117
  pushTextRects(textRunBackgrounds(editable.lines, text));
9824
- if (model.focused && !model.collapsed) {
10118
+ const spanned = text.textSelection;
10119
+ if (spanned !== void 0 || model.focused && !model.collapsed) {
9825
10120
  const selection = parseColor$1(text.selectionColor);
9826
- if (selection !== void 0) for (const box of editable.selectionBoxes()) pushContentRect(box, selection);
10121
+ if (selection !== void 0) for (const box of editable.selectionBoxes(spanned)) pushContentRect(box, selection);
9827
10122
  }
9828
10123
  if (editable.placeholderLines.length > 0) pushTextRun(editable.placeholderLines, colorToCss(text.placeholderColor));
9829
10124
  else {
@@ -9842,7 +10137,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
9842
10137
  }, underline);
9843
10138
  }
9844
10139
  }
9845
- if (model.focused && model.collapsed && caretVisibleAt(model, now)) {
10140
+ if (spanned === void 0 && model.focused && model.collapsed && caretVisibleAt(model, now)) {
9846
10141
  const caretColor = parseColor$1(text.caretColor);
9847
10142
  if (caretColor !== void 0) {
9848
10143
  const caret = editable.caretRect();
@@ -9976,7 +10271,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
9976
10271
  closePrimitives();
9977
10272
  return {
9978
10273
  instanceData: instanceData.take(),
9979
- instanceCount: instanceData.length / 20,
10274
+ instanceCount: instanceData.length / 24,
9980
10275
  texturedData: texturedData.take(),
9981
10276
  texturedCount: texturedData.length / 16,
9982
10277
  clipData: clipData.take(),
@@ -10024,8 +10319,8 @@ function pushScrollbars(out, rec, opacity, transform, rounded, now) {
10024
10319
  pushInstance(out, x, y, width, height, color, 3, opacity, 0, 0, transform, rounded);
10025
10320
  }
10026
10321
  }
10027
- function pushInstance(out, x, y, width, height, color, radius, opacity, borderWidth, kind, transform, clip, gradient = -1) {
10028
- out.ensure(20);
10322
+ function pushInstance(out, x, y, width, height, color, radius, opacity, borderWidth, kind, transform, clip, gradient = -1, shadowX = 0, shadowY = 0, shadowSpread = 0, shadowRadius = 0) {
10323
+ out.ensure(24);
10029
10324
  const data = out.data;
10030
10325
  const at = out.length;
10031
10326
  data[at] = x;
@@ -10048,7 +10343,38 @@ function pushInstance(out, x, y, width, height, color, radius, opacity, borderWi
10048
10343
  data[at + 17] = transform[5];
10049
10344
  data[at + 18] = clip;
10050
10345
  data[at + 19] = gradient;
10051
- out.length = at + 20;
10346
+ data[at + 20] = shadowX;
10347
+ data[at + 21] = shadowY;
10348
+ data[at + 22] = shadowSpread;
10349
+ data[at + 23] = shadowRadius;
10350
+ out.length = at + 24;
10351
+ }
10352
+ /**
10353
+ * One instance per outer shadow, or per inset one, in the order
10354
+ * Canvas2D draws them: the last declared first, since CSS paints the
10355
+ * first shadow on top. The shader evaluates the blurred shape exactly
10356
+ * rather than sampling a blurred texture, so a shadow costs a quad.
10357
+ */
10358
+ function pushShadows(out, rec, paint, opacity, transform, clip, inset) {
10359
+ const shadows = paint.boxShadows;
10360
+ const radius = borderRadiusIsZero(paint.borderRadius) ? 0 : uniformBorderRadius(paint.borderRadius);
10361
+ for (let i = shadows.length - 1; i >= 0; i--) {
10362
+ const shadow = shadows[i];
10363
+ if (shadow.inset === true !== inset || shadow.color.a <= 0) continue;
10364
+ const color = parseColor$1(shadow.color);
10365
+ if (color === void 0) continue;
10366
+ const blur = Math.max(0, shadow.blurRadius);
10367
+ const spread = shadow.spreadRadius;
10368
+ if (inset) {
10369
+ pushInstance(out, rec.x, rec.y, rec.width, rec.height, color, radius, opacity, blur, 3, transform, clip, -1, shadow.offsetX, shadow.offsetY, spread, boxShadowRadius(radius, spread, true));
10370
+ continue;
10371
+ }
10372
+ const width = rec.width + spread * 2;
10373
+ const height = rec.height + spread * 2;
10374
+ if (width <= 0 || height <= 0) continue;
10375
+ const reach = blur * BOX_SHADOW_BLUR_REACH;
10376
+ pushInstance(out, rec.x + shadow.offsetX - spread - reach, rec.y + shadow.offsetY - spread - reach, width + reach * 2, height + reach * 2, color, boxShadowRadius(radius, spread, false), opacity, blur, 2, transform, clip, -1, shadow.offsetX, shadow.offsetY, spread, radius);
10377
+ }
10052
10378
  }
10053
10379
  /**
10054
10380
  * Writes one gradient record for a rectangle of the given size and
@@ -10503,7 +10829,7 @@ function quadVertexLayout() {
10503
10829
  /** Mirrors the float layout documented on INSTANCE_STRIDE_FLOATS. */
10504
10830
  function primitiveInstanceLayout() {
10505
10831
  return {
10506
- arrayStride: 80,
10832
+ arrayStride: 96,
10507
10833
  stepMode: "instance",
10508
10834
  attributes: [
10509
10835
  {
@@ -10529,7 +10855,7 @@ function primitiveInstanceLayout() {
10529
10855
  {
10530
10856
  shaderLocation: 5,
10531
10857
  offset: 44,
10532
- format: "uint32"
10858
+ format: "float32"
10533
10859
  },
10534
10860
  {
10535
10861
  shaderLocation: 6,
@@ -10555,6 +10881,11 @@ function primitiveInstanceLayout() {
10555
10881
  shaderLocation: 10,
10556
10882
  offset: 76,
10557
10883
  format: "float32"
10884
+ },
10885
+ {
10886
+ shaderLocation: 11,
10887
+ offset: 80,
10888
+ format: "float32x4"
10558
10889
  }
10559
10890
  ]
10560
10891
  };
@@ -11022,7 +11353,7 @@ var WebGPURenderer = class {
11022
11353
  glyphPages.flush();
11023
11354
  const uploadStart = this.hooks.onUploadStart !== void 0 || this.hooks.onUploadEnd !== void 0 ? performance.now() : 0;
11024
11355
  if (list.instanceCount > 0) {
11025
- const buffer = this.ensureBuffer(this.instanceBuffer, list.instanceData.byteLength, 80);
11356
+ const buffer = this.ensureBuffer(this.instanceBuffer, list.instanceData.byteLength, 96);
11026
11357
  if (buffer !== this.instanceBuffer) {
11027
11358
  this.instanceBuffer = buffer;
11028
11359
  this.cachedInstanceData = null;
@@ -13470,7 +13801,7 @@ function markNow() {
13470
13801
  * frame is collected, so a node dirtied again while the frame
13471
13802
  * is being processed belongs to the next frame.
13472
13803
  */
13473
- var UiFrame = class {
13804
+ var UiFrame = class UiFrame {
13474
13805
  id;
13475
13806
  time;
13476
13807
  dirty;
@@ -13516,6 +13847,21 @@ var UiFrame = class {
13516
13847
  for (const value of this.dirty.values()) if ((value & flags) !== 0) return true;
13517
13848
  return false;
13518
13849
  }
13850
+ /**
13851
+ * This frame and `later` as one: every node in either, with the
13852
+ * flags it carried in both.
13853
+ *
13854
+ * What the phases after layout read when layout ran more than once
13855
+ * in a frame (see `UiScheduler.recollect`): a node dirtied by a
13856
+ * layout listener has to be re-meant and redrawn like any other
13857
+ * node the frame changed.
13858
+ */
13859
+ merged(later) {
13860
+ if (later.isEmpty()) return this;
13861
+ const dirty = new Map(this.dirty);
13862
+ for (const [node, flags] of later.entries()) dirty.set(node, (dirty.get(node) ?? 0) | flags);
13863
+ return new UiFrame(this.id, this.time, dirty);
13864
+ }
13519
13865
  get size() {
13520
13866
  return this.dirty.size;
13521
13867
  }
@@ -13652,6 +13998,32 @@ var UiScheduler = class {
13652
13998
  this.handleFrame(time);
13653
13999
  }
13654
14000
  /**
14001
+ * Takes what was dirtied since `frame` was collected into that same
14002
+ * frame, rather than leaving it for the next one.
14003
+ *
14004
+ * For a phase that has to finish inside the frame what the frame
14005
+ * started. A layout listener (a `breakpoint`, a `sizeContainer`)
14006
+ * that writes padding after the boxes are final has made those boxes
14007
+ * stale, and painting them would show the stale layout for one frame
14008
+ * before the next corrects it. The runtime lays the writes out again
14009
+ * from what this returns, before anything paints.
14010
+ *
14011
+ * The result holds only the newly dirtied nodes, with `frame`'s id
14012
+ * and time: it is more of the same frame, not a new one, so the
14013
+ * frame count does not move. Anything armed by those writes finds
14014
+ * nothing left to do.
14015
+ */
14016
+ recollect(frame) {
14017
+ const count = this.dirty.drainInto(this.drained);
14018
+ const dirty = /* @__PURE__ */ new Map();
14019
+ for (let i = 0; i < count; i++) {
14020
+ const node = this.drained[i];
14021
+ dirty.set(node, node.dirtyFlags);
14022
+ node.dirtyFlags = 0;
14023
+ }
14024
+ return new UiFrame(frame.id, frame.time, dirty);
14025
+ }
14026
+ /**
13655
14027
  * Runs one frame, and names its three parts for the browser's
13656
14028
  * profiler when anything is recording (`PerformanceMarks`).
13657
14029
  *
@@ -14565,8 +14937,14 @@ const PRESENTATIONAL_CHILDREN = /* @__PURE__ */ new Set([
14565
14937
  * is, carrying `disabled` — unavailable is a thing to announce,
14566
14938
  * hidden is not.
14567
14939
  */
14568
- function buildSemanticsTree(root) {
14569
- return walk(root, null, false);
14940
+ function buildSemanticsTree(root, memory) {
14941
+ return walk(root, null, false, memory);
14942
+ }
14943
+ function semanticsMemory() {
14944
+ return {
14945
+ described: /* @__PURE__ */ new WeakSet(),
14946
+ spans: /* @__PURE__ */ new WeakMap()
14947
+ };
14570
14948
  }
14571
14949
  /**
14572
14950
  * The records one subtree contributes, as if walked in place.
@@ -14588,8 +14966,8 @@ function buildSemanticsTree(root) {
14588
14966
  * `inert` is whether an ancestor above this subtree is disabled, which
14589
14967
  * only the caller can know.
14590
14968
  */
14591
- function buildSemanticsSubtree(node, parent, index, inert) {
14592
- const records = walk(node, parent, inert);
14969
+ function buildSemanticsSubtree(node, parent, index, inert, memory) {
14970
+ const records = walk(node, parent, inert, memory);
14593
14971
  const own = records.get(node.id);
14594
14972
  if (own === void 0) return null;
14595
14973
  records.set(node.id, {
@@ -14598,26 +14976,129 @@ function buildSemanticsSubtree(node, parent, index, inert) {
14598
14976
  });
14599
14977
  return records;
14600
14978
  }
14601
- function walk(root, rootParent, rootInert) {
14602
- const records = /* @__PURE__ */ new Map();
14979
+ /**
14980
+ * Walks a subtree again after the shape of the tree changed inside it,
14981
+ * describing only what changed.
14982
+ *
14983
+ * A full walk asks every node what it means, and moves every record
14984
+ * whose siblings moved. After a block is inserted in a long document
14985
+ * nearly every node means what it did. So a record `reuse.unchanged`
14986
+ * vouches for is taken back as it was, and an untouched transparent
14987
+ * subtree (one with no record of its own, like a block of the document)
14988
+ * is taken back as the run of its parent's children it contributed last
14989
+ * time, without being walked into. Nothing taken back is renumbered:
14990
+ * the caller learns where everything went from `children` and `placed`.
14991
+ *
14992
+ * `node` has to carry a record, as for `buildSemanticsSubtree`; null
14993
+ * otherwise.
14994
+ */
14995
+ function rewalkSemantics(node, parent, index, inert, reuse) {
14996
+ const result = {
14997
+ records: /* @__PURE__ */ new Map(),
14998
+ children: /* @__PURE__ */ new Map(),
14999
+ kept: /* @__PURE__ */ new Set(),
15000
+ placed: []
15001
+ };
15002
+ walk(node, parent, inert, reuse.memory, reuse, result);
15003
+ const own = result.records.get(node.id);
15004
+ if (own === void 0) return null;
15005
+ result.records.set(node.id, {
15006
+ ...own,
15007
+ index
15008
+ });
15009
+ result.placed[0] = {
15010
+ id: node.id,
15011
+ parent,
15012
+ index
15013
+ };
15014
+ return result;
15015
+ }
15016
+ function walk(root, rootParent, rootInert, memory, reuse, rewalk) {
15017
+ const records = rewalk?.records ?? /* @__PURE__ */ new Map();
14603
15018
  const childCounts = /* @__PURE__ */ new Map();
15019
+ /** Each parent's children so far, in order: for spans, and for a rewalk's result. */
15020
+ const given = rewalk?.children ?? /* @__PURE__ */ new Map();
15021
+ const placed = rewalk?.placed;
15022
+ const tracking = memory !== void 0 || rewalk !== void 0;
14604
15023
  const nextIndex = (parent) => {
14605
15024
  const index = childCounts.get(parent) ?? 0;
14606
15025
  childCounts.set(parent, index + 1);
14607
15026
  return index;
14608
15027
  };
15028
+ const note = (parent, id, index) => {
15029
+ if (!tracking) return;
15030
+ let list = given.get(parent);
15031
+ if (list === void 0) given.set(parent, list = []);
15032
+ list.push(id);
15033
+ placed?.push({
15034
+ id,
15035
+ parent,
15036
+ index
15037
+ });
15038
+ };
15039
+ /** Takes back a record nothing changed, subtree and all. */
15040
+ const keep = (id, parent) => {
15041
+ note(parent, id, nextIndex(parent));
15042
+ rewalk.kept.add(id);
15043
+ };
15044
+ /**
15045
+ * Takes back everything an untouched transparent node contributed, as
15046
+ * a run of its parent's old children, without walking into it. False
15047
+ * when its span can't be trusted, and it is walked.
15048
+ */
15049
+ const keepSpan = (node, parent) => {
15050
+ const span = memory.spans.get(node);
15051
+ if (span === void 0 || span.parent !== parent) return false;
15052
+ if (span.count === 0) return true;
15053
+ const at = span.first === null ? -1 : reuse.positionOf(parent, span.first);
15054
+ if (at < 0) return false;
15055
+ const ids = reuse.childrenOf(parent).slice(at, at + span.count);
15056
+ if (ids.length !== span.count) return false;
15057
+ for (const id of ids) keep(id, parent);
15058
+ return true;
15059
+ };
14609
15060
  const visit = (node, parent, inert) => {
14610
15061
  if (node.properties.get("visible") === false) return;
14611
15062
  const disabled = inert || node.properties.get("disabled") === true;
15063
+ if (reuse !== void 0 && node !== root && reuse.unchanged(node)) {
15064
+ if (memory.described.has(node) && reuse.previous.has(node.id)) {
15065
+ keep(node.id, parent);
15066
+ return;
15067
+ }
15068
+ if (keepSpan(node, parent)) return;
15069
+ }
14612
15070
  const record = describe(node, parent, disabled, nextIndex);
14613
15071
  if (record === null) {
15072
+ const start = childCounts.get(parent) ?? 0;
14614
15073
  for (let child = node.firstChild; child !== null; child = child.nextSibling) visit(child, parent, disabled);
15074
+ if (memory !== void 0) {
15075
+ const count = (childCounts.get(parent) ?? 0) - start;
15076
+ memory.spans.set(node, {
15077
+ parent,
15078
+ first: count === 0 ? null : given.get(parent)[start],
15079
+ count
15080
+ });
15081
+ }
14615
15082
  return;
14616
15083
  }
15084
+ memory?.described.add(node);
15085
+ if (node !== root) note(parent, record.id, record.index);
15086
+ else placed?.push({
15087
+ id: record.id,
15088
+ parent,
15089
+ index: record.index
15090
+ });
15091
+ if (rewalk !== void 0 && !given.has(record.id)) given.set(record.id, []);
14617
15092
  const runs = linkRunsOf(node);
14618
15093
  if (runs.length > 0) {
14619
15094
  records.set(record.id, paragraphOf(record));
14620
15095
  appendTextRuns(node, record.id, runs, records);
15096
+ if (tracking) for (let run = 0;; run++) {
15097
+ const id = `${record.id}${TEXT_RUN_ID_SEPARATOR}${run}`;
15098
+ const added = records.get(id);
15099
+ if (added === void 0) break;
15100
+ note(record.id, id, added.index);
15101
+ }
14621
15102
  } else records.set(record.id, record);
14622
15103
  for (let child = node.firstChild; child !== null; child = child.nextSibling) {
14623
15104
  if (claimedByName(node, child)) continue;
@@ -14664,7 +15145,8 @@ function describe(node, parent, disabled, nextIndex) {
14664
15145
  valueText: valueTextOf(node),
14665
15146
  posInSet: node.properties.get("posInSet"),
14666
15147
  setSize: node.properties.get("setSize"),
14667
- level: node.properties.get("level")
15148
+ level: node.properties.get("level"),
15149
+ activeDescendant: node.properties.get("activeDescendant")?.id
14668
15150
  });
14669
15151
  }
14670
15152
  /**
@@ -14828,6 +15310,46 @@ function diffSemantics(previous, next) {
14828
15310
  }
14829
15311
  return patches;
14830
15312
  }
15313
+ /**
15314
+ * Drops the updates that only renumber a record whose siblings kept
15315
+ * their order.
15316
+ *
15317
+ * A record carries its index among its siblings, so inserting one near
15318
+ * the top of a list changes the index of every record after it, and
15319
+ * each of those used to go out as an update: 4,266 patches for one
15320
+ * paragraph inserted in a 5,000-line document, every one of them
15321
+ * crossing to the main thread and rewriting a mirror element. They say
15322
+ * nothing a mirror needs. It applies removals, then adds in document
15323
+ * order at their indices, so the elements that stayed are already in
15324
+ * the right order around the ones that came and went. Only when the
15325
+ * siblings that stayed changed their order among themselves (a move)
15326
+ * do the new indices matter, and then every update is kept.
15327
+ *
15328
+ * The records keep their new indices; this only thins the patches.
15329
+ */
15330
+ function dropIndexShifts(previous, next, patches) {
15331
+ const parents = /* @__PURE__ */ new Set();
15332
+ for (const patch of patches) if (patch.op === "update" && onlyIndexMoved(previous.get(patch.node.id), patch.node)) parents.add(patch.node.parent);
15333
+ if (parents.size === 0) return [...patches];
15334
+ const lastOld = /* @__PURE__ */ new Map();
15335
+ const reordered = /* @__PURE__ */ new Set();
15336
+ for (const record of next.values()) {
15337
+ if (!parents.has(record.parent) || reordered.has(record.parent)) continue;
15338
+ const before = previous.get(record.id);
15339
+ if (before === void 0 || before.parent !== record.parent) continue;
15340
+ if (before.index < (lastOld.get(record.parent) ?? -1)) reordered.add(record.parent);
15341
+ lastOld.set(record.parent, before.index);
15342
+ }
15343
+ return patches.filter((patch) => patch.op !== "update" || reordered.has(patch.node.parent) || !onlyIndexMoved(previous.get(patch.node.id), patch.node));
15344
+ }
15345
+ /** Whether two records differ in their index and in nothing else. */
15346
+ function onlyIndexMoved(before, after) {
15347
+ if (before === void 0 || before.parent !== after.parent || before.index === after.index) return false;
15348
+ return recordsEqual({
15349
+ ...before,
15350
+ index: after.index
15351
+ }, after);
15352
+ }
14831
15353
  /** Structural equality over the record's flat, pruned members. */
14832
15354
  function recordsEqual(a, b) {
14833
15355
  const aKeys = Object.keys(a);
@@ -14847,6 +15369,6 @@ function recordsEqual(a, b) {
14847
15369
  return true;
14848
15370
  }
14849
15371
  //#endregion
14850
- export { AlignContent, AnimationDriver, BUTTON_INTERACTION, Box, Button, CARET_BLINK_MS, CARET_WIDTH, CLIP_STRIDE_BYTES, CLIP_STRIDE_FLOATS, Canvas2DRenderer, CanvasPlatformSurface, CanvasSurface, CanvasTextMeasurer, CharacterCountTextMeasurer, Column, CommandKind, Constraints, CrossAxisAlignment, DEFAULT_BLOCK_SIZE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_WEIGHT, DEFAULT_LINE_HEIGHT_FACTOR, DEFAULT_TEXT_COLOR, DefaultImageResolver, DefaultVideoResolver, DirtyFlags, DirtyNodeSet, EDITOR_PROP, ELLIPSIS, EMPTY_RECORDING, EXTERNAL_FILES, EditableLayout, EditableText, EditableTextModel, EnvironmentNotifier, FlexDirection, FocusNotifier, GLYPH_SUBPIXEL_PHASES, GlyphShaper, Grid, INSPECTOR_HEAT_MS, INSTANCE_STRIDE_BYTES, INSTANCE_STRIDE_FLOATS, IconRasterizer, LABEL_PADDING_X, LayoutEngine, LayoutInspector, LayoutNotifier, LayoutRecord, LazyColumn, LazyGrid, LazyRow, LazySheet, MARK_PREFIX, MAX_GRADIENT_STOPS, MAX_MEASURES_PER_CHILD, MOTION_CHANNELS, MOTION_REST, MOUSE_POINTER, MainAxisAlignment, Mp3Frames, NO_CLIP_INDEX, NodeTransitions, Paint, PaintPictureCache, PaintRecorder, PaintTarget, ParagraphTextMeasurer, PrimitiveKind, Responsive, Row, SCROLLBAR_FADE_MS, SCROLLBAR_HOVER_ZONE, SCROLLBAR_INSET, SCROLLBAR_LINGER_MS, SCROLLBAR_MIN_THUMB, SCROLLBAR_THICKNESS, ScrollView, Stack, TEXTURED_STRIDE_BYTES, TEXTURED_STRIDE_FLOATS, TEXT_MATCHES_PROP, TEXT_RUN_ID_SEPARATOR, TEXT_SELECTION_PROP, Text, UI_ROLES, UI_SEMANTIC_STATES, UI_SUBGRID_AXES, UiAnimation, UiAnimationFrameClock, UiBasicColors, UiBeforeInputEvent, UiBinding, UiBorderRadiuses, UiChildrenBinding, UiContainerSizeSource, UiDragSession, UiEditingController, UiEnvironment, UiEnvironmentKeys, UiEventBinding, UiEventType, UiFindController, UiFocusEvent, UiFocusManager, UiFrame, UiGestureEvent, UiGestureRecognizer, UiGraph, UiGraphBuilder, UiHitTester, UiHostFrameClock, UiInputDispatcher, UiInputEvent, UiInsetRegistry, UiKeyboardController, UiKeyboardEvent, UiManualFrameClock, UiModifierSet, UiNode, UiNodeType, UiPasteEvent, UiPinchEvent, UiPinchRecognizer, UiPlatformAdapter, UiPointerController, UiPointerEvent, UiProperties, UiScheduler, UiSelectionChangeEvent, UiSelectionController, UiSharedElements, UiShortcutRegistry, UiSpring, UiTextChangeEvent, UiTimerFrameClock, UiTouchScroller, UiTransforms, UiTween, UiUnknownModifierPropertyError, UiVirtualSheet, UiVirtualWindow, UiVisualState, UiWheelController, UiWheelDeltaMode, UiWheelEvent, VIRTUAL_INDEX_PROP, VIRTUAL_LEAD_PROP, VIRTUAL_SHEET_PROP, VIRTUAL_WINDOW_PROP, WebGPUError, WebGPUGlyphAtlas, WebGPUGlyphPages, WebGPURenderer, WebGPUSurface, WebGPUTextureCache, accumulatedOffsetTo, animateLayout, applyCanvasTextStyle, assertModifierList, assertTransitionMap, auto, autoFocus, bandOf, borderRadius, borderRadiusCorners, borderRadiusEqual, borderRadiusIsZero, borderRadiusValuesEqual, borderShapes, borders, boxShadow, boxShadowArraysEqual, boxShadowsEqual, breakpoint, bufferSource, buildFontString, buildRenderList, buildSemanticsSubtree, buildSemanticsTree, bumpFontStack, bundle, canDecodeVideo, capturePointer, caretRectFor, caretVisibleAt, clampSize, clearFontStacks, clearLinkHover, clearMatchRanges, clearOverrideProperty, clearSelectionRange, clickOutside, closestPropertyName, colorToCss, colorToHex, colorToRgba, colorValuesEqual, colorsEqual, colorsEqualPalette, commandForKey, computeObjectFitRect, constraintsEqual, containerBands, contentOffset, contextMenu, contrastRatio, createCanvasSurface, createCanvasTextStyle, createElement, createEnvironmentKey, createPaintState, createTextCache, createTween, createWebGPUSurface, cubicBezier, cueAt, darkColors, darkTheme, decorated, decorationColor, decorationRect, defaultMotion, defaultShadows, defaultShapes, defaultSpacing, defaultTextStyle, defaultTypography, defaultVisualState, defineModifier, defineProperty, defineThemeExtension, demuxMp4Audio, demuxMp4Video, densityFactors, describeLength, describeOverrides, detectEditingPlatform, diffSemantics, dragSessionFor, dragSource, draggable, drawOverlayShapes, drawText, dropTarget, easings, editableSpansOf, editorFor, editorOf, fade, fillTextRects, findEnvironmentKey, findMatchesIn, findPropertyDefinition, flattenTextSpans, focusRing, fontStackFor, formatConstraints, formatExplanation, formatShortcut, fr, getPropertyNames, glyphCount, gradientPaint, gradientsEqual, graphemeBoundaries, hasDecorationPhase, hasDrawnText, hasTextLinks, hasThemeExtension, hasVisualState, highContrastColors, hoverable, iconKey, iconSource, imageSource, inheritedPropertyFlags, inheritedPropertyNames, initializeWebGPU, inputsEqual, insetPadding, insetsEqual, interactive, interpolateColor, interpolateNumber, interpolateTransform, interpolatorFor, isAutoLength, isComponentLikeElement, isEditableNode, isFrLength, isLayoutProtocol, isMinMaxTrack, isMotionRest, isMultiline, isNodeFocusable, isNodeHitTestable, isNodeInert, isNodeSelectable, isNodeTabStop, isObservable, isPaintVisible, isPercentLength, isPrintable, isReadOnly, isScrollContainer, isShapeName, isTypographyRole, isUiChild, isUiElement, isUiModifier, isUiRole, isUiSemanticState, isVideoSurface, isWebGPUAvailable, labelNode, labelOrigin, layoutParagraph, layoutTextLines, lazySource, lightColors, lightTheme, lineEndAt, lineIndexAtY, lineIndexForOffset, lineLimit, lineStartAt, linear, linearGradient, linkHoverOf, linkOf, linkRunAtPointIn, markInstant, markNow, matchRangesOf, measure, measureSpan, minmax, motion, nextCaretToggle, nextGraphemeEnd, nextWordEnd, noInsets, noKeyModifiers, noModifiers, noThemeExtensions, normalizeBorderRadius, normalizeColor, normalizeStates, normalizeTextAlign, normalizeTransition, normalizeVerticalAlign, observeViewportInsets, offsetAtPoint, offsetAtPointIn, offsetAtX, offsetForVerticalMove, overrideSources, paintPictures, paintValuesEqual, paintsAfterChildren, paragraphGeometry, paragraphGeometryFrom, parseAlignContent, parseColor, parseCrossAxisAlignment, parseFlexDirection, parseMainAxisAlignment, parseShortcut, parseTransform, parseWebVtt, pathValuesEqual, percent, performanceMarksEnabled, pinchable, placeGridItems, pointerDeviceOf, pop, prepareInputSurface, pressable, previousGraphemeStart, previousWordStart, propertyEffects, propertyIsInherited, propertyValuesEqual, propertyValuesEqualByName, proportionalFontMetrics, provideEnvironment, publishInset, radialGradient, raiseContrast, rangeSource, readMp3Header, recordsEqual, registerFontStack, relativeLuminance, reorderable, repeat, replayPaint, resetOverrideWarnings, resetTransitionWarnings, resolveBoolean, resolveCursor, resolveLength, resolveMotionState, resolveNumber, resolvePaintState, resolveProperty, resolvePropertyByName, resolveString, resolvedSpansOf, rgb8, rgba, rotateFrom, runCanvasStyleInto, runFontString, sameArgs, scaleFrom, scaleSpacing, scrollLeaderOf, scrollPosition, scrollRange, scrollbarThumb, scrollbarThumbs, scrollbarZoneAt, selectableTextNodes, selectableTextOf, selectionRangeOf, selectionRects, selectionRectsIn, semanticsInertAbove, setLinkHover, setMatchRanges, setPerformanceMarks, setSelectionRange, shadowsEqual, shapesEqual, sharedElement, sheetSource, shortcut, shortcuts, sizeContainer, sizeGridTracks, slideDown, slideFrom, slideUp, spacingEqual, spacingSteps, spanAtOffset, spannedRunsFor, spannedTextOf, splitMp3Frames, spring, statesEqual, steps, syncEditorValue, textContentOf, textRunBackgrounds, textRunDecorations, textRunOfRecordId, textRuns, textSpansEqual, textStylesEqual, themeExtension, themeExtensionsEqual, themeTokens, themesEqual, tightenConstraints, touchActionFor, tracePathData, traceRoundedRect, transform, transformIsIdentity, transformsEqual, tween, typographyEqual, uniformBorderRadius, unknownContainerSize, validateGradient, validateRole, validateStates, validateSubgrid, videoFrameSize, videoSource, visualState, visualStatesEqual, wheelDeltaYOf, withContrast, withDensity, withOverrideSource, withThemeExtension, wordRangeAt, wordRangeIn, writeDeclaredProperty, writeOverrideProperty };
15372
+ export { AlignContent, AnimationDriver, BOX_SHADOW_BLUR_REACH, BUTTON_INTERACTION, Box, Button, CARET_BLINK_MS, CARET_WIDTH, CLIP_STRIDE_BYTES, CLIP_STRIDE_FLOATS, Canvas2DRenderer, CanvasPlatformSurface, CanvasSurface, CanvasTextMeasurer, CharacterCountTextMeasurer, Column, CommandKind, Constraints, CrossAxisAlignment, DEFAULT_BLOCK_SIZE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_WEIGHT, DEFAULT_LINE_HEIGHT_FACTOR, DEFAULT_TEXT_COLOR, DefaultImageResolver, DefaultVideoResolver, DirtyFlags, DirtyNodeSet, EDITOR_PROP, ELLIPSIS, EMPTY_RECORDING, EXTERNAL_FILES, EditableLayout, EditableText, EditableTextModel, EnvironmentNotifier, FlexDirection, FocusNotifier, GLYPH_SUBPIXEL_PHASES, GlyphShaper, Grid, INSPECTOR_HEAT_MS, INSTANCE_STRIDE_BYTES, INSTANCE_STRIDE_FLOATS, IconRasterizer, LABEL_PADDING_X, LayoutEngine, LayoutInspector, LayoutNotifier, LayoutRecord, LazyColumn, LazyGrid, LazyRow, LazySheet, MARK_PREFIX, MAX_GRADIENT_STOPS, MAX_MEASURES_PER_CHILD, MOTION_CHANNELS, MOTION_REST, MOUSE_POINTER, MainAxisAlignment, Mp3Frames, NO_CLIP_INDEX, NodeTransitions, Paint, PaintPictureCache, PaintRecorder, PaintTarget, ParagraphTextMeasurer, PrimitiveKind, Responsive, Row, SCROLLBAR_FADE_MS, SCROLLBAR_HOVER_ZONE, SCROLLBAR_INSET, SCROLLBAR_LINGER_MS, SCROLLBAR_MIN_THUMB, SCROLLBAR_THICKNESS, ScrollView, Stack, TEXTURED_STRIDE_BYTES, TEXTURED_STRIDE_FLOATS, TEXT_MATCHES_PROP, TEXT_RUN_ID_SEPARATOR, TEXT_SELECTION_PROP, Text, UI_ROLES, UI_SEMANTIC_STATES, UI_SUBGRID_AXES, UiAnimation, UiAnimationFrameClock, UiBasicColors, UiBeforeInputEvent, UiBinding, UiBorderRadiuses, UiChildrenBinding, UiContainerSizeSource, UiDragSession, UiEditingController, UiEnvironment, UiEnvironmentKeys, UiEventBinding, UiEventType, UiFindController, UiFocusEvent, UiFocusManager, UiFrame, UiGestureEvent, UiGestureRecognizer, UiGraph, UiGraphBuilder, UiHitTester, UiHostFrameClock, UiInputDispatcher, UiInputEvent, UiInsetRegistry, UiKeyboardController, UiKeyboardEvent, UiManualFrameClock, UiModifierSet, UiNode, UiNodeType, UiPasteEvent, UiPinchEvent, UiPinchRecognizer, UiPlatformAdapter, UiPointerController, UiPointerEvent, UiProperties, UiScheduler, UiSelectionChangeEvent, UiSelectionController, UiSharedElements, UiShortcutRegistry, UiSpring, UiTextChangeEvent, UiTimerFrameClock, UiTouchScroller, UiTransforms, UiTween, UiUnknownModifierPropertyError, UiVirtualSheet, UiVirtualWindow, UiVisualState, UiWheelController, UiWheelDeltaMode, UiWheelEvent, VIRTUAL_INDEX_PROP, VIRTUAL_LEAD_PROP, VIRTUAL_SHEET_PROP, VIRTUAL_WINDOW_PROP, WebGPUError, WebGPUGlyphAtlas, WebGPUGlyphPages, WebGPURenderer, WebGPUSurface, WebGPUTextureCache, accumulatedOffsetTo, adjacentField, animateLayout, applyCanvasTextStyle, assertModifierList, assertTransitionMap, auto, autoFocus, bandOf, borderRadius, borderRadiusCorners, borderRadiusEqual, borderRadiusIsZero, borderRadiusValuesEqual, borderShapes, borders, boxShadow, boxShadowArraysEqual, boxShadowRadius, boxShadowReach, boxShadowsEqual, breakpoint, bufferSource, buildFontString, buildRenderList, buildSemanticsSubtree, buildSemanticsTree, bumpFontStack, bundle, canDecodeVideo, capturePointer, caretRectFor, caretVisibleAt, clampSize, clearFontStacks, clearLinkHover, clearMatchRanges, clearOverrideProperty, clearSelectionRange, clickOutside, closestPropertyName, colorToCss, colorToHex, colorToRgba, colorValuesEqual, colorsEqual, colorsEqualPalette, commandForKey, comparePositions, computeObjectFitRect, constraintsEqual, containerBands, contentOffset, contextMenu, contrastRatio, createCanvasSurface, createCanvasTextStyle, createElement, createEnvironmentKey, createPaintState, createTextCache, createTween, createWebGPUSurface, cubicBezier, cueAt, darkColors, darkTheme, decorated, decorationColor, decorationRect, defaultMotion, defaultShadows, defaultShapes, defaultSpacing, defaultTextStyle, defaultTypography, defaultVisualState, defineModifier, defineProperty, defineThemeExtension, demuxMp4Audio, demuxMp4Video, densityFactors, describeLength, describeOverrides, detectEditingPlatform, diffSemantics, dragSessionFor, dragSource, draggable, drawOverlayShapes, drawText, dropIndexShifts, dropTarget, easings, edgeField, editableSpansOf, editingGroupOf, editorFor, editorOf, fade, fillTextRects, findEnvironmentKey, findMatchesIn, findPropertyDefinition, flattenTextSpans, focusRing, fontStackFor, formatConstraints, formatExplanation, formatShortcut, fr, getPropertyNames, glyphCount, gradientPaint, gradientsEqual, graphemeBoundaries, hasDecorationPhase, hasDrawnText, hasTextLinks, hasThemeExtension, hasVisualState, hiddenRangesOf, highContrastColors, hoverable, iconKey, iconSource, imageSource, inheritedPropertyFlags, inheritedPropertyNames, initializeWebGPU, inputsEqual, insetPadding, insetsEqual, interactive, interpolateColor, interpolateNumber, interpolateTransform, interpolatorFor, isAutoLength, isComponentLikeElement, isEditableNode, isFrLength, isLayoutProtocol, isMinMaxTrack, isMotionRest, isMultiline, isNodeFocusable, isNodeHitTestable, isNodeInert, isNodeSelectable, isNodeTabStop, isObservable, isPaintVisible, isPercentLength, isPrintable, isReadOnly, isScrollContainer, isShapeName, isTypographyRole, isUiChild, isUiElement, isUiModifier, isUiRole, isUiSemanticState, isVideoSurface, isWebGPUAvailable, labelNode, labelOrigin, layoutParagraph, layoutTextLines, lazySource, lightColors, lightTheme, lineEndAt, lineIndexAtY, lineIndexForOffset, lineLimit, lineStartAt, linear, linearGradient, linkHoverOf, linkOf, linkRunAtPointIn, markInstant, markNow, matchRangesOf, measure, measureSpan, minmax, motion, nextCaretToggle, nextGraphemeEnd, nextWordEnd, noInsets, noKeyModifiers, noModifiers, noThemeExtensions, normalizeBorderRadius, normalizeColor, normalizeStates, normalizeTextAlign, normalizeTransition, normalizeVerticalAlign, observeViewportInsets, offsetAtPoint, offsetAtPointIn, offsetAtX, offsetForVerticalMove, overrideSources, paintPictures, paintValuesEqual, paintsAfterChildren, paragraphGeometry, paragraphGeometryFrom, parseAlignContent, parseColor, parseCrossAxisAlignment, parseFlexDirection, parseMainAxisAlignment, parseShortcut, parseTransform, parseWebVtt, pathValuesEqual, percent, performanceMarksEnabled, pinchable, placeGridItems, pointerDeviceOf, pop, prepareInputSurface, pressable, previousGraphemeStart, previousWordStart, propertyEffects, propertyIsInherited, propertyValuesEqual, propertyValuesEqualByName, proportionalFontMetrics, provideEnvironment, publishInset, radialGradient, raiseContrast, rangeSource, readMp3Header, recordsEqual, registerFontStack, relativeLuminance, reorderable, repeat, replayPaint, resetOverrideWarnings, resetTransitionWarnings, resolveBoolean, resolveCursor, resolveLength, resolveMotionState, resolveNumber, resolvePaintState, resolveProperty, resolvePropertyByName, resolveString, resolvedSpansOf, rewalkSemantics, rgb8, rgba, rotateFrom, runCanvasStyleInto, runFontString, sameArgs, scaleFrom, scaleSpacing, scrollLeaderOf, scrollPosition, scrollRange, scrollbarThumb, scrollbarThumbs, scrollbarZoneAt, selectableTextNodes, selectableTextOf, selectionRangeOf, selectionRects, selectionRectsIn, semanticsInertAbove, semanticsMemory, setLinkHover, setMatchRanges, setPerformanceMarks, setSelectionRange, shadowsEqual, shapesEqual, sharedElement, sheetSource, shortcut, shortcuts, sizeContainer, sizeGridTracks, slideDown, slideFrom, slideUp, spacingEqual, spacingSteps, spanAtOffset, spannedRunsFor, spannedTextOf, splitMp3Frames, spring, statesEqual, steps, syncEditorValue, textContentOf, textRunBackgrounds, textRunDecorations, textRunOfRecordId, textRuns, textSpansEqual, textStylesEqual, themeExtension, themeExtensionsEqual, themeTokens, themesEqual, tightenConstraints, touchActionFor, tracePathData, traceRoundedRect, transform, transformIsIdentity, transformsEqual, tween, typographyEqual, uniformBorderRadius, unknownContainerSize, validateGradient, validateRole, validateStates, validateSubgrid, videoFrameSize, videoSource, visualState, visualStatesEqual, wheelDeltaYOf, withContrast, withDensity, withOverrideSource, withThemeExtension, wordRangeAt, wordRangeIn, writeDeclaredProperty, writeOverrideProperty };
14851
15373
 
14852
15374
  //# sourceMappingURL=index.js.map