@llui/dom 0.0.4 → 0.0.5
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/el-split.d.ts.map +1 -1
- package/dist/el-split.js +4 -12
- package/dist/el-split.js.map +1 -1
- package/dist/el-template.d.ts.map +1 -1
- package/dist/el-template.js +4 -15
- package/dist/el-template.js.map +1 -1
- package/dist/hmr.d.ts.map +1 -1
- package/dist/hmr.js +2 -0
- package/dist/hmr.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/primitives/branch.d.ts.map +1 -1
- package/dist/primitives/branch.js +2 -0
- package/dist/primitives/branch.js.map +1 -1
- package/dist/primitives/each.d.ts +4 -0
- package/dist/primitives/each.d.ts.map +1 -1
- package/dist/primitives/each.js +236 -105
- package/dist/primitives/each.js.map +1 -1
- package/dist/primitives/selector.d.ts +7 -11
- package/dist/primitives/selector.d.ts.map +1 -1
- package/dist/primitives/selector.js +71 -59
- package/dist/primitives/selector.js.map +1 -1
- package/dist/primitives/text.d.ts.map +1 -1
- package/dist/primitives/text.js +4 -4
- package/dist/primitives/text.js.map +1 -1
- package/dist/scope.d.ts +15 -0
- package/dist/scope.d.ts.map +1 -1
- package/dist/scope.js +96 -15
- package/dist/scope.js.map +1 -1
- package/dist/structural.d.ts +14 -0
- package/dist/structural.d.ts.map +1 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/update-loop.d.ts +15 -0
- package/dist/update-loop.d.ts.map +1 -1
- package/dist/update-loop.js +98 -29
- package/dist/update-loop.js.map +1 -1
- package/package.json +1 -1
- package/dist/chain-update.d.ts +0 -7
- package/dist/chain-update.d.ts.map +0 -1
- package/dist/chain-update.js +0 -16
- package/dist/chain-update.js.map +0 -1
|
@@ -2,103 +2,115 @@ import { getRenderContext } from '../render-context';
|
|
|
2
2
|
import { createBinding, applyBinding } from '../binding';
|
|
3
3
|
import { addDisposer } from '../scope';
|
|
4
4
|
import { FULL_MASK } from '../update-loop';
|
|
5
|
+
import { registerOnClear } from './each';
|
|
5
6
|
/**
|
|
6
7
|
* Optimized "one-of-N" reactive binding — O(1) updates instead of O(n).
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
9
|
+
* Uses a generation counter instead of per-row disposers:
|
|
10
|
+
* - bind() tags entries with the current generation
|
|
11
|
+
* - Individual row removal bumps the generation for that entry (set gen = -1)
|
|
12
|
+
* - Bulk clear bumps the generation and clears the registry via registerOnClear
|
|
13
|
+
* - updateSelector() skips stale entries (gen !== current) and compacts lazily
|
|
10
14
|
*
|
|
11
|
-
*
|
|
12
|
-
* // In view, before each():
|
|
13
|
-
* const sel = selector<State, number>(s => s.selected)
|
|
14
|
-
*
|
|
15
|
-
* // Inside each() render:
|
|
16
|
-
* tr({ class: sel.bind(item(r => r.id), 'class', match => match ? 'danger' : '') })
|
|
17
|
-
*
|
|
18
|
-
* sel.bind() creates and manages the DOM binding directly.
|
|
19
|
-
* Returns Node[] to spread into the element's children (empty — no visible output).
|
|
15
|
+
* Zero per-row closure allocations. Zero Set.delete calls on disposal.
|
|
20
16
|
*/
|
|
21
17
|
export function selector(field) {
|
|
22
18
|
const ctx = getRenderContext();
|
|
23
19
|
const scope = ctx.rootScope;
|
|
24
20
|
const registry = new Map();
|
|
25
21
|
let lastValue = field(ctx.state);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
entry.lastValue = v;
|
|
41
|
-
applyBinding({ kind: entry.kind, node: entry.node, key: entry.key }, v);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
22
|
+
let generation = 0;
|
|
23
|
+
let registeredOnClear = false;
|
|
24
|
+
function updateBucket(bucket, match, gen) {
|
|
25
|
+
let hasStale = false;
|
|
26
|
+
for (let i = 0; i < bucket.length; i++) {
|
|
27
|
+
const entry = bucket[i];
|
|
28
|
+
if (entry.gen !== gen) {
|
|
29
|
+
hasStale = true;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const v = entry.transform(match);
|
|
33
|
+
if (!Object.is(v, entry.lastValue)) {
|
|
34
|
+
entry.lastValue = v;
|
|
35
|
+
applyBinding({ kind: entry.kind, node: entry.node, key: entry.key }, v);
|
|
44
36
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
applyBinding({ kind: entry.kind, node: entry.node, key: entry.key }, v);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
37
|
+
}
|
|
38
|
+
// Lazy compaction — remove stale entries when encountered
|
|
39
|
+
if (hasStale) {
|
|
40
|
+
let w = 0;
|
|
41
|
+
for (let r = 0; r < bucket.length; r++) {
|
|
42
|
+
if (bucket[r].gen === gen)
|
|
43
|
+
bucket[w++] = bucket[r];
|
|
55
44
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
bucket.length = w;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function updateSelector(state) {
|
|
49
|
+
const newValue = field(state);
|
|
50
|
+
if (Object.is(newValue, lastValue))
|
|
51
|
+
return lastValue;
|
|
52
|
+
const gen = generation;
|
|
53
|
+
const oldBucket = registry.get(lastValue);
|
|
54
|
+
if (oldBucket)
|
|
55
|
+
updateBucket(oldBucket, false, gen);
|
|
56
|
+
const newBucket = registry.get(newValue);
|
|
57
|
+
if (newBucket)
|
|
58
|
+
updateBucket(newBucket, true, gen);
|
|
59
|
+
lastValue = newValue;
|
|
60
|
+
return newValue;
|
|
61
|
+
}
|
|
62
|
+
createBinding(scope, {
|
|
63
|
+
mask: FULL_MASK,
|
|
64
|
+
accessor: ((state) => updateSelector(state)),
|
|
59
65
|
kind: 'text',
|
|
60
66
|
node: document.createComment('selector'),
|
|
61
67
|
perItem: false,
|
|
62
68
|
});
|
|
63
69
|
return {
|
|
64
|
-
/**
|
|
65
|
-
* Bind a DOM node to this selector. Called per row inside each().
|
|
66
|
-
* Applies the initial value and registers for O(1) future updates.
|
|
67
|
-
*
|
|
68
|
-
* @param node - The DOM element to bind
|
|
69
|
-
* @param key - The per-item value to compare against the state field
|
|
70
|
-
* @param kind - Binding kind ('class', 'attr', 'prop', etc.)
|
|
71
|
-
* @param propKey - Property/attribute name (e.g., 'class')
|
|
72
|
-
* @param transform - Maps match boolean to the DOM value
|
|
73
|
-
*/
|
|
74
70
|
bind(node, key, kind, propKey, transform) {
|
|
75
71
|
const currentKey = typeof key === 'function' ? key() : key;
|
|
76
72
|
const initialMatch = Object.is(lastValue, currentKey);
|
|
77
73
|
const initialValue = transform(initialMatch);
|
|
78
|
-
// Apply initial value
|
|
79
74
|
applyBinding({ kind, node, key: propKey }, initialValue);
|
|
80
|
-
// Register in selector registry
|
|
81
75
|
const entry = {
|
|
82
76
|
node,
|
|
83
77
|
kind,
|
|
84
78
|
key: propKey,
|
|
85
79
|
lastValue: initialValue,
|
|
86
80
|
transform,
|
|
81
|
+
gen: generation,
|
|
87
82
|
};
|
|
88
83
|
let bucket = registry.get(currentKey);
|
|
89
84
|
if (!bucket) {
|
|
90
|
-
bucket =
|
|
85
|
+
bucket = [];
|
|
91
86
|
registry.set(currentKey, bucket);
|
|
92
87
|
}
|
|
93
|
-
bucket.
|
|
94
|
-
//
|
|
88
|
+
bucket.push(entry);
|
|
89
|
+
// Register bulk clear callback (once per selector per each() block)
|
|
90
|
+
if (!registeredOnClear) {
|
|
91
|
+
registerOnClear(() => {
|
|
92
|
+
generation++;
|
|
93
|
+
registry.clear();
|
|
94
|
+
});
|
|
95
|
+
registeredOnClear = true;
|
|
96
|
+
}
|
|
97
|
+
// Per-row disposer for generic reconcile paths (scope disposal).
|
|
98
|
+
// Uses generation check to skip work if already bulk-cleared.
|
|
99
|
+
const gen = generation;
|
|
95
100
|
const itemScope = getRenderContext().rootScope;
|
|
96
101
|
addDisposer(itemScope, () => {
|
|
97
|
-
|
|
98
|
-
|
|
102
|
+
if (gen !== generation)
|
|
103
|
+
return; // already bulk-cleared, no-op
|
|
104
|
+
const idx = bucket.indexOf(entry);
|
|
105
|
+
if (idx !== -1)
|
|
106
|
+
bucket.splice(idx, 1);
|
|
107
|
+
if (bucket.length === 0)
|
|
99
108
|
registry.delete(currentKey);
|
|
100
109
|
});
|
|
101
110
|
},
|
|
111
|
+
__directUpdate(state) {
|
|
112
|
+
updateSelector(state);
|
|
113
|
+
},
|
|
102
114
|
};
|
|
103
115
|
}
|
|
104
116
|
//# sourceMappingURL=selector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selector.js","sourceRoot":"","sources":["../../src/primitives/selector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"selector.js","sourceRoot":"","sources":["../../src/primitives/selector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AAYxC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,QAAQ,CAAO,KAAkB;IAC/C,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAA;IAC9B,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAA;IAE3B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAsB,CAAA;IAC9C,IAAI,SAAS,GAAM,KAAK,CAAC,GAAG,CAAC,KAAU,CAAC,CAAA;IACxC,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,iBAAiB,GAAG,KAAK,CAAA;IAE7B,SAAS,YAAY,CAAC,MAAuB,EAAE,KAAc,EAAE,GAAW;QACxE,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAE,CAAA;YACxB,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;gBACtB,QAAQ,GAAG,IAAI,CAAA;gBACf,SAAQ;YACV,CAAC;YACD,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;YAChC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;gBACnC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAA;gBACnB,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;YACzE,CAAC;QACH,CAAC;QACD,0DAA0D;QAC1D,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,CAAA;YACT,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACvC,IAAI,MAAM,CAAC,CAAC,CAAE,CAAC,GAAG,KAAK,GAAG;oBAAE,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,CAAA;YACtD,CAAC;YACD,MAAM,CAAC,MAAM,GAAG,CAAC,CAAA;QACnB,CAAC;IACH,CAAC;IAED,SAAS,cAAc,CAAC,KAAQ;QAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;QAC7B,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;YAAE,OAAO,SAAS,CAAA;QACpD,MAAM,GAAG,GAAG,UAAU,CAAA;QAEtB,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QACzC,IAAI,SAAS;YAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;QAElD,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACxC,IAAI,SAAS;YAAE,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;QAEjD,SAAS,GAAG,QAAQ,CAAA;QACpB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,aAAa,CAAC,KAAK,EAAE;QACnB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,CAAC,CAAC,KAAQ,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAA8B;QAC5E,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC;QACxC,OAAO,EAAE,KAAK;KACf,CAAC,CAAA;IAEF,OAAO;QACL,IAAI,CACF,IAAU,EACV,GAAkB,EAClB,IAAiB,EACjB,OAA2B,EAC3B,SAAsC;YAEtC,MAAM,UAAU,GAAG,OAAO,GAAG,KAAK,UAAU,CAAC,CAAC,CAAE,GAAe,EAAE,CAAC,CAAC,CAAC,GAAG,CAAA;YACvE,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;YACrD,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,CAAC,CAAA;YAE5C,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,YAAY,CAAC,CAAA;YAExD,MAAM,KAAK,GAAkB;gBAC3B,IAAI;gBACJ,IAAI;gBACJ,GAAG,EAAE,OAAO;gBACZ,SAAS,EAAE,YAAY;gBACvB,SAAS;gBACT,GAAG,EAAE,UAAU;aAChB,CAAA;YAED,IAAI,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;YACrC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,GAAG,EAAE,CAAA;gBACX,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;YAClC,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAElB,oEAAoE;YACpE,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACvB,eAAe,CAAC,GAAG,EAAE;oBACnB,UAAU,EAAE,CAAA;oBACZ,QAAQ,CAAC,KAAK,EAAE,CAAA;gBAClB,CAAC,CAAC,CAAA;gBACF,iBAAiB,GAAG,IAAI,CAAA;YAC1B,CAAC;YAED,iEAAiE;YACjE,8DAA8D;YAC9D,MAAM,GAAG,GAAG,UAAU,CAAA;YACtB,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC,SAAS,CAAA;YAC9C,WAAW,CAAC,SAAS,EAAE,GAAG,EAAE;gBAC1B,IAAI,GAAG,KAAK,UAAU;oBAAE,OAAM,CAAC,8BAA8B;gBAC7D,MAAM,GAAG,GAAG,MAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;gBAClC,IAAI,GAAG,KAAK,CAAC,CAAC;oBAAE,MAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;gBACtC,IAAI,MAAO,CAAC,MAAM,KAAK,CAAC;oBAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;YACvD,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,cAAc,CAAC,KAAc;YAC3B,cAAc,CAAC,KAAU,CAAC,CAAA;QAC5B,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/primitives/text.ts"],"names":[],"mappings":"AAKA,wBAAgB,IAAI,CAAC,CAAC,EACpB,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,MAAM,EACtD,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/primitives/text.ts"],"names":[],"mappings":"AAKA,wBAAgB,IAAI,CAAC,CAAC,EACpB,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,MAAM,EACtD,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAqCN"}
|
package/dist/primitives/text.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getRenderContext } from '../render-context';
|
|
2
2
|
import { createBinding } from '../binding';
|
|
3
|
-
import {
|
|
3
|
+
import { addCheckedItemUpdater } from '../scope';
|
|
4
4
|
import { FULL_MASK } from '../update-loop';
|
|
5
5
|
export function text(accessor, mask) {
|
|
6
6
|
if (typeof accessor === 'string') {
|
|
@@ -12,10 +12,10 @@ export function text(accessor, mask) {
|
|
|
12
12
|
// Register as direct updater, bypassing Phase 2 binding scan
|
|
13
13
|
if (accessor.length === 0) {
|
|
14
14
|
const get = accessor;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
node.nodeValue = String(get());
|
|
15
|
+
const initial = addCheckedItemUpdater(ctx.rootScope, () => String(get()), (v) => {
|
|
16
|
+
node.nodeValue = v;
|
|
18
17
|
});
|
|
18
|
+
node.nodeValue = initial;
|
|
19
19
|
return node;
|
|
20
20
|
}
|
|
21
21
|
// Component-level state accessor
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/primitives/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/primitives/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,UAAU,IAAI,CAClB,QAAsD,EACtD,IAAa;IAEb,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAA;IAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;IAExC,mEAAmE;IACnE,6DAA6D;IAC7D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,QAAwB,CAAA;QACpC,MAAM,OAAO,GAAG,qBAAqB,CACnC,GAAG,CAAC,SAAS,EACb,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,EACnB,CAAC,CAAC,EAAE,EAAE;YACJ,IAAI,CAAC,SAAS,GAAG,CAAC,CAAA;QACpB,CAAC,CACF,CAAA;QACD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAA;QACxB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,iCAAiC;IACjC,MAAM,WAAW,GAAG,IAAI,IAAI,SAAS,CAAA;IACrC,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE;QAC3C,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,QAAqC;QAC/C,IAAI,EAAE,MAAM;QACZ,IAAI;QACJ,OAAO,EAAE,KAAK;KACf,CAAC,CAAA;IACF,MAAM,YAAY,GAAI,QAA6B,CAAC,GAAG,CAAC,KAAU,CAAC,CAAA;IACnE,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;IACrC,OAAO,CAAC,SAAS,GAAG,YAAY,CAAA;IAEhC,OAAO,IAAI,CAAA;AACb,CAAC"}
|
package/dist/scope.d.ts
CHANGED
|
@@ -18,7 +18,22 @@ export declare function disposeScope(scope: Scope, skipParentRemoval?: boolean):
|
|
|
18
18
|
* individual O(N) splice operations into one O(N) scan.
|
|
19
19
|
*/
|
|
20
20
|
export declare function removeOrphanedChildren(parent: Scope): void;
|
|
21
|
+
/**
|
|
22
|
+
* Bulk dispose an array of sibling scopes — avoids per-scope function call
|
|
23
|
+
* overhead. Used by each() clear path where 1000+ scopes are disposed at once.
|
|
24
|
+
* Caller must call removeOrphanedChildren(parent) afterwards.
|
|
25
|
+
*/
|
|
26
|
+
export declare function disposeScopesBulk(scopes: Scope[]): void;
|
|
21
27
|
export declare function addBinding(scope: Scope, binding: Binding): void;
|
|
22
28
|
export declare function addItemUpdater(scope: Scope, updater: () => void): void;
|
|
29
|
+
/**
|
|
30
|
+
* Register a per-item updater that compares the new value against the last
|
|
31
|
+
* value before applying. Shared by `text()`, `elSplit()`, and `elTemplate()`
|
|
32
|
+
* so the equality-check logic lives in one place.
|
|
33
|
+
*
|
|
34
|
+
* @param apply - DOM write: receives the new value when it differs
|
|
35
|
+
* @returns the initial value (caller should apply it to the DOM)
|
|
36
|
+
*/
|
|
37
|
+
export declare function addCheckedItemUpdater<V>(scope: Scope, get: () => V, apply: (value: V) => void): V;
|
|
23
38
|
export declare function addDisposer(scope: Scope, disposer: () => void): void;
|
|
24
39
|
//# sourceMappingURL=scope.d.ts.map
|
package/dist/scope.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAoB7C,wBAAgB,WAAW,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,KAAK,CAwBvD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,iBAAiB,UAAQ,GAAG,IAAI,CAyC1E;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,CAO1D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CA4BvD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAI/D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAGtE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,CAAC,CASjG;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAGpE"}
|
package/dist/scope.js
CHANGED
|
@@ -4,16 +4,32 @@ const EMPTY_SCOPES = [];
|
|
|
4
4
|
const EMPTY_DISPOSERS = [];
|
|
5
5
|
const EMPTY_BINDINGS = [];
|
|
6
6
|
const EMPTY_UPDATERS = [];
|
|
7
|
+
// Scope pool — reuse disposed scope objects to reduce GC pressure.
|
|
8
|
+
// Capped to avoid memory leaks in apps that create/destroy thousands of rows.
|
|
9
|
+
const SCOPE_POOL = [];
|
|
10
|
+
const SCOPE_POOL_MAX = 2048;
|
|
11
|
+
/** @internal Drain the scope pool — for testing only */
|
|
12
|
+
export function _drainScopePool() {
|
|
13
|
+
SCOPE_POOL.length = 0;
|
|
14
|
+
}
|
|
7
15
|
export function createScope(parent) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
let scope;
|
|
17
|
+
if (SCOPE_POOL.length > 0) {
|
|
18
|
+
scope = SCOPE_POOL.pop();
|
|
19
|
+
scope.id = nextId++;
|
|
20
|
+
scope.parent = parent;
|
|
21
|
+
// Arrays already reset to empties by dispose
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
scope = {
|
|
25
|
+
id: nextId++,
|
|
26
|
+
parent,
|
|
27
|
+
children: EMPTY_SCOPES,
|
|
28
|
+
disposers: EMPTY_DISPOSERS,
|
|
29
|
+
bindings: EMPTY_BINDINGS,
|
|
30
|
+
itemUpdaters: EMPTY_UPDATERS,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
17
33
|
if (parent) {
|
|
18
34
|
if (parent.children === EMPTY_SCOPES)
|
|
19
35
|
parent.children = [];
|
|
@@ -37,11 +53,16 @@ export function disposeScope(scope, skipParentRemoval = false) {
|
|
|
37
53
|
if (!skipParentRemoval)
|
|
38
54
|
removeFromParent(scope);
|
|
39
55
|
scope.parent = null;
|
|
56
|
+
// Don't pool empty scopes from the early-return path — they may be
|
|
57
|
+
// disposed idempotently (twice), which would create pool duplicates
|
|
40
58
|
return;
|
|
41
59
|
}
|
|
42
|
-
|
|
60
|
+
// When skipParentRemoval is true, children don't mutate during disposal —
|
|
61
|
+
// iterate directly without allocating a copy. Otherwise, clone to avoid
|
|
62
|
+
// mutation during iteration.
|
|
63
|
+
const children = skipParentRemoval ? scope.children : scope.children.slice();
|
|
43
64
|
for (const child of children) {
|
|
44
|
-
disposeScope(child);
|
|
65
|
+
disposeScope(child, skipParentRemoval);
|
|
45
66
|
}
|
|
46
67
|
for (const disposer of scope.disposers) {
|
|
47
68
|
disposer();
|
|
@@ -53,13 +74,18 @@ export function disposeScope(scope, skipParentRemoval = false) {
|
|
|
53
74
|
binding.node = null;
|
|
54
75
|
binding.lastValue = undefined;
|
|
55
76
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
scope.
|
|
59
|
-
scope.
|
|
77
|
+
// Reset to shared empties — don't just truncate, so pooled scopes
|
|
78
|
+
// don't hold allocated-but-empty arrays
|
|
79
|
+
scope.disposers = EMPTY_DISPOSERS;
|
|
80
|
+
scope.bindings = EMPTY_BINDINGS;
|
|
81
|
+
scope.children = EMPTY_SCOPES;
|
|
82
|
+
scope.itemUpdaters = EMPTY_UPDATERS;
|
|
60
83
|
if (!skipParentRemoval)
|
|
61
84
|
removeFromParent(scope);
|
|
62
85
|
scope.parent = null;
|
|
86
|
+
// Return to pool for reuse
|
|
87
|
+
if (SCOPE_POOL.length < SCOPE_POOL_MAX)
|
|
88
|
+
SCOPE_POOL.push(scope);
|
|
63
89
|
}
|
|
64
90
|
/**
|
|
65
91
|
* Batch-remove children with `parent === null` from `parent.children`.
|
|
@@ -75,6 +101,42 @@ export function removeOrphanedChildren(parent) {
|
|
|
75
101
|
}
|
|
76
102
|
children.length = w;
|
|
77
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Bulk dispose an array of sibling scopes — avoids per-scope function call
|
|
106
|
+
* overhead. Used by each() clear path where 1000+ scopes are disposed at once.
|
|
107
|
+
* Caller must call removeOrphanedChildren(parent) afterwards.
|
|
108
|
+
*/
|
|
109
|
+
export function disposeScopesBulk(scopes) {
|
|
110
|
+
for (let i = 0; i < scopes.length; i++) {
|
|
111
|
+
const scope = scopes[i];
|
|
112
|
+
// Recursively dispose children
|
|
113
|
+
const children = scope.children;
|
|
114
|
+
if (children.length > 0) {
|
|
115
|
+
disposeScopesBulk(children);
|
|
116
|
+
}
|
|
117
|
+
// Run disposers
|
|
118
|
+
const disposers = scope.disposers;
|
|
119
|
+
for (let d = 0; d < disposers.length; d++)
|
|
120
|
+
disposers[d]();
|
|
121
|
+
// Mark bindings dead
|
|
122
|
+
const bindings = scope.bindings;
|
|
123
|
+
for (let b = 0; b < bindings.length; b++) {
|
|
124
|
+
const binding = bindings[b];
|
|
125
|
+
binding.dead = true;
|
|
126
|
+
binding.accessor = null;
|
|
127
|
+
binding.node = null;
|
|
128
|
+
binding.lastValue = undefined;
|
|
129
|
+
}
|
|
130
|
+
// Reset to shared empties + detach from parent + return to pool
|
|
131
|
+
scope.disposers = EMPTY_DISPOSERS;
|
|
132
|
+
scope.bindings = EMPTY_BINDINGS;
|
|
133
|
+
scope.children = EMPTY_SCOPES;
|
|
134
|
+
scope.itemUpdaters = EMPTY_UPDATERS;
|
|
135
|
+
scope.parent = null;
|
|
136
|
+
if (SCOPE_POOL.length < SCOPE_POOL_MAX)
|
|
137
|
+
SCOPE_POOL.push(scope);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
78
140
|
export function addBinding(scope, binding) {
|
|
79
141
|
binding.ownerScope = scope;
|
|
80
142
|
if (scope.bindings === EMPTY_BINDINGS)
|
|
@@ -86,6 +148,25 @@ export function addItemUpdater(scope, updater) {
|
|
|
86
148
|
scope.itemUpdaters = [];
|
|
87
149
|
scope.itemUpdaters.push(updater);
|
|
88
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Register a per-item updater that compares the new value against the last
|
|
153
|
+
* value before applying. Shared by `text()`, `elSplit()`, and `elTemplate()`
|
|
154
|
+
* so the equality-check logic lives in one place.
|
|
155
|
+
*
|
|
156
|
+
* @param apply - DOM write: receives the new value when it differs
|
|
157
|
+
* @returns the initial value (caller should apply it to the DOM)
|
|
158
|
+
*/
|
|
159
|
+
export function addCheckedItemUpdater(scope, get, apply) {
|
|
160
|
+
let last = get();
|
|
161
|
+
addItemUpdater(scope, () => {
|
|
162
|
+
const v = get();
|
|
163
|
+
if (v === last || (v !== v && last !== last))
|
|
164
|
+
return;
|
|
165
|
+
last = v;
|
|
166
|
+
apply(v);
|
|
167
|
+
});
|
|
168
|
+
return last;
|
|
169
|
+
}
|
|
89
170
|
export function addDisposer(scope, disposer) {
|
|
90
171
|
if (scope.disposers === EMPTY_DISPOSERS)
|
|
91
172
|
scope.disposers = [];
|
package/dist/scope.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAEA,IAAI,MAAM,GAAG,CAAC,CAAA;AAEd,+DAA+D;AAC/D,MAAM,YAAY,GAAY,EAAE,CAAA;AAChC,MAAM,eAAe,GAAsB,EAAE,CAAA;AAC7C,MAAM,cAAc,GAAc,EAAE,CAAA;AACpC,MAAM,cAAc,GAAsB,EAAE,CAAA;AAE5C,MAAM,UAAU,WAAW,CAAC,MAAoB;IAC9C,MAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"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"}
|
package/dist/structural.d.ts
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
export interface StructuralBlock {
|
|
2
|
+
/** Bitmask of state fields this block depends on. If set, the block
|
|
3
|
+
* is skipped when `(mask & dirtyMask) === 0`. FULL_MASK (default)
|
|
4
|
+
* means always run. */
|
|
5
|
+
mask: number;
|
|
2
6
|
reconcile(state: unknown, dirtyMask: number): void;
|
|
7
|
+
/** Same keys, only item data changed — skip mismatch/swap detection */
|
|
8
|
+
reconcileItems?(state: unknown): void;
|
|
9
|
+
/** Remove all items — skip items accessor, go straight to clear path */
|
|
10
|
+
reconcileClear?(): void;
|
|
11
|
+
/** Remove entries whose keys are no longer in the new items array.
|
|
12
|
+
* Avoids Map/Set allocation — linear scan with early exit. */
|
|
13
|
+
reconcileRemove?(state: unknown): void;
|
|
14
|
+
/** Update only the entries at the given indices — O(k) instead of O(n).
|
|
15
|
+
* Used when the compiler detects which indices the update loop modifies. */
|
|
16
|
+
reconcileChanged?(state: unknown, stride: number): void;
|
|
3
17
|
}
|
|
4
18
|
//# sourceMappingURL=structural.d.ts.map
|
package/dist/structural.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structural.d.ts","sourceRoot":"","sources":["../src/structural.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"structural.d.ts","sourceRoot":"","sources":["../src/structural.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B;;4BAEwB;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAClD,uEAAuE;IACvE,cAAc,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;IACrC,wEAAwE;IACxE,cAAc,CAAC,IAAI,IAAI,CAAA;IACvB;mEAC+D;IAC/D,eAAe,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;IACtC;iFAC6E;IAC7E,gBAAgB,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CACxD"}
|
package/dist/types.d.ts
CHANGED
|
@@ -41,7 +41,6 @@ export interface Scope {
|
|
|
41
41
|
children: Scope[];
|
|
42
42
|
disposers: Array<() => void>;
|
|
43
43
|
bindings: Binding[];
|
|
44
|
-
eachItemStable: boolean;
|
|
45
44
|
/** Per-item updaters — called directly by each() when item changes, bypassing Phase 2 */
|
|
46
45
|
itemUpdaters: Array<() => void>;
|
|
47
46
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/update-loop.d.ts
CHANGED
|
@@ -28,4 +28,19 @@ export declare function flushInstance<S, M, E>(inst: ComponentInstance<S, M, E>)
|
|
|
28
28
|
* snapshot/restore, not in app code.
|
|
29
29
|
*/
|
|
30
30
|
export declare function _forceState<S, M, E>(inst: ComponentInstance<S, M, E>, newState: S): void;
|
|
31
|
+
/**
|
|
32
|
+
* Run a handler for a single message: call update(), reconcile blocks
|
|
33
|
+
* with the given method, run Phase 2. Used by compiler-generated __handlers
|
|
34
|
+
* to avoid duplicating boilerplate per message type.
|
|
35
|
+
*
|
|
36
|
+
* @param method 0=reconcile, 1=reconcileItems, 2=reconcileClear, 3=reconcileRemove, -1=skip blocks
|
|
37
|
+
* @public — used by compiler-generated `__handlers`
|
|
38
|
+
*/
|
|
39
|
+
export declare function _handleMsg(inst: ComponentInstance, msg: unknown, dirty: number, method: number): [unknown, unknown[]];
|
|
40
|
+
/**
|
|
41
|
+
* Phase 2: compact dead bindings + update live bindings.
|
|
42
|
+
* Shared between genericUpdate and compiler-generated __update.
|
|
43
|
+
* @public — used by compiler-generated `__update` functions
|
|
44
|
+
*/
|
|
45
|
+
export declare function _runPhase2(state: unknown, dirty: number, bindings: Binding[], bindingsBeforePhase1: number, componentName?: string): void;
|
|
31
46
|
//# sourceMappingURL=update-loop.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-loop.d.ts","sourceRoot":"","sources":["../src/update-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAKnD,eAAO,MAAM,SAAS,QAAiB,CAAA;AAMvC,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,CAAC,GAAG,EAAE;IAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,KAAK,IAAI,GAClE,IAAI,CAEN;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IACtE,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1B,KAAK,EAAE,CAAC,CAAA;IACR,cAAc,EAAE,CAAC,EAAE,CAAA;IACnB,SAAS,EAAE,KAAK,CAAA;IAChB,WAAW,EAAE,OAAO,EAAE,CAAA;IACtB,gBAAgB,EAAE,eAAe,EAAE,CAAA;IACnC,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,kBAAkB,EAAE,OAAO,CAAA;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,CAAC,EAAE,CAAA;IAChB,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAA;IACtB,MAAM,EAAE,WAAW,CAAA;IACnB,eAAe,EAAE,eAAe,CAAA;CACjC;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC7C,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,CAAC,EAAE,OAAO,GACb,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAgC5B;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAI7E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CAiCxF"}
|
|
1
|
+
{"version":3,"file":"update-loop.d.ts","sourceRoot":"","sources":["../src/update-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAKnD,eAAO,MAAM,SAAS,QAAiB,CAAA;AAMvC,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,CAAC,GAAG,EAAE;IAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,KAAK,IAAI,GAClE,IAAI,CAEN;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IACtE,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1B,KAAK,EAAE,CAAC,CAAA;IACR,cAAc,EAAE,CAAC,EAAE,CAAA;IACnB,SAAS,EAAE,KAAK,CAAA;IAChB,WAAW,EAAE,OAAO,EAAE,CAAA;IACtB,gBAAgB,EAAE,eAAe,EAAE,CAAA;IACnC,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,kBAAkB,EAAE,OAAO,CAAA;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,CAAC,EAAE,CAAA;IAChB,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAA;IACtB,MAAM,EAAE,WAAW,CAAA;IACnB,eAAe,EAAE,eAAe,CAAA;CACjC;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC7C,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,CAAC,EAAE,OAAO,GACb,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAgC5B;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAI7E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CAiCxF;AAqGD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,iBAAiB,EACvB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAoCtB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,OAAO,EAAE,EACnB,oBAAoB,EAAE,MAAM,EAC5B,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI,CAuCN"}
|