@mks2508/mks-ui 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/dist/react-ui/hooks/Animation/UseAutoHeight.js +7 -7
  2. package/dist/react-ui/hooks/DOM/UseIsInView.js +3 -3
  3. package/dist/react-ui/hooks/Formatting/UseListFormat.d.ts +49 -0
  4. package/dist/react-ui/hooks/Formatting/UseListFormat.d.ts.map +1 -0
  5. package/dist/react-ui/hooks/Formatting/UseListFormat.js +105 -0
  6. package/dist/react-ui/hooks/State/UseControlledState.js +4 -4
  7. package/dist/react-ui/hooks/State/UseDataState.js +5 -5
  8. package/dist/react-ui/hooks/index.d.ts +2 -0
  9. package/dist/react-ui/hooks/index.d.ts.map +1 -1
  10. package/dist/react-ui/hooks/index.js +1 -0
  11. package/dist/react-ui/index.js +22 -2
  12. package/dist/react-ui/lib/get-strict-context.js +3 -3
  13. package/dist/react-ui/primitives/CountingNumber/index.js +3 -3
  14. package/dist/react-ui/primitives/Highlight/index.js +26 -26
  15. package/dist/react-ui/primitives/Slot/index.js +3 -3
  16. package/dist/react-ui/primitives/index.d.ts +1 -0
  17. package/dist/react-ui/primitives/index.d.ts.map +1 -1
  18. package/dist/react-ui/primitives/index.js +18 -0
  19. package/dist/react-ui/primitives/waapi/Morph/Morph.types.d.ts +76 -0
  20. package/dist/react-ui/primitives/waapi/Morph/Morph.types.d.ts.map +1 -0
  21. package/dist/react-ui/primitives/waapi/Morph/MorphContext.d.ts +11 -0
  22. package/dist/react-ui/primitives/waapi/Morph/MorphContext.d.ts.map +1 -0
  23. package/dist/react-ui/primitives/waapi/Morph/MorphContext.js +19 -0
  24. package/dist/react-ui/primitives/waapi/Morph/index.d.ts +23 -0
  25. package/dist/react-ui/primitives/waapi/Morph/index.d.ts.map +1 -0
  26. package/dist/react-ui/primitives/waapi/Morph/index.js +45 -0
  27. package/dist/react-ui/primitives/waapi/Morph/techniques/index.d.ts +12 -0
  28. package/dist/react-ui/primitives/waapi/Morph/techniques/index.d.ts.map +1 -0
  29. package/dist/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.d.ts +38 -0
  30. package/dist/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.d.ts.map +1 -0
  31. package/dist/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.js +78 -0
  32. package/dist/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.d.ts +23 -0
  33. package/dist/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.d.ts.map +1 -0
  34. package/dist/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.js +140 -0
  35. package/dist/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.d.ts +28 -0
  36. package/dist/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.d.ts.map +1 -0
  37. package/dist/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.js +77 -0
  38. package/dist/react-ui/primitives/waapi/Morph/useMorph.d.ts +27 -0
  39. package/dist/react-ui/primitives/waapi/Morph/useMorph.d.ts.map +1 -0
  40. package/dist/react-ui/primitives/waapi/Morph/useMorph.js +86 -0
  41. package/dist/react-ui/primitives/waapi/Reorder/Reorder.types.d.ts +168 -0
  42. package/dist/react-ui/primitives/waapi/Reorder/Reorder.types.d.ts.map +1 -0
  43. package/dist/react-ui/primitives/waapi/Reorder/index.d.ts +25 -0
  44. package/dist/react-ui/primitives/waapi/Reorder/index.d.ts.map +1 -0
  45. package/dist/react-ui/primitives/waapi/Reorder/index.js +186 -0
  46. package/dist/react-ui/primitives/waapi/Reorder/useReorder.d.ts +26 -0
  47. package/dist/react-ui/primitives/waapi/Reorder/useReorder.d.ts.map +1 -0
  48. package/dist/react-ui/primitives/waapi/Reorder/useReorder.js +48 -0
  49. package/dist/react-ui/primitives/waapi/Reorder/useReorderPresence.d.ts +33 -0
  50. package/dist/react-ui/primitives/waapi/Reorder/useReorderPresence.d.ts.map +1 -0
  51. package/dist/react-ui/primitives/waapi/Reorder/useReorderPresence.js +137 -0
  52. package/dist/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.d.ts +47 -0
  53. package/dist/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.d.ts.map +1 -0
  54. package/dist/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.js +72 -0
  55. package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.d.ts +10 -0
  56. package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.d.ts.map +1 -0
  57. package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.d.ts +74 -0
  58. package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.d.ts.map +1 -0
  59. package/dist/react-ui/primitives/waapi/SlidingNumber/index.d.ts +33 -0
  60. package/dist/react-ui/primitives/waapi/SlidingNumber/index.d.ts.map +1 -0
  61. package/dist/react-ui/primitives/waapi/SlidingNumber/index.js +354 -0
  62. package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.styles.d.ts +25 -0
  63. package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.styles.d.ts.map +1 -0
  64. package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.types.d.ts +57 -0
  65. package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.types.d.ts.map +1 -0
  66. package/dist/react-ui/primitives/waapi/SlidingText/index.d.ts +26 -0
  67. package/dist/react-ui/primitives/waapi/SlidingText/index.d.ts.map +1 -0
  68. package/dist/react-ui/primitives/waapi/SlidingText/index.js +105 -0
  69. package/dist/react-ui/primitives/waapi/core/animationConstants.d.ts +156 -0
  70. package/dist/react-ui/primitives/waapi/core/animationConstants.d.ts.map +1 -0
  71. package/dist/react-ui/primitives/waapi/core/animationConstants.js +180 -0
  72. package/dist/react-ui/primitives/waapi/core/index.d.ts +16 -0
  73. package/dist/react-ui/primitives/waapi/core/index.d.ts.map +1 -0
  74. package/dist/react-ui/primitives/waapi/core/index.js +5 -0
  75. package/dist/react-ui/primitives/waapi/core/types.d.ts +143 -0
  76. package/dist/react-ui/primitives/waapi/core/types.d.ts.map +1 -0
  77. package/dist/react-ui/primitives/waapi/core/useAnimationOrchestrator.d.ts +32 -0
  78. package/dist/react-ui/primitives/waapi/core/useAnimationOrchestrator.d.ts.map +1 -0
  79. package/dist/react-ui/primitives/waapi/core/useAnimationOrchestrator.js +322 -0
  80. package/dist/react-ui/primitives/waapi/core/useElementRegistry.d.ts +21 -0
  81. package/dist/react-ui/primitives/waapi/core/useElementRegistry.d.ts.map +1 -0
  82. package/dist/react-ui/primitives/waapi/core/useElementRegistry.js +65 -0
  83. package/dist/react-ui/primitives/waapi/core/useFLIPAnimation.d.ts +20 -0
  84. package/dist/react-ui/primitives/waapi/core/useFLIPAnimation.d.ts.map +1 -0
  85. package/dist/react-ui/primitives/waapi/core/useFLIPAnimation.js +99 -0
  86. package/dist/react-ui/primitives/waapi/core/usePositionCapture.d.ts +24 -0
  87. package/dist/react-ui/primitives/waapi/core/usePositionCapture.d.ts.map +1 -0
  88. package/dist/react-ui/primitives/waapi/core/usePositionCapture.js +75 -0
  89. package/dist/react-ui/primitives/waapi/index.d.ts +33 -0
  90. package/dist/react-ui/primitives/waapi/index.d.ts.map +1 -0
  91. package/dist/react-ui/primitives/waapi/index.js +18 -0
  92. package/dist/react-ui/ui/Accordion/index.js +3 -3
  93. package/dist/react-ui/ui/Button/index.js +8 -8
  94. package/dist/react-ui/ui/Combobox/index.js +2 -2
  95. package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts +35 -0
  96. package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts.map +1 -0
  97. package/dist/react-ui/ui/DataCard/DataCard.styles.js +114 -0
  98. package/dist/react-ui/ui/DataCard/DataCard.types.d.ts +135 -0
  99. package/dist/react-ui/ui/DataCard/DataCard.types.d.ts.map +1 -0
  100. package/dist/react-ui/ui/DataCard/index.d.ts +129 -0
  101. package/dist/react-ui/ui/DataCard/index.d.ts.map +1 -0
  102. package/dist/react-ui/ui/DataCard/index.js +276 -0
  103. package/dist/react-ui/ui/Menu/index.js +2 -2
  104. package/dist/react-ui/ui/Switch/index.js +3 -3
  105. package/dist/react-ui/ui/Tabs/index.js +3 -3
  106. package/dist/react-ui/ui/TextFlow/TextFlow.styles.d.ts +16 -0
  107. package/dist/react-ui/ui/TextFlow/TextFlow.styles.d.ts.map +1 -0
  108. package/dist/react-ui/ui/TextFlow/TextFlow.types.d.ts +101 -0
  109. package/dist/react-ui/ui/TextFlow/TextFlow.types.d.ts.map +1 -0
  110. package/dist/react-ui/ui/TextFlow/index.d.ts +26 -0
  111. package/dist/react-ui/ui/TextFlow/index.d.ts.map +1 -0
  112. package/dist/react-ui/ui/TextFlow/index.js +187 -0
  113. package/dist/react-ui/ui/index.d.ts +2 -1
  114. package/dist/react-ui/ui/index.d.ts.map +1 -1
  115. package/dist/react-ui/ui/index.js +3 -1
  116. package/package.json +6 -2
  117. package/src/react-ui/hooks/Formatting/UseListFormat.ts +134 -0
  118. package/src/react-ui/hooks/index.ts +3 -0
  119. package/src/react-ui/primitives/index.ts +3 -0
  120. package/src/react-ui/primitives/waapi/Morph/Morph.types.ts +106 -0
  121. package/src/react-ui/primitives/waapi/Morph/MorphContext.tsx +21 -0
  122. package/src/react-ui/primitives/waapi/Morph/index.tsx +56 -0
  123. package/src/react-ui/primitives/waapi/Morph/techniques/index.ts +12 -0
  124. package/src/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.ts +88 -0
  125. package/src/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.ts +175 -0
  126. package/src/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.ts +86 -0
  127. package/src/react-ui/primitives/waapi/Morph/useMorph.ts +100 -0
  128. package/src/react-ui/primitives/waapi/Reorder/Reorder.types.ts +177 -0
  129. package/src/react-ui/primitives/waapi/Reorder/index.tsx +260 -0
  130. package/src/react-ui/primitives/waapi/Reorder/useReorder.ts +46 -0
  131. package/src/react-ui/primitives/waapi/Reorder/useReorderPresence.ts +208 -0
  132. package/src/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.ts +104 -0
  133. package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.ts +14 -0
  134. package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.ts +84 -0
  135. package/src/react-ui/primitives/waapi/SlidingNumber/index.tsx +474 -0
  136. package/src/react-ui/primitives/waapi/SlidingText/SlidingText.styles.ts +32 -0
  137. package/src/react-ui/primitives/waapi/SlidingText/SlidingText.types.ts +69 -0
  138. package/src/react-ui/primitives/waapi/SlidingText/index.tsx +140 -0
  139. package/src/react-ui/primitives/waapi/core/animationConstants.ts +215 -0
  140. package/src/react-ui/primitives/waapi/core/index.ts +53 -0
  141. package/src/react-ui/primitives/waapi/core/types.ts +200 -0
  142. package/src/react-ui/primitives/waapi/core/useAnimationOrchestrator.ts +429 -0
  143. package/src/react-ui/primitives/waapi/core/useElementRegistry.ts +80 -0
  144. package/src/react-ui/primitives/waapi/core/useFLIPAnimation.ts +137 -0
  145. package/src/react-ui/primitives/waapi/core/usePositionCapture.ts +105 -0
  146. package/src/react-ui/primitives/waapi/index.ts +116 -0
  147. package/src/react-ui/styles/animations.css +369 -0
  148. package/src/react-ui/ui/DataCard/DataCard.styles.ts +150 -0
  149. package/src/react-ui/ui/DataCard/DataCard.types.ts +146 -0
  150. package/src/react-ui/ui/DataCard/index.tsx +406 -0
  151. package/src/react-ui/ui/TextFlow/TextFlow.styles.ts +36 -0
  152. package/src/react-ui/ui/TextFlow/TextFlow.types.ts +118 -0
  153. package/src/react-ui/ui/TextFlow/index.tsx +276 -0
  154. package/src/react-ui/ui/index.ts +4 -1
  155. /package/dist/react-ui/components/MorphingPopover/{morphing-popover.module-CgbYV_HS.css → morphing-popover.module-BycNI8nU.css} +0 -0
