@momoyu-ink/kit 0.10.0 → 0.11.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/lib.mjs CHANGED
@@ -22,14 +22,18 @@ __export(lib_exports, {
22
22
  Button: () => Button,
23
23
  Checkbox: () => Checkbox,
24
24
  DEBUG_EMPTY_PAGE: () => DEBUG_EMPTY_PAGE,
25
+ Input: () => Input,
25
26
  OverlayParamsContext: () => OverlayParamsContext,
26
27
  PageParamsContext: () => PageParamsContext,
28
+ Radio: () => Radio,
29
+ RadioGroup: () => RadioGroup,
27
30
  ScrollView: () => ScrollView,
28
31
  Select: () => Select,
29
32
  Slider: () => Slider,
30
33
  StageContextProvider: () => StageContextProvider,
31
34
  a: () => animated,
32
35
  addEventListener: () => addEventListener,
36
+ addFluidObserver: () => addFluidObserver,
33
37
  animated: () => animated,
34
38
  autoState: () => autoState,
35
39
  createBubbleEvent: () => createBubbleEvent,
@@ -56,6 +60,7 @@ __export(lib_exports, {
56
60
  moyu: () => moyu_exports,
57
61
  nextLine: () => nextLine,
58
62
  registerAppStateAdapter: () => registerAppStateAdapter,
63
+ removeFluidObserver: () => removeFluidObserver,
59
64
  replaceUiData: () => replaceUiData,
60
65
  setDefaultAutoTailMs: () => setDefaultAutoTailMs,
61
66
  setWaiting: () => setWaiting,
@@ -97,10 +102,12 @@ import { DefaultEventPriority, NoEventPriority } from "react-reconciler/constant
97
102
  var moyu_exports = {};
98
103
  __export(moyu_exports, {
99
104
  addChild: () => addChild,
105
+ blurEditable: () => blurEditable,
100
106
  createInstance: () => createInstance,
101
107
  destroyInstance: () => destroyInstance,
102
108
  executeNodeCommand: () => executeNodeCommand,
103
109
  executePluginCommand: () => executePluginCommand,
110
+ focusEditable: () => focusEditable,
104
111
  insertChild: () => insertChild,
105
112
  insertChildBefore: () => insertChildBefore,
106
113
  removeChild: () => removeChild,
@@ -138,6 +145,12 @@ function removeChild(nodeId, childNodeId) {
138
145
  function updateProps(nodeId, props) {
139
146
  moyu.pushCommand("update_props", [nodeId, props]);
140
147
  }
148
+ function focusEditable(nodeId) {
149
+ moyu.pushCommand("focus_editable", [nodeId]);
150
+ }
151
+ function blurEditable(nodeId) {
152
+ moyu.pushCommand("blur_editable", [nodeId]);
153
+ }
141
154
  function executeNodeCommand(nodeId, payload) {
142
155
  return moyu.executeNodeCommand(nodeId, payload);
143
156
  }
@@ -781,10 +794,18 @@ globalThis.__moyu_eval_sandbox = (code) => {
781
794
  var spring_exports = {};
782
795
  __export(spring_exports, {
783
796
  a: () => animated,
784
- animated: () => animated
797
+ addFluidObserver: () => addFluidObserver,
798
+ animated: () => animated,
799
+ removeFluidObserver: () => removeFluidObserver
785
800
  });
786
801
  import { createHost } from "@react-spring/animated";
787
- import { Globals, colors, createStringInterpolator } from "@react-spring/shared";
802
+ import {
803
+ Globals,
804
+ addFluidObserver as observeFluidValue,
805
+ colors,
806
+ createStringInterpolator,
807
+ removeFluidObserver as unobserveFluidValue
808
+ } from "@react-spring/shared";
788
809
 
789
810
  // src/spring/primitives.ts
790
811
  var primitives = [
@@ -815,6 +836,8 @@ var host = createHost(primitives, {
815
836
  }
816
837
  });
817
838
  var animated = host.animated;
839
+ var addFluidObserver = observeFluidValue;
840
+ var removeFluidObserver = unobserveFluidValue;
818
841
 
819
842
  // src/lib.ts
820
843
  __reExport(lib_exports, spring_exports);
@@ -839,7 +862,8 @@ function createBubbleEvent(body, targetId) {
839
862
 
840
863
  // src/events/globals.ts
841
864
  var globalEventListeners = {};
842
- var globalRequestAnimationFrameListeners = [];
865
+ var globalRequestAnimationFrameListeners = /* @__PURE__ */ new Map();
866
+ var nextAnimationFrameHandle = 0;
843
867
  var BUBBLE_EVENT_NAMES = ["mouseevent", "touchevent", "keyboardevent", "wheelevent"];
844
868
  globalThis.__moyu_receive_event = (raw_event) => {
845
869
  const { name, body } = raw_event;
@@ -866,7 +890,8 @@ globalThis.__moyu_receive_event = (raw_event) => {
866
890
  return;
867
891
  }
868
892
  case "animationframecallbackevent": {
869
- const listeners = globalRequestAnimationFrameListeners.splice(0);
893
+ const listeners = [...globalRequestAnimationFrameListeners.values()];
894
+ globalRequestAnimationFrameListeners.clear();
870
895
  const { timestamp } = body;
871
896
  for (const listener of listeners) {
872
897
  listener?.(timestamp);
@@ -924,10 +949,13 @@ function handleBubbleEvent(name, body) {
924
949
  }
925
950
  if (globalThis.__moyu_native) {
926
951
  globalThis.requestAnimationFrame = (callback) => {
927
- return globalRequestAnimationFrameListeners.push(callback) - 1;
952
+ const handle = nextAnimationFrameHandle;
953
+ nextAnimationFrameHandle += 1;
954
+ globalRequestAnimationFrameListeners.set(handle, callback);
955
+ return handle;
928
956
  };
929
957
  globalThis.cancelAnimationFrame = (handle) => {
930
- globalRequestAnimationFrameListeners.splice(handle, 1);
958
+ globalRequestAnimationFrameListeners.delete(handle);
931
959
  };
932
960
  }
933
961
 
@@ -1248,6 +1276,7 @@ function Button({
1248
1276
  textOffsetX,
1249
1277
  textOffsetY,
1250
1278
  textAlign = "center",
1279
+ children,
1251
1280
  anchor,
1252
1281
  pivot = anchor,
1253
1282
  interactive,
@@ -1262,6 +1291,20 @@ function Button({
1262
1291
  }) {
1263
1292
  const [hovered, setHovered] = useState(false);
1264
1293
  const [pressed, setPressed] = useState(false);
1294
+ useEffect(() => {
1295
+ if (!pressed) {
1296
+ return;
1297
+ }
1298
+ const release = () => setPressed(false);
1299
+ const removeMouseUp = addEventListener("mouseup", release);
1300
+ const removeTouchEnd = addEventListener("touchend", release);
1301
+ const removeTouchCancel = addEventListener("touchcancel", release);
1302
+ return () => {
1303
+ removeMouseUp();
1304
+ removeTouchEnd();
1305
+ removeTouchCancel();
1306
+ };
1307
+ }, [pressed]);
1265
1308
  useEffect(() => {
1266
1309
  if (disabled) {
1267
1310
  setHovered(false);
@@ -1311,18 +1354,21 @@ function Button({
1311
1354
  setPressed(false);
1312
1355
  }),
1313
1356
  onClick: (event) => event.stopPropagation(),
1314
- children: /* @__PURE__ */ jsx("sprite", { ...spriteProps, src: resolveControlStateValue(src, state), cursor: "pointer", children: text !== void 0 ? /* @__PURE__ */ jsx(
1315
- "text",
1316
- {
1317
- ...resolvedTextStyle,
1318
- text,
1319
- x: textOffsetX,
1320
- y: textOffsetY,
1321
- interactive: false,
1322
- anchor: textAnchor,
1323
- pivot: textAnchor
1324
- }
1325
- ) : void 0 })
1357
+ children: /* @__PURE__ */ jsxs("sprite", { ...spriteProps, src: resolveControlStateValue(src, state), cursor: "pointer", children: [
1358
+ text !== void 0 ? /* @__PURE__ */ jsx(
1359
+ "text",
1360
+ {
1361
+ ...resolvedTextStyle,
1362
+ text,
1363
+ x: textOffsetX,
1364
+ y: textOffsetY,
1365
+ interactive: false,
1366
+ anchor: textAnchor,
1367
+ pivot: textAnchor
1368
+ }
1369
+ ) : void 0,
1370
+ children
1371
+ ] })
1326
1372
  }
1327
1373
  );
1328
1374
  }
@@ -1360,8 +1406,343 @@ function Checkbox({
1360
1406
  );
1361
1407
  }
1362
1408
 
1409
+ // src/components/input.tsx
1410
+ import { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState3 } from "react";
1411
+ var Input = forwardRef(function Input2({
1412
+ value,
1413
+ defaultValue = "",
1414
+ placeholder = "",
1415
+ disabled = false,
1416
+ readOnly = false,
1417
+ autoFocus = false,
1418
+ width,
1419
+ height,
1420
+ paddingX = 0,
1421
+ textStyle,
1422
+ placeholderStyle,
1423
+ caret,
1424
+ background,
1425
+ onInput,
1426
+ onChange,
1427
+ onFocus,
1428
+ onBlur,
1429
+ onCompositionStart,
1430
+ onCompositionUpdate,
1431
+ onCompositionEnd,
1432
+ interactive,
1433
+ cursor = "text",
1434
+ onMouseEnter,
1435
+ onMouseLeave,
1436
+ onMouseDown,
1437
+ onMouseUp,
1438
+ onTouchStart,
1439
+ onTouchEnd,
1440
+ onTouchCancel,
1441
+ ...nodeProps
1442
+ }, ref) {
1443
+ const editableRef = useRef(null);
1444
+ const initialValueRef = useRef(value ?? defaultValue);
1445
+ const initialValue = initialValueRef.current;
1446
+ const stateRef = useRef({
1447
+ value: initialValue,
1448
+ isComposing: false,
1449
+ compositionText: ""
1450
+ });
1451
+ const [state, setState] = useState3(stateRef.current);
1452
+ const [focused, setFocused] = useState3(false);
1453
+ const [hovered, setHovered] = useState3(false);
1454
+ const [pressed, setPressed] = useState3(false);
1455
+ const [caretPosition, setCaretPosition] = useState3();
1456
+ const [caretVisible, setCaretVisible] = useState3(true);
1457
+ const shouldAutoFocusRef = useRef(autoFocus && !disabled);
1458
+ const viewportWidth = Math.max(0, Math.round(width));
1459
+ const viewportHeight = Math.max(0, Math.round(height));
1460
+ const contentWidth = Math.max(0, viewportWidth - paddingX * 2);
1461
+ const { width: caretWidth, height: configuredCaretHeight, blinkInterval, ...caretSpriteProps } = caret;
1462
+ const caretHeight = configuredCaretHeight ?? textStyle.fontSize ?? viewportHeight;
1463
+ const backgroundStyle = background && "idle" in background ? disabled ? background.disabled ?? background.idle : readOnly ? background.readOnly ?? background.idle : pressed ? background.press ?? background.idle : focused ? background.focused ?? background.idle : hovered ? background.hover ?? background.idle : background.idle : background;
1464
+ const displayValue = state.value + state.compositionText;
1465
+ const updateState = useCallback((nextState) => {
1466
+ const previousState = stateRef.current;
1467
+ if (previousState.value === nextState.value && previousState.isComposing === nextState.isComposing && previousState.compositionText === nextState.compositionText) {
1468
+ return;
1469
+ }
1470
+ const displayValueChanged = previousState.value + previousState.compositionText !== nextState.value + nextState.compositionText;
1471
+ stateRef.current = nextState;
1472
+ setState(nextState);
1473
+ if (displayValueChanged) {
1474
+ setCaretPosition(void 0);
1475
+ }
1476
+ setCaretVisible(true);
1477
+ }, []);
1478
+ const handleInput = useCallback(
1479
+ (event) => {
1480
+ updateState(event.state);
1481
+ onInput?.(event.state);
1482
+ },
1483
+ [onInput, updateState]
1484
+ );
1485
+ const handleChange = useCallback(
1486
+ (event) => {
1487
+ updateState(event.state);
1488
+ onChange?.(event.state, event.source);
1489
+ },
1490
+ [onChange, updateState]
1491
+ );
1492
+ const handleFocus = useCallback(
1493
+ (event) => {
1494
+ updateState(event.state);
1495
+ setFocused(true);
1496
+ onFocus?.(event.state);
1497
+ },
1498
+ [onFocus, updateState]
1499
+ );
1500
+ const handleBlur = useCallback(
1501
+ (event) => {
1502
+ updateState(event.state);
1503
+ setFocused(false);
1504
+ onBlur?.(event.state);
1505
+ },
1506
+ [onBlur, updateState]
1507
+ );
1508
+ const handleCompositionStart = useCallback(
1509
+ (event) => {
1510
+ updateState(event.state);
1511
+ onCompositionStart?.(event.state);
1512
+ },
1513
+ [onCompositionStart, updateState]
1514
+ );
1515
+ const handleCompositionUpdate = useCallback(
1516
+ (event) => {
1517
+ updateState(event.state);
1518
+ onCompositionUpdate?.(event.state);
1519
+ },
1520
+ [onCompositionUpdate, updateState]
1521
+ );
1522
+ const handleCompositionEnd = useCallback(
1523
+ (event) => {
1524
+ updateState(event.state);
1525
+ onCompositionEnd?.(event.state);
1526
+ },
1527
+ [onCompositionEnd, updateState]
1528
+ );
1529
+ const handleTextLayout = useCallback((event) => {
1530
+ if (event.text === stateRef.current.value + stateRef.current.compositionText) {
1531
+ setCaretPosition(event.endCursorPosition);
1532
+ }
1533
+ }, []);
1534
+ useImperativeHandle(
1535
+ ref,
1536
+ () => ({
1537
+ focus: () => {
1538
+ if (editableRef.current) {
1539
+ focusEditable(editableRef.current.nodeId);
1540
+ }
1541
+ },
1542
+ blur: () => {
1543
+ if (editableRef.current) {
1544
+ blurEditable(editableRef.current.nodeId);
1545
+ }
1546
+ },
1547
+ getState: () => stateRef.current
1548
+ }),
1549
+ []
1550
+ );
1551
+ useEffect2(() => {
1552
+ if (value === void 0 || value === stateRef.current.value) {
1553
+ return;
1554
+ }
1555
+ editableRef.current?.executeCommand({ subCommand: "setValue", value });
1556
+ const nextState = editableRef.current?.executeCommand({ subCommand: "getState" });
1557
+ if (nextState) {
1558
+ updateState(nextState);
1559
+ }
1560
+ }, [updateState, value]);
1561
+ useEffect2(() => {
1562
+ if (shouldAutoFocusRef.current && editableRef.current) {
1563
+ focusEditable(editableRef.current.nodeId);
1564
+ }
1565
+ }, []);
1566
+ useEffect2(() => {
1567
+ if (!pressed) {
1568
+ return;
1569
+ }
1570
+ const release = () => setPressed(false);
1571
+ const removeMouseUp = addEventListener("mouseup", release);
1572
+ const removeTouchEnd = addEventListener("touchend", release);
1573
+ const removeTouchCancel = addEventListener("touchcancel", release);
1574
+ return () => {
1575
+ removeMouseUp();
1576
+ removeTouchEnd();
1577
+ removeTouchCancel();
1578
+ };
1579
+ }, [pressed]);
1580
+ useEffect2(() => {
1581
+ if (disabled) {
1582
+ setHovered(false);
1583
+ setPressed(false);
1584
+ }
1585
+ }, [disabled]);
1586
+ useEffect2(() => {
1587
+ if (!focused) {
1588
+ setCaretVisible(false);
1589
+ return;
1590
+ }
1591
+ const expectedDisplayValue = displayValue;
1592
+ setCaretVisible(true);
1593
+ const timer = setInterval(() => {
1594
+ if (stateRef.current.value + stateRef.current.compositionText === expectedDisplayValue) {
1595
+ setCaretVisible((visible) => !visible);
1596
+ }
1597
+ }, blinkInterval ?? 500);
1598
+ return () => clearInterval(timer);
1599
+ }, [blinkInterval, displayValue, focused]);
1600
+ useEffect2(() => {
1601
+ if (!focused || !caretPosition) {
1602
+ return;
1603
+ }
1604
+ editableRef.current?.executeCommand({
1605
+ subCommand: "setCaretRect",
1606
+ x: paddingX + caretPosition[0],
1607
+ y: (viewportHeight - caretHeight) / 2,
1608
+ width: caretWidth,
1609
+ height: caretHeight
1610
+ });
1611
+ }, [caretHeight, caretPosition, caretWidth, focused, paddingX, viewportHeight]);
1612
+ const caretX = caretPosition?.[0] ?? 0;
1613
+ return /* @__PURE__ */ jsxs(
1614
+ "editable",
1615
+ {
1616
+ ...nodeProps,
1617
+ ref: editableRef,
1618
+ value: initialValue,
1619
+ disabled,
1620
+ readOnly,
1621
+ interactive: disabled ? false : interactive,
1622
+ cursor,
1623
+ onMouseEnter: mergeEvent(onMouseEnter, () => setHovered(true)),
1624
+ onMouseLeave: mergeEvent(onMouseLeave, () => {
1625
+ setHovered(false);
1626
+ setPressed(false);
1627
+ }),
1628
+ onMouseDown: mergeEvent(onMouseDown, () => setPressed(true)),
1629
+ onMouseUp: mergeEvent(onMouseUp, () => {
1630
+ setPressed(false);
1631
+ setHovered(true);
1632
+ }),
1633
+ onTouchStart: mergeEvent(onTouchStart, () => setPressed(true)),
1634
+ onTouchEnd: mergeEvent(onTouchEnd, () => {
1635
+ setPressed(false);
1636
+ setHovered(true);
1637
+ }),
1638
+ onTouchCancel: mergeEvent(onTouchCancel, () => {
1639
+ setHovered(false);
1640
+ setPressed(false);
1641
+ }),
1642
+ onInput: handleInput,
1643
+ onChange: handleChange,
1644
+ onFocus: handleFocus,
1645
+ onBlur: handleBlur,
1646
+ onCompositionStart: handleCompositionStart,
1647
+ onCompositionUpdate: handleCompositionUpdate,
1648
+ onCompositionEnd: handleCompositionEnd,
1649
+ children: [
1650
+ backgroundStyle ? /* @__PURE__ */ jsx("sprite", { ...backgroundStyle, targetWidth: viewportWidth, targetHeight: viewportHeight, interactive: false }) : null,
1651
+ /* @__PURE__ */ jsxs("clip", { x: paddingX, width: contentWidth, height: viewportHeight, interactive: false, children: [
1652
+ /* @__PURE__ */ jsx(
1653
+ "text",
1654
+ {
1655
+ ...textStyle,
1656
+ text: displayValue,
1657
+ parseMarkup: false,
1658
+ printMode: "instant",
1659
+ anchor: [0, 0.5],
1660
+ pivot: [0, 0.5],
1661
+ interactive: false,
1662
+ onTextLayout: handleTextLayout
1663
+ }
1664
+ ),
1665
+ state.value.length === 0 && state.compositionText.length === 0 && placeholder ? /* @__PURE__ */ jsx(
1666
+ "text",
1667
+ {
1668
+ ...textStyle,
1669
+ ...placeholderStyle,
1670
+ text: placeholder,
1671
+ parseMarkup: false,
1672
+ printMode: "instant",
1673
+ anchor: [0, 0.5],
1674
+ pivot: [0, 0.5],
1675
+ interactive: false
1676
+ }
1677
+ ) : null,
1678
+ /* @__PURE__ */ jsx(
1679
+ "sprite",
1680
+ {
1681
+ ...caretSpriteProps,
1682
+ x: caretX,
1683
+ y: (viewportHeight - caretHeight) / 2,
1684
+ mode: "nineslice",
1685
+ bounds: [0, 0, 0, 0],
1686
+ targetWidth: caretWidth,
1687
+ targetHeight: caretHeight,
1688
+ visible: focused && caretVisible && caretPosition !== void 0,
1689
+ interactive: false
1690
+ }
1691
+ )
1692
+ ] })
1693
+ ]
1694
+ }
1695
+ );
1696
+ });
1697
+
1698
+ // src/components/radio.tsx
1699
+ import { createContext as createContext3, useContext as useContext3, useState as useState4 } from "react";
1700
+ var RadioGroupContext = createContext3(null);
1701
+ function RadioGroup({ value, defaultValue, onValueChange, children, ...containerProps }) {
1702
+ const [internalValue, setInternalValue] = useState4(defaultValue);
1703
+ const currentValue = value ?? internalValue;
1704
+ return /* @__PURE__ */ jsx(
1705
+ RadioGroupContext.Provider,
1706
+ {
1707
+ value: {
1708
+ value: currentValue,
1709
+ select: (nextValue) => {
1710
+ if (nextValue === currentValue) {
1711
+ return;
1712
+ }
1713
+ if (value === void 0) {
1714
+ setInternalValue(nextValue);
1715
+ }
1716
+ onValueChange?.(nextValue);
1717
+ }
1718
+ },
1719
+ children: /* @__PURE__ */ jsx("container", { ...containerProps, children })
1720
+ }
1721
+ );
1722
+ }
1723
+ function Radio({ value, uncheckedSprite, checkedSprite, onPress, ...buttonProps }) {
1724
+ const group = useContext3(RadioGroupContext);
1725
+ if (!group) {
1726
+ throw new Error("Radio must be rendered inside a RadioGroup.");
1727
+ }
1728
+ const checked = group.value === value;
1729
+ return /* @__PURE__ */ jsx(
1730
+ Button,
1731
+ {
1732
+ ...buttonProps,
1733
+ sprite: checked ? checkedSprite : uncheckedSprite,
1734
+ onPress: (event) => {
1735
+ onPress?.(event);
1736
+ if (!event.defaultPrevented) {
1737
+ group.select(value);
1738
+ }
1739
+ }
1740
+ }
1741
+ );
1742
+ }
1743
+
1363
1744
  // src/components/select.tsx
1364
- import { useState as useState3 } from "react";
1745
+ import { useState as useState5 } from "react";
1365
1746
  function Select({
1366
1747
  value,
1367
1748
  defaultValue,
@@ -1380,8 +1761,8 @@ function Select({
1380
1761
  pivot = anchor,
1381
1762
  ...containerProps
1382
1763
  }) {
1383
- const [internalValue, setInternalValue] = useState3(defaultValue);
1384
- const [open, setOpen] = useState3(false);
1764
+ const [internalValue, setInternalValue] = useState5(defaultValue);
1765
+ const [open, setOpen] = useState5(false);
1385
1766
  const currentValue = value ?? internalValue;
1386
1767
  const currentOption = options.find((item) => item.value === currentValue);
1387
1768
  const { paddingX = 0, paddingY = 0, gap = 0, offsetX = 0, offsetY = 0, ...listSprite } = list;
@@ -1413,43 +1794,57 @@ function Select({
1413
1794
  }
1414
1795
  }
1415
1796
  ),
1416
- open && !disabled ? /* @__PURE__ */ jsx("sprite", { ...listSprite, targetHeight: listHeight, x: offsetX, y: (trigger.targetHeight ?? 0) + offsetY, children: /* @__PURE__ */ jsx("vbox", { x: paddingX, y: paddingY, gap, children: options.map((item) => /* @__PURE__ */ jsx(
1417
- Button,
1797
+ open && !disabled ? /* @__PURE__ */ jsx(
1798
+ "sprite",
1418
1799
  {
1419
- sprite: option,
1420
- lockOn: item.value === currentValue ? "press" : void 0,
1421
- text: item.text,
1422
- textStyle,
1423
- textOffsetX,
1424
- textOffsetY,
1425
- textAlign,
1426
- onPress: (event) => {
1427
- if (event.defaultPrevented) {
1428
- return;
1429
- }
1430
- if (value === void 0) {
1431
- setInternalValue(item.value);
1432
- }
1433
- onValueChange?.(item.value, item);
1434
- setOpen(false);
1435
- }
1436
- },
1437
- item.value
1438
- )) }) }) : void 0
1800
+ ...listSprite,
1801
+ excludeFromLayout: true,
1802
+ targetHeight: listHeight,
1803
+ x: offsetX,
1804
+ y: (trigger.targetHeight ?? 0) + offsetY,
1805
+ children: /* @__PURE__ */ jsx("vbox", { x: paddingX, y: paddingY, gap, children: options.map((item) => /* @__PURE__ */ jsx(
1806
+ Button,
1807
+ {
1808
+ sprite: option,
1809
+ lockOn: item.value === currentValue ? "press" : void 0,
1810
+ text: item.text,
1811
+ textStyle,
1812
+ textOffsetX,
1813
+ textOffsetY,
1814
+ textAlign,
1815
+ onPress: (event) => {
1816
+ if (event.defaultPrevented) {
1817
+ return;
1818
+ }
1819
+ if (value === void 0) {
1820
+ setInternalValue(item.value);
1821
+ }
1822
+ onValueChange?.(item.value, item);
1823
+ setOpen(false);
1824
+ }
1825
+ },
1826
+ item.value
1827
+ )) })
1828
+ }
1829
+ ) : void 0
1439
1830
  ]
1440
1831
  }
1441
1832
  );
1442
1833
  }
1443
1834
 
1444
1835
  // src/components/slider.tsx
1445
- import { useCallback, useEffect as useEffect2, useRef, useState as useState4 } from "react";
1836
+ import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef2, useState as useState6 } from "react";
1446
1837
  function clampValue(value) {
1838
+ if (Number.isNaN(value)) {
1839
+ return 0;
1840
+ }
1447
1841
  return Math.max(0, Math.min(1, value));
1448
1842
  }
1449
1843
  function Slider({
1450
1844
  value,
1451
1845
  defaultValue = 0,
1452
1846
  onValueChange,
1847
+ onValueCommit,
1453
1848
  onPress,
1454
1849
  disabled = false,
1455
1850
  track,
@@ -1468,101 +1863,145 @@ function Slider({
1468
1863
  onTouchCancel,
1469
1864
  ...containerProps
1470
1865
  }) {
1471
- const [internalValue, setInternalValue] = useState4(() => clampValue(defaultValue));
1472
- const [hovered, setHovered] = useState4(false);
1473
- const [dragging, setDragging] = useState4(false);
1474
- const draggingRef = useRef(false);
1866
+ const [internalValue, setInternalValue] = useState6(() => clampValue(defaultValue));
1867
+ const [dragging, setDragging] = useState6(false);
1475
1868
  const currentValue = clampValue(value ?? internalValue);
1869
+ const currentValueRef = useRef2(currentValue);
1870
+ currentValueRef.current = currentValue;
1871
+ const dragStateRef = useRef2(null);
1476
1872
  const distance = Math.max(0, track.targetWidth - thumb.targetWidth);
1477
- const state = disabled ? "disabled" : dragging ? "press" : hovered ? "hover" : "idle";
1478
- const { src: trackSrc, ...trackProps } = track;
1479
- const { src: thumbSrc, ...thumbProps } = thumb;
1480
- const updateValue = (event) => {
1481
- event.stopPropagation();
1482
- if (distance === 0) {
1483
- return;
1484
- }
1485
- const nextValue = clampValue((event.offsetX - thumb.targetWidth / 2) / distance);
1873
+ const setSliderValue = useCallback2((nextValue) => {
1874
+ const clampedValue = clampValue(nextValue);
1875
+ currentValueRef.current = clampedValue;
1486
1876
  if (value === void 0) {
1487
- setInternalValue(nextValue);
1877
+ setInternalValue(clampedValue);
1488
1878
  }
1489
- onValueChange?.(nextValue);
1490
- };
1491
- const endDragging = useCallback(() => {
1492
- draggingRef.current = false;
1879
+ onValueChange?.(clampedValue);
1880
+ }, [onValueChange, value]);
1881
+ const endDragging = useCallback2((commit) => {
1882
+ if (dragStateRef.current === null) {
1883
+ return;
1884
+ }
1885
+ dragStateRef.current = null;
1493
1886
  setDragging(false);
1494
- }, []);
1495
- useEffect2(() => {
1496
- const handleEnd = () => {
1497
- if (draggingRef.current) {
1498
- endDragging();
1887
+ if (commit) {
1888
+ onValueCommit?.(currentValueRef.current);
1889
+ }
1890
+ }, [onValueCommit]);
1891
+ useEffect3(() => {
1892
+ const handleMouseUp = () => endDragging(true);
1893
+ const handleTouchEnd = (event) => {
1894
+ if (dragStateRef.current?.touchIdentifier === event.identifier) {
1895
+ endDragging(true);
1896
+ }
1897
+ };
1898
+ const handleTouchCancel2 = (event) => {
1899
+ if (dragStateRef.current?.touchIdentifier === event.identifier) {
1900
+ endDragging(false);
1499
1901
  }
1500
1902
  };
1501
- const removeMouseUp = addEventListener("mouseup", handleEnd);
1502
- const removeTouchEnd = addEventListener("touchend", handleEnd);
1503
- const removeTouchCancel = addEventListener("touchcancel", handleEnd);
1903
+ const removeMouseUp = addEventListener("mouseup", handleMouseUp);
1904
+ const removeTouchEnd = addEventListener("touchend", handleTouchEnd);
1905
+ const removeTouchCancel = addEventListener("touchcancel", handleTouchCancel2);
1504
1906
  return () => {
1505
1907
  removeMouseUp();
1506
1908
  removeTouchEnd();
1507
1909
  removeTouchCancel();
1508
1910
  };
1509
1911
  }, [endDragging]);
1510
- useEffect2(() => {
1912
+ useEffect3(() => {
1511
1913
  if (disabled) {
1512
- endDragging();
1513
- setHovered(false);
1914
+ endDragging(false);
1514
1915
  }
1515
1916
  }, [disabled, endDragging]);
1516
1917
  const startDragging = (event) => {
1918
+ event.stopPropagation();
1919
+ if (dragStateRef.current !== null) {
1920
+ return;
1921
+ }
1922
+ const thumbPosition = currentValueRef.current * distance;
1923
+ dragStateRef.current = {
1924
+ startPosition: event.offsetX,
1925
+ startValue: currentValueRef.current,
1926
+ touchIdentifier: "identifier" in event ? event.identifier : void 0,
1927
+ startedOnThumb: event.offsetX >= thumbPosition && event.offsetX <= thumbPosition + thumb.targetWidth,
1928
+ moved: false
1929
+ };
1930
+ setDragging(true);
1931
+ };
1932
+ const moveDragging = (event) => {
1933
+ const dragState = dragStateRef.current;
1934
+ if (dragState === null || "identifier" in event && dragState.touchIdentifier !== event.identifier || distance === 0) {
1935
+ return;
1936
+ }
1937
+ event.stopPropagation();
1938
+ const delta = event.offsetX - dragState.startPosition;
1939
+ if (delta !== 0) {
1940
+ dragState.moved = true;
1941
+ }
1942
+ setSliderValue(dragState.startValue + delta / distance);
1943
+ };
1944
+ const handlePress = (event) => {
1945
+ const dragState = dragStateRef.current;
1946
+ if (dragState === null || "identifier" in event && dragState.touchIdentifier !== event.identifier) {
1947
+ return;
1948
+ }
1517
1949
  onPress?.(event);
1518
1950
  if (event.defaultPrevented) {
1951
+ endDragging(false);
1519
1952
  return;
1520
1953
  }
1521
- draggingRef.current = true;
1522
- setDragging(true);
1523
- updateValue(event);
1954
+ if (!dragState.moved && !dragState.startedOnThumb && distance > 0) {
1955
+ setSliderValue((event.offsetX - thumb.targetWidth / 2) / distance);
1956
+ }
1957
+ endDragging(true);
1958
+ };
1959
+ const handleTouchCancel = (event) => {
1960
+ if (dragStateRef.current?.touchIdentifier === event.identifier) {
1961
+ endDragging(false);
1962
+ }
1524
1963
  };
1525
1964
  return /* @__PURE__ */ jsx(
1526
- "container",
1965
+ Button,
1527
1966
  {
1528
1967
  ...containerProps,
1529
1968
  anchor,
1530
1969
  pivot,
1531
- interactive: disabled ? false : interactive,
1532
- onMouseEnter: mergeEvent(onMouseEnter, () => setHovered(true)),
1533
- onMouseLeave: mergeEvent(onMouseLeave, () => {
1534
- setHovered(false);
1535
- if (!draggingRef.current) {
1536
- setDragging(false);
1537
- }
1538
- }),
1970
+ interactive,
1971
+ disabled,
1972
+ lockOn: dragging ? "press" : void 0,
1973
+ sprite: {
1974
+ ...track,
1975
+ pivot: [0, 0.5],
1976
+ y: (track.targetHeight ?? 0) / 2
1977
+ },
1978
+ onPress: handlePress,
1979
+ onMouseEnter,
1980
+ onMouseLeave,
1539
1981
  onMouseDown: mergeEvent(onMouseDown, startDragging),
1540
- onMouseUp: mergeEvent(onMouseUp, endDragging),
1541
- onMouseMove: mergeEvent(onMouseMove, (event) => {
1542
- if (draggingRef.current) {
1543
- updateValue(event);
1544
- }
1545
- }),
1982
+ onMouseUp,
1983
+ onMouseMove: mergeEvent(onMouseMove, moveDragging),
1546
1984
  onTouchStart: mergeEvent(onTouchStart, startDragging),
1547
- onTouchMove: mergeEvent(onTouchMove, (event) => {
1548
- if (draggingRef.current) {
1549
- updateValue(event);
1550
- }
1551
- }),
1552
- onTouchEnd: mergeEvent(onTouchEnd, endDragging),
1553
- onTouchCancel: mergeEvent(onTouchCancel, endDragging),
1554
- onClick: (event) => event.stopPropagation(),
1555
- children: /* @__PURE__ */ jsx("sprite", { ...trackProps, src: resolveControlStateValue(trackSrc, state), cursor: "pointer", children: /* @__PURE__ */ jsx(
1556
- "sprite",
1985
+ onTouchMove: mergeEvent(onTouchMove, moveDragging),
1986
+ onTouchEnd,
1987
+ onTouchCancel: mergeEvent(onTouchCancel, handleTouchCancel),
1988
+ children: /* @__PURE__ */ jsx(
1989
+ Button,
1557
1990
  {
1558
- ...thumbProps,
1559
- src: resolveControlStateValue(thumbSrc, state),
1991
+ sprite: {
1992
+ ...thumb,
1993
+ anchor: [0, 0.5],
1994
+ pivot: [0, 0.5],
1995
+ x: 0,
1996
+ interactive: false
1997
+ },
1998
+ lockOn: dragging ? "press" : void 0,
1999
+ x: currentValue * distance,
1560
2000
  anchor: [0, 0.5],
1561
2001
  pivot: [0, 0.5],
1562
- x: currentValue * distance,
1563
2002
  interactive: false
1564
2003
  }
1565
- ) })
2004
+ )
1566
2005
  }
1567
2006
  );
1568
2007
  }
@@ -1932,6 +2371,7 @@ var debugSessionController = {
1932
2371
  throw new Error("Page switching is not supported by the app state adapter");
1933
2372
  }
1934
2373
  await appStateAdapter.switchPage(routeName, params);
2374
+ await syncCurrentExecutionCursor();
1935
2375
  return;
1936
2376
  }
1937
2377
  if (navigator.hasOverlay(routeName)) {
@@ -2522,7 +2962,7 @@ function useFadeOut(outTime, pause = false, onFinished) {
2522
2962
 
2523
2963
  // src/hooks/useScrollView.ts
2524
2964
  import { useSpringValue } from "@react-spring/core";
2525
- import { useCallback as useCallback2, useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState5 } from "react";
2965
+ import { useCallback as useCallback3, useEffect as useEffect4, useMemo, useRef as useRef3, useState as useState7 } from "react";
2526
2966
  function clamp(value, min, max) {
2527
2967
  return Math.max(min, Math.min(max, value));
2528
2968
  }
@@ -2542,13 +2982,13 @@ function useScrollView({
2542
2982
  initialPosition = "start",
2543
2983
  wheelStep = 72
2544
2984
  }) {
2545
- const [contentHeight, setContentHeight] = useState5(0);
2546
- const [hasContentLayout, setHasContentLayout] = useState5(false);
2547
- const scrollTargetRef = useRef2(0);
2548
- const didSetInitialPositionRef = useRef2(false);
2549
- const touchDraggingRef = useRef2(false);
2550
- const touchStartYRef = useRef2(0);
2551
- const touchStartOffsetRef = useRef2(0);
2985
+ const [contentHeight, setContentHeight] = useState7(0);
2986
+ const [hasContentLayout, setHasContentLayout] = useState7(false);
2987
+ const scrollTargetRef = useRef3(0);
2988
+ const didSetInitialPositionRef = useRef3(false);
2989
+ const touchDraggingRef = useRef3(false);
2990
+ const touchStartYRef = useRef3(0);
2991
+ const touchStartOffsetRef = useRef3(0);
2552
2992
  const scrollOffset = useSpringValue(0, {
2553
2993
  config: {
2554
2994
  tension: 320,
@@ -2556,7 +2996,7 @@ function useScrollView({
2556
2996
  }
2557
2997
  });
2558
2998
  const maxScroll = useMemo(() => Math.max(0, contentHeight - viewportHeight), [contentHeight, viewportHeight]);
2559
- const scrollTo = useCallback2(
2999
+ const scrollTo = useCallback3(
2560
3000
  (nextOffset, immediate = false) => {
2561
3001
  const offset = clamp(nextOffset, 0, maxScroll);
2562
3002
  if (offset === scrollTargetRef.current && !immediate) {
@@ -2567,13 +3007,13 @@ function useScrollView({
2567
3007
  },
2568
3008
  [maxScroll, scrollOffset]
2569
3009
  );
2570
- const scrollToRatio = useCallback2(
3010
+ const scrollToRatio = useCallback3(
2571
3011
  (ratio, immediate = false) => {
2572
3012
  scrollTo(clamp(ratio, 0, 1) * maxScroll, immediate);
2573
3013
  },
2574
3014
  [maxScroll, scrollTo]
2575
3015
  );
2576
- const handleContentLayout = useCallback2(
3016
+ const handleContentLayout = useCallback3(
2577
3017
  (event) => {
2578
3018
  if (!didSetInitialPositionRef.current) {
2579
3019
  const initialOffset = initialPosition === "end" ? Math.max(0, event.height - viewportHeight) : 0;
@@ -2586,13 +3026,13 @@ function useScrollView({
2586
3026
  },
2587
3027
  [initialPosition, scrollOffset, viewportHeight]
2588
3028
  );
2589
- useEffect3(() => {
3029
+ useEffect4(() => {
2590
3030
  if (!hasContentLayout) {
2591
3031
  return;
2592
3032
  }
2593
3033
  scrollTo(scrollTargetRef.current, true);
2594
3034
  }, [hasContentLayout, maxScroll, scrollTo]);
2595
- const handleWheel = useCallback2(
3035
+ const handleWheel = useCallback3(
2596
3036
  (event) => {
2597
3037
  if (maxScroll <= 0) {
2598
3038
  return;
@@ -2607,7 +3047,7 @@ function useScrollView({
2607
3047
  },
2608
3048
  [maxScroll, scrollTo, viewportHeight, wheelStep]
2609
3049
  );
2610
- const handleTouchStart = useCallback2(
3050
+ const handleTouchStart = useCallback3(
2611
3051
  (event) => {
2612
3052
  if (maxScroll <= 0) {
2613
3053
  return;
@@ -2619,7 +3059,7 @@ function useScrollView({
2619
3059
  },
2620
3060
  [maxScroll]
2621
3061
  );
2622
- const handleTouchMove = useCallback2(
3062
+ const handleTouchMove = useCallback3(
2623
3063
  (event) => {
2624
3064
  if (!touchDraggingRef.current) {
2625
3065
  return;
@@ -2629,7 +3069,7 @@ function useScrollView({
2629
3069
  },
2630
3070
  [scrollTo]
2631
3071
  );
2632
- const handleTouchEnd = useCallback2((event) => {
3072
+ const handleTouchEnd = useCallback3((event) => {
2633
3073
  if (!touchDraggingRef.current) {
2634
3074
  return;
2635
3075
  }
@@ -2651,7 +3091,7 @@ function useScrollView({
2651
3091
  }
2652
3092
 
2653
3093
  // src/hooks/useScenario.ts
2654
- import { useEffect as useEffect4 } from "react";
3094
+ import { useEffect as useEffect5 } from "react";
2655
3095
  var currentScenarioSession = null;
2656
3096
  var scenarioSessionId = 0;
2657
3097
  var scenarioLifecycleQueue = Promise.resolve();
@@ -2793,7 +3233,7 @@ function setWaiting(time, skippable) {
2793
3233
  executePluginCommand("scenario", { subCommand: "setWaiting", time, skippable });
2794
3234
  }
2795
3235
  function useScenario(stories, startName, entryName, goNextOnLoad = false) {
2796
- useEffect4(() => {
3236
+ useEffect5(() => {
2797
3237
  const session = acquireScenarioSession({
2798
3238
  stories: normalizeStories(stories),
2799
3239
  startName,
@@ -2807,9 +3247,9 @@ function useScenario(stories, startName, entryName, goNextOnLoad = false) {
2807
3247
  }
2808
3248
 
2809
3249
  // src/hooks/useSoundEffect.ts
2810
- import { useCallback as useCallback3, useEffect as useEffect5 } from "react";
3250
+ import { useCallback as useCallback4, useEffect as useEffect6 } from "react";
2811
3251
  function useSoundEffect(src) {
2812
- useEffect5(() => {
3252
+ useEffect6(() => {
2813
3253
  return () => {
2814
3254
  try {
2815
3255
  if (src) {
@@ -2824,7 +3264,7 @@ function useSoundEffect(src) {
2824
3264
  }
2825
3265
  };
2826
3266
  }, [src]);
2827
- return useCallback3(() => {
3267
+ return useCallback4(() => {
2828
3268
  try {
2829
3269
  if (src) {
2830
3270
  executePluginCommand("audio", {
@@ -2840,7 +3280,7 @@ function useSoundEffect(src) {
2840
3280
  }
2841
3281
 
2842
3282
  // src/hooks/useStage.ts
2843
- import { createContext as createContext3, useContext as useContext3, useEffect as useEffect6, createElement as createElement2, useCallback as useCallback4 } from "react";
3283
+ import { createContext as createContext4, useContext as useContext4, useEffect as useEffect7, createElement as createElement2, useCallback as useCallback5 } from "react";
2844
3284
  import { proxy as proxy5, useSnapshot as useSnapshot5 } from "valtio";
2845
3285
  var SKIP_INTERVAL_MS = 80;
2846
3286
  var DEFAULT_FAST_FORWARD_STEP_LIMIT = 1e4;
@@ -2926,6 +3366,9 @@ function createStage() {
2926
3366
  return addToRegistry(interruptCallbacks, cb);
2927
3367
  }
2928
3368
  function tryInterrupt() {
3369
+ if (tryFinishActiveWait()) {
3370
+ return true;
3371
+ }
2929
3372
  for (const cb of interruptCallbacks) {
2930
3373
  try {
2931
3374
  if (cb()) return true;
@@ -2973,6 +3416,8 @@ function createStage() {
2973
3416
  let _autoTicketSeq = 0;
2974
3417
  const _pendingAutoTickets = /* @__PURE__ */ new Map();
2975
3418
  let _fastForwardRuntime = null;
3419
+ let _activeWait = null;
3420
+ let _activeWaitSeq = 0;
2976
3421
  let _managedAdvanceInFlight = false;
2977
3422
  let _managedAdvancePending = false;
2978
3423
  function resetManagedAdvanceState() {
@@ -3061,12 +3506,53 @@ function createStage() {
3061
3506
  });
3062
3507
  }
3063
3508
  function requestNextLine() {
3509
+ if (_activeWait !== null) {
3510
+ return;
3511
+ }
3064
3512
  if (isManagedAdvanceActive()) {
3065
3513
  scheduleManagedAdvance();
3066
3514
  return;
3067
3515
  }
3068
3516
  void Promise.resolve(nextLine()).catch(handleManagedAdvanceError);
3069
3517
  }
3518
+ function invalidateActiveWait() {
3519
+ if (_activeWait === null) {
3520
+ return;
3521
+ }
3522
+ _activeWait.settled = true;
3523
+ _activeWait = null;
3524
+ }
3525
+ function settleActiveWait(wait, error) {
3526
+ if (_activeWait !== wait || wait.settled) {
3527
+ return;
3528
+ }
3529
+ wait.settled = true;
3530
+ _activeWait = null;
3531
+ if (error !== void 0) {
3532
+ console.error(`[Stage] Promise hold ${wait.id} rejected:`, error);
3533
+ }
3534
+ requestNextLine();
3535
+ }
3536
+ function tryFinishActiveWait() {
3537
+ const wait = _activeWait;
3538
+ if (wait === null || !wait.skippable || wait.settled) {
3539
+ return false;
3540
+ }
3541
+ const finish = wait.until.finish;
3542
+ if (typeof finish === "function") {
3543
+ try {
3544
+ finish.call(wait.until);
3545
+ } catch (error) {
3546
+ console.error(`[Stage] Failed to finish Promise hold ${wait.id}:`, error);
3547
+ }
3548
+ } else {
3549
+ console.warn(
3550
+ `[Stage] Skipping Promise hold ${wait.id} without finish(); the underlying operation may continue.`
3551
+ );
3552
+ }
3553
+ settleActiveWait(wait);
3554
+ return true;
3555
+ }
3070
3556
  function clearAutoResumeTimer() {
3071
3557
  if (_autoResumeTimer !== null) {
3072
3558
  clearTimeout(_autoResumeTimer);
@@ -3254,7 +3740,11 @@ function createStage() {
3254
3740
  if (isAnyBlockerActive()) return;
3255
3741
  skipState.active = true;
3256
3742
  invokeSkipCallbacks();
3743
+ const activeWait = _activeWait;
3257
3744
  tryInterrupt();
3745
+ if (activeWait !== null && activeWait !== _activeWait) {
3746
+ return;
3747
+ }
3258
3748
  scheduleSkipNextLine();
3259
3749
  }
3260
3750
  function stopSkip() {
@@ -3273,6 +3763,7 @@ function createStage() {
3273
3763
  if (fastForwardState.active) return;
3274
3764
  if (isAnyAutoBlockerActive()) return;
3275
3765
  autoState.active = true;
3766
+ if (_activeWait !== null) return;
3276
3767
  tryInterrupt();
3277
3768
  scheduleAutoNextLine();
3278
3769
  }
@@ -3309,6 +3800,7 @@ function createStage() {
3309
3800
  return fastForwardState.active;
3310
3801
  }
3311
3802
  function resetRuntimeState() {
3803
+ invalidateActiveWait();
3312
3804
  skipState.active = false;
3313
3805
  autoState.active = false;
3314
3806
  fastForwardState.active = false;
@@ -3354,7 +3846,7 @@ function createStage() {
3354
3846
  setWaiting(time, skippable);
3355
3847
  }
3356
3848
  },
3357
- hold() {
3849
+ hold(until, skippable = false) {
3358
3850
  handled = true;
3359
3851
  if (warpActive) {
3360
3852
  return;
@@ -3363,6 +3855,24 @@ function createStage() {
3363
3855
  requestNextLine();
3364
3856
  return;
3365
3857
  }
3858
+ if (until !== void 0) {
3859
+ invalidateActiveWait();
3860
+ const wait = {
3861
+ id: ++_activeWaitSeq,
3862
+ until,
3863
+ skippable,
3864
+ settled: false
3865
+ };
3866
+ _activeWait = wait;
3867
+ void Promise.resolve(until).then(
3868
+ () => settleActiveWait(wait),
3869
+ (error) => settleActiveWait(wait, error)
3870
+ );
3871
+ if (skipState.active) {
3872
+ tryFinishActiveWait();
3873
+ }
3874
+ return;
3875
+ }
3366
3876
  if (skipState.active && !unskippableFlag) {
3367
3877
  if (isAnyBlockerActive()) {
3368
3878
  stopSkip();
@@ -3422,6 +3932,7 @@ function createStage() {
3422
3932
  return parsed.data;
3423
3933
  }
3424
3934
  function dispatchCommand(e) {
3935
+ invalidateActiveWait();
3425
3936
  for (const cb of beforeHandleCommandCallbacks) {
3426
3937
  try {
3427
3938
  cb(e);
@@ -3450,6 +3961,7 @@ function createStage() {
3450
3961
  }
3451
3962
  }
3452
3963
  function dispatchTextLine(e) {
3964
+ invalidateActiveWait();
3453
3965
  const { control, wasHandled } = buildControl();
3454
3966
  for (const handler of textLineHandlers) {
3455
3967
  handler(e, control);
@@ -3483,6 +3995,7 @@ function createStage() {
3483
3995
  })
3484
3996
  ];
3485
3997
  return () => {
3998
+ resetRuntimeState();
3486
3999
  for (const cleanup of cleanups) cleanup();
3487
4000
  };
3488
4001
  }
@@ -3503,52 +4016,54 @@ function createStage() {
3503
4016
  startAuto,
3504
4017
  stopAuto,
3505
4018
  isAutoing,
4019
+ setDefaultAutoTailMs,
3506
4020
  startFastForward,
3507
4021
  stopFastForward,
3508
4022
  isFastForwarding,
4023
+ getSeekingType,
3509
4024
  resetRuntimeState,
3510
4025
  bindEvents
3511
4026
  };
3512
4027
  }
3513
- var StageContext = createContext3(null);
4028
+ var StageContext = createContext4(null);
3514
4029
  function useStageContext() {
3515
- const ctx = useContext3(StageContext);
4030
+ const ctx = useContext4(StageContext);
3516
4031
  if (!ctx) throw new Error("useStageContext must be used within StageContextProvider");
3517
4032
  return ctx;
3518
4033
  }
3519
4034
  function StageContextProvider({ stage, children }) {
3520
- useEffect6(() => {
4035
+ useEffect7(() => {
3521
4036
  return stage.bindEvents();
3522
4037
  }, [stage]);
3523
4038
  return createElement2(StageContext.Provider, { value: stage }, children);
3524
4039
  }
3525
4040
  function useSkipCallback(callback) {
3526
4041
  const stage = useStageContext();
3527
- useEffect6(() => {
4042
+ useEffect7(() => {
3528
4043
  return stage.addSkipCallback(callback);
3529
4044
  }, [stage, callback]);
3530
4045
  }
3531
4046
  function useInterruptCallback(callback) {
3532
4047
  const stage = useStageContext();
3533
- useEffect6(() => {
4048
+ useEffect7(() => {
3534
4049
  return stage.addInterruptCallback(callback);
3535
4050
  }, [stage, callback]);
3536
4051
  }
3537
4052
  function useSkipBlocker(callback) {
3538
4053
  const stage = useStageContext();
3539
- useEffect6(() => {
4054
+ useEffect7(() => {
3540
4055
  return stage.addSkipBlocker(callback);
3541
4056
  }, [stage, callback]);
3542
4057
  }
3543
4058
  function useAutoBlocker(callback) {
3544
4059
  const stage = useStageContext();
3545
- useEffect6(() => {
4060
+ useEffect7(() => {
3546
4061
  return stage.addAutoBlocker(callback);
3547
4062
  }, [stage, callback]);
3548
4063
  }
3549
4064
  function useAutoTicket() {
3550
4065
  const stage = useStageContext();
3551
- return useCallback4(
4066
+ return useCallback5(
3552
4067
  (options) => {
3553
4068
  return stage.issueAutoTicket(options);
3554
4069
  },
@@ -3557,7 +4072,7 @@ function useAutoTicket() {
3557
4072
  }
3558
4073
  function useBeforeHandleCommandCallback(callback) {
3559
4074
  const stage = useStageContext();
3560
- useEffect6(() => {
4075
+ useEffect7(() => {
3561
4076
  return stage.addBeforeHandleCommandCallback(callback);
3562
4077
  }, [stage, callback]);
3563
4078
  }
@@ -3568,14 +4083,18 @@ export {
3568
4083
  Button,
3569
4084
  Checkbox,
3570
4085
  DEBUG_EMPTY_PAGE,
4086
+ Input,
3571
4087
  OverlayParamsContext,
3572
4088
  PageParamsContext,
4089
+ Radio,
4090
+ RadioGroup,
3573
4091
  ScrollView,
3574
4092
  Select,
3575
4093
  Slider,
3576
4094
  StageContextProvider,
3577
4095
  animated as a,
3578
4096
  addEventListener,
4097
+ addFluidObserver,
3579
4098
  animated,
3580
4099
  autoState,
3581
4100
  createBubbleEvent,
@@ -3602,6 +4121,7 @@ export {
3602
4121
  moyu_exports as moyu,
3603
4122
  nextLine,
3604
4123
  registerAppStateAdapter,
4124
+ removeFluidObserver,
3605
4125
  replaceUiData,
3606
4126
  setDefaultAutoTailMs,
3607
4127
  setWaiting,