@jxsuite/studio 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. package/canvas.html +21 -0
  2. package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
  3. package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
  4. package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
  5. package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
  6. package/dist/chunks/{components-799jpvhm.js → components-2bpqp4mq.js} +5 -7
  7. package/dist/chunks/{components-799jpvhm.js.map → components-2bpqp4mq.js.map} +1 -1
  8. package/dist/chunks/content-source-34gnkbnn.js +38 -0
  9. package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
  10. package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
  11. package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
  12. package/dist/chunks/extension-sections-6mqydz35.js +301 -0
  13. package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
  14. package/dist/chunks/files-8kn321h1.js +70 -0
  15. package/dist/chunks/files-8kn321h1.js.map +9 -0
  16. package/dist/chunks/{format-host-8jxwts2p.js → format-host-mkwsmt8d.js} +3 -3
  17. package/dist/chunks/git-panel-tjbr191d.js +51 -0
  18. package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
  19. package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
  20. package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
  21. package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
  22. package/dist/chunks/layers-panel-87pb25km.js +58 -0
  23. package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
  24. package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
  25. package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
  26. package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
  27. package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
  28. package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
  29. package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
  30. package/dist/chunks/right-panel-zpdxd98t.js +37 -0
  31. package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
  32. package/dist/chunks/section-registry-zmckaxf4.js +30 -0
  33. package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
  34. package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
  35. package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
  36. package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
  37. package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
  38. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
  39. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
  40. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
  41. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
  42. package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
  43. package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
  44. package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
  45. package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
  46. package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
  47. package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
  48. package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
  49. package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
  50. package/dist/chunks/studio-41exgzhq.js +6690 -0
  51. package/dist/chunks/studio-41exgzhq.js.map +38 -0
  52. package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
  53. package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
  54. package/dist/chunks/studio-50k77cca.js +1787 -0
  55. package/dist/chunks/studio-50k77cca.js.map +18 -0
  56. package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
  57. package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
  58. package/dist/chunks/studio-6f0am8f2.js +53 -0
  59. package/dist/chunks/studio-6f0am8f2.js.map +10 -0
  60. package/dist/chunks/studio-6nmjc5qk.js +7002 -0
  61. package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
  62. package/dist/chunks/studio-7afd21nw.js +67 -0
  63. package/dist/chunks/studio-7afd21nw.js.map +10 -0
  64. package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
  65. package/dist/chunks/studio-7bmdvzne.js.map +10 -0
  66. package/dist/chunks/studio-8jpzqk5s.js +128 -0
  67. package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
  68. package/dist/chunks/studio-94m77tgk.js +1482 -0
  69. package/dist/chunks/studio-94m77tgk.js.map +13 -0
  70. package/dist/chunks/studio-9je6w5sq.js +1000 -0
  71. package/dist/chunks/studio-9je6w5sq.js.map +16 -0
  72. package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
  73. package/dist/chunks/{studio-gs6kqdt1.js → studio-adn0z1k3.js} +14 -8
  74. package/dist/chunks/{studio-gs6kqdt1.js.map → studio-adn0z1k3.js.map} +3 -3
  75. package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
  76. package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
  77. package/dist/chunks/studio-bw5dz6km.js +608 -0
  78. package/dist/chunks/studio-bw5dz6km.js.map +21 -0
  79. package/dist/chunks/studio-c6s5getc.js +4232 -0
  80. package/dist/chunks/studio-c6s5getc.js.map +39 -0
  81. package/dist/chunks/studio-cjm7fdjf.js +451 -0
  82. package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
  83. package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
  84. package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
  85. package/dist/chunks/studio-dg7zyt5x.js +28 -0
  86. package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
  87. package/dist/chunks/studio-dzcyvvvz.js +166 -0
  88. package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
  89. package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
  90. package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
  91. package/dist/chunks/studio-f12h6177.js +411 -0
  92. package/dist/chunks/studio-f12h6177.js.map +13 -0
  93. package/dist/chunks/studio-hbp1s8m9.js +1817 -0
  94. package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
  95. package/dist/chunks/studio-k2sxjph5.js +15295 -0
  96. package/dist/chunks/studio-k2sxjph5.js.map +235 -0
  97. package/dist/chunks/studio-myje51t3.js +385 -0
  98. package/dist/chunks/studio-myje51t3.js.map +12 -0
  99. package/dist/chunks/studio-na6rwzhw.js +353 -0
  100. package/dist/chunks/studio-na6rwzhw.js.map +11 -0
  101. package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
  102. package/dist/chunks/studio-p471gg5n.js.map +14 -0
  103. package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
  104. package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
  105. package/dist/chunks/{studio-esrewxap.js → studio-s519zc99.js} +3 -3
  106. package/dist/chunks/studio-sas7mt3k.js +75 -0
  107. package/dist/chunks/studio-sas7mt3k.js.map +10 -0
  108. package/dist/chunks/studio-t5wqwzdh.js +74 -0
  109. package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
  110. package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
  111. package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
  112. package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
  113. package/dist/chunks/studio-tr20m8g8.js.map +9 -0
  114. package/dist/chunks/{studio-v7jkjqng.js → studio-v96qfnww.js} +5514 -4291
  115. package/dist/chunks/studio-v96qfnww.js.map +54 -0
  116. package/dist/chunks/studio-vcetc91k.js +659 -0
  117. package/dist/chunks/studio-vcetc91k.js.map +10 -0
  118. package/dist/chunks/{studio-jm0z592w.js → studio-vmymjefp.js} +2972 -4937
  119. package/dist/chunks/studio-vmymjefp.js.map +98 -0
  120. package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
  121. package/dist/chunks/studio-x9hmy5kr.js +390 -0
  122. package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
  123. package/dist/chunks/studio-xa0ce0n7.js +335 -0
  124. package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
  125. package/dist/chunks/studio-xm3dbxvn.js +378 -0
  126. package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
  127. package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
  128. package/dist/chunks/studio-zv37yrfa.js +1054 -0
  129. package/dist/chunks/studio-zv37yrfa.js.map +13 -0
  130. package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
  131. package/dist/chunks/ws-client-654ts66j.js.map +11 -0
  132. package/dist/iframe-entry.js +668 -230
  133. package/dist/studio.js +21080 -32585
  134. package/index.html +35 -4685
  135. package/package.json +17 -15
  136. package/src/about/about-modal.ts +42 -11
  137. package/src/browse/library-commands.ts +240 -0
  138. package/src/browse/library-layouts.ts +369 -0
  139. package/src/browse/library-model.ts +396 -0
  140. package/src/browse/library-pane.ts +1049 -0
  141. package/src/browse/library-preview.ts +252 -0
  142. package/src/browse/library-source.ts +150 -0
  143. package/src/canvas/canvas-helpers.ts +33 -9
  144. package/src/canvas/canvas-live-render.ts +45 -29
  145. package/src/canvas/canvas-patcher.ts +151 -31
  146. package/src/canvas/canvas-perf.ts +46 -7
  147. package/src/canvas/canvas-render.ts +1092 -220
  148. package/src/canvas/canvas-surface.ts +240 -0
  149. package/src/canvas/canvas-utils.ts +1166 -124
  150. package/src/canvas/iframe-drop.ts +2 -1
  151. package/src/canvas/iframe-entry.ts +241 -4
  152. package/src/canvas/iframe-host.ts +1226 -143
  153. package/src/canvas/iframe-inline-edit.ts +31 -0
  154. package/src/canvas/iframe-interaction.ts +76 -16
  155. package/src/canvas/iframe-keys.ts +107 -45
  156. package/src/canvas/iframe-overlay.ts +38 -1
  157. package/src/canvas/iframe-protocol.ts +137 -2
  158. package/src/canvas/iframe-render.ts +70 -2
  159. package/src/canvas/iframe-slash.ts +6 -0
  160. package/src/canvas/path-mapping.ts +56 -6
  161. package/src/canvas/surface-registry.ts +292 -0
  162. package/src/collab/collab-commands.ts +244 -0
  163. package/src/collab/collab-session.ts +198 -32
  164. package/src/collab/collab-state.ts +28 -2
  165. package/src/collab/presence-chips.ts +100 -9
  166. package/src/commands/active-registry.ts +42 -0
  167. package/src/commands/app-commands.ts +176 -0
  168. package/src/commands/budget.ts +158 -0
  169. package/src/commands/command-args.ts +253 -0
  170. package/src/commands/context.ts +387 -0
  171. package/src/commands/defaults.ts +580 -0
  172. package/src/commands/keymap.ts +571 -0
  173. package/src/commands/levels.ts +345 -0
  174. package/src/commands/live-context.ts +193 -0
  175. package/src/commands/reference.ts +227 -0
  176. package/src/commands/registry.ts +293 -0
  177. package/src/component-props.ts +3 -2
  178. package/src/content/draft-state.ts +106 -0
  179. package/src/content/entry-commands.ts +282 -0
  180. package/src/content/entry-editor.ts +327 -0
  181. package/src/content/entry-fields.ts +116 -0
  182. package/src/content/entry-model.ts +175 -0
  183. package/src/editor/canvas-context-menu.ts +17 -11
  184. package/src/editor/canvas-slash-bridge.ts +11 -4
  185. package/src/editor/context-menu.ts +804 -204
  186. package/src/editor/convert-to-component.ts +31 -10
  187. package/src/editor/convert-to-repeater.ts +3 -2
  188. package/src/editor/inline-edit-apply.ts +5 -5
  189. package/src/editor/inline-edit.ts +86 -50
  190. package/src/editor/insert-zone-action.ts +1 -1
  191. package/src/editor/shortcuts.ts +1043 -329
  192. package/src/editor/slash-menu.ts +1 -0
  193. package/src/files/elements.ts +166 -0
  194. package/src/files/file-ops.ts +178 -31
  195. package/src/files/files.ts +898 -268
  196. package/src/files/fs-events.ts +21 -0
  197. package/src/files/media-meta.ts +203 -0
  198. package/src/files/media-paths.ts +141 -0
  199. package/src/files/media-upload.ts +7 -3
  200. package/src/files/media-usage.ts +189 -0
  201. package/src/github/github-auth.ts +235 -33
  202. package/src/github/github-publish.ts +80 -21
  203. package/src/grid/grid-controller.ts +152 -12
  204. package/src/grid/grid-layout.ts +225 -20
  205. package/src/grid/grid-open.ts +120 -0
  206. package/src/grid/grid-panel.ts +554 -39
  207. package/src/grid/grid-source.ts +27 -1
  208. package/src/grid/redirects-grid.ts +599 -0
  209. package/src/grid/redirects.ts +398 -0
  210. package/src/grid/sources/content-source.ts +108 -2
  211. package/src/i18n/i18n-commands.ts +322 -0
  212. package/src/new-project/add-repo-modal.ts +8 -10
  213. package/src/new-project/import-tab.ts +7 -0
  214. package/src/new-project/location-fields.ts +9 -1
  215. package/src/new-project/new-project-modal.ts +221 -245
  216. package/src/packages/jxsuite-update.ts +97 -48
  217. package/src/packages/pull-package-sync.ts +18 -9
  218. package/src/page-params.ts +2 -1
  219. package/src/panels/activity-bar.ts +152 -91
  220. package/src/panels/activity-panel.ts +481 -0
  221. package/src/panels/ai-chat/chat-markdown.ts +8 -3
  222. package/src/panels/ai-chat/chat-view.ts +245 -18
  223. package/src/panels/ai-chat/composer.ts +31 -5
  224. package/src/panels/ai-chat/sessions-view.ts +17 -10
  225. package/src/panels/ai-panel.ts +279 -53
  226. package/src/panels/block-action-bar.ts +1115 -224
  227. package/src/panels/bottom-dock.ts +337 -0
  228. package/src/panels/canvas-dnd-bridge.ts +37 -8
  229. package/src/panels/chat-panel.ts +29 -12
  230. package/src/panels/data-explorer.ts +254 -112
  231. package/src/panels/data-grid.ts +10 -4
  232. package/src/panels/dnd.ts +28 -51
  233. package/src/panels/editors.ts +434 -107
  234. package/src/panels/elements-panel.ts +66 -2
  235. package/src/panels/empty-state.ts +112 -0
  236. package/src/panels/events-panel.ts +596 -82
  237. package/src/panels/formula-workspace.ts +408 -218
  238. package/src/panels/frontmatter-fields.ts +51 -10
  239. package/src/panels/frontmatter-panel.ts +357 -79
  240. package/src/panels/git-panel.ts +375 -164
  241. package/src/panels/head-panel.ts +791 -85
  242. package/src/panels/i18n-panel.ts +592 -0
  243. package/src/panels/imports-panel.ts +95 -85
  244. package/src/panels/jump-bar.ts +584 -0
  245. package/src/panels/layers-panel.ts +1106 -328
  246. package/src/panels/left-panel.ts +109 -204
  247. package/src/panels/navigator-panels.ts +131 -0
  248. package/src/panels/overlays.ts +7 -2
  249. package/src/panels/pane-context.ts +1477 -0
  250. package/src/panels/pane-grid.ts +406 -0
  251. package/src/panels/panel-registry.ts +340 -0
  252. package/src/panels/panel-scheduler.ts +75 -0
  253. package/src/panels/problems-panel.ts +234 -0
  254. package/src/panels/properties-panel.ts +946 -1139
  255. package/src/panels/provenance.ts +258 -0
  256. package/src/panels/quick-search.ts +791 -122
  257. package/src/panels/right-panel.ts +228 -102
  258. package/src/panels/seo-modal.ts +395 -0
  259. package/src/panels/settings-pane.ts +203 -0
  260. package/src/panels/signals-panel.ts +354 -137
  261. package/src/panels/statement-editor.ts +41 -25
  262. package/src/panels/statusbar.ts +342 -106
  263. package/src/panels/style-panel.ts +974 -463
  264. package/src/panels/style-utils.ts +3 -3
  265. package/src/panels/stylebook-doc.ts +4 -2
  266. package/src/panels/stylebook-layers-panel.ts +3 -2
  267. package/src/panels/stylebook-panel.ts +51 -26
  268. package/src/panels/tab-strip.ts +1058 -78
  269. package/src/panels/target-line.ts +274 -0
  270. package/src/panels/toolbar.ts +631 -484
  271. package/src/panels/welcome-screen.ts +301 -198
  272. package/src/platform-errors.ts +26 -3
  273. package/src/platform.ts +96 -2
  274. package/src/platforms/cloud.ts +71 -8
  275. package/src/platforms/devserver.ts +92 -29
  276. package/src/publish/deploy-checklist.ts +383 -0
  277. package/src/publish/pages-service.ts +10 -1
  278. package/src/publish/publish-commands.ts +218 -0
  279. package/src/publish/publish-panel.ts +110 -16
  280. package/src/recent-projects.ts +3 -2
  281. package/src/services/a11y-report.ts +505 -0
  282. package/src/services/ai-models.ts +30 -1
  283. package/src/services/ai-project-tools.ts +29 -10
  284. package/src/services/ai-system-prompt.ts +53 -14
  285. package/src/services/ai-tools.ts +39 -3
  286. package/src/services/ai-writes.ts +154 -0
  287. package/src/services/announce.ts +97 -0
  288. package/src/services/automation.ts +424 -175
  289. package/src/services/cem-export.ts +9 -4
  290. package/src/services/clock.ts +61 -0
  291. package/src/services/document-assistant.ts +36 -8
  292. package/src/services/idle.ts +179 -0
  293. package/src/services/import-client.ts +26 -0
  294. package/src/services/monaco-buffer.ts +627 -0
  295. package/src/services/monaco-lazy.ts +36 -0
  296. package/src/services/notify.ts +271 -0
  297. package/src/services/profile.ts +155 -0
  298. package/src/services/references.ts +0 -0
  299. package/src/services/token-lint.ts +3 -2
  300. package/src/services/tool-executor.ts +53 -7
  301. package/src/services/trusted-types.ts +123 -0
  302. package/src/settings/contexts-section.ts +427 -0
  303. package/src/settings/contributed-section.ts +149 -11
  304. package/src/settings/css-vars-editor.ts +306 -349
  305. package/src/settings/defs-editor.ts +93 -34
  306. package/src/settings/dependencies-editor.ts +7 -7
  307. package/src/settings/extension-sections.ts +37 -5
  308. package/src/settings/general-settings.ts +204 -121
  309. package/src/settings/locales-section.ts +347 -0
  310. package/src/settings/preferences-accounts.ts +140 -0
  311. package/src/settings/preferences-dialog.ts +620 -0
  312. package/src/settings/preferences-keymap.ts +270 -0
  313. package/src/settings/project-sections.ts +260 -0
  314. package/src/settings/section-registry.ts +169 -0
  315. package/src/settings/settings-document.ts +385 -0
  316. package/src/shell.ts +1549 -0
  317. package/src/site-context.ts +45 -20
  318. package/src/state.ts +14 -275
  319. package/src/store.ts +88 -43
  320. package/src/studio.ts +790 -346
  321. package/src/style/live-preview.ts +36 -0
  322. package/src/style/project-styles.ts +349 -0
  323. package/src/style/token-ref.ts +123 -0
  324. package/src/tabs/patch-ops.ts +16 -4
  325. package/src/tabs/project-config.ts +416 -0
  326. package/src/tabs/selection.ts +323 -0
  327. package/src/tabs/tab.ts +182 -47
  328. package/src/tabs/transact.ts +209 -28
  329. package/src/types.ts +68 -13
  330. package/src/ui/ai-credentials-form.ts +39 -35
  331. package/src/ui/ai-managed-connect.ts +7 -1
  332. package/src/ui/dynamic-slot.ts +224 -81
  333. package/src/ui/expression-editor.ts +71 -63
  334. package/src/ui/field-input.ts +4 -6
  335. package/src/ui/field-row.ts +215 -38
  336. package/src/ui/form-controls.ts +194 -7
  337. package/src/ui/layers.ts +492 -69
  338. package/src/ui/media-picker.ts +115 -25
  339. package/src/ui/panel-resize.ts +109 -91
  340. package/src/ui/progress-modal.ts +131 -50
  341. package/src/ui/regions.ts +462 -0
  342. package/src/ui/schema-form.ts +229 -45
  343. package/src/ui/spectrum.ts +24 -8
  344. package/src/ui/timing.ts +49 -0
  345. package/src/ui/value-selector.ts +20 -0
  346. package/src/ui/value-source.ts +348 -0
  347. package/src/ui/virtual-window.ts +400 -0
  348. package/src/utils/edit-display.ts +3 -2
  349. package/src/utils/inherited-style.ts +67 -37
  350. package/src/view.ts +64 -78
  351. package/src/workspace/pane-derive.ts +1258 -0
  352. package/src/workspace/session.ts +317 -0
  353. package/src/workspace/workspace.ts +1345 -23
  354. package/styles/canvas.css +653 -0
  355. package/styles/forced-colors.css +106 -0
  356. package/styles/inspector.css +1454 -0
  357. package/styles/overlays.css +2704 -0
  358. package/styles/panels.css +1701 -0
  359. package/styles/shell.css +1423 -0
  360. package/styles/tokens.css +151 -0
  361. package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
  362. package/dist/chunks/extension-sections-qr3drkkw.js +0 -531
  363. package/dist/chunks/extension-sections-qr3drkkw.js.map +0 -12
  364. package/dist/chunks/files-j8a1t06k.js +0 -50
  365. package/dist/chunks/files-j8a1t06k.js.map +0 -9
  366. package/dist/chunks/git-panel-xtq5z81x.js +0 -28
  367. package/dist/chunks/git-panel-xtq5z81x.js.map +0 -9
  368. package/dist/chunks/layers-panel-ancn2wpq.js +0 -26
  369. package/dist/chunks/layers-panel-ancn2wpq.js.map +0 -9
  370. package/dist/chunks/settings-modal-17ttr96g.js +0 -29
  371. package/dist/chunks/settings-modal-17ttr96g.js.map +0 -9
  372. package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
  373. package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
  374. package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
  375. package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
  376. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
  377. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
  378. package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
  379. package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
  380. package/dist/chunks/studio-0xgs7xrs.js +0 -429
  381. package/dist/chunks/studio-0xgs7xrs.js.map +0 -13
  382. package/dist/chunks/studio-4d8hzcz5.js +0 -3427
  383. package/dist/chunks/studio-4d8hzcz5.js.map +0 -26
  384. package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
  385. package/dist/chunks/studio-9smfzqhc.js +0 -19
  386. package/dist/chunks/studio-9smfzqhc.js.map +0 -10
  387. package/dist/chunks/studio-jm0z592w.js.map +0 -115
  388. package/dist/chunks/studio-m2t4mdg5.js +0 -1854
  389. package/dist/chunks/studio-m2t4mdg5.js.map +0 -18
  390. package/dist/chunks/studio-n4p11dfy.js +0 -853
  391. package/dist/chunks/studio-n4p11dfy.js.map +0 -12
  392. package/dist/chunks/studio-qkvt37c0.js.map +0 -9
  393. package/dist/chunks/studio-sjh1wt1a.js +0 -3744
  394. package/dist/chunks/studio-sjh1wt1a.js.map +0 -22
  395. package/dist/chunks/studio-v7jkjqng.js.map +0 -46
  396. package/dist/chunks/studio-xq0t7n5t.js +0 -140
  397. package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
  398. package/dist/chunks/studio-xze4zrs1.js.map +0 -10
  399. package/dist/chunks/studio-yfcstdzy.js +0 -399
  400. package/dist/chunks/studio-yfcstdzy.js.map +0 -12
  401. package/dist/chunks/studio-zp7jncs8.js +0 -469
  402. package/dist/chunks/studio-zp7jncs8.js.map +0 -14
  403. package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
  404. package/src/browse/browse-modal.ts +0 -69
  405. package/src/browse/browse.ts +0 -904
  406. package/src/canvas/canvas-diff.ts +0 -216
  407. package/src/canvas/nested-site-style.ts +0 -58
  408. package/src/new-project/design-fields.ts +0 -264
  409. package/src/new-project/templates.ts +0 -61
  410. package/src/panels/tab-bar.ts +0 -548
  411. package/src/settings/settings-modal.ts +0 -203
  412. /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
  413. /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
  414. /package/dist/chunks/{format-host-8jxwts2p.js.map → format-host-mkwsmt8d.js.map} +0 -0
  415. /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
  416. /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
  417. /package/dist/chunks/{studio-esrewxap.js.map → studio-s519zc99.js.map} +0 -0
  418. /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
  419. /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
@@ -0,0 +1,32 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/utils/canvas-media.ts", "../src/workspace/pane-derive.ts", "../src/files/media-meta.ts", "../src/ui/media-picker.ts", "../src/panels/data-explorer.ts", "../src/panels/editors.ts", "../src/utils/preview-format.ts", "../src/services/preview-eval.ts", "../src/services/live-preview.ts", "../src/panels/formula-workspace.ts", "../src/ui/color-selector.ts", "../src/panels/style-utils.ts", "../src/ui/unit-selector.ts", "../src/ui/icons.ts", "../src/ui/button-group.ts", "../src/ui/widgets.ts", "../src/panels/style-inputs.ts", "../../../node_modules/lit-html/development/directives/keyed.js", "../src/ui/field-input.ts", "../src/utils/link-target.ts", "../src/panels/properties-panel.ts", "../src/panels/statement-editor.ts", "../src/panels/signals-panel.ts"],
4
+ "sourcesContent": [
5
+ "/// <reference lib=\"dom\" />\n/// <reference lib=\"dom.iterable\" />\n/** Canvas media/breakpoint utilities — pure functions extracted for testability. */\n\nimport { pureSchemeOf } from \"@jxsuite/runtime\";\n\n/**\n * True when a feature query participates in the forced-scheme contract (spec §9.5) — a pure\n * prefers-color-scheme query. These surface as the Auto/Light/Dark control, not generic toggles.\n *\n * @param {string} query\n * @returns {boolean}\n */\nexport function isSchemeQuery(query: string): boolean {\n return pureSchemeOf(query) !== null;\n}\n\n/**\n * The scheme a feature query targets (\"light\" | \"dark\"), or null for non-scheme queries.\n *\n * @param {string} query\n * @returns {\"light\" | \"dark\" | null}\n */\nexport function schemeOfQuery(query: string): \"light\" | \"dark\" | null {\n return pureSchemeOf(query);\n}\n\n/**\n * Classify $media entries into size breakpoints (get a canvas each) and feature queries (rendered\n * as toolbar toggles).\n *\n * @param {Record<string, string> | null | undefined} mediaDef\n * @returns {{\n * sizeBreakpoints: { name: string; query: string; width: number; type: string }[];\n * featureQueries: { name: string; query: string }[];\n * baseWidth: number;\n * }}\n */\nexport function parseMediaEntries(mediaDef?: Record<string, string> | null) {\n if (!mediaDef) {\n return { baseWidth: 320, featureQueries: [], sizeBreakpoints: [] };\n }\n const features = [];\n const sizes = [];\n let baseWidth = 320;\n for (const [name, query] of Object.entries(mediaDef)) {\n if (name === \"--\") {\n const wm = String(query).match(/^(\\d+)\\s*px$/);\n baseWidth = wm ? Number(wm[1]!) : 320;\n continue;\n }\n const minMatch = query.match(/min-width:\\s*([\\d.]+)px/);\n const maxMatch = query.match(/max-width:\\s*([\\d.]+)px/);\n if (minMatch) {\n sizes.push({ name, query, type: \"min\", width: Number(minMatch[1]!) });\n } else if (maxMatch) {\n sizes.push({ name, query, type: \"max\", width: Number(maxMatch[1]!) });\n } else {\n features.push({ name, query });\n }\n }\n sizes.sort((a, b) => (a.type === \"min\" ? a.width - b.width : b.width - a.width));\n return { baseWidth, featureQueries: features, sizeBreakpoints: sizes };\n}\n\n/**\n * Compute which named breakpoints are active at a given canvas width.\n *\n * @param {{ name: string; width: number; type: string }[]} sizeBreakpoints\n * @param {number} canvasWidth\n * @returns {Set<string>}\n */\nexport function activeBreakpointsForWidth(\n sizeBreakpoints: { name: string; width: number; type: string }[],\n canvasWidth: number,\n) {\n const active = new Set<string>();\n for (const bp of sizeBreakpoints) {\n if (bp.type === \"min\" && canvasWidth >= bp.width) {\n active.add(bp.name);\n } else if (bp.type === \"max\" && canvasWidth <= bp.width) {\n active.add(bp.name);\n }\n }\n return active;\n}\n",
6
+ "/**\n * Derived panes (§18.4) — the pane beside this one, showing a projection of it.\n *\n * **Two families, one field.** `Pane.derived` carries either a LENS or a COMPANION, and the\n * distinction is not cosmetic — it is what keeps §14.1 intact:\n *\n * - A **lens** (`code`, `diff`, `breakpoint`) draws the SAME document the source pane owns, in a\n * mode, at a breakpoint or against a diff of its own. It owns no tab at all, so no id maps to two\n * documents and no document takes two ids. `canvas-surface.ts`'s `tabOfPane` takes one hop\n * through `sourcePaneId`, and every pane-scoped renderer in the package starts working on it for\n * free — which is also why the follow costs nothing: switching tabs in the source pane repaints\n * the lens because it is the same reactive read.\n * - A **companion** (`layout`, `component`) shows a DIFFERENT document chosen by a rule from the\n * source. That is an ordinary path-keyed tab this pane owns; the derivation only decides which of\n * its tabs is on screen, which is what activation has always done.\n *\n * §14.1 is therefore SHARPENED rather than amended: **ownership is one-to-one, display is\n * many-to-one.** A tab id appears in at most one pane's `tabOrder`, and every verb that closes,\n * disposes, reorders, pins or MRU-tracks a tab resolves through `paneOfTab` — so it addresses the\n * owner and only the owner. `closeTab`, `detachTab`, `setTabPinned`, `moveTab`, `renameTab`,\n * `rememberClosedTab`, `ensureCollab`, `promoteMru` and `openFileInTab`'s dedupe need no change at\n * all: none of them can see a lens pane, whose `tabOrder` is empty.\n *\n * **What is NOT here, and why.** No derived Tab of any kind — no `derived:code:<path>` id sharing a\n * document, no off-map `Map<paneId, Tab>`. Both mint a second tab LIFETIME: the first costs four\n * exclusion predicates (MRU, reopen-closed, collab keying, close-all counting) that must each be\n * written and tested rather than assumed; the second costs a second disposal path, where one missed\n * `disposeTab` is an `effectScope` reacting to a document forever. Neither is needed once ownership\n * and display are separated.\n */\n\nimport { effect } from \"../reactivity\";\nimport { componentRegistry } from \"../files/components\";\nimport { getNodeAtPath, parentElementPath } from \"../store\";\n\nimport { canvasPerf } from \"../canvas/canvas-perf\";\nimport { canvasModeOfTab, tabOfPane } from \"../canvas/canvas-surface\";\nimport { parseMediaEntries } from \"../utils/canvas-media\";\nimport { getEffectiveLayoutPath, getEffectiveLocales, getEffectiveMedia } from \"../site-context\";\nimport { localeLabel, translationPathFor } from \"@jxsuite/schema/locale\";\nimport { shell } from \"../shell\";\nimport {\n activePane,\n detachTab,\n insertIntoPane,\n paneById,\n promoteTab,\n sidePane,\n workspace,\n} from \"./workspace\";\nimport {\n argsSchema,\n enumArg,\n enumProperty,\n optionalStringArg,\n stringProperty,\n} from \"../commands/command-args\";\n\nimport type { DerivationStatus, Pane, PaneDerivation } from \"./workspace\";\nimport type { AnyCommand } from \"../commands/registry\";\nimport type { Tab } from \"../tabs/tab\";\nimport type { GitDiffState, GitFileStatus } from \"../types\";\nimport type { JxPath } from \"../state\";\n\n/** Every projection `pane.derive` offers, in the order the preset menu lists them. */\nexport const DERIVE_PRESETS = [\n \"code\",\n \"layout\",\n \"component\",\n \"diff\",\n \"breakpoint\",\n \"locale\",\n] as const;\n\nexport type DerivePreset = (typeof DERIVE_PRESETS)[number];\n\n/**\n * The canvas mode a preset needs the SOURCE document to DECLARE, for the presets that need one.\n *\n * `tab.capabilities.modes` is the format's own answer to \"what can this document be shown as\", and\n * the preset menu consulted it nowhere: over a document that declares `[\"settings\", \"stylebook\",\n * \"source\"]` it still offered \"Same page at Base\" — a lens whose stage can only draw an empty\n * artboard — and \"Component definition\", whose rule can never resolve because nothing in a settings\n * form is a component instance. Both produced a pane the author then had to close.\n *\n * Two presets are absent, for two different reasons. `diff` needs no mode: a comparison is two\n * texts and every document has those, and it is already gated on the file having changes. `layout`\n * is gated on the layout RESOLVING, which {@link presetRefusal} checks directly.\n *\n * **That second gate is NOT a mode check in disguise, and a comment here said it was** — \"a\n * document with no design board has no layout either\". It is false: `getEffectiveLayoutPath` falls\n * back to `projectConfig.defaults.layout`, which every starter sets, so a document declaring\n * `[\"stylebook\", \"source\"]` resolves the project's layout and IS offered the row. That is a\n * deliberate answer rather than an oversight — the companion opens a real layout document the\n * author can edit, unlike the empty artboard `breakpoint` would draw or the rule `component` could\n * never resolve — but it is a fact about the project's default, not about this document, so it is\n * pinned by a test (`per-preset refusals` · \"Layout's gate is the layout RESOLVING\") instead of\n * being asserted here in prose.\n */\nconst MODE_FOR_PRESET: Readonly<Partial<Record<DerivePreset, string>>> = {\n breakpoint: \"design\",\n code: \"source\",\n component: \"design\",\n};\n\n/** How a mode is spelled in a refusal — the words on the Editor axis, not the internal ids. */\nconst MODE_WORDS: Readonly<Record<string, string>> = { design: \"Design\", source: \"Code\" };\n\n/** Said by a diff lens whose comparison came back empty. One sentence, one home. */\nconst DIFF_UNREADABLE = \"Could not read this file's comparison against HEAD.\";\n\n/** What the derivation commands and the follow need from the rest of Studio. */\nexport interface DerivationDeps {\n /**\n * `files/files.ts`'s `openFileInPane` — read a document from disk and show it in a named pane,\n * browsing rather than committing and leaving the keyboard where it is.\n *\n * Injected rather than imported so this module owns no I/O and no test has to stand up a platform\n * to prove the follow memoises.\n */\n openFileInPane: (paneId: string, path: string) => void | Promise<void>;\n /**\n * Read one file's comparison against HEAD — `gitShow(HEAD)` plus the working copy.\n *\n * **The diff lens has to load its own, and that is the whole of finding 4.** It used to snapshot\n * `shell.git.diffState`: an app-level slot written only when the author clicks a file IN THE GIT\n * PANEL, carrying THAT file's path and never re-read. So the preset was refused for a page that\n * genuinely has changes, and when it was offered it could render a comparison of an unrelated\n * file under a label promising this pane's document. A lens draws the source pane's document or\n * it is not a lens.\n *\n * Resolves to `null` when the comparison cannot be produced; the pane says so rather than drawing\n * somebody else's file.\n */\n loadDiff: (path: string, fileStatus: string) => Promise<GitDiffState | null>;\n /**\n * Is there a file at this project-relative path? The locale companion's one question.\n *\n * Injected for the reason {@link openFileInPane} is, and asked at all for a sharper one:\n * {@link companionTarget} is pure and synchronous, so it cannot stat anything — and a companion\n * that answers with the path a translation WOULD have hands `openFileInPane` a file that is not\n * there, which fails into a blank pane under a chip naming a language. The pane has to be able to\n * say \"there is no French copy of this yet\", and only a read of the disk can tell it that.\n */\n fileExists: (path: string) => Promise<boolean>;\n}\n\n/**\n * A dependency set that does nothing — for callers that read DECLARATIONS rather than run verbs.\n *\n * The sibling of `commands/defaults.ts`'s `noopCommandDeps()`, and here for the same reason: the\n * command-level check, the chrome budget and the generated keyboard sheet all build the whole\n * command set to inspect its records, and every one of them would otherwise hand-write a stub for a\n * verb it will never call. One stub, named, beside the interface it satisfies.\n *\n * @returns {DerivationDeps}\n */\nexport function noopDerivationDeps(): DerivationDeps {\n return {\n fileExists: () => Promise.resolve(false),\n loadDiff: () => Promise.resolve(null),\n openFileInPane: () => {},\n };\n}\n\n/** The label each preset takes in the menu and in the derived pane's own strip chip. */\nexport const PRESET_LABELS: Readonly<Record<DerivePreset, string>> = {\n breakpoint: \"Same page at\",\n code: \"Code\",\n component: \"Component definition\",\n diff: \"Diff vs HEAD\",\n layout: \"Layout\",\n /* An UNFINISHED sentence, like `breakpoint`'s, because the row and the chip both finish it with\n the locale's own autonym — \"Same page in français\". Jx has no message catalogue (§13.3): a\n translation is a different file in a different directory, so this preset opens that file\n rather than re-rendering this one, and the label says \"the same page\" about the document\n rather than about the text on screen. */\n locale: \"Same page in\",\n};\n\n// ─── Reading ──────────────────────────────────────────────────────────────────\n\n/**\n * The derivation a pane is drawing under, or null.\n *\n * Re-exported from `canvas/canvas-surface.ts`, which is where the pane-scoped RENDERERS already\n * resolve everything else and which this module imports from. One name, one answer.\n */\nexport { derivationOfPane } from \"../canvas/canvas-surface\";\n\n/** What a derived pane SHOULD be showing right now. The pure half of the follow. */\nexport interface DerivedTarget {\n kind: \"lens\" | \"companion\";\n /** Lens: the canvas mode this pane draws in. Null for a companion. */\n mode: string | null;\n /** Lens (`breakpoint`): the media name, null for base. */\n media: string | null;\n /** Companion: the path this pane should show, or null to HOLD the one it has. */\n path: string | null;\n /**\n * Lens (`diff`): the document whose comparison this pane must still LOAD, or null when it has the\n * right one. The impure half acts on it; resolving it stays a read.\n */\n diffPath: string | null;\n /**\n * Companion (`locale`): the translation whose EXISTENCE this pane must still establish, or null\n * when the answer is already in hand. {@link diffPath}'s companion twin, and for the same reason —\n * the resolver decides WHAT to ask, {@link probeTranslationFor} asks it, and neither answer\n * carries a `probePath`, so the follow cannot re-enter.\n */\n probePath: string | null;\n /**\n * Companion (`layout`): the node to select once the document is on screen, or null.\n *\n * The deleted `openLayoutAtNode` existed precisely because \"Open Layout →\" dropped the author\n * into a layout file with nothing selected and left them to find the header again by eye. The\n * derivation carries it now — which is what `panels/properties-panel.ts`'s ledger entry claimed\n * for a release while nothing read `layoutPath` at all.\n */\n select: JxPath | null;\n status: DerivationStatus;\n /** Printed by the pane when `status` is `unavailable`. Empty otherwise. */\n reason: string;\n}\n\n/**\n * Resolve what `paneId` should be showing, from its derivation and its source pane.\n *\n * **Pure**: it reads state and returns an answer, writes nothing, and schedules nothing. That is\n * what makes the follow testable with no rAF, no platform and no canvas — the whole of the\n * derivation's decision-making is one function returning a value.\n *\n * \"State\" includes {@link _diffLoads}, which is module-scoped rather than on the derivation — a\n * read, and still no write. A comparison that came back empty has to be REMEMBERED somewhere the\n * resolver can see, because a terminal answer written straight onto `derived.status` is overwritten\n * by the next frame's resolve, and the pane then says \"Loading…\" forever while asking for nothing.\n *\n * @param {string} paneId\n * @returns {DerivedTarget | null} Null when this pane is not derived.\n */\nexport function derivedTarget(paneId: string): DerivedTarget | null {\n const derived = paneById(paneId)?.derived;\n if (!derived) {\n return null;\n }\n const source = tabOfPane(derived.sourcePaneId);\n if (!source) {\n return {\n diffPath: null,\n kind: derived.kind,\n media: null,\n mode: null,\n path: null,\n probePath: null,\n reason: \"The pane this one follows has no document open.\",\n select: null,\n status: \"unavailable\",\n };\n }\n if (derived.kind === \"lens\") {\n return lensTarget(paneId, derived, source);\n }\n return companionTarget(paneId, derived, source);\n}\n\n/** A lens's target: a mode, and for `breakpoint` a media the source document actually declares. */\nfunction lensTarget(\n paneId: string,\n derived: Extract<PaneDerivation, { kind: \"lens\" }>,\n source: Tab,\n): DerivedTarget {\n const base = {\n diffPath: null,\n kind: \"lens\" as const,\n media: derived.media,\n mode: derived.mode,\n path: null,\n probePath: null,\n select: null,\n };\n if (derived.preset === \"diff\") {\n /* THE SOURCE PANE'S DOCUMENT, resolved every time rather than snapshotted once. This branch\n used to read `derived.diff === null`, a copy of `shell.git.diffState` taken when the lens\n was made — so the lens went on rendering whatever file the Git panel had last opened, and\n switching the source tab changed nothing at all. */\n const path = source.documentPath;\n if (!gitChangeFor(path)) {\n return {\n ...base,\n reason: \"Nothing to compare — this file matches HEAD.\",\n status: \"unavailable\",\n };\n }\n if (derived.diff?.filePath === path) {\n return { ...base, reason: \"\", status: \"ready\" };\n }\n /* A read that came back EMPTY is an answer, and it has to survive the next frame. The failure\n used to be written straight onto `derived.status`, where the follow's very next resolve\n overwrote it with `loading` — so a lens whose comparison could not be read said \"Loading\n this file's changes…\" for the rest of the session while asking for nothing. `_diffLoads`\n remembers per pane which path was asked and how it went, and the answer is composed here\n with every other one. */\n if (_diffLoads.get(paneId)?.failed && _diffLoads.get(paneId)?.path === path) {\n return { ...base, reason: DIFF_UNREADABLE, status: \"unavailable\" };\n }\n return { ...base, diffPath: path, reason: \"\", status: \"loading\" };\n }\n if (derived.preset === \"code\" && canvasModeOfTab(source) === \"source\") {\n /* TWO MONACO MODELS ON ONE URI, refused for as long as the state lasts rather than once at\n creation. `presetRefusal` decides whether a Code lens can be MADE; nothing decided whether\n it could still be drawn, and one click on the source pane's Editor axis put both panes in\n Code over the same file. Real Monaco throws `Cannot create model because a model with the\n same URI already exists` inside the floating `void mountSourceEditor(…)` in\n `canvas/canvas-render.ts` — an unhandled rejection and a blank Code pane. Unreachable before\n derived panes, because one pane could show one document once. */\n return {\n ...base,\n reason: \"The pane this one follows is showing Code — one document has one editor.\",\n status: \"unavailable\",\n };\n }\n if (derived.preset === \"breakpoint\" && !declaredMedia(source).includes(derived.media)) {\n return {\n ...base,\n reason: `This document does not declare a \"${derived.media ?? \"base\"}\" breakpoint.`,\n status: \"unavailable\",\n };\n }\n return { ...base, reason: \"\", status: \"ready\" };\n}\n\n/**\n * The source-control entry for `path`, when it has changes a comparison can be built from.\n *\n * `M` and `A` and nothing else — the same two `panels/git-panel.ts` opens a diff for, because an\n * untracked or deleted file has no pair of texts to put side by side. `shell.git.status` is the\n * project's whole answer to \"what has changed\", so a diff lens can be offered for a page the author\n * has never clicked in the Git panel, which is the common case and was the refused one.\n *\n * A `null` path needs no guard of its own: no entry in `files` has a null path, so the search\n * simply finds nothing, and a guard whose true branch returns what the false branch already returns\n * is a branch no test can distinguish.\n *\n * @param {string | null} path\n * @returns {GitFileStatus | null}\n */\nfunction gitChangeFor(path: string | null): GitFileStatus | null {\n return (\n shell.git.status?.files.find(\n (file) => file.path === path && (file.status === \"M\" || file.status === \"A\"),\n ) ?? null\n );\n}\n\n/**\n * A companion's target: the path the rule resolves to, or `null` to HOLD.\n *\n * **`null` is a hold, not a change**, and that is the difference between a usable following pane\n * and one nobody leaves open. Clicking a paragraph outside any component resolves to no definition;\n * blanking the pane on that click makes it flicker between a document and an empty state as the\n * author works, and this is the preset somebody leaves open all day.\n *\n * **A hold is only honest where the next gesture could answer differently.** `component` holds\n * because the author's next click may land inside one. `locale` does not: a document with no copy\n * in that language has no copy in it until somebody writes one, and a pane silently holding the\n * previous document under a chip saying \"Same page in français\" is a lie the author cannot see\n * through. That answer is `unavailable` with the sentence, which is what makes creating the\n * translation the obvious next move rather than a guess.\n */\nfunction companionTarget(\n paneId: string,\n derived: Extract<PaneDerivation, { kind: \"companion\" }>,\n source: Tab,\n): DerivedTarget {\n const base = { diffPath: null, kind: \"companion\" as const, media: null, mode: null };\n if (derived.preset === \"layout\") {\n /* THE FILE THE CLICKED CHROME CAME FROM, when there is one.\n `shell.layoutSelection` is a `LayoutHit`: the layout document the canvas hit test resolved\n and the node's path INSIDE it. Resolving the page's own `$layout` instead is a different\n answer for a nested chain — click a header contributed by `layouts/marketing.json`, which\n `layouts/base.json` wraps, and the page's `$layout` names the wrong one of the two. It is\n also the only thing that carries the SELECTION, which is what \"Open Layout →\" is for. The\n hit is transient — `iframe-host.ts` clears it the moment the author clicks page content —\n so the page's own layout remains the answer for a derivation created from the preset menu. */\n const hit = shell.layoutSelection;\n const path =\n hit?.layoutFile ??\n getEffectiveLayoutPath(source.doc.document.$layout as string | false | undefined);\n return path === null\n ? {\n ...base,\n path: null,\n probePath: null,\n reason: \"This page has no layout.\",\n select: null,\n status: \"unavailable\",\n }\n : {\n ...base,\n path,\n probePath: null,\n reason: \"\",\n /* A SELECTION only when a click produced one. `path` IS `hit.layoutFile` whenever there\n is a hit — the line above says so — so a second `hit.layoutFile === path` guard here\n was a condition with no false branch, and an unreachable branch is a claim nobody can\n check. What stops a node path from layout A landing inside layout B is\n {@link selectInPane}, which compares against the document actually on screen. */\n select: hit ? (hit.layoutPath as JxPath) : null,\n status: \"ready\",\n };\n }\n if (derived.preset === \"locale\") {\n /* WHERE THE TRANSLATION WOULD LIVE, which is a different question from whether it is there.\n `translationPathFor` is the same string math the build runs, so the path this resolves to is\n the path the site would serve; it answers null for a document no locale can address at all —\n a layout, a component, a file at the project root — and for a tag the project stopped\n declaring, which is the case {@link presetRefusal} cannot catch because it runs once. */\n const i18n = getEffectiveLocales();\n const wanted =\n source.documentPath === null || derived.locale === null\n ? null\n : translationPathFor(source.documentPath, derived.locale, i18n);\n if (wanted === null) {\n return {\n ...base,\n path: null,\n probePath: null,\n reason: \"This document has no path in that locale.\",\n select: null,\n status: \"unavailable\",\n };\n }\n /* AND WHETHER IT IS THERE, which this function cannot ask: it is pure and synchronous, and\n handing back a path for a file that does not exist makes `openFileInPane` fail into a blank\n pane — §18.4's last paragraph refuses exactly that. {@link _localeProbes} is the same shape\n {@link _diffLoads} is, for the same reason: a terminal answer written onto `derived.status`\n is overwritten by the next frame's resolve, so the pane would say \"Loading…\" forever about a\n file nobody is reading. */\n const probe = _localeProbes.get(paneId);\n if (probe?.path !== wanted || probe.exists === null) {\n return {\n ...base,\n path: null,\n probePath: wanted,\n reason: \"\",\n select: null,\n status: \"loading\",\n };\n }\n if (!probe.exists) {\n return {\n ...base,\n path: null,\n probePath: null,\n reason:\n `No ${localeLabel(derived.locale)} copy of this document yet — ` +\n \"the Languages panel can create one.\",\n select: null,\n status: \"unavailable\",\n };\n }\n return { ...base, path: wanted, probePath: null, reason: \"\", select: null, status: \"ready\" };\n }\n const path = componentPathUnderSelection(source);\n if (path === null) {\n return derived.resolved === null\n ? {\n ...base,\n path: null,\n probePath: null,\n reason: \"Select an element inside a component to see its definition.\",\n select: null,\n status: \"unavailable\",\n }\n : { ...base, path: null, probePath: null, reason: \"\", select: null, status: \"ready\" };\n }\n return { ...base, path, probePath: null, reason: \"\", select: null, status: \"ready\" };\n}\n\n/** Every size breakpoint a document declares, plus `null` for base. */\nexport function declaredMedia(tab: Tab): (string | null)[] {\n const { sizeBreakpoints } = parseMediaEntries(getEffectiveMedia(tab.doc.document.$media));\n return [null, ...sizeBreakpoints.map((bp) => bp.name)];\n}\n\n/* There is no `rawDocOf`. It read the document through `toRaw` under a docstring explaining that\n traversing the reactive proxy would make every node the walk touches a dependency — true of a\n read INSIDE an effect, and none of these are. **Tracking is a property of where a read happens,\n not of which object it happens on**: {@link derivedTarget} and {@link presetRefusal} are reached\n from `queueRetarget`'s rAF, from `loadDiffFor`'s `.then`, from a command's `run` and from\n `panels/pane-context.ts`'s click handler, and there is no active effect at any of those. So the\n `toRaw` bought nothing that being outside an effect had not already bought, and no state the app\n can reach could tell it from its absence. What the resolvers DO read is declared by\n {@link installDerivationEffects}, which is the only place a read of theirs is ever observed. */\n\n/**\n * The component definition the selection sits inside, or null.\n *\n * Walks UP from the selected node, because the author clicks the paragraph and means the card. That\n * is also what makes the memo work: twenty clicks inside one `<my-card>` all resolve to the same\n * definition, so `applyDerivation` does nothing at all — no render, no host post, no file read.\n *\n * @param {Tab | null} tab\n * @returns {string | null}\n */\nexport function componentPathUnderSelection(tab: Tab | null): string | null {\n const [selected] = tab?.session.selection ?? [];\n if (!tab || !selected) {\n return null;\n }\n const doc = tab.doc.document;\n let path: JxPath | null = [...selected];\n while (path) {\n const node = getNodeAtPath(doc, path);\n const entry = node\n ? componentRegistry.find((candidate) => candidate.tagName === node.tagName)\n : null;\n if (entry?.path) {\n return entry.path;\n }\n path = parentElementPath(path) as JxPath | null;\n }\n return null;\n}\n\n// ─── Writing ─────────────────────────────────────────────────────────────────\n\n/**\n * Make `paneId` a derived pane. The one writer of `Pane.derived`, with {@link clearPaneDerivation}.\n *\n * Refuses a derivation naming a pane that is not in the grid, or naming this pane — invariant D1,\n * asserted and never repaired: a self-derivation is an infinite `tabOfPane` hop, and a dangling\n * `sourcePaneId` is a stage drawing a document that has no pane.\n *\n * @param {string} paneId\n * @param {PaneDerivation} derivation\n */\nexport function setPaneDerivation(paneId: string, derivation: PaneDerivation): void {\n if (derivation.sourcePaneId === paneId || !paneById(derivation.sourcePaneId)) {\n throw new RangeError(\n `pane \"${paneId}\" cannot derive from \"${derivation.sourcePaneId}\" — a derivation names ` +\n `another pane that is in the grid`,\n );\n }\n writeDerivation(paneId, derivation);\n}\n\n/**\n * Write `pane.derived` and forget the answers the previous one had in hand — its comparison and its\n * translation probe alike. **The only writer, both ways.**\n *\n * A new derivation is a new question, so the previous one's answer is not an answer to it — and a\n * pane that has stopped deriving has no question at all. That was two `_diffLoads.delete` calls\n * under a comment reading \"both writers forget it; nothing else may\", which is an invariant stated\n * twice and enforced in neither place: only one of the two could be reached by a test, so inverting\n * the other was a mutation the whole suite could not see. One line, one call site each.\n *\n * `workspace.ts` writes `pane.derived = null` twice more — {@link receivingPane} and `closePane`'s\n * D4 — and deliberately does not route through here: those are grid facts, this module imports from\n * that one, and a pane can only derive AGAIN through {@link setPaneDerivation}, which forgets.\n */\nfunction writeDerivation(paneId: string, derivation: PaneDerivation | null): void {\n const pane = paneById(paneId);\n if (pane) {\n _diffLoads.delete(paneId);\n _localeProbes.delete(paneId);\n pane.derived = derivation;\n }\n}\n\n/**\n * Stop deriving. The pane keeps whatever tabs it owns — a companion's document stays open, which is\n * exactly what Pin means — and a lens, owning none, becomes an empty pane its next collapse\n * removes.\n *\n * @param {string} paneId\n */\nexport function clearPaneDerivation(paneId: string): void {\n writeDerivation(paneId, null);\n}\n\n/**\n * Bring `paneId` into line with {@link derivedTarget}. Idempotent, and safe to run every frame.\n *\n * The only impure half of the follow, and it does exactly two things: it records the status the\n * pane draws, and — for a companion whose answer has CHANGED — it re-points the pane at the new\n * document. The memo is on `resolved`, the answer, not on the selection that produced it.\n *\n * @param {string} paneId\n * @param {DerivationDeps} deps\n */\nexport function applyDerivation(paneId: string, deps: DerivationDeps): void {\n const pane = paneById(paneId);\n const derived = pane?.derived;\n const target = derivedTarget(paneId);\n if (!pane || !derived || !target) {\n return;\n }\n canvasPerf.derivedResolves += 1;\n derived.status = target.status;\n derived.reason = target.reason;\n if (derived.kind === \"lens\") {\n /* Invariant D2, enforced rather than assumed: a lens owns NO tab. Anything sitting in its\n strip when the lens was created has already been handed back to the source pane by\n `pane.derive`; this is the belt to those braces, and it is what keeps `paneOfTab` — which\n every destructive tab verb resolves through — unable to name a lens pane at all.\n The tabs MOVE rather than being dropped: a detach with no insert would leave a live tab in\n `workspace.tabs` that no pane holds, which is a document nobody can reach and nobody can\n close. Nothing a derivation does may lose a document. */\n const source = paneById(derived.sourcePaneId);\n if (pane.tabOrder.length > 0 || pane.activeTabId !== null) {\n const owned = [...pane.tabOrder];\n for (const tabId of owned) {\n detachTab(tabId);\n if (source) {\n insertIntoPane(source, tabId);\n }\n }\n pane.activeTabId = null;\n }\n /* A DIFF LENS HOLDS A COMPARISON ONLY WHILE IT IS THE SOURCE DOCUMENT'S, and nothing enforced\n that. `derivedTarget` says `ready` for exactly the case where the one in hand is the right\n one; every other answer — the wrong file in hand after a tab switch, a source document with\n no changes, no source document at all — means the pane is holding somebody else's, and\n `canvas/canvas-render.ts` draws whatever is in this field rather than the notice beside it.\n Clearing it is what makes that file's `if (!gitDiffState)` fire. The previous release\n shipped a comment claiming this was fixed and no line that did it. */\n if (derived.preset === \"diff\" && target.status !== \"ready\") {\n derived.diff = null;\n }\n loadDiffFor(paneId, target, deps);\n return;\n }\n /* FIRST, unlike {@link loadDiffFor}, which is the last thing the lens half does. A probe that has\n not answered yet resolves to `path: null` — the hold — and the hold returns two statements\n below, so a call at the end of this function would never be reached by the one target that\n needs it. */\n probeTranslationFor(paneId, target, deps);\n /* THE MEMO IS ABOUT WHAT IS ON SCREEN, so it cannot outlive the document being on screen.\n A resolved companion owns a real tab, so `panels/tab-strip.ts` draws a real chip with a real\n ✕ — and closing it left the pane holding a derivation whose `resolved` still named the file\n that had just gone. `paneIsEmpty` counts the derivation as a subject so the pane stayed; the\n strip fell back to the derivation chip; and the stage said \"Looking for something to show\n here…\" for the rest of the session, because every following frame found `target.path ===\n derived.resolved` and did nothing. Forgetting the answer when the pane is showing nothing is\n what lets the next frame ask the question again. */\n if (derived.resolved !== null && tabOfPane(paneId) === null) {\n derived.resolved = null;\n }\n if (target.path === null || target.path === derived.resolved) {\n // Same document, possibly a different node inside it — clicking a second piece of layout chrome\n // Moves the selection without re-reading the file.\n selectInPane(paneId, target);\n return;\n }\n derived.resolved = target.path;\n canvasPerf.derivedRetargets += 1;\n const opening = deps.openFileInPane(paneId, target.path);\n if (target.select === null) {\n return;\n }\n /* The selection lands AFTER the open, because there is no tab to select in until then. Awaiting\n rather than firing both is what makes \"Open Layout →\" arrive at the node the author clicked\n instead of at the top of a file they now have to search. */\n void Promise.resolve(opening).then(() => {\n selectInPane(paneId, target);\n });\n}\n\n/**\n * Select `target.select` in whatever `paneId` is showing, when that is the document it is about.\n *\n * Idempotent, and it has to be: {@link applyDerivation} runs every frame the follow fires, and a\n * `session.selection` write is a reactive write that repaints the Inspector, the overlays and the\n * block bar. Comparing first is what keeps a following pane free.\n */\nfunction selectInPane(paneId: string, target: DerivedTarget): void {\n const wanted = target.select;\n const tab = tabOfPane(paneId);\n if (!wanted || !tab || (target.path !== null && tab.documentPath !== target.path)) {\n return;\n }\n const [current] = tab.session.selection;\n if (current?.length === wanted.length && current.every((seg, i) => seg === wanted[i])) {\n return;\n }\n tab.session.selection = [[...wanted]];\n}\n\n/**\n * The comparison each diff lens has ASKED for, and how that went.\n *\n * Never cleared on COMPLETION, only when the wanted path changes, so the follow's next frame cannot\n * re-issue a failing request forever. `failed` is the half that was missing: the status\n * `loadDiffFor` wrote when the read came back empty was overwritten by the very next resolve, and\n * the pane went back to saying \"Loading this file's changes…\" permanently. A terminal answer has to\n * live where {@link lensTarget} — which composes every other answer — can see it.\n */\nconst _diffLoads = new Map<string, { path: string; failed: boolean }>();\n\n/**\n * Fetch the comparison a diff lens is missing, once.\n *\n * @param {string} paneId\n * @param {DerivedTarget} target\n * @param {DerivationDeps} deps\n */\nfunction loadDiffFor(paneId: string, target: DerivedTarget, deps: DerivationDeps): void {\n const path = target.diffPath;\n const change = gitChangeFor(path);\n if (path === null || !change || _diffLoads.get(paneId)?.path === path) {\n return;\n }\n _diffLoads.set(paneId, { failed: false, path });\n deps\n .loadDiff(path, change.status)\n .then((state) => {\n const live = paneById(paneId)?.derived;\n if (\n live?.kind !== \"lens\" ||\n live.preset !== \"diff\" ||\n _diffLoads.get(paneId)?.path !== path\n ) {\n return;\n }\n if (state) {\n live.diff = state;\n } else {\n _diffLoads.set(paneId, { failed: true, path });\n }\n /* Re-resolve rather than writing a status here: `ready` with the comparison in hand,\n `unavailable` with {@link DIFF_UNREADABLE} when the read came back empty — composed in the\n one function that composes every other answer, so the next frame agrees with this one. It\n cannot re-enter, because neither of those answers carries a `diffPath`. */\n applyDerivation(paneId, deps);\n })\n .catch((error: unknown) => {\n console.error(\"loadDiff error:\", error);\n });\n}\n\n/**\n * Which translation each locale companion has ASKED about, and whether it is there.\n *\n * {@link _diffLoads}'s twin, and cleared by the same writer for the same reason. `exists` is\n * THREE-valued on purpose: `null` is \"asked, no answer yet\", which is the state the pane draws\n * \"Loading…\" for, and it cannot be folded into `false` — `false` is a terminal answer with a\n * sentence naming the language and offering to create the file, and showing that sentence for the\n * frame between the question and the answer would tell the author their translation is missing\n * every time they open the pane.\n */\nconst _localeProbes = new Map<string, { path: string; exists: boolean | null }>();\n\n/**\n * Ask whether the translation a locale companion wants is on disk, once per wanted path.\n *\n * @param {string} paneId\n * @param {DerivedTarget} target\n * @param {DerivationDeps} deps\n */\nfunction probeTranslationFor(paneId: string, target: DerivedTarget, deps: DerivationDeps): void {\n const path = target.probePath;\n if (path === null || _localeProbes.get(paneId)?.path === path) {\n return;\n }\n _localeProbes.set(paneId, { exists: null, path });\n deps\n .fileExists(path)\n .then((exists) => {\n const live = paneById(paneId)?.derived;\n /* THE ANSWER TO THE QUESTION THAT IS STILL BEING ASKED. A read issued for `fr` that lands\n after the author retargeted the pane at `de` would otherwise write `de`'s memo with `fr`'s\n answer — the same late-landing hazard {@link loadDiffFor} carries, and the same guard. */\n if (\n live?.kind !== \"companion\" ||\n live.preset !== \"locale\" ||\n _localeProbes.get(paneId)?.path !== path\n ) {\n return;\n }\n _localeProbes.set(paneId, { exists, path });\n /* Re-resolve rather than writing a status here, for {@link loadDiffFor}'s reason: both\n answers are composed by {@link companionTarget} beside every other one, and neither of\n them carries a `probePath`, so this cannot re-enter. */\n applyDerivation(paneId, deps);\n })\n .catch((error: unknown) => {\n console.error(\"fileExists error:\", error);\n });\n}\n\n// ─── The follow ───────────────────────────────────────────────────────────────\n\n/** One pending retarget per pane. A shared id would let one pane swallow the other's frame. */\nconst _retargetRafIds = new Map<string, number>();\n\n/**\n * Run `applyDerivation` on the next frame, once per pane however many times it is asked.\n *\n * **Scheduled, never synchronous.** The effect below reads `workspace.panes`, and a retarget writes\n * `pane.tabOrder` through `openFileInPane` — an effect that triggers itself, which is the hazard\n * `panels/pane-grid.ts` names at its own reconciler. The rAF hop is the same shape\n * `scheduleCanvasRender` uses, for the same reason.\n */\nfunction queueRetarget(paneId: string, deps: DerivationDeps): void {\n if (_retargetRafIds.has(paneId)) {\n return;\n }\n _retargetRafIds.set(\n paneId,\n requestAnimationFrame(() => {\n _retargetRafIds.delete(paneId);\n try {\n applyDerivation(paneId, deps);\n } catch (error) {\n console.error(\"applyDerivation error:\", error);\n }\n }),\n );\n}\n\n/**\n * Subscribe ONE pane's follow. Called from `studio.ts`'s per-pane effect scope, so it is stopped\n * when the pane leaves the grid.\n *\n * **Most of the follow is STRUCTURAL, and that is still the design.** `tabOfPane(paneId)` reads the\n * source pane's `activeTabId`, so the render effects already installed for this pane track it and\n * repaint when the source pane switches document.\n *\n * **Every derivation subscribes, and this effect is where.** No preset \"follows structurally and\n * declares nothing\": the body below reads THIS pane's `activeTabId` and `tabOfPane(sourcePaneId)`\n * unconditionally, whatever the preset — `diff` and `breakpoint` are the two that add nothing on\n * top. An input a resolver consults and the effect does not observe is an answer nobody asks for:\n * this docstring claimed the `$layout` subscription for a release while the effect did not have it,\n * the Code lens's refusal against a source pane showing Code arrived the same way, and so did\n * {@link applyDerivation}'s memo-forget, whose comment described closing a companion's document\n * while nothing re-ran the follow when it closed.\n *\n * The list is BY INPUT rather than by preset, because `layout` declares two of them. Every input is\n * a HUMAN GESTURE rather than a keystroke — closing a tab in this pane, switching the source pane's\n * document, a layout click, a selection, a click on the Editor axis — except the page's own\n * `$layout`, whose per-transaction cost is stated at the read itself. `layout` follows the layout\n * HIT and `$layout`; `component` is the only preset that observes the SELECTION, and it memoises on\n * its answer; `code` observes the source pane's canvas mode, because the refusal that keeps two\n * Monaco models off one URI is a standing answer about a value one click changes.\n *\n * Each of those claims is a test rather than a sentence — see `pane-derive.test.ts`'s \"the follow\n * NOTICES the close\", \"a companion re-resolves when the SOURCE pane switches document\", \"the layout\n * follow OBSERVES the hit\", \"changing the page's layout MOVES the companion\", \"clicking into a\n * component RE-POINTS the pane\" and \"a Code lens notices the source pane switching to Code\".\n *\n * @param {string} paneId\n * @param {DerivationDeps} deps\n */\nexport function installDerivationEffects(paneId: string, deps: DerivationDeps): void {\n effect(() => {\n const pane = paneById(paneId);\n const derived = pane?.derived;\n if (!derived) {\n return;\n }\n /* THIS PANE'S OWN TAB, for both kinds, and its absence is the interesting value.\n `applyDerivation` forgets a companion's memo when the pane is showing nothing, so the next\n frame asks the question again — and there was no next frame. The tracked inputs were the\n SOURCE pane's tab and the selection, neither of which a `closeTab` in the following pane\n touches, so closing the document a layout companion had opened left the pane stranded behind\n a memo naming a file that was gone: the exact failure that comment describes, with the fix\n one call away from ever running. A lens reads it too, for one line's worth of the same\n reason: invariant D2 says a lens owns no tab, `applyDerivation` hands one back if it finds\n one, and an insertion nothing observes is an insertion nothing repairs.\n It costs one resolve per open or close in this pane — a gesture, not a keystroke — and no\n retarget, because the answer the memo compares against has not changed. */\n void pane.activeTabId;\n /* The rest of the tracked inputs, and only these: which tab the source pane is showing, and —\n for the presets that observe them — that tab's selection, editor kind and `$layout`. What\n the RESOLVERS read is not among them, because they run in `queueRetarget`'s rAF where no\n effect is active: an untracked read is untracked because of WHERE it happens. So typing,\n which replaces `tab.doc.document`, re-runs this effect only for the one preset that reads\n that field HERE. */\n const source = tabOfPane(derived.sourcePaneId);\n if (derived.kind === \"lens\" && derived.preset === \"code\") {\n /* The SOURCE pane's editor kind, and only this preset reads it. {@link lensTarget} refuses a\n Code lens for as long as the pane it follows is ALSO showing Code — two Monaco models on\n one URI — and that is a standing answer about a value one click on the Editor axis\n changes. Untracked, the refusal would be computed only on some later frame that\n re-resolved for another reason, and until then the stage mounts the second model, which is\n the throw the refusal exists to prevent. One human gesture per change, like the layout\n hit; nothing per keystroke. */\n void source?.session.ui.canvasMode;\n }\n if (derived.kind === \"companion\" && derived.preset === \"component\") {\n void source?.session.selection;\n }\n /* `locale` ADDS NOTHING, and the omission is the honest answer rather than a gap. The two\n inputs above — this pane's own tab and the source pane's — are exactly what it reads: the\n locale is fixed on the derivation, and the file it wants is a function of the source\n document's path. Its third input, the project's declared locales, CANNOT be tracked:\n `projectState` is a plain `let` (`store/state.ts`) that `setProjectState` replaces whole, so\n no effect anywhere observes it. Adding a locale in Project Settings therefore does not\n re-run this follow; the next retarget — any tab switch in either pane — picks it up, and\n {@link companionTarget} re-reads the list every time it resolves, so the pane cannot go on\n showing a locale the project has stopped declaring. A `void` read of a non-reactive value\n would look like a subscription and be none, which is the shape the `layout` preset shipped\n a release of. */\n if (derived.kind === \"companion\" && derived.preset === \"layout\") {\n /* The LAYOUT hit, which is what \"Open Layout →\" is a follow of. It changes only when the\n author clicks layout chrome (`iframe-host.ts` writes it) or clicks page content (which\n clears it) — a human gesture, not a keystroke — so it costs nothing to observe and it is\n the difference between a following layout pane and one frozen on the first header. */\n void shell.layoutSelection;\n /* AND the page's own `$layout`, which is the answer whenever there is no hit. The docstring\n above claimed this preset followed it while the effect did not read it at all: the\n resolver's read happens in the rAF, where nothing is tracking, so changing a page's layout\n in the Inspector left the companion on the old file with the pure half answering correctly\n and nothing calling it. An input a resolver consults and the effect does not observe is an\n answer nobody asks for.\n The cost is stated rather than hidden. `tab.doc.document` is replaced by every\n transaction, so this re-runs on a keystroke — but `queueRetarget` collapses a frame's\n worth into one rAF and `applyDerivation` memoises on the resolved PATH, so the expensive\n half (the file read) still happens exactly once per real change of layout. `component`\n does NOT read it, and its memo test is what holds that: it types twenty characters and\n asserts the resolve count does not move, which a per-transaction read here would break. */\n void source?.doc.document?.$layout;\n }\n queueRetarget(paneId, deps);\n });\n}\n\n// ─── Commands ─────────────────────────────────────────────────────────────────\n\n/**\n * The refusal for a preset that cannot be built right now, or null when it can.\n *\n * **Run-time, not `enablement`** — the same shape `canvas.setMode` uses, and for the same reason:\n * `enablement` is ONE sentence for the whole command and five presets have five reasons. The menu\n * renders each row disabled with the sentence this returns, and `run` throws a `RangeError`\n * carrying it, so the tooltip and the refusal are the same words.\n *\n * `locale` takes a fourth argument, DEFAULTED rather than added to every call: the two callers that\n * ask about a breakpoint have nothing to say about a language, and a required parameter would have\n * made them pass a `null` that means nothing at those sites.\n *\n * @param {DerivePreset} preset\n * @param {string} sourcePaneId\n * @param {string | null} media\n * @param {string | null} locale\n * @returns {string | null}\n */\nexport function presetRefusal(\n preset: DerivePreset,\n sourcePaneId: string,\n media: string | null,\n locale: string | null = null,\n): string | null {\n const source = tabOfPane(sourcePaneId);\n if (!source) {\n return \"an open document\";\n }\n /* WHAT THE DOCUMENT CAN BE SHOWN AS, asked before anything else. See {@link MODE_FOR_PRESET}:\n three of the five presets put the pane into a named canvas mode, and the menu offered all five\n over a document whose format declares neither. */\n const needed = MODE_FOR_PRESET[preset];\n if (needed && !source.capabilities.modes.includes(needed)) {\n return `a document with a ${MODE_WORDS[needed]} view — this one declares none`;\n }\n if (preset === \"code\") {\n /* Refused at CREATION, and refused again for as long as it lasts. Two Code views of one file\n is a second Monaco model on one URI, which real Monaco throws on; this predicate stops the\n lens being MADE that way, and {@link lensTarget} stops it being DRAWN that way when the\n source pane switches to Code afterwards. A comment here once claimed one predicate bought\n the whole of that safety, and one click on the Editor axis was enough to disprove it. */\n return canvasModeOfTab(source) === \"source\"\n ? \"a source pane that is not already showing Code\"\n : null;\n }\n if (preset === \"diff\") {\n /* Asked of THIS DOCUMENT's source-control status, not of an app-level slot. It read\n `shell.git.diffState === null`, which is written only when the author clicks a file in the\n Git panel — so the row was refused for a page that genuinely has changes, and offered for a\n page that does not the moment some other file's diff was on screen. */\n return gitChangeFor(source.documentPath) === null ? \"a file with changes against HEAD\" : null;\n }\n if (preset === \"breakpoint\") {\n return declaredMedia(source).includes(media)\n ? null\n : \"a breakpoint this document declares — see Project Settings › Contexts\";\n }\n if (preset === \"layout\") {\n /* REFUSED UP FRONT, because the answer is a stable fact about the document rather than a\n standing rule waiting on the author's next click. Offered anyway, choosing it published a\n derivation whose companion never opened anything: a pane holding a derivation and no tabs,\n which `paneIsEmpty` will not collapse, whose strip drew nothing and whose stage drew nothing.\n `component` is deliberately NOT refused the same way — \"select an element inside a component\"\n is a rule that resolves on the next click, which is the whole point of leaving it open. */\n return getEffectiveLayoutPath(source.doc.document.$layout as string | false | undefined) ===\n null\n ? \"a page with a layout — this one declares none\"\n : null;\n }\n if (preset === \"locale\") {\n /* THE PROJECT'S OWN LIST, read at the moment the menu is drawn. `projectState` is a plain\n module-level `let` replaced wholesale by `setProjectState`, so a locale added in Project\n Settings is visible to the next call and to nothing that cached one. */\n const i18n = getEffectiveLocales();\n if (i18n === null || i18n.locales.length < 2) {\n return \"a project that declares more than one locale — see Project Settings › Locales\";\n }\n /* A PATH, because a translation is a FILE (§13.3) rather than a rendering: an unsaved document\n has nowhere for its sibling to be, and `translationPathFor` would answer null for it one\n frame later with a sentence about locales instead of about saving. */\n if (source.documentPath === null) {\n return \"a document that has been saved\";\n }\n return locale !== null && i18n.locales.includes(locale)\n ? null\n : \"a locale this project declares\";\n }\n return null;\n}\n\n/**\n * Why `paneId` cannot derive, or null when it can. **A pure function OF THE PANE.**\n *\n * `pane.derive`'s `enablement` opened with `activePane()` and the menu asked the registry\n * `disabledReason(\"pane.derive\")` for a pane it had been handed by name — so the same pane got two\n * answers depending on where the keyboard was, and every row in the SECONDARY pane's menu was\n * permanently disabled the moment the author clicked into the lens beside it.\n *\n * **The structural point, stated once here.** A command's `enablement(ctx)` receives no pane, and\n * it cannot: a command's subject IS the focused pane, which is what makes `⌘\\` mean \"split the\n * thing I am looking at\". A per-pane MENU is a different question with a different subject, so it\n * must not be routed through a predicate that resolves one. The answer therefore lives in a pure\n * predicate the menu calls with its own pane, and the command record reuses it for the focused one\n * — one rule, two subjects, no second definition site.\n *\n * `scripts/check-pane-singletons.ts` rule 4 charges a pane-scoped function for reading the focus\n * one hop in, and it could not see this one: the hop was a METHOD CALL on a registry value,\n * dispatched by a string id to a closure built in another module. Following THAT needs a type\n * checker. What the rule can decide is that the question was asked, so `disabledReason` and\n * `isEnabled` are focus reads now — see that file's {@link FOCUS_NAMES}. The closure is still\n * invisible and is not pretended otherwise.\n *\n * @param {string} paneId\n * @returns {string | null}\n */\nexport function deriveRefusal(paneId: string): string | null {\n const pane = paneById(paneId);\n return pane && pane.activeTabId !== null && pane.derived === null ? null : DERIVE_REQUIRES;\n}\n\n/** The one sentence `pane.derive` refuses with — its `requires`, and the menu's disabled reason. */\nconst DERIVE_REQUIRES = \"an open document in a pane that is not itself derived\";\n\n/** The derivation record a preset builds, given the pane it derives from. */\nfunction derivationFor(\n preset: DerivePreset,\n sourcePaneId: string,\n media: string | null,\n locale: string | null = null,\n): PaneDerivation {\n /* A COMPANION, because the French copy of this page is a different FILE — §13.3 has no message\n catalogue, so there is no rendering of this document that is the French one. A lens here would\n be a second copy of the same page under a chip naming another language, which is the defect\n this module's own header warns about: a projection that changes only the chip. */\n if (preset === \"locale\") {\n return {\n kind: \"companion\",\n locale,\n preset,\n reason: \"\",\n resolved: null,\n sourcePaneId,\n status: \"loading\",\n };\n }\n if (preset === \"layout\" || preset === \"component\") {\n return {\n kind: \"companion\",\n preset,\n reason: \"\",\n resolved: null,\n sourcePaneId,\n status: \"loading\",\n };\n }\n const mode = preset === \"code\" ? \"source\" : preset === \"diff\" ? \"git-diff\" : \"design\";\n return {\n /* NO COMPARISON, whatever the Git panel happens to be holding. This seeded itself from\n `shell.git.diffState` — an app-level slot carrying the file the author last clicked in the\n Git panel — so a brand-new Diff lens's FIRST PAINT was somebody else's document, under a\n chip naming this one, until the follow's frame corrected it. The lens loads its own. */\n diff: null,\n kind: \"lens\",\n media: preset === \"breakpoint\" ? media : null,\n mode,\n preset,\n reason: \"\",\n sourcePaneId,\n status: \"loading\",\n zoom: 1,\n };\n}\n\n/**\n * Whether `pane` can be pinned — a companion can, a lens cannot.\n *\n * A companion names a different FILE, so promoting its preview tab and dropping the derivation\n * leaves an ordinary tab, exactly as §18.4 says. A lens has no document of its own: pinning it\n * would have to mint a second tab for a path that already has one, which is the §14.1 violation the\n * whole design exists to avoid. Its exit is `pane.unsplit`.\n */\nfunction pinnablePane(): Pane | null {\n return workspace.panes.find((pane) => pinRefusal(pane.id) === null) ?? null;\n}\n\n/**\n * Why `paneId` cannot be pinned, or null when it can. Pure, like {@link deriveRefusal}.\n *\n * **Unlike `pane.derive`, the COMMAND's subject is the grid rather than the focused pane**, and\n * that is deliberate: the author reaches \"Keep This Document\" from the palette while the keyboard\n * is in the page they are editing, and a grid holds at most one derived pane — `pane.derive` puts\n * the projection in `sidePane()`, and `workspace.ts`'s `MAX_PANES` is 2. {@link pinnablePane} finds\n * it by scanning, which reads no focus and is therefore the same answer from anywhere — so the\n * preset menu can ask it about its own pane and get an answer about its own pane.\n *\n * @param {string} paneId\n * @returns {string | null}\n */\nexport function pinRefusal(paneId: string): string | null {\n const pane = paneById(paneId);\n return pane?.derived?.kind === \"companion\" && pane.activeTabId ? null : PIN_REQUIRES;\n}\n\n/** `pane.pin`'s `requires`, and the menu's disabled reason. One sentence, one home. */\nconst PIN_REQUIRES =\n \"a derived pane showing a document of its own — Code, Diff and breakpoint views project \" +\n \"the document already open beside them\";\n\n/**\n * The derivation commands: `pane.derive` and `pane.pin`.\n *\n * They live here rather than in `paneCommands()` because a capability's record belongs beside its\n * implementation — the same rule the tab and pane commands follow. `pane.compareWith` deliberately\n * stays in `workspace.ts`: it is a transport verb over the pane model and needs none of this.\n *\n * @param {DerivationDeps} deps\n * @returns {AnyCommand[]}\n */\nexport function derivationCommands(deps: DerivationDeps): AnyCommand[] {\n return [\n {\n args: argsSchema(\n {\n locale: stringProperty('BCP 47 tag for preset \"locale\". Ignored by every other preset.'),\n media: stringProperty(\n 'Breakpoint name for preset \"breakpoint\" — omit or leave empty for the base size. ' +\n \"Ignored by every other preset.\",\n ),\n preset: enumProperty(\n DERIVE_PRESETS,\n \"Which projection of this pane's document to show beside it.\",\n ),\n },\n [\"preset\"],\n ),\n id: \"pane.derive\",\n title: \"Show Beside This…\",\n category: \"View\",\n level: \"document\",\n /* NOT in the palette, and that is a fact about the palette rather than a judgement about\n this verb: `panels/quick-search.ts`'s `paletteArgs` can prompt for exactly ONE closed value\n space, so a command with two properties is dropped from command mode entirely. Declaring\n `\"palette\"` here would declare a surface that never renders the row — the same\n \"declared and never drawn\" defect `context/pane` itself spent two phases being. The preset\n menu on the pane's context bar is this command's surface, and every row there IS the\n command with its arguments (§13.5), which is also how the screenshot manifest addresses\n it. */\n menus: [\"context/pane\"],\n group: \"5_pane\",\n when: (ctx) => ctx.document.open,\n /* One sentence, because `enablement` only has one. What each preset needs is decided at run\n time by {@link presetRefusal}, which the menu also reads to disable a row with its own\n reason.\n The FOCUS is read HERE and only here — a command's subject is the pane the keyboard is in,\n and that read belongs at the record where a reviewer can see it. {@link deriveRefusal} is\n the pane-scoped predicate underneath, which is what the per-pane menu calls instead. */\n enablement: () => deriveRefusal(activePane().id) === null,\n requires: DERIVE_REQUIRES,\n undo: \"none\",\n aiTool: {\n description: \"Show a projection of the current document in the pane beside it.\",\n name: \"show_beside\",\n },\n run: (_ctx, args) => {\n const preset = enumArg(\"pane.derive\", args, \"preset\", DERIVE_PRESETS);\n /* `??`, not `||`. `optionalStringArg` answers `undefined` or a non-empty string — it is\n `stringArg` underneath, which REFUSES `\"\"` — so the two operators cannot disagree here,\n and the `||` implied a blank the caller can never deliver. */\n const media = optionalStringArg(\"pane.derive\", args, \"media\") ?? null;\n const locale = optionalStringArg(\"pane.derive\", args, \"locale\") ?? null;\n const source = activePane();\n const refusal = presetRefusal(preset, source.id, media, locale);\n if (refusal) {\n throw new RangeError(\n `command \"pane.derive\" argument \"preset\": \"${preset}\" requires ${refusal}`,\n );\n }\n const target = sidePane();\n /* The DERIVATION IS PUBLISHED FIRST, and the order is not cosmetic.\n §18.1 rule 3 removes a pane with no subject, and `detachTab` applies it as each tab\n leaves — so handing the side pane's tabs back before it had a derivation collapsed the\n very pane about to become the lens, and `setPaneDerivation` then wrote onto a pane that\n was no longer in the grid. `paneIsEmpty` counts a derivation as a subject; giving the\n pane one first is what makes the hand-back safe. Nothing renders between these two\n statements — `run` is synchronous to the end — so no frame observes a lens with tabs. */\n setPaneDerivation(target.id, derivationFor(preset, source.id, media, locale));\n /* NOTHING IS CLOSED. Whatever the side pane was holding goes back to the pane the author\n is in — the same promise `closePane` makes — so a derivation is a layout action rather\n than a destructive one. */\n /* `detachTab` reassigns `activeTabId` to `tabOrder.at(-1) ?? null` as each tab leaves, so\n the pane's own field is already `null` when the last one has gone: a trailing\n `target.activeTabId = null` here wrote the value it already held, and inverting it\n changed nothing any state could reach. `applyDerivation` still owns the D2 repair for a\n tab that arrives afterwards. */\n const displaced = [...target.tabOrder];\n for (const tabId of displaced) {\n detachTab(tabId);\n insertIntoPane(source, tabId);\n }\n applyDerivation(target.id, deps);\n // The focus does NOT move. An assistant pane does not take the keyboard: the author asked\n // To SEE something beside what they are doing, not to go and work on it.\n },\n },\n {\n id: \"pane.pin\",\n title: \"Keep This Document\",\n category: \"View\",\n level: \"document\",\n menus: [\"context/pane\", \"palette\"],\n group: \"5_pane\",\n /* Enabled for a COMPANION only, and the sentence says which — §18.4's \"until it is pinned, at\n which point it becomes an ordinary tab\" is true for `layout` and `component` and impossible\n for `code`, `diff` and `breakpoint`. */\n enablement: () => pinnablePane() !== null,\n requires: PIN_REQUIRES,\n undo: \"none\",\n run: () => {\n const pane = pinnablePane();\n if (!pane?.activeTabId) {\n return;\n }\n promoteTab(pane.activeTabId);\n clearPaneDerivation(pane.id);\n },\n },\n ];\n}\n",
7
+ "/**\n * Media metadata — what a file IS, for surfaces that show media rather than resolve it.\n *\n * Three facts, and each has an \"unknown\" that is not a zero:\n *\n * - **Size and modified time** come from the directory listing the caller already performed. A media\n * surface enumerates a directory to draw itself, so `seedMediaMeta` folds those entries in for\n * free and {@link loadMediaMeta} is the fallback for a path nobody enumerated.\n * - **Pixel dimensions** are OPPORTUNISTIC. There is no stat that returns them and no decoder in the\n * shell, so the only honest source is an `<img>` that already loaded — which every media surface\n * renders anyway. {@link recordImageSize} is how that surface hands the number back, and until\n * one does, the dimensions are `null` and the summary simply omits them. Downloading the file a\n * second time to measure it would be a network request per thumbnail for a line of text.\n *\n * A missing number is `null` everywhere, never `0`. `0 × 0` and `0 B` are things a real file can\n * almost be, so they must not double as \"we did not find out\" — the same rule\n * `services/references.ts` applies to a count it cannot answer.\n *\n * The cache is dropped wholesale by {@link invalidateMediaMeta}, wired to the same post-upload\n * invalidation the media picker's listing uses. There is no TTL: a size that expires on a timer is\n * wrong at an unannounced moment.\n *\n * @docs studio/projects/media\n */\n\nimport { getPlatform } from \"../platform\";\nimport { baseName, dirName, normalizeProjectPath } from \"./media-paths\";\nimport { extensionOf, mediaKind } from \"./media-upload\";\nimport type { AssetKind } from \"./media-upload\";\nimport type { DirEntry } from \"../types\";\n\n/** Everything a media surface can say about one file without opening it. */\nexport interface MediaMeta {\n /** Project-relative, forward-slashed. */\n path: string;\n /** Filename only. */\n name: string;\n /** Lowercased extension including the dot, or `\"\"`. */\n ext: string;\n /** What kind of element it wants to become — the same classification `uploadAssets` records. */\n kind: AssetKind;\n /** Bytes on disk, or null when the listing did not say. */\n bytes: number | null;\n /** ISO modification time, or null when the listing did not say. */\n modified: string | null;\n /** Intrinsic width in CSS pixels, or null until an `<img>` for this file has loaded. */\n width: number | null;\n /** Intrinsic height in CSS pixels, or null until an `<img>` for this file has loaded. */\n height: number | null;\n}\n\n/** Settled metadata, by project-relative path. */\nconst settled = new Map<string, MediaMeta>();\n/** In-flight listings, so N surfaces asking about one path share one round trip. */\nconst inFlight = new Map<string, Promise<MediaMeta>>();\n/**\n * Dimensions reported by a loaded `<img>`, kept beside the cache rather than inside it.\n *\n * A surface can measure a thumbnail before anyone asks for its size — and a `loadMediaMeta` that\n * landed afterwards would otherwise overwrite the one fact that cost a decode to learn.\n */\nconst measured = new Map<string, { width: number; height: number }>();\n\n/** Build a meta record from a path and whatever the listing knew about it. */\nfunction metaFrom(path: string, entry: DirEntry | undefined): MediaMeta {\n const name = baseName(path);\n const dims = measured.get(path);\n return {\n bytes: typeof entry?.size === \"number\" ? entry.size : null,\n ext: extensionOf(name),\n height: dims?.height ?? null,\n kind: mediaKind({ name }),\n modified: entry?.modified ?? null,\n name,\n path,\n width: dims?.width ?? null,\n };\n}\n\n/**\n * The metadata known right now, WITHOUT starting a request.\n *\n * Templates call this: a lit render is synchronous, and a render that listed a directory every time\n * it ran would re-list on its own repaint.\n */\nexport function peekMediaMeta(path: string): MediaMeta | null {\n return settled.get(normalizeProjectPath(path)) ?? null;\n}\n\n/**\n * Fold a directory listing into the cache — the cheap path, for a surface that just enumerated.\n *\n * Only file entries are recorded, and an entry never overwrites a settled record: the listing that\n * arrives second is not more truthful than the one that arrived first, and replacing the record\n * would drop measured dimensions from the object templates are already holding.\n */\nexport function seedMediaMeta(entries: Iterable<DirEntry>): void {\n for (const entry of entries) {\n if (entry.type !== \"file\") {\n continue;\n }\n const path = normalizeProjectPath(entry.path);\n if (!settled.has(path)) {\n settled.set(path, metaFrom(path, entry));\n }\n }\n}\n\n/**\n * Ask for one file's metadata, or join the ask already in flight.\n *\n * Never rejects. A directory that cannot be listed yields a record whose numbers are `null` — \"we\n * do not know how big it is\" is a renderable answer, and a thrown error at this altitude would only\n * be caught and turned back into one by every caller.\n */\nexport async function loadMediaMeta(path: string): Promise<MediaMeta> {\n const key = normalizeProjectPath(path);\n const done = settled.get(key);\n if (done) {\n return done;\n }\n const running = inFlight.get(key);\n if (running) {\n return running;\n }\n const pending = (async (): Promise<MediaMeta> => {\n let entry: DirEntry | undefined;\n try {\n const listing = await getPlatform().listDirectory(dirName(key));\n entry = listing.find((item) => normalizeProjectPath(item.path) === key);\n } catch {\n // Unreadable or not yet created — the size stays unknown rather than becoming zero.\n entry = undefined;\n }\n return metaFrom(key, entry);\n })();\n inFlight.set(key, pending);\n const meta = await pending;\n inFlight.delete(key);\n settled.set(key, meta);\n return meta;\n}\n\n/**\n * Record the intrinsic size of a file whose `<img>` has loaded.\n *\n * @returns Whether this was new information — the caller repaints only when it was, so a template\n * that re-renders its thumbnails (and re-fires their `load` from cache) does not loop.\n */\nexport function recordImageSize(path: string, width: number, height: number): boolean {\n if (!(width > 0 && height > 0)) {\n return false; // A broken or still-decoding image reports 0 — that is not a measurement.\n }\n const key = normalizeProjectPath(path);\n const known = measured.get(key);\n if (known && known.width === width && known.height === height) {\n return false;\n }\n measured.set(key, { height, width });\n const meta = settled.get(key);\n if (meta) {\n settled.set(key, { ...meta, height, width });\n }\n return true;\n}\n\n/** Drop every cached record and measurement. Called wherever the media listing is invalidated. */\nexport function invalidateMediaMeta(): void {\n settled.clear();\n measured.clear();\n}\n\n/** `84 KB`, `1.2 MB`, `903 B` — one significant fraction, because this is a caption. */\nexport function formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n if (bytes < 1024 * 1024) {\n return `${Math.round(bytes / 1024)} KB`;\n }\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\n/**\n * The one-line caption a media surface shows: `1200 × 800 · 84 KB`.\n *\n * Unknown facts are omitted rather than rendered as a placeholder, so the line shortens instead of\n * filling with dashes. It is `\"\"` when nothing at all is known, which a template renders as\n * nothing.\n */\nexport function mediaMetaSummary(meta: MediaMeta | null): string {\n if (!meta) {\n return \"\";\n }\n const parts: string[] = [];\n if (meta.width !== null && meta.height !== null) {\n parts.push(`${meta.width} × ${meta.height}`);\n }\n if (meta.bytes !== null) {\n parts.push(formatBytes(meta.bytes));\n }\n return parts.join(\" · \");\n}\n",
8
+ "/// <reference lib=\"dom\" />\n/**\n * Media Picker — combobox-style widget for selecting or uploading project media files.\n *\n * Shows an editable text input for manual URL entry, an Upload button that adds a new file to the\n * project and assigns it, and a Browse dropdown of media already in the project's public/\n * directory, with thumbnail previews for images.\n *\n * **The browse list carries metadata, and it costs nothing.** Size comes from the directory listing\n * the widget already performs to enumerate the files (`seedMediaMeta`), and pixel dimensions come\n * from the thumbnails it already loads (`recordImageSize`) — measuring an image is a decode the\n * `<img>` has finished by the time `load` fires, so the caption is a read of work already done\n * rather than a second fetch per row. What is NOT here is a usage count: `findReferences` sweeps\n * every document in the project per query, and fifty of those to caption a dropdown is the wrong\n * trade. Usage is asked once, about one file, where it changes a decision — the delete confirmation\n * (`files/media-usage.ts`).\n *\n * @docs studio/projects/media\n */\n\nimport { html, render as litRender, nothing } from \"lit-html\";\nimport { live } from \"lit-html/directives/live.js\";\nimport { ref } from \"lit-html/directives/ref.js\";\nimport { getPlatform } from \"../platform\";\nimport { debouncedStyleCommit, renderOnly } from \"../store\";\nimport { getLayerSlot, popoverLayerFor } from \"./layers\";\nimport type { LayerKind } from \"./layers\";\nimport { rectOf } from \"../utils/geometry\";\nimport { loopbackAssetSrc } from \"../canvas/canvas-origin\";\nimport { previewAssetSrc } from \"../canvas/content-assets\";\nimport {\n IMAGE_EXTENSIONS,\n MEDIA_EXTENSIONS,\n UPLOAD_ACCEPT,\n extensionOf,\n uploadAssets,\n} from \"../files/media-upload\";\nimport {\n invalidateMediaMeta,\n mediaMetaSummary,\n peekMediaMeta,\n recordImageSize,\n seedMediaMeta,\n} from \"../files/media-meta\";\nimport { mediaSiteUrl } from \"../files/media-paths\";\n\n// ─── Media file cache ────────────────────────────────────────────────────────\n\n/** One browsable media file: the ref a pick writes, and the file that ref names. */\ninterface MediaEntry {\n /** The value committed to the field — the site URL, which is the authored form. */\n path: string;\n /** Project-relative path on disk, the key everything in `media-meta` is stored under. */\n file: string;\n name: string;\n isImage: boolean;\n}\n\nlet mediaCache: MediaEntry[] = [];\nlet mediaCacheLoaded = false;\n\n/**\n * Recursively collect media files from a directory, seeding {@link seedMediaMeta} with the listing\n * on the way past — the size of every row is already in the response that enumerated it.\n */\nasync function collectMedia(\n dir: string,\n platform: ReturnType<typeof getPlatform>,\n): Promise<MediaEntry[]> {\n const results: MediaEntry[] = [];\n try {\n const entries = await platform.listDirectory(dir);\n seedMediaMeta(entries);\n for (const entry of entries) {\n if (entry.type === \"directory\") {\n const sub = await collectMedia(entry.path, platform);\n results.push(...sub);\n } else {\n const ext = extensionOf(entry.name);\n if (MEDIA_EXTENSIONS.has(ext)) {\n results.push({\n file: entry.path,\n isImage: IMAGE_EXTENSIONS.has(ext),\n name: entry.name,\n // The site URL is what production serves and therefore what a document should say.\n // Media-paths holds the one definition of that mapping.\n path: mediaSiteUrl(entry.path),\n });\n }\n }\n }\n } catch {\n // Directory may not exist\n }\n return results;\n}\n\nasync function loadMediaCache() {\n if (mediaCacheLoaded) {\n return;\n }\n const platform = getPlatform();\n mediaCache = await collectMedia(\"public\", platform);\n mediaCacheLoaded = true;\n // Re-render the host panels so the browse popover has entries to show once the async listing\n // Resolves. Mirrors loadLayoutEntries()'s renderOnly() in head-panel.\n renderOnly(\"leftPanel\", \"rightPanel\", \"frontmatterPanel\");\n}\n\n/**\n * Force media cache reload (e.g. after upload).\n *\n * The metadata cache goes with it, and for the same reason: both were derived from a listing that\n * is now out of date, and a size that survives the write it contradicts is worse than no size.\n */\nexport function invalidateMediaCache() {\n mediaCache = [];\n mediaCacheLoaded = false;\n invalidateMediaMeta();\n}\n\n// ─── Popover state ───────────────────────────────────────────────────────────\n\n/** @type {((val: string) => void) | null} */\nlet _popoverOnCommit: ((val: string) => void) | null = null;\n\n/** @type {HTMLElement | null} */\nlet _popoverAnchorEl: HTMLElement | null = null;\n/**\n * Which layer the open popover is living in.\n *\n * Chosen from the anchor at open time and then REMEMBERED, because `getLayerSlot` keys its slots by\n * `${layer}:${id}`: dismissing through a different layer than the one that opened would clear an\n * empty slot and leave the real popover on screen.\n */\nlet _popoverLayer: LayerKind = \"popover\";\n\n/** The open popover's slot — the one place that names the layer and the id together. */\nfunction popoverSlot(): HTMLElement {\n return getLayerSlot(_popoverLayer, \"media-picker\");\n}\n\n/**\n * The popover's z-index, which depends on the company it is keeping.\n *\n * In `#layer-popover` it has the layer to itself and 30 is enough — that is what it has always\n * been, and every panel-hosted picker keeps rendering identically. Sharing a layer with a modal\n * body is different: those declare `z-index: 1000` (`.seo-modal`, `.about-modal`, `.settings-modal`\n * — the house shape), so a picker anchored inside one is a later sibling that still paints beneath\n * it. Beating that number is the whole point of moving layers in the first place.\n */\nfunction popoverZIndex(): number {\n return _popoverLayer === \"popover\" ? 30 : 1001;\n}\n\n/** @type {HTMLInputElement | null} */\nlet _popoverFilterEl: HTMLInputElement | null = null;\n\nlet _popoverFilter = \"\";\n\nfunction dismissMediaPickerPopover() {\n _popoverFilter = \"\";\n _popoverOnCommit = null;\n _popoverAnchorEl = null;\n _popoverFilterEl = null;\n document.removeEventListener(\"keydown\", onPopoverKeydown, true);\n document.removeEventListener(\"mousedown\", onPopoverOutsideClick, true);\n litRender(nothing, popoverSlot());\n}\n\n/** @param {KeyboardEvent} e */\nfunction onPopoverKeydown(e: KeyboardEvent) {\n if (e.key === \"Escape\") {\n dismissMediaPickerPopover();\n e.preventDefault();\n e.stopPropagation();\n }\n}\n\n/** @param {MouseEvent} e */\nfunction onPopoverOutsideClick(e: MouseEvent) {\n const host = popoverSlot();\n if (!host.contains(e.target as Node)) {\n dismissMediaPickerPopover();\n }\n}\n\n/** A repaint scheduled by a thumbnail that just reported its size, or 0 when none is pending. */\nlet _sizeRepaint = 0;\n\n/**\n * Fold a loaded thumbnail's intrinsic size into the metadata cache and, if that was news, repaint\n * the popover once so the caption appears.\n *\n * The repaint is coalesced across a whole grid of images landing in the same frame, and it cannot\n * loop: re-rendering recreates the `<img>` elements, whose `load` fires again from cache, and\n * `recordImageSize` returns false the second time because the measurement has not changed.\n */\nfunction noteImageSize(file: string, target: EventTarget | null) {\n const img = target as HTMLImageElement | null;\n if (!img || !recordImageSize(file, img.naturalWidth, img.naturalHeight) || _sizeRepaint !== 0) {\n return;\n }\n _sizeRepaint = requestAnimationFrame(() => {\n _sizeRepaint = 0;\n if (_popoverAnchorEl) {\n renderMediaPickerPopover();\n }\n });\n}\n\nfunction renderMediaPickerPopover() {\n const host = popoverSlot();\n const rect = _popoverAnchorEl ? rectOf(_popoverAnchorEl) : undefined;\n if (!rect) {\n return;\n }\n\n const query = _popoverFilter.toLowerCase();\n const filtered = query\n ? mediaCache.filter(\n (m) => m.path.toLowerCase().includes(query) || m.name.toLowerCase().includes(query),\n )\n : mediaCache;\n const options = filtered.slice(0, 50);\n\n // Compute initial position below the anchor\n let { left } = rect;\n let top = rect.bottom + 4;\n\n // Estimate popover dimensions for viewport clamping before first paint\n const estimatedWidth = 280;\n const estimatedHeight = Math.min(options.length * 36 + 48, 360);\n\n if (left + estimatedWidth > window.innerWidth - 8) {\n left = Math.max(8, window.innerWidth - estimatedWidth - 8);\n }\n if (top + estimatedHeight > window.innerHeight - 8) {\n top = Math.max(8, rect.top - estimatedHeight - 4);\n }\n\n let _popoverEl: HTMLElement | null = null;\n\n litRender(\n html`\n <sp-popover\n open\n data-jx-region=\"overlay.menu:media-picker\"\n ${ref((el) => {\n _popoverEl = (el as HTMLElement | undefined) || null;\n })}\n style=\"position:fixed;left:${left}px;top:${top}px;z-index:${popoverZIndex()};max-height:360px;overflow-y:auto;min-width:240px\"\n >\n <input\n class=\"media-picker-filter\"\n type=\"text\"\n placeholder=\"Search images…\"\n autocomplete=\"off\"\n style=\"display:block;width:100%;box-sizing:border-box;padding:6px 10px;border:none;border-bottom:1px solid var(--border, #444);outline:none;font-size:13px;background:transparent;color:inherit\"\n ${ref((el) => {\n _popoverFilterEl = (el as HTMLInputElement | null) || null;\n })}\n @input=${(e: Event) => {\n _popoverFilter = (e.target as HTMLInputElement).value;\n renderMediaPickerPopover();\n }}\n @click=${(e: MouseEvent) => e.stopPropagation()}\n />\n <sp-menu\n style=\"min-width:220px\"\n @change=${(e: Event) => {\n _popoverOnCommit?.((e.target as HTMLInputElement).value);\n dismissMediaPickerPopover();\n }}\n >\n ${\n options.length > 0\n ? options.map((m) => {\n const caption = mediaMetaSummary(peekMediaMeta(m.file));\n return html`\n <sp-menu-item value=${m.path}>\n ${\n m.isImage\n ? html`<img\n slot=\"icon\"\n src=${loopbackAssetSrc(m.path)}\n alt=\"\"\n style=\"width:24px;height:24px;object-fit:cover;border-radius:var(--spectrum-corner-radius-75, 2px)\"\n @load=${(e: Event) => noteImageSize(m.file, e.target)}\n />`\n : nothing\n }\n ${m.name}\n ${caption ? html`<span slot=\"description\">${caption}</span>` : nothing}\n </sp-menu-item>\n `;\n })\n : html`<sp-menu-item disabled>No matches</sp-menu-item>`\n }\n ${\n filtered.length > 50\n ? html`<sp-menu-item disabled>…${filtered.length - 50} more</sp-menu-item>`\n : nothing\n }\n </sp-menu>\n </sp-popover>\n `,\n host,\n );\n\n // Fine-tune position after render using actual measured dimensions\n requestAnimationFrame(() => {\n if (_popoverEl) {\n const popoverRect = rectOf(_popoverEl);\n let adjLeft = popoverRect.left;\n let adjTop = popoverRect.top;\n let needsAdjust = false;\n\n if (popoverRect.right > window.innerWidth - 4) {\n adjLeft = Math.max(4, window.innerWidth - popoverRect.width - 4);\n needsAdjust = true;\n }\n if (popoverRect.bottom > window.innerHeight - 4) {\n adjTop = Math.max(4, window.innerHeight - popoverRect.height - 4);\n needsAdjust = true;\n }\n if (popoverRect.left < 4) {\n adjLeft = 4;\n needsAdjust = true;\n }\n if (popoverRect.top < 4) {\n adjTop = 4;\n needsAdjust = true;\n }\n\n if (needsAdjust) {\n _popoverEl.style.left = `${adjLeft}px`;\n _popoverEl.style.top = `${adjTop}px`;\n }\n }\n\n if (_popoverFilterEl) {\n _popoverFilterEl.focus();\n }\n });\n}\n\n/**\n * @param {HTMLElement} anchorEl\n * @param {(val: string) => void} onCommit\n */\nfunction showMediaPickerPopover(anchorEl: HTMLElement, onCommit: (val: string) => void) {\n dismissMediaPickerPopover();\n _popoverOnCommit = onCommit;\n _popoverAnchorEl = anchorEl;\n // Before the first render, so every later `popoverSlot()` agrees with where it was drawn.\n _popoverLayer = popoverLayerFor(anchorEl);\n _popoverFilter = \"\";\n renderMediaPickerPopover();\n document.addEventListener(\"keydown\", onPopoverKeydown, true);\n requestAnimationFrame(() => {\n document.addEventListener(\"mousedown\", onPopoverOutsideClick, true);\n });\n}\n\n// ─── Render ──────────────────────────────────────────────────────────────────\n\n/**\n * Upload files chosen in a media field's file input and assign the first one to the field. Exported\n * for the unit tests — the hidden input is created on demand, so there is no other way to reach\n * it.\n *\n * @param {FileList | File[]} files\n * @param {(val: string) => void} onCommit\n */\nexport async function uploadAndAssign(\n files: FileList | File[],\n onCommit: (val: string) => void,\n): Promise<void> {\n const uploaded = await uploadAssets([...files]);\n const [first] = uploaded;\n if (first) {\n onCommit(first.ref);\n }\n}\n\n/**\n * Open the OS file picker for a media field. The input is created per click and discarded after — a\n * persistent hidden input in the template would be recreated by lit on every panel re-render.\n *\n * @param {(val: string) => void} onCommit\n */\nfunction pickAndUpload(onCommit: (val: string) => void) {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.multiple = true;\n input.accept = UPLOAD_ACCEPT;\n input.addEventListener(\"change\", () => {\n if (input.files?.length) {\n void uploadAndAssign(input.files, onCommit);\n }\n });\n input.click();\n}\n\n/**\n * Render the media picker widget for src-type attributes.\n *\n * @param {string} prop — attribute name (e.g. \"src\")\n * @param {string} value — current attribute value\n * @param {(val: string) => void} onCommit — commit callback\n * @returns {import(\"lit-html\").TemplateResult}\n */\nexport function renderMediaPicker(prop: string, value: string, onCommit: (val: string) => void) {\n // Kick off async load (won't block render)\n void loadMediaCache();\n\n const currentValue = value || \"\";\n const isImage = IMAGE_EXTENSIONS.has(extensionOf(currentValue));\n\n return html`\n <div class=\"media-picker\">\n ${\n isImage && currentValue\n ? html`<img\n class=\"media-picker-thumb\"\n src=${loopbackAssetSrc(previewAssetSrc(currentValue))}\n alt=\"\"\n />`\n : nothing\n }\n <sp-textfield\n size=\"s\"\n placeholder=\"/image.jpg\"\n .value=${live(currentValue)}\n @input=${debouncedStyleCommit(`media:${prop}`, 400, (e: Event) =>\n onCommit((e.target as HTMLInputElement).value),\n )}\n @focus=${() => loadMediaCache()}\n ></sp-textfield>\n <sp-action-button\n class=\"media-picker-upload\"\n size=\"xs\"\n quiet\n title=\"Upload media\"\n @click=${() => pickAndUpload(onCommit)}\n >\n <sp-icon-upload slot=\"icon\"></sp-icon-upload>\n </sp-action-button>\n <!-- No data-jx-region here. The class IS the handle: ui/regions.ts derives\n inspector/field:PROP/browse by finding this button inside the Inspector's own\n [data-prop] row, so the id resolves to one element however many panes are drawing a\n media picker. The stamp claimed an inspector/... id on every picker the app renders,\n including the two the Document Header card draws inside each pane's STAGE. -->\n <sp-action-button\n class=\"media-picker-browse\"\n size=\"xs\"\n quiet\n title=\"Browse media\"\n @click=${(e: MouseEvent) => {\n void loadMediaCache();\n showMediaPickerPopover(e.currentTarget as HTMLElement, onCommit);\n }}\n >\n <sp-icon-image slot=\"icon\"></sp-icon-image>\n </sp-action-button>\n </div>\n `;\n}\n",
9
+ "/// <reference lib=\"dom\" />\n// ─── Data Explorer ──────────────────────────────────────────────────────────\n\nimport { html, nothing } from \"lit-html\";\nimport type { TemplateResult } from \"lit-html\";\nimport { activeTab } from \"../workspace/workspace\";\nimport { renderOnly } from \"../store\";\nimport { booleanArg, stringArg, stringProperty } from \"../commands/command-args\";\nimport { registerPanel } from \"./panel-registry\";\nimport type { AnyCommand, CommandRegistry } from \"../commands/registry\";\n\n/**\n * The focused tab's expansion record, created on first write.\n *\n * `ui.dataRows` rather than a module Set: expansion is a property of the document you are reading,\n * and a module-global one followed you to the next tab and showed rows open that that document does\n * not define.\n */\nfunction rowsUi(): Record<string, boolean> | null {\n const ui = activeTab.value?.session.ui;\n if (!ui) {\n return null;\n }\n return (ui.dataRows ??= {});\n}\n\n/*\n * ── The truncation markers, which are now BUTTONS ────────────────────────────\n *\n * The tree caps arrays at 20, objects at 30 and depth at 5, and printed \"… 5 more\" as inert text.\n * That is the panel telling you it has the answer and will not show it — the exact case a user\n * opens this panel for is the fetch that returned something unexpected at item 40. Plan §11.2:\n * \"truncation markers gain real expand actions.\"\n *\n * Raising a limit is remembered per marker rather than globally, so opening one long array does not\n * re-render every other one at full length, and it never lowers: a step is a step.\n */\nconst MORE_STEP = 50;\n\n/** The focused tab's raised-limit record, created on first write. */\nfunction limitsUi(): Record<string, number> | null {\n const ui = activeTab.value?.session.ui;\n if (!ui) {\n return null;\n }\n return (ui.dataLimits ??= {});\n}\n\n/** The cap for one marker: the default, plus whatever the reader has asked for. */\nfunction capFor(path: string, kind: \"items\" | \"keys\" | \"depth\", base: number): number {\n return base + (limitsUi()?.[`${path}\\u0000${kind}`] ?? 0);\n}\n\n/** Raise one marker's limit by a step. Exported for the tests. */\nexport function raiseDataLimit(path: string, kind: \"items\" | \"keys\" | \"depth\"): void {\n const limits = limitsUi();\n if (!limits) {\n return;\n }\n const key = `${path}\\u0000${kind}`;\n limits[key] = (limits[key] ?? 0) + MORE_STEP;\n}\n\n/**\n * One truncation marker: a button that shows more of what is already in hand.\n *\n * It repaints through `renderOnly(\"leftPanel\")` rather than a callback, because this renderer is\n * called from three places and threading a repaint through all of them to reach one `<button>`\n * would put a required callback on a pure formatter.\n */\nfunction moreTemplate(\n path: string,\n kind: \"items\" | \"keys\" | \"depth\",\n indent: string,\n label: string,\n after?: () => string,\n) {\n return html`<button\n type=\"button\"\n class=\"data-leaf data-ellipsis data-more\"\n style=\"padding-left:${indent}\"\n title=${after?.() ?? `Show ${MORE_STEP} more`}\n @click=${(e: Event) => {\n e.stopPropagation();\n raiseDataLimit(path, kind);\n renderOnly(\"leftPanel\");\n }}\n >\n ${label}\n </button>`;\n}\n\n/** Unwrap a Vue ref (has .value and .__v_isRef) to get the underlying value. */\nexport function unwrapSignal(value: unknown) {\n if (value && typeof value === \"object\" && (value as Record<string, unknown>).__v_isRef) {\n return (value as Record<string, unknown>).value;\n }\n return value;\n}\n\n/** Type label for a signal value in the data explorer. */\nexport function dataTypeLabel(value: unknown) {\n const v = unwrapSignal(value);\n if (v === null) {\n return \"null\";\n }\n if (v === undefined) {\n return \"pending\";\n }\n if (Array.isArray(v)) {\n return `Array(${v.length})`;\n }\n if (typeof v === \"object\") {\n return `{${Object.keys(v).length}}`;\n }\n return typeof v;\n}\n\n/* THE VALUE LIST IS GONE, AND ITS ROWS ARE THE DEFINITION ROWS — `panels/signals-panel.ts`.\n It listed every state entry with its badge and what it resolved to, one rail tab away from a\n panel listing every state entry with its badge and how it is defined: the same names twice, and\n you read one to understand the other. Plan §11.2 asks for \"definitions + live values in one row\",\n so the definition row now carries the resolved type and expands to the value tree, and what is\n left here is the tree renderer, the type label and the row-expansion record the merged rows read.\n `renderDataTreeTemplate` is unchanged — it was never the redundant half. */\n/**\n * Recursively render a JSON value as a tree view (Lit template).\n *\n * @returns {import(\"lit-html\").TemplateResult}\n */\nexport function renderDataTreeTemplate(\n value: unknown,\n depth: number,\n maxDepth = 5,\n path = \"\",\n): TemplateResult {\n const indent = `${(depth + 1) * 12}px`;\n\n if (depth > capFor(path, \"depth\", maxDepth)) {\n return moreTemplate(path, \"depth\", indent, \"…\", () => `Show ${MORE_STEP} more levels`);\n }\n\n if (value === null || value === undefined) {\n return html`<div class=\"data-leaf data-null\" style=\"padding-left:${indent}\">\n ${String(value)}\n </div>`;\n }\n\n if (typeof value !== \"object\") {\n const text =\n typeof value === \"string\" && value.length > 200\n ? `\"${value.slice(0, 200)}\\u2026\"`\n : JSON.stringify(value);\n return html`<div class=\"data-leaf data-${typeof value}\" style=\"padding-left:${indent}\">\n ${text}\n </div>`;\n }\n\n if (Array.isArray(value)) {\n const cap = capFor(path, \"items\", 20);\n const items: TemplateResult[] = value.slice(0, cap).map((item, i) => {\n if (item === null || item === undefined || typeof item !== \"object\") {\n const valText =\n typeof item === \"string\" && item.length > 80\n ? `\"${item.slice(0, 80)}\\u2026\"`\n : JSON.stringify(item);\n return html`<div class=\"data-branch\" style=\"padding-left:${indent}\">\n <span class=\"data-key\">[${i}] </span\n ><span class=\"data-value data-${item === null ? \"null\" : typeof item}\">${valText}</span>\n </div>`;\n }\n const label = Array.isArray(item)\n ? `Array(${item.length})`\n : `{${Object.keys(item as object).length}}`;\n return html`\n <div class=\"data-branch\" style=\"padding-left:${indent}\">\n <span class=\"data-key\">[${i}] </span\n ><span class=\"data-value data-object-label\">${label}</span>\n </div>\n ${renderDataTreeTemplate(item, depth + 1, maxDepth, `${path}/${i}`)}\n `;\n });\n return html`${items}${\n value.length > cap\n ? moreTemplate(path, \"items\", indent, `… ${value.length - cap} more`)\n : nothing\n }`;\n }\n\n // Object\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj);\n const cap = capFor(path, \"keys\", 30);\n const items: TemplateResult[] = keys.slice(0, cap).map((key) => {\n const v = obj[key];\n if (v === null || v === undefined || typeof v !== \"object\") {\n const valText =\n typeof v === \"string\" && v.length > 80 ? `\"${v.slice(0, 80)}\\u2026\"` : JSON.stringify(v);\n return html`<div class=\"data-branch\" style=\"padding-left:${indent}\">\n <span class=\"data-key\">${key}: </span\n ><span class=\"data-value data-${v === null ? \"null\" : typeof v}\">${valText}</span>\n </div>`;\n }\n const label = Array.isArray(v) ? `Array(${v.length})` : `{${Object.keys(v).length}}`;\n return html`\n <div class=\"data-branch\" style=\"padding-left:${indent}\">\n <span class=\"data-key\">${key}: </span\n ><span class=\"data-value data-object-label\">${label}</span>\n </div>\n ${renderDataTreeTemplate(v, depth + 1, maxDepth, `${path}/${key}`)}\n `;\n });\n return html`${items}${\n keys.length > cap ? moreTemplate(path, \"keys\", indent, `… ${keys.length - cap} more`) : nothing\n }`;\n}\n\n// ─── Commands ─────────────────────────────────────────────────────────────────\n\n/** Expand (or collapse) one data row's value tree. Idempotent — expanding twice is expanding once. */\nexport function setDataRowExpanded(name: string, expanded: boolean): void {\n const rows = rowsUi();\n if (!rows) {\n return;\n }\n if (expanded) {\n rows[name] = true;\n } else {\n delete rows[name];\n }\n}\n\n/** Whether a data row is currently expanded. Exported for the tests and the command's idempotence. */\nexport function isDataRowExpanded(name: string): boolean {\n return rowsUi()?.[name] === true;\n}\n\n/** The expanded rows, in no particular order — `formula.openWorkspace` asks when it has no target. */\nexport function expandedDataRows(): string[] {\n return Object.keys(rowsUi() ?? {});\n}\n\n/** Drop every expansion AND every raised limit on the focused tab — a fresh document, and tests. */\nexport function resetDataRowExpansion(): void {\n const ui = activeTab.value?.session.ui;\n if (ui) {\n ui.dataRows = {};\n ui.dataLimits = {};\n }\n}\n\n/** The state entry names the open document defines — what a row can be named by. */\nfunction definedDataNames(): string[] {\n return Object.keys(activeTab.value?.doc.document?.state ?? {});\n}\n\n/** What the data verb needs that this module does not own. */\nexport interface DataExplorerCommandDeps {\n /** Repaint the Navigator so the expanded row's tree appears — `left-panel.ts`'s `render`. */\n renderLeftPanel: () => void;\n}\n\n/**\n * The Data panel's row verb.\n *\n * `expandRow` reads as a delta but is not one: it names the state it ends in, which is why it\n * survives `__jxAutomation`'s `/\\.toggle[A-Z]/` refusal and why running it twice photographs the\n * same picture. The collapse direction is `{ expanded: false }` on the same record rather than a\n * second id.\n *\n * REFUSES a name the open document does not define. The predecessor matched the row by its rendered\n * label through an XPath, so a document without that entry silently pressed nothing and the shot\n * recorded a collapsed panel as if it were the feature.\n *\n * @param {DataExplorerCommandDeps} deps\n * @returns {AnyCommand[]}\n */\nexport function dataExplorerCommands(deps: DataExplorerCommandDeps): AnyCommand[] {\n return [\n {\n args: {\n additionalProperties: false,\n properties: {\n expanded: {\n default: true,\n description: \"True to expand the row's value tree, false to collapse it.\",\n type: \"boolean\",\n },\n name: stringProperty(\"The state entry's name, as the document defines it.\"),\n },\n required: [\"name\"],\n type: \"object\",\n },\n category: \"Document\",\n id: \"data.expandRow\",\n level: \"document\",\n menus: [\"palette\"],\n group: \"5_data\",\n requires: \"an open document that defines data\",\n when: (ctx) => ctx.document.open,\n run: (_commandCtx, args) => {\n const name = stringArg(\"data.expandRow\", args, \"name\");\n const defined = definedDataNames();\n if (!defined.includes(name)) {\n throw new RangeError(\n `command \"data.expandRow\" argument \"name\": \"${name}\" is not defined by this ` +\n `document — it defines: ${defined.length > 0 ? defined.join(\", \") : \"nothing\"}`,\n );\n }\n const { expanded } = args as { expanded?: unknown };\n // `expanded` defaults to true but is never COERCED: `{ expanded: \"no\" }` would otherwise\n // Read as a collapse, which is the class of silent wrong answer this whole record exists\n // To stop.\n setDataRowExpanded(\n name,\n expanded === undefined || booleanArg(\"data.expandRow\", args, \"expanded\"),\n );\n deps.renderLeftPanel();\n },\n title: \"Expand Data Row\",\n },\n ];\n}\n\n/**\n * Register the Data panel's row verb.\n *\n * @param {CommandRegistry} registry\n * @param {DataExplorerCommandDeps} deps\n */\nexport function registerDataExplorerCommands(\n registry: CommandRegistry,\n deps: DataExplorerCommandDeps,\n): void {\n registry.registerAll(dataExplorerCommands(deps));\n}\n\n/**\n * Contribute the Data panel — the DEFINITIONS and the values they resolve to, in one place.\n *\n * `level: \"document\"`, because both belong to the open document.\n *\n * **This is where the State editor lives now.** Plan §11.2 always said so (\"State panel + inline\n * editor → Navigator › Data\"), but the two halves shipped apart: the rail button was taken away to\n * keep the DOCUMENT group at four, the merge was deferred, and the editor was left reachable only\n * by typing its name into the palette. So the one surface for declaring a state variable — or a\n * component property, which is a state entry with a default — became unfindable, which is a\n * capability lost rather than a control moved.\n *\n * Defining and watching are the same task interrupted: you add an entry, then look at what it\n * resolved to. Two panels made that two panels.\n */\nexport function registerDataPanel(): void {\n registerPanel({\n id: \"data\",\n title: \"Data\",\n level: \"document\",\n dock: \"navigator\",\n icon: \"sp-icon-data\",\n requiresDocument: \"Open a page to give it data — values it can read, compute or fetch.\",\n render: (ctx) =>\n // `ctx.doc!` — `requiresDocument` means the registry renders the empty state instead of\n // Calling this, the same assertion `head-panel.ts` makes for the same reason.\n ctx.deps.renderSignalsTemplate(ctx.doc!, {\n refreshData: ctx.deps.refreshData,\n renderLeftPanel: ctx.rerender,\n }),\n });\n}\n",
10
+ "/// <reference lib=\"dom\" />\n/**\n * The Logic dock's CODE surface — the Monaco function-body editor and its state-scope completions.\n *\n * It used to take over the canvas: `renderFunctionEditor` cleared `canvasWrap`, dropped every\n * canvas panel and mounted Monaco over the stage, so the page whose handler you were writing was\n * the one thing you could not see while writing it. It is a surface of the Bottom dock's **Logic**\n * tab now (plan §12 P8.5); `panels/formula-workspace.ts` owns that tab's record and calls the three\n * exports below — {@link functionEditorTemplate} for the container, {@link syncFunctionEditor} from\n * the panel's `afterRender`, and {@link closeFunctionEditor} for its Close. The canvas keeps\n * rendering the page underneath the dock; `canvas/canvas-render.ts` no longer knows this surface\n * exists.\n *\n * **The mount is driven by the DOM, not by a render call.** A dock tab's body is re-rendered by lit\n * whenever anything it reads changes, and lit will happily replace the container element out from\n * under a live Monaco instance (switching to the formula surface and back does exactly that). So\n * `syncFunctionEditor` asks the one question that matters — is the editor I hold still inside the\n * container I was just handed? — and rebuilds when the answer is no. Re-checking the target string\n * alone, which is all the takeover ever did, would have left a detached editor holding the user's\n * unsaved body.\n *\n * **The move changed the REPAINT rate, not just the teardown rate, and the repaint is the one that\n * runs with the user's hands on the keyboard.** The dock's `afterRender` effect tracks every badge\n * in the strip — Problems' count, Activity's running list, Source Control's file count, which git\n * polls every 30 seconds — so this module's sync runs on events that have nothing to do with the\n * code surface. Every write below therefore asks `services/monaco-buffer.ts` whether the buffer has\n * moved on first. Identity (\"is this still the same editor?\") is the OTHER question, still asked\n * where it applies, and it is passed by a repaint into a live editor mid-word.\n */\n\nimport type * as monaco from \"monaco-editor\";\nimport { loadMonaco, mountStillWanted } from \"../services/monaco-lazy\";\nimport { isJsonObject } from \"@jxsuite/schema/guards\";\nimport { html } from \"lit-html\";\n\nimport { getNodeAtPath, renderOnly, updateUi } from \"../store\";\nimport { activeTab, tabIsLive } from \"../workspace/workspace\";\nimport { mutateUpdateDef, mutateUpdateProperty, transactDoc } from \"../tabs/transact\";\nimport { view } from \"../view\";\nimport { codeService, getFunctionArgs, setLintMarkers } from \"../services/code-services\";\nimport {\n BUFFER_COMMIT,\n bufferIsLive,\n bufferMovedOn,\n bufferWrites,\n cancelBufferWrites,\n commitBufferWrites,\n} from \"../services/monaco-buffer\";\nimport { globalEntries, namedFormulaEntries } from \"../ui/formula-catalog\";\nimport { notify } from \"../services/notify\";\n\nimport type { BufferWrites } from \"../services/monaco-buffer\";\nimport type { OxLintDiagnostic } from \"../services/code-services\";\nimport type { JxPrototypeDef } from \"@jxsuite/schema/types\";\nimport type { JxPath } from \"../state\";\nimport type { Tab } from \"../tabs/tab\";\nimport type { TemplateResult } from \"lit-html\";\n\ntype EditingTarget =\n | { type: \"def\"; defName: string }\n | { type: \"event\"; path: JxPath; eventKey: string };\n\n/** The Monaco instance plus the four fields this module hangs off it (declared in `../view`). */\ntype FunctionEditor = NonNullable<typeof view.functionEditor>;\n\n/**\n * The body `editing` names, read out of `tab`'s document.\n *\n * The tab is a PARAMETER, not `activeTab.value`. Every read and every write in this module is about\n * one document — the one whose editor is mounted — and the focused tab is only incidentally that\n * document.\n *\n * @param {Tab | null | undefined} tab\n * @param {EditingTarget | null | undefined} editing\n */\nfunction getFunctionBody(tab: Tab | null | undefined, editing: EditingTarget | null | undefined) {\n const document = tab?.doc.document;\n // Read body off any object-shaped def (covers legacy entries without $prototype).\n const bodyOf = (def: unknown) =>\n isJsonObject(def) && typeof def.body === \"string\" ? def.body : \"\";\n if (editing?.type === \"def\") {\n return bodyOf(document?.state?.[editing.defName]);\n } else if (editing?.type === \"event\") {\n const node = getNodeAtPath(document!, editing.path);\n return node ? bodyOf(node[editing.eventKey]) : \"\";\n }\n return \"\";\n}\n\n/** Where Monaco goes inside the Logic tab. Empty on purpose — the editor fills it imperatively. */\nexport function functionEditorTemplate(): TemplateResult {\n return html`<div class=\"fw-code\"></div>`;\n}\n\n/**\n * Create, re-target or tear down the Monaco instance for the Logic tab's current body.\n *\n * The panel's `afterRender` hook, so it runs against the DOM lit has just painted.\n *\n * @param {HTMLElement} host The panel body element the Logic tab was rendered into.\n */\nexport function syncFunctionEditor(host: HTMLElement): void {\n const tab = activeTab.value;\n const editing = tab?.session.ui.editingFunction as EditingTarget | null | undefined;\n const container = editing && tab ? host.querySelector<HTMLElement>(\".fw-code\") : null;\n if (!container || !tab || !editing) {\n // Either nothing is open in the code surface, or the formula surface is showing: whichever\n // Monaco instance we hold is detached DOM, and holding it leaks a model plus its listeners.\n disposeFunctionEditor();\n return;\n }\n\n const current = view.functionEditor;\n const attached = Boolean(current && container.contains(current.getDomNode() as Node | null));\n /* THE TAB IS HALF OF THE IDENTITY, and the half that used to be missing.\n `_editingTarget` is a JSON string built from the target alone, and the ordinary target\n `{\"eventKey\":\"onclick\",\"path\":[\"children\",0],\"type\":\"event\"}` is the SAME string for the first\n button on any two pages. Two tabs whose strings match would take this branch across a tab\n switch, keeping an editor whose buffer holds the OTHER document's handler — and, once the\n buffer is ahead, keeping it without even re-syncing. Comparing the tab by identity turns that\n into the rebuild it always was. */\n if (\n current &&\n attached &&\n current._editingTab === tab &&\n current._editingTarget === JSON.stringify(editing)\n ) {\n /* THE RE-SYNC, and the one thing it is not allowed to do.\n This branch exists for the edit that arrives from somewhere else — an undo, a collaborator,\n a rename that rewrote the body — and its job is to show it. The comparison it makes is\n \"buffer ≠ document\", which is ALSO true of every keystroke between a keypress and the 500ms\n commit; resolving that in the document's favour reverts what is being typed. And because the\n dock repaints on Problems counts, Activity and a 30-second git poll, that window is hit by\n events the author never connected to their editor: the word half-finished under the cursor\n jumps back to what it was a moment ago, for no reason they can see.\n `bufferMovedOn` is the difference between the two cases. An edit from elsewhere lands while\n the buffer is settled; a keystroke does not. */\n const body = getFunctionBody(tab, editing);\n if (!bufferMovedOn(current) && current.getValue() !== body) {\n current._ignoreNextChange = true;\n current.setValue(body);\n // The buffer just took the DOCUMENT's text, so the two agree again. Declared rather than\n // Inferred: clause 3 is a fact the writer owns, and this write is the one that clears it.\n current._writes?.markSettled();\n }\n return;\n }\n\n disposeFunctionEditor();\n container.textContent = \"\";\n const body = getFunctionBody(tab, editing);\n const args = getFunctionArgs(editing, tab.doc.document);\n void mountFunctionEditor(container, tab, editing, body, args);\n}\n\n/**\n * Drop the function editor, its model, and the debounced work armed over it. Safe to call when\n * there is nothing to drop.\n *\n * **What happens to the armed commit is the whole correctness of the teardown.** Monaco's\n * `dispose()` runs `_detachModel()`, and `CodeEditorWidget.getValue()` opens with `if\n * (!this._modelData) return \"\";`. A disposed editor therefore answers the EMPTY STRING, not the\n * buffer it was holding. The mount arms a 500ms timer that reads `getValue()` and writes it into\n * the document, so every surviving timer was a scheduled deletion of the user's handler:\n *\n * - Type, then click Problems / the dock's × / ⌘\\ to another pane — `syncFunctionEditor` disposes\n * synchronously, and half a second later the body is `\"\"` and the tab is dirty.\n * - Worse, click **Close** — `closeFunctionEditor` minifies, writes the correct body, disposes, and\n * the orphan timer overwrites that correct write with `\"\"`. The action that exists to save the\n * work was the one that destroyed it.\n *\n * The takeover never saw this because it was torn down by exactly one thing (closing it, which\n * happened to be slower than the debounce). A dock tab is torn down by five, four of them new in\n * P8. Handling it here rather than guarding inside each callback is deliberate: a guard on \"is this\n * still the current editor?\" is passed by a timer that fires after a REMOUNT.\n *\n * **But cancelling alone is the same loss with the alarm switched off.** The armed commit IS the\n * last half-second of typing; dropping it means the pre-typing body survives instead of an empty\n * one, and `doc.dirty` stays `false`, so nothing anywhere says an edit went missing. Five ways out\n * of the surface measured as silent loss — switching the dock tab, opening another target, opening\n * a formula through `openLogicTarget`, collapsing the dock, and a same-target switch to another\n * TAB. {@link commitBufferWrites} reads the buffer while it is still alive, writes it to the tab it\n * was mounted for, and only then drops what is left. The order is the fix, not the call.\n *\n * **Seven, and the last two are not this function's.** ⌘W / the tab × and quitting destroy the TAB:\n * `closeTab` deletes it from `workspace.tabs` before any repaint reaches this disposer, so the\n * commit flushed here finds `tabIsLive(tab) === false` and correctly writes nothing. Those two are\n * fixed at the gate that decides — `services/monaco-buffer.ts`'s `commitTabBuffers` runs the commit\n * while the tab is still open, and `tabBufferUnsaved` answers for typing no commit could land.\n *\n * **AND THE COMMIT IS ALLOWED TO FAIL, at which point this is a deletion.** The collab freeze\n * refuses the body write outright; a collaborator deleting the element the handler hangs off leaves\n * `editing.path` resolving to nothing. Either way `commitBufferWrites` returns false, and the very\n * next line detaches the model — so `buffersForTab` stops finding the buffer and `tabBufferUnsaved`\n * goes back to answering \"nothing to lose\" about text that no longer exists anywhere.\n *\n * Refusing the teardown is not on offer here, which is why the answer is a message rather than a\n * bail-out: every caller is a repaint or a mode transition that has ALREADY replaced the container\n * (the dock's `afterRender`, `closeFunctionEditor`'s tail), so keeping the instance would keep a\n * live Monaco bound to detached DOM — the leak `syncFunctionEditor` exists to close, and an editor\n * the author cannot see or reach is not a rescued edit. `closeFunctionEditor` is where a refusal\n * DOES keep the surface, because it is a gesture and the surface is still standing.\n */\nexport function disposeFunctionEditor(): void {\n const editor = view.functionEditor;\n if (editor) {\n commitBufferWrites(editor, \"logic\");\n editor.dispose();\n view.functionEditor = null;\n }\n}\n\n/**\n * The one way a body is written into a document, bound to the tab and target it is for.\n *\n * Two callers used to carry their own copy of this def/event branch — the 500ms commit and the\n * Close — and each resolved the tab it wrote to at CALL time, through `activeTab.value`. That is\n * \"whatever is focused now\", which is the tab the buffer came from only when nothing happened in\n * between. Bound here instead, at mount, so the two cannot answer differently and neither can\n * answer with a document the buffer was never filled from.\n *\n * `tabIsLive` rather than \"is it active\": the write belongs to its tab whether or not that tab is\n * the one on screen, and a tab that has been CLOSED is the one case where the write must not happen\n * at all — nothing would ever read it, and `transactDoc` would still push history and dirty a\n * document the user has already dismissed.\n *\n * **A WRITE IS ALLOWED TO BE REFUSED, and the buffer has to hear about it.** `transactDoc` consults\n * the collab gate, which under the source-canonical freeze blocks every structural edit including\n * the lock holder's own — so this returns having changed nothing. Settling the buffer anyway told\n * `tabBufferUnsaved` (and therefore `shouldWarnOnClose` and `hasUnsavedTabs`) that the document had\n * been given the author's text when it had not, and every subsequent close discarded it without a\n * word. So the settle is conditional on the write LANDING, and the answer is handed back to the\n * caller: the debounce has nothing useful to do with it (the gate raises its own keyed toast on\n * every refusal), but the Close does — see {@link closeFunctionEditor} — and so does every\n * disposer, through `commitBufferWrites`.\n *\n * **Three ways it does not land, not one.** The tab is gone; the collab gate refuses; or the node\n * `editing.path` names has been deleted out from under the open editor, in which case there is no\n * coordinate to write to at all.\n *\n * @param {Tab} tab The document this buffer was filled from.\n * @param {EditingTarget} editing The def or event binding inside it.\n * @param {BufferWrites} [writes] The buffer's debounce holder, when there is a buffer: a completed\n * write is precisely what settles clause 3.\n * @returns {(body: string) => boolean} True when the body reached the document.\n */\nfunction bodyWriter(tab: Tab, editing: EditingTarget, writes?: BufferWrites) {\n return (newBody: string): boolean => {\n if (!tabIsLive(tab)) {\n return false;\n }\n let wrote = false;\n if (editing.type === \"def\") {\n wrote = transactDoc(tab, (t) => mutateUpdateDef(t, editing.defName, { body: newBody }));\n } else if (editing.type === \"event\") {\n const node = getNodeAtPath(tab.doc.document, editing.path);\n /* THE ELEMENT THE HANDLER HANGS OFF CAN GO WHILE THE EDITOR IS OPEN — a collaborator's\n delete arriving over the wire, or the author's own ⌘Z. `editing.path` then resolves to\n nothing, and `mutateUpdateProperty` read `getNodeAtPath(...)[key]` straight through it:\n `undefined is not an object`, thrown out of the 500ms commit and, through\n `commitBufferWrites`, out of the dock panel's `afterRender`.\n There is no coordinate left to write the body to, so the honest answer is that the write\n did not happen. Reporting it as a success would settle the buffer and tell every close\n gate the document had been given text that has nowhere to be. */\n if (!node) {\n return false;\n }\n const current = node[editing.eventKey] || {};\n wrote = transactDoc(tab, (t) =>\n mutateUpdateProperty(t, editing.path, editing.eventKey, {\n ...(current as object),\n $prototype: \"Function\",\n body: newBody,\n }),\n );\n }\n // The document now holds what the buffer holds — clause 3 is cleared by the write that made it\n // True, not by a timer expiring, and never by a write that was refused.\n if (wrote) {\n writes?.markSettled();\n }\n return wrote;\n };\n}\n\n/**\n * Close the code surface: minify what is in the buffer, write it back, and clear the target.\n *\n * The write is the reason the Close is a real one rather than a tab switch. It lived in `studio.ts`\n * beside the pane context bar's crumb, which was its only caller; the Logic tab's Close is the\n * second, and a body-saving routine that two surfaces call belongs beside the editor whose buffer\n * it reads.\n *\n * **The minify is an await, and a retarget fits inside it.** The buffer and the target are both\n * read BEFORE it; the teardown after it acts on whatever is mounted then. Open A, click Close, and\n * while `minify` is in flight click \"Open in code editor\" on B: the write still belongs to A and\n * still lands on A, but the dispose-and-clear would have killed B's live editor and closed a\n * document position the user had just asked for. So the write is unconditional and the TEARDOWN is\n * conditional — they answer to different moments in time and only one of them is still A's.\n *\n * **But that is TWO obligations, and only one of them is the editor's.** Guarding the whole tail on\n * `view.functionEditor === editor` conflated them, and the case it got wrong is the ordinary one:\n * an editor torn down inside the minify and NOT retargeted — collapse the dock, select Problems, ⌘\\\n * to another pane — leaves `view.functionEditor` null, so the guard bailed and `editingFunction`\n * was never cleared. Nothing else clears it, so the Logic tab stayed on the strip pointing at a\n * body the user had just dismissed, and re-opening the dock restored the editor they closed.\n * Disposing belongs to the instance; clearing the target belongs to the TARGET, and the only thing\n * with a claim on the target is a retarget that already replaced it.\n *\n * **The write goes through the editor's own `_commitBody`, not through the focused tab.** That\n * writer was bound at mount to the tab and target this buffer belongs to, so the Close and the\n * debounce cannot land in different places. An editor handle this module did not mount carries no\n * writer, and then the only meaning the gesture has left is its own tab and its own target — the\n * same {@link bodyWriter}, bound to those.\n *\n * **AND THE WRITE CAN BE REFUSED, in which case there is nothing left to close over.** Under the\n * source-canonical freeze the collab gate blocks the body commit, and this used to carry on:\n * minify, refused write, `cancelBufferWrites` (the armed commit gone too), dispose, target cleared.\n * The Close button — the one action whose entire purpose is to save the body — destroyed it, and\n * the standing \"frozen\" chip in the presence strip does not say that a button just did nothing. A\n * refusal therefore keeps the surface exactly as it is (the text stays on screen, the target stays\n * open) and says why, once, through the same Problems/toast channel every other failed write uses.\n * Nothing is re-armed: the buffer is still marked typed, so the close and quit gates already know\n * the work exists.\n */\nexport async function closeFunctionEditor(): Promise<void> {\n const tab = activeTab.value;\n const editing = tab?.session.ui.editingFunction as EditingTarget | null | undefined;\n if (!tab || !editing) {\n return;\n }\n const editor = view.functionEditor;\n if (editor) {\n const currentCode = editor.getValue();\n const minResult = await codeService(\"minify\", { code: currentCode });\n /* Cancelled AFTER the round trip, not before it. Either position stops the armed commit from\n replaying raw text over the minified body, but cancelling first means a minify that REJECTS\n takes the user's last keystrokes with it — there would be no armed commit left to write them.\n Left armed, the worst case is that the timer fires mid-await and writes the same text to the\n same target a moment before the minified version lands on top of it. */\n cancelBufferWrites(editor);\n const write = editor._commitBody ?? bodyWriter(tab, editing);\n if (!write(minResult?.code ?? currentCode)) {\n notify.warn(\n \"The handler could not be saved — source editing holds this document. Your code is still in the editor.\",\n {\n key: \"logic.close-refused\",\n source: \"Logic\",\n ...(tab.documentPath ? { path: tab.documentPath } : {}),\n },\n );\n return;\n }\n if (view.functionEditor !== null && view.functionEditor !== editor) {\n return;\n }\n // A no-op when the teardown already happened, which is the whole point: the clear below still\n // Runs, because a target with no editor is precisely the state nothing else resolves.\n disposeFunctionEditor();\n }\n updateUi(activeTab.value, \"editingFunction\", null);\n}\n\n/**\n * Whether the mount started for `container` / `tab` / `editing` is still the one the app wants.\n *\n * The three clauses `services/monaco-lazy.ts` states, spelled for this surface: the container is\n * still in the document, no other mount has already produced the editor, and the dock still wants\n * exactly this tab and this target. Asked AFTER the Monaco load, because that load is a cold\n * dynamic import of 12.6 MB and the user has hundreds of milliseconds to close the surface,\n * retarget it or switch tabs inside it — each of which used to end with a live editor nobody could\n * reach, assigned to `view.functionEditor` where the next sync would overwrite the handle rather\n * than dispose it.\n *\n * `activeTab.value === tab` covers the tab having been closed as well as merely left: a closed tab\n * is nobody's active tab, and the dock only ever shows the active one's target.\n */\nfunction functionMountWanted(container: HTMLElement, tab: Tab, editing: EditingTarget): boolean {\n return mountStillWanted(container, view.functionEditor, () => {\n const current = activeTab.value;\n return (\n current === tab &&\n JSON.stringify(current.session.ui.editingFunction ?? null) === JSON.stringify(editing)\n );\n });\n}\n\n/**\n * Create the function-body editor once Monaco has loaded.\n *\n * The container is in the DOM when this is called and the target is current — but neither is still\n * guaranteed on the far side of the `await`, which is why {@link functionMountWanted} is asked\n * again there. Nothing else covers it: `syncFunctionEditor` runs from the dock's `afterRender`, so\n * it cannot see a mount that has not produced an editor yet.\n *\n * **`tab` is captured here and never re-read.** Everything below — the commit, the format\n * continuation, the lint continuations — names THIS tab, because a buffer belongs to the document\n * it was filled from and to no other. Resolving through `activeTab.value` at callback time meant\n * the 500ms commit addressed whatever tab was focused when the timer fired: open `a.json`, Edit\n * Event Handler on `children[0].onclick`, open `b.json`, same handler, type one character in A and\n * click B's tab inside the window, and B's handler was replaced by A's buffer while A never\n * received the edit at all.\n */\nasync function mountFunctionEditor(\n editorContainer: HTMLElement,\n tab: Tab,\n editing: EditingTarget,\n body: string,\n args: string[],\n): Promise<void> {\n const monacoNs = await loadMonaco();\n if (!functionMountWanted(editorContainer, tab, editing)) {\n return;\n }\n // Completions used to register at studio startup, which would now await the lazy load and undo it.\n // The editor is the only surface they serve, and the registration is idempotent.\n void registerFunctionCompletions();\n const editor: FunctionEditor = monacoNs.editor.create(editorContainer, {\n automaticLayout: true,\n fontFamily: \"'JetBrains Mono', 'SF Mono', 'Fira Code', 'Consolas', monospace\",\n fontSize: 12,\n language: \"javascript\",\n lineNumbers: \"on\",\n minimap: { enabled: false },\n scrollBeyondLastLine: false,\n tabSize: 2,\n theme: \"vs-dark\",\n value: body,\n wordWrap: \"on\",\n });\n editor._editingTarget = JSON.stringify(editing);\n editor._editingTab = tab;\n const writes = bufferWrites(editor);\n\n // The writer this buffer will use for the rest of its life, bound to the tab and target it was\n // Mounted for. The debounce below and `closeFunctionEditor` both go through it.\n editor._commitBody = bodyWriter(tab, editing, writes);\n view.functionEditor = editor;\n\n let lintGen = 0;\n\n // Format on open — show pretty-printed code, then run initial lint.\n //\n // Both continuations address `editor`, not `view.functionEditor`. That handle is a variable, and\n // A code service round-trip is long enough to retarget twice: it names whatever is mounted NOW,\n // So answering a stale request through it wrote one def's formatted body into another def's\n // Editor. `editor` is the instance the request was made FOR, and the identity check is how a\n // Request that outlived it says nothing at all.\n //\n // Identity is where that reasoning STOPPED, and the common case is the one it misses: no\n // Retarget happened, so the guard passes — and a cold format round trip is long enough to type\n // Into. What lands is the formatting of the body as it was BEFORE those keystrokes, on top of\n // Them. `body` is what the request was computed from, so passing it as `expected` is the whole\n // Difference between \"still the same editor\" and \"still the same text\".\n void codeService(\"format\", { args, code: body }).then((result) => {\n if (\n result?.code != null &&\n view.functionEditor === editor &&\n tabIsLive(tab) &&\n !bufferMovedOn(editor, body)\n ) {\n editor._ignoreNextChange = true;\n editor.setValue(result.code);\n /* AND SAY SO, or the next repaint un-formats it in front of the author.\n This text did not come from the document and is deliberately never committed to it, so the\n buffer is now ahead. Inferred from the debounce it would read as \"settled\" — `setValue`\n sets `_ignoreNextChange`, the change handler returns before it can arm anything — and the\n re-sync branch would resolve the difference in the document's favour. With the dock\n repainting on the Problems badge, on Activity and on a 30-second git poll, \"Format on open\"\n visibly undid itself within seconds of every open. */\n writes.markAhead();\n }\n });\n void codeService(\"lint\", { args, code: body }).then((result) => {\n if (\n result?.diagnostics &&\n view.functionEditor === editor &&\n tabIsLive(tab) &&\n bufferIsLive(editor)\n ) {\n setLintMarkers(editor, result.diagnostics as OxLintDiagnostic[]);\n }\n });\n\n editor.onDidChangeModelContent(() => {\n if (editor._ignoreNextChange) {\n editor._ignoreNextChange = false;\n return;\n }\n\n // A keystroke. The buffer is ahead of the document from this instant until the commit lands —\n // Stated as a fact rather than left to be read off the timer, because the timer is only ONE of\n // The ways a buffer gets ahead and the other one is invisible to it. `markTyped` rather than\n // `markAhead`: this text is the AUTHOR'S, so it is also the text a close would destroy, and\n // Format-on-open's (below) is not.\n writes.markTyped();\n\n writes.arm(BUFFER_COMMIT, 500, () => {\n editor._commitBody?.(editor.getValue());\n renderOnly(\"leftPanel\");\n });\n\n writes.arm(\"lint\", 750, () => {\n lintGen += 1;\n const gen = lintGen;\n const currentCode = editor.getValue();\n void codeService(\"lint\", { args, code: currentCode }).then((result) => {\n // `lintGen` is per-MOUNT, so it can only order this editor's own requests; a remount\n // Starts a fresh generation that a stale closure's `gen` still matches. The identity check\n // Is the half that spans mounts, and the tab is the half that spans documents.\n if (\n gen !== lintGen ||\n view.functionEditor !== editor ||\n !tabIsLive(tab) ||\n !bufferIsLive(editor)\n ) {\n return;\n }\n if (result?.diagnostics) {\n setLintMarkers(editor, result.diagnostics as OxLintDiagnostic[]);\n }\n });\n });\n });\n}\n\n// Register Monaco JS completion provider for state scope variables (once)\nexport async function registerFunctionCompletions() {\n if (view._completionRegistered) {\n return;\n }\n view._completionRegistered = true;\n const monacoNs = await loadMonaco();\n monacoNs.languages.registerCompletionItemProvider(\"javascript\", {\n provideCompletionItems(model, position) {\n if (!activeTab.value) {\n return { suggestions: [] };\n }\n const defs = activeTab.value.doc.document?.state || {};\n const word = model.getWordUntilPosition(position);\n const range = {\n endColumn: word.endColumn,\n endLineNumber: position.lineNumber,\n startColumn: word.startColumn,\n startLineNumber: position.lineNumber,\n };\n\n // Named-formula catalog metadata enriches their completions with documentation.\n const formulaDocs = new Map(namedFormulaEntries(defs).map((e) => [e.name, e.description]));\n\n const suggestions: monaco.languages.CompletionItem[] = Object.entries(defs).map(\n ([key, def]) => {\n let kind = monacoNs.languages.CompletionItemKind.Variable;\n if (\n (def as JxPrototypeDef)?.$prototype === \"Function\" ||\n (def as Record<string, unknown>)?.$handler ||\n formulaDocs.has(key)\n ) {\n kind = monacoNs.languages.CompletionItemKind.Function;\n } else if ((def as JxPrototypeDef)?.$prototype) {\n kind = monacoNs.languages.CompletionItemKind.Property;\n }\n const item: monaco.languages.CompletionItem = {\n insertText: `state.${key}`,\n kind,\n label: `state.${key}`,\n range,\n };\n const documentation = formulaDocs.get(key);\n if (documentation) {\n item.documentation = documentation;\n }\n return item;\n },\n );\n\n // Blessed pure globals from the formula catalog (Math.*, JSON.*, Object.*, …).\n for (const entry of globalEntries()) {\n suggestions.push({\n documentation: entry.description,\n insertText: `window.${entry.label}`,\n kind: monacoNs.languages.CompletionItemKind.Function,\n label: entry.label,\n range,\n });\n }\n return { suggestions };\n },\n triggerCharacters: [\".\"],\n });\n}\n",
11
+ "/**\n * Display formatting for live expression-preview values, shared by the parent-side snapshot\n * evaluator (services/preview-eval.ts) and the in-iframe live evaluator (canvas/iframe-eval.ts) so\n * both realms badge values with identical truncation rules. Dependency-light and DOM-free (the\n * strip-events pattern) so importing it never grows the iframe bundle.\n */\n\nconst MAX_BADGE_LENGTH = 48;\n\n/** Format a runtime value as a short badge string. */\nexport function formatPreviewValue(value?: unknown): string {\n if (value === undefined) {\n return \"undefined\";\n }\n let text: string;\n try {\n text =\n typeof value === \"string\" ? JSON.stringify(value) : (JSON.stringify(value) ?? \"undefined\");\n } catch {\n text = String(value);\n }\n if (text.length > MAX_BADGE_LENGTH) {\n text = `${text.slice(0, MAX_BADGE_LENGTH - 1)}…`;\n }\n return text;\n}\n",
12
+ "/// <reference lib=\"dom\" />\n/**\n * Parent-side live expression preview (spec §19.9).\n *\n * Evaluates an expression node against the canvas iframe's last dataScope snapshot\n * (tab.session.canvas.scope) on a structuredClone, so mutating operators are safe — they mutate the\n * clone, never the live canvas. The engine's trace hook reports every sub-node's value keyed by its\n * path within the tree; values are formatted to display strings at report time so later mutations\n * of the clone cannot retroactively change a badge.\n */\n\nimport { evaluateExpression, isMutating } from \"@jxsuite/runtime/expression\";\nimport { toRaw } from \"../reactivity\";\n// Imported for local use AND re-exported below so existing consumers keep their import site.\n// oxlint-disable-next-line unicorn/prefer-export-from\nimport { formatPreviewValue } from \"../utils/preview-format\";\n\nimport type { ExpressionNode } from \"@jxsuite/runtime/expression\";\n\nexport interface ExpressionPreview {\n /** Path-keyed display values: \"\" is the root node, \"value/target\" a nested operand, etc. */\n values: Map<string, string>;\n /** Evaluation error message, if the expression threw. */\n error: string | null;\n /** Whether the root operator mutates its target (badge renders as an effect, not a value). */\n mutating: boolean;\n}\n\n// The formatter is shared with the in-iframe live evaluator: it lives in utils/preview-format.ts\n// (dependency-light, safe for the iframe bundle) and is re-exported here so existing consumers\n// Keep their import site.\nexport { formatPreviewValue };\n\n/**\n * Evaluate `node` against a scope snapshot for display. Returns null when no snapshot is available\n * (canvas not yet rendered) — the editor renders no badges rather than wrong ones.\n */\nexport function previewExpression(\n node: unknown,\n scope?: Record<string, unknown> | null,\n): ExpressionPreview | null {\n if (!scope || !node || typeof node !== \"object\" || !(\"operator\" in node)) {\n return null;\n }\n\n let state: Record<string, unknown>;\n try {\n // Callers hand over tab.session.canvas.scope, which the reactive session tree wraps in a\n // Proxy — structuredClone rejects proxies, so unwrap to the raw snapshot first.\n state = structuredClone(toRaw(scope));\n } catch {\n // Snapshot values are JSON-safe by construction (serialize-scope), but stay defensive.\n return null;\n }\n\n const values = new Map<string, string>();\n const expr = node as ExpressionNode;\n let errorMessage: string | null = null;\n try {\n evaluateExpression(expr, state, null, undefined, {\n report: (path, value) => values.set(path.join(\"/\"), formatPreviewValue(value)),\n });\n } catch (error) {\n errorMessage = error instanceof Error ? error.message : String(error);\n }\n\n return { error: errorMessage, mutating: isMutating(expr.operator), values };\n}\n",
13
+ "/// <reference lib=\"dom\" />\n/**\n * Live expression preview (M6) — upgrades the parent-side snapshot evaluation\n * (services/preview-eval.ts) to LIVE-context evaluation inside the canvas iframe, over the\n * `evalExpr`/`evalResult` bridge. The iframe evaluates against the real resolved scope (real\n * repeater items, real `window#/` globals, uncapped values); the snapshot evaluator stays the\n * fallback whenever no iframe host can answer (canvas not mounted, workspace takeover, timeout,\n * stale-gen reply).\n *\n * Call sites stay synchronous: {@link livePreviewExpression} returns the freshest available preview\n * immediately (the retained live result when it matches the expression, else the snapshot\n * evaluation) and kicks a debounced live refresh; when a CHANGED live result lands it is stored on\n * `tab.session.canvas.livePreviews` (mirroring how `canvas.scope` is stored) and the caller's\n * `onUpdate` re-renders the panel through its existing scheduler.\n */\n\nimport { isMutating } from \"@jxsuite/runtime/expression\";\nimport { previewExpression } from \"./preview-eval\";\nimport { requestCanvasEval } from \"../canvas/iframe-host\";\n\nimport type { ExpressionPreview } from \"./preview-eval\";\nimport type { StoredLivePreview, Tab } from \"../tabs/tab\";\n\n/** Debounce (ms) between a call site's render and the posted evalExpr — the presence-measure idiom. */\nexport const LIVE_PREVIEW_DEBOUNCE_MS = 100;\n\n/** Pending debounced refreshes keyed by `tabId\u0000targetId` (latest expression wins). */\nconst timers = new Map<string, ReturnType<typeof setTimeout>>();\n\n/** The staleness key a stored live result is checked against: the expression + its context. */\nfunction exprKeyOf(node: unknown, contextPath: (string | number)[] | null): string {\n return JSON.stringify([node, contextPath]);\n}\n\n/** Whether `node` is an evaluable expression node (same gate as previewExpression). */\nfunction isExprNode(node: unknown): node is { operator: string } {\n return Boolean(node && typeof node === \"object\" && \"operator\" in node);\n}\n\n/** Rebuild an ExpressionPreview from stored/wire values (mutating derives from the node itself). */\nfunction toPreview(\n node: { operator: string },\n values: [string, string][],\n error: string | null,\n): ExpressionPreview {\n return { error, mutating: isMutating(node.operator), values: new Map(values) };\n}\n\n/**\n * Ask the canvas iframe to evaluate `node` live. Resolves null when no host answers (no iframe for\n * this tab, ~300ms timeout, or a stale-gen reply) — the caller falls back to the snapshot.\n */\nasync function fetchLivePreview(\n tab: Tab,\n node: { operator: string },\n contextPath: (string | number)[] | null,\n): Promise<ExpressionPreview | null> {\n const results = await requestCanvasEval(tab.id, [{ id: \"0\", node }], contextPath);\n const result = results?.find((r) => r.id === \"0\");\n return result ? toPreview(node, result.values, result.error ?? null) : null;\n}\n\n/**\n * Evaluate `node` for display, preferring the live canvas scope: live-context evaluation in the\n * iframe when a host answers within the timeout, else the parent-side snapshot evaluation. Returns\n * null when `node` is not an expression node or no evaluation basis exists at all.\n */\nexport async function requestLivePreview(\n tab: Tab,\n node: unknown,\n contextPath: (string | number)[] | null = null,\n): Promise<ExpressionPreview | null> {\n if (!isExprNode(node)) {\n return null;\n }\n const live = await fetchLivePreview(tab, node, contextPath);\n return live ?? previewExpression(node, tab.session.canvas.scope);\n}\n\n/**\n * Synchronous call-site wrapper. Returns the retained live preview when it matches this exact\n * expression+context, else the snapshot evaluation — and (debounced) refreshes the live result in\n * the background, invoking `onUpdate` only when a CHANGED result lands so re-render loops cannot\n * self-sustain (an identical refresh stores silently and the chain stops).\n */\nexport function livePreviewExpression(\n tab: Tab | null | undefined,\n targetId: string,\n node: unknown,\n contextPath: (string | number)[] | null = null,\n onUpdate?: () => void,\n): ExpressionPreview | null {\n if (!tab || !isExprNode(node)) {\n return null;\n }\n const key = exprKeyOf(node, contextPath);\n scheduleLiveRefresh(tab, targetId, node, contextPath, key, onUpdate);\n const stored = tab.session.canvas.livePreviews?.[targetId];\n if (stored && stored.key === key) {\n return toPreview(node, stored.values, stored.error);\n }\n return previewExpression(node, tab.session.canvas.scope);\n}\n\n/** Debounce a live refresh for (tab, target); the latest expression/context/callback wins. */\nfunction scheduleLiveRefresh(\n tab: Tab,\n targetId: string,\n node: { operator: string },\n contextPath: (string | number)[] | null,\n key: string,\n onUpdate?: () => void,\n): void {\n const timerKey = `${tab.id}\u0000${targetId}`;\n const existing = timers.get(timerKey);\n if (existing) {\n clearTimeout(existing);\n }\n timers.set(\n timerKey,\n setTimeout(() => {\n timers.delete(timerKey);\n void (async () => {\n const live = await fetchLivePreview(tab, node, contextPath);\n if (!live) {\n return; // No live answer — the call site keeps rendering the snapshot values.\n }\n const stored: StoredLivePreview = {\n error: live.error,\n key,\n values: [...live.values.entries()],\n };\n const prev = tab.session.canvas.livePreviews?.[targetId];\n const changed =\n !prev ||\n prev.key !== key ||\n prev.error !== stored.error ||\n JSON.stringify(prev.values) !== JSON.stringify(stored.values);\n (tab.session.canvas.livePreviews ??= {})[targetId] = stored;\n if (changed) {\n onUpdate?.();\n }\n })();\n }, LIVE_PREVIEW_DEBOUNCE_MS),\n );\n}\n",
14
+ "/// <reference lib=\"dom\" />\n/**\n * ⑪ · Logic — the formula workspace and the function editor, hosted by the Bottom dock.\n *\n * **What changed, and why it is the whole point.** Both of these surfaces used to TAKE OVER the\n * canvas: `TabUi.editingFormula` (this file) and `TabUi.editingFunction` (`panels/editors.ts`) each\n * cleared `canvasWrap`, dropped every canvas panel and drew themselves over the stage. So the one\n * artefact whose values you are authoring — the page — was the one thing you could not see while\n * authoring them, and the workspace's own data rail existed to paper over it: a frozen snapshot of\n * a scope, shown because the live thing had just been unmounted. Plan §12 P8.5: \"no editor hides\n * the page it computes.\" They are a **tab of the Bottom dock** now (§3.2 ⑪), which sits under the\n * pane grid, so the page renders beside the formula and keeps rendering while you edit it.\n *\n * **A dock tab is not a reparented takeover.** The surface has to work at dock height, so the\n * header is one row, the chip pipeline and the result are single lines, the data rail is a narrow\n * column that scrolls rather than a 280px slab, and every measurement lives in `styles/panels.css`\n * instead of the inline `style=` attributes that kept seventeen `fw-*` classes on\n * `scripts/check-styles.ts`'s orphan list.\n *\n * **One target, two surfaces, one tab.** {@link logicTarget} is the single reader of the two\n * `TabUi` fields, and the function editor wins when both are set — the precedence `tabs/tab.ts` has\n * always documented, now stated in exactly one place. The tab's `when` is that same predicate, so\n * Logic exists only while something is open in it, and `panels/bottom-dock.ts` reveals the dock on\n * that tab when a target appears.\n *\n * **The close is real.** Both surfaces carry one, and closing is the only thing that clears the\n * target — leaving the dock, switching tabs and collapsing the dock all keep your place, because\n * the editor no longer owns a screen it would otherwise be stranded on.\n *\n * Every edit immutably replaces the selected sub-node within the root and writes the WHOLE root\n * node back through `transactDoc` — undo/redo and the canvas patch come free, and because the\n * canvas is still mounted the patch lands in a page you can watch.\n */\n\nimport { html } from \"lit-html\";\nimport { getEventBinding, isExpressionDef, isJsonObject } from \"@jxsuite/schema/guards\";\n\nimport { shallowRef } from \"../reactivity\";\nimport { getNodeAtPath, updateUi } from \"../store\";\nimport { activeTab } from \"../workspace/workspace\";\nimport { mutateAddDef, mutateUpdateDef, mutateUpdateProperty, transactDoc } from \"../tabs/transact\";\nimport { setBottomTab } from \"../shell\";\nimport { chipSummary, renderFormulaChips } from \"../ui/formula-chips\";\nimport { renderExpressionEditor } from \"../ui/expression-editor\";\nimport { applyCatalogPick, formulaCatalog } from \"../ui/formula-catalog\";\nimport { openFormulaPalette } from \"../ui/formula-palette\";\nimport { livePreviewExpression } from \"../services/live-preview\";\nimport { closeFunctionEditor, functionEditorTemplate, syncFunctionEditor } from \"./editors\";\nimport { registerPanel } from \"./panel-registry\";\nimport { renderEmptyState } from \"./empty-state\";\nimport { dataTypeLabel, renderDataTreeTemplate, unwrapSignal } from \"./data-explorer\";\n\nimport {\n argsSchema,\n pathArg,\n pathProperty,\n stringArg,\n stringProperty,\n} from \"../commands/command-args\";\n\nimport type { JxNodeValue } from \"../tabs/transact\";\nimport type { AnyCommand, CommandRegistry } from \"../commands/registry\";\nimport type { PanelBody } from \"./panel-registry\";\nimport type { ExpressionPreview } from \"../services/preview-eval\";\nimport type { FormulaEditDef, FunctionEditDef, JsonValue } from \"../types\";\nimport type { Tab } from \"../tabs/tab\";\nimport type { JxStateDefinition } from \"@jxsuite/schema/types\";\nimport type { TemplateResult } from \"lit-html\";\n\ntype NodePath = (string | number)[];\n\n/** What the Logic tab is showing: the Monaco function body, or the structured `$expression`. */\nexport type LogicTarget =\n | { surface: \"function\"; editing: FunctionEditDef }\n | { surface: \"formula\"; editing: FormulaEditDef };\n\n/**\n * The Logic tab's target, or `null` when nothing is open in it.\n *\n * The ONE reader of `TabUi.editingFunction` / `TabUi.editingFormula`, and therefore the one place\n * their precedence is decided. Two surfaces used to answer that question separately — the canvas\n * render pipeline by branch order, the pane context bar by an `||` — which is two definition sites\n * for a rule neither of them stated.\n *\n * @param {Tab | null} [tab] The tab to read; defaults to the focused one.\n * @returns {LogicTarget | null}\n */\nexport function logicTarget(tab: Tab | null = activeTab.value): LogicTarget | null {\n const ui = tab?.session.ui;\n if (!ui) {\n return null;\n }\n if (ui.editingFunction) {\n return { editing: ui.editingFunction as FunctionEditDef, surface: \"function\" };\n }\n if (ui.editingFormula) {\n return { editing: ui.editingFormula as FormulaEditDef, surface: \"formula\" };\n }\n return null;\n}\n\n/**\n * Put the Logic tab on screen. Idempotent.\n *\n * `setBottomTab` is the shell's own \"reveal\" — it selects the tab AND opens the dock, for the same\n * reason `setActivityTab` does: \"show me the formula\" means the formula is on screen when the call\n * returns, not that a tab is selected inside a closed dock.\n */\nexport function revealLogicPanel(): void {\n setBottomTab(\"logic\");\n}\n\n/**\n * Open something in the Logic tab and put it on screen. The one WRITER of the two `TabUi` fields\n * {@link logicTarget} reads, as that is its one reader.\n *\n * **One tab holds one target, so opening either surface clears the other.** `logicTarget` gives the\n * function editor precedence when both are set, which is the right tie-break for a state that\n * should never occur — and every opener used to create it. Four buttons and two commands each set\n * their own field and left the other alone, so \"Open in formula workspace\" on an `$expression`\n * while a Function body was open was a dead click: the dock went on showing the function, and the\n * target key had not changed so nothing revealed either. Writing both fields here means the fifth\n * opener inherits the rule instead of re-deciding it.\n *\n * **The reveal is the OTHER half, and it is a different event from the dock's.**\n * `panels/bottom-dock.ts` reveals when a target APPEARS or CHANGES, at most once per target — that\n * is what lets you close the dock over an open formula and have it stay closed (§16.3). Neither\n * half can do the other's job: an effect on the target cannot see \"the user pressed the button\n * again\" (same target, no change, no reveal — the dock stayed shut and the button did nothing), and\n * a gesture cannot cover a target that appears without one. So the gesture says so explicitly, and\n * this is what makes a call to it a gesture.\n *\n * @param {LogicTarget} target The surface to show and what it should be pointed at.\n */\nexport function openLogicTarget(target: LogicTarget): void {\n updateUi(\n activeTab.value,\n \"editingFunction\",\n target.surface === \"function\" ? target.editing : null,\n );\n updateUi(activeTab.value, \"editingFormula\", target.surface === \"formula\" ? target.editing : null);\n revealLogicPanel();\n}\n\nfunction isExprNode(value: unknown): value is Record<string, unknown> {\n return isJsonObject(value) && typeof value.operator === \"string\";\n}\n\n// ─── Document access ─────────────────────────────────────────────────────────\n\n/** Read the workspace target's current root expression node from the document. */\nexport function formulaRoot(tab: Tab, editing: FormulaEditDef): Record<string, unknown> | null {\n const { document } = tab.doc;\n if (editing.type === \"def\" && editing.defName) {\n const def = document?.state?.[editing.defName];\n return isExpressionDef(def) ? (def.$expression as unknown as Record<string, unknown>) : null;\n }\n if (editing.type === \"event\" && editing.path && editing.eventKey) {\n const node = getNodeAtPath(document, editing.path);\n const binding = node ? getEventBinding(node, editing.eventKey) : undefined;\n return isExpressionDef(binding)\n ? (binding.$expression as unknown as Record<string, unknown>)\n : null;\n }\n return null;\n}\n\n/**\n * Resolve a chip selection to its editable node: the deepest expression-node prefix of `path` (head\n * chips target ref/literal operands; stale paths fall back toward the root).\n */\nfunction resolveSelection(\n root: Record<string, unknown>,\n path: NodePath,\n): { node: Record<string, unknown>; path: NodePath } {\n let current: unknown = root;\n let node: Record<string, unknown> = root;\n let nodePath: NodePath = [];\n for (const [i, seg] of path.entries()) {\n if (!current || typeof current !== \"object\") {\n break;\n }\n current = (current as Record<string, unknown>)[seg as keyof typeof current];\n if (isExprNode(current)) {\n node = current;\n nodePath = path.slice(0, i + 1);\n }\n }\n return { node, path: nodePath };\n}\n\n/** Immutably replace the value at `path` within `node` (object keys / array indexes). */\nfunction replaceAtPath(node: unknown, path: NodePath, value: unknown): unknown {\n if (path.length === 0) {\n return value;\n }\n const [head, ...rest] = path as [string | number, ...NodePath];\n if (Array.isArray(node)) {\n const copy = [...(node as unknown[])];\n copy[Number(head)] = replaceAtPath(copy[Number(head)], rest, value);\n return copy;\n }\n const base: Record<string, unknown> = isJsonObject(node) ? node : {};\n return { ...base, [head]: replaceAtPath(base[head as string], rest, value) };\n}\n\n/** Write the whole updated root node back to the document position (one undo step). */\nfunction writeRoot(tab: Tab, editing: FormulaEditDef, newRoot: unknown) {\n if (editing.type === \"def\" && editing.defName) {\n const { defName } = editing;\n transactDoc(tab, (t) => mutateUpdateDef(t, defName, { $expression: newRoot as JsonValue }));\n } else if (editing.type === \"event\" && editing.path && editing.eventKey) {\n const { eventKey, path } = editing;\n transactDoc(tab, (t) =>\n mutateUpdateProperty(t, path, eventKey, { $expression: newRoot } as JxNodeValue),\n );\n }\n}\n\n/** Close the workspace — clears `editingFormula`; the Logic tab leaves the strip with it. */\nexport function closeFormulaWorkspace() {\n updateUi(activeTab.value, \"editingFormula\", null);\n}\n\n// ─── The Logic tab ───────────────────────────────────────────────────────────\n\n/**\n * The chip selection, keyed by the target it belongs to.\n *\n * Keyed rather than reset, because the reset used to happen INSIDE the render — and a render that\n * writes the state it reads is a reactive loop the moment the surface becomes an effect, which is\n * exactly what hosting it in the dock makes it. A selection whose key no longer matches simply does\n * not apply, so retargeting starts at the root with nothing written.\n */\nconst _selection = shallowRef<{ tab: Tab | null; key: string; path: NodePath }>({\n key: \"\",\n path: [],\n tab: null,\n});\n\n/**\n * The document position a selection belongs to. Paired with the tab OBJECT, never its id: a tab\n * that was closed and reopened at the same path is a different document, and inheriting a chip\n * selection into it is how you edit the wrong sub-node of a formula that merely looks the same.\n */\nfunction selectionKey(editing: FormulaEditDef): string {\n return JSON.stringify(editing);\n}\n\n/**\n * Register the Bottom dock's Logic tab.\n *\n * Defined here and registered from `panels/bottom-dock.ts`, the same way Problems is defined beside\n * its notification store: the dock owns the strip, the surface owns the record.\n */\nexport function registerLogicPanel(): void {\n registerPanel({\n id: \"logic\",\n title: \"Logic\",\n level: \"document\",\n dock: \"bottom\",\n icon: \"sp-icon-event\",\n // No rail button: Logic has no steady state to badge. It exists while a formula or a function\n // Is open and leaves the strip when you close it, which is what `when` says below.\n rail: false,\n when: () => logicTarget() !== null,\n render: (ctx) => logicPanelBody(ctx.rerender),\n afterRender: (_ctx, host) => syncFunctionEditor(host),\n });\n}\n\n/**\n * What the Logic tab draws.\n *\n * @param {() => void} rerender The dock's repaint, handed to the live-preview refresh.\n * @returns {PanelBody}\n */\nexport function logicPanelBody(rerender: () => void): PanelBody {\n const tab = activeTab.value;\n const target = logicTarget(tab);\n if (!tab || !target) {\n return renderEmptyState({\n message: \"Open a formula or a function to edit it here, beside the page it computes.\",\n });\n }\n return target.surface === \"function\"\n ? functionPaneTemplate(target.editing)\n : workspaceTemplate(tab, target.editing, rerender);\n}\n\n/** The one header both surfaces wear: what is open, what kind it is, its verbs, and the close. */\nfunction logicHeaderTemplate(\n glyph: string,\n name: string,\n kind: string,\n title: string,\n verbs: TemplateResult | null,\n close: () => void,\n): TemplateResult {\n return html`\n <div class=\"fw-header\">\n <span class=\"fw-title\" title=${title}>${glyph} ${name}</span>\n <span class=\"fw-kind\">${kind}</span>\n <div class=\"fw-header-gap\"></div>\n ${verbs}\n <sp-action-button\n quiet\n size=\"s\"\n class=\"fw-close\"\n title=\"Close\"\n @click=${() => {\n close();\n }}\n >\n <sp-icon-close slot=\"icon\"></sp-icon-close>\n Close\n </sp-action-button>\n </div>\n `;\n}\n\n/** The Monaco function body, at dock height. The editor itself is mounted by `afterRender`. */\nfunction functionPaneTemplate(editing: FunctionEditDef): TemplateResult {\n const name = editing.defName ?? editing.eventKey ?? \"?\";\n return html`\n <div class=\"formula-workspace formula-workspace--code\">\n ${logicHeaderTemplate(\n \"ƒ\",\n name,\n editing.type === \"def\" ? \"function body\" : \"event handler\",\n editing.type === \"def\" ? `state/${name}` : name,\n null,\n () => {\n void closeFunctionEditor();\n },\n )}\n ${functionEditorTemplate()}\n </div>\n `;\n}\n\nfunction workspaceTemplate(\n tab: Tab,\n editing: FormulaEditDef,\n rerender: () => void,\n): TemplateResult {\n const stateEntries = (tab.doc.document?.state ?? {}) as Record<string, JxStateDefinition>;\n const name = (editing.type === \"def\" ? editing.defName : editing.eventKey) ?? \"?\";\n const root = formulaRoot(tab, editing);\n const kind = editing.type === \"def\" ? \"state expression\" : \"event expression\";\n const title = editing.type === \"def\" ? `state/${name}` : name;\n\n if (!root) {\n return html`\n <div class=\"formula-workspace\">\n ${logicHeaderTemplate(\"fx\", name, kind, title, null, closeFormulaWorkspace)}\n <div class=\"fw-body\">\n ${renderEmptyState({ message: \"No expression found at this document position.\" })}\n </div>\n </div>\n `;\n }\n\n const { scope } = tab.session.canvas;\n // Live-context evaluation in the canvas iframe with snapshot fallback (M6). The canvas is no\n // Longer unmounted while this surface is open — that is the entire point of the move — so the\n // Live path is the ORDINARY case now rather than the one that never happened. An event target's\n // Element path is the context, so repeater-template formulas bind the first item's $map scope.\n const preview = livePreviewExpression(\n tab,\n `formula:${JSON.stringify(editing)}`,\n root,\n editing.type === \"event\" ? (editing.path ?? null) : null,\n rerender,\n );\n const stored = _selection.value;\n const key = selectionKey(editing);\n const { node: selected, path: selectedPath } = resolveSelection(\n root,\n stored.tab === tab && stored.key === key ? stored.path : [],\n );\n const write = (next: unknown) => writeRoot(tab, editing, next);\n const writeSelected = (next: unknown) => write(replaceAtPath(root, selectedPath, next));\n const onChipSelect = (path: NodePath) => {\n _selection.value = { key, path, tab };\n };\n\n const catalogButton = html`\n <sp-action-button\n quiet\n size=\"s\"\n class=\"fw-browse-catalog\"\n title=\"Browse catalog\"\n @click=${(e: Event) =>\n openFormulaPalette({\n anchor: e.currentTarget as HTMLElement,\n entries: formulaCatalog(stateEntries),\n onPick: (entry) =>\n applyCatalogPick(entry, writeSelected, {\n onInsertDef: (defName, def) =>\n transactDoc(activeTab.value, (t) =>\n mutateAddDef(t, defName, def as Record<string, JsonValue>),\n ),\n stateEntries,\n }),\n })}\n >\n <sp-icon-brackets slot=\"icon\"></sp-icon-brackets>\n Catalog\n </sp-action-button>\n `;\n\n return html`\n <div class=\"formula-workspace\">\n ${logicHeaderTemplate(\"fx\", name, kind, title, catalogButton, closeFormulaWorkspace)}\n <div class=\"fw-chips\">${renderFormulaChips(root, onChipSelect, { preview })}</div>\n <div class=\"fw-body\">\n <div class=\"fw-editor\">\n <div class=\"fw-selected\">\n Selected:\n <span class=\"fw-selected-node\"\n >${selectedPath.length === 0 ? \"root\" : chipSummary(selected)}</span\n >\n </div>\n ${renderExpressionEditor(selected, writeSelected, {\n allowEventRef: editing.type === \"event\",\n depth: 1,\n path: selectedPath,\n preview,\n stateDefs: Object.keys(stateEntries),\n stateEntries,\n })}\n </div>\n ${dataRailTemplate(scope)}\n </div>\n ${resultTemplate(preview)}\n </div>\n `;\n}\n\n/** The live data context — a SECOND opinion now that the page itself is on screen, not the only one. */\nfunction dataRailTemplate(scope: Record<string, unknown> | null | undefined): TemplateResult {\n const scopeEntries = scope ? Object.entries(scope) : [];\n return html`\n <div class=\"fw-context\">\n <div class=\"fw-context-title\">Data</div>\n ${\n scopeEntries.length === 0\n ? html`<div class=\"empty-state\">No canvas data snapshot yet</div>`\n : scopeEntries.map(([name, value]) => {\n const unwrapped = unwrapSignal(value);\n return html`\n <div class=\"fw-context-entry\">\n <div class=\"fw-context-head\">\n <span class=\"fw-context-name\">${name}</span>\n <span class=\"fw-context-type\">${dataTypeLabel(value)}</span>\n </div>\n <div class=\"data-tree\">${renderDataTreeTemplate(unwrapped, 0, 4)}</div>\n </div>\n `;\n })\n }\n </div>\n `;\n}\n\n/** The root result, the evaluation error, or the honest \"nothing has evaluated this yet\". */\nfunction resultTemplate(preview: ExpressionPreview | null): TemplateResult {\n if (preview?.error) {\n return html`<div class=\"fw-result fw-result--error\">${preview.error}</div>`;\n }\n if (preview) {\n return html`\n <div class=\"fw-result\">\n = ${preview.values.get(\"\") ?? \"undefined\"}\n ${preview.mutating ? html`<span class=\"fw-result-note\">(mutates target)</span>` : \"\"}\n </div>\n `;\n }\n return html`\n <div class=\"fw-result fw-result--pending\">\n Preview unavailable — the canvas has not posted a data snapshot yet\n </div>\n `;\n}\n\n// ─── Commands ─────────────────────────────────────────────────────────────────\n\n/**\n * The formula/function EDITOR verbs — open a state entry's body or an event binding in Logic.\n *\n * They live here rather than beside `panels/editors.ts`'s renderer because this module already owns\n * the other half of the same idea: `editingFormula` (the structured workspace) and\n * `editingFunction` (the code editor) are two surfaces of ONE dock tab, addressing the same two\n * document positions — a state entry by `defName`, or an element event binding by `path` +\n * `eventKey`.\n *\n * Both REFUSE a target the document does not hold. The predecessors wrote `ui.editingFunction`\n * straight from the automation hook with no check at all, so a renamed def opened an editor over\n * nothing and the shot photographed an empty takeover.\n *\n * @returns {AnyCommand[]}\n */\nexport function formulaEditorCommands(): AnyCommand[] {\n return [\n {\n args: argsSchema({\n defName: stringProperty(\"The state entry whose body to open in the code editor.\"),\n }),\n category: \"Document\",\n id: \"formula.editDef\",\n level: \"document\",\n menus: [\"palette\"],\n group: \"5_data\",\n requires: \"an open document that defines state\",\n when: (ctx) => ctx.document.open,\n run: (_commandCtx, args) => {\n const defName = stringArg(\"formula.editDef\", args, \"defName\");\n const tab = activeTab.value;\n if (!tab) {\n throw new RangeError(`command \"formula.editDef\" needs an open document`);\n }\n const defs = tab.doc.document?.state ?? {};\n if (!(defName in defs)) {\n const defined = Object.keys(defs);\n throw new RangeError(\n `command \"formula.editDef\" argument \"defName\": \"${defName}\" is not a state entry ` +\n `this document defines — it defines: ` +\n `${defined.length > 0 ? defined.join(\", \") : \"nothing\"}`,\n );\n }\n openLogicTarget({ editing: { defName, type: \"def\" }, surface: \"function\" });\n },\n title: \"Edit Function\",\n },\n {\n args: argsSchema({\n eventKey: stringProperty('The event binding, e.g. \"onclick\".'),\n path: pathProperty(\"The document path of the element that carries the binding.\"),\n }),\n category: \"Document\",\n id: \"formula.editEvent\",\n level: \"document\",\n menus: [\"palette\"],\n group: \"5_data\",\n requires: \"an open document\",\n when: (ctx) => ctx.document.open,\n run: (_commandCtx, args) => {\n const eventKey = stringArg(\"formula.editEvent\", args, \"eventKey\");\n const path = pathArg(\"formula.editEvent\", args, \"path\");\n const tab = activeTab.value;\n if (!tab) {\n throw new RangeError(`command \"formula.editEvent\" needs an open document`);\n }\n if (!getNodeAtPath(tab.doc.document, path)) {\n throw new RangeError(\n `command \"formula.editEvent\" argument \"path\": [${path.join(\", \")}] addresses no ` +\n `node in ${tab.documentPath ?? \"the open document\"}`,\n );\n }\n openLogicTarget({ editing: { eventKey, path, type: \"event\" }, surface: \"function\" });\n },\n title: \"Edit Event Handler\",\n },\n ];\n}\n\n/**\n * Register the formula/function editor verbs.\n *\n * @param {CommandRegistry} registry\n */\nexport function registerFormulaEditorCommands(registry: CommandRegistry): void {\n registry.registerAll(formulaEditorCommands());\n}\n",
15
+ "/// <reference lib=\"dom\" />\n/**\n * Color-selector.js — Color input widget with swatch, text field, and popover picker.\n *\n * Uses sp-overlay trigger pattern for positioning (same as unit-selector and value-selector). The\n * popover content is a JxColorPopover LitElement that reactively syncs color between the area,\n * slider, and text field via a single `color` property.\n *\n * When the value is a var(--color-*) reference matching a defined color variable, the input\n * switches to picker mode showing the title-cased variable name (e.g. \"Primary Blue\") with a\n * swatch, similar to jx-value-selector's dual-mode behavior.\n */\n\nimport { LitElement, html, nothing } from \"lit\";\nimport { html as litHtml } from \"lit-html\";\nimport { live } from \"lit-html/directives/live.js\";\nimport { debouncedStyleCommit } from \"../store\";\nimport { activeTab } from \"../workspace/workspace\";\nimport { getEffectiveStyle } from \"../site-context\";\nimport { kebabToLabel } from \"../utils/studio-utils\";\n\ninterface ColorVar {\n name: string;\n value: string;\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\n/** Extract --color-* CSS custom properties from the effective (site + document) style. */\nfunction getColorVars() {\n const style = getEffectiveStyle(activeTab.value?.doc.document?.style);\n if (!style) {\n return [];\n }\n const vars = [];\n for (const [k, v] of Object.entries(style)) {\n if (k.startsWith(\"--color\") && (typeof v === \"string\" || typeof v === \"number\")) {\n vars.push({ name: k, value: String(v) });\n }\n }\n return vars;\n}\n\n/**\n * Convert a color variable name to a title-case label. Strips the \"--color-\" prefix and converts\n * kebab to title case. e.g. \"--color-primary-blue\" → \"Primary Blue\"\n */\nfunction varToLabel(name: string) {\n return kebabToLabel(name.replace(/^--color-?/, \"\"));\n}\n\n/** Resolve a color value for display — if it's a var() reference, look up the actual color. */\nfunction resolveColorForDisplay(val: string | number | undefined) {\n if (!val) {\n return \"transparent\";\n }\n const s = String(val);\n const m = s.match(/^var\\((--[^)]+)\\)$/);\n if (m) {\n const style = getEffectiveStyle(activeTab.value?.doc.document?.style);\n const resolved = style?.[m[1]!];\n if (typeof resolved === \"string\") {\n return resolved;\n }\n return \"transparent\";\n }\n return s;\n}\n\nfunction safeColor(val: string | number | undefined) {\n if (!val) {\n return \"transparent\";\n }\n return resolveColorForDisplay(val);\n}\n\n/** Normalize a color string to include # prefix for hex values. */\nfunction normalizeHex(c: string) {\n if (!c) {\n return c;\n }\n if (c.startsWith(\"var(\") || c.startsWith(\"rgb\") || c.startsWith(\"hsl\")) {\n return c;\n }\n return c.replace(/^#?/, \"#\");\n}\n\n/**\n * Check if a value is a var() reference that matches a defined color variable.\n *\n * @param {string | number | undefined} value\n * @param {{ name: string; value: string }[]} colorVars\n */\nfunction matchesColorVar(\n value: string | number | undefined,\n colorVars: { name: string; value: string }[],\n) {\n if (!value || typeof value !== \"string\") {\n return null;\n }\n const m = value.match(/^var\\((--[^)]+)\\)$/);\n if (!m) {\n return null;\n }\n return colorVars.find((cv) => cv.name === m[1]) || null;\n}\n\n// ─── JxColorPopover LitElement ──────────────────────────────────────────────\n\nexport class JxColorPopover extends LitElement {\n static override properties = {\n color: { type: String },\n colorVars: { attribute: false },\n displayColor: { attribute: false, type: String },\n };\n\n declare color: string;\n declare displayColor: string;\n declare colorVars: ColorVar[];\n\n constructor() {\n super();\n this.color = \"\";\n this.displayColor = \"#000000\";\n this.colorVars = [];\n }\n\n /** No shadow DOM — render directly into light DOM for Spectrum theming */\n override createRenderRoot() {\n return this;\n }\n\n /** @param {Map<string, unknown>} changed */\n override willUpdate(changed: Map<string, unknown>) {\n if (changed.has(\"color\")) {\n const raw = resolveColorForDisplay(this.color);\n if (!raw || raw === \"transparent\") {\n this.displayColor = \"#000000\";\n } else if (raw.startsWith(\"#\") || raw.startsWith(\"rgb\") || raw.startsWith(\"hsl\")) {\n this.displayColor = raw;\n } else {\n this.displayColor = `#${raw}`;\n }\n }\n }\n\n _handleArea(e: Event) {\n const color = normalizeHex(String((e.target as HTMLElement & { color: string }).color));\n this.displayColor = color;\n this.color = color;\n this.dispatchEvent(new CustomEvent(\"color-change\", { bubbles: true, detail: color }));\n }\n\n _handleSlider(e: Event) {\n const color = normalizeHex(String((e.target as HTMLElement & { color: string }).color));\n this.displayColor = color;\n this.color = color;\n this.dispatchEvent(new CustomEvent(\"color-change\", { bubbles: true, detail: color }));\n }\n\n _handleText(e: Event) {\n const val = (e.target as HTMLInputElement).value.trim();\n if (!val) {\n return;\n }\n this.displayColor = val;\n this.color = val;\n this.dispatchEvent(new CustomEvent(\"color-change\", { bubbles: true, detail: val }));\n }\n\n _handleSwatch(e: Event, varName: string) {\n e.stopPropagation();\n const varRef = `var(${varName})`;\n this.color = varRef;\n this.dispatchEvent(new CustomEvent(\"color-change\", { bubbles: true, detail: varRef }));\n }\n\n override render() {\n return html`\n <div class=\"color-popover-inner\">\n <sp-color-area\n style=\"width:200px; height:150px; --mod-colorarea-width:200px; --mod-colorarea-height:150px\"\n .color=${this.displayColor}\n @input=${this._handleArea}\n ></sp-color-area>\n <sp-color-slider\n style=\"width:200px; --mod-colorslider-length:200px\"\n .color=${this.displayColor}\n @input=${this._handleSlider}\n ></sp-color-slider>\n <sp-textfield\n size=\"s\"\n style=\"width:200px\"\n .value=${live(this.color || \"\")}\n placeholder=\"#000000\"\n @change=${this._handleText}\n ></sp-textfield>\n ${\n this.colorVars.length > 0\n ? html`\n <sp-divider size=\"s\"></sp-divider>\n <span class=\"color-popover-swatches-label\">Color Tokens</span>\n <sp-swatch-group size=\"xs\" border=\"light\" rounding=\"none\">\n ${this.colorVars.map(\n (cv) => html`\n <sp-swatch\n color=${cv.value}\n .value=${cv.name}\n title=${cv.name}\n @click=${(e: Event) => this._handleSwatch(e, cv.name)}\n ></sp-swatch>\n `,\n )}\n </sp-swatch-group>\n `\n : nothing\n }\n </div>\n `;\n }\n}\n\n// ─── Color input widget ─────────────────────────────────────────────────────\n\n/**\n * Render a color selector: swatch + text field + overlay popover. Uses sp-overlay trigger pattern\n * (same as unit-selector and value-selector).\n *\n * When value is a var(--color-*) matching a defined variable, switches to picker mode showing\n * title-cased label with swatch (e.g. \"Primary Blue\").\n *\n * @param {string} prop — property key (for debounce namespace)\n * @param {string | number | undefined} value — current color value\n * @param {(color: string) => void} onChange — commit callback\n * @returns {import(\"lit-html\").TemplateResult}\n */\nexport function renderColorSelector(\n /** @type {string} */ prop: string,\n /** @type {string | number | undefined} */ value: string | number | undefined,\n /** @type {(color: string) => void} */ onChange: (color: string) => void,\n) {\n const colorVars = getColorVars();\n const matchedVar = matchesColorVar(value, colorVars);\n const triggerId = `color-trigger-${prop}`;\n const pickerTriggerId = `color-picker-${prop}`;\n\n // ─── Picker mode: value matches a defined color variable ───\n if (matchedVar) {\n return litHtml`\n <div class=\"style-input-color\">\n <sp-swatch\n size=\"s\"\n rounding=\"none\"\n border=\"light\"\n color=${matchedVar.value}\n id=${triggerId}\n ></sp-swatch>\n <sp-overlay trigger=\"${triggerId}@click\" placement=\"bottom-start\" type=\"auto\">\n <sp-popover style=\"padding:12px\">\n <jx-color-popover\n .color=${value || \"\"}\n .colorVars=${colorVars}\n @color-change=${(e: CustomEvent) => onChange(e.detail as string)}\n ></jx-color-popover>\n </sp-popover>\n </sp-overlay>\n <sp-picker\n id=${pickerTriggerId}\n size=\"s\"\n style=\"flex:1; min-width:0\"\n .value=${`var(${matchedVar.name})`}\n @change=${(e: Event) => {\n e.stopPropagation();\n onChange((e.target as HTMLInputElement).value);\n }}\n >\n ${colorVars.map(\n (cv) => litHtml`\n <sp-menu-item value=${`var(${cv.name})`}>\n <sp-swatch\n slot=\"icon\"\n size=\"xs\"\n rounding=\"none\"\n border=\"light\"\n color=${cv.value}\n ></sp-swatch>\n ${varToLabel(cv.name)}\n </sp-menu-item>\n `,\n )}\n </sp-picker>\n </div>\n `;\n }\n\n // ─── Text mode: custom color value or empty ───\n return litHtml`\n <div class=\"style-input-color\" id=${triggerId}>\n <sp-swatch\n size=\"s\"\n rounding=\"none\"\n border=\"light\"\n color=${safeColor(value)}\n ></sp-swatch>\n <sp-textfield\n size=\"s\"\n style=\"flex:1; min-width:0\"\n .value=${live(value || \"\")}\n @click=${(e: Event) => e.stopPropagation()}\n @input=${debouncedStyleCommit(`color:${prop}`, 400, (e: Event) => {\n onChange((e.target as HTMLInputElement).value.trim());\n })}\n ></sp-textfield>\n <sp-overlay trigger=\"${triggerId}@click\" placement=\"bottom-start\" type=\"auto\">\n <sp-popover style=\"padding:12px\">\n <jx-color-popover\n .color=${value || \"\"}\n .colorVars=${colorVars}\n @color-change=${(e: CustomEvent) => onChange(e.detail as string)}\n ></jx-color-popover>\n </sp-popover>\n </sp-overlay>\n </div>\n `;\n}\n\n/** Whether any color popover is currently open. */\nexport function isColorPopoverOpen() {\n return Boolean(document.querySelector(\".style-input-color sp-overlay[open]\"));\n}\n",
16
+ "/** Style utilities — pure CSS helper functions used by the style panel. */\n\nimport type { JxMutableNode } from \"@jxsuite/schema/types\";\n\nimport { getNodeAtPath } from \"../store\";\nimport { activeTab } from \"../workspace/workspace\";\nimport { primarySelection } from \"../tabs/selection\";\nimport cssMeta from \"../../data/css-meta.json\";\n\nlet cssInitialMap = new Map<string, string>();\n\n/** Initialise cssInitialMap from webdata — call once during bootstrap. */\nexport function initCssData(webdata: { cssProps: string[][] }) {\n cssInitialMap = new Map(webdata.cssProps as [string, string][]);\n}\n\n/** Get the CSS initial-value map (populated by initCssData). */\nexport function getCssInitialMap() {\n return cssInitialMap;\n}\n\n// ─── Condition helpers ──────────────────────────────────────────────────────\n\n/** @param {{ prop: string; values: string[] }} cond @param {Record<string, unknown>} styles */\nexport function conditionPasses(\n cond: { prop: string; values: string[] },\n styles: Record<string, unknown>,\n) {\n const val = (styles[cond.prop] ?? \"\") as string;\n if (cond.values.length === 0) {\n return val !== \"\" && val !== \"initial\";\n }\n return cond.values.includes(val);\n}\n\n/**\n * @param {{ $show?: { prop: string; values: string[] }[] }} entry @param {Record<string, unknown>}\n * styles\n */\nexport function allConditionsPass(\n entry: { $show?: { prop: string; values: string[] }[] },\n styles: Record<string, unknown>,\n) {\n return (entry.$show ?? []).every((/** @type {{ prop: string; values: string[] }} */ c) =>\n conditionPasses(c, styles),\n );\n}\n\n// ─── Auto-open sections ─────────────────────────────────────────────────────\n\n/** @param {JxMutableNode} node @param {Record<string, boolean>} currentSections */\nexport function autoOpenSections(node: JxMutableNode, currentSections: Record<string, boolean>) {\n const style = node.style || {};\n const result = { ...currentSections };\n for (const prop of Object.keys(style)) {\n if (typeof style[prop] === \"object\") {\n continue;\n }\n const entry = (cssMeta.$defs as Record<string, Record<string, unknown>>)[prop];\n const section = (entry?.$section as string) ?? \"other\";\n if (!result[section]) {\n result[section] = true;\n }\n }\n return result;\n}\n\n// ─── Shorthand expand/compress ──────────────────────────────────────────────\n\n/** Get longhands for a shorthand property from css-meta */\nexport function getLonghands(shorthandProp: string) {\n const entry = (cssMeta.$defs as Record<string, Record<string, unknown>>)[shorthandProp];\n if (entry?.$longhands) {\n return (entry.$longhands as string[])\n .map((name: string) => ({\n entry: (cssMeta.$defs as Record<string, Record<string, unknown>>)[name] || {\n $order: 0,\n },\n name,\n }))\n .toSorted(\n (\n /** @type {{ entry: Record<string, unknown> }} */ a,\n /** @type {{ entry: Record<string, unknown> }} */ b,\n ) => (a.entry.$order as number) - (b.entry.$order as number),\n );\n }\n const result = [];\n for (const [name, e] of Object.entries(cssMeta.$defs) as [string, Record<string, unknown>][]) {\n if (e.$shorthand === shorthandProp) {\n result.push({ entry: e, name });\n }\n }\n result.sort((a, b) => (a.entry.$order as number) - (b.entry.$order as number));\n return result;\n}\n\n/**\n * Expand a CSS shorthand value into individual longhand values following the standard 1–4 value\n * TRBL pattern.\n */\nexport function expandShorthand(shortVal: string, count: number) {\n if (!shortVal) {\n return Array.from({ length: count }, () => \"\");\n }\n const parts = shortVal.trim().split(/\\s+/);\n if (count !== 4 || parts.length === 0) {\n return Array.from({ length: count }, () => \"\");\n }\n if (parts.length === 1) {\n return [parts[0], parts[0], parts[0], parts[0]];\n }\n if (parts.length === 2) {\n return [parts[0], parts[1], parts[0], parts[1]];\n }\n if (parts.length === 3) {\n return [parts[0], parts[1], parts[2], parts[1]];\n }\n return [parts[0], parts[1], parts[2], parts[3]];\n}\n\n/** Compress 4 TRBL values back into the shortest valid CSS shorthand string. */\nexport function compressShorthand(vals: string[]) {\n const [t, r, b, l] = vals;\n if (t === r && r === b && b === l) {\n return t;\n }\n if (t === b && r === l) {\n return `${t} ${r}`;\n }\n if (r === l) {\n return `${t} ${r} ${b}`;\n }\n return `${t} ${r} ${b} ${l}`;\n}\n\n// ─── Border-side shorthand parsing ──────────────────────────────────────────\n\nexport const BORDER_STYLES = new Set([\n \"none\",\n \"solid\",\n \"dashed\",\n \"dotted\",\n \"double\",\n \"groove\",\n \"ridge\",\n \"inset\",\n \"outset\",\n \"hidden\",\n]);\n\n/**\n * Parse a border-side shorthand value into [width, style, color].\n *\n * @param {string} value\n * @returns {string[]}\n */\nexport function expandBorderSide(value: string) {\n if (!value) {\n return [\"\", \"\", \"\"];\n }\n const tokens = [];\n let current = \"\";\n let depth = 0;\n for (const ch of value.trim()) {\n if (ch === \"(\") {\n depth += 1;\n }\n if (ch === \")\") {\n depth -= 1;\n }\n if (ch === \" \" && depth === 0) {\n if (current) {\n tokens.push(current);\n }\n current = \"\";\n } else {\n current += ch;\n }\n }\n if (current) {\n tokens.push(current);\n }\n\n let width = \"\";\n let style = \"\";\n let color = \"\";\n\n for (const tok of tokens) {\n if (!style && BORDER_STYLES.has(tok)) {\n style = tok;\n } else if (!width && /^[\\d.]/.test(tok)) {\n width = tok;\n } else {\n color = color ? `${color} ${tok}` : tok;\n }\n }\n\n return [width, style, color];\n}\n\n/**\n * Recompose border-side longhand values into a shorthand string.\n *\n * @param {string[]} vals\n * @returns {string}\n */\nexport function compressBorderSide(vals: string[]) {\n return vals.filter((v) => v && v.trim()).join(\" \");\n}\n\n// ─── Font helpers ───────────────────────────────────────────────────────────\n\n/** Extract --font-* CSS custom properties from the document root style. */\nexport function getFontVars() {\n const style = activeTab.value?.doc.document?.style;\n if (!style) {\n return [];\n }\n const vars = [];\n for (const [k, v] of Object.entries(style)) {\n if (k.startsWith(\"--font\") && (typeof v === \"string\" || typeof v === \"number\")) {\n vars.push({ name: k, value: String(v) });\n }\n }\n return vars;\n}\n\n/** Typography CSS properties that should preview their values in-menu */\nexport const TYPO_PREVIEW_PROPS = new Set([\n \"fontStyle\",\n \"fontVariant\",\n \"textTransform\",\n \"textDecoration\",\n]);\n\n/** Resolve the current font family for typography preview (handles var() references) */\nexport function currentFontFamily() {\n const tab = activeTab.value;\n const selected = primarySelection(tab?.session.selection);\n const node = selected ? getNodeAtPath(tab!.doc.document, selected) : null;\n const raw = node?.style?.fontFamily;\n if (!raw) {\n return \"\";\n }\n const m = typeof raw === \"string\" && raw.match(/^var\\((--[^)]+)\\)$/);\n if (m) {\n return tab?.doc.document?.style?.[m[1]!] || \"\";\n }\n return raw;\n}\n\nexport { default as cssMeta } from \"../../data/css-meta.json\";\nexport { camelToKebab } from \"../utils/studio-utils\";\n",
17
+ "/// <reference lib=\"dom\" />\n/**\n * Unit-selector.js — Number + unit picker widget.\n *\n * Renders a text field for numeric input paired with a unit picker dropdown. Handles keywords\n * (auto, inherit, etc.) alongside numeric+unit values.\n */\n\nimport { html, nothing } from \"lit-html\";\nimport { live } from \"lit-html/directives/live.js\";\nimport { classMap } from \"lit-html/directives/class-map.js\";\nimport { cancelStyleDebounce, debouncedStyleCommit } from \"../store\";\n\nexport const UNIT_RE = /^(-?[\\d.]+)(px|rem|em|%|vw|vh|svw|svh|dvh|ms|s|fr|ch|ex|deg)?$/;\n\n/**\n * Render a number + unit selector widget.\n *\n * @param {Record<string, unknown>} entry — css-meta entry with $units and $keywords arrays\n * @param {string} prop — property key (for debounce namespace)\n * @param {string | number | undefined} value — current value (e.g. \"12px\", \"auto\", \"\")\n * @param {(val: string) => void} onChange — commit callback\n * @param {string} [placeholder]\n * @returns {import(\"lit-html\").TemplateResult}\n */\nexport function renderUnitSelector(\n /** @type {Record<string, unknown>} */ entry: Record<string, unknown>,\n /** @type {string} */ prop: string,\n /** @type {string | number | undefined} */ value: string | number | undefined,\n /** @type {(val: string) => void} */ onChange: (val: string) => void,\n /** @type {string} */ placeholder = \"\",\n) {\n const units = (entry.$units || []) as string[];\n const keywords = (entry.$keywords || []) as string[];\n const strVal = String(value ?? \"\");\n const match = strVal.match(UNIT_RE);\n const isKeyword = !match && strVal !== \"\" && keywords.includes(strVal);\n const isNumericVal = (v: string) => /^-?\\d*\\.?\\d*$/.test(v);\n\n const currentUnit = isKeyword ? units[0] || \"\" : match ? match[2] || \"\" : units[0] || \"\";\n let displayValue;\n if (isKeyword) {\n displayValue = strVal;\n } else if (match) {\n displayValue = match[1]!;\n } else if (strVal !== \"\") {\n // Intentional partial parse: shorthand like \"10px 20px\" displays its leading number.\n // Number() yields NaN for those, so Number.parseFloat stays (see unit-selector tests).\n // oxlint-disable-next-line unicorn/prefer-number-coercion\n const num = Number.parseFloat(strVal);\n displayValue = Number.isNaN(num) ? strVal : String(num);\n } else {\n displayValue = \"\";\n }\n\n // Parse placeholder so inherited values display as \"500\" not \"500px\"\n const placeholderMatch = placeholder.match(UNIT_RE);\n const numericPlaceholder = placeholderMatch ? placeholderMatch[1]! : placeholder || \"0\";\n\n const isExpression = isKeyword || (displayValue !== \"\" && !isNumericVal(displayValue));\n const hasUnits = units.length > 0 || keywords.length > 0;\n const btnId = `style-unit-${prop}`;\n\n const commitValue = (rawVal: string) => {\n const val = rawVal.trim();\n if (val === \"\") {\n onChange(\"\");\n return;\n }\n if (isNumericVal(val)) {\n onChange(units.length > 0 ? val + currentUnit : val);\n } else {\n onChange(val);\n }\n };\n\n return html`\n <div class=\"style-input-number-unit\">\n <div\n class=${classMap({\n \"input-group\": true,\n \"is-expression\": isExpression,\n })}\n >\n <sp-textfield\n size=\"s\"\n placeholder=${numericPlaceholder}\n .value=${live(displayValue)}\n @input=${debouncedStyleCommit(`nui:${prop}`, 400, (e: Event) => {\n commitValue((e.target as HTMLInputElement).value);\n })}\n @change=${(e: Event) => {\n cancelStyleDebounce(`nui:${prop}`);\n commitValue((e.target as HTMLInputElement).value);\n }}\n ></sp-textfield>\n ${\n hasUnits\n ? html`\n <sp-picker-button id=${btnId} size=\"s\">\n <span slot=\"label\">${currentUnit || units[0] || \"\"}</span>\n </sp-picker-button>\n <sp-overlay trigger=\"${btnId}@click\" placement=\"bottom-end\" offset=\"4\">\n <sp-popover style=\"min-width: var(--spectrum-component-width-900, 64px)\">\n <sp-menu\n label=\"CSS unit\"\n @change=${(e: Event) => {\n const chosen = (e.target as HTMLInputElement).value;\n if (keywords.includes(chosen)) {\n onChange(chosen);\n } else if (units.includes(chosen)) {\n const curMatch = String(value ?? \"\").match(UNIT_RE);\n const numPart = curMatch ? curMatch[1] : \"\";\n if (numPart) {\n onChange(numPart + chosen);\n }\n }\n }}\n >\n ${units.map((u: string) => html`<sp-menu-item value=${u}>${u}</sp-menu-item>`)}\n ${\n keywords.length > 0 && units.length > 0\n ? html`<sp-menu-divider></sp-menu-divider>`\n : nothing\n }\n ${keywords.map(\n (kw: string) => html`<sp-menu-item value=${kw}>${kw}</sp-menu-item>`,\n )}\n </sp-menu>\n </sp-popover>\n </sp-overlay>\n `\n : nothing\n }\n </div>\n </div>\n `;\n}\n",
18
+ "// Packages/studio/icons.js\n// Icon templates for style sidebar button groups.\n// Uses Spectrum workflow icons where available; custom SVGs for flex-specific concepts.\n\nimport { html } from \"lit\";\n\nexport const icons = {\n // ─── Arrows — flexDirection ───\n \"arrow-right\": html`<sp-icon-arrow-right slot=\"icon\"></sp-icon-arrow-right>`,\n \"arrow-left\": html`<sp-icon-arrow-left slot=\"icon\"></sp-icon-arrow-left>`,\n \"arrow-down\": html`<sp-icon-arrow-down slot=\"icon\"></sp-icon-arrow-down>`,\n \"arrow-up\": html`<sp-icon-arrow-up slot=\"icon\"></sp-icon-arrow-up>`,\n\n // ─── Text align — textAlign ───\n \"text-align-left\": html`<sp-icon-text-align-left slot=\"icon\"></sp-icon-text-align-left>`,\n \"text-align-center\": html`<sp-icon-text-align-center slot=\"icon\"></sp-icon-text-align-center>`,\n \"text-align-right\": html`<sp-icon-text-align-right slot=\"icon\"></sp-icon-text-align-right>`,\n \"text-align-justify\": html`<sp-icon-text-align-justify slot=\"icon\"></sp-icon-text-align-justify>`,\n\n // ─── flexWrap ───\n \"wrap-text\": html`<sp-icon-flip-vertical slot=\"icon\"></sp-icon-flip-vertical>`,\n\n // ─── alignItems / alignSelf — vertical alignment within container ───\n \"align-start-v\": html`<sp-icon-align-top slot=\"icon\"></sp-icon-align-top>`,\n \"align-end-v\": html`<sp-icon-align-bottom slot=\"icon\"></sp-icon-align-bottom>`,\n \"align-center-v\": html`<sp-icon-align-middle slot=\"icon\"></sp-icon-align-middle>`,\n \"align-stretch-v\": html`<sp-icon-distribute-vertically\n slot=\"icon\"\n ></sp-icon-distribute-vertically>`,\n \"align-baseline\": html`<sp-icon-text-baseline-shift slot=\"icon\"></sp-icon-text-baseline-shift>`,\n\n // ─── justifyContent — horizontal distribution within container ───\n \"justify-start\": html`<sp-icon-align-left slot=\"icon\"></sp-icon-align-left>`,\n \"justify-end\": html`<sp-icon-align-right slot=\"icon\"></sp-icon-align-right>`,\n \"justify-center\": html`<sp-icon-align-center slot=\"icon\"></sp-icon-align-center>`,\n \"justify-between\": html`<sp-icon-distribute-space-horiz\n slot=\"icon\"\n ></sp-icon-distribute-space-horiz>`,\n \"justify-around\": html`<sp-icon-distribute-horizontally\n slot=\"icon\"\n ></sp-icon-distribute-horizontally>`,\n \"justify-evenly\": html`<sp-icon-distribute-horizontal-center\n slot=\"icon\"\n ></sp-icon-distribute-horizontal-center>`,\n\n // ─── display mode icons ───\n \"display-flex\": html`<sp-icon-view-column slot=\"icon\"></sp-icon-view-column>`,\n \"display-grid\": html`<sp-icon-view-grid slot=\"icon\"></sp-icon-view-grid>`,\n \"display-block\": html`<sp-icon-box slot=\"icon\"></sp-icon-box>`,\n \"display-inline\": html`<sp-icon-remove slot=\"icon\"></sp-icon-remove>`,\n \"display-none\": html`<sp-icon-visibility-off slot=\"icon\"></sp-icon-visibility-off>`,\n};\n",
19
+ "/// <reference lib=\"dom\" />\n/**\n * Button-group.js — Action group + overflow picker widget.\n *\n * Renders a compact button group for enum values with an optional overflow picker for additional\n * options that don't fit in the button bar.\n */\n\nimport { html, nothing } from \"lit-html\";\nimport { classMap } from \"lit-html/directives/class-map.js\";\nimport { abbreviateValue, kebabToLabel } from \"../utils/studio-utils\";\nimport { icons } from \"./icons\";\n\n/**\n * Render a button group widget with optional overflow menu.\n *\n * @param {Record<string, unknown>} entry — css-meta entry with $buttonValues, enum, $icons\n * @param {string} prop — property key (for menu ID namespace)\n * @param {string | number | undefined} value — current value\n * @param {(val: string) => void} onChange — commit callback\n * @returns {import(\"lit-html\").TemplateResult}\n */\nexport function renderButtonGroup(\n /** @type {Record<string, unknown>} */ entry: Record<string, unknown>,\n /** @type {string} */ prop: string,\n /** @type {string | number | undefined} */ value: string | number | undefined,\n /** @type {(val: string) => void} */ onChange: (val: string) => void,\n) {\n const values = (entry.$buttonValues || entry.enum || []) as string[];\n const iconMap: Record<string, string> = (entry.$icons || {}) as Record<string, string>;\n const buttonValues = entry.$buttonValues as string[] | undefined;\n const enumValues = entry.enum as string[] | undefined;\n const extra =\n buttonValues && enumValues && enumValues.length > buttonValues.length\n ? enumValues.filter((v: string) => !buttonValues.includes(v))\n : [];\n\n const menuId = `style-btngrp-${prop}`;\n const hasExtra = extra.length > 0;\n const extraSelected = hasExtra && extra.includes(String(value));\n\n return html`\n <div\n class=${classMap({\n \"button-group-combo\": true,\n \"has-overflow\": hasExtra,\n })}\n >\n <sp-action-group size=\"s\" compact>\n ${values.map(\n (v: string) => html`\n <sp-action-button\n size=\"s\"\n value=${v}\n title=${v}\n ?selected=${v === value}\n @click=${() => onChange(v === value ? \"\" : v)}\n >\n ${\n iconMap[v] && (icons as Record<string, unknown>)[iconMap[v]]\n ? (icons as Record<string, unknown>)[iconMap[v]]\n : abbreviateValue(v)\n }\n </sp-action-button>\n `,\n )}\n </sp-action-group>\n ${\n hasExtra\n ? html`\n <sp-picker-button\n size=\"s\"\n id=${menuId}\n class=${classMap({ \"has-selection\": extraSelected })}\n ></sp-picker-button>\n <sp-overlay trigger=\"${menuId}@click\" placement=\"bottom-end\" type=\"auto\">\n <sp-popover>\n <sp-menu\n @change=${(e: Event) => {\n if ((e.target as HTMLInputElement).value) {\n onChange((e.target as HTMLInputElement).value);\n }\n }}\n >\n <sp-menu-item value=\"__none__\">—</sp-menu-item>\n ${extra.map((v: string) => {\n const label = v.includes(\"-\")\n ? kebabToLabel(v)\n : v.replace(/^./, (c: string) => c.toUpperCase());\n return html`<sp-menu-item value=${v} ?selected=${v === value}\n >${label}</sp-menu-item\n >`;\n })}\n </sp-menu>\n </sp-popover>\n </sp-overlay>\n `\n : nothing\n }\n </div>\n `;\n}\n",
20
+ "/// <reference lib=\"dom\" />\n/**\n * Widgets.js — Widget type dispatcher and simple widget renderers.\n *\n * This module provides `widgetForType()` which dispatches to the appropriate widget based on the\n * inferred type from css-meta/schema entries, plus the simpler widget renderers (text, number,\n * select/combobox).\n *\n * Complex widgets are imported from their dedicated modules: - renderColorSelector →\n * ui/color-selector.js - renderUnitSelector → ui/unit-selector.js - renderButtonGroup →\n * ui/button-group.js\n */\n\nimport { html } from \"lit-html\";\nimport { live } from \"lit-html/directives/live.js\";\nimport { ifDefined } from \"lit-html/directives/if-defined.js\";\nimport { debouncedStyleCommit } from \"../store\";\nimport { renderColorSelector } from \"./color-selector\";\nimport { renderUnitSelector } from \"./unit-selector\";\nimport { renderButtonGroup } from \"./button-group\";\nimport { renderMediaPicker } from \"./media-picker\";\nimport type { TemplateResult } from \"lit-html\";\n\n/**\n * Render a plain text input widget.\n *\n * @param {string} prop\n * @param {string | number | undefined} value\n * @param {(val: string) => void} onChange\n * @param {string} [placeholder]\n * @returns {import(\"lit-html\").TemplateResult}\n */\nexport function renderTextInput(\n prop: string,\n value: string | number | undefined,\n onChange: (val: string) => void,\n placeholder = \"\",\n) {\n return html`\n <sp-textfield\n size=\"s\"\n placeholder=${placeholder}\n .value=${live(String(value ?? \"\"))}\n @input=${debouncedStyleCommit(`text:${prop}`, 400, (e: Event) =>\n onChange((e.target as HTMLInputElement).value),\n )}\n ></sp-textfield>\n `;\n}\n\n/**\n * Render a number input widget (sp-number-field).\n *\n * @param {Record<string, unknown>} entry\n * @param {string} prop\n * @param {string | number | undefined} value\n * @param {(val: string | number) => void} onChange\n * @param {string} [placeholder]\n * @returns {import(\"lit-html\").TemplateResult}\n */\nexport function renderNumberInput(\n entry: Record<string, unknown>,\n prop: string,\n value: string | number | undefined,\n onChange: (val: string | number) => void,\n placeholder = \"\",\n) {\n const minimum = entry.minimum as number | undefined;\n const maximum = entry.maximum as number | undefined;\n return html`\n <sp-number-field\n size=\"s\"\n hide-stepper\n .value=${live(value !== undefined && value !== \"\" ? Number(value) : undefined)}\n placeholder=${placeholder}\n min=${ifDefined(minimum)}\n max=${ifDefined(maximum)}\n step=${ifDefined(maximum !== undefined && maximum <= 1 ? 0.1 : undefined)}\n @change=${debouncedStyleCommit(`num:${prop}`, 400, (e: Event) => {\n const v = (e.target as HTMLInputElement & { value: number | undefined }).value;\n if (v === undefined || Number.isNaN(v)) {\n onChange(\"\");\n } else {\n onChange(Number(v));\n }\n })}\n ></sp-number-field>\n `;\n}\n\n/**\n * Dispatch to the appropriate widget based on inferred type.\n *\n * @param {string} type — one of: button-group, color, number-unit, number, select, combobox, text\n * @param {Record<string, unknown>} entry — css-meta or schema entry\n * @param {string} prop — property key\n * @param {string | number | undefined} value — current value\n * @param {(val: string | number) => void} onCommit — commit callback\n * @param {{\n * placeholder?: string;\n * renderSelect?: (\n * entry: Record<string, unknown>,\n * prop: string,\n * value: string | number | undefined,\n * onCommit: (val: string | number) => void,\n * ) => import(\"lit-html\").TemplateResult;\n * renderCombobox?: (\n * entry: Record<string, unknown>,\n * prop: string,\n * value: string | number | undefined,\n * onCommit: (val: string | number) => void,\n * ) => import(\"lit-html\").TemplateResult;\n * }} [opts]\n * @returns {import(\"lit-html\").TemplateResult}\n */\nexport function widgetForType(\n type: string,\n entry: Record<string, unknown>,\n prop: string,\n value: string | number | undefined,\n onCommit: (val: string | number) => void,\n opts: {\n placeholder?: string;\n renderSelect?: (\n entry: Record<string, unknown>,\n prop: string,\n value: string | number | undefined,\n onCommit: (val: string | number) => void,\n ) => TemplateResult;\n renderCombobox?: (\n entry: Record<string, unknown>,\n prop: string,\n value: string | number | undefined,\n onCommit: (val: string | number) => void,\n ) => TemplateResult;\n } = {},\n) {\n switch (type) {\n case \"button-group\": {\n return renderButtonGroup(entry, prop, value, onCommit);\n }\n case \"color\": {\n return renderColorSelector(prop, value, onCommit);\n }\n case \"number-unit\": {\n return renderUnitSelector(entry, prop, value, onCommit, opts.placeholder);\n }\n case \"number\": {\n return renderNumberInput(entry, prop, value, onCommit, opts.placeholder);\n }\n case \"media\": {\n return renderMediaPicker(prop, String(value ?? \"\"), onCommit);\n }\n case \"select\": {\n // Allow caller to override select rendering (e.g. for typography preview)\n if (opts.renderSelect) {\n return opts.renderSelect(entry, prop, value, onCommit);\n }\n return renderTextInput(prop, value, onCommit, opts.placeholder);\n }\n case \"combobox\": {\n // Allow caller to override combobox rendering (e.g. for font family)\n if (opts.renderCombobox) {\n return opts.renderCombobox(entry, prop, value, onCommit);\n }\n return renderTextInput(prop, value, onCommit, opts.placeholder);\n }\n default: {\n return renderTextInput(prop, value, onCommit, opts.placeholder);\n }\n }\n}\n",
21
+ "/// <reference lib=\"dom\" />\n/** Style input widgets — keyword, select, combobox, and font renderers for the style panel. */\n\nimport { html } from \"lit-html\";\nimport { live } from \"lit-html/directives/live.js\";\nimport { debouncedStyleCommit } from \"../store\";\nimport { activeTab } from \"../workspace/workspace\";\nimport { mutateUpdateStyle, transactDoc } from \"../tabs/transact\";\nimport { widgetForType as _widgetForType } from \"../ui/widgets\";\nimport { friendlyNameToVar, kebabToLabel, varDisplayName } from \"../utils/studio-utils\";\nimport {\n TYPO_PREVIEW_PROPS,\n camelToKebab,\n currentFontFamily,\n getCssInitialMap,\n getFontVars,\n} from \"./style-utils\";\n\n/**\n * Dual-mode keyword input — shared by select (enum) and combobox (examples) widgets.\n *\n * @param {string[]} options @param {string} prop @param {string} value @param {(value: string) =>\n * void} onChange\n */\nexport function renderKeywordInput(\n options: string[],\n prop: string,\n value: string,\n onChange: (value: string) => void,\n) {\n const cssInitialMap = getCssInitialMap();\n const isTypoPreview = TYPO_PREVIEW_PROPS.has(prop) || prop === \"fontWeight\";\n const font = isTypoPreview ? currentFontFamily() : \"\";\n const cssProp = isTypoPreview ? camelToKebab(prop) : \"\";\n\n const comboOptions = options.map((v: string) => {\n const label = v.includes(\"-\")\n ? kebabToLabel(v)\n : v.replace(/^./, (c: string) => c.toUpperCase());\n const style = isTypoPreview ? `${cssProp}: ${v};${font ? ` font-family: ${font}` : \"\"}` : \"\";\n return { label, style, value: v };\n });\n\n return html`<jx-value-selector\n size=\"s\"\n .value=${value || \"\"}\n placeholder=${cssInitialMap.get(prop) || \"\"}\n .options=${comboOptions}\n @change=${(e: Event) => onChange((e.target as HTMLInputElement).value)}\n @input=${debouncedStyleCommit(`kw:${prop}`, 400, (e: Event) =>\n onChange((e.target as HTMLInputElement).value),\n )}\n ></jx-value-selector>`;\n}\n\n/**\n * @param {Record<string, unknown>} entry @param {string} prop @param {string | number | undefined}\n * value @param {(value: string) => void} onChange\n */\nexport function renderSelectInput(\n entry: Record<string, unknown>,\n prop: string,\n value: string | number | undefined,\n onChange: (value: string) => void,\n) {\n const options = Array.isArray(entry.enum) ? (entry.enum as string[]) : [];\n return renderKeywordInput(options, prop, String(value ?? \"\"), onChange);\n}\n\n/** @param {{ title: string; value: string }} preset @param {(value: string) => void} onChange */\nfunction handleFontPresetSelection(\n preset: { title: string; value: string },\n onChange: (value: string) => void,\n) {\n const varName = friendlyNameToVar(preset.title, \"--font-\");\n if (!activeTab.value?.doc.document?.style?.[varName]) {\n transactDoc(activeTab.value, (t) => mutateUpdateStyle(t, [], varName, preset.value));\n }\n onChange(`var(${varName})`);\n}\n\n/**\n * @param {string} val @param {{ title: string; value: string }[]} presets @param {(value: string)\n * => void} onChange\n */\nfunction handleFontSelection(\n val: string,\n presets: { title: string; value: string }[],\n onChange: (value: string) => void,\n) {\n if (!val) {\n return;\n }\n if (val.startsWith(\"__preset__:\")) {\n const title = val.slice(\"__preset__:\".length);\n const preset = presets.find(\n (/** @type {{ title: string; value: string }} */ p) => p.title === title,\n );\n if (preset) {\n handleFontPresetSelection(preset, onChange);\n }\n return;\n }\n if (val.startsWith(\"--\")) {\n onChange(`var(${val})`);\n return;\n }\n const preset = presets.find(\n (/** @type {{ title: string; value: string }} */ p) => p.title === val,\n );\n if (preset) {\n handleFontPresetSelection(preset, onChange);\n return;\n }\n const fontVars = getFontVars();\n const matchedVar = fontVars.find(\n (/** @type {{ name: string; value: string }} */ fv) =>\n varDisplayName(fv.name, \"--font-\") === val,\n );\n if (matchedVar) {\n onChange(`var(${matchedVar.name})`);\n return;\n }\n onChange(val);\n}\n\n/**\n * Build font options array for jx-value-selector.\n *\n * @param {{ name: string; value: string }[]} fontVars @param {{ title: string; value: string }[]}\n * presets\n * @returns {({ value: string; label: string; style: string } | { divider: true })[]}\n */\nexport function buildFontOptions(\n fontVars: { name: string; value: string }[],\n presets: { title: string; value: string }[],\n) {\n const opts: ({ value: string; label: string; style: string } | { divider: true })[] =\n fontVars.map((fv) => ({\n label: varDisplayName(fv.name, \"--font-\"),\n style: `font-family: ${fv.value}`,\n value: fv.name,\n }));\n const unadded = presets.filter(\n (/** @type {{ title: string; value: string }} */ p) =>\n !fontVars.some(\n (/** @type {{ name: string; value: string }} */ fv) =>\n fv.name === friendlyNameToVar(p.title, \"--font-\"),\n ),\n );\n if (unadded.length > 0 && opts.length > 0) {\n opts.push({ divider: true });\n }\n for (const p of unadded) {\n opts.push({\n label: p.title,\n style: `font-family: ${p.value}`,\n value: `__preset__:${p.title}`,\n });\n }\n return opts;\n}\n\n/**\n * @param {{\n * enum?: string[];\n * examples?: string[];\n * presets?: { title: string; value: string }[];\n * }} entry\n * @param {string} prop @param {string} value @param {(value: string) => void} onChange\n */\nexport function renderComboboxInput(\n entry: Record<string, unknown>,\n prop: string,\n rawValue: string | number | undefined,\n onChange: (value: string) => void,\n) {\n const value = String(rawValue ?? \"\");\n const cssInitialMap = getCssInitialMap();\n const fontVars = prop === \"fontFamily\" ? getFontVars() : [];\n const presets = Array.isArray(entry.presets)\n ? (entry.presets as { title: string; value: string }[])\n : [];\n const examples = Array.isArray(entry.examples) ? (entry.examples as string[]) : [];\n\n if (prop === \"fontFamily\") {\n const varMatch = typeof value === \"string\" && value.match(/^var\\((--[^)]+)\\)$/);\n const comboValue = varMatch ? varMatch[1] : value || \"\";\n const fontOptions = buildFontOptions(fontVars, presets);\n return html`<jx-value-selector\n size=\"s\"\n .value=${comboValue}\n placeholder=${cssInitialMap.get(\"fontFamily\") || \"\"}\n .options=${fontOptions}\n @change=${(e: Event) =>\n handleFontSelection((e.target as HTMLInputElement).value, presets, onChange)}\n @input=${debouncedStyleCommit(\"combo:fontFamily\", 400, (e: Event) =>\n onChange((e.target as HTMLInputElement).value),\n )}\n ></jx-value-selector>`;\n }\n\n if (examples.length > 0) {\n return renderKeywordInput(examples, prop, value, onChange);\n }\n\n return html`\n <sp-textfield\n size=\"s\"\n placeholder=${cssInitialMap.get(prop) || \"\"}\n .value=${live(value || \"\")}\n @input=${debouncedStyleCommit(`combo:${prop}`, 400, (e: Event) =>\n onChange((e.target as HTMLInputElement).value),\n )}\n ></sp-textfield>\n `;\n}\n\n/**\n * Style-aware widgetForType — wraps the generic widget renderer with style-specific select/combobox\n * inputs and CSS initial-value placeholders.\n */\nexport function widgetForType(\n type: string,\n entry: Record<string, unknown>,\n prop: string,\n value: string,\n onCommit: (value: string) => void,\n opts: { placeholder?: string } = {},\n) {\n const cssInitialMap = getCssInitialMap();\n return _widgetForType(type, entry, prop, value, onCommit as (val: string | number) => void, {\n placeholder: opts.placeholder || cssInitialMap.get(prop) || \"\",\n renderCombobox: renderComboboxInput,\n renderSelect: renderSelectInput,\n });\n}\n",
22
+ "/**\n * @license\n * Copyright 2021 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nimport { nothing } from '../lit-html.js';\nimport { directive, Directive, } from '../directive.js';\nimport { setCommittedValue } from '../directive-helpers.js';\nclass Keyed extends Directive {\n constructor() {\n super(...arguments);\n this.key = nothing;\n }\n render(k, v) {\n this.key = k;\n return v;\n }\n update(part, [k, v]) {\n if (k !== this.key) {\n // Clear the part before returning a value. The one-arg form of\n // setCommittedValue sets the value to a sentinel which forces a\n // commit the next render.\n setCommittedValue(part);\n this.key = k;\n }\n return v;\n }\n}\n/**\n * Associates a renderable value with a unique key. When the key changes, the\n * previous DOM is removed and disposed before rendering the next value, even\n * if the value - such as a template - is the same.\n *\n * This is useful for forcing re-renders of stateful components, or working\n * with code that expects new data to generate new HTML elements, such as some\n * animation techniques.\n */\nexport const keyed = directive(Keyed);\n//# sourceMappingURL=keyed.js.map",
23
+ "/// <reference lib=\"dom\" />\n/**\n * Field-input.ts — Controlled text-input widgets with a draft-state layer.\n *\n * The single input paradigm for every Studio panel. Each field is identified by a stable `key`.\n * While a field is focused/edited, its in-progress text lives in a per-key DRAFT, decoupled from\n * the document. The visible value is always `getFieldValue(key, committed)` bound via lit's `live`\n * directive, so a render that slips through mid-edit never resets the field to a stale value.\n *\n * Commit semantics (consistent across all panels): commit a short debounce after typing pauses (so\n * the canvas/preview updates live) AND immediately on blur or Enter (so the latest value is never\n * lost). The draft is cleared on blur/Enter, after which the field reflects the committed (possibly\n * normalized) document value again.\n *\n * Pair this with the focus-aware panel scheduler (panels/panel-scheduler.ts), which keeps the panel\n * from re-rendering at all while a field is focused.\n */\n\nimport { html } from \"lit-html\";\nimport type { TemplateResult } from \"lit-html\";\nimport { live } from \"lit-html/directives/live.js\";\nimport { keyed } from \"lit-html/directives/keyed.js\";\nimport { LIVE_PREVIEW } from \"./timing\";\n\n/** A lit-renderable value (template or directive result). */\ntype Renderable = unknown;\n\ninterface DraftEntry {\n value: string;\n timer?: ReturnType<typeof setTimeout>;\n}\n\n/** Active per-field drafts, keyed by a stable field key. */\nconst _drafts = new Map<string, DraftEntry>();\n\n/** The committed value to show for a field — the live draft while editing, else `committed`. */\nexport function getFieldValue(key: string, committed: string): string {\n const d = _drafts.get(key);\n return d ? d.value : committed;\n}\n\n/** Whether a draft is currently being edited for `key`. */\nexport function hasDraft(key: string): boolean {\n return _drafts.has(key);\n}\n\n/** Record the in-progress value for a field without committing it. */\nexport function setDraft(key: string, value: string): void {\n const d = _drafts.get(key);\n if (d) {\n d.value = value;\n } else {\n _drafts.set(key, { value });\n }\n}\n\n/** Discard a field's draft (and cancel any pending debounced commit). */\nexport function clearDraft(key: string): void {\n const d = _drafts.get(key);\n if (d?.timer) {\n clearTimeout(d.timer);\n }\n _drafts.delete(key);\n}\n\n/**\n * Schedule a debounced commit of the current draft, KEEPING the draft afterwards so the field stays\n * controlled by the in-progress text until the user blurs. The committed value flows to the\n * document (live preview) while the cursor/text stay untouched. Exported for unit testing.\n */\nexport function scheduleDraftCommit(key: string, ms: number, commit: (v: string) => void): void {\n const d = _drafts.get(key);\n if (!d) {\n return;\n }\n if (d.timer) {\n clearTimeout(d.timer);\n }\n d.timer = setTimeout(() => {\n const cur = _drafts.get(key);\n if (!cur) {\n return;\n }\n delete cur.timer;\n commit(cur.value);\n }, ms);\n}\n\n/**\n * Flush a field's draft immediately (blur/Enter): commit the latest value and clear the draft so\n * the field reflects the committed document value on the next render.\n */\nexport function commitField(key: string, commit: (v: string) => void): void {\n const d = _drafts.get(key);\n if (!d) {\n return;\n }\n if (d.timer) {\n clearTimeout(d.timer);\n }\n const { value } = d;\n _drafts.delete(key);\n commit(value);\n}\n\n/** Shared option bag for the text widgets. */\nexport interface FieldOpts {\n placeholder?: string;\n size?: string;\n debounceMs?: number;\n /**\n * When to commit to the document: - \"live\" (default): debounced while typing AND on blur/Enter\n * (live preview). - \"blur\": only on blur/Enter — for fields where mid-typing commits are\n * disruptive (e.g. renaming a signal, which would rename on every keystroke pause).\n */\n commitMode?: \"live\" | \"blur\";\n /** Extra inline style for the control. */\n style?: string;\n /** Disable the control. */\n disabled?: boolean;\n}\n\ninterface TextAreaOpts extends FieldOpts {\n minHeight?: string;\n mono?: boolean;\n}\n\nfunction makeHandlers(\n key: string,\n ms: number,\n commit: (v: string) => void,\n commitMode: \"live\" | \"blur\" = \"live\",\n) {\n return {\n onCommit: (e: Event) => {\n const v = (e.target as HTMLInputElement).value;\n setDraft(key, v);\n commitField(key, commit);\n },\n onInput: (e: Event) => {\n const v = (e.target as HTMLInputElement).value;\n setDraft(key, v);\n if (commitMode === \"live\") {\n scheduleDraftCommit(key, ms, commit);\n }\n },\n onKeydown: (e: KeyboardEvent, multiline: boolean) => {\n if (e.key === \"Enter\" && !multiline) {\n commitField(key, commit);\n }\n },\n };\n}\n\n/**\n * Single-line Spectrum text field bound to the draft layer.\n *\n * @param key Stable field identity (e.g. \"head:og:title\", \"fm:title\", \"prop:0/1/className\").\n * @param value Committed value from the document.\n * @param commit Writes the value to the document (transactDoc/mutate…).\n */\nexport function spTextField(\n key: string,\n value: string,\n commit: (v: string) => void,\n opts: FieldOpts = {},\n): Renderable {\n const ms = opts.debounceMs ?? LIVE_PREVIEW;\n const { onInput, onCommit, onKeydown } = makeHandlers(key, ms, commit, opts.commitMode);\n return keyed(\n key,\n html`\n <sp-textfield\n size=${opts.size ?? \"s\"}\n placeholder=${opts.placeholder ?? \"\"}\n ?disabled=${Boolean(opts.disabled)}\n style=${opts.style ?? \"\"}\n .value=${live(getFieldValue(key, value))}\n @input=${onInput}\n @change=${onCommit}\n @keydown=${(e: KeyboardEvent) => onKeydown(e, false)}\n ></sp-textfield>\n `,\n );\n}\n\n/** Multiline Spectrum text field bound to the draft layer (Enter inserts a newline). */\nexport function spTextArea(\n key: string,\n value: string,\n commit: (v: string) => void,\n opts: FieldOpts = {},\n): Renderable {\n const ms = opts.debounceMs ?? LIVE_PREVIEW;\n const { onInput, onCommit } = makeHandlers(key, ms, commit, opts.commitMode);\n return keyed(\n key,\n html`\n <sp-textfield\n multiline\n size=${opts.size ?? \"s\"}\n placeholder=${opts.placeholder ?? \"\"}\n ?disabled=${Boolean(opts.disabled)}\n style=${opts.style ?? \"\"}\n .value=${live(getFieldValue(key, value))}\n @input=${onInput}\n @change=${onCommit}\n ></sp-textfield>\n `,\n );\n}\n\n/** Native `<textarea class=\"field-input\">` bound to the draft layer (used by code-ish fields). */\nexport function rawTextArea(\n key: string,\n value: string,\n commit: (v: string) => void,\n opts: TextAreaOpts = {},\n): Renderable {\n const ms = opts.debounceMs ?? LIVE_PREVIEW;\n const { onInput, onCommit } = makeHandlers(key, ms, commit, opts.commitMode);\n const style = [\n `min-height:${opts.minHeight ?? \"40px\"}`,\n opts.mono ? \"font-family:var(--font-mono);font-size:var(--spectrum-font-size-50,11px)\" : \"\",\n opts.style ?? \"\",\n ]\n .filter(Boolean)\n .join(\";\");\n return keyed(\n key,\n html`\n <textarea\n class=\"field-input\"\n style=${style}\n placeholder=${opts.placeholder ?? \"\"}\n ?disabled=${Boolean(opts.disabled)}\n .value=${live(getFieldValue(key, value))}\n @input=${onInput}\n @change=${onCommit}\n ></textarea>\n `,\n );\n}\n\n/**\n * Spectrum number field. Numbers are short and not prone to the typing-truncation bug, so this\n * commits on change (blur/Enter) only — no draft buffering. `commit` receives the parsed number, or\n * undefined when the field is cleared / invalid.\n */\nexport function spNumberField(\n value: number | undefined,\n commit: (v: number | undefined) => void,\n opts: FieldOpts & { hideStepper?: boolean; min?: number; max?: number } = {},\n): TemplateResult {\n return html`\n <sp-number-field\n size=${opts.size ?? \"s\"}\n ?hide-stepper=${opts.hideStepper ?? true}\n ?disabled=${Boolean(opts.disabled)}\n style=${opts.style ?? \"\"}\n .value=${live(value !== undefined ? Number(value) : undefined)}\n @change=${(e: Event) => {\n const raw = (e.target as HTMLInputElement).value;\n const n = Number(raw);\n commit(raw === \"\" || Number.isNaN(n) ? undefined : n);\n }}\n ></sp-number-field>\n `;\n}\n",
24
+ "/**\n * Link-target.ts — pure, dependency-free helpers for classifying and composing anchor `href`\n * targets in the properties panel's Link section.\n *\n * `classifyHref` splits a raw href string into a discriminated `{ kind, value }` pair so the UI can\n * offer a target-kind selector (Internal page / External URL / #anchor / mailto: / tel:).\n * `composeHref` is its inverse — the two round-trip for every kind so editing through the UI never\n * corrupts an href.\n *\n * Both functions are total (never throw) and have no DOM or platform dependencies, so they are\n * fully unit-testable in isolation.\n */\n\n/** The distinct target kinds an anchor href can address. */\nexport type LinkKind = \"internal\" | \"external\" | \"anchor\" | \"mailto\" | \"tel\";\n\n/** A classified href: its {@link LinkKind} plus the \"bare\" value for that kind's input. */\nexport interface LinkTarget {\n kind: LinkKind;\n /**\n * The user-facing value for the kind's input: - internal → the path (e.g. `/about/`) - external →\n * the full href (e.g. `https://x.com`) - anchor → the fragment WITHOUT the leading `#` (e.g.\n * `section`) - mailto → the email address WITHOUT the `mailto:` scheme - tel → the phone number\n * WITHOUT the `tel:` scheme\n */\n value: string;\n}\n\n/** Matches an absolute URL scheme like `http://`, `https://`, `ftp://`, or protocol-relative `//`. */\nconst ABSOLUTE_SCHEME = /^([a-z][a-z\\d+.-]*:)?\\/\\//i;\n\n/**\n * Classify a raw `href` string into a {@link LinkTarget}.\n *\n * Rules (checked in order): 1. `mailto:…` → `{ kind: \"mailto\", value: address }` 2. `tel:…` → `{\n * kind: \"tel\", value: number }` 3. `#…` → `{ kind: \"anchor\", value: rest }` (leading `#` stripped)\n * 4. absolute (`http(s)://…`) or protocol-relative (`//…`) → `{ kind: \"external\", value: href }` 5.\n * `/…` → `{ kind: \"internal\", value: path }` 6. anything else → `{ kind: \"external\", value: href\n * }`\n *\n * @param href The raw attribute value (may be empty)\n */\nexport function classifyHref(href = \"\"): LinkTarget {\n const value = href;\n const lower = value.toLowerCase();\n\n if (lower.startsWith(\"mailto:\")) {\n return { kind: \"mailto\", value: value.slice(\"mailto:\".length) };\n }\n if (lower.startsWith(\"tel:\")) {\n return { kind: \"tel\", value: value.slice(\"tel:\".length) };\n }\n if (value.startsWith(\"#\")) {\n return { kind: \"anchor\", value: value.slice(1) };\n }\n if (ABSOLUTE_SCHEME.test(value)) {\n return { kind: \"external\", value };\n }\n if (value.startsWith(\"/\")) {\n return { kind: \"internal\", value };\n }\n return { kind: \"external\", value };\n}\n\n/**\n * Compose an `href` string from a {@link LinkKind} and its bare value — the inverse of\n * {@link classifyHref}. An empty (or whitespace-only) value yields `\"\"` for every kind so callers\n * can treat \"cleared\" uniformly. Round-trips with `classifyHref` for every kind.\n *\n * @param kind The target kind\n * @param value The bare value for that kind (address/number/fragment/path/href)\n */\nexport function composeHref(kind: LinkKind, value: string): string {\n const bare = (value ?? \"\").trim();\n if (!bare) {\n return \"\";\n }\n switch (kind) {\n case \"mailto\": {\n return `mailto:${bare}`;\n }\n case \"tel\": {\n return `tel:${bare}`;\n }\n case \"anchor\": {\n return bare.startsWith(\"#\") ? bare : `#${bare}`;\n }\n // Internal / external — the bare value IS the href.\n default: {\n return bare;\n }\n }\n}\n",
25
+ "/// <reference lib=\"dom\" />\n/**\n * The Content tab — everything about WHAT this element is and says.\n *\n * Plan §6.5 re-split the inspector by task. Content is the element itself (tag, id, class, text),\n * its HTML attributes, its link target, its custom attributes, its component props and its media.\n * Three things left, and each left for a place that already had a better claim on it:\n *\n * - **Repeater · Switch · Observed Attributes · CSS Properties · CSS Parts → the Logic tab.** Wiring\n * a `$switch` and wiring a click handler are the same task (`panels/events-panel.ts`).\n * - **The Page section → the Document Header card.** `panels/head-panel.ts` owns the one layout\n * picker; this panel drew a second one that could disagree with it.\n * - **Media breakpoint DEFINITIONS → Project Settings › Contexts** (P4). Nothing remains here: the\n * only reason adding a breakpoint used to cost you your element selection.\n *\n * What is left is one accordion of rows, all of which go through `ui/field-row.ts`.\n */\n\nimport { html, nothing } from \"lit-html\";\nimport type { TemplateResult } from \"lit-html\";\nimport { live } from \"lit-html/directives/live.js\";\nimport { debouncedStyleCommit, getNodeAtPath, renderOnly } from \"../store\";\nimport { displayTagName, isRef, isTagExpression } from \"@jxsuite/schema/guards\";\nimport type { DirEntry, JsonValue } from \"../types\";\nimport {\n mutateUpdateAttribute,\n mutateUpdateDef,\n mutateUpdateProp,\n mutateUpdateProperty,\n transactDoc,\n} from \"../tabs/transact\";\nimport { activeTab, workspace } from \"../workspace/workspace\";\nimport { deriveRefusal } from \"../workspace/pane-derive\";\nimport { primarySelection, unifyValues } from \"../tabs/selection\";\nimport { shell } from \"../shell\";\nimport {\n argsSchema,\n booleanArg,\n booleanProperty,\n stringArg,\n stringProperty,\n} from \"../commands/command-args\";\nimport type { LayoutSelection } from \"../shell\";\nimport type { AnyCommand, CommandRegistry } from \"../commands/registry\";\nimport { activeRegistry } from \"../commands/active-registry\";\nimport { componentRegistry } from \"../files/components\";\nimport { widgetForType } from \"./style-inputs\";\nimport { renderFieldRow, renderKvRow } from \"../ui/field-row\";\nimport type { FieldProvenance } from \"./provenance\";\nimport { renderDynamicSlot, slotMode } from \"../ui/dynamic-slot\";\nimport { spTextArea, spTextField } from \"../ui/field-input\";\nimport { attrLabel, camelToLabel, inferInputType, parseCemType } from \"../utils/studio-utils\";\nimport { classifyHref, composeHref } from \"../utils/link-target\";\nimport type { LinkKind } from \"../utils/link-target\";\nimport {\n clickAnythingTo,\n openPageAction,\n renderEmptyState,\n staleSelectionMessage,\n} from \"./empty-state\";\nimport { renderMediaPicker } from \"../ui/media-picker\";\nimport { renderColorSelector } from \"../ui/color-selector\";\nimport {\n loadUsages,\n peekUsages,\n retryUsages,\n usageFiles,\n usageHeadline,\n} from \"../services/references\";\nimport { getPlatform } from \"../platform\";\nimport htmlMeta from \"../../data/html-meta.json\";\n\nimport type {\n JxAttributeValue,\n JxMutableNode,\n JxPrototypeDef,\n JxStateDefinition,\n JxStateObject,\n} from \"@jxsuite/schema/types\";\nimport type { SignalOption } from \"../ui/dynamic-slot\";\nimport type { JxPath } from \"../state\";\n\ninterface HtmlMetaEntry {\n $section: string;\n $order: number;\n $attr?: string;\n $elements?: string[];\n $label?: string;\n $input?: string;\n $shorthand?: boolean;\n type?: string;\n [key: string]: unknown;\n}\n\n// ─── The binding vocabulary, shared with the Logic tab ───────────────────────\n\n/**\n * The two extra signals a position inside a repeater template can bind to, or `null` outside one.\n *\n * A \"map\" segment addresses a repeater template (`[…, \"children\", i, \"map\", …]`, or the legacy `[…,\n * \"children\", \"map\", …]`), so anything at or below it is inside one.\n *\n * Exported because Content and Logic both offer them and there is one right answer: a `$switch`\n * inside a `$map` can read `$map/item`, and so can the `alt` attribute two nodes below it.\n */\nexport function mapSignalsFor(path: JxPath): SignalOption[] | null {\n return path.includes(\"map\")\n ? [\n { label: \"$map/item\", value: \"$map/item\" },\n { label: \"$map/index\", value: \"$map/index\" },\n ]\n : null;\n}\n\n/** State keys a value position may bind to — handlers and Functions are not values. */\nexport function bindableSignalNames(doc: JxMutableNode): string[] {\n return Object.entries(doc.state || {})\n .filter(\n ([, d]) =>\n !(d as Record<string, unknown>)?.$handler &&\n (d as JxPrototypeDef)?.$prototype !== \"Function\",\n )\n .map(([defName]) => defName);\n}\n\n/**\n * Render a state entry's default value as the static input text when unbinding.\n *\n * @param {import(\"@jxsuite/schema/types\").JxStateDefinition | undefined} def\n * @returns {string}\n */\nexport function defaultAsString(def: JxStateDefinition | undefined) {\n if (!def || typeof def !== \"object\" || Array.isArray(def)) {\n return \"\";\n }\n const dv = (def as JxStateObject).default;\n if (dv === undefined) {\n return \"\";\n }\n return typeof dv === \"object\" ? JSON.stringify(dv) : String(dv);\n}\n\n/** Who a bound value comes from, in the fewest words that are true — the chip's donor text. */\nfunction bindingDonor(value: unknown): string {\n if (isRef(value)) {\n const ref = value.$ref;\n return ref.startsWith(\"#/state/\") ? ref.slice(8) : ref || \"nothing yet\";\n }\n return typeof value === \"string\" ? \"a template\" : \"a formula\";\n}\n\n/**\n * The state entry a bound value reads, when the chip can name one — a `$ref` or a `${…}` template.\n *\n * §6.2's table says a bound chip \"click opens the source\", and on the Content tab it did not: both\n * bound branches returned a `donor` and a `title` and no `onClick`, so `renderProvenanceChip` drew\n * a handler-less span. The Style tab's chip has jumped to the Data panel since P5; the same promise\n * on the other tab was a label. Same regex as `style-panel.ts`'s `templateSignalOf`, because both\n * spellings of a template (`${x}` and `${state.x}`) name the same entry.\n */\nfunction boundSignalOf(value: unknown): string | null {\n if (isRef(value)) {\n const ref = value.$ref;\n return ref.startsWith(\"#/state/\") ? (ref.slice(8).split(\"/\")[0] ?? null) : null;\n }\n if (typeof value !== \"string\") {\n return null;\n }\n return /\\$\\{\\s*(?:state\\.)?([A-Za-z_$][\\w$]*)/.exec(value)?.[1] ?? null;\n}\n\n/**\n * Reveal the state entry a bound field reads: the Data panel, and that entry's row.\n *\n * Both verbs, because the rail tab alone leaves you looking at a collapsed list — the same pair the\n * Style tab's chip runs.\n */\nfunction revealSignal(name: string): void {\n const registry = activeRegistry();\n void registry?.run(\"view.setActivity\", { tab: \"data\" });\n void registry?.run(\"data.expandRow\", { name });\n}\n\n/**\n * The bound chip, naming its donor and — when the donor is a state entry — opening it.\n *\n * The entry list is read here rather than threaded through both callers' signatures: the two\n * provenance functions differ in everything else, and the question \"does this document define\n * `title`?\" has one answer that neither of them should have to be handed.\n */\nfunction boundProvenance(value: unknown, title: string): FieldProvenance {\n const signal = boundSignalOf(value);\n const document = activeTab.value?.doc.document;\n const known = signal && document ? bindableSignalNames(document).includes(signal) : false;\n return {\n donor: bindingDonor(value),\n state: \"bound\",\n title,\n // Only when the document actually defines it: a chip that jumps to a row that is not there\n // Would be a worse answer than a chip that does not jump.\n ...(known && signal ? { onClick: () => revealSignal(signal) } : {}),\n };\n}\n\n// ─── Sub-templates ──────────────────────────────────────────────────────────\n\n/**\n * Component props, each row carrying §6.2's provenance chip — the SECOND cascade.\n *\n * A component instance's value for a prop either overrides the component's declared default or does\n * not exist, and until now the two were the same blank field. The chip states which, and in the\n * inherited case it names the donor AND jumps to it: the donor of a component default is the\n * component definition, which this panel can already open.\n */\nfunction renderComponentPropsFieldsTemplate(\n node: JxMutableNode,\n path: JxPath,\n mapSignals: SignalOption[] | null,\n navigateToComponent: (path: string) => void,\n) {\n const tab = activeTab.value;\n const comp = componentRegistry.find((c) => c.tagName === displayTagName(node.tagName));\n const definitionOfThis = isComponentDefinitionOpen(node);\n if (!comp || !comp.props) {\n return renderEmptyState({\n compact: true,\n message: \"This component is not in the project's library, so it has no settings to show.\",\n });\n }\n const isNpm = comp.source === \"npm\";\n /* In the definition the \"value\" of a setting is its DECLARED DEFAULT — the state entry's\n `default` — not a per-instance override, so the row reads and writes there instead. */\n const stateEntries = (tab?.doc.document.state ?? {}) as Record<string, { default?: JsonValue }>;\n const currentVals: Record<string, unknown> = definitionOfThis\n ? Object.fromEntries(comp.props.map((prop) => [prop.name, stateEntries[prop.name]?.default]))\n : isNpm\n ? node.attributes || {}\n : node.$props || {};\n const updateFn = definitionOfThis\n ? (name: string, v?: JsonValue) =>\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { default: v }))\n : isNpm\n ? (name: string, v?: JsonValue) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateAttribute(\n t,\n path,\n name,\n v === \"\" ? undefined : (v as JxAttributeValue | undefined),\n ),\n )\n : (name: string, v?: JsonValue) =>\n transactDoc(activeTab.value, (t) => mutateUpdateProp(t, path, name, v));\n\n const defs = tab!.doc.document.state || {};\n const signalNames = bindableSignalNames(tab!.doc.document);\n const extraSignals = mapSignals;\n\n return html`\n ${comp.props.map((prop) => {\n const rawValue = currentVals[prop.name];\n const boundRef = isRef(rawValue) ? rawValue.$ref : null;\n const hasVal = rawValue !== undefined && rawValue !== null;\n const parsed = parseCemType(prop.type);\n const onChange = (v?: JsonValue) => updateFn(prop.name, v);\n const staticVal = slotMode(rawValue) === \"literal\" ? String(rawValue ?? \"\") : \"\";\n\n // De-escalating to literal restores the bound signal's declared default (old unbind behavior).\n const literalDefault = boundRef\n ? defaultAsString(defs[boundRef.startsWith(\"#/state/\") ? boundRef.slice(8) : boundRef]) ||\n undefined\n : undefined;\n\n /** @type {ReturnType<typeof setTimeout> | undefined} */\n let debounce: ReturnType<typeof setTimeout> | undefined;\n let widgetTpl;\n if (prop.format === \"image\") {\n widgetTpl = renderMediaPicker(prop.name, staticVal, onChange);\n } else if (prop.format === \"color\") {\n widgetTpl = renderColorSelector(prop.name, staticVal, onChange);\n } else if (prop.format === \"date\") {\n widgetTpl = spTextField(\n `cprop:${prop.name}`,\n String(staticVal),\n (v: string) => onChange(v),\n {\n placeholder: \"YYYY-MM-DD\",\n },\n );\n } else if (parsed.kind === \"boolean\") {\n widgetTpl = html`<sp-checkbox\n size=\"s\"\n .checked=${live(Boolean(staticVal))}\n @change=${(e: Event) => onChange((e.target as HTMLInputElement).checked || undefined)}\n ></sp-checkbox>`;\n } else if (parsed.kind === \"number\") {\n widgetTpl = html`<sp-number-field\n size=\"s\"\n .value=${live(staticVal)}\n @input=${(e: Event) => {\n clearTimeout(debounce);\n debounce = setTimeout(() => onChange((e.target as HTMLInputElement).value), 400);\n }}\n ></sp-number-field>`;\n } else if (parsed.kind === \"combobox\") {\n const options = parsed.options as string[];\n widgetTpl = html`<jx-value-selector\n .value=${String(staticVal)}\n size=\"s\"\n placeholder=\"—\"\n .options=${options.map((o) => ({ label: camelToLabel(o), value: o }))}\n @change=${(e: Event & { detail?: { value?: string } }) =>\n onChange(e.detail?.value ?? (e.target as HTMLInputElement).value)}\n ></jx-value-selector>`;\n } else {\n widgetTpl = spTextField(`cprop:${prop.name}`, String(staticVal), (v: string) =>\n onChange(v),\n );\n }\n\n const slot = renderDynamicSlot({\n caps: \"componentProp\",\n extraSignals,\n fieldKey: `cprop|${path.join(\"/\")}|${prop.name}`,\n literalDefault,\n onChange,\n staticWidget: widgetTpl,\n stateDefs: signalNames,\n value: rawValue,\n });\n\n return renderFieldRow({\n hasValue: hasVal,\n label: camelToLabel(prop.name),\n labelExtra: slot.modeButton,\n prop: prop.name,\n provenance: componentPropProvenance(prop, rawValue, hasVal, {\n // No donor and no jump in the definition: the value IS the component's default, and\n // \"→ the component definition\" would open the document already in front of you.\n isDefinition: definitionOfThis,\n onClear: () => updateFn(prop.name),\n ...(definitionOfThis || !comp.path\n ? {}\n : { openDefinition: () => navigateToComponent(comp.path!) }),\n }),\n widget: slot.widget,\n });\n })}\n ${\n comp.props.length === 0\n ? renderEmptyState({\n compact: true,\n message: definitionOfThis\n ? \"This component declares no settings yet. Add a state entry with a default to \" +\n \"give whoever places it something to fill in.\"\n : \"This component has no settings to fill in yet.\",\n })\n : nothing\n }\n ${\n // A link to the definition, from inside the definition, is a link to here.\n comp.path && !definitionOfThis\n ? html`<span class=\"kv-add\" @click=${() => navigateToComponent(comp.path!)}\n >→ Edit definition</span\n >`\n : nothing\n }\n `;\n}\n\n/**\n * Is the selected node an INSTANCE of a component, or the definition of one?\n *\n * A component's own root tag has a hyphen, so \"the tag contains a dash\" answers yes to both — and\n * that is what put the instance form in front of someone editing the component itself. The\n * distinguishing fact is whose document this is: if the component's definition path IS the open\n * file, there is no instance, no override and no donor to jump to.\n */\nexport function isComponentDefinitionOpen(node: JxMutableNode): boolean {\n const comp = componentRegistry.find((c) => c.tagName === displayTagName(node.tagName));\n const open = activeTab.value?.documentPath;\n return comp?.path !== undefined && open !== undefined && comp.path === open;\n}\n\n/**\n * Which of §6.2's four states a component-prop row is in.\n *\n * Bound beats set (a `$ref` IS a value, but \"bound to `title`\" is the more useful sentence); set\n * beats inherited; a prop with no declared default and no value is plain Default and draws\n * nothing.\n */\nfunction componentPropProvenance(\n prop: { name: string; default?: unknown; description?: string },\n rawValue: unknown,\n hasVal: boolean,\n actions: {\n onClear: () => void;\n openDefinition?: (() => void) | undefined;\n /** Editing the component itself, where there is no instance and therefore no donor. */\n isDefinition?: boolean;\n },\n): FieldProvenance {\n if (hasVal && slotMode(rawValue) !== \"literal\") {\n return boundProvenance(rawValue, `Bound — ${prop.name}`);\n }\n if (hasVal) {\n return { onClick: actions.onClear, state: \"set\", title: `Clear ${prop.name}` };\n }\n /* INHERITED is a statement about somewhere ELSE, so it cannot be true here. In the definition an\n unset field means this component ships no default for that setting — which is `default`, the\n state that draws nothing, not a badge pointing at itself. */\n if (prop.default !== undefined && !actions.isDefinition) {\n return {\n donor: \"the component default\",\n state: \"inherited\",\n title: `Not set here — the component's default (${String(prop.default)}) applies`,\n ...(actions.openDefinition ? { onClick: actions.openDefinition } : {}),\n };\n }\n return { state: \"default\" };\n}\n\n/** Custom attrs fields template — attributes this element's schema does not know about. */\nfunction renderCustomAttrsFieldsTemplate(\n path: JxPath,\n attrs: Record<string, unknown>,\n knownAttrNames: Set<string>,\n) {\n const customAttrs = Object.entries(attrs).filter(([k]) => !knownAttrNames.has(k));\n return html`\n ${customAttrs.map(([attr, val]) =>\n renderKvRow({\n name: attr,\n onCommit: (newAttr: string, newVal: string) => {\n if (newAttr !== attr) {\n transactDoc(activeTab.value, (t) => {\n mutateUpdateAttribute(t, path, attr);\n mutateUpdateAttribute(t, path, newAttr, newVal);\n });\n } else {\n transactDoc(activeTab.value, (t) => mutateUpdateAttribute(t, path, attr, newVal));\n }\n },\n onDelete: () => transactDoc(activeTab.value, (t) => mutateUpdateAttribute(t, path, attr)),\n value: String(val),\n }),\n )}\n <span\n class=\"kv-add\"\n @click=${() => transactDoc(activeTab.value, (t) => mutateUpdateAttribute(t, path, \"data-\", \"\"))}\n >+ Add attribute</span\n >\n `;\n}\n\n// ─── Page-route enumeration (for the Link-target Internal picker) ─────────────\n\n/** @type {string[] | null} — cached list of internal routes derived from the pages/ tree. */\nlet pageRouteEntries: string[] | null = null;\n\n/**\n * Derive a site route from a page file path relative to `pages/`, following the file-based routing\n * convention: `index.json` → the directory route, `[slug].json` → `:slug`, all others drop their\n * extension. Directory routes get a trailing slash (`/about/`); the root is `/`.\n *\n * @param {string} relPath — path relative to `pages/`, forward-slashed (e.g. \"blog/[slug].json\").\n * @returns {string}\n */\nfunction routeForPagePath(relPath: string): string {\n const withoutExt = relPath.replace(/\\.[^./]+$/, \"\");\n const segments = withoutExt\n .split(\"/\")\n .map((seg) => (seg.startsWith(\"[\") ? `:${seg.slice(1, -1)}` : seg));\n const isIndex = segments.at(-1) === \"index\";\n if (isIndex) {\n segments.pop();\n }\n const body = segments.join(\"/\");\n if (!body) {\n return \"/\";\n }\n // Dynamic routes keep no trailing slash; static routes are directory-style (trailing slash).\n return isIndex || body.includes(\":\") ? `/${body}${isIndex ? \"/\" : \"\"}` : `/${body}/`;\n}\n\n/** Recursively walk the pages/ tree and populate {@link pageRouteEntries} with derived routes. */\nasync function loadPageRouteEntries() {\n const platform = getPlatform();\n const routes: string[] = [];\n const docExts = new Set([\".json\", \".md\", \".html\"]);\n async function walk(dir: string, rel: string) {\n let listing: DirEntry[];\n try {\n listing = await platform.listDirectory(dir);\n } catch {\n return;\n }\n for (const entry of listing) {\n const childRel = rel ? `${rel}/${entry.name}` : entry.name;\n if (entry.type === \"directory\") {\n await walk(entry.path ?? `${dir}/${entry.name}`, childRel);\n } else if (docExts.has(entry.name.slice(entry.name.lastIndexOf(\".\")))) {\n routes.push(routeForPagePath(childRel));\n }\n }\n }\n await walk(\"pages\", \"\");\n pageRouteEntries = [...new Set(routes)].toSorted((a, b) => a.localeCompare(b));\n renderOnly(\"rightPanel\");\n}\n\nexport function invalidatePageRouteCache() {\n pageRouteEntries = null;\n}\n\n/**\n * Composite Link-target control for an anchor's `href` — a kind selector (Internal / External /\n * Anchor / Email / Phone) plus the matching input, backed by classifyHref/composeHref so edits\n * round-trip. Internal targets render an sp-picker of page routes enumerated from the pages/ tree.\n *\n * @param {JxMutableNode} node\n * @param {JxPath} path\n */\nfunction renderLinkTargetField(node: JxMutableNode, path: JxPath) {\n const raw = typeof node.attributes?.href === \"string\" ? node.attributes.href : \"\";\n const { kind, value } = classifyHref(raw);\n\n const commit = (nextKind: LinkKind, nextValue: string) => {\n const composed = composeHref(nextKind, nextValue);\n transactDoc(activeTab.value!, (t) =>\n mutateUpdateAttribute(t, path, \"href\", composed || undefined),\n );\n };\n\n const kindOptions: { value: LinkKind; label: string }[] = [\n { label: \"Internal Page\", value: \"internal\" },\n { label: \"External URL\", value: \"external\" },\n { label: \"Anchor\", value: \"anchor\" },\n { label: \"Email\", value: \"mailto\" },\n { label: \"Phone\", value: \"tel\" },\n ];\n\n const kindSelector = html`\n <sp-picker\n class=\"link-target-kind\"\n size=\"s\"\n value=${kind}\n @change=${(e: Event) => {\n const nextKind = (e.target as HTMLInputElement).value as LinkKind;\n // Switching kind reinterprets the current value under the new kind.\n commit(nextKind, value);\n }}\n >\n ${kindOptions.map((o) => html`<sp-menu-item value=${o.value}>${o.label}</sp-menu-item>`)}\n </sp-picker>\n `;\n\n let valueInput;\n if (kind === \"internal\") {\n if (pageRouteEntries === null) {\n void loadPageRouteEntries();\n }\n const routes = pageRouteEntries ?? [];\n const knownValue = value !== \"\" && !routes.includes(value);\n valueInput = html`\n <sp-picker\n class=\"link-target-value\"\n size=\"s\"\n value=${value}\n @change=${(e: Event) => commit(\"internal\", (e.target as HTMLInputElement).value)}\n >\n ${knownValue ? html`<sp-menu-item value=${value}>${value}</sp-menu-item>` : nothing}\n ${routes.map((r) => html`<sp-menu-item value=${r}>${r}</sp-menu-item>`)}\n </sp-picker>\n `;\n } else {\n const placeholder =\n kind === \"mailto\"\n ? \"name@example.com\"\n : kind === \"tel\"\n ? \"+15551234567\"\n : kind === \"anchor\"\n ? \"section-id\"\n : \"https://example.com\";\n valueInput = html`\n <sp-textfield\n class=\"link-target-value\"\n size=\"s\"\n placeholder=${placeholder}\n .value=${live(value)}\n @input=${debouncedStyleCommit(\"link:href\", 400, (e: Event) =>\n commit(kind, (e.target as HTMLInputElement).value),\n )}\n ></sp-textfield>\n `;\n }\n\n return renderFieldRow({\n hasValue: raw !== \"\",\n label: \"Link\",\n onClear: () => transactDoc(activeTab.value, (t) => mutateUpdateAttribute(t, path, \"href\")),\n prop: \"href\",\n widget: html`<div class=\"link-target-field\">${kindSelector}${valueInput}</div>`,\n });\n}\n\n/**\n * Real enum picker (sp-picker) for the anchor `target` attribute, replacing the generic\n * jx-value-selector so the four browsing-context keywords are offered as a dropdown.\n *\n * @param {JxMutableNode} node\n * @param {JxPath} path\n * @param {HtmlMetaEntry} entry\n */\nfunction renderTargetField(node: JxMutableNode, path: JxPath, entry: HtmlMetaEntry) {\n const options = Array.isArray(entry.enum) ? (entry.enum as string[]) : [];\n const current = typeof node.attributes?.target === \"string\" ? node.attributes.target : \"\";\n return renderFieldRow({\n hasValue: current !== \"\",\n label: attrLabel(entry, \"target\"),\n onClear: () => transactDoc(activeTab.value, (t) => mutateUpdateAttribute(t, path, \"target\")),\n prop: \"target\",\n widget: html`\n <sp-picker\n class=\"link-target-window\"\n size=\"s\"\n value=${current}\n @change=${(e: Event) =>\n transactDoc(activeTab.value!, (t) =>\n mutateUpdateAttribute(\n t,\n path,\n \"target\",\n (e.target as HTMLInputElement).value || undefined,\n ),\n )}\n >\n ${options.map((o) => html`<sp-menu-item value=${o}>${o}</sp-menu-item>`)}\n </sp-picker>\n `,\n });\n}\n\n/**\n * True when an attribute value is a binding (a `$ref` object or a template string containing\n * `${…}`), so the Link-target special-case must fall back to the raw widget to keep it editable.\n */\nfunction isBoundAttrValue(value: unknown): boolean {\n return isRef(value) || (typeof value === \"string\" && value.includes(\"${\"));\n}\n\n// ─── Layout selection panel ─────────────────────────────────────────────────\n\n/*\n * There is no `openLayoutAtNode`, and every line of it was wrong by the time it was deleted.\n *\n * Its docstring said `navigateToComponent` \"swaps the tab's document (pushing the page onto the\n * document stack)\" — two releases stale: nothing has swapped since §14.1 landed and there is no\n * document stack. Then it did four things, and the last three were the defect:\n *\n * 1. **Navigate.** Now the command's job, and the command opens the layout BESIDE the page rather\n * than over the page it is teaching about — §8.2's promise since P3, never shipped.\n * 2. **`setLayoutSelection(null)`.** Its stated reason — \"the layout is now the open document, so\n * its nodes are ordinary editable content\" — stops being true the moment the layout opens beside\n * the page rather than replacing it. Clearing it is precisely what killed the follow on its first\n * frame, and it is what made the Inspector blank at the instant the layout appeared.\n * 3. **Re-select against `activeTab`.** The focus deliberately stays in the page now, so the tab\n * this reached was the wrong one. The selection is carried by the derivation instead —\n * `pane-derive.ts`'s `DerivedTarget.select`, read from `shell.layoutSelection`'s `layoutPath`\n * and applied to the companion pane's tab once the open resolves. For one release that sentence\n * was written here and nothing implemented it: `layoutPath` had no consumer outside the canvas\n * hit test, `derivationFor(\"layout\")` stored `{resolved: null}`, and the exact regression this\n * ledger entry describes — dropped into a layout file with nothing selected — was back while\n * the comment denied it.\n *\n * The companion resolves `shell.layoutSelection.layoutFile` in preference to the page's own\n * `$layout` for the same reason the old code did: they are different answers for a nested chain,\n * and the one the author clicked is the one they meant.\n * 4. **`renderOnly(\"rightPanel\")`.** `panels/right-panel.ts:106` tracks `shell.layoutSelection`\n * itself and `:212` reads it, so the repaint was already subscribed — a second, imperative\n * subscription that only looked necessary because the function above had just cleared the state\n * the real one is keyed on.\n */\n\n/**\n * The Layout-element panel — what the inspector says when you click page chrome.\n *\n * It spent a release cycle unreachable: `shell.layoutSelection` had this reader and no writer, so\n * clicking the site name in the header — the first click a new user makes — did nothing at all. The\n * canvas hit test writes it now (§8.2), and `panels/right-panel.ts` tracks it, so the panel\n * renders.\n */\n/**\n * The chip that opens the layout beside the page.\n *\n * **Drawn only where it can run**, which is why the condition lives at the call site rather than\n * inside the handler. `canvas/iframe-host.ts` focuses the pane a layout click landed in — including\n * a LENS, which draws layout chrome because it draws the same document — and from a derived pane\n * `pane.derive` can only throw `an open document in a pane that is not itself derived`, into a\n * floating `void registry.run(…)` that swallows it. A chip that does nothing when you press it is\n * worse than no chip: the sentence above it already says where the element comes from, and in that\n * shell the layout is either already beside you or one Unsplit away.\n */\nfunction openLayoutTpl(): TemplateResult {\n return html`<span\n class=\"kv-add\"\n @click=${() => {\n /* ONE command, addressed by id — the chip is a control, not a second definition site for\n what \"open the layout\" means. It opens the layout BESIDE the page and leaves the keyboard\n in the page, so the next click on layout chrome moves the side pane's selection instead of\n teaching the author what a pane is. */\n void activeRegistry()?.run(\"pane.derive\", { preset: \"layout\" });\n }}\n >Open Layout →</span\n >`;\n}\n\nfunction renderLayoutSelectionPanel() {\n const selection = shell.layoutSelection as LayoutSelection;\n const tagName = selection.tagName || \"element\";\n const { className } = selection;\n const displayPath = selection.layoutFile || \"layout\";\n\n return html`\n <div class=\"style-sidebar\">\n <sp-accordion allow-multiple size=\"s\">\n <sp-accordion-item label=\"Layout Element\" open>\n <div class=\"style-section-body\">\n <div class=\"layout-origin\">\n <span class=\"layout-origin-badge\">Layout</span>\n <code class=\"layout-origin-tag\">&lt;${tagName}&gt;</code>\n </div>\n ${\n className\n ? renderFieldRow({\n hasValue: false,\n label: \"Class\",\n prop: \"className\",\n widget: html`<span class=\"layout-origin-class\">${className}</span>`,\n })\n : nothing\n }\n <p class=\"layout-origin-note\">\n This element comes from ${displayPath}, which wraps every page that uses it. Open the\n layout to edit it.\n </p>\n ${deriveRefusal(workspace.activePaneId) === null ? openLayoutTpl() : nothing}\n </div>\n </sp-accordion-item>\n </sp-accordion>\n </div>\n `;\n}\n\n// ─── Usages (§9.6) ───────────────────────────────────────────────────────────\n\n/**\n * The Usage section's key, in the same per-tab `inspectorSections` record every other section uses,\n * so `inspector.setSection` addresses it exactly like the rest and nothing needs a second store.\n */\nconst USAGES_SECTION = \"__usages\";\n\n/**\n * The component instance's usage line — \"Used on 7 pages →\", expanding to the files.\n *\n * Three things this deliberately does NOT do. It does not render when the host cannot answer\n * (`usagesSupported()` is `capability.findReferences`): a confident \"0\" for a component used\n * everywhere is worse than no line at all. It does not ask on every paint — `peekUsages` is\n * side-effect-free and only a cold target starts a request, which repaints once when it lands. And\n * it does not swallow a failure: a failed count says so and offers Retry, because \"we could not\n * check\" and \"nothing uses this\" are the two answers a user must never confuse.\n *\n * @param tagName — the instance's custom-element tag.\n * @param componentPath — its definition file, when the registry knows one. Passing both asks the\n * one question that covers file references AND element instances.\n */\nfunction renderUsagesSection(tagName: string, componentPath: string | null) {\n const query = { tagName, ...(componentPath ? { path: componentPath } : {}) };\n const state = peekUsages(query);\n // ONE gate, and it is the peek itself: a host with no `findReferences` answers \"unsupported\"\n // Synchronously, and the section does not exist. A separate `usagesSupported()` guard above this\n // Would make the arm below unreachable, which is a branch nothing can ever test.\n if (state?.status === \"unsupported\") {\n return nothing;\n }\n if (state === null) {\n // Cold: ask once, and repaint the inspector when the answer arrives.\n void loadUsages(query).then(() => renderOnly(\"rightPanel\"));\n }\n\n let body;\n let heading = \"Usage\";\n if (state === null || state.status === \"pending\") {\n body = html`<div class=\"usage-note\">Counting references…</div>`;\n } else if (state.status === \"failed\") {\n heading = \"Usage · unknown\";\n body = html`\n <div class=\"usage-note\">\n References could not be counted: ${state.message}. This is not the same as “unused”.\n </div>\n <sp-action-button\n size=\"s\"\n quiet\n @click=${() => {\n void retryUsages(query).then(() => renderOnly(\"rightPanel\"));\n }}\n >Retry</sp-action-button\n >\n `;\n } else {\n const files = usageFiles(state.result);\n heading = usageHeadline(state.result);\n body =\n files.length === 0\n ? html`<div class=\"usage-note\">\n Nothing else in this project places <code>&lt;${tagName}&gt;</code> yet.\n </div>`\n : html`${files.map(\n (file) => html`\n <button\n class=\"usage-row\"\n type=\"button\"\n title=${file.refs.map((r) => `${r.refType} ${r.ref} ×${r.count}`).join(\", \")}\n @click=${() => openUsage(file.path)}\n >\n <span class=\"usage-row-path\">${file.path}</span>\n <span class=\"usage-row-count\">${file.count}</span>\n </button>\n `,\n )}`;\n }\n\n return html`\n <sp-accordion-item\n label=${heading}\n ?open=${isInspectorSectionOpen(USAGES_SECTION, false)}\n @sp-accordion-item-toggle=${() =>\n setInspectorSection(USAGES_SECTION, !isInspectorSectionOpen(USAGES_SECTION, false))}\n >\n <div class=\"style-section-body\">${body}</div>\n </sp-accordion-item>\n `;\n}\n\n/** Open a referencing file in a tab — the \"→\" half of \"Used on N pages →\". */\nfunction openUsage(path: string): void {\n // Lazy import: `files/files.ts` imports this panel's siblings, and a static edge here would close\n // The inspector → files → inspector cycle.\n void import(\"../files/files\").then((m) => m.openFileInTab(path));\n}\n\n/** Send the user to the tab that DOES answer, without this module importing the dock. */\nfunction showLogicTab(): void {\n void import(\"./right-panel\").then((m) => m.setInspectorTab(\"events\"));\n}\n\n// ─── Main entry point ───────────────────────────────────────────────────────\n\n/**\n * The Content tab — lit-html template with accordion sections.\n *\n * @param {{ navigateToComponent: (path: string) => void }} ctx\n */\nexport function renderPropertiesPanelTemplate(ctx: {\n navigateToComponent: (path: string) => void;\n}) {\n const tab = activeTab.value;\n if (!tab) {\n return renderEmptyState({\n actions: [openPageAction()],\n message: \"Open a page to inspect and style what you click.\",\n });\n }\n\n // Layout element selected — show read-only info with link to open layout\n if (shell.layoutSelection) {\n return renderLayoutSelectionPanel();\n }\n\n const selected = primarySelection(tab.session.selection);\n if (!selected) {\n return renderEmptyState({ message: clickAnythingTo(\"edit its content\") });\n }\n const path: JxPath = selected;\n const node = getNodeAtPath(tab.doc.document, path);\n if (!node) {\n return renderEmptyState({ message: staleSelectionMessage() });\n }\n\n // A repeating list has no content of its own — it has a source and a template, and both are\n // Wiring. Content says where the answer lives rather than drawing an empty accordion (§6.5).\n if (node.$prototype === \"Array\") {\n return renderEmptyState({\n actions: [{ label: \"Open Logic\", run: showLogicTab }],\n detail: \"Its items, filter, sort and template are wiring, so they live in Logic.\",\n message: \"A repeating list has no content of its own.\",\n });\n }\n\n // The whole selection the Content tab edits. `[path]` when one element is selected, which is\n // Every existing call site's behaviour unchanged.\n const targets: JxPath[] = tab.session.selection.length > 0 ? tab.session.selection : [path];\n const doc = tab.doc.document;\n const isCustomInstance = displayTagName(node.tagName).includes(\"-\");\n const chosenTag = isTagExpression(node.tagName) ? node.tagName.$expression : null;\n const tagName = displayTagName(node.tagName) || \"div\";\n const attrs = node.attributes || {};\n\n const mapSignals = mapSignalsFor(path);\n // Signals offered to attribute/textContent bindings (handlers and Functions excluded).\n const bindableSignals = bindableSignalNames(tab.doc.document);\n\n function renderAttrRow(attr: string, entry: HtmlMetaEntry, value: unknown) {\n const type = inferInputType(entry);\n const hasVal = value !== undefined && value !== \"\";\n // One write per selected element, inside ONE transaction (§6.5). `targets` is `[path]` for a\n // Single selection, so this is the same single mutation it has always been.\n const commitAttr = (v?: JsonValue) =>\n transactDoc(activeTab.value!, (t) => {\n for (const target of targets) {\n mutateUpdateAttribute(t, target, attr, v as JxAttributeValue | undefined);\n }\n });\n\n // Enhanced Link handling: only for anchors (a/area) with a plain (non-binding) value. Bindings\n // ($ref objects or ${…} template strings) fall through to the raw widget to stay editable.\n const isAnchor = tagName === \"a\" || tagName === \"area\";\n if (isAnchor && !isBoundAttrValue(value)) {\n if (attr === \"href\") {\n return renderLinkTargetField(node, path);\n }\n if (attr === \"target\") {\n return renderTargetField(node, path, entry);\n }\n }\n\n const attrSlot = (staticWidget: unknown) =>\n renderDynamicSlot({\n caps: \"attribute\",\n extraSignals: mapSignals,\n fieldKey: `attr|${path.join(\"/\")}|${attr}`,\n onChange: commitAttr,\n staticWidget,\n stateDefs: bindableSignals,\n value,\n });\n\n const literalWidget =\n entry.type === \"boolean\"\n ? html`\n <sp-checkbox\n size=\"s\"\n .checked=${live(Boolean(value))}\n @change=${(e: Event) => commitAttr((e.target as HTMLInputElement).checked ? \"\" : undefined)}\n >\n </sp-checkbox>\n `\n : widgetForType(type, entry, attr, isRef(value) ? \"\" : String(value || \"\"), (v: string) =>\n commitAttr(v || undefined),\n );\n const slot = attrSlot(literalWidget);\n return renderFieldRow({\n hasValue: hasVal,\n label: attrLabel(entry, attr),\n labelExtra: slot.modeButton,\n prop: attr,\n provenance: attributeProvenance(\n attr,\n value,\n hasVal,\n () =>\n transactDoc(activeTab.value, (t) => {\n for (const target of targets) {\n mutateUpdateAttribute(t, target, attr);\n }\n }),\n mixedAcrossSelection(doc, targets, (n) => (n?.attributes ?? {})[attr] ?? null),\n ),\n widget: slot.widget,\n });\n }\n\n // ── Collect applicable attributes from html-meta ──\n const applicableAttrs = {} as Record<string, HtmlMetaEntry>;\n for (const [attr, entry] of Object.entries(htmlMeta.$defs) as [string, HtmlMetaEntry][]) {\n if (!entry.$elements || entry.$elements.includes(displayTagName(tagName))) {\n // The $attr field aliases a $defs key to a different attribute name.\n // This lets the same attribute (e.g. \"name\") carry per-element metadata.\n applicableAttrs[entry.$attr ?? attr] = entry;\n }\n }\n\n const attrSections: Record<string, { name: string; entry: HtmlMetaEntry }[]> = {};\n for (const sec of htmlMeta.$sections) {\n attrSections[sec.key] = [];\n }\n for (const [attr, entry] of Object.entries(applicableAttrs)) {\n const secKey = entry.$section;\n if (attrSections[secKey]) {\n attrSections[secKey].push({ entry, name: attr });\n }\n }\n for (const sec of htmlMeta.$sections) {\n attrSections[sec.key]!.sort(\n (a: { name: string; entry: HtmlMetaEntry }, b: { name: string; entry: HtmlMetaEntry }) =>\n a.entry.$order - b.entry.$order,\n );\n }\n\n const knownAttrNames = new Set(Object.keys(applicableAttrs));\n if (isCustomInstance) {\n const comp = componentRegistry.find((c) => c.tagName === node.tagName);\n if (comp?.props) {\n for (const p of comp.props) {\n knownAttrNames.add(p.name);\n }\n }\n }\n const customAttrs = Object.entries(attrs).filter(([k]) => !knownAttrNames.has(k));\n\n const autoOpen = new Set();\n for (const [attr] of Object.entries(attrs)) {\n const entry = applicableAttrs[attr];\n if (entry) {\n autoOpen.add(entry.$section);\n }\n }\n if (customAttrs.length > 0) {\n autoOpen.add(\"__custom\");\n }\n\n function isSectionOpen(key: string) {\n return isInspectorSectionOpen(key, autoOpen.has(key));\n }\n\n function toggleSection(key: string) {\n // One writer: the accordion's own click and `inspector.setSection` land in the same function,\n // So the command and the control cannot disagree about what \"open\" means.\n setInspectorSection(key, !isSectionOpen(key));\n }\n\n // ── Build section templates ─────────────────────────────────────────\n\n const textSlot = renderDynamicSlot({\n caps: \"textProperty\",\n extraSignals: mapSignals,\n fieldKey: `prop|${path.join(\"/\")}|textContent`,\n onChange: (v?: JsonValue) =>\n transactDoc(activeTab.value, (t) => mutateUpdateProperty(t, path, \"textContent\", v)),\n staticWidget: spTextArea(\n \"prop:textContent\",\n typeof node.textContent === \"string\" ? node.textContent : \"\",\n (v: string) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateProperty(t, path, \"textContent\", v || undefined),\n ),\n ),\n stateDefs: bindableSignals,\n value: node.textContent,\n });\n\n /**\n * A draft key for one field ON THIS NODE.\n *\n * The three Element rows used constant keys — `\"prop:tagName\"`, `\"prop:$id\"`, `\"prop:className\"`\n * — and `ui/field-input.ts`'s draft map is module-global, so every element shared one draft slot\n * per field. Type a class name, click a sibling before blurring, and the sibling's Class row\n * showed the text you had typed for the first one; blur it there and the commit landed on the\n * WRONG element. Plan §11.4 asks for \"drafts keyed by node path (today all elements share one\n * draft slot per field)\".\n */\n const fieldKey = (name: string) => `prop:${path.join(\"/\")}:${name}`;\n\n /**\n * The set-here chip for a document property, with the tooltip in the label's own words.\n *\n * The derived tooltip would read \"Clear textContent\"; the label above it reads \"Text Content\".\n * The row's key and the row's name are different vocabularies, and the tooltip belongs to the one\n * the user is looking at.\n */\n const propertyChip = (name: string, human: string): FieldProvenance => ({\n onClick: () => transactDoc(activeTab.value, (t) => mutateUpdateProperty(t, path, name)),\n state: \"set\",\n title: `Clear ${human}`,\n });\n\n const elemT = html`\n <sp-accordion-item\n label=\"Element\"\n ?open=${isSectionOpen(\"__element\") !== false}\n @sp-accordion-item-toggle=${() => toggleSection(\"__element\")}\n >\n <div class=\"style-section-body\">\n ${(() => {\n /* THE SHARED SLOT, not a hand-rolled control.\n `tagName` is a bindable position like any other — a literal name or a `TagExpression`\n — so it gets the same Value Source chip and the same expression editor as `href`, a\n style declaration or an event handler. The rungs are DERIVED from\n `SLOT_POSITION_SCHEMAS.elementTag`, which is why only Fixed value and Formula are\n offered: `TagName` carries a pattern, so `isFreeStringSchema` refuses a template rung,\n and a `${…}` in tag position is precisely what that pattern exists to reject.\n\n The seed is ours because the generic one is `{ operator: \"??\" }`, which a\n `TagExpression` does not admit — clicking the chip would otherwise write a document\n that fails its own validator. */\n const tagSlot = renderDynamicSlot({\n caps: \"elementTag\",\n fieldKey: `${path.join(\".\")}:tagName`,\n onChange: (next) => {\n transactDoc(activeTab.value, (t) =>\n mutateUpdateProperty(t, path, \"tagName\", next ?? undefined),\n );\n },\n seedFor: (mode) =>\n mode === \"expression\"\n ? {\n $expression: {\n initial: tagName,\n operator: \"?:\",\n target: null,\n value: tagName,\n },\n }\n : undefined,\n staticWidget: spTextField(fieldKey(\"tagName\"), tagName, (v: string) => {\n transactDoc(activeTab.value, (t) =>\n mutateUpdateProperty(t, path, \"tagName\", v || undefined),\n );\n }),\n stateDefs: bindableSignalNames(activeTab.value!.doc.document),\n value: node.tagName as JsonValue | undefined,\n });\n return renderFieldRow({\n hasValue: chosenTag !== null,\n label: \"Tag\",\n labelExtra: tagSlot.modeButton,\n prop: \"tagName\",\n widget: tagSlot.widget,\n });\n })()}\n ${renderFieldRow({\n hasValue: Boolean(node.$id),\n label: \"ID\",\n prop: \"$id\",\n ...(node.$id ? { provenance: propertyChip(\"$id\", \"ID\") } : {}),\n widget: spTextField(fieldKey(\"$id\"), String(node.$id || \"\"), (v: string) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateProperty(t, path, \"$id\", v || undefined),\n ),\n ),\n })}\n ${renderFieldRow({\n hasValue: Boolean(node.className),\n label: \"Class\",\n prop: \"className\",\n ...(node.className ? { provenance: propertyChip(\"className\", \"class\") } : {}),\n widget: spTextField(fieldKey(\"className\"), String(node.className || \"\"), (v: string) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateProperty(t, path, \"className\", v || undefined),\n ),\n ),\n })}\n ${\n !Array.isArray(node.children) || node.children.length === 0\n ? renderFieldRow({\n hasValue: node.textContent !== undefined,\n label: \"Text Content\",\n labelExtra: textSlot.modeButton,\n prop: \"textContent\",\n widget: textSlot.widget,\n ...(node.textContent === undefined\n ? {}\n : { provenance: propertyChip(\"textContent\", \"text\") }),\n })\n : nothing\n }\n ${renderFieldRow({\n hasValue: Boolean(node.hidden),\n label: \"Hidden\",\n prop: \"hidden\",\n ...(node.hidden ? { provenance: propertyChip(\"hidden\", \"hidden\") } : {}),\n widget: html`\n <sp-checkbox\n size=\"s\"\n .checked=${live(Boolean(node.hidden))}\n @change=${(e: Event) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateProperty(\n t,\n path,\n \"hidden\",\n (e.target as HTMLInputElement).checked || undefined,\n ),\n )}\n >\n </sp-checkbox>\n `,\n })}\n </div>\n </sp-accordion-item>\n `;\n\n const editingDefinition = isCustomInstance && isComponentDefinitionOpen(node);\n const compPropsT = isCustomInstance\n ? html`\n <sp-accordion-item\n label=${editingDefinition ? \"Component Defaults\" : \"Component Settings\"}\n open\n >\n <div class=\"style-section-body\">\n ${renderComponentPropsFieldsTemplate(node, path, mapSignals, ctx.navigateToComponent)}\n </div>\n </sp-accordion-item>\n `\n : nothing;\n\n // \"Used on N pages →\". Only for a component instance: an ordinary <div> is not a thing that can\n // Be reused, so the question does not arise.\n const usagesT = isCustomInstance\n ? renderUsagesSection(\n displayTagName(tagName),\n componentRegistry.find((c) => c.tagName === displayTagName(tagName))?.path ?? null,\n )\n : nothing;\n\n const attrSectionTemplates = htmlMeta.$sections\n .filter((sec) => attrSections[sec.key]!.length > 0)\n .map((sec) => {\n const sectionAttrs = attrSections[sec.key]!;\n const setCount = sectionAttrs.filter(\n (a: { name: string; entry: HtmlMetaEntry }) => attrs[a.name] !== undefined,\n ).length;\n return html`\n <sp-accordion-item\n label=${sec.label}\n ?open=${isSectionOpen(sec.key)}\n @sp-accordion-item-toggle=${() => toggleSection(sec.key)}\n >\n ${sectionDot(setCount)}\n <div class=\"style-section-body\">\n ${sectionAttrs.map((a: { name: string; entry: HtmlMetaEntry }) =>\n renderAttrRow(a.name, a.entry, attrs[a.name]),\n )}\n </div>\n </sp-accordion-item>\n `;\n });\n\n const customSectionT =\n customAttrs.length > 0 || Object.keys(attrs).length > 0\n ? html`\n <sp-accordion-item\n label=\"Custom\"\n ?open=${isSectionOpen(\"__custom\")}\n @sp-accordion-item-toggle=${() => toggleSection(\"__custom\")}\n >\n ${sectionDot(customAttrs.length)}\n <div class=\"style-section-body\">\n ${renderCustomAttrsFieldsTemplate(path, attrs, knownAttrNames)}\n </div>\n </sp-accordion-item>\n `\n : nothing;\n\n return html`\n <div class=\"style-sidebar\">\n <sp-accordion allow-multiple size=\"s\">\n ${elemT} ${compPropsT} ${usagesT} ${attrSectionTemplates} ${customSectionT}\n </sp-accordion>\n </div>\n `;\n}\n\n/**\n * The collapsed-header provenance dot (§6.2), and the end of a false affordance.\n *\n * It inherited `.set-dot`'s `cursor: pointer` and its \"turns red on hover\" rule, which together say\n * \"click me to clear this\" — and nothing happened, because it never had a handler. It is not a\n * control and it is not deleted either: §6.2 puts a provenance dot on collapsed accordion headers\n * precisely so a section's state is legible while closed, and clicking anywhere in the header\n * already toggles the section, so a second, different meaning for the same click would be worse\n * than the silence. So it keeps the information and gives up the affordance: an inert, labelled\n * indicator that says how many values in the section are set.\n */\nfunction sectionDot(setCount: number) {\n return setCount > 0\n ? html`<span\n slot=\"heading\"\n class=\"set-dot set-dot--section\"\n aria-hidden=\"true\"\n title=${`${setCount} value${setCount === 1 ? \"\" : \"s\"} set in this section`}\n ></span>`\n : nothing;\n}\n\n/** Which of §6.2's states an HTML-attribute row is in. Attributes have no third cascade layer. */\nfunction attributeProvenance(\n attr: string,\n value: unknown,\n hasVal: boolean,\n onClear: () => void,\n mixedCount = 0,\n): FieldProvenance {\n // Mixed first, for the same reason the Style tab decides it first: it is a fact about the\n // SELECTION, and the primary's own value says nothing about whether the others agree. A count of\n // 0 (a selection of one) can never reach this branch, so single-selection rows are untouched.\n if (mixedCount > 0) {\n return { donor: String(mixedCount), onClick: onClear, state: \"mixed\" };\n }\n if (hasVal && (isRef(value) || (typeof value === \"string\" && value.includes(\"${\")))) {\n return boundProvenance(value, `Bound — ${attr}`);\n }\n return hasVal ? { onClick: onClear, state: \"set\", title: `Clear ${attr}` } : { state: \"default\" };\n}\n\n/**\n * How many selected elements disagree about `key` on `read` — 0 when they agree or there is one.\n *\n * The Content tab's two cascades (HTML attributes and component props) both need the same answer\n * about the same set, so the question is asked once here and answered with `unifyValues`, the same\n * comparison the Style tab uses.\n *\n * @param {JxMutableNode} doc\n * @param {readonly JxPath[]} targets\n * @param {(node: JxMutableNode | undefined) => unknown} read\n * @returns {number}\n */\nexport function mixedAcrossSelection(\n doc: JxMutableNode,\n targets: readonly JxPath[],\n read: (node: JxMutableNode | undefined) => unknown,\n): number {\n if (targets.length < 2) {\n return 0;\n }\n const values = targets.map((path) => read(getNodeAtPath(doc, path) as JxMutableNode | undefined));\n return unifyValues(values).mixed ? targets.length : 0;\n}\n\n// ─── Section state ────────────────────────────────────────────────────────────\n\n/**\n * The Inspector's fixed section keys — the accordion rows the inspector always draws.\n *\n * Attribute-schema sections add their own keys at render time (a class's `$section`), so this is a\n * floor, not a closed set: {@link inspectorSectionKeys} unions it with whatever the OPEN DOCUMENT\n * declares, and that union is what `inspector.setSection` validates against. A fixed enum would\n * refuse a section the user is looking at; no validation at all would accept the label the old\n * `inspector.toggleSection` step passed (\"Element\", not `__element`) and silently do nothing.\n *\n * `__media` left with the breakpoint definitions, which are Project Settings › Contexts now (P4).\n * `__observed`, `__cssprops` and `__cssparts` are drawn by the Logic tab; the key space is the\n * INSPECTOR's, not one tab's, so `inspector.setSection` keeps addressing all of them.\n */\nexport const INSPECTOR_SECTION_KEYS = [\n \"__element\",\n \"__observed\",\n \"__usages\",\n \"__custom\",\n \"__cssprops\",\n \"__cssparts\",\n] as const;\n\nexport type InspectorSectionKey = (typeof INSPECTOR_SECTION_KEYS)[number];\n\n/** Section keys addressable right now: the fixed rows plus any already recorded for this tab. */\nexport function inspectorSectionKeys(): string[] {\n const recorded = Object.keys(activeTab.value?.session.ui.inspectorSections ?? {});\n return [...new Set<string>([...INSPECTOR_SECTION_KEYS, ...recorded])];\n}\n\n/**\n * Whether one Inspector section is expanded, falling back to the caller's default.\n *\n * The fallback is the caller's because it is not a constant: an attribute section opens itself when\n * one of its attributes is set, and Usage never does. Only the panel drawing the row knows.\n */\nexport function isInspectorSectionOpen(section: string, fallback: boolean): boolean {\n const recorded = activeTab.value?.session.ui.inspectorSections?.[section];\n return recorded === undefined ? fallback : recorded;\n}\n\n/**\n * Open or close one Inspector section, per tab.\n *\n * The pair `{ section, open }` is the whole point: `inspector.toggleSection` named a DELTA against\n * a section whose state depended on the selected node's own attributes (`autoOpen`), so the same\n * three manifest steps opened a section on one document and closed it on the next. Writing a new\n * object rather than mutating in place is what the reactive read in `isSectionOpen` depends on.\n */\nexport function setInspectorSection(section: string, open: boolean): void {\n const tab = activeTab.value;\n if (!tab) {\n return;\n }\n tab.session.ui.inspectorSections = { ...tab.session.ui.inspectorSections, [section]: open };\n}\n\n// ─── Commands ─────────────────────────────────────────────────────────────────\n\n/**\n * The Inspector's section verb. **This is the setter that retires `inspector.toggleSection`.**\n *\n * @returns {AnyCommand[]}\n */\nexport function inspectorCommands(): AnyCommand[] {\n return [\n {\n args: argsSchema({\n open: booleanProperty(\"True to expand the section, false to collapse it.\"),\n section: stringProperty(\n \"The section key — one of the fixed rows (__element, __observed, __usages, \" +\n \"__custom, __cssprops, __cssparts) or an attribute schema's own $section.\",\n ),\n }),\n category: \"View\",\n id: \"inspector.setSection\",\n level: \"document\",\n menus: [\"palette\"],\n group: \"4_docks\",\n requires: \"an open document\",\n when: (ctx) => ctx.document.open,\n run: (_commandCtx, args) => {\n const open = booleanArg(\"inspector.setSection\", args, \"open\");\n const section = stringArg(\"inspector.setSection\", args, \"section\");\n const known = inspectorSectionKeys();\n if (!known.includes(section)) {\n throw new RangeError(\n `command \"inspector.setSection\" argument \"section\": \"${section}\" is not a section ` +\n `this document declares — declared: ${known.join(\", \")}`,\n );\n }\n setInspectorSection(section, open);\n },\n title: \"Show Inspector Section\",\n },\n {\n /**\n * Find Usages. Defined ONCE, here, and rendered twice: the palette gets it from the app\n * registry, and `editor/context-menu.ts` pulls the `context/element` records out of this same\n * set into the menu it builds — so the row and the palette entry cannot drift in title, chord\n * or availability. It reads `ctx.selection.kind`, which both contexts populate from the node\n * under the cursor, so one `run` serves the menu's target and the canvas selection alike.\n *\n * `when` is the capability, not a `try`: a host with no `findReferences` route hides the\n * command rather than offering a verb that answers \"0 usages\" for a component on every page.\n */\n category: \"Selection\",\n id: \"selection.findUsages\",\n level: \"selection\",\n menus: [\"context/element\", \"palette\"],\n group: \"4_identity\",\n undo: \"none\",\n when: (ctx) => ctx.capability.findReferences && ctx.selection.isComponentInstance,\n requires: \"a component instance, on a backend that can search the project\",\n run: () => {\n const tagName = componentSelectionTag();\n if (!tagName) {\n return;\n }\n const componentPath = componentRegistry.find((c) => c.tagName === tagName)?.path ?? null;\n setInspectorSection(USAGES_SECTION, true);\n void loadUsages({ tagName, ...(componentPath ? { path: componentPath } : {}) }).then(() =>\n renderOnly(\"rightPanel\"),\n );\n },\n title: \"Find Usages\",\n },\n ];\n}\n\n/**\n * The tag of the selected component instance, or null.\n *\n * Read from the document rather than from a menu target so the one record works in both registries:\n * the context menu's own `getContext` reports the right-clicked node's tag as `selection.kind`, and\n * the app's reports the canvas selection's. This is the fallback for the app registry, where the\n * selection lives on the tab.\n */\nfunction componentSelectionTag(): string | null {\n const tab = activeTab.value;\n const selection = primarySelection(tab?.session.selection);\n if (!tab || !selection) {\n return null;\n }\n const node = getNodeAtPath(tab.doc.document, selection);\n const tagName = typeof node?.tagName === \"string\" ? node.tagName : \"\";\n return tagName.includes(\"-\") ? tagName : null;\n}\n\n/**\n * Register the Inspector's section verb.\n *\n * @param {CommandRegistry} registry\n */\nexport function registerInspectorCommands(registry: CommandRegistry): void {\n registry.registerAll(inspectorCommands());\n}\n",
26
+ "/// <reference lib=\"dom\" />\n// oxlint-disable unicorn/no-thenable -- `then` is the JSON Schema conditional keyword (spec §20), not a promise\n/**\n * Statement editor (spec §20) — vertical statement-card list for structured function bodies.\n *\n * Renders a Function entry's `body: JxStatement[]` as cards on a connector line: bare expression\n * nodes (mutation or `call`), `if`/`then`/`else` branches, `$switch`/`cases` multiway branches, and\n * WHATWG `dispatchEvent` statements. Branch bodies render as indented lanes (the expression\n * editor's `border-left` nesting idiom) with their own add-statement pickers. Cards drag-reorder\n * within their lane via the pragmatic-drag-and-drop tree-item pattern (see panels/dnd.ts). All\n * edits flow through `onChange(next)` immutably — no statement object is mutated in place.\n *\n * **The layout is CSS, in `styles/inspector.css` (§ \"The statement editor\").** Every frame, indent\n * and connector here used to be an inline `style=` attribute, so nothing in the chain could set\n * `min-width: 0` and the operand controls refused to shrink: in a 280px Inspector an If/Else card\n * pushed Operator, Target and Value past the right edge of the window. This editor has two hosts of\n * very different widths — the Navigator's State panel and the Inspector's Events tab — plus the\n * Bottom dock, so a fixed pixel layout is wrong by construction and only a stylesheet can say so.\n */\n\nimport { html, nothing } from \"lit-html\";\nimport { live } from \"lit-html/directives/live.js\";\nimport { ref } from \"lit-html/directives/ref.js\";\nimport { combine } from \"@atlaskit/pragmatic-drag-and-drop/combine\";\nimport { disableNativeDragPreview } from \"@atlaskit/pragmatic-drag-and-drop/element/disable-native-drag-preview\";\nimport {\n attachInstruction,\n extractInstruction,\n} from \"@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item\";\nimport { isJsonObject } from \"@jxsuite/schema/guards\";\nimport { renderExpressionEditor, renderOperandEditor } from \"../ui/expression-editor\";\nimport { renderFieldRow } from \"../ui/field-row\";\n\nimport type {\n CemEvent,\n JxDispatchStatement,\n JxIfStatement,\n JxStatement,\n JxStateDefinition,\n JxSwitchStatement,\n} from \"@jxsuite/schema/types\";\nimport type { TemplateResult } from \"lit-html\";\n\n// ─── Options ─────────────────────────────────────────────────────────────────\n\nexport interface StatementEditorOpts {\n stateDefs: string[];\n stateEntries?: Record<string, JxStateDefinition> | null;\n allowEventRef: boolean;\n /** The entry's declared CEM events — offered as dispatchEvent name completions. */\n emits?: CemEvent[];\n /**\n * The region id of THIS editor, supplied by the surface that is drawing it.\n *\n * Required, and required of every host, which is the point. The editor used to hard-stamp\n * `navigator/statements` on itself, and it has two hosts that can be open at the same time — the\n * Navigator's State panel (`signals-panel.ts`) and the INSPECTOR's Events tab\n * (`events-panel.ts`). `resolveRegion` takes the last match in document order and `#right-panel`\n * follows `#left-panel`, so the id resolved to the Inspector's editor while saying Navigator, and\n * the shot that crops it cropped the wrong control.\n *\n * A shared control cannot know where it is, so it may not claim to. This is the same verdict\n * `ui/regions.ts`'s `DERIVED_RESOLVERS` records for the media picker's Browse button — _an\n * `inspector/…` id on an element outside the Inspector is not a pane-scoping problem, it is a\n * wrong id_ — reached the other way round: the picker's id is derived from the Inspector because\n * nothing addresses the card's copies, whereas both statement editors are real surfaces that\n * deserve names, so the HOST names them.\n */\n region: string;\n}\n\n/**\n * A lane address inside the statement tree: alternating [index, branchKey] steps, where a `cases`\n * step consumes three entries ([index, \"cases\", caseKey]). The empty path is the top-level\n * statement list.\n */\ntype LanePath = (string | number)[];\n\n// ─── Statement Kind Detection ────────────────────────────────────────────────\n\n/** Discriminate a statement's kind, mirroring the runtime's detection order (spec §20.2). */\nexport function statementKind(stmt: unknown): \"expression\" | \"if\" | \"switch\" | \"dispatch\" {\n if (isJsonObject(stmt)) {\n if (\"operator\" in stmt) {\n return \"expression\";\n }\n if (\"if\" in stmt) {\n return \"if\";\n }\n if (\"$switch\" in stmt) {\n return \"switch\";\n }\n if (\"dispatchEvent\" in stmt) {\n return \"dispatch\";\n }\n }\n return \"expression\";\n}\n\nconst ASSIGN_OPS = new Set([\"=\", \"+=\", \"-=\", \"*=\", \"/=\"]);\n\n/** Card header label — ECMA/WHATWG naming (spec §20.2). */\nfunction kindLabel(stmt: unknown): string {\n switch (statementKind(stmt)) {\n case \"if\": {\n return \"If / Else\";\n }\n case \"switch\": {\n return \"Switch\";\n }\n case \"dispatch\": {\n return \"Dispatch event\";\n }\n default: {\n const op = isJsonObject(stmt) ? String(stmt.operator ?? \"\") : \"\";\n if (ASSIGN_OPS.has(op)) {\n return \"Set state\";\n }\n if (op === \"call\") {\n return \"Call\";\n }\n return \"Expression\";\n }\n }\n}\n\n// ─── Add-statement Seeds (spec §20 shapes) ───────────────────────────────────\n\nconst STATEMENT_SEEDS: Record<string, () => JxStatement> = {\n call: () => ({ operator: \"call\", target: { $ref: \"\" }, value: [] }),\n dispatch: () => ({ dispatchEvent: \"\" }),\n if: () => ({\n if: { operator: \"===\", target: { $ref: \"\" }, value: null },\n then: [],\n }),\n set: () => ({ operator: \"=\", target: { $ref: \"\" }, value: null }),\n switch: () => ({ $switch: { $ref: \"\" }, cases: {} }),\n};\n\n// ─── Lane Addressing (immutable read/write through nested statement lists) ───\n\n/** Resolve the statement list a lane path points at; null when the path is stale. */\nexport function laneListAt(list: JxStatement[], path: LanePath): JxStatement[] | null {\n if (path.length === 0) {\n return list;\n }\n const [idx, key] = path;\n /*\n * `unknown`, not a cast to `Record<string, unknown>`. A `JxStatement` is a union of interfaces\n * with no index signature, so asserting one into an open bag is a lie TypeScript rightly refuses\n * — and it was buying nothing, because `isJsonObject` takes `unknown` and narrows to exactly the\n * open bag this wants. The guard on the next line is the real check either way.\n */\n const stmt: unknown = typeof idx === \"number\" ? list[idx] : null;\n if (!isJsonObject(stmt) || typeof key !== \"string\") {\n return null;\n }\n if (key === \"cases\") {\n const caseKey = path.at(2);\n const { cases } = stmt;\n if (typeof caseKey !== \"string\" || !isJsonObject(cases) || !Array.isArray(cases[caseKey])) {\n return null;\n }\n return laneListAt(cases[caseKey] as unknown as JxStatement[], path.slice(3));\n }\n if (!Array.isArray(stmt[key])) {\n return null;\n }\n return laneListAt(stmt[key] as unknown as JxStatement[], path.slice(2));\n}\n\n/** Rebuild the statement tree with the lane at `path` replaced by `next` — fully immutable. */\nexport function withLaneList(\n list: JxStatement[],\n path: LanePath,\n next: JxStatement[],\n): JxStatement[] {\n if (path.length === 0) {\n return next;\n }\n const idx = path[0] as number;\n const key = path[1] as string;\n const stmt = list[idx] as unknown as Record<string, unknown>;\n let updated: Record<string, unknown>;\n if (key === \"cases\") {\n const caseKey = path[2] as string;\n const cases = { ...(stmt.cases as Record<string, JxStatement[]>) };\n cases[caseKey] = withLaneList(cases[caseKey] ?? [], path.slice(3), next);\n updated = { ...stmt, cases };\n } else {\n updated = {\n ...stmt,\n [key]: withLaneList((stmt[key] as JxStatement[] | undefined) ?? [], path.slice(2), next),\n };\n }\n return list.map((s, i) => (i === idx ? (updated as unknown as JxStatement) : s));\n}\n\n// ─── Drag-reorder (pragmatic-drag-and-drop, per-lane) ────────────────────────\n\n/** Active DnD registration cleanup per editor root — replaced on every re-render. */\nconst dndRegistrations = new WeakMap<HTMLElement, () => void>();\n\n/**\n * Register drag-reorder on all statement rows under `root` (post-render, like registerLayersDnD).\n * Rows may only reorder within their own lane — the source's lane id must match the target's.\n */\nfunction registerStatementsDnD(\n root: HTMLElement,\n statements: JxStatement[],\n onChange: (next: JxStatement[]) => void,\n) {\n requestAnimationFrame(async () => {\n // Deferred adapter import — keeps this panel's import graph adapter-free at module load.\n const { draggable, dropTargetForElements } =\n await import(\"@atlaskit/pragmatic-drag-and-drop/element/adapter\");\n dndRegistrations.get(root)?.();\n const cleanups: (() => void)[] = [];\n\n for (const row of root.querySelectorAll(\"[data-stmt-row]\") as NodeListOf<HTMLElement>) {\n const laneId = row.dataset.stmtLane ?? \"[]\";\n const index = Math.trunc(Number(row.dataset.stmtIndex)) || 0;\n const handle = row.querySelector(\".statement-drag-handle\");\n\n cleanups.push(\n combine(\n draggable({\n element: row,\n ...(handle ? { dragHandle: handle } : {}),\n getInitialData() {\n return { index, lane: laneId, type: \"statement\" };\n },\n onGenerateDragPreview({\n nativeSetDragImage,\n }: {\n nativeSetDragImage: ((image: Element, x: number, y: number) => void) | null;\n }) {\n disableNativeDragPreview({ nativeSetDragImage });\n },\n onDragStart() {\n row.classList.add(\"dragging\");\n },\n onDrop() {\n row.classList.remove(\"dragging\");\n },\n }),\n dropTargetForElements({\n element: row,\n canDrop({ source }: { source: { data: Record<string, unknown> } }) {\n return source.data.type === \"statement\" && source.data.lane === laneId;\n },\n getData({\n input,\n element,\n }: {\n input: Parameters<typeof attachInstruction>[1][\"input\"];\n element: Element;\n }) {\n return attachInstruction(\n { index },\n {\n block: [\"make-child\"],\n currentLevel: 0,\n element,\n indentPerLevel: 16,\n input,\n mode: \"standard\",\n },\n ) as Record<string | symbol, unknown>;\n },\n onDrag({ self }: { self: { data: Record<string, unknown> } }) {\n const instruction = extractInstruction(self.data);\n row.classList.toggle(\"drop-above\", instruction?.type === \"reorder-above\");\n row.classList.toggle(\"drop-below\", instruction?.type === \"reorder-below\");\n },\n onDragLeave() {\n row.classList.remove(\"drop-above\", \"drop-below\");\n },\n onDrop({\n self,\n source,\n }: {\n self: { data: Record<string, unknown> };\n source: { data: Record<string, unknown> };\n }) {\n row.classList.remove(\"drop-above\", \"drop-below\");\n const instruction = extractInstruction(self.data);\n if (\n !instruction ||\n (instruction.type !== \"reorder-above\" && instruction.type !== \"reorder-below\")\n ) {\n return;\n }\n const from = source.data.index as number;\n const lanePath = JSON.parse(laneId) as LanePath;\n const lane = laneListAt(statements, lanePath);\n if (!lane || from === index) {\n return;\n }\n let insertAt = instruction.type === \"reorder-above\" ? index : index + 1;\n if (from < insertAt) {\n insertAt -= 1;\n }\n if (insertAt === from) {\n return;\n }\n const nextLane = lane.filter((_, i) => i !== from);\n nextLane.splice(insertAt, 0, lane[from]!);\n onChange(withLaneList(statements, lanePath, nextLane));\n },\n }),\n ),\n );\n }\n\n dndRegistrations.set(root, () => {\n for (const cleanup of cleanups) {\n cleanup();\n }\n });\n });\n}\n\n// ─── Small shared widgets ────────────────────────────────────────────────────\n\nfunction operandOpts(opts: StatementEditorOpts) {\n return {\n allowEventRef: opts.allowEventRef,\n depth: 0,\n stateDefs: opts.stateDefs,\n stateEntries: opts.stateEntries ?? null,\n };\n}\n\n/** The \"+ Add statement\" picker appended to every lane. */\nfunction renderAddStatement(\n list: JxStatement[],\n commit: (next: JxStatement[]) => void,\n): TemplateResult {\n return html`\n <sp-picker\n size=\"s\"\n quiet\n class=\"statement-add\"\n label=\"+ Add statement\"\n placeholder=\"+ Add statement\"\n .value=${live(\"\")}\n @change=${(e: Event) => {\n const kind = (e.target as HTMLInputElement).value;\n const seed = STATEMENT_SEEDS[kind];\n if (!seed) {\n return;\n }\n (e.target as HTMLInputElement).value = \"\";\n commit([...list, seed()]);\n }}\n >\n <sp-menu-item value=\"set\">Set state</sp-menu-item>\n <sp-menu-item value=\"call\">Call function</sp-menu-item>\n <sp-menu-item value=\"if\">If / Else</sp-menu-item>\n <sp-menu-item value=\"switch\">Switch</sp-menu-item>\n <sp-menu-item value=\"dispatch\">Dispatch event</sp-menu-item>\n </sp-picker>\n `;\n}\n\n/** An indented branch lane: header label (+ optional remove) above a nested statement list. */\nfunction renderLane(\n label: string | TemplateResult,\n list: JxStatement[],\n commit: (next: JxStatement[]) => void,\n opts: StatementEditorOpts,\n lanePath: LanePath,\n extras: { onRemove?: () => void } = {},\n): TemplateResult {\n return html`\n <div class=\"statement-lane\">\n <div class=\"statement-lane-header\">\n <span class=\"statement-lane-label\">${label}</span>\n ${\n extras.onRemove\n ? html`\n <sp-action-button\n quiet\n size=\"xs\"\n class=\"statement-lane-remove\"\n title=\"Remove branch\"\n @click=${extras.onRemove}\n >\n <sp-icon-delete slot=\"icon\"></sp-icon-delete>\n </sp-action-button>\n `\n : nothing\n }\n </div>\n ${renderStatementList(list, commit, opts, lanePath)}\n </div>\n `;\n}\n\n// ─── Kind-specific card bodies ───────────────────────────────────────────────\n\nfunction renderIfBody(\n stmt: JxIfStatement,\n commit: (next: JxStatement) => void,\n opts: StatementEditorOpts,\n lanePath: LanePath,\n index: number,\n): TemplateResult {\n return html`\n ${renderFieldRow({\n hasValue: false,\n label: \"If\",\n prop: \"if\",\n widget: renderOperandEditor(\n stmt.if,\n (v) => commit({ ...stmt, if: v } as JxStatement),\n operandOpts(opts),\n ),\n })}\n ${renderLane(\"Then\", stmt.then ?? [], (next) => commit({ ...stmt, then: next }), opts, [\n ...lanePath,\n index,\n \"then\",\n ])}\n ${\n Array.isArray(stmt.else)\n ? renderLane(\n \"Else\",\n stmt.else,\n (next) => commit({ ...stmt, else: next }),\n opts,\n [...lanePath, index, \"else\"],\n {\n onRemove: () => {\n const { else: _else, ...rest } = stmt;\n commit(rest as JxStatement);\n },\n },\n )\n : html`\n <sp-action-button\n quiet\n size=\"s\"\n class=\"statement-add-else\"\n @click=${() => commit({ ...stmt, else: [] })}\n >\n + Add else\n </sp-action-button>\n `\n }\n `;\n}\n\nfunction renderSwitchBody(\n stmt: JxSwitchStatement,\n commit: (next: JxStatement) => void,\n opts: StatementEditorOpts,\n lanePath: LanePath,\n index: number,\n): TemplateResult {\n const cases = isJsonObject(stmt.cases) ? (stmt.cases as Record<string, JxStatement[]>) : {};\n const entries = Object.entries(cases);\n const setCases = (next: Record<string, JxStatement[]>) =>\n commit({ ...stmt, cases: next } as JxStatement);\n\n return html`\n ${renderFieldRow({\n hasValue: false,\n label: \"Switch on\",\n prop: \"$switch\",\n widget: renderOperandEditor(\n stmt.$switch,\n (v) => commit({ ...stmt, $switch: v } as JxStatement),\n operandOpts(opts),\n ),\n })}\n ${entries.map(([key, list]) =>\n renderLane(\n html`\n <sp-textfield\n size=\"s\"\n class=\"statement-case-key\"\n placeholder=\"value\"\n .value=${live(key)}\n @change=${(e: Event) => {\n const newKey = (e.target as HTMLInputElement).value;\n if (newKey === key) {\n return;\n }\n const next: Record<string, JxStatement[]> = {};\n for (const [k, v] of entries) {\n next[k === key ? newKey : k] = v;\n }\n setCases(next);\n }}\n ></sp-textfield>\n `,\n Array.isArray(list) ? list : [],\n (next) => setCases({ ...cases, [key]: next }),\n opts,\n [...lanePath, index, \"cases\", key],\n {\n onRemove: () => {\n const next = { ...cases };\n delete next[key];\n setCases(next);\n },\n },\n ),\n )}\n ${renderLane(\n \"Default\",\n Array.isArray(stmt.default) ? stmt.default : [],\n (next) => {\n if (next.length === 0) {\n const { default: _default, ...rest } = stmt;\n commit(rest as JxStatement);\n return;\n }\n commit({ ...stmt, default: next } as JxStatement);\n },\n opts,\n [...lanePath, index, \"default\"],\n )}\n <sp-action-button\n quiet\n size=\"s\"\n class=\"statement-add-case\"\n @click=${() => {\n let n = entries.length + 1;\n let key = `case ${n}`;\n while (Object.hasOwn(cases, key)) {\n n += 1;\n key = `case ${n}`;\n }\n setCases({ ...cases, [key]: [] });\n }}\n >\n + Add case\n </sp-action-button>\n `;\n}\n\nfunction renderDispatchBody(\n stmt: JxDispatchStatement,\n commit: (next: JxStatement) => void,\n opts: StatementEditorOpts,\n): TemplateResult {\n const emitNames = (opts.emits ?? [])\n .map((e) => e.name)\n .filter((n): n is string => typeof n === \"string\" && n.length > 0);\n const commitName = (e: Event) =>\n commit({ ...stmt, dispatchEvent: (e.target as HTMLInputElement).value } as JxStatement);\n const toggle = (key: \"bubbles\" | \"composed\") => (e: Event) => {\n const { checked } = e.target as HTMLInputElement;\n const { [key]: _removed, ...rest } = stmt;\n commit((checked ? { ...rest, [key]: true } : rest) as JxStatement);\n };\n\n return html`\n ${renderFieldRow({\n hasValue: false,\n label: \"Event\",\n prop: \"dispatchEvent\",\n widget:\n emitNames.length > 0\n ? html`\n <sp-combobox\n size=\"s\"\n allows-custom-value\n class=\"statement-dispatch-name\"\n .value=${live(stmt.dispatchEvent ?? \"\")}\n @change=${commitName}\n >\n ${emitNames.map((n) => html`<sp-menu-item value=${n}>${n}</sp-menu-item>`)}\n </sp-combobox>\n `\n : html`\n <sp-textfield\n size=\"s\"\n class=\"statement-dispatch-name\"\n placeholder=\"event-name\"\n .value=${live(stmt.dispatchEvent ?? \"\")}\n @input=${commitName}\n ></sp-textfield>\n `,\n })}\n ${renderFieldRow({\n hasValue: false,\n label: \"Detail\",\n prop: \"detail\",\n widget: renderOperandEditor(\n stmt.detail ?? null,\n (v) => commit({ ...stmt, detail: v } as JxStatement),\n operandOpts(opts),\n ),\n })}\n ${renderFieldRow({\n hasValue: false,\n label: \"Options\",\n prop: \"eventInit\",\n widget: html`\n <div class=\"statement-dispatch-options\">\n <sp-checkbox\n size=\"s\"\n class=\"statement-dispatch-bubbles\"\n ?checked=${Boolean(stmt.bubbles)}\n @change=${toggle(\"bubbles\")}\n >Bubbles</sp-checkbox\n >\n <sp-checkbox\n size=\"s\"\n class=\"statement-dispatch-composed\"\n ?checked=${Boolean(stmt.composed)}\n @change=${toggle(\"composed\")}\n >Composed</sp-checkbox\n >\n </div>\n `,\n })}\n `;\n}\n\n// ─── Statement Card + List ───────────────────────────────────────────────────\n\nfunction renderStatementCard(\n stmt: JxStatement,\n index: number,\n list: JxStatement[],\n commitList: (next: JxStatement[]) => void,\n opts: StatementEditorOpts,\n lanePath: LanePath,\n): TemplateResult {\n const kind = statementKind(stmt);\n const commit = (next: JxStatement) => commitList(list.map((s, i) => (i === index ? next : s)));\n\n let body: TemplateResult;\n switch (kind) {\n case \"if\": {\n body = renderIfBody(stmt as JxIfStatement, commit, opts, lanePath, index);\n break;\n }\n case \"switch\": {\n body = renderSwitchBody(stmt as JxSwitchStatement, commit, opts, lanePath, index);\n break;\n }\n case \"dispatch\": {\n body = renderDispatchBody(stmt as JxDispatchStatement, commit, opts);\n break;\n }\n default: {\n body = renderExpressionEditor(stmt, (n) => commit(n as JxStatement), {\n allowEventRef: opts.allowEventRef,\n stateDefs: opts.stateDefs,\n stateEntries: opts.stateEntries ?? null,\n });\n break;\n }\n }\n\n return html`\n <div\n class=\"statement-card\"\n data-stmt-row\n data-stmt-kind=${kind}\n data-stmt-lane=${JSON.stringify(lanePath)}\n data-stmt-index=${index}\n >\n <div class=\"statement-card-header\">\n <span class=\"statement-drag-handle\" title=\"Drag to reorder\">⠿</span>\n <span class=\"statement-kind-label\">${kindLabel(stmt)}</span>\n <sp-action-button\n quiet\n size=\"xs\"\n class=\"statement-delete\"\n title=\"Delete statement\"\n @click=${() => commitList(list.filter((_, i) => i !== index))}\n >\n <sp-icon-delete slot=\"icon\"></sp-icon-delete>\n </sp-action-button>\n </div>\n <div class=\"statement-card-body\">${body}</div>\n </div>\n `;\n}\n\n/** One lane's vertical card list on its connector line, ending in the add-statement picker. */\nfunction renderStatementList(\n list: JxStatement[],\n commitList: (next: JxStatement[]) => void,\n opts: StatementEditorOpts,\n lanePath: LanePath,\n): TemplateResult {\n return html`\n <div class=\"statement-list\">\n ${list.map((stmt, index) =>\n renderStatementCard(stmt, index, list, commitList, opts, lanePath),\n )}\n ${renderAddStatement(list, commitList)}\n </div>\n `;\n}\n\n// ─── Entry Point ─────────────────────────────────────────────────────────────\n\n/**\n * Render a structured function body (spec §20) as an editable statement-card list. `onChange`\n * receives a fresh statement array on every edit; the input array is never mutated.\n */\nexport function renderStatementEditor(\n statements: JxStatement[],\n onChange: (next: JxStatement[]) => void,\n opts: StatementEditorOpts,\n): TemplateResult {\n const safe = Array.isArray(statements) ? statements : [];\n return html`\n <div\n class=\"statement-editor\"\n data-jx-region=${opts.region}\n ${ref((el) => {\n if (el) {\n registerStatementsDnD(el as HTMLElement, safe, onChange);\n }\n })}\n >\n ${renderStatementList(safe, onChange, opts, [])}\n </div>\n `;\n}\n",
27
+ "/// <reference lib=\"dom\" />\n/**\n * Signals panel — signal/def helpers, signals template, CEM editors, plugin schema forms.\n *\n * Extracted from studio.js to reduce file size.\n */\n\nimport { html, nothing } from \"lit-html\";\nimport { displayTagName } from \"@jxsuite/schema/guards\";\nimport { classMap } from \"lit-html/directives/class-map.js\";\nimport { dynamicRouteParams } from \"../page-params\";\nimport { projectState } from \"../state\";\nimport type { JsonValue } from \"../types\";\nimport { activeTab } from \"../workspace/workspace\";\nimport {\n mutateAddDef,\n mutateRemoveDef,\n mutateRenameDef,\n mutateUpdateDef,\n transactDoc,\n} from \"../tabs/transact\";\nimport { renderFieldRow } from \"../ui/field-row\";\nimport { rawTextArea, spTextField } from \"../ui/field-input\";\nimport {\n expressionHint,\n isActionExpression,\n renderExpressionEditor,\n} from \"../ui/expression-editor\";\nimport { renderEmptyState } from \"./empty-state\";\nimport {\n dataTypeLabel,\n expandedDataRows,\n isDataRowExpanded,\n renderDataTreeTemplate,\n setDataRowExpanded,\n unwrapSignal,\n} from \"./data-explorer\";\nimport { openLogicTarget } from \"./formula-workspace\";\nimport { bindableSignalNames } from \"./properties-panel\";\nimport { renderStatementEditor } from \"./statement-editor\";\nimport { NAVIGATOR_STATEMENTS_REGION } from \"../ui/regions\";\nimport { livePreviewExpression } from \"../services/live-preview\";\nimport { renderMediaPicker } from \"../ui/media-picker\";\nimport { renderOnly } from \"../store\";\nimport { renderForm } from \"../ui/schema-form\";\nimport { resolveContextPointer } from \"../services/context-resolver\";\nimport type { JsonSchema } from \"../ui/schema-form\";\nimport type { TabUi } from \"../tabs/tab\";\nimport type {\n CemEvent,\n CemParameter,\n JxMutableNode,\n JxStatement,\n JxStateDefinition,\n} from \"@jxsuite/schema/types\";\nimport { fetchPluginSchema, pluginSchemaCache } from \"../services/code-services\";\nimport { getExtensions, loadExtensions } from \"../format/format-host\";\nimport { optionalStringArg, stringProperty } from \"../commands/command-args\";\nimport type { TemplateResult } from \"lit-html\";\nimport type { AnyCommand, CommandRegistry } from \"../commands/registry\";\n\ninterface SignalsPanelState {\n document: JxMutableNode;\n ui?: TabUi | Record<string, unknown>;\n mode?: string;\n selection?: (string | number)[][];\n canvas?: Record<string, unknown> | null;\n _collapsedSignalCats?: Set<string>;\n documentPath?: string | null | undefined;\n}\n\n/**\n * What the State panel's template needs from its host: a repaint, and nothing else.\n *\n * It carried `renderCanvas` and `updateSession` too, and both are gone for the same reason. The\n * canvas hook lost its last caller when the takeovers went and was left threaded from\n * `registerStatePanel`; the session writer lost its two when the Logic buttons started going\n * through `openLogicTarget`, which addresses the focused tab itself. A ctx field with no reader is\n * an invitation to write the wrong thing through it.\n */\ninterface SignalsPanelCtx {\n renderLeftPanel: () => void;\n /**\n * Re-fire automatic `Request` entries and repaint (the Refresh button).\n *\n * Edit and design suppress automatic fetches — a full render re-resolves every state entry, so\n * authoring would refetch constantly — which is why watching a fetched value needs a verb and not\n * just a repaint.\n */\n refreshData?: () => void;\n}\n\nexport interface SignalDef {\n $prototype?: string;\n $src?: string;\n $export?: string;\n $compute?: string;\n $deps?: string[];\n $expression?: Record<string, unknown>;\n $handler?: string;\n type?: string;\n default?: unknown;\n body?: string | unknown[];\n parameters?: string[];\n timing?: string;\n description?: string;\n fields?: Record<string, unknown>;\n url?: string;\n method?: string;\n key?: string;\n database?: string;\n store?: string;\n version?: number;\n name?: string;\n attribute?: string;\n reflects?: boolean;\n deprecated?: string | boolean;\n format?: string;\n emits?: CemEvent[];\n [key: string]: unknown;\n}\n\n// ─── Module-local state ─────────────────────────────────────────────────────\n\n/**\n * The rename that was refused, and why — cleared by the next accepted one.\n *\n * A collision used to be a silent no-op: the field kept the typed name, the document kept the old\n * one, and nothing said which had won. Plan §11.2 asks for \"collision-checked rename with a visible\n * error\", and half of that had shipped.\n */\nlet renameError: { name: string; message: string } | null = null;\n\n/** Track which functions have the advanced param editor open. */\nconst advancedParamOpen = new Set();\n\n/** Default templates for creating new signal definitions. */\nconst DEF_TEMPLATES = {\n computed: { $compute: \"\", $deps: [] },\n cookie: { $prototype: \"Cookie\", default: \"\", name: \"\" },\n expression: { $expression: { operator: \"=\", target: null } },\n external: { $prototype: \"\", $src: \"\" },\n formData: { $prototype: \"FormData\", fields: {} },\n function: { $prototype: \"Function\", body: \"\", parameters: [] },\n indexedDB: { $prototype: \"IndexedDB\", database: \"\", store: \"\", version: 1 },\n localStorage: { $prototype: \"LocalStorage\", default: null, key: \"\" },\n map: { $prototype: \"Map\", default: {} },\n request: { $prototype: \"Request\", method: \"GET\", timing: \"client\", url: \"\" },\n sessionStorage: { $prototype: \"SessionStorage\", default: null, key: \"\" },\n set: { $prototype: \"Set\", default: [] },\n state: { default: \"\", type: \"string\" },\n} as Record<string, SignalDef>;\n\n/** Keys handled by the framework — skip when rendering schema fields. */\nconst STUDIO_RESERVED_KEYS = new Set([\n \"$prototype\",\n \"$src\",\n \"$export\",\n \"timing\",\n \"default\",\n \"description\",\n \"body\",\n \"parameters\",\n \"name\",\n \"attribute\",\n \"reflects\",\n \"deprecated\",\n \"emits\",\n]);\n\n// ─── Signals / defs helpers ──────────────────────────────────────────────────\n\n/**\n * Extension-manifest state classes for the add-state picker: plain `$prototype` targets (no\n * admission blocks) across the enabled extensions, each with its `$studio.stateDefaults` hint\n * (specs/extensions.md §10). Manifest classes need no `$src` — the registry resolves them.\n */\nexport function extensionStateClasses(): {\n name: string;\n stateDefaults?: Record<string, unknown>;\n}[] {\n const out: { name: string; stateDefaults?: Record<string, unknown> }[] = [];\n for (const ext of getExtensions()) {\n for (const cls of ext.classes ?? []) {\n if (cls.state) {\n out.push({\n name: cls.name,\n ...(cls.stateDefaults === undefined ? {} : { stateDefaults: cls.stateDefaults }),\n });\n }\n }\n }\n return out;\n}\n\n/**\n * View a state entry through the panel's flattened editing lens. Naked primitive and array entries\n * surface as an empty view — the renderers guard every field access.\n *\n * @param {import(\"@jxsuite/schema/types\").JxStateDefinition} def\n * @returns {SignalDef}\n */\nfunction asSignalDef(def: JxStateDefinition): SignalDef {\n return (typeof def === \"object\" && def !== null && !Array.isArray(def) ? def : {}) as SignalDef;\n}\n\n/**\n * Classify a state entry into a category string.\n *\n * @param {SignalDef | unknown} def\n */\nexport function defCategory(def: SignalDef | unknown) {\n if (!def) {\n return \"state\";\n }\n const d = def as SignalDef;\n if (d.$expression) {\n return \"expression\";\n }\n if (d.$handler || d.$prototype === \"Function\") {\n return \"function\";\n }\n if (d.$compute) {\n return \"computed\";\n }\n if (d.$prototype) {\n return \"data\";\n }\n return \"state\";\n}\n\n/**\n * Badge label for a def category.\n *\n * @param {SignalDef | unknown} def\n */\nexport function defBadgeLabel(def: SignalDef | unknown) {\n if (!def) {\n return \"S\";\n }\n const d = def as SignalDef;\n if (d.$expression) {\n return \"E\";\n }\n if (d.$handler || d.$prototype === \"Function\") {\n return \"F\";\n }\n if (d.$compute) {\n return \"C\";\n }\n if (d.$prototype) {\n return d.$prototype.charAt(0);\n }\n return \"S\";\n}\n\n/**\n * Hint text for a signal row.\n *\n * @param {string} name\n * @param {SignalDef | null | undefined} def\n */\nexport function defHint(_name: string, def: SignalDef | null | undefined) {\n if (!def) {\n return \"\";\n }\n if (def.$expression) {\n return expressionHint(def.$expression);\n }\n if (def.$prototype === \"Function\") {\n if (Array.isArray(def.body)) {\n return `${def.body.length} statement${def.body.length === 1 ? \"\" : \"s\"}`;\n }\n if (def.body) {\n return def.body.length > 20 ? `${def.body.slice(0, 20)}...` : def.body;\n }\n if (def.$src) {\n return def.$src;\n }\n return \"function\";\n }\n if (def.$handler) {\n return \"handler (legacy)\";\n }\n if (def.$compute) {\n return `=${def.$compute.length > 20 ? `${def.$compute.slice(0, 20)}...` : def.$compute}`;\n }\n if (def.$prototype === \"Request\") {\n return `${def.method || \"GET\"} ${(def.url || \"\").slice(0, 20)}`;\n }\n if (def.$prototype === \"LocalStorage\" || def.$prototype === \"SessionStorage\") {\n return def.key || \"\";\n }\n if (def.$prototype === \"IndexedDB\") {\n return def.database || \"\";\n }\n if (def.$prototype === \"Cookie\") {\n return def.name || \"\";\n }\n if (def.$prototype) {\n return def.$prototype;\n }\n if (def.attribute) {\n return `[${def.attribute}] ${def.type || \"\"}`;\n }\n return def.type || \"\";\n}\n\n/**\n * Whether the current document defines a custom element (hyphenated tagName).\n *\n * @param {SignalsPanelState} S\n */\nexport function isCustomElementDoc(S: SignalsPanelState) {\n return displayTagName(S.document.tagName).includes(\"-\");\n}\n\n/**\n * Recursively collect CSS `part` attributes from the document tree.\n *\n * @param {JxMutableNode | null | undefined} node\n * @param {{ name: string; tag: string }[]} [parts]\n */\nexport function collectCssParts(\n node: JxMutableNode | null | undefined,\n parts: { name: string; tag: string }[] = [],\n) {\n const part = node?.attributes?.part;\n if (typeof part === \"string\" && part) {\n parts.push({ name: part, tag: displayTagName(node?.tagName) || \"div\" });\n }\n if (Array.isArray(node?.children)) {\n for (const c of node.children) {\n if (typeof c !== \"string\") {\n collectCssParts(c, parts);\n }\n }\n }\n return parts;\n}\n\n/**\n * Resolve a $ref value to a display string using signal defaults. Used by the canvas to show real\n * values instead of raw refs.\n *\n * @param {unknown} value\n * @param {Record<string, SignalDef> | null | undefined} defs\n */\nexport function resolveDefaultForCanvas(\n value: unknown,\n defs: Record<string, JxStateDefinition> | null | undefined,\n) {\n if (!value || typeof value !== \"object\" || !(value as Record<string, unknown>).$ref) {\n return value;\n }\n const ref = (value as Record<string, unknown>).$ref as string;\n /** @type {string | undefined} */\n let defName;\n if (ref.startsWith(\"#/state/\")) {\n defName = ref.slice(8);\n } else if (ref.startsWith(\"$\")) {\n defName = ref;\n } else {\n return `{${ref}}`;\n }\n\n const rawDef = defs?.[defName];\n if (!rawDef) {\n return `{${defName}}`;\n }\n const def = asSignalDef(rawDef);\n\n // State signal → use default\n if (!def.$compute && !def.$prototype) {\n if (def.default !== undefined && def.default !== null) {\n if (typeof def.default === \"object\") {\n return JSON.stringify(def.default);\n }\n return String(def.default);\n }\n return \"\";\n }\n // Computed → expression indicator\n if (def.$compute) {\n return `\\u0192(${defName})`;\n }\n // Request → URL hint\n if (def.$prototype === \"Request\") {\n return `\\u27F3 ${def.url || \"fetch\"}`;\n }\n // Storage → use default or key\n if (def.$prototype === \"LocalStorage\" || def.$prototype === \"SessionStorage\") {\n if (def.default !== undefined && def.default !== null) {\n if (typeof def.default === \"object\") {\n return JSON.stringify(def.default);\n }\n return String(def.default);\n }\n return `[${def.key || \"storage\"}]`;\n }\n if (def.$prototype) {\n return `{${def.$prototype}}`;\n }\n return `{${defName}}`;\n}\n\n// ─── Simple field row ────────────────────────────────────────────────────────\n\n/**\n * Simple field row for signal editors — vertical stacked layout.\n *\n * `error` paints the row invalid and prints the message in a `role=\"alert\"` line, which is how a\n * refused rename says so instead of silently keeping the old name.\n */\nexport function signalFieldRow(\n label: string,\n value: string,\n onChange: (value: string) => void,\n error?: string | undefined,\n) {\n return renderFieldRow({\n prop: label,\n label,\n hasValue: false,\n ...(error === undefined ? {} : { error }),\n // CommitMode \"blur\": signal fields (rename, src, etc.) commit on blur/Enter only — a debounced\n // Mid-typing commit would, e.g., rename the signal on every keystroke pause.\n widget: spTextField(\n `sig:${label}`,\n value,\n (v: string) => {\n if (v !== value) {\n onChange(v);\n }\n },\n { commitMode: \"blur\" },\n ),\n });\n}\n\n/** Normalize a parameter entry to a CEM object. */\nexport function normParam(p: string | CemParameter): CemParameter {\n return typeof p === \"string\" ? { name: p } : p;\n}\n\n/** Extract the display text from a CEM `{ text }` type value, if present. */\nfunction cemTypeText(type: JsonValue | undefined): string {\n if (typeof type === \"object\" && type !== null && !Array.isArray(type)) {\n const { text } = type;\n if (typeof text === \"string\") {\n return text;\n }\n }\n return \"\";\n}\n\n// ─── Left panel: Signals ─────────────────────────────────────────────────────\n\n/**\n * Add a def from one of the built-in templates under a free name, and expand it for editing. Shared\n * by the \"+ Add…\" picker and the panel's empty state, so both create the same thing.\n */\nfunction addTemplateDef(type: string, S: SignalsPanelState, ctx: SignalsPanelCtx) {\n const template = DEF_TEMPLATES[type];\n if (!template) {\n return;\n }\n const nameBase = type === \"function\" ? \"newFunction\" : \"$newSignal\";\n let n = nameBase;\n let i = 1;\n while (S.document.state && S.document.state[n]) {\n n = nameBase + i;\n i += 1;\n }\n transactDoc(activeTab.value, (t) =>\n mutateAddDef(t, n, structuredClone(template) as Record<string, JsonValue>),\n );\n setDataRowExpanded(n, true);\n ctx.renderLeftPanel();\n}\n\n/**\n * @param {SignalsPanelState} S\n * @param {SignalsPanelCtx} ctx\n */\n/**\n * ONE summary slot per row, and the resolved value wins it as soon as there is one.\n *\n * The row wants to say four things about an entry — its category, its name, how it is defined and\n * what it became — and a 240px Navigator fits three. Eliding both summaries to make room produced\n * \"recentproje… C… Array(3)\": two truncated descriptions and a truncated identity. So the\n * definition hint holds the slot until the canvas resolves a value and then steps aside for it, and\n * the full definition is one click down in fields — which is what the hint was abbreviating.\n *\n * The switch is whether the canvas has reported a scope AT ALL, not whether this entry appears in\n * it. An entry the canvas ran and did not produce is \"pending\", which is a fact about the value; a\n * panel opened before the canvas has rendered knows nothing about any of them, and guessing\n * \"pending\" for the whole list there would be a fact about the panel dressed up as one about data.\n *\n * ENTRIES THAT CANNOT HOLD A VALUE never get the column. A function and an assignment expression\n * are things the page DOES, not things it knows, and they are absent from the resolved scope for\n * exactly that reason — so the value column called all eight of a component's `setFilter` handlers\n * \"pending\", which reads as \"still loading\" for something that will never load.\n */\nfunction summary(name: string, def: SignalDef, live: unknown, resolved: boolean) {\n const holdsNoValue =\n defCategory(def) === \"function\" ||\n (def.$expression != null && isActionExpression(def.$expression));\n if (!resolved || holdsNoValue) {\n const hint = defHint(name, def);\n return html`<span class=\"signal-hint\" title=${hint}>${hint}</span>`;\n }\n return html`<span\n class=${classMap({ \"data-pending\": unwrapSignal(live) === null, \"data-type\": true })}\n title=\"What this resolved to on the canvas\"\n >${dataTypeLabel(live)}</span\n >`;\n}\n\nexport function renderSignalsTemplate(S: SignalsPanelState, ctx: SignalsPanelCtx) {\n const defs = S.document.state || {};\n const entries = Object.entries(defs);\n // What the canvas actually resolved these to. `S.canvas` is the session's canvas record, so this\n // Costs a property read — the panel already had the scope in hand and rendered it in a second\n // Panel anyway.\n const liveScope = (S.canvas?.scope ?? null) as Record<string, unknown> | null;\n const scope = liveScope ?? {};\n // A Refresh is out and the canvas has not answered. Read off the tab, so it survives the repaints\n // Between the press and the `dataScope` that ends it.\n const refreshing = S.canvas?.refreshing === true;\n\n // Warm the extensions payload so manifest state classes appear in the add picker (the panel\n // Re-renders constantly; loadExtensions memoizes, so this is a one-time fetch per project).\n void loadExtensions();\n\n // Group by category\n const groups = {\n computed: [],\n data: [],\n expression: [],\n function: [],\n state: [],\n } as Record<string, [string, SignalDef][]>;\n for (const [name, def] of entries) {\n groups[defCategory(def)]!.push([name, asSignalDef(def)]);\n }\n\n const categories = [\n { items: groups.state!, key: \"state\", label: \"State\" },\n { items: groups.computed!, key: \"computed\", label: \"Computed\" },\n { items: groups.data!, key: \"data\", label: \"Data\" },\n { items: groups.expression!, key: \"expression\", label: \"Expressions\" },\n { items: groups.function!, key: \"function\", label: \"Functions\" },\n ];\n\n S._collapsedSignalCats ||= new Set();\n const collapsedCats = S._collapsedSignalCats;\n\n const catTemplates = categories\n .filter((c) => c.items.length > 0)\n .map(\n ({ key, label, items }) => html`\n <sp-accordion-item\n label=\"${label} (${items.length})\"\n ?open=${!collapsedCats.has(key)}\n @sp-accordion-item-toggle=${() => {\n if (collapsedCats.has(key)) {\n collapsedCats.delete(key);\n } else {\n collapsedCats.add(key);\n }\n ctx.renderLeftPanel();\n }}\n >\n ${items.map(([name, def]) => {\n const isExpanded: boolean = isDataRowExpanded(name);\n const live = scope[name];\n return html`\n <div\n class=${classMap({ expanded: isExpanded, \"signal-row\": true })}\n @click=${() => {\n setDataRowExpanded(name, !isExpanded);\n ctx.renderLeftPanel();\n }}\n >\n <span class=\"signal-badge ${defCategory(def)}\">${defBadgeLabel(def)}</span>\n <span class=\"signal-name\">${name}</span>\n ${summary(name, def, live, liveScope !== null)}\n <sp-action-button\n quiet\n size=\"xs\"\n class=\"signal-del\"\n @click=${(e: Event) => {\n e.stopPropagation();\n transactDoc(activeTab.value, (t) => mutateRemoveDef(t, name));\n }}\n >\n <sp-icon-delete slot=\"icon\"></sp-icon-delete>\n </sp-action-button>\n </div>\n ${\n isExpanded\n ? html`<div class=\"signal-editor\">\n ${renderSignalEditorTemplate(S, name, def, ctx)}\n <div class=\"signal-live\">\n <span class=\"signal-live-label\">Resolved to</span>\n <div class=\"data-tree\">\n ${renderDataTreeTemplate(unwrapSignal(live), 0, 5, name)}\n </div>\n </div>\n </div>`\n : nothing\n }\n `;\n })}\n </sp-accordion-item>\n `,\n );\n\n return html`\n <div class=${classMap({ \"is-refreshing\": refreshing, \"signals-panel\": true })}>\n ${\n ctx.refreshData && entries.length > 0\n ? html`<div class=\"data-explorer-toolbar\">\n <sp-action-button\n quiet\n size=\"s\"\n class=\"data-refresh-btn\"\n ?disabled=${refreshing}\n @click=${() => {\n ctx.refreshData?.();\n ctx.renderLeftPanel();\n }}\n >\n ${\n refreshing\n ? html`<sp-progress-circle\n slot=\"icon\"\n indeterminate\n size=\"s\"\n label=\"Refreshing\"\n ></sp-progress-circle>`\n : html`<sp-icon-refresh slot=\"icon\"></sp-icon-refresh>`\n }\n ${refreshing ? \"Refreshing…\" : \"Refresh\"}\n </sp-action-button>\n </div>`\n : nothing\n }\n <sp-accordion allow-multiple size=\"s\"> ${catTemplates} </sp-accordion>\n ${\n entries.length === 0\n ? renderEmptyState({\n actions: [{ label: \"Add a value\", run: () => addTemplateDef(\"state\", S, ctx) }],\n message:\n \"Data lives here — values this page can read, compute or fetch, \" +\n \"ready to bind to any element.\",\n })\n : nothing\n }\n <div class=\"signals-add\">\n <sp-picker\n size=\"s\"\n label=\"+ Add…\"\n placeholder=\"+ Add…\"\n @change=${(e: Event) => {\n const type = (e.target as HTMLInputElement).value;\n if (!type) {\n return;\n }\n\n // Extension-manifest state classes (\"ext:Session\"): no $src needed — the registry\n // Resolves them; the descriptor's stateDefaults seed the def (e.g. timing \"client\").\n if (type.startsWith(\"ext:\")) {\n const protoName = type.slice(4);\n const cls = extensionStateClasses().find((c) => c.name === protoName);\n let n = `$${protoName.charAt(0).toLowerCase()}${protoName.slice(1)}`;\n let i = 1;\n const base = n;\n while (S.document.state && S.document.state[n]) {\n n = base + i;\n i += 1;\n }\n transactDoc(activeTab.value, (t) =>\n mutateAddDef(t, n, {\n $prototype: protoName,\n ...cls?.stateDefaults,\n } as Record<string, JsonValue>),\n );\n setDataRowExpanded(n, true);\n ctx.renderLeftPanel();\n return;\n }\n\n // Handle import-based prototypes (e.g., \"import:ContentCollection\")\n if (type.startsWith(\"import:\")) {\n const protoName = type.slice(7);\n const src = projectState?.projectConfig?.imports?.[protoName];\n let n = `$${protoName.charAt(0).toLowerCase()}${protoName.slice(1)}`;\n let i = 1;\n const base = n;\n while (S.document.state && S.document.state[n]) {\n n = base + i;\n i += 1;\n }\n transactDoc(activeTab.value, (t) =>\n mutateAddDef(\n t,\n n,\n /** @type {Record<string, JsonValue>} */ {\n $prototype: protoName,\n },\n ),\n );\n setDataRowExpanded(n, true);\n if (src) {\n void fetchPluginSchema(\n { $prototype: protoName, $src: src },\n {\n ...(S.documentPath != null && {\n documentPath: S.documentPath,\n }),\n },\n ).then(() => ctx.renderLeftPanel());\n } else {\n ctx.renderLeftPanel();\n }\n return;\n }\n\n addTemplateDef(type, S, ctx);\n }}\n >\n <sp-menu-item value=\"state\">Value</sp-menu-item>\n <sp-menu-item value=\"computed\">Computed</sp-menu-item>\n <sp-menu-divider></sp-menu-divider>\n <sp-menu-item value=\"request\">Fetch from a URL</sp-menu-item>\n <sp-menu-item value=\"localStorage\">LocalStorage</sp-menu-item>\n <sp-menu-item value=\"sessionStorage\">SessionStorage</sp-menu-item>\n <sp-menu-item value=\"indexedDB\">IndexedDB</sp-menu-item>\n <sp-menu-item value=\"cookie\">Cookie</sp-menu-item>\n <sp-menu-item value=\"set\">Set</sp-menu-item>\n <sp-menu-item value=\"map\">Map</sp-menu-item>\n <sp-menu-item value=\"formData\">FormData</sp-menu-item>\n <sp-menu-item value=\"external\">From a module…</sp-menu-item>\n ${\n projectState?.projectConfig?.imports\n ? html`<sp-menu-divider></sp-menu-divider>${Object.keys(\n projectState.projectConfig.imports,\n ).map(\n (k: string) => html`<sp-menu-item value=\"import:${k}\">${k}</sp-menu-item>`,\n )}`\n : nothing\n }\n ${\n extensionStateClasses().length > 0\n ? html`<sp-menu-divider></sp-menu-divider>${extensionStateClasses().map(\n (cls) => html`<sp-menu-item value=\"ext:${cls.name}\">${cls.name}</sp-menu-item>`,\n )}`\n : nothing\n }\n <sp-menu-divider></sp-menu-divider>\n <sp-menu-item value=\"expression\">Expression</sp-menu-item>\n <sp-menu-item value=\"function\">Function</sp-menu-item>\n </sp-picker>\n </div>\n </div>\n `;\n}\n\n/** Render inline editor fields for a specific signal/def type. */\nfunction renderSignalEditorTemplate(\n S: SignalsPanelState,\n name: string,\n defArg: SignalDef,\n ctx: SignalsPanelCtx,\n) {\n const def = typeof defArg === \"object\" && defArg !== null ? defArg : { default: defArg };\n const cat = defCategory(def);\n\n // Helper for picker rows\n const pickerRow = (\n label: string,\n options: string[],\n currentVal: string,\n onChange: (value: string) => void,\n ) =>\n renderFieldRow({\n hasValue: false,\n label,\n prop: label,\n widget: html`\n <sp-picker\n size=\"s\"\n value=${currentVal}\n @change=${(e: Event) => onChange((e.target as HTMLInputElement).value)}\n >\n ${options.map((opt: string) => html`<sp-menu-item value=${opt}>${opt}</sp-menu-item>`)}\n </sp-picker>\n `,\n });\n\n // Helper for textarea rows — uses the shared draft layer (commits on blur/Enter and a 500ms\n // Debounce) so a panel re-render mid-edit can't truncate the in-progress text.\n const textareaRow = (\n label: string,\n value: string,\n onChange: (value: string) => void,\n opts: { minHeight?: string; mono?: boolean } = {},\n ) =>\n renderFieldRow({\n hasValue: false,\n label,\n prop: label,\n widget: rawTextArea(`sig:${label}`, value, onChange, {\n debounceMs: 500,\n ...(opts.minHeight != null && { minHeight: opts.minHeight }),\n ...(opts.mono != null && { mono: opts.mono }),\n }),\n });\n\n /*\n * Name field (common to all).\n *\n * Every refusal SAYS SO. A collision silently kept the old name while the field showed the new\n * one, so the panel and the document disagreed and only the canvas could tell you which had won —\n * and an empty name did the same. The expansion follows the rename so the editor you are typing\n * in is still the one on screen afterwards.\n */\n const nameField = signalFieldRow(\n \"Name\",\n name,\n (v: string) => {\n const next = v.trim();\n if (next === name) {\n renameError = null;\n return;\n }\n if (!next) {\n renameError = { message: \"A name is required.\", name };\n } else if (S.document.state?.[next]) {\n renameError = { message: `\"${next}\" is already defined by this document.`, name };\n } else {\n renameError = null;\n // The expansion follows the rename, so the editor you are typing in is still the one on\n // Screen when the row list repaints under the new name.\n setDataRowExpanded(name, false);\n setDataRowExpanded(next, true);\n transactDoc(activeTab.value, (t) => mutateRenameDef(t, name, next));\n }\n ctx.renderLeftPanel();\n },\n renameError?.name === name ? renameError.message : undefined,\n );\n\n let fields: TemplateResult | typeof nothing = nothing;\n\n if (cat === \"state\") {\n const defaultVal =\n def.default !== undefined && def.default !== null\n ? typeof def.default === \"object\"\n ? JSON.stringify(def.default)\n : String(def.default)\n : \"\";\n\n const cemFields = isCustomElementDoc(S)\n ? html`\n ${signalFieldRow(\"Attribute\", def.attribute || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { attribute: v || undefined }),\n ),\n )}\n ${renderFieldRow({\n hasValue: false,\n label: \"Reflects\",\n prop: \"reflects\",\n widget: html`\n <sp-checkbox\n class=\"field-check\"\n ?checked=${Boolean(def.reflects)}\n @change=${(e: Event) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, {\n reflects: (e.target as HTMLInputElement).checked || undefined,\n }),\n )}\n ></sp-checkbox>\n `,\n })}\n ${signalFieldRow(\n \"Deprecated\",\n typeof def.deprecated === \"string\" ? def.deprecated : \"\",\n (v: string) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { deprecated: v || undefined }),\n ),\n )}\n `\n : nothing;\n\n fields = html`\n ${pickerRow(\n \"Type\",\n [\"string\", \"integer\", \"number\", \"boolean\", \"array\", \"object\"],\n def.type || \"string\",\n (v: string) => transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { type: v })),\n )}\n ${\n def.type === \"string\" || !def.type\n ? pickerRow(\"Format\", [\"\", \"image\", \"date\", \"color\"], def.format || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { format: v || undefined }),\n ),\n )\n : nothing\n }\n ${\n def.format === \"image\"\n ? renderFieldRow({\n hasValue: false,\n label: \"Default\",\n prop: \"Default\",\n widget: renderMediaPicker(\"default\", defaultVal, (v: string) => {\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { default: v || undefined }),\n );\n }),\n })\n : signalFieldRow(\"Default\", defaultVal, (v: string) => {\n let parsed: unknown = v;\n if (def.type === \"integer\") {\n parsed = Math.trunc(Number(v)) || 0;\n } else if (def.type === \"number\") {\n parsed = Number(v) || 0;\n } else if (def.type === \"boolean\") {\n parsed = v === \"true\";\n } else if (def.type === \"array\" || def.type === \"object\") {\n try {\n parsed = JSON.parse(v);\n } catch {\n parsed = v;\n }\n }\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { default: parsed as JsonValue }),\n );\n })\n }\n ${signalFieldRow(\"Description\", def.description || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { description: v || undefined }),\n ),\n )}\n ${cemFields}\n `;\n } else if (cat === \"computed\") {\n let debounce: ReturnType<typeof setTimeout> | undefined;\n fields = html`\n ${renderFieldRow({\n hasValue: false,\n label: \"Expression\",\n prop: \"expression\",\n widget: html`\n <textarea\n class=\"field-input\"\n style=\"min-height:40px\"\n .value=${def.$compute || \"\"}\n @input=${(e: Event) => {\n clearTimeout(debounce);\n debounce = setTimeout(() => {\n const expr = (e.target as HTMLInputElement).value;\n const depMatches = expr.match(/\\$[a-zA-Z_]\\w*/g) || [];\n const deps = [...new Set(depMatches)].map((d) => `#/state/${d}`);\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { $compute: expr, $deps: deps }),\n );\n }, 500);\n }}\n ></textarea>\n `,\n })}\n ${\n def.$deps && def.$deps.length > 0\n ? renderFieldRow({\n hasValue: false,\n label: \"Dependencies\",\n prop: \"dependencies\",\n widget: html`\n <span class=\"signal-hint\" style=\"flex:1;max-width:none\"\n >${def.$deps.map((d: string) => d.replace(\"#/state/\", \"\")).join(\", \")}</span\n >\n `,\n })\n : nothing\n }\n `;\n } else if (cat === \"data\") {\n fields = renderDataSourceFields(S, name, def, textareaRow, pickerRow, ctx);\n } else if (cat === \"function\") {\n fields = renderFunctionFields(S, name, def, textareaRow, ctx);\n } else if (cat === \"expression\") {\n const exprNode = def.$expression || { operator: \"=\", target: null };\n fields = html`\n <div style=\"display:flex;align-items:center;gap:4px\">\n <span class=\"field-label\" style=\"flex:1\">Expression</span>\n <sp-action-button\n size=\"xs\"\n quiet\n title=\"Open in formula workspace\"\n @click=${() => {\n // One call, because a click is BOTH events: it names the target and it asks for the\n // Surface. Setting the field alone leaned on the dock's reveal effect, which fires at\n // Most once per target — so clicking this again after closing the dock was a dead\n // Click. It also left `editingFunction` set, and that one wins the tie.\n openLogicTarget({ editing: { defName: name, type: \"def\" }, surface: \"formula\" });\n }}\n >\n <sp-icon-align-bottom slot=\"icon\"></sp-icon-align-bottom>\n </sp-action-button>\n </div>\n ${renderExpressionEditor(\n exprNode,\n (newNode: unknown) =>\n transactDoc(activeTab.value, (t) =>\n // Expression editors emit JSON expression nodes.\n mutateUpdateDef(t, name, { $expression: newNode as JsonValue }),\n ),\n {\n allowEventRef: false,\n // Live-context evaluation in the canvas iframe, snapshot fallback (M6). The signals\n // Panel lives in the left panel — re-render it when a fresh live result lands.\n preview: livePreviewExpression(activeTab.value, `def:${name}`, exprNode, null, () =>\n renderOnly(\"leftPanel\"),\n ),\n onInsertDef: (defName, vendored) =>\n transactDoc(activeTab.value, (t) =>\n mutateAddDef(t, defName, vendored as Record<string, JsonValue>),\n ),\n stateDefs: Object.keys(S.document.state || {}),\n stateEntries: S.document.state || {},\n },\n )}\n `;\n }\n\n return html`${nameField}${fields}`;\n}\n\n/** Data source fields for signal editor */\nfunction renderDataSourceFields(\n S: SignalsPanelState,\n name: string,\n def: SignalDef,\n textareaRow: (\n label: string,\n value: string,\n onChange: (value: string) => void,\n opts?: { minHeight?: string; mono?: boolean },\n ) => TemplateResult,\n pickerRow: (\n label: string,\n options: string[],\n currentVal: string,\n onChange: (value: string) => void,\n ) => TemplateResult,\n ctx: SignalsPanelCtx,\n) {\n const proto = def.$prototype;\n\n if (proto === \"Request\") {\n return html`\n ${signalFieldRow(\"URL\", def.url || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { url: v })),\n )}\n ${pickerRow(\n \"Method\",\n [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\"],\n def.method || \"GET\",\n (v: string) => transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { method: v })),\n )}\n ${pickerRow(\"Timing\", [\"client\", \"server\"], def.timing || \"client\", (v: string) =>\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { timing: v })),\n )}\n `;\n }\n if (proto === \"LocalStorage\" || proto === \"SessionStorage\") {\n const defaultStr =\n def.default !== undefined && def.default !== null\n ? typeof def.default === \"object\"\n ? JSON.stringify(def.default, null, 2)\n : String(def.default)\n : \"\";\n return html`\n ${signalFieldRow(\"Key\", def.key || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { key: v })),\n )}\n ${textareaRow(\"Default\", defaultStr, (v: string) => {\n try {\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { default: JSON.parse(v) }));\n } catch {\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { default: v }));\n }\n })}\n `;\n }\n if (proto === \"IndexedDB\") {\n return html`\n ${signalFieldRow(\"Database\", def.database || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { database: v })),\n )}\n ${signalFieldRow(\"Store\", def.store || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { store: v })),\n )}\n ${signalFieldRow(\"Version\", String(def.version || 1), (v: string) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { version: Math.trunc(Number(v)) || 1 }),\n ),\n )}\n `;\n }\n if (proto === \"Cookie\") {\n return html`\n ${signalFieldRow(\"Cookie\", def.name || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { name: v })),\n )}\n ${signalFieldRow(\"Default\", String(def.default || \"\"), (v: string) =>\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { default: v })),\n )}\n `;\n }\n if (proto === \"Set\" || proto === \"Map\" || proto === \"FormData\") {\n const fieldName = proto === \"FormData\" ? \"fields\" : \"default\";\n const fieldLabel = proto === \"FormData\" ? \"Fields\" : \"Default\";\n const defaultStr =\n def.default !== undefined && def.default !== null\n ? JSON.stringify(def.default, null, 2)\n : proto === \"FormData\"\n ? JSON.stringify(def.fields || {}, null, 2)\n : \"\";\n return textareaRow(fieldLabel, defaultStr, (v: string) => {\n try {\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { [fieldName]: JSON.parse(v) as unknown }),\n );\n } catch {}\n });\n }\n // Schema-driven fallback\n return renderExternalPrototypeEditorTemplate(S, name, def, ctx);\n}\n\n/** Function fields for signal editor */\nfunction renderFunctionFields(\n S: SignalsPanelState,\n name: string,\n def: SignalDef,\n _textareaRow: (\n label: string,\n value: string,\n onChange: (value: string) => void,\n opts?: { minHeight?: string; mono?: boolean },\n ) => TemplateResult,\n ctx: SignalsPanelCtx,\n) {\n const descriptionField = signalFieldRow(\"Description\", def.description || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { description: v || undefined })),\n );\n\n // Structured bodies (spec §20) are a body MODE of the function category, not a new entity:\n // \"Statements\" renders the statement-card editor over `body: JxStatement[]`; \"Code\" is the\n // Textarea/Monaco path over `body: string`. Switching modes replaces the body with the other\n // Representation's empty seed — an explicit mode change, nothing is converted.\n const bodyIsStatements = Array.isArray(def.body);\n const bodyModeToggle = html`\n <sp-action-group size=\"s\" compact class=\"body-mode-toggle\">\n <sp-action-button\n size=\"s\"\n class=\"body-mode-statements\"\n ?selected=${bodyIsStatements}\n @click=${() => {\n if (!bodyIsStatements) {\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { body: [] }));\n ctx.renderLeftPanel();\n }\n }}\n >\n Statements\n </sp-action-button>\n <sp-action-button\n size=\"s\"\n class=\"body-mode-code\"\n ?selected=${!bodyIsStatements}\n @click=${() => {\n if (bodyIsStatements) {\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { body: \"\" }));\n ctx.renderLeftPanel();\n }\n }}\n >\n Code\n </sp-action-button>\n </sp-action-group>\n `;\n\n const bodyField = def.$src\n ? html`\n ${signalFieldRow(\"Source\", def.$src || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { $src: v || undefined })),\n )}\n ${signalFieldRow(\"Export\", def.$export || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { $export: v || undefined }),\n ),\n )}\n `\n : html`\n <div style=\"display:flex;align-items:center;gap:4px\">\n <span class=\"field-label\" style=\"flex:1\">Body</span>\n ${bodyModeToggle}\n ${\n bodyIsStatements\n ? nothing\n : html`\n <sp-action-button\n size=\"xs\"\n quiet\n title=\"Open in code editor\"\n @click=${() => {\n // Target AND reveal, in one call. See the formula button above.\n openLogicTarget({\n editing: { defName: name, type: \"def\" },\n surface: \"function\",\n });\n }}\n >\n <sp-icon-code slot=\"icon\"></sp-icon-code>\n </sp-action-button>\n `\n }\n </div>\n ${\n bodyIsStatements\n ? renderStatementEditor(\n def.body as JxStatement[],\n (next) => {\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { body: next as unknown as JsonValue }),\n );\n ctx.renderLeftPanel();\n },\n {\n allowEventRef: true,\n emits: def.emits ?? [],\n // This editor is in the Navigator's State panel; the Events tab's is not.\n region: NAVIGATOR_STATEMENTS_REGION,\n stateDefs: Object.keys(S.document.state || {}),\n stateEntries: S.document.state || {},\n },\n )\n : html`\n <textarea\n class=\"field-input\"\n style=\"min-height:60px;font-family:var(--font-mono);font-size:var(--spectrum-font-size-50, 11px)\"\n .value=${typeof def.body === \"string\" ? def.body : \"\"}\n @input=${(e: Event) => {\n const v = (e.target as HTMLInputElement).value;\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { body: v }));\n }}\n ></textarea>\n `\n }\n `;\n\n return html`\n ${descriptionField} ${renderParameterEditorTemplate(S, name, def, ctx)}\n ${isCustomElementDoc(S) ? renderEmitsEditorTemplate(S, name, def) : nothing} ${bodyField}\n `;\n}\n\n// ─── CEM Editors ─────────────────────────────────────────────────────────────\n\n/** Render CEM parameter editor with basic/advanced toggle. */\nfunction renderParameterEditorTemplate(\n _S: SignalsPanelState,\n name: string,\n def: SignalDef,\n ctx: SignalsPanelCtx,\n) {\n const params = (def.parameters || []).map((p) => normParam(p));\n const isAdvanced = advancedParamOpen.has(name);\n\n if (!isAdvanced) {\n // Basic mode: name chips\n return renderFieldRow({\n hasValue: false,\n label: \"Parameters\",\n prop: \"parameters\",\n widget: html`\n <div style=\"display:flex;flex-wrap:wrap;gap:4px;align-items:center\">\n ${params.map(\n (p: CemParameter, i: number) => html`\n <span\n style=\"display:inline-flex;align-items:center;gap:2px;padding:1px 6px;border-radius:var(--radius);background:var(--hover-bg);font-size:var(--spectrum-font-size-50, 11px);font-family:var(--font-mono)\"\n >\n ${p.name || \"?\"}\n <span\n style=\"cursor:pointer;opacity:0.5;margin-left:2px\"\n @click=${() => {\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, {\n parameters: params.some((_: unknown, j: number) => j !== i)\n ? params.filter((_: unknown, j: number) => j !== i)\n : undefined,\n }),\n );\n }}\n >×</span\n >\n </span>\n `,\n )}\n <input\n class=\"field-input\"\n style=\"width:60px;flex:0 0 auto;font-size:var(--spectrum-font-size-50, 11px)\"\n placeholder=\"+\"\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === \"Enter\" && (e.target as HTMLInputElement).value.trim()) {\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, {\n parameters: [...params, { name: (e.target as HTMLInputElement).value.trim() }],\n }),\n );\n }\n }}\n />\n </div>\n <span\n style=\"font-size:10px;color:var(--fg-dim);cursor:pointer;width:100%;margin-top:2px\"\n @click=${() => {\n advancedParamOpen.add(name);\n ctx.renderLeftPanel();\n }}\n >▸ Advanced</span\n >\n `,\n });\n }\n\n // Advanced mode: full rows\n return renderFieldRow({\n hasValue: false,\n label: \"Parameters\",\n prop: \"parameters\",\n widget: html`\n <div style=\"display:flex;flex-direction:column;gap:4px\">\n ${params.map(\n (p: CemParameter, i: number) => html`\n <div style=\"display:flex;gap:4px;align-items:center\">\n <input\n class=\"field-input\"\n .value=${p.name || \"\"}\n placeholder=\"name\"\n style=\"flex:1\"\n @change=${(e: Event) => {\n const next = [...params];\n next[i] = {\n ...next[i],\n name: (e.target as HTMLInputElement).value,\n };\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { parameters: next }),\n );\n }}\n />\n <input\n class=\"field-input\"\n .value=${cemTypeText(p.type)}\n placeholder=\"type\"\n style=\"flex:1\"\n @change=${(e: Event) => {\n const next = [...params];\n const val = (e.target as HTMLInputElement).value;\n const { type: _t, ...rest } = next[i]!;\n next[i] = val ? { ...rest, type: { text: val } } : rest;\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { parameters: next }),\n );\n }}\n />\n <input\n class=\"field-input\"\n .value=${p.description || \"\"}\n placeholder=\"desc\"\n style=\"flex:2\"\n @change=${(e: Event) => {\n const next = [...params];\n const val = (e.target as HTMLInputElement).value;\n const { description: _d, ...rest } = next[i]!;\n next[i] = val ? { ...rest, description: val } : rest;\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { parameters: next }),\n );\n }}\n />\n <input\n type=\"checkbox\"\n title=\"optional\"\n .checked=${Boolean(p.optional)}\n @change=${(e: Event) => {\n const next = [...params];\n const { checked } = e.target as HTMLInputElement;\n const { optional: _o, ...rest } = next[i]!;\n next[i] = checked ? { ...rest, optional: true } : rest;\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { parameters: next }),\n );\n }}\n />\n <span\n style=\"cursor:pointer;opacity:0.5\"\n @click=${() => {\n const next = params.filter((_: unknown, j: number) => j !== i);\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, {\n parameters: next.length > 0 ? next : undefined,\n }),\n );\n }}\n >×</span\n >\n </div>\n `,\n )}\n <button\n class=\"kv-add\"\n @click=${() =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, {\n parameters: [...params, { name: \"\" }],\n }),\n )}\n >\n + Add parameter\n </button>\n </div>\n <span\n style=\"font-size:10px;color:var(--fg-dim);cursor:pointer;width:100%;margin-top:2px\"\n @click=${() => {\n advancedParamOpen.delete(name);\n ctx.renderLeftPanel();\n }}\n >▾ Basic</span\n >\n `,\n });\n}\n\n/** Render CEM emits editor for function state entries. */\nfunction renderEmitsEditorTemplate(S: SignalsPanelState, name: string, def: SignalDef) {\n const emits = def.emits || ([] as CemEvent[]);\n if (emits.length === 0 && !isCustomElementDoc(S)) {\n return nothing;\n }\n\n return html`\n <div\n style=\"font-size:var(--spectrum-font-size-50, 11px);font-weight:600;color:var(--fg-dim);margin:8px 0 4px;text-transform:uppercase;letter-spacing:0.05em\"\n >\n Emits\n </div>\n ${emits.map(\n (ev: CemEvent, i: number) => html`\n <div style=\"display:flex;gap:4px;align-items:center;margin-bottom:4px\">\n <input\n class=\"field-input\"\n .value=${ev.name || \"\"}\n placeholder=\"event name\"\n style=\"flex:1\"\n @change=${(e: Event) => {\n const next = [...emits];\n next[i] = {\n ...next[i],\n name: (e.target as HTMLInputElement).value,\n };\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { emits: next }));\n }}\n />\n <input\n class=\"field-input\"\n .value=${cemTypeText(ev.type)}\n placeholder=\"type\"\n style=\"flex:1\"\n @change=${(e: Event) => {\n const next = [...emits];\n const val = (e.target as HTMLInputElement).value;\n const { type: _t, ...rest } = next[i]!;\n next[i] = val ? { ...rest, type: { text: val } } : rest;\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { emits: next }));\n }}\n />\n <input\n class=\"field-input\"\n .value=${ev.description || \"\"}\n placeholder=\"description\"\n style=\"flex:2\"\n @change=${(e: Event) => {\n const next = [...emits];\n const val = (e.target as HTMLInputElement).value;\n const { description: _d, ...rest } = next[i]!;\n next[i] = val ? { ...rest, description: val } : rest;\n transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { emits: next }));\n }}\n />\n <span\n style=\"cursor:pointer;opacity:0.5\"\n @click=${() => {\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, {\n emits: emits.some((_: unknown, j: number) => j !== i)\n ? emits.filter((_: unknown, j: number) => j !== i)\n : undefined,\n }),\n );\n }}\n >×</span\n >\n </div>\n `,\n )}\n <button\n class=\"kv-add\"\n @click=${() =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { emits: [...emits, { name: \"\" }] }),\n )}\n >\n + Add event\n </button>\n `;\n}\n\n// ─── Plugin schema-driven form rendering ────────────────────────────────────\n\n/**\n * Resolve a schema context pointer for signal config forms — a thin wrapper over the generic\n * `resolveContextPointer` making the content-type roots always-present (a missing section resolves\n * to `{}` → empty choices rather than a plain textfield): the parser's real descriptors point at\n * the `#/$context/content` root, while the deprecated `\"$contentTypes\"` string sentinel and the\n * legacy `#/$context/contentTypes` root keep resolving bit-for-bit for old class descriptors.\n *\n * @param {string} pointer\n * @param {Record<string, unknown>} [scope] - Parent def for `{@param}` substitution\n * @returns {unknown}\n */\nfunction resolveSignalsContextPointer(pointer: string, scope?: Record<string, unknown>): unknown {\n if (pointer === \"#/$context/content\") {\n return projectState?.projectConfig?.content ?? {};\n }\n if (pointer === \"$contentTypes\" || pointer === \"#/$context/contentTypes\") {\n return projectState?.projectConfig?.contentTypes ?? {};\n }\n return resolveContextPointer(pointer, {\n projectConfig: (projectState?.projectConfig ?? {}) as Record<string, unknown>,\n ...(scope !== undefined && { scope }),\n });\n}\n\n/**\n * Render config form fields from a JSON Schema `properties` object — a thin wrapper over the shared\n * schema-form engine. Skips studio-reserved keys, resolves enum/context refs against the project\n * config, and commits every patch through transactDoc/mutateUpdateDef.\n */\nexport function renderSchemaFieldsTemplate(\n schema: JsonSchema | null | undefined,\n def: SignalDef,\n name: string,\n S: SignalsPanelState,\n ctx: SignalsPanelCtx | null = null,\n) {\n if (!schema?.properties) {\n return nothing;\n }\n\n const properties = Object.fromEntries(\n Object.entries(schema.properties).filter(([prop]) => !STUDIO_RESERVED_KEYS.has(prop)),\n );\n\n return renderForm({ ...schema, properties }, def as Record<string, unknown>, {\n context: {\n fieldKeyPrefix: name,\n params: dynamicRouteParams(S.documentPath),\n resolvePointer: resolveSignalsContextPointer,\n // A config value may point at any signal but this one — a def that reads itself is a cycle.\n signals: bindableSignalNames(S.document).filter((signal) => signal !== name),\n },\n onChange: (patch) => transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, patch)),\n ...(ctx && { rerender: () => ctx.renderLeftPanel() }),\n });\n}\n\n/**\n * Render editor fields for an external $prototype + $src plugin. Shows $src/$export inputs plus\n * schema-driven config fields.\n */\nexport function renderExternalPrototypeEditorTemplate(\n S: SignalsPanelState,\n name: string,\n def: SignalDef,\n ctx: SignalsPanelCtx,\n) {\n // Schema-driven config fields (async with cache)\n let schemaContent: TemplateResult | typeof nothing = nothing;\n const importedPath = def.$prototype\n ? projectState?.projectConfig?.imports?.[def.$prototype]\n : null;\n const resolvedSrc = def.$src || importedPath;\n if (resolvedSrc && def.$prototype) {\n const cacheKey = `${resolvedSrc}::${def.$prototype}`;\n if (pluginSchemaCache.has(cacheKey)) {\n const schema = pluginSchemaCache.get(cacheKey);\n if (schema) {\n schemaContent = html`\n ${\n schema.description\n ? html`<div class=\"signal-hint\" style=\"padding:4px 0 8px\">${schema.description}</div>`\n : nothing\n }\n ${renderSchemaFieldsTemplate(schema as JsonSchema, def, name, S, ctx)}\n `;\n }\n } else {\n // Trigger async load — will re-render when cached\n schemaContent = html`<div\n style=\"padding:4px 0;font-size:var(--spectrum-font-size-50, 11px);color:var(--fg-dim);font-style:italic\"\n >\n Loading schema…\n </div>`;\n void fetchPluginSchema(def, {\n ...(S.documentPath != null && { documentPath: S.documentPath }),\n }).then((schema) => {\n if (schema) {\n ctx.renderLeftPanel();\n }\n });\n }\n }\n\n return html`\n ${\n importedPath\n ? html`<div\n class=\"signal-hint\"\n style=\"padding:4px 0 2px;font-size:var(--spectrum-font-size-50, 11px);color:var(--fg-dim)\"\n >\n ${def.$prototype}\n </div>`\n : html`\n ${signalFieldRow(\"Source\", def.$src || \"\", (v: string) => {\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { $src: v || undefined }),\n );\n pluginSchemaCache.delete(`${v}::${def.$prototype}`);\n })}\n ${signalFieldRow(\"Kind\", def.$prototype || \"\", (v: string) => {\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { $prototype: v || undefined }),\n );\n pluginSchemaCache.delete(`${def.$src}::${v}`);\n })}\n `\n }\n ${\n def.$export\n ? signalFieldRow(\"Export\", def.$export || \"\", (v: string) =>\n transactDoc(activeTab.value, (t) =>\n mutateUpdateDef(t, name, { $export: v || undefined }),\n ),\n )\n : nothing\n }\n ${schemaContent}\n `;\n}\n\n// ─── Commands ─────────────────────────────────────────────────────────────────\n\n/* THE ROW VERB IS `data.expandRow` — one gesture, one command.\n `state.selectSignal` opened exactly one editor and `data.expandRow` opened any number of value\n trees, on the same rows, from two panels. Merging the panels merged the verbs, and the survivor\n is the one that names the state it ends in (`{expanded: false}` collapses, running it twice\n photographs the same picture) rather than the one whose only argument was a new selection. */\n\n/** The state entries the open document defines. */\nfunction definedSignalNames(): string[] {\n return Object.keys(activeTab.value?.doc.document?.state ?? {});\n}\n\n/* THE VERB NEEDS NOTHING FROM ITS HOST ANY MORE.\n `SignalsCommandDeps` carried `renderLeftPanel` for `state.selectSignal`, which is gone; the one\n verb left reveals its own surface through `openLogicTarget`. A dep with no reader is an\n invitation to write the wrong thing through it, which is why the parameter went with it. */\n\n/**\n * Open a state entry's formula in the Bottom dock.\n *\n * It used to be an XPath press matching the row's RENDERED NAME, which plan §13's R1 forbids\n * outright: a panel that starts eliding long names, or grouping differently, breaks a shot by\n * improving the app. The document defines these names, so the document is what validates them.\n *\n * It defaults its target to the one open Data row — the button it replaces is rendered inside that\n * entry's own editor, so \"the one that is open\" is what a reader means, and with several open it\n * asks rather than guesses. It REFUSES a signal with no `$expression`: the workspace edits an\n * expression tree, and opening it over a plain state entry used to paint an empty canvas takeover.\n *\n * It goes through `openLogicTarget` rather than the canvas repaint it used to fire, for the same\n * reason the panel BUTTONS do. A command is the palette's and the automation's door:\n * `formula.editDef` and `formula.editEvent` both leave the surface on screen when they return, and\n * a verb that merely arms a dock the user has collapsed would report success while showing nothing.\n * The reveal is idempotent.\n *\n * @returns {AnyCommand[]}\n */\nexport function signalsCommands(): AnyCommand[] {\n /** The named entry, or a refusal listing what the document does define. */\n function requireDef(commandId: string, name: string): SignalDef {\n const defs = (activeTab.value?.doc.document?.state ?? {}) as Record<string, SignalDef>;\n const def = defs[name];\n if (!def) {\n const defined = definedSignalNames();\n throw new RangeError(\n `command \"${commandId}\" argument \"name\": \"${name}\" is not a state entry this document ` +\n `defines — it defines: ${defined.length > 0 ? defined.join(\", \") : \"nothing\"}`,\n );\n }\n return def;\n }\n\n return [\n {\n args: {\n additionalProperties: false,\n properties: {\n defName: stringProperty(\n \"The state entry whose $expression to edit. Defaults to the selected one.\",\n ),\n },\n required: [],\n type: \"object\",\n },\n category: \"Document\",\n id: \"formula.openWorkspace\",\n level: \"document\",\n menus: [\"palette\"],\n group: \"5_data\",\n requires: \"a selected state entry that holds a formula\",\n when: (ctx) => ctx.document.open,\n run: (_commandCtx, args) => {\n const named = optionalStringArg(\"formula.openWorkspace\", args, \"defName\");\n // With no argument the target is the one open row — and only if there is exactly one.\n // Multiple rows open is now the normal state of this panel, so \"the selected one\" has to\n // Refuse an ambiguous answer rather than pick the first key it happens to enumerate.\n const open = expandedDataRows();\n const defName = named ?? (open.length === 1 ? open[0]! : null);\n if (defName === null) {\n throw new RangeError(\n open.length > 1\n ? `command \"formula.openWorkspace\" needs a target: ${open.length} Data rows are ` +\n `open (${open.join(\", \")}), so pass \"defName\"`\n : `command \"formula.openWorkspace\" needs a target: pass \"defName\", or open a state ` +\n `entry's row first with data.expandRow`,\n );\n }\n const def = requireDef(\"formula.openWorkspace\", defName);\n if (!def.$expression) {\n throw new RangeError(\n `command \"formula.openWorkspace\" argument \"defName\": \"${defName}\" holds no ` +\n `$expression — the workspace edits formulas, and this entry is not one`,\n );\n }\n // The workspace reads its target off the tab; the Bottom dock's Logic tab is where it\n // Draws. Nothing on the canvas depends on this field any more.\n openLogicTarget({ editing: { defName, type: \"def\" }, surface: \"formula\" });\n },\n title: \"Open Formula Workspace\",\n },\n ];\n}\n\n/**\n * Register the State panel's verbs.\n *\n * @param {CommandRegistry} registry\n */\nexport function registerSignalsCommands(registry: CommandRegistry): void {\n registry.registerAll(signalsCommands());\n}\n\n/* THE STATE PANEL IS GONE, AND ITS EDITOR IS IN DATA — `panels/data-explorer.ts`.\n It was registered here `rail: false`, waiting for plan §11.2's merge into Data, and the merge did\n not follow: the button was removed and the editor was left reachable only by typing \"State\" into\n the palette. Declaring a state variable — or a component property, which is a state entry with a\n default — is not an advanced move to hide behind a search box, so `renderSignalsTemplate` is now\n rendered by the Data panel and there is no second record. A stored `leftTab: \"state\"` migrates to\n `data` in `shell.ts`. */\n"
28
+ ],
29
+ "mappings": "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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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",
30
+ "debugId": "B0BC80E7BED86F2664756E2164756E21",
31
+ "names": []
32
+ }