@@ -0,0 +1,322 @@
1
+ import { EASINGS, EFFECTS, TIMING, TRANSFORMS } from "./animationConstants.js";
2
+ import { useElementRegistry } from "./useElementRegistry.js";
3
+ import { usePositionCapture } from "./usePositionCapture.js";
4
+ import { useFLIPAnimation } from "./useFLIPAnimation.js";
5
+ import { useCallback, useEffect, useRef } from "react";
6
+
7
+ //#region src/react-ui/primitives/waapi/core/useAnimationOrchestrator.ts
8
+ /**
9
+ * Main animation orchestrator hook.
10
+ * Composes useElementRegistry, usePositionCapture, and useFLIPAnimation
11
+ * into a full FLIP exit/enter pipeline.
12
+ *
13
+ * Handles the full exit animation sequence:
14
+ * 1. Capture positions of remaining elements (FIRST)
15
+ * 2. Apply position:absolute to exiting element
16
+ * 3. Force synchronous reflow
17
+ * 4. Capture AFTER positions (LAST)
18
+ * 5. Calculate INVERT deltas and PLAY FLIP animations
19
+ * 6. Run exit animation (per-token stagger or whole-element)
20
+ * 7. Wait for all animations to complete
21
+ * 8. Cleanup and notify completion
22
+ *
23
+ * @param config - Optional orchestrator configuration
24
+ * @returns Full orchestrator API
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * const orchestrator = useAnimationOrchestrator({
29
+ * onExitComplete: (id) => removeFromList(id)
30
+ * });
31
+ *
32
+ * <div ref={el => orchestrator.registerElement('item-1', el)} />
33
+ *
34
+ * await orchestrator.startExit('item-1');
35
+ * ```
36
+ */
37
+ function useAnimationOrchestrator(config) {
38
+ const configRef = useRef(config);
39
+ useEffect(() => {
40
+ configRef.current = config;
41
+ }, [config]);
42
+ const stateRef = useRef({
43
+ animatingIds: /* @__PURE__ */ new Set(),
44
+ positions: /* @__PURE__ */ new Map(),
45
+ activeAnimations: /* @__PURE__ */ new Map()
46
+ });
47
+ const registry = useElementRegistry();
48
+ const positions = usePositionCapture(registry.getAll, { minDeltaPx: config?.minDeltaPx ?? TIMING.MIN_DELTA_PX });
49
+ const flip = useFLIPAnimation();
50
+ const exitDuration = config?.exitDuration ?? TIMING.EXIT_DURATION;
51
+ const flipDuration = config?.flipDuration ?? TIMING.FLIP_DURATION;
52
+ const exitEasing = config?.exitEasing ?? EASINGS.EASE_IN_CUBIC;
53
+ const cancelAnimation = useCallback((id) => {
54
+ const animations = stateRef.current.activeAnimations.get(id);
55
+ if (animations) {
56
+ animations.forEach((anim) => anim.cancel());
57
+ stateRef.current.activeAnimations.delete(id);
58
+ }
59
+ stateRef.current.animatingIds.delete(id);
60
+ flip.cancel(id);
61
+ }, [flip]);
62
+ const cancelAllAnimations = useCallback(() => {
63
+ stateRef.current.activeAnimations.forEach((animations) => {
64
+ animations.forEach((anim) => anim.cancel());
65
+ });
66
+ stateRef.current.activeAnimations.clear();
67
+ stateRef.current.animatingIds.clear();
68
+ flip.cancelAll();
69
+ }, [flip]);
70
+ const flipBehavior = config?.flipBehavior ?? "all";
71
+ const exitPositionStrategy = config?.exitPositionStrategy ?? "absolute-fixed";
72
+ /**
73
+ * Full FLIP exit implementation.
74
+ * Based on research from Paul Lewis (aerotwist.com), react-flip-move,
75
+ * and Framer Motion popLayout mode.
76
+ */
77
+ const startExit = useCallback(async (id, options) => {
78
+ const el = registry.get(id);
79
+ if (!el || stateRef.current.animatingIds.has(id)) return;
80
+ stateRef.current.animatingIds.add(id);
81
+ const duration = options?.duration ?? exitDuration;
82
+ const easing = options?.easing ?? exitEasing;
83
+ const allElements = registry.getAll();
84
+ const beforePositions = /* @__PURE__ */ new Map();
85
+ const exitingRect = el.getBoundingClientRect();
86
+ beforePositions.set(id, exitingRect);
87
+ allElements.forEach((element, elemId) => {
88
+ if (elemId !== id) {
89
+ const rect = element.getBoundingClientRect();
90
+ if (rect.width > 0 && rect.height > 0) beforePositions.set(elemId, rect);
91
+ }
92
+ });
93
+ const parent = el.parentElement;
94
+ el.dataset.reorderState = "exiting";
95
+ if (exitPositionStrategy === "absolute-fixed") el.dataset.exitPosition = "absolute";
96
+ const parentRectBefore = parent?.getBoundingClientRect() || {
97
+ left: 0,
98
+ top: 0
99
+ };
100
+ const absoluteLeft = exitingRect.left - parentRectBefore.left;
101
+ const absoluteTop = exitingRect.top - parentRectBefore.top;
102
+ if (exitPositionStrategy === "absolute-fixed") {
103
+ el.style.position = "absolute";
104
+ el.style.left = `${absoluteLeft}px`;
105
+ el.style.top = `${absoluteTop}px`;
106
+ el.style.width = `${exitingRect.width}px`;
107
+ el.style.height = `${exitingRect.height}px`;
108
+ el.style.margin = "0";
109
+ }
110
+ const parentRectAfter = parent?.getBoundingClientRect() || {
111
+ left: 0,
112
+ top: 0
113
+ };
114
+ const parentDeltaX = parentRectAfter.left - parentRectBefore.left;
115
+ const parentDeltaY = parentRectAfter.top - parentRectBefore.top;
116
+ if (Math.abs(parentDeltaX) > .5 || Math.abs(parentDeltaY) > .5) el.style.transform = `translate(${-parentDeltaX}px, ${-parentDeltaY}px)`;
117
+ const afterPositions = /* @__PURE__ */ new Map();
118
+ allElements.forEach((element, elemId) => {
119
+ if (elemId !== id) {
120
+ const rect = element.getBoundingClientRect();
121
+ if (rect.width > 0 && rect.height > 0) afterPositions.set(elemId, rect);
122
+ }
123
+ });
124
+ const flipAnimations = [];
125
+ if (flipBehavior !== "none") {
126
+ let siblingsToAnimate = [];
127
+ if (flipBehavior === "all") siblingsToAnimate = [...afterPositions.keys()];
128
+ else if (flipBehavior === "siblings-after") {
129
+ const elementsWithIds = Array.from(allElements.entries());
130
+ elementsWithIds.sort((a, b) => {
131
+ const posA = a[1];
132
+ const posB = b[1];
133
+ return posA.compareDocumentPosition(posB) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
134
+ });
135
+ const sortedKeys = elementsWithIds.map(([k]) => k);
136
+ const exitingIndex = sortedKeys.indexOf(id);
137
+ if (exitingIndex !== -1) siblingsToAnimate = sortedKeys.slice(exitingIndex + 1).filter((k) => afterPositions.has(k));
138
+ }
139
+ siblingsToAnimate.forEach((siblingId) => {
140
+ const before = beforePositions.get(siblingId);
141
+ const after = afterPositions.get(siblingId);
142
+ if (!before || !after) return;
143
+ const deltaX = before.left - after.left;
144
+ const deltaY = before.top - after.top;
145
+ if (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1) {
146
+ const siblingEl = allElements.get(siblingId);
147
+ if (siblingEl) {
148
+ siblingEl.dataset.reorderState = "flipping";
149
+ siblingEl.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
150
+ const anim = siblingEl.animate([{ transform: `translate(${deltaX}px, ${deltaY}px)` }, { transform: "none" }], {
151
+ duration: flipDuration,
152
+ easing: EASINGS.MATERIAL_DECELERATE,
153
+ fill: "forwards"
154
+ });
155
+ flipAnimations.push(anim);
156
+ anim.finished.then(() => {
157
+ siblingEl.style.transform = "";
158
+ siblingEl.dataset.reorderState = "idle";
159
+ }).catch(() => {
160
+ siblingEl.style.transform = "";
161
+ siblingEl.dataset.reorderState = "idle";
162
+ });
163
+ }
164
+ }
165
+ });
166
+ }
167
+ const exitAnimations = [];
168
+ const tokens = el.querySelectorAll(".waapi-sliding-text-token");
169
+ if (tokens.length > 0) tokens.forEach((token, index) => {
170
+ const delay = index * TIMING.EXIT_STAGGER;
171
+ const anim = token.animate([{
172
+ opacity: 1,
173
+ transform: "translateY(0) scale(1)",
174
+ filter: "blur(0px)"
175
+ }, {
176
+ opacity: 0,
177
+ transform: `translateY(${TRANSFORMS.OFFSET_Y_EXIT}px) scale(${TRANSFORMS.SCALE_EXIT})`,
178
+ filter: `blur(${EFFECTS.BLUR_EXIT}px)`
179
+ }], {
180
+ duration,
181
+ easing,
182
+ delay,
183
+ fill: "forwards"
184
+ });
185
+ exitAnimations.push(anim);
186
+ });
187
+ else {
188
+ const anim = el.animate([{
189
+ opacity: 1,
190
+ transform: "scale(1)"
191
+ }, {
192
+ opacity: 0,
193
+ transform: `scale(${TRANSFORMS.SCALE_EXIT})`
194
+ }], {
195
+ duration,
196
+ easing,
197
+ fill: "forwards"
198
+ });
199
+ exitAnimations.push(anim);
200
+ }
201
+ stateRef.current.activeAnimations.set(id, [...exitAnimations, ...flipAnimations]);
202
+ try {
203
+ await Promise.all([...exitAnimations.map((a) => a.finished), ...flipAnimations.map((a) => a.finished)]);
204
+ } catch {
205
+ stateRef.current.animatingIds.delete(id);
206
+ stateRef.current.activeAnimations.delete(id);
207
+ return;
208
+ }
209
+ stateRef.current.animatingIds.delete(id);
210
+ stateRef.current.activeAnimations.delete(id);
211
+ el.dataset.reorderState = "completed";
212
+ if (exitPositionStrategy === "absolute-fixed") {
213
+ el.style.removeProperty("position");
214
+ el.style.removeProperty("left");
215
+ el.style.removeProperty("top");
216
+ el.style.removeProperty("width");
217
+ el.style.removeProperty("height");
218
+ el.style.removeProperty("margin");
219
+ }
220
+ delete el.dataset.exitPosition;
221
+ registry.unregister(id);
222
+ options?.onComplete?.();
223
+ configRef.current?.onExitComplete?.(id);
224
+ }, [
225
+ registry,
226
+ exitDuration,
227
+ exitEasing,
228
+ flipDuration,
229
+ flipBehavior,
230
+ exitPositionStrategy
231
+ ]);
232
+ /**
233
+ * Start enter animation for an element.
234
+ *
235
+ * Architecture: CSS + WAAPI
236
+ * - Assumes element already has data-reorder-state="entering" (set by Reorder.tsx)
237
+ * - CSS [data-reorder-state="entering"] { opacity: 0; transform: translateY(-8px) scale(0.95); }
238
+ * - WAAPI animates FROM that state TO visible
239
+ * - Sets data-reorder-state="idle" on completion
240
+ */
241
+ const startEnter = useCallback(async (id, options) => {
242
+ const el = registry.get(id);
243
+ if (!el) return;
244
+ if (!el.dataset.reorderState) el.dataset.reorderState = "entering";
245
+ const enterDuration = configRef.current?.enterDuration ?? TIMING.ENTER_DURATION;
246
+ const enterEasing = configRef.current?.enterEasing ?? EASINGS.MATERIAL_DECELERATE;
247
+ const duration = options?.duration ?? enterDuration;
248
+ const easing = options?.easing ?? enterEasing;
249
+ const stagger = options?.stagger ?? TIMING.ENTER_STAGGER;
250
+ const tokens = el.querySelectorAll(".waapi-sliding-text-token");
251
+ const animations = [];
252
+ const fromKeyframe = {
253
+ opacity: 0,
254
+ transform: "translateY(-8px) scale(0.95)"
255
+ };
256
+ const toKeyframe = {
257
+ opacity: 1,
258
+ transform: "none"
259
+ };
260
+ if (tokens.length > 0) tokens.forEach((token, index) => {
261
+ const delay = index * stagger;
262
+ token.dataset.reorderIndex = String(index);
263
+ const anim = token.animate([{
264
+ ...fromKeyframe,
265
+ filter: `blur(${EFFECTS.BLUR_ENTER}px)`
266
+ }, {
267
+ ...toKeyframe,
268
+ filter: "blur(0px)"
269
+ }], {
270
+ duration,
271
+ easing,
272
+ delay,
273
+ fill: "forwards"
274
+ });
275
+ animations.push(anim);
276
+ });
277
+ else {
278
+ const anim = el.animate([fromKeyframe, toKeyframe], {
279
+ duration,
280
+ easing,
281
+ fill: "forwards"
282
+ });
283
+ animations.push(anim);
284
+ }
285
+ try {
286
+ await Promise.all(animations.map((a) => a.finished));
287
+ } catch {
288
+ el.dataset.reorderState = "idle";
289
+ return;
290
+ }
291
+ el.dataset.reorderState = "idle";
292
+ options?.onComplete?.();
293
+ configRef.current?.onEnterComplete?.(id);
294
+ }, [registry]);
295
+ const isAnimating = useCallback((id) => {
296
+ if (id) return stateRef.current.animatingIds.has(id);
297
+ return stateRef.current.animatingIds.size > 0;
298
+ }, []);
299
+ const capturePositions = useCallback((excludeIds) => {
300
+ return positions.capture(excludeIds);
301
+ }, [positions]);
302
+ useEffect(() => {
303
+ return () => {
304
+ cancelAllAnimations();
305
+ };
306
+ }, [cancelAllAnimations]);
307
+ return {
308
+ registry,
309
+ positions,
310
+ flip,
311
+ registerElement: registry.register,
312
+ startExit,
313
+ startEnter,
314
+ isAnimating,
315
+ cancelAnimation,
316
+ cancelAllAnimations,
317
+ capturePositions
318
+ };
319
+ }
320
+
321
+ //#endregion
322
+ export { useAnimationOrchestrator };
@@ -0,0 +1,21 @@
1
+ import type { IElementRegistryAPI, IElementRegistryCallbacks } from './types';
2
+ /**
3
+ * Hook for tracking DOM elements by ID.
4
+ * Extracted from the WAAPI animation system's element registration logic.
5
+ *
6
+ * @param callbacks - Optional lifecycle callbacks for register/unregister events
7
+ * @returns Registry API for managing elements by ID
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * const registry = useElementRegistry({
12
+ * onRegister: (id) => console.log(`Registered: ${id}`),
13
+ * onUnregister: (id) => console.log(`Unregistered: ${id}`)
14
+ * });
15
+ *
16
+ * // In render:
17
+ * <div ref={el => registry.register('item-1', el)} />
18
+ * ```
19
+ */
20
+ export declare function useElementRegistry(callbacks?: IElementRegistryCallbacks): IElementRegistryAPI;
21
+ //# sourceMappingURL=useElementRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useElementRegistry.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/core/useElementRegistry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,CAAC,EAAE,yBAAyB,GACpC,mBAAmB,CAwDrB"}
@@ -0,0 +1,65 @@
1
+ import { useCallback, useEffect, useRef } from "react";
2
+
3
+ //#region src/react-ui/primitives/waapi/core/useElementRegistry.ts
4
+ /**
5
+ * Hook for tracking DOM elements by ID.
6
+ * Extracted from the WAAPI animation system's element registration logic.
7
+ *
8
+ * @param callbacks - Optional lifecycle callbacks for register/unregister events
9
+ * @returns Registry API for managing elements by ID
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * const registry = useElementRegistry({
14
+ * onRegister: (id) => console.log(`Registered: ${id}`),
15
+ * onUnregister: (id) => console.log(`Unregistered: ${id}`)
16
+ * });
17
+ *
18
+ * // In render:
19
+ * <div ref={el => registry.register('item-1', el)} />
20
+ * ```
21
+ */
22
+ function useElementRegistry(callbacks) {
23
+ const elementsRef = useRef(/* @__PURE__ */ new Map());
24
+ const callbacksRef = useRef(callbacks);
25
+ useEffect(() => {
26
+ callbacksRef.current = callbacks;
27
+ }, [callbacks]);
28
+ return {
29
+ register: useCallback((id, el) => {
30
+ if (el) {
31
+ elementsRef.current.set(id, el);
32
+ callbacksRef.current?.onRegister?.(id, el);
33
+ } else if (elementsRef.current.has(id)) {
34
+ elementsRef.current.delete(id);
35
+ callbacksRef.current?.onUnregister?.(id);
36
+ }
37
+ }, []),
38
+ unregister: useCallback((id) => {
39
+ if (elementsRef.current.has(id)) {
40
+ elementsRef.current.delete(id);
41
+ callbacksRef.current?.onUnregister?.(id);
42
+ }
43
+ }, []),
44
+ get: useCallback((id) => {
45
+ return elementsRef.current.get(id);
46
+ }, []),
47
+ getAll: useCallback(() => {
48
+ return new Map(elementsRef.current);
49
+ }, []),
50
+ has: useCallback((id) => {
51
+ return elementsRef.current.has(id);
52
+ }, []),
53
+ clear: useCallback(() => {
54
+ const ids = Array.from(elementsRef.current.keys());
55
+ elementsRef.current.clear();
56
+ ids.forEach((id) => callbacksRef.current?.onUnregister?.(id));
57
+ }, []),
58
+ get size() {
59
+ return elementsRef.current.size;
60
+ }
61
+ };
62
+ }
63
+
64
+ //#endregion
65
+ export { useElementRegistry };
@@ -0,0 +1,20 @@
1
+ import type { IFLIPAnimationAPI } from './types';
2
+ /**
3
+ * Hook for executing FLIP (First-Last-Invert-Play) animations.
4
+ * Uses spring easing for natural motion with slight overshoot.
5
+ *
6
+ * @returns FLIP animation API with animate, cancel, and status methods
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * const flip = useFLIPAnimation();
11
+ *
12
+ * // After calculating deltas:
13
+ * await flip.animateAll(elements, deltas, {
14
+ * duration: 300,
15
+ * onComplete: (id) => console.log(`${id} completed`)
16
+ * });
17
+ * ```
18
+ */
19
+ export declare function useFLIPAnimation(): IFLIPAnimationAPI;
20
+ //# sourceMappingURL=useFLIPAnimation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFLIPAnimation.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/core/useFLIPAnimation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAqC,MAAM,SAAS,CAAC;AAKpF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,IAAI,iBAAiB,CAgHpD"}
@@ -0,0 +1,99 @@
1
+ import { EASINGS, TIMING } from "./animationConstants.js";
2
+ import { useCallback, useEffect, useRef } from "react";
3
+
4
+ //#region src/react-ui/primitives/waapi/core/useFLIPAnimation.ts
5
+ const DEFAULT_DURATION = TIMING.FLIP_DURATION;
6
+ const DEFAULT_EASING = EASINGS.SPRING_GENTLE;
7
+ /**
8
+ * Hook for executing FLIP (First-Last-Invert-Play) animations.
9
+ * Uses spring easing for natural motion with slight overshoot.
10
+ *
11
+ * @returns FLIP animation API with animate, cancel, and status methods
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * const flip = useFLIPAnimation();
16
+ *
17
+ * // After calculating deltas:
18
+ * await flip.animateAll(elements, deltas, {
19
+ * duration: 300,
20
+ * onComplete: (id) => console.log(`${id} completed`)
21
+ * });
22
+ * ```
23
+ */
24
+ function useFLIPAnimation() {
25
+ const activeAnimationsRef = useRef(/* @__PURE__ */ new Map());
26
+ const animatingIdsRef = useRef(/* @__PURE__ */ new Set());
27
+ const animate = useCallback((element, delta, options) => {
28
+ const duration = options?.duration ?? DEFAULT_DURATION;
29
+ const easing = options?.easing ?? DEFAULT_EASING;
30
+ if (activeAnimationsRef.current.has(delta.id)) activeAnimationsRef.current.get(delta.id)?.cancel();
31
+ animatingIdsRef.current.add(delta.id);
32
+ options?.onStart?.(delta.id);
33
+ const animation = element.animate([{ transform: `translate3d(${delta.deltaX}px, ${delta.deltaY}px, 0)` }, { transform: "translate3d(0, 0, 0)" }], {
34
+ duration,
35
+ easing
36
+ });
37
+ activeAnimationsRef.current.set(delta.id, animation);
38
+ animation.onfinish = () => {
39
+ animatingIdsRef.current.delete(delta.id);
40
+ activeAnimationsRef.current.delete(delta.id);
41
+ options?.onComplete?.(delta.id);
42
+ };
43
+ animation.oncancel = () => {
44
+ animatingIdsRef.current.delete(delta.id);
45
+ activeAnimationsRef.current.delete(delta.id);
46
+ };
47
+ return animation;
48
+ }, []);
49
+ const animateAll = useCallback(async (elements, deltas, options) => {
50
+ const animations = [];
51
+ deltas.forEach((delta, id) => {
52
+ if (!delta.isSignificant) return;
53
+ const element = elements.get(id);
54
+ if (!element) return;
55
+ const anim = animate(element, delta, options);
56
+ animations.push(anim);
57
+ });
58
+ if (animations.length === 0) return;
59
+ await Promise.all(animations.map((anim) => anim.finished.catch(() => {})));
60
+ }, [animate]);
61
+ const cancel = useCallback((id) => {
62
+ const animation = activeAnimationsRef.current.get(id);
63
+ if (animation) {
64
+ animation.cancel();
65
+ activeAnimationsRef.current.delete(id);
66
+ animatingIdsRef.current.delete(id);
67
+ }
68
+ }, []);
69
+ const cancelAll = useCallback(() => {
70
+ activeAnimationsRef.current.forEach((animation) => animation.cancel());
71
+ activeAnimationsRef.current.clear();
72
+ animatingIdsRef.current.clear();
73
+ }, []);
74
+ const isAnimating = useCallback((id) => {
75
+ if (id) return animatingIdsRef.current.has(id);
76
+ return animatingIdsRef.current.size > 0;
77
+ }, []);
78
+ useEffect(() => {
79
+ return () => {
80
+ cancelAll();
81
+ };
82
+ }, [cancelAll]);
83
+ const api = useRef({
84
+ animate,
85
+ animateAll,
86
+ cancel,
87
+ cancelAll,
88
+ isAnimating
89
+ });
90
+ api.current.animate = animate;
91
+ api.current.animateAll = animateAll;
92
+ api.current.cancel = cancel;
93
+ api.current.cancelAll = cancelAll;
94
+ api.current.isAnimating = isAnimating;
95
+ return api.current;
96
+ }
97
+
98
+ //#endregion
99
+ export { useFLIPAnimation };
@@ -0,0 +1,24 @@
1
+ import type { IPositionCaptureAPI, IPositionCaptureOptions } from './types';
2
+ /**
3
+ * Hook for capturing element positions and calculating FLIP deltas.
4
+ * Extracted from the WAAPI animation system's position capture logic.
5
+ *
6
+ * @param getElements - Function that returns the current element map
7
+ * @param options - Optional configuration (e.g. minimum delta threshold)
8
+ * @returns Position capture API with capture, delta calculation, and cache
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * const registry = useElementRegistry();
13
+ * const positions = usePositionCapture(registry.getAll);
14
+ *
15
+ * // Before layout change:
16
+ * const before = positions.capture();
17
+ *
18
+ * // After layout change:
19
+ * const after = positions.capture();
20
+ * const deltas = positions.calculateDeltas(before, after);
21
+ * ```
22
+ */
23
+ export declare function usePositionCapture(getElements: () => Map<string, HTMLElement>, options?: IPositionCaptureOptions): IPositionCaptureAPI;
24
+ //# sourceMappingURL=usePositionCapture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePositionCapture.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/core/usePositionCapture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAc,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAIxF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EAC3C,OAAO,CAAC,EAAE,uBAAuB,GAChC,mBAAmB,CA0ErB"}
@@ -0,0 +1,75 @@
1
+ import { TIMING } from "./animationConstants.js";
2
+ import { useCallback, useRef } from "react";
3
+
4
+ //#region src/react-ui/primitives/waapi/core/usePositionCapture.ts
5
+ const DEFAULT_MIN_DELTA_PX = TIMING.MIN_DELTA_PX;
6
+ /**
7
+ * Hook for capturing element positions and calculating FLIP deltas.
8
+ * Extracted from the WAAPI animation system's position capture logic.
9
+ *
10
+ * @param getElements - Function that returns the current element map
11
+ * @param options - Optional configuration (e.g. minimum delta threshold)
12
+ * @returns Position capture API with capture, delta calculation, and cache
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * const registry = useElementRegistry();
17
+ * const positions = usePositionCapture(registry.getAll);
18
+ *
19
+ * // Before layout change:
20
+ * const before = positions.capture();
21
+ *
22
+ * // After layout change:
23
+ * const after = positions.capture();
24
+ * const deltas = positions.calculateDeltas(before, after);
25
+ * ```
26
+ */
27
+ function usePositionCapture(getElements, options) {
28
+ const lastCaptureRef = useRef(/* @__PURE__ */ new Map());
29
+ const minDeltaPx = options?.minDeltaPx ?? DEFAULT_MIN_DELTA_PX;
30
+ return {
31
+ capture: useCallback((excludeIds) => {
32
+ const positions = /* @__PURE__ */ new Map();
33
+ getElements().forEach((el, id) => {
34
+ if (excludeIds?.has(id)) return;
35
+ const rect = el.getBoundingClientRect();
36
+ if (rect.width > 0 && rect.height > 0) positions.set(id, rect);
37
+ });
38
+ lastCaptureRef.current = positions;
39
+ return positions;
40
+ }, [getElements]),
41
+ getPosition: useCallback((id) => {
42
+ return lastCaptureRef.current.get(id);
43
+ }, []),
44
+ calculateDeltas: useCallback((before, after) => {
45
+ const deltas = /* @__PURE__ */ new Map();
46
+ after.forEach((newRect, id) => {
47
+ const prevRect = before.get(id);
48
+ if (!prevRect) return;
49
+ const deltaX = prevRect.left - newRect.left;
50
+ const deltaY = prevRect.top - newRect.top;
51
+ const deltaWidth = prevRect.width - newRect.width;
52
+ const deltaHeight = prevRect.height - newRect.height;
53
+ const isSignificant = Math.abs(deltaX) >= minDeltaPx || Math.abs(deltaY) >= minDeltaPx || Math.abs(deltaWidth) >= minDeltaPx || Math.abs(deltaHeight) >= minDeltaPx;
54
+ deltas.set(id, {
55
+ id,
56
+ deltaX,
57
+ deltaY,
58
+ deltaWidth,
59
+ deltaHeight,
60
+ isSignificant
61
+ });
62
+ });
63
+ return deltas;
64
+ }, [minDeltaPx]),
65
+ getLastCapture: useCallback(() => {
66
+ return new Map(lastCaptureRef.current);
67
+ }, []),
68
+ clear: useCallback(() => {
69
+ lastCaptureRef.current.clear();
70
+ }, [])
71
+ };
72
+ }
73
+
74
+ //#endregion
75
+ export { usePositionCapture };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * WAAPI Animation Primitives
3
+ *
4
+ * Lightweight, performant React animation components built on the Web Animations API (WAAPI).
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { SlidingNumber, SlidingText, Reorder, Morph } from '@mks2508/mks-ui/react/primitives/waapi';
9
+ * ```
10
+ */
11
+ export { TIMING, TRANSFORMS, EFFECTS, EASINGS, RESPONSIVE_CONFIGS, ANIMATION_CONFIGS, ANIMATION_DEFAULTS, PRESETS, getResponsiveDuration, getResponsiveStagger, } from './core';
12
+ export { useElementRegistry } from './core';
13
+ export { usePositionCapture } from './core';
14
+ export { useFLIPAnimation } from './core';
15
+ export { useAnimationOrchestrator } from './core';
16
+ export type { IFLIPDelta, IAnimationTiming, IPositionRect, IElementRegistryAPI, IElementRegistryCallbacks, IPositionCaptureAPI, IPositionCaptureOptions, IFLIPAnimationAPI, IFLIPAnimationOptions, IExitOptions, IEnterOptions, IAnimationOrchestratorConfig, IAnimationOrchestratorAPI, IOrchestratorState, IAnimationEvent, FLIPBehavior, ExitPositionStrategy, AnimationPhase, } from './core';
17
+ export { SlidingNumber } from './SlidingNumber';
18
+ export type { ISlidingNumberProps, IFormatOptions, } from './SlidingNumber/SlidingNumber.types';
19
+ export { SlidingText } from './SlidingText';
20
+ export type { ISlidingTextProps } from './SlidingText/SlidingText.types';
21
+ export { Reorder } from './Reorder';
22
+ export type { IReorderProps, ReorderLayout, DurationConfig, StaggerConfig, IUseReorderReturn, IUseReorderConfig, IReorderItemState, IReorderContextValue, IUseReorderPresenceConfig, IUseReorderPresenceReturn, } from './Reorder/Reorder.types';
23
+ export { useReorder } from './Reorder/useReorder';
24
+ export { useReorderPresence } from './Reorder/useReorderPresence';
25
+ export { calculateSeparatorCoordination, shouldShowSeparator } from './Reorder/utils/separatorCoordination';
26
+ export { Morph } from './Morph';
27
+ export type { IMorphProps, IMorphContextValue, IUseMorphConfig, IUseMorphReturn, MorphTechnique, IFLIPClipPathOptions, IFLIPClipPathAPI, ICSSGridMorphOptions, ICSSGridMorphAPI, IViewTransitionsOptions, IViewTransitionsAPI, } from './Morph/Morph.types';
28
+ export { useMorph } from './Morph/useMorph';
29
+ export { useMorphContext } from './Morph/MorphContext';
30
+ export { useFLIPClipPath } from './Morph/techniques/useFLIPClipPath';
31
+ export { useCSSGridMorph } from './Morph/techniques/useCSSGridMorph';
32
+ export { useViewTransitions } from './Morph/techniques/useViewTransitions';
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/react-ui/primitives/waapi/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,EACL,MAAM,EACN,UAAU,EACV,OAAO,EACP,OAAO,EACP,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,OAAO,EACP,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAE,wBAAwB,EAAE,MAAM,QAAQ,CAAC;AAGlD,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,4BAA4B,EAC5B,yBAAyB,EACzB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,cAAc,GACf,MAAM,QAAQ,CAAC;AAKhB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EACV,mBAAmB,EACnB,cAAc,GACf,MAAM,qCAAqC,CAAC;AAK7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAKzE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,8BAA8B,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAK5G,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC"}