@almadar/ui 6.51.2 → 6.53.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/{EntityBindingContext-BbxrwSb9.d.ts → AwaitingSkeletonContext-Bh399p1x.d.ts} +17 -2
- package/dist/{Canvas3DHost-CLC_jXh_.d.ts → Canvas3DHost-B-y2TNij.d.ts} +1 -1
- package/dist/{FileTree-RKQqRhIM.d.ts → FileTree-DUi7e7Z8.d.ts} +5 -5
- package/dist/{GameAudioProvider-BgWLggIy.d.ts → GameAudioProvider-DyBvYP2c.d.ts} +1 -1
- package/dist/{NavStackContext-B-XLULCO.d.ts → NavStackContext-04NLdXsY.d.ts} +8 -0
- package/dist/Typography-JGSDH4JP.js +5 -0
- package/dist/{UISlotContext-DNM8iXna.d.ts → UISlotContext-CS487Uoc.d.ts} +1 -1
- package/dist/{UISlotRenderer-7UYHFW4S.js → UISlotRenderer-JT34I3O7.js} +9 -9
- package/dist/avl/index.cjs +39958 -38525
- package/dist/avl/index.d.ts +8 -5
- package/dist/avl/index.js +37 -26
- package/dist/{chunk-JXUYEO7U.js → chunk-2LFBQ4IS.js} +7 -1
- package/dist/{chunk-GIPZSCND.js → chunk-3EF5SDIJ.js} +31157 -31206
- package/dist/{chunk-GHXWGQTX.js → chunk-4OZDHCZV.js} +1 -1
- package/dist/{chunk-HQDKHLFG.js → chunk-64WACXM7.js} +15 -1
- package/dist/{chunk-FGHRVJCI.js → chunk-6O37FCX4.js} +13 -2
- package/dist/{chunk-BUEIZY54.js → chunk-7LM6I3NA.js} +8 -7
- package/dist/chunk-CBIJP5PL.js +284 -0
- package/dist/{chunk-MWPX2O4M.js → chunk-GMDMOYXD.js} +3 -16
- package/dist/{chunk-YKHNK5JH.js → chunk-GODZKHAL.js} +11 -4
- package/dist/{chunk-T7IH5ABO.js → chunk-IKULQIDX.js} +199 -88
- package/dist/{chunk-NTO555KF.js → chunk-JRW33U35.js} +183 -62
- package/dist/{chunk-OLZ3EEML.js → chunk-KQXXO42S.js} +106 -90
- package/dist/chunk-OKWD7LPO.js +80 -0
- package/dist/{chunk-YHY5K2Y7.js → chunk-PEST66PN.js} +6 -0
- package/dist/{chunk-L55SAFKL.js → chunk-UGHAADU5.js} +77 -1
- package/dist/{chunk-6CFYRP4S.js → chunk-VHTJRS2N.js} +4 -8
- package/dist/{chunk-R4V7IZQP.js → chunk-WPNM2KC6.js} +2 -2
- package/dist/{cn-CO-0rolG.d.ts → cn-ClXGlIOY.d.ts} +2 -2
- package/dist/components/index.cjs +46084 -44766
- package/dist/components/index.d.ts +645 -699
- package/dist/components/index.js +621 -13
- package/dist/context/index.cjs +20 -7
- package/dist/context/index.d.ts +3 -3
- package/dist/context/index.js +3 -3
- package/dist/hooks/index.cjs +126 -9
- package/dist/hooks/index.d.ts +32 -7
- package/dist/hooks/index.js +7 -7
- package/dist/lib/drawable/three/index.cjs +79 -2
- package/dist/lib/drawable/three/index.d.ts +3 -3
- package/dist/lib/drawable/three/index.js +7 -7
- package/dist/lib/index.cjs +116 -2
- package/dist/lib/index.d.ts +29 -6
- package/dist/lib/index.js +6 -5
- package/dist/locales/index.cjs +231 -3
- package/dist/locales/index.js +155 -3
- package/dist/{paintDispatch-CMgOyVjS.d.ts → paintDispatch-_6EhJCiL.d.ts} +6 -6
- package/dist/providers/index.cjs +36404 -35028
- package/dist/providers/index.d.ts +34 -9
- package/dist/providers/index.js +82 -19
- package/dist/renderer/index.cjs +6 -0
- package/dist/renderer/index.d.ts +1 -1
- package/dist/renderer/index.js +1 -1
- package/dist/runtime/index.cjs +37861 -36437
- package/dist/runtime/index.d.ts +6 -4
- package/dist/runtime/index.js +11 -11
- package/dist/ssr/index.cjs +584 -181
- package/dist/ssr/index.d.cts +36 -44
- package/dist/ssr/index.d.ts +36 -44
- package/dist/ssr/index.js +527 -124
- package/dist/{themeTokens-CN9WCXQc.d.ts → themeTokens-Ccu7EmGY.d.ts} +4 -2
- package/dist/{useUISlots-CwUWM1ra.d.ts → useUISlots-1dk2TR4j.d.ts} +1 -9
- package/dist/{verificationRegistry-DBHfOR9y.d.ts → verificationRegistry-CD7Xb40L.d.ts} +1 -1
- package/locales/ar.json +77 -1
- package/locales/en.json +77 -1
- package/locales/sl.json +77 -1
- package/package.json +13 -10
- package/tailwind-preset.cjs +37 -1
- package/themes/_base.css +114 -8
- package/themes/_contract.md +6 -0
- package/themes/almadar-website.css +2 -0
- package/themes/almadar.css +2 -0
- package/themes/aqua.css +5 -3
- package/themes/arabesque.css +9 -7
- package/themes/art-deco.css +5 -3
- package/themes/art-nouveau.css +4 -0
- package/themes/atelier.css +10 -8
- package/themes/bauhaus.css +2 -0
- package/themes/bloomberg-dense.css +13 -11
- package/themes/blueprint.css +2 -0
- package/themes/clay.css +2 -0
- package/themes/comic.css +12 -10
- package/themes/constructivist.css +2 -0
- package/themes/corporate.css +4 -2
- package/themes/cyberpunk.css +2 -0
- package/themes/frutiger-aero.css +2 -0
- package/themes/game-adventure.css +1 -0
- package/themes/game-rpg.css +1 -0
- package/themes/game-sci-fi.css +1 -0
- package/themes/game-ui-pack.css +1 -0
- package/themes/gazette.css +10 -8
- package/themes/glass.css +17 -15
- package/themes/gothic.css +2 -0
- package/themes/ink-wash.css +2 -0
- package/themes/kawaii.css +2 -0
- package/themes/kiosk.css +17 -15
- package/themes/linear-clean.css +12 -10
- package/themes/luxury.css +2 -0
- package/themes/mac-classic.css +2 -0
- package/themes/material.css +2 -0
- package/themes/memphis.css +2 -0
- package/themes/mid-century.css +2 -0
- package/themes/minimalist.css +2 -0
- package/themes/mudcloth.css +2 -0
- package/themes/neon.css +2 -0
- package/themes/neumorphic.css +2 -0
- package/themes/newsprint.css +2 -0
- package/themes/notion-editorial.css +12 -10
- package/themes/pixel.css +2 -0
- package/themes/prism.css +20 -18
- package/themes/retro.css +2 -0
- package/themes/risograph.css +2 -0
- package/themes/scandi.css +2 -0
- package/themes/sketch.css +2 -0
- package/themes/solarpunk.css +2 -0
- package/themes/steampunk.css +2 -0
- package/themes/swiss.css +2 -0
- package/themes/terminal.css +8 -6
- package/themes/trait-wars.css +2 -0
- package/themes/ukiyo-e.css +2 -0
- package/themes/vaporwave.css +2 -0
- package/themes/victorian.css +2 -0
- package/themes/wabi-sabi.css +2 -0
- package/themes/win95.css +2 -0
- package/themes/wireframe.css +2 -0
- package/themes/zine.css +2 -0
- package/dist/Typography-2Z3JKWHN.js +0 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEventBus } from './chunk-6EV3OEBQ.js';
|
|
2
|
-
import { useCallback, useSyncExternalStore, useRef,
|
|
2
|
+
import { createContext, useCallback, useSyncExternalStore, useRef, useState, useContext, useEffect, useMemo } from 'react';
|
|
3
3
|
|
|
4
4
|
function useMediaQuery(query) {
|
|
5
5
|
const subscribe = useCallback(
|
|
@@ -20,6 +20,122 @@ function useMediaQuery(query) {
|
|
|
20
20
|
function hasMatchMedia() {
|
|
21
21
|
return typeof window !== "undefined" && typeof window.matchMedia === "function";
|
|
22
22
|
}
|
|
23
|
+
var counts = /* @__PURE__ */ new Map();
|
|
24
|
+
var keyListeners = /* @__PURE__ */ new Map();
|
|
25
|
+
var seq = 0;
|
|
26
|
+
function notify(key) {
|
|
27
|
+
keyListeners.get(key)?.forEach((cb) => cb());
|
|
28
|
+
}
|
|
29
|
+
function newPendingKey() {
|
|
30
|
+
seq += 1;
|
|
31
|
+
return `pending-${seq}`;
|
|
32
|
+
}
|
|
33
|
+
function beginPending(key) {
|
|
34
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
35
|
+
if (counts.get(key) === 1) notify(key);
|
|
36
|
+
}
|
|
37
|
+
function endPending(key) {
|
|
38
|
+
const n = (counts.get(key) ?? 0) - 1;
|
|
39
|
+
if (n > 0) {
|
|
40
|
+
counts.set(key, n);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
counts.delete(key);
|
|
44
|
+
notify(key);
|
|
45
|
+
}
|
|
46
|
+
function isPending(key) {
|
|
47
|
+
return (counts.get(key) ?? 0) > 0;
|
|
48
|
+
}
|
|
49
|
+
function subscribePending(key, cb) {
|
|
50
|
+
let set = keyListeners.get(key);
|
|
51
|
+
if (!set) {
|
|
52
|
+
set = /* @__PURE__ */ new Set();
|
|
53
|
+
keyListeners.set(key, set);
|
|
54
|
+
}
|
|
55
|
+
set.add(cb);
|
|
56
|
+
return () => {
|
|
57
|
+
set?.delete(cb);
|
|
58
|
+
if (set && set.size === 0) keyListeners.delete(key);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
var PendingScopeContext = createContext(null);
|
|
62
|
+
function usePendingScopeValue() {
|
|
63
|
+
const keys = useRef(/* @__PURE__ */ new Set());
|
|
64
|
+
const listeners = useRef(/* @__PURE__ */ new Set());
|
|
65
|
+
const emitChange = useCallback(() => listeners.current.forEach((cb) => cb()), []);
|
|
66
|
+
return useState(() => ({
|
|
67
|
+
track: (key) => {
|
|
68
|
+
if (!isPending(key)) return;
|
|
69
|
+
keys.current.add(key);
|
|
70
|
+
emitChange();
|
|
71
|
+
const unsub = subscribePending(key, () => {
|
|
72
|
+
if (isPending(key)) return;
|
|
73
|
+
keys.current.delete(key);
|
|
74
|
+
unsub();
|
|
75
|
+
emitChange();
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
hasPending: () => keys.current.size > 0,
|
|
79
|
+
subscribe: (cb) => {
|
|
80
|
+
listeners.current.add(cb);
|
|
81
|
+
return () => listeners.current.delete(cb);
|
|
82
|
+
}
|
|
83
|
+
}))[0];
|
|
84
|
+
}
|
|
85
|
+
function useScopeHasPending(scope) {
|
|
86
|
+
return useSyncExternalStore(
|
|
87
|
+
useCallback((cb) => scope ? scope.subscribe(cb) : () => {
|
|
88
|
+
}, [scope]),
|
|
89
|
+
() => scope ? scope.hasPending() : false,
|
|
90
|
+
() => false
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
function usePendingAction() {
|
|
94
|
+
const scope = useContext(PendingScopeContext);
|
|
95
|
+
const [key, setKey] = useState(null);
|
|
96
|
+
const pending = useSyncExternalStore(
|
|
97
|
+
useCallback((cb) => key ? subscribePending(key, cb) : () => {
|
|
98
|
+
}, [key]),
|
|
99
|
+
() => key ? isPending(key) : false,
|
|
100
|
+
() => false
|
|
101
|
+
);
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
if (key && !pending) setKey(null);
|
|
104
|
+
}, [key, pending]);
|
|
105
|
+
const activate = useCallback((emit) => {
|
|
106
|
+
const k = newPendingKey();
|
|
107
|
+
emit(k);
|
|
108
|
+
if (!isPending(k)) return;
|
|
109
|
+
scope?.track(k);
|
|
110
|
+
setKey(k);
|
|
111
|
+
}, [scope]);
|
|
112
|
+
return { pending, activate };
|
|
113
|
+
}
|
|
114
|
+
function usePendingRows() {
|
|
115
|
+
const [rows, setRows] = useState(/* @__PURE__ */ new Map());
|
|
116
|
+
const unsubs = useRef(/* @__PURE__ */ new Map());
|
|
117
|
+
useEffect(() => () => unsubs.current.forEach((u) => u()), []);
|
|
118
|
+
const activateRow = useCallback((rowId, emit) => {
|
|
119
|
+
const k = newPendingKey();
|
|
120
|
+
emit(k);
|
|
121
|
+
if (!isPending(k)) return;
|
|
122
|
+
setRows((prev) => new Map(prev).set(rowId, k));
|
|
123
|
+
unsubs.current.get(rowId)?.();
|
|
124
|
+
unsubs.current.set(rowId, subscribePending(k, () => {
|
|
125
|
+
if (isPending(k)) return;
|
|
126
|
+
unsubs.current.get(rowId)?.();
|
|
127
|
+
unsubs.current.delete(rowId);
|
|
128
|
+
setRows((prev) => {
|
|
129
|
+
if (prev.get(rowId) !== k) return prev;
|
|
130
|
+
const next = new Map(prev);
|
|
131
|
+
next.delete(rowId);
|
|
132
|
+
return next;
|
|
133
|
+
});
|
|
134
|
+
}));
|
|
135
|
+
}, []);
|
|
136
|
+
const isRowPending = useCallback((rowId) => rows.has(rowId), [rows]);
|
|
137
|
+
return { isRowPending, activateRow };
|
|
138
|
+
}
|
|
23
139
|
function useInfiniteScroll(onLoadMore, options = {}) {
|
|
24
140
|
const { rootMargin = "200px", hasMore = true, isLoading = false } = options;
|
|
25
141
|
const observerRef = useRef(null);
|
|
@@ -50,6 +166,11 @@ function useInfiniteScroll(onLoadMore, options = {}) {
|
|
|
50
166
|
}, [rootMargin]);
|
|
51
167
|
return { sentinelRef };
|
|
52
168
|
}
|
|
169
|
+
|
|
170
|
+
// hooks/usePrefersReducedMotion.ts
|
|
171
|
+
function usePrefersReducedMotion() {
|
|
172
|
+
return useMediaQuery("(prefers-reduced-motion: reduce)");
|
|
173
|
+
}
|
|
53
174
|
function useSwipeGesture(callbacks, options = {}) {
|
|
54
175
|
const { threshold = 50, velocityThreshold = 0.3, preventDefault = false } = options;
|
|
55
176
|
const startX = useRef(0);
|
|
@@ -428,6 +549,66 @@ function parseQueryBinding(binding) {
|
|
|
428
549
|
field: parts.length > 1 ? parts.slice(1).join(".") : void 0
|
|
429
550
|
};
|
|
430
551
|
}
|
|
552
|
+
function usePullToRefresh(onRefresh, options = {}) {
|
|
553
|
+
const { threshold = 60, maxPull = 120 } = options;
|
|
554
|
+
const [pullDistance, setPullDistance] = useState(0);
|
|
555
|
+
const [isPulling, setIsPulling] = useState(false);
|
|
556
|
+
const [isRefreshing, setIsRefreshing] = useState(false);
|
|
557
|
+
const startY = useRef(0);
|
|
558
|
+
const scrollTopRef = useRef(0);
|
|
559
|
+
const onTouchStart = useCallback((e) => {
|
|
560
|
+
const container = e.currentTarget;
|
|
561
|
+
scrollTopRef.current = container.scrollTop;
|
|
562
|
+
if (scrollTopRef.current <= 0) {
|
|
563
|
+
startY.current = e.touches[0].clientY;
|
|
564
|
+
setIsPulling(true);
|
|
565
|
+
}
|
|
566
|
+
}, []);
|
|
567
|
+
const onTouchMove = useCallback((e) => {
|
|
568
|
+
if (!isPulling || isRefreshing) return;
|
|
569
|
+
const container = e.currentTarget;
|
|
570
|
+
if (container.scrollTop > 0) {
|
|
571
|
+
setPullDistance(0);
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
const dy = e.touches[0].clientY - startY.current;
|
|
575
|
+
if (dy > 0) {
|
|
576
|
+
const distance = Math.min(dy * 0.5, maxPull);
|
|
577
|
+
setPullDistance(distance);
|
|
578
|
+
}
|
|
579
|
+
}, [isPulling, isRefreshing, maxPull]);
|
|
580
|
+
const onTouchEnd = useCallback(() => {
|
|
581
|
+
if (!isPulling) return;
|
|
582
|
+
setIsPulling(false);
|
|
583
|
+
if (pullDistance >= threshold && !isRefreshing) {
|
|
584
|
+
setIsRefreshing(true);
|
|
585
|
+
setPullDistance(threshold);
|
|
586
|
+
onRefresh();
|
|
587
|
+
} else {
|
|
588
|
+
setPullDistance(0);
|
|
589
|
+
}
|
|
590
|
+
}, [isPulling, pullDistance, threshold, isRefreshing, onRefresh]);
|
|
591
|
+
const endRefresh = useCallback(() => {
|
|
592
|
+
setIsRefreshing(false);
|
|
593
|
+
setPullDistance(0);
|
|
594
|
+
}, []);
|
|
595
|
+
const containerProps = {
|
|
596
|
+
onTouchStart,
|
|
597
|
+
onTouchMove,
|
|
598
|
+
onTouchEnd,
|
|
599
|
+
style: {
|
|
600
|
+
transform: pullDistance > 0 ? `translateY(${pullDistance}px)` : void 0,
|
|
601
|
+
transition: isPulling ? "none" : "transform 300ms ease-out"
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
return {
|
|
605
|
+
pullDistance,
|
|
606
|
+
isPulling,
|
|
607
|
+
isRefreshing,
|
|
608
|
+
containerProps,
|
|
609
|
+
endRefresh
|
|
610
|
+
};
|
|
611
|
+
}
|
|
431
612
|
function useDragReorder(initialItems, onReorder) {
|
|
432
613
|
const [items, setItems] = useState(initialItems);
|
|
433
614
|
const [dragIndex, setDragIndex] = useState(-1);
|
|
@@ -496,65 +677,5 @@ function useDragReorder(initialItems, onReorder) {
|
|
|
496
677
|
getItemProps
|
|
497
678
|
};
|
|
498
679
|
}
|
|
499
|
-
function usePullToRefresh(onRefresh, options = {}) {
|
|
500
|
-
const { threshold = 60, maxPull = 120 } = options;
|
|
501
|
-
const [pullDistance, setPullDistance] = useState(0);
|
|
502
|
-
const [isPulling, setIsPulling] = useState(false);
|
|
503
|
-
const [isRefreshing, setIsRefreshing] = useState(false);
|
|
504
|
-
const startY = useRef(0);
|
|
505
|
-
const scrollTopRef = useRef(0);
|
|
506
|
-
const onTouchStart = useCallback((e) => {
|
|
507
|
-
const container = e.currentTarget;
|
|
508
|
-
scrollTopRef.current = container.scrollTop;
|
|
509
|
-
if (scrollTopRef.current <= 0) {
|
|
510
|
-
startY.current = e.touches[0].clientY;
|
|
511
|
-
setIsPulling(true);
|
|
512
|
-
}
|
|
513
|
-
}, []);
|
|
514
|
-
const onTouchMove = useCallback((e) => {
|
|
515
|
-
if (!isPulling || isRefreshing) return;
|
|
516
|
-
const container = e.currentTarget;
|
|
517
|
-
if (container.scrollTop > 0) {
|
|
518
|
-
setPullDistance(0);
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
const dy = e.touches[0].clientY - startY.current;
|
|
522
|
-
if (dy > 0) {
|
|
523
|
-
const distance = Math.min(dy * 0.5, maxPull);
|
|
524
|
-
setPullDistance(distance);
|
|
525
|
-
}
|
|
526
|
-
}, [isPulling, isRefreshing, maxPull]);
|
|
527
|
-
const onTouchEnd = useCallback(() => {
|
|
528
|
-
if (!isPulling) return;
|
|
529
|
-
setIsPulling(false);
|
|
530
|
-
if (pullDistance >= threshold && !isRefreshing) {
|
|
531
|
-
setIsRefreshing(true);
|
|
532
|
-
setPullDistance(threshold);
|
|
533
|
-
onRefresh();
|
|
534
|
-
} else {
|
|
535
|
-
setPullDistance(0);
|
|
536
|
-
}
|
|
537
|
-
}, [isPulling, pullDistance, threshold, isRefreshing, onRefresh]);
|
|
538
|
-
const endRefresh = useCallback(() => {
|
|
539
|
-
setIsRefreshing(false);
|
|
540
|
-
setPullDistance(0);
|
|
541
|
-
}, []);
|
|
542
|
-
const containerProps = {
|
|
543
|
-
onTouchStart,
|
|
544
|
-
onTouchMove,
|
|
545
|
-
onTouchEnd,
|
|
546
|
-
style: {
|
|
547
|
-
transform: pullDistance > 0 ? `translateY(${pullDistance}px)` : void 0,
|
|
548
|
-
transition: isPulling ? "none" : "transform 300ms ease-out"
|
|
549
|
-
}
|
|
550
|
-
};
|
|
551
|
-
return {
|
|
552
|
-
pullDistance,
|
|
553
|
-
isPulling,
|
|
554
|
-
isRefreshing,
|
|
555
|
-
containerProps,
|
|
556
|
-
endRefresh
|
|
557
|
-
};
|
|
558
|
-
}
|
|
559
680
|
|
|
560
|
-
export { ALMADAR_DND_MIME, parseQueryBinding, useAuthContext, useCanvasGestures, useDragReorder, useDraggable, useDropZone, useInfiniteScroll, useLongPress, useMediaQuery, usePullToRefresh, useQuerySingleton, useSwipeGesture };
|
|
681
|
+
export { ALMADAR_DND_MIME, PendingScopeContext, beginPending, endPending, parseQueryBinding, useAuthContext, useCanvasGestures, useDragReorder, useDraggable, useDropZone, useInfiniteScroll, useLongPress, useMediaQuery, usePendingAction, usePendingRows, usePendingScopeValue, usePrefersReducedMotion, usePullToRefresh, useQuerySingleton, useScopeHasPending, useSwipeGesture };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { domPassthrough, cn } from './chunk-64WACXM7.js';
|
|
2
|
+
import { useState, useRef, useCallback, useLayoutEffect, useEffect, useSyncExternalStore } from 'react';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { ENTER_DELAY_STEPS, ENTER_ANIMATIONS, isFileValue } from '@almadar/core';
|
|
5
|
+
export { getNestedValue } from '@almadar/core';
|
|
2
6
|
import { perfStore, pushPerfEntry } from '@almadar/runtime/ui';
|
|
3
7
|
export { PERF_NAMESPACE, clearPerf, perfEnd, perfGauge, perfStart, perfTime, perfTimeAsync } from '@almadar/runtime/ui';
|
|
4
|
-
import { isFileValue } from '@almadar/core';
|
|
5
|
-
export { getNestedValue } from '@almadar/core';
|
|
6
8
|
import { createLogger, isLogLevelEnabled } from '@almadar/logger';
|
|
7
9
|
|
|
8
10
|
// lib/jazari/svg-paths.ts
|
|
@@ -85,17 +87,97 @@ function eightPointedStarPath(cx, cy, outerR, innerR) {
|
|
|
85
87
|
function arrowheadPath(size) {
|
|
86
88
|
return `M 0 0 L ${size} ${size / 2} L 0 ${size} Z`;
|
|
87
89
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
var SAFE_EXIT_MS = 1e3;
|
|
91
|
+
var motionEnabledCache = null;
|
|
92
|
+
function isMotionEnabled() {
|
|
93
|
+
if (typeof document === "undefined") return true;
|
|
94
|
+
if (motionEnabledCache !== null) return motionEnabledCache;
|
|
95
|
+
const v = getComputedStyle(document.documentElement).getPropertyValue("--motion-enable").trim().toLowerCase();
|
|
96
|
+
motionEnabledCache = v !== "off";
|
|
97
|
+
return motionEnabledCache;
|
|
98
|
+
}
|
|
99
|
+
function usePresence(show, opts) {
|
|
100
|
+
const { animation, animate = true, onExited } = opts;
|
|
101
|
+
const [mounted, setMounted] = useState(show);
|
|
102
|
+
const [exiting, setExiting] = useState(false);
|
|
103
|
+
const prev = useRef(show);
|
|
104
|
+
const onExitedRef = useRef(onExited);
|
|
105
|
+
onExitedRef.current = onExited;
|
|
106
|
+
const safeTimer = useRef(null);
|
|
107
|
+
const clearSafe = useCallback(() => {
|
|
108
|
+
if (safeTimer.current) {
|
|
109
|
+
clearTimeout(safeTimer.current);
|
|
110
|
+
safeTimer.current = null;
|
|
111
|
+
}
|
|
112
|
+
}, []);
|
|
113
|
+
const finishExit = useCallback(() => {
|
|
114
|
+
clearSafe();
|
|
115
|
+
setExiting(false);
|
|
116
|
+
setMounted(false);
|
|
117
|
+
onExitedRef.current?.();
|
|
118
|
+
}, [clearSafe]);
|
|
119
|
+
useLayoutEffect(() => {
|
|
120
|
+
const moving = animate && isMotionEnabled();
|
|
121
|
+
if (show && !prev.current) {
|
|
122
|
+
setExiting(false);
|
|
123
|
+
setMounted(true);
|
|
124
|
+
} else if (!show && prev.current) {
|
|
125
|
+
if (moving) {
|
|
126
|
+
setExiting(true);
|
|
127
|
+
clearSafe();
|
|
128
|
+
safeTimer.current = setTimeout(finishExit, SAFE_EXIT_MS);
|
|
129
|
+
} else {
|
|
130
|
+
setMounted(false);
|
|
131
|
+
setExiting(false);
|
|
132
|
+
onExitedRef.current?.();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
prev.current = show;
|
|
136
|
+
}, [show, animate, clearSafe, finishExit]);
|
|
137
|
+
useEffect(() => () => clearSafe(), [clearSafe]);
|
|
138
|
+
const disabled = !animate || !isMotionEnabled();
|
|
139
|
+
const className = disabled ? "" : show ? `animate-${animation}-in` : `animate-${animation}-out`;
|
|
140
|
+
const onAnimationEnd = useCallback(
|
|
141
|
+
(e) => {
|
|
142
|
+
if (e.target !== e.currentTarget) return;
|
|
143
|
+
if (exiting) finishExit();
|
|
144
|
+
},
|
|
145
|
+
[exiting, finishExit]
|
|
146
|
+
);
|
|
147
|
+
return { mounted, exiting, className, onAnimationEnd };
|
|
90
148
|
}
|
|
91
|
-
var
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
ts: commitTime,
|
|
96
|
-
detail: { baseDuration }
|
|
97
|
-
});
|
|
149
|
+
var Presence = ({ show, className, children, ...rest }) => {
|
|
150
|
+
const { mounted, className: animClass, onAnimationEnd } = usePresence(show, rest);
|
|
151
|
+
if (!mounted) return null;
|
|
152
|
+
return /* @__PURE__ */ jsx("div", { className: cn(animClass, className), onAnimationEnd, ...domPassthrough(rest), children });
|
|
98
153
|
};
|
|
154
|
+
Presence.displayName = "Presence";
|
|
155
|
+
var ENTER_SLOT_CLASS = "almadar-enter-slot";
|
|
156
|
+
function asEnterAnimation(value) {
|
|
157
|
+
return ENTER_ANIMATIONS.find((e) => e === value);
|
|
158
|
+
}
|
|
159
|
+
var MAX_ENTER_DELAY = ENTER_DELAY_STEPS.length;
|
|
160
|
+
function enterClassName(enter, enterDelay) {
|
|
161
|
+
if (enter === void 0 || enter === "none" || !isMotionEnabled()) return void 0;
|
|
162
|
+
const base = `almadar-enter-${enter}`;
|
|
163
|
+
if (enterDelay === void 0 || !Number.isInteger(enterDelay) || enterDelay < 1 || enterDelay > MAX_ENTER_DELAY) return base;
|
|
164
|
+
return `${base} almadar-enter-delay-${enterDelay}`;
|
|
165
|
+
}
|
|
166
|
+
function slotPlaysDefaultEnter(rootEnter) {
|
|
167
|
+
return rootEnter === void 0 && isMotionEnabled();
|
|
168
|
+
}
|
|
169
|
+
function useSlotEnterRestart(ref, contentKey, active) {
|
|
170
|
+
const lastKey = useRef(contentKey);
|
|
171
|
+
useLayoutEffect(() => {
|
|
172
|
+
if (lastKey.current === contentKey) return;
|
|
173
|
+
lastKey.current = contentKey;
|
|
174
|
+
const el = ref.current;
|
|
175
|
+
if (!el || !active) return;
|
|
176
|
+
el.classList.remove(ENTER_SLOT_CLASS);
|
|
177
|
+
void el.offsetWidth;
|
|
178
|
+
el.classList.add(ENTER_SLOT_CLASS);
|
|
179
|
+
}, [contentKey, active, ref]);
|
|
180
|
+
}
|
|
99
181
|
|
|
100
182
|
// lib/editorMotions.ts
|
|
101
183
|
var EDITOR_MOTIONS = [
|
|
@@ -579,6 +661,17 @@ function middleSnake(a, aLo, aHi, b, bLo, bHi) {
|
|
|
579
661
|
}
|
|
580
662
|
throw new Error("computeLineDiff: no middle snake \u2014 unreachable for differing texts");
|
|
581
663
|
}
|
|
664
|
+
function usePerfBuffer() {
|
|
665
|
+
return useSyncExternalStore(perfStore.subscribe, perfStore.getSnapshot, perfStore.getSnapshot);
|
|
666
|
+
}
|
|
667
|
+
var profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, commitTime) => {
|
|
668
|
+
pushPerfEntry({
|
|
669
|
+
name: `profiler:${id}:${phase}`,
|
|
670
|
+
durationMs: actualDuration,
|
|
671
|
+
ts: commitTime,
|
|
672
|
+
detail: { baseDuration }
|
|
673
|
+
});
|
|
674
|
+
};
|
|
582
675
|
|
|
583
676
|
// lib/lessonSegmentUtils.ts
|
|
584
677
|
function parseMarkdownWithCodeBlocks(content) {
|
|
@@ -766,83 +859,6 @@ function toLogMetaValue(v) {
|
|
|
766
859
|
return String(v);
|
|
767
860
|
}
|
|
768
861
|
|
|
769
|
-
// lib/parseLessonSegments.ts
|
|
770
|
-
function extractTagContent(content, tagName) {
|
|
771
|
-
const closedTagRegex = new RegExp(`<${tagName}>([\\s\\S]*?)<\\/${tagName}>`, "i");
|
|
772
|
-
const closedMatch = content.match(closedTagRegex);
|
|
773
|
-
if (closedMatch) {
|
|
774
|
-
return { content: closedMatch[1].trim(), fullMatch: closedMatch[0] };
|
|
775
|
-
}
|
|
776
|
-
const unclosedTagRegex = new RegExp(
|
|
777
|
-
`<${tagName}>([\\s\\S]*?)(?=<(?:activate|connect|reflect|bloom|prq|question|answer|visualize)|\\n\\n#|$)`,
|
|
778
|
-
"i"
|
|
779
|
-
);
|
|
780
|
-
const unclosedMatch = content.match(unclosedTagRegex);
|
|
781
|
-
if (unclosedMatch) {
|
|
782
|
-
return { content: unclosedMatch[1].trim(), fullMatch: unclosedMatch[0] };
|
|
783
|
-
}
|
|
784
|
-
return null;
|
|
785
|
-
}
|
|
786
|
-
function parseLessonSegments(lesson) {
|
|
787
|
-
if (!lesson) return [];
|
|
788
|
-
let content = lesson.replace(/<prq>[\s\S]*?<\/prq>/gi, "").trim();
|
|
789
|
-
const segments = [];
|
|
790
|
-
const activateResult = extractTagContent(content, "activate");
|
|
791
|
-
if (activateResult) {
|
|
792
|
-
segments.push({ type: "activate", question: activateResult.content });
|
|
793
|
-
content = content.replace(activateResult.fullMatch, "").trim();
|
|
794
|
-
}
|
|
795
|
-
const connectResult = extractTagContent(content, "connect");
|
|
796
|
-
if (connectResult) {
|
|
797
|
-
segments.push({ type: "connect", content: connectResult.content });
|
|
798
|
-
content = content.replace(connectResult.fullMatch, "").trim();
|
|
799
|
-
}
|
|
800
|
-
const tagRegex = new RegExp(
|
|
801
|
-
'(?<reflect><reflect>(?<reflectClosed>[\\s\\S]*?)<\\/reflect>)|(?<reflectUnclosed><reflect>(?<reflectOpen>[\\s\\S]*?)(?=<(?:activate|connect|reflect|bloom|prq|question|answer|visualize)|\\n\\n#|$))|(?<bloom><bloom\\s+level="(?<bloomLevel>remember|understand|apply|analyze|evaluate|create)">(?<bloomClosed>[\\s\\S]*?)<\\/bloom>)|(?<bloomUnclosed><bloom\\s+level="(?<bloomLevelUn>remember|understand|apply|analyze|evaluate|create)">(?<bloomOpen>[\\s\\S]*?)(?=<(?:activate|connect|reflect|bloom|prq|question|answer|visualize)|\\n\\n#|$))|(?<quiz><question>(?<quizQuestion>[\\s\\S]*?)<\\/question>\\s*<answer>(?<quizAnswer>[\\s\\S]*?)<\\/answer>)|(?<visualize><visualize\\s+type="(?<vizType>algorithms|math|physics|biology|chemistry|probability)"\\s+description="(?<vizDesc>[^"]*?)"\\s*\\/?>)',
|
|
802
|
-
"gi"
|
|
803
|
-
);
|
|
804
|
-
let lastIndex = 0;
|
|
805
|
-
let match;
|
|
806
|
-
while ((match = tagRegex.exec(content)) !== null) {
|
|
807
|
-
const before = content.slice(lastIndex, match.index);
|
|
808
|
-
if (before.trim()) {
|
|
809
|
-
segments.push(...parseMarkdownWithCodeBlocks(before));
|
|
810
|
-
}
|
|
811
|
-
const g = match.groups ?? {};
|
|
812
|
-
if (g.reflect || g.reflectUnclosed) {
|
|
813
|
-
const prompt = (g.reflectClosed ?? g.reflectOpen ?? "").trim();
|
|
814
|
-
if (prompt) segments.push({ type: "reflect", prompt });
|
|
815
|
-
} else if (g.bloom || g.bloomUnclosed) {
|
|
816
|
-
const level = g.bloomLevel ?? g.bloomLevelUn;
|
|
817
|
-
const bloomContent = g.bloomClosed ?? g.bloomOpen ?? "";
|
|
818
|
-
if (level && bloomContent) {
|
|
819
|
-
const qMatch = bloomContent.match(/<question>([\s\S]*?)<\/question>/i);
|
|
820
|
-
const aMatch = bloomContent.match(/<answer>([\s\S]*?)<\/answer>/i);
|
|
821
|
-
if (qMatch && aMatch) {
|
|
822
|
-
segments.push({ type: "bloom", level, question: qMatch[1].trim(), answer: aMatch[1].trim() });
|
|
823
|
-
} else if (qMatch) {
|
|
824
|
-
segments.push({ type: "bloom", level, question: qMatch[1].trim(), answer: "(Answer not provided)" });
|
|
825
|
-
} else {
|
|
826
|
-
const clean = bloomContent.replace(/^\*\*Question\s*\d*:?\*\*\s*/i, "").replace(/^\*\*Q\d*:?\*\*\s*/i, "").trim();
|
|
827
|
-
if (clean) segments.push({ type: "bloom", level, question: clean, answer: "(See answers section below)" });
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
} else if (g.quiz) {
|
|
831
|
-
segments.push({ type: "quiz", question: g.quizQuestion.trim(), answer: g.quizAnswer.trim() });
|
|
832
|
-
} else if (g.visualize) {
|
|
833
|
-
segments.push({
|
|
834
|
-
type: "visualization",
|
|
835
|
-
visualizationType: g.vizType,
|
|
836
|
-
description: g.vizDesc ?? ""
|
|
837
|
-
});
|
|
838
|
-
}
|
|
839
|
-
lastIndex = tagRegex.lastIndex;
|
|
840
|
-
}
|
|
841
|
-
const remaining = content.slice(lastIndex);
|
|
842
|
-
if (remaining.trim()) segments.push(...parseMarkdownWithCodeBlocks(remaining));
|
|
843
|
-
return segments;
|
|
844
|
-
}
|
|
845
|
-
|
|
846
862
|
// lib/traitRegistry.ts
|
|
847
863
|
var traits = /* @__PURE__ */ new Map();
|
|
848
864
|
var listeners = /* @__PURE__ */ new Set();
|
|
@@ -1102,4 +1118,4 @@ function initDebugShortcut() {
|
|
|
1102
1118
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
1103
1119
|
}
|
|
1104
1120
|
|
|
1105
|
-
export { EDITOR_MOTIONS, EDITOR_OPERATORS, INDENT_UNIT, applyMotion, applyOperator, arrowheadPath, brainIconPath, clearDebugEvents, clearEntityProvider, clearGuardHistory, clearTicks, clearTraits, computeLineDiff, debug, debugCollision, debugError, debugGameState, debugGroup, debugGroupEnd, debugInput, debugPhysics, debugTable, debugTime, debugTimeEnd, debugWarn, eightPointedStarPath, gearTeethPath, getAllTicks, getAllTraits, getDebugEvents, getEntitiesByType, getEntityById, getEntitySnapshot, getEventsBySource, getEventsByType, getGuardEvaluationsForTrait, getGuardHistory, getRecentEvents, getRecentGuardEvaluations, getTick, getTrait, initDebugShortcut, isDebugEnabled, isDebugEnabled2, isEditorMotion, isEditorOperator, lockIconPath, logDebugEvent, logEffectExecuted, logError, logEventFired, logInfo, logStateChange, logWarning, motionRange, onDebugToggle, parseContentSegments,
|
|
1121
|
+
export { EDITOR_MOTIONS, EDITOR_OPERATORS, ENTER_SLOT_CLASS, INDENT_UNIT, MAX_ENTER_DELAY, Presence, applyMotion, applyOperator, arrowheadPath, asEnterAnimation, brainIconPath, clearDebugEvents, clearEntityProvider, clearGuardHistory, clearTicks, clearTraits, computeLineDiff, debug, debugCollision, debugError, debugGameState, debugGroup, debugGroupEnd, debugInput, debugPhysics, debugTable, debugTime, debugTimeEnd, debugWarn, eightPointedStarPath, enterClassName, gearTeethPath, getAllTicks, getAllTraits, getDebugEvents, getEntitiesByType, getEntityById, getEntitySnapshot, getEventsBySource, getEventsByType, getGuardEvaluationsForTrait, getGuardHistory, getRecentEvents, getRecentGuardEvaluations, getTick, getTrait, initDebugShortcut, isDebugEnabled, isDebugEnabled2, isEditorMotion, isEditorOperator, isMotionEnabled, lockIconPath, logDebugEvent, logEffectExecuted, logError, logEventFired, logInfo, logStateChange, logWarning, motionRange, onDebugToggle, parseContentSegments, parseMarkdownWithCodeBlocks, parseMarkdownWithCodeBlocks2, pipeIconPath, profilerOnRender, recordGuardEvaluation, registerTick, registerTrait, resolveImageUrl, setDebugEnabled, setEntityProvider, setTickActive, slotPlaysDefaultEnter, subscribeToDebugEvents, subscribeToGuardChanges, subscribeToTickChanges, subscribeToTraitChanges, toggleDebug, unregisterTick, unregisterTrait, updateGuardResult, updateTickExecution, updateTraitState, usePerfBuffer, usePresence, useSlotEnterRestart };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { parseMarkdownWithCodeBlocks } from './chunk-KQXXO42S.js';
|
|
2
|
+
|
|
3
|
+
// lib/parseLessonSegments.ts
|
|
4
|
+
function extractTagContent(content, tagName) {
|
|
5
|
+
const closedTagRegex = new RegExp(`<${tagName}>([\\s\\S]*?)<\\/${tagName}>`, "i");
|
|
6
|
+
const closedMatch = content.match(closedTagRegex);
|
|
7
|
+
if (closedMatch) {
|
|
8
|
+
return { content: closedMatch[1].trim(), fullMatch: closedMatch[0] };
|
|
9
|
+
}
|
|
10
|
+
const unclosedTagRegex = new RegExp(
|
|
11
|
+
`<${tagName}>([\\s\\S]*?)(?=<(?:activate|connect|reflect|bloom|prq|question|answer|visualize)|\\n\\n#|$)`,
|
|
12
|
+
"i"
|
|
13
|
+
);
|
|
14
|
+
const unclosedMatch = content.match(unclosedTagRegex);
|
|
15
|
+
if (unclosedMatch) {
|
|
16
|
+
return { content: unclosedMatch[1].trim(), fullMatch: unclosedMatch[0] };
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
function parseLessonSegments(lesson) {
|
|
21
|
+
if (!lesson) return [];
|
|
22
|
+
let content = lesson.replace(/<prq>[\s\S]*?<\/prq>/gi, "").trim();
|
|
23
|
+
const segments = [];
|
|
24
|
+
const activateResult = extractTagContent(content, "activate");
|
|
25
|
+
if (activateResult) {
|
|
26
|
+
segments.push({ type: "activate", question: activateResult.content });
|
|
27
|
+
content = content.replace(activateResult.fullMatch, "").trim();
|
|
28
|
+
}
|
|
29
|
+
const connectResult = extractTagContent(content, "connect");
|
|
30
|
+
if (connectResult) {
|
|
31
|
+
segments.push({ type: "connect", content: connectResult.content });
|
|
32
|
+
content = content.replace(connectResult.fullMatch, "").trim();
|
|
33
|
+
}
|
|
34
|
+
const tagRegex = new RegExp(
|
|
35
|
+
'(?<reflect><reflect>(?<reflectClosed>[\\s\\S]*?)<\\/reflect>)|(?<reflectUnclosed><reflect>(?<reflectOpen>[\\s\\S]*?)(?=<(?:activate|connect|reflect|bloom|prq|question|answer|visualize)|\\n\\n#|$))|(?<bloom><bloom\\s+level="(?<bloomLevel>remember|understand|apply|analyze|evaluate|create)">(?<bloomClosed>[\\s\\S]*?)<\\/bloom>)|(?<bloomUnclosed><bloom\\s+level="(?<bloomLevelUn>remember|understand|apply|analyze|evaluate|create)">(?<bloomOpen>[\\s\\S]*?)(?=<(?:activate|connect|reflect|bloom|prq|question|answer|visualize)|\\n\\n#|$))|(?<quiz><question>(?<quizQuestion>[\\s\\S]*?)<\\/question>\\s*<answer>(?<quizAnswer>[\\s\\S]*?)<\\/answer>)|(?<visualize><visualize\\s+type="(?<vizType>algorithms|math|physics|biology|chemistry|probability)"\\s+description="(?<vizDesc>[^"]*?)"\\s*\\/?>)',
|
|
36
|
+
"gi"
|
|
37
|
+
);
|
|
38
|
+
let lastIndex = 0;
|
|
39
|
+
let match;
|
|
40
|
+
while ((match = tagRegex.exec(content)) !== null) {
|
|
41
|
+
const before = content.slice(lastIndex, match.index);
|
|
42
|
+
if (before.trim()) {
|
|
43
|
+
segments.push(...parseMarkdownWithCodeBlocks(before));
|
|
44
|
+
}
|
|
45
|
+
const g = match.groups ?? {};
|
|
46
|
+
if (g.reflect || g.reflectUnclosed) {
|
|
47
|
+
const prompt = (g.reflectClosed ?? g.reflectOpen ?? "").trim();
|
|
48
|
+
if (prompt) segments.push({ type: "reflect", prompt });
|
|
49
|
+
} else if (g.bloom || g.bloomUnclosed) {
|
|
50
|
+
const level = g.bloomLevel ?? g.bloomLevelUn;
|
|
51
|
+
const bloomContent = g.bloomClosed ?? g.bloomOpen ?? "";
|
|
52
|
+
if (level && bloomContent) {
|
|
53
|
+
const qMatch = bloomContent.match(/<question>([\s\S]*?)<\/question>/i);
|
|
54
|
+
const aMatch = bloomContent.match(/<answer>([\s\S]*?)<\/answer>/i);
|
|
55
|
+
if (qMatch && aMatch) {
|
|
56
|
+
segments.push({ type: "bloom", level, question: qMatch[1].trim(), answer: aMatch[1].trim() });
|
|
57
|
+
} else if (qMatch) {
|
|
58
|
+
segments.push({ type: "bloom", level, question: qMatch[1].trim(), answer: "(Answer not provided)" });
|
|
59
|
+
} else {
|
|
60
|
+
const clean = bloomContent.replace(/^\*\*Question\s*\d*:?\*\*\s*/i, "").replace(/^\*\*Q\d*:?\*\*\s*/i, "").trim();
|
|
61
|
+
if (clean) segments.push({ type: "bloom", level, question: clean, answer: "(See answers section below)" });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
} else if (g.quiz) {
|
|
65
|
+
segments.push({ type: "quiz", question: g.quizQuestion.trim(), answer: g.quizAnswer.trim() });
|
|
66
|
+
} else if (g.visualize) {
|
|
67
|
+
segments.push({
|
|
68
|
+
type: "visualization",
|
|
69
|
+
visualizationType: g.vizType,
|
|
70
|
+
description: g.vizDesc ?? ""
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
lastIndex = tagRegex.lastIndex;
|
|
74
|
+
}
|
|
75
|
+
const remaining = content.slice(lastIndex);
|
|
76
|
+
if (remaining.trim()) segments.push(...parseMarkdownWithCodeBlocks(remaining));
|
|
77
|
+
return segments;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export { parseLessonSegments };
|
|
@@ -11,6 +11,12 @@ var SLOT_DEFINITIONS = {
|
|
|
11
11
|
name: "sidebar",
|
|
12
12
|
type: "inline"
|
|
13
13
|
},
|
|
14
|
+
dock: {
|
|
15
|
+
name: "dock",
|
|
16
|
+
type: "portal",
|
|
17
|
+
portalTarget: "body",
|
|
18
|
+
zIndex: 850
|
|
19
|
+
},
|
|
14
20
|
// -------------------------------------------------------------------------
|
|
15
21
|
// Portal Slots - Render to document.body via React Portal
|
|
16
22
|
// -------------------------------------------------------------------------
|