@weapp-vite/web 1.3.15 → 1.3.17
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/README.md +2 -2
- package/dist/_virtual/_rolldown/runtime.mjs +18 -0
- package/dist/compiler/wxml/attributes.mjs +93 -0
- package/dist/compiler/wxml/attributes.mjs.map +1 -0
- package/dist/compiler/wxml/compile.mjs +158 -0
- package/dist/compiler/wxml/compile.mjs.map +1 -0
- package/dist/compiler/wxml/dependency.mjs +31 -0
- package/dist/compiler/wxml/dependency.mjs.map +1 -0
- package/dist/compiler/wxml/interpolation.mjs +142 -0
- package/dist/compiler/wxml/interpolation.mjs.map +1 -0
- package/dist/compiler/wxml/navigation.mjs +85 -0
- package/dist/compiler/wxml/navigation.mjs.map +1 -0
- package/dist/compiler/wxml/parser.mjs +41 -0
- package/dist/compiler/wxml/parser.mjs.map +1 -0
- package/dist/compiler/wxml/renderer.mjs +114 -0
- package/dist/compiler/wxml/renderer.mjs.map +1 -0
- package/dist/compiler/wxml/specialNodes.mjs +85 -0
- package/dist/compiler/wxml/specialNodes.mjs.map +1 -0
- package/dist/compiler/wxs.mjs +83 -0
- package/dist/compiler/wxs.mjs.map +1 -0
- package/dist/css/wxss.d.mts +25 -0
- package/dist/css/wxss.mjs +17 -0
- package/dist/css/wxss.mjs.map +1 -0
- package/dist/index.d.mts +18 -2
- package/dist/index.mjs +18 -3
- package/dist/plugin/constants.mjs +43 -0
- package/dist/plugin/constants.mjs.map +1 -0
- package/dist/plugin/entry.mjs +29 -0
- package/dist/plugin/entry.mjs.map +1 -0
- package/dist/plugin/files.mjs +58 -0
- package/dist/plugin/files.mjs.map +1 -0
- package/dist/plugin/index.d.mts +33 -0
- package/dist/plugin/index.mjs +188 -0
- package/dist/plugin/index.mjs.map +1 -0
- package/dist/plugin/navigation.mjs +20 -0
- package/dist/plugin/navigation.mjs.map +1 -0
- package/dist/plugin/path.mjs +85 -0
- package/dist/plugin/path.mjs.map +1 -0
- package/dist/plugin/register.mjs +83 -0
- package/dist/plugin/register.mjs.map +1 -0
- package/dist/plugin/scan.mjs +195 -0
- package/dist/plugin/scan.mjs.map +1 -0
- package/dist/plugin/scanConfig.mjs +45 -0
- package/dist/plugin/scanConfig.mjs.map +1 -0
- package/dist/plugin/state.mjs +22 -0
- package/dist/plugin/state.mjs.map +1 -0
- package/dist/plugin/types.d.mts +46 -0
- package/dist/plugin.d.mts +3 -2
- package/dist/plugin.mjs +3 -2
- package/dist/runtime/button/helpers.mjs +92 -0
- package/dist/runtime/button/helpers.mjs.map +1 -0
- package/dist/runtime/button/index.d.mts +9 -0
- package/dist/runtime/button/index.mjs +198 -0
- package/dist/runtime/button/index.mjs.map +1 -0
- package/dist/runtime/button/style.mjs +168 -0
- package/dist/runtime/button/style.mjs.map +1 -0
- package/dist/runtime/component/behavior.mjs +98 -0
- package/dist/runtime/component/behavior.mjs.map +1 -0
- package/dist/runtime/component/constants.mjs +13 -0
- package/dist/runtime/component/constants.mjs.map +1 -0
- package/dist/runtime/component/dom.mjs +32 -0
- package/dist/runtime/component/dom.mjs.map +1 -0
- package/dist/runtime/component/element.mjs +208 -0
- package/dist/runtime/component/element.mjs.map +1 -0
- package/dist/runtime/component/events.mjs +49 -0
- package/dist/runtime/component/events.mjs.map +1 -0
- package/dist/runtime/component/index.d.mts +7 -0
- package/dist/runtime/component/index.mjs +44 -0
- package/dist/runtime/component/index.mjs.map +1 -0
- package/dist/runtime/component/state.mjs +63 -0
- package/dist/runtime/component/state.mjs.map +1 -0
- package/dist/runtime/component/types.d.mts +49 -0
- package/dist/runtime/component/utils.mjs +39 -0
- package/dist/runtime/component/utils.mjs.map +1 -0
- package/dist/runtime/execution.d.mts +7 -0
- package/dist/runtime/execution.mjs +37 -0
- package/dist/runtime/execution.mjs.map +1 -0
- package/dist/runtime/index.d.mts +16 -2
- package/dist/runtime/index.mjs +16 -2
- package/dist/runtime/legacyTemplate/dom.mjs +76 -0
- package/dist/runtime/legacyTemplate/dom.mjs.map +1 -0
- package/dist/runtime/legacyTemplate/expression.mjs +113 -0
- package/dist/runtime/legacyTemplate/expression.mjs.map +1 -0
- package/dist/runtime/legacyTemplate/index.d.mts +9 -0
- package/dist/runtime/legacyTemplate/index.mjs +132 -0
- package/dist/runtime/legacyTemplate/index.mjs.map +1 -0
- package/dist/runtime/legacyTemplate/types.d.mts +6 -0
- package/dist/runtime/navigationBar/index.d.mts +10 -0
- package/dist/runtime/navigationBar/index.mjs +162 -0
- package/dist/runtime/navigationBar/index.mjs.map +1 -0
- package/dist/runtime/navigationBar/style.mjs +108 -0
- package/dist/runtime/navigationBar/style.mjs.map +1 -0
- package/dist/runtime/polyfill/ad.mjs +150 -0
- package/dist/runtime/polyfill/ad.mjs.map +1 -0
- package/dist/runtime/polyfill/appState.mjs +31 -0
- package/dist/runtime/polyfill/appState.mjs.map +1 -0
- package/dist/runtime/polyfill/async.mjs +31 -0
- package/dist/runtime/polyfill/async.mjs.map +1 -0
- package/dist/runtime/polyfill/auth.mjs +120 -0
- package/dist/runtime/polyfill/auth.mjs.map +1 -0
- package/dist/runtime/polyfill/authApi.mjs +101 -0
- package/dist/runtime/polyfill/authApi.mjs.map +1 -0
- package/dist/runtime/polyfill/background.mjs +31 -0
- package/dist/runtime/polyfill/background.mjs.map +1 -0
- package/dist/runtime/polyfill/canvasContext.mjs +115 -0
- package/dist/runtime/polyfill/canvasContext.mjs.map +1 -0
- package/dist/runtime/polyfill/capability.mjs +20 -0
- package/dist/runtime/polyfill/capability.mjs.map +1 -0
- package/dist/runtime/polyfill/cloud.mjs +39 -0
- package/dist/runtime/polyfill/cloud.mjs.map +1 -0
- package/dist/runtime/polyfill/device.mjs +44 -0
- package/dist/runtime/polyfill/device.mjs.map +1 -0
- package/dist/runtime/polyfill/deviceApi.mjs +31 -0
- package/dist/runtime/polyfill/deviceApi.mjs.map +1 -0
- package/dist/runtime/polyfill/deviceAuthSystemApi.d.mts +102 -0
- package/dist/runtime/polyfill/deviceAuthSystemApi.mjs +144 -0
- package/dist/runtime/polyfill/deviceAuthSystemApi.mjs.map +1 -0
- package/dist/runtime/polyfill/filePicker.mjs +158 -0
- package/dist/runtime/polyfill/filePicker.mjs.map +1 -0
- package/dist/runtime/polyfill/fileSystemManager.mjs +45 -0
- package/dist/runtime/polyfill/fileSystemManager.mjs.map +1 -0
- package/dist/runtime/polyfill/files.mjs +118 -0
- package/dist/runtime/polyfill/files.mjs.map +1 -0
- package/dist/runtime/polyfill/index.d.mts +40 -0
- package/dist/runtime/polyfill/index.mjs +110 -0
- package/dist/runtime/polyfill/index.mjs.map +1 -0
- package/dist/runtime/polyfill/interaction.mjs +38 -0
- package/dist/runtime/polyfill/interaction.mjs.map +1 -0
- package/dist/runtime/polyfill/interactionApi.mjs +54 -0
- package/dist/runtime/polyfill/interactionApi.mjs.map +1 -0
- package/dist/runtime/polyfill/location.mjs +106 -0
- package/dist/runtime/polyfill/location.mjs.map +1 -0
- package/dist/runtime/polyfill/locationApi.mjs +120 -0
- package/dist/runtime/polyfill/locationApi.mjs.map +1 -0
- package/dist/runtime/polyfill/mediaActions.mjs +52 -0
- package/dist/runtime/polyfill/mediaActions.mjs.map +1 -0
- package/dist/runtime/polyfill/mediaApi/file.mjs +63 -0
- package/dist/runtime/polyfill/mediaApi/file.mjs.map +1 -0
- package/dist/runtime/polyfill/mediaApi/info.mjs +59 -0
- package/dist/runtime/polyfill/mediaApi/info.mjs.map +1 -0
- package/dist/runtime/polyfill/mediaApi/picker.mjs +82 -0
- package/dist/runtime/polyfill/mediaApi/picker.mjs.map +1 -0
- package/dist/runtime/polyfill/mediaApi/preview.mjs +39 -0
- package/dist/runtime/polyfill/mediaApi/preview.mjs.map +1 -0
- package/dist/runtime/polyfill/mediaApi/process.mjs +46 -0
- package/dist/runtime/polyfill/mediaApi/process.mjs.map +1 -0
- package/dist/runtime/polyfill/mediaInfo.mjs +136 -0
- package/dist/runtime/polyfill/mediaInfo.mjs.map +1 -0
- package/dist/runtime/polyfill/mediaPicker.mjs +213 -0
- package/dist/runtime/polyfill/mediaPicker.mjs.map +1 -0
- package/dist/runtime/polyfill/mediaProcess.mjs +65 -0
- package/dist/runtime/polyfill/mediaProcess.mjs.map +1 -0
- package/dist/runtime/polyfill/menuApi.mjs +70 -0
- package/dist/runtime/polyfill/menuApi.mjs.map +1 -0
- package/dist/runtime/polyfill/navigationBarRuntime.mjs +66 -0
- package/dist/runtime/polyfill/navigationBarRuntime.mjs.map +1 -0
- package/dist/runtime/polyfill/network/request.mjs +162 -0
- package/dist/runtime/polyfill/network/request.mjs.map +1 -0
- package/dist/runtime/polyfill/network/requestBridge.mjs +49 -0
- package/dist/runtime/polyfill/network/requestBridge.mjs.map +1 -0
- package/dist/runtime/polyfill/network/status.mjs +55 -0
- package/dist/runtime/polyfill/network/status.mjs.map +1 -0
- package/dist/runtime/polyfill/platformApi.mjs +33 -0
- package/dist/runtime/polyfill/platformApi.mjs.map +1 -0
- package/dist/runtime/polyfill/platformRuntime.mjs +120 -0
- package/dist/runtime/polyfill/platformRuntime.mjs.map +1 -0
- package/dist/runtime/polyfill/routeRuntime/dom.mjs +36 -0
- package/dist/runtime/polyfill/routeRuntime/dom.mjs.map +1 -0
- package/dist/runtime/polyfill/routeRuntime/lifecycle.mjs +83 -0
- package/dist/runtime/polyfill/routeRuntime/lifecycle.mjs.map +1 -0
- package/dist/runtime/polyfill/routeRuntime/options.d.mts +33 -0
- package/dist/runtime/polyfill/routeRuntime/options.mjs +76 -0
- package/dist/runtime/polyfill/routeRuntime/options.mjs.map +1 -0
- package/dist/runtime/polyfill/routeRuntime/url.mjs +35 -0
- package/dist/runtime/polyfill/routeRuntime/url.mjs.map +1 -0
- package/dist/runtime/polyfill/routeRuntime.d.mts +43 -0
- package/dist/runtime/polyfill/routeRuntime.mjs +202 -0
- package/dist/runtime/polyfill/routeRuntime.mjs.map +1 -0
- package/dist/runtime/polyfill/runtimeCapabilityApi.mjs +26 -0
- package/dist/runtime/polyfill/runtimeCapabilityApi.mjs.map +1 -0
- package/dist/runtime/polyfill/runtimeDataApi.d.mts +79 -0
- package/dist/runtime/polyfill/runtimeDataApi.mjs +134 -0
- package/dist/runtime/polyfill/runtimeDataApi.mjs.map +1 -0
- package/dist/runtime/polyfill/runtimeInfra.mjs +40 -0
- package/dist/runtime/polyfill/runtimeInfra.mjs.map +1 -0
- package/dist/runtime/polyfill/runtimeOps.mjs +62 -0
- package/dist/runtime/polyfill/runtimeOps.mjs.map +1 -0
- package/dist/runtime/polyfill/selectorQuery.mjs +204 -0
- package/dist/runtime/polyfill/selectorQuery.mjs.map +1 -0
- package/dist/runtime/polyfill/storage.mjs +103 -0
- package/dist/runtime/polyfill/storage.mjs.map +1 -0
- package/dist/runtime/polyfill/storageAsync.mjs +62 -0
- package/dist/runtime/polyfill/storageAsync.mjs.map +1 -0
- package/dist/runtime/polyfill/subscribe.mjs +30 -0
- package/dist/runtime/polyfill/subscribe.mjs.map +1 -0
- package/dist/runtime/polyfill/system.mjs +111 -0
- package/dist/runtime/polyfill/system.mjs.map +1 -0
- package/dist/runtime/polyfill/systemApi.mjs +65 -0
- package/dist/runtime/polyfill/systemApi.mjs.map +1 -0
- package/dist/runtime/polyfill/types/base.d.mts +12 -0
- package/dist/runtime/polyfill/types/common.d.mts +126 -0
- package/dist/runtime/polyfill/types/locationRuntime.d.mts +151 -0
- package/dist/runtime/polyfill/types/mediaAuth.d.mts +152 -0
- package/dist/runtime/polyfill/types/platformRuntime.d.mts +141 -0
- package/dist/runtime/polyfill/types/systemAuth.d.mts +122 -0
- package/dist/runtime/polyfill/ui.mjs +135 -0
- package/dist/runtime/polyfill/ui.mjs.map +1 -0
- package/dist/runtime/polyfill/uiFeedback.mjs +35 -0
- package/dist/runtime/polyfill/uiFeedback.mjs.map +1 -0
- package/dist/runtime/polyfill/uiMediaApi.d.mts +172 -0
- package/dist/runtime/polyfill/uiMediaApi.mjs +162 -0
- package/dist/runtime/polyfill/uiMediaApi.mjs.map +1 -0
- package/dist/runtime/polyfill/videoContext.mjs +56 -0
- package/dist/runtime/polyfill/videoContext.mjs.map +1 -0
- package/dist/runtime/polyfill/vkSession.mjs +58 -0
- package/dist/runtime/polyfill/vkSession.mjs.map +1 -0
- package/dist/runtime/polyfill/windowResize.mjs +39 -0
- package/dist/runtime/polyfill/windowResize.mjs.map +1 -0
- package/dist/runtime/polyfill/worker.mjs +77 -0
- package/dist/runtime/polyfill/worker.mjs.map +1 -0
- package/dist/runtime/polyfill.d.mts +5 -0
- package/dist/runtime/renderContext.d.mts +21 -0
- package/dist/runtime/renderContext.mjs +147 -0
- package/dist/runtime/renderContext.mjs.map +1 -0
- package/dist/runtime/rpx.d.mts +9 -0
- package/dist/runtime/rpx.mjs +27 -0
- package/dist/runtime/rpx.mjs.map +1 -0
- package/dist/runtime/style.d.mts +6 -0
- package/dist/runtime/style.mjs +37 -0
- package/dist/runtime/style.mjs.map +1 -0
- package/dist/runtime/template.d.mts +10 -0
- package/dist/runtime/warning.d.mts +10 -0
- package/dist/runtime/warning.mjs +43 -0
- package/dist/runtime/warning.mjs.map +1 -0
- package/dist/{slugify-B4l45KNs.mjs → shared/slugify.mjs} +3 -1
- package/dist/shared/slugify.mjs.map +1 -0
- package/dist/shared/wxml.mjs +83 -0
- package/dist/shared/wxml.mjs.map +1 -0
- package/package.json +2 -2
- package/dist/index-w9xxIH-l.d.mts +0 -1229
- package/dist/plugin-BARxSPO8.mjs +0 -1567
- package/dist/plugin-DP2iPVmw.d.mts +0 -96
- package/dist/runtime-D6j2_x_N.mjs +0 -6251
package/README.md
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
实验性的 H5 运行时与工具集,为 `weapp-vite` 工程提供最小化的浏览器适配能力:
|
|
4
4
|
|
|
5
5
|
- 将 `wxml` 模板编译为渲染函数,并在 Web Components 中渲染
|
|
6
|
-
- 支持 `wx
|
|
6
|
+
- 支持 `wx` / `a` / `tt` / `s` 前缀的条件与循环指令,以及插值语法等常见模板语法糖
|
|
7
7
|
- 将小程序 `Page` / `Component` 映射为自定义元素,Shadow DOM 隔离样式与事件
|
|
8
8
|
- 事件桥接(如 `bindtap` → `click`),保留 `this.setData`、`this.triggerEvent` 等调用体验
|
|
9
|
-
- `wx.navigateTo` / `
|
|
9
|
+
- 提供宿主中立的小程序桥,并兼容 `wx.navigateTo` / `my.navigateTo` / `tt.navigateTo` 等路由调用,以及 `getCurrentPages`、`onLoad`、`onShow`、`onHide`、`onUnload` 生命周期
|
|
10
10
|
- `App` 级别的 `onLaunch` / `onShow` 回调、`getApp` 全局实例访问
|
|
11
11
|
- `wxss` → `css` 的基础转换,默认按 `1rpx = 0.5px`
|
|
12
12
|
- 提供 Vite 插件,自动把 `.wxml` / `.wxss` 转换为 Web 侧模块
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) {
|
|
6
|
+
__defProp(target, name, {
|
|
7
|
+
get: all[name],
|
|
8
|
+
enumerable: true
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
if (!no_symbols) {
|
|
12
|
+
__defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
13
|
+
}
|
|
14
|
+
return target;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { __exportAll };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { CONTROL_ATTRS, EVENT_KIND_ALIAS, EVENT_PREFIX_RE, hasControlAttribute, normalizeAttributeName, resolveControlAttributeValue } from "../../shared/wxml.mjs";
|
|
2
|
+
import { buildExpression, parseInterpolations } from "./interpolation.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/compiler/wxml/attributes.ts
|
|
5
|
+
function extractFor(attribs) {
|
|
6
|
+
const expr = resolveControlAttributeValue(attribs, "for");
|
|
7
|
+
const itemName = resolveControlAttributeValue(attribs, "for-item")?.trim() || "item";
|
|
8
|
+
let indexName = resolveControlAttributeValue(attribs, "for-index")?.trim() || "index";
|
|
9
|
+
const key = resolveControlAttributeValue(attribs, "key");
|
|
10
|
+
const restAttribs = {};
|
|
11
|
+
for (const [name, value] of Object.entries(attribs)) {
|
|
12
|
+
if (CONTROL_ATTRS.has(name)) continue;
|
|
13
|
+
restAttribs[name] = value;
|
|
14
|
+
}
|
|
15
|
+
if (itemName === indexName) indexName = `${indexName}Index`;
|
|
16
|
+
return {
|
|
17
|
+
expr,
|
|
18
|
+
itemName,
|
|
19
|
+
indexName,
|
|
20
|
+
key,
|
|
21
|
+
restAttribs
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function isConditionalElement(node) {
|
|
25
|
+
if (node.type !== "element") return false;
|
|
26
|
+
const attribs = node.attribs ?? {};
|
|
27
|
+
return hasControlAttribute(attribs, "if") || hasControlAttribute(attribs, "elif") || hasControlAttribute(attribs, "else");
|
|
28
|
+
}
|
|
29
|
+
function stripControlAttributes(attribs) {
|
|
30
|
+
const result = {};
|
|
31
|
+
for (const [name, value] of Object.entries(attribs)) if (!CONTROL_ATTRS.has(name)) result[name] = value;
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
function parseEventAttribute(name) {
|
|
35
|
+
if (name.includes(":")) {
|
|
36
|
+
const [prefix, rawEvent] = name.split(":", 2);
|
|
37
|
+
return {
|
|
38
|
+
prefix,
|
|
39
|
+
rawEvent
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const match = EVENT_PREFIX_RE.exec(name);
|
|
43
|
+
if (!match) return;
|
|
44
|
+
return {
|
|
45
|
+
prefix: name.slice(0, name.length - match[1].length),
|
|
46
|
+
rawEvent: match[1]
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function resolveComponentTagName(name, componentTags) {
|
|
50
|
+
if (!componentTags) return;
|
|
51
|
+
return componentTags[name] ?? componentTags[name.toLowerCase()];
|
|
52
|
+
}
|
|
53
|
+
const PROPERTY_BIND_EXCLUSIONS = new Set([
|
|
54
|
+
"class",
|
|
55
|
+
"style",
|
|
56
|
+
"id",
|
|
57
|
+
"slot"
|
|
58
|
+
]);
|
|
59
|
+
function shouldBindAsProperty(name) {
|
|
60
|
+
if (PROPERTY_BIND_EXCLUSIONS.has(name)) return false;
|
|
61
|
+
if (name.startsWith("data-") || name.startsWith("aria-")) return false;
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
function normalizePropertyName(name) {
|
|
65
|
+
return name.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
66
|
+
}
|
|
67
|
+
function renderAttributes(attribs, scopeVar, wxsVar, options) {
|
|
68
|
+
let buffer = "";
|
|
69
|
+
for (const [rawName, rawValue] of Object.entries(attribs)) {
|
|
70
|
+
if (options?.skipControl && CONTROL_ATTRS.has(rawName)) continue;
|
|
71
|
+
const eventInfo = parseEventAttribute(rawName);
|
|
72
|
+
if (eventInfo) {
|
|
73
|
+
const event = eventInfo.rawEvent.toLowerCase();
|
|
74
|
+
const handlerExpr = buildExpression(parseInterpolations(rawValue ?? ""), scopeVar, wxsVar);
|
|
75
|
+
const domEvent = EVENT_KIND_ALIAS[event] ?? event;
|
|
76
|
+
const flags = {
|
|
77
|
+
catch: eventInfo.prefix.includes("catch"),
|
|
78
|
+
capture: eventInfo.prefix.includes("capture")
|
|
79
|
+
};
|
|
80
|
+
buffer += ` @${domEvent}=\${ctx.event(${JSON.stringify(event)}, ${handlerExpr}, ${scopeVar}, ${wxsVar}, ${JSON.stringify(flags)})}`;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const useProperty = options?.preferProperty && shouldBindAsProperty(rawName);
|
|
84
|
+
const name = useProperty ? normalizePropertyName(rawName) : normalizeAttributeName(rawName);
|
|
85
|
+
const expr = buildExpression(parseInterpolations(rawValue ?? ""), scopeVar, wxsVar);
|
|
86
|
+
buffer += ` ${useProperty ? "." : ""}${name}=\${${expr}}`;
|
|
87
|
+
}
|
|
88
|
+
return buffer;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
export { extractFor, isConditionalElement, renderAttributes, resolveComponentTagName, stripControlAttributes };
|
|
93
|
+
//# sourceMappingURL=attributes.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributes.mjs","names":[],"sources":["../../../src/compiler/wxml/attributes.ts"],"sourcesContent":["import type { RenderElementNode, RenderNode } from './types'\nimport {\n CONTROL_ATTRS,\n EVENT_KIND_ALIAS,\n EVENT_PREFIX_RE,\n hasControlAttribute,\n normalizeAttributeName,\n resolveControlAttributeValue,\n} from '../../shared/wxml'\nimport { buildExpression, parseInterpolations } from './interpolation'\n\nexport function extractFor(attribs: Record<string, string>) {\n const expr = resolveControlAttributeValue(attribs, 'for')\n const itemName = resolveControlAttributeValue(attribs, 'for-item')?.trim() || 'item'\n let indexName = resolveControlAttributeValue(attribs, 'for-index')?.trim() || 'index'\n const key = resolveControlAttributeValue(attribs, 'key')\n const restAttribs: Record<string, string> = {}\n for (const [name, value] of Object.entries(attribs)) {\n if (CONTROL_ATTRS.has(name)) {\n continue\n }\n restAttribs[name] = value\n }\n if (itemName === indexName) {\n indexName = `${indexName}Index`\n }\n return { expr, itemName, indexName, key, restAttribs }\n}\n\nexport function isConditionalElement(node: RenderNode): node is RenderElementNode {\n if (node.type !== 'element') {\n return false\n }\n const attribs = node.attribs ?? {}\n return hasControlAttribute(attribs, 'if')\n || hasControlAttribute(attribs, 'elif')\n || hasControlAttribute(attribs, 'else')\n}\n\nexport function stripControlAttributes(attribs: Record<string, string>) {\n const result: Record<string, string> = {}\n for (const [name, value] of Object.entries(attribs)) {\n if (!CONTROL_ATTRS.has(name)) {\n result[name] = value\n }\n }\n return result\n}\n\nfunction parseEventAttribute(name: string) {\n if (name.includes(':')) {\n const [prefix, rawEvent] = name.split(':', 2)\n return { prefix, rawEvent }\n }\n const match = EVENT_PREFIX_RE.exec(name)\n if (!match) {\n return undefined\n }\n return { prefix: name.slice(0, name.length - match[1].length), rawEvent: match[1] }\n}\n\nexport function resolveComponentTagName(name: string, componentTags?: Record<string, string>) {\n if (!componentTags) {\n return undefined\n }\n return componentTags[name] ?? componentTags[name.toLowerCase()]\n}\n\nconst PROPERTY_BIND_EXCLUSIONS = new Set(['class', 'style', 'id', 'slot'])\n\nfunction shouldBindAsProperty(name: string) {\n if (PROPERTY_BIND_EXCLUSIONS.has(name)) {\n return false\n }\n if (name.startsWith('data-') || name.startsWith('aria-')) {\n return false\n }\n return true\n}\n\nfunction normalizePropertyName(name: string) {\n return name.replace(/-([a-z])/g, (_, char: string) => char.toUpperCase())\n}\n\nexport function renderAttributes(\n attribs: Record<string, string>,\n scopeVar: string,\n wxsVar: string,\n options?: { skipControl?: boolean, preferProperty?: boolean },\n) {\n let buffer = ''\n for (const [rawName, rawValue] of Object.entries(attribs)) {\n if (options?.skipControl && CONTROL_ATTRS.has(rawName)) {\n continue\n }\n const eventInfo = parseEventAttribute(rawName)\n if (eventInfo) {\n const event = eventInfo.rawEvent.toLowerCase()\n const handlerExpr = buildExpression(parseInterpolations(rawValue ?? ''), scopeVar, wxsVar)\n const domEvent = EVENT_KIND_ALIAS[event] ?? event\n const flags = {\n catch: eventInfo.prefix.includes('catch'),\n capture: eventInfo.prefix.includes('capture'),\n }\n buffer += ` @${domEvent}=\\${ctx.event(${JSON.stringify(event)}, ${handlerExpr}, ${scopeVar}, ${wxsVar}, ${JSON.stringify(flags)})}`\n continue\n }\n const useProperty = options?.preferProperty && shouldBindAsProperty(rawName)\n const name = useProperty ? normalizePropertyName(rawName) : normalizeAttributeName(rawName)\n const expr = buildExpression(parseInterpolations(rawValue ?? ''), scopeVar, wxsVar)\n buffer += ` ${useProperty ? '.' : ''}${name}=\\${${expr}}`\n }\n return buffer\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { addDependency, createDependencyContext, warnCircularTemplate, warnReadTemplate } from "./dependency.mjs";
|
|
2
|
+
import { buildNavigationBarAttrs, extractNavigationBarFromPageMeta } from "./navigation.mjs";
|
|
3
|
+
import { parseWxml } from "./parser.mjs";
|
|
4
|
+
import { renderer } from "./renderer.mjs";
|
|
5
|
+
import { collectSpecialNodes, normalizeTemplatePath, shouldMarkWxsImport, toRelativeImport } from "./specialNodes.mjs";
|
|
6
|
+
import { readFileSync } from "node:fs";
|
|
7
|
+
|
|
8
|
+
//#region src/compiler/wxml/compile.ts
|
|
9
|
+
function compileWxml(options) {
|
|
10
|
+
const dependencyContext = options.dependencyContext ?? createDependencyContext();
|
|
11
|
+
const expandDependencies = options.expandDependencies ?? !options.dependencyContext;
|
|
12
|
+
const warnings = dependencyContext.warnings;
|
|
13
|
+
const expandDependencyTree = (dependencies, importer) => {
|
|
14
|
+
for (const target of dependencies) {
|
|
15
|
+
if (!target) continue;
|
|
16
|
+
if (dependencyContext.active.has(target)) {
|
|
17
|
+
warnCircularTemplate(dependencyContext, importer, target);
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (dependencyContext.visited.has(target)) continue;
|
|
21
|
+
dependencyContext.visited.add(target);
|
|
22
|
+
dependencyContext.active.add(target);
|
|
23
|
+
let source;
|
|
24
|
+
try {
|
|
25
|
+
source = readFileSync(target, "utf8");
|
|
26
|
+
} catch {
|
|
27
|
+
warnReadTemplate(dependencyContext, target);
|
|
28
|
+
dependencyContext.active.delete(target);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
expandDependencyTree(compileWxml({
|
|
33
|
+
id: target,
|
|
34
|
+
source,
|
|
35
|
+
resolveTemplatePath: options.resolveTemplatePath,
|
|
36
|
+
resolveWxsPath: options.resolveWxsPath,
|
|
37
|
+
dependencyContext,
|
|
38
|
+
expandDependencies: false
|
|
39
|
+
}).dependencies, target);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (error instanceof Error && error.message) warnings.push(`[web] 无法解析模板依赖: ${target} ${error.message}`);
|
|
42
|
+
}
|
|
43
|
+
dependencyContext.active.delete(target);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
let nodes = parseWxml(options.source);
|
|
47
|
+
let navigationBarAttrs;
|
|
48
|
+
if (options.navigationBar) {
|
|
49
|
+
const extracted = extractNavigationBarFromPageMeta(nodes);
|
|
50
|
+
nodes = extracted.nodes;
|
|
51
|
+
if (extracted.warnings.length > 0) warnings.push(...extracted.warnings);
|
|
52
|
+
navigationBarAttrs = extracted.attrs;
|
|
53
|
+
}
|
|
54
|
+
const templates = [];
|
|
55
|
+
const includes = [];
|
|
56
|
+
const imports = [];
|
|
57
|
+
const wxs = [];
|
|
58
|
+
const renderNodesList = collectSpecialNodes(nodes, {
|
|
59
|
+
templates,
|
|
60
|
+
includes,
|
|
61
|
+
imports,
|
|
62
|
+
wxs,
|
|
63
|
+
wxsModules: /* @__PURE__ */ new Map(),
|
|
64
|
+
warnings,
|
|
65
|
+
sourceId: options.id,
|
|
66
|
+
resolveTemplate: (raw) => options.resolveTemplatePath(raw, options.id),
|
|
67
|
+
resolveWxs: (raw) => options.resolveWxsPath(raw, options.id)
|
|
68
|
+
});
|
|
69
|
+
if (options.navigationBar && options.navigationBar.config.navigationStyle !== "custom") {
|
|
70
|
+
const attrs = buildNavigationBarAttrs(options.navigationBar.config, navigationBarAttrs);
|
|
71
|
+
renderNodesList.unshift({
|
|
72
|
+
type: "element",
|
|
73
|
+
name: "weapp-navigation-bar",
|
|
74
|
+
attribs: attrs
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const importLines = [`import { html } from 'lit'`, `import { repeat } from 'lit/directives/repeat.js'`];
|
|
78
|
+
const bodyLines = [];
|
|
79
|
+
const directDependencies = [];
|
|
80
|
+
for (const entry of imports) {
|
|
81
|
+
const importPath = normalizeTemplatePath(toRelativeImport(options.id, entry.id));
|
|
82
|
+
importLines.push(`import { templates as ${entry.importName} } from '${importPath}'`);
|
|
83
|
+
addDependency(entry.id, dependencyContext, directDependencies);
|
|
84
|
+
}
|
|
85
|
+
for (const entry of includes) {
|
|
86
|
+
const importPath = normalizeTemplatePath(toRelativeImport(options.id, entry.id));
|
|
87
|
+
importLines.push(`import { render as ${entry.importName} } from '${importPath}'`);
|
|
88
|
+
addDependency(entry.id, dependencyContext, directDependencies);
|
|
89
|
+
}
|
|
90
|
+
for (const entry of wxs) if (entry.kind === "src") {
|
|
91
|
+
const baseImport = normalizeTemplatePath(toRelativeImport(options.id, entry.value));
|
|
92
|
+
const importPath = shouldMarkWxsImport(entry.value) ? `${baseImport}?wxs` : baseImport;
|
|
93
|
+
importLines.push(`import ${entry.importName} from '${importPath}'`);
|
|
94
|
+
addDependency(entry.value, dependencyContext, directDependencies);
|
|
95
|
+
}
|
|
96
|
+
if (templates.length > 0 || imports.length > 0) {
|
|
97
|
+
const templatePairs = [];
|
|
98
|
+
for (const entry of imports) templatePairs.push(`...${entry.importName}`);
|
|
99
|
+
for (const template of templates) {
|
|
100
|
+
const rendered = renderer.renderNodes(template.nodes, "scope", "__wxs_modules", options.componentTags);
|
|
101
|
+
templatePairs.push(`${JSON.stringify(template.name)}: (scope, ctx) => ${rendered}`);
|
|
102
|
+
}
|
|
103
|
+
bodyLines.push(`const __templates = { ${templatePairs.join(", ")} }`);
|
|
104
|
+
} else bodyLines.push(`const __templates = {}`);
|
|
105
|
+
if (wxs.length > 0) {
|
|
106
|
+
bodyLines.push(`const __wxs_inline_cache = Object.create(null)`);
|
|
107
|
+
bodyLines.push(`let __wxs_modules = {}`);
|
|
108
|
+
const wxsMapEntries = [];
|
|
109
|
+
for (const entry of wxs) {
|
|
110
|
+
if (entry.kind === "inline") {
|
|
111
|
+
const inlineCode = entry.value.trim();
|
|
112
|
+
const cacheKey = JSON.stringify(entry.module);
|
|
113
|
+
if (inlineCode) {
|
|
114
|
+
bodyLines.push(`function ${entry.importName}(ctx) {`);
|
|
115
|
+
bodyLines.push(` if (!__wxs_inline_cache[${cacheKey}]) {`);
|
|
116
|
+
bodyLines.push(` __wxs_inline_cache[${cacheKey}] = ctx.createWxsModule(${JSON.stringify(inlineCode)}, ${JSON.stringify(options.id)})`);
|
|
117
|
+
bodyLines.push(` }`);
|
|
118
|
+
bodyLines.push(` return __wxs_inline_cache[${cacheKey}]`);
|
|
119
|
+
bodyLines.push(`}`);
|
|
120
|
+
} else bodyLines.push(`function ${entry.importName}() { return {} }`);
|
|
121
|
+
wxsMapEntries.push(`${JSON.stringify(entry.module)}: ${entry.importName}(ctx)`);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
wxsMapEntries.push(`${JSON.stringify(entry.module)}: ${entry.importName}`);
|
|
125
|
+
}
|
|
126
|
+
bodyLines.push(`function __resolveWxsModules(ctx) {`);
|
|
127
|
+
bodyLines.push(` return { ${wxsMapEntries.join(", ")} }`);
|
|
128
|
+
bodyLines.push(`}`);
|
|
129
|
+
} else bodyLines.push(`const __wxs_modules = {}`);
|
|
130
|
+
const includesRender = includes.map((entry) => `${entry.importName}(scope, ctx)`);
|
|
131
|
+
const renderContent = renderer.renderNodes(renderNodesList, "scope", "__wxs_modules", options.componentTags);
|
|
132
|
+
const contentExpr = includesRender.length > 0 ? `[${[...includesRender, renderContent].join(", ")}]` : renderContent;
|
|
133
|
+
bodyLines.push(`export function render(scope, ctx) {`);
|
|
134
|
+
if (wxs.length > 0) bodyLines.push(` __wxs_modules = __resolveWxsModules(ctx)`);
|
|
135
|
+
bodyLines.push(` return ${contentExpr}`);
|
|
136
|
+
bodyLines.push(`}`);
|
|
137
|
+
bodyLines.push(`export const templates = __templates`);
|
|
138
|
+
bodyLines.push(`export default render`);
|
|
139
|
+
if (expandDependencies) {
|
|
140
|
+
dependencyContext.visited.add(options.id);
|
|
141
|
+
dependencyContext.active.add(options.id);
|
|
142
|
+
expandDependencyTree(directDependencies, options.id);
|
|
143
|
+
dependencyContext.active.delete(options.id);
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
code: [
|
|
147
|
+
...importLines,
|
|
148
|
+
"",
|
|
149
|
+
...bodyLines
|
|
150
|
+
].join("\n"),
|
|
151
|
+
dependencies: expandDependencies ? dependencyContext.dependencies : directDependencies,
|
|
152
|
+
warnings: warnings.length > 0 ? warnings : void 0
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
//#endregion
|
|
157
|
+
export { compileWxml };
|
|
158
|
+
//# sourceMappingURL=compile.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.mjs","names":[],"sources":["../../../src/compiler/wxml/compile.ts"],"sourcesContent":["import type {\n ImportEntry,\n IncludeEntry,\n TemplateDefinition,\n WxmlCompileOptions,\n WxmlCompileResult,\n WxsEntry,\n} from './types'\n\nimport { readFileSync } from 'node:fs'\nimport { addDependency, createDependencyContext, warnCircularTemplate, warnReadTemplate } from './dependency'\nimport { buildNavigationBarAttrs, extractNavigationBarFromPageMeta } from './navigation'\nimport { parseWxml } from './parser'\nimport { renderer } from './renderer'\nimport { collectSpecialNodes, normalizeTemplatePath, shouldMarkWxsImport, toRelativeImport } from './specialNodes'\n\nexport function compileWxml(options: WxmlCompileOptions): WxmlCompileResult {\n const dependencyContext = options.dependencyContext ?? createDependencyContext()\n const expandDependencies = options.expandDependencies ?? !options.dependencyContext\n const warnings = dependencyContext.warnings\n\n const expandDependencyTree = (dependencies: string[], importer: string) => {\n for (const target of dependencies) {\n if (!target) {\n continue\n }\n if (dependencyContext.active.has(target)) {\n warnCircularTemplate(dependencyContext, importer, target)\n continue\n }\n if (dependencyContext.visited.has(target)) {\n continue\n }\n dependencyContext.visited.add(target)\n dependencyContext.active.add(target)\n let source: string\n try {\n source = readFileSync(target, 'utf8')\n }\n catch {\n warnReadTemplate(dependencyContext, target)\n dependencyContext.active.delete(target)\n continue\n }\n try {\n const result = compileWxml({\n id: target,\n source,\n resolveTemplatePath: options.resolveTemplatePath,\n resolveWxsPath: options.resolveWxsPath,\n dependencyContext,\n expandDependencies: false,\n })\n expandDependencyTree(result.dependencies, target)\n }\n catch (error) {\n if (error instanceof Error && error.message) {\n warnings.push(`[web] 无法解析模板依赖: ${target} ${error.message}`)\n }\n }\n dependencyContext.active.delete(target)\n }\n }\n\n let nodes = parseWxml(options.source)\n let navigationBarAttrs: Record<string, string> | undefined\n if (options.navigationBar) {\n const extracted = extractNavigationBarFromPageMeta(nodes)\n nodes = extracted.nodes\n if (extracted.warnings.length > 0) {\n warnings.push(...extracted.warnings)\n }\n navigationBarAttrs = extracted.attrs\n }\n\n const templates: TemplateDefinition[] = []\n const includes: IncludeEntry[] = []\n const imports: ImportEntry[] = []\n const wxs: WxsEntry[] = []\n const wxsModules = new Map<string, string>()\n\n const renderNodesList = collectSpecialNodes(nodes, {\n templates,\n includes,\n imports,\n wxs,\n wxsModules,\n warnings,\n sourceId: options.id,\n resolveTemplate: (raw: string) => options.resolveTemplatePath(raw, options.id),\n resolveWxs: (raw: string) => options.resolveWxsPath(raw, options.id),\n })\n\n if (options.navigationBar && options.navigationBar.config.navigationStyle !== 'custom') {\n const attrs = buildNavigationBarAttrs(options.navigationBar.config, navigationBarAttrs)\n renderNodesList.unshift({\n type: 'element',\n name: 'weapp-navigation-bar',\n attribs: attrs,\n })\n }\n\n const importLines: string[] = [\n `import { html } from 'lit'`,\n `import { repeat } from 'lit/directives/repeat.js'`,\n ]\n const bodyLines: string[] = []\n const directDependencies: string[] = []\n\n for (const entry of imports) {\n const importPath = normalizeTemplatePath(toRelativeImport(options.id, entry.id))\n importLines.push(`import { templates as ${entry.importName} } from '${importPath}'`)\n addDependency(entry.id, dependencyContext, directDependencies)\n }\n\n for (const entry of includes) {\n const importPath = normalizeTemplatePath(toRelativeImport(options.id, entry.id))\n importLines.push(`import { render as ${entry.importName} } from '${importPath}'`)\n addDependency(entry.id, dependencyContext, directDependencies)\n }\n\n for (const entry of wxs) {\n if (entry.kind === 'src') {\n const baseImport = normalizeTemplatePath(toRelativeImport(options.id, entry.value))\n const importPath = shouldMarkWxsImport(entry.value)\n ? `${baseImport}?wxs`\n : baseImport\n importLines.push(`import ${entry.importName} from '${importPath}'`)\n addDependency(entry.value, dependencyContext, directDependencies)\n }\n }\n\n if (templates.length > 0 || imports.length > 0) {\n const templatePairs: string[] = []\n for (const entry of imports) {\n templatePairs.push(`...${entry.importName}`)\n }\n for (const template of templates) {\n const rendered = renderer.renderNodes(template.nodes, 'scope', '__wxs_modules', options.componentTags)\n templatePairs.push(`${JSON.stringify(template.name)}: (scope, ctx) => ${rendered}`)\n }\n bodyLines.push(`const __templates = { ${templatePairs.join(', ')} }`)\n }\n else {\n bodyLines.push(`const __templates = {}`)\n }\n\n if (wxs.length > 0) {\n bodyLines.push(`const __wxs_inline_cache = Object.create(null)`)\n bodyLines.push(`let __wxs_modules = {}`)\n const wxsMapEntries: string[] = []\n for (const entry of wxs) {\n if (entry.kind === 'inline') {\n const inlineCode = entry.value.trim()\n const cacheKey = JSON.stringify(entry.module)\n if (inlineCode) {\n bodyLines.push(`function ${entry.importName}(ctx) {`)\n bodyLines.push(` if (!__wxs_inline_cache[${cacheKey}]) {`)\n bodyLines.push(` __wxs_inline_cache[${cacheKey}] = ctx.createWxsModule(${JSON.stringify(inlineCode)}, ${JSON.stringify(options.id)})`)\n bodyLines.push(` }`)\n bodyLines.push(` return __wxs_inline_cache[${cacheKey}]`)\n bodyLines.push(`}`)\n }\n else {\n bodyLines.push(`function ${entry.importName}() { return {} }`)\n }\n wxsMapEntries.push(`${JSON.stringify(entry.module)}: ${entry.importName}(ctx)`)\n continue\n }\n wxsMapEntries.push(`${JSON.stringify(entry.module)}: ${entry.importName}`)\n }\n bodyLines.push(`function __resolveWxsModules(ctx) {`)\n bodyLines.push(` return { ${wxsMapEntries.join(', ')} }`)\n bodyLines.push(`}`)\n }\n else {\n bodyLines.push(`const __wxs_modules = {}`)\n }\n\n const includesRender = includes.map(entry => `${entry.importName}(scope, ctx)`)\n const renderContent = renderer.renderNodes(renderNodesList, 'scope', '__wxs_modules', options.componentTags)\n const contentExpr = includesRender.length > 0\n ? `[${[...includesRender, renderContent].join(', ')}]`\n : renderContent\n\n bodyLines.push(`export function render(scope, ctx) {`)\n if (wxs.length > 0) {\n bodyLines.push(` __wxs_modules = __resolveWxsModules(ctx)`)\n }\n bodyLines.push(` return ${contentExpr}`)\n bodyLines.push(`}`)\n bodyLines.push(`export const templates = __templates`)\n bodyLines.push(`export default render`)\n\n if (expandDependencies) {\n dependencyContext.visited.add(options.id)\n dependencyContext.active.add(options.id)\n expandDependencyTree(directDependencies, options.id)\n dependencyContext.active.delete(options.id)\n }\n\n const code = [...importLines, '', ...bodyLines].join('\\n')\n const dependencies = expandDependencies ? dependencyContext.dependencies : directDependencies\n return {\n code,\n dependencies,\n warnings: warnings.length > 0 ? warnings : undefined,\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/compiler/wxml/dependency.ts
|
|
2
|
+
function createDependencyContext() {
|
|
3
|
+
return {
|
|
4
|
+
warnings: [],
|
|
5
|
+
dependencies: [],
|
|
6
|
+
dependencySet: /* @__PURE__ */ new Set(),
|
|
7
|
+
visited: /* @__PURE__ */ new Set(),
|
|
8
|
+
active: /* @__PURE__ */ new Set(),
|
|
9
|
+
circularWarnings: /* @__PURE__ */ new Set()
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function addDependency(value, context, direct) {
|
|
13
|
+
if (!context.dependencySet.has(value)) {
|
|
14
|
+
context.dependencySet.add(value);
|
|
15
|
+
context.dependencies.push(value);
|
|
16
|
+
direct?.push(value);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function warnReadTemplate(context, target) {
|
|
20
|
+
context.warnings.push(`[web] 无法读取模板依赖: ${target}`);
|
|
21
|
+
}
|
|
22
|
+
function warnCircularTemplate(context, from, target) {
|
|
23
|
+
const key = `${from}=>${target}`;
|
|
24
|
+
if (context.circularWarnings.has(key)) return;
|
|
25
|
+
context.circularWarnings.add(key);
|
|
26
|
+
context.warnings.push(`[web] WXML 循环引用: ${from} -> ${target}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
export { addDependency, createDependencyContext, warnCircularTemplate, warnReadTemplate };
|
|
31
|
+
//# sourceMappingURL=dependency.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependency.mjs","names":[],"sources":["../../../src/compiler/wxml/dependency.ts"],"sourcesContent":["import type { WxmlDependencyContext } from './types'\n\nexport function createDependencyContext(): WxmlDependencyContext {\n return {\n warnings: [],\n dependencies: [],\n dependencySet: new Set(),\n visited: new Set(),\n active: new Set(),\n circularWarnings: new Set(),\n }\n}\n\nexport function addDependency(\n value: string,\n context: WxmlDependencyContext,\n direct?: string[],\n) {\n if (!context.dependencySet.has(value)) {\n context.dependencySet.add(value)\n context.dependencies.push(value)\n direct?.push(value)\n }\n}\n\nexport function warnReadTemplate(context: WxmlDependencyContext, target: string) {\n context.warnings.push(`[web] 无法读取模板依赖: ${target}`)\n}\n\nexport function warnCircularTemplate(\n context: WxmlDependencyContext,\n from: string,\n target: string,\n) {\n const key = `${from}=>${target}`\n if (context.circularWarnings.has(key)) {\n return\n }\n context.circularWarnings.add(key)\n context.warnings.push(`[web] WXML 循环引用: ${from} -> ${target}`)\n}\n"],"mappings":";AAEA,SAAgB,0BAAiD;AAC/D,QAAO;EACL,UAAU,EAAE;EACZ,cAAc,EAAE;EAChB,+BAAe,IAAI,KAAK;EACxB,yBAAS,IAAI,KAAK;EAClB,wBAAQ,IAAI,KAAK;EACjB,kCAAkB,IAAI,KAAK;EAC5B;;AAGH,SAAgB,cACd,OACA,SACA,QACA;AACA,KAAI,CAAC,QAAQ,cAAc,IAAI,MAAM,EAAE;AACrC,UAAQ,cAAc,IAAI,MAAM;AAChC,UAAQ,aAAa,KAAK,MAAM;AAChC,UAAQ,KAAK,MAAM;;;AAIvB,SAAgB,iBAAiB,SAAgC,QAAgB;AAC/E,SAAQ,SAAS,KAAK,mBAAmB,SAAS;;AAGpD,SAAgB,qBACd,SACA,MACA,QACA;CACA,MAAM,MAAM,GAAG,KAAK,IAAI;AACxB,KAAI,QAAQ,iBAAiB,IAAI,IAAI,CACnC;AAEF,SAAQ,iBAAiB,IAAI,IAAI;AACjC,SAAQ,SAAS,KAAK,oBAAoB,KAAK,MAAM,SAAS"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
//#region src/compiler/wxml/interpolation.ts
|
|
2
|
+
function parseInterpolations(value) {
|
|
3
|
+
const parts = [];
|
|
4
|
+
if (!value.includes("{{")) return [{
|
|
5
|
+
type: "text",
|
|
6
|
+
value
|
|
7
|
+
}];
|
|
8
|
+
let cursor = 0;
|
|
9
|
+
while (cursor < value.length) {
|
|
10
|
+
const start = value.indexOf("{{", cursor);
|
|
11
|
+
if (start === -1) {
|
|
12
|
+
parts.push({
|
|
13
|
+
type: "text",
|
|
14
|
+
value: value.slice(cursor)
|
|
15
|
+
});
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
if (start > cursor) parts.push({
|
|
19
|
+
type: "text",
|
|
20
|
+
value: value.slice(cursor, start)
|
|
21
|
+
});
|
|
22
|
+
const end = value.indexOf("}}", start + 2);
|
|
23
|
+
if (end === -1) {
|
|
24
|
+
parts.push({
|
|
25
|
+
type: "text",
|
|
26
|
+
value: value.slice(start)
|
|
27
|
+
});
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
const expr = value.slice(start + 2, end).trim();
|
|
31
|
+
if (expr) parts.push({
|
|
32
|
+
type: "expr",
|
|
33
|
+
value: expr
|
|
34
|
+
});
|
|
35
|
+
cursor = end + 2;
|
|
36
|
+
}
|
|
37
|
+
return parts;
|
|
38
|
+
}
|
|
39
|
+
function buildExpression(parts, scopeVar, wxsVar) {
|
|
40
|
+
if (parts.length === 0) return "\"\"";
|
|
41
|
+
if (parts.length === 1 && parts[0]?.type === "text") return JSON.stringify(parts[0].value);
|
|
42
|
+
if (parts.length === 1 && parts[0]?.type === "expr") return `ctx.eval(${JSON.stringify(parts[0].value)}, ${scopeVar}, ${wxsVar})`;
|
|
43
|
+
return `(${parts.map((part) => {
|
|
44
|
+
if (part.type === "text") return JSON.stringify(part.value);
|
|
45
|
+
return `ctx.eval(${JSON.stringify(part.value)}, ${scopeVar}, ${wxsVar})`;
|
|
46
|
+
}).join(" + ")})`;
|
|
47
|
+
}
|
|
48
|
+
function hasTopLevelColon(expression) {
|
|
49
|
+
let depth = 0;
|
|
50
|
+
let inSingleQuote = false;
|
|
51
|
+
let inDoubleQuote = false;
|
|
52
|
+
let inTemplate = false;
|
|
53
|
+
let escaped = false;
|
|
54
|
+
let sawTopLevelQuestion = false;
|
|
55
|
+
for (let index = 0; index < expression.length; index += 1) {
|
|
56
|
+
const char = expression[index];
|
|
57
|
+
if (inSingleQuote) {
|
|
58
|
+
if (escaped) {
|
|
59
|
+
escaped = false;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (char === "\\") {
|
|
63
|
+
escaped = true;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (char === "'") inSingleQuote = false;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (inDoubleQuote) {
|
|
70
|
+
if (escaped) {
|
|
71
|
+
escaped = false;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (char === "\\") {
|
|
75
|
+
escaped = true;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (char === "\"") inDoubleQuote = false;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (inTemplate) {
|
|
82
|
+
if (escaped) {
|
|
83
|
+
escaped = false;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (char === "\\") {
|
|
87
|
+
escaped = true;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (char === "`") inTemplate = false;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (char === "'") {
|
|
94
|
+
inSingleQuote = true;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (char === "\"") {
|
|
98
|
+
inDoubleQuote = true;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (char === "`") {
|
|
102
|
+
inTemplate = true;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (char === "(" || char === "[" || char === "{") {
|
|
106
|
+
depth += 1;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (char === ")" || char === "]" || char === "}") {
|
|
110
|
+
depth = Math.max(0, depth - 1);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (depth !== 0) continue;
|
|
114
|
+
if (char === "?") {
|
|
115
|
+
sawTopLevelQuestion = true;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (char === ":") return !sawTopLevelQuestion;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
function shouldWrapShorthandObject(expression) {
|
|
123
|
+
const trimmed = expression.trim();
|
|
124
|
+
if (!trimmed) return false;
|
|
125
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[") || trimmed.startsWith("(")) return false;
|
|
126
|
+
return hasTopLevelColon(trimmed);
|
|
127
|
+
}
|
|
128
|
+
function buildTemplateDataExpression(raw, scopeVar, wxsVar) {
|
|
129
|
+
const parts = parseInterpolations(raw.trim());
|
|
130
|
+
if (parts.length === 1 && parts[0]?.type === "expr") {
|
|
131
|
+
const expr = parts[0].value.trim();
|
|
132
|
+
if (expr) return buildExpression([{
|
|
133
|
+
type: "expr",
|
|
134
|
+
value: shouldWrapShorthandObject(expr) ? `{ ${expr} }` : expr
|
|
135
|
+
}], scopeVar, wxsVar);
|
|
136
|
+
}
|
|
137
|
+
return buildExpression(parseInterpolations(raw), scopeVar, wxsVar);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
//#endregion
|
|
141
|
+
export { buildExpression, buildTemplateDataExpression, parseInterpolations };
|
|
142
|
+
//# sourceMappingURL=interpolation.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpolation.mjs","names":[],"sources":["../../../src/compiler/wxml/interpolation.ts"],"sourcesContent":["import type { InterpolationPart } from './types'\n\nexport function parseInterpolations(value: string): InterpolationPart[] {\n const parts: InterpolationPart[] = []\n if (!value.includes('{{')) {\n return [{ type: 'text', value }]\n }\n let cursor = 0\n while (cursor < value.length) {\n const start = value.indexOf('{{', cursor)\n if (start === -1) {\n parts.push({ type: 'text', value: value.slice(cursor) })\n break\n }\n if (start > cursor) {\n parts.push({ type: 'text', value: value.slice(cursor, start) })\n }\n const end = value.indexOf('}}', start + 2)\n if (end === -1) {\n parts.push({ type: 'text', value: value.slice(start) })\n break\n }\n const expr = value.slice(start + 2, end).trim()\n if (expr) {\n parts.push({ type: 'expr', value: expr })\n }\n cursor = end + 2\n }\n return parts\n}\n\nexport function buildExpression(parts: InterpolationPart[], scopeVar: string, wxsVar: string) {\n if (parts.length === 0) {\n return '\"\"'\n }\n if (parts.length === 1 && parts[0]?.type === 'text') {\n return JSON.stringify(parts[0].value)\n }\n if (parts.length === 1 && parts[0]?.type === 'expr') {\n return `ctx.eval(${JSON.stringify(parts[0].value)}, ${scopeVar}, ${wxsVar})`\n }\n const segments = parts.map((part) => {\n if (part.type === 'text') {\n return JSON.stringify(part.value)\n }\n return `ctx.eval(${JSON.stringify(part.value)}, ${scopeVar}, ${wxsVar})`\n })\n return `(${segments.join(' + ')})`\n}\n\nfunction hasTopLevelColon(expression: string) {\n let depth = 0\n let inSingleQuote = false\n let inDoubleQuote = false\n let inTemplate = false\n let escaped = false\n let sawTopLevelQuestion = false\n\n for (let index = 0; index < expression.length; index += 1) {\n const char = expression[index]!\n\n if (inSingleQuote) {\n if (escaped) {\n escaped = false\n continue\n }\n if (char === '\\\\') {\n escaped = true\n continue\n }\n if (char === '\\'') {\n inSingleQuote = false\n }\n continue\n }\n if (inDoubleQuote) {\n if (escaped) {\n escaped = false\n continue\n }\n if (char === '\\\\') {\n escaped = true\n continue\n }\n if (char === '\"') {\n inDoubleQuote = false\n }\n continue\n }\n if (inTemplate) {\n if (escaped) {\n escaped = false\n continue\n }\n if (char === '\\\\') {\n escaped = true\n continue\n }\n if (char === '`') {\n inTemplate = false\n }\n continue\n }\n\n if (char === '\\'') {\n inSingleQuote = true\n continue\n }\n if (char === '\"') {\n inDoubleQuote = true\n continue\n }\n if (char === '`') {\n inTemplate = true\n continue\n }\n\n if (char === '(' || char === '[' || char === '{') {\n depth += 1\n continue\n }\n if (char === ')' || char === ']' || char === '}') {\n depth = Math.max(0, depth - 1)\n continue\n }\n\n if (depth !== 0) {\n continue\n }\n\n if (char === '?') {\n sawTopLevelQuestion = true\n continue\n }\n if (char === ':') {\n return !sawTopLevelQuestion\n }\n }\n\n return false\n}\n\nfunction shouldWrapShorthandObject(expression: string) {\n const trimmed = expression.trim()\n if (!trimmed) {\n return false\n }\n if (trimmed.startsWith('{') || trimmed.startsWith('[') || trimmed.startsWith('(')) {\n return false\n }\n return hasTopLevelColon(trimmed)\n}\n\nexport function buildTemplateDataExpression(raw: string, scopeVar: string, wxsVar: string) {\n const trimmed = raw.trim()\n const parts = parseInterpolations(trimmed)\n if (parts.length === 1 && parts[0]?.type === 'expr') {\n const expr = parts[0].value.trim()\n if (expr) {\n const normalizedExpr = shouldWrapShorthandObject(expr) ? `{ ${expr} }` : expr\n return buildExpression([{ type: 'expr', value: normalizedExpr }], scopeVar, wxsVar)\n }\n }\n return buildExpression(parseInterpolations(raw), scopeVar, wxsVar)\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
//#region src/compiler/wxml/navigation.ts
|
|
2
|
+
const NAVIGATION_BAR_ATTRS = new Set([
|
|
3
|
+
"title",
|
|
4
|
+
"background-color",
|
|
5
|
+
"text-style",
|
|
6
|
+
"front-color",
|
|
7
|
+
"loading"
|
|
8
|
+
]);
|
|
9
|
+
function stripPageMetaNodes(nodes) {
|
|
10
|
+
const stripped = [];
|
|
11
|
+
for (const node of nodes) {
|
|
12
|
+
if (node.type === "element" && node.name === "page-meta") continue;
|
|
13
|
+
if (node.type === "element" && node.children?.length) {
|
|
14
|
+
const nextChildren = stripPageMetaNodes(node.children);
|
|
15
|
+
if (nextChildren !== node.children) {
|
|
16
|
+
stripped.push({
|
|
17
|
+
...node,
|
|
18
|
+
children: nextChildren
|
|
19
|
+
});
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
stripped.push(node);
|
|
24
|
+
}
|
|
25
|
+
return stripped;
|
|
26
|
+
}
|
|
27
|
+
function pickNavigationBarAttrs(attribs) {
|
|
28
|
+
if (!attribs) return;
|
|
29
|
+
const picked = {};
|
|
30
|
+
for (const [key, value] of Object.entries(attribs)) if (NAVIGATION_BAR_ATTRS.has(key)) picked[key] = value;
|
|
31
|
+
return Object.keys(picked).length > 0 ? picked : void 0;
|
|
32
|
+
}
|
|
33
|
+
function findNavigationBarInPageMeta(node) {
|
|
34
|
+
const children = node.children ?? [];
|
|
35
|
+
for (const child of children) if (child.type === "element" && child.name === "navigation-bar") return child;
|
|
36
|
+
}
|
|
37
|
+
function extractNavigationBarFromPageMeta(nodes) {
|
|
38
|
+
let pageMetaIndex = -1;
|
|
39
|
+
let navigationBar;
|
|
40
|
+
for (let i = 0; i < nodes.length; i += 1) {
|
|
41
|
+
const node = nodes[i];
|
|
42
|
+
if (node.type === "element" && node.name === "page-meta") {
|
|
43
|
+
if (pageMetaIndex === -1) pageMetaIndex = i;
|
|
44
|
+
if (!navigationBar) navigationBar = findNavigationBarInPageMeta(node);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const warnings = [];
|
|
48
|
+
if (pageMetaIndex > 0) warnings.push("[web] page-meta 需要作为页面第一个节点,已忽略其位置约束。");
|
|
49
|
+
return {
|
|
50
|
+
nodes: pageMetaIndex === -1 ? nodes : stripPageMetaNodes(nodes),
|
|
51
|
+
attrs: navigationBar ? pickNavigationBarAttrs(navigationBar.attribs) : void 0,
|
|
52
|
+
warnings
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function toAttributeValue(value) {
|
|
56
|
+
if (value == null) return;
|
|
57
|
+
if (typeof value === "string") return value;
|
|
58
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
59
|
+
}
|
|
60
|
+
function buildNavigationBarAttrs(config, overrides) {
|
|
61
|
+
const attrs = {};
|
|
62
|
+
if (config?.title !== void 0) {
|
|
63
|
+
const value = toAttributeValue(config.title);
|
|
64
|
+
if (value !== void 0) attrs.title = value;
|
|
65
|
+
}
|
|
66
|
+
if (config?.backgroundColor !== void 0) {
|
|
67
|
+
const value = toAttributeValue(config.backgroundColor);
|
|
68
|
+
if (value !== void 0) attrs["background-color"] = value;
|
|
69
|
+
}
|
|
70
|
+
if (config?.textStyle !== void 0) {
|
|
71
|
+
const value = toAttributeValue(config.textStyle);
|
|
72
|
+
if (value !== void 0) attrs["text-style"] = value;
|
|
73
|
+
}
|
|
74
|
+
if (config?.frontColor !== void 0) {
|
|
75
|
+
const value = toAttributeValue(config.frontColor);
|
|
76
|
+
if (value !== void 0) attrs["front-color"] = value;
|
|
77
|
+
}
|
|
78
|
+
if (config?.loading) attrs.loading = "true";
|
|
79
|
+
if (overrides) for (const [key, value] of Object.entries(overrides)) attrs[key] = value;
|
|
80
|
+
return attrs;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
//#endregion
|
|
84
|
+
export { buildNavigationBarAttrs, extractNavigationBarFromPageMeta };
|
|
85
|
+
//# sourceMappingURL=navigation.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.mjs","names":[],"sources":["../../../src/compiler/wxml/navigation.ts"],"sourcesContent":["import type { NavigationBarConfig, RenderElementNode, RenderNode } from './types'\n\nconst NAVIGATION_BAR_ATTRS = new Set([\n 'title',\n 'background-color',\n 'text-style',\n 'front-color',\n 'loading',\n])\n\nfunction stripPageMetaNodes(nodes: RenderNode[]): RenderNode[] {\n const stripped: RenderNode[] = []\n for (const node of nodes) {\n if (node.type === 'element' && node.name === 'page-meta') {\n continue\n }\n if (node.type === 'element' && node.children?.length) {\n const nextChildren = stripPageMetaNodes(node.children)\n if (nextChildren !== node.children) {\n stripped.push({ ...node, children: nextChildren })\n continue\n }\n }\n stripped.push(node)\n }\n return stripped\n}\n\nfunction pickNavigationBarAttrs(attribs: Record<string, string> | undefined) {\n if (!attribs) {\n return undefined\n }\n const picked: Record<string, string> = {}\n for (const [key, value] of Object.entries(attribs)) {\n if (NAVIGATION_BAR_ATTRS.has(key)) {\n picked[key] = value\n }\n }\n return Object.keys(picked).length > 0 ? picked : undefined\n}\n\nfunction findNavigationBarInPageMeta(node: RenderElementNode) {\n const children = node.children ?? []\n for (const child of children) {\n if (child.type === 'element' && child.name === 'navigation-bar') {\n return child\n }\n }\n return undefined\n}\n\nexport function extractNavigationBarFromPageMeta(nodes: RenderNode[]): {\n nodes: RenderNode[]\n attrs?: Record<string, string>\n warnings: string[]\n} {\n let pageMetaIndex = -1\n let navigationBar: RenderElementNode | undefined\n for (let i = 0; i < nodes.length; i += 1) {\n const node = nodes[i]\n if (node.type === 'element' && node.name === 'page-meta') {\n if (pageMetaIndex === -1) {\n pageMetaIndex = i\n }\n if (!navigationBar) {\n navigationBar = findNavigationBarInPageMeta(node)\n }\n }\n }\n const warnings: string[] = []\n if (pageMetaIndex > 0) {\n warnings.push('[web] page-meta 需要作为页面第一个节点,已忽略其位置约束。')\n }\n const cleaned = pageMetaIndex === -1 ? nodes : stripPageMetaNodes(nodes)\n const attrs = navigationBar ? pickNavigationBarAttrs(navigationBar.attribs) : undefined\n return { nodes: cleaned, attrs, warnings }\n}\n\nfunction toAttributeValue(value: unknown) {\n if (value == null) {\n return undefined\n }\n if (typeof value === 'string') {\n return value\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value)\n }\n return undefined\n}\n\nexport function buildNavigationBarAttrs(\n config: NavigationBarConfig | undefined,\n overrides?: Record<string, string>,\n) {\n const attrs: Record<string, string> = {}\n if (config?.title !== undefined) {\n const value = toAttributeValue(config.title)\n if (value !== undefined) {\n attrs.title = value\n }\n }\n if (config?.backgroundColor !== undefined) {\n const value = toAttributeValue(config.backgroundColor)\n if (value !== undefined) {\n attrs['background-color'] = value\n }\n }\n if (config?.textStyle !== undefined) {\n const value = toAttributeValue(config.textStyle)\n if (value !== undefined) {\n attrs['text-style'] = value\n }\n }\n if (config?.frontColor !== undefined) {\n const value = toAttributeValue(config.frontColor)\n if (value !== undefined) {\n attrs['front-color'] = value\n }\n }\n if (config?.loading) {\n attrs.loading = 'true'\n }\n if (overrides) {\n for (const [key, value] of Object.entries(overrides)) {\n attrs[key] = value\n }\n }\n return attrs\n}\n"],"mappings":";AAEA,MAAM,uBAAuB,IAAI,IAAI;CACnC;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAS,mBAAmB,OAAmC;CAC7D,MAAM,WAAyB,EAAE;AACjC,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,KAAK,SAAS,aAAa,KAAK,SAAS,YAC3C;AAEF,MAAI,KAAK,SAAS,aAAa,KAAK,UAAU,QAAQ;GACpD,MAAM,eAAe,mBAAmB,KAAK,SAAS;AACtD,OAAI,iBAAiB,KAAK,UAAU;AAClC,aAAS,KAAK;KAAE,GAAG;KAAM,UAAU;KAAc,CAAC;AAClD;;;AAGJ,WAAS,KAAK,KAAK;;AAErB,QAAO;;AAGT,SAAS,uBAAuB,SAA6C;AAC3E,KAAI,CAAC,QACH;CAEF,MAAM,SAAiC,EAAE;AACzC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,CAChD,KAAI,qBAAqB,IAAI,IAAI,CAC/B,QAAO,OAAO;AAGlB,QAAO,OAAO,KAAK,OAAO,CAAC,SAAS,IAAI,SAAS;;AAGnD,SAAS,4BAA4B,MAAyB;CAC5D,MAAM,WAAW,KAAK,YAAY,EAAE;AACpC,MAAK,MAAM,SAAS,SAClB,KAAI,MAAM,SAAS,aAAa,MAAM,SAAS,iBAC7C,QAAO;;AAMb,SAAgB,iCAAiC,OAI/C;CACA,IAAI,gBAAgB;CACpB,IAAI;AACJ,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxC,MAAM,OAAO,MAAM;AACnB,MAAI,KAAK,SAAS,aAAa,KAAK,SAAS,aAAa;AACxD,OAAI,kBAAkB,GACpB,iBAAgB;AAElB,OAAI,CAAC,cACH,iBAAgB,4BAA4B,KAAK;;;CAIvD,MAAM,WAAqB,EAAE;AAC7B,KAAI,gBAAgB,EAClB,UAAS,KAAK,wCAAwC;AAIxD,QAAO;EAAE,OAFO,kBAAkB,KAAK,QAAQ,mBAAmB,MAAM;EAE/C,OADX,gBAAgB,uBAAuB,cAAc,QAAQ,GAAG;EAC9C;EAAU;;AAG5C,SAAS,iBAAiB,OAAgB;AACxC,KAAI,SAAS,KACX;AAEF,KAAI,OAAO,UAAU,SACnB,QAAO;AAET,KAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAChD,QAAO,OAAO,MAAM;;AAKxB,SAAgB,wBACd,QACA,WACA;CACA,MAAM,QAAgC,EAAE;AACxC,KAAI,QAAQ,UAAU,QAAW;EAC/B,MAAM,QAAQ,iBAAiB,OAAO,MAAM;AAC5C,MAAI,UAAU,OACZ,OAAM,QAAQ;;AAGlB,KAAI,QAAQ,oBAAoB,QAAW;EACzC,MAAM,QAAQ,iBAAiB,OAAO,gBAAgB;AACtD,MAAI,UAAU,OACZ,OAAM,sBAAsB;;AAGhC,KAAI,QAAQ,cAAc,QAAW;EACnC,MAAM,QAAQ,iBAAiB,OAAO,UAAU;AAChD,MAAI,UAAU,OACZ,OAAM,gBAAgB;;AAG1B,KAAI,QAAQ,eAAe,QAAW;EACpC,MAAM,QAAQ,iBAAiB,OAAO,WAAW;AACjD,MAAI,UAAU,OACZ,OAAM,iBAAiB;;AAG3B,KAAI,QAAQ,QACV,OAAM,UAAU;AAElB,KAAI,UACF,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,UAAU,CAClD,OAAM,OAAO;AAGjB,QAAO"}
|