@fluixi/compiler 1.0.0-alpha.104 → 1.0.0-alpha.106
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/analyze/static-graph.cjs +1 -1
- package/dist/analyze/static-graph.mjs +1 -1
- package/dist/{babel-5SX36G76.mjs → babel-HJY4RVAV.mjs} +33 -20
- package/dist/{chunk-NWF66YTU.mjs → chunk-4XEOMQ57.mjs} +1 -1
- package/dist/{chunk-FMQPBKTW.mjs → chunk-JUFI6IR3.mjs} +1 -1
- package/dist/{chunk-NUET3BJB.mjs → chunk-LCQHL2VQ.mjs} +132 -10
- package/dist/{chunk-2O2YW5ZO.mjs → chunk-LGUZRHYN.mjs} +2 -2
- package/dist/{chunk-RBIYCE6M.mjs → chunk-TDN5MYWI.mjs} +1 -1
- package/dist/{chunk-ZDZKJQ5N.mjs → chunk-W7DYOMXJ.mjs} +2 -2
- package/dist/{chunk-DN33T5GJ.mjs → chunk-WHEDRMNR.mjs} +1 -1
- package/dist/codegen/backends/imperative.cjs +130 -8
- package/dist/codegen/backends/imperative.d.ts.map +1 -1
- package/dist/codegen/backends/imperative.js +62 -0
- package/dist/codegen/backends/imperative.mjs +130 -8
- package/dist/codegen/partial-template.cjs +80 -8
- package/dist/codegen/partial-template.d.cts +21 -4
- package/dist/codegen/partial-template.d.ts +21 -4
- package/dist/codegen/partial-template.d.ts.map +1 -1
- package/dist/codegen/partial-template.js +0 -0
- package/dist/codegen/partial-template.mjs +80 -8
- package/dist/codegen/serialize-static.cjs +1 -0
- package/dist/codegen/serialize-static.d.cts +8 -0
- package/dist/codegen/serialize-static.d.ts +8 -0
- package/dist/codegen/serialize-static.d.ts.map +1 -1
- package/dist/codegen/serialize-static.js +1 -1
- package/dist/codegen/serialize-static.mjs +1 -0
- package/dist/frontend/babel/build-ir-html.cjs +149 -21
- package/dist/frontend/babel/build-ir-html.d.cts +3 -1
- package/dist/frontend/babel/build-ir-html.d.ts +3 -1
- package/dist/frontend/babel/build-ir-html.d.ts.map +1 -1
- package/dist/frontend/babel/build-ir-html.mjs +149 -21
- package/dist/frontend/babel/build-ir.cjs +149 -21
- package/dist/frontend/babel/build-ir.d.cts +11 -2
- package/dist/frontend/babel/build-ir.d.ts +11 -2
- package/dist/frontend/babel/build-ir.d.ts.map +1 -1
- package/dist/frontend/babel/build-ir.js +15 -9
- package/dist/frontend/babel/build-ir.mjs +149 -21
- package/dist/frontend/babel/index.cjs +160 -25
- package/dist/frontend/babel/index.mjs +160 -25
- package/dist/frontend/babel/lower-template.cjs +149 -21
- package/dist/frontend/babel/lower-template.d.cts +2 -1
- package/dist/frontend/babel/lower-template.d.ts +2 -1
- package/dist/frontend/babel/lower-template.d.ts.map +1 -1
- package/dist/frontend/babel/lower-template.js +4 -4
- package/dist/frontend/babel/lower-template.mjs +149 -21
- package/dist/frontend/babel/plugin.cjs +158 -23
- package/dist/frontend/babel/plugin.js +9 -2
- package/dist/frontend/babel/plugin.mjs +158 -23
- package/dist/index.cjs +131 -9
- package/dist/index.mjs +131 -9
- package/dist/integrations.cjs +165 -33
- package/dist/integrations.mjs +11 -11
- package/dist/lower/compile-template.cjs +131 -9
- package/dist/lower/compile-template.mjs +131 -9
- package/dist/lower/jsx.cjs +130 -8
- package/dist/lower/jsx.mjs +130 -8
- package/dist/lower/template.cjs +130 -8
- package/dist/lower/template.mjs +130 -8
- package/dist/resolve/builtins.cjs +1 -1
- package/dist/resolve/builtins.mjs +1 -1
- package/dist/{server-fns-3Z3ZKJLB.mjs → server-fns-WZJK4BJE.mjs} +5 -5
- package/dist/{server-functions-DB7AHWE6.mjs → server-functions-4KTFFEO3.mjs} +3 -3
- package/dist/transform/index.cjs +135 -16
- package/dist/transform/index.mjs +135 -16
- package/dist/transform/templates.cjs +134 -15
- package/dist/transform/templates.d.ts.map +1 -1
- package/dist/transform/templates.js +4 -8
- package/dist/transform/templates.mjs +134 -15
- package/dist/{transform-VMK2URDB.mjs → transform-NO46NFQH.mjs} +11 -14
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +4 -4
|
@@ -162,10 +162,64 @@ function isHole(node) {
|
|
|
162
162
|
function isTemplateChild(node) {
|
|
163
163
|
return node.kind === "text" || node.kind === "element" && isTemplateElement(node);
|
|
164
164
|
}
|
|
165
|
+
var PROPERTY_BINDS = /* @__PURE__ */ new Set(["indeterminate"]);
|
|
166
|
+
function disposition(prop) {
|
|
167
|
+
if (prop.kind === "spread") return null;
|
|
168
|
+
if (prop.name === "ref") return "ref";
|
|
169
|
+
if (prop.name === "use") return "use";
|
|
170
|
+
if (prop.kind === "event") return prop.event ? "event" : null;
|
|
171
|
+
if (prop.kind === "prop") return "property";
|
|
172
|
+
if (prop.kind !== "attr") return null;
|
|
173
|
+
const name = prop.name;
|
|
174
|
+
if (name.startsWith("on:")) return "nativeEvent";
|
|
175
|
+
if (name.startsWith("prop:")) return "property";
|
|
176
|
+
if (name.startsWith("attr:")) return "attr";
|
|
177
|
+
if (name.startsWith("bool:")) return "boolAttr";
|
|
178
|
+
if (name === "className" || name === "class") {
|
|
179
|
+
return isPlainLiteralAttr(prop) ? "serialize" : "class";
|
|
180
|
+
}
|
|
181
|
+
if (name === "classList") {
|
|
182
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
183
|
+
return prop.reactive ? "classListDynamic" : "classList";
|
|
184
|
+
}
|
|
185
|
+
if (name === "style") {
|
|
186
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
187
|
+
return prop.reactive ? "styleDynamic" : "style";
|
|
188
|
+
}
|
|
189
|
+
if (name.includes(":")) return null;
|
|
190
|
+
if (PROPERTY_ONLY.has(name)) return null;
|
|
191
|
+
if (PROPERTY_BINDS.has(name)) return "property";
|
|
192
|
+
if (prop.expr === void 0) return isPlainLiteralAttr(prop) ? "serialize" : null;
|
|
193
|
+
return "attr";
|
|
194
|
+
}
|
|
195
|
+
function effectiveProps(el) {
|
|
196
|
+
const order = [];
|
|
197
|
+
const byName = /* @__PURE__ */ new Map();
|
|
198
|
+
for (const prop of el.props) {
|
|
199
|
+
if (!byName.has(prop.name)) order.push(prop.name);
|
|
200
|
+
byName.set(prop.name, prop);
|
|
201
|
+
}
|
|
202
|
+
return order.map((name) => byName.get(name));
|
|
203
|
+
}
|
|
204
|
+
function propPlan(el) {
|
|
205
|
+
const custom = el.tag.includes("-");
|
|
206
|
+
const plan = { serialize: [], bindings: [] };
|
|
207
|
+
for (const prop of effectiveProps(el)) {
|
|
208
|
+
const kind = disposition(prop);
|
|
209
|
+
if (kind === null) return null;
|
|
210
|
+
if (kind === "serialize") {
|
|
211
|
+
plan.serialize.push(prop);
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (custom) return null;
|
|
215
|
+
plan.bindings.push({ prop, kind });
|
|
216
|
+
}
|
|
217
|
+
return plan;
|
|
218
|
+
}
|
|
165
219
|
function isTemplateElement(node) {
|
|
166
220
|
if (node.svg) return false;
|
|
167
221
|
if (isRawTextElement(node.tag)) return false;
|
|
168
|
-
if (!node
|
|
222
|
+
if (!propPlan(node)) return false;
|
|
169
223
|
return node.children.every((c) => isTemplateChild(c) || isHole(c));
|
|
170
224
|
}
|
|
171
225
|
function containsHole(node) {
|
|
@@ -173,6 +227,15 @@ function containsHole(node) {
|
|
|
173
227
|
const children = node.children;
|
|
174
228
|
return children ? children.some(containsHole) : false;
|
|
175
229
|
}
|
|
230
|
+
function containsBinding(node) {
|
|
231
|
+
if (node.kind !== "element") return false;
|
|
232
|
+
const plan = propPlan(node);
|
|
233
|
+
if (plan && plan.bindings.length > 0) return true;
|
|
234
|
+
return node.children.some(containsBinding);
|
|
235
|
+
}
|
|
236
|
+
function interesting(node) {
|
|
237
|
+
return containsHole(node) || containsBinding(node);
|
|
238
|
+
}
|
|
176
239
|
function addressable(el) {
|
|
177
240
|
for (let i = 0; i < el.children.length; i++) {
|
|
178
241
|
const child = el.children[i];
|
|
@@ -186,9 +249,10 @@ function addressable(el) {
|
|
|
186
249
|
function planPartialTemplate(root) {
|
|
187
250
|
if (!isTemplateElement(root)) return null;
|
|
188
251
|
if (!addressable(root)) return null;
|
|
189
|
-
if (!root
|
|
252
|
+
if (!interesting(root)) return null;
|
|
190
253
|
const steps = [];
|
|
191
254
|
const holes = [];
|
|
255
|
+
const bindings = [];
|
|
192
256
|
let refCount = 0;
|
|
193
257
|
const declare = (expr) => {
|
|
194
258
|
const ref = `_n$${refCount++}`;
|
|
@@ -196,11 +260,17 @@ function planPartialTemplate(root) {
|
|
|
196
260
|
return ref;
|
|
197
261
|
};
|
|
198
262
|
walk(root, "_el$");
|
|
199
|
-
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes };
|
|
263
|
+
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes, bindings };
|
|
200
264
|
function walk(el, elementRef) {
|
|
265
|
+
const plan = propPlan(el);
|
|
266
|
+
if (plan) {
|
|
267
|
+
for (const binding of plan.bindings) {
|
|
268
|
+
bindings.push({ ref: elementRef, prop: binding.prop, kind: binding.kind });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
201
271
|
let last = -1;
|
|
202
272
|
el.children.forEach((child, i) => {
|
|
203
|
-
if (
|
|
273
|
+
if (interesting(child)) last = i;
|
|
204
274
|
});
|
|
205
275
|
let previous = null;
|
|
206
276
|
for (let i = 0; i <= last; i++) {
|
|
@@ -214,19 +284,21 @@ function planPartialTemplate(root) {
|
|
|
214
284
|
continue;
|
|
215
285
|
}
|
|
216
286
|
const ref = declare(expr);
|
|
217
|
-
if (child.kind === "element" &&
|
|
287
|
+
if (child.kind === "element" && interesting(child)) walk(child, ref);
|
|
218
288
|
previous = ref;
|
|
219
289
|
}
|
|
220
290
|
}
|
|
221
291
|
}
|
|
222
292
|
function serializeWithMarkers(el) {
|
|
223
|
-
return serializeStatic(
|
|
293
|
+
return serializeStatic(templateTree(el)).split(SENTINEL).join(HOLE_START + HOLE_END);
|
|
224
294
|
}
|
|
225
|
-
function
|
|
295
|
+
function templateTree(el) {
|
|
296
|
+
const plan = propPlan(el);
|
|
226
297
|
return {
|
|
227
298
|
...el,
|
|
299
|
+
props: plan ? plan.serialize : [],
|
|
228
300
|
children: el.children.map(
|
|
229
|
-
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ?
|
|
301
|
+
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ? templateTree(child) : child
|
|
230
302
|
)
|
|
231
303
|
};
|
|
232
304
|
}
|
|
@@ -499,6 +571,55 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
499
571
|
const mark = at ? `globalThis.${SOURCE_MARKER}?.(${JSON.stringify(at.file)},${at.line},${at.column},${JSON.stringify(name)}), ` : "";
|
|
500
572
|
return `createMemo(${paren(`${mark}() => createComponent(${name}, ${obj})`, "value")})`;
|
|
501
573
|
}
|
|
574
|
+
function bindingTarget(binding) {
|
|
575
|
+
const name = binding.prop.name;
|
|
576
|
+
if (binding.kind === "boolAttr") return name.slice("bool:".length);
|
|
577
|
+
if (name.startsWith("prop:")) return name.slice("prop:".length);
|
|
578
|
+
if (name.startsWith("attr:")) return name.slice("attr:".length);
|
|
579
|
+
return htmlAttrName(name);
|
|
580
|
+
}
|
|
581
|
+
function bindingStatement(binding, used) {
|
|
582
|
+
const { ref, prop, kind } = binding;
|
|
583
|
+
const value = propValue(prop);
|
|
584
|
+
switch (kind) {
|
|
585
|
+
case "class":
|
|
586
|
+
used.add("setClassName");
|
|
587
|
+
return `setClassName(${ref}, ${value});`;
|
|
588
|
+
case "classList":
|
|
589
|
+
used.add("setClassList");
|
|
590
|
+
return `setClassList(${ref}, ${value}, []);`;
|
|
591
|
+
case "classListDynamic":
|
|
592
|
+
used.add("setDynamicClassList");
|
|
593
|
+
return `setDynamicClassList(${ref}, ${value});`;
|
|
594
|
+
case "style":
|
|
595
|
+
used.add("setStyle");
|
|
596
|
+
return `setStyle(${ref}, ${value}, []);`;
|
|
597
|
+
case "styleDynamic":
|
|
598
|
+
used.add("setDynamicStyle");
|
|
599
|
+
return `setDynamicStyle(${ref}, ${value});`;
|
|
600
|
+
case "attr":
|
|
601
|
+
used.add("setDynamicAttribute");
|
|
602
|
+
return `setDynamicAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
603
|
+
case "property":
|
|
604
|
+
used.add("setDynamicProperty");
|
|
605
|
+
return `setDynamicProperty(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
606
|
+
case "boolAttr":
|
|
607
|
+
used.add("setDynamicBoolAttribute");
|
|
608
|
+
return `setDynamicBoolAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
609
|
+
case "event":
|
|
610
|
+
used.add("addDelegatedEventListener");
|
|
611
|
+
return `addDelegatedEventListener(${ref}, ${JSON.stringify(prop.event.name)}, ${value});`;
|
|
612
|
+
case "nativeEvent":
|
|
613
|
+
used.add("addNativeEventListener");
|
|
614
|
+
return `addNativeEventListener(${ref}, ${JSON.stringify(prop.name.slice(3))}, ${value});`;
|
|
615
|
+
case "ref":
|
|
616
|
+
used.add("handleRef");
|
|
617
|
+
return `handleRef(${value}, ${ref});`;
|
|
618
|
+
case "use":
|
|
619
|
+
used.add("applyUse");
|
|
620
|
+
return `applyUse(${ref}, ${value});`;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
502
623
|
function staticAttrAssignment(el, prop) {
|
|
503
624
|
const name = htmlAttrName(prop.name);
|
|
504
625
|
const value = prop.literal;
|
|
@@ -549,6 +670,7 @@ function emitNode(node, used, templates) {
|
|
|
549
670
|
`const _el$ = templateNode(${id}, ${JSON.stringify(plan.tag)}, true${at ? `, false, ${JSON.stringify(at)}` : ""});`
|
|
550
671
|
];
|
|
551
672
|
for (const step of plan.steps) lines.push(`const ${step.ref} = ${step.expr};`);
|
|
673
|
+
for (const binding of plan.bindings) lines.push(bindingStatement(binding, used));
|
|
552
674
|
for (const hole of plan.holes) {
|
|
553
675
|
lines.push(
|
|
554
676
|
`insert(${hole.parentRef}, holeScope(${hole.startRef}, () => ${paren(emitNode(hole.node, used, templates), "arrowBody")}), ${hole.endRef}, holeContent(${hole.startRef}, ${hole.endRef}));`
|
|
@@ -1807,7 +1929,7 @@ var generate = _generate.default ?? _generate;
|
|
|
1807
1929
|
function gen(node) {
|
|
1808
1930
|
return generate(node, { concise: true }).code;
|
|
1809
1931
|
}
|
|
1810
|
-
function transformNestedJSX(node, used, onNested) {
|
|
1932
|
+
function transformNestedJSX(node, used, onNested, emit) {
|
|
1811
1933
|
const clone = t.cloneNode(node, true);
|
|
1812
1934
|
const file = t.file(t.program([t.expressionStatement(clone)]));
|
|
1813
1935
|
let changed = false;
|
|
@@ -1820,9 +1942,12 @@ function transformNestedJSX(node, used, onNested) {
|
|
|
1820
1942
|
traverse(file, {
|
|
1821
1943
|
"JSXElement|JSXFragment"(path) {
|
|
1822
1944
|
const jsx = path.node;
|
|
1823
|
-
const nestedIR = buildIR(jsx, used, onNested);
|
|
1945
|
+
const nestedIR = buildIR(jsx, used, onNested, emit);
|
|
1824
1946
|
onNested?.(nestedIR);
|
|
1825
|
-
const { code, imports, templates } = imperativeBackend.emit(nestedIR, {
|
|
1947
|
+
const { code, imports, templates } = imperativeBackend.emit(nestedIR, {
|
|
1948
|
+
templateClone: emit?.templateClone,
|
|
1949
|
+
partialTemplates: emit?.partialTemplates ?? true
|
|
1950
|
+
});
|
|
1826
1951
|
emitInto(path, inlineTemplates(code, templates), imports);
|
|
1827
1952
|
},
|
|
1828
1953
|
// Nested html templates compose: ${cond ? html`...` : html`...`},
|
|
@@ -1830,26 +1955,29 @@ function transformNestedJSX(node, used, onNested) {
|
|
|
1830
1955
|
TaggedTemplateExpression(path) {
|
|
1831
1956
|
const tag = path.node.tag;
|
|
1832
1957
|
if (!t.isIdentifier(tag) || tag.name !== "html" && tag.name !== "svg") return;
|
|
1833
|
-
const ir = buildIRFromHtml(path.node, used, { svg: tag.name === "svg", onNested });
|
|
1958
|
+
const ir = buildIRFromHtml(path.node, used, { svg: tag.name === "svg", onNested, emit });
|
|
1834
1959
|
onNested?.(ir);
|
|
1835
|
-
const { code, imports, templates } = imperativeBackend.emit(ir, {
|
|
1960
|
+
const { code, imports, templates } = imperativeBackend.emit(ir, {
|
|
1961
|
+
templateClone: emit?.templateClone,
|
|
1962
|
+
partialTemplates: emit?.partialTemplates ?? true
|
|
1963
|
+
});
|
|
1836
1964
|
emitInto(path, inlineTemplates(code, templates), imports);
|
|
1837
1965
|
}
|
|
1838
1966
|
});
|
|
1839
1967
|
return changed ? file.program.body[0].expression : node;
|
|
1840
1968
|
}
|
|
1841
|
-
function genExpr(node, used, onNested) {
|
|
1842
|
-
return gen(transformNestedJSX(node, used, onNested));
|
|
1969
|
+
function genExpr(node, used, onNested, emit) {
|
|
1970
|
+
return gen(transformNestedJSX(node, used, onNested, emit));
|
|
1843
1971
|
}
|
|
1844
1972
|
function isReactiveExpr(node) {
|
|
1845
1973
|
return isReactiveShape(shapeOf(node));
|
|
1846
1974
|
}
|
|
1847
|
-
function buildIR(node, used = /* @__PURE__ */ new Set(), onNested) {
|
|
1975
|
+
function buildIR(node, used = /* @__PURE__ */ new Set(), onNested, emit) {
|
|
1848
1976
|
const ir = buildJsxIR(node, {
|
|
1849
1977
|
code: (n) => (
|
|
1850
1978
|
// A member-expression tag (`<ns.Foo/>`) is not an Expression, so it cannot go
|
|
1851
1979
|
// through the nested-JSX compile: it only ever needs printing.
|
|
1852
|
-
n.type === "JSXMemberExpression" ? gen(n) : genExpr(n, used, onNested)
|
|
1980
|
+
n.type === "JSXMemberExpression" ? gen(n) : genExpr(n, used, onNested, emit)
|
|
1853
1981
|
),
|
|
1854
1982
|
used
|
|
1855
1983
|
});
|
|
@@ -1861,16 +1989,16 @@ var generate2 = _generate2.default ?? _generate2;
|
|
|
1861
1989
|
function gen2(node) {
|
|
1862
1990
|
return generate2(node, { concise: true }).code;
|
|
1863
1991
|
}
|
|
1864
|
-
function bindHole(expr, used, onNested) {
|
|
1992
|
+
function bindHole(expr, used, onNested, emit) {
|
|
1865
1993
|
const hole = {
|
|
1866
|
-
code: genExpr(expr, used, onNested),
|
|
1994
|
+
code: genExpr(expr, used, onNested, emit),
|
|
1867
1995
|
reactive: isReactiveExpr(expr)
|
|
1868
1996
|
};
|
|
1869
1997
|
if (t2.isArrowFunctionExpression(expr) && !t2.isBlockStatement(expr.body)) {
|
|
1870
1998
|
const body = expr.body;
|
|
1871
1999
|
hole.arrow = {
|
|
1872
2000
|
params: expr.params.map((p) => gen2(p)),
|
|
1873
|
-
body: genExpr(body, used, onNested),
|
|
2001
|
+
body: genExpr(body, used, onNested, emit),
|
|
1874
2002
|
bodyReactive: isReactiveExpr(body)
|
|
1875
2003
|
};
|
|
1876
2004
|
}
|
|
@@ -1879,7 +2007,7 @@ function bindHole(expr, used, onNested) {
|
|
|
1879
2007
|
}
|
|
1880
2008
|
function lowerHtmlTemplate(node, used, opts = {}) {
|
|
1881
2009
|
const quasi = node.quasi;
|
|
1882
|
-
const holes = quasi.expressions.map((e) => bindHole(e, used, opts.onNested));
|
|
2010
|
+
const holes = quasi.expressions.map((e) => bindHole(e, used, opts.onNested, opts.emit));
|
|
1883
2011
|
return lowerTemplate(buildPieces(quasi), holes, used, opts);
|
|
1884
2012
|
}
|
|
1885
2013
|
function buildPieces(quasi) {
|
|
@@ -145,10 +145,64 @@ function isHole(node) {
|
|
|
145
145
|
function isTemplateChild(node) {
|
|
146
146
|
return node.kind === "text" || node.kind === "element" && isTemplateElement(node);
|
|
147
147
|
}
|
|
148
|
+
var PROPERTY_BINDS = /* @__PURE__ */ new Set(["indeterminate"]);
|
|
149
|
+
function disposition(prop) {
|
|
150
|
+
if (prop.kind === "spread") return null;
|
|
151
|
+
if (prop.name === "ref") return "ref";
|
|
152
|
+
if (prop.name === "use") return "use";
|
|
153
|
+
if (prop.kind === "event") return prop.event ? "event" : null;
|
|
154
|
+
if (prop.kind === "prop") return "property";
|
|
155
|
+
if (prop.kind !== "attr") return null;
|
|
156
|
+
const name = prop.name;
|
|
157
|
+
if (name.startsWith("on:")) return "nativeEvent";
|
|
158
|
+
if (name.startsWith("prop:")) return "property";
|
|
159
|
+
if (name.startsWith("attr:")) return "attr";
|
|
160
|
+
if (name.startsWith("bool:")) return "boolAttr";
|
|
161
|
+
if (name === "className" || name === "class") {
|
|
162
|
+
return isPlainLiteralAttr(prop) ? "serialize" : "class";
|
|
163
|
+
}
|
|
164
|
+
if (name === "classList") {
|
|
165
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
166
|
+
return prop.reactive ? "classListDynamic" : "classList";
|
|
167
|
+
}
|
|
168
|
+
if (name === "style") {
|
|
169
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
170
|
+
return prop.reactive ? "styleDynamic" : "style";
|
|
171
|
+
}
|
|
172
|
+
if (name.includes(":")) return null;
|
|
173
|
+
if (PROPERTY_ONLY.has(name)) return null;
|
|
174
|
+
if (PROPERTY_BINDS.has(name)) return "property";
|
|
175
|
+
if (prop.expr === void 0) return isPlainLiteralAttr(prop) ? "serialize" : null;
|
|
176
|
+
return "attr";
|
|
177
|
+
}
|
|
178
|
+
function effectiveProps(el) {
|
|
179
|
+
const order = [];
|
|
180
|
+
const byName = /* @__PURE__ */ new Map();
|
|
181
|
+
for (const prop of el.props) {
|
|
182
|
+
if (!byName.has(prop.name)) order.push(prop.name);
|
|
183
|
+
byName.set(prop.name, prop);
|
|
184
|
+
}
|
|
185
|
+
return order.map((name) => byName.get(name));
|
|
186
|
+
}
|
|
187
|
+
function propPlan(el) {
|
|
188
|
+
const custom = el.tag.includes("-");
|
|
189
|
+
const plan = { serialize: [], bindings: [] };
|
|
190
|
+
for (const prop of effectiveProps(el)) {
|
|
191
|
+
const kind = disposition(prop);
|
|
192
|
+
if (kind === null) return null;
|
|
193
|
+
if (kind === "serialize") {
|
|
194
|
+
plan.serialize.push(prop);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
if (custom) return null;
|
|
198
|
+
plan.bindings.push({ prop, kind });
|
|
199
|
+
}
|
|
200
|
+
return plan;
|
|
201
|
+
}
|
|
148
202
|
function isTemplateElement(node) {
|
|
149
203
|
if (node.svg) return false;
|
|
150
204
|
if (isRawTextElement(node.tag)) return false;
|
|
151
|
-
if (!node
|
|
205
|
+
if (!propPlan(node)) return false;
|
|
152
206
|
return node.children.every((c) => isTemplateChild(c) || isHole(c));
|
|
153
207
|
}
|
|
154
208
|
function containsHole(node) {
|
|
@@ -156,6 +210,15 @@ function containsHole(node) {
|
|
|
156
210
|
const children = node.children;
|
|
157
211
|
return children ? children.some(containsHole) : false;
|
|
158
212
|
}
|
|
213
|
+
function containsBinding(node) {
|
|
214
|
+
if (node.kind !== "element") return false;
|
|
215
|
+
const plan = propPlan(node);
|
|
216
|
+
if (plan && plan.bindings.length > 0) return true;
|
|
217
|
+
return node.children.some(containsBinding);
|
|
218
|
+
}
|
|
219
|
+
function interesting(node) {
|
|
220
|
+
return containsHole(node) || containsBinding(node);
|
|
221
|
+
}
|
|
159
222
|
function addressable(el) {
|
|
160
223
|
for (let i = 0; i < el.children.length; i++) {
|
|
161
224
|
const child = el.children[i];
|
|
@@ -169,9 +232,10 @@ function addressable(el) {
|
|
|
169
232
|
function planPartialTemplate(root) {
|
|
170
233
|
if (!isTemplateElement(root)) return null;
|
|
171
234
|
if (!addressable(root)) return null;
|
|
172
|
-
if (!root
|
|
235
|
+
if (!interesting(root)) return null;
|
|
173
236
|
const steps = [];
|
|
174
237
|
const holes = [];
|
|
238
|
+
const bindings = [];
|
|
175
239
|
let refCount = 0;
|
|
176
240
|
const declare = (expr) => {
|
|
177
241
|
const ref = `_n$${refCount++}`;
|
|
@@ -179,11 +243,17 @@ function planPartialTemplate(root) {
|
|
|
179
243
|
return ref;
|
|
180
244
|
};
|
|
181
245
|
walk(root, "_el$");
|
|
182
|
-
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes };
|
|
246
|
+
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes, bindings };
|
|
183
247
|
function walk(el, elementRef) {
|
|
248
|
+
const plan = propPlan(el);
|
|
249
|
+
if (plan) {
|
|
250
|
+
for (const binding of plan.bindings) {
|
|
251
|
+
bindings.push({ ref: elementRef, prop: binding.prop, kind: binding.kind });
|
|
252
|
+
}
|
|
253
|
+
}
|
|
184
254
|
let last = -1;
|
|
185
255
|
el.children.forEach((child, i) => {
|
|
186
|
-
if (
|
|
256
|
+
if (interesting(child)) last = i;
|
|
187
257
|
});
|
|
188
258
|
let previous = null;
|
|
189
259
|
for (let i = 0; i <= last; i++) {
|
|
@@ -197,19 +267,21 @@ function planPartialTemplate(root) {
|
|
|
197
267
|
continue;
|
|
198
268
|
}
|
|
199
269
|
const ref = declare(expr);
|
|
200
|
-
if (child.kind === "element" &&
|
|
270
|
+
if (child.kind === "element" && interesting(child)) walk(child, ref);
|
|
201
271
|
previous = ref;
|
|
202
272
|
}
|
|
203
273
|
}
|
|
204
274
|
}
|
|
205
275
|
function serializeWithMarkers(el) {
|
|
206
|
-
return serializeStatic(
|
|
276
|
+
return serializeStatic(templateTree(el)).split(SENTINEL).join(HOLE_START + HOLE_END);
|
|
207
277
|
}
|
|
208
|
-
function
|
|
278
|
+
function templateTree(el) {
|
|
279
|
+
const plan = propPlan(el);
|
|
209
280
|
return {
|
|
210
281
|
...el,
|
|
282
|
+
props: plan ? plan.serialize : [],
|
|
211
283
|
children: el.children.map(
|
|
212
|
-
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ?
|
|
284
|
+
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ? templateTree(child) : child
|
|
213
285
|
)
|
|
214
286
|
};
|
|
215
287
|
}
|
|
@@ -482,6 +554,55 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
482
554
|
const mark = at ? `globalThis.${SOURCE_MARKER}?.(${JSON.stringify(at.file)},${at.line},${at.column},${JSON.stringify(name)}), ` : "";
|
|
483
555
|
return `createMemo(${paren(`${mark}() => createComponent(${name}, ${obj})`, "value")})`;
|
|
484
556
|
}
|
|
557
|
+
function bindingTarget(binding) {
|
|
558
|
+
const name = binding.prop.name;
|
|
559
|
+
if (binding.kind === "boolAttr") return name.slice("bool:".length);
|
|
560
|
+
if (name.startsWith("prop:")) return name.slice("prop:".length);
|
|
561
|
+
if (name.startsWith("attr:")) return name.slice("attr:".length);
|
|
562
|
+
return htmlAttrName(name);
|
|
563
|
+
}
|
|
564
|
+
function bindingStatement(binding, used) {
|
|
565
|
+
const { ref, prop, kind } = binding;
|
|
566
|
+
const value = propValue(prop);
|
|
567
|
+
switch (kind) {
|
|
568
|
+
case "class":
|
|
569
|
+
used.add("setClassName");
|
|
570
|
+
return `setClassName(${ref}, ${value});`;
|
|
571
|
+
case "classList":
|
|
572
|
+
used.add("setClassList");
|
|
573
|
+
return `setClassList(${ref}, ${value}, []);`;
|
|
574
|
+
case "classListDynamic":
|
|
575
|
+
used.add("setDynamicClassList");
|
|
576
|
+
return `setDynamicClassList(${ref}, ${value});`;
|
|
577
|
+
case "style":
|
|
578
|
+
used.add("setStyle");
|
|
579
|
+
return `setStyle(${ref}, ${value}, []);`;
|
|
580
|
+
case "styleDynamic":
|
|
581
|
+
used.add("setDynamicStyle");
|
|
582
|
+
return `setDynamicStyle(${ref}, ${value});`;
|
|
583
|
+
case "attr":
|
|
584
|
+
used.add("setDynamicAttribute");
|
|
585
|
+
return `setDynamicAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
586
|
+
case "property":
|
|
587
|
+
used.add("setDynamicProperty");
|
|
588
|
+
return `setDynamicProperty(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
589
|
+
case "boolAttr":
|
|
590
|
+
used.add("setDynamicBoolAttribute");
|
|
591
|
+
return `setDynamicBoolAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
592
|
+
case "event":
|
|
593
|
+
used.add("addDelegatedEventListener");
|
|
594
|
+
return `addDelegatedEventListener(${ref}, ${JSON.stringify(prop.event.name)}, ${value});`;
|
|
595
|
+
case "nativeEvent":
|
|
596
|
+
used.add("addNativeEventListener");
|
|
597
|
+
return `addNativeEventListener(${ref}, ${JSON.stringify(prop.name.slice(3))}, ${value});`;
|
|
598
|
+
case "ref":
|
|
599
|
+
used.add("handleRef");
|
|
600
|
+
return `handleRef(${value}, ${ref});`;
|
|
601
|
+
case "use":
|
|
602
|
+
used.add("applyUse");
|
|
603
|
+
return `applyUse(${ref}, ${value});`;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
485
606
|
function staticAttrAssignment(el, prop) {
|
|
486
607
|
const name = htmlAttrName(prop.name);
|
|
487
608
|
const value = prop.literal;
|
|
@@ -532,6 +653,7 @@ function emitNode(node, used, templates) {
|
|
|
532
653
|
`const _el$ = templateNode(${id}, ${JSON.stringify(plan.tag)}, true${at ? `, false, ${JSON.stringify(at)}` : ""});`
|
|
533
654
|
];
|
|
534
655
|
for (const step of plan.steps) lines.push(`const ${step.ref} = ${step.expr};`);
|
|
656
|
+
for (const binding of plan.bindings) lines.push(bindingStatement(binding, used));
|
|
535
657
|
for (const hole of plan.holes) {
|
|
536
658
|
lines.push(
|
|
537
659
|
`insert(${hole.parentRef}, holeScope(${hole.startRef}, () => ${paren(emitNode(hole.node, used, templates), "arrowBody")}), ${hole.endRef}, holeContent(${hole.startRef}, ${hole.endRef}));`
|
|
@@ -1382,16 +1504,16 @@ var generate = import_generator.default.default ?? import_generator.default;
|
|
|
1382
1504
|
function gen(node) {
|
|
1383
1505
|
return generate(node, { concise: true }).code;
|
|
1384
1506
|
}
|
|
1385
|
-
function bindHole(expr, used, onNested) {
|
|
1507
|
+
function bindHole(expr, used, onNested, emit) {
|
|
1386
1508
|
const hole = {
|
|
1387
|
-
code: genExpr(expr, used, onNested),
|
|
1509
|
+
code: genExpr(expr, used, onNested, emit),
|
|
1388
1510
|
reactive: isReactiveExpr(expr)
|
|
1389
1511
|
};
|
|
1390
1512
|
if (import_core.types.isArrowFunctionExpression(expr) && !import_core.types.isBlockStatement(expr.body)) {
|
|
1391
1513
|
const body = expr.body;
|
|
1392
1514
|
hole.arrow = {
|
|
1393
1515
|
params: expr.params.map((p) => gen(p)),
|
|
1394
|
-
body: genExpr(body, used, onNested),
|
|
1516
|
+
body: genExpr(body, used, onNested, emit),
|
|
1395
1517
|
bodyReactive: isReactiveExpr(body)
|
|
1396
1518
|
};
|
|
1397
1519
|
}
|
|
@@ -1400,7 +1522,7 @@ function bindHole(expr, used, onNested) {
|
|
|
1400
1522
|
}
|
|
1401
1523
|
function lowerHtmlTemplate(node, used, opts = {}) {
|
|
1402
1524
|
const quasi = node.quasi;
|
|
1403
|
-
const holes = quasi.expressions.map((e) => bindHole(e, used, opts.onNested));
|
|
1525
|
+
const holes = quasi.expressions.map((e) => bindHole(e, used, opts.onNested, opts.emit));
|
|
1404
1526
|
return lowerTemplate(buildPieces(quasi), holes, used, opts);
|
|
1405
1527
|
}
|
|
1406
1528
|
function buildPieces(quasi) {
|
|
@@ -1888,7 +2010,7 @@ var generate2 = import_generator2.default.default ?? import_generator2.default;
|
|
|
1888
2010
|
function gen2(node) {
|
|
1889
2011
|
return generate2(node, { concise: true }).code;
|
|
1890
2012
|
}
|
|
1891
|
-
function transformNestedJSX(node, used, onNested) {
|
|
2013
|
+
function transformNestedJSX(node, used, onNested, emit) {
|
|
1892
2014
|
const clone = import_core2.types.cloneNode(node, true);
|
|
1893
2015
|
const file = import_core2.types.file(import_core2.types.program([import_core2.types.expressionStatement(clone)]));
|
|
1894
2016
|
let changed = false;
|
|
@@ -1901,9 +2023,12 @@ function transformNestedJSX(node, used, onNested) {
|
|
|
1901
2023
|
(0, import_core2.traverse)(file, {
|
|
1902
2024
|
"JSXElement|JSXFragment"(path) {
|
|
1903
2025
|
const jsx = path.node;
|
|
1904
|
-
const nestedIR = buildIR(jsx, used, onNested);
|
|
2026
|
+
const nestedIR = buildIR(jsx, used, onNested, emit);
|
|
1905
2027
|
onNested?.(nestedIR);
|
|
1906
|
-
const { code, imports, templates } = imperativeBackend.emit(nestedIR, {
|
|
2028
|
+
const { code, imports, templates } = imperativeBackend.emit(nestedIR, {
|
|
2029
|
+
templateClone: emit?.templateClone,
|
|
2030
|
+
partialTemplates: emit?.partialTemplates ?? true
|
|
2031
|
+
});
|
|
1907
2032
|
emitInto(path, inlineTemplates(code, templates), imports);
|
|
1908
2033
|
},
|
|
1909
2034
|
// Nested html templates compose: ${cond ? html`...` : html`...`},
|
|
@@ -1911,16 +2036,19 @@ function transformNestedJSX(node, used, onNested) {
|
|
|
1911
2036
|
TaggedTemplateExpression(path) {
|
|
1912
2037
|
const tag = path.node.tag;
|
|
1913
2038
|
if (!import_core2.types.isIdentifier(tag) || tag.name !== "html" && tag.name !== "svg") return;
|
|
1914
|
-
const ir = buildIRFromHtml(path.node, used, { svg: tag.name === "svg", onNested });
|
|
2039
|
+
const ir = buildIRFromHtml(path.node, used, { svg: tag.name === "svg", onNested, emit });
|
|
1915
2040
|
onNested?.(ir);
|
|
1916
|
-
const { code, imports, templates } = imperativeBackend.emit(ir, {
|
|
2041
|
+
const { code, imports, templates } = imperativeBackend.emit(ir, {
|
|
2042
|
+
templateClone: emit?.templateClone,
|
|
2043
|
+
partialTemplates: emit?.partialTemplates ?? true
|
|
2044
|
+
});
|
|
1917
2045
|
emitInto(path, inlineTemplates(code, templates), imports);
|
|
1918
2046
|
}
|
|
1919
2047
|
});
|
|
1920
2048
|
return changed ? file.program.body[0].expression : node;
|
|
1921
2049
|
}
|
|
1922
|
-
function genExpr(node, used, onNested) {
|
|
1923
|
-
return gen2(transformNestedJSX(node, used, onNested));
|
|
2050
|
+
function genExpr(node, used, onNested, emit) {
|
|
2051
|
+
return gen2(transformNestedJSX(node, used, onNested, emit));
|
|
1924
2052
|
}
|
|
1925
2053
|
var SVG_TAGS2 = /* @__PURE__ */ new Set([
|
|
1926
2054
|
"svg",
|
|
@@ -1939,12 +2067,12 @@ var SVG_TAGS2 = /* @__PURE__ */ new Set([
|
|
|
1939
2067
|
function isReactiveExpr(node) {
|
|
1940
2068
|
return isReactiveShape(shapeOf(node));
|
|
1941
2069
|
}
|
|
1942
|
-
function buildIR(node, used = /* @__PURE__ */ new Set(), onNested) {
|
|
2070
|
+
function buildIR(node, used = /* @__PURE__ */ new Set(), onNested, emit) {
|
|
1943
2071
|
const ir = buildJsxIR(node, {
|
|
1944
2072
|
code: (n) => (
|
|
1945
2073
|
// A member-expression tag (`<ns.Foo/>`) is not an Expression, so it cannot go
|
|
1946
2074
|
// through the nested-JSX compile: it only ever needs printing.
|
|
1947
|
-
n.type === "JSXMemberExpression" ? gen2(n) : genExpr(n, used, onNested)
|
|
2075
|
+
n.type === "JSXMemberExpression" ? gen2(n) : genExpr(n, used, onNested, emit)
|
|
1948
2076
|
),
|
|
1949
2077
|
used
|
|
1950
2078
|
});
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { types as t } from '@babel/core';
|
|
16
16
|
import type { IRNode } from '../../ir/nodes.cjs';
|
|
17
17
|
/** Stringify an expression, compiling any JSX nested inside it first. */
|
|
18
|
-
export declare function genExpr(node: t.Expression, used: Set<string>, onNested?: NestedHook): string;
|
|
18
|
+
export declare function genExpr(node: t.Expression, used: Set<string>, onNested?: NestedHook, emit?: NestedEmitOptions): string;
|
|
19
19
|
/**
|
|
20
20
|
* Called with the IR of JSX (or a template) found inside an expression.
|
|
21
21
|
*
|
|
@@ -25,6 +25,15 @@ export declare function genExpr(node: t.Expression, used: Set<string>, onNested?
|
|
|
25
25
|
* reference to `Input` that nothing imported.
|
|
26
26
|
*/
|
|
27
27
|
export type NestedHook = (ir: IRNode) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Emit switches for JSX compiled inside an expression. The front-end passes its
|
|
30
|
+
* own, so a root inside a callback or a hole compiles the way a top-level root
|
|
31
|
+
* does; absent a front-end, partial templates stay on, as at the top level.
|
|
32
|
+
*/
|
|
33
|
+
export interface NestedEmitOptions {
|
|
34
|
+
partialTemplates?: boolean;
|
|
35
|
+
templateClone?: boolean;
|
|
36
|
+
}
|
|
28
37
|
export declare const SVG_TAGS: Set<string>;
|
|
29
38
|
export declare function isReactiveExpr(node: t.Expression): boolean;
|
|
30
39
|
/**
|
|
@@ -32,4 +41,4 @@ export declare function isReactiveExpr(node: t.Expression): boolean;
|
|
|
32
41
|
* front-end supplies is how an expression becomes source, `genExpr`, which also
|
|
33
42
|
* compiles any JSX or `` html`` `` nested inside it.
|
|
34
43
|
*/
|
|
35
|
-
export declare function buildIR(node: t.JSXElement | t.JSXFragment, used?: Set<string>, onNested?: NestedHook): IRNode;
|
|
44
|
+
export declare function buildIR(node: t.JSXElement | t.JSXFragment, used?: Set<string>, onNested?: NestedHook, emit?: NestedEmitOptions): IRNode;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { types as t } from '@babel/core';
|
|
16
16
|
import type { IRNode } from '../../ir/nodes.js';
|
|
17
17
|
/** Stringify an expression, compiling any JSX nested inside it first. */
|
|
18
|
-
export declare function genExpr(node: t.Expression, used: Set<string>, onNested?: NestedHook): string;
|
|
18
|
+
export declare function genExpr(node: t.Expression, used: Set<string>, onNested?: NestedHook, emit?: NestedEmitOptions): string;
|
|
19
19
|
/**
|
|
20
20
|
* Called with the IR of JSX (or a template) found inside an expression.
|
|
21
21
|
*
|
|
@@ -25,6 +25,15 @@ export declare function genExpr(node: t.Expression, used: Set<string>, onNested?
|
|
|
25
25
|
* reference to `Input` that nothing imported.
|
|
26
26
|
*/
|
|
27
27
|
export type NestedHook = (ir: IRNode) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Emit switches for JSX compiled inside an expression. The front-end passes its
|
|
30
|
+
* own, so a root inside a callback or a hole compiles the way a top-level root
|
|
31
|
+
* does; absent a front-end, partial templates stay on, as at the top level.
|
|
32
|
+
*/
|
|
33
|
+
export interface NestedEmitOptions {
|
|
34
|
+
partialTemplates?: boolean;
|
|
35
|
+
templateClone?: boolean;
|
|
36
|
+
}
|
|
28
37
|
export declare const SVG_TAGS: Set<string>;
|
|
29
38
|
export declare function isReactiveExpr(node: t.Expression): boolean;
|
|
30
39
|
/**
|
|
@@ -32,5 +41,5 @@ export declare function isReactiveExpr(node: t.Expression): boolean;
|
|
|
32
41
|
* front-end supplies is how an expression becomes source, `genExpr`, which also
|
|
33
42
|
* compiles any JSX or `` html`` `` nested inside it.
|
|
34
43
|
*/
|
|
35
|
-
export declare function buildIR(node: t.JSXElement | t.JSXFragment, used?: Set<string>, onNested?: NestedHook): IRNode;
|
|
44
|
+
export declare function buildIR(node: t.JSXElement | t.JSXFragment, used?: Set<string>, onNested?: NestedHook, emit?: NestedEmitOptions): IRNode;
|
|
36
45
|
//# sourceMappingURL=build-ir.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-ir.d.ts","sourceRoot":"","sources":["../../../src/frontend/babel/build-ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,KAAK,IAAI,CAAC,EAAsB,MAAM,aAAa,CAAC;AAI7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"build-ir.d.ts","sourceRoot":"","sources":["../../../src/frontend/babel/build-ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,KAAK,IAAI,CAAC,EAAsB,MAAM,aAAa,CAAC;AAI7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AA8DhD,yEAAyE;AACzE,wBAAgB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAEtH;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;AAE9C;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,QAAQ,aAGnB,CAAC;AA2BH,wBAAgB,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,GAAG,OAAO,CAE1D;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,WAAW,EAClC,IAAI,GAAE,GAAG,CAAC,MAAM,CAAa,EAC7B,QAAQ,CAAC,EAAE,UAAU,EACrB,IAAI,CAAC,EAAE,iBAAiB,GACvB,MAAM,CAWR"}
|