sibujs 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -25
- package/dist/browser.cjs +804 -2
- package/dist/browser.d.cts +591 -1
- package/dist/browser.d.ts +591 -1
- package/dist/browser.js +50 -8
- package/dist/build.cjs +655 -237
- package/dist/build.js +15 -93
- package/dist/cdn.global.js +188 -7
- package/dist/chunk-2BYQDGN3.js +742 -0
- package/dist/chunk-32DY64NT.js +282 -0
- package/dist/chunk-3AIRKM3B.js +1263 -0
- package/dist/chunk-3X2YG6YM.js +505 -0
- package/dist/chunk-5X6PP2UK.js +28 -0
- package/dist/chunk-77L6NL3X.js +1097 -0
- package/dist/chunk-BGN5ZMP4.js +26 -0
- package/dist/chunk-BTU3TJDS.js +365 -0
- package/dist/chunk-CHF5OHIA.js +61 -0
- package/dist/chunk-CMBFNA7L.js +27 -0
- package/dist/chunk-CNZ35WI2.js +178 -0
- package/dist/chunk-DAHRH4ON.js +331 -0
- package/dist/chunk-EBGIRKQY.js +616 -0
- package/dist/chunk-EUZND3CB.js +27 -0
- package/dist/chunk-F3FA4F32.js +292 -0
- package/dist/chunk-JAKHTMQU.js +1000 -0
- package/dist/chunk-JCI5M6U6.js +956 -0
- package/dist/chunk-KQPDEVVS.js +398 -0
- package/dist/chunk-M4NLBH4I.js +725 -0
- package/dist/chunk-NEKUBFPT.js +60 -0
- package/dist/chunk-NYVAC6P5.js +37 -0
- package/dist/chunk-PTQJDMRT.js +146 -0
- package/dist/chunk-QWZG56ET.js +2744 -0
- package/dist/chunk-TSOKIX5Z.js +654 -0
- package/dist/chunk-UHNL42EF.js +2730 -0
- package/dist/chunk-VRW3FULF.js +725 -0
- package/dist/chunk-WZSPOOER.js +84 -0
- package/dist/chunk-YT6HQ6AM.js +14 -0
- package/dist/chunk-ZD6OAMTH.js +277 -0
- package/dist/chunk-ZWKZCBO6.js +317 -0
- package/dist/contracts-DDrwxvJ-.d.cts +245 -0
- package/dist/contracts-DDrwxvJ-.d.ts +245 -0
- package/dist/contracts-xo5ckdRP.d.cts +240 -0
- package/dist/contracts-xo5ckdRP.d.ts +240 -0
- package/dist/data.cjs +35 -2
- package/dist/data.d.cts +7 -0
- package/dist/data.d.ts +7 -0
- package/dist/data.js +9 -8
- package/dist/devtools.cjs +122 -0
- package/dist/devtools.d.cts +69 -461
- package/dist/devtools.d.ts +69 -461
- package/dist/devtools.js +127 -6
- package/dist/ecosystem.cjs +23 -6
- package/dist/ecosystem.d.cts +1 -1
- package/dist/ecosystem.d.ts +1 -1
- package/dist/ecosystem.js +10 -9
- package/dist/extras.cjs +1208 -88
- package/dist/extras.d.cts +6 -6
- package/dist/extras.d.ts +6 -6
- package/dist/extras.js +70 -33
- package/dist/index.cjs +663 -158
- package/dist/index.d.cts +398 -40
- package/dist/index.d.ts +398 -40
- package/dist/index.js +39 -21
- package/dist/introspect-BumjnBKr.d.cts +477 -0
- package/dist/introspect-CZrlcaYy.d.ts +477 -0
- package/dist/introspect-Cb0zgpi2.d.cts +477 -0
- package/dist/introspect-Y2xNXGSf.d.ts +477 -0
- package/dist/motion.js +4 -4
- package/dist/patterns.cjs +51 -24
- package/dist/patterns.d.cts +19 -57
- package/dist/patterns.d.ts +19 -57
- package/dist/patterns.js +8 -16
- package/dist/performance.js +4 -4
- package/dist/plugins.cjs +429 -82
- package/dist/plugins.d.cts +27 -4
- package/dist/plugins.d.ts +27 -4
- package/dist/plugins.js +156 -37
- package/dist/ssr-4PBXAOO3.js +40 -0
- package/dist/ssr-Do_SiVoL.d.cts +201 -0
- package/dist/ssr-Do_SiVoL.d.ts +201 -0
- package/dist/ssr.cjs +312 -60
- package/dist/ssr.d.cts +10 -1
- package/dist/ssr.d.ts +10 -1
- package/dist/ssr.js +13 -10
- package/dist/tagFactory-DaJ0YWX6.d.cts +47 -0
- package/dist/tagFactory-DaJ0YWX6.d.ts +47 -0
- package/dist/testing.cjs +233 -2
- package/dist/testing.d.cts +42 -1
- package/dist/testing.d.ts +42 -1
- package/dist/testing.js +129 -2
- package/dist/ui.cjs +374 -8
- package/dist/ui.d.cts +252 -2
- package/dist/ui.d.ts +252 -2
- package/dist/ui.js +329 -11
- package/dist/widgets.js +7 -7
- package/package.json +1 -1
package/dist/extras.cjs
CHANGED
|
@@ -32,6 +32,7 @@ __export(extras_exports, {
|
|
|
32
32
|
VirtualList: () => VirtualList,
|
|
33
33
|
accordion: () => accordion,
|
|
34
34
|
animate: () => animate,
|
|
35
|
+
animationFrame: () => animationFrame,
|
|
35
36
|
announce: () => announce,
|
|
36
37
|
antdAdapter: () => antdAdapter,
|
|
37
38
|
aria: () => aria,
|
|
@@ -44,6 +45,8 @@ __export(extras_exports, {
|
|
|
44
45
|
block: () => block,
|
|
45
46
|
bounceIn: () => bounceIn,
|
|
46
47
|
bounceOut: () => bounceOut,
|
|
48
|
+
bounds: () => bounds,
|
|
49
|
+
broadcast: () => broadcast,
|
|
47
50
|
bundlerMetadata: () => bundlerMetadata,
|
|
48
51
|
calculateDelay: () => calculateDelay,
|
|
49
52
|
chakraAdapter: () => chakraAdapter,
|
|
@@ -61,7 +64,6 @@ __export(extras_exports, {
|
|
|
61
64
|
combobox: () => combobox,
|
|
62
65
|
compareSemVer: () => compareSemVer,
|
|
63
66
|
componentAdapter: () => componentAdapter,
|
|
64
|
-
composable: () => composable,
|
|
65
67
|
compose: () => compose,
|
|
66
68
|
composeMiddleware: () => composeMiddleware,
|
|
67
69
|
conditional: () => conditional,
|
|
@@ -71,12 +73,10 @@ __export(extras_exports, {
|
|
|
71
73
|
createBundle: () => createBundle,
|
|
72
74
|
createChunkRegistry: () => createChunkRegistry,
|
|
73
75
|
createDevtoolsOverlay: () => createDevtoolsOverlay,
|
|
74
|
-
createEffect: () => createEffect,
|
|
75
76
|
createErrorReporter: () => createErrorReporter,
|
|
76
77
|
createGuard: () => createGuard,
|
|
77
78
|
createHMRBoundary: () => createHMRBoundary,
|
|
78
79
|
createISR: () => createISR,
|
|
79
|
-
createMemo: () => createMemo,
|
|
80
80
|
createMicroApp: () => createMicroApp,
|
|
81
81
|
createMiddlewareChain: () => createMiddlewareChain,
|
|
82
82
|
createMigrationRunner: () => createMigrationRunner,
|
|
@@ -85,7 +85,6 @@ __export(extras_exports, {
|
|
|
85
85
|
createProfiler: () => createProfiler,
|
|
86
86
|
createSSRCache: () => createSSRCache,
|
|
87
87
|
createSharedScope: () => createSharedScope,
|
|
88
|
-
createSignal: () => createSignal,
|
|
89
88
|
createSlots: () => createSlots,
|
|
90
89
|
createTestHarness: () => createTestHarness,
|
|
91
90
|
createTheme: () => createTheme,
|
|
@@ -117,10 +116,12 @@ __export(extras_exports, {
|
|
|
117
116
|
email: () => email,
|
|
118
117
|
enableDebug: () => enableDebug,
|
|
119
118
|
env: () => env,
|
|
119
|
+
escapeScriptJson: () => escapeScriptJson,
|
|
120
120
|
eventBus: () => eventBus,
|
|
121
121
|
executeLoader: () => executeLoader,
|
|
122
122
|
fadeIn: () => fadeIn,
|
|
123
123
|
fadeOut: () => fadeOut,
|
|
124
|
+
favicon: () => favicon,
|
|
124
125
|
fileUpload: () => fileUpload,
|
|
125
126
|
flipIn: () => flipIn,
|
|
126
127
|
flushScheduler: () => flushScheduler,
|
|
@@ -129,6 +130,8 @@ __export(extras_exports, {
|
|
|
129
130
|
formatCurrency: () => formatCurrency,
|
|
130
131
|
formatError: () => formatError,
|
|
131
132
|
formatNumber: () => formatNumber,
|
|
133
|
+
fullscreen: () => fullscreen,
|
|
134
|
+
gamepad: () => gamepad,
|
|
132
135
|
generateStaticSite: () => generateStaticSite,
|
|
133
136
|
geo: () => geo,
|
|
134
137
|
getActiveDevTools: () => getActiveDevTools,
|
|
@@ -147,6 +150,7 @@ __export(extras_exports, {
|
|
|
147
150
|
hydrateIslands: () => hydrateIslands,
|
|
148
151
|
hydrateProgressively: () => hydrateProgressively,
|
|
149
152
|
idle: () => idle,
|
|
153
|
+
imageLoader: () => imageLoader,
|
|
150
154
|
infiniteQuery: () => infiniteQuery,
|
|
151
155
|
infiniteScroll: () => infiniteScroll,
|
|
152
156
|
initDevTools: () => initDevTools,
|
|
@@ -159,6 +163,7 @@ __export(extras_exports, {
|
|
|
159
163
|
isHMRAvailable: () => isHMRAvailable,
|
|
160
164
|
isWasmCached: () => isWasmCached,
|
|
161
165
|
island: () => island,
|
|
166
|
+
keyboard: () => keyboard,
|
|
162
167
|
lazyChunk: () => lazyChunk,
|
|
163
168
|
lazyLoad: () => lazyLoad,
|
|
164
169
|
lazyModule: () => lazyModule,
|
|
@@ -175,7 +180,10 @@ __export(extras_exports, {
|
|
|
175
180
|
min: () => min,
|
|
176
181
|
minLength: () => minLength,
|
|
177
182
|
mobXAdapter: () => mobXAdapter,
|
|
183
|
+
mouse: () => mouse,
|
|
178
184
|
mutation: () => mutation,
|
|
185
|
+
mutationObserver: () => mutationObserver,
|
|
186
|
+
network: () => network,
|
|
179
187
|
noSideEffect: () => noSideEffect,
|
|
180
188
|
normalize: () => normalize,
|
|
181
189
|
normalizedStore: () => normalizedStore,
|
|
@@ -192,6 +200,7 @@ __export(extras_exports, {
|
|
|
192
200
|
persisted: () => persisted,
|
|
193
201
|
phoneMask: () => phoneMask,
|
|
194
202
|
plugin: () => plugin,
|
|
203
|
+
pointerLock: () => pointerLock,
|
|
195
204
|
popover: () => popover,
|
|
196
205
|
precompile: () => precompile,
|
|
197
206
|
prefetch: () => prefetch,
|
|
@@ -243,6 +252,7 @@ __export(extras_exports, {
|
|
|
243
252
|
slideIn: () => slideIn,
|
|
244
253
|
slideOut: () => slideOut,
|
|
245
254
|
socket: () => socket,
|
|
255
|
+
speech: () => speech,
|
|
246
256
|
spring: () => spring,
|
|
247
257
|
springSignal: () => springSignal,
|
|
248
258
|
ssnMask: () => ssnMask,
|
|
@@ -254,8 +264,11 @@ __export(extras_exports, {
|
|
|
254
264
|
stream: () => stream,
|
|
255
265
|
suspenseSwapScript: () => suspenseSwapScript,
|
|
256
266
|
svgElement: () => svgElement,
|
|
267
|
+
svgFavicon: () => svgFavicon,
|
|
268
|
+
swipe: () => swipe,
|
|
257
269
|
syncAdapter: () => syncAdapter,
|
|
258
270
|
tabs: () => tabs,
|
|
271
|
+
textSelection: () => textSelection,
|
|
259
272
|
throttle: () => throttle,
|
|
260
273
|
timeMask: () => timeMask,
|
|
261
274
|
timeline: () => timeline,
|
|
@@ -270,11 +283,16 @@ __export(extras_exports, {
|
|
|
270
283
|
triggerPluginUnmount: () => triggerPluginUnmount,
|
|
271
284
|
trustHTML: () => trustHTML,
|
|
272
285
|
uniqueId: () => uniqueId,
|
|
286
|
+
urlState: () => urlState,
|
|
273
287
|
validateProps: () => validateProps,
|
|
274
288
|
validators: () => validators,
|
|
289
|
+
vibrate: () => vibrate,
|
|
275
290
|
viewTransition: () => viewTransition,
|
|
291
|
+
visibility: () => visibility,
|
|
292
|
+
wakeLock: () => wakeLock,
|
|
276
293
|
walkDependencyGraph: () => walkDependencyGraph,
|
|
277
294
|
wasm: () => wasm,
|
|
295
|
+
windowSize: () => windowSize,
|
|
278
296
|
withBoundary: () => withBoundary,
|
|
279
297
|
withDefaults: () => withDefaults,
|
|
280
298
|
withErrorTracking: () => withErrorTracking,
|
|
@@ -1512,6 +1530,13 @@ async function preloadRoute(route, context2) {
|
|
|
1512
1530
|
}
|
|
1513
1531
|
|
|
1514
1532
|
// src/ui/socket.ts
|
|
1533
|
+
function validateWsUrl(raw) {
|
|
1534
|
+
const trimmed = raw.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
1535
|
+
if (!trimmed) return null;
|
|
1536
|
+
const lower = trimmed.toLowerCase();
|
|
1537
|
+
if (lower.startsWith("ws://") || lower.startsWith("wss://")) return trimmed;
|
|
1538
|
+
return null;
|
|
1539
|
+
}
|
|
1515
1540
|
function socket(url, options) {
|
|
1516
1541
|
const autoReconnect = options?.autoReconnect ?? false;
|
|
1517
1542
|
const reconnectDelay = options?.reconnectDelay ?? 1e3;
|
|
@@ -1530,8 +1555,13 @@ function socket(url, options) {
|
|
|
1530
1555
|
}
|
|
1531
1556
|
function connect() {
|
|
1532
1557
|
if (disposed) return;
|
|
1558
|
+
const safeUrl = validateWsUrl(getUrl());
|
|
1559
|
+
if (safeUrl === null) {
|
|
1560
|
+
setStatus("closed");
|
|
1561
|
+
return;
|
|
1562
|
+
}
|
|
1533
1563
|
setStatus("connecting");
|
|
1534
|
-
ws = new WebSocket(
|
|
1564
|
+
ws = new WebSocket(safeUrl, protocols);
|
|
1535
1565
|
ws.onopen = () => {
|
|
1536
1566
|
setStatus("open");
|
|
1537
1567
|
reconnectCount = 0;
|
|
@@ -1592,7 +1622,34 @@ function socket(url, options) {
|
|
|
1592
1622
|
return { data: data2, status, send, close, dispose };
|
|
1593
1623
|
}
|
|
1594
1624
|
|
|
1625
|
+
// src/utils/sanitize.ts
|
|
1626
|
+
function sanitizeUrl(url) {
|
|
1627
|
+
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
1628
|
+
if (!trimmed) return "";
|
|
1629
|
+
const lower = trimmed.toLowerCase();
|
|
1630
|
+
if (lower.startsWith("javascript:") || lower.startsWith("data:") || lower.startsWith("vbscript:") || lower.startsWith("blob:")) {
|
|
1631
|
+
return "";
|
|
1632
|
+
}
|
|
1633
|
+
return trimmed;
|
|
1634
|
+
}
|
|
1635
|
+
function sanitizeCSSValue(value) {
|
|
1636
|
+
const lower = value.toLowerCase().replace(/\s+/g, "");
|
|
1637
|
+
if (lower.includes("url(") || lower.includes("expression(") || lower.includes("javascript:") || lower.includes("-moz-binding")) {
|
|
1638
|
+
return "";
|
|
1639
|
+
}
|
|
1640
|
+
return value;
|
|
1641
|
+
}
|
|
1642
|
+
var URL_ATTRIBUTES = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "cite", "poster", "background", "srcset"]);
|
|
1643
|
+
function isUrlAttribute(attr) {
|
|
1644
|
+
return URL_ATTRIBUTES.has(attr);
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1595
1647
|
// src/ui/stream.ts
|
|
1648
|
+
function validateSseUrl(raw) {
|
|
1649
|
+
const safe = sanitizeUrl(raw);
|
|
1650
|
+
if (!safe) return null;
|
|
1651
|
+
return safe;
|
|
1652
|
+
}
|
|
1596
1653
|
function stream(url, options) {
|
|
1597
1654
|
const autoReconnect = options?.autoReconnect ?? false;
|
|
1598
1655
|
const [data2, setData] = signal(null);
|
|
@@ -1603,8 +1660,13 @@ function stream(url, options) {
|
|
|
1603
1660
|
let reconnectTimer = null;
|
|
1604
1661
|
function connect() {
|
|
1605
1662
|
if (disposed) return;
|
|
1663
|
+
const safeUrl = validateSseUrl(url);
|
|
1664
|
+
if (safeUrl === null) {
|
|
1665
|
+
setStatus("closed");
|
|
1666
|
+
return;
|
|
1667
|
+
}
|
|
1606
1668
|
setStatus("connecting");
|
|
1607
|
-
source2 = new EventSource(
|
|
1669
|
+
source2 = new EventSource(safeUrl, {
|
|
1608
1670
|
withCredentials: options?.withCredentials ?? false
|
|
1609
1671
|
});
|
|
1610
1672
|
source2.onopen = () => {
|
|
@@ -2103,6 +2165,766 @@ function formatCurrency(value, currency, options) {
|
|
|
2103
2165
|
}).format(value);
|
|
2104
2166
|
}
|
|
2105
2167
|
|
|
2168
|
+
// src/browser/visibility.ts
|
|
2169
|
+
function visibility() {
|
|
2170
|
+
if (typeof document === "undefined") {
|
|
2171
|
+
const [visible2] = signal(true);
|
|
2172
|
+
return { visible: visible2, dispose: () => {
|
|
2173
|
+
} };
|
|
2174
|
+
}
|
|
2175
|
+
const [visible, setVisible] = signal(!document.hidden);
|
|
2176
|
+
const handler = () => setVisible(!document.hidden);
|
|
2177
|
+
document.addEventListener("visibilitychange", handler);
|
|
2178
|
+
function dispose() {
|
|
2179
|
+
document.removeEventListener("visibilitychange", handler);
|
|
2180
|
+
}
|
|
2181
|
+
return { visible, dispose };
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2184
|
+
// src/browser/network.ts
|
|
2185
|
+
function network() {
|
|
2186
|
+
const connection = typeof navigator !== "undefined" ? navigator.connection ?? navigator.mozConnection ?? navigator.webkitConnection : void 0;
|
|
2187
|
+
const [effectiveType, setEffectiveType] = signal(connection?.effectiveType ?? "unknown");
|
|
2188
|
+
const [downlink, setDownlink] = signal(connection?.downlink ?? 0);
|
|
2189
|
+
const [rtt, setRtt] = signal(connection?.rtt ?? 0);
|
|
2190
|
+
const [saveData, setSaveData] = signal(connection?.saveData ?? false);
|
|
2191
|
+
if (!connection) {
|
|
2192
|
+
return { effectiveType, downlink, rtt, saveData, dispose: () => {
|
|
2193
|
+
} };
|
|
2194
|
+
}
|
|
2195
|
+
const update = () => {
|
|
2196
|
+
setEffectiveType(connection.effectiveType ?? "unknown");
|
|
2197
|
+
setDownlink(connection.downlink ?? 0);
|
|
2198
|
+
setRtt(connection.rtt ?? 0);
|
|
2199
|
+
setSaveData(connection.saveData ?? false);
|
|
2200
|
+
};
|
|
2201
|
+
connection.addEventListener("change", update);
|
|
2202
|
+
function dispose() {
|
|
2203
|
+
connection?.removeEventListener("change", update);
|
|
2204
|
+
}
|
|
2205
|
+
return { effectiveType, downlink, rtt, saveData, dispose };
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
// src/browser/mouse.ts
|
|
2209
|
+
function mouse(options = {}) {
|
|
2210
|
+
const [x, setX] = signal(0);
|
|
2211
|
+
const [y, setY] = signal(0);
|
|
2212
|
+
if (typeof window === "undefined") {
|
|
2213
|
+
return { x, y, dispose: () => {
|
|
2214
|
+
} };
|
|
2215
|
+
}
|
|
2216
|
+
const target = options.target ?? window;
|
|
2217
|
+
const trackTouch = options.touch ?? true;
|
|
2218
|
+
const onMove = (e) => {
|
|
2219
|
+
setX(e.clientX);
|
|
2220
|
+
setY(e.clientY);
|
|
2221
|
+
};
|
|
2222
|
+
const onTouchMove = (e) => {
|
|
2223
|
+
if (e.touches.length === 0) return;
|
|
2224
|
+
setX(e.touches[0].clientX);
|
|
2225
|
+
setY(e.touches[0].clientY);
|
|
2226
|
+
};
|
|
2227
|
+
target.addEventListener("mousemove", onMove, { passive: true });
|
|
2228
|
+
if (trackTouch) {
|
|
2229
|
+
target.addEventListener("touchmove", onTouchMove, { passive: true });
|
|
2230
|
+
}
|
|
2231
|
+
function dispose() {
|
|
2232
|
+
target.removeEventListener("mousemove", onMove);
|
|
2233
|
+
if (trackTouch) {
|
|
2234
|
+
target.removeEventListener("touchmove", onTouchMove);
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
return { x, y, dispose };
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
// src/browser/swipe.ts
|
|
2241
|
+
function swipe(target, options = {}) {
|
|
2242
|
+
const threshold = options.threshold ?? 50;
|
|
2243
|
+
const [direction, setDirection] = signal(null);
|
|
2244
|
+
if (typeof window === "undefined") {
|
|
2245
|
+
return { direction, dispose: () => {
|
|
2246
|
+
} };
|
|
2247
|
+
}
|
|
2248
|
+
let startX = 0;
|
|
2249
|
+
let startY = 0;
|
|
2250
|
+
let tracking = false;
|
|
2251
|
+
const onStart = (e) => {
|
|
2252
|
+
if (e.touches.length === 0) return;
|
|
2253
|
+
startX = e.touches[0].clientX;
|
|
2254
|
+
startY = e.touches[0].clientY;
|
|
2255
|
+
tracking = true;
|
|
2256
|
+
};
|
|
2257
|
+
const onEnd = (e) => {
|
|
2258
|
+
if (!tracking) return;
|
|
2259
|
+
tracking = false;
|
|
2260
|
+
const touch = e.changedTouches[0];
|
|
2261
|
+
if (!touch) return;
|
|
2262
|
+
const dx = touch.clientX - startX;
|
|
2263
|
+
const dy = touch.clientY - startY;
|
|
2264
|
+
const absX = Math.abs(dx);
|
|
2265
|
+
const absY = Math.abs(dy);
|
|
2266
|
+
if (Math.max(absX, absY) < threshold) return;
|
|
2267
|
+
let dir;
|
|
2268
|
+
if (absX > absY) {
|
|
2269
|
+
dir = dx > 0 ? "right" : "left";
|
|
2270
|
+
} else {
|
|
2271
|
+
dir = dy > 0 ? "down" : "up";
|
|
2272
|
+
}
|
|
2273
|
+
setDirection(dir);
|
|
2274
|
+
options.onSwipe?.(dir, Math.max(absX, absY));
|
|
2275
|
+
};
|
|
2276
|
+
target.addEventListener("touchstart", onStart, { passive: true });
|
|
2277
|
+
target.addEventListener("touchend", onEnd, { passive: true });
|
|
2278
|
+
function dispose() {
|
|
2279
|
+
target.removeEventListener("touchstart", onStart);
|
|
2280
|
+
target.removeEventListener("touchend", onEnd);
|
|
2281
|
+
}
|
|
2282
|
+
return { direction, dispose };
|
|
2283
|
+
}
|
|
2284
|
+
|
|
2285
|
+
// src/browser/windowSize.ts
|
|
2286
|
+
function windowSize() {
|
|
2287
|
+
if (typeof window === "undefined") {
|
|
2288
|
+
const [width2] = signal(0);
|
|
2289
|
+
const [height2] = signal(0);
|
|
2290
|
+
return { width: width2, height: height2, dispose: () => {
|
|
2291
|
+
} };
|
|
2292
|
+
}
|
|
2293
|
+
const [width, setWidth] = signal(window.innerWidth);
|
|
2294
|
+
const [height, setHeight] = signal(window.innerHeight);
|
|
2295
|
+
const handler = () => {
|
|
2296
|
+
setWidth(window.innerWidth);
|
|
2297
|
+
setHeight(window.innerHeight);
|
|
2298
|
+
};
|
|
2299
|
+
window.addEventListener("resize", handler, { passive: true });
|
|
2300
|
+
function dispose() {
|
|
2301
|
+
window.removeEventListener("resize", handler);
|
|
2302
|
+
}
|
|
2303
|
+
return { width, height, dispose };
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
// src/browser/urlState.ts
|
|
2307
|
+
function urlState() {
|
|
2308
|
+
if (typeof window === "undefined") {
|
|
2309
|
+
const [params2] = signal(new URLSearchParams());
|
|
2310
|
+
const [hash2] = signal("");
|
|
2311
|
+
return {
|
|
2312
|
+
params: params2,
|
|
2313
|
+
hash: hash2,
|
|
2314
|
+
setParams: () => {
|
|
2315
|
+
},
|
|
2316
|
+
setHash: () => {
|
|
2317
|
+
},
|
|
2318
|
+
dispose: () => {
|
|
2319
|
+
}
|
|
2320
|
+
};
|
|
2321
|
+
}
|
|
2322
|
+
const [params, setParamsSignal] = signal(new URLSearchParams(window.location.search));
|
|
2323
|
+
const [hash, setHashSignal] = signal(window.location.hash);
|
|
2324
|
+
const syncFromLocation = () => {
|
|
2325
|
+
setParamsSignal(new URLSearchParams(window.location.search));
|
|
2326
|
+
setHashSignal(window.location.hash);
|
|
2327
|
+
};
|
|
2328
|
+
const onPopState = () => syncFromLocation();
|
|
2329
|
+
window.addEventListener("popstate", onPopState);
|
|
2330
|
+
function setParams(next, opts = {}) {
|
|
2331
|
+
const p2 = next instanceof URLSearchParams ? next : new URLSearchParams(next);
|
|
2332
|
+
const query2 = p2.toString();
|
|
2333
|
+
const newUrl = `${window.location.pathname}${query2 ? `?${query2}` : ""}${window.location.hash}`;
|
|
2334
|
+
if (opts.replace) window.history.replaceState(null, "", newUrl);
|
|
2335
|
+
else window.history.pushState(null, "", newUrl);
|
|
2336
|
+
setParamsSignal(new URLSearchParams(p2));
|
|
2337
|
+
}
|
|
2338
|
+
function setHash(next, opts = {}) {
|
|
2339
|
+
const normalized = next.startsWith("#") ? next : next ? `#${next}` : "";
|
|
2340
|
+
const newUrl = `${window.location.pathname}${window.location.search}${normalized}`;
|
|
2341
|
+
if (opts.replace) window.history.replaceState(null, "", newUrl);
|
|
2342
|
+
else window.history.pushState(null, "", newUrl);
|
|
2343
|
+
setHashSignal(normalized);
|
|
2344
|
+
}
|
|
2345
|
+
function dispose() {
|
|
2346
|
+
window.removeEventListener("popstate", onPopState);
|
|
2347
|
+
}
|
|
2348
|
+
return { params, hash, setParams, setHash, dispose };
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
// src/browser/broadcast.ts
|
|
2352
|
+
function broadcast(channelName) {
|
|
2353
|
+
if (typeof BroadcastChannel === "undefined") {
|
|
2354
|
+
const [last2] = signal(null);
|
|
2355
|
+
return { last: last2, post: () => {
|
|
2356
|
+
}, dispose: () => {
|
|
2357
|
+
} };
|
|
2358
|
+
}
|
|
2359
|
+
const [last, setLast] = signal(null);
|
|
2360
|
+
const channel = new BroadcastChannel(channelName);
|
|
2361
|
+
const handler = (ev) => setLast(ev.data);
|
|
2362
|
+
channel.addEventListener("message", handler);
|
|
2363
|
+
function post(message) {
|
|
2364
|
+
channel.postMessage(message);
|
|
2365
|
+
}
|
|
2366
|
+
function dispose() {
|
|
2367
|
+
channel.removeEventListener("message", handler);
|
|
2368
|
+
channel.close();
|
|
2369
|
+
}
|
|
2370
|
+
return { last, post, dispose };
|
|
2371
|
+
}
|
|
2372
|
+
|
|
2373
|
+
// src/browser/fullscreen.ts
|
|
2374
|
+
function fullscreen() {
|
|
2375
|
+
if (typeof document === "undefined") {
|
|
2376
|
+
const [isFullscreen2] = signal(false);
|
|
2377
|
+
const [element2] = signal(null);
|
|
2378
|
+
return {
|
|
2379
|
+
isFullscreen: isFullscreen2,
|
|
2380
|
+
element: element2,
|
|
2381
|
+
enter: async () => {
|
|
2382
|
+
},
|
|
2383
|
+
exit: async () => {
|
|
2384
|
+
},
|
|
2385
|
+
toggle: async () => {
|
|
2386
|
+
},
|
|
2387
|
+
dispose: () => {
|
|
2388
|
+
}
|
|
2389
|
+
};
|
|
2390
|
+
}
|
|
2391
|
+
const [isFullscreen, setIsFullscreen] = signal(!!document.fullscreenElement);
|
|
2392
|
+
const [element, setElement] = signal(document.fullscreenElement);
|
|
2393
|
+
const handler = () => {
|
|
2394
|
+
setIsFullscreen(!!document.fullscreenElement);
|
|
2395
|
+
setElement(document.fullscreenElement);
|
|
2396
|
+
};
|
|
2397
|
+
document.addEventListener("fullscreenchange", handler);
|
|
2398
|
+
async function enter(el) {
|
|
2399
|
+
if (!document.fullscreenElement && el.requestFullscreen) {
|
|
2400
|
+
await el.requestFullscreen();
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
async function exit() {
|
|
2404
|
+
if (document.fullscreenElement && document.exitFullscreen) {
|
|
2405
|
+
await document.exitFullscreen();
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
async function toggle(el) {
|
|
2409
|
+
if (document.fullscreenElement) await exit();
|
|
2410
|
+
else await enter(el);
|
|
2411
|
+
}
|
|
2412
|
+
function dispose() {
|
|
2413
|
+
document.removeEventListener("fullscreenchange", handler);
|
|
2414
|
+
}
|
|
2415
|
+
return { isFullscreen, element, enter, exit, toggle, dispose };
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
// src/browser/wakeLock.ts
|
|
2419
|
+
function wakeLock() {
|
|
2420
|
+
const [active, setActive] = signal(false);
|
|
2421
|
+
if (typeof navigator === "undefined" || !("wakeLock" in navigator) || typeof document === "undefined") {
|
|
2422
|
+
return {
|
|
2423
|
+
active,
|
|
2424
|
+
request: async () => {
|
|
2425
|
+
},
|
|
2426
|
+
release: async () => {
|
|
2427
|
+
},
|
|
2428
|
+
dispose: () => {
|
|
2429
|
+
}
|
|
2430
|
+
};
|
|
2431
|
+
}
|
|
2432
|
+
const api = navigator.wakeLock;
|
|
2433
|
+
let sentinel = null;
|
|
2434
|
+
async function request() {
|
|
2435
|
+
try {
|
|
2436
|
+
sentinel = await api.request("screen");
|
|
2437
|
+
setActive(true);
|
|
2438
|
+
sentinel.addEventListener("release", () => {
|
|
2439
|
+
setActive(false);
|
|
2440
|
+
});
|
|
2441
|
+
} catch {
|
|
2442
|
+
setActive(false);
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
async function release() {
|
|
2446
|
+
if (sentinel && !sentinel.released) {
|
|
2447
|
+
await sentinel.release();
|
|
2448
|
+
}
|
|
2449
|
+
sentinel = null;
|
|
2450
|
+
setActive(false);
|
|
2451
|
+
}
|
|
2452
|
+
const onVisibility = () => {
|
|
2453
|
+
if (sentinel?.released && !document.hidden) {
|
|
2454
|
+
void request();
|
|
2455
|
+
}
|
|
2456
|
+
};
|
|
2457
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
2458
|
+
function dispose() {
|
|
2459
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
2460
|
+
void release();
|
|
2461
|
+
}
|
|
2462
|
+
return { active, request, release, dispose };
|
|
2463
|
+
}
|
|
2464
|
+
|
|
2465
|
+
// src/browser/animationFrame.ts
|
|
2466
|
+
function animationFrame(options = {}) {
|
|
2467
|
+
const [delta, setDelta] = signal(0);
|
|
2468
|
+
const [elapsed, setElapsed] = signal(0);
|
|
2469
|
+
const [running, setRunning] = signal(false);
|
|
2470
|
+
if (typeof requestAnimationFrame === "undefined") {
|
|
2471
|
+
return {
|
|
2472
|
+
delta,
|
|
2473
|
+
elapsed,
|
|
2474
|
+
running,
|
|
2475
|
+
pause: () => {
|
|
2476
|
+
},
|
|
2477
|
+
resume: () => {
|
|
2478
|
+
},
|
|
2479
|
+
dispose: () => {
|
|
2480
|
+
}
|
|
2481
|
+
};
|
|
2482
|
+
}
|
|
2483
|
+
let id = null;
|
|
2484
|
+
let prev = -1;
|
|
2485
|
+
let start = -1;
|
|
2486
|
+
const minFrameMs = options.fpsLimit ? 1e3 / options.fpsLimit : 0;
|
|
2487
|
+
const step = (now) => {
|
|
2488
|
+
if (start < 0) start = now;
|
|
2489
|
+
const firstTick = prev < 0;
|
|
2490
|
+
const dt2 = firstTick ? 0 : now - prev;
|
|
2491
|
+
if (firstTick || dt2 >= minFrameMs) {
|
|
2492
|
+
setDelta(dt2);
|
|
2493
|
+
setElapsed(now - start);
|
|
2494
|
+
prev = now;
|
|
2495
|
+
}
|
|
2496
|
+
id = requestAnimationFrame(step);
|
|
2497
|
+
};
|
|
2498
|
+
function resume() {
|
|
2499
|
+
if (id !== null) return;
|
|
2500
|
+
setRunning(true);
|
|
2501
|
+
id = requestAnimationFrame(step);
|
|
2502
|
+
}
|
|
2503
|
+
function pause() {
|
|
2504
|
+
if (id !== null) {
|
|
2505
|
+
cancelAnimationFrame(id);
|
|
2506
|
+
id = null;
|
|
2507
|
+
}
|
|
2508
|
+
setRunning(false);
|
|
2509
|
+
prev = -1;
|
|
2510
|
+
start = -1;
|
|
2511
|
+
}
|
|
2512
|
+
function dispose() {
|
|
2513
|
+
pause();
|
|
2514
|
+
}
|
|
2515
|
+
if (options.immediate !== false) resume();
|
|
2516
|
+
return { delta, elapsed, running, pause, resume, dispose };
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
// src/browser/mutationObserver.ts
|
|
2520
|
+
function mutationObserver(target, options = { childList: true, subtree: true }) {
|
|
2521
|
+
const [records, setRecords] = signal([]);
|
|
2522
|
+
if (typeof MutationObserver === "undefined") {
|
|
2523
|
+
return { records, dispose: () => {
|
|
2524
|
+
} };
|
|
2525
|
+
}
|
|
2526
|
+
const observer = new MutationObserver((batch2) => {
|
|
2527
|
+
setRecords(batch2);
|
|
2528
|
+
});
|
|
2529
|
+
observer.observe(target, options);
|
|
2530
|
+
function dispose() {
|
|
2531
|
+
observer.disconnect();
|
|
2532
|
+
}
|
|
2533
|
+
return { records, dispose };
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
// src/browser/bounds.ts
|
|
2537
|
+
var ZERO = {
|
|
2538
|
+
x: 0,
|
|
2539
|
+
y: 0,
|
|
2540
|
+
width: 0,
|
|
2541
|
+
height: 0,
|
|
2542
|
+
top: 0,
|
|
2543
|
+
left: 0,
|
|
2544
|
+
right: 0,
|
|
2545
|
+
bottom: 0
|
|
2546
|
+
};
|
|
2547
|
+
function readRect(el) {
|
|
2548
|
+
const r = el.getBoundingClientRect();
|
|
2549
|
+
return {
|
|
2550
|
+
x: r.x,
|
|
2551
|
+
y: r.y,
|
|
2552
|
+
width: r.width,
|
|
2553
|
+
height: r.height,
|
|
2554
|
+
top: r.top,
|
|
2555
|
+
left: r.left,
|
|
2556
|
+
right: r.right,
|
|
2557
|
+
bottom: r.bottom
|
|
2558
|
+
};
|
|
2559
|
+
}
|
|
2560
|
+
function bounds(target) {
|
|
2561
|
+
const [rect2, setRect] = signal(ZERO);
|
|
2562
|
+
if (typeof window === "undefined" || !target) {
|
|
2563
|
+
return {
|
|
2564
|
+
rect: rect2,
|
|
2565
|
+
refresh: () => {
|
|
2566
|
+
},
|
|
2567
|
+
dispose: () => {
|
|
2568
|
+
}
|
|
2569
|
+
};
|
|
2570
|
+
}
|
|
2571
|
+
function refresh() {
|
|
2572
|
+
setRect(readRect(target));
|
|
2573
|
+
}
|
|
2574
|
+
refresh();
|
|
2575
|
+
let resizeObserver = null;
|
|
2576
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
2577
|
+
resizeObserver = new ResizeObserver(refresh);
|
|
2578
|
+
resizeObserver.observe(target);
|
|
2579
|
+
}
|
|
2580
|
+
const onScroll = () => refresh();
|
|
2581
|
+
window.addEventListener("scroll", onScroll, { passive: true, capture: true });
|
|
2582
|
+
function dispose() {
|
|
2583
|
+
resizeObserver?.disconnect();
|
|
2584
|
+
window.removeEventListener("scroll", onScroll, { capture: true });
|
|
2585
|
+
}
|
|
2586
|
+
return { rect: rect2, refresh, dispose };
|
|
2587
|
+
}
|
|
2588
|
+
|
|
2589
|
+
// src/browser/keyboard.ts
|
|
2590
|
+
function keyboard(options = {}) {
|
|
2591
|
+
const [pressed, setPressed] = signal(/* @__PURE__ */ new Set());
|
|
2592
|
+
if (typeof window === "undefined") {
|
|
2593
|
+
return {
|
|
2594
|
+
pressed,
|
|
2595
|
+
isPressed: () => false,
|
|
2596
|
+
dispose: () => {
|
|
2597
|
+
}
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
const target = options.target ?? window;
|
|
2601
|
+
const filter = options.keys ? new Set(options.keys) : null;
|
|
2602
|
+
const onDown = (e) => {
|
|
2603
|
+
if (filter && !filter.has(e.key)) return;
|
|
2604
|
+
setPressed((prev) => {
|
|
2605
|
+
if (prev.has(e.key)) return prev;
|
|
2606
|
+
const next = new Set(prev);
|
|
2607
|
+
next.add(e.key);
|
|
2608
|
+
return next;
|
|
2609
|
+
});
|
|
2610
|
+
};
|
|
2611
|
+
const onUp = (e) => {
|
|
2612
|
+
if (filter && !filter.has(e.key)) return;
|
|
2613
|
+
setPressed((prev) => {
|
|
2614
|
+
if (!prev.has(e.key)) return prev;
|
|
2615
|
+
const next = new Set(prev);
|
|
2616
|
+
next.delete(e.key);
|
|
2617
|
+
return next;
|
|
2618
|
+
});
|
|
2619
|
+
};
|
|
2620
|
+
const onBlur = () => setPressed(/* @__PURE__ */ new Set());
|
|
2621
|
+
target.addEventListener("keydown", onDown);
|
|
2622
|
+
target.addEventListener("keyup", onUp);
|
|
2623
|
+
window.addEventListener("blur", onBlur);
|
|
2624
|
+
function isPressed(key) {
|
|
2625
|
+
return pressed().has(key);
|
|
2626
|
+
}
|
|
2627
|
+
function dispose() {
|
|
2628
|
+
target.removeEventListener("keydown", onDown);
|
|
2629
|
+
target.removeEventListener("keyup", onUp);
|
|
2630
|
+
window.removeEventListener("blur", onBlur);
|
|
2631
|
+
}
|
|
2632
|
+
return { pressed, isPressed, dispose };
|
|
2633
|
+
}
|
|
2634
|
+
|
|
2635
|
+
// src/browser/speech.ts
|
|
2636
|
+
function speech() {
|
|
2637
|
+
const [speaking, setSpeaking] = signal(false);
|
|
2638
|
+
const [paused, setPaused] = signal(false);
|
|
2639
|
+
if (typeof window === "undefined" || typeof window.speechSynthesis === "undefined") {
|
|
2640
|
+
return {
|
|
2641
|
+
speaking,
|
|
2642
|
+
paused,
|
|
2643
|
+
speak: () => {
|
|
2644
|
+
},
|
|
2645
|
+
pause: () => {
|
|
2646
|
+
},
|
|
2647
|
+
resume: () => {
|
|
2648
|
+
},
|
|
2649
|
+
cancel: () => {
|
|
2650
|
+
},
|
|
2651
|
+
dispose: () => {
|
|
2652
|
+
}
|
|
2653
|
+
};
|
|
2654
|
+
}
|
|
2655
|
+
const synth = window.speechSynthesis;
|
|
2656
|
+
const interval = setInterval(() => {
|
|
2657
|
+
setSpeaking(synth.speaking);
|
|
2658
|
+
setPaused(synth.paused);
|
|
2659
|
+
}, 200);
|
|
2660
|
+
function speak(text2, options = {}) {
|
|
2661
|
+
const u2 = new SpeechSynthesisUtterance(text2);
|
|
2662
|
+
if (options.lang) u2.lang = options.lang;
|
|
2663
|
+
if (options.rate != null) u2.rate = options.rate;
|
|
2664
|
+
if (options.pitch != null) u2.pitch = options.pitch;
|
|
2665
|
+
if (options.volume != null) u2.volume = options.volume;
|
|
2666
|
+
if (options.voice) {
|
|
2667
|
+
const voices = synth.getVoices();
|
|
2668
|
+
const match = voices.find((v) => v.name === options.voice);
|
|
2669
|
+
if (match) u2.voice = match;
|
|
2670
|
+
}
|
|
2671
|
+
u2.addEventListener("start", () => setSpeaking(true));
|
|
2672
|
+
u2.addEventListener("end", () => {
|
|
2673
|
+
setSpeaking(false);
|
|
2674
|
+
setPaused(false);
|
|
2675
|
+
});
|
|
2676
|
+
u2.addEventListener("error", () => {
|
|
2677
|
+
setSpeaking(false);
|
|
2678
|
+
setPaused(false);
|
|
2679
|
+
});
|
|
2680
|
+
synth.speak(u2);
|
|
2681
|
+
}
|
|
2682
|
+
function dispose() {
|
|
2683
|
+
clearInterval(interval);
|
|
2684
|
+
synth.cancel();
|
|
2685
|
+
}
|
|
2686
|
+
return {
|
|
2687
|
+
speaking,
|
|
2688
|
+
paused,
|
|
2689
|
+
speak,
|
|
2690
|
+
pause: () => synth.pause(),
|
|
2691
|
+
resume: () => synth.resume(),
|
|
2692
|
+
cancel: () => synth.cancel(),
|
|
2693
|
+
dispose
|
|
2694
|
+
};
|
|
2695
|
+
}
|
|
2696
|
+
|
|
2697
|
+
// src/browser/gamepad.ts
|
|
2698
|
+
function gamepad() {
|
|
2699
|
+
const [pads, setPads] = signal([]);
|
|
2700
|
+
if (typeof window === "undefined" || typeof navigator === "undefined" || typeof navigator.getGamepads !== "function") {
|
|
2701
|
+
return { pads, dispose: () => {
|
|
2702
|
+
} };
|
|
2703
|
+
}
|
|
2704
|
+
let rafId = null;
|
|
2705
|
+
function snapshot(pad) {
|
|
2706
|
+
return {
|
|
2707
|
+
index: pad.index,
|
|
2708
|
+
id: pad.id,
|
|
2709
|
+
connected: pad.connected,
|
|
2710
|
+
buttons: pad.buttons.map((b2) => ({ pressed: b2.pressed, value: b2.value })),
|
|
2711
|
+
axes: [...pad.axes]
|
|
2712
|
+
};
|
|
2713
|
+
}
|
|
2714
|
+
function equal(a2, b2) {
|
|
2715
|
+
if (a2.length !== b2.length) return false;
|
|
2716
|
+
for (let i2 = 0; i2 < a2.length; i2++) {
|
|
2717
|
+
const pa = a2[i2];
|
|
2718
|
+
const pb = b2[i2];
|
|
2719
|
+
if (pa.index !== pb.index || pa.connected !== pb.connected) return false;
|
|
2720
|
+
if (pa.buttons.length !== pb.buttons.length) return false;
|
|
2721
|
+
for (let j = 0; j < pa.buttons.length; j++) {
|
|
2722
|
+
if (pa.buttons[j].pressed !== pb.buttons[j].pressed) return false;
|
|
2723
|
+
if (pa.buttons[j].value !== pb.buttons[j].value) return false;
|
|
2724
|
+
}
|
|
2725
|
+
if (pa.axes.length !== pb.axes.length) return false;
|
|
2726
|
+
for (let j = 0; j < pa.axes.length; j++) {
|
|
2727
|
+
if (pa.axes[j] !== pb.axes[j]) return false;
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
return true;
|
|
2731
|
+
}
|
|
2732
|
+
function poll() {
|
|
2733
|
+
const raw = navigator.getGamepads();
|
|
2734
|
+
const snap = Array.from(raw).filter((g2) => g2 !== null).map(snapshot);
|
|
2735
|
+
const current = pads();
|
|
2736
|
+
if (!equal(current, snap)) setPads(snap);
|
|
2737
|
+
rafId = requestAnimationFrame(poll);
|
|
2738
|
+
}
|
|
2739
|
+
function startPolling() {
|
|
2740
|
+
if (rafId === null) poll();
|
|
2741
|
+
}
|
|
2742
|
+
function stopPolling() {
|
|
2743
|
+
if (rafId !== null) {
|
|
2744
|
+
cancelAnimationFrame(rafId);
|
|
2745
|
+
rafId = null;
|
|
2746
|
+
}
|
|
2747
|
+
}
|
|
2748
|
+
const onConnect = () => startPolling();
|
|
2749
|
+
const onDisconnect = () => {
|
|
2750
|
+
const raw = navigator.getGamepads();
|
|
2751
|
+
const hasAny = Array.from(raw).some((g2) => g2 !== null);
|
|
2752
|
+
if (!hasAny) stopPolling();
|
|
2753
|
+
};
|
|
2754
|
+
window.addEventListener("gamepadconnected", onConnect);
|
|
2755
|
+
window.addEventListener("gamepaddisconnected", onDisconnect);
|
|
2756
|
+
const initial = Array.from(navigator.getGamepads()).some((g2) => g2 !== null);
|
|
2757
|
+
if (initial) startPolling();
|
|
2758
|
+
function dispose() {
|
|
2759
|
+
stopPolling();
|
|
2760
|
+
window.removeEventListener("gamepadconnected", onConnect);
|
|
2761
|
+
window.removeEventListener("gamepaddisconnected", onDisconnect);
|
|
2762
|
+
}
|
|
2763
|
+
return { pads, dispose };
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2766
|
+
// src/browser/pointerLock.ts
|
|
2767
|
+
function pointerLock() {
|
|
2768
|
+
const [locked, setLocked] = signal(false);
|
|
2769
|
+
if (typeof document === "undefined") {
|
|
2770
|
+
return {
|
|
2771
|
+
locked,
|
|
2772
|
+
request: () => {
|
|
2773
|
+
},
|
|
2774
|
+
exit: () => {
|
|
2775
|
+
},
|
|
2776
|
+
dispose: () => {
|
|
2777
|
+
}
|
|
2778
|
+
};
|
|
2779
|
+
}
|
|
2780
|
+
const handler = () => {
|
|
2781
|
+
setLocked(!!document.pointerLockElement);
|
|
2782
|
+
};
|
|
2783
|
+
document.addEventListener("pointerlockchange", handler);
|
|
2784
|
+
function request(element) {
|
|
2785
|
+
if (typeof element.requestPointerLock === "function") {
|
|
2786
|
+
element.requestPointerLock();
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
function exit() {
|
|
2790
|
+
if (typeof document.exitPointerLock === "function") {
|
|
2791
|
+
document.exitPointerLock();
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
function dispose() {
|
|
2795
|
+
document.removeEventListener("pointerlockchange", handler);
|
|
2796
|
+
}
|
|
2797
|
+
return { locked, request, exit, dispose };
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
// src/browser/vibrate.ts
|
|
2801
|
+
function vibrate(pattern2) {
|
|
2802
|
+
if (typeof navigator === "undefined" || typeof navigator.vibrate !== "function") {
|
|
2803
|
+
return false;
|
|
2804
|
+
}
|
|
2805
|
+
return navigator.vibrate(pattern2);
|
|
2806
|
+
}
|
|
2807
|
+
|
|
2808
|
+
// src/browser/favicon.ts
|
|
2809
|
+
function favicon(url) {
|
|
2810
|
+
if (typeof document === "undefined") return;
|
|
2811
|
+
let link2 = document.querySelector("link[rel='icon']");
|
|
2812
|
+
if (!link2) {
|
|
2813
|
+
link2 = document.createElement("link");
|
|
2814
|
+
link2.rel = "icon";
|
|
2815
|
+
document.head.appendChild(link2);
|
|
2816
|
+
}
|
|
2817
|
+
link2.href = url;
|
|
2818
|
+
}
|
|
2819
|
+
function svgFavicon(svg2) {
|
|
2820
|
+
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg2)}`;
|
|
2821
|
+
}
|
|
2822
|
+
|
|
2823
|
+
// src/browser/textSelection.ts
|
|
2824
|
+
function textSelection() {
|
|
2825
|
+
const [text2, setText] = signal("");
|
|
2826
|
+
const [rect2, setRect] = signal(null);
|
|
2827
|
+
if (typeof document === "undefined") {
|
|
2828
|
+
return {
|
|
2829
|
+
text: text2,
|
|
2830
|
+
rect: rect2,
|
|
2831
|
+
hasSelection: () => false,
|
|
2832
|
+
clear: () => {
|
|
2833
|
+
},
|
|
2834
|
+
dispose: () => {
|
|
2835
|
+
}
|
|
2836
|
+
};
|
|
2837
|
+
}
|
|
2838
|
+
const handler = () => {
|
|
2839
|
+
const sel = document.getSelection();
|
|
2840
|
+
if (!sel || sel.rangeCount === 0 || sel.isCollapsed) {
|
|
2841
|
+
setText("");
|
|
2842
|
+
setRect(null);
|
|
2843
|
+
return;
|
|
2844
|
+
}
|
|
2845
|
+
setText(sel.toString());
|
|
2846
|
+
try {
|
|
2847
|
+
const r = sel.getRangeAt(0).getBoundingClientRect();
|
|
2848
|
+
setRect(r.width > 0 || r.height > 0 ? r : null);
|
|
2849
|
+
} catch {
|
|
2850
|
+
setRect(null);
|
|
2851
|
+
}
|
|
2852
|
+
};
|
|
2853
|
+
document.addEventListener("selectionchange", handler);
|
|
2854
|
+
function clear() {
|
|
2855
|
+
const sel = document.getSelection();
|
|
2856
|
+
sel?.removeAllRanges();
|
|
2857
|
+
setText("");
|
|
2858
|
+
setRect(null);
|
|
2859
|
+
}
|
|
2860
|
+
function dispose() {
|
|
2861
|
+
document.removeEventListener("selectionchange", handler);
|
|
2862
|
+
}
|
|
2863
|
+
return {
|
|
2864
|
+
text: text2,
|
|
2865
|
+
rect: rect2,
|
|
2866
|
+
hasSelection: () => text2().length > 0,
|
|
2867
|
+
clear,
|
|
2868
|
+
dispose
|
|
2869
|
+
};
|
|
2870
|
+
}
|
|
2871
|
+
|
|
2872
|
+
// src/browser/imageLoader.ts
|
|
2873
|
+
function imageLoader(src) {
|
|
2874
|
+
const [status, setStatus] = signal("pending");
|
|
2875
|
+
const [image, setImage] = signal(null);
|
|
2876
|
+
const [width, setWidth] = signal(0);
|
|
2877
|
+
const [height, setHeight] = signal(0);
|
|
2878
|
+
if (typeof Image === "undefined") {
|
|
2879
|
+
return {
|
|
2880
|
+
status,
|
|
2881
|
+
image,
|
|
2882
|
+
width,
|
|
2883
|
+
height,
|
|
2884
|
+
dispose: () => {
|
|
2885
|
+
}
|
|
2886
|
+
};
|
|
2887
|
+
}
|
|
2888
|
+
let current = null;
|
|
2889
|
+
let disposed = false;
|
|
2890
|
+
function start(url) {
|
|
2891
|
+
if (current) {
|
|
2892
|
+
current.onload = null;
|
|
2893
|
+
current.onerror = null;
|
|
2894
|
+
}
|
|
2895
|
+
setStatus("pending");
|
|
2896
|
+
setImage(null);
|
|
2897
|
+
const img2 = new Image();
|
|
2898
|
+
current = img2;
|
|
2899
|
+
img2.onload = () => {
|
|
2900
|
+
if (disposed || current !== img2) return;
|
|
2901
|
+
setImage(img2);
|
|
2902
|
+
setWidth(img2.naturalWidth);
|
|
2903
|
+
setHeight(img2.naturalHeight);
|
|
2904
|
+
setStatus("loaded");
|
|
2905
|
+
};
|
|
2906
|
+
img2.onerror = () => {
|
|
2907
|
+
if (disposed || current !== img2) return;
|
|
2908
|
+
setStatus("error");
|
|
2909
|
+
};
|
|
2910
|
+
img2.src = url;
|
|
2911
|
+
}
|
|
2912
|
+
if (typeof src === "function") {
|
|
2913
|
+
start(src());
|
|
2914
|
+
} else {
|
|
2915
|
+
start(src);
|
|
2916
|
+
}
|
|
2917
|
+
function dispose() {
|
|
2918
|
+
disposed = true;
|
|
2919
|
+
if (current) {
|
|
2920
|
+
current.onload = null;
|
|
2921
|
+
current.onerror = null;
|
|
2922
|
+
current = null;
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
return { status, image, width, height, dispose };
|
|
2926
|
+
}
|
|
2927
|
+
|
|
2106
2928
|
// src/patterns/machine.ts
|
|
2107
2929
|
function machine(config) {
|
|
2108
2930
|
const [state, setState] = signal(config.initial);
|
|
@@ -2133,8 +2955,13 @@ function machine(config) {
|
|
|
2133
2955
|
stateDef.exit(ctx);
|
|
2134
2956
|
}
|
|
2135
2957
|
if (action) {
|
|
2136
|
-
const
|
|
2137
|
-
|
|
2958
|
+
const rawPatch = action(ctx);
|
|
2959
|
+
const next = { ...ctx };
|
|
2960
|
+
for (const key of Object.keys(rawPatch)) {
|
|
2961
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
2962
|
+
next[key] = rawPatch[key];
|
|
2963
|
+
}
|
|
2964
|
+
setContext(next);
|
|
2138
2965
|
}
|
|
2139
2966
|
setState(target);
|
|
2140
2967
|
const targetDef = config.states[target];
|
|
@@ -2167,6 +2994,7 @@ function persisted(key, initial, options = {}) {
|
|
|
2167
2994
|
const deserialize = options.deserialize || JSON.parse;
|
|
2168
2995
|
const encrypt = options.encrypt;
|
|
2169
2996
|
const decrypt = options.decrypt;
|
|
2997
|
+
const syncTabs = options.session ? false : options.syncTabs ?? true;
|
|
2170
2998
|
let restored = initial;
|
|
2171
2999
|
try {
|
|
2172
3000
|
let raw = storage.getItem(key);
|
|
@@ -2178,8 +3006,10 @@ function persisted(key, initial, options = {}) {
|
|
|
2178
3006
|
} catch {
|
|
2179
3007
|
}
|
|
2180
3008
|
const [value, setValue] = signal(restored);
|
|
3009
|
+
let applyingFromStorage = false;
|
|
2181
3010
|
effect(() => {
|
|
2182
3011
|
const current = value();
|
|
3012
|
+
if (applyingFromStorage) return;
|
|
2183
3013
|
try {
|
|
2184
3014
|
let serialized = serialize(current);
|
|
2185
3015
|
if (encrypt) serialized = encrypt(serialized);
|
|
@@ -2187,6 +3017,47 @@ function persisted(key, initial, options = {}) {
|
|
|
2187
3017
|
} catch {
|
|
2188
3018
|
}
|
|
2189
3019
|
});
|
|
3020
|
+
let storageListener = null;
|
|
3021
|
+
if (syncTabs && typeof window !== "undefined") {
|
|
3022
|
+
storageListener = (e) => {
|
|
3023
|
+
if (e.storageArea !== storage || e.key !== key) return;
|
|
3024
|
+
if (e.newValue === null) {
|
|
3025
|
+
applyingFromStorage = true;
|
|
3026
|
+
try {
|
|
3027
|
+
setValue(initial);
|
|
3028
|
+
} finally {
|
|
3029
|
+
applyingFromStorage = false;
|
|
3030
|
+
}
|
|
3031
|
+
return;
|
|
3032
|
+
}
|
|
3033
|
+
try {
|
|
3034
|
+
let raw = e.newValue;
|
|
3035
|
+
if (decrypt) raw = decrypt(raw);
|
|
3036
|
+
const parsed = deserialize(raw);
|
|
3037
|
+
if (options.validate && !options.validate(parsed)) return;
|
|
3038
|
+
applyingFromStorage = true;
|
|
3039
|
+
try {
|
|
3040
|
+
setValue(parsed);
|
|
3041
|
+
} finally {
|
|
3042
|
+
applyingFromStorage = false;
|
|
3043
|
+
}
|
|
3044
|
+
} catch {
|
|
3045
|
+
}
|
|
3046
|
+
};
|
|
3047
|
+
window.addEventListener("storage", storageListener);
|
|
3048
|
+
}
|
|
3049
|
+
const dispose = () => {
|
|
3050
|
+
if (storageListener && typeof window !== "undefined") {
|
|
3051
|
+
window.removeEventListener("storage", storageListener);
|
|
3052
|
+
storageListener = null;
|
|
3053
|
+
}
|
|
3054
|
+
};
|
|
3055
|
+
Object.defineProperty(setValue, "dispose", {
|
|
3056
|
+
value: dispose,
|
|
3057
|
+
enumerable: false,
|
|
3058
|
+
writable: false,
|
|
3059
|
+
configurable: false
|
|
3060
|
+
});
|
|
2190
3061
|
return [value, setValue];
|
|
2191
3062
|
}
|
|
2192
3063
|
|
|
@@ -2353,17 +3224,6 @@ function globalStore(config) {
|
|
|
2353
3224
|
return { getState, select: select3, dispatch, subscribe, reset };
|
|
2354
3225
|
}
|
|
2355
3226
|
|
|
2356
|
-
// src/patterns/primitives.ts
|
|
2357
|
-
function createSignal(value) {
|
|
2358
|
-
return signal(value);
|
|
2359
|
-
}
|
|
2360
|
-
function createMemo(fn) {
|
|
2361
|
-
return derived(fn);
|
|
2362
|
-
}
|
|
2363
|
-
function createEffect(fn) {
|
|
2364
|
-
return effect(fn);
|
|
2365
|
-
}
|
|
2366
|
-
|
|
2367
3227
|
// src/patterns/hoc.ts
|
|
2368
3228
|
function withWrapper(WrappedComponent, wrapper) {
|
|
2369
3229
|
return (props) => wrapper(WrappedComponent, props);
|
|
@@ -2376,9 +3236,6 @@ function compose(...wrappers) {
|
|
|
2376
3236
|
}
|
|
2377
3237
|
|
|
2378
3238
|
// src/patterns/composable.ts
|
|
2379
|
-
function composable(setup) {
|
|
2380
|
-
return setup;
|
|
2381
|
-
}
|
|
2382
3239
|
function RenderProp(props) {
|
|
2383
3240
|
return props.render(props.data());
|
|
2384
3241
|
}
|
|
@@ -3375,8 +4232,25 @@ function announce(message, priority = "polite") {
|
|
|
3375
4232
|
|
|
3376
4233
|
// src/ui/scopedStyle.ts
|
|
3377
4234
|
var scopeCounter = 0;
|
|
4235
|
+
function decodeCssEscapes(css) {
|
|
4236
|
+
return css.replace(/\\([0-9a-f]{1,6})[ \t\n\r\f]?|\\([^\n])/gi, (_match, hex, ch) => {
|
|
4237
|
+
if (hex) {
|
|
4238
|
+
const code2 = Number.parseInt(hex, 16);
|
|
4239
|
+
if (Number.isFinite(code2) && code2 > 0 && code2 <= 1114111) {
|
|
4240
|
+
try {
|
|
4241
|
+
return String.fromCodePoint(code2);
|
|
4242
|
+
} catch {
|
|
4243
|
+
return "";
|
|
4244
|
+
}
|
|
4245
|
+
}
|
|
4246
|
+
return "";
|
|
4247
|
+
}
|
|
4248
|
+
return ch || "";
|
|
4249
|
+
});
|
|
4250
|
+
}
|
|
3378
4251
|
function sanitizeCSS(css) {
|
|
3379
|
-
let sanitized = css
|
|
4252
|
+
let sanitized = decodeCssEscapes(css);
|
|
4253
|
+
sanitized = sanitized.replace(/@import\s+[^;]+;/gi, "/* @import removed */");
|
|
3380
4254
|
sanitized = sanitized.replace(/url\s*\(\s*(?:"[^"]*"|'[^']*'|[^)]*)\s*\)/gi, "/* url() removed */");
|
|
3381
4255
|
sanitized = sanitized.replace(/expression\s*\(\s*(?:"[^"]*"|'[^']*'|[^)]*)\s*\)/gi, "/* expression() removed */");
|
|
3382
4256
|
sanitized = sanitized.replace(/-moz-binding\s*:[^;]+;/gi, "/* -moz-binding removed */");
|
|
@@ -3426,31 +4300,22 @@ function removeScopedStyle(scopeId) {
|
|
|
3426
4300
|
if (el) el.remove();
|
|
3427
4301
|
}
|
|
3428
4302
|
|
|
3429
|
-
// src/utils/sanitize.ts
|
|
3430
|
-
function sanitizeUrl(url) {
|
|
3431
|
-
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
3432
|
-
if (!trimmed) return "";
|
|
3433
|
-
const lower = trimmed.toLowerCase();
|
|
3434
|
-
if (lower.startsWith("javascript:") || lower.startsWith("data:") || lower.startsWith("vbscript:") || lower.startsWith("blob:")) {
|
|
3435
|
-
return "";
|
|
3436
|
-
}
|
|
3437
|
-
return trimmed;
|
|
3438
|
-
}
|
|
3439
|
-
function sanitizeCSSValue(value) {
|
|
3440
|
-
const lower = value.toLowerCase().replace(/\s+/g, "");
|
|
3441
|
-
if (lower.includes("url(") || lower.includes("expression(") || lower.includes("javascript:") || lower.includes("-moz-binding")) {
|
|
3442
|
-
return "";
|
|
3443
|
-
}
|
|
3444
|
-
return value;
|
|
3445
|
-
}
|
|
3446
|
-
var URL_ATTRIBUTES = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "cite", "poster", "background", "srcset"]);
|
|
3447
|
-
function isUrlAttribute(attr) {
|
|
3448
|
-
return URL_ATTRIBUTES.has(attr);
|
|
3449
|
-
}
|
|
3450
|
-
|
|
3451
4303
|
// src/reactivity/bindAttribute.ts
|
|
3452
4304
|
var _isDev4 = isDev();
|
|
4305
|
+
function isEventHandlerAttr(name) {
|
|
4306
|
+
if (name.length < 3) return false;
|
|
4307
|
+
const lower = name.toLowerCase();
|
|
4308
|
+
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
4309
|
+
}
|
|
3453
4310
|
function bindAttribute(el, attr, getter) {
|
|
4311
|
+
if (isEventHandlerAttr(attr)) {
|
|
4312
|
+
if (_isDev4)
|
|
4313
|
+
devWarn(
|
|
4314
|
+
`bindAttribute: refusing to bind event-handler attribute "${attr}". Use on:{ ${attr.slice(2)}: fn } instead.`
|
|
4315
|
+
);
|
|
4316
|
+
return () => {
|
|
4317
|
+
};
|
|
4318
|
+
}
|
|
3454
4319
|
function commit() {
|
|
3455
4320
|
let value;
|
|
3456
4321
|
try {
|
|
@@ -4374,11 +5239,34 @@ function preloadModules(urls) {
|
|
|
4374
5239
|
}
|
|
4375
5240
|
|
|
4376
5241
|
// src/platform/head.ts
|
|
4377
|
-
var HEAD_URL_ATTRS = /* @__PURE__ */ new Set(["href", "src"
|
|
5242
|
+
var HEAD_URL_ATTRS = /* @__PURE__ */ new Set(["href", "src"]);
|
|
4378
5243
|
function sanitizeHeadAttr(key, value) {
|
|
4379
5244
|
if (HEAD_URL_ATTRS.has(key)) return sanitizeUrl(value);
|
|
4380
5245
|
return value;
|
|
4381
5246
|
}
|
|
5247
|
+
function isDangerousMetaRefresh(metaProps) {
|
|
5248
|
+
const httpEquiv = metaProps["http-equiv"];
|
|
5249
|
+
if (typeof httpEquiv !== "string") return false;
|
|
5250
|
+
if (httpEquiv.toLowerCase() !== "refresh") return false;
|
|
5251
|
+
const content = metaProps.content;
|
|
5252
|
+
if (typeof content !== "string") return false;
|
|
5253
|
+
const normalized = content.replace(/[\x00-\x20\x7f-\x9f]+/g, "").toLowerCase();
|
|
5254
|
+
return normalized.includes("url=javascript:") || normalized.includes("url=data:") || normalized.includes("url=vbscript:") || normalized.includes("url=blob:");
|
|
5255
|
+
}
|
|
5256
|
+
var SAFE_HEAD_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
|
|
5257
|
+
function isEventHandlerAttr2(name) {
|
|
5258
|
+
if (name.length < 3) return false;
|
|
5259
|
+
const lower = name.toLowerCase();
|
|
5260
|
+
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
5261
|
+
}
|
|
5262
|
+
function isSafeHeadAttr(name) {
|
|
5263
|
+
if (!SAFE_HEAD_ATTR_NAME.test(name)) return false;
|
|
5264
|
+
if (isEventHandlerAttr2(name)) return false;
|
|
5265
|
+
return true;
|
|
5266
|
+
}
|
|
5267
|
+
function escapeScriptJsonLocal(json) {
|
|
5268
|
+
return json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
5269
|
+
}
|
|
4382
5270
|
function Head(props) {
|
|
4383
5271
|
const anchor = document.createComment("sibu-head");
|
|
4384
5272
|
const managedElements = [];
|
|
@@ -4405,15 +5293,17 @@ function Head(props) {
|
|
|
4405
5293
|
}
|
|
4406
5294
|
if (props.meta) {
|
|
4407
5295
|
for (const metaProps of props.meta) {
|
|
5296
|
+
if (isDangerousMetaRefresh(metaProps)) continue;
|
|
4408
5297
|
const el = document.createElement("meta");
|
|
4409
5298
|
for (const [key, value] of Object.entries(metaProps)) {
|
|
5299
|
+
if (!isSafeHeadAttr(key)) continue;
|
|
4410
5300
|
if (typeof value === "function") {
|
|
4411
5301
|
const cleanupFn = effect(() => {
|
|
4412
|
-
el.setAttribute(key, value());
|
|
5302
|
+
el.setAttribute(key, sanitizeHeadAttr(key, value()));
|
|
4413
5303
|
});
|
|
4414
5304
|
effectCleanups.push(cleanupFn);
|
|
4415
5305
|
} else {
|
|
4416
|
-
el.setAttribute(key, value);
|
|
5306
|
+
el.setAttribute(key, sanitizeHeadAttr(key, value));
|
|
4417
5307
|
}
|
|
4418
5308
|
}
|
|
4419
5309
|
document.head.appendChild(el);
|
|
@@ -4424,6 +5314,7 @@ function Head(props) {
|
|
|
4424
5314
|
for (const linkProps of props.link) {
|
|
4425
5315
|
const el = document.createElement("link");
|
|
4426
5316
|
for (const [key, value] of Object.entries(linkProps)) {
|
|
5317
|
+
if (!isSafeHeadAttr(key)) continue;
|
|
4427
5318
|
el.setAttribute(key, sanitizeHeadAttr(key, value));
|
|
4428
5319
|
}
|
|
4429
5320
|
document.head.appendChild(el);
|
|
@@ -4434,6 +5325,7 @@ function Head(props) {
|
|
|
4434
5325
|
for (const scriptProps of props.script) {
|
|
4435
5326
|
const el = document.createElement("script");
|
|
4436
5327
|
for (const [key, value] of Object.entries(scriptProps)) {
|
|
5328
|
+
if (!isSafeHeadAttr(key)) continue;
|
|
4437
5329
|
el.setAttribute(key, sanitizeHeadAttr(key, value));
|
|
4438
5330
|
}
|
|
4439
5331
|
document.head.appendChild(el);
|
|
@@ -4444,7 +5336,10 @@ function Head(props) {
|
|
|
4444
5336
|
const existing = document.head.querySelector("base");
|
|
4445
5337
|
if (existing) existing.remove();
|
|
4446
5338
|
const el = document.createElement("base");
|
|
4447
|
-
if (props.base.href)
|
|
5339
|
+
if (props.base.href) {
|
|
5340
|
+
const safeHref = sanitizeUrl(props.base.href);
|
|
5341
|
+
if (safeHref) el.href = safeHref;
|
|
5342
|
+
}
|
|
4448
5343
|
if (props.base.target) el.target = props.base.target;
|
|
4449
5344
|
document.head.appendChild(el);
|
|
4450
5345
|
managedElements.push(el);
|
|
@@ -4459,7 +5354,7 @@ function setStructuredData(data2) {
|
|
|
4459
5354
|
const script2 = document.createElement("script");
|
|
4460
5355
|
script2.type = "application/ld+json";
|
|
4461
5356
|
script2.setAttribute("data-sibu", "true");
|
|
4462
|
-
script2.textContent = JSON.stringify(data2);
|
|
5357
|
+
script2.textContent = escapeScriptJsonLocal(JSON.stringify(data2));
|
|
4463
5358
|
document.head.appendChild(script2);
|
|
4464
5359
|
}
|
|
4465
5360
|
function setCanonical(url) {
|
|
@@ -4474,12 +5369,39 @@ function setCanonical(url) {
|
|
|
4474
5369
|
|
|
4475
5370
|
// src/platform/ssr.ts
|
|
4476
5371
|
var _isDev5 = isDev();
|
|
5372
|
+
var SAFE_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
|
|
5373
|
+
function isSafeAttrName(name) {
|
|
5374
|
+
return SAFE_ATTR_NAME.test(name);
|
|
5375
|
+
}
|
|
5376
|
+
function isEventHandlerAttr3(name) {
|
|
5377
|
+
if (name.length < 3) return false;
|
|
5378
|
+
const lower = name.toLowerCase();
|
|
5379
|
+
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
5380
|
+
}
|
|
5381
|
+
var URL_ATTRS = /* @__PURE__ */ new Set([
|
|
5382
|
+
"href",
|
|
5383
|
+
"src",
|
|
5384
|
+
"action",
|
|
5385
|
+
"formaction",
|
|
5386
|
+
"cite",
|
|
5387
|
+
"poster",
|
|
5388
|
+
"background",
|
|
5389
|
+
"srcset",
|
|
5390
|
+
"ping",
|
|
5391
|
+
"manifest",
|
|
5392
|
+
"data",
|
|
5393
|
+
"xlink:href"
|
|
5394
|
+
]);
|
|
4477
5395
|
function ssrErrorComment(err) {
|
|
4478
5396
|
if (_isDev5) {
|
|
4479
|
-
|
|
5397
|
+
const msg = escapeHtml(err instanceof Error ? err.message : String(err));
|
|
5398
|
+
return `<!--SSR error: ${safeCommentText(msg)}-->`;
|
|
4480
5399
|
}
|
|
4481
5400
|
return "<!--SSR error-->";
|
|
4482
5401
|
}
|
|
5402
|
+
function safeCommentText(text2) {
|
|
5403
|
+
return text2.replace(/-->/g, "-->").replace(/--!>/g, "--!>").replace(/<!--/g, "<!--").replace(/--$/g, "---");
|
|
5404
|
+
}
|
|
4483
5405
|
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
4484
5406
|
"area",
|
|
4485
5407
|
"base",
|
|
@@ -4510,16 +5432,30 @@ function renderToString(element) {
|
|
|
4510
5432
|
return escapeHtml(element.textContent || "");
|
|
4511
5433
|
}
|
|
4512
5434
|
if (element.nodeType === 8) {
|
|
4513
|
-
|
|
4514
|
-
return `<!--${content}-->`;
|
|
5435
|
+
return `<!--${safeCommentText(element.textContent || "")}-->`;
|
|
4515
5436
|
}
|
|
4516
5437
|
if (!(element instanceof HTMLElement)) {
|
|
4517
|
-
return element.textContent || "";
|
|
5438
|
+
return escapeHtml(element.textContent || "");
|
|
4518
5439
|
}
|
|
4519
5440
|
const tag = element.tagName.toLowerCase();
|
|
5441
|
+
if (tag === "script" || tag === "style") {
|
|
5442
|
+
return _isDev5 ? `<!--ssr:${tag}-stripped-->` : "";
|
|
5443
|
+
}
|
|
5444
|
+
if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
|
|
5445
|
+
return _isDev5 ? "<!--ssr:invalid-tag-->" : "";
|
|
5446
|
+
}
|
|
4520
5447
|
let html2 = `<${tag}`;
|
|
4521
5448
|
for (const attr of Array.from(element.attributes)) {
|
|
4522
|
-
|
|
5449
|
+
const rawName = attr.name;
|
|
5450
|
+
if (!isSafeAttrName(rawName)) continue;
|
|
5451
|
+
if (isEventHandlerAttr3(rawName)) continue;
|
|
5452
|
+
const lowerName = rawName.toLowerCase();
|
|
5453
|
+
let value = attr.value;
|
|
5454
|
+
if (URL_ATTRS.has(lowerName)) {
|
|
5455
|
+
value = sanitizeUrl(value);
|
|
5456
|
+
if (!value) continue;
|
|
5457
|
+
}
|
|
5458
|
+
html2 += ` ${rawName}="${escapeAttr(value)}"`;
|
|
4523
5459
|
}
|
|
4524
5460
|
if (element.dataset && !element.dataset.sibuHydrate) {
|
|
4525
5461
|
html2 += ` data-sibu-ssr="true"`;
|
|
@@ -4538,8 +5474,25 @@ function renderToString(element) {
|
|
|
4538
5474
|
html2 += `</${tag}>`;
|
|
4539
5475
|
return html2;
|
|
4540
5476
|
}
|
|
4541
|
-
function hydrate(component, container) {
|
|
5477
|
+
function hydrate(component, container, options = {}) {
|
|
4542
5478
|
const clientTree = component();
|
|
5479
|
+
if (options.diagnostics) {
|
|
5480
|
+
const mismatches = [];
|
|
5481
|
+
collectMismatches(container.firstElementChild, clientTree, "", mismatches);
|
|
5482
|
+
if (mismatches.length > 0) {
|
|
5483
|
+
const first = mismatches[0];
|
|
5484
|
+
if (options.onMismatch) {
|
|
5485
|
+
options.onMismatch(first);
|
|
5486
|
+
} else if (_isDev5) {
|
|
5487
|
+
console.warn(
|
|
5488
|
+
`[Sibu hydration] ${first.message}
|
|
5489
|
+
at ${first.path}
|
|
5490
|
+
server: ${first.serverValue}
|
|
5491
|
+
client: ${first.clientValue}`
|
|
5492
|
+
);
|
|
5493
|
+
}
|
|
5494
|
+
}
|
|
5495
|
+
}
|
|
4543
5496
|
hydrateNode(container.firstElementChild, clientTree);
|
|
4544
5497
|
container.setAttribute("data-sibu-hydrated", "true");
|
|
4545
5498
|
}
|
|
@@ -4551,9 +5504,119 @@ function hydrateNode(serverNode, clientNode) {
|
|
|
4551
5504
|
hydrateNode(serverChildren[i2], clientChildren[i2]);
|
|
4552
5505
|
}
|
|
4553
5506
|
}
|
|
5507
|
+
function collectMismatches(serverNode, clientNode, path2, out, max2 = 5) {
|
|
5508
|
+
if (out.length >= max2) return;
|
|
5509
|
+
const nodePath = path2 || clientNode?.tagName?.toLowerCase() || "(root)";
|
|
5510
|
+
if (!serverNode && clientNode) {
|
|
5511
|
+
out.push({
|
|
5512
|
+
kind: "child-count",
|
|
5513
|
+
path: nodePath,
|
|
5514
|
+
serverValue: "(missing)",
|
|
5515
|
+
clientValue: clientNode.tagName.toLowerCase(),
|
|
5516
|
+
message: "Client rendered a node that the server did not emit."
|
|
5517
|
+
});
|
|
5518
|
+
return;
|
|
5519
|
+
}
|
|
5520
|
+
if (serverNode && !clientNode) {
|
|
5521
|
+
out.push({
|
|
5522
|
+
kind: "child-count",
|
|
5523
|
+
path: nodePath,
|
|
5524
|
+
serverValue: serverNode.tagName.toLowerCase(),
|
|
5525
|
+
clientValue: "(missing)",
|
|
5526
|
+
message: "Server rendered a node that the client did not produce."
|
|
5527
|
+
});
|
|
5528
|
+
return;
|
|
5529
|
+
}
|
|
5530
|
+
if (!serverNode || !clientNode) return;
|
|
5531
|
+
if (serverNode.tagName !== clientNode.tagName) {
|
|
5532
|
+
out.push({
|
|
5533
|
+
kind: "tag",
|
|
5534
|
+
path: nodePath,
|
|
5535
|
+
serverValue: serverNode.tagName.toLowerCase(),
|
|
5536
|
+
clientValue: clientNode.tagName.toLowerCase(),
|
|
5537
|
+
message: "Element tag mismatch \u2014 server and client disagree on the element type."
|
|
5538
|
+
});
|
|
5539
|
+
return;
|
|
5540
|
+
}
|
|
5541
|
+
const skipAttrs = /* @__PURE__ */ new Set(["data-sibu-ssr", "data-sibu-hydrated", "data-sibu-island"]);
|
|
5542
|
+
const serverAttrs = /* @__PURE__ */ new Map();
|
|
5543
|
+
for (const a2 of Array.from(serverNode.attributes)) {
|
|
5544
|
+
if (!skipAttrs.has(a2.name)) serverAttrs.set(a2.name, a2.value);
|
|
5545
|
+
}
|
|
5546
|
+
const clientAttrs = /* @__PURE__ */ new Map();
|
|
5547
|
+
for (const a2 of Array.from(clientNode.attributes)) {
|
|
5548
|
+
if (!skipAttrs.has(a2.name)) clientAttrs.set(a2.name, a2.value);
|
|
5549
|
+
}
|
|
5550
|
+
for (const [name, value] of serverAttrs) {
|
|
5551
|
+
if (out.length >= max2) return;
|
|
5552
|
+
if (!clientAttrs.has(name)) {
|
|
5553
|
+
out.push({
|
|
5554
|
+
kind: "attribute",
|
|
5555
|
+
path: `${nodePath}[${name}]`,
|
|
5556
|
+
serverValue: value,
|
|
5557
|
+
clientValue: "(missing)",
|
|
5558
|
+
message: `Attribute "${name}" present on server but missing on client.`
|
|
5559
|
+
});
|
|
5560
|
+
} else if (clientAttrs.get(name) !== value) {
|
|
5561
|
+
out.push({
|
|
5562
|
+
kind: "attribute",
|
|
5563
|
+
path: `${nodePath}[${name}]`,
|
|
5564
|
+
serverValue: value,
|
|
5565
|
+
clientValue: clientAttrs.get(name) ?? "",
|
|
5566
|
+
message: `Attribute "${name}" differs between server and client.`
|
|
5567
|
+
});
|
|
5568
|
+
}
|
|
5569
|
+
}
|
|
5570
|
+
for (const [name, value] of clientAttrs) {
|
|
5571
|
+
if (out.length >= max2) return;
|
|
5572
|
+
if (!serverAttrs.has(name)) {
|
|
5573
|
+
out.push({
|
|
5574
|
+
kind: "attribute",
|
|
5575
|
+
path: `${nodePath}[${name}]`,
|
|
5576
|
+
serverValue: "(missing)",
|
|
5577
|
+
clientValue: value,
|
|
5578
|
+
message: `Attribute "${name}" present on client but missing on server.`
|
|
5579
|
+
});
|
|
5580
|
+
}
|
|
5581
|
+
}
|
|
5582
|
+
const serverChildren = Array.from(serverNode.children);
|
|
5583
|
+
const clientChildren = Array.from(clientNode.children);
|
|
5584
|
+
const max22 = Math.max(serverChildren.length, clientChildren.length);
|
|
5585
|
+
for (let i2 = 0; i2 < max22; i2++) {
|
|
5586
|
+
if (out.length >= max2) return;
|
|
5587
|
+
const childPath = `${nodePath} > ${clientChildren[i2]?.tagName?.toLowerCase() ?? serverChildren[i2]?.tagName?.toLowerCase() ?? "?"}:nth-child(${i2 + 1})`;
|
|
5588
|
+
collectMismatches(serverChildren[i2] ?? null, clientChildren[i2] ?? null, childPath, out, max2);
|
|
5589
|
+
}
|
|
5590
|
+
}
|
|
4554
5591
|
function trustHTML(html2) {
|
|
4555
5592
|
return html2;
|
|
4556
5593
|
}
|
|
5594
|
+
function buildAttrString(attrs, { allowEventHandlers = false } = {}) {
|
|
5595
|
+
if (!attrs) return "";
|
|
5596
|
+
const out = [];
|
|
5597
|
+
for (const rawKey of Object.keys(attrs)) {
|
|
5598
|
+
if (!Object.hasOwn(attrs, rawKey)) continue;
|
|
5599
|
+
if (!isSafeAttrName(rawKey)) continue;
|
|
5600
|
+
if (!allowEventHandlers && isEventHandlerAttr3(rawKey)) continue;
|
|
5601
|
+
const lowerKey = rawKey.toLowerCase();
|
|
5602
|
+
let value = String(attrs[rawKey]);
|
|
5603
|
+
if (URL_ATTRS.has(lowerKey)) {
|
|
5604
|
+
value = sanitizeUrl(value);
|
|
5605
|
+
if (!value) continue;
|
|
5606
|
+
}
|
|
5607
|
+
out.push(`${rawKey}="${escapeAttr(value)}"`);
|
|
5608
|
+
}
|
|
5609
|
+
return out.join(" ");
|
|
5610
|
+
}
|
|
5611
|
+
function isDangerousMetaRefresh2(metaProps) {
|
|
5612
|
+
const httpEquiv = metaProps["http-equiv"];
|
|
5613
|
+
if (typeof httpEquiv !== "string") return false;
|
|
5614
|
+
if (httpEquiv.toLowerCase() !== "refresh") return false;
|
|
5615
|
+
const content = metaProps.content;
|
|
5616
|
+
if (typeof content !== "string") return false;
|
|
5617
|
+
const normalized = content.replace(/[\x00-\x20\x7f-\x9f]+/g, "").toLowerCase();
|
|
5618
|
+
return normalized.includes("url=javascript:") || normalized.includes("url=data:") || normalized.includes("url=vbscript:") || normalized.includes("url=blob:");
|
|
5619
|
+
}
|
|
4557
5620
|
function renderToDocument(component, options = {}) {
|
|
4558
5621
|
let content;
|
|
4559
5622
|
try {
|
|
@@ -4561,14 +5624,22 @@ function renderToDocument(component, options = {}) {
|
|
|
4561
5624
|
} catch (err) {
|
|
4562
5625
|
content = ssrErrorComment(err);
|
|
4563
5626
|
}
|
|
4564
|
-
const metaTags = (options.meta || []).map(
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
).
|
|
4570
|
-
|
|
4571
|
-
|
|
5627
|
+
const metaTags = (options.meta || []).map((attrs) => {
|
|
5628
|
+
if (isDangerousMetaRefresh2(attrs)) return "";
|
|
5629
|
+
const pairs = buildAttrString(attrs);
|
|
5630
|
+
return pairs ? `<meta ${pairs} />` : "";
|
|
5631
|
+
}).filter(Boolean).join("\n ");
|
|
5632
|
+
const linkTags = (options.links || []).map((attrs) => {
|
|
5633
|
+
const pairs = buildAttrString(attrs);
|
|
5634
|
+
return pairs ? `<link ${pairs} />` : "";
|
|
5635
|
+
}).filter(Boolean).join("\n ");
|
|
5636
|
+
const scriptTags = (options.scripts || []).map((src) => {
|
|
5637
|
+
const safe = sanitizeUrl(String(src));
|
|
5638
|
+
if (!safe) return "";
|
|
5639
|
+
return `<script src="${escapeAttr(safe)}"></script>`;
|
|
5640
|
+
}).filter(Boolean).join("\n ");
|
|
5641
|
+
const bodyAttrPairs = buildAttrString(options.bodyAttrs);
|
|
5642
|
+
const bodyAttrs = bodyAttrPairs ? ` ${bodyAttrPairs}` : "";
|
|
4572
5643
|
return `<!DOCTYPE html>
|
|
4573
5644
|
<html>
|
|
4574
5645
|
<head>
|
|
@@ -4601,18 +5672,34 @@ async function* renderToStream(element) {
|
|
|
4601
5672
|
return;
|
|
4602
5673
|
}
|
|
4603
5674
|
if (element.nodeType === 8) {
|
|
4604
|
-
|
|
4605
|
-
yield `<!--${content}-->`;
|
|
5675
|
+
yield `<!--${safeCommentText(element.textContent || "")}-->`;
|
|
4606
5676
|
return;
|
|
4607
5677
|
}
|
|
4608
5678
|
if (!(element instanceof HTMLElement)) {
|
|
4609
|
-
yield element.textContent || "";
|
|
5679
|
+
yield escapeHtml(element.textContent || "");
|
|
4610
5680
|
return;
|
|
4611
5681
|
}
|
|
4612
5682
|
const tag = element.tagName.toLowerCase();
|
|
5683
|
+
if (tag === "script" || tag === "style") {
|
|
5684
|
+
if (_isDev5) yield `<!--ssr:${tag}-stripped-->`;
|
|
5685
|
+
return;
|
|
5686
|
+
}
|
|
5687
|
+
if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
|
|
5688
|
+
if (_isDev5) yield "<!--ssr:invalid-tag-->";
|
|
5689
|
+
return;
|
|
5690
|
+
}
|
|
4613
5691
|
let openTag = `<${tag}`;
|
|
4614
5692
|
for (const attr of Array.from(element.attributes)) {
|
|
4615
|
-
|
|
5693
|
+
const rawName = attr.name;
|
|
5694
|
+
if (!isSafeAttrName(rawName)) continue;
|
|
5695
|
+
if (isEventHandlerAttr3(rawName)) continue;
|
|
5696
|
+
const lowerName = rawName.toLowerCase();
|
|
5697
|
+
let value = attr.value;
|
|
5698
|
+
if (URL_ATTRS.has(lowerName)) {
|
|
5699
|
+
value = sanitizeUrl(value);
|
|
5700
|
+
if (!value) continue;
|
|
5701
|
+
}
|
|
5702
|
+
openTag += ` ${rawName}="${escapeAttr(value)}"`;
|
|
4616
5703
|
}
|
|
4617
5704
|
if (VOID_ELEMENTS.has(tag)) {
|
|
4618
5705
|
yield `${openTag} />`;
|
|
@@ -4660,8 +5747,9 @@ function hydrateIslands(container, islands) {
|
|
|
4660
5747
|
const markers = container.querySelectorAll("[data-sibu-island]");
|
|
4661
5748
|
for (const marker2 of Array.from(markers)) {
|
|
4662
5749
|
const id = marker2.getAttribute("data-sibu-island") ?? "";
|
|
5750
|
+
if (!Object.hasOwn(islands, id)) continue;
|
|
4663
5751
|
const factory = islands[id];
|
|
4664
|
-
if (
|
|
5752
|
+
if (typeof factory !== "function") continue;
|
|
4665
5753
|
const clientTree = factory();
|
|
4666
5754
|
hydrateNode(marker2, clientTree);
|
|
4667
5755
|
marker2.setAttribute("data-sibu-hydrated", "true");
|
|
@@ -4673,8 +5761,9 @@ function hydrateProgressively(container, islands, options) {
|
|
|
4673
5761
|
const cleanups = [];
|
|
4674
5762
|
for (const marker2 of Array.from(markers)) {
|
|
4675
5763
|
const id = marker2.getAttribute("data-sibu-island") ?? "";
|
|
5764
|
+
if (!Object.hasOwn(islands, id)) continue;
|
|
4676
5765
|
const factory = islands[id];
|
|
4677
|
-
if (
|
|
5766
|
+
if (typeof factory !== "function") continue;
|
|
4678
5767
|
const observer = new IntersectionObserver(
|
|
4679
5768
|
(entries) => {
|
|
4680
5769
|
for (const entry of entries) {
|
|
@@ -4713,24 +5802,33 @@ function ssrSuspense(props) {
|
|
|
4713
5802
|
}));
|
|
4714
5803
|
return { element: wrapper, promise };
|
|
4715
5804
|
}
|
|
5805
|
+
var SAFE_SUSPENSE_ID = /^[A-Za-z0-9_-]+$/;
|
|
4716
5806
|
function suspenseSwapScript(id, nonce) {
|
|
4717
|
-
|
|
5807
|
+
if (!SAFE_SUSPENSE_ID.test(id)) {
|
|
5808
|
+
throw new Error(
|
|
5809
|
+
`[SibuJS SSR] suspenseSwapScript: id must match [A-Za-z0-9_-]+ (got: ${JSON.stringify(id.slice(0, 32))})`
|
|
5810
|
+
);
|
|
5811
|
+
}
|
|
4718
5812
|
const nonceAttr = nonce ? ` nonce="${escapeAttr(nonce)}"` : "";
|
|
4719
|
-
return `<script${nonceAttr}>(function(){var t=document.getElementById("sibu-resolved-${
|
|
5813
|
+
return `<script${nonceAttr}>(function(){var t=document.getElementById("sibu-resolved-${id}");var f=document.querySelector('[data-sibu-suspense-id="${id}"]');if(t&&f){while(t.firstChild)f.appendChild(t.firstChild);t.remove();f.removeAttribute("data-sibu-suspense-id");}})()</script>`;
|
|
4720
5814
|
}
|
|
4721
|
-
async function* renderToSuspenseStream(element, pendingBoundaries = []) {
|
|
5815
|
+
async function* renderToSuspenseStream(element, pendingBoundaries = [], options) {
|
|
4722
5816
|
yield* renderToStream(element);
|
|
4723
5817
|
if (pendingBoundaries.length > 0) {
|
|
4724
5818
|
const resolved = await Promise.all(pendingBoundaries);
|
|
4725
5819
|
for (const { id, html: html2 } of resolved) {
|
|
4726
|
-
|
|
4727
|
-
yield
|
|
5820
|
+
if (!SAFE_SUSPENSE_ID.test(id)) continue;
|
|
5821
|
+
yield `<div hidden id="sibu-resolved-${id}">${html2}</div>`;
|
|
5822
|
+
yield suspenseSwapScript(id, options?.nonce);
|
|
4728
5823
|
}
|
|
4729
5824
|
}
|
|
4730
5825
|
}
|
|
4731
5826
|
var SSR_DATA_ATTR = "__SIBU_SSR_DATA__";
|
|
5827
|
+
function escapeScriptJson(json) {
|
|
5828
|
+
return json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
5829
|
+
}
|
|
4732
5830
|
function serializeState(state, nonce) {
|
|
4733
|
-
const json = JSON.stringify(state)
|
|
5831
|
+
const json = escapeScriptJson(JSON.stringify(state));
|
|
4734
5832
|
const nonceAttr = nonce ? ` nonce="${escapeAttr(nonce)}"` : "";
|
|
4735
5833
|
return `<script${nonceAttr}>window.${SSR_DATA_ATTR}=${json}</script>`;
|
|
4736
5834
|
}
|
|
@@ -4745,7 +5843,7 @@ function escapeHtml(str) {
|
|
|
4745
5843
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
4746
5844
|
}
|
|
4747
5845
|
function escapeAttr(str) {
|
|
4748
|
-
return str.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
5846
|
+
return str.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
4749
5847
|
}
|
|
4750
5848
|
|
|
4751
5849
|
// src/platform/customElement.ts
|
|
@@ -5300,16 +6398,20 @@ function appendChildren(el, nodes) {
|
|
|
5300
6398
|
var tagFactory = (tag, ns) => (first, second) => {
|
|
5301
6399
|
const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
|
|
5302
6400
|
if (first === void 0) return el;
|
|
5303
|
-
if (
|
|
6401
|
+
if (typeof first === "string") {
|
|
6402
|
+
if (second !== void 0) {
|
|
6403
|
+
el.setAttribute("class", first);
|
|
6404
|
+
appendChildren(el, second);
|
|
6405
|
+
return el;
|
|
6406
|
+
}
|
|
5304
6407
|
el.textContent = first;
|
|
5305
6408
|
return el;
|
|
5306
6409
|
}
|
|
5307
|
-
if (
|
|
5308
|
-
el.
|
|
5309
|
-
appendChildren(el, second);
|
|
6410
|
+
if (typeof first === "number") {
|
|
6411
|
+
el.textContent = String(first);
|
|
5310
6412
|
return el;
|
|
5311
6413
|
}
|
|
5312
|
-
if (Array.isArray(first) || first instanceof Node) {
|
|
6414
|
+
if (Array.isArray(first) || first instanceof Node || typeof first === "function") {
|
|
5313
6415
|
appendChildren(el, first);
|
|
5314
6416
|
return el;
|
|
5315
6417
|
}
|
|
@@ -5318,7 +6420,7 @@ var tagFactory = (tag, ns) => (first, second) => {
|
|
|
5318
6420
|
if (pClass != null) applyClass(el, pClass);
|
|
5319
6421
|
const pId = props.id;
|
|
5320
6422
|
if (pId != null) el.id = pId;
|
|
5321
|
-
const pNodes = props.nodes;
|
|
6423
|
+
const pNodes = second !== void 0 ? second : props.nodes;
|
|
5322
6424
|
if (pNodes != null) appendChildren(el, pNodes);
|
|
5323
6425
|
const pOn = props.on;
|
|
5324
6426
|
if (pOn) {
|
|
@@ -6095,7 +7197,7 @@ var bundlerMetadata = {
|
|
|
6095
7197
|
sideEffects: false,
|
|
6096
7198
|
modules: {
|
|
6097
7199
|
core: ["html", "mount", "each", "slots", "fragment", "catch", "portal", "directives"],
|
|
6098
|
-
hooks: ["signal", "effect", "derived", "watch", "store", "ref", "
|
|
7200
|
+
hooks: ["signal", "effect", "derived", "watch", "store", "ref", "array", "deepSignal"],
|
|
6099
7201
|
plugins: ["router", "i18n"],
|
|
6100
7202
|
components: ["ErrorBoundary", "Loading"],
|
|
6101
7203
|
ssr: ["ssr"],
|
|
@@ -8619,6 +9721,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8619
9721
|
VirtualList,
|
|
8620
9722
|
accordion,
|
|
8621
9723
|
animate,
|
|
9724
|
+
animationFrame,
|
|
8622
9725
|
announce,
|
|
8623
9726
|
antdAdapter,
|
|
8624
9727
|
aria,
|
|
@@ -8631,6 +9734,8 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8631
9734
|
block,
|
|
8632
9735
|
bounceIn,
|
|
8633
9736
|
bounceOut,
|
|
9737
|
+
bounds,
|
|
9738
|
+
broadcast,
|
|
8634
9739
|
bundlerMetadata,
|
|
8635
9740
|
calculateDelay,
|
|
8636
9741
|
chakraAdapter,
|
|
@@ -8648,7 +9753,6 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8648
9753
|
combobox,
|
|
8649
9754
|
compareSemVer,
|
|
8650
9755
|
componentAdapter,
|
|
8651
|
-
composable,
|
|
8652
9756
|
compose,
|
|
8653
9757
|
composeMiddleware,
|
|
8654
9758
|
conditional,
|
|
@@ -8658,12 +9762,10 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8658
9762
|
createBundle,
|
|
8659
9763
|
createChunkRegistry,
|
|
8660
9764
|
createDevtoolsOverlay,
|
|
8661
|
-
createEffect,
|
|
8662
9765
|
createErrorReporter,
|
|
8663
9766
|
createGuard,
|
|
8664
9767
|
createHMRBoundary,
|
|
8665
9768
|
createISR,
|
|
8666
|
-
createMemo,
|
|
8667
9769
|
createMicroApp,
|
|
8668
9770
|
createMiddlewareChain,
|
|
8669
9771
|
createMigrationRunner,
|
|
@@ -8672,7 +9774,6 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8672
9774
|
createProfiler,
|
|
8673
9775
|
createSSRCache,
|
|
8674
9776
|
createSharedScope,
|
|
8675
|
-
createSignal,
|
|
8676
9777
|
createSlots,
|
|
8677
9778
|
createTestHarness,
|
|
8678
9779
|
createTheme,
|
|
@@ -8704,10 +9805,12 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8704
9805
|
email,
|
|
8705
9806
|
enableDebug,
|
|
8706
9807
|
env,
|
|
9808
|
+
escapeScriptJson,
|
|
8707
9809
|
eventBus,
|
|
8708
9810
|
executeLoader,
|
|
8709
9811
|
fadeIn,
|
|
8710
9812
|
fadeOut,
|
|
9813
|
+
favicon,
|
|
8711
9814
|
fileUpload,
|
|
8712
9815
|
flipIn,
|
|
8713
9816
|
flushScheduler,
|
|
@@ -8716,6 +9819,8 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8716
9819
|
formatCurrency,
|
|
8717
9820
|
formatError,
|
|
8718
9821
|
formatNumber,
|
|
9822
|
+
fullscreen,
|
|
9823
|
+
gamepad,
|
|
8719
9824
|
generateStaticSite,
|
|
8720
9825
|
geo,
|
|
8721
9826
|
getActiveDevTools,
|
|
@@ -8734,6 +9839,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8734
9839
|
hydrateIslands,
|
|
8735
9840
|
hydrateProgressively,
|
|
8736
9841
|
idle,
|
|
9842
|
+
imageLoader,
|
|
8737
9843
|
infiniteQuery,
|
|
8738
9844
|
infiniteScroll,
|
|
8739
9845
|
initDevTools,
|
|
@@ -8746,6 +9852,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8746
9852
|
isHMRAvailable,
|
|
8747
9853
|
isWasmCached,
|
|
8748
9854
|
island,
|
|
9855
|
+
keyboard,
|
|
8749
9856
|
lazyChunk,
|
|
8750
9857
|
lazyLoad,
|
|
8751
9858
|
lazyModule,
|
|
@@ -8762,7 +9869,10 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8762
9869
|
min,
|
|
8763
9870
|
minLength,
|
|
8764
9871
|
mobXAdapter,
|
|
9872
|
+
mouse,
|
|
8765
9873
|
mutation,
|
|
9874
|
+
mutationObserver,
|
|
9875
|
+
network,
|
|
8766
9876
|
noSideEffect,
|
|
8767
9877
|
normalize,
|
|
8768
9878
|
normalizedStore,
|
|
@@ -8779,6 +9889,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8779
9889
|
persisted,
|
|
8780
9890
|
phoneMask,
|
|
8781
9891
|
plugin,
|
|
9892
|
+
pointerLock,
|
|
8782
9893
|
popover,
|
|
8783
9894
|
precompile,
|
|
8784
9895
|
prefetch,
|
|
@@ -8830,6 +9941,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8830
9941
|
slideIn,
|
|
8831
9942
|
slideOut,
|
|
8832
9943
|
socket,
|
|
9944
|
+
speech,
|
|
8833
9945
|
spring,
|
|
8834
9946
|
springSignal,
|
|
8835
9947
|
ssnMask,
|
|
@@ -8841,8 +9953,11 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8841
9953
|
stream,
|
|
8842
9954
|
suspenseSwapScript,
|
|
8843
9955
|
svgElement,
|
|
9956
|
+
svgFavicon,
|
|
9957
|
+
swipe,
|
|
8844
9958
|
syncAdapter,
|
|
8845
9959
|
tabs,
|
|
9960
|
+
textSelection,
|
|
8846
9961
|
throttle,
|
|
8847
9962
|
timeMask,
|
|
8848
9963
|
timeline,
|
|
@@ -8857,11 +9972,16 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
8857
9972
|
triggerPluginUnmount,
|
|
8858
9973
|
trustHTML,
|
|
8859
9974
|
uniqueId,
|
|
9975
|
+
urlState,
|
|
8860
9976
|
validateProps,
|
|
8861
9977
|
validators,
|
|
9978
|
+
vibrate,
|
|
8862
9979
|
viewTransition,
|
|
9980
|
+
visibility,
|
|
9981
|
+
wakeLock,
|
|
8863
9982
|
walkDependencyGraph,
|
|
8864
9983
|
wasm,
|
|
9984
|
+
windowSize,
|
|
8865
9985
|
withBoundary,
|
|
8866
9986
|
withDefaults,
|
|
8867
9987
|
withErrorTracking,
|