base-paint 0.3.13 → 0.3.15

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.
Files changed (1826) hide show
  1. package/README.md +218 -15
  2. package/dist/blocks.d.ts +188 -14
  3. package/dist/blocks.d.ts.map +1 -1
  4. package/dist/blocks.js +781 -78
  5. package/dist/blocks.js.map +1 -1
  6. package/dist/charts.d.ts +6 -61
  7. package/dist/charts.d.ts.map +1 -1
  8. package/dist/charts.js +6 -2034
  9. package/dist/charts.js.map +1 -1
  10. package/dist/components/bulk-bar/attrs.d.ts +176 -0
  11. package/dist/components/bulk-bar/attrs.d.ts.map +1 -0
  12. package/dist/components/bulk-bar/attrs.js +184 -0
  13. package/dist/components/bulk-bar/attrs.js.map +1 -0
  14. package/dist/components/bulk-bar/index.d.ts +25 -0
  15. package/dist/components/bulk-bar/index.d.ts.map +1 -0
  16. package/dist/components/bulk-bar/index.js +23 -0
  17. package/dist/components/bulk-bar/index.js.map +1 -0
  18. package/dist/components/bulk-bar/model.d.ts +74 -0
  19. package/dist/components/bulk-bar/model.d.ts.map +1 -0
  20. package/dist/components/bulk-bar/model.js +239 -0
  21. package/dist/components/bulk-bar/model.js.map +1 -0
  22. package/dist/components/bulk-bar/render.d.ts +3 -0
  23. package/dist/components/bulk-bar/render.d.ts.map +1 -0
  24. package/dist/components/bulk-bar/render.js +195 -0
  25. package/dist/components/bulk-bar/render.js.map +1 -0
  26. package/dist/components/bulk-bar/runtime.d.ts +3 -0
  27. package/dist/components/bulk-bar/runtime.d.ts.map +1 -0
  28. package/dist/components/bulk-bar/runtime.js +135 -0
  29. package/dist/components/bulk-bar/runtime.js.map +1 -0
  30. package/dist/components/bulk-bar/style-column.d.ts +5 -0
  31. package/dist/components/bulk-bar/style-column.d.ts.map +1 -0
  32. package/dist/components/bulk-bar/style-column.js +191 -0
  33. package/dist/components/bulk-bar/style-column.js.map +1 -0
  34. package/dist/components/bulk-bar/style-confirm.d.ts +5 -0
  35. package/dist/components/bulk-bar/style-confirm.d.ts.map +1 -0
  36. package/dist/components/bulk-bar/style-confirm.js +236 -0
  37. package/dist/components/bulk-bar/style-confirm.js.map +1 -0
  38. package/dist/components/bulk-bar/style-sizes.d.ts +15 -0
  39. package/dist/components/bulk-bar/style-sizes.d.ts.map +1 -0
  40. package/dist/components/bulk-bar/style-sizes.js +14 -0
  41. package/dist/components/bulk-bar/style-sizes.js.map +1 -0
  42. package/dist/components/bulk-bar/style.d.ts +6 -0
  43. package/dist/components/bulk-bar/style.d.ts.map +1 -0
  44. package/dist/components/bulk-bar/style.js +239 -0
  45. package/dist/components/bulk-bar/style.js.map +1 -0
  46. package/dist/components/calendar-month/attrs.d.ts +85 -0
  47. package/dist/components/calendar-month/attrs.d.ts.map +1 -0
  48. package/dist/components/calendar-month/attrs.js +76 -0
  49. package/dist/components/calendar-month/attrs.js.map +1 -0
  50. package/dist/components/calendar-month/index.d.ts +13 -0
  51. package/dist/components/calendar-month/index.d.ts.map +1 -0
  52. package/dist/components/calendar-month/index.js +11 -0
  53. package/dist/components/calendar-month/index.js.map +1 -0
  54. package/dist/components/calendar-month/model.d.ts +31 -0
  55. package/dist/components/calendar-month/model.d.ts.map +1 -0
  56. package/dist/components/calendar-month/model.js +142 -0
  57. package/dist/components/calendar-month/model.js.map +1 -0
  58. package/dist/components/calendar-month/render.d.ts +3 -0
  59. package/dist/components/calendar-month/render.d.ts.map +1 -0
  60. package/dist/components/calendar-month/render.js +84 -0
  61. package/dist/components/calendar-month/render.js.map +1 -0
  62. package/dist/components/calendar-month/style.d.ts +14 -0
  63. package/dist/components/calendar-month/style.d.ts.map +1 -0
  64. package/dist/components/calendar-month/style.js +210 -0
  65. package/dist/components/calendar-month/style.js.map +1 -0
  66. package/dist/components/cash-waterline/attrs.d.ts +131 -0
  67. package/dist/components/cash-waterline/attrs.d.ts.map +1 -0
  68. package/dist/components/cash-waterline/attrs.js +157 -0
  69. package/dist/components/cash-waterline/attrs.js.map +1 -0
  70. package/dist/components/cash-waterline/fields.d.ts +26 -0
  71. package/dist/components/cash-waterline/fields.d.ts.map +1 -0
  72. package/dist/components/cash-waterline/fields.js +174 -0
  73. package/dist/components/cash-waterline/fields.js.map +1 -0
  74. package/dist/components/cash-waterline/index.d.ts +14 -0
  75. package/dist/components/cash-waterline/index.d.ts.map +1 -0
  76. package/dist/components/cash-waterline/index.js +12 -0
  77. package/dist/components/cash-waterline/index.js.map +1 -0
  78. package/dist/components/cash-waterline/model.d.ts +117 -0
  79. package/dist/components/cash-waterline/model.d.ts.map +1 -0
  80. package/dist/components/cash-waterline/model.js +242 -0
  81. package/dist/components/cash-waterline/model.js.map +1 -0
  82. package/dist/components/cash-waterline/render.d.ts +3 -0
  83. package/dist/components/cash-waterline/render.d.ts.map +1 -0
  84. package/dist/components/cash-waterline/render.js +203 -0
  85. package/dist/components/cash-waterline/render.js.map +1 -0
  86. package/dist/components/cash-waterline/style-forms.d.ts +7 -0
  87. package/dist/components/cash-waterline/style-forms.d.ts.map +1 -0
  88. package/dist/components/cash-waterline/style-forms.js +337 -0
  89. package/dist/components/cash-waterline/style-forms.js.map +1 -0
  90. package/dist/components/cash-waterline/style.d.ts +9 -0
  91. package/dist/components/cash-waterline/style.d.ts.map +1 -0
  92. package/dist/components/cash-waterline/style.js +224 -0
  93. package/dist/components/cash-waterline/style.js.map +1 -0
  94. package/dist/components/charts/bar.d.ts +11 -0
  95. package/dist/components/charts/bar.d.ts.map +1 -0
  96. package/dist/components/charts/bar.js +257 -0
  97. package/dist/components/charts/bar.js.map +1 -0
  98. package/dist/components/charts/combo.d.ts +11 -0
  99. package/dist/components/charts/combo.d.ts.map +1 -0
  100. package/dist/components/charts/combo.js +113 -0
  101. package/dist/components/charts/combo.js.map +1 -0
  102. package/dist/components/charts/coords.d.ts +134 -0
  103. package/dist/components/charts/coords.d.ts.map +1 -0
  104. package/dist/components/charts/coords.js +182 -0
  105. package/dist/components/charts/coords.js.map +1 -0
  106. package/dist/components/charts/dispatch.d.ts +15 -0
  107. package/dist/components/charts/dispatch.d.ts.map +1 -0
  108. package/dist/components/charts/dispatch.js +41 -0
  109. package/dist/components/charts/dispatch.js.map +1 -0
  110. package/dist/components/charts/donut.d.ts +11 -0
  111. package/dist/components/charts/donut.d.ts.map +1 -0
  112. package/dist/components/charts/donut.js +90 -0
  113. package/dist/components/charts/donut.js.map +1 -0
  114. package/dist/components/charts/gauge.d.ts +11 -0
  115. package/dist/components/charts/gauge.d.ts.map +1 -0
  116. package/dist/components/charts/gauge.js +48 -0
  117. package/dist/components/charts/gauge.js.map +1 -0
  118. package/dist/components/charts/helpers.d.ts +20 -0
  119. package/dist/components/charts/helpers.d.ts.map +1 -0
  120. package/dist/components/charts/helpers.js +58 -0
  121. package/dist/components/charts/helpers.js.map +1 -0
  122. package/dist/components/charts/index.d.ts +10 -0
  123. package/dist/components/charts/index.d.ts.map +1 -0
  124. package/dist/components/charts/index.js +9 -0
  125. package/dist/components/charts/index.js.map +1 -0
  126. package/dist/components/charts/line.d.ts +13 -0
  127. package/dist/components/charts/line.d.ts.map +1 -0
  128. package/dist/components/charts/line.js +675 -0
  129. package/dist/components/charts/line.js.map +1 -0
  130. package/dist/components/charts/options.d.ts +62 -0
  131. package/dist/components/charts/options.d.ts.map +1 -0
  132. package/dist/components/charts/options.js +113 -0
  133. package/dist/components/charts/options.js.map +1 -0
  134. package/dist/components/charts/progress.d.ts +11 -0
  135. package/dist/components/charts/progress.d.ts.map +1 -0
  136. package/dist/components/charts/progress.js +49 -0
  137. package/dist/components/charts/progress.js.map +1 -0
  138. package/dist/components/charts/scatter.d.ts +11 -0
  139. package/dist/components/charts/scatter.d.ts.map +1 -0
  140. package/dist/components/charts/scatter.js +116 -0
  141. package/dist/components/charts/scatter.js.map +1 -0
  142. package/dist/components/charts/shared.d.ts +64 -0
  143. package/dist/components/charts/shared.d.ts.map +1 -0
  144. package/dist/components/charts/shared.js +159 -0
  145. package/dist/components/charts/shared.js.map +1 -0
  146. package/dist/components/charts/sparkline.d.ts +11 -0
  147. package/dist/components/charts/sparkline.d.ts.map +1 -0
  148. package/dist/components/charts/sparkline.js +52 -0
  149. package/dist/components/charts/sparkline.js.map +1 -0
  150. package/dist/components/charts/style.d.ts +19 -0
  151. package/dist/components/charts/style.d.ts.map +1 -0
  152. package/dist/components/charts/style.js +120 -0
  153. package/dist/components/charts/style.js.map +1 -0
  154. package/dist/components/charts/svg.d.ts +23 -0
  155. package/dist/components/charts/svg.d.ts.map +1 -0
  156. package/dist/components/charts/svg.js +143 -0
  157. package/dist/components/charts/svg.js.map +1 -0
  158. package/dist/components/command-palette/attrs.d.ts +165 -0
  159. package/dist/components/command-palette/attrs.d.ts.map +1 -0
  160. package/dist/components/command-palette/attrs.js +162 -0
  161. package/dist/components/command-palette/attrs.js.map +1 -0
  162. package/dist/components/command-palette/index.d.ts +18 -0
  163. package/dist/components/command-palette/index.d.ts.map +1 -0
  164. package/dist/components/command-palette/index.js +16 -0
  165. package/dist/components/command-palette/index.js.map +1 -0
  166. package/dist/components/command-palette/model.d.ts +46 -0
  167. package/dist/components/command-palette/model.d.ts.map +1 -0
  168. package/dist/components/command-palette/model.js +164 -0
  169. package/dist/components/command-palette/model.js.map +1 -0
  170. package/dist/components/command-palette/render.d.ts +3 -0
  171. package/dist/components/command-palette/render.d.ts.map +1 -0
  172. package/dist/components/command-palette/render.js +153 -0
  173. package/dist/components/command-palette/render.js.map +1 -0
  174. package/dist/components/command-palette/runtime.d.ts +3 -0
  175. package/dist/components/command-palette/runtime.d.ts.map +1 -0
  176. package/dist/components/command-palette/runtime.js +153 -0
  177. package/dist/components/command-palette/runtime.js.map +1 -0
  178. package/dist/components/command-palette/style.d.ts +5 -0
  179. package/dist/components/command-palette/style.d.ts.map +1 -0
  180. package/dist/components/command-palette/style.js +346 -0
  181. package/dist/components/command-palette/style.js.map +1 -0
  182. package/dist/components/compare-columns/attrs.d.ts +79 -0
  183. package/dist/components/compare-columns/attrs.d.ts.map +1 -0
  184. package/dist/components/compare-columns/attrs.js +86 -0
  185. package/dist/components/compare-columns/attrs.js.map +1 -0
  186. package/dist/components/compare-columns/index.d.ts +14 -0
  187. package/dist/components/compare-columns/index.d.ts.map +1 -0
  188. package/dist/components/compare-columns/index.js +12 -0
  189. package/dist/components/compare-columns/index.js.map +1 -0
  190. package/dist/components/compare-columns/model.d.ts +35 -0
  191. package/dist/components/compare-columns/model.d.ts.map +1 -0
  192. package/dist/components/compare-columns/model.js +112 -0
  193. package/dist/components/compare-columns/model.js.map +1 -0
  194. package/dist/components/compare-columns/render.d.ts +4 -0
  195. package/dist/components/compare-columns/render.d.ts.map +1 -0
  196. package/dist/components/compare-columns/render.js +92 -0
  197. package/dist/components/compare-columns/render.js.map +1 -0
  198. package/dist/components/compare-columns/style.d.ts +13 -0
  199. package/dist/components/compare-columns/style.d.ts.map +1 -0
  200. package/dist/components/compare-columns/style.js +287 -0
  201. package/dist/components/compare-columns/style.js.map +1 -0
  202. package/dist/components/confirm-strip/attrs.d.ts +111 -0
  203. package/dist/components/confirm-strip/attrs.d.ts.map +1 -0
  204. package/dist/components/confirm-strip/attrs.js +100 -0
  205. package/dist/components/confirm-strip/attrs.js.map +1 -0
  206. package/dist/components/confirm-strip/index.d.ts +32 -0
  207. package/dist/components/confirm-strip/index.d.ts.map +1 -0
  208. package/dist/components/confirm-strip/index.js +30 -0
  209. package/dist/components/confirm-strip/index.js.map +1 -0
  210. package/dist/components/confirm-strip/model.d.ts +40 -0
  211. package/dist/components/confirm-strip/model.d.ts.map +1 -0
  212. package/dist/components/confirm-strip/model.js +112 -0
  213. package/dist/components/confirm-strip/model.js.map +1 -0
  214. package/dist/components/confirm-strip/render.d.ts +3 -0
  215. package/dist/components/confirm-strip/render.d.ts.map +1 -0
  216. package/dist/components/confirm-strip/render.js +79 -0
  217. package/dist/components/confirm-strip/render.js.map +1 -0
  218. package/dist/components/confirm-strip/runtime.d.ts +3 -0
  219. package/dist/components/confirm-strip/runtime.d.ts.map +1 -0
  220. package/dist/components/confirm-strip/runtime.js +61 -0
  221. package/dist/components/confirm-strip/runtime.js.map +1 -0
  222. package/dist/components/confirm-strip/style.d.ts +13 -0
  223. package/dist/components/confirm-strip/style.d.ts.map +1 -0
  224. package/dist/components/confirm-strip/style.js +302 -0
  225. package/dist/components/confirm-strip/style.js.map +1 -0
  226. package/dist/components/controls/action-bar.d.ts +42 -0
  227. package/dist/components/controls/action-bar.d.ts.map +1 -0
  228. package/dist/components/controls/action-bar.js +216 -0
  229. package/dist/components/controls/action-bar.js.map +1 -0
  230. package/dist/components/controls/bind.d.ts +22 -0
  231. package/dist/components/controls/bind.d.ts.map +1 -0
  232. package/dist/components/controls/bind.js +62 -0
  233. package/dist/components/controls/bind.js.map +1 -0
  234. package/dist/components/controls/copy.d.ts +18 -0
  235. package/dist/components/controls/copy.d.ts.map +1 -0
  236. package/dist/components/controls/copy.js +132 -0
  237. package/dist/components/controls/copy.js.map +1 -0
  238. package/dist/components/controls/helpers-meta.d.ts +87 -0
  239. package/dist/components/controls/helpers-meta.d.ts.map +1 -0
  240. package/dist/components/controls/helpers-meta.js +114 -0
  241. package/dist/components/controls/helpers-meta.js.map +1 -0
  242. package/dist/components/controls/helpers.d.ts +11 -0
  243. package/dist/components/controls/helpers.d.ts.map +1 -0
  244. package/dist/components/controls/helpers.js +630 -0
  245. package/dist/components/controls/helpers.js.map +1 -0
  246. package/dist/components/controls/index.d.ts +13 -0
  247. package/dist/components/controls/index.d.ts.map +1 -0
  248. package/dist/components/controls/index.js +12 -0
  249. package/dist/components/controls/index.js.map +1 -0
  250. package/dist/components/controls/shared.d.ts +23 -0
  251. package/dist/components/controls/shared.d.ts.map +1 -0
  252. package/dist/components/controls/shared.js +48 -0
  253. package/dist/components/controls/shared.js.map +1 -0
  254. package/dist/components/controls/status.d.ts +20 -0
  255. package/dist/components/controls/status.d.ts.map +1 -0
  256. package/dist/components/controls/status.js +84 -0
  257. package/dist/components/controls/status.js.map +1 -0
  258. package/dist/components/controls/toast.d.ts +43 -0
  259. package/dist/components/controls/toast.d.ts.map +1 -0
  260. package/dist/components/controls/toast.js +164 -0
  261. package/dist/components/controls/toast.js.map +1 -0
  262. package/dist/components/date-range/attrs.d.ts +134 -0
  263. package/dist/components/date-range/attrs.d.ts.map +1 -0
  264. package/dist/components/date-range/attrs.js +136 -0
  265. package/dist/components/date-range/attrs.js.map +1 -0
  266. package/dist/components/date-range/index.d.ts +33 -0
  267. package/dist/components/date-range/index.d.ts.map +1 -0
  268. package/dist/components/date-range/index.js +31 -0
  269. package/dist/components/date-range/index.js.map +1 -0
  270. package/dist/components/date-range/model.d.ts +49 -0
  271. package/dist/components/date-range/model.d.ts.map +1 -0
  272. package/dist/components/date-range/model.js +160 -0
  273. package/dist/components/date-range/model.js.map +1 -0
  274. package/dist/components/date-range/render.d.ts +5 -0
  275. package/dist/components/date-range/render.d.ts.map +1 -0
  276. package/dist/components/date-range/render.js +208 -0
  277. package/dist/components/date-range/render.js.map +1 -0
  278. package/dist/components/date-range/runtime.d.ts +3 -0
  279. package/dist/components/date-range/runtime.d.ts.map +1 -0
  280. package/dist/components/date-range/runtime.js +240 -0
  281. package/dist/components/date-range/runtime.js.map +1 -0
  282. package/dist/components/date-range/style-calendar.d.ts +5 -0
  283. package/dist/components/date-range/style-calendar.d.ts.map +1 -0
  284. package/dist/components/date-range/style-calendar.js +144 -0
  285. package/dist/components/date-range/style-calendar.js.map +1 -0
  286. package/dist/components/date-range/style.d.ts +5 -0
  287. package/dist/components/date-range/style.d.ts.map +1 -0
  288. package/dist/components/date-range/style.js +259 -0
  289. package/dist/components/date-range/style.js.map +1 -0
  290. package/dist/components/dialog/attrs.d.ts +100 -0
  291. package/dist/components/dialog/attrs.d.ts.map +1 -0
  292. package/dist/components/dialog/attrs.js +76 -0
  293. package/dist/components/dialog/attrs.js.map +1 -0
  294. package/dist/components/dialog/index.d.ts +34 -0
  295. package/dist/components/dialog/index.d.ts.map +1 -0
  296. package/dist/components/dialog/index.js +32 -0
  297. package/dist/components/dialog/index.js.map +1 -0
  298. package/dist/components/dialog/model.d.ts +32 -0
  299. package/dist/components/dialog/model.d.ts.map +1 -0
  300. package/dist/components/dialog/model.js +109 -0
  301. package/dist/components/dialog/model.js.map +1 -0
  302. package/dist/components/dialog/render.d.ts +5 -0
  303. package/dist/components/dialog/render.d.ts.map +1 -0
  304. package/dist/components/dialog/render.js +96 -0
  305. package/dist/components/dialog/render.js.map +1 -0
  306. package/dist/components/dialog/runtime.d.ts +3 -0
  307. package/dist/components/dialog/runtime.d.ts.map +1 -0
  308. package/dist/components/dialog/runtime.js +73 -0
  309. package/dist/components/dialog/runtime.js.map +1 -0
  310. package/dist/components/dialog/style.d.ts +14 -0
  311. package/dist/components/dialog/style.d.ts.map +1 -0
  312. package/dist/components/dialog/style.js +133 -0
  313. package/dist/components/dialog/style.js.map +1 -0
  314. package/dist/components/drawer-sheet/attrs.d.ts +113 -0
  315. package/dist/components/drawer-sheet/attrs.d.ts.map +1 -0
  316. package/dist/components/drawer-sheet/attrs.js +110 -0
  317. package/dist/components/drawer-sheet/attrs.js.map +1 -0
  318. package/dist/components/drawer-sheet/index.d.ts +35 -0
  319. package/dist/components/drawer-sheet/index.d.ts.map +1 -0
  320. package/dist/components/drawer-sheet/index.js +32 -0
  321. package/dist/components/drawer-sheet/index.js.map +1 -0
  322. package/dist/components/drawer-sheet/model.d.ts +36 -0
  323. package/dist/components/drawer-sheet/model.d.ts.map +1 -0
  324. package/dist/components/drawer-sheet/model.js +118 -0
  325. package/dist/components/drawer-sheet/model.js.map +1 -0
  326. package/dist/components/drawer-sheet/render.d.ts +5 -0
  327. package/dist/components/drawer-sheet/render.d.ts.map +1 -0
  328. package/dist/components/drawer-sheet/render.js +116 -0
  329. package/dist/components/drawer-sheet/render.js.map +1 -0
  330. package/dist/components/drawer-sheet/runtime.d.ts +3 -0
  331. package/dist/components/drawer-sheet/runtime.d.ts.map +1 -0
  332. package/dist/components/drawer-sheet/runtime.js +105 -0
  333. package/dist/components/drawer-sheet/runtime.js.map +1 -0
  334. package/dist/components/drawer-sheet/style.d.ts +8 -0
  335. package/dist/components/drawer-sheet/style.d.ts.map +1 -0
  336. package/dist/components/drawer-sheet/style.js +136 -0
  337. package/dist/components/drawer-sheet/style.js.map +1 -0
  338. package/dist/components/due-row/attrs.d.ts +106 -0
  339. package/dist/components/due-row/attrs.d.ts.map +1 -0
  340. package/dist/components/due-row/attrs.js +75 -0
  341. package/dist/components/due-row/attrs.js.map +1 -0
  342. package/dist/components/due-row/index.d.ts +35 -0
  343. package/dist/components/due-row/index.d.ts.map +1 -0
  344. package/dist/components/due-row/index.js +33 -0
  345. package/dist/components/due-row/index.js.map +1 -0
  346. package/dist/components/due-row/model.d.ts +35 -0
  347. package/dist/components/due-row/model.d.ts.map +1 -0
  348. package/dist/components/due-row/model.js +100 -0
  349. package/dist/components/due-row/model.js.map +1 -0
  350. package/dist/components/due-row/render.d.ts +6 -0
  351. package/dist/components/due-row/render.d.ts.map +1 -0
  352. package/dist/components/due-row/render.js +100 -0
  353. package/dist/components/due-row/render.js.map +1 -0
  354. package/dist/components/due-row/runtime.d.ts +3 -0
  355. package/dist/components/due-row/runtime.d.ts.map +1 -0
  356. package/dist/components/due-row/runtime.js +39 -0
  357. package/dist/components/due-row/runtime.js.map +1 -0
  358. package/dist/components/due-row/style.d.ts +15 -0
  359. package/dist/components/due-row/style.d.ts.map +1 -0
  360. package/dist/components/due-row/style.js +322 -0
  361. package/dist/components/due-row/style.js.map +1 -0
  362. package/dist/components/editable-value/attrs.d.ts +81 -0
  363. package/dist/components/editable-value/attrs.d.ts.map +1 -0
  364. package/dist/components/editable-value/attrs.js +43 -0
  365. package/dist/components/editable-value/attrs.js.map +1 -0
  366. package/dist/components/editable-value/index.d.ts +33 -0
  367. package/dist/components/editable-value/index.d.ts.map +1 -0
  368. package/dist/components/editable-value/index.js +31 -0
  369. package/dist/components/editable-value/index.js.map +1 -0
  370. package/dist/components/editable-value/render.d.ts +4 -0
  371. package/dist/components/editable-value/render.d.ts.map +1 -0
  372. package/dist/components/editable-value/render.js +142 -0
  373. package/dist/components/editable-value/render.js.map +1 -0
  374. package/dist/components/editable-value/runtime.d.ts +3 -0
  375. package/dist/components/editable-value/runtime.d.ts.map +1 -0
  376. package/dist/components/editable-value/runtime.js +178 -0
  377. package/dist/components/editable-value/runtime.js.map +1 -0
  378. package/dist/components/editable-value/style.d.ts +8 -0
  379. package/dist/components/editable-value/style.d.ts.map +1 -0
  380. package/dist/components/editable-value/style.js +55 -0
  381. package/dist/components/editable-value/style.js.map +1 -0
  382. package/dist/components/entry-rows/index.d.ts +11 -0
  383. package/dist/components/entry-rows/index.d.ts.map +1 -0
  384. package/dist/components/entry-rows/index.js +9 -0
  385. package/dist/components/entry-rows/index.js.map +1 -0
  386. package/dist/components/entry-rows/render.d.ts +33 -0
  387. package/dist/components/entry-rows/render.d.ts.map +1 -0
  388. package/dist/components/entry-rows/render.js +64 -0
  389. package/dist/components/entry-rows/render.js.map +1 -0
  390. package/dist/components/entry-rows/style.d.ts +9 -0
  391. package/dist/components/entry-rows/style.d.ts.map +1 -0
  392. package/dist/components/entry-rows/style.js +131 -0
  393. package/dist/components/entry-rows/style.js.map +1 -0
  394. package/dist/components/filter-chips/attrs.d.ts +119 -0
  395. package/dist/components/filter-chips/attrs.d.ts.map +1 -0
  396. package/dist/components/filter-chips/attrs.js +83 -0
  397. package/dist/components/filter-chips/attrs.js.map +1 -0
  398. package/dist/components/filter-chips/index.d.ts +38 -0
  399. package/dist/components/filter-chips/index.d.ts.map +1 -0
  400. package/dist/components/filter-chips/index.js +36 -0
  401. package/dist/components/filter-chips/index.js.map +1 -0
  402. package/dist/components/filter-chips/model.d.ts +30 -0
  403. package/dist/components/filter-chips/model.d.ts.map +1 -0
  404. package/dist/components/filter-chips/model.js +91 -0
  405. package/dist/components/filter-chips/model.js.map +1 -0
  406. package/dist/components/filter-chips/render.d.ts +5 -0
  407. package/dist/components/filter-chips/render.d.ts.map +1 -0
  408. package/dist/components/filter-chips/render.js +91 -0
  409. package/dist/components/filter-chips/render.js.map +1 -0
  410. package/dist/components/filter-chips/runtime.d.ts +3 -0
  411. package/dist/components/filter-chips/runtime.d.ts.map +1 -0
  412. package/dist/components/filter-chips/runtime.js +138 -0
  413. package/dist/components/filter-chips/runtime.js.map +1 -0
  414. package/dist/components/filter-chips/style.d.ts +9 -0
  415. package/dist/components/filter-chips/style.d.ts.map +1 -0
  416. package/dist/components/filter-chips/style.js +116 -0
  417. package/dist/components/filter-chips/style.js.map +1 -0
  418. package/dist/components/flow-ribbon/attrs.d.ts +120 -0
  419. package/dist/components/flow-ribbon/attrs.d.ts.map +1 -0
  420. package/dist/components/flow-ribbon/attrs.js +174 -0
  421. package/dist/components/flow-ribbon/attrs.js.map +1 -0
  422. package/dist/components/flow-ribbon/fields.d.ts +50 -0
  423. package/dist/components/flow-ribbon/fields.d.ts.map +1 -0
  424. package/dist/components/flow-ribbon/fields.js +206 -0
  425. package/dist/components/flow-ribbon/fields.js.map +1 -0
  426. package/dist/components/flow-ribbon/forms.d.ts +127 -0
  427. package/dist/components/flow-ribbon/forms.d.ts.map +1 -0
  428. package/dist/components/flow-ribbon/forms.js +218 -0
  429. package/dist/components/flow-ribbon/forms.js.map +1 -0
  430. package/dist/components/flow-ribbon/index.d.ts +14 -0
  431. package/dist/components/flow-ribbon/index.d.ts.map +1 -0
  432. package/dist/components/flow-ribbon/index.js +13 -0
  433. package/dist/components/flow-ribbon/index.js.map +1 -0
  434. package/dist/components/flow-ribbon/model.d.ts +6 -0
  435. package/dist/components/flow-ribbon/model.d.ts.map +1 -0
  436. package/dist/components/flow-ribbon/model.js +72 -0
  437. package/dist/components/flow-ribbon/model.js.map +1 -0
  438. package/dist/components/flow-ribbon/render.d.ts +3 -0
  439. package/dist/components/flow-ribbon/render.d.ts.map +1 -0
  440. package/dist/components/flow-ribbon/render.js +191 -0
  441. package/dist/components/flow-ribbon/render.js.map +1 -0
  442. package/dist/components/flow-ribbon/style-forms.d.ts +8 -0
  443. package/dist/components/flow-ribbon/style-forms.d.ts.map +1 -0
  444. package/dist/components/flow-ribbon/style-forms.js +255 -0
  445. package/dist/components/flow-ribbon/style-forms.js.map +1 -0
  446. package/dist/components/flow-ribbon/style-rails.d.ts +5 -0
  447. package/dist/components/flow-ribbon/style-rails.d.ts.map +1 -0
  448. package/dist/components/flow-ribbon/style-rails.js +130 -0
  449. package/dist/components/flow-ribbon/style-rails.js.map +1 -0
  450. package/dist/components/flow-ribbon/style.d.ts +5 -0
  451. package/dist/components/flow-ribbon/style.d.ts.map +1 -0
  452. package/dist/components/flow-ribbon/style.js +216 -0
  453. package/dist/components/flow-ribbon/style.js.map +1 -0
  454. package/dist/components/gantt-timeline/attrs.d.ts +145 -0
  455. package/dist/components/gantt-timeline/attrs.d.ts.map +1 -0
  456. package/dist/components/gantt-timeline/attrs.js +120 -0
  457. package/dist/components/gantt-timeline/attrs.js.map +1 -0
  458. package/dist/components/gantt-timeline/index.d.ts +14 -0
  459. package/dist/components/gantt-timeline/index.d.ts.map +1 -0
  460. package/dist/components/gantt-timeline/index.js +12 -0
  461. package/dist/components/gantt-timeline/index.js.map +1 -0
  462. package/dist/components/gantt-timeline/layout.d.ts +112 -0
  463. package/dist/components/gantt-timeline/layout.d.ts.map +1 -0
  464. package/dist/components/gantt-timeline/layout.js +136 -0
  465. package/dist/components/gantt-timeline/layout.js.map +1 -0
  466. package/dist/components/gantt-timeline/model.d.ts +7 -0
  467. package/dist/components/gantt-timeline/model.d.ts.map +1 -0
  468. package/dist/components/gantt-timeline/model.js +222 -0
  469. package/dist/components/gantt-timeline/model.js.map +1 -0
  470. package/dist/components/gantt-timeline/render.d.ts +3 -0
  471. package/dist/components/gantt-timeline/render.d.ts.map +1 -0
  472. package/dist/components/gantt-timeline/render.js +138 -0
  473. package/dist/components/gantt-timeline/render.js.map +1 -0
  474. package/dist/components/gantt-timeline/scale.d.ts +50 -0
  475. package/dist/components/gantt-timeline/scale.d.ts.map +1 -0
  476. package/dist/components/gantt-timeline/scale.js +108 -0
  477. package/dist/components/gantt-timeline/scale.js.map +1 -0
  478. package/dist/components/gantt-timeline/style-marks.d.ts +5 -0
  479. package/dist/components/gantt-timeline/style-marks.d.ts.map +1 -0
  480. package/dist/components/gantt-timeline/style-marks.js +199 -0
  481. package/dist/components/gantt-timeline/style-marks.js.map +1 -0
  482. package/dist/components/gantt-timeline/style.d.ts +22 -0
  483. package/dist/components/gantt-timeline/style.d.ts.map +1 -0
  484. package/dist/components/gantt-timeline/style.js +306 -0
  485. package/dist/components/gantt-timeline/style.js.map +1 -0
  486. package/dist/components/goal-stairs/attrs.d.ts +100 -0
  487. package/dist/components/goal-stairs/attrs.d.ts.map +1 -0
  488. package/dist/components/goal-stairs/attrs.js +101 -0
  489. package/dist/components/goal-stairs/attrs.js.map +1 -0
  490. package/dist/components/goal-stairs/index.d.ts +16 -0
  491. package/dist/components/goal-stairs/index.d.ts.map +1 -0
  492. package/dist/components/goal-stairs/index.js +14 -0
  493. package/dist/components/goal-stairs/index.js.map +1 -0
  494. package/dist/components/goal-stairs/model.d.ts +44 -0
  495. package/dist/components/goal-stairs/model.d.ts.map +1 -0
  496. package/dist/components/goal-stairs/model.js +126 -0
  497. package/dist/components/goal-stairs/model.js.map +1 -0
  498. package/dist/components/goal-stairs/render.d.ts +3 -0
  499. package/dist/components/goal-stairs/render.d.ts.map +1 -0
  500. package/dist/components/goal-stairs/render.js +76 -0
  501. package/dist/components/goal-stairs/render.js.map +1 -0
  502. package/dist/components/goal-stairs/style.d.ts +22 -0
  503. package/dist/components/goal-stairs/style.d.ts.map +1 -0
  504. package/dist/components/goal-stairs/style.js +321 -0
  505. package/dist/components/goal-stairs/style.js.map +1 -0
  506. package/dist/components/heat-grid/attrs.d.ts +72 -0
  507. package/dist/components/heat-grid/attrs.d.ts.map +1 -0
  508. package/dist/components/heat-grid/attrs.js +75 -0
  509. package/dist/components/heat-grid/attrs.js.map +1 -0
  510. package/dist/components/heat-grid/index.d.ts +15 -0
  511. package/dist/components/heat-grid/index.d.ts.map +1 -0
  512. package/dist/components/heat-grid/index.js +13 -0
  513. package/dist/components/heat-grid/index.js.map +1 -0
  514. package/dist/components/heat-grid/model.d.ts +41 -0
  515. package/dist/components/heat-grid/model.d.ts.map +1 -0
  516. package/dist/components/heat-grid/model.js +176 -0
  517. package/dist/components/heat-grid/model.js.map +1 -0
  518. package/dist/components/heat-grid/render.d.ts +3 -0
  519. package/dist/components/heat-grid/render.d.ts.map +1 -0
  520. package/dist/components/heat-grid/render.js +104 -0
  521. package/dist/components/heat-grid/render.js.map +1 -0
  522. package/dist/components/heat-grid/style.d.ts +7 -0
  523. package/dist/components/heat-grid/style.d.ts.map +1 -0
  524. package/dist/components/heat-grid/style.js +269 -0
  525. package/dist/components/heat-grid/style.js.map +1 -0
  526. package/dist/components/help/index.d.ts +8 -0
  527. package/dist/components/help/index.d.ts.map +1 -0
  528. package/dist/components/help/index.js +7 -0
  529. package/dist/components/help/index.js.map +1 -0
  530. package/dist/components/help/render.d.ts +25 -0
  531. package/dist/components/help/render.d.ts.map +1 -0
  532. package/dist/components/help/render.js +246 -0
  533. package/dist/components/help/render.js.map +1 -0
  534. package/dist/components/help/schema.d.ts +12 -0
  535. package/dist/components/help/schema.d.ts.map +1 -0
  536. package/dist/components/help/schema.js +221 -0
  537. package/dist/components/help/schema.js.map +1 -0
  538. package/dist/components/help/shared.d.ts +34 -0
  539. package/dist/components/help/shared.d.ts.map +1 -0
  540. package/dist/components/help/shared.js +56 -0
  541. package/dist/components/help/shared.js.map +1 -0
  542. package/dist/components/help/shell.d.ts +18 -0
  543. package/dist/components/help/shell.d.ts.map +1 -0
  544. package/dist/components/help/shell.js +30 -0
  545. package/dist/components/help/shell.js.map +1 -0
  546. package/dist/components/help/template.d.ts +18 -0
  547. package/dist/components/help/template.d.ts.map +1 -0
  548. package/dist/components/help/template.js +67 -0
  549. package/dist/components/help/template.js.map +1 -0
  550. package/dist/components/hour-band/attrs.d.ts +96 -0
  551. package/dist/components/hour-band/attrs.d.ts.map +1 -0
  552. package/dist/components/hour-band/attrs.js +89 -0
  553. package/dist/components/hour-band/attrs.js.map +1 -0
  554. package/dist/components/hour-band/index.d.ts +17 -0
  555. package/dist/components/hour-band/index.d.ts.map +1 -0
  556. package/dist/components/hour-band/index.js +15 -0
  557. package/dist/components/hour-band/index.js.map +1 -0
  558. package/dist/components/hour-band/model.d.ts +51 -0
  559. package/dist/components/hour-band/model.d.ts.map +1 -0
  560. package/dist/components/hour-band/model.js +149 -0
  561. package/dist/components/hour-band/model.js.map +1 -0
  562. package/dist/components/hour-band/render.d.ts +3 -0
  563. package/dist/components/hour-band/render.d.ts.map +1 -0
  564. package/dist/components/hour-band/render.js +100 -0
  565. package/dist/components/hour-band/render.js.map +1 -0
  566. package/dist/components/hour-band/style.d.ts +9 -0
  567. package/dist/components/hour-band/style.d.ts.map +1 -0
  568. package/dist/components/hour-band/style.js +134 -0
  569. package/dist/components/hour-band/style.js.map +1 -0
  570. package/dist/components/index.d.ts +103 -0
  571. package/dist/components/index.d.ts.map +1 -0
  572. package/dist/components/index.js +171 -0
  573. package/dist/components/index.js.map +1 -0
  574. package/dist/components/invoice-lines/attrs.d.ts +77 -0
  575. package/dist/components/invoice-lines/attrs.d.ts.map +1 -0
  576. package/dist/components/invoice-lines/attrs.js +75 -0
  577. package/dist/components/invoice-lines/attrs.js.map +1 -0
  578. package/dist/components/invoice-lines/index.d.ts +15 -0
  579. package/dist/components/invoice-lines/index.d.ts.map +1 -0
  580. package/dist/components/invoice-lines/index.js +13 -0
  581. package/dist/components/invoice-lines/index.js.map +1 -0
  582. package/dist/components/invoice-lines/model.d.ts +58 -0
  583. package/dist/components/invoice-lines/model.d.ts.map +1 -0
  584. package/dist/components/invoice-lines/model.js +180 -0
  585. package/dist/components/invoice-lines/model.js.map +1 -0
  586. package/dist/components/invoice-lines/render.d.ts +3 -0
  587. package/dist/components/invoice-lines/render.d.ts.map +1 -0
  588. package/dist/components/invoice-lines/render.js +116 -0
  589. package/dist/components/invoice-lines/render.js.map +1 -0
  590. package/dist/components/invoice-lines/style.d.ts +13 -0
  591. package/dist/components/invoice-lines/style.d.ts.map +1 -0
  592. package/dist/components/invoice-lines/style.js +271 -0
  593. package/dist/components/invoice-lines/style.js.map +1 -0
  594. package/dist/components/key-value-list/attrs.d.ts +49 -0
  595. package/dist/components/key-value-list/attrs.d.ts.map +1 -0
  596. package/dist/components/key-value-list/attrs.js +43 -0
  597. package/dist/components/key-value-list/attrs.js.map +1 -0
  598. package/dist/components/key-value-list/index.d.ts +14 -0
  599. package/dist/components/key-value-list/index.d.ts.map +1 -0
  600. package/dist/components/key-value-list/index.js +12 -0
  601. package/dist/components/key-value-list/index.js.map +1 -0
  602. package/dist/components/key-value-list/model.d.ts +16 -0
  603. package/dist/components/key-value-list/model.d.ts.map +1 -0
  604. package/dist/components/key-value-list/model.js +49 -0
  605. package/dist/components/key-value-list/model.js.map +1 -0
  606. package/dist/components/key-value-list/render.d.ts +5 -0
  607. package/dist/components/key-value-list/render.d.ts.map +1 -0
  608. package/dist/components/key-value-list/render.js +61 -0
  609. package/dist/components/key-value-list/render.js.map +1 -0
  610. package/dist/components/key-value-list/style.d.ts +5 -0
  611. package/dist/components/key-value-list/style.d.ts.map +1 -0
  612. package/dist/components/key-value-list/style.js +136 -0
  613. package/dist/components/key-value-list/style.js.map +1 -0
  614. package/dist/components/ledger-rows/index.d.ts +11 -0
  615. package/dist/components/ledger-rows/index.d.ts.map +1 -0
  616. package/dist/components/ledger-rows/index.js +9 -0
  617. package/dist/components/ledger-rows/index.js.map +1 -0
  618. package/dist/components/ledger-rows/render.d.ts +27 -0
  619. package/dist/components/ledger-rows/render.d.ts.map +1 -0
  620. package/dist/components/ledger-rows/render.js +58 -0
  621. package/dist/components/ledger-rows/render.js.map +1 -0
  622. package/dist/components/ledger-rows/style.d.ts +5 -0
  623. package/dist/components/ledger-rows/style.d.ts.map +1 -0
  624. package/dist/components/ledger-rows/style.js +88 -0
  625. package/dist/components/ledger-rows/style.js.map +1 -0
  626. package/dist/components/multi-checks/attrs.d.ts +138 -0
  627. package/dist/components/multi-checks/attrs.d.ts.map +1 -0
  628. package/dist/components/multi-checks/attrs.js +119 -0
  629. package/dist/components/multi-checks/attrs.js.map +1 -0
  630. package/dist/components/multi-checks/index.d.ts +14 -0
  631. package/dist/components/multi-checks/index.d.ts.map +1 -0
  632. package/dist/components/multi-checks/index.js +12 -0
  633. package/dist/components/multi-checks/index.js.map +1 -0
  634. package/dist/components/multi-checks/model.d.ts +63 -0
  635. package/dist/components/multi-checks/model.d.ts.map +1 -0
  636. package/dist/components/multi-checks/model.js +214 -0
  637. package/dist/components/multi-checks/model.js.map +1 -0
  638. package/dist/components/multi-checks/render.d.ts +3 -0
  639. package/dist/components/multi-checks/render.d.ts.map +1 -0
  640. package/dist/components/multi-checks/render.js +228 -0
  641. package/dist/components/multi-checks/render.js.map +1 -0
  642. package/dist/components/multi-checks/runtime.d.ts +19 -0
  643. package/dist/components/multi-checks/runtime.d.ts.map +1 -0
  644. package/dist/components/multi-checks/runtime.js +127 -0
  645. package/dist/components/multi-checks/runtime.js.map +1 -0
  646. package/dist/components/multi-checks/style.d.ts +15 -0
  647. package/dist/components/multi-checks/style.d.ts.map +1 -0
  648. package/dist/components/multi-checks/style.js +380 -0
  649. package/dist/components/multi-checks/style.js.map +1 -0
  650. package/dist/components/note-block/attrs.d.ts +56 -0
  651. package/dist/components/note-block/attrs.d.ts.map +1 -0
  652. package/dist/components/note-block/attrs.js +52 -0
  653. package/dist/components/note-block/attrs.js.map +1 -0
  654. package/dist/components/note-block/index.d.ts +14 -0
  655. package/dist/components/note-block/index.d.ts.map +1 -0
  656. package/dist/components/note-block/index.js +12 -0
  657. package/dist/components/note-block/index.js.map +1 -0
  658. package/dist/components/note-block/model.d.ts +22 -0
  659. package/dist/components/note-block/model.d.ts.map +1 -0
  660. package/dist/components/note-block/model.js +70 -0
  661. package/dist/components/note-block/model.js.map +1 -0
  662. package/dist/components/note-block/render.d.ts +3 -0
  663. package/dist/components/note-block/render.d.ts.map +1 -0
  664. package/dist/components/note-block/render.js +88 -0
  665. package/dist/components/note-block/render.js.map +1 -0
  666. package/dist/components/note-block/style.d.ts +11 -0
  667. package/dist/components/note-block/style.d.ts.map +1 -0
  668. package/dist/components/note-block/style.js +182 -0
  669. package/dist/components/note-block/style.js.map +1 -0
  670. package/dist/components/number-stepper/attrs.d.ts +113 -0
  671. package/dist/components/number-stepper/attrs.d.ts.map +1 -0
  672. package/dist/components/number-stepper/attrs.js +106 -0
  673. package/dist/components/number-stepper/attrs.js.map +1 -0
  674. package/dist/components/number-stepper/index.d.ts +26 -0
  675. package/dist/components/number-stepper/index.d.ts.map +1 -0
  676. package/dist/components/number-stepper/index.js +24 -0
  677. package/dist/components/number-stepper/index.js.map +1 -0
  678. package/dist/components/number-stepper/model.d.ts +25 -0
  679. package/dist/components/number-stepper/model.d.ts.map +1 -0
  680. package/dist/components/number-stepper/model.js +141 -0
  681. package/dist/components/number-stepper/model.js.map +1 -0
  682. package/dist/components/number-stepper/render.d.ts +5 -0
  683. package/dist/components/number-stepper/render.d.ts.map +1 -0
  684. package/dist/components/number-stepper/render.js +176 -0
  685. package/dist/components/number-stepper/render.js.map +1 -0
  686. package/dist/components/number-stepper/runtime.d.ts +3 -0
  687. package/dist/components/number-stepper/runtime.d.ts.map +1 -0
  688. package/dist/components/number-stepper/runtime.js +203 -0
  689. package/dist/components/number-stepper/runtime.js.map +1 -0
  690. package/dist/components/number-stepper/style.d.ts +5 -0
  691. package/dist/components/number-stepper/style.d.ts.map +1 -0
  692. package/dist/components/number-stepper/style.js +309 -0
  693. package/dist/components/number-stepper/style.js.map +1 -0
  694. package/dist/components/page/fact-strip.d.ts +36 -0
  695. package/dist/components/page/fact-strip.d.ts.map +1 -0
  696. package/dist/components/page/fact-strip.js +91 -0
  697. package/dist/components/page/fact-strip.js.map +1 -0
  698. package/dist/components/page/index.d.ts +13 -0
  699. package/dist/components/page/index.d.ts.map +1 -0
  700. package/dist/components/page/index.js +12 -0
  701. package/dist/components/page/index.js.map +1 -0
  702. package/dist/components/page/media.d.ts +67 -0
  703. package/dist/components/page/media.d.ts.map +1 -0
  704. package/dist/components/page/media.js +191 -0
  705. package/dist/components/page/media.js.map +1 -0
  706. package/dist/components/page/shared.d.ts +12 -0
  707. package/dist/components/page/shared.d.ts.map +1 -0
  708. package/dist/components/page/shared.js +34 -0
  709. package/dist/components/page/shared.js.map +1 -0
  710. package/dist/components/page/style.d.ts +5 -0
  711. package/dist/components/page/style.d.ts.map +1 -0
  712. package/dist/components/page/style.js +28 -0
  713. package/dist/components/page/style.js.map +1 -0
  714. package/dist/components/page/timeline.d.ts +25 -0
  715. package/dist/components/page/timeline.d.ts.map +1 -0
  716. package/dist/components/page/timeline.js +79 -0
  717. package/dist/components/page/timeline.js.map +1 -0
  718. package/dist/components/page-bars/index.d.ts +98 -0
  719. package/dist/components/page-bars/index.d.ts.map +1 -0
  720. package/dist/components/page-bars/index.js +180 -0
  721. package/dist/components/page-bars/index.js.map +1 -0
  722. package/dist/components/page-bars/style.d.ts +14 -0
  723. package/dist/components/page-bars/style.d.ts.map +1 -0
  724. package/dist/components/page-bars/style.js +231 -0
  725. package/dist/components/page-bars/style.js.map +1 -0
  726. package/dist/components/page-head/attrs.d.ts +57 -0
  727. package/dist/components/page-head/attrs.d.ts.map +1 -0
  728. package/dist/components/page-head/attrs.js +53 -0
  729. package/dist/components/page-head/attrs.js.map +1 -0
  730. package/dist/components/page-head/index.d.ts +13 -0
  731. package/dist/components/page-head/index.d.ts.map +1 -0
  732. package/dist/components/page-head/index.js +11 -0
  733. package/dist/components/page-head/index.js.map +1 -0
  734. package/dist/components/page-head/model.d.ts +23 -0
  735. package/dist/components/page-head/model.d.ts.map +1 -0
  736. package/dist/components/page-head/model.js +77 -0
  737. package/dist/components/page-head/model.js.map +1 -0
  738. package/dist/components/page-head/render.d.ts +3 -0
  739. package/dist/components/page-head/render.d.ts.map +1 -0
  740. package/dist/components/page-head/render.js +84 -0
  741. package/dist/components/page-head/render.js.map +1 -0
  742. package/dist/components/page-head/style.d.ts +9 -0
  743. package/dist/components/page-head/style.d.ts.map +1 -0
  744. package/dist/components/page-head/style.js +245 -0
  745. package/dist/components/page-head/style.js.map +1 -0
  746. package/dist/components/page-nav/index.d.ts +55 -0
  747. package/dist/components/page-nav/index.d.ts.map +1 -0
  748. package/dist/components/page-nav/index.js +125 -0
  749. package/dist/components/page-nav/index.js.map +1 -0
  750. package/dist/components/page-nav/style.d.ts +23 -0
  751. package/dist/components/page-nav/style.d.ts.map +1 -0
  752. package/dist/components/page-nav/style.js +93 -0
  753. package/dist/components/page-nav/style.js.map +1 -0
  754. package/dist/components/page-ui/index.d.ts +67 -0
  755. package/dist/components/page-ui/index.d.ts.map +1 -0
  756. package/dist/components/page-ui/index.js +394 -0
  757. package/dist/components/page-ui/index.js.map +1 -0
  758. package/dist/components/page-ui/toast.d.ts +16 -0
  759. package/dist/components/page-ui/toast.d.ts.map +1 -0
  760. package/dist/components/page-ui/toast.js +47 -0
  761. package/dist/components/page-ui/toast.js.map +1 -0
  762. package/dist/components/photo-compare/attrs.d.ts +84 -0
  763. package/dist/components/photo-compare/attrs.d.ts.map +1 -0
  764. package/dist/components/photo-compare/attrs.js +86 -0
  765. package/dist/components/photo-compare/attrs.js.map +1 -0
  766. package/dist/components/photo-compare/index.d.ts +16 -0
  767. package/dist/components/photo-compare/index.d.ts.map +1 -0
  768. package/dist/components/photo-compare/index.js +14 -0
  769. package/dist/components/photo-compare/index.js.map +1 -0
  770. package/dist/components/photo-compare/model.d.ts +38 -0
  771. package/dist/components/photo-compare/model.d.ts.map +1 -0
  772. package/dist/components/photo-compare/model.js +87 -0
  773. package/dist/components/photo-compare/model.js.map +1 -0
  774. package/dist/components/photo-compare/render.d.ts +3 -0
  775. package/dist/components/photo-compare/render.d.ts.map +1 -0
  776. package/dist/components/photo-compare/render.js +98 -0
  777. package/dist/components/photo-compare/render.js.map +1 -0
  778. package/dist/components/photo-compare/runtime.d.ts +3 -0
  779. package/dist/components/photo-compare/runtime.d.ts.map +1 -0
  780. package/dist/components/photo-compare/runtime.js +39 -0
  781. package/dist/components/photo-compare/runtime.js.map +1 -0
  782. package/dist/components/photo-compare/style.d.ts +14 -0
  783. package/dist/components/photo-compare/style.d.ts.map +1 -0
  784. package/dist/components/photo-compare/style.js +396 -0
  785. package/dist/components/photo-compare/style.js.map +1 -0
  786. package/dist/components/photo-grid/attrs.d.ts +78 -0
  787. package/dist/components/photo-grid/attrs.d.ts.map +1 -0
  788. package/dist/components/photo-grid/attrs.js +78 -0
  789. package/dist/components/photo-grid/attrs.js.map +1 -0
  790. package/dist/components/photo-grid/index.d.ts +13 -0
  791. package/dist/components/photo-grid/index.d.ts.map +1 -0
  792. package/dist/components/photo-grid/index.js +11 -0
  793. package/dist/components/photo-grid/index.js.map +1 -0
  794. package/dist/components/photo-grid/model.d.ts +35 -0
  795. package/dist/components/photo-grid/model.d.ts.map +1 -0
  796. package/dist/components/photo-grid/model.js +123 -0
  797. package/dist/components/photo-grid/model.js.map +1 -0
  798. package/dist/components/photo-grid/render.d.ts +3 -0
  799. package/dist/components/photo-grid/render.d.ts.map +1 -0
  800. package/dist/components/photo-grid/render.js +116 -0
  801. package/dist/components/photo-grid/render.js.map +1 -0
  802. package/dist/components/photo-grid/style.d.ts +17 -0
  803. package/dist/components/photo-grid/style.d.ts.map +1 -0
  804. package/dist/components/photo-grid/style.js +110 -0
  805. package/dist/components/photo-grid/style.js.map +1 -0
  806. package/dist/components/popover-menu/attrs.d.ts +98 -0
  807. package/dist/components/popover-menu/attrs.d.ts.map +1 -0
  808. package/dist/components/popover-menu/attrs.js +81 -0
  809. package/dist/components/popover-menu/attrs.js.map +1 -0
  810. package/dist/components/popover-menu/index.d.ts +33 -0
  811. package/dist/components/popover-menu/index.d.ts.map +1 -0
  812. package/dist/components/popover-menu/index.js +30 -0
  813. package/dist/components/popover-menu/index.js.map +1 -0
  814. package/dist/components/popover-menu/model.d.ts +26 -0
  815. package/dist/components/popover-menu/model.d.ts.map +1 -0
  816. package/dist/components/popover-menu/model.js +79 -0
  817. package/dist/components/popover-menu/model.js.map +1 -0
  818. package/dist/components/popover-menu/render.d.ts +3 -0
  819. package/dist/components/popover-menu/render.d.ts.map +1 -0
  820. package/dist/components/popover-menu/render.js +84 -0
  821. package/dist/components/popover-menu/render.js.map +1 -0
  822. package/dist/components/popover-menu/runtime.d.ts +3 -0
  823. package/dist/components/popover-menu/runtime.d.ts.map +1 -0
  824. package/dist/components/popover-menu/runtime.js +107 -0
  825. package/dist/components/popover-menu/runtime.js.map +1 -0
  826. package/dist/components/popover-menu/style.d.ts +8 -0
  827. package/dist/components/popover-menu/style.d.ts.map +1 -0
  828. package/dist/components/popover-menu/style.js +92 -0
  829. package/dist/components/popover-menu/style.js.map +1 -0
  830. package/dist/components/progress-list/attrs.d.ts +77 -0
  831. package/dist/components/progress-list/attrs.d.ts.map +1 -0
  832. package/dist/components/progress-list/attrs.js +72 -0
  833. package/dist/components/progress-list/attrs.js.map +1 -0
  834. package/dist/components/progress-list/index.d.ts +16 -0
  835. package/dist/components/progress-list/index.d.ts.map +1 -0
  836. package/dist/components/progress-list/index.js +14 -0
  837. package/dist/components/progress-list/index.js.map +1 -0
  838. package/dist/components/progress-list/model.d.ts +34 -0
  839. package/dist/components/progress-list/model.d.ts.map +1 -0
  840. package/dist/components/progress-list/model.js +132 -0
  841. package/dist/components/progress-list/model.js.map +1 -0
  842. package/dist/components/progress-list/render.d.ts +3 -0
  843. package/dist/components/progress-list/render.d.ts.map +1 -0
  844. package/dist/components/progress-list/render.js +84 -0
  845. package/dist/components/progress-list/render.js.map +1 -0
  846. package/dist/components/progress-list/style.d.ts +10 -0
  847. package/dist/components/progress-list/style.d.ts.map +1 -0
  848. package/dist/components/progress-list/style.js +207 -0
  849. package/dist/components/progress-list/style.js.map +1 -0
  850. package/dist/components/progress-ring/attrs.d.ts +59 -0
  851. package/dist/components/progress-ring/attrs.d.ts.map +1 -0
  852. package/dist/components/progress-ring/attrs.js +65 -0
  853. package/dist/components/progress-ring/attrs.js.map +1 -0
  854. package/dist/components/progress-ring/index.d.ts +13 -0
  855. package/dist/components/progress-ring/index.d.ts.map +1 -0
  856. package/dist/components/progress-ring/index.js +11 -0
  857. package/dist/components/progress-ring/index.js.map +1 -0
  858. package/dist/components/progress-ring/model.d.ts +32 -0
  859. package/dist/components/progress-ring/model.d.ts.map +1 -0
  860. package/dist/components/progress-ring/model.js +113 -0
  861. package/dist/components/progress-ring/model.js.map +1 -0
  862. package/dist/components/progress-ring/render.d.ts +3 -0
  863. package/dist/components/progress-ring/render.d.ts.map +1 -0
  864. package/dist/components/progress-ring/render.js +91 -0
  865. package/dist/components/progress-ring/render.js.map +1 -0
  866. package/dist/components/progress-ring/style.d.ts +9 -0
  867. package/dist/components/progress-ring/style.d.ts.map +1 -0
  868. package/dist/components/progress-ring/style.js +230 -0
  869. package/dist/components/progress-ring/style.js.map +1 -0
  870. package/dist/components/punch-strip/index.d.ts +12 -0
  871. package/dist/components/punch-strip/index.d.ts.map +1 -0
  872. package/dist/components/punch-strip/index.js +10 -0
  873. package/dist/components/punch-strip/index.js.map +1 -0
  874. package/dist/components/punch-strip/render.d.ts +24 -0
  875. package/dist/components/punch-strip/render.d.ts.map +1 -0
  876. package/dist/components/punch-strip/render.js +63 -0
  877. package/dist/components/punch-strip/render.js.map +1 -0
  878. package/dist/components/punch-strip/style.d.ts +8 -0
  879. package/dist/components/punch-strip/style.d.ts.map +1 -0
  880. package/dist/components/punch-strip/style.js +94 -0
  881. package/dist/components/punch-strip/style.js.map +1 -0
  882. package/dist/components/radar-profile/attrs.d.ts +110 -0
  883. package/dist/components/radar-profile/attrs.d.ts.map +1 -0
  884. package/dist/components/radar-profile/attrs.js +179 -0
  885. package/dist/components/radar-profile/attrs.js.map +1 -0
  886. package/dist/components/radar-profile/forms.d.ts +146 -0
  887. package/dist/components/radar-profile/forms.d.ts.map +1 -0
  888. package/dist/components/radar-profile/forms.js +258 -0
  889. package/dist/components/radar-profile/forms.js.map +1 -0
  890. package/dist/components/radar-profile/index.d.ts +13 -0
  891. package/dist/components/radar-profile/index.d.ts.map +1 -0
  892. package/dist/components/radar-profile/index.js +12 -0
  893. package/dist/components/radar-profile/index.js.map +1 -0
  894. package/dist/components/radar-profile/model.d.ts +5 -0
  895. package/dist/components/radar-profile/model.d.ts.map +1 -0
  896. package/dist/components/radar-profile/model.js +156 -0
  897. package/dist/components/radar-profile/model.js.map +1 -0
  898. package/dist/components/radar-profile/render.d.ts +3 -0
  899. package/dist/components/radar-profile/render.d.ts.map +1 -0
  900. package/dist/components/radar-profile/render.js +193 -0
  901. package/dist/components/radar-profile/render.js.map +1 -0
  902. package/dist/components/radar-profile/scale.d.ts +65 -0
  903. package/dist/components/radar-profile/scale.d.ts.map +1 -0
  904. package/dist/components/radar-profile/scale.js +132 -0
  905. package/dist/components/radar-profile/scale.js.map +1 -0
  906. package/dist/components/radar-profile/style-forms.d.ts +5 -0
  907. package/dist/components/radar-profile/style-forms.d.ts.map +1 -0
  908. package/dist/components/radar-profile/style-forms.js +192 -0
  909. package/dist/components/radar-profile/style-forms.js.map +1 -0
  910. package/dist/components/radar-profile/style.d.ts +5 -0
  911. package/dist/components/radar-profile/style.d.ts.map +1 -0
  912. package/dist/components/radar-profile/style.js +471 -0
  913. package/dist/components/radar-profile/style.js.map +1 -0
  914. package/dist/components/radio-cards/attrs.d.ts +99 -0
  915. package/dist/components/radio-cards/attrs.d.ts.map +1 -0
  916. package/dist/components/radio-cards/attrs.js +85 -0
  917. package/dist/components/radio-cards/attrs.js.map +1 -0
  918. package/dist/components/radio-cards/index.d.ts +14 -0
  919. package/dist/components/radio-cards/index.d.ts.map +1 -0
  920. package/dist/components/radio-cards/index.js +12 -0
  921. package/dist/components/radio-cards/index.js.map +1 -0
  922. package/dist/components/radio-cards/model.d.ts +33 -0
  923. package/dist/components/radio-cards/model.d.ts.map +1 -0
  924. package/dist/components/radio-cards/model.js +104 -0
  925. package/dist/components/radio-cards/model.js.map +1 -0
  926. package/dist/components/radio-cards/render.d.ts +3 -0
  927. package/dist/components/radio-cards/render.d.ts.map +1 -0
  928. package/dist/components/radio-cards/render.js +138 -0
  929. package/dist/components/radio-cards/render.js.map +1 -0
  930. package/dist/components/radio-cards/runtime.d.ts +17 -0
  931. package/dist/components/radio-cards/runtime.d.ts.map +1 -0
  932. package/dist/components/radio-cards/runtime.js +54 -0
  933. package/dist/components/radio-cards/runtime.js.map +1 -0
  934. package/dist/components/radio-cards/style.d.ts +17 -0
  935. package/dist/components/radio-cards/style.d.ts.map +1 -0
  936. package/dist/components/radio-cards/style.js +284 -0
  937. package/dist/components/radio-cards/style.js.map +1 -0
  938. package/dist/components/range-bar/attrs.d.ts +96 -0
  939. package/dist/components/range-bar/attrs.d.ts.map +1 -0
  940. package/dist/components/range-bar/attrs.js +71 -0
  941. package/dist/components/range-bar/attrs.js.map +1 -0
  942. package/dist/components/range-bar/index.d.ts +13 -0
  943. package/dist/components/range-bar/index.d.ts.map +1 -0
  944. package/dist/components/range-bar/index.js +11 -0
  945. package/dist/components/range-bar/index.js.map +1 -0
  946. package/dist/components/range-bar/model.d.ts +39 -0
  947. package/dist/components/range-bar/model.d.ts.map +1 -0
  948. package/dist/components/range-bar/model.js +139 -0
  949. package/dist/components/range-bar/model.js.map +1 -0
  950. package/dist/components/range-bar/render.d.ts +3 -0
  951. package/dist/components/range-bar/render.d.ts.map +1 -0
  952. package/dist/components/range-bar/render.js +86 -0
  953. package/dist/components/range-bar/render.js.map +1 -0
  954. package/dist/components/range-bar/style.d.ts +15 -0
  955. package/dist/components/range-bar/style.d.ts.map +1 -0
  956. package/dist/components/range-bar/style.js +210 -0
  957. package/dist/components/range-bar/style.js.map +1 -0
  958. package/dist/components/rank-list/attrs.d.ts +55 -0
  959. package/dist/components/rank-list/attrs.d.ts.map +1 -0
  960. package/dist/components/rank-list/attrs.js +61 -0
  961. package/dist/components/rank-list/attrs.js.map +1 -0
  962. package/dist/components/rank-list/index.d.ts +14 -0
  963. package/dist/components/rank-list/index.d.ts.map +1 -0
  964. package/dist/components/rank-list/index.js +12 -0
  965. package/dist/components/rank-list/index.js.map +1 -0
  966. package/dist/components/rank-list/model.d.ts +30 -0
  967. package/dist/components/rank-list/model.d.ts.map +1 -0
  968. package/dist/components/rank-list/model.js +102 -0
  969. package/dist/components/rank-list/model.js.map +1 -0
  970. package/dist/components/rank-list/render.d.ts +4 -0
  971. package/dist/components/rank-list/render.d.ts.map +1 -0
  972. package/dist/components/rank-list/render.js +83 -0
  973. package/dist/components/rank-list/render.js.map +1 -0
  974. package/dist/components/rank-list/style.d.ts +15 -0
  975. package/dist/components/rank-list/style.d.ts.map +1 -0
  976. package/dist/components/rank-list/style.js +247 -0
  977. package/dist/components/rank-list/style.js.map +1 -0
  978. package/dist/components/rating-row/attrs.d.ts +94 -0
  979. package/dist/components/rating-row/attrs.d.ts.map +1 -0
  980. package/dist/components/rating-row/attrs.js +90 -0
  981. package/dist/components/rating-row/attrs.js.map +1 -0
  982. package/dist/components/rating-row/index.d.ts +14 -0
  983. package/dist/components/rating-row/index.d.ts.map +1 -0
  984. package/dist/components/rating-row/index.js +12 -0
  985. package/dist/components/rating-row/index.js.map +1 -0
  986. package/dist/components/rating-row/model.d.ts +28 -0
  987. package/dist/components/rating-row/model.d.ts.map +1 -0
  988. package/dist/components/rating-row/model.js +99 -0
  989. package/dist/components/rating-row/model.js.map +1 -0
  990. package/dist/components/rating-row/render.d.ts +3 -0
  991. package/dist/components/rating-row/render.d.ts.map +1 -0
  992. package/dist/components/rating-row/render.js +122 -0
  993. package/dist/components/rating-row/render.js.map +1 -0
  994. package/dist/components/rating-row/runtime.d.ts +18 -0
  995. package/dist/components/rating-row/runtime.d.ts.map +1 -0
  996. package/dist/components/rating-row/runtime.js +92 -0
  997. package/dist/components/rating-row/runtime.js.map +1 -0
  998. package/dist/components/rating-row/style.d.ts +13 -0
  999. package/dist/components/rating-row/style.d.ts.map +1 -0
  1000. package/dist/components/rating-row/style.js +234 -0
  1001. package/dist/components/rating-row/style.js.map +1 -0
  1002. package/dist/components/result-row/attrs.d.ts +50 -0
  1003. package/dist/components/result-row/attrs.d.ts.map +1 -0
  1004. package/dist/components/result-row/attrs.js +31 -0
  1005. package/dist/components/result-row/attrs.js.map +1 -0
  1006. package/dist/components/result-row/index.d.ts +29 -0
  1007. package/dist/components/result-row/index.d.ts.map +1 -0
  1008. package/dist/components/result-row/index.js +27 -0
  1009. package/dist/components/result-row/index.js.map +1 -0
  1010. package/dist/components/result-row/model.d.ts +22 -0
  1011. package/dist/components/result-row/model.d.ts.map +1 -0
  1012. package/dist/components/result-row/model.js +53 -0
  1013. package/dist/components/result-row/model.js.map +1 -0
  1014. package/dist/components/result-row/render.d.ts +5 -0
  1015. package/dist/components/result-row/render.d.ts.map +1 -0
  1016. package/dist/components/result-row/render.js +87 -0
  1017. package/dist/components/result-row/render.js.map +1 -0
  1018. package/dist/components/result-row/style.d.ts +11 -0
  1019. package/dist/components/result-row/style.d.ts.map +1 -0
  1020. package/dist/components/result-row/style.js +67 -0
  1021. package/dist/components/result-row/style.js.map +1 -0
  1022. package/dist/components/scale-bar/index.d.ts +11 -0
  1023. package/dist/components/scale-bar/index.d.ts.map +1 -0
  1024. package/dist/components/scale-bar/index.js +9 -0
  1025. package/dist/components/scale-bar/index.js.map +1 -0
  1026. package/dist/components/scale-bar/render.d.ts +23 -0
  1027. package/dist/components/scale-bar/render.d.ts.map +1 -0
  1028. package/dist/components/scale-bar/render.js +79 -0
  1029. package/dist/components/scale-bar/render.js.map +1 -0
  1030. package/dist/components/scale-bar/style.d.ts +8 -0
  1031. package/dist/components/scale-bar/style.d.ts.map +1 -0
  1032. package/dist/components/scale-bar/style.js +86 -0
  1033. package/dist/components/scale-bar/style.js.map +1 -0
  1034. package/dist/components/scatter-fit/attrs.d.ts +106 -0
  1035. package/dist/components/scatter-fit/attrs.d.ts.map +1 -0
  1036. package/dist/components/scatter-fit/attrs.js +112 -0
  1037. package/dist/components/scatter-fit/attrs.js.map +1 -0
  1038. package/dist/components/scatter-fit/forms.d.ts +86 -0
  1039. package/dist/components/scatter-fit/forms.d.ts.map +1 -0
  1040. package/dist/components/scatter-fit/forms.js +149 -0
  1041. package/dist/components/scatter-fit/forms.js.map +1 -0
  1042. package/dist/components/scatter-fit/index.d.ts +13 -0
  1043. package/dist/components/scatter-fit/index.d.ts.map +1 -0
  1044. package/dist/components/scatter-fit/index.js +11 -0
  1045. package/dist/components/scatter-fit/index.js.map +1 -0
  1046. package/dist/components/scatter-fit/model.d.ts +5 -0
  1047. package/dist/components/scatter-fit/model.d.ts.map +1 -0
  1048. package/dist/components/scatter-fit/model.js +146 -0
  1049. package/dist/components/scatter-fit/model.js.map +1 -0
  1050. package/dist/components/scatter-fit/render.d.ts +3 -0
  1051. package/dist/components/scatter-fit/render.d.ts.map +1 -0
  1052. package/dist/components/scatter-fit/render.js +140 -0
  1053. package/dist/components/scatter-fit/render.js.map +1 -0
  1054. package/dist/components/scatter-fit/scale.d.ts +60 -0
  1055. package/dist/components/scatter-fit/scale.d.ts.map +1 -0
  1056. package/dist/components/scatter-fit/scale.js +193 -0
  1057. package/dist/components/scatter-fit/scale.js.map +1 -0
  1058. package/dist/components/scatter-fit/style-forms.d.ts +7 -0
  1059. package/dist/components/scatter-fit/style-forms.d.ts.map +1 -0
  1060. package/dist/components/scatter-fit/style-forms.js +168 -0
  1061. package/dist/components/scatter-fit/style-forms.js.map +1 -0
  1062. package/dist/components/scatter-fit/style.d.ts +8 -0
  1063. package/dist/components/scatter-fit/style.d.ts.map +1 -0
  1064. package/dist/components/scatter-fit/style.js +272 -0
  1065. package/dist/components/scatter-fit/style.js.map +1 -0
  1066. package/dist/components/search-field/attrs.d.ts +136 -0
  1067. package/dist/components/search-field/attrs.d.ts.map +1 -0
  1068. package/dist/components/search-field/attrs.js +98 -0
  1069. package/dist/components/search-field/attrs.js.map +1 -0
  1070. package/dist/components/search-field/index.d.ts +39 -0
  1071. package/dist/components/search-field/index.d.ts.map +1 -0
  1072. package/dist/components/search-field/index.js +37 -0
  1073. package/dist/components/search-field/index.js.map +1 -0
  1074. package/dist/components/search-field/model.d.ts +27 -0
  1075. package/dist/components/search-field/model.d.ts.map +1 -0
  1076. package/dist/components/search-field/model.js +92 -0
  1077. package/dist/components/search-field/model.js.map +1 -0
  1078. package/dist/components/search-field/render.d.ts +7 -0
  1079. package/dist/components/search-field/render.d.ts.map +1 -0
  1080. package/dist/components/search-field/render.js +107 -0
  1081. package/dist/components/search-field/render.js.map +1 -0
  1082. package/dist/components/search-field/runtime.d.ts +3 -0
  1083. package/dist/components/search-field/runtime.d.ts.map +1 -0
  1084. package/dist/components/search-field/runtime.js +299 -0
  1085. package/dist/components/search-field/runtime.js.map +1 -0
  1086. package/dist/components/search-field/style.d.ts +9 -0
  1087. package/dist/components/search-field/style.d.ts.map +1 -0
  1088. package/dist/components/search-field/style.js +113 -0
  1089. package/dist/components/search-field/style.js.map +1 -0
  1090. package/dist/components/section-head/attrs.d.ts +53 -0
  1091. package/dist/components/section-head/attrs.d.ts.map +1 -0
  1092. package/dist/components/section-head/attrs.js +45 -0
  1093. package/dist/components/section-head/attrs.js.map +1 -0
  1094. package/dist/components/section-head/index.d.ts +14 -0
  1095. package/dist/components/section-head/index.d.ts.map +1 -0
  1096. package/dist/components/section-head/index.js +12 -0
  1097. package/dist/components/section-head/index.js.map +1 -0
  1098. package/dist/components/section-head/model.d.ts +16 -0
  1099. package/dist/components/section-head/model.d.ts.map +1 -0
  1100. package/dist/components/section-head/model.js +61 -0
  1101. package/dist/components/section-head/model.js.map +1 -0
  1102. package/dist/components/section-head/render.d.ts +6 -0
  1103. package/dist/components/section-head/render.d.ts.map +1 -0
  1104. package/dist/components/section-head/render.js +68 -0
  1105. package/dist/components/section-head/render.js.map +1 -0
  1106. package/dist/components/section-head/style.d.ts +7 -0
  1107. package/dist/components/section-head/style.d.ts.map +1 -0
  1108. package/dist/components/section-head/style.js +172 -0
  1109. package/dist/components/section-head/style.js.map +1 -0
  1110. package/dist/components/shared/escape.d.ts +3 -0
  1111. package/dist/components/shared/escape.d.ts.map +1 -0
  1112. package/dist/components/shared/escape.js +11 -0
  1113. package/dist/components/shared/escape.js.map +1 -0
  1114. package/dist/components/shared/typography.d.ts +32 -0
  1115. package/dist/components/shared/typography.d.ts.map +1 -0
  1116. package/dist/components/shared/typography.js +31 -0
  1117. package/dist/components/shared/typography.js.map +1 -0
  1118. package/dist/components/shared/validate.d.ts +26 -0
  1119. package/dist/components/shared/validate.d.ts.map +1 -0
  1120. package/dist/components/shared/validate.js +75 -0
  1121. package/dist/components/shared/validate.js.map +1 -0
  1122. package/dist/components/sheet-frame/index.d.ts +14 -0
  1123. package/dist/components/sheet-frame/index.d.ts.map +1 -0
  1124. package/dist/components/sheet-frame/index.js +12 -0
  1125. package/dist/components/sheet-frame/index.js.map +1 -0
  1126. package/dist/components/sheet-frame/render.d.ts +21 -0
  1127. package/dist/components/sheet-frame/render.d.ts.map +1 -0
  1128. package/dist/components/sheet-frame/render.js +45 -0
  1129. package/dist/components/sheet-frame/render.js.map +1 -0
  1130. package/dist/components/sheet-frame/style.d.ts +14 -0
  1131. package/dist/components/sheet-frame/style.d.ts.map +1 -0
  1132. package/dist/components/sheet-frame/style.js +105 -0
  1133. package/dist/components/sheet-frame/style.js.map +1 -0
  1134. package/dist/components/skeleton/attrs.d.ts +47 -0
  1135. package/dist/components/skeleton/attrs.d.ts.map +1 -0
  1136. package/dist/components/skeleton/attrs.js +62 -0
  1137. package/dist/components/skeleton/attrs.js.map +1 -0
  1138. package/dist/components/skeleton/index.d.ts +25 -0
  1139. package/dist/components/skeleton/index.d.ts.map +1 -0
  1140. package/dist/components/skeleton/index.js +23 -0
  1141. package/dist/components/skeleton/index.js.map +1 -0
  1142. package/dist/components/skeleton/model.d.ts +15 -0
  1143. package/dist/components/skeleton/model.d.ts.map +1 -0
  1144. package/dist/components/skeleton/model.js +34 -0
  1145. package/dist/components/skeleton/model.js.map +1 -0
  1146. package/dist/components/skeleton/render.d.ts +3 -0
  1147. package/dist/components/skeleton/render.d.ts.map +1 -0
  1148. package/dist/components/skeleton/render.js +60 -0
  1149. package/dist/components/skeleton/render.js.map +1 -0
  1150. package/dist/components/skeleton/style.d.ts +27 -0
  1151. package/dist/components/skeleton/style.d.ts.map +1 -0
  1152. package/dist/components/skeleton/style.js +223 -0
  1153. package/dist/components/skeleton/style.js.map +1 -0
  1154. package/dist/components/skin/contract.d.ts +177 -0
  1155. package/dist/components/skin/contract.d.ts.map +1 -0
  1156. package/dist/components/skin/contract.js +89 -0
  1157. package/dist/components/skin/contract.js.map +1 -0
  1158. package/dist/components/skin/index.d.ts +29 -0
  1159. package/dist/components/skin/index.d.ts.map +1 -0
  1160. package/dist/components/skin/index.js +75 -0
  1161. package/dist/components/skin/index.js.map +1 -0
  1162. package/dist/components/skin/skins/blueprint.d.ts +40 -0
  1163. package/dist/components/skin/skins/blueprint.d.ts.map +1 -0
  1164. package/dist/components/skin/skins/blueprint.js +47 -0
  1165. package/dist/components/skin/skins/blueprint.js.map +1 -0
  1166. package/dist/components/skin/skins/broadsheet.d.ts +38 -0
  1167. package/dist/components/skin/skins/broadsheet.d.ts.map +1 -0
  1168. package/dist/components/skin/skins/broadsheet.js +44 -0
  1169. package/dist/components/skin/skins/broadsheet.js.map +1 -0
  1170. package/dist/components/skin/skins/ink.d.ts +40 -0
  1171. package/dist/components/skin/skins/ink.d.ts.map +1 -0
  1172. package/dist/components/skin/skins/ink.js +59 -0
  1173. package/dist/components/skin/skins/ink.js.map +1 -0
  1174. package/dist/components/skin/skins/neutral.d.ts +38 -0
  1175. package/dist/components/skin/skins/neutral.d.ts.map +1 -0
  1176. package/dist/components/skin/skins/neutral.js +46 -0
  1177. package/dist/components/skin/skins/neutral.js.map +1 -0
  1178. package/dist/components/skin/skins/paper.d.ts +40 -0
  1179. package/dist/components/skin/skins/paper.d.ts.map +1 -0
  1180. package/dist/components/skin/skins/paper.js +57 -0
  1181. package/dist/components/skin/skins/paper.js.map +1 -0
  1182. package/dist/components/skin/skins/terminal.d.ts +40 -0
  1183. package/dist/components/skin/skins/terminal.d.ts.map +1 -0
  1184. package/dist/components/skin/skins/terminal.js +53 -0
  1185. package/dist/components/skin/skins/terminal.js.map +1 -0
  1186. package/dist/components/slider-row/attrs.d.ts +115 -0
  1187. package/dist/components/slider-row/attrs.d.ts.map +1 -0
  1188. package/dist/components/slider-row/attrs.js +113 -0
  1189. package/dist/components/slider-row/attrs.js.map +1 -0
  1190. package/dist/components/slider-row/index.d.ts +28 -0
  1191. package/dist/components/slider-row/index.d.ts.map +1 -0
  1192. package/dist/components/slider-row/index.js +26 -0
  1193. package/dist/components/slider-row/index.js.map +1 -0
  1194. package/dist/components/slider-row/model.d.ts +25 -0
  1195. package/dist/components/slider-row/model.d.ts.map +1 -0
  1196. package/dist/components/slider-row/model.js +136 -0
  1197. package/dist/components/slider-row/model.js.map +1 -0
  1198. package/dist/components/slider-row/render.d.ts +7 -0
  1199. package/dist/components/slider-row/render.d.ts.map +1 -0
  1200. package/dist/components/slider-row/render.js +183 -0
  1201. package/dist/components/slider-row/render.js.map +1 -0
  1202. package/dist/components/slider-row/runtime.d.ts +3 -0
  1203. package/dist/components/slider-row/runtime.d.ts.map +1 -0
  1204. package/dist/components/slider-row/runtime.js +139 -0
  1205. package/dist/components/slider-row/runtime.js.map +1 -0
  1206. package/dist/components/slider-row/style.d.ts +5 -0
  1207. package/dist/components/slider-row/style.d.ts.map +1 -0
  1208. package/dist/components/slider-row/style.js +330 -0
  1209. package/dist/components/slider-row/style.js.map +1 -0
  1210. package/dist/components/small-multiples/attrs.d.ts +76 -0
  1211. package/dist/components/small-multiples/attrs.d.ts.map +1 -0
  1212. package/dist/components/small-multiples/attrs.js +77 -0
  1213. package/dist/components/small-multiples/attrs.js.map +1 -0
  1214. package/dist/components/small-multiples/index.d.ts +14 -0
  1215. package/dist/components/small-multiples/index.d.ts.map +1 -0
  1216. package/dist/components/small-multiples/index.js +12 -0
  1217. package/dist/components/small-multiples/index.js.map +1 -0
  1218. package/dist/components/small-multiples/model.d.ts +34 -0
  1219. package/dist/components/small-multiples/model.d.ts.map +1 -0
  1220. package/dist/components/small-multiples/model.js +129 -0
  1221. package/dist/components/small-multiples/model.js.map +1 -0
  1222. package/dist/components/small-multiples/render.d.ts +3 -0
  1223. package/dist/components/small-multiples/render.d.ts.map +1 -0
  1224. package/dist/components/small-multiples/render.js +75 -0
  1225. package/dist/components/small-multiples/render.js.map +1 -0
  1226. package/dist/components/small-multiples/scale.d.ts +33 -0
  1227. package/dist/components/small-multiples/scale.d.ts.map +1 -0
  1228. package/dist/components/small-multiples/scale.js +104 -0
  1229. package/dist/components/small-multiples/scale.js.map +1 -0
  1230. package/dist/components/small-multiples/style.d.ts +7 -0
  1231. package/dist/components/small-multiples/style.d.ts.map +1 -0
  1232. package/dist/components/small-multiples/style.js +260 -0
  1233. package/dist/components/small-multiples/style.js.map +1 -0
  1234. package/dist/components/sort-toggle/attrs.d.ts +116 -0
  1235. package/dist/components/sort-toggle/attrs.d.ts.map +1 -0
  1236. package/dist/components/sort-toggle/attrs.js +85 -0
  1237. package/dist/components/sort-toggle/attrs.js.map +1 -0
  1238. package/dist/components/sort-toggle/index.d.ts +38 -0
  1239. package/dist/components/sort-toggle/index.d.ts.map +1 -0
  1240. package/dist/components/sort-toggle/index.js +36 -0
  1241. package/dist/components/sort-toggle/index.js.map +1 -0
  1242. package/dist/components/sort-toggle/model.d.ts +27 -0
  1243. package/dist/components/sort-toggle/model.d.ts.map +1 -0
  1244. package/dist/components/sort-toggle/model.js +87 -0
  1245. package/dist/components/sort-toggle/model.js.map +1 -0
  1246. package/dist/components/sort-toggle/render.d.ts +5 -0
  1247. package/dist/components/sort-toggle/render.d.ts.map +1 -0
  1248. package/dist/components/sort-toggle/render.js +72 -0
  1249. package/dist/components/sort-toggle/render.js.map +1 -0
  1250. package/dist/components/sort-toggle/runtime.d.ts +3 -0
  1251. package/dist/components/sort-toggle/runtime.d.ts.map +1 -0
  1252. package/dist/components/sort-toggle/runtime.js +187 -0
  1253. package/dist/components/sort-toggle/runtime.js.map +1 -0
  1254. package/dist/components/sort-toggle/style.d.ts +9 -0
  1255. package/dist/components/sort-toggle/style.d.ts.map +1 -0
  1256. package/dist/components/sort-toggle/style.js +100 -0
  1257. package/dist/components/sort-toggle/style.js.map +1 -0
  1258. package/dist/components/spread-dist/attrs.d.ts +86 -0
  1259. package/dist/components/spread-dist/attrs.d.ts.map +1 -0
  1260. package/dist/components/spread-dist/attrs.js +96 -0
  1261. package/dist/components/spread-dist/attrs.js.map +1 -0
  1262. package/dist/components/spread-dist/forms.d.ts +83 -0
  1263. package/dist/components/spread-dist/forms.d.ts.map +1 -0
  1264. package/dist/components/spread-dist/forms.js +136 -0
  1265. package/dist/components/spread-dist/forms.js.map +1 -0
  1266. package/dist/components/spread-dist/index.d.ts +13 -0
  1267. package/dist/components/spread-dist/index.d.ts.map +1 -0
  1268. package/dist/components/spread-dist/index.js +11 -0
  1269. package/dist/components/spread-dist/index.js.map +1 -0
  1270. package/dist/components/spread-dist/model.d.ts +5 -0
  1271. package/dist/components/spread-dist/model.d.ts.map +1 -0
  1272. package/dist/components/spread-dist/model.js +117 -0
  1273. package/dist/components/spread-dist/model.js.map +1 -0
  1274. package/dist/components/spread-dist/render.d.ts +3 -0
  1275. package/dist/components/spread-dist/render.d.ts.map +1 -0
  1276. package/dist/components/spread-dist/render.js +108 -0
  1277. package/dist/components/spread-dist/render.js.map +1 -0
  1278. package/dist/components/spread-dist/scale.d.ts +35 -0
  1279. package/dist/components/spread-dist/scale.d.ts.map +1 -0
  1280. package/dist/components/spread-dist/scale.js +124 -0
  1281. package/dist/components/spread-dist/scale.js.map +1 -0
  1282. package/dist/components/spread-dist/style.d.ts +8 -0
  1283. package/dist/components/spread-dist/style.d.ts.map +1 -0
  1284. package/dist/components/spread-dist/style.js +341 -0
  1285. package/dist/components/spread-dist/style.js.map +1 -0
  1286. package/dist/components/stacked-bar/attrs.d.ts +56 -0
  1287. package/dist/components/stacked-bar/attrs.d.ts.map +1 -0
  1288. package/dist/components/stacked-bar/attrs.js +58 -0
  1289. package/dist/components/stacked-bar/attrs.js.map +1 -0
  1290. package/dist/components/stacked-bar/index.d.ts +13 -0
  1291. package/dist/components/stacked-bar/index.d.ts.map +1 -0
  1292. package/dist/components/stacked-bar/index.js +11 -0
  1293. package/dist/components/stacked-bar/index.js.map +1 -0
  1294. package/dist/components/stacked-bar/model.d.ts +36 -0
  1295. package/dist/components/stacked-bar/model.d.ts.map +1 -0
  1296. package/dist/components/stacked-bar/model.js +106 -0
  1297. package/dist/components/stacked-bar/model.js.map +1 -0
  1298. package/dist/components/stacked-bar/render.d.ts +3 -0
  1299. package/dist/components/stacked-bar/render.d.ts.map +1 -0
  1300. package/dist/components/stacked-bar/render.js +74 -0
  1301. package/dist/components/stacked-bar/render.js.map +1 -0
  1302. package/dist/components/stacked-bar/style.d.ts +7 -0
  1303. package/dist/components/stacked-bar/style.d.ts.map +1 -0
  1304. package/dist/components/stacked-bar/style.js +228 -0
  1305. package/dist/components/stacked-bar/style.js.map +1 -0
  1306. package/dist/components/stat-inline/attrs.d.ts +45 -0
  1307. package/dist/components/stat-inline/attrs.d.ts.map +1 -0
  1308. package/dist/components/stat-inline/attrs.js +35 -0
  1309. package/dist/components/stat-inline/attrs.js.map +1 -0
  1310. package/dist/components/stat-inline/index.d.ts +14 -0
  1311. package/dist/components/stat-inline/index.d.ts.map +1 -0
  1312. package/dist/components/stat-inline/index.js +12 -0
  1313. package/dist/components/stat-inline/index.js.map +1 -0
  1314. package/dist/components/stat-inline/model.d.ts +15 -0
  1315. package/dist/components/stat-inline/model.d.ts.map +1 -0
  1316. package/dist/components/stat-inline/model.js +49 -0
  1317. package/dist/components/stat-inline/model.js.map +1 -0
  1318. package/dist/components/stat-inline/render.d.ts +5 -0
  1319. package/dist/components/stat-inline/render.d.ts.map +1 -0
  1320. package/dist/components/stat-inline/render.js +59 -0
  1321. package/dist/components/stat-inline/render.js.map +1 -0
  1322. package/dist/components/stat-inline/style.d.ts +5 -0
  1323. package/dist/components/stat-inline/style.d.ts.map +1 -0
  1324. package/dist/components/stat-inline/style.js +70 -0
  1325. package/dist/components/stat-inline/style.js.map +1 -0
  1326. package/dist/components/status-row/attrs.d.ts +65 -0
  1327. package/dist/components/status-row/attrs.d.ts.map +1 -0
  1328. package/dist/components/status-row/attrs.js +50 -0
  1329. package/dist/components/status-row/attrs.js.map +1 -0
  1330. package/dist/components/status-row/index.d.ts +23 -0
  1331. package/dist/components/status-row/index.d.ts.map +1 -0
  1332. package/dist/components/status-row/index.js +21 -0
  1333. package/dist/components/status-row/index.js.map +1 -0
  1334. package/dist/components/status-row/model.d.ts +25 -0
  1335. package/dist/components/status-row/model.d.ts.map +1 -0
  1336. package/dist/components/status-row/model.js +79 -0
  1337. package/dist/components/status-row/model.js.map +1 -0
  1338. package/dist/components/status-row/render.d.ts +6 -0
  1339. package/dist/components/status-row/render.d.ts.map +1 -0
  1340. package/dist/components/status-row/render.js +69 -0
  1341. package/dist/components/status-row/render.js.map +1 -0
  1342. package/dist/components/status-row/style.d.ts +15 -0
  1343. package/dist/components/status-row/style.d.ts.map +1 -0
  1344. package/dist/components/status-row/style.js +289 -0
  1345. package/dist/components/status-row/style.js.map +1 -0
  1346. package/dist/components/step-flow/attrs.d.ts +65 -0
  1347. package/dist/components/step-flow/attrs.d.ts.map +1 -0
  1348. package/dist/components/step-flow/attrs.js +52 -0
  1349. package/dist/components/step-flow/attrs.js.map +1 -0
  1350. package/dist/components/step-flow/index.d.ts +23 -0
  1351. package/dist/components/step-flow/index.d.ts.map +1 -0
  1352. package/dist/components/step-flow/index.js +21 -0
  1353. package/dist/components/step-flow/index.js.map +1 -0
  1354. package/dist/components/step-flow/model.d.ts +24 -0
  1355. package/dist/components/step-flow/model.d.ts.map +1 -0
  1356. package/dist/components/step-flow/model.js +77 -0
  1357. package/dist/components/step-flow/model.js.map +1 -0
  1358. package/dist/components/step-flow/render.d.ts +6 -0
  1359. package/dist/components/step-flow/render.d.ts.map +1 -0
  1360. package/dist/components/step-flow/render.js +65 -0
  1361. package/dist/components/step-flow/render.js.map +1 -0
  1362. package/dist/components/step-flow/style.d.ts +13 -0
  1363. package/dist/components/step-flow/style.d.ts.map +1 -0
  1364. package/dist/components/step-flow/style.js +240 -0
  1365. package/dist/components/step-flow/style.js.map +1 -0
  1366. package/dist/components/streak-badge/attrs.d.ts +49 -0
  1367. package/dist/components/streak-badge/attrs.d.ts.map +1 -0
  1368. package/dist/components/streak-badge/attrs.js +35 -0
  1369. package/dist/components/streak-badge/attrs.js.map +1 -0
  1370. package/dist/components/streak-badge/index.d.ts +22 -0
  1371. package/dist/components/streak-badge/index.d.ts.map +1 -0
  1372. package/dist/components/streak-badge/index.js +20 -0
  1373. package/dist/components/streak-badge/index.js.map +1 -0
  1374. package/dist/components/streak-badge/model.d.ts +18 -0
  1375. package/dist/components/streak-badge/model.d.ts.map +1 -0
  1376. package/dist/components/streak-badge/model.js +44 -0
  1377. package/dist/components/streak-badge/model.js.map +1 -0
  1378. package/dist/components/streak-badge/render.d.ts +6 -0
  1379. package/dist/components/streak-badge/render.d.ts.map +1 -0
  1380. package/dist/components/streak-badge/render.js +39 -0
  1381. package/dist/components/streak-badge/render.js.map +1 -0
  1382. package/dist/components/streak-badge/style.d.ts +13 -0
  1383. package/dist/components/streak-badge/style.d.ts.map +1 -0
  1384. package/dist/components/streak-badge/style.js +134 -0
  1385. package/dist/components/streak-badge/style.js.map +1 -0
  1386. package/dist/components/style/action-bar.d.ts +12 -0
  1387. package/dist/components/style/action-bar.d.ts.map +1 -0
  1388. package/dist/components/style/action-bar.js +117 -0
  1389. package/dist/components/style/action-bar.js.map +1 -0
  1390. package/dist/components/style/copy-button.d.ts +10 -0
  1391. package/dist/components/style/copy-button.d.ts.map +1 -0
  1392. package/dist/components/style/copy-button.js +226 -0
  1393. package/dist/components/style/copy-button.js.map +1 -0
  1394. package/dist/components/style/empty-state.d.ts +10 -0
  1395. package/dist/components/style/empty-state.d.ts.map +1 -0
  1396. package/dist/components/style/empty-state.js +40 -0
  1397. package/dist/components/style/empty-state.js.map +1 -0
  1398. package/dist/components/style/error-receipt.d.ts +16 -0
  1399. package/dist/components/style/error-receipt.d.ts.map +1 -0
  1400. package/dist/components/style/error-receipt.js +58 -0
  1401. package/dist/components/style/error-receipt.js.map +1 -0
  1402. package/dist/components/style/help-shell.d.ts +13 -0
  1403. package/dist/components/style/help-shell.d.ts.map +1 -0
  1404. package/dist/components/style/help-shell.js +559 -0
  1405. package/dist/components/style/help-shell.js.map +1 -0
  1406. package/dist/components/style/index.d.ts +9 -0
  1407. package/dist/components/style/index.d.ts.map +1 -0
  1408. package/dist/components/style/index.js +7 -0
  1409. package/dist/components/style/index.js.map +1 -0
  1410. package/dist/components/style/parts.d.ts +29 -0
  1411. package/dist/components/style/parts.d.ts.map +1 -0
  1412. package/dist/components/style/parts.js +40 -0
  1413. package/dist/components/style/parts.js.map +1 -0
  1414. package/dist/components/style/sheet.d.ts +16 -0
  1415. package/dist/components/style/sheet.d.ts.map +1 -0
  1416. package/dist/components/style/sheet.js +124 -0
  1417. package/dist/components/style/sheet.js.map +1 -0
  1418. package/dist/components/style/status-badge.d.ts +18 -0
  1419. package/dist/components/style/status-badge.d.ts.map +1 -0
  1420. package/dist/components/style/status-badge.js +48 -0
  1421. package/dist/components/style/status-badge.js.map +1 -0
  1422. package/dist/components/style/toast.d.ts +10 -0
  1423. package/dist/components/style/toast.d.ts.map +1 -0
  1424. package/dist/components/style/toast.js +218 -0
  1425. package/dist/components/style/toast.js.map +1 -0
  1426. package/dist/components/style/tokens.d.ts +27 -0
  1427. package/dist/components/style/tokens.d.ts.map +1 -0
  1428. package/dist/components/style/tokens.js +29 -0
  1429. package/dist/components/style/tokens.js.map +1 -0
  1430. package/dist/components/sub-list/attrs.d.ts +79 -0
  1431. package/dist/components/sub-list/attrs.d.ts.map +1 -0
  1432. package/dist/components/sub-list/attrs.js +81 -0
  1433. package/dist/components/sub-list/attrs.js.map +1 -0
  1434. package/dist/components/sub-list/index.d.ts +14 -0
  1435. package/dist/components/sub-list/index.d.ts.map +1 -0
  1436. package/dist/components/sub-list/index.js +12 -0
  1437. package/dist/components/sub-list/index.js.map +1 -0
  1438. package/dist/components/sub-list/model.d.ts +41 -0
  1439. package/dist/components/sub-list/model.d.ts.map +1 -0
  1440. package/dist/components/sub-list/model.js +96 -0
  1441. package/dist/components/sub-list/model.js.map +1 -0
  1442. package/dist/components/sub-list/render.d.ts +3 -0
  1443. package/dist/components/sub-list/render.d.ts.map +1 -0
  1444. package/dist/components/sub-list/render.js +106 -0
  1445. package/dist/components/sub-list/render.js.map +1 -0
  1446. package/dist/components/sub-list/style.d.ts +12 -0
  1447. package/dist/components/sub-list/style.d.ts.map +1 -0
  1448. package/dist/components/sub-list/style.js +327 -0
  1449. package/dist/components/sub-list/style.js.map +1 -0
  1450. package/dist/components/summary-head/index.d.ts +12 -0
  1451. package/dist/components/summary-head/index.d.ts.map +1 -0
  1452. package/dist/components/summary-head/index.js +10 -0
  1453. package/dist/components/summary-head/index.js.map +1 -0
  1454. package/dist/components/summary-head/render.d.ts +32 -0
  1455. package/dist/components/summary-head/render.d.ts.map +1 -0
  1456. package/dist/components/summary-head/render.js +73 -0
  1457. package/dist/components/summary-head/render.js.map +1 -0
  1458. package/dist/components/summary-head/style.d.ts +14 -0
  1459. package/dist/components/summary-head/style.d.ts.map +1 -0
  1460. package/dist/components/summary-head/style.js +155 -0
  1461. package/dist/components/summary-head/style.js.map +1 -0
  1462. package/dist/components/switch-row/attrs.d.ts +92 -0
  1463. package/dist/components/switch-row/attrs.d.ts.map +1 -0
  1464. package/dist/components/switch-row/attrs.js +88 -0
  1465. package/dist/components/switch-row/attrs.js.map +1 -0
  1466. package/dist/components/switch-row/index.d.ts +30 -0
  1467. package/dist/components/switch-row/index.d.ts.map +1 -0
  1468. package/dist/components/switch-row/index.js +28 -0
  1469. package/dist/components/switch-row/index.js.map +1 -0
  1470. package/dist/components/switch-row/model.d.ts +18 -0
  1471. package/dist/components/switch-row/model.d.ts.map +1 -0
  1472. package/dist/components/switch-row/model.js +50 -0
  1473. package/dist/components/switch-row/model.js.map +1 -0
  1474. package/dist/components/switch-row/render.d.ts +3 -0
  1475. package/dist/components/switch-row/render.d.ts.map +1 -0
  1476. package/dist/components/switch-row/render.js +112 -0
  1477. package/dist/components/switch-row/render.js.map +1 -0
  1478. package/dist/components/switch-row/runtime.d.ts +5 -0
  1479. package/dist/components/switch-row/runtime.d.ts.map +1 -0
  1480. package/dist/components/switch-row/runtime.js +62 -0
  1481. package/dist/components/switch-row/runtime.js.map +1 -0
  1482. package/dist/components/switch-row/style.d.ts +5 -0
  1483. package/dist/components/switch-row/style.d.ts.map +1 -0
  1484. package/dist/components/switch-row/style.js +258 -0
  1485. package/dist/components/switch-row/style.js.map +1 -0
  1486. package/dist/components/sync-status/attrs.d.ts +97 -0
  1487. package/dist/components/sync-status/attrs.d.ts.map +1 -0
  1488. package/dist/components/sync-status/attrs.js +90 -0
  1489. package/dist/components/sync-status/attrs.js.map +1 -0
  1490. package/dist/components/sync-status/index.d.ts +19 -0
  1491. package/dist/components/sync-status/index.d.ts.map +1 -0
  1492. package/dist/components/sync-status/index.js +17 -0
  1493. package/dist/components/sync-status/index.js.map +1 -0
  1494. package/dist/components/sync-status/model.d.ts +29 -0
  1495. package/dist/components/sync-status/model.d.ts.map +1 -0
  1496. package/dist/components/sync-status/model.js +73 -0
  1497. package/dist/components/sync-status/model.js.map +1 -0
  1498. package/dist/components/sync-status/render.d.ts +3 -0
  1499. package/dist/components/sync-status/render.d.ts.map +1 -0
  1500. package/dist/components/sync-status/render.js +95 -0
  1501. package/dist/components/sync-status/render.js.map +1 -0
  1502. package/dist/components/sync-status/runtime.d.ts +3 -0
  1503. package/dist/components/sync-status/runtime.d.ts.map +1 -0
  1504. package/dist/components/sync-status/runtime.js +83 -0
  1505. package/dist/components/sync-status/runtime.js.map +1 -0
  1506. package/dist/components/sync-status/style.d.ts +10 -0
  1507. package/dist/components/sync-status/style.d.ts.map +1 -0
  1508. package/dist/components/sync-status/style.js +256 -0
  1509. package/dist/components/sync-status/style.js.map +1 -0
  1510. package/dist/components/task-list/attrs.d.ts +97 -0
  1511. package/dist/components/task-list/attrs.d.ts.map +1 -0
  1512. package/dist/components/task-list/attrs.js +76 -0
  1513. package/dist/components/task-list/attrs.js.map +1 -0
  1514. package/dist/components/task-list/index.d.ts +33 -0
  1515. package/dist/components/task-list/index.d.ts.map +1 -0
  1516. package/dist/components/task-list/index.js +31 -0
  1517. package/dist/components/task-list/index.js.map +1 -0
  1518. package/dist/components/task-list/model.d.ts +33 -0
  1519. package/dist/components/task-list/model.d.ts.map +1 -0
  1520. package/dist/components/task-list/model.js +105 -0
  1521. package/dist/components/task-list/model.js.map +1 -0
  1522. package/dist/components/task-list/render.d.ts +6 -0
  1523. package/dist/components/task-list/render.d.ts.map +1 -0
  1524. package/dist/components/task-list/render.js +112 -0
  1525. package/dist/components/task-list/render.js.map +1 -0
  1526. package/dist/components/task-list/runtime.d.ts +3 -0
  1527. package/dist/components/task-list/runtime.d.ts.map +1 -0
  1528. package/dist/components/task-list/runtime.js +75 -0
  1529. package/dist/components/task-list/runtime.js.map +1 -0
  1530. package/dist/components/task-list/style.d.ts +15 -0
  1531. package/dist/components/task-list/style.d.ts.map +1 -0
  1532. package/dist/components/task-list/style.js +282 -0
  1533. package/dist/components/task-list/style.js.map +1 -0
  1534. package/dist/components/template/fill.d.ts +10 -0
  1535. package/dist/components/template/fill.d.ts.map +1 -0
  1536. package/dist/components/template/fill.js +193 -0
  1537. package/dist/components/template/fill.js.map +1 -0
  1538. package/dist/components/template/index.d.ts +8 -0
  1539. package/dist/components/template/index.d.ts.map +1 -0
  1540. package/dist/components/template/index.js +7 -0
  1541. package/dist/components/template/index.js.map +1 -0
  1542. package/dist/components/template/markers.d.ts +60 -0
  1543. package/dist/components/template/markers.d.ts.map +1 -0
  1544. package/dist/components/template/markers.js +130 -0
  1545. package/dist/components/template/markers.js.map +1 -0
  1546. package/dist/components/template/shared.d.ts +20 -0
  1547. package/dist/components/template/shared.d.ts.map +1 -0
  1548. package/dist/components/template/shared.js +25 -0
  1549. package/dist/components/template/shared.js.map +1 -0
  1550. package/dist/components/text/api.d.ts +14 -0
  1551. package/dist/components/text/api.d.ts.map +1 -0
  1552. package/dist/components/text/api.js +76 -0
  1553. package/dist/components/text/api.js.map +1 -0
  1554. package/dist/components/text/formats.d.ts +30 -0
  1555. package/dist/components/text/formats.d.ts.map +1 -0
  1556. package/dist/components/text/formats.js +120 -0
  1557. package/dist/components/text/formats.js.map +1 -0
  1558. package/dist/components/text/index.d.ts +8 -0
  1559. package/dist/components/text/index.d.ts.map +1 -0
  1560. package/dist/components/text/index.js +7 -0
  1561. package/dist/components/text/index.js.map +1 -0
  1562. package/dist/components/text/input.d.ts +27 -0
  1563. package/dist/components/text/input.d.ts.map +1 -0
  1564. package/dist/components/text/input.js +114 -0
  1565. package/dist/components/text/input.js.map +1 -0
  1566. package/dist/components/text/log.d.ts +12 -0
  1567. package/dist/components/text/log.d.ts.map +1 -0
  1568. package/dist/components/text/log.js +28 -0
  1569. package/dist/components/text/log.js.map +1 -0
  1570. package/dist/components/text/rows.d.ts +27 -0
  1571. package/dist/components/text/rows.d.ts.map +1 -0
  1572. package/dist/components/text/rows.js +100 -0
  1573. package/dist/components/text/rows.js.map +1 -0
  1574. package/dist/components/text/shared.d.ts +35 -0
  1575. package/dist/components/text/shared.d.ts.map +1 -0
  1576. package/dist/components/text/shared.js +29 -0
  1577. package/dist/components/text/shared.js.map +1 -0
  1578. package/dist/components/timer-card/attrs.d.ts +99 -0
  1579. package/dist/components/timer-card/attrs.d.ts.map +1 -0
  1580. package/dist/components/timer-card/attrs.js +97 -0
  1581. package/dist/components/timer-card/attrs.js.map +1 -0
  1582. package/dist/components/timer-card/index.d.ts +34 -0
  1583. package/dist/components/timer-card/index.d.ts.map +1 -0
  1584. package/dist/components/timer-card/index.js +32 -0
  1585. package/dist/components/timer-card/index.js.map +1 -0
  1586. package/dist/components/timer-card/model.d.ts +19 -0
  1587. package/dist/components/timer-card/model.d.ts.map +1 -0
  1588. package/dist/components/timer-card/model.js +63 -0
  1589. package/dist/components/timer-card/model.js.map +1 -0
  1590. package/dist/components/timer-card/render.d.ts +8 -0
  1591. package/dist/components/timer-card/render.d.ts.map +1 -0
  1592. package/dist/components/timer-card/render.js +107 -0
  1593. package/dist/components/timer-card/render.js.map +1 -0
  1594. package/dist/components/timer-card/runtime.d.ts +3 -0
  1595. package/dist/components/timer-card/runtime.d.ts.map +1 -0
  1596. package/dist/components/timer-card/runtime.js +132 -0
  1597. package/dist/components/timer-card/runtime.js.map +1 -0
  1598. package/dist/components/timer-card/style.d.ts +15 -0
  1599. package/dist/components/timer-card/style.d.ts.map +1 -0
  1600. package/dist/components/timer-card/style.js +243 -0
  1601. package/dist/components/timer-card/style.js.map +1 -0
  1602. package/dist/components/toast-card/attrs.d.ts +109 -0
  1603. package/dist/components/toast-card/attrs.d.ts.map +1 -0
  1604. package/dist/components/toast-card/attrs.js +120 -0
  1605. package/dist/components/toast-card/attrs.js.map +1 -0
  1606. package/dist/components/toast-card/index.d.ts +29 -0
  1607. package/dist/components/toast-card/index.d.ts.map +1 -0
  1608. package/dist/components/toast-card/index.js +27 -0
  1609. package/dist/components/toast-card/index.js.map +1 -0
  1610. package/dist/components/toast-card/model.d.ts +29 -0
  1611. package/dist/components/toast-card/model.d.ts.map +1 -0
  1612. package/dist/components/toast-card/model.js +103 -0
  1613. package/dist/components/toast-card/model.js.map +1 -0
  1614. package/dist/components/toast-card/render.d.ts +13 -0
  1615. package/dist/components/toast-card/render.d.ts.map +1 -0
  1616. package/dist/components/toast-card/render.js +74 -0
  1617. package/dist/components/toast-card/render.js.map +1 -0
  1618. package/dist/components/toast-card/runtime.d.ts +5 -0
  1619. package/dist/components/toast-card/runtime.d.ts.map +1 -0
  1620. package/dist/components/toast-card/runtime.js +109 -0
  1621. package/dist/components/toast-card/runtime.js.map +1 -0
  1622. package/dist/components/toast-card/style.d.ts +10 -0
  1623. package/dist/components/toast-card/style.d.ts.map +1 -0
  1624. package/dist/components/toast-card/style.js +208 -0
  1625. package/dist/components/toast-card/style.js.map +1 -0
  1626. package/dist/components/tooltip/attrs.d.ts +84 -0
  1627. package/dist/components/tooltip/attrs.d.ts.map +1 -0
  1628. package/dist/components/tooltip/attrs.js +85 -0
  1629. package/dist/components/tooltip/attrs.js.map +1 -0
  1630. package/dist/components/tooltip/index.d.ts +27 -0
  1631. package/dist/components/tooltip/index.d.ts.map +1 -0
  1632. package/dist/components/tooltip/index.js +24 -0
  1633. package/dist/components/tooltip/index.js.map +1 -0
  1634. package/dist/components/tooltip/model.d.ts +18 -0
  1635. package/dist/components/tooltip/model.d.ts.map +1 -0
  1636. package/dist/components/tooltip/model.js +43 -0
  1637. package/dist/components/tooltip/model.js.map +1 -0
  1638. package/dist/components/tooltip/render.d.ts +3 -0
  1639. package/dist/components/tooltip/render.d.ts.map +1 -0
  1640. package/dist/components/tooltip/render.js +59 -0
  1641. package/dist/components/tooltip/render.js.map +1 -0
  1642. package/dist/components/tooltip/runtime.d.ts +3 -0
  1643. package/dist/components/tooltip/runtime.d.ts.map +1 -0
  1644. package/dist/components/tooltip/runtime.js +81 -0
  1645. package/dist/components/tooltip/runtime.js.map +1 -0
  1646. package/dist/components/tooltip/style.d.ts +8 -0
  1647. package/dist/components/tooltip/style.d.ts.map +1 -0
  1648. package/dist/components/tooltip/style.js +84 -0
  1649. package/dist/components/tooltip/style.js.map +1 -0
  1650. package/dist/components/undo-timeline/attrs.d.ts +204 -0
  1651. package/dist/components/undo-timeline/attrs.d.ts.map +1 -0
  1652. package/dist/components/undo-timeline/attrs.js +192 -0
  1653. package/dist/components/undo-timeline/attrs.js.map +1 -0
  1654. package/dist/components/undo-timeline/ids.d.ts +20 -0
  1655. package/dist/components/undo-timeline/ids.d.ts.map +1 -0
  1656. package/dist/components/undo-timeline/ids.js +39 -0
  1657. package/dist/components/undo-timeline/ids.js.map +1 -0
  1658. package/dist/components/undo-timeline/index.d.ts +27 -0
  1659. package/dist/components/undo-timeline/index.d.ts.map +1 -0
  1660. package/dist/components/undo-timeline/index.js +26 -0
  1661. package/dist/components/undo-timeline/index.js.map +1 -0
  1662. package/dist/components/undo-timeline/model.d.ts +72 -0
  1663. package/dist/components/undo-timeline/model.d.ts.map +1 -0
  1664. package/dist/components/undo-timeline/model.js +237 -0
  1665. package/dist/components/undo-timeline/model.js.map +1 -0
  1666. package/dist/components/undo-timeline/render.d.ts +3 -0
  1667. package/dist/components/undo-timeline/render.d.ts.map +1 -0
  1668. package/dist/components/undo-timeline/render.js +250 -0
  1669. package/dist/components/undo-timeline/render.js.map +1 -0
  1670. package/dist/components/undo-timeline/runtime.d.ts +3 -0
  1671. package/dist/components/undo-timeline/runtime.d.ts.map +1 -0
  1672. package/dist/components/undo-timeline/runtime.js +184 -0
  1673. package/dist/components/undo-timeline/runtime.js.map +1 -0
  1674. package/dist/components/undo-timeline/style-impact.d.ts +5 -0
  1675. package/dist/components/undo-timeline/style-impact.d.ts.map +1 -0
  1676. package/dist/components/undo-timeline/style-impact.js +193 -0
  1677. package/dist/components/undo-timeline/style-impact.js.map +1 -0
  1678. package/dist/components/undo-timeline/style-track.d.ts +5 -0
  1679. package/dist/components/undo-timeline/style-track.d.ts.map +1 -0
  1680. package/dist/components/undo-timeline/style-track.js +299 -0
  1681. package/dist/components/undo-timeline/style-track.js.map +1 -0
  1682. package/dist/components/undo-timeline/style.d.ts +7 -0
  1683. package/dist/components/undo-timeline/style.d.ts.map +1 -0
  1684. package/dist/components/undo-timeline/style.js +224 -0
  1685. package/dist/components/undo-timeline/style.js.map +1 -0
  1686. package/dist/components/undo-timeline/text.d.ts +37 -0
  1687. package/dist/components/undo-timeline/text.d.ts.map +1 -0
  1688. package/dist/components/undo-timeline/text.js +36 -0
  1689. package/dist/components/undo-timeline/text.js.map +1 -0
  1690. package/dist/components/window-picker/attrs.d.ts +109 -0
  1691. package/dist/components/window-picker/attrs.d.ts.map +1 -0
  1692. package/dist/components/window-picker/attrs.js +70 -0
  1693. package/dist/components/window-picker/attrs.js.map +1 -0
  1694. package/dist/components/window-picker/index.d.ts +33 -0
  1695. package/dist/components/window-picker/index.d.ts.map +1 -0
  1696. package/dist/components/window-picker/index.js +30 -0
  1697. package/dist/components/window-picker/index.js.map +1 -0
  1698. package/dist/components/window-picker/model.d.ts +33 -0
  1699. package/dist/components/window-picker/model.d.ts.map +1 -0
  1700. package/dist/components/window-picker/model.js +150 -0
  1701. package/dist/components/window-picker/model.js.map +1 -0
  1702. package/dist/components/window-picker/render.d.ts +10 -0
  1703. package/dist/components/window-picker/render.d.ts.map +1 -0
  1704. package/dist/components/window-picker/render.js +69 -0
  1705. package/dist/components/window-picker/render.js.map +1 -0
  1706. package/dist/components/window-picker/runtime.d.ts +3 -0
  1707. package/dist/components/window-picker/runtime.d.ts.map +1 -0
  1708. package/dist/components/window-picker/runtime.js +160 -0
  1709. package/dist/components/window-picker/runtime.js.map +1 -0
  1710. package/dist/components/window-picker/style.d.ts +11 -0
  1711. package/dist/components/window-picker/style.d.ts.map +1 -0
  1712. package/dist/components/window-picker/style.js +100 -0
  1713. package/dist/components/window-picker/style.js.map +1 -0
  1714. package/dist/components/wizard-shell/attrs.d.ts +182 -0
  1715. package/dist/components/wizard-shell/attrs.d.ts.map +1 -0
  1716. package/dist/components/wizard-shell/attrs.js +155 -0
  1717. package/dist/components/wizard-shell/attrs.js.map +1 -0
  1718. package/dist/components/wizard-shell/index.d.ts +16 -0
  1719. package/dist/components/wizard-shell/index.d.ts.map +1 -0
  1720. package/dist/components/wizard-shell/index.js +14 -0
  1721. package/dist/components/wizard-shell/index.js.map +1 -0
  1722. package/dist/components/wizard-shell/model.d.ts +57 -0
  1723. package/dist/components/wizard-shell/model.d.ts.map +1 -0
  1724. package/dist/components/wizard-shell/model.js +203 -0
  1725. package/dist/components/wizard-shell/model.js.map +1 -0
  1726. package/dist/components/wizard-shell/render.d.ts +3 -0
  1727. package/dist/components/wizard-shell/render.d.ts.map +1 -0
  1728. package/dist/components/wizard-shell/render.js +201 -0
  1729. package/dist/components/wizard-shell/render.js.map +1 -0
  1730. package/dist/components/wizard-shell/runtime.d.ts +20 -0
  1731. package/dist/components/wizard-shell/runtime.d.ts.map +1 -0
  1732. package/dist/components/wizard-shell/runtime.js +84 -0
  1733. package/dist/components/wizard-shell/runtime.js.map +1 -0
  1734. package/dist/components/wizard-shell/style-answer.d.ts +5 -0
  1735. package/dist/components/wizard-shell/style-answer.d.ts.map +1 -0
  1736. package/dist/components/wizard-shell/style-answer.js +220 -0
  1737. package/dist/components/wizard-shell/style-answer.js.map +1 -0
  1738. package/dist/components/wizard-shell/style.d.ts +5 -0
  1739. package/dist/components/wizard-shell/style.d.ts.map +1 -0
  1740. package/dist/components/wizard-shell/style.js +283 -0
  1741. package/dist/components/wizard-shell/style.js.map +1 -0
  1742. package/dist/components//346/270/205/345/215/225.d.ts +72 -0
  1743. package/dist/components//346/270/205/345/215/225.d.ts.map +1 -0
  1744. package/dist/components//346/270/205/345/215/225.js +182 -0
  1745. package/dist/components//346/270/205/345/215/225.js.map +1 -0
  1746. package/dist/contract.js +0 -1
  1747. package/dist/controls.d.ts +6 -160
  1748. package/dist/controls.d.ts.map +1 -1
  1749. package/dist/controls.js +6 -1417
  1750. package/dist/controls.js.map +1 -1
  1751. package/dist/docShell.d.ts +10 -2
  1752. package/dist/docShell.d.ts.map +1 -1
  1753. package/dist/docShell.js +8 -4
  1754. package/dist/docShell.js.map +1 -1
  1755. package/dist/editableValue.d.ts +93 -0
  1756. package/dist/editableValue.d.ts.map +1 -0
  1757. package/dist/editableValue.js +415 -0
  1758. package/dist/editableValue.js.map +1 -0
  1759. package/dist/font.js +0 -1
  1760. package/dist/help.d.ts +4 -21
  1761. package/dist/help.d.ts.map +1 -1
  1762. package/dist/help.js +4 -619
  1763. package/dist/help.js.map +1 -1
  1764. package/dist/helpShell.d.ts.map +1 -1
  1765. package/dist/helpShell.js +2 -3
  1766. package/dist/helpShell.js.map +1 -1
  1767. package/dist/index.d.ts +31 -11
  1768. package/dist/index.d.ts.map +1 -1
  1769. package/dist/index.js +25 -9
  1770. package/dist/index.js.map +1 -1
  1771. package/dist/injector.js +0 -1
  1772. package/dist/output/saveHtml.js +0 -1
  1773. package/dist/pageBars.d.ts +93 -0
  1774. package/dist/pageBars.d.ts.map +1 -0
  1775. package/dist/pageBars.js +176 -0
  1776. package/dist/pageBars.js.map +1 -0
  1777. package/dist/pageBarsCss.d.ts +11 -0
  1778. package/dist/pageBarsCss.d.ts.map +1 -0
  1779. package/dist/pageBarsCss.js +229 -0
  1780. package/dist/pageBarsCss.js.map +1 -0
  1781. package/dist/pageNav.d.ts +51 -0
  1782. package/dist/pageNav.d.ts.map +1 -0
  1783. package/dist/pageNav.js +122 -0
  1784. package/dist/pageNav.js.map +1 -0
  1785. package/dist/pageNavCss.d.ts +14 -0
  1786. package/dist/pageNavCss.d.ts.map +1 -0
  1787. package/dist/pageNavCss.js +85 -0
  1788. package/dist/pageNavCss.js.map +1 -0
  1789. package/dist/pageShapes.d.ts +12 -3
  1790. package/dist/pageShapes.d.ts.map +1 -1
  1791. package/dist/pageShapes.js +32 -3
  1792. package/dist/pageShapes.js.map +1 -1
  1793. package/dist/pageUi.d.ts +7 -47
  1794. package/dist/pageUi.d.ts.map +1 -1
  1795. package/dist/pageUi.js +7 -351
  1796. package/dist/pageUi.js.map +1 -1
  1797. package/dist/spec/charts.d.ts +6 -0
  1798. package/dist/spec/charts.d.ts.map +1 -1
  1799. package/dist/spec/charts.js +0 -1
  1800. package/dist/spec/charts.js.map +1 -1
  1801. package/dist/spec/controls.js +0 -1
  1802. package/dist/spec/help.js +0 -1
  1803. package/dist/spec/index.d.ts +5 -5
  1804. package/dist/spec/index.d.ts.map +1 -1
  1805. package/dist/spec/index.js +42 -5
  1806. package/dist/spec/index.js.map +1 -1
  1807. package/dist/spec/style.js +0 -1
  1808. package/dist/spec/template.js +0 -1
  1809. package/dist/spec/text.d.ts +7 -7
  1810. package/dist/spec/text.d.ts.map +1 -1
  1811. package/dist/spec/text.js +1 -2
  1812. package/dist/spec/text.js.map +1 -1
  1813. package/dist/style.d.ts +6 -40
  1814. package/dist/style.d.ts.map +1 -1
  1815. package/dist/style.js +6 -1370
  1816. package/dist/style.js.map +1 -1
  1817. package/dist/template.d.ts +4 -24
  1818. package/dist/template.d.ts.map +1 -1
  1819. package/dist/template.js +4 -360
  1820. package/dist/template.js.map +1 -1
  1821. package/dist/text.d.ts +4 -16
  1822. package/dist/text.d.ts.map +1 -1
  1823. package/dist/text.js +4 -451
  1824. package/dist/text.js.map +1 -1
  1825. package/dist/ui.js +0 -1
  1826. package/package.json +2 -2
package/dist/helpShell.js CHANGED
@@ -27,9 +27,9 @@ export class HelpShellError extends Error {
27
27
  }
28
28
  }
29
29
  /** 壳前缀(源首行至 help-data 开标签尾,verbatim;改源跑 gen,禁手工改)。 */
30
- export const HELP_SHELL_PREFIX = "<!DOCTYPE html>\r\n<html lang=\"zh-CN\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<title>__HELP_TITLE__</title>\r\n<style>\r\n *{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}\r\n :root{--fg:#1d1d1f;--fg2:#6e6e73;--fg3:#86868b;--bg:#f2f2f7;--card:#fff;--line:#d1d1d6;--blue:#007aff;--blue2:#0a63ce;--soft:#f0f6ff;--ok:#34c759;--orange:#ff9500;--red:#ff3b30;--shadow:0 1px 2px rgba(0,0,0,.04),0 4px 14px rgba(0,0,0,.05)}\r\n body{font-family:-apple-system,BlinkMacSystemFont,\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--fg);line-height:1.5;-webkit-font-smoothing:antialiased;font-size:14px}\r\n button{font-family:inherit}\r\n .stage{min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:24px 16px 60px;background:var(--bg)}\r\n .phone{width:680px;max-width:100%;height:auto;background:transparent;border-radius:0;border:0;overflow:visible;position:relative;box-shadow:none}\r\n .screen{height:auto;overflow:visible;-webkit-overflow-scrolling:touch;background:transparent;scrollbar-width:none;overscroll-behavior-y:auto}\r\n .screen::-webkit-scrollbar{display:none}\r\n .notch{display:none}\r\n .app{padding:12px 0 74px}\r\n .app-inner{padding:0 6px}\r\n .hero{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:11px 12px;margin-bottom:8px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}\r\n .h-left{flex:1;min-width:0}\r\n .eyebrow{font-size:9px;color:var(--blue);font-weight:800;letter-spacing:.07em;text-transform:uppercase}\r\n h1{font-size:19px;line-height:1.15;letter-spacing:-.02em}\r\n .lead{color:var(--fg2);font-size:11.5px}\r\n .hero-steps{display:flex;align-items:center;gap:4px;flex-basis:100%;margin-top:6px}\r\n .hero-steps .step{background:var(--soft);border:1px solid #d7e6ff;color:var(--blue2);font-weight:700;font-size:10.5px;padding:3px 10px;border-radius:999px;white-space:nowrap}\r\n .hero-steps .arrow{color:var(--blue);font-weight:800;font-size:11px}\r\n .h-badge{background:var(--soft);border:1px solid #d7e6ff;color:var(--blue2);font-size:11px;font-weight:700;padding:4px 10px;border-radius:999px;white-space:nowrap;flex-shrink:0}\r\n /* ===== D4 首次使用横幅(可配 · 未初始化时显示 · 可手动关闭)===== */\r\n .init-banner{background:linear-gradient(135deg,#0a63ce,#007aff 55%,#34c759);color:#fff;border-radius:12px;padding:12px 14px;margin-bottom:8px;display:flex;align-items:center;gap:12px;flex-wrap:wrap;position:relative}\r\n .init-banner .ib-text{flex:1;min-width:200px;padding-right:26px}\r\n .init-banner .ib-title{font-size:14px;font-weight:800;margin-bottom:2px}\r\n .init-banner .ib-sub{font-size:11.5px;opacity:.9;line-height:1.5}\r\n .init-banner .copy-btn{background:#fff;color:var(--blue);min-height:30px;font-weight:700;border-radius:999px;padding:0 11px;font-size:11.5px;flex-shrink:0;margin-right:26px}\r\n .init-banner .ib-close{position:absolute;top:8px;right:8px;width:22px;height:22px;border-radius:50%;border:0;background:rgba(255,255,255,.22);color:#fff;font-size:12px;cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:1;flex-shrink:0}\r\n /* 初始化步骤卡(可选 · 技能传 steps 显示 · >4 步横向滑动)*/\r\n .init-steps{display:flex;gap:6px;flex-basis:100%;margin-top:4px;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:2px}\r\n .init-steps::-webkit-scrollbar{display:none}\r\n .init-step{flex:0 0 calc(25% - 4.5px);background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.28);border-radius:10px;padding:7px 5px;text-align:center;min-width:0}\r\n .init-step .s-n{width:20px;height:20px;border-radius:50%;background:#fff;color:var(--blue2);font-weight:800;font-size:10px;display:flex;align-items:center;justify-content:center;margin:0 auto 4px}\r\n .init-step .s-t{font-size:9.5px;font-weight:700;color:#fff;line-height:1.3;word-break:break-all}\r\n .init-step .s-d{font-size:8px;color:rgba(255,255,255,.75);margin-top:1px;line-height:1.3;word-break:break-all}\r\n /* ===== 关于 Tab(最后 · 域概览 + 联系作者 + 版本)===== */\r\n .about-sec{background:var(--card);border:1px solid var(--line);border-radius:12px;margin-bottom:8px;overflow:hidden}\r\n .about-sec .as-head{padding:9px 12px;font-size:13px;font-weight:800;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:7px}\r\n .about-sec .as-body{padding:4px 12px 8px}\r\n .about-row{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px dashed var(--line);font-size:12.5px}\r\n .about-row:last-child{border-bottom:0}\r\n .about-row .a-ico{width:30px;height:30px;border-radius:9px;background:var(--soft);color:var(--blue2);display:flex;align-items:center;justify-content:center;font-size:15px;flex-shrink:0}\r\n .about-row .a-ico svg{width:17px;height:17px;display:block}\r\n .about-row .a-t{flex:1;min-width:0}\r\n .about-row .a-t b{font-size:12.5px;display:block}\r\n .about-row .a-t span{font-size:10.5px;color:var(--fg3)}\r\n .about-row .a-badge{font-size:9.5px;color:var(--fg3);background:var(--bg);border-radius:999px;padding:1px 8px;flex-shrink:0}\r\n .about-row .a-link{color:var(--blue);font-size:10.5px;word-break:break-all}\r\n .about-row .a-copy{min-height:28px;padding:0 10px;font-size:10.5px;border-radius:8px;flex-shrink:0}\r\n /* ===== D4 联系作者(可配)===== */\r\n .contact-box{background:var(--card);border:1px solid var(--line);border-radius:12px;margin-top:10px;overflow:hidden}\r\n .contact-box>summary{min-height:44px;padding:0 13px;cursor:pointer;font-size:13.5px;font-weight:700;list-style:none;display:flex;align-items:center;gap:8px;user-select:none}\r\n .contact-box>summary::-webkit-details-marker{display:none}\r\n .contact-box>summary::before{content:\"▸\";font-size:11px;color:var(--fg3);transition:transform .15s;flex-shrink:0}\r\n .contact-box[open]>summary::before{transform:rotate(90deg);color:var(--blue)}\r\n .contact-body{padding:4px 13px 12px}\r\n .contact-item{display:flex;gap:10px;align-items:center;font-size:12.5px;color:var(--fg2);padding:7px 0;border-bottom:1px dashed var(--line)}\r\n .contact-item:last-child{border-bottom:0}\r\n .contact-item .k{font-weight:700;color:var(--fg);min-width:64px;flex-shrink:0}\r\n .contact-item a{color:var(--blue);text-decoration:none;word-break:break-all}\r\n .contact-copy{margin-top:10px}\r\n .search-wrap{position:sticky;top:0;z-index:400;background:rgba(242,242,247,.92);-webkit-backdrop-filter:saturate(180%) blur(14px);backdrop-filter:saturate(180%) blur(14px);padding:5px 0;margin-bottom:2px}\r\n .search-box{position:relative}\r\n .search-box input{width:100%;border:1px solid var(--line);border-radius:10px;padding:9px 34px 9px 34px;font-size:13.5px;background:#fff;outline:none}\r\n .search-box input:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(0,122,255,.13)}\r\n .s-icon{position:absolute;left:11px;top:50%;transform:translateY(-50%);font-size:13px;color:var(--fg3);pointer-events:none}\r\n .s-clear{position:absolute;right:9px;top:50%;transform:translateY(-50%);width:20px;height:20px;border-radius:50%;border:0;background:var(--bg);color:var(--fg3);font-size:12px;cursor:pointer;display:none;align-items:center;justify-content:center;line-height:1}\r\n .hitcount{font-size:11px;color:var(--fg2);margin-bottom:5px;text-align:center}\r\n .search-empty{background:var(--card);border:1.5px dashed var(--line);border-radius:12px;padding:20px 12px;text-align:center;color:var(--fg3);font-size:12.5px}\r\n .chip{display:inline-block;background:var(--soft);color:var(--blue2);padding:1px 7px 1px 0;border-radius:999px;font-size:9.5px;font-weight:700;flex-shrink:0;line-height:1.55}\r\n .type-badge{display:inline-block;padding:1px 7px;border-radius:999px;font-size:9px;font-weight:700;flex-shrink:0;background:#e9e9ee;color:#666;line-height:1.55}\r\n .t-view{background:#e8f2ff;color:#0a63ce}\r\n .t-wizard{background:#e2f7f5;color:#00897b}\r\n .t-collect{background:#e7f8ee;color:#1a7a3a}\r\n .t-result{background:#e8f2ff;color:#0a63ce}\r\n .t-batch{background:#f3e9fb;color:#8e3fc9}\r\n .t-dev{background:#fff1e2;color:#b25b00}\r\n .copy-btn{display:inline-flex;align-items:center;justify-content:center;border:0;background:var(--blue);color:#fff;border-radius:8px;padding:0 9px;font-size:11.5px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;min-height:36px;transition:background .12s}\r\n .copy-btn:active{background:var(--blue2)}\r\n .copy-btn.ghost{background:#fff;color:var(--blue);border:1px solid var(--blue)}\r\n mark{background:#ffe08a;border-radius:3px;padding:0 1px;color:inherit}\r\n\r\n /* ===== 横向滑动容器(ViewPager)===== */\r\n .pages{display:flex;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;scrollbar-width:none;scroll-behavior:smooth;align-items:flex-start}\r\n .pages::-webkit-scrollbar{display:none}\r\n .page{flex:0 0 100%;scroll-snap-align:start}\r\n\r\n /* ===== 二级:子功能折叠组 ===== */\r\n .page{display:flex;flex-direction:column}\r\n .subgroup{background:var(--card);border:1px solid var(--line);border-radius:12px;margin-bottom:8px;overflow:hidden;display:flex;flex-direction:column}\r\n .subgroup>summary{min-height:44px;padding:0 12px;display:flex;align-items:center;gap:8px;list-style:none;cursor:pointer;font-size:13.5px;font-weight:700;user-select:none;flex-shrink:0}\r\n .subgroup>summary::-webkit-details-marker{display:none}\r\n .subgroup>summary::before{content:\"▸\";font-size:11px;color:var(--fg3);transition:transform .15s;flex-shrink:0}\r\n .subgroup[open]>summary::before{transform:rotate(90deg);color:var(--blue)}\r\n .subgroup .sg-count{font-size:10px;color:var(--fg3);font-weight:600;margin-left:auto;background:var(--bg);border-radius:999px;padding:1px 8px}\r\n .subgroup .sg-body{padding:7px 8px 9px;display:flex;flex-direction:column;flex:1;min-height:0}\r\n .subgroup:not([open]) .sg-body{display:none}\r\n\r\n /* ===== 三级:2 列场景卡片 ===== */\r\n .grid{display:grid;grid-template-columns:1fr 1fr;gap:7px}\r\n .mini{background:var(--bg);border:1px solid var(--line);border-radius:12px;padding:9px;display:flex;flex-direction:column;gap:6px;cursor:pointer;box-shadow:none;transition:transform .08s;min-width:0;overflow:hidden}\r\n .mini:active{transform:scale(.985);background:#eaeaef}\r\n .mini .m-top{display:flex;align-items:center;justify-content:flex-end;gap:2px;min-height:18px;flex-wrap:wrap}\r\n .mini .m-top .chip{max-width:65%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0;margin-right:auto}\r\n .mini .m-top .type-badge{flex-shrink:0;white-space:nowrap}\r\n .mini .m-bottom{display:flex;align-items:center;gap:8px;min-width:0}\r\n .mini .m-name{flex:1;min-width:0;font-size:12.5px;font-weight:700;line-height:1.35;word-break:break-all;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\r\n .mini .copy-btn{min-height:26px;padding:0 9px;font-size:11px;border-radius:9px;flex-shrink:0}\r\n\r\n /* ===== 底部 Tab(可横向滑动)===== */\r\n .tab-bar{position:fixed;left:0;right:0;bottom:0;background:rgba(255,255,255,.94);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);border-top:1px solid var(--line);display:flex;z-index:600;padding:6px 8px calc(6px + env(safe-area-inset-bottom,0));gap:6px;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;touch-action:pan-x}\r\n /* 宽屏: Tab 栏宽度对齐主体内容区(居中限宽, 不横跨全屏); 手机端保持全宽(见 media query)*/\r\n @media(min-width:501px){\r\n .tab-bar{width:680px;max-width:100%;left:50%;transform:translateX(-50%);border-left:1px solid var(--line);border-right:1px solid var(--line);border-radius:0}\r\n }\r\n .tab-bar::-webkit-scrollbar{display:none}\r\n .tab{flex:0 0 auto;min-width:66px;display:flex;flex-direction:column;align-items:center;gap:3px;padding:5px 10px 4px;cursor:pointer;font-size:10px;color:var(--fg3);font-weight:600;min-height:54px;justify-content:center;border:0;background:none;border-radius:14px;transition:background .08s,color .08s,box-shadow .08s;white-space:nowrap}\r\n .tab .t-ico{width:22px;height:22px;display:flex;align-items:center;justify-content:center;line-height:1}\r\n .tab .t-ico svg{width:20px;height:20px;display:block}\r\n .tab .t-ico .t-emoji{font-size:16px;line-height:1}\r\n .tab.active{background:var(--blue);color:#fff;box-shadow:0 4px 12px rgba(0,122,255,.3)}\r\n .tab.active .t-ico{transform:scale(1.05)}\r\n\r\n /* ===== Sheet 弹层(高度自适应内容 · 不满屏不滚动)===== */\r\n .sheet-mask{position:fixed;left:8px;right:8px;top:8px;bottom:8px;background:rgba(0,0,0,.45);opacity:0;pointer-events:none;transition:opacity .25s;z-index:900;border-radius:36px}\r\n .sheet-mask.show{opacity:1;pointer-events:auto}\r\n .sheet{position:fixed;left:8px;right:8px;bottom:8px;background:var(--card);border-radius:22px 22px 36px 36px;padding:10px 16px calc(8px + env(safe-area-inset-bottom,0));transform:translateY(105%);transition:transform .32s cubic-bezier(.32,.72,.24,1);z-index:901;max-height:82%;display:flex;flex-direction:column;box-shadow:0 -8px 40px rgba(0,0,0,.25)}\r\n .sheet.show{transform:translateY(0)}\r\n .sheet .grip{width:38px;height:4.5px;border-radius:999px;background:var(--line);margin:0 auto 12px;flex-shrink:0}\r\n .sheet .s-scroll{overflow-y:auto;flex:1;min-height:0;scrollbar-width:none;padding-bottom:66px}\r\n .sheet .s-scroll::-webkit-scrollbar{display:none}\r\n .sheet .s-head{display:flex;align-items:center;gap:3.5px;flex-wrap:wrap;margin-bottom:4px}\r\n .sheet .s-title{font-size:17px;font-weight:700;flex-basis:100%;line-height:1.3}\r\n .sheet .s-close{position:absolute;top:16px;right:16px;width:30px;height:30px;border-radius:50%;border:0;background:var(--bg);color:var(--fg3);font-size:15px;cursor:pointer;display:flex;align-items:center;justify-content:center}\r\n .sheet .prompt-box{background:#1d1d1d;color:#f5f5f7;border-radius:12px;padding:11px 13px;white-space:pre-wrap;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.65;margin-top:9px;word-break:break-all}\r\n .sheet .pform{margin-top:9px;background:var(--bg);border:1px solid var(--line);border-radius:12px;padding:9px 10px}\r\n .sheet .pfield{display:flex;align-items:center;gap:7px;margin-bottom:7px}\r\n .sheet .pfield:last-of-type{margin-bottom:0}\r\n .sheet .pfield label{font-size:12px;color:var(--fg2);font-weight:600;flex-shrink:0;min-width:72px}\r\n .sheet .pfield label em{color:var(--fg3);font-weight:400;font-size:9px}\r\n .sheet .pfield input{flex:1;min-width:0;border:1px solid var(--line);border-radius:9px;padding:8px 10px;font-size:13px;background:#fff;outline:none;font-family:inherit;color:var(--fg)}\r\n .sheet .pfield input:focus{border-color:var(--blue);box-shadow:0 0 0 2px rgba(0,122,255,.12)}\r\n /* 未填时:灰淡背景 + 提示文字(placeholder 由技能方提供)*/\r\n .sheet .pfield input:placeholder-shown{background:#f2f2f4;border-color:#e0e0e4;color:#8e8e93}\r\n .sheet .pfield input:placeholder-shown:focus{background:#fff;border-color:var(--blue)}\r\n .sheet .pprev{margin-top:9px;background:#1d1d1d;color:#f5f5f7;border-radius:12px;padding:11px 13px;font-size:12px;line-height:1.65;word-break:break-all;white-space:pre-wrap;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}\r\n .sheet .pprev .pv-label{font-size:9px;color:#8e8e93;display:block;letter-spacing:.05em;margin-bottom:4px}\r\n .sheet .s-actions{position:absolute;left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom,0));display:flex;gap:8px;flex-shrink:0}\r\n .sheet .s-actions .copy-btn{flex:1;min-height:48px;font-size:13px;font-weight:600;border-radius:12px;background:var(--blue);color:#fff;border:0;box-shadow:none}\r\n @media(max-width:500px){\r\n body{background:var(--bg)}\r\n .stage{padding:0;background:var(--bg)}\r\n /* #507 地址栏进出整屏跳动:老浏览器不懂 dvh 会整行丢弃,100vh 兜底须写在前 */\r\n .phone{width:100%;height:100vh;height:100dvh;border:0;border-radius:0;max-height:none;background:var(--bg);overflow:hidden}\r\n .screen{height:100%;overflow-y:auto;-webkit-overflow-scrolling:touch;background:var(--bg);overscroll-behavior-y:contain}\r\n .notch{display:none}\r\n .sheet-mask{left:0;right:0;top:0;bottom:0;border-radius:0}\r\n .sheet{left:0;right:0;bottom:0;border-radius:22px 22px 0 0}\r\n }\r\n /* ===== #642 小触摸目标:命中区扩到 ≥44×44(视觉尺寸一字不动)=====\r\n 覆盖层挂在按钮自己的 ::after 上(绝对定位不参与布局,不吃独立点击事件)——命中的仍是按钮本体,\r\n 故 [data-c] 点击委派与 .mini 卡片点击口径不变;三处图标键本已 position:absolute,只补 ::after,不再重复给 relative。 */\r\n .mini .copy-btn,.init-banner .copy-btn,.copy-btn.a-copy{position:relative}\r\n .mini .copy-btn::after,.init-banner .copy-btn::after,.copy-btn.a-copy::after{content:\"\";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:max(100%,44px);height:max(100%,44px)}\r\n .ib-close::after,.s-clear::after,.sheet .s-close::after{content:\"\";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:max(100%,44px);height:max(100%,44px)}\r\n</style>\r\n</head>\r\n<body>\r\n\r\n<div class=\"stage\">\r\n\r\n <div class=\"phone\"><div class=\"notch\"></div><div class=\"screen\" id=\"screen\"></div></div>\r\n\r\n <div class=\"sheet-mask\" id=\"sheetMask\"></div>\r\n <div class=\"sheet\" id=\"sheet\">\r\n <div class=\"grip\"></div>\r\n <button class=\"s-close\" id=\"sheetClose\">✕</button>\r\n <div class=\"s-scroll\">\r\n <div class=\"s-head\" id=\"shHead\"></div>\r\n <div id=\"shBody\"></div>\r\n </div>\r\n <div class=\"s-actions\">\r\n <button class=\"copy-btn\" id=\"shCopy\">复制</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"toast\" id=\"toast\" style=\"display:none\"></div>\r\n</div>\r\n\r\n<!-- 公共组件注入管线 -->\r\n<script id=\"help-data\" type=\"application/json\">";
30
+ export const HELP_SHELL_PREFIX = "<!DOCTYPE html>\r\n<html lang=\"zh-CN\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<title>__HELP_TITLE__</title>\r\n<style>\r\n *{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}\r\n :root{--fg:#1d1d1f;--fg2:#6e6e73;--fg3:#86868b;--bg:#f2f2f7;--card:#fff;--line:#d1d1d6;--blue:#007aff;--blue2:#0a63ce;--soft:#f0f6ff;--ok:#34c759;--orange:#ff9500;--red:#ff3b30;--shadow:0 1px 2px rgba(0,0,0,.04),0 4px 14px rgba(0,0,0,.05)}/* 滚动条槽位恒留:切 tab 时 lockPagesHeight 按页改文档高,「基础信息/关于」两页矮到不需要竖排滚动条,视口可用宽随之差一个滚动条宽 → 居中手机壳与固定底线 tab 条左右平移(水平抖动)*/html{scrollbar-gutter:stable}\r\n body{font-family:-apple-system,BlinkMacSystemFont,\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--fg);line-height:1.5;-webkit-font-smoothing:antialiased;font-size:14px}\r\n button{font-family:inherit}\r\n .stage{min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:24px 16px 60px;background:var(--bg)}\r\n .phone{width:680px;max-width:100%;height:auto;background:transparent;border-radius:0;border:0;overflow:visible;position:relative;box-shadow:none}\r\n .screen{height:auto;overflow:visible;-webkit-overflow-scrolling:touch;background:transparent;scrollbar-width:none;overscroll-behavior-y:auto}\r\n .screen::-webkit-scrollbar{display:none}\r\n .notch{display:none}\r\n .app{padding:12px 0 74px}\r\n .app-inner{padding:0 6px}\r\n .hero{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:11px 12px;margin-bottom:8px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}\r\n .h-left{flex:1;min-width:0}\r\n .eyebrow{font-size:9px;color:var(--blue);font-weight:800;letter-spacing:.07em;text-transform:uppercase}\r\n h1{font-size:19px;line-height:1.15;letter-spacing:-.02em}\r\n .lead{color:var(--fg2);font-size:11.5px}\r\n .hero-steps{display:flex;align-items:center;gap:4px;flex-basis:100%;margin-top:6px}\r\n .hero-steps .step{background:var(--soft);border:1px solid #d7e6ff;color:var(--blue2);font-weight:700;font-size:10.5px;padding:3px 10px;border-radius:999px;white-space:nowrap}\r\n .hero-steps .arrow{color:var(--blue);font-weight:800;font-size:11px}\r\n .h-badge{background:var(--soft);border:1px solid #d7e6ff;color:var(--blue2);font-size:11px;font-weight:700;padding:4px 10px;border-radius:999px;white-space:nowrap;flex-shrink:0}\r\n /* ===== D4 首次使用横幅(可配 · 未初始化时显示 · 可手动关闭)===== */\r\n .init-banner{background:linear-gradient(135deg,#0a63ce,#007aff 55%,#34c759);color:#fff;border-radius:12px;padding:12px 14px;margin-bottom:8px;display:flex;align-items:center;gap:12px;flex-wrap:wrap;position:relative}\r\n .init-banner .ib-text{flex:1;min-width:200px;padding-right:26px}\r\n .init-banner .ib-title{font-size:14px;font-weight:800;margin-bottom:2px}\r\n .init-banner .ib-sub{font-size:11.5px;opacity:.9;line-height:1.5}\r\n .init-banner .copy-btn{background:#fff;color:var(--blue);min-height:30px;font-weight:700;border-radius:999px;padding:0 11px;font-size:11.5px;flex-shrink:0;margin-right:26px}\r\n .init-banner .ib-close{position:absolute;top:8px;right:8px;width:22px;height:22px;border-radius:50%;border:0;background:rgba(255,255,255,.22);color:#fff;font-size:12px;cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:1;flex-shrink:0}\r\n /* 初始化步骤卡(可选 · 技能传 steps 显示 · >4 步横向滑动)*/\r\n .init-steps{display:flex;gap:6px;flex-basis:100%;margin-top:4px;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:2px}\r\n .init-steps::-webkit-scrollbar{display:none}\r\n .init-step{flex:0 0 calc(25% - 4.5px);background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.28);border-radius:10px;padding:7px 5px;text-align:center;min-width:0}\r\n .init-step .s-n{width:20px;height:20px;border-radius:50%;background:#fff;color:var(--blue2);font-weight:800;font-size:10px;display:flex;align-items:center;justify-content:center;margin:0 auto 4px}\r\n .init-step .s-t{font-size:9.5px;font-weight:700;color:#fff;line-height:1.3;word-break:break-all}\r\n .init-step .s-d{font-size:8px;color:rgba(255,255,255,.75);margin-top:1px;line-height:1.3;word-break:break-all}\r\n /* ===== 关于 Tab(最后 · 域概览 + 联系作者 + 版本)===== */\r\n .about-sec{background:var(--card);border:1px solid var(--line);border-radius:12px;margin-bottom:8px;overflow:hidden}\r\n .about-sec .as-head{padding:9px 12px;font-size:13px;font-weight:800;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:7px}\r\n .about-sec .as-body{padding:4px 12px 8px}\r\n .about-row{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px dashed var(--line);font-size:12.5px}\r\n .about-row:last-child{border-bottom:0}\r\n .about-row .a-ico{width:30px;height:30px;border-radius:9px;background:var(--soft);color:var(--blue2);display:flex;align-items:center;justify-content:center;font-size:15px;flex-shrink:0}\r\n .about-row .a-ico svg{width:17px;height:17px;display:block}\r\n .about-row .a-t{flex:1;min-width:0}\r\n .about-row .a-t b{font-size:12.5px;display:block}\r\n .about-row .a-t span{font-size:10.5px;color:var(--fg3)}\r\n .about-row .a-badge{font-size:9.5px;color:var(--fg3);background:var(--bg);border-radius:999px;padding:1px 8px;flex-shrink:0}\r\n .about-row .a-link{color:var(--blue);font-size:10.5px;word-break:break-all}\r\n .about-row .a-copy{min-height:28px;padding:0 10px;font-size:10.5px;border-radius:8px;flex-shrink:0}\r\n /* ===== D4 联系作者(可配)===== */\r\n .contact-box{background:var(--card);border:1px solid var(--line);border-radius:12px;margin-top:10px;overflow:hidden}\r\n .contact-box>summary{min-height:44px;padding:0 13px;cursor:pointer;font-size:13.5px;font-weight:700;list-style:none;display:flex;align-items:center;gap:8px;user-select:none}\r\n .contact-box>summary::-webkit-details-marker{display:none}\r\n .contact-box>summary::before{content:\"▸\";font-size:11px;color:var(--fg3);transition:transform .15s;flex-shrink:0}\r\n .contact-box[open]>summary::before{transform:rotate(90deg);color:var(--blue)}\r\n .contact-body{padding:4px 13px 12px}\r\n .contact-item{display:flex;gap:10px;align-items:center;font-size:12.5px;color:var(--fg2);padding:7px 0;border-bottom:1px dashed var(--line)}\r\n .contact-item:last-child{border-bottom:0}\r\n .contact-item .k{font-weight:700;color:var(--fg);min-width:64px;flex-shrink:0}\r\n .contact-item a{color:var(--blue);text-decoration:none;word-break:break-all}\r\n .contact-copy{margin-top:10px}\r\n .search-wrap{position:sticky;top:0;z-index:400;background:rgba(242,242,247,.92);-webkit-backdrop-filter:saturate(180%) blur(14px);backdrop-filter:saturate(180%) blur(14px);padding:5px 0;margin-bottom:2px}\r\n .search-box{position:relative}\r\n .search-box input{width:100%;border:1px solid var(--line);border-radius:10px;padding:9px 34px 9px 34px;font-size:13.5px;background:#fff;outline:none}\r\n .search-box input:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(0,122,255,.13)}\r\n .s-icon{position:absolute;left:11px;top:50%;transform:translateY(-50%);font-size:13px;color:var(--fg3);pointer-events:none}\r\n .s-clear{position:absolute;right:9px;top:50%;transform:translateY(-50%);width:20px;height:20px;border-radius:50%;border:0;background:var(--bg);color:var(--fg3);font-size:12px;cursor:pointer;display:none;align-items:center;justify-content:center;line-height:1}\r\n .hitcount{font-size:11px;color:var(--fg2);margin-bottom:5px;text-align:center}\r\n .search-empty{background:var(--card);border:1.5px dashed var(--line);border-radius:12px;padding:20px 12px;text-align:center;color:var(--fg3);font-size:12.5px}\r\n .chip{display:inline-block;background:var(--soft);color:var(--blue2);padding:1px 7px 1px 0;border-radius:999px;font-size:9.5px;font-weight:700;flex-shrink:0;line-height:1.55}\r\n .type-badge{display:inline-block;padding:1px 7px;border-radius:999px;font-size:9px;font-weight:700;flex-shrink:0;background:#e9e9ee;color:#666;line-height:1.55}\r\n .t-view{background:#e8f2ff;color:#0a63ce}\r\n .t-wizard{background:#e2f7f5;color:#00897b}\r\n .t-collect{background:#e7f8ee;color:#1a7a3a}\r\n .t-result{background:#e8f2ff;color:#0a63ce}\r\n .t-batch{background:#f3e9fb;color:#8e3fc9}\r\n .t-dev{background:#fff1e2;color:#b25b00}\r\n .copy-btn{display:inline-flex;align-items:center;justify-content:center;border:0;background:var(--blue);color:#fff;border-radius:8px;padding:0 9px;font-size:11.5px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;min-height:36px;transition:background .12s}\r\n .copy-btn:active{background:var(--blue2)}\r\n .copy-btn.ghost{background:#fff;color:var(--blue);border:1px solid var(--blue)}\r\n mark{background:#ffe08a;border-radius:3px;padding:0 1px;color:inherit}\r\n\r\n /* ===== 横向滑动容器(ViewPager)===== */\r\n .pages{display:flex;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;scrollbar-width:none;scroll-behavior:smooth;align-items:flex-start}\r\n .pages::-webkit-scrollbar{display:none}\r\n .page{flex:0 0 100%;scroll-snap-align:start}\r\n\r\n /* ===== 二级:子功能折叠组 ===== */\r\n .page{display:flex;flex-direction:column}\r\n .subgroup{background:var(--card);border:1px solid var(--line);border-radius:12px;margin-bottom:8px;overflow:hidden;display:flex;flex-direction:column}\r\n .subgroup>summary{min-height:44px;padding:0 12px;display:flex;align-items:center;gap:8px;list-style:none;cursor:pointer;font-size:13.5px;font-weight:700;user-select:none;flex-shrink:0}\r\n .subgroup>summary::-webkit-details-marker{display:none}\r\n .subgroup>summary::before{content:\"▸\";font-size:11px;color:var(--fg3);transition:transform .15s;flex-shrink:0}\r\n .subgroup[open]>summary::before{transform:rotate(90deg);color:var(--blue)}\r\n .subgroup .sg-count{font-size:10px;color:var(--fg3);font-weight:600;margin-left:auto;background:var(--bg);border-radius:999px;padding:1px 8px}\r\n .subgroup .sg-body{padding:7px 8px 9px;display:flex;flex-direction:column;flex:1;min-height:0}\r\n .subgroup:not([open]) .sg-body{display:none}\r\n\r\n /* ===== 三级:2 列场景卡片 ===== */\r\n .grid{display:grid;grid-template-columns:1fr 1fr;gap:7px}\r\n .mini{background:var(--bg);border:1px solid var(--line);border-radius:12px;padding:9px;display:flex;flex-direction:column;gap:6px;cursor:pointer;box-shadow:none;transition:transform .08s;min-width:0;overflow:hidden}\r\n .mini:active{transform:scale(.985);background:#eaeaef}\r\n .mini .m-top{display:flex;align-items:center;justify-content:flex-end;gap:2px;min-height:18px;flex-wrap:wrap}\r\n .mini .m-top .chip{max-width:65%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0;margin-right:auto}\r\n .mini .m-top .type-badge{flex-shrink:0;white-space:nowrap}\r\n .mini .m-bottom{display:flex;align-items:center;gap:8px;min-width:0}\r\n .mini .m-name{flex:1;min-width:0;font-size:12.5px;font-weight:700;line-height:1.35;word-break:break-all;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\r\n .mini .copy-btn{min-height:26px;padding:0 9px;font-size:11px;border-radius:9px;flex-shrink:0}\r\n\r\n /* ===== 底部 Tab(可横向滑动)===== */\r\n .tab-bar{position:fixed;left:0;right:0;bottom:0;background:rgba(255,255,255,.94);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);border-top:1px solid var(--line);display:flex;z-index:600;padding:6px 8px calc(6px + env(safe-area-inset-bottom,0));gap:6px;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;touch-action:pan-x}\r\n /* 宽屏: Tab 栏宽度对齐主体内容区(居中限宽, 不横跨全屏); 手机端保持全宽(见 media query)*/\r\n @media(min-width:501px){\r\n .tab-bar{width:680px;max-width:100%;left:50%;transform:translateX(-50%);border-left:1px solid var(--line);border-right:1px solid var(--line);border-radius:0}\r\n }\r\n .tab-bar::-webkit-scrollbar{display:none}\r\n .tab{flex:0 0 auto;min-width:66px;display:flex;flex-direction:column;align-items:center;gap:3px;padding:5px 10px 4px;cursor:pointer;font-size:10px;color:var(--fg3);font-weight:600;min-height:54px;justify-content:center;border:0;background:none;border-radius:14px;transition:background .08s,color .08s,box-shadow .08s;white-space:nowrap}\r\n .tab .t-ico{width:22px;height:22px;display:flex;align-items:center;justify-content:center;line-height:1}\r\n .tab .t-ico svg{width:20px;height:20px;display:block}\r\n .tab .t-ico .t-emoji{font-size:16px;line-height:1}\r\n .tab.active{background:var(--blue);color:#fff;box-shadow:0 4px 12px rgba(0,122,255,.3)}\r\n .tab.active .t-ico{transform:scale(1.05)}\r\n\r\n /* ===== Sheet 弹层(高度自适应内容 · 不满屏不滚动)===== */\r\n .sheet-mask{position:fixed;left:8px;right:8px;top:8px;bottom:8px;background:rgba(0,0,0,.45);opacity:0;pointer-events:none;transition:opacity .25s;z-index:900;border-radius:36px}\r\n .sheet-mask.show{opacity:1;pointer-events:auto}\r\n .sheet{position:fixed;left:8px;right:8px;bottom:8px;background:var(--card);border-radius:22px 22px 36px 36px;padding:10px 16px calc(8px + env(safe-area-inset-bottom,0));transform:translateY(105%);transition:transform .32s cubic-bezier(.32,.72,.24,1);z-index:901;max-height:82%;display:flex;flex-direction:column;box-shadow:0 -8px 40px rgba(0,0,0,.25)}\r\n .sheet.show{transform:translateY(0)}\r\n .sheet .grip{width:38px;height:4.5px;border-radius:999px;background:var(--line);margin:0 auto 12px;flex-shrink:0}\r\n .sheet .s-scroll{overflow-y:auto;flex:1;min-height:0;scrollbar-width:none;padding-bottom:66px}\r\n .sheet .s-scroll::-webkit-scrollbar{display:none}\r\n .sheet .s-head{display:flex;align-items:center;gap:3.5px;flex-wrap:wrap;margin-bottom:4px}\r\n .sheet .s-title{font-size:17px;font-weight:700;flex-basis:100%;line-height:1.3}\r\n .sheet .s-close{position:absolute;top:16px;right:16px;width:30px;height:30px;border-radius:50%;border:0;background:var(--bg);color:var(--fg3);font-size:15px;cursor:pointer;display:flex;align-items:center;justify-content:center}\r\n .sheet .prompt-box{background:#1d1d1d;color:#f5f5f7;border-radius:12px;padding:11px 13px;white-space:pre-wrap;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.65;margin-top:9px;word-break:break-all}\r\n .sheet .pform{margin-top:9px;background:var(--bg);border:1px solid var(--line);border-radius:12px;padding:9px 10px}\r\n .sheet .pfield{display:flex;align-items:center;gap:7px;margin-bottom:7px}\r\n .sheet .pfield:last-of-type{margin-bottom:0}\r\n .sheet .pfield label{font-size:12px;color:var(--fg2);font-weight:600;flex-shrink:0;min-width:72px}\r\n .sheet .pfield label em{color:var(--fg3);font-weight:400;font-size:9px}\r\n .sheet .pfield input{flex:1;min-width:0;border:1px solid var(--line);border-radius:9px;padding:8px 10px;font-size:13px;background:#fff;outline:none;font-family:inherit;color:var(--fg)}\r\n .sheet .pfield input:focus{border-color:var(--blue);box-shadow:0 0 0 2px rgba(0,122,255,.12)}\r\n /* 未填时:灰淡背景 + 提示文字(placeholder 由技能方提供)*/\r\n .sheet .pfield input:placeholder-shown{background:#f2f2f4;border-color:#e0e0e4;color:#8e8e93}\r\n .sheet .pfield input:placeholder-shown:focus{background:#fff;border-color:var(--blue)}\r\n .sheet .pprev{margin-top:9px;background:#1d1d1d;color:#f5f5f7;border-radius:12px;padding:11px 13px;font-size:12px;line-height:1.65;word-break:break-all;white-space:pre-wrap;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}\r\n .sheet .pprev .pv-label{font-size:9px;color:#8e8e93;display:block;letter-spacing:.05em;margin-bottom:4px}\r\n .sheet .s-actions{position:absolute;left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom,0));display:flex;gap:8px;flex-shrink:0}\r\n .sheet .s-actions .copy-btn{flex:1;min-height:48px;font-size:13px;font-weight:600;border-radius:12px;background:var(--blue);color:#fff;border:0;box-shadow:none}\r\n @media(max-width:500px){\r\n body{background:var(--bg)}\r\n .stage{padding:0;background:var(--bg)}\r\n /* #507 地址栏进出整屏跳动:老浏览器不懂 dvh 会整行丢弃,100vh 兜底须写在前 */\r\n .phone{width:100%;height:100vh;height:100dvh;border:0;border-radius:0;max-height:none;background:var(--bg);overflow:hidden}\r\n .screen{height:100%;overflow-y:auto;-webkit-overflow-scrolling:touch;background:var(--bg);overscroll-behavior-y:contain}\r\n .notch{display:none}\r\n .sheet-mask{left:0;right:0;top:0;bottom:0;border-radius:0}\r\n .sheet{left:0;right:0;bottom:0;border-radius:22px 22px 0 0}\r\n }\r\n /* ===== #642 小触摸目标:命中区扩到 ≥44×44(视觉尺寸一字不动)=====\r\n 覆盖层挂在按钮自己的 ::after 上(绝对定位不参与布局,不吃独立点击事件)——命中的仍是按钮本体,\r\n 故 [data-c] 点击委派与 .mini 卡片点击口径不变;三处图标键本已 position:absolute,只补 ::after,不再重复给 relative。 */\r\n .mini .copy-btn,.init-banner .copy-btn,.copy-btn.a-copy{position:relative}\r\n .mini .copy-btn::after,.init-banner .copy-btn::after,.copy-btn.a-copy::after{content:\"\";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:max(100%,44px);height:max(100%,44px)}\r\n .ib-close::after,.s-clear::after,.sheet .s-close::after{content:\"\";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:max(100%,44px);height:max(100%,44px)}\r\n</style>\r\n</head>\r\n<body>\r\n\r\n<div class=\"stage\">\r\n\r\n <div class=\"phone\"><div class=\"notch\"></div><div class=\"screen\" id=\"screen\"></div></div>\r\n\r\n <div class=\"sheet-mask\" id=\"sheetMask\"></div>\r\n <div class=\"sheet\" id=\"sheet\">\r\n <div class=\"grip\"></div>\r\n <button class=\"s-close\" id=\"sheetClose\">✕</button>\r\n <div class=\"s-scroll\">\r\n <div class=\"s-head\" id=\"shHead\"></div>\r\n <div id=\"shBody\"></div>\r\n </div>\r\n <div class=\"s-actions\">\r\n <button class=\"copy-btn\" id=\"shCopy\">复制</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"toast\" id=\"toast\" style=\"display:none\"></div>\r\n</div>\r\n\r\n<!-- 公共组件注入管线 -->\r\n<script id=\"help-data\" type=\"application/json\">";
31
31
  /** 壳后缀(help-data 配对 script 闭标签至源文末,含 helpers+共享 CSS+运行时,verbatim;改源跑 gen,禁手工改)。 */
32
- export const HELP_SHELL_SUFFIX = "</script>\r\n<script>\r\n/* Base Skill 控件库 v1.2(唯一真相源 · 跨技能 · 领域无关)\r\n * 契约: docs/component-contract.md v1.2\r\n * v1.2 核心(#269 试点用户拍板):\r\n * - snapshot 结构化接口: buildDataText/buildLogText 领域无关(title/summary/sections)\r\n * - toast 通用提示控件: 4 形态(徽章/操作/计数/留空)+ 队列 + 图标库 + 多操作 + 富详情 + 无障碍\r\n * - 复制按钮控件化: 复制数据/日志 = Base 控件;预览/格式选择/脱敏/导出\r\n * - 新控件 P0+P1: formPrompt/selectList/confirm/foldBox/statusBadge/emptyState/errorReceipt\r\n * - 结构校验违规直接报错(硬拦截)\r\n * 注入点: SHARED-HELPERS 占位符(由 injector.py 替换本文件)\r\n * 修改必须走公共层 ISSUE(总纲 09)+ CHANGELOG(见 docs/component-contract.md §8)\r\n */\r\n\r\n/* ── P0 守卫组 ── */\r\nfunction esc(s){return String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));}\r\nfunction arr(v){return Array.isArray(v)?v:[];}\r\nfunction val(v){return v===null||v===undefined||v===''?'<span style=\"color:var(--fg3)\">未填写</span>':esc(v);}\r\nfunction yes(v){return v?'<span class=\"ok\">通过</span>':'<span class=\"bad\">未通过</span>';}\r\nfunction validate(p){if(!p||typeof p!=='object')return{ok:false,msg:'数据未注入'};if(p.status!=='ok')return{ok:false,msg:p.message||'数据状态非 ok'};if(!p.data||typeof p.data!=='object')return{ok:false,msg:'data 缺失'};return{ok:true};}\r\nfunction _fbCopy(s){var ok=false;try{var t=document.createElement('textarea');t.value=s;t.style.cssText='position:fixed;left:-9999px;top:0;opacity:0';document.body.appendChild(t);t.focus();t.select();ok=document.execCommand('copy');document.body.removeChild(t);}catch(e){ok=false;}return ok;}\r\n\r\n/* ── 复制动作 v2(不改按钮文字 + toast 反馈 · v1.10 #328 文案钩子)──\r\n * copyText(s, opts?)\r\n * opts: { silent, toast:{ok:{msg,detail,icon?}, fail:{msg,detail,icon?}}, onOk, onFail }\r\n * - toast 文案配置: 只覆盖提供的字段, 缺省回落默认文案(08 规范: 文案由技能按场景自设计)\r\n * - onOk/onFail 回调: 成功/最终失败必触发; silent 时不弹 toast 仍触发回调\r\n * - 未传新选项: 行为与 v1.9 逐字一致(向后兼容)\r\n */\r\nfunction copyText(s, opts){\r\n opts = opts || {};\r\n if(!s) return;\r\n var t = opts.toast || {}, okCfg = t.ok || {}, failCfg = t.fail || {};\r\n var okMsg = okCfg.msg !== undefined ? okCfg.msg : '已复制';\r\n var okDetail = okCfg.detail !== undefined ? okCfg.detail : '粘贴给 AI';\r\n var failMsg = failCfg.msg !== undefined ? failCfg.msg : '复制失败';\r\n var failDetail = failCfg.detail !== undefined ? failCfg.detail : '长按选择文本手动复制';\r\n function ok(){\r\n if(opts.onOk) opts.onOk();\r\n if(!opts.silent){\r\n var o = {};\r\n if(okCfg.icon) o.icon = okCfg.icon;\r\n toast(okMsg, okDetail, Object.keys(o).length ? o : undefined);\r\n }\r\n }\r\n function fail(){\r\n if(opts.onFail) opts.onFail();\r\n if(!opts.silent){\r\n var o = {badge:{text:'失败',type:'danger'}};\r\n if(failCfg.icon) o.icon = failCfg.icon;\r\n toast(failMsg, failDetail, o);\r\n }\r\n }\r\n if(navigator.clipboard&&navigator.clipboard.writeText){\r\n try{\r\n var pr=navigator.clipboard.writeText(s);\r\n if(pr&&pr.then){pr.then(function(){ok();}).catch(function(){_fbCopy(s)?ok():fail();});}\r\n else{ok();}\r\n }catch(e){_fbCopy(s)?ok():fail();}\r\n }else{_fbCopy(s)?ok():fail();}\r\n}\r\n\r\n/* ── toast 通用提示控件 v1.8(堆叠模式 · #304)──\r\n * toast(msg, detail?, options?)\r\n * options: { icon, badge:{text,type}, actions:[{label,onClick}], count, lines:[], code, timeout, maxStack }\r\n * 向后兼容: toast(msg, detail) = 等价 v1.1\r\n * 堆叠模式(v1.8 · #304 用户拍板): 同屏最多 N 条同时可见(N 默认 5, opts.maxStack 可配,\r\n * 栈容量取栈内各 toast maxStack 最大值; ≤820px 视口自动收窄为 3); 老上旧下(新 toast\r\n * 贴屏幕底部出现, 旧的向上顶, 间距 8px); 超 N 挤掉最旧(FIFO); 单条独立计时消失\r\n */\r\n(function(){\r\n var stack = null;\r\n var styleInjected = false;\r\n var DEFAULT_MAX = 5;\r\n var MOBILE_MAX = 3;\r\n var ICONS = { copy:'📋', ok:'✅', warn:'⚠️', danger:'❌', info:'💡' };\r\n var CSS = '.hm-toast-stack{position:fixed;left:50%;bottom:calc(24px + env(safe-area-inset-bottom,0));transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;gap:8px;z-index:9999;pointer-events:none}.hm-toast{position:relative;transform:scale(.9);opacity:0;background:rgba(28,28,30,.94);-webkit-backdrop-filter:blur(20px) saturate(180%);backdrop-filter:blur(20px) saturate(180%);color:#f0f0f0;border-radius:14px;padding:13px 14px 13px 16px;display:flex;align-items:flex-start;gap:12px;max-width:480px;min-width:300px;box-shadow:0 10px 32px rgba(0,0,0,.32),0 0 0 .5px rgba(255,255,255,.08) inset;pointer-events:none;transition:opacity .22s ease-out,transform .22s cubic-bezier(.34,1.56,.64,1)}.hm-toast.show{opacity:1;transform:scale(1);pointer-events:auto}.hm-toast-icon{font-size:20px;line-height:1;padding-top:1px;flex-shrink:0}.hm-toast-body{flex:1;min-width:0}.hm-toast-title-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.hm-toast-title{font-weight:600;font-size:12.5px;line-height:1.4;color:#fff;margin-bottom:2px}.hm-toast-detail{font-size:11px;line-height:1.5;color:#c8c8cc}.hm-toast-lines{font-size:11px;line-height:1.55;color:#c8c8cc}.hm-toast-code{background:rgba(0,0,0,.32);border-radius:8px;padding:8px 10px;font-size:10.5px;line-height:1.5;color:#aeb0b8;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;margin-top:6px;max-height:140px;overflow:auto}.hm-toast-chip{font-size:10px;font-weight:700;padding:2px 8px;border-radius:999px;letter-spacing:.02em;flex-shrink:0}.hm-toast-chip.ok{background:rgba(52,199,89,.18);color:#4dd96b}.hm-toast-chip.warn{background:rgba(255,149,0,.18);color:#ffb340}.hm-toast-chip.danger{background:rgba(255,59,48,.18);color:#ff6961}.hm-toast-chip.gray{background:rgba(255,255,255,.12);color:#c8c8cc}.hm-toast-count{font-size:10px;font-weight:700;color:#c8c8cc;background:rgba(255,255,255,.08);padding:2px 8px;border-radius:6px;font-variant-numeric:tabular-nums;flex-shrink:0}.hm-toast-act{font-size:11px;font-weight:600;color:#4dd96b;border:none;background:none;cursor:pointer;padding:2px 4px;flex-shrink:0;font-family:inherit}.hm-toast-act:active{opacity:.7}.hm-toast-close{background:rgba(255,255,255,.10);color:#34c759;border:0;border-radius:8px;padding:5px 9px;font-size:10.5px;font-weight:500;font-family:inherit;cursor:pointer;white-space:nowrap;margin-left:6px;flex-shrink:0}.hm-toast-close:active{background:rgba(255,255,255,.2)}@media(max-width:820px){.hm-toast-stack{left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom,0));transform:none;align-items:stretch}.hm-toast{transform:scale(.95);max-width:none;min-width:0}.hm-toast.show{transform:scale(1)}}';\r\n\r\n function ensureStyle(){\r\n if(styleInjected) return;\r\n styleInjected = true;\r\n var st = document.createElement('style');\r\n st.id = 'hm-toast-style';\r\n st.textContent = CSS;\r\n document.head.appendChild(st);\r\n }\r\n\r\n function getStack(){\r\n if(!stack){\r\n stack = document.createElement('div');\r\n /* 栈要带 CSS 那条 fixed 定位规则的选择器类名(`.hm-toast-stack`):只写 id 时提示落在文档流末尾,不悬浮。 */\r\n stack.className = 'hm-toast-stack';\r\n stack.id = 'hm-toast-stack';\r\n document.body.appendChild(stack);\r\n }\r\n return stack;\r\n }\r\n\r\n function isMobile(){\r\n return window.matchMedia('(max-width: 820px)').matches;\r\n }\r\n\r\n /* 栈容量 = 栈内各 toast maxStack 的最大值(空栈默认 5); 移动端 ≤820px 收窄为 3 */\r\n function stackCap(){\r\n var cap = 0;\r\n if(stack) stack.querySelectorAll('.hm-toast').forEach(function(t){\r\n var m = parseInt(t.getAttribute('data-max')||DEFAULT_MAX, 10);\r\n if(m > cap) cap = m;\r\n });\r\n if(cap === 0) cap = DEFAULT_MAX;\r\n if(isMobile() && cap > MOBILE_MAX) cap = MOBILE_MAX;\r\n return cap;\r\n }\r\n\r\n /* 超 N 挤掉最旧(FIFO) */\r\n function evictOldest(){\r\n var cap = stackCap();\r\n while(stack.querySelectorAll('.hm-toast').length > cap){\r\n var oldest = stack.querySelector('.hm-toast');\r\n if(!oldest) break;\r\n clearTimeout(oldest._timer);\r\n oldest.remove();\r\n }\r\n }\r\n\r\n function dismiss(t){\r\n if(!t || !t.isConnected) return;\r\n clearTimeout(t._timer);\r\n t.classList.remove('show');\r\n setTimeout(function(){\r\n if(t.isConnected) t.remove();\r\n }, 250);\r\n }\r\n\r\n function show(item){\r\n var opts = item.opts;\r\n var container = getStack();\r\n ensureStyle();\r\n var msg = item.msg, detail = item.detail;\r\n var t = document.createElement('div');\r\n t.className = 'hm-toast';\r\n t.setAttribute('role','status');\r\n t.setAttribute('aria-live','polite');\r\n t.setAttribute('data-max', String(opts.maxStack || DEFAULT_MAX));\r\n var icon = ICONS[opts.icon] || opts.icon || '📋';\r\n var titleRow = '<span class=\"hm-toast-title\">'+esc(msg)+'</span>';\r\n if(opts.badge){\r\n var b = opts.badge;\r\n var btype = ['ok','warn','danger'].indexOf(b.type)>=0 ? b.type : 'ok';\r\n titleRow += '<span class=\"hm-toast-chip '+btype+'\">'+esc(b.text)+'</span>';\r\n }\r\n if(opts.count){\r\n titleRow += '<span class=\"hm-toast-count\">'+esc(opts.count)+'</span>';\r\n }\r\n if(opts.actions && opts.actions.length){\r\n opts.actions.slice(0,2).forEach(function(a){\r\n titleRow += '<button class=\"hm-toast-act\" data-act=\"'+esc(a.label)+'\">'+esc(a.label)+'</button>';\r\n });\r\n }\r\n var bodyHtml = '<div class=\"hm-toast-title-row\">'+titleRow+'</div>';\r\n if(detail){\r\n bodyHtml += '<div class=\"hm-toast-detail\">'+esc(detail)+'</div>';\r\n }\r\n if(opts.lines && opts.lines.length){\r\n bodyHtml += '<div class=\"hm-toast-lines\">'+opts.lines.map(function(l){return esc(l);}).join('<br>')+'</div>';\r\n }\r\n if(opts.code){\r\n bodyHtml += '<div class=\"hm-toast-code\">'+esc(opts.code)+'</div>';\r\n }\r\n t.innerHTML = '<div class=\"hm-toast-icon\">'+icon+'</div><div class=\"hm-toast-body\">'+bodyHtml+'</div><button class=\"hm-toast-close\">✓ 知道了</button>';\r\n container.appendChild(t);\r\n evictOldest();\r\n if(opts.actions && opts.actions.length){\r\n var actBtns = t.querySelectorAll('.hm-toast-act');\r\n opts.actions.slice(0,2).forEach(function(a, i){\r\n actBtns[i].addEventListener('click', function(){\r\n var f = a.onClick;\r\n dismiss(t);\r\n if(f) setTimeout(f, 0);\r\n });\r\n });\r\n }\r\n t.querySelector('.hm-toast-close').addEventListener('click', function(){ dismiss(t); });\r\n var timer = setTimeout(function(){ dismiss(t); }, opts.timeout || 4500);\r\n t._timer = timer;\r\n requestAnimationFrame(function(){ t.classList.add('show'); });\r\n }\r\n\r\n window" + ".toast = function(msg, detail, options){\r\n options = options || {};\r\n show({ msg: msg, detail: detail || '', opts: options });\r\n };\r\n /* 清空栈(技能页面销毁/测试用):移除当前全部显示 */\r\n window" + ".__hmToastFlush = function(){\r\n if(!stack) return;\r\n stack.querySelectorAll('.hm-toast').forEach(function(t){ clearTimeout(t._timer); t.remove(); });\r\n };\r\n})();\r\n\r\n/* ── snapshot 结构校验(违规直接报错)── */\r\nfunction _validateSnapshot(s){\r\n if(!s || typeof s !== 'object'){\r\n throw new Error('snapshot 违规: scene.snapshot 必须是对象');\r\n }\r\n if(typeof s.title !== 'string' || !s.title.trim()){\r\n throw new Error('snapshot 违规: title 必须是非空字符串');\r\n }\r\n if(!Array.isArray(s.summary)){\r\n throw new Error('snapshot 违规: summary 必须是数组');\r\n }\r\n if(!Array.isArray(s.sections)){\r\n throw new Error('snapshot 违规: sections 必须是数组');\r\n }\r\n s.sections.forEach(function(sec, i){\r\n if(!sec || typeof sec !== 'object' || typeof sec.heading !== 'string' || !Array.isArray(sec.rows)){\r\n throw new Error('snapshot 违规: sections['+i+'] 必须含 heading(字符串) + rows(数组)');\r\n }\r\n });\r\n return true;\r\n}\r\n\r\n/* 行渲染: 支持字符串 或 {text, sensitive}(脱敏)*/\r\nfunction _rowText(r){\r\n if(r && typeof r === 'object' && !Array.isArray(r)){\r\n if(r.sensitive) return '****(敏感字段已脱敏)';\r\n return String(r.text ?? '');\r\n }\r\n return String(r ?? '');\r\n}\r\n\r\n/* ── buildDataText v1.2(snapshot 结构化 · 领域无关 · format 支持)──\r\n * buildDataText(p, format?) format: 'text'(默认) | 'json' | 'csv'\r\n */\r\nfunction buildDataText(p, format){\r\n var d = p && p.data || {};\r\n var me = d.meta || {};\r\n var s = d.scene || {};\r\n var snap = s.snapshot;\r\n _validateSnapshot(snap);\r\n format = format || 'text';\r\n\r\n if(format === 'json'){\r\n return JSON.stringify(snap, null, 2);\r\n }\r\n if(format === 'csv'){\r\n var out = [];\r\n out.push(snap.title);\r\n out.push(snap.summary.map(_rowText).join('; '));\r\n snap.sections.forEach(function(sec){\r\n out.push('[' + sec.heading + ']');\r\n sec.rows.forEach(function(r){ out.push(_rowText(r)); });\r\n });\r\n return out.join('\\n');\r\n }\r\n\r\n var L = ['【'+(me.skill_name||me.command_cn||'')+' · '+(me.command_cn||'')+'】'];\r\n L.push('场景: '+(me.command_cn||'')+(s.scene_id?('('+s.scene_id+')'):'')+(me.wake_word?(' · 唤醒词「'+me.wake_word+'」'):''));\r\n L.push('时间: '+(me.occurred_at||''));\r\n if(snap.summary.length){\r\n snap.summary.forEach(function(x){ L.push(_rowText(x)); });\r\n }\r\n snap.sections.forEach(function(sec){\r\n if(!sec.rows.length) return;\r\n L.push('▍'+sec.heading);\r\n sec.rows.forEach(function(r){ L.push(' · '+_rowText(r)); });\r\n });\r\n return L.join('\\n');\r\n}\r\n\r\n/* ── buildLogText v1.2(6 段日志 · format 支持)── */\r\nfunction buildLogText(p, format){\r\n var d = p && p.data || {};\r\n var me = d.meta || {};\r\n var s = d.scene || {};\r\n var cl = d.copy_log || s.copy_log || {};\r\n format = format || 'text';\r\n\r\n var L = ['① 场景标识'];\r\n L.push(' 命 令: '+(me.command_cn||''));\r\n L.push(' 唤醒词: '+(me.wake_word||'(未知)'));\r\n L.push(' 场景名: '+(me.command_cn||'')+(s.scene_id?('('+s.scene_id+')'):''));\r\n L.push('');\r\n L.push('② AI 思考链');\r\n L.push(' '+(cl.thinking||'(本地渲染 · 无 AI 链)'));\r\n L.push('');\r\n L.push('③ 底层数据结构');\r\n L.push(' '+(cl.data_structure||'(只读查询)'));\r\n L.push('');\r\n L.push('④ 调用链');\r\n L.push(' '+(cl.call_chain||'(未知)'));\r\n L.push('');\r\n L.push('⑤ 时间戳 + 版本');\r\n L.push(' 本地时间: '+(cl.timestamp||me.occurred_at||'(未知)'));\r\n L.push(' 版 本: '+(me.skill_version||'(未知)'));\r\n L.push('');\r\n L.push('⑥ 异常信息');\r\n L.push(' '+(cl.exception||'无'));\r\n return L.join('\\n');\r\n}\r\n\r\n/* ── metaHeader / remindersBlock(v1.1 保留)── */\r\nfunction metaHeader(p, m){var me=p.data.meta||{};var stage=m&&m.stage?('<span class=\"stage\">'+esc(m.stage)+'</span>'):'';return '<header class=\"hero\"><div class=\"eyebrow\" style=\"color:#8e8e93;font-size:11px;font-weight:600\">'+esc(me.command_cn||'')+' · '+esc(me.occurred_at||'')+'</div><h1>'+esc(m&&m.title||me.command_cn||'')+'</h1>'+(m&&m.lead?'<p class=\"lead\">'+esc(m.lead)+'</p>':'')+stage+'</header>';}\r\nfunction remindersBlock(p){var rs=arr(p.data.reminders);if(!rs.length)return '';return '<section class=\"remind\"><h2>顺路提醒</h2>'+rs.map(r=>'<div class=\"remind-item '+(r.type==='warn'?'warn':r.type==='danger'?'bad':'')+'\">'+esc(r.text)+'</div>').join('')+'</section>';}\r\n\r\n/* ── actionBar v1.2(场景按钮 + 复制数据/日志 ghost)──\r\n * actionBar(p, extra?, opts?) opts: { preview, formatMenu, download }\r\n */\r\nfunction actionBar(p, extra, opts){\r\n window" + ".__hmPayload = p;\r\n opts = opts || {};\r\n var btns = arr(extra || []);\r\n var sb = opts.noSb ? [] : arr(p && p.data && p.data.scene && p.data.scene.buttons || []);\r\n var html = '<div class=\"hm-actions\">';\r\n btns.concat(sb).forEach(function(b){\r\n html += '<button class=\"copy '+(b.kind||'')+'\" onclick=\"copyText(this.dataset.t)\" data-t=\"'+esc(b.text).replace(/\"/g,'&quot;')+'\">'+esc(b.label)+'</button>';\r\n });\r\n html += '<button class=\"copy ghost\" onclick=\"'+(opts.preview?'window.__hmCopyData(true)':'copyText(buildDataText(window.__hmPayload))')+'\">复制数据</button>';\r\n html += '<button class=\"copy ghost\" onclick=\"'+(opts.preview?'window.__hmCopyLog(true)':'copyText(buildLogText(window.__hmPayload))')+'\">复制日志</button>';\r\n html += '</div>';\r\n if(opts.preview){\r\n html += '<div class=\"hm-preview-overlay\" id=\"hm-preview\" style=\"display:none\">'\r\n + '<div class=\"hm-preview-panel\"><div class=\"hm-preview-head\"><span id=\"hm-preview-title\">复制预览</span>'\r\n + '<button class=\"hm-preview-close\" onclick=\"document.getElementById(\\'hm-preview\\').style.display=\\'none\\'\">✕</button></div>'\r\n + '<pre class=\"hm-preview-body\" id=\"hm-preview-body\"></pre>'\r\n + '<div class=\"hm-preview-actions\"><button class=\"copy primary\" id=\"hm-preview-confirm\">复制</button>'\r\n + '<button class=\"copy\" onclick=\"document.getElementById(\\'hm-preview\\').style.display=\\'none\\'\">取消</button></div>'\r\n + '</div></div>';\r\n }\r\n return html;\r\n}\r\n\r\n/* 复制预览面板(actionBar preview 模式) */\r\nfunction _showCopyPreview(kind){\r\n var p = window.__hmPayload;\r\n var body = document.getElementById('hm-preview-body');\r\n var title = document.getElementById('hm-preview-title');\r\n if(!body) return;\r\n var text = kind === 'log' ? buildLogText(p) : buildDataText(p);\r\n title.textContent = kind === 'log' ? '复制日志 · 预览' : '复制数据 · 预览';\r\n body.textContent = text;\r\n document.getElementById('hm-preview').style.display = 'flex';\r\n document.getElementById('hm-preview-confirm').onclick = function(){\r\n copyText(text);\r\n document.getElementById('hm-preview').style.display = 'none';\r\n };\r\n}\r\nwindow" + ".__hmCopyData = function(){ _showCopyPreview('data'); };\r\nwindow" + ".__hmCopyLog = function(){ _showCopyPreview('log'); };\r\n\r\n/* ── formPrompt(P0 · 用户填参数表单 + 实时预览 + 空值拦截)──\r\n * formPrompt(fields, template) → HTML 字符串\r\n * fields: [{ key, label, type:'text'|'number'|'select', options?, default?, placeholder? }]\r\n * template: 含 {key} 占位符的 prompt 模板\r\n */\r\nfunction formPrompt(fields, template){\r\n fields = arr(fields);\r\n var uid = 'fp' + Math.random().toString(36).slice(2,7);\r\n var html = '<div class=\"fp\" id=\"'+uid+'\">';\r\n fields.forEach(function(f, i){\r\n var fid = uid + '-f' + i;\r\n html += '<div class=\"fp-field\"><label class=\"fp-label\">'+esc(f.label)+'</label>';\r\n if(f.type === 'select'){\r\n html += '<select class=\"fp-input\" id=\"'+fid+'\" data-key=\"'+esc(f.key)+'\">';\r\n arr(f.options).forEach(function(o){\r\n var sel = (String(o.value ?? o) === String(f.default ?? '')) ? ' selected' : '';\r\n html += '<option value=\"'+esc(o.value ?? o)+'\"'+sel+'>'+esc(o.label ?? o)+'</option>';\r\n });\r\n html += '</select>';\r\n } else {\r\n html += '<input class=\"fp-input\" id=\"'+fid+'\" type=\"'+(f.type==='number'?'number':'text')+'\" data-key=\"'+esc(f.key)+'\" value=\"'+esc(f.default ?? '')+'\" placeholder=\"'+esc(f.placeholder ?? '')+'\">';\r\n }\r\n html += '</div>';\r\n });\r\n html += '<div class=\"fp-preview\"><div class=\"fp-preview-label\">Prompt 预览</div><pre class=\"fp-preview-body\" id=\"'+uid+'-preview\"></pre></div>';\r\n html += '<div class=\"fp-actions\"><button class=\"copy primary\" id=\"'+uid+'-btn\">复制指令</button></div>';\r\n html += '</div>';\r\n\r\n function renderPreview(){\r\n var vals = {};\r\n fields.forEach(function(f, i){\r\n var el = document.getElementById(uid + '-f' + i);\r\n vals[f.key] = el ? el.value : '';\r\n });\r\n var text = String(template || '').replace(/\\{(\\w+)\\}/g, function(_, k){ return vals[k] ?? ''; });\r\n document.getElementById(uid + '-preview').textContent = text;\r\n var btn = document.getElementById(uid + '-btn');\r\n var emptyRequired = fields.some(function(f){ return f.required && !vals[f.key]; });\r\n if(emptyRequired){\r\n btn.disabled = true;\r\n btn.textContent = '请填写必填项';\r\n } else {\r\n btn.disabled = false;\r\n btn.textContent = '复制指令';\r\n }\r\n }\r\n\r\n setTimeout(function(){\r\n fields.forEach(function(f, i){\r\n var el = document.getElementById(uid + '-f' + i);\r\n if(el){\r\n el.addEventListener('input', renderPreview);\r\n el.addEventListener('change', renderPreview);\r\n }\r\n });\r\n document.getElementById(uid + '-btn').addEventListener('click', function(){\r\n if(this.disabled) { toast('请先填写','必填字段未填写',{badge:{text:'提示',type:'warn'}}); return; }\r\n var text = document.getElementById(uid + '-preview').textContent;\r\n copyText(text);\r\n });\r\n renderPreview();\r\n }, 0);\r\n\r\n return html;\r\n}\r\n\r\n/* ── selectList(P0 · 勾选列表 + 批量操作 + 计数联动 + 行内控件 v1.9)──\r\n * selectList(items, batchActions?, opts?)\r\n * items: [{ id, title, sub?, group?, widget? }]\r\n * widget(v1.9 · #327): { type:'date'|'text'|'select', key, label?, placeholder?, options? }\r\n * - options: [ {value,label} | '原始值' ](select 用; 缺省渲染占位「请选择」)\r\n * - 非法 type 降级 text(宽容渲染, 不报错); key 缺省 'w'+行号\r\n * batchActions: [{ label, kind:'ok'|'danger', onClick(ids, values?) }]\r\n * - v1.9: onClick 第二参 values = 勾选条目对应的行内值 { [id]: { [key]: value } }\r\n * (只读勾选条目; 未填 → null, 不报错; 未勾选条目不参与)\r\n * opts: { onSubmit(selectedIds, values) } —— v1.9 读取接口(选定形态, 等价 getValues)\r\n * - 任意批量操作按钮点击后触发(与 onClick 并列; 无勾选时不触发, 与既有拦截一致)\r\n * - values = 全部行内值 { [id]: { [key]: value } }(含未勾选条目; 未填 → null; 无 widget 条目不出现)\r\n * 安全: 行内 label/placeholder/option value+label 渲染一律 esc, 零注入面\r\n * 兼容: 未声明 widget 的既有调用渲染输出与行为完全不变(守卫测试回归 outerHTML)\r\n */\r\nfunction selectList(items, batchActions, opts){\r\n items = arr(items);\r\n batchActions = arr(batchActions);\r\n opts = opts || {};\r\n var uid = 'sl' + Math.random().toString(36).slice(2,7);\r\n var groups = {};\r\n items.forEach(function(it){\r\n var g = it.group || '';\r\n (groups[g] = groups[g] || []).push(it);\r\n });\r\n var groupNames = Object.keys(groups);\r\n\r\n /* 行内控件 HTML(v1.9 · #327): 未声明 widget → 空串, 渲染零变化 */\r\n function widgetHtml(it, idx){\r\n var w = it.widget;\r\n if(!w || typeof w !== 'object') return '';\r\n var t = w.type === 'date' ? 'date' : (w.type === 'select' ? 'select' : 'text'); // 非法 type 降级 text\r\n var key = w.key != null ? String(w.key) : ('w' + idx);\r\n var lbl = w.label ? '<span class=\"sl-widget-label\">'+esc(w.label)+'</span>' : '';\r\n var inner;\r\n if(t === 'select'){\r\n inner = '<select class=\"sl-widget-input\" data-wkey=\"'+esc(key)+'\">';\r\n var os = arr(w.options);\r\n if(!os.length) inner += '<option value=\"\">请选择</option>';\r\n os.forEach(function(o){\r\n var ov = (o && typeof o === 'object') ? (o.value != null ? o.value : o.label) : o;\r\n var ol = (o && typeof o === 'object') ? (o.label != null ? o.label : o.value) : o;\r\n inner += '<option value=\"'+esc(String(ov == null ? '' : ov))+'\">'+esc(String(ol == null ? '' : ol))+'</option>';\r\n });\r\n inner += '</select>';\r\n } else {\r\n inner = '<input class=\"sl-widget-input\" data-wkey=\"'+esc(key)+'\" type=\"'+t+'\"'\r\n + (w.placeholder ? ' placeholder=\"'+esc(w.placeholder)+'\"' : '')\r\n + '>';\r\n }\r\n return '<span class=\"sl-widget\">'+lbl+inner+'</span>';\r\n }\r\n\r\n var html = '<div class=\"sl\" id=\"'+uid+'\">';\r\n if(batchActions.length){\r\n html += '<div class=\"sl-batchbar\" id=\"'+uid+'-batch\">';\r\n batchActions.forEach(function(a){\r\n html += '<button class=\"copy '+(a.kind==='danger'?'red':'primary')+'\" data-batch=\"'+esc(a.label)+'\">'+esc(a.label)+'</button>';\r\n });\r\n html += '<span class=\"sl-count\" id=\"'+uid+'-count\">已选 0/'+items.length+'</span>';\r\n html += '</div>';\r\n }\r\n groupNames.forEach(function(g){\r\n var gItems = groups[g];\r\n html += '<div class=\"sl-group\"><div class=\"sl-group-head\">'+esc(g||'全部');\r\n html += ' <span class=\"sl-group-count\">本组已选 0/'+gItems.length+'</span></div>';\r\n html += '<div class=\"sl-group-items\">';\r\n gItems.forEach(function(it, idx){\r\n html += '<label class=\"sl-item\"><input type=\"checkbox\" data-id=\"'+esc(it.id)+'\" data-g=\"'+esc(g)+'\">'\r\n + '<span class=\"sl-item-body\"><span class=\"sl-item-title\">'+esc(it.title)+'</span>'\r\n + (it.sub?'<span class=\"sl-item-sub\">'+esc(it.sub)+'</span>':'')\r\n + widgetHtml(it, idx)\r\n + '</span></label>';\r\n });\r\n html += '</div></div>';\r\n });\r\n html += '</div>';\r\n\r\n setTimeout(function(){\r\n var root = document.getElementById(uid);\r\n var checkboxes = root.querySelectorAll('input[type=\"checkbox\"]');\r\n var globalCount = document.getElementById(uid + '-count');\r\n function update(){\r\n var total = checkboxes.length;\r\n var checked = root.querySelectorAll('input[type=\"checkbox\"]:checked').length;\r\n if(globalCount) globalCount.textContent = '已选 '+checked+'/'+total;\r\n root.querySelectorAll('.sl-group').forEach(function(gEl){\r\n var boxes = gEl.querySelectorAll('input[type=\"checkbox\"]');\r\n var c = gEl.querySelectorAll('input[type=\"checkbox\"]:checked').length;\r\n var lbl = gEl.querySelector('.sl-group-count');\r\n if(lbl) lbl.textContent = '本组已选 '+c+'/'+boxes.length;\r\n });\r\n return checked;\r\n }\r\n checkboxes.forEach(function(cb){\r\n cb.addEventListener('change', update);\r\n });\r\n /* 行内值读取(v1.9 · #327): 计数只随勾选态, 控件值变化不干扰 */\r\n function widgetVal(el){\r\n var v = el.value;\r\n return (v === '' || v === null || v === undefined) ? null : v; // 未填统一归一 null\r\n }\r\n function readAll(){\r\n var out = {};\r\n root.querySelectorAll('.sl-item').forEach(function(itemEl){\r\n var cb = itemEl.querySelector('input[type=\"checkbox\"]');\r\n var id = cb ? cb.getAttribute('data-id') : null;\r\n if(id == null) return;\r\n itemEl.querySelectorAll('.sl-widget-input').forEach(function(el){\r\n var key = el.getAttribute('data-wkey');\r\n if(key == null) return;\r\n (out[id] = out[id] || {})[key] = widgetVal(el);\r\n });\r\n });\r\n return out;\r\n }\r\n function readChecked(){\r\n var out = {};\r\n root.querySelectorAll('input[type=\"checkbox\"]:checked').forEach(function(cb){\r\n var id = cb.getAttribute('data-id');\r\n var itemEl = cb.closest('.sl-item');\r\n itemEl.querySelectorAll('.sl-widget-input').forEach(function(el){\r\n var key = el.getAttribute('data-wkey');\r\n if(key == null) return;\r\n (out[id] = out[id] || {})[key] = widgetVal(el);\r\n });\r\n });\r\n return out;\r\n }\r\n root.querySelectorAll('[data-batch]').forEach(function(btn){\r\n btn.addEventListener('click', function(){\r\n var ids = root.querySelectorAll('input[type=\"checkbox\"]:checked');\r\n if(!ids.length){ toast('请先勾选','勾选要处理的条目',{badge:{text:'提示',type:'warn'}}); return; }\r\n var idList = Array.prototype.map.call(ids, function(x){ return x.getAttribute('data-id'); });\r\n var a = batchActions.filter(function(x){ return x.label === btn.getAttribute('data-batch'); })[0];\r\n if(a && a.onClick) a.onClick(idList, readChecked()); // v1.9: 第二参 = 勾选条目行内值\r\n if(opts.onSubmit) opts.onSubmit(idList, readAll()); // v1.9: 读取接口 = 全部行内值\r\n });\r\n });\r\n update();\r\n }, 0);\r\n\r\n return html;\r\n}\r\n\r\n/* ── confirm(P0 · 危险操作二次确认)──\r\n * confirm({ title, detail?, danger?, onOk })\r\n */\r\nfunction confirm(cfg){\r\n cfg = cfg || {};\r\n var overlay = document.createElement('div');\r\n overlay.className = 'hm-confirm-overlay';\r\n overlay.innerHTML = '<div class=\"hm-confirm-panel\">'\r\n + '<div class=\"hm-confirm-title\">'+(cfg.danger?'⚠️ ':'')+esc(cfg.title||'确认操作')+'</div>'\r\n + (cfg.detail?'<div class=\"hm-confirm-detail\">'+esc(cfg.detail)+'</div>':'')\r\n + '<div class=\"hm-confirm-actions\">'\r\n + '<button class=\"copy '+(cfg.danger?'red':'primary')+'\" data-c=\"1\">'+(cfg.danger?'确认删除':'确认')+'</button>'\r\n + '<button class=\"copy\" data-c=\"0\">取消</button>'\r\n + '</div></div>';\r\n document.body.appendChild(overlay);\r\n overlay.querySelector('[data-c=\"1\"]').addEventListener('click', function(){\r\n overlay.remove();\r\n if(cfg.onOk) cfg.onOk();\r\n });\r\n overlay.querySelector('[data-c=\"0\"]').addEventListener('click', function(){ overlay.remove(); });\r\n overlay.addEventListener('click', function(e){\r\n if(e.target === overlay) overlay.remove();\r\n });\r\n}\r\n\r\n/* ── foldBox(P1 · 折叠区)── */\r\nfunction foldBox(title, contentHtml){\r\n return '<details class=\"hm-fold\"><summary>'+esc(title)+'</summary><div class=\"hm-fold-body\">'+(contentHtml||'')+'</div></details>';\r\n}\r\n\r\n/* ── statusBadge(P1 · 状态徽章)──\r\n * statusBadge(status, text?)\r\n * status: 'ok'|'warn'|'danger'|'empty'(非法值降级 'empty', 防无样式徽章)\r\n * text: 自定义文案(缺省用语义默认: 成功/警告/失败/无数据)\r\n * 安全: status 白名单后直拼 class(无注入面); text 经 esc\r\n */\r\nvar STATUS_BADGE_MAP = { ok:'成功', warn:'警告', danger:'失败', empty:'无数据' };\r\nfunction statusBadge(status, text){\r\n status = STATUS_BADGE_MAP[status] ? status : 'empty'; // 非法/未知值降级 empty\r\n var txt = (text === null || text === undefined || text === '') ? STATUS_BADGE_MAP[status] : String(text);\r\n return '<span class=\"hm-status '+status+'\">'+esc(txt)+'</span>';\r\n}\r\n\r\n/* ── emptyState(P1 · 空状态)──\r\n * emptyState({icon?, text, hint?, action?})\r\n * icon: emoji/文本图标(esc)\r\n * text: 主文案(缺省 '暂无数据', esc)\r\n * hint: 次要提示(esc)\r\n * action: 操作区 HTML —— 受信 HTML 透传(调用方负责其内容安全, 通常为按钮;\r\n * 如含用户数据必须先 esc)。其余字段一律 esc, 防 XSS。\r\n */\r\nfunction emptyState(cfg){\r\n cfg = cfg || {};\r\n return '<div class=\"hm-empty\">'\r\n + (cfg.icon?'<div class=\"hm-empty-icon\">'+esc(cfg.icon)+'</div>':'')\r\n + '<div class=\"hm-empty-text\">'+esc(cfg.text||'暂无数据')+'</div>'\r\n + (cfg.hint?'<div class=\"hm-empty-hint\">'+esc(cfg.hint)+'</div>':'')\r\n + (cfg.action?('<div class=\"hm-empty-action\">'+cfg.action+'</div>'):'')\r\n + '</div>';\r\n}\r\n\r\n/* ── errorReceipt(P1 · 错误回执 · 08 规范 §6.1 三层反馈)──\r\n * errorReceipt({message, retryPrompt?, data?, log?, payload?})\r\n * message: 错误描述(esc, 缺省 '操作失败')\r\n * retryPrompt: 修正重试按钮文案(有则渲染「修正重试」按钮, 复制该 prompt)\r\n * data: 复制数据按钮内容(字符串直传; 或省略时从 payload 生成)\r\n * log: 复制日志按钮内容(字符串直传; 或省略时从 payload 生成)\r\n * payload: 数据信封 {status, data:{meta, scene}} —— 显式传入, 优先于全局\r\n * __hmPayload: 兼容全局兜底(actionBar 已设置; 显式 payload 优先)\r\n * 布局: 修正重试 primary 独立一行 + 复制数据/日志 ghost 一行 2 个(08 规范奇数按钮)\r\n * 安全: message/data/log 经 esc + data-t 中转(onclick 仅 copyText(this.dataset.t), 零注入面)\r\n */\r\nfunction errorReceipt(cfg){\r\n cfg = cfg || {};\r\n var payload = cfg.payload || window.__hmPayload || null;\r\n var dataText = cfg.data != null ? String(cfg.data) : '';\r\n var logText = cfg.log != null ? String(cfg.log) : '';\r\n // 有效数据源 = payload 含 scene.snapshot(残缺 payload 视为无数据, 不生成垃圾复制内容)\r\n var pValid = !!(payload && payload.data && payload.data.scene && payload.data.scene.snapshot);\r\n if(!dataText && pValid){\r\n try { dataText = buildDataText(payload); } catch(e){ dataText = ''; } // 数据不完整 → 不渲染复制数据按钮(错误回执容错)\r\n }\r\n if(!logText && pValid){\r\n try { logText = buildLogText(payload); } catch(e){ logText = ''; } // 同上\r\n }\r\n var html = '<div class=\"hm-error\">'\r\n + '<div class=\"hm-error-title\">❌ '+esc(cfg.message||'操作失败')+'</div>';\r\n if(cfg.retryPrompt){\r\n html += '<div class=\"hm-actions\"><button class=\"copy primary wide\" onclick=\"copyText(this.dataset.t)\" data-t=\"'+esc(cfg.retryPrompt).replace(/\"/g,'&quot;')+'\">修正重试</button></div>';\r\n }\r\n var btns = '';\r\n if(dataText) btns += '<button class=\"copy ghost\" onclick=\"copyText(this.dataset.t)\" data-t=\"'+esc(dataText).replace(/\"/g,'&quot;')+'\">复制数据</button>';\r\n if(logText) btns += '<button class=\"copy ghost\" onclick=\"copyText(this.dataset.t)\" data-t=\"'+esc(logText).replace(/\"/g,'&quot;')+'\">复制日志</button>';\r\n if(btns) html += '<div class=\"hm-actions\">'+btns+'</div>';\r\n return html + '</div>';\r\n}\r\n\r\n/* ── smartSelect 选择器组件(v1.12 · #312 · 复用优先·新建其次)──\r\n * smartSelect(inputEl, config) → { getState, getValue }\r\n * 字段级组件: 一页 N 实例, 每字段一容器一 config 一隐藏 input, 互不干扰。\r\n * 定位: 与 copyText/actionBar 同级 Base 组件; 账户/分类/账本/运动类型等\r\n * 「复用优先·新建其次」字段通用; 零领域词, label/文案/选项/prompt 全由外部注入。\r\n * config(snake_case, 与数据契约 form.selector.<fieldKey> 对齐):\r\n * options: [{name, disabled}] 已有项(含停用态); 缺省 [] 且无推断/推荐/initial → 降级普通输入\r\n * inferred: string|null AI 推断最可能的已有项\r\n * recommended_new: string|null AI 推荐新建项(不在 options 中)\r\n * initial: {name, source}|null 显式初始选中; source 白名单 = _SS_SOURCES\r\n * maxChips: number|null 候选区折叠阈值(v1.12 · 缺省 8; 非正整数=不折叠;\r\n * 折叠态只显前 maxChips 个 + 「展开全部(N)」, 选中项保可见; 搜索时全量过滤)\r\n * texts: {candTitle, search, newPlaceholder, newButton, emptyButton,\r\n * badgeInferred, badgeRecommendedNew, badgeExisting, badgeHistory, badgeCustom,\r\n * cardSrc:{inferred, recommended_new, existing, history, custom, empty}}\r\n * theme: {brand, brandSoft, onBrand, deep} 缺省账本藏蓝 #123A63\r\n * 初始选中推导(initial 缺省时): AI 推断 > 历史预填(input.value) > AI 推荐新建 > 空\r\n * 行为: 已选卡片(chips 顶部, SVG ✓+来源徽章) + 候选 chips(超限折叠) + 搜索过滤(全量) + 自定义新建\r\n * (重名自动选中已有) + 相似提示 + 留空按钮; 停用划线置灰不可点; 绝不静默填错\r\n * 回填协议: input.value + dataset.source + dataset.new('1'=新建) + change 事件(bubbles)\r\n * 安全: 所有动态文本经 esc; 类名全 ss- 命名空间(封装纪律, 防宿主同名类冲突)\r\n * 校验: 结构违规直接报错(对齐 Base v1.2「违规直接报错」)\r\n */\r\nvar _SS_SOURCES = ['inferred','recommended_new','existing','history','custom','empty'];\r\nvar _SS_THEME = { brand:'#123a63', brandSoft:'#e9f0f7', onBrand:'#ffffff', deep:'#0b1f3b' };\r\nvar _SS_TEXTS = {\r\n candTitle:'候选(点击更换 · 输入过滤)',\r\n search:'输入过滤候选',\r\n newPlaceholder:'输入新名称',\r\n newButton:'+ 新建',\r\n emptyButton:'留空(不填)',\r\n badgeInferred:'AI 推断',\r\n badgeRecommendedNew:'AI 推荐·新建',\r\n badgeExisting:'已有',\r\n badgeHistory:'历史',\r\n badgeCustom:'自定义',\r\n cardSrc:{\r\n inferred:'AI 推断 · 识别到相关信息',\r\n recommended_new:'AI 推荐新建 · 提交时创建',\r\n existing:'从已有项中选',\r\n history:'沿用历史记录',\r\n custom:'自定义新建 · 提交时创建',\r\n empty:'不填该字段'\r\n }\r\n};\r\nfunction smartSelect(inputEl, config){\r\n /* ── 结构校验(违规直接报错)── */\r\n if(!inputEl || inputEl.tagName !== 'INPUT'){\r\n throw new Error('smartSelect 违规: inputEl 必须是 <input> 元素');\r\n }\r\n if(!config || typeof config !== 'object' || Array.isArray(config)){\r\n throw new Error('smartSelect 违规: config 必须是对象');\r\n }\r\n var options = config.options === undefined ? [] : config.options;\r\n if(!Array.isArray(options)){\r\n throw new Error('smartSelect 违规: options 必须是数组');\r\n }\r\n options.forEach(function(o, i){\r\n if(!o || typeof o !== 'object' || typeof o.name !== 'string' || !o.name.trim()){\r\n throw new Error('smartSelect 违规: options['+i+'] 必须含非空 name(字符串)');\r\n }\r\n if(o.disabled !== undefined && typeof o.disabled !== 'boolean'){\r\n throw new Error('smartSelect 违规: options['+i+'].disabled 必须是布尔');\r\n }\r\n });\r\n ['inferred','recommended_new'].forEach(function(k){\r\n var v = config[k];\r\n if(v !== undefined && v !== null && typeof v !== 'string'){\r\n throw new Error('smartSelect 违规: '+k+' 必须是字符串或 null');\r\n }\r\n });\r\n if(config.initial !== undefined && config.initial !== null){\r\n var ini = config.initial;\r\n if(!ini || typeof ini !== 'object' || typeof ini.name !== 'string'\r\n || _SS_SOURCES.indexOf(ini.source) < 0){\r\n throw new Error('smartSelect 违规: initial 必须含 name(字符串) + source(白名单 '+_SS_SOURCES.join('|')+')');\r\n }\r\n }\r\n if(config.texts !== undefined && (typeof config.texts !== 'object' || Array.isArray(config.texts))){\r\n throw new Error('smartSelect 违规: texts 必须是对象');\r\n }\r\n if(config.theme !== undefined && (typeof config.theme !== 'object' || Array.isArray(config.theme))){\r\n throw new Error('smartSelect 违规: theme 必须是对象');\r\n }\r\n\r\n var texts = Object.assign({}, _SS_TEXTS, config.texts || {});\r\n texts.cardSrc = Object.assign({}, _SS_TEXTS.cardSrc, (config.texts && config.texts.cardSrc) || {});\r\n var theme = Object.assign({}, _SS_THEME, config.theme || {});\r\n var custom = [];\r\n /* 候选区折叠(v1.12): maxChips 可配(缺省 8, 0/负数/非数字=不折叠) · 搜索时全量过滤 */\r\n var maxChips = (config.maxChips === undefined || config.maxChips === null)\r\n ? 8\r\n : ((typeof config.maxChips === 'number' && config.maxChips > 0)\r\n ? Math.floor(config.maxChips) : null);\r\n var searchRaw = '';\r\n var searchQ = '';\r\n var expanded = false;\r\n\r\n /* ── 降级模式: 无选项/无推断/无推荐/无 initial → 普通输入 ── */\r\n var degraded = !options.length && !config.inferred && !config.recommended_new && !config.initial;\r\n if(degraded){\r\n inputEl.classList.add('ss-plain');\r\n inputEl.style.display = '';\r\n inputEl.removeAttribute('hidden');\r\n var syncDegraded = function(){\r\n var v = inputEl.value;\r\n inputEl.dataset.source = v ? 'custom' : 'empty';\r\n inputEl.dataset.new = v ? '1' : '0';\r\n };\r\n syncDegraded();\r\n inputEl.addEventListener('input', syncDegraded);\r\n return {\r\n getState: function(){ var v = inputEl.value; return { name: v || null, mode: v ? 'custom' : 'empty' }; },\r\n getValue: function(){ return inputEl.value; }\r\n };\r\n }\r\n\r\n /* ── 初始选中推导: initial > AI 推断 > 历史预填(input.value) > AI 推荐新建 > 空 ── */\r\n var state;\r\n if(config.initial){\r\n state = { name: config.initial.name, mode: config.initial.source };\r\n } else if(config.inferred){\r\n state = { name: config.inferred, mode: 'inferred' };\r\n } else if(inputEl.value){\r\n state = { name: inputEl.value, mode: 'history' };\r\n } else if(config.recommended_new){\r\n state = { name: config.recommended_new, mode: 'recommended_new' };\r\n } else {\r\n state = { name: null, mode: 'empty' };\r\n }\r\n\r\n inputEl.style.display = 'none';\r\n var root = document.createElement('div');\r\n root.className = 'ss-root';\r\n root.style.setProperty('--ss-brand', theme.brand);\r\n root.style.setProperty('--ss-brand-soft', theme.brandSoft);\r\n root.style.setProperty('--ss-on-brand', theme.onBrand);\r\n root.style.setProperty('--ss-deep', theme.deep);\r\n inputEl.parentNode.insertBefore(root, inputEl.nextSibling);\r\n\r\n var CHECK_SVG = '<svg viewBox=\"0 0 20 20\" fill=\"none\"><path d=\"M4 10.5l4 4 8-9\" stroke=\"#fff\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>';\r\n var CIRCLE_SVG = '<svg viewBox=\"0 0 20 20\" fill=\"none\"><circle cx=\"10\" cy=\"10\" r=\"7\" stroke=\"#8b949e\" stroke-width=\"2\"/><path d=\"M7 10h6\" stroke=\"#8b949e\" stroke-width=\"2\" stroke-linecap=\"round\"/></svg>';\r\n\r\n function badgeHtml(mode){\r\n if(mode === 'inferred') return '<span class=\"ss-badge ss-badge-ai\">'+esc(texts.badgeInferred)+'</span>';\r\n if(mode === 'recommended_new') return '<span class=\"ss-badge ss-badge-new\">'+esc(texts.badgeRecommendedNew)+'</span>';\r\n if(mode === 'custom') return '<span class=\"ss-badge ss-badge-plain\">'+esc(texts.badgeCustom)+'</span>';\r\n if(mode === 'history') return '<span class=\"ss-badge ss-badge-plain\">'+esc(texts.badgeHistory)+'</span>';\r\n if(mode === 'existing') return '<span class=\"ss-badge ss-badge-plain\">'+esc(texts.badgeExisting)+'</span>';\r\n return '';\r\n }\r\n\r\n function writeBack(){\r\n inputEl.value = state.name || '';\r\n inputEl.dataset.source = state.mode || 'empty';\r\n inputEl.dataset.new = (state.mode === 'recommended_new' || state.mode === 'custom') ? '1' : '0';\r\n inputEl.dispatchEvent(new Event('change', { bubbles: true }));\r\n }\r\n\r\n function setSel(name, mode){\r\n state.name = name;\r\n state.mode = mode;\r\n render();\r\n writeBack();\r\n }\r\n\r\n function allNames(){\r\n var names = options.map(function(o){ return o.name; });\r\n return names.concat(custom);\r\n }\r\n\r\n function similarHint(v){\r\n if(!v) return '';\r\n var s = allNames().filter(function(n){\r\n return n !== v && (n.indexOf(v) >= 0 || v.indexOf(n) >= 0);\r\n });\r\n return s.length ? '已有相似「'+s[0]+'」, 是否使用已有的?(点候选即选)' : '';\r\n }\r\n\r\n function render(){\r\n function isSel(n, m){ return state.name === n && state.mode === m; }\r\n var card = state.name\r\n ? '<div class=\"ss-card\"><div class=\"ss-ic\">'+CHECK_SVG+'</div>'\r\n + '<div class=\"ss-body\"><div class=\"ss-nm\">'+esc(state.name)+'</div>'\r\n + '<div class=\"ss-src\">'+esc(texts.cardSrc[state.mode] || '')+'</div></div>'\r\n + badgeHtml(state.mode) + '</div>'\r\n : '<div class=\"ss-card ss-card-empty\"><div class=\"ss-ic\">'+CIRCLE_SVG+'</div>'\r\n + '<div class=\"ss-body\"><div class=\"ss-nm\">'+esc(texts.emptyButton)+'</div>'\r\n + '<div class=\"ss-src\">'+esc(texts.cardSrc.empty || '')+'</div></div></div>';\r\n function chip(n, m, dis, badge){\r\n var sel = !dis && isSel(n, m);\r\n return '<button type=\"button\" class=\"ss-chip'+(dis?' ss-chip-dis':'')+(sel?' ss-chip-sel':'')+'\"'\r\n + (dis ? ' disabled' : ' data-n=\"'+esc(n)+'\" data-m=\"'+m+'\"')\r\n + '>'+(sel?'✓ ':'')+esc(n)+badge+(dis?' · 停用':'')+'</button>';\r\n }\r\n var chips = []; // chip HTML\r\n var chipsMeta = []; // 对齐元信息 {name, sel}(折叠保可见/搜索过滤用)\r\n function pushChip(n, m, dis, badge){\r\n var sel = !dis && isSel(n, m);\r\n chipsMeta.push({ name: n, sel: sel });\r\n chips.push(chip(n, m, dis, badge));\r\n }\r\n if(config.inferred){\r\n pushChip(config.inferred, 'inferred', false, '<span class=\"ss-badge ss-badge-ai\">'+esc(texts.badgeInferred)+'</span>');\r\n }\r\n if(config.recommended_new){\r\n pushChip(config.recommended_new, 'recommended_new', false, '<span class=\"ss-badge ss-badge-new\">'+esc(texts.badgeRecommendedNew)+'</span>');\r\n }\r\n options.forEach(function(o){\r\n if(o.name === config.inferred || o.name === config.recommended_new) return;\r\n pushChip(o.name, 'existing', !!o.disabled, '');\r\n });\r\n custom.forEach(function(n){\r\n pushChip(n, 'custom', false, '<span class=\"ss-badge ss-badge-plain\">'+esc(texts.badgeCustom)+'</span>');\r\n });\r\n\r\n /* 候选区折叠(v1.12): 折叠态只显前 maxChips 个, 选中项保可见; 搜索时全量过滤 */\r\n var showAll = !maxChips || expanded || !!searchQ || chips.length <= maxChips;\r\n var list = chips;\r\n var listMeta = chipsMeta;\r\n if(!showAll){\r\n var selIdx = -1;\r\n for(var i = 0; i < chipsMeta.length; i++){\r\n if(chipsMeta[i].sel){ selIdx = i; break; }\r\n }\r\n list = chips.slice(0, maxChips);\r\n listMeta = chipsMeta.slice(0, maxChips);\r\n if(selIdx >= maxChips){\r\n list[maxChips - 1] = chips[selIdx];\r\n listMeta[maxChips - 1] = chipsMeta[selIdx];\r\n }\r\n }\r\n var out = [];\r\n for(var j = 0; j < list.length; j++){\r\n if(searchQ && listMeta[j].name.toLowerCase().indexOf(searchQ) < 0) continue;\r\n out.push(list[j]);\r\n }\r\n var moreBtn = '';\r\n if(!showAll){\r\n moreBtn = '<button type=\"button\" class=\"ss-more\" data-more=\"1\">展开全部('+chips.length+')</button>';\r\n } else if(expanded && maxChips && chips.length > maxChips && !searchQ){\r\n moreBtn = '<button type=\"button\" class=\"ss-more\" data-more=\"0\">收起</button>';\r\n }\r\n\r\n root.innerHTML =\r\n card\r\n + '<div class=\"ss-title\">'+esc(texts.candTitle)+'</div>'\r\n + '<input class=\"ss-search\" placeholder=\"'+esc(texts.search)+'\">'\r\n + '<div class=\"ss-chips\">'+out.join('')+moreBtn+'</div>'\r\n + '<div class=\"ss-new\"><input placeholder=\"'+esc(texts.newPlaceholder)+'\"><button type=\"button\">'+esc(texts.newButton)+'</button></div>'\r\n + '<div class=\"ss-hint\"></div>'\r\n + '<button type=\"button\" class=\"ss-empty\">'+esc(texts.emptyButton)+'</button>';\r\n\r\n /* 搜索框内容跨 render 保持(过滤状态不丢, 输入框不空) */\r\n if(searchRaw) root.querySelector('.ss-search').value = searchRaw;\r\n root.querySelector('.ss-search').addEventListener('input', function(e){\r\n searchRaw = e.target.value;\r\n searchQ = searchRaw.trim().toLowerCase();\r\n render();\r\n });\r\n root.querySelectorAll('.ss-more').forEach(function(el){\r\n el.addEventListener('click', function(){\r\n expanded = el.getAttribute('data-more') === '1';\r\n render();\r\n });\r\n });\r\n root.querySelectorAll('.ss-chip[data-n]').forEach(function(el){\r\n el.addEventListener('click', function(){ setSel(el.getAttribute('data-n'), el.getAttribute('data-m')); });\r\n });\r\n var newIn = root.querySelector('.ss-new input');\r\n var doNew = function(){\r\n var v = newIn.value.trim();\r\n if(!v) return;\r\n if(allNames().indexOf(v) >= 0){ setSel(v, 'existing'); return; }\r\n custom.unshift(v);\r\n setSel(v, 'custom');\r\n };\r\n root.querySelector('.ss-new button').addEventListener('click', doNew);\r\n newIn.addEventListener('keydown', function(e){ if(e.key === 'Enter') doNew(); });\r\n newIn.addEventListener('input', function(){\r\n var h = root.querySelector('.ss-hint');\r\n var s = similarHint(newIn.value.trim());\r\n h.textContent = s;\r\n h.style.display = s ? '' : 'none';\r\n });\r\n root.querySelector('.ss-empty').addEventListener('click', function(){ setSel(null, 'empty'); });\r\n }\r\n\r\n render();\r\n writeBack();\r\n\r\n return {\r\n getState: function(){ return { name: state.name, mode: state.mode }; },\r\n getValue: function(){ return inputEl.value; }\r\n };\r\n}\r\n</script>\r\n<style>\r\n/* Base Skill token A 组 + 控件样式 v1.11(唯一真相源 · 跨技能 · 领域无关)\r\n * 来源: 居家管家模板 :root token(对齐 #248/08-HTML交互规范.md 按钮规范)\r\n * v1.2: 新增新控件样式(formPrompt/selectList/confirm/foldBox/statusBadge/emptyState/errorReceipt/复制预览面板)\r\n * v1.7: .hm-actions 自约束 max-width 520px 居中(#322 · 修复复制按钮被容器拉伸成半屏宽, 胶囊语义恢复)\r\n * v1.9: selectList 行内控件样式(.sl-widget* · #327 · 样式走 token A 组)\r\n * v1.11: smartSelect 选择器组件样式(.ss-* · #312 · 主题色经 .ss-root 内联 CSS 变量覆盖, 缺省账本藏蓝)\r\n * v1.12: smartSelect 候选区折叠按钮(.ss-more · #312 实测反馈: 大量候选时折叠+展开)\r\n * 注入点: 由 injector.py 的 SHARED-CSS 占位符注入(模板声明点, 勿含闭合标签字样)\r\n */\r\n\r\n/* ── token A 组(12 变量, 与组件契约 §6.4 一致)── */\r\n:root {\r\n --fg: #1d1d1f; /* 主文字 */\r\n --fg2: #6e6e73; /* 次级文字 */\r\n --fg3: #86868b; /* 弱化文字/占位 */\r\n --bg: #f5f5f7; /* 页面底色 */\r\n --card: #ffffff; /* 卡片底 */\r\n --line: #d2d2d7; /* 分隔线 */\r\n --blue: #007aff; /* 主色(场景按钮) */\r\n --blue2: #0a63ce; /* 主色深(按压态/链接) */\r\n --soft: #f5f8ff; /* 浅蓝底(stage 徽章) */\r\n --ok: #34c759; /* 成功/通过 */\r\n --shadow: 0 1px 2px rgba(0,0,0,.04), 0 12px 36px rgba(0,0,0,.06);\r\n}\r\n\r\n/* ── 复制按钮基础(对齐 08 规范: ≤3 色按功能区分)── */\r\nbutton.copy {\r\n -webkit-tap-highlight-color: transparent;\r\n touch-action: manipulation;\r\n -webkit-touch-callout: none;\r\n border: none;\r\n background: var(--line);\r\n color: var(--fg);\r\n border-radius: 999px;\r\n padding: 10px 12px;\r\n font-weight: 700;\r\n cursor: pointer;\r\n margin: 0;\r\n font-size: 13.5px;\r\n min-height: 44px;\r\n min-width: 0;\r\n flex: 1 1 0;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n white-space: nowrap;\r\n font-family: inherit;\r\n}\r\nbutton.copy:focus { outline: none; }\r\nbutton.copy:active { filter: brightness(.93); }\r\nbutton.copy:disabled { opacity: .45; cursor: not-allowed; }\r\n\r\n/* 主场景按钮(蓝实心, 单色系) */\r\nbutton.copy.primary {\r\n background: var(--blue);\r\n color: #fff;\r\n}\r\nbutton.copy.primary:active { background: var(--blue2); }\r\n\r\n/* 危险/破坏性操作(红实心) */\r\nbutton.copy.red {\r\n background: #ff3b30;\r\n color: #fff;\r\n}\r\nbutton.copy.red:active { background: #c0392b; }\r\n\r\n/* ghost: 复制数据/复制日志 = 白底 + 轻主色描边 + 主色文字胶囊(独立一行)\r\n * v1.26 · #329 降权重: 描边 1px/38% 透明度 + 12px/600 + min-height 40px —— 视觉重心归主操作(VLM 两轮反馈)\r\n * v1.28 · 审查修复: 透明度 35%→38%(与拍板页 329-ghost对比拍板页.html B 方案所见一致) */\r\nbutton.copy.ghost {\r\n background: var(--card);\r\n color: var(--blue);\r\n border: 1px solid var(--blue);\r\n border-color: color-mix(in srgb, var(--blue) 38%, transparent);\r\n min-height: 40px;\r\n font-size: 12px;\r\n font-weight: 600;\r\n}\r\n\r\n/* ── actionBar 网格(偶数一行 2 个; 奇数时重要按钮单独一行由模板控制 wide)── */\r\n.hm-actions {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr;\r\n gap: 8px;\r\n margin-top: 14px;\r\n /* v1.7 #322: 胶囊按钮自约束宽度——避免被全宽容器拉伸成半屏宽块(跨技能一致) */\r\n max-width: 520px;\r\n margin-left: auto;\r\n margin-right: auto;\r\n box-sizing: border-box;\r\n}\r\n.hm-actions .copy.wide {\r\n grid-column: 1 / -1;\r\n background: var(--blue);\r\n color: #fff;\r\n border: none;\r\n}\r\n\r\n/* 成功/失败徽章(yes 函数用) */\r\n.ok { color: var(--ok); font-weight: 700; }\r\n.bad { color: #ff3b30; font-weight: 700; }\r\n\r\n/* ── formPrompt(参数表单)── */\r\n.fp { background: var(--card); border: 1px solid var(--line); border-radius: 16px; padding: 18px 20px; margin: 12px 0; }\r\n.fp-field { margin-bottom: 12px; }\r\n.fp-label { display: block; font-size: 12px; font-weight: 700; color: var(--fg2); margin-bottom: 6px; letter-spacing: .02em; }\r\n.fp-input {\r\n width: 100%;\r\n border: 1.5px solid var(--line);\r\n border-radius: 10px;\r\n padding: 10px 12px;\r\n font-size: 14px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n background: #fff;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n min-height: 44px;\r\n}\r\n.fp-input:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(0,122,255,.12); }\r\n.fp-preview { background: #fafbfc; border: 1px dashed var(--line); border-radius: 10px; padding: 10px 14px; margin: 10px 0; }\r\n.fp-preview-label { font-size: 10.5px; font-weight: 700; color: var(--fg3); text-transform: uppercase; letter-spacing: .06em; margin-bottom: 6px; }\r\n.fp-preview-body {\r\n font-size: 12px;\r\n color: var(--fg2);\r\n font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;\r\n line-height: 1.6;\r\n white-space: pre-wrap;\r\n word-break: break-all;\r\n overflow-wrap: anywhere;\r\n margin: 0;\r\n}\r\n.fp-actions { margin-top: 12px; }\r\n\r\n/* ── selectList(勾选列表 + 批量操作)── */\r\n.sl { margin: 12px 0; }\r\n.sl-batchbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 14px; padding-bottom: 14px; border-bottom: 1px solid var(--line); }\r\n.sl-count { font-size: 12px; font-weight: 600; color: var(--fg2); margin-left: auto; white-space: nowrap; }\r\n.sl-group { margin-bottom: 14px; }\r\n.sl-group-head { display: flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 700; margin-bottom: 8px; }\r\n.sl-group-count { font-size: 11px; font-weight: 600; color: var(--fg3); }\r\n.sl-group-items { display: flex; flex-direction: column; gap: 6px; }\r\n.sl-item {\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 10px;\r\n background: #fafbfc;\r\n border: 1px solid var(--line);\r\n border-radius: 12px;\r\n padding: 12px 14px;\r\n cursor: pointer;\r\n font-family: inherit;\r\n transition: border-color .15s, background .15s;\r\n}\r\n.sl-item:hover { border-color: var(--blue); background: #fff; }\r\n.sl-item input[type=\"checkbox\"] { width: 20px; height: 20px; margin-top: 2px; accent-color: var(--blue); flex-shrink: 0; }\r\n.sl-item-body { flex: 1; min-width: 0; }\r\n.sl-item-title { display: block; font-size: 13.5px; font-weight: 600; color: var(--fg); line-height: 1.5; word-break: break-word; }\r\n.sl-item-sub { display: block; font-size: 12px; color: var(--fg3); margin-top: 2px; line-height: 1.5; word-break: break-word; }\r\n\r\n/* ── selectList 行内控件(v1.9 · #327 · 样式走 token A 组)── */\r\n.sl-widget { display: block; margin-top: 8px; }\r\n.sl-widget-label { display: block; font-size: 11px; font-weight: 600; color: var(--fg3); margin-bottom: 4px; }\r\n.sl-widget-input {\r\n width: 100%;\r\n box-sizing: border-box;\r\n border: 1.5px solid var(--line);\r\n border-radius: 8px;\r\n padding: 8px 10px;\r\n font-size: 13px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n background: #fff;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n min-height: 40px;\r\n}\r\n.sl-widget-input:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(0,122,255,.12); }\r\n\r\n/* ── confirm 对话框 ── */\r\n.hm-confirm-overlay {\r\n position: fixed; inset: 0;\r\n background: rgba(0,0,0,.4);\r\n display: flex; align-items: center; justify-content: center;\r\n z-index: 10000;\r\n padding: 20px;\r\n animation: hmFade .18s ease-out;\r\n}\r\n@keyframes hmFade { from { opacity: 0; } to { opacity: 1; } }\r\n.hm-confirm-panel {\r\n background: var(--card);\r\n border-radius: 20px;\r\n max-width: 420px;\r\n width: 100%;\r\n padding: 24px 26px;\r\n box-shadow: var(--shadow);\r\n animation: hmPop .22s cubic-bezier(.34,1.56,.64,1);\r\n}\r\n@keyframes hmPop { from { transform: scale(.9); opacity: 0; } to { transform: scale(1); opacity: 1; } }\r\n/* ── #507 减动效归零档(照老壳 style.ts 归零档补:默认态一字不动,只在 reduce 下归零)──\r\n * 覆盖本母版本文件全部动效:summary 小三角 .15s/.mini 按压 .08s/.tab .08s/.copy-btn .12s/\r\n * .sl-item 行 .15s/.sheet-mask 淡入 .25s/.sheet 滑入 .32s/toast 入场 .22s/hmFade .18s/hmPop .22s。\r\n * toast 样式由 JS 后注入(晚于本表),归零规则须挂祖先类提权重才盖得住;.sheet 只停 transition\r\n * (不碰 transform 终态,否则弹层开合定位失效),动效停、状态照走。 */\r\n@media (prefers-reduced-motion: reduce){\r\n.contact-box>summary::before,.subgroup>summary::before{transition:none}\r\n.mini,.tab,.copy-btn,.sl-item{transition:none}\r\n.mini:active{transform:none}\r\n.sheet,.sheet-mask{transition:none}\r\n.hm-toast-stack .hm-toast{transition:none}\r\n.hm-confirm-overlay{animation:none}\r\n.hm-confirm-panel{animation:none}\r\n}\r\n.hm-confirm-title { font-size: 17px; font-weight: 700; margin-bottom: 8px; }\r\n.hm-confirm-detail { font-size: 13.5px; color: var(--fg2); line-height: 1.65; margin-bottom: 16px; }\r\n.hm-confirm-actions { display: flex; gap: 10px; }\r\n.hm-confirm-actions .copy { flex: 1; }\r\n\r\n/* ── foldBox 折叠区 ── */\r\n.hm-fold {\r\n background: #fafbfc;\r\n border: 1px solid var(--line);\r\n border-radius: 12px;\r\n padding: 12px 16px;\r\n margin: 10px 0;\r\n font-size: 13px;\r\n}\r\n.hm-fold summary { cursor: pointer; font-weight: 600; color: var(--blue2); outline: none; font-size: 13px; user-select: none; }\r\n.hm-fold summary::marker { color: var(--blue); }\r\n.hm-fold[open] summary { margin-bottom: 10px; }\r\n.hm-fold-body { font-size: 12.5px; line-height: 1.6; color: var(--fg2); }\r\n\r\n/* ── statusBadge 状态徽章 ── */\r\n.hm-status {\r\n display: inline-flex; align-items: center; gap: 6px;\r\n padding: 6px 14px; border-radius: 999px; font-size: 13px; font-weight: 600;\r\n width: fit-content;\r\n}\r\n.hm-status.ok { background: #e6f7ec; color: #1f8c3d; }\r\n.hm-status.warn { background: #fff5e0; color: #a25b00; }\r\n.hm-status.danger { background: #fff0ee; color: #a83228; }\r\n.hm-status.empty { background: #f0f0f3; color: #6e6e73; }\r\n\r\n/* ── emptyState 空状态 ── */\r\n.hm-empty {\r\n background: #fafbfc;\r\n border: 1px dashed var(--line);\r\n border-radius: 12px;\r\n padding: 26px 20px;\r\n text-align: center;\r\n color: var(--fg2);\r\n font-size: 13.5px;\r\n line-height: 1.7;\r\n}\r\n.hm-empty-icon { font-size: 32px; margin-bottom: 8px; }\r\n.hm-empty-text { font-weight: 600; color: var(--fg); }\r\n.hm-empty-hint { font-size: 12.5px; color: var(--fg3); margin-top: 4px; }\r\n.hm-empty-action { margin-top: 14px; }\r\n\r\n/* ── errorReceipt 错误回执 ── */\r\n.hm-error {\r\n background: #fff0ee;\r\n border: 1.5px solid #ffc4c0;\r\n border-radius: 16px;\r\n padding: 20px 22px;\r\n margin: 12px 0;\r\n}\r\n.hm-error-title { font-size: 15px; font-weight: 700; color: #a83228; margin-bottom: 14px; }\r\n/* errorReceipt 内按钮布局: 第一个 .hm-actions(修正重试)贴标题; 后续 .hm-actions(复制数据/日志)与上方保持间距, 防贴死(#290 修复) */\r\n.hm-error .hm-actions { margin-top: 0; }\r\n.hm-error .hm-actions + .hm-actions { margin-top: 14px; }\r\n@media (max-width: 820px) {\r\n .hm-error { padding: 16px 14px; }\r\n .hm-error-title { margin-bottom: 12px; }\r\n}\r\n\r\n/* ── 复制预览面板(actionBar preview)── */\r\n.hm-preview-overlay {\r\n position: fixed; inset: 0;\r\n background: rgba(0,0,0,.4);\r\n display: flex; align-items: center; justify-content: center;\r\n z-index: 10001;\r\n padding: 16px;\r\n}\r\n.hm-preview-panel {\r\n background: var(--card);\r\n border-radius: 16px;\r\n max-width: 560px;\r\n width: 100%;\r\n max-height: 80vh;\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n box-shadow: var(--shadow);\r\n}\r\n.hm-preview-head {\r\n display: flex; align-items: center; justify-content: space-between;\r\n padding: 14px 18px;\r\n border-bottom: 1px solid var(--line);\r\n font-size: 14px; font-weight: 700;\r\n}\r\n.hm-preview-close { border: none; background: none; font-size: 15px; color: var(--fg3); cursor: pointer; padding: 4px; }\r\n.hm-preview-body {\r\n flex: 1;\r\n overflow: auto;\r\n padding: 14px 18px;\r\n font-size: 12px;\r\n line-height: 1.65;\r\n font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;\r\n white-space: pre-wrap;\r\n word-break: break-all;\r\n overflow-wrap: anywhere;\r\n color: var(--fg2);\r\n margin: 0;\r\n}\r\n.hm-preview-actions { display: flex; gap: 10px; padding: 12px 18px; border-top: 1px solid var(--line); }\r\n.hm-preview-actions .copy { flex: 1; }\r\n\r\n/* 手机适配: 单列网格保持按钮不换行 */\r\n@media (max-width: 820px) {\r\n .hm-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }\r\n .hm-actions .copy.wide { grid-column: 1 / -1; }\r\n .hm-actions .copy { min-height: 46px; }\r\n .sl-batchbar { flex-direction: column; align-items: stretch; }\r\n .sl-count { margin-left: 0; }\r\n .hm-confirm-panel { padding: 20px 18px; }\r\n}\r\n\r\n/* ── smartSelect 选择器组件(v1.11 · #312 · 复用优先·新建其次)──\r\n * 类名全 ss- 命名空间(封装纪律, 防宿主同名类冲突); 主题色 = .ss-root 内联 CSS 变量,\r\n * 缺省账本藏蓝 #123A63(deep #0B1F3B / soft #E9F0F7), 每实例可独立覆盖\r\n */\r\n.ss-root {\r\n --ss-brand: #123a63;\r\n --ss-brand-soft: #e9f0f7;\r\n --ss-on-brand: #ffffff;\r\n --ss-deep: #0b1f3b;\r\n margin-top: 6px;\r\n}\r\n.ss-card {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 12px 14px;\r\n border-radius: 10px;\r\n border: 2px solid var(--ss-brand);\r\n background: var(--ss-brand-soft);\r\n}\r\n.ss-card .ss-ic {\r\n width: 34px;\r\n height: 34px;\r\n border-radius: 50%;\r\n background: var(--ss-brand);\r\n flex: none;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n.ss-card .ss-ic svg { width: 18px; height: 18px; }\r\n.ss-body { flex: 1; min-width: 0; }\r\n.ss-nm { font-size: 16px; font-weight: 700; color: var(--fg); word-break: break-word; }\r\n.ss-src { font-size: 11px; color: var(--fg3); margin-top: 2px; }\r\n.ss-card.ss-card-empty { border: 2px dashed var(--line); background: transparent; }\r\n.ss-card.ss-card-empty .ss-ic { background: transparent; border: 2px solid var(--fg3); }\r\n.ss-card.ss-card-empty .ss-nm { color: var(--fg3); }\r\n.ss-badge {\r\n display: inline-block;\r\n font-size: 10px;\r\n line-height: 1;\r\n padding: 2px 6px;\r\n border-radius: 10px;\r\n flex-shrink: 0;\r\n}\r\n.ss-badge-ai { background: var(--ss-brand-soft); color: var(--ss-brand); }\r\n.ss-badge-new { background: #fff8c5; color: #9a6700; }\r\n.ss-badge-plain { background: #eef; color: var(--fg3); }\r\n.ss-title { font-size: 11px; color: var(--fg3); margin: 10px 0 6px; }\r\n.ss-search {\r\n width: 100%;\r\n box-sizing: border-box;\r\n padding: 8px 12px;\r\n border: 1.5px solid var(--line);\r\n border-radius: 8px;\r\n font-size: 13px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n background: #fff;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n min-height: 40px;\r\n}\r\n.ss-search:focus { outline: none; border-color: var(--ss-brand); box-shadow: 0 0 0 3px rgba(18, 58, 99, .12); }\r\n.ss-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }\r\n.ss-chip {\r\n padding: 6px 12px;\r\n border: 1.5px solid var(--line);\r\n border-radius: 16px;\r\n font-size: 13px;\r\n background: #fff;\r\n cursor: pointer;\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n -webkit-tap-highlight-color: transparent;\r\n touch-action: manipulation;\r\n}\r\n.ss-chip:hover { border-color: var(--ss-brand); }\r\n.ss-chip.ss-chip-sel {\r\n background: var(--ss-brand);\r\n border-color: var(--ss-brand);\r\n color: var(--ss-on-brand);\r\n font-weight: 700;\r\n box-shadow: 0 2px 6px rgba(0, 0, 0, .18);\r\n}\r\n.ss-chip.ss-chip-sel .ss-badge-ai { background: rgba(255, 255, 255, .2); color: #fff; }\r\n.ss-chip.ss-chip-sel .ss-badge-new { background: rgba(255, 255, 255, .25); color: #ffe9a8; }\r\n.ss-chip.ss-chip-sel .ss-badge-plain { background: rgba(255, 255, 255, .18); color: #fff; }\r\n.ss-chip.ss-chip-dis {\r\n color: var(--fg3);\r\n text-decoration: line-through;\r\n cursor: not-allowed;\r\n background: var(--bg);\r\n border-color: var(--line);\r\n}\r\n/* 候选区折叠按钮(v1.12 · #312 实测反馈: 分类几十上百时 chips 全量平铺过长) */\r\n.ss-more {\r\n padding: 6px 12px;\r\n border: 1.5px dashed var(--line);\r\n border-radius: 16px;\r\n font-size: 12.5px;\r\n background: var(--bg);\r\n color: var(--fg2);\r\n cursor: pointer;\r\n font-family: inherit;\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n min-height: 36px;\r\n -webkit-tap-highlight-color: transparent;\r\n touch-action: manipulation;\r\n}\r\n.ss-more:hover { border-color: var(--ss-brand); color: var(--ss-brand); background: #fff; }\r\n.ss-new { display: flex; gap: 8px; margin-top: 10px; }\r\n.ss-new input {\r\n flex: 1;\r\n min-width: 0;\r\n padding: 8px 12px;\r\n border: 1.5px solid var(--line);\r\n border-radius: 8px;\r\n font-size: 13px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n background: #fff;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n min-height: 40px;\r\n}\r\n.ss-new input:focus { outline: none; border-color: var(--ss-brand); }\r\n.ss-new button {\r\n padding: 0 14px;\r\n border: 1.5px solid var(--line);\r\n border-radius: 8px;\r\n background: #fff;\r\n color: var(--fg);\r\n font-size: 13px;\r\n cursor: pointer;\r\n white-space: nowrap;\r\n font-family: inherit;\r\n min-height: 40px;\r\n}\r\n.ss-new button:hover { border-color: var(--ss-brand); color: var(--ss-brand); }\r\n.ss-hint { margin-top: 6px; font-size: 12px; color: #b25b00; display: none; }\r\n.ss-empty {\r\n margin-top: 8px;\r\n width: 100%;\r\n padding: 8px;\r\n border: 1px dashed var(--line);\r\n border-radius: 8px;\r\n background: transparent;\r\n color: var(--fg3);\r\n cursor: pointer;\r\n font-family: inherit;\r\n font-size: 13px;\r\n min-height: 36px;\r\n}\r\n.ss-empty:hover { border-color: var(--ss-brand); color: var(--ss-brand); }\r\n/* 降级模式(options 空数组等 → 普通输入) */\r\n.ss-plain {\r\n width: 100%;\r\n box-sizing: border-box;\r\n padding: 8px 12px;\r\n border: 1.5px solid var(--line);\r\n border-radius: 8px;\r\n font-size: 13px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n background: #fff;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n min-height: 44px;\r\n}\r\n.ss-plain:focus { outline: none; border-color: var(--ss-brand); box-shadow: 0 0 0 3px rgba(18, 58, 99, .12); }\r\n@media (max-width: 820px) {\r\n .ss-new { flex-direction: column; align-items: stretch; }\r\n .ss-new button { min-height: 44px; }\r\n .ss-chip { min-height: 38px; }\r\n}\r\n</style>\r\n\r\n<script>\r\n/* ===== 技能身份与数据(scene-data 契约 v1 · 全外部注入)===== */\r\nvar HELP = JSON.parse(document.getElementById('help-data').textContent);\r\nvar SKILL_NAME = HELP.skill_name || '';\r\nvar TITLE = HELP.title || '能力速查台';\r\nvar SUBTITLE = HELP.subtitle || '';\r\nvar META_BLOCKS = HELP.meta_blocks || [];\r\nvar INIT_BANNER = HELP.init_banner || null;\r\nvar CONTACT = HELP.contact || null;\r\nvar SKILL_VERSION = HELP.version || '';\r\nvar ABOUT_EXTRA = {};\r\nvar RECOMMENDATIONS = HELP.recommendations || [];\r\n\r\n/* 契约 v1 (groups[{id,icon,label,subgroups[{id,label,scenes[]}]}])\r\n -> 原型内部结构 (key/icon/name + subgroups[{name,scenes}]) */\r\nfunction normalizeScenes(scenes){\r\n return (scenes || []).map(function(s){\r\n return {\r\n id: s.id,\r\n name: s.title,\r\n chip: s.wake_word,\r\n types: (s.types && s.types.length ? s.types : []),\r\n dev: (s.status === '【待开发】'),\r\n prompt: s.prompt_template,\r\n params: (s.editable_fields || []).map(function(f){\r\n return { key: f.name, label: f.label, value: f.value || '', req: !!f.required, hint: f.hint || '' };\r\n })\r\n };\r\n });\r\n}\r\nvar GROUPS = (HELP.groups || []).map(function(g){\r\n return {\r\n key: g.id, icon: g.icon || 'grid', name: g.label,\r\n subgroups: (g.subgroups || []).map(function(sg){\r\n return { name: sg.label, scenes: normalizeScenes(sg.scenes) };\r\n })\r\n };\r\n});\r\n\r\n/* ===== 扁平化索引(原型逻辑 · 渲染/卡片/搜索依赖)===== */\r\nvar ALL = [];\r\nvar SCENE = {};\r\nGROUPS.forEach(function(g){\r\n g.subgroups.forEach(function(sg){\r\n sg.scenes.forEach(function(s){\r\n s.g = g.name; s.gkey = g.key; s.gico = g.icon; s.sg = sg.name;\r\n ALL.push(s); SCENE[s.id] = s;\r\n });\r\n });\r\n});\r\n\r\nfunction esc(s){ return String(s==null?'':s).replace(/[&<>\"']/g, function(c){ return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]; }); }\r\n/* 类型徽章: types 数组元素可为字符串(默认配色)或 {text,bg,fg}(调用者自定义颜色, 缺省走默认) */\r\nvar TYPE_DEFAULT = {\r\n '采集': {bg:'#e7f8ee', fg:'#1a7a3a'},\r\n '查看': {bg:'#e8f2ff', fg:'#0a63ce'},\r\n '结果': {bg:'#e8f2ff', fg:'#0a63ce'},\r\n '向导': {bg:'#e2f7f5', fg:'#00897b'},\r\n '批量': {bg:'#f3e9fb', fg:'#8e3fc9'},\r\n '校验': {bg:'#e8f2ff', fg:'#0a63ce'},\r\n '选择': {bg:'#e8f2ff', fg:'#0a63ce'},\r\n '过程': {bg:'#e2f7f5', fg:'#00897b'},\r\n '回执': {bg:'#e8f2ff', fg:'#0a63ce'},\r\n '录入': {bg:'#e7f8ee', fg:'#1a7a3a'}\r\n};\r\nfunction typeBadgeHTML(t){\r\n var text, bg, fg;\r\n if (t && typeof t === 'object') {\r\n text = t.text;\r\n var d = TYPE_DEFAULT[text] || TYPE_DEFAULT['查看'];\r\n bg = t.bg || d.bg;\r\n fg = t.fg || d.fg;\r\n } else {\r\n text = t;\r\n var d2 = TYPE_DEFAULT[text] || TYPE_DEFAULT['查看'];\r\n bg = d2.bg; fg = d2.fg;\r\n }\r\n return '<span class=\"type-badge\" style=\"background:' + esc(bg) + ';color:' + esc(fg) + '\">' + esc(text) + '</span>';\r\n}\r\nfunction chipHTML(s){\r\n var h = '<span class=\"chip\">' + esc(s.chip) + '</span>';\r\n if (s.dev) h += '<span class=\"type-badge t-dev\">待开发</span>';\r\n (s.types || []).forEach(function(t){ h += typeBadgeHTML(t); });\r\n return h;\r\n}\r\n\r\n/* ===== SVG 图标库 ===== */\r\nvar SVG_ICONS = {\r\n write:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M17 3a2.8 2.8 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z\"/></svg>',\r\n calendar:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"/><line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"/><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"/><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"/></svg>',\r\n chart:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"20\" x2=\"18\" y2=\"10\"/><line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"4\"/><line x1=\"6\" y1=\"20\" x2=\"6\" y2=\"14\"/></svg>',\r\n grid:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"/></svg>',\r\n target:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><circle cx=\"12\" cy=\"12\" r=\"5\"/><circle cx=\"12\" cy=\"12\" r=\"1\"/></svg>',\r\n rocket:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09Z\"/><path d=\"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2Z\"/><path d=\"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0\"/><path d=\"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5\"/></svg>'\r\n};\r\nfunction tabIconHTML(g){\r\n var svg = SVG_ICONS[g.icon];\r\n if (svg) return '<span class=\"t-ico\">' + svg + '</span>';\r\n return '<span class=\"t-ico\"><span class=\"t-emoji\">' + esc(g.icon) + '</span></span>';\r\n}\r\n\r\n/* ===== 参数机制:prompt + 末尾每行「key: value」===== */\r\nfunction readParams(id){\r\n var fm = document.querySelector('.pform[data-pid=\"' + id + '\"]');\r\n var v = {};\r\n if (fm) fm.querySelectorAll('input[data-p]').forEach(function(inp){ v[inp.dataset.p] = inp.value; });\r\n return v;\r\n}\r\nfunction buildPrompt(s, v){\r\n v = v || {};\r\n var lines = [s.prompt];\r\n var paramLines = [];\r\n (s.params || []).forEach(function(p){\r\n var val = (v[p.key] != null ? v[p.key] : '').trim();\r\n if (val) paramLines.push(p.label + ': ' + val);\r\n });\r\n if (paramLines.length) lines.push(''); /* 空行分隔 */\r\n lines = lines.concat(paramLines);\r\n return lines.join('\\n');\r\n}\r\nfunction getMissing(s, v){\r\n return (s.params || []).filter(function(p){ return p.req && !(v[p.key] || '').trim(); }).map(function(p){ return p.label; });\r\n}\r\n\r\n/* ===== 渲染主页面 ===== */\r\nvar screen = document.getElementById('screen');\r\nvar h = '<div class=\"app\"><div class=\"app-inner\">' +\r\n '<header class=\"hero\"><div class=\"h-left\"><div class=\"eyebrow\">' + esc(SKILL_NAME) + '</div><h1>' + esc(TITLE) + '</h1><div class=\"lead\">' + ALL.length + ' 场景 · 点击卡片查看详情并复制指令</div></div><span class=\"h-badge\">' + ALL.length + ' 场景</span>' +\r\n '<div class=\"hero-steps\"><span class=\"step\">🔍 找场景</span><span class=\"arrow\">→</span><span class=\"step\">📋 复制指令</span><span class=\"arrow\">→</span><span class=\"step\">💬 发给 AI</span></div>' +\r\n '</header>' +\r\n (INIT_BANNER && !INIT_BANNER.hidden ? '<div class=\"init-banner\" id=\"initBanner\"><div class=\"ib-text\"><div class=\"ib-title\">' + esc(INIT_BANNER.title) + '</div><div class=\"ib-sub\">' + esc(INIT_BANNER.subtitle) + '</div></div><button class=\"copy-btn\" data-c=\"' + esc(INIT_BANNER.prompt) + '\">' + esc(INIT_BANNER.button_text) + '</button>' + (INIT_BANNER.closable === false ? '' : '<button class=\"ib-close\" id=\"initClose\" aria-label=\"关闭\">✕</button>') +\r\n (INIT_BANNER.steps && INIT_BANNER.steps.length ? '<div class=\"init-steps\">' + INIT_BANNER.steps.map(function(st, i){ return '<div class=\"init-step\"><div class=\"s-n\">' + (i+1) + '</div><div class=\"s-t\">' + esc(st.title) + '</div>' + (st.desc ? '<div class=\"s-d\">' + esc(st.desc) + '</div>' : '') + '</div>'; }).join('') + '</div>' : '') +\r\n '</div>' : '') +\r\n '<div class=\"search-wrap\"><div class=\"search-box\"><span class=\"s-icon\">🔍</span><input id=\"sB\" type=\"search\" placeholder=\"搜索全部场景\" autocomplete=\"off\"><button class=\"s-clear\" id=\"sClear\">✕</button></div></div>' +\r\n '<div class=\"hitcount\" id=\"hitC\" hidden></div><div class=\"search-empty\" id=\"emptyC\" hidden>没有找到相关场景,换个词试试~</div>' +\r\n '<div class=\"pages\" id=\"pages\">';\r\nGROUPS.forEach(function(g){\r\n h += '<div class=\"page\" data-page=\"' + g.key + '\">';\r\n g.subgroups.forEach(function(sg){\r\n h += '<details class=\"subgroup\" open><summary>' + sg.name + '<span class=\"sg-count\">' + sg.scenes.length + '</span></summary><div class=\"sg-body\"><div class=\"grid\">';\r\n sg.scenes.forEach(function(s){\r\n h += '<div class=\"mini\" data-key=\"' + s.id + '\">' +\r\n '<div class=\"m-top\">' + chipHTML(s) + '</div>' +\r\n '<div class=\"m-bottom\">' +\r\n '<div class=\"m-name\">' + esc(s.name) + '</div>' +\r\n '<button class=\"copy-btn\" data-c=\"' + esc(buildPrompt(s, {})) + '\">复制</button>' +\r\n '</div>' +\r\n '</div>';\r\n });\r\n h += '</div></div></details>';\r\n });\r\n h += '</div>';\r\n});\r\n/* ===== 关于 Tab(最后 · 联系作者 + 版本 + 其他技能 · 拼在 pages 容器内)===== */\r\nh += '<div class=\"page\" data-page=\"about\">';\r\n/* ① 联系作者(第一位)*/\r\nif (CONTACT && CONTACT.items && CONTACT.items.length) {\r\n h += '<div class=\"about-sec\"><div class=\"as-head\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"width:14px;height:14px;flex-shrink:0\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg> 联系作者</div><div class=\"as-body\">';\r\n CONTACT.items.forEach(function(it){\r\n if (it.url && String(it.value).indexOf('http') === 0) {\r\n h += '<div class=\"about-row\"><span class=\"a-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg></span><div class=\"a-t\"><b>' + esc(it.label) + '</b><a class=\"a-link\" href=\"' + esc(it.value) + '\" target=\"_blank\" rel=\"noopener\">' + esc(it.value) + '</a></div></div>';\r\n } else {\r\n h += '<div class=\"about-row\"><span class=\"a-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg></span><div class=\"a-t\"><b>' + esc(it.label) + '</b><span>' + esc(it.value) + '</span></div></div>';\r\n }\r\n });\r\n if (CONTACT.copy_all) {\r\n var contactTxt = CONTACT.items.map(function(it){ return it.label + ': ' + it.value; }).join('\\n');\r\n h += '<div class=\"about-row\"><span class=\"a-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg></span><div class=\"a-t\"><b>一键复制</b><span>全部联系信息</span></div><button class=\"copy-btn a-copy\" data-c=\"' + esc(contactTxt) + '\">复制</button></div>';\r\n }\r\n h += '</div></div>';\r\n}\r\n/* ② 版本(第二位)*/\r\nh += '<div class=\"about-sec\"><div class=\"as-head\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"width:14px;height:14px;flex-shrink:0\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16\"/><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/></svg> 版本</div><div class=\"as-body\"><div class=\"about-row\"><span class=\"a-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z\"/><line x1=\"7\" y1=\"7\" x2=\"7.01\" y2=\"7\"/></svg></span><div class=\"a-t\"><b>' + esc(SKILL_NAME) + '</b><span>v' + esc(SKILL_VERSION) + ' · HELP 模板 v4</span></div></div></div></div>';\r\n/* ③ 其他技能(第三位 · SVG 图标)*/\r\nif (RECOMMENDATIONS && RECOMMENDATIONS.length) {\r\n h += '<div class=\"about-sec\"><div class=\"as-head\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"width:14px;height:14px;flex-shrink:0\"><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/><path d=\"M12 2a7 7 0 0 0-4 12.7c.6.5 1 1.4 1 2.3h6c0-.9.4-1.8 1-2.3A7 7 0 0 0 12 2z\"/></svg> 其他技能</div><div class=\"as-body\">';\r\n RECOMMENDATIONS.forEach(function(r){\r\n h += '<div class=\"about-row\"><span class=\"a-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"/></svg></span><div class=\"a-t\"><b>' + esc(r.name) + '</b><span>' + esc(r.desc) + '</span></div>' + (r.wake ? '<span class=\"a-badge\">' + esc(r.wake) + '</span>' : '') + '</div>';\r\n });\r\n h += '</div></div>';\r\n}\r\nh += '</div>'; /* 关闭 about page */\r\nh += '</div></div>'; /* 关闭 pages + app-inner */\r\nh += '<div class=\"tab-bar\" id=\"tabBar\">';\r\nGROUPS.forEach(function(g, i){\r\n h += '<button class=\"tab' + (i===0?' active':'') + '\" data-nav=\"' + g.key + '\">' + tabIconHTML(g) + g.name + '</button>';\r\n});\r\nh += '<button class=\"tab\" data-nav=\"about\"><span class=\"t-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16\"/><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/></svg></span>关于</button>';\r\nh += '</div></div>';\r\nscreen.innerHTML = h;\r\n\r\n/* 初始化横幅手动关闭(✕)*/\r\nvar initClose = document.getElementById('initClose');\r\nif (initClose) initClose.addEventListener('click', function(){\r\n var b = document.getElementById('initBanner');\r\n if (b) b.style.display = 'none';\r\n});\r\n/* ===== 自然滚动: 内容跟手, 搜索栏 sticky 吸顶(CSS) =====\r\n 旧版两段式 transform 抵消导致: 吸顶前内容不跟手、短页(关于)滚不到吸顶 → 全部移除 */\r\n/* 页面高度 = 内容自然高度(不撑高): 内容短则页面短, 滑到底即停, 不出灰色空白\r\n (原实现 pg.style.minHeight = screen.clientHeight 把短页撑到一屏高,\r\n 内容下方露出透明 page 背景 → 灰色底被顶上来;#289 用户验收拍板)*/\r\n\r\n/* ===== 滑动切页(ViewPager)===== */\r\nvar pages = document.getElementById('pages');\r\nvar tabs = Array.prototype.slice.call(document.querySelectorAll('.tab'));\r\nvar screen = document.querySelector('.screen');\r\n/* ③ 容器高度锁定: 用内容实际全高(而非首屏高), 防空白可滑也防内容被截断 */\r\nfunction lockPagesHeight(idx){\r\n if (idx === undefined) idx = Math.min(curIndex(), pages.children.length - 1);\r\n var pg = pages.children[idx];\r\n if (!pg) return;\r\n pages.style.height = pg.scrollHeight + 'px';\r\n}\r\nfunction curIndex(){ return Math.round(pages.scrollLeft / pages.clientWidth); }\r\nfunction syncTab(){\r\n var i = Math.min(curIndex(), tabs.length - 1);\r\n tabs.forEach(function(t, j){ t.classList.toggle('active', j === i); });\r\n}\r\npages.addEventListener('scroll', function(){\r\n clearTimeout(syncTab._t);\r\n syncTab._t = setTimeout(function(){\r\n if (Date.now() < syncTab._lockUntil) return; /* 点击后的滚动动画期不覆盖 active */\r\n syncTab();\r\n lockPagesHeight(); /* 横向滑动结束也校准高度 */\r\n }, 15);\r\n}, {passive:true});\r\ntabs.forEach(function(t){\r\n t.addEventListener('click', function(){\r\n var i = tabs.indexOf(t);\r\n tabs.forEach(function(x, j){ x.classList.toggle('active', j === i); });\r\n syncTab._lockUntil = Date.now() + 900; /* 锁 ~0.9s: 覆盖点击动画期即可, 缩短滑动跟手延迟 */\r\n /* 切换立即: ① 归零纵向滚动(防旧位置灰色遮挡) ② 立即锁定新页高度(防内容截断/滑不动) */\r\n /* 手机端: .screen 是滚动容器, scrollTop=0 = 回到内容顶部(页面不跳);\r\n 宽屏: .screen overflow:visible, 真正滚动的是 window —— 定位到 pages 容器顶部(搜索栏处), 不跳整页最上层 */\r\n if (screen.scrollTop !== undefined && screen.clientHeight > 0 && screen.scrollHeight > screen.clientHeight) {\r\n screen.scrollTop = 0;\r\n } else {\r\n var pagesTop = pages.getBoundingClientRect().top + (window.pageYOffset || document.documentElement.scrollTop || 0);\r\n /* 落点必须再让开吸顶搜索栏: 只减 8px 时 .pages 顶正好落在吸顶栏之下, 当页第一个元素(首个子功能组摘要)被压成一条缝,\r\n 点不到也看不见 —— 吸顶栏高动态取(不写死像素: 视口宽/字体缩放都会改它), 取不到时按 0 退化为原行为 */\r\n var stickyBar = document.querySelector('.search-wrap');\r\n window.scrollTo(0, Math.max(0, pagesTop - (stickyBar ? stickyBar.offsetHeight : 0) - 8));\r\n }\r\n pages.style.scrollSnapType = 'none';\r\n pages.scrollTo({left: i * pages.clientWidth, behavior:'smooth'});\r\n lockPagesHeight(i); /* 直接传目标索引, 不等动画 */\r\n /* 点击的 Tab 尽可能居中显示(首尾贴边) */\r\n centerTab(t);\r\n setTimeout(function(){\r\n pages.style.scrollSnapType = '';\r\n syncTab._lockUntil = 0; /* 动画结束立即解锁, 之后滑动变色实时跟手 */\r\n lockPagesHeight(i); /* 动画结束后再校准一次 */\r\n }, 900);\r\n });\r\n});\r\n/* ===== Tab 条: 点击的 Tab 居中显示 ===== */\r\nfunction centerTab(tab){\r\n var bar = document.getElementById('tabBar');\r\n var max = bar.scrollWidth - bar.clientWidth;\r\n var target = tab.offsetLeft + tab.offsetWidth / 2 - bar.clientWidth / 2;\r\n target = Math.max(0, Math.min(target, max));\r\n bar.scrollTo({left: target, behavior: 'smooth'});\r\n}\r\n\r\n/* ===== Sheet 弹层(B3: 复制不自动关 · B4: 无参数显 prompt)===== */\r\nvar mask = document.getElementById('sheetMask');\r\nvar sheet = document.getElementById('sheet');\r\nvar shHead = document.getElementById('shHead');\r\nvar shBody = document.getElementById('shBody');\r\nvar shCopy = document.getElementById('shCopy');\r\nvar curScene = null;\r\n\r\nfunction openSheet(s){\r\n curScene = s;\r\n shHead.innerHTML = '<span class=\"s-title\">' + esc(s.name) + '</span>' + chipHTML(s);\r\n var form = '';\r\n var hasParams = s.params && s.params.length;\r\n if (hasParams) {\r\n form = '<div class=\"pform\" data-pid=\"' + s.id + '\">';\r\n s.params.forEach(function(p){\r\n form += '<div class=\"pfield\"><label>' + esc(p.label) + (p.req ? '' : '<em>选填</em>') + '</label>' +\r\n '<input data-p=\"' + esc(p.key) + '\" value=\"' + esc(p.value || '') + '\" placeholder=\"' + esc(p.hint || '') + '\"></div>';\r\n });\r\n form += '</div>';\r\n }\r\n /* 预览:prompt + 末尾 key:value(有参数时实时重组)*/\r\n var prev = '<div class=\"pprev\"><span class=\"pv-label\">Prompt 预览</span><span data-prev>' + esc(buildPrompt(s, {})) + '</span></div>';\r\n shBody.innerHTML = form + prev;\r\n shCopy.dataset.pid = s.id;\r\n shCopy.dataset.c = buildPrompt(s, {});\r\n /* 参数化实时预览 */\r\n var fm = sheet.querySelector('.pform');\r\n if (fm) fm.addEventListener('input', function(){\r\n var pv = sheet.querySelector('[data-prev]');\r\n if (pv) pv.textContent = buildPrompt(s, readParams(s.id));\r\n });\r\n mask.classList.add('show');\r\n sheet.classList.add('show');\r\n sheet.querySelector('.s-scroll').scrollTop = 0;\r\n}\r\nfunction closeSheet(){\r\n mask.classList.remove('show');\r\n sheet.classList.remove('show');\r\n}\r\nmask.addEventListener('click', closeSheet);\r\ndocument.getElementById('sheetClose').addEventListener('click', closeSheet);\r\n\r\n/* ===== 卡片交互 ===== */\r\nscreen.addEventListener('click', function(e){\r\n var mini = e.target.closest('.mini');\r\n if (mini) {\r\n if (e.target.closest('[data-c]')) return;\r\n openSheet(SCENE[mini.dataset.key]);\r\n }\r\n});\r\n\r\n/* ===== Toast(公共组件)===== */\r\nfunction showToast(){\r\n toast('已复制', '粘贴给 AI,技能会自动执行,完成后你会拿到结果 HTML。', {icon:'copy'});\r\n}\r\nfunction toastMsg(msg){\r\n toast('请先填写: ' + msg, '填写完整后再复制指令', {icon:'warn', badge:{text:'未完成', type:'warn'}});\r\n}\r\nfunction doCopy(text){\r\n var ta = document.createElement('textarea');\r\n ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0';\r\n document.body.appendChild(ta); ta.select();\r\n try { document.execCommand('copy'); } catch(e){}\r\n document.body.removeChild(ta);\r\n}\r\n\r\n/* ===== 全局复制(含参数校验)===== */\r\ndocument.addEventListener('click', function(e){\r\n var b = e.target.closest('[data-c]');\r\n if (!b) return;\r\n e.preventDefault(); e.stopPropagation();\r\n var s = SCENE[b.dataset.pid || (b.closest('.mini') ? b.closest('.mini').dataset.key : '')];\r\n var text = b.dataset.c;\r\n if (s && s.params && s.params.length) {\r\n var v = readParams(s.id);\r\n var miss = getMissing(s, v);\r\n if (miss.length) { toastMsg(miss.join('、')); return; }\r\n text = buildPrompt(s, v);\r\n }\r\n doCopy(text);\r\n showToast();\r\n /* B3: 复制后不自动关弹窗 */\r\n});\r\n\r\n/* ===== 搜索(全局跨 Tab + 自动跳转 + 高亮)===== */\r\nvar sB = document.getElementById('sB');\r\nvar sClear = document.getElementById('sClear');\r\nvar lastQuery = '';\r\nfunction doSearch(){\r\n var q = sB.value.trim().toLowerCase();\r\n sClear.style.display = q ? 'flex' : 'none';\r\n if (!q) {\r\n var cur = curIndex();\r\n Array.prototype.forEach.call(pages.children, function(pg, i){\r\n pg.querySelectorAll('.mini').forEach(function(m){\r\n m.style.display = '';\r\n m.querySelector('.m-name').innerHTML = esc(SCENE[m.dataset.key].name);\r\n });\r\n pg.querySelectorAll('.subgroup').forEach(function(sg){ sg.style.display = ''; });\r\n });\r\n /* 恢复全量后必须同步重算高度锁: 筛选期 .pages 被锁在「筛选后」的当页高, 不重算就当页被锁矮,\r\n 后半页连同末张场景卡一起滚不到 —— 这里的 scrollTo 目标就是当前位置(不触发 scroll 事件), 兜不住这次重算 */\r\n lockPagesHeight();\r\n if (lastQuery) pages.scrollTo({left: cur * pages.clientWidth, behavior:'smooth'});\r\n lastQuery = '';\r\n document.getElementById('hitC').hidden = true;\r\n document.getElementById('emptyC').hidden = true;\r\n return;\r\n }\r\n lastQuery = q;\r\n var total = 0, firstHitPage = -1;\r\n Array.prototype.forEach.call(pages.children, function(pg, i){\r\n var pageHit = 0;\r\n pg.querySelectorAll('.mini').forEach(function(m){\r\n var show = m.textContent.toLowerCase().indexOf(q) > -1;\r\n m.style.display = show ? '' : 'none';\r\n if (show) pageHit++;\r\n var orig = SCENE[m.dataset.key].name;\r\n var i2 = orig.toLowerCase().indexOf(q);\r\n if (q && i2 >= 0) m.querySelector('.m-name').innerHTML = esc(orig.slice(0,i2)) + '<mark>' + esc(orig.slice(i2,i2+q.length)) + '</mark>' + esc(orig.slice(i2+q.length));\r\n else m.querySelector('.m-name').innerHTML = esc(orig);\r\n });\r\n /* 子功能组:无命中则隐藏 */\r\n pg.querySelectorAll('.subgroup').forEach(function(sg){\r\n var vis = sg.querySelectorAll('.mini:not([style*=\"none\"])').length > 0;\r\n sg.style.display = vis ? '' : 'none';\r\n if (q && vis) sg.open = true;\r\n });\r\n total += pageHit;\r\n if (pageHit > 0 && firstHitPage === -1) firstHitPage = i;\r\n });\r\n if (firstHitPage >= 0 && firstHitPage !== curIndex()) {\r\n pages.scrollTo({left: firstHitPage * pages.clientWidth, behavior:'smooth'});\r\n }\r\n document.getElementById('hitC').hidden = false;\r\n document.getElementById('hitC').textContent = '匹配 ' + total + ' 个场景';\r\n document.getElementById('emptyC').hidden = total > 0;\r\n}\r\nsB.addEventListener('input', doSearch);\r\nsClear.addEventListener('click', function(){ sB.value = ''; doSearch(); sB.focus(); });\r\n/* 初始锁定 + 子功能组折叠/展开时高度校准 */\r\nlockPagesHeight();\r\ndocument.addEventListener('click', function(e){\r\n var sg = e.target.closest('.subgroup > summary');\r\n if (sg) setTimeout(lockPagesHeight, 60); /* details 切换后重算 */\r\n});\r\n</script>\r\n</body>\r\n</html>\r\n";
32
+ export const HELP_SHELL_SUFFIX = "</script>\r\n<script>\r\n/* Base Skill 控件库 v1.2(唯一真相源 · 跨技能 · 领域无关)\r\n * 契约: docs/component-contract.md v1.2\r\n * v1.2 核心(#269 试点用户拍板):\r\n * - snapshot 结构化接口: buildDataText/buildLogText 领域无关(title/summary/sections)\r\n * - toast 通用提示控件: 4 形态(徽章/操作/计数/留空)+ 队列 + 图标库 + 多操作 + 富详情 + 无障碍\r\n * - 复制按钮控件化: 复制数据/日志 = Base 控件;预览/格式选择/脱敏/导出\r\n * - 新控件 P0+P1: formPrompt/selectList/confirm/foldBox/statusBadge/emptyState/errorReceipt\r\n * - 结构校验违规直接报错(硬拦截)\r\n * 注入点: SHARED-HELPERS 占位符(由 injector.py 替换本文件)\r\n * 修改必须走公共层 ISSUE(总纲 09)+ CHANGELOG(见 docs/component-contract.md §8)\r\n */\r\n\r\n/* ── P0 守卫组 ── */\r\nfunction esc(s){return String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));}\r\nfunction arr(v){return Array.isArray(v)?v:[];}\r\nfunction val(v){return v===null||v===undefined||v===''?'<span style=\"color:var(--fg3)\">未填写</span>':esc(v);}\r\nfunction yes(v){return v?'<span class=\"ok\">通过</span>':'<span class=\"bad\">未通过</span>';}\r\nfunction validate(p){if(!p||typeof p!=='object')return{ok:false,msg:'数据未注入'};if(p.status!=='ok')return{ok:false,msg:p.message||'数据状态非 ok'};if(!p.data||typeof p.data!=='object')return{ok:false,msg:'data 缺失'};return{ok:true};}\r\nfunction _fbCopy(s){var ok=false;try{var t=document.createElement('textarea');t.value=s;t.style.cssText='position:fixed;left:-9999px;top:0;opacity:0';document.body.appendChild(t);t.focus();t.select();ok=document.execCommand('copy');document.body.removeChild(t);}catch(e){ok=false;}return ok;}\r\n\r\n/* ── 复制动作 v2(不改按钮文字 + toast 反馈 · v1.10 #328 文案钩子)──\r\n * copyText(s, opts?)\r\n * opts: { silent, toast:{ok:{msg,detail,icon?}, fail:{msg,detail,icon?}}, onOk, onFail }\r\n * - toast 文案配置: 只覆盖提供的字段, 缺省回落默认文案(08 规范: 文案由技能按场景自设计)\r\n * - onOk/onFail 回调: 成功/最终失败必触发; silent 时不弹 toast 仍触发回调\r\n * - 未传新选项: 行为与 v1.9 逐字一致(向后兼容)\r\n */\r\nfunction copyText(s, opts){\r\n opts = opts || {};\r\n if(!s) return;\r\n var t = opts.toast || {}, okCfg = t.ok || {}, failCfg = t.fail || {};\r\n var okMsg = okCfg.msg !== undefined ? okCfg.msg : '已复制';\r\n var okDetail = okCfg.detail !== undefined ? okCfg.detail : '粘贴给 AI';\r\n var failMsg = failCfg.msg !== undefined ? failCfg.msg : '复制失败';\r\n var failDetail = failCfg.detail !== undefined ? failCfg.detail : '长按选择文本手动复制';\r\n function ok(){\r\n if(opts.onOk) opts.onOk();\r\n if(!opts.silent){\r\n var o = {};\r\n if(okCfg.icon) o.icon = okCfg.icon;\r\n toast(okMsg, okDetail, Object.keys(o).length ? o : undefined);\r\n }\r\n }\r\n function fail(){\r\n if(opts.onFail) opts.onFail();\r\n if(!opts.silent){\r\n var o = {badge:{text:'失败',type:'danger'}};\r\n if(failCfg.icon) o.icon = failCfg.icon;\r\n toast(failMsg, failDetail, o);\r\n }\r\n }\r\n if(navigator.clipboard&&navigator.clipboard.writeText){\r\n try{\r\n var pr=navigator.clipboard.writeText(s);\r\n if(pr&&pr.then){pr.then(function(){ok();}).catch(function(){_fbCopy(s)?ok():fail();});}\r\n else{ok();}\r\n }catch(e){_fbCopy(s)?ok():fail();}\r\n }else{_fbCopy(s)?ok():fail();}\r\n}\r\n\r\n/* ── toast 通用提示控件 v1.8(堆叠模式 · #304)──\r\n * toast(msg, detail?, options?)\r\n * options: { icon, badge:{text,type}, actions:[{label,onClick}], count, lines:[], code, timeout, maxStack }\r\n * 向后兼容: toast(msg, detail) = 等价 v1.1\r\n * 堆叠模式(v1.8 · #304 用户拍板): 同屏最多 N 条同时可见(N 默认 5, opts.maxStack 可配,\r\n * 栈容量取栈内各 toast maxStack 最大值; ≤820px 视口自动收窄为 3); 老上旧下(新 toast\r\n * 贴屏幕底部出现, 旧的向上顶, 间距 8px); 超 N 挤掉最旧(FIFO); 单条独立计时消失\r\n */\r\n(function(){\r\n var stack = null;\r\n var styleInjected = false;\r\n var DEFAULT_MAX = 5;\r\n var MOBILE_MAX = 3;\r\n var ICONS = { copy:'📋', ok:'✅', warn:'⚠️', danger:'❌', info:'💡' };\r\n var CSS = '.hm-toast-stack{position:fixed;left:50%;bottom:calc(24px + env(safe-area-inset-bottom,0));transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;gap:8px;z-index:9999;pointer-events:none}.hm-toast{position:relative;transform:scale(.9);opacity:0;background:rgba(28,28,30,.94);-webkit-backdrop-filter:blur(20px) saturate(180%);backdrop-filter:blur(20px) saturate(180%);color:#f0f0f0;border-radius:14px;padding:13px 14px 13px 16px;display:flex;align-items:flex-start;gap:12px;max-width:480px;min-width:300px;box-shadow:0 10px 32px rgba(0,0,0,.32),0 0 0 .5px rgba(255,255,255,.08) inset;pointer-events:none;transition:opacity .22s ease-out,transform .22s cubic-bezier(.34,1.56,.64,1)}.hm-toast.show{opacity:1;transform:scale(1);pointer-events:auto}.hm-toast-icon{font-size:20px;line-height:1;padding-top:1px;flex-shrink:0}.hm-toast-body{flex:1;min-width:0}.hm-toast-title-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.hm-toast-title{font-weight:600;font-size:12.5px;line-height:1.4;color:#fff;margin-bottom:2px}.hm-toast-detail{font-size:11px;line-height:1.5;color:#c8c8cc}.hm-toast-lines{font-size:11px;line-height:1.55;color:#c8c8cc}.hm-toast-code{background:rgba(0,0,0,.32);border-radius:8px;padding:8px 10px;font-size:10.5px;line-height:1.5;color:#aeb0b8;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;margin-top:6px;max-height:140px;overflow:auto}.hm-toast-chip{font-size:10px;font-weight:700;padding:2px 8px;border-radius:999px;letter-spacing:.02em;flex-shrink:0}.hm-toast-chip.ok{background:rgba(52,199,89,.18);color:#4dd96b}.hm-toast-chip.warn{background:rgba(255,149,0,.18);color:#ffb340}.hm-toast-chip.danger{background:rgba(255,59,48,.18);color:#ff6961}.hm-toast-chip.gray{background:rgba(255,255,255,.12);color:#c8c8cc}.hm-toast-count{font-size:10px;font-weight:700;color:#c8c8cc;background:rgba(255,255,255,.08);padding:2px 8px;border-radius:6px;font-variant-numeric:tabular-nums;flex-shrink:0}.hm-toast-act{font-size:11px;font-weight:600;color:#4dd96b;border:none;background:none;cursor:pointer;padding:2px 4px;flex-shrink:0;font-family:inherit}.hm-toast-act:active{opacity:.7}.hm-toast-close{background:rgba(255,255,255,.10);color:#34c759;border:0;border-radius:8px;padding:5px 9px;font-size:10.5px;font-weight:500;font-family:inherit;cursor:pointer;white-space:nowrap;margin-left:6px;flex-shrink:0}.hm-toast-close:active{background:rgba(255,255,255,.2)}@media(max-width:820px){.hm-toast-stack{left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom,0));transform:none;align-items:stretch}.hm-toast{transform:scale(.95);max-width:none;min-width:0}.hm-toast.show{transform:scale(1)}}';\r\n\r\n function ensureStyle(){\r\n if(styleInjected) return;\r\n styleInjected = true;\r\n var st = document.createElement('style');\r\n st.id = 'hm-toast-style';\r\n st.textContent = CSS;\r\n document.head.appendChild(st);\r\n }\r\n\r\n function getStack(){\r\n if(!stack){\r\n stack = document.createElement('div');\r\n /* 栈要带 CSS 那条 fixed 定位规则的选择器类名(`.hm-toast-stack`):只写 id 时提示落在文档流末尾,不悬浮。 */\r\n stack.className = 'hm-toast-stack';\r\n stack.id = 'hm-toast-stack';\r\n document.body.appendChild(stack);\r\n }\r\n return stack;\r\n }\r\n\r\n function isMobile(){\r\n return window.matchMedia('(max-width: 820px)').matches;\r\n }\r\n\r\n /* 栈容量 = 栈内各 toast maxStack 的最大值(空栈默认 5); 移动端 ≤820px 收窄为 3 */\r\n function stackCap(){\r\n var cap = 0;\r\n if(stack) stack.querySelectorAll('.hm-toast').forEach(function(t){\r\n var m = parseInt(t.getAttribute('data-max')||DEFAULT_MAX, 10);\r\n if(m > cap) cap = m;\r\n });\r\n if(cap === 0) cap = DEFAULT_MAX;\r\n if(isMobile() && cap > MOBILE_MAX) cap = MOBILE_MAX;\r\n return cap;\r\n }\r\n\r\n /* 超 N 挤掉最旧(FIFO) */\r\n function evictOldest(){\r\n var cap = stackCap();\r\n while(stack.querySelectorAll('.hm-toast').length > cap){\r\n var oldest = stack.querySelector('.hm-toast');\r\n if(!oldest) break;\r\n clearTimeout(oldest._timer);\r\n oldest.remove();\r\n }\r\n }\r\n\r\n function dismiss(t){\r\n if(!t || !t.isConnected) return;\r\n clearTimeout(t._timer);\r\n t.classList.remove('show');\r\n setTimeout(function(){\r\n if(t.isConnected) t.remove();\r\n }, 250);\r\n }\r\n\r\n function show(item){\r\n var opts = item.opts;\r\n var container = getStack();\r\n ensureStyle();\r\n var msg = item.msg, detail = item.detail;\r\n var t = document.createElement('div');\r\n t.className = 'hm-toast';\r\n t.setAttribute('role','status');\r\n t.setAttribute('aria-live','polite');\r\n t.setAttribute('data-max', String(opts.maxStack || DEFAULT_MAX));\r\n var icon = ICONS[opts.icon] || opts.icon || '📋';\r\n var titleRow = '<span class=\"hm-toast-title\">'+esc(msg)+'</span>';\r\n if(opts.badge){\r\n var b = opts.badge;\r\n var btype = ['ok','warn','danger'].indexOf(b.type)>=0 ? b.type : 'ok';\r\n titleRow += '<span class=\"hm-toast-chip '+btype+'\">'+esc(b.text)+'</span>';\r\n }\r\n if(opts.count){\r\n titleRow += '<span class=\"hm-toast-count\">'+esc(opts.count)+'</span>';\r\n }\r\n if(opts.actions && opts.actions.length){\r\n opts.actions.slice(0,2).forEach(function(a){\r\n titleRow += '<button class=\"hm-toast-act\" data-act=\"'+esc(a.label)+'\">'+esc(a.label)+'</button>';\r\n });\r\n }\r\n var bodyHtml = '<div class=\"hm-toast-title-row\">'+titleRow+'</div>';\r\n if(detail){\r\n bodyHtml += '<div class=\"hm-toast-detail\">'+esc(detail)+'</div>';\r\n }\r\n if(opts.lines && opts.lines.length){\r\n bodyHtml += '<div class=\"hm-toast-lines\">'+opts.lines.map(function(l){return esc(l);}).join('<br>')+'</div>';\r\n }\r\n if(opts.code){\r\n bodyHtml += '<div class=\"hm-toast-code\">'+esc(opts.code)+'</div>';\r\n }\r\n t.innerHTML = '<div class=\"hm-toast-icon\">'+icon+'</div><div class=\"hm-toast-body\">'+bodyHtml+'</div><button class=\"hm-toast-close\">✓ 知道了</button>';\r\n container.appendChild(t);\r\n evictOldest();\r\n if(opts.actions && opts.actions.length){\r\n var actBtns = t.querySelectorAll('.hm-toast-act');\r\n opts.actions.slice(0,2).forEach(function(a, i){\r\n actBtns[i].addEventListener('click', function(){\r\n var f = a.onClick;\r\n dismiss(t);\r\n if(f) setTimeout(f, 0);\r\n });\r\n });\r\n }\r\n t.querySelector('.hm-toast-close').addEventListener('click', function(){ dismiss(t); });\r\n var timer = setTimeout(function(){ dismiss(t); }, opts.timeout || 4500);\r\n t._timer = timer;\r\n requestAnimationFrame(function(){ t.classList.add('show'); });\r\n }\r\n\r\n window" + ".toast = function(msg, detail, options){\r\n options = options || {};\r\n show({ msg: msg, detail: detail || '', opts: options });\r\n };\r\n /* 清空栈(技能页面销毁/测试用):移除当前全部显示 */\r\n window" + ".__hmToastFlush = function(){\r\n if(!stack) return;\r\n stack.querySelectorAll('.hm-toast').forEach(function(t){ clearTimeout(t._timer); t.remove(); });\r\n };\r\n})();\r\n\r\n/* ── snapshot 结构校验(违规直接报错)── */\r\nfunction _validateSnapshot(s){\r\n if(!s || typeof s !== 'object'){\r\n throw new Error('snapshot 违规: scene.snapshot 必须是对象');\r\n }\r\n if(typeof s.title !== 'string' || !s.title.trim()){\r\n throw new Error('snapshot 违规: title 必须是非空字符串');\r\n }\r\n if(!Array.isArray(s.summary)){\r\n throw new Error('snapshot 违规: summary 必须是数组');\r\n }\r\n if(!Array.isArray(s.sections)){\r\n throw new Error('snapshot 违规: sections 必须是数组');\r\n }\r\n s.sections.forEach(function(sec, i){\r\n if(!sec || typeof sec !== 'object' || typeof sec.heading !== 'string' || !Array.isArray(sec.rows)){\r\n throw new Error('snapshot 违规: sections['+i+'] 必须含 heading(字符串) + rows(数组)');\r\n }\r\n });\r\n return true;\r\n}\r\n\r\n/* 行渲染: 支持字符串 或 {text, sensitive}(脱敏)*/\r\nfunction _rowText(r){\r\n if(r && typeof r === 'object' && !Array.isArray(r)){\r\n if(r.sensitive) return '****(敏感字段已脱敏)';\r\n return String(r.text ?? '');\r\n }\r\n return String(r ?? '');\r\n}\r\n\r\n/* ── buildDataText v1.2(snapshot 结构化 · 领域无关 · format 支持)──\r\n * buildDataText(p, format?) format: 'text'(默认) | 'json' | 'csv'\r\n */\r\nfunction buildDataText(p, format){\r\n var d = p && p.data || {};\r\n var me = d.meta || {};\r\n var s = d.scene || {};\r\n var snap = s.snapshot;\r\n _validateSnapshot(snap);\r\n format = format || 'text';\r\n\r\n if(format === 'json'){\r\n return JSON.stringify(snap, null, 2);\r\n }\r\n if(format === 'csv'){\r\n var out = [];\r\n out.push(snap.title);\r\n out.push(snap.summary.map(_rowText).join('; '));\r\n snap.sections.forEach(function(sec){\r\n out.push('[' + sec.heading + ']');\r\n sec.rows.forEach(function(r){ out.push(_rowText(r)); });\r\n });\r\n return out.join('\\n');\r\n }\r\n\r\n var L = ['【'+(me.skill_name||me.command_cn||'')+' · '+(me.command_cn||'')+'】'];\r\n L.push('场景: '+(me.command_cn||'')+(s.scene_id?('('+s.scene_id+')'):'')+(me.wake_word?(' · 唤醒词「'+me.wake_word+'」'):''));\r\n L.push('时间: '+(me.occurred_at||''));\r\n if(snap.summary.length){\r\n snap.summary.forEach(function(x){ L.push(_rowText(x)); });\r\n }\r\n snap.sections.forEach(function(sec){\r\n if(!sec.rows.length) return;\r\n L.push('▍'+sec.heading);\r\n sec.rows.forEach(function(r){ L.push(' · '+_rowText(r)); });\r\n });\r\n return L.join('\\n');\r\n}\r\n\r\n/* ── buildLogText v1.2(6 段日志 · format 支持)── */\r\nfunction buildLogText(p, format){\r\n var d = p && p.data || {};\r\n var me = d.meta || {};\r\n var s = d.scene || {};\r\n var cl = d.copy_log || s.copy_log || {};\r\n format = format || 'text';\r\n\r\n var L = ['① 场景标识'];\r\n L.push(' 命 令: '+(me.command_cn||''));\r\n L.push(' 唤醒词: '+(me.wake_word||'(未知)'));\r\n L.push(' 场景名: '+(me.command_cn||'')+(s.scene_id?('('+s.scene_id+')'):''));\r\n L.push('');\r\n L.push('② AI 思考链');\r\n L.push(' '+(cl.thinking||'(本地渲染 · 无 AI 链)'));\r\n L.push('');\r\n L.push('③ 底层数据结构');\r\n L.push(' '+(cl.data_structure||'(只读查询)'));\r\n L.push('');\r\n L.push('④ 调用链');\r\n L.push(' '+(cl.call_chain||'(未知)'));\r\n L.push('');\r\n L.push('⑤ 时间戳 + 版本');\r\n L.push(' 本地时间: '+(cl.timestamp||me.occurred_at||'(未知)'));\r\n L.push(' 版 本: '+(me.skill_version||'(未知)'));\r\n L.push('');\r\n L.push('⑥ 异常信息');\r\n L.push(' '+(cl.exception||'无'));\r\n return L.join('\\n');\r\n}\r\n\r\n/* ── metaHeader / remindersBlock(v1.1 保留)── */\r\nfunction metaHeader(p, m){var me=p.data.meta||{};var stage=m&&m.stage?('<span class=\"stage\">'+esc(m.stage)+'</span>'):'';return '<header class=\"hero\"><div class=\"eyebrow\" style=\"color:#8e8e93;font-size:11px;font-weight:600\">'+esc(me.command_cn||'')+' · '+esc(me.occurred_at||'')+'</div><h1>'+esc(m&&m.title||me.command_cn||'')+'</h1>'+(m&&m.lead?'<p class=\"lead\">'+esc(m.lead)+'</p>':'')+stage+'</header>';}\r\nfunction remindersBlock(p){var rs=arr(p.data.reminders);if(!rs.length)return '';return '<section class=\"remind\"><h2>顺路提醒</h2>'+rs.map(r=>'<div class=\"remind-item '+(r.type==='warn'?'warn':r.type==='danger'?'bad':'')+'\">'+esc(r.text)+'</div>').join('')+'</section>';}\r\n\r\n/* ── actionBar v1.2(场景按钮 + 复制数据/日志 ghost)──\r\n * actionBar(p, extra?, opts?) opts: { preview, formatMenu, download }\r\n */\r\nfunction actionBar(p, extra, opts){\r\n window" + ".__hmPayload = p;\r\n opts = opts || {};\r\n var btns = arr(extra || []);\r\n var sb = opts.noSb ? [] : arr(p && p.data && p.data.scene && p.data.scene.buttons || []);\r\n var html = '<div class=\"hm-actions\">';\r\n btns.concat(sb).forEach(function(b){\r\n html += '<button class=\"copy '+(b.kind||'')+'\" onclick=\"copyText(this.dataset.t)\" data-t=\"'+esc(b.text).replace(/\"/g,'&quot;')+'\">'+esc(b.label)+'</button>';\r\n });\r\n html += '<button class=\"copy ghost\" onclick=\"'+(opts.preview?'window.__hmCopyData(true)':'copyText(buildDataText(window.__hmPayload))')+'\">复制数据</button>';\r\n html += '<button class=\"copy ghost\" onclick=\"'+(opts.preview?'window.__hmCopyLog(true)':'copyText(buildLogText(window.__hmPayload))')+'\">复制日志</button>';\r\n html += '</div>';\r\n if(opts.preview){\r\n html += '<div class=\"hm-preview-overlay\" id=\"hm-preview\" style=\"display:none\">'\r\n + '<div class=\"hm-preview-panel\"><div class=\"hm-preview-head\"><span id=\"hm-preview-title\">复制预览</span>'\r\n + '<button class=\"hm-preview-close\" onclick=\"document.getElementById(\\'hm-preview\\').style.display=\\'none\\'\">✕</button></div>'\r\n + '<pre class=\"hm-preview-body\" id=\"hm-preview-body\"></pre>'\r\n + '<div class=\"hm-preview-actions\"><button class=\"copy primary\" id=\"hm-preview-confirm\">复制</button>'\r\n + '<button class=\"copy\" onclick=\"document.getElementById(\\'hm-preview\\').style.display=\\'none\\'\">取消</button></div>'\r\n + '</div></div>';\r\n }\r\n return html;\r\n}\r\n\r\n/* 复制预览面板(actionBar preview 模式) */\r\nfunction _showCopyPreview(kind){\r\n var p = window.__hmPayload;\r\n var body = document.getElementById('hm-preview-body');\r\n var title = document.getElementById('hm-preview-title');\r\n if(!body) return;\r\n var text = kind === 'log' ? buildLogText(p) : buildDataText(p);\r\n title.textContent = kind === 'log' ? '复制日志 · 预览' : '复制数据 · 预览';\r\n body.textContent = text;\r\n document.getElementById('hm-preview').style.display = 'flex';\r\n document.getElementById('hm-preview-confirm').onclick = function(){\r\n copyText(text);\r\n document.getElementById('hm-preview').style.display = 'none';\r\n };\r\n}\r\nwindow" + ".__hmCopyData = function(){ _showCopyPreview('data'); };\r\nwindow" + ".__hmCopyLog = function(){ _showCopyPreview('log'); };\r\n\r\n/* ── formPrompt(P0 · 用户填参数表单 + 实时预览 + 空值拦截)──\r\n * formPrompt(fields, template) → HTML 字符串\r\n * fields: [{ key, label, type:'text'|'number'|'select', options?, default?, placeholder? }]\r\n * template: 含 {key} 占位符的 prompt 模板\r\n */\r\nfunction formPrompt(fields, template){\r\n fields = arr(fields);\r\n var uid = 'fp' + Math.random().toString(36).slice(2,7);\r\n var html = '<div class=\"fp\" id=\"'+uid+'\">';\r\n fields.forEach(function(f, i){\r\n var fid = uid + '-f' + i;\r\n html += '<div class=\"fp-field\"><label class=\"fp-label\">'+esc(f.label)+'</label>';\r\n if(f.type === 'select'){\r\n html += '<select class=\"fp-input\" id=\"'+fid+'\" data-key=\"'+esc(f.key)+'\">';\r\n arr(f.options).forEach(function(o){\r\n var sel = (String(o.value ?? o) === String(f.default ?? '')) ? ' selected' : '';\r\n html += '<option value=\"'+esc(o.value ?? o)+'\"'+sel+'>'+esc(o.label ?? o)+'</option>';\r\n });\r\n html += '</select>';\r\n } else {\r\n html += '<input class=\"fp-input\" id=\"'+fid+'\" type=\"'+(f.type==='number'?'number':'text')+'\" data-key=\"'+esc(f.key)+'\" value=\"'+esc(f.default ?? '')+'\" placeholder=\"'+esc(f.placeholder ?? '')+'\">';\r\n }\r\n html += '</div>';\r\n });\r\n html += '<div class=\"fp-preview\"><div class=\"fp-preview-label\">Prompt 预览</div><pre class=\"fp-preview-body\" id=\"'+uid+'-preview\"></pre></div>';\r\n html += '<div class=\"fp-actions\"><button class=\"copy primary\" id=\"'+uid+'-btn\">复制指令</button></div>';\r\n html += '</div>';\r\n\r\n function renderPreview(){\r\n var vals = {};\r\n fields.forEach(function(f, i){\r\n var el = document.getElementById(uid + '-f' + i);\r\n vals[f.key] = el ? el.value : '';\r\n });\r\n var text = String(template || '').replace(/\\{(\\w+)\\}/g, function(_, k){ return vals[k] ?? ''; });\r\n document.getElementById(uid + '-preview').textContent = text;\r\n var btn = document.getElementById(uid + '-btn');\r\n var emptyRequired = fields.some(function(f){ return f.required && !vals[f.key]; });\r\n if(emptyRequired){\r\n btn.disabled = true;\r\n btn.textContent = '请填写必填项';\r\n } else {\r\n btn.disabled = false;\r\n btn.textContent = '复制指令';\r\n }\r\n }\r\n\r\n setTimeout(function(){\r\n fields.forEach(function(f, i){\r\n var el = document.getElementById(uid + '-f' + i);\r\n if(el){\r\n el.addEventListener('input', renderPreview);\r\n el.addEventListener('change', renderPreview);\r\n }\r\n });\r\n document.getElementById(uid + '-btn').addEventListener('click', function(){\r\n if(this.disabled) { toast('请先填写','必填字段未填写',{badge:{text:'提示',type:'warn'}}); return; }\r\n var text = document.getElementById(uid + '-preview').textContent;\r\n copyText(text);\r\n });\r\n renderPreview();\r\n }, 0);\r\n\r\n return html;\r\n}\r\n\r\n/* ── selectList(P0 · 勾选列表 + 批量操作 + 计数联动 + 行内控件 v1.9)──\r\n * selectList(items, batchActions?, opts?)\r\n * items: [{ id, title, sub?, group?, widget? }]\r\n * widget(v1.9 · #327): { type:'date'|'text'|'select', key, label?, placeholder?, options? }\r\n * - options: [ {value,label} | '原始值' ](select 用; 缺省渲染占位「请选择」)\r\n * - 非法 type 降级 text(宽容渲染, 不报错); key 缺省 'w'+行号\r\n * batchActions: [{ label, kind:'ok'|'danger', onClick(ids, values?) }]\r\n * - v1.9: onClick 第二参 values = 勾选条目对应的行内值 { [id]: { [key]: value } }\r\n * (只读勾选条目; 未填 → null, 不报错; 未勾选条目不参与)\r\n * opts: { onSubmit(selectedIds, values) } —— v1.9 读取接口(选定形态, 等价 getValues)\r\n * - 任意批量操作按钮点击后触发(与 onClick 并列; 无勾选时不触发, 与既有拦截一致)\r\n * - values = 全部行内值 { [id]: { [key]: value } }(含未勾选条目; 未填 → null; 无 widget 条目不出现)\r\n * 安全: 行内 label/placeholder/option value+label 渲染一律 esc, 零注入面\r\n * 兼容: 未声明 widget 的既有调用渲染输出与行为完全不变(守卫测试回归 outerHTML)\r\n */\r\nfunction selectList(items, batchActions, opts){\r\n items = arr(items);\r\n batchActions = arr(batchActions);\r\n opts = opts || {};\r\n var uid = 'sl' + Math.random().toString(36).slice(2,7);\r\n var groups = {};\r\n items.forEach(function(it){\r\n var g = it.group || '';\r\n (groups[g] = groups[g] || []).push(it);\r\n });\r\n var groupNames = Object.keys(groups);\r\n\r\n /* 行内控件 HTML(v1.9 · #327): 未声明 widget → 空串, 渲染零变化 */\r\n function widgetHtml(it, idx){\r\n var w = it.widget;\r\n if(!w || typeof w !== 'object') return '';\r\n var t = w.type === 'date' ? 'date' : (w.type === 'select' ? 'select' : 'text'); // 非法 type 降级 text\r\n var key = w.key != null ? String(w.key) : ('w' + idx);\r\n var lbl = w.label ? '<span class=\"sl-widget-label\">'+esc(w.label)+'</span>' : '';\r\n var inner;\r\n if(t === 'select'){\r\n inner = '<select class=\"sl-widget-input\" data-wkey=\"'+esc(key)+'\">';\r\n var os = arr(w.options);\r\n if(!os.length) inner += '<option value=\"\">请选择</option>';\r\n os.forEach(function(o){\r\n var ov = (o && typeof o === 'object') ? (o.value != null ? o.value : o.label) : o;\r\n var ol = (o && typeof o === 'object') ? (o.label != null ? o.label : o.value) : o;\r\n inner += '<option value=\"'+esc(String(ov == null ? '' : ov))+'\">'+esc(String(ol == null ? '' : ol))+'</option>';\r\n });\r\n inner += '</select>';\r\n } else {\r\n inner = '<input class=\"sl-widget-input\" data-wkey=\"'+esc(key)+'\" type=\"'+t+'\"'\r\n + (w.placeholder ? ' placeholder=\"'+esc(w.placeholder)+'\"' : '')\r\n + '>';\r\n }\r\n return '<span class=\"sl-widget\">'+lbl+inner+'</span>';\r\n }\r\n\r\n var html = '<div class=\"sl\" id=\"'+uid+'\">';\r\n if(batchActions.length){\r\n html += '<div class=\"sl-batchbar\" id=\"'+uid+'-batch\">';\r\n batchActions.forEach(function(a){\r\n html += '<button class=\"copy '+(a.kind==='danger'?'red':'primary')+'\" data-batch=\"'+esc(a.label)+'\">'+esc(a.label)+'</button>';\r\n });\r\n html += '<span class=\"sl-count\" id=\"'+uid+'-count\">已选 0/'+items.length+'</span>';\r\n html += '</div>';\r\n }\r\n groupNames.forEach(function(g){\r\n var gItems = groups[g];\r\n html += '<div class=\"sl-group\"><div class=\"sl-group-head\">'+esc(g||'全部');\r\n html += ' <span class=\"sl-group-count\">本组已选 0/'+gItems.length+'</span></div>';\r\n html += '<div class=\"sl-group-items\">';\r\n gItems.forEach(function(it, idx){\r\n html += '<label class=\"sl-item\"><input type=\"checkbox\" data-id=\"'+esc(it.id)+'\" data-g=\"'+esc(g)+'\">'\r\n + '<span class=\"sl-item-body\"><span class=\"sl-item-title\">'+esc(it.title)+'</span>'\r\n + (it.sub?'<span class=\"sl-item-sub\">'+esc(it.sub)+'</span>':'')\r\n + widgetHtml(it, idx)\r\n + '</span></label>';\r\n });\r\n html += '</div></div>';\r\n });\r\n html += '</div>';\r\n\r\n setTimeout(function(){\r\n var root = document.getElementById(uid);\r\n var checkboxes = root.querySelectorAll('input[type=\"checkbox\"]');\r\n var globalCount = document.getElementById(uid + '-count');\r\n function update(){\r\n var total = checkboxes.length;\r\n var checked = root.querySelectorAll('input[type=\"checkbox\"]:checked').length;\r\n if(globalCount) globalCount.textContent = '已选 '+checked+'/'+total;\r\n root.querySelectorAll('.sl-group').forEach(function(gEl){\r\n var boxes = gEl.querySelectorAll('input[type=\"checkbox\"]');\r\n var c = gEl.querySelectorAll('input[type=\"checkbox\"]:checked').length;\r\n var lbl = gEl.querySelector('.sl-group-count');\r\n if(lbl) lbl.textContent = '本组已选 '+c+'/'+boxes.length;\r\n });\r\n return checked;\r\n }\r\n checkboxes.forEach(function(cb){\r\n cb.addEventListener('change', update);\r\n });\r\n /* 行内值读取(v1.9 · #327): 计数只随勾选态, 控件值变化不干扰 */\r\n function widgetVal(el){\r\n var v = el.value;\r\n return (v === '' || v === null || v === undefined) ? null : v; // 未填统一归一 null\r\n }\r\n function readAll(){\r\n var out = {};\r\n root.querySelectorAll('.sl-item').forEach(function(itemEl){\r\n var cb = itemEl.querySelector('input[type=\"checkbox\"]');\r\n var id = cb ? cb.getAttribute('data-id') : null;\r\n if(id == null) return;\r\n itemEl.querySelectorAll('.sl-widget-input').forEach(function(el){\r\n var key = el.getAttribute('data-wkey');\r\n if(key == null) return;\r\n (out[id] = out[id] || {})[key] = widgetVal(el);\r\n });\r\n });\r\n return out;\r\n }\r\n function readChecked(){\r\n var out = {};\r\n root.querySelectorAll('input[type=\"checkbox\"]:checked').forEach(function(cb){\r\n var id = cb.getAttribute('data-id');\r\n var itemEl = cb.closest('.sl-item');\r\n itemEl.querySelectorAll('.sl-widget-input').forEach(function(el){\r\n var key = el.getAttribute('data-wkey');\r\n if(key == null) return;\r\n (out[id] = out[id] || {})[key] = widgetVal(el);\r\n });\r\n });\r\n return out;\r\n }\r\n root.querySelectorAll('[data-batch]').forEach(function(btn){\r\n btn.addEventListener('click', function(){\r\n var ids = root.querySelectorAll('input[type=\"checkbox\"]:checked');\r\n if(!ids.length){ toast('请先勾选','勾选要处理的条目',{badge:{text:'提示',type:'warn'}}); return; }\r\n var idList = Array.prototype.map.call(ids, function(x){ return x.getAttribute('data-id'); });\r\n var a = batchActions.filter(function(x){ return x.label === btn.getAttribute('data-batch'); })[0];\r\n if(a && a.onClick) a.onClick(idList, readChecked()); // v1.9: 第二参 = 勾选条目行内值\r\n if(opts.onSubmit) opts.onSubmit(idList, readAll()); // v1.9: 读取接口 = 全部行内值\r\n });\r\n });\r\n update();\r\n }, 0);\r\n\r\n return html;\r\n}\r\n\r\n/* ── confirm(P0 · 危险操作二次确认)──\r\n * confirm({ title, detail?, danger?, onOk })\r\n */\r\nfunction confirm(cfg){\r\n cfg = cfg || {};\r\n var overlay = document.createElement('div');\r\n overlay.className = 'hm-confirm-overlay';\r\n overlay.innerHTML = '<div class=\"hm-confirm-panel\">'\r\n + '<div class=\"hm-confirm-title\">'+(cfg.danger?'⚠️ ':'')+esc(cfg.title||'确认操作')+'</div>'\r\n + (cfg.detail?'<div class=\"hm-confirm-detail\">'+esc(cfg.detail)+'</div>':'')\r\n + '<div class=\"hm-confirm-actions\">'\r\n + '<button class=\"copy '+(cfg.danger?'red':'primary')+'\" data-c=\"1\">'+(cfg.danger?'确认删除':'确认')+'</button>'\r\n + '<button class=\"copy\" data-c=\"0\">取消</button>'\r\n + '</div></div>';\r\n document.body.appendChild(overlay);\r\n overlay.querySelector('[data-c=\"1\"]').addEventListener('click', function(){\r\n overlay.remove();\r\n if(cfg.onOk) cfg.onOk();\r\n });\r\n overlay.querySelector('[data-c=\"0\"]').addEventListener('click', function(){ overlay.remove(); });\r\n overlay.addEventListener('click', function(e){\r\n if(e.target === overlay) overlay.remove();\r\n });\r\n}\r\n\r\n/* ── foldBox(P1 · 折叠区)── */\r\nfunction foldBox(title, contentHtml){\r\n return '<details class=\"hm-fold\"><summary>'+esc(title)+'</summary><div class=\"hm-fold-body\">'+(contentHtml||'')+'</div></details>';\r\n}\r\n\r\n/* ── statusBadge(P1 · 状态徽章)──\r\n * statusBadge(status, text?)\r\n * status: 'ok'|'warn'|'danger'|'empty'(非法值降级 'empty', 防无样式徽章)\r\n * text: 自定义文案(缺省用语义默认: 成功/警告/失败/无数据)\r\n * 安全: status 白名单后直拼 class(无注入面); text 经 esc\r\n */\r\nvar STATUS_BADGE_MAP = { ok:'成功', warn:'警告', danger:'失败', empty:'无数据' };\r\nfunction statusBadge(status, text){\r\n status = STATUS_BADGE_MAP[status] ? status : 'empty'; // 非法/未知值降级 empty\r\n var txt = (text === null || text === undefined || text === '') ? STATUS_BADGE_MAP[status] : String(text);\r\n return '<span class=\"hm-status '+status+'\">'+esc(txt)+'</span>';\r\n}\r\n\r\n/* ── emptyState(P1 · 空状态)──\r\n * emptyState({icon?, text, hint?, action?})\r\n * icon: emoji/文本图标(esc)\r\n * text: 主文案(缺省 '暂无数据', esc)\r\n * hint: 次要提示(esc)\r\n * action: 操作区 HTML —— 受信 HTML 透传(调用方负责其内容安全, 通常为按钮;\r\n * 如含用户数据必须先 esc)。其余字段一律 esc, 防 XSS。\r\n */\r\nfunction emptyState(cfg){\r\n cfg = cfg || {};\r\n return '<div class=\"hm-empty\">'\r\n + (cfg.icon?'<div class=\"hm-empty-icon\">'+esc(cfg.icon)+'</div>':'')\r\n + '<div class=\"hm-empty-text\">'+esc(cfg.text||'暂无数据')+'</div>'\r\n + (cfg.hint?'<div class=\"hm-empty-hint\">'+esc(cfg.hint)+'</div>':'')\r\n + (cfg.action?('<div class=\"hm-empty-action\">'+cfg.action+'</div>'):'')\r\n + '</div>';\r\n}\r\n\r\n/* ── errorReceipt(P1 · 错误回执 · 08 规范 §6.1 三层反馈)──\r\n * errorReceipt({message, retryPrompt?, data?, log?, payload?})\r\n * message: 错误描述(esc, 缺省 '操作失败')\r\n * retryPrompt: 修正重试按钮文案(有则渲染「修正重试」按钮, 复制该 prompt)\r\n * data: 复制数据按钮内容(字符串直传; 或省略时从 payload 生成)\r\n * log: 复制日志按钮内容(字符串直传; 或省略时从 payload 生成)\r\n * payload: 数据信封 {status, data:{meta, scene}} —— 显式传入, 优先于全局\r\n * __hmPayload: 兼容全局兜底(actionBar 已设置; 显式 payload 优先)\r\n * 布局: 修正重试 primary 独立一行 + 复制数据/日志 ghost 一行 2 个(08 规范奇数按钮)\r\n * 安全: message/data/log 经 esc + data-t 中转(onclick 仅 copyText(this.dataset.t), 零注入面)\r\n */\r\nfunction errorReceipt(cfg){\r\n cfg = cfg || {};\r\n var payload = cfg.payload || window.__hmPayload || null;\r\n var dataText = cfg.data != null ? String(cfg.data) : '';\r\n var logText = cfg.log != null ? String(cfg.log) : '';\r\n // 有效数据源 = payload 含 scene.snapshot(残缺 payload 视为无数据, 不生成垃圾复制内容)\r\n var pValid = !!(payload && payload.data && payload.data.scene && payload.data.scene.snapshot);\r\n if(!dataText && pValid){\r\n try { dataText = buildDataText(payload); } catch(e){ dataText = ''; } // 数据不完整 → 不渲染复制数据按钮(错误回执容错)\r\n }\r\n if(!logText && pValid){\r\n try { logText = buildLogText(payload); } catch(e){ logText = ''; } // 同上\r\n }\r\n var html = '<div class=\"hm-error\">'\r\n + '<div class=\"hm-error-title\">❌ '+esc(cfg.message||'操作失败')+'</div>';\r\n if(cfg.retryPrompt){\r\n html += '<div class=\"hm-actions\"><button class=\"copy primary wide\" onclick=\"copyText(this.dataset.t)\" data-t=\"'+esc(cfg.retryPrompt).replace(/\"/g,'&quot;')+'\">修正重试</button></div>';\r\n }\r\n var btns = '';\r\n if(dataText) btns += '<button class=\"copy ghost\" onclick=\"copyText(this.dataset.t)\" data-t=\"'+esc(dataText).replace(/\"/g,'&quot;')+'\">复制数据</button>';\r\n if(logText) btns += '<button class=\"copy ghost\" onclick=\"copyText(this.dataset.t)\" data-t=\"'+esc(logText).replace(/\"/g,'&quot;')+'\">复制日志</button>';\r\n if(btns) html += '<div class=\"hm-actions\">'+btns+'</div>';\r\n return html + '</div>';\r\n}\r\n\r\n/* ── smartSelect 选择器组件(v1.12 · #312 · 复用优先·新建其次)──\r\n * smartSelect(inputEl, config) → { getState, getValue }\r\n * 字段级组件: 一页 N 实例, 每字段一容器一 config 一隐藏 input, 互不干扰。\r\n * 定位: 与 copyText/actionBar 同级 Base 组件; 账户/分类/账本/运动类型等\r\n * 「复用优先·新建其次」字段通用; 零领域词, label/文案/选项/prompt 全由外部注入。\r\n * config(snake_case, 与数据契约 form.selector.<fieldKey> 对齐):\r\n * options: [{name, disabled}] 已有项(含停用态); 缺省 [] 且无推断/推荐/initial → 降级普通输入\r\n * inferred: string|null AI 推断最可能的已有项\r\n * recommended_new: string|null AI 推荐新建项(不在 options 中)\r\n * initial: {name, source}|null 显式初始选中; source 白名单 = _SS_SOURCES\r\n * maxChips: number|null 候选区折叠阈值(v1.12 · 缺省 8; 非正整数=不折叠;\r\n * 折叠态只显前 maxChips 个 + 「展开全部(N)」, 选中项保可见; 搜索时全量过滤)\r\n * texts: {candTitle, search, newPlaceholder, newButton, emptyButton,\r\n * badgeInferred, badgeRecommendedNew, badgeExisting, badgeHistory, badgeCustom,\r\n * cardSrc:{inferred, recommended_new, existing, history, custom, empty}}\r\n * theme: {brand, brandSoft, onBrand, deep} 缺省账本藏蓝 #123A63\r\n * 初始选中推导(initial 缺省时): AI 推断 > 历史预填(input.value) > AI 推荐新建 > 空\r\n * 行为: 已选卡片(chips 顶部, SVG ✓+来源徽章) + 候选 chips(超限折叠) + 搜索过滤(全量) + 自定义新建\r\n * (重名自动选中已有) + 相似提示 + 留空按钮; 停用划线置灰不可点; 绝不静默填错\r\n * 回填协议: input.value + dataset.source + dataset.new('1'=新建) + change 事件(bubbles)\r\n * 安全: 所有动态文本经 esc; 类名全 ss- 命名空间(封装纪律, 防宿主同名类冲突)\r\n * 校验: 结构违规直接报错(对齐 Base v1.2「违规直接报错」)\r\n */\r\nvar _SS_SOURCES = ['inferred','recommended_new','existing','history','custom','empty'];\r\nvar _SS_THEME = { brand:'#123a63', brandSoft:'#e9f0f7', onBrand:'#ffffff', deep:'#0b1f3b' };\r\nvar _SS_TEXTS = {\r\n candTitle:'候选(点击更换 · 输入过滤)',\r\n search:'输入过滤候选',\r\n newPlaceholder:'输入新名称',\r\n newButton:'+ 新建',\r\n emptyButton:'留空(不填)',\r\n badgeInferred:'AI 推断',\r\n badgeRecommendedNew:'AI 推荐·新建',\r\n badgeExisting:'已有',\r\n badgeHistory:'历史',\r\n badgeCustom:'自定义',\r\n cardSrc:{\r\n inferred:'AI 推断 · 识别到相关信息',\r\n recommended_new:'AI 推荐新建 · 提交时创建',\r\n existing:'从已有项中选',\r\n history:'沿用历史记录',\r\n custom:'自定义新建 · 提交时创建',\r\n empty:'不填该字段'\r\n }\r\n};\r\nfunction smartSelect(inputEl, config){\r\n /* ── 结构校验(违规直接报错)── */\r\n if(!inputEl || inputEl.tagName !== 'INPUT'){\r\n throw new Error('smartSelect 违规: inputEl 必须是 <input> 元素');\r\n }\r\n if(!config || typeof config !== 'object' || Array.isArray(config)){\r\n throw new Error('smartSelect 违规: config 必须是对象');\r\n }\r\n var options = config.options === undefined ? [] : config.options;\r\n if(!Array.isArray(options)){\r\n throw new Error('smartSelect 违规: options 必须是数组');\r\n }\r\n options.forEach(function(o, i){\r\n if(!o || typeof o !== 'object' || typeof o.name !== 'string' || !o.name.trim()){\r\n throw new Error('smartSelect 违规: options['+i+'] 必须含非空 name(字符串)');\r\n }\r\n if(o.disabled !== undefined && typeof o.disabled !== 'boolean'){\r\n throw new Error('smartSelect 违规: options['+i+'].disabled 必须是布尔');\r\n }\r\n });\r\n ['inferred','recommended_new'].forEach(function(k){\r\n var v = config[k];\r\n if(v !== undefined && v !== null && typeof v !== 'string'){\r\n throw new Error('smartSelect 违规: '+k+' 必须是字符串或 null');\r\n }\r\n });\r\n if(config.initial !== undefined && config.initial !== null){\r\n var ini = config.initial;\r\n if(!ini || typeof ini !== 'object' || typeof ini.name !== 'string'\r\n || _SS_SOURCES.indexOf(ini.source) < 0){\r\n throw new Error('smartSelect 违规: initial 必须含 name(字符串) + source(白名单 '+_SS_SOURCES.join('|')+')');\r\n }\r\n }\r\n if(config.texts !== undefined && (typeof config.texts !== 'object' || Array.isArray(config.texts))){\r\n throw new Error('smartSelect 违规: texts 必须是对象');\r\n }\r\n if(config.theme !== undefined && (typeof config.theme !== 'object' || Array.isArray(config.theme))){\r\n throw new Error('smartSelect 违规: theme 必须是对象');\r\n }\r\n\r\n var texts = Object.assign({}, _SS_TEXTS, config.texts || {});\r\n texts.cardSrc = Object.assign({}, _SS_TEXTS.cardSrc, (config.texts && config.texts.cardSrc) || {});\r\n var theme = Object.assign({}, _SS_THEME, config.theme || {});\r\n var custom = [];\r\n /* 候选区折叠(v1.12): maxChips 可配(缺省 8, 0/负数/非数字=不折叠) · 搜索时全量过滤 */\r\n var maxChips = (config.maxChips === undefined || config.maxChips === null)\r\n ? 8\r\n : ((typeof config.maxChips === 'number' && config.maxChips > 0)\r\n ? Math.floor(config.maxChips) : null);\r\n var searchRaw = '';\r\n var searchQ = '';\r\n var expanded = false;\r\n\r\n /* ── 降级模式: 无选项/无推断/无推荐/无 initial → 普通输入 ── */\r\n var degraded = !options.length && !config.inferred && !config.recommended_new && !config.initial;\r\n if(degraded){\r\n inputEl.classList.add('ss-plain');\r\n inputEl.style.display = '';\r\n inputEl.removeAttribute('hidden');\r\n var syncDegraded = function(){\r\n var v = inputEl.value;\r\n inputEl.dataset.source = v ? 'custom' : 'empty';\r\n inputEl.dataset.new = v ? '1' : '0';\r\n };\r\n syncDegraded();\r\n inputEl.addEventListener('input', syncDegraded);\r\n return {\r\n getState: function(){ var v = inputEl.value; return { name: v || null, mode: v ? 'custom' : 'empty' }; },\r\n getValue: function(){ return inputEl.value; }\r\n };\r\n }\r\n\r\n /* ── 初始选中推导: initial > AI 推断 > 历史预填(input.value) > AI 推荐新建 > 空 ── */\r\n var state;\r\n if(config.initial){\r\n state = { name: config.initial.name, mode: config.initial.source };\r\n } else if(config.inferred){\r\n state = { name: config.inferred, mode: 'inferred' };\r\n } else if(inputEl.value){\r\n state = { name: inputEl.value, mode: 'history' };\r\n } else if(config.recommended_new){\r\n state = { name: config.recommended_new, mode: 'recommended_new' };\r\n } else {\r\n state = { name: null, mode: 'empty' };\r\n }\r\n\r\n inputEl.style.display = 'none';\r\n var root = document.createElement('div');\r\n root.className = 'ss-root';\r\n root.style.setProperty('--ss-brand', theme.brand);\r\n root.style.setProperty('--ss-brand-soft', theme.brandSoft);\r\n root.style.setProperty('--ss-on-brand', theme.onBrand);\r\n root.style.setProperty('--ss-deep', theme.deep);\r\n inputEl.parentNode.insertBefore(root, inputEl.nextSibling);\r\n\r\n var CHECK_SVG = '<svg viewBox=\"0 0 20 20\" fill=\"none\"><path d=\"M4 10.5l4 4 8-9\" stroke=\"#fff\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>';\r\n var CIRCLE_SVG = '<svg viewBox=\"0 0 20 20\" fill=\"none\"><circle cx=\"10\" cy=\"10\" r=\"7\" stroke=\"#8b949e\" stroke-width=\"2\"/><path d=\"M7 10h6\" stroke=\"#8b949e\" stroke-width=\"2\" stroke-linecap=\"round\"/></svg>';\r\n\r\n function badgeHtml(mode){\r\n if(mode === 'inferred') return '<span class=\"ss-badge ss-badge-ai\">'+esc(texts.badgeInferred)+'</span>';\r\n if(mode === 'recommended_new') return '<span class=\"ss-badge ss-badge-new\">'+esc(texts.badgeRecommendedNew)+'</span>';\r\n if(mode === 'custom') return '<span class=\"ss-badge ss-badge-plain\">'+esc(texts.badgeCustom)+'</span>';\r\n if(mode === 'history') return '<span class=\"ss-badge ss-badge-plain\">'+esc(texts.badgeHistory)+'</span>';\r\n if(mode === 'existing') return '<span class=\"ss-badge ss-badge-plain\">'+esc(texts.badgeExisting)+'</span>';\r\n return '';\r\n }\r\n\r\n function writeBack(){\r\n inputEl.value = state.name || '';\r\n inputEl.dataset.source = state.mode || 'empty';\r\n inputEl.dataset.new = (state.mode === 'recommended_new' || state.mode === 'custom') ? '1' : '0';\r\n inputEl.dispatchEvent(new Event('change', { bubbles: true }));\r\n }\r\n\r\n function setSel(name, mode){\r\n state.name = name;\r\n state.mode = mode;\r\n render();\r\n writeBack();\r\n }\r\n\r\n function allNames(){\r\n var names = options.map(function(o){ return o.name; });\r\n return names.concat(custom);\r\n }\r\n\r\n function similarHint(v){\r\n if(!v) return '';\r\n var s = allNames().filter(function(n){\r\n return n !== v && (n.indexOf(v) >= 0 || v.indexOf(n) >= 0);\r\n });\r\n return s.length ? '已有相似「'+s[0]+'」, 是否使用已有的?(点候选即选)' : '';\r\n }\r\n\r\n function render(){\r\n function isSel(n, m){ return state.name === n && state.mode === m; }\r\n var card = state.name\r\n ? '<div class=\"ss-card\"><div class=\"ss-ic\">'+CHECK_SVG+'</div>'\r\n + '<div class=\"ss-body\"><div class=\"ss-nm\">'+esc(state.name)+'</div>'\r\n + '<div class=\"ss-src\">'+esc(texts.cardSrc[state.mode] || '')+'</div></div>'\r\n + badgeHtml(state.mode) + '</div>'\r\n : '<div class=\"ss-card ss-card-empty\"><div class=\"ss-ic\">'+CIRCLE_SVG+'</div>'\r\n + '<div class=\"ss-body\"><div class=\"ss-nm\">'+esc(texts.emptyButton)+'</div>'\r\n + '<div class=\"ss-src\">'+esc(texts.cardSrc.empty || '')+'</div></div></div>';\r\n function chip(n, m, dis, badge){\r\n var sel = !dis && isSel(n, m);\r\n return '<button type=\"button\" class=\"ss-chip'+(dis?' ss-chip-dis':'')+(sel?' ss-chip-sel':'')+'\"'\r\n + (dis ? ' disabled' : ' data-n=\"'+esc(n)+'\" data-m=\"'+m+'\"')\r\n + '>'+(sel?'✓ ':'')+esc(n)+badge+(dis?' · 停用':'')+'</button>';\r\n }\r\n var chips = []; // chip HTML\r\n var chipsMeta = []; // 对齐元信息 {name, sel}(折叠保可见/搜索过滤用)\r\n function pushChip(n, m, dis, badge){\r\n var sel = !dis && isSel(n, m);\r\n chipsMeta.push({ name: n, sel: sel });\r\n chips.push(chip(n, m, dis, badge));\r\n }\r\n if(config.inferred){\r\n pushChip(config.inferred, 'inferred', false, '<span class=\"ss-badge ss-badge-ai\">'+esc(texts.badgeInferred)+'</span>');\r\n }\r\n if(config.recommended_new){\r\n pushChip(config.recommended_new, 'recommended_new', false, '<span class=\"ss-badge ss-badge-new\">'+esc(texts.badgeRecommendedNew)+'</span>');\r\n }\r\n options.forEach(function(o){\r\n if(o.name === config.inferred || o.name === config.recommended_new) return;\r\n pushChip(o.name, 'existing', !!o.disabled, '');\r\n });\r\n custom.forEach(function(n){\r\n pushChip(n, 'custom', false, '<span class=\"ss-badge ss-badge-plain\">'+esc(texts.badgeCustom)+'</span>');\r\n });\r\n\r\n /* 候选区折叠(v1.12): 折叠态只显前 maxChips 个, 选中项保可见; 搜索时全量过滤 */\r\n var showAll = !maxChips || expanded || !!searchQ || chips.length <= maxChips;\r\n var list = chips;\r\n var listMeta = chipsMeta;\r\n if(!showAll){\r\n var selIdx = -1;\r\n for(var i = 0; i < chipsMeta.length; i++){\r\n if(chipsMeta[i].sel){ selIdx = i; break; }\r\n }\r\n list = chips.slice(0, maxChips);\r\n listMeta = chipsMeta.slice(0, maxChips);\r\n if(selIdx >= maxChips){\r\n list[maxChips - 1] = chips[selIdx];\r\n listMeta[maxChips - 1] = chipsMeta[selIdx];\r\n }\r\n }\r\n var out = [];\r\n for(var j = 0; j < list.length; j++){\r\n if(searchQ && listMeta[j].name.toLowerCase().indexOf(searchQ) < 0) continue;\r\n out.push(list[j]);\r\n }\r\n var moreBtn = '';\r\n if(!showAll){\r\n moreBtn = '<button type=\"button\" class=\"ss-more\" data-more=\"1\">展开全部('+chips.length+')</button>';\r\n } else if(expanded && maxChips && chips.length > maxChips && !searchQ){\r\n moreBtn = '<button type=\"button\" class=\"ss-more\" data-more=\"0\">收起</button>';\r\n }\r\n\r\n root.innerHTML =\r\n card\r\n + '<div class=\"ss-title\">'+esc(texts.candTitle)+'</div>'\r\n + '<input class=\"ss-search\" placeholder=\"'+esc(texts.search)+'\">'\r\n + '<div class=\"ss-chips\">'+out.join('')+moreBtn+'</div>'\r\n + '<div class=\"ss-new\"><input placeholder=\"'+esc(texts.newPlaceholder)+'\"><button type=\"button\">'+esc(texts.newButton)+'</button></div>'\r\n + '<div class=\"ss-hint\"></div>'\r\n + '<button type=\"button\" class=\"ss-empty\">'+esc(texts.emptyButton)+'</button>';\r\n\r\n /* 搜索框内容跨 render 保持(过滤状态不丢, 输入框不空) */\r\n if(searchRaw) root.querySelector('.ss-search').value = searchRaw;\r\n root.querySelector('.ss-search').addEventListener('input', function(e){\r\n searchRaw = e.target.value;\r\n searchQ = searchRaw.trim().toLowerCase();\r\n render();\r\n });\r\n root.querySelectorAll('.ss-more').forEach(function(el){\r\n el.addEventListener('click', function(){\r\n expanded = el.getAttribute('data-more') === '1';\r\n render();\r\n });\r\n });\r\n root.querySelectorAll('.ss-chip[data-n]').forEach(function(el){\r\n el.addEventListener('click', function(){ setSel(el.getAttribute('data-n'), el.getAttribute('data-m')); });\r\n });\r\n var newIn = root.querySelector('.ss-new input');\r\n var doNew = function(){\r\n var v = newIn.value.trim();\r\n if(!v) return;\r\n if(allNames().indexOf(v) >= 0){ setSel(v, 'existing'); return; }\r\n custom.unshift(v);\r\n setSel(v, 'custom');\r\n };\r\n root.querySelector('.ss-new button').addEventListener('click', doNew);\r\n newIn.addEventListener('keydown', function(e){ if(e.key === 'Enter') doNew(); });\r\n newIn.addEventListener('input', function(){\r\n var h = root.querySelector('.ss-hint');\r\n var s = similarHint(newIn.value.trim());\r\n h.textContent = s;\r\n h.style.display = s ? '' : 'none';\r\n });\r\n root.querySelector('.ss-empty').addEventListener('click', function(){ setSel(null, 'empty'); });\r\n }\r\n\r\n render();\r\n writeBack();\r\n\r\n return {\r\n getState: function(){ return { name: state.name, mode: state.mode }; },\r\n getValue: function(){ return inputEl.value; }\r\n };\r\n}\r\n</script>\r\n<style>\r\n/* Base Skill token A 组 + 控件样式 v1.11(唯一真相源 · 跨技能 · 领域无关)\r\n * 来源: 居家管家模板 :root token(对齐 #248/08-HTML交互规范.md 按钮规范)\r\n * v1.2: 新增新控件样式(formPrompt/selectList/confirm/foldBox/statusBadge/emptyState/errorReceipt/复制预览面板)\r\n * v1.7: .hm-actions 自约束 max-width 520px 居中(#322 · 修复复制按钮被容器拉伸成半屏宽, 胶囊语义恢复)\r\n * v1.9: selectList 行内控件样式(.sl-widget* · #327 · 样式走 token A 组)\r\n * v1.11: smartSelect 选择器组件样式(.ss-* · #312 · 主题色经 .ss-root 内联 CSS 变量覆盖, 缺省账本藏蓝)\r\n * v1.12: smartSelect 候选区折叠按钮(.ss-more · #312 实测反馈: 大量候选时折叠+展开)\r\n * 注入点: 由 injector.py 的 SHARED-CSS 占位符注入(模板声明点, 勿含闭合标签字样)\r\n */\r\n\r\n/* ── token A 组(12 变量, 与组件契约 §6.4 一致)── */\r\n:root {\r\n --fg: #1d1d1f; /* 主文字 */\r\n --fg2: #6e6e73; /* 次级文字 */\r\n --fg3: #86868b; /* 弱化文字/占位 */\r\n --bg: #f5f5f7; /* 页面底色 */\r\n --card: #ffffff; /* 卡片底 */\r\n --line: #d2d2d7; /* 分隔线 */\r\n --blue: #007aff; /* 主色(场景按钮) */\r\n --blue2: #0a63ce; /* 主色深(按压态/链接) */\r\n --soft: #f5f8ff; /* 浅蓝底(stage 徽章) */\r\n --ok: #34c759; /* 成功/通过 */\r\n --shadow: 0 1px 2px rgba(0,0,0,.04), 0 12px 36px rgba(0,0,0,.06);\r\n}\r\n\r\n/* ── 复制按钮基础(对齐 08 规范: ≤3 色按功能区分)── */\r\nbutton.copy {\r\n -webkit-tap-highlight-color: transparent;\r\n touch-action: manipulation;\r\n -webkit-touch-callout: none;\r\n border: none;\r\n background: var(--line);\r\n color: var(--fg);\r\n border-radius: 999px;\r\n padding: 10px 12px;\r\n font-weight: 700;\r\n cursor: pointer;\r\n margin: 0;\r\n font-size: 13.5px;\r\n min-height: 44px;\r\n min-width: 0;\r\n flex: 1 1 0;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n white-space: nowrap;\r\n font-family: inherit;\r\n}\r\nbutton.copy:focus { outline: none; }\r\nbutton.copy:active { filter: brightness(.93); }\r\nbutton.copy:disabled { opacity: .45; cursor: not-allowed; }\r\n\r\n/* 主场景按钮(蓝实心, 单色系) */\r\nbutton.copy.primary {\r\n background: var(--blue);\r\n color: #fff;\r\n}\r\nbutton.copy.primary:active { background: var(--blue2); }\r\n\r\n/* 危险/破坏性操作(红实心) */\r\nbutton.copy.red {\r\n background: #ff3b30;\r\n color: #fff;\r\n}\r\nbutton.copy.red:active { background: #c0392b; }\r\n\r\n/* ghost: 复制数据/复制日志 = 白底 + 轻主色描边 + 主色文字胶囊(独立一行)\r\n * v1.26 · #329 降权重: 描边 1px/38% 透明度 + 12px/600 + min-height 40px —— 视觉重心归主操作(VLM 两轮反馈)\r\n * v1.28 · 审查修复: 透明度 35%→38%(与拍板页 329-ghost对比拍板页.html B 方案所见一致) */\r\nbutton.copy.ghost {\r\n background: var(--card);\r\n color: var(--blue);\r\n border: 1px solid var(--blue);\r\n border-color: color-mix(in srgb, var(--blue) 38%, transparent);\r\n min-height: 40px;\r\n font-size: 12px;\r\n font-weight: 600;\r\n}\r\n\r\n/* ── actionBar 网格(偶数一行 2 个; 奇数时重要按钮单独一行由模板控制 wide)── */\r\n.hm-actions {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr;\r\n gap: 8px;\r\n margin-top: 14px;\r\n /* v1.7 #322: 胶囊按钮自约束宽度——避免被全宽容器拉伸成半屏宽块(跨技能一致) */\r\n max-width: 520px;\r\n margin-left: auto;\r\n margin-right: auto;\r\n box-sizing: border-box;\r\n}\r\n.hm-actions .copy.wide {\r\n grid-column: 1 / -1;\r\n background: var(--blue);\r\n color: #fff;\r\n border: none;\r\n}\r\n\r\n/* 成功/失败徽章(yes 函数用) */\r\n.ok { color: var(--ok); font-weight: 700; }\r\n.bad { color: #ff3b30; font-weight: 700; }\r\n\r\n/* ── formPrompt(参数表单)── */\r\n.fp { background: var(--card); border: 1px solid var(--line); border-radius: 16px; padding: 18px 20px; margin: 12px 0; }\r\n.fp-field { margin-bottom: 12px; }\r\n.fp-label { display: block; font-size: 12px; font-weight: 700; color: var(--fg2); margin-bottom: 6px; letter-spacing: .02em; }\r\n.fp-input {\r\n width: 100%;\r\n border: 1.5px solid var(--line);\r\n border-radius: 10px;\r\n padding: 10px 12px;\r\n font-size: 14px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n background: #fff;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n min-height: 44px;\r\n}\r\n.fp-input:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(0,122,255,.12); }\r\n.fp-preview { background: #fafbfc; border: 1px dashed var(--line); border-radius: 10px; padding: 10px 14px; margin: 10px 0; }\r\n.fp-preview-label { font-size: 10.5px; font-weight: 700; color: var(--fg3); text-transform: uppercase; letter-spacing: .06em; margin-bottom: 6px; }\r\n.fp-preview-body {\r\n font-size: 12px;\r\n color: var(--fg2);\r\n font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;\r\n line-height: 1.6;\r\n white-space: pre-wrap;\r\n word-break: break-all;\r\n overflow-wrap: anywhere;\r\n margin: 0;\r\n}\r\n.fp-actions { margin-top: 12px; }\r\n\r\n/* ── selectList(勾选列表 + 批量操作)── */\r\n.sl { margin: 12px 0; }\r\n.sl-batchbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 14px; padding-bottom: 14px; border-bottom: 1px solid var(--line); }\r\n.sl-count { font-size: 12px; font-weight: 600; color: var(--fg2); margin-left: auto; white-space: nowrap; }\r\n.sl-group { margin-bottom: 14px; }\r\n.sl-group-head { display: flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 700; margin-bottom: 8px; }\r\n.sl-group-count { font-size: 11px; font-weight: 600; color: var(--fg3); }\r\n.sl-group-items { display: flex; flex-direction: column; gap: 6px; }\r\n.sl-item {\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 10px;\r\n background: #fafbfc;\r\n border: 1px solid var(--line);\r\n border-radius: 12px;\r\n padding: 12px 14px;\r\n cursor: pointer;\r\n font-family: inherit;\r\n transition: border-color .15s, background .15s;\r\n}\r\n.sl-item:hover { border-color: var(--blue); background: #fff; }\r\n.sl-item input[type=\"checkbox\"] { width: 20px; height: 20px; margin-top: 2px; accent-color: var(--blue); flex-shrink: 0; }\r\n.sl-item-body { flex: 1; min-width: 0; }\r\n.sl-item-title { display: block; font-size: 13.5px; font-weight: 600; color: var(--fg); line-height: 1.5; word-break: break-word; }\r\n.sl-item-sub { display: block; font-size: 12px; color: var(--fg3); margin-top: 2px; line-height: 1.5; word-break: break-word; }\r\n\r\n/* ── selectList 行内控件(v1.9 · #327 · 样式走 token A 组)── */\r\n.sl-widget { display: block; margin-top: 8px; }\r\n.sl-widget-label { display: block; font-size: 11px; font-weight: 600; color: var(--fg3); margin-bottom: 4px; }\r\n.sl-widget-input {\r\n width: 100%;\r\n box-sizing: border-box;\r\n border: 1.5px solid var(--line);\r\n border-radius: 8px;\r\n padding: 8px 10px;\r\n font-size: 13px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n background: #fff;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n min-height: 40px;\r\n}\r\n.sl-widget-input:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(0,122,255,.12); }\r\n\r\n/* ── confirm 对话框 ── */\r\n.hm-confirm-overlay {\r\n position: fixed; inset: 0;\r\n background: rgba(0,0,0,.4);\r\n display: flex; align-items: center; justify-content: center;\r\n z-index: 10000;\r\n padding: 20px;\r\n animation: hmFade .18s ease-out;\r\n}\r\n@keyframes hmFade { from { opacity: 0; } to { opacity: 1; } }\r\n.hm-confirm-panel {\r\n background: var(--card);\r\n border-radius: 20px;\r\n max-width: 420px;\r\n width: 100%;\r\n padding: 24px 26px;\r\n box-shadow: var(--shadow);\r\n animation: hmPop .22s cubic-bezier(.34,1.56,.64,1);\r\n}\r\n@keyframes hmPop { from { transform: scale(.9); opacity: 0; } to { transform: scale(1); opacity: 1; } }\r\n/* ── #507 减动效归零档(照老壳 style.ts 归零档补:默认态一字不动,只在 reduce 下归零)──\r\n * 覆盖本母版本文件全部动效:summary 小三角 .15s/.mini 按压 .08s/.tab .08s/.copy-btn .12s/\r\n * .sl-item 行 .15s/.sheet-mask 淡入 .25s/.sheet 滑入 .32s/toast 入场 .22s/hmFade .18s/hmPop .22s。\r\n * toast 样式由 JS 后注入(晚于本表),归零规则须挂祖先类提权重才盖得住;.sheet 只停 transition\r\n * (不碰 transform 终态,否则弹层开合定位失效),动效停、状态照走。 */\r\n@media (prefers-reduced-motion: reduce){\r\n.contact-box>summary::before,.subgroup>summary::before{transition:none}\r\n.mini,.tab,.copy-btn,.sl-item{transition:none}\r\n.mini:active{transform:none}\r\n.sheet,.sheet-mask{transition:none}\r\n.hm-toast-stack .hm-toast{transition:none}\r\n.hm-confirm-overlay{animation:none}\r\n.hm-confirm-panel{animation:none}\r\n}\r\n.hm-confirm-title { font-size: 17px; font-weight: 700; margin-bottom: 8px; }\r\n.hm-confirm-detail { font-size: 13.5px; color: var(--fg2); line-height: 1.65; margin-bottom: 16px; }\r\n.hm-confirm-actions { display: flex; gap: 10px; }\r\n.hm-confirm-actions .copy { flex: 1; }\r\n\r\n/* ── foldBox 折叠区 ── */\r\n.hm-fold {\r\n background: #fafbfc;\r\n border: 1px solid var(--line);\r\n border-radius: 12px;\r\n padding: 12px 16px;\r\n margin: 10px 0;\r\n font-size: 13px;\r\n}\r\n.hm-fold summary { cursor: pointer; font-weight: 600; color: var(--blue2); outline: none; font-size: 13px; user-select: none; }\r\n.hm-fold summary::marker { color: var(--blue); }\r\n.hm-fold[open] summary { margin-bottom: 10px; }\r\n.hm-fold-body { font-size: 12.5px; line-height: 1.6; color: var(--fg2); }\r\n\r\n/* ── statusBadge 状态徽章 ── */\r\n.hm-status {\r\n display: inline-flex; align-items: center; gap: 6px;\r\n padding: 6px 14px; border-radius: 999px; font-size: 13px; font-weight: 600;\r\n width: fit-content;\r\n}\r\n.hm-status.ok { background: #e6f7ec; color: #1f8c3d; }\r\n.hm-status.warn { background: #fff5e0; color: #a25b00; }\r\n.hm-status.danger { background: #fff0ee; color: #a83228; }\r\n.hm-status.empty { background: #f0f0f3; color: #6e6e73; }\r\n\r\n/* ── emptyState 空状态 ── */\r\n.hm-empty {\r\n background: #fafbfc;\r\n border: 1px dashed var(--line);\r\n border-radius: 12px;\r\n padding: 26px 20px;\r\n text-align: center;\r\n color: var(--fg2);\r\n font-size: 13.5px;\r\n line-height: 1.7;\r\n}\r\n.hm-empty-icon { font-size: 32px; margin-bottom: 8px; }\r\n.hm-empty-text { font-weight: 600; color: var(--fg); }\r\n.hm-empty-hint { font-size: 12.5px; color: var(--fg3); margin-top: 4px; }\r\n.hm-empty-action { margin-top: 14px; }\r\n\r\n/* ── errorReceipt 错误回执 ── */\r\n.hm-error {\r\n background: #fff0ee;\r\n border: 1.5px solid #ffc4c0;\r\n border-radius: 16px;\r\n padding: 20px 22px;\r\n margin: 12px 0;\r\n}\r\n.hm-error-title { font-size: 15px; font-weight: 700; color: #a83228; margin-bottom: 14px; }\r\n/* errorReceipt 内按钮布局: 第一个 .hm-actions(修正重试)贴标题; 后续 .hm-actions(复制数据/日志)与上方保持间距, 防贴死(#290 修复) */\r\n.hm-error .hm-actions { margin-top: 0; }\r\n.hm-error .hm-actions + .hm-actions { margin-top: 14px; }\r\n@media (max-width: 820px) {\r\n .hm-error { padding: 16px 14px; }\r\n .hm-error-title { margin-bottom: 12px; }\r\n}\r\n\r\n/* ── 复制预览面板(actionBar preview)── */\r\n.hm-preview-overlay {\r\n position: fixed; inset: 0;\r\n background: rgba(0,0,0,.4);\r\n display: flex; align-items: center; justify-content: center;\r\n z-index: 10001;\r\n padding: 16px;\r\n}\r\n.hm-preview-panel {\r\n background: var(--card);\r\n border-radius: 16px;\r\n max-width: 560px;\r\n width: 100%;\r\n max-height: 80vh;\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n box-shadow: var(--shadow);\r\n}\r\n.hm-preview-head {\r\n display: flex; align-items: center; justify-content: space-between;\r\n padding: 14px 18px;\r\n border-bottom: 1px solid var(--line);\r\n font-size: 14px; font-weight: 700;\r\n}\r\n.hm-preview-close { border: none; background: none; font-size: 15px; color: var(--fg3); cursor: pointer; padding: 4px; }\r\n.hm-preview-body {\r\n flex: 1;\r\n overflow: auto;\r\n padding: 14px 18px;\r\n font-size: 12px;\r\n line-height: 1.65;\r\n font-family: ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;\r\n white-space: pre-wrap;\r\n word-break: break-all;\r\n overflow-wrap: anywhere;\r\n color: var(--fg2);\r\n margin: 0;\r\n}\r\n.hm-preview-actions { display: flex; gap: 10px; padding: 12px 18px; border-top: 1px solid var(--line); }\r\n.hm-preview-actions .copy { flex: 1; }\r\n\r\n/* 手机适配: 单列网格保持按钮不换行 */\r\n@media (max-width: 820px) {\r\n .hm-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }\r\n .hm-actions .copy.wide { grid-column: 1 / -1; }\r\n .hm-actions .copy { min-height: 46px; }\r\n .sl-batchbar { flex-direction: column; align-items: stretch; }\r\n .sl-count { margin-left: 0; }\r\n .hm-confirm-panel { padding: 20px 18px; }\r\n}\r\n\r\n/* ── smartSelect 选择器组件(v1.11 · #312 · 复用优先·新建其次)──\r\n * 类名全 ss- 命名空间(封装纪律, 防宿主同名类冲突); 主题色 = .ss-root 内联 CSS 变量,\r\n * 缺省账本藏蓝 #123A63(deep #0B1F3B / soft #E9F0F7), 每实例可独立覆盖\r\n */\r\n.ss-root {\r\n --ss-brand: #123a63;\r\n --ss-brand-soft: #e9f0f7;\r\n --ss-on-brand: #ffffff;\r\n --ss-deep: #0b1f3b;\r\n margin-top: 6px;\r\n}\r\n.ss-card {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 12px 14px;\r\n border-radius: 10px;\r\n border: 2px solid var(--ss-brand);\r\n background: var(--ss-brand-soft);\r\n}\r\n.ss-card .ss-ic {\r\n width: 34px;\r\n height: 34px;\r\n border-radius: 50%;\r\n background: var(--ss-brand);\r\n flex: none;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n.ss-card .ss-ic svg { width: 18px; height: 18px; }\r\n.ss-body { flex: 1; min-width: 0; }\r\n.ss-nm { font-size: 16px; font-weight: 700; color: var(--fg); word-break: break-word; }\r\n.ss-src { font-size: 11px; color: var(--fg3); margin-top: 2px; }\r\n.ss-card.ss-card-empty { border: 2px dashed var(--line); background: transparent; }\r\n.ss-card.ss-card-empty .ss-ic { background: transparent; border: 2px solid var(--fg3); }\r\n.ss-card.ss-card-empty .ss-nm { color: var(--fg3); }\r\n.ss-badge {\r\n display: inline-block;\r\n font-size: 10px;\r\n line-height: 1;\r\n padding: 2px 6px;\r\n border-radius: 10px;\r\n flex-shrink: 0;\r\n}\r\n.ss-badge-ai { background: var(--ss-brand-soft); color: var(--ss-brand); }\r\n.ss-badge-new { background: #fff8c5; color: #9a6700; }\r\n.ss-badge-plain { background: #eef; color: var(--fg3); }\r\n.ss-title { font-size: 11px; color: var(--fg3); margin: 10px 0 6px; }\r\n.ss-search {\r\n width: 100%;\r\n box-sizing: border-box;\r\n padding: 8px 12px;\r\n border: 1.5px solid var(--line);\r\n border-radius: 8px;\r\n font-size: 13px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n background: #fff;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n min-height: 40px;\r\n}\r\n.ss-search:focus { outline: none; border-color: var(--ss-brand); box-shadow: 0 0 0 3px rgba(18, 58, 99, .12); }\r\n.ss-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }\r\n.ss-chip {\r\n padding: 6px 12px;\r\n border: 1.5px solid var(--line);\r\n border-radius: 16px;\r\n font-size: 13px;\r\n background: #fff;\r\n cursor: pointer;\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n -webkit-tap-highlight-color: transparent;\r\n touch-action: manipulation;\r\n}\r\n.ss-chip:hover { border-color: var(--ss-brand); }\r\n.ss-chip.ss-chip-sel {\r\n background: var(--ss-brand);\r\n border-color: var(--ss-brand);\r\n color: var(--ss-on-brand);\r\n font-weight: 700;\r\n box-shadow: 0 2px 6px rgba(0, 0, 0, .18);\r\n}\r\n.ss-chip.ss-chip-sel .ss-badge-ai { background: rgba(255, 255, 255, .2); color: #fff; }\r\n.ss-chip.ss-chip-sel .ss-badge-new { background: rgba(255, 255, 255, .25); color: #ffe9a8; }\r\n.ss-chip.ss-chip-sel .ss-badge-plain { background: rgba(255, 255, 255, .18); color: #fff; }\r\n.ss-chip.ss-chip-dis {\r\n color: var(--fg3);\r\n text-decoration: line-through;\r\n cursor: not-allowed;\r\n background: var(--bg);\r\n border-color: var(--line);\r\n}\r\n/* 候选区折叠按钮(v1.12 · #312 实测反馈: 分类几十上百时 chips 全量平铺过长) */\r\n.ss-more {\r\n padding: 6px 12px;\r\n border: 1.5px dashed var(--line);\r\n border-radius: 16px;\r\n font-size: 12.5px;\r\n background: var(--bg);\r\n color: var(--fg2);\r\n cursor: pointer;\r\n font-family: inherit;\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n min-height: 36px;\r\n -webkit-tap-highlight-color: transparent;\r\n touch-action: manipulation;\r\n}\r\n.ss-more:hover { border-color: var(--ss-brand); color: var(--ss-brand); background: #fff; }\r\n.ss-new { display: flex; gap: 8px; margin-top: 10px; }\r\n.ss-new input {\r\n flex: 1;\r\n min-width: 0;\r\n padding: 8px 12px;\r\n border: 1.5px solid var(--line);\r\n border-radius: 8px;\r\n font-size: 13px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n background: #fff;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n min-height: 40px;\r\n}\r\n.ss-new input:focus { outline: none; border-color: var(--ss-brand); }\r\n.ss-new button {\r\n padding: 0 14px;\r\n border: 1.5px solid var(--line);\r\n border-radius: 8px;\r\n background: #fff;\r\n color: var(--fg);\r\n font-size: 13px;\r\n cursor: pointer;\r\n white-space: nowrap;\r\n font-family: inherit;\r\n min-height: 40px;\r\n}\r\n.ss-new button:hover { border-color: var(--ss-brand); color: var(--ss-brand); }\r\n.ss-hint { margin-top: 6px; font-size: 12px; color: #b25b00; display: none; }\r\n.ss-empty {\r\n margin-top: 8px;\r\n width: 100%;\r\n padding: 8px;\r\n border: 1px dashed var(--line);\r\n border-radius: 8px;\r\n background: transparent;\r\n color: var(--fg3);\r\n cursor: pointer;\r\n font-family: inherit;\r\n font-size: 13px;\r\n min-height: 36px;\r\n}\r\n.ss-empty:hover { border-color: var(--ss-brand); color: var(--ss-brand); }\r\n/* 降级模式(options 空数组等 → 普通输入) */\r\n.ss-plain {\r\n width: 100%;\r\n box-sizing: border-box;\r\n padding: 8px 12px;\r\n border: 1.5px solid var(--line);\r\n border-radius: 8px;\r\n font-size: 13px;\r\n font-family: inherit;\r\n color: var(--fg);\r\n background: #fff;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n min-height: 44px;\r\n}\r\n.ss-plain:focus { outline: none; border-color: var(--ss-brand); box-shadow: 0 0 0 3px rgba(18, 58, 99, .12); }\r\n@media (max-width: 820px) {\r\n .ss-new { flex-direction: column; align-items: stretch; }\r\n .ss-new button { min-height: 44px; }\r\n .ss-chip { min-height: 38px; }\r\n}\r\n</style>\r\n\r\n<script>\r\n/* ===== 技能身份与数据(scene-data 契约 v1 · 全外部注入)===== */\r\nvar HELP = JSON.parse(document.getElementById('help-data').textContent);\r\nvar SKILL_NAME = HELP.skill_name || '';\r\nvar TITLE = HELP.title || '能力速查台';\r\nvar SUBTITLE = HELP.subtitle || '';\r\nvar META_BLOCKS = HELP.meta_blocks || [];\r\nvar INIT_BANNER = HELP.init_banner || null;\r\nvar CONTACT = HELP.contact || null;\r\nvar SKILL_VERSION = HELP.version || '';\r\nvar ABOUT_EXTRA = {};\r\nvar RECOMMENDATIONS = HELP.recommendations || [];\r\n\r\n/* 契约 v1 (groups[{id,icon,label,subgroups[{id,label,scenes[]}]}])\r\n -> 原型内部结构 (key/icon/name + subgroups[{name,scenes}]) */\r\nfunction normalizeScenes(scenes){\r\n return (scenes || []).map(function(s){\r\n return {\r\n id: s.id,\r\n name: s.title,\r\n chip: s.wake_word,\r\n types: (s.types && s.types.length ? s.types : []),\r\n dev: (s.status === '【待开发】'),\r\n prompt: s.prompt_template,\r\n params: (s.editable_fields || []).map(function(f){\r\n return { key: f.name, label: f.label, value: f.value || '', req: !!f.required, hint: f.hint || '' };\r\n })\r\n };\r\n });\r\n}\r\nvar GROUPS = (HELP.groups || []).map(function(g){\r\n return {\r\n key: g.id, icon: g.icon || 'grid', name: g.label,\r\n subgroups: (g.subgroups || []).map(function(sg){\r\n return { name: sg.label, scenes: normalizeScenes(sg.scenes) };\r\n })\r\n };\r\n});\r\n\r\n/* ===== 扁平化索引(原型逻辑 · 渲染/卡片/搜索依赖)===== */\r\nvar ALL = [];\r\nvar SCENE = {};\r\nGROUPS.forEach(function(g){\r\n g.subgroups.forEach(function(sg){\r\n sg.scenes.forEach(function(s){\r\n s.g = g.name; s.gkey = g.key; s.gico = g.icon; s.sg = sg.name;\r\n ALL.push(s); SCENE[s.id] = s;\r\n });\r\n });\r\n});\r\n\r\nfunction esc(s){ return String(s==null?'':s).replace(/[&<>\"']/g, function(c){ return {'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]; }); }\r\n/* 类型徽章: types 数组元素可为字符串(默认配色)或 {text,bg,fg}(调用者自定义颜色, 缺省走默认) */\r\nvar TYPE_DEFAULT = {\r\n '采集': {bg:'#e7f8ee', fg:'#1a7a3a'},\r\n '查看': {bg:'#e8f2ff', fg:'#0a63ce'},\r\n '结果': {bg:'#e8f2ff', fg:'#0a63ce'},\r\n '向导': {bg:'#e2f7f5', fg:'#00897b'},\r\n '批量': {bg:'#f3e9fb', fg:'#8e3fc9'},\r\n '校验': {bg:'#e8f2ff', fg:'#0a63ce'},\r\n '选择': {bg:'#e8f2ff', fg:'#0a63ce'},\r\n '过程': {bg:'#e2f7f5', fg:'#00897b'},\r\n '回执': {bg:'#e8f2ff', fg:'#0a63ce'},\r\n '录入': {bg:'#e7f8ee', fg:'#1a7a3a'}\r\n};\r\nfunction typeBadgeHTML(t){\r\n var text, bg, fg;\r\n if (t && typeof t === 'object') {\r\n text = t.text;\r\n var d = TYPE_DEFAULT[text] || TYPE_DEFAULT['查看'];\r\n bg = t.bg || d.bg;\r\n fg = t.fg || d.fg;\r\n } else {\r\n text = t;\r\n var d2 = TYPE_DEFAULT[text] || TYPE_DEFAULT['查看'];\r\n bg = d2.bg; fg = d2.fg;\r\n }\r\n return '<span class=\"type-badge\" style=\"background:' + esc(bg) + ';color:' + esc(fg) + '\">' + esc(text) + '</span>';\r\n}\r\nfunction chipHTML(s){\r\n var h = '<span class=\"chip\">' + esc(s.chip) + '</span>';\r\n if (s.dev) h += '<span class=\"type-badge t-dev\">待开发</span>';\r\n (s.types || []).forEach(function(t){ h += typeBadgeHTML(t); });\r\n return h;\r\n}\r\n\r\n/* ===== SVG 图标库 ===== */\r\nvar SVG_ICONS = {\r\n write:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M17 3a2.8 2.8 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z\"/></svg>',\r\n calendar:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"/><line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"/><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"/><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"/></svg>',\r\n chart:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"20\" x2=\"18\" y2=\"10\"/><line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"4\"/><line x1=\"6\" y1=\"20\" x2=\"6\" y2=\"14\"/></svg>',\r\n grid:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"/></svg>',\r\n target:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><circle cx=\"12\" cy=\"12\" r=\"5\"/><circle cx=\"12\" cy=\"12\" r=\"1\"/></svg>',\r\n rocket:'<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09Z\"/><path d=\"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2Z\"/><path d=\"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0\"/><path d=\"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5\"/></svg>'\r\n};\r\nfunction tabIconHTML(g){\r\n var svg = SVG_ICONS[g.icon];\r\n if (svg) return '<span class=\"t-ico\">' + svg + '</span>';\r\n return '<span class=\"t-ico\"><span class=\"t-emoji\">' + esc(g.icon) + '</span></span>';\r\n}\r\n\r\n/* ===== 参数机制:prompt + 末尾每行「key: value」===== */\r\nfunction readParams(id){\r\n var fm = document.querySelector('.pform[data-pid=\"' + id + '\"]');\r\n var v = {};\r\n if (fm) fm.querySelectorAll('input[data-p]').forEach(function(inp){ v[inp.dataset.p] = inp.value; });\r\n return v;\r\n}\r\nfunction buildPrompt(s, v){\r\n v = v || {};\r\n var lines = [s.prompt];\r\n var paramLines = [];\r\n (s.params || []).forEach(function(p){\r\n var val = (v[p.key] != null ? v[p.key] : '').trim();\r\n if (val) paramLines.push(p.label + ': ' + val);\r\n });\r\n if (paramLines.length) lines.push(''); /* 空行分隔 */\r\n lines = lines.concat(paramLines);\r\n return lines.join('\\n');\r\n}\r\nfunction getMissing(s, v){\r\n return (s.params || []).filter(function(p){ return p.req && !(v[p.key] || '').trim(); }).map(function(p){ return p.label; });\r\n}\r\n\r\n/* ===== 渲染主页面 ===== */\r\nvar screen = document.getElementById('screen');\r\nvar h = '<div class=\"app\"><div class=\"app-inner\">' +\r\n '<header class=\"hero\"><div class=\"h-left\"><div class=\"eyebrow\">' + esc(SKILL_NAME) + '</div><h1>' + esc(TITLE) + '</h1><div class=\"lead\">' + ALL.length + ' 场景 · 点击卡片查看详情并复制指令</div></div><span class=\"h-badge\">' + ALL.length + ' 场景</span>' +\r\n '<div class=\"hero-steps\"><span class=\"step\">🔍 找场景</span><span class=\"arrow\">→</span><span class=\"step\">📋 复制指令</span><span class=\"arrow\">→</span><span class=\"step\">💬 发给 AI</span></div>' +\r\n '</header>' +\r\n (INIT_BANNER && !INIT_BANNER.hidden ? '<div class=\"init-banner\" id=\"initBanner\"><div class=\"ib-text\"><div class=\"ib-title\">' + esc(INIT_BANNER.title) + '</div><div class=\"ib-sub\">' + esc(INIT_BANNER.subtitle) + '</div></div><button class=\"copy-btn\" data-c=\"' + esc(INIT_BANNER.prompt) + '\">' + esc(INIT_BANNER.button_text) + '</button>' + (INIT_BANNER.closable === false ? '' : '<button class=\"ib-close\" id=\"initClose\" aria-label=\"关闭\">✕</button>') +\r\n (INIT_BANNER.steps && INIT_BANNER.steps.length ? '<div class=\"init-steps\">' + INIT_BANNER.steps.map(function(st, i){ return '<div class=\"init-step\"><div class=\"s-n\">' + (i+1) + '</div><div class=\"s-t\">' + esc(st.title) + '</div>' + (st.desc ? '<div class=\"s-d\">' + esc(st.desc) + '</div>' : '') + '</div>'; }).join('') + '</div>' : '') +\r\n '</div>' : '') +\r\n '<div class=\"search-wrap\"><div class=\"search-box\"><span class=\"s-icon\">🔍</span><input id=\"sB\" type=\"search\" placeholder=\"搜索全部场景\" autocomplete=\"off\"><button class=\"s-clear\" id=\"sClear\">✕</button></div></div>' +\r\n '<div class=\"hitcount\" id=\"hitC\" hidden></div><div class=\"search-empty\" id=\"emptyC\" hidden>没有找到相关场景,换个词试试~</div>' +\r\n '<div class=\"pages\" id=\"pages\">';\r\nGROUPS.forEach(function(g){\r\n h += '<div class=\"page\" data-page=\"' + g.key + '\">';\r\n g.subgroups.forEach(function(sg, si){\r\n /* 默认只展开本页第一个二级分组(其余折叠):首屏看得见一组内容,又不被十几个分组撑成长卷。\r\n 用户 2026-09-24 裁定;搜索清空后也回到这一态,见 doSearch 的复位支。 */\r\n h += '<details class=\"subgroup\"' + (si === 0 ? ' open' : '') + '><summary>' + sg.name + '<span class=\"sg-count\">' + sg.scenes.length + '</span></summary><div class=\"sg-body\"><div class=\"grid\">';\r\n sg.scenes.forEach(function(s){\r\n h += '<div class=\"mini\" data-key=\"' + s.id + '\">' +\r\n '<div class=\"m-top\">' + chipHTML(s) + '</div>' +\r\n '<div class=\"m-bottom\">' +\r\n '<div class=\"m-name\">' + esc(s.name) + '</div>' +\r\n '<button class=\"copy-btn\" data-c=\"' + esc(buildPrompt(s, {})) + '\">复制</button>' +\r\n '</div>' +\r\n '</div>';\r\n });\r\n h += '</div></div></details>';\r\n });\r\n h += '</div>';\r\n});\r\n/* ===== 关于 Tab(最后 · 联系作者 + 版本 + 其他技能 · 拼在 pages 容器内)===== */\r\nh += '<div class=\"page\" data-page=\"about\">';\r\n/* ① 联系作者(第一位)*/\r\nif (CONTACT && CONTACT.items && CONTACT.items.length) {\r\n h += '<div class=\"about-sec\"><div class=\"as-head\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"width:14px;height:14px;flex-shrink:0\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg> 联系作者</div><div class=\"as-body\">';\r\n CONTACT.items.forEach(function(it){\r\n if (it.url && String(it.value).indexOf('http') === 0) {\r\n h += '<div class=\"about-row\"><span class=\"a-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg></span><div class=\"a-t\"><b>' + esc(it.label) + '</b><a class=\"a-link\" href=\"' + esc(it.value) + '\" target=\"_blank\" rel=\"noopener\">' + esc(it.value) + '</a></div></div>';\r\n } else {\r\n h += '<div class=\"about-row\"><span class=\"a-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg></span><div class=\"a-t\"><b>' + esc(it.label) + '</b><span>' + esc(it.value) + '</span></div></div>';\r\n }\r\n });\r\n if (CONTACT.copy_all) {\r\n var contactTxt = CONTACT.items.map(function(it){ return it.label + ': ' + it.value; }).join('\\n');\r\n h += '<div class=\"about-row\"><span class=\"a-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg></span><div class=\"a-t\"><b>一键复制</b><span>全部联系信息</span></div><button class=\"copy-btn a-copy\" data-c=\"' + esc(contactTxt) + '\">复制</button></div>';\r\n }\r\n h += '</div></div>';\r\n}\r\n/* ② 版本(第二位)*/\r\nh += '<div class=\"about-sec\"><div class=\"as-head\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"width:14px;height:14px;flex-shrink:0\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16\"/><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/></svg> 版本</div><div class=\"as-body\"><div class=\"about-row\"><span class=\"a-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z\"/><line x1=\"7\" y1=\"7\" x2=\"7.01\" y2=\"7\"/></svg></span><div class=\"a-t\"><b>' + esc(SKILL_NAME) + '</b><span>v' + esc(SKILL_VERSION) + ' · HELP 模板 v4</span></div></div></div></div>';\r\n/* ③ 其他技能(第三位 · SVG 图标)*/\r\nif (RECOMMENDATIONS && RECOMMENDATIONS.length) {\r\n h += '<div class=\"about-sec\"><div class=\"as-head\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"width:14px;height:14px;flex-shrink:0\"><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/><path d=\"M12 2a7 7 0 0 0-4 12.7c.6.5 1 1.4 1 2.3h6c0-.9.4-1.8 1-2.3A7 7 0 0 0 12 2z\"/></svg> 其他技能</div><div class=\"as-body\">';\r\n RECOMMENDATIONS.forEach(function(r){\r\n h += '<div class=\"about-row\"><span class=\"a-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"/><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"/></svg></span><div class=\"a-t\"><b>' + esc(r.name) + '</b><span>' + esc(r.desc) + '</span></div>' + (r.wake ? '<span class=\"a-badge\">' + esc(r.wake) + '</span>' : '') + '</div>';\r\n });\r\n h += '</div></div>';\r\n}\r\nh += '</div>'; /* 关闭 about page */\r\nh += '</div></div>'; /* 关闭 pages + app-inner */\r\nh += '<div class=\"tab-bar\" id=\"tabBar\">';\r\nGROUPS.forEach(function(g, i){\r\n h += '<button class=\"tab' + (i===0?' active':'') + '\" data-nav=\"' + g.key + '\">' + tabIconHTML(g) + g.name + '</button>';\r\n});\r\nh += '<button class=\"tab\" data-nav=\"about\"><span class=\"t-ico\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16\"/><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/></svg></span>关于</button>';\r\nh += '</div></div>';\r\nscreen.innerHTML = h;\r\n\r\n/* 初始化横幅手动关闭(✕)*/\r\nvar initClose = document.getElementById('initClose');\r\nif (initClose) initClose.addEventListener('click', function(){\r\n var b = document.getElementById('initBanner');\r\n if (b) b.style.display = 'none';\r\n});\r\n/* ===== 自然滚动: 内容跟手, 搜索栏 sticky 吸顶(CSS) =====\r\n 旧版两段式 transform 抵消导致: 吸顶前内容不跟手、短页(关于)滚不到吸顶 → 全部移除 */\r\n/* 页面高度 = 内容自然高度(不撑高): 内容短则页面短, 滑到底即停, 不出灰色空白\r\n (原实现 pg.style.minHeight = screen.clientHeight 把短页撑到一屏高,\r\n 内容下方露出透明 page 背景 → 灰色底被顶上来;#289 用户验收拍板)*/\r\n\r\n/* ===== 滑动切页(ViewPager)===== */\r\nvar pages = document.getElementById('pages');\r\nvar tabs = Array.prototype.slice.call(document.querySelectorAll('.tab'));\r\nvar screen = document.querySelector('.screen');\r\n/* ③ 容器高度锁定: 用内容实际全高(而非首屏高), 防空白可滑也防内容被截断 */\r\nfunction lockPagesHeight(idx){\r\n if (idx === undefined) idx = Math.min(curIndex(), pages.children.length - 1);\r\n var pg = pages.children[idx];\r\n if (!pg) return;\r\n pages.style.height = pg.scrollHeight + 'px';\r\n}\r\nfunction curIndex(){ return Math.round(pages.scrollLeft / pages.clientWidth); }\r\nfunction syncTab(){\r\n var i = Math.min(curIndex(), tabs.length - 1);\r\n tabs.forEach(function(t, j){ t.classList.toggle('active', j === i); });\r\n}\r\npages.addEventListener('scroll', function(){\r\n clearTimeout(syncTab._t);\r\n syncTab._t = setTimeout(function(){\r\n if (Date.now() < syncTab._lockUntil) return; /* 点击后的滚动动画期不覆盖 active */\r\n syncTab();\r\n lockPagesHeight(); /* 横向滑动结束也校准高度 */\r\n }, 15);\r\n}, {passive:true});\r\ntabs.forEach(function(t){\r\n t.addEventListener('click', function(){\r\n var i = tabs.indexOf(t);\r\n tabs.forEach(function(x, j){ x.classList.toggle('active', j === i); });\r\n syncTab._lockUntil = Date.now() + 900; /* 锁 ~0.9s: 覆盖点击动画期即可, 缩短滑动跟手延迟 */\r\n /* 切换立即: ① 归零纵向滚动(防旧位置灰色遮挡) ② 立即锁定新页高度(防内容截断/滑不动) */\r\n /* 手机端: .screen 是滚动容器, scrollTop=0 = 回到内容顶部(页面不跳);\r\n 宽屏: .screen overflow:visible, 真正滚动的是 window —— 定位到 pages 容器顶部(搜索栏处), 不跳整页最上层 */\r\n if (screen.scrollTop !== undefined && screen.clientHeight > 0 && screen.scrollHeight > screen.clientHeight) {\r\n screen.scrollTop = 0;\r\n } else {\r\n var pagesTop = pages.getBoundingClientRect().top + (window.pageYOffset || document.documentElement.scrollTop || 0);\r\n /* 落点必须再让开吸顶搜索栏: 只减 8px 时 .pages 顶正好落在吸顶栏之下, 当页第一个元素(首个子功能组摘要)被压成一条缝,\r\n 点不到也看不见 —— 吸顶栏高动态取(不写死像素: 视口宽/字体缩放都会改它), 取不到时按 0 退化为原行为 */\r\n var stickyBar = document.querySelector('.search-wrap');\r\n window.scrollTo(0, Math.max(0, pagesTop - (stickyBar ? stickyBar.offsetHeight : 0) - 8));\r\n }\r\n pages.style.scrollSnapType = 'none';\r\n pages.scrollTo({left: i * pages.clientWidth, behavior:'smooth'});\r\n lockPagesHeight(i); /* 直接传目标索引, 不等动画 */\r\n /* 点击的 Tab 尽可能居中显示(首尾贴边) */\r\n centerTab(t);\r\n setTimeout(function(){\r\n pages.style.scrollSnapType = '';\r\n syncTab._lockUntil = 0; /* 动画结束立即解锁, 之后滑动变色实时跟手 */\r\n lockPagesHeight(i); /* 动画结束后再校准一次 */\r\n }, 900);\r\n });\r\n});\r\n/* ===== Tab 条: 点击的 Tab 居中显示 ===== */\r\nfunction centerTab(tab){\r\n var bar = document.getElementById('tabBar');\r\n var max = bar.scrollWidth - bar.clientWidth;\r\n var target = tab.offsetLeft + tab.offsetWidth / 2 - bar.clientWidth / 2;\r\n target = Math.max(0, Math.min(target, max));\r\n bar.scrollTo({left: target, behavior: 'smooth'});\r\n}\r\n\r\n/* ===== Sheet 弹层(B3: 复制不自动关 · B4: 无参数显 prompt)===== */\r\nvar mask = document.getElementById('sheetMask');\r\nvar sheet = document.getElementById('sheet');\r\nvar shHead = document.getElementById('shHead');\r\nvar shBody = document.getElementById('shBody');\r\nvar shCopy = document.getElementById('shCopy');\r\nvar curScene = null;\r\n\r\nfunction openSheet(s){\r\n curScene = s;\r\n shHead.innerHTML = '<span class=\"s-title\">' + esc(s.name) + '</span>' + chipHTML(s);\r\n var form = '';\r\n var hasParams = s.params && s.params.length;\r\n if (hasParams) {\r\n form = '<div class=\"pform\" data-pid=\"' + s.id + '\">';\r\n s.params.forEach(function(p){\r\n form += '<div class=\"pfield\"><label>' + esc(p.label) + (p.req ? '' : '<em>选填</em>') + '</label>' +\r\n '<input data-p=\"' + esc(p.key) + '\" value=\"' + esc(p.value || '') + '\" placeholder=\"' + esc(p.hint || '') + '\"></div>';\r\n });\r\n form += '</div>';\r\n }\r\n /* 预览:prompt + 末尾 key:value(有参数时实时重组)*/\r\n var prev = '<div class=\"pprev\"><span class=\"pv-label\">Prompt 预览</span><span data-prev>' + esc(buildPrompt(s, {})) + '</span></div>';\r\n shBody.innerHTML = form + prev;\r\n shCopy.dataset.pid = s.id;\r\n shCopy.dataset.c = buildPrompt(s, {});\r\n /* 参数化实时预览 */\r\n var fm = sheet.querySelector('.pform');\r\n if (fm) fm.addEventListener('input', function(){\r\n var pv = sheet.querySelector('[data-prev]');\r\n if (pv) pv.textContent = buildPrompt(s, readParams(s.id));\r\n });\r\n mask.classList.add('show');\r\n sheet.classList.add('show');\r\n sheet.querySelector('.s-scroll').scrollTop = 0;\r\n}\r\nfunction closeSheet(){\r\n mask.classList.remove('show');\r\n sheet.classList.remove('show');\r\n}\r\nmask.addEventListener('click', closeSheet);\r\ndocument.getElementById('sheetClose').addEventListener('click', closeSheet);\r\n\r\n/* ===== 卡片交互 ===== */\r\nscreen.addEventListener('click', function(e){\r\n var mini = e.target.closest('.mini');\r\n if (mini) {\r\n if (e.target.closest('[data-c]')) return;\r\n openSheet(SCENE[mini.dataset.key]);\r\n }\r\n});\r\n\r\n/* ===== Toast(公共组件)===== */\r\nfunction showToast(){\r\n toast('已复制', '粘贴给 AI,技能会自动执行,完成后你会拿到结果 HTML。', {icon:'copy'});\r\n}\r\nfunction toastMsg(msg){\r\n toast('请先填写: ' + msg, '填写完整后再复制指令', {icon:'warn', badge:{text:'未完成', type:'warn'}});\r\n}\r\nfunction doCopy(text){\r\n var ta = document.createElement('textarea');\r\n ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0';\r\n document.body.appendChild(ta); ta.select();\r\n try { document.execCommand('copy'); } catch(e){}\r\n document.body.removeChild(ta);\r\n}\r\n\r\n/* ===== 全局复制(含参数校验)===== */\r\ndocument.addEventListener('click', function(e){\r\n var b = e.target.closest('[data-c]');\r\n if (!b) return;\r\n e.preventDefault(); e.stopPropagation();\r\n var s = SCENE[b.dataset.pid || (b.closest('.mini') ? b.closest('.mini').dataset.key : '')];\r\n var text = b.dataset.c;\r\n if (s && s.params && s.params.length) {\r\n var v = readParams(s.id);\r\n var miss = getMissing(s, v);\r\n if (miss.length) { toastMsg(miss.join('、')); return; }\r\n text = buildPrompt(s, v);\r\n }\r\n doCopy(text);\r\n showToast();\r\n /* B3: 复制后不自动关弹窗 */\r\n});\r\n\r\n/* ===== 搜索(全局跨 Tab + 自动跳转 + 高亮)===== */\r\nvar sB = document.getElementById('sB');\r\nvar sClear = document.getElementById('sClear');\r\nvar lastQuery = '';\r\nfunction doSearch(){\r\n var q = sB.value.trim().toLowerCase();\r\n sClear.style.display = q ? 'flex' : 'none';\r\n if (!q) {\r\n var cur = curIndex();\r\n Array.prototype.forEach.call(pages.children, function(pg, i){\r\n pg.querySelectorAll('.mini').forEach(function(m){\r\n m.style.display = '';\r\n m.querySelector('.m-name').innerHTML = esc(SCENE[m.dataset.key].name);\r\n });\r\n /* 清空搜索=回到默认态:只第一个二级分组展开(搜索期把命中的组都打开过,不复位就留下了)。 */\r\n pg.querySelectorAll('.subgroup').forEach(function(sg, si){ sg.style.display = ''; sg.open = si === 0; });\r\n });\r\n /* 恢复全量后必须同步重算高度锁: 筛选期 .pages 被锁在「筛选后」的当页高, 不重算就当页被锁矮,\r\n 后半页连同末张场景卡一起滚不到 —— 这里的 scrollTo 目标就是当前位置(不触发 scroll 事件), 兜不住这次重算 */\r\n lockPagesHeight();\r\n if (lastQuery) pages.scrollTo({left: cur * pages.clientWidth, behavior:'smooth'});\r\n lastQuery = '';\r\n document.getElementById('hitC').hidden = true;\r\n document.getElementById('emptyC').hidden = true;\r\n return;\r\n }\r\n lastQuery = q;\r\n var total = 0, firstHitPage = -1;\r\n Array.prototype.forEach.call(pages.children, function(pg, i){\r\n var pageHit = 0;\r\n pg.querySelectorAll('.mini').forEach(function(m){\r\n var show = m.textContent.toLowerCase().indexOf(q) > -1;\r\n m.style.display = show ? '' : 'none';\r\n if (show) pageHit++;\r\n var orig = SCENE[m.dataset.key].name;\r\n var i2 = orig.toLowerCase().indexOf(q);\r\n if (q && i2 >= 0) m.querySelector('.m-name').innerHTML = esc(orig.slice(0,i2)) + '<mark>' + esc(orig.slice(i2,i2+q.length)) + '</mark>' + esc(orig.slice(i2+q.length));\r\n else m.querySelector('.m-name').innerHTML = esc(orig);\r\n });\r\n /* 子功能组:无命中则隐藏 */\r\n pg.querySelectorAll('.subgroup').forEach(function(sg){\r\n var vis = sg.querySelectorAll('.mini:not([style*=\"none\"])').length > 0;\r\n sg.style.display = vis ? '' : 'none';\r\n if (q && vis) sg.open = true;\r\n });\r\n total += pageHit;\r\n if (pageHit > 0 && firstHitPage === -1) firstHitPage = i;\r\n });\r\n if (firstHitPage >= 0 && firstHitPage !== curIndex()) {\r\n pages.scrollTo({left: firstHitPage * pages.clientWidth, behavior:'smooth'});\r\n }\r\n document.getElementById('hitC').hidden = false;\r\n document.getElementById('hitC').textContent = '匹配 ' + total + ' 个场景';\r\n document.getElementById('emptyC').hidden = total > 0;\r\n}\r\nsB.addEventListener('input', doSearch);\r\nsClear.addEventListener('click', function(){ sB.value = ''; doSearch(); sB.focus(); });\r\n/* 初始锁定 + 子功能组折叠/展开时高度校准 */\r\nlockPagesHeight();\r\ndocument.addEventListener('click', function(e){\r\n var sg = e.target.closest('.subgroup > summary');\r\n if (sg) setTimeout(lockPagesHeight, 60); /* details 切换后重算 */\r\n});\r\n</script>\r\n</body>\r\n</html>\r\n";
33
33
  /** help-data 容器开标签(PREFIX 与 SUFFIX 的切分锚点)。 */
34
34
  export const HELP_SHELL_DATA_OPEN = "<script id=\"help-data\" type=\"application/json\">";
35
35
  /** 文档标题占位(在 PREFIX 内;渲染时替换,源里写死即回原型水印)。 */
@@ -62,4 +62,3 @@ export function renderHelpShellHtml(data) {
62
62
  }
63
63
  /** #136 标准出口(`renderHelpShellHtml` 同实现;skill 侧只传自家 HELP JSON 即接)。 */
64
64
  export const renderHelpShell = renderHelpShellHtml;
65
- //# sourceMappingURL=helpShell.js.map