@jalvin/runtime 2.0.41 → 2.0.43
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/bibi.d.ts +0 -4
- package/dist/bibi.d.ts.map +1 -1
- package/dist/bibi.js +9 -11
- package/dist/bibi.js.map +1 -1
- package/dist/coroutines.js +47 -22
- package/dist/coroutines.js.map +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +224 -20
- package/dist/index.js.map +1 -1
- package/dist/stateflow.js +19 -8
- package/dist/stateflow.js.map +1 -1
- package/dist/stdlib/collections.js +108 -55
- package/dist/stdlib/collections.js.map +1 -1
- package/dist/stdlib/conversions.d.ts +0 -2
- package/dist/stdlib/conversions.d.ts.map +1 -1
- package/dist/stdlib/conversions.js +29 -17
- package/dist/stdlib/conversions.js.map +1 -1
- package/dist/stdlib/delegates.js +28 -14
- package/dist/stdlib/delegates.js.map +1 -1
- package/dist/stdlib/equality.js +4 -1
- package/dist/stdlib/equality.js.map +1 -1
- package/dist/stdlib/index.js +28 -12
- package/dist/stdlib/index.js.map +1 -1
- package/dist/stdlib/io.js +6 -2
- package/dist/stdlib/io.js.map +1 -1
- package/dist/stdlib/math.js +37 -29
- package/dist/stdlib/math.js.map +1 -1
- package/dist/stdlib/random.js +8 -3
- package/dist/stdlib/random.js.map +1 -1
- package/dist/stdlib/regex.js +8 -4
- package/dist/stdlib/regex.js.map +1 -1
- package/dist/stdlib/result.js +9 -3
- package/dist/stdlib/result.js.map +1 -1
- package/dist/stdlib/strings.js +51 -24
- package/dist/stdlib/strings.js.map +1 -1
- package/dist/stdlib/timing.js +8 -3
- package/dist/stdlib/timing.js.map +1 -1
- package/dist/stdlib/types.js +29 -13
- package/dist/stdlib/types.js.map +1 -1
- package/dist/ui.d.ts +69 -12
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +228 -130
- package/dist/ui.js.map +1 -1
- package/package.json +1 -1
- package/dist/dom.d.ts +0 -15
- package/dist/dom.d.ts.map +0 -1
- package/dist/dom.js +0 -212
- package/dist/dom.js.map +0 -1
- package/dist/nav.d.ts +0 -104
- package/dist/nav.d.ts.map +0 -1
- package/dist/nav.js +0 -261
- package/dist/nav.js.map +0 -1
package/dist/dom.js
DELETED
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
2
|
-
// Jalvin DOM Runtime — Virtual DOM and Patching
|
|
3
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
4
|
-
/**
|
|
5
|
-
* Creates a Virtual DOM Node instead of a real element.
|
|
6
|
-
*/
|
|
7
|
-
export function jalvinCreateElement(tag, props, ...children) {
|
|
8
|
-
if (typeof tag === "function") {
|
|
9
|
-
// We expect components to return VNodes directly now.
|
|
10
|
-
return tag(props || {}, children);
|
|
11
|
-
}
|
|
12
|
-
// Flatten children
|
|
13
|
-
const flatChildren = [];
|
|
14
|
-
const append = (child) => {
|
|
15
|
-
if (child === null || child === undefined)
|
|
16
|
-
return;
|
|
17
|
-
if (Array.isArray(child)) {
|
|
18
|
-
child.forEach(append);
|
|
19
|
-
}
|
|
20
|
-
else if (typeof child === "object" && child.tag) {
|
|
21
|
-
// It's a VNode
|
|
22
|
-
flatChildren.push(child);
|
|
23
|
-
}
|
|
24
|
-
else if (typeof child === "object" && typeof child.nodeType === "number") {
|
|
25
|
-
// Fallback for native DOM nodes (try to avoid this, but support it if necessary)
|
|
26
|
-
flatChildren.push(child);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
// Primitives to strings
|
|
30
|
-
flatChildren.push(String(child));
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
const childrenArray = Array.isArray(children[0]) && children.length === 1
|
|
34
|
-
? children[0]
|
|
35
|
-
: children;
|
|
36
|
-
if (Array.isArray(childrenArray)) {
|
|
37
|
-
childrenArray.forEach(append);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
append(childrenArray);
|
|
41
|
-
}
|
|
42
|
-
return { tag: tag, props: props || {}, children: flatChildren };
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* A basic diffing algorithm to update the DOM without recreating it.
|
|
46
|
-
*/
|
|
47
|
-
export function patch(parentEl, newVNode, oldVNode, index = 0) {
|
|
48
|
-
const child = parentEl.childNodes[index];
|
|
49
|
-
if (!oldVNode) {
|
|
50
|
-
// ADD: Node doesn't exist, append it.
|
|
51
|
-
if (newVNode !== null) {
|
|
52
|
-
parentEl.appendChild(createDOMNode(newVNode));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
else if (!newVNode) {
|
|
56
|
-
// REMOVE: Node exists but new one doesn't. Remove it.
|
|
57
|
-
if (child)
|
|
58
|
-
parentEl.removeChild(child);
|
|
59
|
-
}
|
|
60
|
-
else if (changed(newVNode, oldVNode)) {
|
|
61
|
-
// REPLACE: Node type changed entirely.
|
|
62
|
-
if (child) {
|
|
63
|
-
parentEl.replaceChild(createDOMNode(newVNode), child);
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
parentEl.appendChild(createDOMNode(newVNode));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
else if (typeof newVNode === "object" && typeof oldVNode === "object" && newVNode.tag === oldVNode.tag) {
|
|
70
|
-
// UPDATE: Same tag, update props and children.
|
|
71
|
-
if (!child)
|
|
72
|
-
return;
|
|
73
|
-
// Guard: native DOM node (e.g. a stray TextNode) — sync text and bail, no VNode children to recurse.
|
|
74
|
-
if (newVNode.nodeType !== undefined) {
|
|
75
|
-
if (newVNode.nodeType === 3 && child.nodeType === 3) {
|
|
76
|
-
const newText = newVNode.data ?? "";
|
|
77
|
-
if (child.data !== newText)
|
|
78
|
-
child.data = newText;
|
|
79
|
-
}
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
const el = child;
|
|
83
|
-
newVNode.el = el;
|
|
84
|
-
updateProps(el, newVNode.props, oldVNode.props);
|
|
85
|
-
// Recursively patch children.
|
|
86
|
-
const newLength = newVNode.children.length;
|
|
87
|
-
const oldLength = oldVNode.children.length;
|
|
88
|
-
const max = Math.max(newLength, oldLength);
|
|
89
|
-
// We iterate backwards when removing children to avoid index shifting issues,
|
|
90
|
-
// but a simpler approach for basic patching is forward iteration, then trim.
|
|
91
|
-
for (let i = 0; i < max; i++) {
|
|
92
|
-
patch(el, newVNode.children[i] ?? null, oldVNode.children[i] ?? null, i);
|
|
93
|
-
}
|
|
94
|
-
// Trim excess children if old length was greater
|
|
95
|
-
while (el.childNodes.length > newLength) {
|
|
96
|
-
el.removeChild(el.lastChild);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
function createDOMNode(vnode) {
|
|
101
|
-
if (typeof vnode === "string") {
|
|
102
|
-
return document.createTextNode(vnode);
|
|
103
|
-
}
|
|
104
|
-
if (vnode.tag === undefined) {
|
|
105
|
-
// Must be a native DOM node that snuck in
|
|
106
|
-
return vnode;
|
|
107
|
-
}
|
|
108
|
-
const el = document.createElement(vnode.tag);
|
|
109
|
-
vnode.el = el;
|
|
110
|
-
updateProps(el, vnode.props, {});
|
|
111
|
-
for (const child of vnode.children) {
|
|
112
|
-
el.appendChild(createDOMNode(child));
|
|
113
|
-
}
|
|
114
|
-
return el;
|
|
115
|
-
}
|
|
116
|
-
function changed(node1, node2) {
|
|
117
|
-
if (typeof node1 !== typeof node2)
|
|
118
|
-
return true;
|
|
119
|
-
if (typeof node1 === "string" && node1 !== node2)
|
|
120
|
-
return true;
|
|
121
|
-
if (typeof node1 === "object" && typeof node2 === "object") {
|
|
122
|
-
const nt1 = node1.nodeType;
|
|
123
|
-
const nt2 = node2.nodeType;
|
|
124
|
-
if (nt1 !== undefined || nt2 !== undefined) {
|
|
125
|
-
if (nt1 !== nt2)
|
|
126
|
-
return true;
|
|
127
|
-
if (nt1 === 3)
|
|
128
|
-
return node1.data !== node2.data;
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
if (node1.tag !== node2.tag)
|
|
132
|
-
return true;
|
|
133
|
-
}
|
|
134
|
-
return false;
|
|
135
|
-
}
|
|
136
|
-
function updateProps(el, newProps, oldProps) {
|
|
137
|
-
// Remove old props
|
|
138
|
-
for (const key in oldProps) {
|
|
139
|
-
if (!(key in newProps)) {
|
|
140
|
-
if (key === "style") {
|
|
141
|
-
el.style.cssText = "";
|
|
142
|
-
}
|
|
143
|
-
else if (key.startsWith("on")) {
|
|
144
|
-
// We handle event listeners via a unified dispatcher to easily update them
|
|
145
|
-
removeEvent(el, key);
|
|
146
|
-
}
|
|
147
|
-
else if (key === "className") {
|
|
148
|
-
el.className = "";
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
el[key] = undefined;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
// Set new props
|
|
156
|
-
for (const key in newProps) {
|
|
157
|
-
const value = newProps[key];
|
|
158
|
-
const oldValue = oldProps[key];
|
|
159
|
-
if (value === oldValue)
|
|
160
|
-
continue;
|
|
161
|
-
if (key === "style") {
|
|
162
|
-
if (typeof value === "object") {
|
|
163
|
-
// Clear previous style first to handle removed properties
|
|
164
|
-
el.style.cssText = "";
|
|
165
|
-
Object.assign(el.style, value);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
else if (key.startsWith("on") && typeof value === "function") {
|
|
169
|
-
updateEvent(el, key, value);
|
|
170
|
-
}
|
|
171
|
-
else if (key === "className") {
|
|
172
|
-
el.className = String(value ?? "");
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
el[key] = value;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
// Global event registry for elements so we can easily swap listeners without removing/re-adding DOM listeners constantly.
|
|
180
|
-
const eventRegistry = new WeakMap();
|
|
181
|
-
function getRegistry(el) {
|
|
182
|
-
let reg = eventRegistry.get(el);
|
|
183
|
-
if (!reg) {
|
|
184
|
-
reg = {};
|
|
185
|
-
eventRegistry.set(el, reg);
|
|
186
|
-
}
|
|
187
|
-
return reg;
|
|
188
|
-
}
|
|
189
|
-
function updateEvent(el, propKey, handler) {
|
|
190
|
-
const eventName = propKey.slice(2).toLowerCase();
|
|
191
|
-
const reg = getRegistry(el);
|
|
192
|
-
if (!reg[eventName]) {
|
|
193
|
-
// Add real DOM listener once
|
|
194
|
-
el.addEventListener(eventName, (e) => {
|
|
195
|
-
const currentHandler = getRegistry(el)[eventName];
|
|
196
|
-
if (currentHandler) {
|
|
197
|
-
// Wrap the native event with React-like synthetic structure for compatibility with existing UI code
|
|
198
|
-
currentHandler(e);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
// Just update the stored reference
|
|
203
|
-
reg[eventName] = handler;
|
|
204
|
-
}
|
|
205
|
-
function removeEvent(el, propKey) {
|
|
206
|
-
const eventName = propKey.slice(2).toLowerCase();
|
|
207
|
-
const reg = getRegistry(el);
|
|
208
|
-
if (reg[eventName]) {
|
|
209
|
-
delete reg[eventName];
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
//# sourceMappingURL=dom.js.map
|
package/dist/dom.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../src/dom.ts"],"names":[],"mappings":"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"}
|
package/dist/nav.d.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { type StateFlow } from "./stateflow.js";
|
|
2
|
-
import type { VNode } from "./dom.js";
|
|
3
|
-
/** Information about the currently active destination in the back stack. */
|
|
4
|
-
export interface BackStackEntry {
|
|
5
|
-
/** The matched route pattern, e.g. "profile/{userId}" */
|
|
6
|
-
route: string;
|
|
7
|
-
/** The actual navigated path, e.g. "profile/42" */
|
|
8
|
-
destination: string;
|
|
9
|
-
/** Path parameters extracted from the pattern, e.g. { userId: "42" } */
|
|
10
|
-
arguments: Record<string, string>;
|
|
11
|
-
}
|
|
12
|
-
/** Options passed to NavController.navigate(). */
|
|
13
|
-
export interface NavOptions {
|
|
14
|
-
/** Pop back stack until this route pattern is reached before pushing the new destination. */
|
|
15
|
-
popUpTo?: string;
|
|
16
|
-
/** Whether to also pop the popUpTo destination itself. Default false. */
|
|
17
|
-
popUpToInclusive?: boolean;
|
|
18
|
-
/** Skip pushing if the current destination is already this route. Default false. */
|
|
19
|
-
launchSingleTop?: boolean;
|
|
20
|
-
}
|
|
21
|
-
interface CompiledRoute {
|
|
22
|
-
pattern: string;
|
|
23
|
-
regex: RegExp;
|
|
24
|
-
paramNames: string[];
|
|
25
|
-
content: (entry: BackStackEntry) => VNode;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Collects route definitions registered by composable() calls.
|
|
29
|
-
* Passed as the argument to the NavHost trailing-block lambda.
|
|
30
|
-
*/
|
|
31
|
-
export declare class NavGraphBuilder {
|
|
32
|
-
/** @internal */
|
|
33
|
-
readonly _routes: CompiledRoute[];
|
|
34
|
-
/**
|
|
35
|
-
* Register a route destination.
|
|
36
|
-
*
|
|
37
|
-
* @param pattern Route pattern with optional {param} placeholders,
|
|
38
|
-
* e.g. "home", "profile/{userId}", "post/{id}/comments".
|
|
39
|
-
* @param content Composable that renders this destination.
|
|
40
|
-
* Receives the BackStackEntry so it can read route arguments.
|
|
41
|
-
*/
|
|
42
|
-
composable(pattern: string, content: (entry: BackStackEntry) => VNode): void;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Manages the navigation back stack and drives route transitions.
|
|
46
|
-
*
|
|
47
|
-
* Create one via rememberNavController() and pass it to NavHost.
|
|
48
|
-
* Then thread it to screens that need to trigger navigation.
|
|
49
|
-
*/
|
|
50
|
-
export declare class NavController {
|
|
51
|
-
private readonly _backStack;
|
|
52
|
-
/** The top-most entry in the back stack, or null before the first navigation. */
|
|
53
|
-
readonly currentBackStackEntry: StateFlow<BackStackEntry | null>;
|
|
54
|
-
private _resolver;
|
|
55
|
-
constructor();
|
|
56
|
-
private _navigateTo;
|
|
57
|
-
/** @internal — NavHost sets this on every render. */
|
|
58
|
-
_setResolver(resolver: (destination: string) => BackStackEntry): void;
|
|
59
|
-
/** @internal — NavHost calls this once on mount to seed the initial destination. */
|
|
60
|
-
_initFromHash(startDestination: string): void;
|
|
61
|
-
private _popTo;
|
|
62
|
-
/**
|
|
63
|
-
* Navigate to a destination.
|
|
64
|
-
*
|
|
65
|
-
* @param destination The literal path to navigate to, e.g. "profile/42".
|
|
66
|
-
* This is the *destination* string, not the route pattern.
|
|
67
|
-
*/
|
|
68
|
-
navigate(destination: string, options?: NavOptions): void;
|
|
69
|
-
/**
|
|
70
|
-
* Pop the current destination off the back stack (the system back action).
|
|
71
|
-
* Returns true if navigation happened, false if the stack had only one entry.
|
|
72
|
-
*/
|
|
73
|
-
popBackStack(): boolean;
|
|
74
|
-
/** Returns true if there is a previous destination to pop to. */
|
|
75
|
-
canPopBackStack(): boolean;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Creates a NavController and remembers it across recompositions.
|
|
79
|
-
* Call this at the root of your component tree.
|
|
80
|
-
*/
|
|
81
|
-
export declare function rememberNavController(): NavController;
|
|
82
|
-
/**
|
|
83
|
-
* The root navigation composable. Renders whichever route matches the current
|
|
84
|
-
* destination in the NavController's back stack.
|
|
85
|
-
*
|
|
86
|
-
* The children block receives a NavGraphBuilder and should call
|
|
87
|
-
* graph.composable() to register each destination:
|
|
88
|
-
*
|
|
89
|
-
* NavHost(navController = nav, startDestination = "home") { graph ->
|
|
90
|
-
* graph.composable("home") { HomeScreen(navController = nav) }
|
|
91
|
-
* graph.composable("profile/{userId}") { entry ->
|
|
92
|
-
* ProfileScreen(userId = entry.arguments["userId"], navController = nav)
|
|
93
|
-
* }
|
|
94
|
-
* }
|
|
95
|
-
*
|
|
96
|
-
* In compiled TypeScript the children array will contain a single function
|
|
97
|
-
* (graph: NavGraphBuilder) => void that populates the builder.
|
|
98
|
-
*/
|
|
99
|
-
export declare function NavHost(props: {
|
|
100
|
-
navController: NavController;
|
|
101
|
-
startDestination: string;
|
|
102
|
-
}, children?: Array<((builder: NavGraphBuilder) => void) | any>): VNode;
|
|
103
|
-
export {};
|
|
104
|
-
//# sourceMappingURL=nav.d.ts.map
|
package/dist/nav.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nav.d.ts","sourceRoot":"","sources":["../src/nav.ts"],"names":[],"mappings":"AAaA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAElE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAOtC,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,kDAAkD;AAClD,MAAM,WAAW,UAAU;IACzB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oFAAoF;IACpF,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAMD,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,KAAK,CAAC;CAC3C;AAsCD;;;GAGG;AACH,qBAAa,eAAe;IAC1B,gBAAgB;IAChB,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,CAAM;IAEvC;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,KAAK,GAAG,IAAI;CAI7E;AAuBD;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8C;IAEzE,iFAAiF;IACjF,QAAQ,CAAC,qBAAqB,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAIjE,OAAO,CAAC,SAAS,CAA0D;;IAqB3E,OAAO,CAAC,WAAW;IAQnB,qDAAqD;IACrD,YAAY,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,cAAc,GAAG,IAAI;IAIrE,oFAAoF;IACpF,aAAa,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAK7C,OAAO,CAAC,MAAM;IAed;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAsBzD;;;OAGG;IACH,YAAY,IAAI,OAAO;IAUvB,iEAAiE;IACjE,eAAe,IAAI,OAAO;CAG3B;AAMD;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,aAAa,CAErD;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CACrB,KAAK,EAAE;IAAE,aAAa,EAAE,aAAa,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,EACjE,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,GAC3D,KAAK,CAiDP"}
|
package/dist/nav.js
DELETED
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
2
|
-
// Jalvin Router — Compose Navigation-style declarative routing
|
|
3
|
-
//
|
|
4
|
-
// API mirrors Jetpack Compose Navigation:
|
|
5
|
-
// val nav = rememberNavController()
|
|
6
|
-
// NavHost(navController = nav, startDestination = "home") { graph ->
|
|
7
|
-
// graph.composable("home") { HomeScreen(navController = nav) }
|
|
8
|
-
// graph.composable("profile/{userId}") { entry ->
|
|
9
|
-
// ProfileScreen(userId = entry.arguments["userId"])
|
|
10
|
-
// }
|
|
11
|
-
// }
|
|
12
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
-
import { MutableStateFlow } from "./stateflow.js";
|
|
14
|
-
import { remember, collectAsState } from "./ui.js";
|
|
15
|
-
import { jalvinCreateElement } from "./dom.js";
|
|
16
|
-
function compilePattern(pattern) {
|
|
17
|
-
const paramNames = [];
|
|
18
|
-
// Split on {paramName} to alternate between literal segments and param slots
|
|
19
|
-
const parts = pattern.split(/\{(\w+)\}/);
|
|
20
|
-
let regexStr = "";
|
|
21
|
-
for (let i = 0; i < parts.length; i++) {
|
|
22
|
-
if (i % 2 === 0) {
|
|
23
|
-
// Literal segment — escape regex metacharacters
|
|
24
|
-
regexStr += (parts[i] ?? "").replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
// Param slot — capture any non-slash sequence
|
|
28
|
-
paramNames.push(parts[i] ?? "");
|
|
29
|
-
regexStr += "([^/]+)";
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return { regex: new RegExp(`^${regexStr}$`), paramNames };
|
|
33
|
-
}
|
|
34
|
-
function matchRoute(routes, destination) {
|
|
35
|
-
for (const route of routes) {
|
|
36
|
-
const match = destination.match(route.regex);
|
|
37
|
-
if (match) {
|
|
38
|
-
const args = {};
|
|
39
|
-
route.paramNames.forEach((name, i) => {
|
|
40
|
-
args[name] = decodeURIComponent(match[i + 1] ?? "");
|
|
41
|
-
});
|
|
42
|
-
return { route: route.pattern, destination, arguments: args };
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
48
|
-
// NavGraphBuilder — the DSL block inside NavHost { graph -> ... }
|
|
49
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
50
|
-
/**
|
|
51
|
-
* Collects route definitions registered by composable() calls.
|
|
52
|
-
* Passed as the argument to the NavHost trailing-block lambda.
|
|
53
|
-
*/
|
|
54
|
-
export class NavGraphBuilder {
|
|
55
|
-
/** @internal */
|
|
56
|
-
_routes = [];
|
|
57
|
-
/**
|
|
58
|
-
* Register a route destination.
|
|
59
|
-
*
|
|
60
|
-
* @param pattern Route pattern with optional {param} placeholders,
|
|
61
|
-
* e.g. "home", "profile/{userId}", "post/{id}/comments".
|
|
62
|
-
* @param content Composable that renders this destination.
|
|
63
|
-
* Receives the BackStackEntry so it can read route arguments.
|
|
64
|
-
*/
|
|
65
|
-
composable(pattern, content) {
|
|
66
|
-
const { regex, paramNames } = compilePattern(pattern);
|
|
67
|
-
this._routes.push({ pattern, regex, paramNames, content });
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
71
|
-
// Hash-based URL helpers
|
|
72
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
73
|
-
function getHashDestination() {
|
|
74
|
-
if (typeof window === "undefined")
|
|
75
|
-
return "";
|
|
76
|
-
const hash = window.location.hash;
|
|
77
|
-
if (hash.startsWith("#/"))
|
|
78
|
-
return hash.slice(2);
|
|
79
|
-
if (hash.startsWith("#"))
|
|
80
|
-
return hash.slice(1);
|
|
81
|
-
return "";
|
|
82
|
-
}
|
|
83
|
-
function setHashDestination(destination) {
|
|
84
|
-
if (typeof window === "undefined")
|
|
85
|
-
return;
|
|
86
|
-
window.location.hash = destination ? "#/" + destination : "#/";
|
|
87
|
-
}
|
|
88
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
89
|
-
// NavController
|
|
90
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
91
|
-
/**
|
|
92
|
-
* Manages the navigation back stack and drives route transitions.
|
|
93
|
-
*
|
|
94
|
-
* Create one via rememberNavController() and pass it to NavHost.
|
|
95
|
-
* Then thread it to screens that need to trigger navigation.
|
|
96
|
-
*/
|
|
97
|
-
export class NavController {
|
|
98
|
-
_backStack = new MutableStateFlow([]);
|
|
99
|
-
/** The top-most entry in the back stack, or null before the first navigation. */
|
|
100
|
-
currentBackStackEntry;
|
|
101
|
-
// The resolver is updated by NavHost on every render so it always reflects
|
|
102
|
-
// the current route table (in case routes are defined dynamically).
|
|
103
|
-
_resolver = null;
|
|
104
|
-
constructor() {
|
|
105
|
-
const currentFlow = new MutableStateFlow(null);
|
|
106
|
-
this.currentBackStackEntry = currentFlow;
|
|
107
|
-
// Derive currentBackStackEntry from the back stack top
|
|
108
|
-
this._backStack.collect((stack) => {
|
|
109
|
-
currentFlow.value = stack.length > 0 ? (stack[stack.length - 1] ?? null) : null;
|
|
110
|
-
});
|
|
111
|
-
// Sync with browser back/forward buttons
|
|
112
|
-
if (typeof window !== "undefined") {
|
|
113
|
-
window.addEventListener("hashchange", () => {
|
|
114
|
-
this._navigateTo(getHashDestination());
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// Resolves a destination string → BackStackEntry and pushes it, unless
|
|
119
|
-
// we're already there.
|
|
120
|
-
_navigateTo(destination) {
|
|
121
|
-
if (!this._resolver)
|
|
122
|
-
return;
|
|
123
|
-
const current = this.currentBackStackEntry.value;
|
|
124
|
-
if (current?.destination === destination)
|
|
125
|
-
return;
|
|
126
|
-
const entry = this._resolver(destination);
|
|
127
|
-
this._backStack.update((s) => [...s, entry]);
|
|
128
|
-
}
|
|
129
|
-
/** @internal — NavHost sets this on every render. */
|
|
130
|
-
_setResolver(resolver) {
|
|
131
|
-
this._resolver = resolver;
|
|
132
|
-
}
|
|
133
|
-
/** @internal — NavHost calls this once on mount to seed the initial destination. */
|
|
134
|
-
_initFromHash(startDestination) {
|
|
135
|
-
const initial = getHashDestination() || startDestination;
|
|
136
|
-
this._navigateTo(initial);
|
|
137
|
-
}
|
|
138
|
-
_popTo(routePattern, inclusive) {
|
|
139
|
-
this._backStack.update((stack) => {
|
|
140
|
-
// Find the last occurrence of the pattern in the stack
|
|
141
|
-
let idx = -1;
|
|
142
|
-
for (let i = stack.length - 1; i >= 0; i--) {
|
|
143
|
-
if (stack[i]?.route === routePattern) {
|
|
144
|
-
idx = i;
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
if (idx === -1)
|
|
149
|
-
return stack;
|
|
150
|
-
return inclusive ? stack.slice(0, idx) : stack.slice(0, idx + 1);
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Navigate to a destination.
|
|
155
|
-
*
|
|
156
|
-
* @param destination The literal path to navigate to, e.g. "profile/42".
|
|
157
|
-
* This is the *destination* string, not the route pattern.
|
|
158
|
-
*/
|
|
159
|
-
navigate(destination, options) {
|
|
160
|
-
if (options?.popUpTo !== undefined) {
|
|
161
|
-
this._popTo(options.popUpTo, options.popUpToInclusive ?? false);
|
|
162
|
-
}
|
|
163
|
-
if (options?.launchSingleTop &&
|
|
164
|
-
this.currentBackStackEntry.value?.destination === destination) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
const prevHash = getHashDestination();
|
|
168
|
-
setHashDestination(destination);
|
|
169
|
-
// If the hash was already at this destination, hashchange won't fire,
|
|
170
|
-
// so we push directly.
|
|
171
|
-
if (prevHash === destination) {
|
|
172
|
-
this._navigateTo(destination);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Pop the current destination off the back stack (the system back action).
|
|
177
|
-
* Returns true if navigation happened, false if the stack had only one entry.
|
|
178
|
-
*/
|
|
179
|
-
popBackStack() {
|
|
180
|
-
const stack = this._backStack.value;
|
|
181
|
-
if (stack.length <= 1)
|
|
182
|
-
return false;
|
|
183
|
-
const prev = stack[stack.length - 2];
|
|
184
|
-
this._backStack.update((s) => s.slice(0, -1));
|
|
185
|
-
setHashDestination(prev.destination);
|
|
186
|
-
return true;
|
|
187
|
-
}
|
|
188
|
-
/** Returns true if there is a previous destination to pop to. */
|
|
189
|
-
canPopBackStack() {
|
|
190
|
-
return this._backStack.value.length > 1;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
194
|
-
// rememberNavController
|
|
195
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
196
|
-
/**
|
|
197
|
-
* Creates a NavController and remembers it across recompositions.
|
|
198
|
-
* Call this at the root of your component tree.
|
|
199
|
-
*/
|
|
200
|
-
export function rememberNavController() {
|
|
201
|
-
return remember(() => new NavController());
|
|
202
|
-
}
|
|
203
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
204
|
-
// NavHost
|
|
205
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
206
|
-
/**
|
|
207
|
-
* The root navigation composable. Renders whichever route matches the current
|
|
208
|
-
* destination in the NavController's back stack.
|
|
209
|
-
*
|
|
210
|
-
* The children block receives a NavGraphBuilder and should call
|
|
211
|
-
* graph.composable() to register each destination:
|
|
212
|
-
*
|
|
213
|
-
* NavHost(navController = nav, startDestination = "home") { graph ->
|
|
214
|
-
* graph.composable("home") { HomeScreen(navController = nav) }
|
|
215
|
-
* graph.composable("profile/{userId}") { entry ->
|
|
216
|
-
* ProfileScreen(userId = entry.arguments["userId"], navController = nav)
|
|
217
|
-
* }
|
|
218
|
-
* }
|
|
219
|
-
*
|
|
220
|
-
* In compiled TypeScript the children array will contain a single function
|
|
221
|
-
* (graph: NavGraphBuilder) => void that populates the builder.
|
|
222
|
-
*/
|
|
223
|
-
export function NavHost(props, children) {
|
|
224
|
-
const { navController, startDestination } = props;
|
|
225
|
-
// Build the route table by running the DSL block
|
|
226
|
-
const graph = new NavGraphBuilder();
|
|
227
|
-
if (children) {
|
|
228
|
-
for (const child of children) {
|
|
229
|
-
if (typeof child === "function")
|
|
230
|
-
child(graph);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
const routes = graph._routes;
|
|
234
|
-
// Resolver: maps a raw destination string to a BackStackEntry using the route table.
|
|
235
|
-
// Falls back to a synthetic entry (triggers 404 render) if no pattern matches.
|
|
236
|
-
const resolve = (destination) => matchRoute(routes, destination) ?? {
|
|
237
|
-
route: destination,
|
|
238
|
-
destination,
|
|
239
|
-
arguments: {},
|
|
240
|
-
};
|
|
241
|
-
// Keep the resolver current so hashchange events always use the latest routes.
|
|
242
|
-
navController._setResolver(resolve);
|
|
243
|
-
// Seed the initial destination once on mount.
|
|
244
|
-
remember(() => {
|
|
245
|
-
navController._initFromHash(startDestination);
|
|
246
|
-
return true;
|
|
247
|
-
}, [navController, startDestination]);
|
|
248
|
-
// Subscribe to route changes — this re-renders NavHost when destination changes.
|
|
249
|
-
const current = collectAsState(navController.currentBackStackEntry);
|
|
250
|
-
if (!current) {
|
|
251
|
-
// Still initializing; render nothing.
|
|
252
|
-
return jalvinCreateElement("div", { style: { display: "none" } });
|
|
253
|
-
}
|
|
254
|
-
const matched = routes.find((r) => r.pattern === current.route);
|
|
255
|
-
if (matched) {
|
|
256
|
-
return matched.content(current);
|
|
257
|
-
}
|
|
258
|
-
// No route matched — render a 404 placeholder.
|
|
259
|
-
return jalvinCreateElement("div", { style: { padding: "16px", color: "#c00", fontFamily: "monospace" } }, `404 — no route matched "${current.destination}"`);
|
|
260
|
-
}
|
|
261
|
-
//# sourceMappingURL=nav.js.map
|
package/dist/nav.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nav.js","sourceRoot":"","sources":["../src/nav.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,+DAA+D;AAC/D,EAAE;AACF,0CAA0C;AAC1C,sCAAsC;AACtC,uEAAuE;AACvE,mEAAmE;AACnE,sDAAsD;AACtD,0DAA0D;AAC1D,QAAQ;AACR,MAAM;AACN,gFAAgF;AAEhF,OAAO,EAAE,gBAAgB,EAAkB,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAqC/C,SAAS,cAAc,CAAC,OAAe;IACrC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,6EAA6E;IAC7E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACzC,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAChB,gDAAgD;YAChD,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACN,8CAA8C;YAC9C,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAChC,QAAQ,IAAI,SAAS,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,MAAM,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,UAAU,EAAE,CAAC;AAC5D,CAAC;AAED,SAAS,UAAU,CAAC,MAAuB,EAAE,WAAmB;IAC9D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAA2B,EAAE,CAAC;YACxC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;gBACnC,IAAI,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC;YACH,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAChE,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gFAAgF;AAChF,kEAAkE;AAClE,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,OAAO,eAAe;IAC1B,gBAAgB;IACP,OAAO,GAAoB,EAAE,CAAC;IAEvC;;;;;;;OAOG;IACH,UAAU,CAAC,OAAe,EAAE,OAAyC;QACnE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7D,CAAC;CACF;AAED,gFAAgF;AAChF,yBAAyB;AACzB,gFAAgF;AAEhF,SAAS,kBAAkB;IACzB,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;IAClC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/C,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,kBAAkB,CAAC,WAAmB;IAC7C,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO;IAC1C,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AACjE,CAAC;AAED,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,OAAO,aAAa;IACP,UAAU,GAAG,IAAI,gBAAgB,CAAmB,EAAE,CAAC,CAAC;IAEzE,iFAAiF;IACxE,qBAAqB,CAAmC;IAEjE,2EAA2E;IAC3E,oEAAoE;IAC5D,SAAS,GAAqD,IAAI,CAAC;IAE3E;QACE,MAAM,WAAW,GAAG,IAAI,gBAAgB,CAAwB,IAAI,CAAC,CAAC;QACtE,IAAI,CAAC,qBAAqB,GAAG,WAAW,CAAC;QAEzC,uDAAuD;QACvD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAChC,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAClF,CAAC,CAAC,CAAC;QAEH,yCAAyC;QACzC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE;gBACzC,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC,CAAC;YACzC,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,uBAAuB;IACf,WAAW,CAAC,WAAmB;QACrC,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC;QACjD,IAAI,OAAO,EAAE,WAAW,KAAK,WAAW;YAAE,OAAO;QACjD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,qDAAqD;IACrD,YAAY,CAAC,QAAiD;QAC5D,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,oFAAoF;IACpF,aAAa,CAAC,gBAAwB;QACpC,MAAM,OAAO,GAAG,kBAAkB,EAAE,IAAI,gBAAgB,CAAC;QACzD,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAEO,MAAM,CAAC,YAAoB,EAAE,SAAkB;QACrD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YAC/B,uDAAuD;YACvD,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC;YACb,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,YAAY,EAAE,CAAC;oBACrC,GAAG,GAAG,CAAC,CAAC;oBACR,MAAM;gBACR,CAAC;YACH,CAAC;YACD,IAAI,GAAG,KAAK,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC7B,OAAO,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,WAAmB,EAAE,OAAoB;QAChD,IAAI,OAAO,EAAE,OAAO,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,IAAI,KAAK,CAAC,CAAC;QAClE,CAAC;QAED,IACE,OAAO,EAAE,eAAe;YACxB,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,WAAW,KAAK,WAAW,EAC7D,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;QACtC,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAEhC,sEAAsE;QACtE,uBAAuB;QACvB,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC7B,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,YAAY;QACV,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QACpC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QAEpC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;QACtC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iEAAiE;IACjE,eAAe;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1C,CAAC;CACF;AAED,gFAAgF;AAChF,wBAAwB;AACxB,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAEhF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,OAAO,CACrB,KAAiE,EACjE,QAA4D;IAE5D,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC;IAElD,iDAAiD;IACjD,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;IACpC,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,OAAO,KAAK,KAAK,UAAU;gBAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;IAE7B,qFAAqF;IACrF,+EAA+E;IAC/E,MAAM,OAAO,GAAG,CAAC,WAAmB,EAAkB,EAAE,CACtD,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI;QACjC,KAAK,EAAE,WAAW;QAClB,WAAW;QACX,SAAS,EAAE,EAAE;KACd,CAAC;IAEJ,+EAA+E;IAC/E,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAEpC,8CAA8C;IAC9C,QAAQ,CAAC,GAAG,EAAE;QACZ,aAAa,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC,EAAE,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAEtC,iFAAiF;IACjF,MAAM,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAEpE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,sCAAsC;QACtC,OAAO,mBAAmB,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IAChE,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,+CAA+C;IAC/C,OAAO,mBAAmB,CACxB,KAAK,EACL,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EACtE,2BAA2B,OAAO,CAAC,WAAW,GAAG,CAClD,CAAC;AACJ,CAAC"}
|