@proteus-vue/component-ir 0.1.0

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/index.js ADDED
@@ -0,0 +1,1140 @@
1
+ // src/schema.ts
2
+ var SEMANTIC_ENUM = [
3
+ // —— 布局原语(G-32 ① Layout 12:G-22 泛化——swiper/scroll-view/movable 消灭为属性)——
4
+ "layout.box",
5
+ "layout.inline",
6
+ "layout.stack",
7
+ "layout.grid",
8
+ "layout.fluid",
9
+ "layout.adaptive",
10
+ "layout.fit",
11
+ "layout.spacer",
12
+ "layout.divider",
13
+ "layout.scroll",
14
+ "layout.virtual-list",
15
+ "layout.masonry",
16
+ // ★G-31 B4:Fluid 体系扩展语义(有明确系统原生对应——原则 #10.8)
17
+ "layout.split",
18
+ "layout.safe",
19
+ "layout.sidebar",
20
+ // —— 基础 UI 原语(G-32 ② UI 18 + 既有按钮)——
21
+ "ui.text",
22
+ "ui.heading",
23
+ "ui.rich-text",
24
+ "ui.icon",
25
+ "ui.image",
26
+ "ui.avatar",
27
+ "ui.media",
28
+ "ui.canvas",
29
+ "ui.svg",
30
+ "ui.input",
31
+ "ui.textarea",
32
+ "ui.select",
33
+ "ui.checkbox",
34
+ "ui.radio",
35
+ "ui.switch",
36
+ "ui.slider",
37
+ "ui.picker",
38
+ "ui.form",
39
+ "ui.button",
40
+ // 既有按钮(小程序对照 row 14)
41
+ // ★G-31 B4:既有组件对齐(p-list-view/p-nav-bar)
42
+ "ui.list",
43
+ "ui.nav",
44
+ // —— 容器/导航原语(G-32 ③ Shell 10)——
45
+ "shell.page",
46
+ "shell.nav",
47
+ "shell.tabbar",
48
+ "shell.segment",
49
+ "shell.drawer",
50
+ "shell.modal",
51
+ "shell.popover",
52
+ "shell.toast",
53
+ "shell.action-sheet",
54
+ // —— 交互/手势原语(G-32 ④ Gesture——组件形态 2 个;v-gesture: 指令归绑定层不产生 C-IR 节点)——
55
+ "gesture.draggable",
56
+ "gesture.scrollable",
57
+ // —— 工程原语(G-32 ⑥ Engineering——组件形态 3 个;Hook/路由方法归 API 层)——
58
+ "engineering.router-link",
59
+ "engineering.transition",
60
+ "engineering.animate",
61
+ // —— 能力入口(G-28 组件化:p-* 能力入口组件;useXxx Hook 归 API 层不产生 C-IR 节点)——
62
+ "capability.scan-qr",
63
+ "capability.pick-photo",
64
+ "capability.location"
65
+ ];
66
+ var COMPONENT_IR_SCHEMA = {
67
+ $schema: "https://json-schema.org/draft/2020-12/schema",
68
+ $id: "https://proteus.dev/schemas/component-ir.json",
69
+ title: "Proteus Component IR (C-IR)",
70
+ type: "object",
71
+ required: ["tag", "semantic", "props", "children"],
72
+ properties: {
73
+ tag: { type: "string", pattern: "^p-[a-z0-9-]+$" },
74
+ semantic: { type: "string", enum: SEMANTIC_ENUM },
75
+ props: { type: "object", additionalProperties: true },
76
+ children: { type: "array", items: { $ref: "#" }, default: [] },
77
+ capabilities: { type: "array", items: { type: "object", required: ["name"] } },
78
+ degradation: { type: "object", additionalProperties: { enum: ["supported", "fallback", "unsupported"] } }
79
+ }
80
+ };
81
+ var TAG_SEMANTIC_MAP = {
82
+ // G-32 ① 布局原语(12)
83
+ "p-box": "layout.box",
84
+ "p-inline": "layout.inline",
85
+ "p-stack": "layout.stack",
86
+ "p-grid": "layout.grid",
87
+ "p-fluid": "layout.fluid",
88
+ "p-adaptive": "layout.adaptive",
89
+ "p-fit": "layout.fit",
90
+ "p-spacer": "layout.spacer",
91
+ "p-divider": "layout.divider",
92
+ "p-scroll": "layout.scroll",
93
+ "p-virtual-list": "layout.virtual-list",
94
+ "p-masonry": "layout.masonry",
95
+ // G-32 ② UI 原语(18)
96
+ "p-text": "ui.text",
97
+ "p-heading": "ui.heading",
98
+ "p-rich-text": "ui.rich-text",
99
+ "p-icon": "ui.icon",
100
+ "p-image": "ui.image",
101
+ "p-avatar": "ui.avatar",
102
+ "p-media": "ui.media",
103
+ "p-canvas": "ui.canvas",
104
+ "p-svg": "ui.svg",
105
+ "p-input": "ui.input",
106
+ "p-textarea": "ui.textarea",
107
+ "p-select": "ui.select",
108
+ "p-checkbox": "ui.checkbox",
109
+ "p-radio": "ui.radio",
110
+ "p-switch": "ui.switch",
111
+ "p-slider": "ui.slider",
112
+ "p-picker": "ui.picker",
113
+ "p-form": "ui.form",
114
+ "p-button": "ui.button",
115
+ // 既有按钮
116
+ // G-32 ③ Shell 原语(10)
117
+ "p-page": "shell.page",
118
+ "p-nav": "shell.nav",
119
+ "p-tabbar": "shell.tabbar",
120
+ "p-segment": "shell.segment",
121
+ "p-drawer": "shell.drawer",
122
+ "p-modal": "shell.modal",
123
+ "p-popover": "shell.popover",
124
+ "p-toast": "shell.toast",
125
+ "p-action-sheet": "shell.action-sheet",
126
+ "p-split": "layout.split",
127
+ // ★已落地绑定(G-32 S10 分栏语义——layout.split 承载)
128
+ // G-32 ④ Gesture 组件形态(2)
129
+ "p-draggable": "gesture.draggable",
130
+ "p-scrollable": "gesture.scrollable",
131
+ // G-32 ⑥ Engineering 组件形态(3)
132
+ "p-router-link": "engineering.router-link",
133
+ // ★E18 组件形态(p- 前缀产 C-IR)
134
+ "router-link": "engineering.router-link",
135
+ // ★兼容别名(Vue Router 风格 <router-link> 标签;非 catalog 条目——p-view 先例 G-31 B4)
136
+ "p-transition": "engineering.transition",
137
+ "p-animate": "engineering.animate",
138
+ // G-31 能力入口
139
+ "p-scan-qr": "capability.scan-qr",
140
+ "p-pick-photo": "capability.pick-photo",
141
+ "p-location": "capability.location",
142
+ // ★G-31 B4 现有组件对齐(src/components 实际标签 → L1 语义)
143
+ "p-view": "layout.box",
144
+ // 原子容器 = p-box 角色
145
+ "p-list-view": "ui.list",
146
+ "p-nav-bar": "ui.nav",
147
+ // ★G-31 B4 Fluid 体系扩展语义(有明确系统原生对应——原则 #10.8)
148
+ "p-safe": "layout.safe",
149
+ "p-sidebar": "layout.sidebar"
150
+ };
151
+
152
+ // src/validate.ts
153
+ var DEFAULT_DESIGN_WIDTH = 375;
154
+ function validateComponentIR(ir) {
155
+ const diags = [];
156
+ if (!ir || typeof ir !== "object") {
157
+ return [{ code: "CIR_INVALID", message: "C-IR \u5FC5\u987B\u4E3A\u5BF9\u8C61" }];
158
+ }
159
+ const node = ir;
160
+ if (typeof node.tag !== "string" || !/^p-[a-z0-9-]+$/.test(node.tag)) {
161
+ diags.push({ code: "CIR_INVALID_TAG", message: `tag="${String(node.tag)}" \u975E\u6CD5\u2014\u2014\u5FC5\u987B p- \u524D\u7F00 + \u8BED\u4E49\u540D\u8BCD\uFF08G-31.1\uFF09` });
162
+ }
163
+ if (typeof node.semantic !== "string" || SEMANTIC_ENUM.indexOf(node.semantic) < 0) {
164
+ diags.push({ code: "CIR_INVALID_SEMANTIC", message: `semantic="${String(node.semantic)}" \u975E\u6CD5\u2014\u2014\u987B\u4E3A\u8BED\u4E49\u679A\u4E3E\uFF08<domain>.<kind>\uFF09` });
165
+ }
166
+ if (node.props === null || typeof node.props !== "object") {
167
+ diags.push({ code: "CIR_INVALID_PROPS", message: "props \u5FC5\u987B\u4E3A\u5BF9\u8C61" });
168
+ }
169
+ const caps = node.capabilities;
170
+ if (Array.isArray(caps) && caps.length) {
171
+ const declared = new Set(Object.keys(node.degradation ?? {}));
172
+ for (const cap2 of caps) {
173
+ if (typeof cap2 === "object" && cap2 !== null && typeof cap2.name === "string" && !declared.has(cap2.name)) {
174
+ diags.push({ code: "CMP006", message: `capability "${cap2.name}" \u672A\u58F0\u660E degradation\uFF08supported/fallback/unsupported\uFF09\u2014\u2014G-31.2` });
175
+ }
176
+ }
177
+ }
178
+ if (Array.isArray(node.children)) {
179
+ for (const child of node.children) {
180
+ diags.push.apply(diags, validateComponentIR(child));
181
+ }
182
+ }
183
+ return diags;
184
+ }
185
+ function validateGridConstraints(props, designWidth = DEFAULT_DESIGN_WIDTH) {
186
+ const minColWidth = props.minColWidth ?? props.minColWidth;
187
+ const maxCols = props.maxCols;
188
+ if (typeof minColWidth === "number" && typeof maxCols === "number" && maxCols > 1) {
189
+ const needed = minColWidth * maxCols;
190
+ if (needed > designWidth) {
191
+ return [
192
+ {
193
+ code: "GRID_CONFLICT",
194
+ message: `min-col-width=${minColWidth} \xD7 max-cols=${maxCols} = ${needed} > \u8BBE\u8BA1\u5BBD ${designWidth}\u2014\u2014max-cols=${maxCols} \u6C38\u4E0D\u8FBE\uFF08\u6C38\u8FDC\u5355\u5217\uFF09\uFF0C\u8BF7\u8C03\u5C0F min-col-width \u6216 max-cols`
195
+ }
196
+ ];
197
+ }
198
+ }
199
+ return [];
200
+ }
201
+ function validateComponentTree(ir, designWidth = DEFAULT_DESIGN_WIDTH) {
202
+ const diags = validateComponentIR(ir);
203
+ if (ir && typeof ir === "object") {
204
+ const node = ir;
205
+ if (node.props && typeof node.props === "object") {
206
+ diags.push.apply(diags, validateGridConstraints(node.props, designWidth));
207
+ }
208
+ if (Array.isArray(node.children)) {
209
+ for (const child of node.children) {
210
+ diags.push.apply(diags, validateComponentTree(child, designWidth));
211
+ }
212
+ }
213
+ }
214
+ return diags;
215
+ }
216
+
217
+ // src/map.ts
218
+ var SEMANTIC_BACKEND_MAP = {
219
+ // —— 布局原语(G-22 四原语 + box/adaptive)——
220
+ "layout.box": {
221
+ "vue-dom": "div.proteus-box",
222
+ "native-ios": "UIView",
223
+ "native-android": "FrameLayout",
224
+ "native-harmony": "Stack",
225
+ skyline: "view",
226
+ flutter: "Container",
227
+ headless: "box"
228
+ },
229
+ "layout.stack": {
230
+ "vue-dom": "div.proteus-stack",
231
+ "native-ios": "UIStackView",
232
+ "native-android": "LinearLayout",
233
+ "native-harmony": "Flex",
234
+ skyline: "view.flex",
235
+ flutter: "Flex",
236
+ headless: "stack"
237
+ },
238
+ "layout.grid": {
239
+ "vue-dom": "div.proteus-grid",
240
+ "native-ios": "UICollectionView",
241
+ "native-android": "GridLayoutManager",
242
+ "native-harmony": "Grid",
243
+ skyline: "grid",
244
+ // Skyline 原生 grid 组件(编译期静态 WXSS)
245
+ flutter: "GridView",
246
+ headless: "grid"
247
+ },
248
+ "layout.fluid": {
249
+ "vue-dom": "div.proteus-fluid",
250
+ "native-ios": "AutoLayout",
251
+ "native-android": "ConstraintLayout",
252
+ "native-harmony": "Flex.fluid",
253
+ skyline: "view.fluid",
254
+ flutter: "Wrap",
255
+ headless: "fluid"
256
+ },
257
+ "layout.adaptive": {
258
+ "vue-dom": "div.proteus-adaptive",
259
+ "native-ios": "UISheet",
260
+ "native-android": "BottomSheetDialog",
261
+ "native-harmony": "Sheet",
262
+ // @ohos.arkui.advanced
263
+ skyline: "half-screen",
264
+ flutter: "showModal",
265
+ headless: "adaptive"
266
+ },
267
+ "layout.fit": {
268
+ "vue-dom": "div.proteus-fit",
269
+ "native-ios": "intrinsicSize",
270
+ "native-android": "wrapContent",
271
+ "native-harmony": "fitContent",
272
+ skyline: "view.fit",
273
+ flutter: "IntrinsicWidth",
274
+ headless: "fit"
275
+ },
276
+ // ★G-31 B4:Fluid 体系扩展语义(五端映射)
277
+ "layout.split": {
278
+ "vue-dom": "div.proteus-split",
279
+ "native-ios": "UISplitViewController",
280
+ "native-android": "SlidingPaneLayout",
281
+ "native-harmony": "SideBarContainer",
282
+ skyline: "view.split",
283
+ flutter: "Row",
284
+ headless: "split"
285
+ },
286
+ "layout.safe": {
287
+ "vue-dom": "div.proteus-safe",
288
+ "native-ios": "safeAreaLayoutGuide",
289
+ "native-android": "WindowInsets",
290
+ "native-harmony": "getAvoidArea",
291
+ skyline: "env.safe-area",
292
+ flutter: "SafeArea",
293
+ headless: "safe"
294
+ },
295
+ "layout.sidebar": {
296
+ "vue-dom": "div.proteus-sidebar",
297
+ "native-ios": "UISplitViewController.side",
298
+ "native-android": "NavigationRail",
299
+ "native-harmony": "SideBarContainer",
300
+ skyline: "view.sidebar",
301
+ flutter: "NavigationRail",
302
+ headless: "sidebar"
303
+ },
304
+ // —— 基础 UI 原语 ——
305
+ "ui.text": {
306
+ "vue-dom": "span",
307
+ "native-ios": "UILabel",
308
+ "native-android": "TextView",
309
+ "native-harmony": "Text",
310
+ skyline: "text",
311
+ flutter: "Text",
312
+ headless: "text"
313
+ },
314
+ "ui.button": {
315
+ "vue-dom": "button",
316
+ "native-ios": "UIButton",
317
+ "native-android": "Button",
318
+ "native-harmony": "Button",
319
+ skyline: "button",
320
+ flutter: "FilledButton",
321
+ headless: "button"
322
+ },
323
+ "ui.image": {
324
+ "vue-dom": "img",
325
+ "native-ios": "UIImageView",
326
+ "native-android": "ImageView",
327
+ "native-harmony": "Image",
328
+ skyline: "image",
329
+ flutter: "Image",
330
+ headless: "image"
331
+ },
332
+ "ui.input": {
333
+ "vue-dom": "input",
334
+ "native-ios": "UITextField",
335
+ "native-android": "EditText",
336
+ "native-harmony": "TextInput",
337
+ skyline: "input",
338
+ flutter: "TextField",
339
+ headless: "input"
340
+ },
341
+ "ui.list": {
342
+ "vue-dom": "div.proteus-list",
343
+ "native-ios": "UITableView",
344
+ "native-android": "RecyclerView",
345
+ "native-harmony": "List",
346
+ skyline: "list-view",
347
+ flutter: "ListView",
348
+ headless: "list"
349
+ },
350
+ "ui.nav": {
351
+ "vue-dom": "nav",
352
+ "native-ios": "UINavigationController",
353
+ "native-android": "NavigationRail",
354
+ "native-harmony": "Navigation",
355
+ skyline: "navigator",
356
+ flutter: "Navigator",
357
+ headless: "nav"
358
+ },
359
+ // —— 能力入口(G-28 组件化)——
360
+ "capability.scan-qr": {
361
+ "vue-dom": "button.proteus-scan-qr",
362
+ "native-ios": "AVCaptureSession",
363
+ "native-android": "CameraX",
364
+ "native-harmony": "ScanKit",
365
+ skyline: "wx.scanCode",
366
+ flutter: "scanQR",
367
+ headless: "scan-qr"
368
+ },
369
+ "capability.pick-photo": {
370
+ "vue-dom": "input.proteus-pick-photo",
371
+ "native-ios": "UIImagePicker",
372
+ "native-android": "PhotoPicker",
373
+ "native-harmony": "PhotoViewPicker",
374
+ skyline: "wx.chooseMedia",
375
+ flutter: "pickPhoto",
376
+ headless: "pick-photo"
377
+ },
378
+ "capability.location": {
379
+ "vue-dom": "button.proteus-location",
380
+ "native-ios": "CLLocationManager",
381
+ "native-android": "FusedLocation",
382
+ "native-harmony": "geoLocationManager",
383
+ skyline: "wx.getLocation",
384
+ flutter: "getLocation",
385
+ headless: "location"
386
+ },
387
+ // ★G-32 B1:新增 implemented 语义(16 个——布局补齐 6 + UI 补齐 4(+textarea) + Shell 4)
388
+ "layout.inline": {
389
+ "vue-dom": "div.proteus-inline",
390
+ "native-ios": "UITextAttachment",
391
+ "native-android": "TextView.inline",
392
+ "native-harmony": "Span",
393
+ skyline: "view.inline",
394
+ flutter: "InlineSpan",
395
+ headless: "inline"
396
+ },
397
+ "layout.spacer": {
398
+ "vue-dom": "div.proteus-spacer",
399
+ "native-ios": "UILayoutGuide",
400
+ "native-android": "Space",
401
+ "native-harmony": "Blank",
402
+ // ArkUI Blank 弹性空白
403
+ skyline: "view.spacer",
404
+ flutter: "Spacer",
405
+ headless: "spacer"
406
+ },
407
+ "layout.divider": {
408
+ "vue-dom": "hr.proteus-divider",
409
+ "native-ios": "UIView.divider",
410
+ "native-android": "View.divider",
411
+ "native-harmony": "Divider",
412
+ // ArkUI Divider
413
+ skyline: "view.divider",
414
+ flutter: "Divider",
415
+ headless: "divider"
416
+ },
417
+ "layout.scroll": {
418
+ "vue-dom": "div.proteus-scroll",
419
+ "native-ios": "UIScrollView",
420
+ "native-android": "ScrollView",
421
+ "native-harmony": "Scroll",
422
+ // ArkUI Scroll
423
+ skyline: "scroll-view",
424
+ flutter: "ScrollView",
425
+ headless: "scroll"
426
+ },
427
+ "layout.virtual-list": {
428
+ "vue-dom": "div.proteus-virtual-list",
429
+ "native-ios": "UICollectionView",
430
+ "native-android": "RecyclerView",
431
+ "native-harmony": "List",
432
+ skyline: "list-view",
433
+ flutter: "ListView",
434
+ headless: "virtual-list"
435
+ },
436
+ "layout.masonry": {
437
+ "vue-dom": "div.proteus-masonry",
438
+ "native-ios": "UICollectionView.masonry",
439
+ "native-android": "StaggeredGridLayoutManager",
440
+ "native-harmony": "WaterFlow",
441
+ // ArkUI WaterFlow 瀑布流
442
+ skyline: "grid.masonry",
443
+ flutter: "SliverMasonryGrid",
444
+ headless: "masonry"
445
+ },
446
+ "ui.heading": {
447
+ "vue-dom": "div.proteus-heading",
448
+ "native-ios": "UILabel.heading",
449
+ "native-android": "TextView.heading",
450
+ "native-harmony": "Text.heading",
451
+ skyline: "text.heading",
452
+ flutter: "Text.heading",
453
+ headless: "heading"
454
+ },
455
+ "ui.icon": {
456
+ "vue-dom": "span.proteus-icon",
457
+ "native-ios": "UIImageView.icon",
458
+ "native-android": "ImageView.icon",
459
+ "native-harmony": "SymbolGlyph",
460
+ // ArkUI 符号图标
461
+ skyline: "icon",
462
+ flutter: "Icon",
463
+ headless: "icon"
464
+ },
465
+ "ui.textarea": {
466
+ "vue-dom": "textarea",
467
+ "native-ios": "UITextView",
468
+ "native-android": "EditText.multiline",
469
+ "native-harmony": "TextArea",
470
+ // ArkUI TextArea
471
+ skyline: "textarea",
472
+ flutter: "TextField.multiline",
473
+ headless: "textarea"
474
+ },
475
+ "ui.switch": {
476
+ "vue-dom": "div.proteus-switch",
477
+ "native-ios": "UISwitch",
478
+ "native-android": "Switch",
479
+ "native-harmony": "Toggle",
480
+ // ArkUI Toggle
481
+ skyline: "switch",
482
+ flutter: "Switch",
483
+ headless: "switch"
484
+ },
485
+ "ui.slider": {
486
+ "vue-dom": "div.proteus-slider",
487
+ "native-ios": "UISlider",
488
+ "native-android": "SeekBar",
489
+ "native-harmony": "Slider",
490
+ // ArkUI Slider
491
+ skyline: "slider",
492
+ flutter: "Slider",
493
+ headless: "slider"
494
+ },
495
+ "shell.nav": {
496
+ "vue-dom": "nav.proteus-nav",
497
+ "native-ios": "UINavigationBar",
498
+ "native-android": "Toolbar",
499
+ "native-harmony": "NavigationBar",
500
+ skyline: "navigator",
501
+ flutter: "AppBar",
502
+ headless: "nav"
503
+ },
504
+ "shell.tabbar": {
505
+ "vue-dom": "nav.proteus-tabbar",
506
+ "native-ios": "UITabBar",
507
+ "native-android": "BottomNavigationView",
508
+ "native-harmony": "Tabs",
509
+ // ArkUI Tabs
510
+ skyline: "tabbar",
511
+ flutter: "BottomNavigationBar",
512
+ headless: "tabbar"
513
+ },
514
+ "shell.drawer": {
515
+ "vue-dom": "aside.proteus-drawer",
516
+ "native-ios": "UIView.drawer",
517
+ "native-android": "DrawerLayout",
518
+ "native-harmony": "Panel",
519
+ skyline: "view.drawer",
520
+ flutter: "Drawer",
521
+ headless: "drawer"
522
+ },
523
+ "shell.modal": {
524
+ "vue-dom": "div.proteus-modal",
525
+ "native-ios": "UIAlertController",
526
+ "native-android": "Dialog",
527
+ "native-harmony": "CustomDialog",
528
+ skyline: "modal",
529
+ flutter: "showDialog",
530
+ headless: "modal"
531
+ },
532
+ // ★G-32 B4:Shell 补齐(page/segment/popover/action-sheet)+ UI 补齐(rich-text/avatar/media/canvas/svg/select/checkbox/radio/picker/form)
533
+ "shell.page": {
534
+ "vue-dom": "div.proteus-page",
535
+ "native-ios": "UIViewController",
536
+ "native-android": "Activity",
537
+ "native-harmony": "Page",
538
+ // ArkUI Page
539
+ skyline: "page",
540
+ flutter: "Scaffold",
541
+ headless: "page"
542
+ },
543
+ "shell.segment": {
544
+ "vue-dom": "div.proteus-segment",
545
+ "native-ios": "UISegmentedControl",
546
+ "native-android": "TabLayout",
547
+ "native-harmony": "Segmented",
548
+ // ArkUI 分段器
549
+ skyline: "segment",
550
+ flutter: "SegmentedButton",
551
+ headless: "segment"
552
+ },
553
+ "shell.popover": {
554
+ "vue-dom": "div.proteus-popover",
555
+ "native-ios": "UIPopoverController",
556
+ "native-android": "PopupWindow",
557
+ "native-harmony": "Popup",
558
+ // ArkUI Popup
559
+ skyline: "view.popover",
560
+ flutter: "showMenu",
561
+ headless: "popover"
562
+ },
563
+ "shell.action-sheet": {
564
+ "vue-dom": "div.proteus-action-sheet",
565
+ "native-ios": "UIAlertController.actionSheet",
566
+ "native-android": "BottomSheet",
567
+ "native-harmony": "ActionSheet",
568
+ // ArkUI ActionSheetDialog
569
+ skyline: "action-sheet",
570
+ flutter: "showModalBottomSheet",
571
+ headless: "action-sheet"
572
+ },
573
+ "ui.rich-text": {
574
+ "vue-dom": "div.proteus-rich-text",
575
+ "native-ios": "UITextView.attributed",
576
+ "native-android": "TextView.html",
577
+ "native-harmony": "RichText",
578
+ // ArkUI RichText
579
+ skyline: "rich-text",
580
+ flutter: "RichText",
581
+ headless: "rich-text"
582
+ },
583
+ "ui.avatar": {
584
+ "vue-dom": "div.proteus-avatar",
585
+ "native-ios": "UIImageView.avatar",
586
+ "native-android": "ImageView.avatar",
587
+ "native-harmony": "Image.avatar",
588
+ skyline: "image.avatar",
589
+ flutter: "CircleAvatar",
590
+ headless: "avatar"
591
+ },
592
+ "ui.media": {
593
+ "vue-dom": "div.proteus-media",
594
+ "native-ios": "AVPlayerView",
595
+ "native-android": "VideoView",
596
+ "native-harmony": "Video",
597
+ // ArkUI Video
598
+ skyline: "video",
599
+ flutter: "VideoPlayer",
600
+ headless: "media"
601
+ },
602
+ "ui.canvas": {
603
+ "vue-dom": "canvas",
604
+ "native-ios": "UIView.canvas",
605
+ "native-android": "SurfaceView",
606
+ "native-harmony": "Canvas",
607
+ // ArkUI Canvas
608
+ skyline: "canvas",
609
+ flutter: "CustomPaint",
610
+ headless: "canvas"
611
+ },
612
+ "ui.svg": {
613
+ "vue-dom": "svg",
614
+ "native-ios": "UIView.svg",
615
+ "native-android": "VectorDrawable",
616
+ "native-harmony": "Shape",
617
+ // ArkUI Shape
618
+ skyline: "view.svg",
619
+ flutter: "SvgPicture",
620
+ headless: "svg"
621
+ },
622
+ "ui.select": {
623
+ "vue-dom": "div.proteus-select",
624
+ "native-ios": "UIPickerView",
625
+ "native-android": "Spinner",
626
+ "native-harmony": "Select",
627
+ // ArkUI Select
628
+ skyline: "picker",
629
+ flutter: "DropdownButton",
630
+ headless: "select"
631
+ },
632
+ "ui.checkbox": {
633
+ "vue-dom": "div.proteus-checkbox",
634
+ "native-ios": "UIButton.checkbox",
635
+ "native-android": "CheckBox",
636
+ "native-harmony": "Checkbox",
637
+ // ArkUI Checkbox
638
+ skyline: "checkbox",
639
+ flutter: "Checkbox",
640
+ headless: "checkbox"
641
+ },
642
+ "ui.radio": {
643
+ "vue-dom": "div.proteus-radio",
644
+ "native-ios": "UIButton.radio",
645
+ "native-android": "RadioButton",
646
+ "native-harmony": "Radio",
647
+ // ArkUI Radio
648
+ skyline: "radio",
649
+ flutter: "Radio",
650
+ headless: "radio"
651
+ },
652
+ "ui.picker": {
653
+ "vue-dom": "div.proteus-picker",
654
+ "native-ios": "UIDatePicker",
655
+ "native-android": "DatePicker",
656
+ "native-harmony": "DatePicker",
657
+ // ArkUI DatePicker
658
+ skyline: "picker-view",
659
+ flutter: "showDatePicker",
660
+ headless: "picker"
661
+ },
662
+ "ui.form": {
663
+ "vue-dom": "form",
664
+ "native-ios": "UIView.form",
665
+ "native-android": "LinearLayout.form",
666
+ "native-harmony": "FormComponent",
667
+ // ArkUI FormComponent
668
+ skyline: "form",
669
+ flutter: "Form",
670
+ headless: "form"
671
+ },
672
+ // ★G-32 B4 ④ Gesture 组件形态(drag/scrollable——指令/useGesture 属绑定层不产渲染节点)
673
+ "gesture.draggable": {
674
+ "vue-dom": "div.proteus-draggable",
675
+ "native-ios": "UIPanGestureRecognizer",
676
+ "native-android": "GestureDetector",
677
+ "native-harmony": "PanGesture",
678
+ // ArkUI PanGesture
679
+ skyline: "movable-view",
680
+ flutter: "Draggable",
681
+ headless: "draggable"
682
+ },
683
+ "gesture.scrollable": {
684
+ "vue-dom": "div.proteus-scrollable",
685
+ "native-ios": "UIScrollView.gesture",
686
+ "native-android": "NestedScrollView",
687
+ "native-harmony": "Scroll.gesture",
688
+ // ArkUI Scroll + 手势增强
689
+ skyline: "scroll-view",
690
+ flutter: "Scrollable",
691
+ headless: "scrollable"
692
+ },
693
+ // ★G-32 B5 尾巴:E18 声明式导航组件形态(p-router-link——语义「导航目标」;点击 emit('navigate') 由工程层执行)
694
+ "engineering.router-link": {
695
+ "vue-dom": "a.proteus-router-link",
696
+ "native-ios": "UIButton.link",
697
+ "native-android": "TextView.link",
698
+ "native-harmony": "Text.link",
699
+ skyline: "navigator",
700
+ // Skyline <navigator> 声明式导航
701
+ flutter: "TextButton",
702
+ headless: "router-link"
703
+ },
704
+ // ★G-32 B5 续二:工程原语动画组件形态(E19 transition / E20 animate——纯 CSS 声明语义;Hook 归 API 层不产节点)
705
+ "engineering.transition": {
706
+ "vue-dom": "div.proteus-transition",
707
+ "native-ios": "UIView.transition",
708
+ // UIView transition(with:duration:options:) 显隐过渡
709
+ "native-android": "View.animate.transition",
710
+ // ObjectAnimator alpha/translation 组合
711
+ "native-harmony": "animateTo.transition",
712
+ // ArkUI animateTo 显隐过渡
713
+ skyline: "view.transition",
714
+ // Skyline transition CSS
715
+ flutter: "AnimatedOpacity",
716
+ headless: "transition"
717
+ },
718
+ "engineering.animate": {
719
+ "vue-dom": "div.proteus-animate",
720
+ "native-ios": "CAKeyframeAnimation",
721
+ // 核心动画关键帧
722
+ "native-android": "ValueAnimator",
723
+ // 属性动画
724
+ "native-harmony": "Animator.transition",
725
+ // ArkUI Animator
726
+ skyline: "view.animation",
727
+ // Skyline animation CSS
728
+ flutter: "AnimationController",
729
+ headless: "animate"
730
+ }
731
+ };
732
+ function mapSemanticToBackend(semantic, backendId) {
733
+ const row = SEMANTIC_BACKEND_MAP[semantic];
734
+ if (!row) return null;
735
+ return row[backendId] ?? null;
736
+ }
737
+
738
+ // src/to-ir.ts
739
+ function toComponentIR(tag, props = {}, children = []) {
740
+ if (!tag.startsWith("p-")) return null;
741
+ const semantic = TAG_SEMANTIC_MAP[tag];
742
+ if (!semantic) return null;
743
+ return { tag, semantic, props: { ...props }, children };
744
+ }
745
+ function toComponentTree(tag, props = {}, children = []) {
746
+ const irChildren = [];
747
+ for (const c of children) {
748
+ const sub = toComponentTree(c.tag, c.props, c.children ?? []);
749
+ if (sub) irChildren.push(sub);
750
+ }
751
+ return toComponentIR(tag, props, irChildren);
752
+ }
753
+
754
+ // src/primitives.ts
755
+ var LAYOUT = [
756
+ { id: "L1", kind: "layout", semantic: "layout.box", tag: "p-box", props: ["aspectRatio", "overflow"], mpEquiv: "<view>", tier: "L1", status: "implemented" },
757
+ { id: "L2", kind: "layout", semantic: "layout.inline", tag: "p-inline", props: ["wrap"], mpEquiv: "<text> \u5185\u8054", tier: "L1", status: "implemented" },
758
+ { id: "L3", kind: "layout", semantic: "layout.stack", tag: "p-stack", props: ["direction", "gap", "align", "wrap", "snap", "loop"], mpEquiv: "flex + scroll-view + swiper", tier: "L1", status: "implemented" },
759
+ { id: "L4", kind: "layout", semantic: "layout.grid", tag: "p-grid", props: ["minColWidth", "maxCols", "gap", "autoFlow"], mpEquiv: "<view> + CSS Grid", tier: "L1", status: "implemented" },
760
+ { id: "L5", kind: "layout", semantic: "layout.fluid", tag: "p-fluid", props: ["breakpoints", "minItemWidth"], mpEquiv: "\u54CD\u5E94\u5F0F CSS", tier: "L1", status: "implemented" },
761
+ { id: "L6", kind: "layout", semantic: "layout.adaptive", tag: "p-adaptive", props: ["sheet", "dialog", "popover", "drawer"], mpEquiv: "\u65E0\uFF08\u5BB9\u5668\u5BBD\u5EA6\u8BED\u4E49\u65AD\u70B9\uFF09", tier: "L1", status: "implemented" },
762
+ { id: "L7", kind: "layout", semantic: "layout.fit", tag: "p-fit", props: ["mode"], mpEquiv: "fit-content", tier: "L1", status: "implemented" },
763
+ { id: "L8", kind: "layout", semantic: "layout.spacer", tag: "p-spacer", props: ["grow", "shrink"], mpEquiv: "flex:1", tier: "L1", status: "implemented" },
764
+ { id: "L9", kind: "layout", semantic: "layout.divider", tag: "p-divider", props: ["orientation", "inset"], mpEquiv: "<view> + border", tier: "L1", status: "implemented" },
765
+ { id: "L10", kind: "layout", semantic: "layout.scroll", tag: "p-scroll", props: ["axis", "paging", "refresh", "indicator"], mpEquiv: "<scroll-view>", tier: "L1", status: "implemented" },
766
+ { id: "L11", kind: "layout", semantic: "layout.virtual-list", tag: "p-virtual-list", props: ["itemSize", "buffer", "direction"], mpEquiv: "<scroll-view> + \u624B\u52A8\u56DE\u6536", tier: "L1", status: "implemented" },
767
+ { id: "L12", kind: "layout", semantic: "layout.masonry", tag: "p-masonry", props: ["colCount", "gap"], mpEquiv: "\u7B2C\u4E09\u65B9\u7011\u5E03\u6D41", tier: "L1", status: "implemented" }
768
+ ];
769
+ var UI = [
770
+ { id: "U1", kind: "ui", semantic: "ui.text", tag: "p-text", props: ["content", "selectable", "truncate", "align"], mpEquiv: "<text>", tier: "L1", status: "implemented" },
771
+ { id: "U2", kind: "ui", semantic: "ui.heading", tag: "p-heading", props: ["level"], mpEquiv: "<h1>-<h6>", tier: "L1", status: "implemented" },
772
+ { id: "U3", kind: "ui", semantic: "ui.rich-text", tag: "p-rich-text", props: ["source", "schema"], mpEquiv: "<rich-text>", tier: "L1", status: "implemented" },
773
+ { id: "U4", kind: "ui", semantic: "ui.icon", tag: "p-icon", props: ["name", "size", "color", "spin"], mpEquiv: "<icon>", tier: "L1", status: "implemented" },
774
+ { id: "U5", kind: "ui", semantic: "ui.image", tag: "p-image", props: ["src", "fit", "placeholder", "lazy"], mpEquiv: "<image>", tier: "L1", status: "implemented" },
775
+ { id: "U6", kind: "ui", semantic: "ui.avatar", tag: "p-avatar", props: ["src", "shape", "size", "fallback"], mpEquiv: "\u7EC4\u5408", tier: "L1", status: "implemented" },
776
+ { id: "U7", kind: "ui", semantic: "ui.media", tag: "p-media", props: ["kind", "controls", "autoplay", "poster", "loop", "muted", "pictureInPicture"], mpEquiv: "<video>+<audio>", tier: "L1", status: "implemented" },
777
+ { id: "U8", kind: "ui", semantic: "ui.canvas", tag: "p-canvas", props: ["engine", "resolution"], mpEquiv: "<canvas>", tier: "L1", status: "implemented" },
778
+ { id: "U9", kind: "ui", semantic: "ui.svg", tag: "p-svg", props: ["path", "viewbox"], mpEquiv: "\u65E0", tier: "L1", status: "implemented" },
779
+ { id: "U10", kind: "ui", semantic: "ui.input", tag: "p-input", props: ["type", "mask", "validation", "clearable"], mpEquiv: "<input>", tier: "L1", status: "implemented" },
780
+ { id: "U11", kind: "ui", semantic: "ui.textarea", tag: "p-textarea", props: ["autosize", "maxLength", "count"], mpEquiv: "<textarea>", tier: "L1", status: "implemented" },
781
+ { id: "U12", kind: "ui", semantic: "ui.select", tag: "p-select", props: ["options", "multiple", "searchable", "cascader"], mpEquiv: "<picker> \u90E8\u5206", tier: "L1", status: "implemented" },
782
+ { id: "U13", kind: "ui", semantic: "ui.checkbox", tag: "p-checkbox", props: ["checked", "indeterminate", "group"], mpEquiv: "<checkbox>", tier: "L1", status: "implemented" },
783
+ { id: "U14", kind: "ui", semantic: "ui.radio", tag: "p-radio", props: ["value", "group"], mpEquiv: "<radio>", tier: "L1", status: "implemented" },
784
+ { id: "U15", kind: "ui", semantic: "ui.switch", tag: "p-switch", props: ["checked", "loading"], mpEquiv: "<switch>", tier: "L1", status: "implemented" },
785
+ { id: "U16", kind: "ui", semantic: "ui.slider", tag: "p-slider", props: ["min", "max", "step", "range"], mpEquiv: "<slider>", tier: "L1", status: "implemented" },
786
+ { id: "U17", kind: "ui", semantic: "ui.picker", tag: "p-picker", props: ["mode", "start", "end"], mpEquiv: "<picker>", tier: "L1", status: "implemented" },
787
+ { id: "U18", kind: "ui", semantic: "ui.form", tag: "p-form", props: ["model", "rules", "layout"], mpEquiv: "\u7EC4\u5408", tier: "L1", status: "implemented" }
788
+ ];
789
+ var SHELL = [
790
+ { id: "S1", kind: "shell", semantic: "shell.page", tag: "p-page", props: ["title", "statusBar", "pullRefresh"], mpEquiv: "<page>", tier: "L1", status: "implemented" },
791
+ { id: "S2", kind: "shell", semantic: "shell.nav", tag: "p-nav", props: ["title", "transparent"], mpEquiv: "\u5BFC\u822A\u680F\u914D\u7F6E", tier: "L1", status: "implemented" },
792
+ { id: "S3", kind: "shell", semantic: "shell.tabbar", tag: "p-tabbar", props: ["tabs", "active", "badge"], mpEquiv: "<tabbar>", tier: "L1", status: "implemented" },
793
+ { id: "S4", kind: "shell", semantic: "shell.segment", tag: "p-segment", props: ["options", "active"], mpEquiv: "<segment>", tier: "L1", status: "implemented" },
794
+ { id: "S5", kind: "shell", semantic: "shell.drawer", tag: "p-drawer", props: ["side", "width", "overlay"], mpEquiv: "\u7EC4\u5408", tier: "L1", status: "implemented" },
795
+ { id: "S6", kind: "shell", semantic: "shell.modal", tag: "p-modal", props: ["open", "dismissible", "sheet", "dialog", "alert"], mpEquiv: "<modal>+wx.showModal", tier: "L1", status: "implemented" },
796
+ { id: "S7", kind: "shell", semantic: "shell.popover", tag: "p-popover", props: ["trigger", "placement"], mpEquiv: "\u7EC4\u5408", tier: "L1", status: "implemented" },
797
+ { id: "S8", kind: "shell", semantic: "shell.toast", tag: "p-toast", props: ["message", "duration", "type"], mpEquiv: "wx.showToast", tier: "L1", status: "planned" },
798
+ { id: "S9", kind: "shell", semantic: "shell.action-sheet", tag: "p-action-sheet", props: ["actions", "cancel"], mpEquiv: "wx.showActionSheet", tier: "L1", status: "implemented" },
799
+ { id: "S10", kind: "shell", semantic: "layout.split", tag: "p-split", props: ["breakpoint", "ratio", "collapse"], mpEquiv: "\u65E0\uFF08\u5206\u680F\u5E03\u5C40\uFF09", tier: "L1", status: "implemented" }
800
+ // ★已落地绑定:分栏语义由 layout.split 承载(G-32 文档为 shell.split——机器事实以实现为准)
801
+ ];
802
+ var GESTURE = [
803
+ { id: "G1", kind: "gesture", semantic: "gesture.tap", api: "v-gesture:tap", props: ["count"], mpEquiv: "bindtap", tier: "L1", status: "planned" },
804
+ { id: "G2", kind: "gesture", semantic: "gesture.longpress", api: "v-gesture:longpress", props: ["duration", "onEnd"], mpEquiv: "bindlongpress", tier: "L1", status: "planned" },
805
+ { id: "G3", kind: "gesture", semantic: "gesture.swipe", api: "v-gesture:swipe", props: ["direction", "threshold"], mpEquiv: "bindswipe", tier: "L1", status: "planned" },
806
+ { id: "G4", kind: "gesture", semantic: "gesture.pan", api: "v-gesture:pan", props: ["axis", "bounds"], mpEquiv: "bindtouchmove", tier: "L1", status: "planned" },
807
+ { id: "G5", kind: "gesture", semantic: "gesture.pinch", api: "v-gesture:pinch", props: ["scale", "onChange"], mpEquiv: "touchstart/move \u7EC4\u5408", tier: "L1", status: "planned" },
808
+ { id: "G6", kind: "gesture", semantic: "gesture.rotate", api: "v-gesture:rotate", props: ["angle"], mpEquiv: "\u7EC4\u5408", tier: "L1", status: "planned" },
809
+ { id: "G7", kind: "gesture", semantic: "gesture.press", api: "v-gesture:press", props: ["force"], mpEquiv: "3D Touch", tier: "L1", status: "planned" },
810
+ { id: "G8", kind: "gesture", semantic: "gesture.draggable", tag: "p-draggable", props: ["ghost", "snapToGrid", "onDrop"], mpEquiv: "movable-view", tier: "L1", status: "implemented" },
811
+ { id: "G9", kind: "gesture", semantic: "gesture.scrollable", tag: "p-scrollable", props: ["bounce", "refresh", "loadMore"], mpEquiv: "<scroll-view>", tier: "L1", status: "implemented" },
812
+ { id: "G10", kind: "gesture", semantic: "gesture.use-gesture", api: "useGesture()", props: ["recognizers", "simultaneous"], mpEquiv: "\u65E0", tier: "L1", status: "planned" }
813
+ ];
814
+ function cap(id, name, api, mpEquiv, returnType) {
815
+ return { id, kind: "capability", semantic: `capability.${name}`, api, props: [returnType], mpEquiv, tier: "L1", status: "planned" };
816
+ }
817
+ var CAPABILITY = [
818
+ // 7.1 设备/硬件(15)
819
+ cap("C1", "camera", "useCamera()", "wx.createCameraContext", "Result<Media>"),
820
+ cap("C2", "microphone", "useMicrophone()", "RecorderManager", "Result<AudioBuffer>"),
821
+ { id: "C3", kind: "capability", semantic: "capability.location", api: "useLocation()", props: ["Result<Coords>"], mpEquiv: "wx.getLocation", tier: "L1", status: "implemented" },
822
+ cap("C4", "map", "useMap()", "wx.createMapContext", "MapController"),
823
+ cap("C5", "sensor", "useSensor()", "onAccelerometer/onCompass/onGyroscope", "SensorStream"),
824
+ cap("C6", "vibrate", "useVibrate()", "wx.vibrateShort/Long", "void"),
825
+ cap("C7", "battery", "useBattery()", "wx.getBatteryInfo", "BatteryInfo"),
826
+ cap("C8", "network", "useNetwork()", "wx.getNetworkType", "NetworkType"),
827
+ cap("C9", "clipboard", "useClipboard()", "wx.set/getClipboardData", "Result<string>"),
828
+ cap("C10", "screen", "useScreen()", "wx.getSystemInfo", "ScreenInfo"),
829
+ cap("C11", "device", "useDevice()", "wx.getSystemInfo", "DeviceInfo"),
830
+ cap("C12", "orientation", "useOrientation()", "wx.onDeviceOrientationChange", "Orientation"),
831
+ cap("C13", "brightness", "useBrightness()", "wx.setScreenBrightness", "Result<void>"),
832
+ cap("C14", "keyboard", "useKeyboard()", "wx.onKeyboardHeightChange", "KeyboardInfo"),
833
+ cap("C15", "storage", "useStorage()", "wx.set/getStorage", "StorageAPI"),
834
+ // 7.2 系统/OS(10)
835
+ cap("C16", "permission", "usePermission()", "wx.authorize", "Result<PermissionStatus>"),
836
+ cap("C17", "notification", "useNotification()", "wx.requestSubscribeMessage", "NotificationAPI"),
837
+ cap("C18", "share", "useShare()", "wx.shareAppMessage", "Result<void>"),
838
+ cap("C19", "contact", "useContact()", "wx.chooseContact", "Result<Contact[]>"),
839
+ cap("C20", "calendar", "useCalendar()", "wx.addPhoneCalendar", "CalendarAPI"),
840
+ cap("C21", "phone-call", "usePhoneCall()", "wx.makePhoneCall", "Result<void>"),
841
+ cap("C22", "sms", "useSMS()", "wx.??\uFF08\u53D7\u9650\uFF09", "Result<void>"),
842
+ cap("C23", "app-lifecycle", "useAppLifecycle()", "App.onLaunch/onShow", "LifecycleHooks"),
843
+ cap("C24", "page-lifecycle", "usePageLifecycle()", "Page.onLoad/onShow", "LifecycleHooks"),
844
+ cap("C25", "background", "useBackground()", "wx.onBackground", "BackgroundAPI"),
845
+ // 7.3 通信/数据(10)
846
+ cap("C26", "fetch", "useFetch()", "wx.request", "Promise<T>"),
847
+ cap("C27", "websocket", "useWebSocket()", "wx.connectSocket", "WSConnection"),
848
+ cap("C28", "socket-task", "useSocketTask()", "wx.SocketTask", "SocketTask"),
849
+ cap("C29", "upload", "useUpload()", "wx.uploadFile", "Progress<Result>"),
850
+ cap("C30", "download", "useDownload()", "wx.downloadFile", "Progress<Result>"),
851
+ cap("C31", "data-channel", "useDataChannel()", "wx...\uFF08\u76F4\u64AD/\u5B9E\u65F6\uFF09", "Channel"),
852
+ cap("C32", "cookie", "useCookie()", "\u65E0", "CookieJar"),
853
+ cap("C33", "auth", "useAuth()", "\u7EC4\u5408", "AuthState"),
854
+ cap("C34", "analytics", "useAnalytics()", "wx.reportEvent", "TrackAPI"),
855
+ cap("C35", "log", "useLog()", "console + \u4E0A\u62A5", "Logger"),
856
+ // 7.4 扩展能力(10)
857
+ cap("C36", "bluetooth", "useBluetooth()", "wx.openBluetoothAdapter", "BluetoothAPI"),
858
+ cap("C37", "nfc", "useNFC()", "wx.getHCEState", "NFCAPI"),
859
+ cap("C38", "biometric", "useBiometric()", "wx.checkIsSupportFingerPrint", "Result<boolean>"),
860
+ cap("C39", "face-id", "useFaceID()", "\u7EC4\u5408", "Result<boolean>"),
861
+ cap("C40", "payment", "usePayment()", "wx.requestPayment", "Result<PayResult>"),
862
+ cap("C41", "login", "useLogin()", "wx.login", "Result<Token>"),
863
+ cap("C42", "qr-code", "useQRCode()", "wx.scanCode + canvas", "Result<string>"),
864
+ cap("C43", "file-system", "useFileSystem()", "wx.getFileSystemManager", "FSAdapter"),
865
+ cap("C44", "archive", "useArchive()", "wx.compressFile", "Result<void>"),
866
+ cap("C45", "shortcut", "useShortcut()", "wx.addToDesktop", "Result<void>"),
867
+ cap("C46", "in-app-purchase", "useInAppPurchase()", "wx.requestPayment \u6269\u5C55", "Result<Receipt>"),
868
+ // 7.5 平台特有(4——C47-C50,此前 7.4 末 C46,总 50)
869
+ { id: "C47", kind: "capability", semantic: "capability.mini-program", api: "useMiniProgram()", props: ["MPContext"], mpEquiv: "wx.navigateToMiniProgram", tier: "L1", status: "planned" },
870
+ { id: "C48", kind: "capability", semantic: "capability.embedded", api: "useEmbedded()", props: ["HostContext"], mpEquiv: "\u65E0\uFF08\u88AB\u5BBF\u4E3B\u5D4C\u5165\uFF09", tier: "L1", status: "planned" },
871
+ { id: "C49", kind: "capability", semantic: "capability.live", api: "useLive()", props: ["LiveRoom"], mpEquiv: "wx...\uFF08\u76F4\u64AD\u7EC4\u4EF6\uFF09", tier: "L1", status: "planned" },
872
+ { id: "C50", kind: "capability", semantic: "capability.extension", api: "useExtension()", props: ["ExtensionAPI"], mpEquiv: "\u65E0\uFF08\u63D2\u4EF6/\u6269\u5C55\u70B9 G-21\uFF09", tier: "L1", status: "planned" }
873
+ ];
874
+ var ENGINEERING = [
875
+ { id: "E1", kind: "engineering", semantic: "engineering.state", api: "useState()", mpEquiv: "data", tier: "L1", status: "planned" },
876
+ { id: "E2", kind: "engineering", semantic: "engineering.computed", api: "useComputed()", mpEquiv: "computed", tier: "L1", status: "planned" },
877
+ { id: "E3", kind: "engineering", semantic: "engineering.watch", api: "useWatch()", mpEquiv: "watch", tier: "L1", status: "planned" },
878
+ { id: "E4", kind: "engineering", semantic: "engineering.store", api: "useStore()", mpEquiv: "getApp().globalData", tier: "L1", status: "planned" },
879
+ { id: "E5", kind: "engineering", semantic: "engineering.provide-inject", api: "useProvide()/useInject()", mpEquiv: "\u65E0", tier: "L1", status: "planned" },
880
+ { id: "E6", kind: "engineering", semantic: "engineering.lifecycle", api: "useLifecycle()", mpEquiv: "onLoad/onShow/onHide/onUnload", tier: "L1", status: "planned" },
881
+ { id: "E7", kind: "engineering", semantic: "engineering.ready", api: "useReady()", mpEquiv: "onReady", tier: "L1", status: "planned" },
882
+ { id: "E8", kind: "engineering", semantic: "engineering.error-boundary", api: "useErrorBoundary()", mpEquiv: "onError", tier: "L1", status: "planned" },
883
+ { id: "E9", kind: "engineering", semantic: "engineering.page-param", api: "usePageParam()", mpEquiv: "onLoad(options)", tier: "L1", status: "planned" },
884
+ { id: "E10", kind: "engineering", semantic: "engineering.route", api: "useRoute()", mpEquiv: "getCurrentPages()", tier: "L1", status: "planned" },
885
+ { id: "E11", kind: "engineering", semantic: "engineering.router-push", api: "router.push()", mpEquiv: "wx.navigateTo", tier: "L1", status: "planned" },
886
+ { id: "E12", kind: "engineering", semantic: "engineering.router-replace", api: "router.replace()", mpEquiv: "wx.redirectTo", tier: "L1", status: "planned" },
887
+ { id: "E13", kind: "engineering", semantic: "engineering.router-back", api: "router.back()", mpEquiv: "wx.navigateBack", tier: "L1", status: "planned" },
888
+ { id: "E14", kind: "engineering", semantic: "engineering.router-switch-tab", api: "router.switchTab()", mpEquiv: "wx.switchTab", tier: "L1", status: "planned" },
889
+ { id: "E15", kind: "engineering", semantic: "engineering.router-relaunch", api: "router.reLaunch()", mpEquiv: "wx.reLaunch", tier: "L1", status: "planned" },
890
+ { id: "E16", kind: "engineering", semantic: "engineering.router-before-each", api: "router.beforeEach()", mpEquiv: "onLaunch \u624B\u52A8", tier: "L1", status: "planned" },
891
+ { id: "E17", kind: "engineering", semantic: "engineering.router-after-each", api: "router.afterEach()", mpEquiv: "\u65E0", tier: "L1", status: "planned" },
892
+ { id: "E18", kind: "engineering", semantic: "engineering.router-link", tag: "p-router-link", props: ["to", "replace", "switchTab"], mpEquiv: "<navigator>", tier: "L1", status: "implemented" },
893
+ { id: "E19", kind: "engineering", semantic: "engineering.transition", tag: "p-transition", props: ["name", "mode"], mpEquiv: "transition CSS", tier: "L1", status: "implemented" },
894
+ { id: "E20", kind: "engineering", semantic: "engineering.animate", tag: "p-animate", props: ["keyframes", "duration"], mpEquiv: "animation CSS", tier: "L1", status: "implemented" },
895
+ { id: "E21", kind: "engineering", semantic: "engineering.animation", api: "useAnimation()", mpEquiv: "wx.createAnimation", tier: "L1", status: "planned" },
896
+ { id: "E22", kind: "engineering", semantic: "engineering.gesture-animation", api: "useGestureAnimation()", mpEquiv: "\u7EC4\u5408", tier: "L1", status: "planned" },
897
+ { id: "E23", kind: "engineering", semantic: "engineering.scroll-animation", api: "useScrollAnimation()", mpEquiv: "\u7EC4\u5408", tier: "L1", status: "planned" },
898
+ { id: "E24", kind: "engineering", semantic: "engineering.devtools", api: "useDevTools()", mpEquiv: "\u5C0F\u7A0B\u5E8F DevTools", tier: "L1", status: "planned" },
899
+ { id: "E25", kind: "engineering", semantic: "engineering.inspector", api: "useInspector()", mpEquiv: "\u65E0", tier: "L1", status: "planned" },
900
+ { id: "E26", kind: "engineering", semantic: "engineering.performance", api: "usePerformance()", mpEquiv: "wx.reportPerformance", tier: "L1", status: "planned" },
901
+ { id: "E27", kind: "engineering", semantic: "engineering.define-component", api: "defineComponent()", mpEquiv: "Component()", tier: "L1", status: "planned" },
902
+ { id: "E28", kind: "engineering", semantic: "engineering.define-capability", api: "defineCapability()", mpEquiv: "\u65E0", tier: "L1", status: "planned" }
903
+ ];
904
+ var PRIMITIVE_CATALOG = [...LAYOUT, ...UI, ...SHELL, ...GESTURE, ...CAPABILITY, ...ENGINEERING];
905
+ function componentPrimitives(kinds = ["layout", "ui", "shell", "gesture", "engineering"]) {
906
+ return PRIMITIVE_CATALOG.filter((p) => p.tag && kinds.includes(p.kind));
907
+ }
908
+ function implementedPrimitives() {
909
+ return PRIMITIVE_CATALOG.filter((p) => p.status === "implemented");
910
+ }
911
+ function primitiveById(id) {
912
+ return PRIMITIVE_CATALOG.find((p) => p.id === id);
913
+ }
914
+ function primitiveBySemantic(semantic) {
915
+ return PRIMITIVE_CATALOG.find((p) => p.semantic === semantic);
916
+ }
917
+ function primitiveByTag(tag) {
918
+ return PRIMITIVE_CATALOG.find((p) => p.tag === tag);
919
+ }
920
+ function checkPrimitiveCatalog() {
921
+ const errors = [];
922
+ if (PRIMITIVE_CATALOG.length !== 128) errors.push(`\u6E05\u5355\u957F\u5EA6 ${PRIMITIVE_CATALOG.length} \u2260 128`);
923
+ const ids = new Set(PRIMITIVE_CATALOG.map((p) => p.id));
924
+ if (ids.size !== PRIMITIVE_CATALOG.length) errors.push("id \u91CD\u590D");
925
+ const sems = new Set(PRIMITIVE_CATALOG.map((p) => p.semantic));
926
+ if (sems.size !== PRIMITIVE_CATALOG.length) errors.push("semantic \u91CD\u590D");
927
+ const tags = PRIMITIVE_CATALOG.filter((p) => p.tag).map((p) => p.tag);
928
+ if (new Set(tags).size !== tags.length) errors.push("tag \u91CD\u590D");
929
+ return errors;
930
+ }
931
+
932
+ // src/conformance.ts
933
+ function extractSemanticTree(snap) {
934
+ return { semantic: snap.semantic, children: snap.children.map(extractSemanticTree) };
935
+ }
936
+ function checkComponentSnapshot(backendId, snapshot) {
937
+ const errors = [];
938
+ const unverified = [];
939
+ let nodes = 0;
940
+ function visit(snap, path) {
941
+ nodes++;
942
+ if (snap.semantic !== snap.type) {
943
+ const row = SEMANTIC_BACKEND_MAP[snap.semantic];
944
+ if (!row) {
945
+ unverified.push({ path, semantic: snap.semantic, expected: null, actual: snap.control, reason: "no-row" });
946
+ } else {
947
+ const mapped = row[backendId];
948
+ if (mapped === void 0) {
949
+ unverified.push({ path, semantic: snap.semantic, expected: null, actual: snap.control, reason: "no-column" });
950
+ } else if (snap.control !== mapped) {
951
+ errors.push({ path, semantic: snap.semantic, expected: mapped, actual: snap.control, reason: "mismatch" });
952
+ }
953
+ }
954
+ } else {
955
+ unverified.push({ path, semantic: snap.semantic, expected: null, actual: snap.control, reason: "compat" });
956
+ }
957
+ snap.children.forEach((c, i) => visit(c, path ? `${path}/${i}` : String(i)));
958
+ }
959
+ visit(snapshot, "");
960
+ return { ok: errors.length === 0, backendId, nodes, errors, unverified };
961
+ }
962
+ function checkSemanticCoverage(minBackends = 3) {
963
+ const gaps = [];
964
+ for (const p of implementedPrimitives()) {
965
+ const row = SEMANTIC_BACKEND_MAP[p.semantic];
966
+ const backends = row ? Object.keys(row) : [];
967
+ if (backends.length < minBackends) gaps.push({ semantic: p.semantic, backends });
968
+ }
969
+ return gaps;
970
+ }
971
+
972
+ // src/audit.ts
973
+ var MP_COMPONENTS = [
974
+ { mp: "<view>", proteus: "layout.box / layout.stack", status: "ok", group: "component" },
975
+ { mp: "<text>", proteus: "ui.text / ui.heading", status: "ok", group: "component" },
976
+ { mp: "<image>", proteus: "ui.image", status: "ok", group: "component" },
977
+ { mp: "<scroll-view>", proteus: "layout.scroll / layout.virtual-list", status: "ok", group: "component" },
978
+ { mp: "<swiper>", proteus: "layout.stack snap/loop\uFF08\u6D88\u706D\u4E3A\u5C5E\u6027\uFF09", status: "ok", group: "component" },
979
+ { mp: "<swiper-item>", proteus: "layout.stack \u5B50\u9879", status: "ok", group: "component" },
980
+ { mp: "<movable-area>", proteus: "gesture.scrollable \u5BB9\u5668", status: "ok", group: "component" },
981
+ { mp: "<movable-view>", proteus: "gesture.draggable", status: "ok", group: "component" },
982
+ { mp: "<cover-view>", proteus: "p-overlay (L2)", status: "compat", group: "component" },
983
+ { mp: "<cover-image>", proteus: "p-overlay + ui.image", status: "compat", group: "component" },
984
+ { mp: "<icon>", proteus: "ui.icon", status: "ok", group: "component" },
985
+ { mp: "<progress>", proteus: "p-progress (L2)", status: "compat", group: "component" },
986
+ { mp: "<rich-text>", proteus: "ui.rich-text", status: "ok", group: "component" },
987
+ { mp: "<button>", proteus: "ui.button", status: "ok", group: "component" },
988
+ { mp: "<form>", proteus: "ui.form", status: "ok", group: "component" },
989
+ { mp: "<input>", proteus: "ui.input", status: "ok", group: "component" },
990
+ { mp: "<textarea>", proteus: "ui.textarea", status: "ok", group: "component" },
991
+ { mp: "<checkbox>", proteus: "ui.checkbox", status: "ok", group: "component" },
992
+ { mp: "<radio>", proteus: "ui.radio", status: "ok", group: "component" },
993
+ { mp: "<picker>", proteus: "ui.picker / ui.select", status: "ok", group: "component" },
994
+ { mp: "<picker-view>", proteus: "ui.picker mode=wheel", status: "ok", group: "component" },
995
+ { mp: "<slider>", proteus: "ui.slider", status: "ok", group: "component" },
996
+ { mp: "<switch>", proteus: "ui.switch", status: "ok", group: "component" },
997
+ { mp: "<label>", proteus: "p-label (L2)", status: "compat", group: "component" },
998
+ { mp: "<navigator>", proteus: "engineering.router-link / router.*", status: "ok", group: "component" },
999
+ { mp: "<audio>", proteus: "ui.media kind=audio\uFF08\u6D88\u706D\u4E3A\u5C5E\u6027\uFF09", status: "ok", group: "component" },
1000
+ { mp: "<video>", proteus: "ui.media kind=video\uFF08\u6D88\u706D\u4E3A\u5C5E\u6027\uFF09", status: "ok", group: "component" },
1001
+ { mp: "<camera>", proteus: "p-camera (L2) + capability.camera", status: "ok", group: "component" },
1002
+ { mp: "<live-player>", proteus: "ui.media kind=live\uFF08\u6D88\u706D\u4E3A\u5C5E\u6027\uFF09", status: "ok", group: "component" },
1003
+ { mp: "<live-pusher>", proteus: "ui.media kind=live mode=push", status: "ok", group: "component" },
1004
+ { mp: "<canvas>", proteus: "ui.canvas", status: "ok", group: "component" },
1005
+ { mp: "<map>", proteus: "p-map (L2) + capability.map", status: "ok", group: "component" },
1006
+ { mp: "<web-view>", proteus: "p-webview (L2)", status: "compat", group: "component" },
1007
+ { mp: "<editor>", proteus: "ui.rich-text editable", status: "ok", group: "component" },
1008
+ { mp: "<ad>", proteus: "p-ad (L2)", status: "compat", group: "component" },
1009
+ { mp: "<official-account>", proteus: "capability.mini-program\uFF08\u5FAE\u4FE1\u79C1\u6709\uFF09", status: "private", group: "component" },
1010
+ { mp: "<open-data>", proteus: "capability.mini-program\uFF08\u5FAE\u4FE1\u79C1\u6709\uFF09", status: "private", group: "component" },
1011
+ { mp: "<share-element>", proteus: "p-share-element (L2)", status: "compat", group: "component" },
1012
+ { mp: "<aria-component>", proteus: "p-aria (L2)", status: "compat", group: "component" },
1013
+ { mp: "<page-container>", proteus: "p-page-container (L2)", status: "compat", group: "component" },
1014
+ { mp: "<voip-room>", proteus: "capability.mini-program\uFF08\u5FAE\u4FE1 VOIP\uFF09", status: "private", group: "component" },
1015
+ { mp: "<guild-room>", proteus: "capability.mini-program\uFF08\u5FAE\u4FE1\u6E38\u620F\uFF09", status: "private", group: "component" }
1016
+ ];
1017
+ var MP_API_GROUPS = [
1018
+ { mp: "wx.request/upload/download/websocket\uFF08\u7F51\u7EDC\uFF09", proteus: "capability.fetch/upload/download/websocket", status: "ok", group: "api" },
1019
+ { mp: "wx.requestPayment", proteus: "capability.payment", status: "ok", group: "api" },
1020
+ { mp: "wx.chooseImage/chooseMedia/previewImage\uFF08\u5A92\u4F53\uFF09", proteus: "capability.camera + ui.image preview", status: "ok", group: "api" },
1021
+ { mp: "wx.startRecord/RecorderManager\uFF08\u5F55\u97F3\uFF09", proteus: "capability.microphone", status: "ok", group: "api" },
1022
+ { mp: "wx.createVideoContext/CameraContext", proteus: "capability.media + ui.media", status: "ok", group: "api" },
1023
+ { mp: "wx.scanCode", proteus: "capability.qr-code / capability.scan-qr", status: "ok", group: "api" },
1024
+ { mp: "wx.saveImageToPhotosAlbum", proteus: "capability.album (L2)", status: "compat", group: "api" },
1025
+ { mp: "wx.getFileSystemManager/*\uFF08\u6587\u4EF6 30+\uFF09", proteus: "capability.file-system", status: "ok", group: "api" },
1026
+ { mp: "wx.compressFile/unzip", proteus: "capability.archive", status: "ok", group: "api" },
1027
+ { mp: "wx.set/get/remove/clearStorage(+Sync)", proteus: "capability.storage", status: "ok", group: "api" },
1028
+ { mp: "wx.getLocation/chooseLocation/openLocation", proteus: "capability.location", status: "ok", group: "api" },
1029
+ { mp: "wx.createMapContext", proteus: "capability.map", status: "ok", group: "api" },
1030
+ { mp: "wx.getSystemInfo\uFF08\u8BBE\u5907/\u5C4F\u5E55/\u7F51\u7EDC/\u7535\u91CF/\u4EAE\u5EA6/\u65B9\u5411/\u9707\u52A8/\u4F20\u611F\u5668/\u526A\u8D34\u677F/\u7535\u8BDD\uFF09", proteus: "capability.device/screen/network/battery/brightness/orientation/vibrate/sensor/clipboard/phone-call", status: "ok", group: "api" },
1031
+ { mp: "wx.openBluetoothAdapter\uFF08\u84DD\u7259 20+\uFF09", proteus: "capability.bluetooth", status: "ok", group: "api" },
1032
+ { mp: "wx.getHCEState\uFF08NFC\uFF09", proteus: "capability.nfc", status: "ok", group: "api" },
1033
+ { mp: "wx.checkIsSupportFingerPrint/FaceID", proteus: "capability.biometric / face-id", status: "ok", group: "api" },
1034
+ { mp: "wx.showToast/showLoading/showModal/showActionSheet", proteus: "shell.toast + capability.toast/loading + shell.modal + shell.action-sheet", status: "ok", group: "api" },
1035
+ { mp: "wx.setNavigationBarTitle/Color", proteus: "shell.nav", status: "ok", group: "api" },
1036
+ { mp: "wx.setTabBarItem/Style/hide/show", proteus: "shell.tabbar", status: "ok", group: "api" },
1037
+ { mp: "wx.pageScrollTo", proteus: "capability.page-scroll", status: "ok", group: "api" },
1038
+ { mp: "wx.createAnimation", proteus: "engineering.animation", status: "ok", group: "api" },
1039
+ { mp: "wx.createSelectorQuery/IntersectionObserver", proteus: "capability.element / intersection", status: "ok", group: "api" },
1040
+ { mp: "wx.navigateTo/redirectTo/navigateBack/switchTab/reLaunch", proteus: "engineering.router-push/replace/back/switch-tab/relaunch", status: "ok", group: "api" },
1041
+ { mp: "wx.getCurrentPages", proteus: "engineering.route", status: "ok", group: "api" },
1042
+ { mp: "App()/Page() \u751F\u547D\u5468\u671F/getApp()", proteus: "engineering.lifecycle + capability.app-lifecycle/page-lifecycle", status: "ok", group: "api" },
1043
+ { mp: "wx.shareAppMessage/requestSubscribeMessage", proteus: "capability.share / notification", status: "ok", group: "api" },
1044
+ { mp: "wx.login/checkSession/getUserInfo/authorize", proteus: "capability.login / auth / permission", status: "ok", group: "api" },
1045
+ { mp: "wx.getUpdateManager", proteus: "capability.update (L2)", status: "compat", group: "api" },
1046
+ { mp: "wx.requestWeChatPay/navigateToMiniProgram/\u6A21\u677F\u6D88\u606F/\u5BA2\u670D\uFF08\u5FAE\u4FE1\u79C1\u6709\uFF09", proteus: "capability.mini-program", status: "private", group: "api" }
1047
+ ];
1048
+ var MP_MAPPING_MATRIX = [...MP_COMPONENTS, ...MP_API_GROUPS];
1049
+ function auditMiniprogramCoverage(matrix = MP_MAPPING_MATRIX) {
1050
+ const missing = matrix.filter((i) => i.status === "missing");
1051
+ const missingItems = missing;
1052
+ const ok = matrix.filter((i) => i.status === "ok").length;
1053
+ const compat = matrix.filter((i) => i.status === "compat").length;
1054
+ const priv = matrix.filter((i) => i.status === "private").length;
1055
+ const total = matrix.length;
1056
+ return {
1057
+ total,
1058
+ ok,
1059
+ compat,
1060
+ private: priv,
1061
+ missing: missingItems.length,
1062
+ percent: total === 0 ? 0 : Math.round((total - missingItems.length) / total * 100),
1063
+ pass: missingItems.length === 0,
1064
+ missingItems
1065
+ };
1066
+ }
1067
+ function auditCatalogConsistency() {
1068
+ const issues = [];
1069
+ const enumSet = new Set(SEMANTIC_ENUM);
1070
+ const catalogTags = PRIMITIVE_CATALOG.filter((p) => p.tag);
1071
+ for (const p of catalogTags) {
1072
+ const tag = p.tag;
1073
+ if (TAG_SEMANTIC_MAP[tag] !== p.semantic) {
1074
+ issues.push({ rule: "C1", detail: `catalog ${p.id} (${tag}) \u8BED\u4E49=${p.semantic} \u2260 TAG_SEMANTIC_MAP=${TAG_SEMANTIC_MAP[tag] ?? "<\u672A\u767B\u8BB0>"}` });
1075
+ }
1076
+ }
1077
+ for (const p of catalogTags) {
1078
+ if (!enumSet.has(p.semantic)) {
1079
+ issues.push({ rule: "C2", detail: `catalog ${p.id} \u8BED\u4E49 ${p.semantic} \u4E0D\u5728 SEMANTIC_ENUM` });
1080
+ }
1081
+ }
1082
+ for (const [tag, sem] of Object.entries(TAG_SEMANTIC_MAP)) {
1083
+ if (!enumSet.has(sem)) {
1084
+ issues.push({ rule: "C3", detail: `${tag} \u2192 ${sem}\uFF08TAG_SEMANTIC_MAP \u503C\u4E0D\u5728 SEMANTIC_ENUM\uFF09` });
1085
+ }
1086
+ }
1087
+ for (const p of PRIMITIVE_CATALOG.filter((x) => x.status === "implemented")) {
1088
+ if (!SEMANTIC_BACKEND_MAP[p.semantic]) {
1089
+ issues.push({ rule: "C4", detail: `${p.id} ${p.semantic}\uFF08implemented \u4F46 SEMANTIC_BACKEND_MAP \u65E0\u884C\uFF09` });
1090
+ }
1091
+ }
1092
+ for (const sem of enumSet) {
1093
+ if (!SEMANTIC_BACKEND_MAP[sem]) {
1094
+ const inCatalog = PRIMITIVE_CATALOG.some((p) => p.semantic === sem);
1095
+ if (!inCatalog) {
1096
+ issues.push({ rule: "C5", detail: `${sem} \u5728 SEMANTIC_ENUM \u4F46\u4E0D\u5728 catalog\uFF08\u5B64\u7ACB\u8BED\u4E49\uFF09` });
1097
+ }
1098
+ }
1099
+ }
1100
+ return issues;
1101
+ }
1102
+ function formatCoverageReport(report) {
1103
+ const lines = [
1104
+ `G-32.1 \u5C0F\u7A0B\u5E8F\u80FD\u529B\u8986\u76D6\u5BA1\u8BA1\uFF1A`,
1105
+ ` \u603B\u8BA1 ${report.total} \xB7 \u2705 L1 ${report.ok}\uFF08${Math.round(report.ok / report.total * 100)}%\uFF09\xB7 \u{1F504} L2/compat ${report.compat} \xB7 \u2B1B \u79C1\u6709 ${report.private} \xB7 \u274C \u7F3A\u5931 ${report.missing}`,
1106
+ ` \u8986\u76D6\u7387 ${report.percent}% ${report.pass ? "\u2705 \u8FBE\u6807\uFF080 \u7F3A\u5931\uFF09" : "\u274C \u672A\u8FBE\u6807\uFF08CI \u7EA2\uFF09"}`
1107
+ ];
1108
+ if (report.missingItems.length) {
1109
+ lines.push(" \u7F3A\u5931\u9879\uFF1A");
1110
+ for (const m of report.missingItems) lines.push(` \u274C ${m.mp} \u2192 ${m.proteus}`);
1111
+ }
1112
+ return lines.join("\n");
1113
+ }
1114
+ export {
1115
+ COMPONENT_IR_SCHEMA,
1116
+ DEFAULT_DESIGN_WIDTH,
1117
+ MP_MAPPING_MATRIX,
1118
+ PRIMITIVE_CATALOG,
1119
+ SEMANTIC_BACKEND_MAP,
1120
+ SEMANTIC_ENUM,
1121
+ TAG_SEMANTIC_MAP,
1122
+ auditCatalogConsistency,
1123
+ auditMiniprogramCoverage,
1124
+ checkComponentSnapshot,
1125
+ checkPrimitiveCatalog,
1126
+ checkSemanticCoverage,
1127
+ componentPrimitives,
1128
+ extractSemanticTree,
1129
+ formatCoverageReport,
1130
+ implementedPrimitives,
1131
+ mapSemanticToBackend,
1132
+ primitiveById,
1133
+ primitiveBySemantic,
1134
+ primitiveByTag,
1135
+ toComponentIR,
1136
+ toComponentTree,
1137
+ validateComponentIR,
1138
+ validateComponentTree,
1139
+ validateGridConstraints
1140
+ };