@aceshooting/lyra-ui 27.0.0 → 28.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 (397) hide show
  1. package/CHANGELOG.md +67 -63
  2. package/README.md +7 -3
  3. package/dist/cli/css-declarations.mjs +1 -0
  4. package/dist/cli/lyra-rename-ledger.mjs +1 -1
  5. package/dist/cli/migrate-wa.mjs +9 -4
  6. package/dist/cli/migration-contract.json +1 -1
  7. package/dist/cli/migration-renames.mjs +2 -2
  8. package/dist/cli/migration-theme-scopes.mjs +3 -0
  9. package/dist/cli/theme-scope-vocabulary.generated.mjs +1 -0
  10. package/dist/components/agent-tools/activity-feed/activity-feed.class.js +1 -1
  11. package/dist/components/agent-tools/agent-eval-dashboard/agent-eval-dashboard.class.js +1 -1
  12. package/dist/components/agent-tools/agent-question/agent-question.class.js +1 -1
  13. package/dist/components/agent-tools/agent-run/agent-run.class.js +1 -1
  14. package/dist/components/agent-tools/agent-trace/agent-trace.class.js +1 -1
  15. package/dist/components/agent-tools/approval-queue/approval-queue.class.js +1 -1
  16. package/dist/components/agent-tools/artifact-panel/artifact-panel.class.js +1 -1
  17. package/dist/components/agent-tools/background-runs/background-runs.class.js +1 -1
  18. package/dist/components/agent-tools/browser-frame/browser-frame.class.js +1 -1
  19. package/dist/components/agent-tools/budget-meter/budget-meter.class.js +1 -1
  20. package/dist/components/agent-tools/change-review/change-review.class.js +1 -1
  21. package/dist/components/agent-tools/commit-card/commit-card.class.js +1 -1
  22. package/dist/components/agent-tools/compare-panel/compare-panel.class.js +1 -1
  23. package/dist/components/agent-tools/confirm-bar/confirm-bar.class.js +1 -1
  24. package/dist/components/agent-tools/connector-manager/connector-manager.class.js +1 -1
  25. package/dist/components/agent-tools/context-inspector/context-inspector.class.js +1 -1
  26. package/dist/components/agent-tools/eval-dataset/eval-dataset.class.js +1 -1
  27. package/dist/components/agent-tools/eval-result/eval-result.class.js +1 -1
  28. package/dist/components/agent-tools/evaluation-run/evaluation-run.class.js +1 -1
  29. package/dist/components/agent-tools/mcp-app/mcp-app.class.js +1 -1
  30. package/dist/components/agent-tools/permission-grant/permission-grant.class.js +1 -1
  31. package/dist/components/agent-tools/permission-rules/permission-rules.class.js +1 -1
  32. package/dist/components/agent-tools/policy-summary/policy-summary.class.js +1 -1
  33. package/dist/components/agent-tools/prompt-studio/prompt-studio.class.js +1 -1
  34. package/dist/components/agent-tools/result-card/result-field.class.js +1 -1
  35. package/dist/components/agent-tools/schema-viewer/schema-viewer.class.js +1 -1
  36. package/dist/components/agent-tools/span-waterfall/span-waterfall.class.js +1 -1
  37. package/dist/components/agent-tools/stack-trace/stack-trace.class.js +1 -1
  38. package/dist/components/agent-tools/subagent-panel/subagent-panel.class.js +2 -2
  39. package/dist/components/agent-tools/task-list/task-list.class.js +2 -2
  40. package/dist/components/agent-tools/terminal/terminal.class.js +1 -1
  41. package/dist/components/agent-tools/test-results/test-results.class.js +1 -1
  42. package/dist/components/agent-tools/thinking-panel/thinking-panel.class.js +1 -1
  43. package/dist/components/agent-tools/tool-approval-dialog/tool-approval-dialog.class.js +1 -1
  44. package/dist/components/agent-tools/tool-call-block/tool-call-block.class.js +1 -1
  45. package/dist/components/agent-tools/tool-call-chip/tool-call-chip.class.js +1 -1
  46. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +1 -1
  47. package/dist/components/agent-tools/tool-result-dialog/tool-result-dialog.class.js +1 -1
  48. package/dist/components/agent-tools/tool-result-view/tool-result-view.class.js +1 -1
  49. package/dist/components/agent-tools/tool-select-dialog/tool-select-dialog.class.js +1 -1
  50. package/dist/components/agent-tools/tool-timeline/tool-timeline.class.js +1 -1
  51. package/dist/components/agent-tools/trace-tree/trace-tree.class.js +2 -2
  52. package/dist/components/charts/chart/box-plot.class.d.ts +4 -2
  53. package/dist/components/charts/chart/box-plot.class.js +6 -5
  54. package/dist/components/charts/chart/chart-token-cache.js +2 -2
  55. package/dist/components/charts/chart/chart.class.d.ts +6 -4
  56. package/dist/components/charts/chart/chart.class.js +8 -7
  57. package/dist/components/charts/chart/histogram.class.js +1 -1
  58. package/dist/components/charts/chart/lite-chart.class.js +1 -1
  59. package/dist/components/conversation/agent-workspace/agent-workspace.class.js +1 -1
  60. package/dist/components/conversation/audio-visualizer/audio-visualizer.class.js +1 -1
  61. package/dist/components/conversation/branch-picker/branch-picker.class.js +1 -1
  62. package/dist/components/conversation/chat-composer/chat-composer.class.js +1 -1
  63. package/dist/components/conversation/chat-message/chat-message.class.js +1 -1
  64. package/dist/components/conversation/chat-viewport/chat-viewport.class.js +1 -1
  65. package/dist/components/conversation/checkpoint/checkpoint.class.js +1 -1
  66. package/dist/components/conversation/code-block/code-block-base.class.js +1 -1
  67. package/dist/components/conversation/code-block/code-block-core.class.js +1 -1
  68. package/dist/components/conversation/code-block/code-block.class.js +1 -1
  69. package/dist/components/conversation/conversation-item/conversation-item.class.js +1 -1
  70. package/dist/components/conversation/generation-metrics/generation-metrics.class.js +1 -1
  71. package/dist/components/conversation/handoff-divider/handoff-divider.class.js +1 -1
  72. package/dist/components/conversation/markdown/markdown-base.class.js +1 -1
  73. package/dist/components/conversation/markdown/markdown-core.class.js +1 -1
  74. package/dist/components/conversation/markdown/markdown.class.js +1 -1
  75. package/dist/components/conversation/message-actions/message-actions.class.js +1 -1
  76. package/dist/components/conversation/message-feedback/message-feedback.class.js +1 -1
  77. package/dist/components/conversation/message-parts/message-parts.class.js +1 -1
  78. package/dist/components/conversation/model-select/model-select.class.js +1 -1
  79. package/dist/components/conversation/model-settings-panel/model-settings-panel.class.js +1 -1
  80. package/dist/components/conversation/prompt-input/prompt-input.class.js +1 -1
  81. package/dist/components/conversation/prompt-queue/prompt-queue.class.js +1 -1
  82. package/dist/components/conversation/push-to-talk/push-to-talk.class.js +1 -1
  83. package/dist/components/conversation/realtime-session/realtime-session.class.js +1 -1
  84. package/dist/components/conversation/selection-toolbar/selection-toolbar.class.js +1 -1
  85. package/dist/components/conversation/stream-status/stream-status.class.js +1 -1
  86. package/dist/components/conversation/suggestion-chips/suggestion-chips.class.js +1 -1
  87. package/dist/components/conversation/thread-list/thread-list.class.js +1 -1
  88. package/dist/components/conversation/transcript-feed/transcript-feed.class.js +1 -1
  89. package/dist/components/conversation/typing-indicator/typing-indicator.class.js +1 -1
  90. package/dist/components/conversation/usage-badge/usage-badge.class.js +1 -1
  91. package/dist/components/conversation/voice-picker/voice-picker.class.js +1 -1
  92. package/dist/components/data/calendar/calendar.class.js +1 -1
  93. package/dist/components/data/condition-builder/condition-builder.class.js +1 -1
  94. package/dist/components/data/context-meter/context-meter.class.js +1 -1
  95. package/dist/components/data/data-grid/data-grid.class.d.ts +2 -2
  96. package/dist/components/data/data-grid/data-grid.class.js +3 -3
  97. package/dist/components/data/document-library/document-library.class.js +1 -1
  98. package/dist/components/data/env-list/env-list.class.js +1 -1
  99. package/dist/components/data/file-tree/file-tree.class.d.ts +2 -2
  100. package/dist/components/data/file-tree/file-tree.class.js +1 -1
  101. package/dist/components/data/flow-canvas/flow-canvas.class.js +1 -1
  102. package/dist/components/data/flow-controls/flow-controls.class.js +1 -1
  103. package/dist/components/data/flow-minimap/flow-minimap.class.js +1 -1
  104. package/dist/components/data/flow-node/flow-node.class.js +1 -1
  105. package/dist/components/data/flow-run-status/flow-run-status.class.js +1 -1
  106. package/dist/components/data/funnel/funnel.class.js +1 -1
  107. package/dist/components/data/gauge/gauge.class.js +1 -1
  108. package/dist/components/data/graph-query-builder/graph-query-builder.class.js +1 -1
  109. package/dist/components/data/heatmap/heatmap.class.d.ts +2 -1
  110. package/dist/components/data/heatmap/heatmap.class.js +2 -2
  111. package/dist/components/data/heatmap/heatmap.styles.js +1 -1
  112. package/dist/components/data/pagination/pagination.class.d.ts +2 -0
  113. package/dist/components/data/pagination/pagination.class.js +1 -1
  114. package/dist/components/data/pagination/pagination.styles.js +1 -1
  115. package/dist/components/data/sequence-strip/sequence-strip.class.js +1 -1
  116. package/dist/components/data/sparkline/sparkline.class.js +1 -1
  117. package/dist/components/data/stat/stat.class.js +1 -1
  118. package/dist/components/data/table/table.class.d.ts +23 -2
  119. package/dist/components/data/table/table.class.js +5 -3
  120. package/dist/components/data/table/table.styles.js +1 -1
  121. package/dist/components/data/timeline/timeline.class.js +1 -1
  122. package/dist/components/data/tree/tree.class.js +1 -1
  123. package/dist/components/data/word-cloud/word-cloud.class.js +1 -1
  124. package/dist/components/forms/button/button.class.js +1 -1
  125. package/dist/components/forms/checkbox/checkbox.class.js +1 -1
  126. package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
  127. package/dist/components/forms/code-editor/code-editor.class.js +1 -1
  128. package/dist/components/forms/color-picker/color-picker.class.d.ts +8 -4
  129. package/dist/components/forms/color-picker/color-picker.class.js +2 -2
  130. package/dist/components/forms/combobox/combobox.class.js +1 -1
  131. package/dist/components/forms/country-picker/country-picker.class.js +1 -1
  132. package/dist/components/forms/currency-picker/currency-picker.class.js +1 -1
  133. package/dist/components/forms/date-picker/date-input.class.js +1 -1
  134. package/dist/components/forms/date-picker/date-picker.class.js +1 -1
  135. package/dist/components/forms/emoji-picker/emoji-data-loader.js +1 -1
  136. package/dist/components/forms/emoji-picker/emoji-picker.class.d.ts +7 -4
  137. package/dist/components/forms/emoji-picker/emoji-picker.class.js +5 -5
  138. package/dist/components/forms/icon-button/icon-button.class.d.ts +4 -0
  139. package/dist/components/forms/icon-button/icon-button.class.js +1 -1
  140. package/dist/components/forms/icon-button/icon-button.styles.js +1 -1
  141. package/dist/components/forms/input/input-shared.js +1 -1
  142. package/dist/components/forms/input/input.class.js +1 -1
  143. package/dist/components/forms/input/native-time-input.class.js +1 -1
  144. package/dist/components/forms/input/number-input.class.js +1 -1
  145. package/dist/components/forms/input/time-input.class.js +1 -1
  146. package/dist/components/forms/locale-picker/locale-picker.class.js +1 -1
  147. package/dist/components/forms/otp-input/otp-input.class.js +1 -1
  148. package/dist/components/forms/phone-input/phone-input.class.js +1 -1
  149. package/dist/components/forms/radio/radio-group.class.js +1 -1
  150. package/dist/components/forms/radio/radio.class.js +1 -1
  151. package/dist/components/forms/rubric-form/rubric-form.class.js +4 -4
  152. package/dist/components/forms/select/select.class.js +1 -1
  153. package/dist/components/forms/signature-pad/signature-pad.class.js +1 -1
  154. package/dist/components/forms/slider/slider.class.js +1 -1
  155. package/dist/components/forms/switch/switch.class.js +1 -1
  156. package/dist/components/forms/textarea/textarea.class.js +1 -1
  157. package/dist/components/forms/time-range/time-range.class.js +1 -1
  158. package/dist/components/forms/time-zone-picker/time-zone-picker.class.js +1 -1
  159. package/dist/components/forms/token-input/token-input.class.js +1 -1
  160. package/dist/components/forms/unit-picker/unit-picker.class.js +1 -1
  161. package/dist/components/layout/app-rail/app-rail-item.class.js +1 -1
  162. package/dist/components/layout/app-rail/app-rail.class.d.ts +70 -7
  163. package/dist/components/layout/app-rail/app-rail.class.js +16 -4
  164. package/dist/components/layout/app-rail/app-rail.styles.js +1 -1
  165. package/dist/components/layout/app-rail-group/app-rail-group.class.js +1 -1
  166. package/dist/components/layout/breadcrumb/breadcrumb.class.js +1 -1
  167. package/dist/components/layout/card/card.class.js +1 -1
  168. package/dist/components/layout/carousel/carousel.class.js +1 -1
  169. package/dist/components/layout/command-palette/command-palette.class.js +1 -1
  170. package/dist/components/layout/dashboard-grid/dashboard-grid.class.js +1 -1
  171. package/dist/components/layout/details/accordion-item.class.js +1 -1
  172. package/dist/components/layout/details/details.class.js +1 -1
  173. package/dist/components/layout/dock-panel/dock-panel.class.js +1 -1
  174. package/dist/components/layout/drilldown-panel/drilldown-panel.class.js +1 -1
  175. package/dist/components/layout/filter-bar/filter-bar.class.js +1 -1
  176. package/dist/components/layout/menu/menu.class.js +1 -1
  177. package/dist/components/layout/menubar/menubar.class.js +1 -1
  178. package/dist/components/layout/multi-split/multi-split.class.js +1 -1
  179. package/dist/components/layout/navigation-menu/navigation-menu.class.js +1 -1
  180. package/dist/components/layout/page/page.class.js +1 -1
  181. package/dist/components/layout/reorder-list/reorder-item.class.js +1 -1
  182. package/dist/components/layout/reorder-list/reorder-list.class.js +1 -1
  183. package/dist/components/layout/responsive-panel/responsive-panel.class.js +1 -1
  184. package/dist/components/layout/scroller/scroller.class.js +1 -1
  185. package/dist/components/layout/segmented/segmented.class.d.ts +7 -4
  186. package/dist/components/layout/segmented/segmented.styles.js +1 -1
  187. package/dist/components/layout/split-panel/split-panel.class.js +1 -1
  188. package/dist/components/layout/tab-group/tab-group.class.js +1 -1
  189. package/dist/components/layout/tab-group/tab.class.js +1 -1
  190. package/dist/components/layout/virtual-list/virtual-list.styles.js +1 -1
  191. package/dist/components/layout/widget/widget.class.js +1 -1
  192. package/dist/components/media/animated-image/animated-image.class.js +1 -1
  193. package/dist/components/media/attachment-chip/attachment-chip.class.js +1 -1
  194. package/dist/components/media/attachment-trigger/attachment-trigger.class.js +2 -2
  195. package/dist/components/media/av-player/av-player.class.js +1 -1
  196. package/dist/components/media/avatar-group/avatar-group.class.js +1 -1
  197. package/dist/components/media/drop-zone/drop-zone.class.js +1 -1
  198. package/dist/components/media/file-icon/file-icon.class.js +1 -1
  199. package/dist/components/media/file-input/file-input.class.js +1 -1
  200. package/dist/components/media/flag/flag.class.js +1 -1
  201. package/dist/components/media/image-comparer/image-comparer.class.js +1 -1
  202. package/dist/components/media/image-viewer/image-viewer.class.d.ts +2 -1
  203. package/dist/components/media/image-viewer/image-viewer.class.js +4 -2
  204. package/dist/components/media/image-viewer/image-viewer.styles.js +1 -1
  205. package/dist/components/media/lightbox/lightbox.class.js +1 -1
  206. package/dist/components/media/map/map.class.js +1 -1
  207. package/dist/components/media/media-card/media-card.class.js +1 -1
  208. package/dist/components/media/pan-zoom/pan-zoom.class.js +1 -1
  209. package/dist/components/media/qr-code/qr-code.class.d.ts +2 -2
  210. package/dist/components/media/qr-code/qr-code.class.js +1 -1
  211. package/dist/components/media/sequence-playback/sequence-playback.class.js +1 -1
  212. package/dist/components/media/video/video.class.js +1 -1
  213. package/dist/components/media/video-playlist/video-playlist.class.js +1 -1
  214. package/dist/components/media/zoomable-frame/zoomable-frame.class.js +1 -1
  215. package/dist/components/overlays/alert/alert.class.js +1 -1
  216. package/dist/components/overlays/badge/tag.class.js +1 -1
  217. package/dist/components/overlays/callout/callout.class.js +1 -1
  218. package/dist/components/overlays/chip/chip-group.class.js +1 -1
  219. package/dist/components/overlays/chip/chip.class.js +1 -1
  220. package/dist/components/overlays/context-menu/context-menu.class.js +1 -1
  221. package/dist/components/overlays/dialog/confirm.js +1 -1
  222. package/dist/components/overlays/dialog/dialog.class.js +1 -1
  223. package/dist/components/overlays/kbd/kbd.class.js +1 -1
  224. package/dist/components/overlays/overlay/popover.class.js +1 -1
  225. package/dist/components/overlays/overlay/tooltip.class.js +1 -1
  226. package/dist/components/overlays/progress/progress-bar.class.js +1 -1
  227. package/dist/components/overlays/progress/progress-ring.class.js +1 -1
  228. package/dist/components/overlays/rating/rating.class.js +1 -1
  229. package/dist/components/overlays/skeleton/skeleton.class.js +1 -1
  230. package/dist/components/overlays/spinner/spinner.class.js +1 -1
  231. package/dist/components/overlays/toast/toast-item.class.js +1 -1
  232. package/dist/components/overlays/toast/toast.class.js +1 -1
  233. package/dist/components/retrieval/chunk-inspector/chunk-inspector.class.js +1 -1
  234. package/dist/components/retrieval/citation-badge/citation-badge.class.js +1 -1
  235. package/dist/components/retrieval/claim-evidence/claim-evidence.class.js +1 -1
  236. package/dist/components/retrieval/community-card/community-card.class.js +1 -1
  237. package/dist/components/retrieval/embedding-explorer/embedding-explorer.class.js +1 -1
  238. package/dist/components/retrieval/entity-card/entity-card.class.js +1 -1
  239. package/dist/components/retrieval/entity-chip/entity-chip.class.js +1 -1
  240. package/dist/components/retrieval/entity-dossier/entity-dossier.class.js +1 -1
  241. package/dist/components/retrieval/graph/graph.class.js +1 -1
  242. package/dist/components/retrieval/graph-legend/graph-legend.class.js +1 -1
  243. package/dist/components/retrieval/grounding-summary/grounding-summary.class.js +2 -2
  244. package/dist/components/retrieval/ingestion-queue/ingestion-queue.class.js +1 -1
  245. package/dist/components/retrieval/knowledge-base/knowledge-base.class.js +1 -1
  246. package/dist/components/retrieval/knowledge-base-admin/knowledge-base-admin.class.js +1 -1
  247. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.js +1 -1
  248. package/dist/components/retrieval/memory-panel/memory-panel.class.js +1 -1
  249. package/dist/components/retrieval/mind-map/mind-map.class.js +1 -1
  250. package/dist/components/retrieval/neighbor-list/neighbor-list.class.js +1 -1
  251. package/dist/components/retrieval/node-palette/node-palette.class.js +1 -1
  252. package/dist/components/retrieval/path-strip/path-strip.class.js +1 -1
  253. package/dist/components/retrieval/provenance-panel/provenance-panel.class.js +1 -1
  254. package/dist/components/retrieval/rag-answer/rag-answer.class.js +1 -1
  255. package/dist/components/retrieval/rag-eval-dashboard/rag-eval-dashboard.class.js +1 -1
  256. package/dist/components/retrieval/research-progress/research-progress.class.js +1 -1
  257. package/dist/components/retrieval/retrieval-compare/retrieval-compare.class.js +1 -1
  258. package/dist/components/retrieval/retrieval-results/retrieval-results.class.js +1 -1
  259. package/dist/components/retrieval/retrieval-search/retrieval-search.class.js +1 -1
  260. package/dist/components/retrieval/retrieval-trace/retrieval-trace.class.js +1 -1
  261. package/dist/components/retrieval/source-card/source-card.class.js +1 -1
  262. package/dist/components/retrieval/source-list/source-list.class.js +1 -1
  263. package/dist/components/retrieval/source-picker/source-picker.class.js +1 -1
  264. package/dist/components/utility/copy-button/copy-button.class.js +1 -1
  265. package/dist/components/utility/diff-view/diff-view.class.js +1 -1
  266. package/dist/components/utility/export-button/export-button.class.js +1 -1
  267. package/dist/components/utility/icon/icon.class.js +1 -1
  268. package/dist/components/utility/json-viewer/json-viewer.class.js +1 -1
  269. package/dist/components/utility/known-date/known-date.class.js +1 -1
  270. package/dist/components/utility/mention-popover/mention-popover.class.js +1 -1
  271. package/dist/components/utility/poll-status/poll-status.class.js +1 -1
  272. package/dist/components/utility/random-content/random-content.class.js +1 -1
  273. package/dist/components/utility/tour/tour.class.js +1 -1
  274. package/dist/components/viewers/archive-viewer/archive-viewer.class.js +1 -1
  275. package/dist/components/viewers/calendar-viewer/calendar-viewer.class.js +1 -1
  276. package/dist/components/viewers/contact-viewer/contact-viewer.class.js +1 -1
  277. package/dist/components/viewers/csv-viewer/csv-viewer.class.js +1 -1
  278. package/dist/components/viewers/dataset-viewer/dataset-viewer.class.js +2 -2
  279. package/dist/components/viewers/document-compare/document-compare.class.js +1 -1
  280. package/dist/components/viewers/document-preview/document-preview.class.js +1 -1
  281. package/dist/components/viewers/document-viewer/document-viewer.class.js +1 -1
  282. package/dist/components/viewers/docx-viewer/docx-viewer.class.js +1 -1
  283. package/dist/components/viewers/ebook-viewer/ebook-viewer.class.js +1 -1
  284. package/dist/components/viewers/email-viewer/email-viewer.class.js +1 -1
  285. package/dist/components/viewers/geojson-view/geojson-view.class.js +1 -1
  286. package/dist/components/viewers/geojson-view/geojson-viewer.class.js +1 -1
  287. package/dist/components/viewers/highlight-layer/highlight-layer.class.js +1 -1
  288. package/dist/components/viewers/html-viewer/html-viewer.class.js +1 -1
  289. package/dist/components/viewers/include/include.class.js +1 -1
  290. package/dist/components/viewers/notebook-viewer/notebook-viewer.class.js +1 -1
  291. package/dist/components/viewers/page-rail/page-rail.class.d.ts +1 -1
  292. package/dist/components/viewers/page-rail/page-rail.class.js +3 -3
  293. package/dist/components/viewers/pdf-viewer/pdf-viewer.class.d.ts +2 -2
  294. package/dist/components/viewers/pdf-viewer/pdf-viewer.class.js +2 -2
  295. package/dist/components/viewers/pptx-viewer/pptx-viewer.class.js +1 -1
  296. package/dist/components/viewers/spreadsheet-viewer/spreadsheet-viewer.class.js +1 -1
  297. package/dist/components/viewers/svg-viewer/svg-viewer.class.js +1 -1
  298. package/dist/components/viewers/xml-viewer/xml-viewer.class.js +1 -1
  299. package/dist/events.d.ts +6 -1
  300. package/dist/framework-types.d.ts +1 -1
  301. package/dist/internal/accessibility-visibility.js +1 -1
  302. package/dist/internal/collection-snapshot.js +1 -1
  303. package/dist/internal/default-strings/agent-tools.generated.js +1 -0
  304. package/dist/internal/default-strings/charts.generated.js +1 -0
  305. package/dist/internal/default-strings/conversation.generated.js +1 -0
  306. package/dist/internal/default-strings/data.generated.js +1 -0
  307. package/dist/internal/default-strings/forms.generated.js +1 -0
  308. package/dist/internal/default-strings/layout.generated.js +1 -0
  309. package/dist/internal/default-strings/media.generated.js +1 -0
  310. package/dist/internal/default-strings/overlays.generated.js +1 -0
  311. package/dist/internal/default-strings/retrieval.generated.js +1 -0
  312. package/dist/internal/default-strings/shared.generated.js +1 -0
  313. package/dist/internal/default-strings/utility.generated.js +1 -0
  314. package/dist/internal/default-strings/viewers.generated.js +5 -0
  315. package/dist/internal/dev-mode-attribute-warning.development.js +1 -1
  316. package/dist/internal/dev-mode-attribute-warning.production.js +1 -1
  317. package/dist/internal/document-tokens.d.ts +11 -0
  318. package/dist/internal/document-tokens.generated.js +15 -0
  319. package/dist/internal/document-tokens.js +3 -0
  320. package/dist/internal/form-associated.d.ts +1 -1
  321. package/dist/internal/form-associated.js +1 -1
  322. package/dist/internal/glass-surface.styles.js +1 -1
  323. package/dist/internal/host-tokens.styles.js +1 -0
  324. package/dist/internal/image-zoom.js +1 -0
  325. package/dist/internal/intl-cache.js +1 -1
  326. package/dist/internal/localization-types.d.ts +1 -1
  327. package/dist/internal/localization.js +2 -2
  328. package/dist/internal/lyra-element.d.ts +4 -2
  329. package/dist/internal/lyra-element.js +2 -2
  330. package/dist/internal/nonmodal-overlay-manager.js +1 -1
  331. package/dist/internal/opaque-content-border.styles.js +1 -1
  332. package/dist/internal/open-overlay-ancestors.js +1 -0
  333. package/dist/internal/open-overlay-raise.styles.js +1 -0
  334. package/dist/internal/optional-peer-failure.js +1 -0
  335. package/dist/internal/package-metadata.js +1 -1
  336. package/dist/internal/prefix.js +1 -1
  337. package/dist/internal/specialist-host-tokens.styles.js +1 -0
  338. package/dist/internal/specialist-tokens.generated.js +2 -0
  339. package/dist/internal/step-value.js +1 -1
  340. package/dist/internal/theme-observation.js +1 -1
  341. package/dist/internal/theme-scopes.d.ts +11 -0
  342. package/dist/internal/theme-scopes.js +1 -0
  343. package/dist/looks/shadcn.css +1 -1
  344. package/dist/lyra.d.ts +1 -1
  345. package/dist/lyra.js +1 -1
  346. package/dist/styles/design-tokens.css +1 -1
  347. package/dist/styles/tokens-root.css +1 -1
  348. package/dist/surfaces/glass.css +1 -1
  349. package/dist/testing/happy-dom-shims.d.ts +22 -1
  350. package/dist/testing/happy-dom-shims.js +1 -1
  351. package/dist/testing/index.d.ts +1 -1
  352. package/dist/testing/index.js +1 -1
  353. package/dist/testing/interaction-drivers.d.ts +66 -7
  354. package/dist/testing/interaction-drivers.js +1 -1
  355. package/dist/testing/jsdom-shims.d.ts +70 -0
  356. package/dist/testing/jsdom-shims.js +1 -0
  357. package/dist/theme/look-inputs.d.ts +1 -1
  358. package/dist/theme/look-inputs.js +37 -41
  359. package/dist/theme/theme.d.ts +13 -0
  360. package/dist/theme/theme.js +1 -1
  361. package/dist/theme.css +1 -1
  362. package/dist/utilities/index.d.ts +1 -1
  363. package/dist/utilities/index.js +1 -1
  364. package/dist/utilities/scoped-registry.d.ts +3 -0
  365. package/dist/utilities/scoped-registry.js +1 -1
  366. package/dist/utilities/theme-scopes.d.ts +1 -0
  367. package/dist/utilities/theme-scopes.js +1 -0
  368. package/dist/utilities/tokens.d.ts +1 -0
  369. package/dist/utilities/tokens.js +1 -0
  370. package/llms/components/lr-app-rail.md +51 -4
  371. package/llms/components/lr-box-plot.md +5 -0
  372. package/llms/components/lr-chart.md +6 -0
  373. package/llms/components/lr-emoji-picker.md +13 -8
  374. package/llms/components/lr-heatmap.md +10 -2
  375. package/llms/components/lr-icon-button.md +13 -1
  376. package/llms/components/lr-image-viewer.md +8 -0
  377. package/llms/components/lr-pagination.md +4 -2
  378. package/llms/components/lr-segmented.md +7 -3
  379. package/llms/components/lr-table.md +14 -12
  380. package/llms/components/lr-thread-list.md +4 -3
  381. package/llms/migration.md +9 -0
  382. package/llms/peers.md +1 -1
  383. package/llms/shared/events-and-types.md +41 -0
  384. package/llms/shared/frameworks-and-ssr.md +16 -0
  385. package/llms/shared/imports-and-registration.md +4 -3
  386. package/llms/shared/native-styles-and-utilities.md +38 -3
  387. package/llms/shared/styles-and-tokens.md +242 -102
  388. package/llms/shared/testing-and-utilities.md +104 -7
  389. package/llms/shared.md +445 -115
  390. package/llms/tokens.md +31 -49
  391. package/locales.json +138 -138
  392. package/package.json +16 -8
  393. package/registrations.json +1 -1
  394. package/dist/internal/default-strings.generated.js +0 -5
  395. package/dist/internal/specialist-tokens.styles.js +0 -1
  396. package/dist/internal/tokens/palette.styles.js +0 -1
  397. package/dist/internal/tokens.styles.js +0 -1
@@ -1,4 +1,4 @@
1
- import{VOID_HTML_TAGS,camelCase,commentRanges,finalizeEdits,findTagEnd,kebabCase,lineStarts,localMigrationKey,locationAt,memberStyle,moduleSpecifierContext,parseNamedModuleBindings,parseTagAttributes,regexEscape,reportEntry,scanAllOpeningTags,scanLocalMigrationHazards,serializeLocalDefault,skipBalanced}from"./migration-analysis.mjs";import{invariant}from"./migration-contract.mjs";import{htmlCommentEnd}from"./html-comments.mjs";const RENAME_REVIEW="RENAME_REVIEW",RENAME_TARGET_SHARED_REVIEW="RENAME_TARGET_SHARED_REVIEW",NAME_GAINED_OWNER_REVIEW="NAME_GAINED_OWNER_REVIEW",POLARITY_REVIEW="POLARITY_REVIEW",DETAIL_SHAPE_REVIEW="DETAIL_SHAPE_REVIEW",DETAIL_FIELD_REVIEW="DETAIL_FIELD_REVIEW",DEPRECATED_MEMBER_REVIEW="DEPRECATED_MEMBER_REVIEW",DEPRECATED_CONTENT_REVIEW="DEPRECATED_CONTENT_REVIEW",RENAME_CONFLICT_REVIEW="RENAME_CONFLICT_REVIEW",UNUSED_ACKNOWLEDGEMENT="UNUSED_ACKNOWLEDGEMENT",REVIEW_ACKNOWLEDGEMENT=/lyra-migrate-reviewed:\s*([^\n]*)/g,ACKNOWLEDGEMENT_TOKEN=/^([A-Z][A-Z0-9_]*):(\S+)$/,DEFAULT_SLOT_LABEL="#default",LISTENER_CALL_BEFORE=/(?:\b(?:add|remove)EventListener|\bHostListener)\s*\(\s*$/,LISTENER_RECEIVER_BEFORE=/([A-Za-z_$][\w$]*(?:\s*(?:\?\.|\.)\s*#?[A-Za-z_$][\w$]*|\s*\([^()\n]*\)|\s*!(?!=))*)\s*(?:\?\.|\.)\s*(?:add|remove)EventListener\s*\(\s*$/,LISTENER_HANDLER_AFTER=/^\s*,\s*([A-Za-z_$][\w$]*(?:\s*(?:\?\.|\.)\s*#?[A-Za-z_$][\w$]*)*)\s*[,)]/,EVENT_CONSTRUCTION=/\bnew\s+(?:CustomEvent|Event)\s*(?:<[^>\n]+>)?\(\s*(['"`])(lr-[a-z0-9]+(?:-[a-z0-9]+)*)\1/g,TAG_API_CALL_BEFORE=/(?:\b(?:createElement|querySelector(?:All)?|closest|matches|unsafeStatic|literal)|\bcustomElements\s*\.\s*(?:get|whenDefined|define))\s*(?:<[^>\n]+>)?\(\s*$/,ANCHORED_MEMBER=/\b(?:querySelector|closest|createElement)\s*(?:<[^>\n]+>)?\(\s*(['"`])(lr-[a-z0-9]+(?:-[a-z0-9]+)*)\1\s*\)\s*!?\s*(?:\?\.|\.)\s*([A-Za-z_$][\w$]*)/g,ATTRIBUTE_METHODS=new Set(["setAttribute","getAttribute","hasAttribute","removeAttribute","toggleAttribute"]),LISTENER_METHODS=new Set(["addEventListener","removeEventListener"]),STYLESHEET_FILE=/\.(?:css|scss|sass|less|pcss|styl)$/i,MARKUP_FILE=/\.(?:html?|xhtml|md|markdown|vue|svelte)$/i,ATTRIBUTE_SEMANTICS_FILE=/\.(?:html?|xhtml|md|markdown)$/i,LIT_TEMPLATE_FILE=/\.(?:[cm]?[jt]s)$/i,SELECTOR_LOOKBEHIND=256,ackName=member=>member===""?DEFAULT_SLOT_LABEL:String(member);function mergeRanges(ranges){const merged=[];for(const[start,end]of[...ranges].sort((left,right)=>left[0]-right[0])){const last=merged.at(-1);last&&start<=last[1]?last[1]=Math.max(last[1],end):merged.push([start,end])}return merged}function rangeTester(merged){return offset=>{let low=0,high=merged.length-1;for(;low<=high;){const middle=low+high>>1;if(merged[middle][1]<=offset)low=middle+1;else if(merged[middle][0]>offset)high=middle-1;else return!0}return!1}}function templateLiteralEnd(text,open){let index=open+1;for(;index<text.length;){const character=text[index];if(character==="\\")index+=2;else{if(character==="`")return index+1;character==="$"&&text[index+1]==="{"?index=templateExpressionEnd(text,index+2):index+=1}}return text.length}function templateExpressionEnd(text,index){let depth=1;for(;index<text.length;){const character=text[index];if(character==="`"){index=templateLiteralEnd(text,index);continue}if(character==='"'||character==="'"){for(index+=1;index<text.length&&text[index]!==character&&text[index]!==`
1
+ import{VOID_HTML_TAGS,camelCase,commentRanges,finalizeEdits,findTagEnd,kebabCase,lineStarts,localMigrationKey,locationAt,memberStyle,moduleSpecifierContext,parseNamedModuleBindings,parseTagAttributes,regexEscape,reportEntry,scanAllOpeningTags,scanLocalMigrationHazards,serializeLocalDefault,skipBalanced}from"./migration-analysis.mjs";import{invariant}from"./migration-contract.mjs";import{htmlCommentEnd}from"./html-comments.mjs";import{analyzeThemeScopes}from"./migration-theme-scopes.mjs";const RENAME_REVIEW="RENAME_REVIEW",RENAME_TARGET_SHARED_REVIEW="RENAME_TARGET_SHARED_REVIEW",NAME_GAINED_OWNER_REVIEW="NAME_GAINED_OWNER_REVIEW",POLARITY_REVIEW="POLARITY_REVIEW",DETAIL_SHAPE_REVIEW="DETAIL_SHAPE_REVIEW",DETAIL_FIELD_REVIEW="DETAIL_FIELD_REVIEW",DEPRECATED_MEMBER_REVIEW="DEPRECATED_MEMBER_REVIEW",DEPRECATED_CONTENT_REVIEW="DEPRECATED_CONTENT_REVIEW",RENAME_CONFLICT_REVIEW="RENAME_CONFLICT_REVIEW",UNUSED_ACKNOWLEDGEMENT="UNUSED_ACKNOWLEDGEMENT",REVIEW_ACKNOWLEDGEMENT=/lyra-migrate-reviewed:\s*([^\n]*)/g,ACKNOWLEDGEMENT_TOKEN=/^([A-Z][A-Z0-9_]*):(\S+)$/,DEFAULT_SLOT_LABEL="#default",LISTENER_CALL_BEFORE=/(?:\b(?:add|remove)EventListener|\bHostListener)\s*\(\s*$/,LISTENER_RECEIVER_BEFORE=/([A-Za-z_$][\w$]*(?:\s*(?:\?\.|\.)\s*#?[A-Za-z_$][\w$]*|\s*\([^()\n]*\)|\s*!(?!=))*)\s*(?:\?\.|\.)\s*(?:add|remove)EventListener\s*\(\s*$/,LISTENER_HANDLER_AFTER=/^\s*,\s*([A-Za-z_$][\w$]*(?:\s*(?:\?\.|\.)\s*#?[A-Za-z_$][\w$]*)*)\s*[,)]/,EVENT_CONSTRUCTION=/\bnew\s+(?:CustomEvent|Event)\s*(?:<[^>\n]+>)?\(\s*(['"`])(lr-[a-z0-9]+(?:-[a-z0-9]+)*)\1/g,TAG_API_CALL_BEFORE=/(?:\b(?:createElement|querySelector(?:All)?|closest|matches|unsafeStatic|literal)|\bcustomElements\s*\.\s*(?:get|whenDefined|define))\s*(?:<[^>\n]+>)?\(\s*$/,ANCHORED_MEMBER=/\b(?:querySelector|closest|createElement)\s*(?:<[^>\n]+>)?\(\s*(['"`])(lr-[a-z0-9]+(?:-[a-z0-9]+)*)\1\s*\)\s*!?\s*(?:\?\.|\.)\s*([A-Za-z_$][\w$]*)/g,ATTRIBUTE_METHODS=new Set(["setAttribute","getAttribute","hasAttribute","removeAttribute","toggleAttribute"]),LISTENER_METHODS=new Set(["addEventListener","removeEventListener"]),STYLESHEET_FILE=/\.(?:css|scss|sass|less|pcss|styl)$/i,MARKUP_FILE=/\.(?:html?|xhtml|md|markdown|vue|svelte)$/i,ATTRIBUTE_SEMANTICS_FILE=/\.(?:html?|xhtml|md|markdown)$/i,LIT_TEMPLATE_FILE=/\.(?:[cm]?[jt]s)$/i,SELECTOR_LOOKBEHIND=256,ackName=member=>member===""?DEFAULT_SLOT_LABEL:String(member);function mergeRanges(ranges){const merged=[];for(const[start,end]of[...ranges].sort((left,right)=>left[0]-right[0])){const last=merged.at(-1);last&&start<=last[1]?last[1]=Math.max(last[1],end):merged.push([start,end])}return merged}function rangeTester(merged){return offset=>{let low=0,high=merged.length-1;for(;low<=high;){const middle=low+high>>1;if(merged[middle][1]<=offset)low=middle+1;else if(merged[middle][0]>offset)high=middle-1;else return!0}return!1}}function templateLiteralEnd(text,open){let index=open+1;for(;index<text.length;){const character=text[index];if(character==="\\")index+=2;else{if(character==="`")return index+1;character==="$"&&text[index+1]==="{"?index=templateExpressionEnd(text,index+2):index+=1}}return text.length}function templateExpressionEnd(text,index){let depth=1;for(;index<text.length;){const character=text[index];if(character==="`"){index=templateLiteralEnd(text,index);continue}if(character==='"'||character==="'"){for(index+=1;index<text.length&&text[index]!==character&&text[index]!==`
2
2
  `;)index+=text[index]==="\\"?2:1;index+=1;continue}if(character==="{")depth+=1;else if(character==="}"&&--depth===0)return index+1;index+=1}return text.length}function templateLiteralRanges(text,inComment){const ranges=[];let index=0;for(;index<text.length;){const character=text[index];if(inComment(index))index+=1;else if(character==="`"){const end=templateLiteralEnd(text,index);ranges.push([index,end]),index=end}else if(character==='"'||character==="'"){for(index+=1;index<text.length&&text[index]!==character&&text[index]!==`
3
3
  `;)index+=text[index]==="\\"?2:1;index+=1}else index+=1}return ranges}function taggedTemplateRanges(text,tags,inComment){const ranges=[];for(const match of text.matchAll(new RegExp(`\\b(?:${tags.join("|")})\\s*\``,"g"))){if(inComment(match.index))continue;const open=match.index+match[0].length-1;ranges.push([open,templateLiteralEnd(text,open)])}return mergeRanges(ranges)}function renameIgnoredRanges(text,file){const base=mergeRanges(commentRanges(text)),inBase=rangeTester(base),extra=[],addHtmlComments=(start,end)=>{let index=text.indexOf("<!--",start);for(;index>=0&&index<end;){const finish=htmlCommentEnd(text,index,end);inBase(index)||extra.push([index,finish]),index=text.indexOf("<!--",finish)}};if(MARKUP_FILE.test(file))addHtmlComments(0,text.length);else if(!STYLESHEET_FILE.test(file))for(const[start,end]of templateLiteralRanges(text,inBase))addHtmlComments(start,end);return mergeRanges([...base,...extra])}function scanReviewAcknowledgements(text,ignoredRanges,starts,openingTokens){const tokenAt=new Map(openingTokens.map(token=>[token.start,token])),records=[],byLine=new Map,cover=(line,record)=>{const list=byLine.get(line)??[];list.includes(record)||list.push(record),byLine.set(line,list)};for(const[start,end]of ignoredRanges){const body=text.slice(start,end);if(!body.includes("lyra-migrate-reviewed:"))continue;const firstLine=locationAt(starts,start).line,lastLine=locationAt(starts,Math.max(start,end-1)).line;let next=end;for(;next<text.length&&/[\s}]/.test(text[next]);)next+=1;const followingTag=tokenAt.get(next),standalone=/^\s*\{?\s*$/.test(text.slice(starts[firstLine-1],start));for(const match of body.matchAll(REVIEW_ACKNOWLEDGEMENT)){const tokens=match[1].replace(/(?:\*\/|--!?>)[\s\S]*$/,"").split(/[\s,]+/).filter(Boolean),record={offset:start+match.index,entries:tokens.map(token=>{const parsed=ACKNOWLEDGEMENT_TOKEN.exec(token);return{token,code:parsed?.[1]??null,name:parsed?.[2]??null,used:!1}})};records.push(record);for(let line=firstLine;line<=lastLine;line+=1)cover(line,record);if(standalone&&cover(lastLine+1,record),followingTag){const tagLast=locationAt(starts,followingTag.end).line;for(let line=locationAt(starts,followingTag.start).line;line<=tagLast;line+=1)cover(line,record)}}}return{consume(line,code,member){const name=ackName(member);for(const record of byLine.get(line)??[]){const entry=record.entries.find(candidate=>candidate.code===code&&candidate.name===name);if(entry)return entry.used=!0,!0}return!1},unused:()=>records.flatMap(record=>record.entries.filter(entry=>!entry.used).map(entry=>({offset:record.offset,entry})))}}function quotedStringRanges(text,inComment){const ranges=[];let index=0;for(;index<text.length;){const quote=text[index];if(inComment(index)||quote!=='"'&&quote!=="'"&&quote!=="`"){index+=1;continue}const start=index;for(index+=1;index<text.length&&text[index]!==quote&&(quote==="`"||text[index]!==`
4
- `);)text[index]==="\\"&&(index+=1),index+=1;index+=1,quote!=="`"&&ranges.push([start,index])}return ranges}function stylesheetRanges(text,file,inComment){if(STYLESHEET_FILE.test(file))return[[0,text.length]];const ranges=[];for(const match of text.matchAll(/<style(?:\s[^>]*)?>[\s\S]*?<\/style\s*>/gi))ranges.push([match.index,match.index+match[0].length]);return mergeRanges([...ranges,...taggedTemplateRanges(text,["css"],inComment)])}function compoundTypeBefore(text,index){let start=index,brackets=0,parens=0;const limit=Math.max(0,index-SELECTOR_LOOKBEHIND);for(;start>limit;){const character=text[start-1];if(character==="]")brackets+=1;else if(character==="["){if(brackets===0)break;brackets-=1}else if(character===")")parens+=1;else if(character==="("){if(parens===0)break;parens-=1}else if(brackets===0&&parens===0&&/[\s,>+~{};'"`]/.test(character))break;start-=1}if(start===limit&&limit>0)return null;const compound=text.slice(start,index);return(/^:global\(\s*([A-Za-z][\w-]*)\s*\)$/.exec(compound)??/^([A-Za-z][\w-]*)/.exec(compound))?.[1].toLowerCase()??null}function mentionedTags(text,tags,inComment){const found=new Set;for(const tag of tags)for(const match of text.matchAll(new RegExp(`(?<![\\w-])${tag}(?![\\w-])`,"g")))if(!inComment(match.index)){found.add(tag);break}return found}function elementPairs(text,tag,inComment){const pairs=[],stack=[];for(const match of text.matchAll(new RegExp(`<(/)?${tag}(?=[\\s/>])`,"g"))){if(inComment(match.index))continue;const end=findTagEnd(text,match.index+match[0].length);if(!(end<0))if(match[1]){const opening=stack.pop();opening&&pairs.push({opening,closingStart:match.index})}else/\/\s*>$/.test(text.slice(match.index,end+1))||stack.push({start:match.index,end})}return pairs}function directChildTokens(text,start,end,inComment){const children=[],stack=[],pattern=/<(\/)?([A-Za-z][\w.:-]*)(?=[\s/>])/g;pattern.lastIndex=start;for(let match=pattern.exec(text);match&&match.index<end;match=pattern.exec(text)){if(inComment(match.index))continue;const tokenEnd=findTagEnd(text,match.index+match[0].length);if(tokenEnd<0||tokenEnd>=end)break;const name=match[2].toLowerCase();if(match[1]){const index=stack.lastIndexOf(name);index>=0&&(stack.length=index)}else{const nameStart=match.index+1;stack.length===0&&children.push({tag:name,start:match.index,nameStart,nameEnd:nameStart+match[2].length,end:tokenEnd}),!/\/\s*>$/.test(text.slice(match.index,tokenEnd+1))&&!VOID_HTML_TAGS.has(name)&&stack.push(name)}pattern.lastIndex=tokenEnd+1}return children}function openingTagBraceGroups(text,token){const groups=[];let index=token.nameEnd,quote=null;for(;index<token.end;){const character=text[index];if(quote){character==="\\"?index+=1:character===quote&&(quote=null),index+=1;continue}if(character==='"'||character==="'")quote=character;else if(character==="{"){const end=skipBalanced(text,index,"{","}");!/=\s*$/.test(text.slice(token.nameEnd,index))&&text[index-1]!=="$"&&groups.push({start:index,end,body:text.slice(index+1,end-1).trim()}),index=end;continue}index+=1}return groups}function markupEventName(rawName){if(/^\(lr-[a-z0-9-]+\)$/.test(rawName))return{name:rawName.slice(1,-1),offset:1};if(/^onlr-/.test(rawName))return{name:rawName.slice(2).replace(/Capture$/,""),offset:2};for(const[prefix,separator]of[["@","."],["v-on:","."],["on:","|"]])if(rawName.startsWith(prefix))return{name:rawName.slice(prefix.length).split(separator)[0],offset:prefix.length};return null}function markupMemberBinding(attribute){const raw=attribute.rawName;let match;if(raw.startsWith("?"))return{form:"attribute",offset:1,name:raw.slice(1),dynamic:!0};if(match=/^\[attr\.([^\]]+)\]$/.exec(raw))return{form:"attribute",offset:6,name:match[1],dynamic:!0};if(match=/^\[([A-Za-z_$][\w$]*)\]$/.exec(raw))return{form:"property",offset:1,name:match[1],dynamic:!0};if(raw.startsWith("."))return{form:"property",offset:1,name:raw.slice(1),dynamic:!0};if(raw.startsWith("bind:"))return{form:"property",offset:5,name:raw.slice(5).split("|")[0],dynamic:!0};for(const prefix of["v-bind:",":"])if(raw.startsWith(prefix))return{form:"member",offset:prefix.length,name:raw.slice(prefix.length).split(".")[0],dynamic:!0};if(!/^[A-Za-z][\w-]*$/.test(raw)||/^onlr-/.test(raw))return null;const dynamic=attribute.valueKind==="expression"||/\$\{|\{\{/.test(attribute.value??"");return{form:/[A-Z]/.test(raw)?"property":"attribute",offset:0,name:raw,dynamic}}function attributeEnd(text,attribute){if(attribute.valueEnd===null)return attribute.nameEnd;const quote=text[attribute.valueStart-1];return(quote==='"'||quote==="'")&&text[attribute.valueEnd]===quote?attribute.valueEnd+1:attribute.valueEnd}function boundMemberNames(attributes){const names=new Set;for(const attribute of attributes){const binding=markupMemberBinding(attribute);binding&&names.add(kebabCase(binding.name))}return names}function sortReportEntries(entries,codeKey){return entries.sort((left,right)=>left.line-right.line||left.column-right.column||String(left[codeKey]).localeCompare(String(right[codeKey])))}function reportModuleReviews(text,file,reviews,openingTokens,inComment,warn){if(!reviews.length)return;const packageName="@aceshooting/lyra-ui",specifierOf=subpath=>`${packageName}${subpath.slice(1)}`,named=reviews.filter(entry=>["function","type","constant","class"].includes(entry.kind)),report=(offset,review,context="")=>warn(offset,{member:review.name,code:"DEPRECATED_MODULE_REVIEW",target:review.replacement,message:`${context}${review.kind} ${review.module?`${review.module}#`:""}${review.name} ${review.removedIn?`was removed in ${review.removedIn}`:`is deprecated and scheduled for removal in ${review.removalNotBefore}`}; review ${review.replacement}.`}),namedFor=specifier=>named.filter(entry=>specifier===packageName||specifier===specifierOf(entry.module)),strings=quotedStringRanges(text,inComment),templates=templateLiteralRanges(text,inComment),stringStarts=new Set([...strings,...templates.filter(([start,end])=>!text.slice(start,end).includes("${"))].map(([start])=>start)),inString=rangeTester(strings),inLiteral=rangeTester(mergeRanges([...strings,...templates])),inCss=rangeTester(stylesheetRanges(text,file,inComment)),inMarkup=offset=>openingTokens.some(token=>offset>=token.nameEnd&&offset<token.end),opaque=(offset,specifier,entries)=>{entries.length&&warn(offset,{member:specifier,code:"MODULE_NAMESPACE_REVIEW",target:[...new Set(entries.map(entry=>entry.replacement))].join("; "),message:`Review the namespace or dynamic import of ${specifier} for deprecated exports ${entries.map(entry=>entry.name).join(", ")}. They cannot be safely renamed through aliases; the earliest removal is ${entries.map(entry=>entry.removalNotBefore).sort()[0]}.`})},bindings=/\b(?:import|export)\s+(?:type\s+)?(?:[$A-Z_a-z][$\w]*\s*,\s*)?\{(?<bindings>[^{};]*)\}\s*from\s*(?<quote>['"])(?<source>@aceshooting\/lyra-ui(?:\/[^'"\s]+)?)\k<quote>/g,handledSpecifiers=new Set;for(const match of text.matchAll(bindings)){if(inComment(match.index)||inLiteral(match.index))continue;const available=namedFor(match.groups.source),bodyStart=match.index+match[0].indexOf("{")+1;for(const binding of parseNamedModuleBindings(match.groups.bindings)){const review=available.find(entry=>entry.name===binding.imported);if(!review)continue;const member=[...match.groups.bindings.matchAll(new RegExp(`(?<![$\\w])${regexEscape(binding.imported)}(?![$\\w])`,"g"))].find(candidate=>!inComment(bodyStart+candidate.index));member&&report(bodyStart+member.index,review)}handledSpecifiers.add(match.index+match[0].lastIndexOf(match.groups.source)-1)}for(const match of text.matchAll(/(['"])(@aceshooting\/lyra-ui(?:\/[^'"\s]+)?)\1/g)){if(inComment(match.index))continue;const markup=inMarkup(match.index),css=inCss(match.index);if(!stringStarts.has(match.index)&&!markup&&!css)continue;const before=text.slice(Math.max(0,match.index-500),match.index),context=moduleSpecifierContext(text,match.index),cssImport=css&&/@import\s+(?:url\(\s*)?$/.test(before),resource=markup&&/\b(?:href|src)\s*=\s*$/.test(before);if(!context&&!cssImport&&!resource)continue;const specifier=match[2];for(const review of reviews)(review.kind==="entry-point"||review.kind==="stylesheet")&&specifier===specifierOf(review.name)&&report(match.index+1,review);if(handledSpecifiers.has(match.index)||!context||context.sideEffect)continue;const available=namedFor(specifier);if(context.kind==="binding"&&/\bexport\s+(?:type\s+)?\*\s*(?:as\s+[$A-Z_a-z][$\w]*\s*)?from\s*$/.test(before))for(const review of available)report(match.index+1,review,"This re-export includes ");else opaque(match.index+1,specifier,available)}for(const match of text.matchAll(/@import\s+url\(\s*(@aceshooting\/lyra-ui\/[^\s)'";]+)\s*\)/g))if(!(inComment(match.index)||!inCss(match.index)))for(const review of reviews)review.kind==="stylesheet"&&match[1]===specifierOf(review.name)&&report(match.index+match[0].indexOf(match[1]),review);for(const review of reviews)if(review.kind==="window-event")for(const match of text.matchAll(new RegExp(`(['"\\x60])(${regexEscape(review.name)})\\1`,"g"))){if(inComment(match.index))continue;const before=text.slice(Math.max(0,match.index-200),match.index);(LISTENER_CALL_BEFORE.test(before)||/\bnew\s+(?:CustomEvent|Event)\s*(?:<[^>\n]+>)?\(\s*$/.test(before))&&stringStarts.has(match.index)&&report(match.index+1,review)}else if(review.kind==="root-attribute"){const attributeOffsets=new Set;for(const token of openingTokens)for(const attribute of parseTagAttributes(text,token))attribute.rawName.replace(/^\[attr\.(.+)\]$/,"$1").replace(/^(?:v-bind:|bind:|[?:])/,"")===review.name&&!inString(attribute.nameStart)&&attributeOffsets.add(attribute.nameStart+attribute.rawName.indexOf(review.name));for(const match of text.matchAll(new RegExp(`(?<![\\w-])${regexEscape(review.name)}(?![\\w-])`,"g"))){if(inComment(match.index))continue;const offset=match.index,before=text.slice(Math.max(0,offset-180),offset),after=text.slice(offset+review.name.length),literalApi=/\b(?:getAttribute|setAttribute|hasAttribute|removeAttribute|toggleAttribute)\s*\(\s*['"`]$/.test(before),selector=/\[\s*$/.test(before)&&/^\s*(?:[~|^$*]?=|\])/.test(after),markup=attributeOffsets.has(offset);(literalApi&&stringStarts.has(offset-1)||selector&&(inCss(offset)||inString(offset))||markup)&&report(offset,review)}const datasetName=review.name.slice(5).replace(/-([a-z])/g,(_match,letter)=>letter.toUpperCase()),dataset=new RegExp(`\\bdataset\\s*(?:\\.\\s*${regexEscape(datasetName)}\\b|\\[\\s*(['"])${regexEscape(datasetName)}\\1\\s*\\])`,"g");for(const match of text.matchAll(dataset))!inComment(match.index)&&!inLiteral(match.index)&&report(match.index,review)}}const GLOBAL_REVIEW="GLOBAL_REVIEW",LYRA_PACKAGE="@aceshooting/lyra-ui",NODE_MODULES_LEAD=/(?:^|\/)node_modules\/$/,JSON_FILE=/\.json$/i,IDENTIFIER="[$A-Za-z_][$\\w]*";function applyGlobals(text,file,entries,{inComment,inCss,openingTokens,rewrite,warn}){const modules=entries.filter(entry=>entry.kind==="module"),exported=entries.filter(entry=>entry.kind==="export"),localeKeys=entries.filter(entry=>entry.kind==="locale-key"),review=(offset,entry,member,message)=>warn(offset,{member,code:GLOBAL_REVIEW,target:entry.to,message});if(modules.length){const inMarkup=offset=>openingTokens.some(token=>offset>=token.nameEnd&&offset<token.end),handle=(entry,specifierStart,specifier,safe)=>{safe?rewrite(specifierStart,specifierStart+entry.from.length,entry.to,{tag:null,member:specifier,action:"rewrite-module",target:entry.to,message:`Rewrite ${entry.from} to ${entry.to}: ${entry.summary}`}):review(specifierStart,entry,specifier,`${specifier} is not provably a module specifier here (or is computed): ${entry.summary} Use ${entry.to}${entry.prefix?"...":""} instead.`)},entryFor=specifier=>modules.find(entry=>entry.prefix?specifier.startsWith(entry.from)&&!(entry.except??[]).some(prefix=>specifier.startsWith(prefix)):specifier===entry.from);for(const match of text.matchAll(/(['"`])([^'"`\n]*?@aceshooting\/lyra-ui\/[^'"`\n]*)\1/g)){if(inComment(match.index))continue;const at=match[2].indexOf("@aceshooting/"),lead=match[2].slice(0,at);if(lead&&!NODE_MODULES_LEAD.test(lead))continue;const specifier=match[2].slice(at),entry=entryFor(specifier);if(!entry)continue;const specifierStart=match.index+1+at,before=text.slice(Math.max(0,match.index-500),match.index),context=moduleSpecifierContext(text,match.index),cssImport=inCss(match.index)&&/@import\s+(?:url\(\s*)?$/.test(before),resource=inMarkup(match.index)&&/\b(?:href|src)\s*=\s*$/.test(before),safe=!specifier.includes("${")&&!!(lead||JSON_FILE.test(file)||context||cssImport||resource);handle(entry,specifierStart,specifier,safe)}for(const match of text.matchAll(/@import\s+url\(\s*(@aceshooting\/lyra-ui\/[^\s)'";]+)\s*\)/g)){const entry=entryFor(match[1]);inComment(match.index)||!inCss(match.index)||!entry||handle(entry,match.index+match[0].indexOf(match[1]),match[1],!0)}}if(exported.length){const bindingsPattern=new RegExp(`\\b(?:import|export)\\s+(?:type\\s+)?(?:${IDENTIFIER}\\s*,\\s*)?\\{(?<body>[^{};]*)\\}\\s*from\\s*(?<quote>['"])(?<source>${regexEscape(LYRA_PACKAGE)}(?:\\/[^'"\\s]+)?)\\k<quote>`,"g"),segment=new RegExp(`^(\\s*(?:type\\s+)?)(${IDENTIFIER})(\\s+as\\s+${IDENTIFIER})?\\s*$`,"d");for(const match of text.matchAll(bindingsPattern)){if(inComment(match.index))continue;const bodyStart=match.index+match[0].indexOf("{")+1;for(const part of match.groups.body.matchAll(/[^,]+/g)){const parsed=segment.exec(part[0]),entry=parsed&&exported.find(candidate=>candidate.from===parsed[2]);if(!entry)continue;const nameStart=bodyStart+part.index+parsed.indices[2][0];inComment(nameStart)||(match.groups.source===LYRA_PACKAGE?rewrite(nameStart,nameStart+entry.from.length,parsed[3]?entry.to:`${entry.to} as ${entry.from}`,{tag:null,member:entry.from,action:"rewrite-export",target:entry.to,message:`${entry.from} no longer exists; import ${entry.to}${parsed[3]?"":` as ${entry.from}`}: ${entry.summary}`}):review(nameStart,entry,entry.from,`${entry.from} is not exported by ${match.groups.source} any more: ${entry.summary} Import ${entry.to} from ${LYRA_PACKAGE}.`))}}const receivers=[...[...text.matchAll(new RegExp(`import\\s+(?:type\\s+)?\\*\\s+as\\s+(${IDENTIFIER})\\s+from\\s*(['"])${regexEscape(LYRA_PACKAGE)}\\2`,"g"))].map(match=>match[1]).map(regexEscape),`import\\(\\s*['"]${regexEscape(LYRA_PACKAGE)}['"]\\s*\\)`];for(const entry of exported)for(const match of text.matchAll(new RegExp(`(?<![$\\w.])(?:${receivers.join("|")})\\s*\\.\\s*${entry.from}(?![$\\w])`,"g")))inComment(match.index)||review(match.index+match[0].lastIndexOf(entry.from),entry,entry.from,`${entry.from} no longer exists: ${entry.summary} Use ${entry.to}.`)}for(const entry of entries.filter(candidate=>candidate.kind==="css-property")){const pattern=new RegExp(`${regexEscape(entry.from)}${entry.prefix?"[\\w-]*":"(?![\\w-])"}`,"g");for(const match of text.matchAll(pattern))inComment(match.index)||review(match.index,entry,match[0],`The custom property ${match[0]} was removed: ${entry.summary} Use ${entry.to}.`)}const parts=entries.filter(candidate=>candidate.kind==="part");if(parts.length)for(const match of text.matchAll(/::part\(([^)]*)\)/g)){if(inComment(match.index))continue;const names=match[1].trim().split(/\s+/),type=compoundTypeBefore(text,match.index);for(const entry of parts)!names.includes(entry.from)||!(type===entry.tag||!type&&text.includes(entry.tag))||review(match.index+match[0].indexOf(entry.from),entry,entry.from,`The ${entry.tag} part ${entry.from} changed: ${entry.summary} ${entry.to}`)}if(localeKeys.length&&/registerLyraLocale|bridgeLyraLocale|\.strings\b|@aceshooting\/lyra-ui/.test(text))for(const entry of localeKeys)for(const match of text.matchAll(new RegExp(`(?<![$\\w.-])${entry.from}(?![$\\w-])`,"g"))){const before=text[match.index-1]??"",after=text.slice(match.index+entry.from.length,match.index+entry.from.length+12),quoted=/['"`]/.test(before)&&/^['"`]/.test(after);inComment(match.index)||!(quoted||/^\s*:/.test(after))||review(match.index,entry,entry.from,`The localization key ${entry.from} was removed; use ${entry.to}: ${entry.summary}`)}}function migrateRenameText(original,contract,options){const file=options.file??"<memory>",origin=options.origin,profile=contract.renameProfiles.get(origin);invariant(profile,`unknown migration origin ${String(origin)}`);const result={content:original,changes:[],warnings:[],acknowledged:0,usage:{webawesome:{automatic:0,manual:0},shoelace:{automatic:0,manual:0}},blockedMappings:new Set,blockedEcosystems:new Set,bareImportEcosystems:new Set,blockedLocalMigrations:new Set,constructedEvents:new Set};if(profile.isEmpty)return result;const starts=lineStarts(original),ignoredRanges=renameIgnoredRanges(original,file),inComment=rangeTester(ignoredRanges),openingTokens=scanAllOpeningTags(original,ignoredRanges,inComment),acknowledgements=scanReviewAcknowledgements(original,ignoredRanges,starts,openingTokens),litTemplates=LIT_TEMPLATE_FILE.test(file)?rangeTester(taggedTemplateRanges(original,["html","svg"],inComment)):()=>!1,inLiteral=rangeTester(mergeRanges([...quotedStringRanges(original,inComment),...templateLiteralRanges(original,inComment)])),inCss=rangeTester(stylesheetRanges(original,file,inComment)),attributeSemantics=offset=>ATTRIBUTE_SEMANTICS_FILE.test(file)||litTemplates(offset),release=`Lyra ${profile.toMajor}`,removal=`${profile.aliasRemovalMajor}.0.0`;for(const match of original.matchAll(EVENT_CONSTRUCTION))!inComment(match.index)&&profile.renamesNamed("event",match[2]).length&&result.constructedEvents.add(match[2]);const constructedEvents=new Set([...options.constructedEvents??[],...result.constructedEvents]),listenerIdentity=(quote,name)=>{const receiver=LISTENER_RECEIVER_BEFORE.exec(original.slice(Math.max(0,quote-200),quote))?.[1],handler=LISTENER_HANDLER_AFTER.exec(original.slice(quote+name.length+2,quote+name.length+202))?.[1];return receiver&&handler?`${receiver.replace(/\s+/g,"")}\0${handler.replace(/\s+/g,"")}`:null},listenedNames=new Map;if(profile.data.renames.some(entry=>entry.kind==="event"))for(const match of original.matchAll(/(['"`])(lr-[a-z0-9]+(?:-[a-z0-9]+)*)\1/g)){if(inComment(match.index)||!LISTENER_CALL_BEFORE.test(original.slice(Math.max(0,match.index-120),match.index)))continue;const identity=listenerIdentity(match.index,match[2]);identity&&listenedNames.set(identity,new Set([...listenedNames.get(identity)??[],match[2]]))}const sameHandlerListens=(quote,name)=>{if(!listenedNames.size)return!1;const names=listenedNames.get(listenerIdentity(quote,name));return!!names&&profile.renamesNamed("event",name).some(entry=>names.has(entry.to))},edits=[],seenWarnings=new Set,handledStrings=new Set,handledMembers=new Set,unique=values=>[...new Set(values)],list=values=>unique(values).join(", "),soleTag=entries=>unique(entries.map(entry=>entry.tag)).length===1?entries[0].tag:null,hint=(code,member)=>`After review, mark the site with a "lyra-migrate-reviewed: ${code}:${ackName(member)}" comment.`,rewrite=(start,end,replacement,{tag,member,action,target,message})=>{edits.push({start,end,replacement}),result.changes.push(reportEntry({textStarts:starts,file,offset:start,origin,upstreamTag:tag,upstreamMember:member,action,target,message}))},warn=(offset,{tag=null,member,code,target=null,message})=>{const key=`${offset}:${code}:${member}`;if(!seenWarnings.has(key)){if(seenWarnings.add(key),acknowledgements.consume(locationAt(starts,offset).line,code,member)){result.acknowledged+=1;return}result.warnings.push(reportEntry({textStarts:starts,file,offset,origin,upstreamTag:tag,upstreamMember:member,action:"manual-review",target,warningCode:code,message:`${message} ${hint(code,member)}`}))}},reviewMessage=review=>`${review.kind==="component"?`<${review.tag}>`:review.kind==="slot"&&review.name===""?`Content in the default slot of ${review.tag}`:`The ${review.tag} ${review.kind} ${review.name}`} ${review.removedIn?`was removed in ${review.removedIn}`:`is deprecated and scheduled for removal in ${review.removalNotBefore}`}; migrate to ${review.replacement} by hand.`,reportReview=(offset,review)=>warn(offset,{tag:review.tag,member:review.name,code:DEPRECATED_MEMBER_REVIEW,target:review.replacement,message:reviewMessage(review)}),reportPropertyChange=(offset,entry)=>warn(offset,{tag:entry.tag,member:entry.property,code:"PROPERTY_CHANGE_REVIEW",target:entry.property,message:`Review ${entry.tag}.${entry.property} for ${release}: ${entry.summary}`});reportModuleReviews(original,file,profile.data.moduleReviews,openingTokens,inComment,warn),applyGlobals(original,file,profile.data.globals,{inComment,inCss,openingTokens,rewrite,warn});const unownedReviews=(kind,name,offset,owner)=>{const own=owner?profile.reviewFor(owner,kind,name):null;if(own)reportReview(offset,own);else if(!profile.exposes(kind,name,owner))for(const review of profile.reviewsNamed(kind,name))reportReview(offset,review)},label=kind=>kind==="css-property"?"custom property":kind,detailNote=name=>{const details=profile.detailsNamed(name);return details.length?` Its ${release} detail also changed: ${details.map(entry=>`${entry.tag}: ${entry.summary}`).join(" ")}`:""},unownedMove=({kind,name,start,context,rewritable,action})=>{const renames=profile.renamesNamed(kind,name),targets=unique(renames.map(entry=>entry.to)),constructed=kind==="event"&&constructedEvents.has(name);if(rewritable&&!constructed&&profile.isGlobal(kind,name))return rewrite(start,start+name.length,targets[0],{tag:soleTag(renames),member:name,action,target:targets[0],message:`Rename ${name} to ${targets[0]}; every component exposing it renamed it, and no other component uses ${targets[0]}.`}),targets[0];const sourceKeepers=unique(targets.flatMap(to=>profile.sourceKeepers(kind,name,to))).filter(tag=>!renames.some(entry=>entry.tag===tag)),targetKeepers=unique(targets.flatMap(to=>profile.targetKeepers(kind,name,to))),shared=targets.length===1&&!sourceKeepers.length&&targetKeepers.length>0&&!renames.some(entry=>entry.polarity);return warn(start,{tag:soleTag(renames),member:name,code:shared?RENAME_TARGET_SHARED_REVIEW:RENAME_REVIEW,target:targets.join(" | "),message:(kind==="css-property"?"Custom properties inherit into nested components. ":context==="listener"?"This listener does not prove which element it listens to. ":"This string may name an event of any component. ")+`${list(renames.map(entry=>entry.tag))} renamed the ${label(kind)} ${name} to ${targets.join(" or ")}`+(sourceKeepers.length?`, while ${list(sourceKeepers)} still ${sourceKeepers.length===1?"uses":"use"} ${name}`:"")+(targetKeepers.length?`; ${list(targetKeepers)} already ${targetKeepers.length===1?"uses":"use"} ${targets.join(" and ")}, which this site would start reaching`:"")+(constructed?`; the scanned code also dispatches ${name} itself, so its listeners and dispatches must move together`:"")+`. Update it by hand for the components it is meant for; ${name} keeps working until ${removal}.`+(kind==="event"?detailNote(targets[0]):"")}),null},eventMove=(name,owner,rewritable=!0)=>{if(constructedEvents.has(name))return null;const own=owner?profile.renameFor(owner,"event",name):null;return own?profile.targetKeepers("event",name,own.to).length?null:own.to:!rewritable||!profile.renamesNamed("event",name).length||profile.exposes("event",name,owner)?null:profile.isGlobal("event",name)?profile.renamesNamed("event",name)[0].to:null},conflictMessage=(conflict,subject,to)=>conflict==="same-handler"?`${subject} already listens to ${to} with this same handler; renamed, the two identical registrations would collapse into one, so the handler would run once per activation instead of twice. Rename or remove this call, and its add or remove counterpart, together by hand.`:`${subject} already listens to ${to}; merge the two handlers by hand.`,eventSite=({name,start,owner,context,rewritable=!0,conflict=!1})=>{const retired=owner?profile.retiredEventFor(owner,name):null,retiredCandidates=retired?[retired]:profile.exposes("event",name,owner)?[]:profile.retiredEventsNamed(name);retiredCandidates.length&&warn(start,{tag:retired?owner:soleTag(retiredCandidates),member:name,code:"RETIRED_EVENT_REVIEW",target:unique(retiredCandidates.map(entry=>entry.replacement)).join(", "),message:`${name} is no longer dispatched by ${list(retiredCandidates.map(entry=>entry.tag))} in ${release}. `+retiredCandidates.map(entry=>`${entry.tag}: use ${entry.replacement}. ${entry.summary}`).join(" ")+" Review this listener and its matching removal together; keep unrelated events with the same spelling, check nested event targets, and merge any existing canonical listener without dropping or duplicating handler calls."});const own=owner?profile.renameFor(owner,"event",name):null;let current=name;if(own){const keepers=profile.targetKeepers("event",name,own.to);if(constructedEvents.has(name))warn(start,{tag:owner,member:name,code:RENAME_REVIEW,target:own.to,message:`Not renamed: the scanned code dispatches ${name} itself, so this listener would stop hearing it. Rename the dispatch and its listeners to ${own.to} together; ${name} keeps working until ${removal}.${detailNote(own.to)}`});else if(keepers.length)warn(start,{tag:owner,member:name,code:RENAME_TARGET_SHARED_REVIEW,target:own.to,message:`Not renamed: ${list(keepers)} also ${keepers.length===1?"dispatches":"dispatch"} ${own.to}, so this listener would start receiving their events when they are nested inside this ${owner}. Rename it by hand and ignore events whose target is not this ${owner}; ${name} keeps working until ${removal}.${detailNote(own.to)}`});else if(conflict)warn(start,{tag:owner,member:name,code:RENAME_CONFLICT_REVIEW,target:own.to,message:`${conflictMessage(conflict,`This ${owner}`,own.to)} ${name} keeps working until ${removal}.`});else{const narrowed=profile.sourceKeepers("event",name,own.to).filter(tag=>tag!==owner);rewrite(start,start+name.length,own.to,{tag:owner,member:name,action:"rewrite-event",target:own.to,message:`Rename the ${owner} event ${name} to ${own.to}.`+(narrowed.length?` ${list(narrowed)} still ${narrowed.length===1?"dispatches":"dispatch"} ${name}; this listener stops hearing theirs from nested elements.`:"")}),current=own.to}}else profile.renamesNamed("event",name).length&&!profile.exposes("event",name,owner)&&(conflict?warn(start,{tag:soleTag(profile.renamesNamed("event",name)),member:name,code:RENAME_CONFLICT_REVIEW,target:profile.renamesNamed("event",name)[0].to,message:conflictMessage(conflict,conflict==="same-handler"?"This receiver":"This element",profile.renamesNamed("event",name)[0].to)}):current=unownedMove({kind:"event",name,start,context,rewritable,action:"rewrite-event"})??name);const details=profile.detailsNamed(current),ownDetail=owner?profile.detailFor(owner,current):null;if(ownDetail||details.length&&!profile.exposes("event",current,owner)){const affected=ownDetail?[ownDetail]:details;warn(start,{tag:ownDetail?owner:soleTag(affected),member:current,code:DETAIL_SHAPE_REVIEW,target:current,message:`The ${current} event detail changed in ${release} and cannot be aliased: `+affected.map(entry=>`${entry.tag}: ${entry.summary}`).join(" ")+` Update this handler if it reads the detail of ${ownDetail?`the ${owner} event`:"one of these components"}.`})}const gained=current===name?profile.gainedOwners("event",name):[];gained.length&&!profile.exposes("event",name,owner)&&warn(start,{tag:soleTag(gained.map(tag=>({tag}))),member:name,code:NAME_GAINED_OWNER_REVIEW,target:name,message:`In ${release}, ${list(gained)} also ${gained.length===1?"dispatches":"dispatch"} ${name}. This ${context} does not prove which element it listens to, so it may start receiving those events; ignore them by event target if it should not.`}),unownedReviews("event",name,start,owner)},reportedDetailFieldOffsets=new Set,detailFieldAccess=/\b([A-Za-z_$][\w$]*)\s*(?:\?\.|\.)\s*detail\s*(?:\?\.|\.)\s*(open|collapsed)\b/g,reportDetailField=(field,start,owner=null,event=null)=>{if(reportedDetailFieldOffsets.has(start))return;const exact=owner&&event?profile.detailFieldFor(owner,event):null;if(exact&&exact.field===field){const target=exact.relation==="equal"?"detail.expanded":"!detail.expanded",relation=exact.relation==="equal"?"carries the same value as":"is the inverse of",removal2=exact.removedIn?` It was removed in ${exact.removedIn}.`:" This notice does not assert that the field was removed.";warn(start,{tag:owner,member:field,code:DETAIL_FIELD_REVIEW,target,message:`The ${owner} ${event} detail field ${field} is deprecated: it ${relation} detail.expanded (${exact.notice}). Read ${target} in this handler by hand; no field rewrite was applied.${removal2}`}),reportedDetailFieldOffsets.add(start);return}const candidates=event?profile.detailFieldsNamed(event).filter(entry=>entry.field===field):[],possible=candidates.length?candidates:(profile.data.detailFields??[]).filter(entry=>entry.field===field);if(!possible.length)return;const possibilities=[...new Set(possible.map(entry=>`${entry.tag}/${entry.event} (${entry.relation})`))];warn(start,{tag:null,member:field,code:DETAIL_FIELD_REVIEW,target:null,message:`This detail.${field} read has no proven Lyra tag and event. Matching published field contracts are ${possibilities.join(", ")}; identify the runtime detail type and migrate it by hand. No field rewrite was applied.`}),reportedDetailFieldOffsets.add(start)},inspectMarkupDetailFields=(owner,event,attribute)=>{if(attribute.valueStart===null||attribute.valueEnd===null)return;const value=original.slice(attribute.valueStart,attribute.valueEnd);for(const match of value.matchAll(detailFieldAccess)){const start=attribute.valueStart+match.index+match[0].lastIndexOf(match[2]);reportDetailField(match[2],start,owner,event)}};for(const token of openingTokens){const owner=token.tag.toLowerCase();for(const attribute of parseTagAttributes(original,token)){const event=markupEventName(attribute.rawName);event&&/^lr-/u.test(event.name)&&inspectMarkupDetailFields(owner,event.name,attribute)}}const memberSite=({owner,kind,name,start,forms,dynamic,removal:removalRange})=>{const propertyChange=forms.filter(([candidateKind])=>candidateKind==="property").map(([,candidate])=>profile.propertyChangeFor(owner,candidate)).find(Boolean);propertyChange&&reportPropertyChange(start,propertyChange);const review=forms.map(([candidateKind,candidate])=>profile.reviewFor(owner,candidateKind,candidate)).find(Boolean);review&&reportReview(start,review);const rule=forms.map(([candidateKind,candidate])=>profile.renameFor(owner,candidateKind,candidate)).find(Boolean);if(!rule)return null;if(rule.polarity==="inverted"&&(dynamic||!removalRange)){const target=kind==="binding"?memberStyle(name,rule.to):rule.to;return warn(start,{tag:owner,member:rule.from,code:POLARITY_REVIEW,target:rule.to,message:`${target} is the inverse of ${name} on ${owner}, and this ${kind==="binding"?"binding":kind==="property"?"property access":"attribute binding"} is not a static attribute. Bind the negated value to ${target} by hand; ${name} keeps working until ${removal}.`}),null}return rule},renamedMembers=owner=>unique([...profile.data.renames.filter(entry=>entry.tag===owner&&["attribute","property","event"].includes(entry.kind)).map(entry=>entry.from),...profile.data.reviews.filter(entry=>entry.tag===owner&&["attribute","property","event"].includes(entry.kind)).map(entry=>entry.name),...profile.data.retiredEvents.filter(entry=>entry.tag===owner).map(entry=>entry.event),...profile.data.propertyChanges.filter(entry=>entry.tag===owner).flatMap(entry=>[entry.property,...entry.former?[entry.former]:[]])]),defaultTokens=[];for(const token of openingTokens){const owner=token.tag.toLowerCase(),attributes=parseTagAttributes(original,token),lyraOwner=profile.tags.has(owner),bound=lyraOwner?boundMemberNames(attributes):null,finalNames=new Map,planned=attributes.map(attribute=>{const event=markupEventName(attribute.rawName);let finalRaw=attribute.rawName;if(event&&/^lr-/.test(event.name)){const to=eventMove(event.name,owner);to&&(finalRaw=attribute.rawName.slice(0,event.offset)+to+attribute.rawName.slice(event.offset+event.name.length))}else if(lyraOwner){const binding=markupMemberBinding(attribute),rule=binding&&!binding.form.startsWith("member")&&profile.renameFor(owner,binding.form,binding.name);rule&&!rule.polarity&&(finalRaw=attribute.rawName.slice(0,binding.offset)+rule.to+attribute.rawName.slice(binding.offset+binding.name.length))}const key=finalRaw.toLowerCase();return finalNames.set(key,(finalNames.get(key)??0)+1),{attribute,event,key,renamed:finalRaw!==attribute.rawName}});if(lyraOwner&&renamedMembers(owner).length)for(const group of openingTagBraceGroups(original,token)){const shorthand=/^[A-Za-z_$][\w$]*$/.exec(group.body)?.[0];if(!shorthand){warn(group.start,{tag:owner,member:owner,code:"DYNAMIC_VALUE_REVIEW",target:null,message:`This spread on ${owner} may carry renamed or deprecated members (${list(renamedMembers(owner))}); rename them where the object is built.`});continue}const forms=[["property",camelCase(shorthand)],["attribute",kebabCase(shorthand)]],review=forms.map(([kind,name])=>profile.reviewFor(owner,kind,name)).find(Boolean);review&&reportReview(group.start+1,review);const propertyChange=profile.propertyChangeFor(owner,camelCase(shorthand));propertyChange&&reportPropertyChange(group.start+1,propertyChange);const rule=forms.map(([kind,name])=>profile.renameFor(owner,kind,name)).find(Boolean);rule&&warn(group.start+1,{tag:owner,member:rule.from,code:rule.polarity?POLARITY_REVIEW:RENAME_REVIEW,target:rule.to,message:`The shorthand {${shorthand}} binds the deprecated ${owner} ${rule.kind} ${rule.from}; write ${memberStyle(shorthand,rule.to)}={${rule.polarity?`!${shorthand}`:shorthand}} by hand.`})}for(const{attribute,event,key,renamed}of planned){if(event){/^lr-/.test(event.name)&&(inspectMarkupDetailFields(owner,event.name,attribute),eventSite({name:event.name,start:attribute.nameStart+event.offset,owner,context:"listener",conflict:renamed&&finalNames.get(key)>1}));continue}if(!lyraOwner)continue;if(/^v-(?:bind|on)$/.test(attribute.rawName)||attribute.rawName.startsWith("${")&&!/^\$\{\s*ref\s*\(/.test(attribute.rawName)){renamedMembers(owner).length&&warn(attribute.nameStart,{tag:owner,member:owner,code:"DYNAMIC_VALUE_REVIEW",target:null,message:`This object binding on ${owner} may carry renamed or deprecated members (${list(renamedMembers(owner))}); rename them where the object is built.`});continue}if(attribute.rawName==="exportparts"){if(attribute.valueKind!=="literal"||/\$\{|\{\{/.test(attribute.value??""))continue;for(const match of(attribute.value??"").matchAll(/([^,\s:]+)(\s*:\s*[^,\s]+)?/g)){const inner=match[1],start2=attribute.valueStart+match.index,review=profile.reviewFor(owner,"part",inner);review&&reportReview(start2,review);const rule2=profile.renameFor(owner,"part",inner);rule2&&rewrite(start2,start2+inner.length,match[2]?rule2.to:`${rule2.to}:${inner}`,{tag:owner,member:inner,action:"rewrite-part",target:rule2.to,message:match[2]?`Forward the renamed ${owner} part ${rule2.to} under the same exported name.`:`Forward the renamed ${owner} part ${rule2.to} under its previous exported name ${inner}.`})}continue}const binding=markupMemberBinding(attribute);if(!binding)continue;const forms=binding.form==="member"?[["property",camelCase(binding.name)],["attribute",kebabCase(binding.name)]]:[[binding.form,binding.name]],start=attribute.nameStart+binding.offset,staticAttribute=binding.form==="attribute"&&binding.offset===0&&!binding.dynamic,rule=memberSite({owner,kind:binding.form==="member"?"binding":binding.form,name:binding.name,start,forms,dynamic:binding.dynamic,removal:staticAttribute});if(!rule)continue;if(bound.has(kebabCase(rule.to))||renamed&&finalNames.get(key)>1){warn(start,{tag:owner,member:rule.from,code:RENAME_CONFLICT_REVIEW,target:rule.to,message:`This ${owner} already binds ${rule.to}; remove the deprecated ${rule.from} binding by hand.`});continue}if(rule.polarity==="inverted"){if(!attributeSemantics(token.start)){warn(start,{tag:owner,member:rule.from,code:POLARITY_REVIEW,target:rule.to,message:`${rule.to} is the inverse of ${rule.from}. In this template syntax a static value may be assigned to the ${camelCase(rule.from)} property as a string, where "false" is truthy, so set ${rule.to} by hand.`});continue}if(profile.preservedDefaultsFor(owner).some(entry=>entry.attribute===rule.to&&entry.value===!0)){warn(start,{tag:owner,member:rule.from,code:POLARITY_REVIEW,target:rule.to,message:`${rule.from} has a preserved absent default, so removing an explicit attribute would let a later run insert ${rule.to}. Review this value using the old converter (a presence boolean treats even "false" as true), then migrate it by hand after the default migration is complete.`});continue}const value=attribute.value??"",end=attributeEnd(original,attribute);if(value===""||value==="true"||value===rule.from){let removeFrom=attribute.nameStart;for(;removeFrom>0&&/\s/.test(original[removeFrom-1]);)removeFrom-=1;rewrite(removeFrom,end,"",{tag:owner,member:rule.from,action:"remove-attribute",target:rule.to,message:`Remove ${rule.from}: it restated the ${owner} default, and ${rule.to} is off by default.`})}else value==="false"?rewrite(attribute.nameStart,end,rule.to,{tag:owner,member:rule.from,action:"rewrite-attribute",target:rule.to,message:`Replace ${rule.from}="false" with the presence of ${rule.to}.`}):warn(start,{tag:owner,member:rule.from,code:POLARITY_REVIEW,target:rule.to,message:`${rule.from}="${attribute.value}" is not a boolean literal; set ${rule.to} to its inverse by hand.`});continue}const target=binding.form==="member"?memberStyle(binding.name,rule.to):rule.to;rewrite(start,start+binding.name.length,target,{tag:owner,member:rule.from,action:`rewrite-${rule.kind}`,target:rule.to,message:`Rename the ${owner} ${rule.kind} ${rule.from} to ${rule.to}.`})}lyraOwner&&profile.defaultsFor(owner).length&&defaultTokens.push({token,owner,bound})}const slotTags=[...profile.tags].filter(tag=>profile.slotContentFor(tag).length||[...profile.data.renames,...profile.data.reviews].some(entry=>entry.tag===tag&&entry.kind==="slot"));for(const tag of slotTags)for(const pair of elementPairs(original,tag,inComment))for(const child of directChildTokens(original,pair.opening.end+1,pair.closingStart,inComment)){let slot="",start=child.nameStart;for(const attribute of parseTagAttributes(original,child))if(attribute.rawName==="slot")slot=attribute.valueKind==="literal"?attribute.value??"":null,start=attribute.valueStart??attribute.nameStart;else if(attribute.rawName==="v-slot")slot="";else{const prefix=["v-slot:","#"].find(candidate=>attribute.rawName.startsWith(candidate));prefix&&(slot=attribute.rawName.slice(prefix.length),start=attribute.nameStart+prefix.length,slot==="default"&&(slot=""))}if(slot===null)continue;const review=profile.reviewFor(tag,"slot",slot);review&&reportReview(start,review);const rule=slot===""?null:profile.renameFor(tag,"slot",slot);if(rule&&rewrite(start,start+slot.length,rule.to,{tag,member:slot,action:"rewrite-slot",target:rule.to,message:`Rename the ${tag} slot ${slot} to ${rule.to}.`}),child.tag!=="template")for(const content of profile.slotContentFor(tag)){if(content.slot!==slot)continue;const listed=(content.report??content.allow).includes(child.tag);(content.report?!listed:listed)||warn(child.nameStart,{tag,member:child.tag,code:DEPRECATED_CONTENT_REVIEW,target:null,message:`<${child.tag}> in ${slot===""?"the default slot":`the ${slot} slot`} of ${tag}: ${content.summary}`})}}for(const match of original.matchAll(/::part\(([^)]*)\)/g)){if(inComment(match.index))continue;const owner=compoundTypeBefore(original,match.index),listStart=match.index+7;for(const nameMatch of match[1].matchAll(/\S+/g)){const name=nameMatch[0],start=listStart+nameMatch.index,own=owner?profile.renameFor(owner,"part",name):null;if(own)rewrite(start,start+name.length,own.to,{tag:owner,member:name,action:"rewrite-part",target:own.to,message:`Rename the ${owner} part ${name} to ${own.to}.`});else if(profile.renamesNamed("part",name).length&&!profile.exposes("part",name,owner)){const renames=profile.renamesNamed("part",name),keepers=profile.exposers("part",name).filter(tag=>!renames.some(entry=>entry.tag===tag));warn(start,{tag:soleTag(renames),member:name,code:RENAME_REVIEW,target:list(renames.map(entry=>entry.to)),message:`This ::part() selector does not name the component that owns the part. ${list(renames.map(entry=>entry.tag))} renamed the part ${name} to ${list(renames.map(entry=>entry.to))}`+(keepers.length?`, while ${list(keepers)} still ${keepers.length===1?"exposes":"expose"} ${name}`:"")+". Rename it where the selector reaches a renamed component directly; a part forwarded through exportparts keeps its exported name."})}else if(profile.gainedOwners("part",name).length&&!owner?.startsWith("lr-")){const gained=profile.gainedOwners("part",name);warn(start,{tag:soleTag(gained.map(tag=>({tag}))),member:name,code:NAME_GAINED_OWNER_REVIEW,target:name,message:`In ${release}, ${list(gained)} also ${gained.length===1?"exposes":"expose"} the part ${name}, so this selector may start matching it.`})}unownedReviews("part",name,start,owner)}}const cssNames=new Set([...profile.data.renames.filter(entry=>entry.kind==="css-property").flatMap(entry=>[entry.from,entry.to]),...profile.data.reviews.filter(entry=>entry.kind==="css-property").map(entry=>entry.name)]);if(cssNames.size)for(const match of original.matchAll(/(?<![\w-])--[A-Za-z0-9_-]+/g)){const name=match[0];if(!cssNames.has(name)||inComment(match.index))continue;profile.renamesNamed("css-property",name).length&&unownedMove({kind:"css-property",name,start:match.index,context:"custom property",rewritable:!0,action:"rewrite-css-property"});const declaration=/^\s*['"]?\s*:/.test(original.slice(match.index+name.length,match.index+name.length+16))||/setProperty\s*\(\s*['"`]$/.test(original.slice(Math.max(0,match.index-24),match.index)),gained=profile.gainedOwners("css-property",name);declaration&&gained.length&&warn(match.index,{tag:soleTag(gained.map(tag=>({tag}))),member:name,code:NAME_GAINED_OWNER_REVIEW,target:name,message:`In ${release}, ${list(gained)} also ${gained.length===1?"reads":"read"} ${name}, so this declaration now reaches them when they are nested below it.`});for(const review of profile.reviewsNamed("css-property",name))reportReview(match.index,review)}for(const match of original.matchAll(/\[\s*([A-Za-z_][\w-]*)(?=\s*(?:[~|^$*]?=|\]))/g)){if(inComment(match.index))continue;const owner=compoundTypeBefore(original,match.index);if(!owner||!profile.tags.has(owner))continue;const name=match[1],start=match.index+match[0].length-name.length,review=profile.reviewFor(owner,"attribute",name);review&&reportReview(start,review);const rule=profile.renameFor(owner,"attribute",name);if(rule){if(rule.polarity==="inverted"){warn(start,{tag:owner,member:name,code:POLARITY_REVIEW,target:rule.to,message:`${rule.to} is the inverse of ${name}; rewrite this ${owner} selector to test the opposite state (for example :not([${rule.to}])).`});continue}if(!rule.reflects){warn(start,{tag:owner,member:name,code:RENAME_REVIEW,target:rule.to,message:`${owner} does not reflect ${rule.to}, so [${rule.to}] matches only where markup sets it. Rename this selector once every place that sets ${name} (markup, setAttribute) sets ${rule.to} instead.`});continue}rewrite(start,start+name.length,rule.to,{tag:owner,member:name,action:"rewrite-attribute",target:rule.to,message:`Rename the ${owner} attribute selector [${name}] to [${rule.to}]; ${owner} reflects ${rule.to}.`})}}for(const match of original.matchAll(/:state\(\s*([a-z][a-z0-9-]*)\s*\)/g)){if(inComment(match.index))continue;const owner=compoundTypeBefore(original,match.index),review=owner?profile.reviewFor(owner,"css-state",match[1]):null;review&&reportReview(match.index+match[0].indexOf(match[1]),review)}for(const review of profile.data.reviews.filter(entry=>entry.kind==="component"))for(const match of original.matchAll(new RegExp(`(?<![\\w-])${review.tag}(?![\\w-])`,"g")))inComment(match.index)||original.slice(match.index-2,match.index)==="</"||reportReview(match.index,review);const anchoredDetailListener=/(?:document\.)?querySelector\(\s*(['"])(lr-[a-z0-9-]+)\1\s*\)\s*!?\s*\.\s*addEventListener\(\s*(['"])(lr-[a-z0-9-]+)\3\s*,/g,unownedDetailListener=/[A-Za-z_$][\w$]*\s*\.\s*addEventListener\(\s*(['"])(lr-[a-z0-9-]+)\1\s*,/g,scriptListenerAt=offset=>{const start=Math.max(0,offset-4096),prefix=original.slice(start,offset);let result2=null;for(const pattern of[anchoredDetailListener,unownedDetailListener]){pattern.lastIndex=0;for(const match of prefix.matchAll(pattern)){const event=pattern===anchoredDetailListener?match[4]:match[2],callbackStart=match.index+match[0].length,callback=prefix.slice(callbackStart);!/=>|\bfunction\b/u.test(callback)||/\)\s*;/u.test(callback)||(!result2||match.index>=result2.index)&&(result2={owner:pattern===anchoredDetailListener?match[2]:null,event,index:match.index})}}return result2};for(const match of original.matchAll(detailFieldAccess)){const offset=match.index+match[0].lastIndexOf(match[2]);if(reportedDetailFieldOffsets.has(offset)||inComment(offset)||inLiteral(offset)||inCss(offset))continue;const listener=scriptListenerAt(offset);reportDetailField(match[2],offset,listener?.owner??null,listener?.event??null)}for(const match of original.matchAll(ANCHORED_MEMBER)){if(inComment(match.index))continue;const owner=match[2],member=match[3],start=match.index+match[0].length-member.length,after=start+member.length;if(handledMembers.add(start),LISTENER_METHODS.has(member)||ATTRIBUTE_METHODS.has(member)){const call=/^\s*\(\s*(['"`])([^'"`\n]+)\1/.exec(original.slice(after,after+200));if(!call)continue;const valueStart=after+call[0].length-1-call[2].length;if(handledStrings.add(valueStart-1),LISTENER_METHODS.has(member)){eventSite({name:call[2],start:valueStart,owner,context:"listener",conflict:sameHandlerListens(valueStart-1,call[2])&&"same-handler"});continue}const rule2=memberSite({owner,kind:"attribute",name:call[2],start:valueStart,forms:[["attribute",call[2]]],dynamic:!0});rule2&&rewrite(valueStart,valueStart+call[2].length,rule2.to,{tag:owner,member:rule2.from,action:"rewrite-attribute",target:rule2.to,message:`Rename the ${owner} attribute ${rule2.from} to ${rule2.to}.`});continue}if(!profile.tags.has(owner))continue;if(/^\s*\(/.test(original.slice(after,after+64))){const review=profile.reviewFor(owner,"method",member);review&&reportReview(start,review);continue}const rule=memberSite({owner,kind:"property",name:member,start,forms:[["property",member]],dynamic:!0});rule&&rewrite(start,after,rule.to,{tag:owner,member:rule.from,action:"rewrite-property",target:rule.to,message:`Rename the ${owner} property ${rule.from} to ${rule.to}.`})}const eventNameMatters=name=>profile.renamesNamed("event",name).length||profile.detailsNamed(name).length||profile.retiredEventsNamed(name).length||profile.reviewsNamed("event",name).length||profile.gainedOwners("event",name).length;for(const match of original.matchAll(/(['"`])(?:(window|document|body):)?(lr-[a-z0-9]+(?:-[a-z0-9]+)*)\1/g)){const name=match[3];if(handledStrings.has(match.index)||inComment(match.index)||!eventNameMatters(name))continue;const before=original.slice(Math.max(0,match.index-120),match.index);if(!match[2]&&TAG_API_CALL_BEFORE.test(before))continue;const listener=LISTENER_CALL_BEFORE.test(before);eventSite({name,start:match.index+1+(match[2]?match[2].length+1:0),owner:null,context:listener?"listener":"event name string",rewritable:listener,conflict:listener&&!match[2]&&sameHandlerListens(match.index,name)&&"same-handler"})}const mentioned=mentionedTags(original,profile.tags,inComment),accessRules=new Map,addAccess=(name,candidate)=>accessRules.set(name,[...accessRules.get(name)??[],candidate]);for(const entry of profile.data.renames)entry.kind==="property"&&mentioned.has(entry.tag)&&addAccess(entry.from,{tag:entry.tag,rule:entry,call:!1});for(const entry of profile.data.reviews)(entry.kind==="property"||entry.kind==="method")&&mentioned.has(entry.tag)&&addAccess(entry.name,{tag:entry.tag,review:entry,call:entry.kind==="method"});for(const entry of profile.data.propertyChanges)if(mentioned.has(entry.tag))for(const name of[entry.property,...entry.former?[entry.former]:[]])addAccess(name,{tag:entry.tag,propertyChange:entry,call:!1});if(accessRules.size){const inString=rangeTester(mergeRanges(quotedStringRanges(original,inComment))),inStylesheet=rangeTester(stylesheetRanges(original,file,inComment)),inToken=rangeTester(mergeRanges(openingTokens.map(token=>[token.start+1,token.end])));for(const match of original.matchAll(/(?<=[\w$)\]])\s*(?:\?\.|!?\.)\s*([A-Za-z_$][\w$]*)/g)){const name=match[1],candidates=accessRules.get(name);if(!candidates)continue;const start=match.index+match[0].length-name.length;if(handledMembers.has(start)||reportedDetailFieldOffsets.has(start)||inComment(start)||inString(start)||inStylesheet(start)||inToken(start))continue;const call=/^\s*\(/.test(original.slice(start+name.length,start+name.length+64));for(const candidate of candidates){if(candidate.call!==call)continue;if(candidate.propertyChange){reportPropertyChange(start,candidate.propertyChange);continue}if(candidate.review){reportReview(start,candidate.review);continue}const{rule}=candidate;warn(start,{tag:rule.tag,member:name,code:rule.polarity?POLARITY_REVIEW:RENAME_REVIEW,target:rule.to,message:`If this reads or writes an ${rule.tag}, ${rule.polarity?`use the inverse property .${rule.to}`:`rename .${name} to .${rule.to}`}; .${name} keeps working until ${removal}.`})}}}for(const match of original.matchAll(/\.\s*(?:set|get|has|remove|toggle)Attribute\s*\(\s*(['"`])([a-z][a-z0-9-]*)\1/g)){const name=match[2],start=match.index+match[0].length-1-name.length;if(!(handledStrings.has(start-1)||inComment(match.index)))for(const tag of mentioned){const review=profile.reviewFor(tag,"attribute",name);review&&reportReview(start,review);const rule=profile.renameFor(tag,"attribute",name);rule&&warn(start,{tag,member:name,code:rule.polarity?POLARITY_REVIEW:RENAME_REVIEW,target:rule.to,message:`If this element is an ${tag}, ${rule.polarity?`use the inverse attribute ${rule.to}`:`rename ${name} to ${rule.to}`}; ${name} keeps working until ${removal}.`})}}if(profile.data.defaults.length){const defaultProfiles=new Map([...new Set(profile.data.defaults.map(entry=>entry.tag))].map(tag=>[tag,{origin,tag,defaults:profile.defaultsFor(tag).map(entry=>({member:entry.attribute,value:entry.value}))}])),hazards=scanLocalMigrationHazards(original,defaultProfiles,ignoredRanges,defaultTokens.map(({token})=>({...token,tag:token.tag.toLowerCase()}))),blocked=new Set([...options.blockedLocalMigrations??[],...hazards.blocked]);result.blockedLocalMigrations=hazards.blocked;for(const use of hazards.uses)warn(use.offset,{tag:use.tag,member:use.tag,code:use.warningCode,target:use.tag,message:use.message});for(const{token,owner,bound}of defaultTokens){const missing=profile.defaultsFor(owner).filter(entry=>!profile.defaultAliasesFor(owner,entry.attribute).some(name=>bound.has(name)));if(!missing.length)continue;if(blocked.has(localMigrationKey(origin,owner))){warn(token.nameStart,{tag:owner,member:owner,code:"MAPPING_REVIEW_BLOCKED",target:owner,message:`${owner} did not receive its Lyra ${profile.fromMajor} defaults (${missing.map(entry=>`${entry.attribute}=${String(entry.value)}`).join(", ")}) because the scanned target set accesses it through a DOM alias or an opaque attribute spread. Add them by hand where the previous default matters.`});continue}const insertions=[];for(const entry of missing)insertions.push(serializeLocalDefault({member:entry.attribute,value:entry.value})),result.changes.push(reportEntry({textStarts:starts,file,offset:token.end,origin,upstreamTag:owner,upstreamMember:entry.attribute,action:"insert-default",target:`${entry.attribute}=${String(entry.value)}`,message:`Insert ${entry.attribute} to preserve the Lyra ${profile.fromMajor} default.`}));if(insertions.length){const insertionOffset=original[token.end-1]==="/"?token.end-1:token.end,replacement=/\s/.test(original[insertionOffset-1])?`${insertions.join(" ")} `:` ${insertions.join(" ")}`;edits.push({start:insertionOffset,end:insertionOffset,replacement})}}}if(!profile.skipped.length)for(const{offset,entry}of acknowledgements.unused()){const key=`${offset}:${UNUSED_ACKNOWLEDGEMENT}:${entry.token}`;seenWarnings.has(key)||(seenWarnings.add(key),result.warnings.push(reportEntry({textStarts:starts,file,offset,origin,upstreamTag:null,upstreamMember:entry.token,action:"manual-review",target:null,warningCode:UNUSED_ACKNOWLEDGEMENT,message:entry.code?`The acknowledgement ${entry.token} matches no report on the lines it covers; remove it.`:`The acknowledgement ${entry.token} is not of the form CODE:name, for example DETAIL_SHAPE_REVIEW:lr-close.`})))}return result.content=finalizeEdits(original,edits),sortReportEntries(result.changes,"action"),sortReportEntries(result.warnings,"warningCode"),result}export{migrateRenameText};
4
+ `);)text[index]==="\\"&&(index+=1),index+=1;index+=1,quote!=="`"&&ranges.push([start,index])}return ranges}function stylesheetRanges(text,file,inComment){if(STYLESHEET_FILE.test(file))return[[0,text.length]];const ranges=[];for(const match of text.matchAll(/<style(?:\s[^>]*)?>[\s\S]*?<\/style\s*>/gi))ranges.push([match.index,match.index+match[0].length]);return mergeRanges([...ranges,...taggedTemplateRanges(text,["css"],inComment)])}function compoundTypeBefore(text,index){let start=index,brackets=0,parens=0;const limit=Math.max(0,index-SELECTOR_LOOKBEHIND);for(;start>limit;){const character=text[start-1];if(character==="]")brackets+=1;else if(character==="["){if(brackets===0)break;brackets-=1}else if(character===")")parens+=1;else if(character==="("){if(parens===0)break;parens-=1}else if(brackets===0&&parens===0&&/[\s,>+~{};'"`]/.test(character))break;start-=1}if(start===limit&&limit>0)return null;const compound=text.slice(start,index);return(/^:global\(\s*([A-Za-z][\w-]*)\s*\)$/.exec(compound)??/^([A-Za-z][\w-]*)/.exec(compound))?.[1].toLowerCase()??null}function mentionedTags(text,tags,inComment){const found=new Set;for(const tag of tags)for(const match of text.matchAll(new RegExp(`(?<![\\w-])${tag}(?![\\w-])`,"g")))if(!inComment(match.index)){found.add(tag);break}return found}function elementPairs(text,tag,inComment){const pairs=[],stack=[];for(const match of text.matchAll(new RegExp(`<(/)?${tag}(?=[\\s/>])`,"g"))){if(inComment(match.index))continue;const end=findTagEnd(text,match.index+match[0].length);if(!(end<0))if(match[1]){const opening=stack.pop();opening&&pairs.push({opening,closingStart:match.index})}else/\/\s*>$/.test(text.slice(match.index,end+1))||stack.push({start:match.index,end})}return pairs}function directChildTokens(text,start,end,inComment){const children=[],stack=[],pattern=/<(\/)?([A-Za-z][\w.:-]*)(?=[\s/>])/g;pattern.lastIndex=start;for(let match=pattern.exec(text);match&&match.index<end;match=pattern.exec(text)){if(inComment(match.index))continue;const tokenEnd=findTagEnd(text,match.index+match[0].length);if(tokenEnd<0||tokenEnd>=end)break;const name=match[2].toLowerCase();if(match[1]){const index=stack.lastIndexOf(name);index>=0&&(stack.length=index)}else{const nameStart=match.index+1;stack.length===0&&children.push({tag:name,start:match.index,nameStart,nameEnd:nameStart+match[2].length,end:tokenEnd}),!/\/\s*>$/.test(text.slice(match.index,tokenEnd+1))&&!VOID_HTML_TAGS.has(name)&&stack.push(name)}pattern.lastIndex=tokenEnd+1}return children}function openingTagBraceGroups(text,token){const groups=[];let index=token.nameEnd,quote=null;for(;index<token.end;){const character=text[index];if(quote){character==="\\"?index+=1:character===quote&&(quote=null),index+=1;continue}if(character==='"'||character==="'")quote=character;else if(character==="{"){const end=skipBalanced(text,index,"{","}");!/=\s*$/.test(text.slice(token.nameEnd,index))&&text[index-1]!=="$"&&groups.push({start:index,end,body:text.slice(index+1,end-1).trim()}),index=end;continue}index+=1}return groups}function markupEventName(rawName){if(/^\(lr-[a-z0-9-]+\)$/.test(rawName))return{name:rawName.slice(1,-1),offset:1};if(/^onlr-/.test(rawName))return{name:rawName.slice(2).replace(/Capture$/,""),offset:2};for(const[prefix,separator]of[["@","."],["v-on:","."],["on:","|"]])if(rawName.startsWith(prefix))return{name:rawName.slice(prefix.length).split(separator)[0],offset:prefix.length};return null}function markupMemberBinding(attribute){const raw=attribute.rawName;let match;if(raw.startsWith("?"))return{form:"attribute",offset:1,name:raw.slice(1),dynamic:!0};if(match=/^\[attr\.([^\]]+)\]$/.exec(raw))return{form:"attribute",offset:6,name:match[1],dynamic:!0};if(match=/^\[([A-Za-z_$][\w$]*)\]$/.exec(raw))return{form:"property",offset:1,name:match[1],dynamic:!0};if(raw.startsWith("."))return{form:"property",offset:1,name:raw.slice(1),dynamic:!0};if(raw.startsWith("bind:"))return{form:"property",offset:5,name:raw.slice(5).split("|")[0],dynamic:!0};for(const prefix of["v-bind:",":"])if(raw.startsWith(prefix))return{form:"member",offset:prefix.length,name:raw.slice(prefix.length).split(".")[0],dynamic:!0};if(!/^[A-Za-z][\w-]*$/.test(raw)||/^onlr-/.test(raw))return null;const dynamic=attribute.valueKind==="expression"||/\$\{|\{\{/.test(attribute.value??"");return{form:/[A-Z]/.test(raw)?"property":"attribute",offset:0,name:raw,dynamic}}function attributeEnd(text,attribute){if(attribute.valueEnd===null)return attribute.nameEnd;const quote=text[attribute.valueStart-1];return(quote==='"'||quote==="'")&&text[attribute.valueEnd]===quote?attribute.valueEnd+1:attribute.valueEnd}function boundMemberNames(attributes){const names=new Set;for(const attribute of attributes){const binding=markupMemberBinding(attribute);binding&&names.add(kebabCase(binding.name))}return names}function sortReportEntries(entries,codeKey){return entries.sort((left,right)=>left.line-right.line||left.column-right.column||String(left[codeKey]).localeCompare(String(right[codeKey])))}function reportModuleReviews(text,file,reviews,openingTokens,inComment,warn){if(!reviews.length)return;const packageName="@aceshooting/lyra-ui",specifierOf=subpath=>`${packageName}${subpath.slice(1)}`,named=reviews.filter(entry=>["function","type","constant","class"].includes(entry.kind)),report=(offset,review,context="")=>warn(offset,{member:review.name,code:"DEPRECATED_MODULE_REVIEW",target:review.replacement,message:`${context}${review.kind} ${review.module?`${review.module}#`:""}${review.name} ${review.removedIn?`was removed in ${review.removedIn}`:`is deprecated and scheduled for removal in ${review.removalNotBefore}`}; review ${review.replacement}.`}),namedFor=specifier=>named.filter(entry=>specifier===packageName||specifier===specifierOf(entry.module)),strings=quotedStringRanges(text,inComment),templates=templateLiteralRanges(text,inComment),stringStarts=new Set([...strings,...templates.filter(([start,end])=>!text.slice(start,end).includes("${"))].map(([start])=>start)),inString=rangeTester(strings),inLiteral=rangeTester(mergeRanges([...strings,...templates])),inCss=rangeTester(stylesheetRanges(text,file,inComment)),inMarkup=offset=>openingTokens.some(token=>offset>=token.nameEnd&&offset<token.end),opaque=(offset,specifier,entries)=>{entries.length&&warn(offset,{member:specifier,code:"MODULE_NAMESPACE_REVIEW",target:[...new Set(entries.map(entry=>entry.replacement))].join("; "),message:`Review the namespace or dynamic import of ${specifier} for deprecated exports ${entries.map(entry=>entry.name).join(", ")}. They cannot be safely renamed through aliases; the earliest removal is ${entries.map(entry=>entry.removalNotBefore).sort()[0]}.`})},bindings=/\b(?:import|export)\s+(?:type\s+)?(?:[$A-Z_a-z][$\w]*\s*,\s*)?\{(?<bindings>[^{};]*)\}\s*from\s*(?<quote>['"])(?<source>@aceshooting\/lyra-ui(?:\/[^'"\s]+)?)\k<quote>/g,handledSpecifiers=new Set;for(const match of text.matchAll(bindings)){if(inComment(match.index)||inLiteral(match.index))continue;const available=namedFor(match.groups.source),bodyStart=match.index+match[0].indexOf("{")+1;for(const binding of parseNamedModuleBindings(match.groups.bindings)){const review=available.find(entry=>entry.name===binding.imported);if(!review)continue;const member=[...match.groups.bindings.matchAll(new RegExp(`(?<![$\\w])${regexEscape(binding.imported)}(?![$\\w])`,"g"))].find(candidate=>!inComment(bodyStart+candidate.index));member&&report(bodyStart+member.index,review)}handledSpecifiers.add(match.index+match[0].lastIndexOf(match.groups.source)-1)}for(const match of text.matchAll(/(['"])(@aceshooting\/lyra-ui(?:\/[^'"\s]+)?)\1/g)){if(inComment(match.index))continue;const markup=inMarkup(match.index),css=inCss(match.index);if(!stringStarts.has(match.index)&&!markup&&!css)continue;const before=text.slice(Math.max(0,match.index-500),match.index),context=moduleSpecifierContext(text,match.index),cssImport=css&&/@import\s+(?:url\(\s*)?$/.test(before),resource=markup&&/\b(?:href|src)\s*=\s*$/.test(before);if(!context&&!cssImport&&!resource)continue;const specifier=match[2];for(const review of reviews)(review.kind==="entry-point"||review.kind==="stylesheet")&&specifier===specifierOf(review.name)&&report(match.index+1,review);if(handledSpecifiers.has(match.index)||!context||context.sideEffect)continue;const available=namedFor(specifier);if(context.kind==="binding"&&/\bexport\s+(?:type\s+)?\*\s*(?:as\s+[$A-Z_a-z][$\w]*\s*)?from\s*$/.test(before))for(const review of available)report(match.index+1,review,"This re-export includes ");else opaque(match.index+1,specifier,available)}for(const match of text.matchAll(/@import\s+url\(\s*(@aceshooting\/lyra-ui\/[^\s)'";]+)\s*\)/g))if(!(inComment(match.index)||!inCss(match.index)))for(const review of reviews)review.kind==="stylesheet"&&match[1]===specifierOf(review.name)&&report(match.index+match[0].indexOf(match[1]),review);for(const review of reviews)if(review.kind==="window-event")for(const match of text.matchAll(new RegExp(`(['"\\x60])(${regexEscape(review.name)})\\1`,"g"))){if(inComment(match.index))continue;const before=text.slice(Math.max(0,match.index-200),match.index);(LISTENER_CALL_BEFORE.test(before)||/\bnew\s+(?:CustomEvent|Event)\s*(?:<[^>\n]+>)?\(\s*$/.test(before))&&stringStarts.has(match.index)&&report(match.index+1,review)}else if(review.kind==="root-attribute"){const attributeOffsets=new Set;for(const token of openingTokens)for(const attribute of parseTagAttributes(text,token))attribute.rawName.replace(/^\[attr\.(.+)\]$/,"$1").replace(/^(?:v-bind:|bind:|[?:])/,"")===review.name&&!inString(attribute.nameStart)&&attributeOffsets.add(attribute.nameStart+attribute.rawName.indexOf(review.name));for(const match of text.matchAll(new RegExp(`(?<![\\w-])${regexEscape(review.name)}(?![\\w-])`,"g"))){if(inComment(match.index))continue;const offset=match.index,before=text.slice(Math.max(0,offset-180),offset),after=text.slice(offset+review.name.length),literalApi=/\b(?:getAttribute|setAttribute|hasAttribute|removeAttribute|toggleAttribute)\s*\(\s*['"`]$/.test(before),selector=/\[\s*$/.test(before)&&/^\s*(?:[~|^$*]?=|\])/.test(after),markup=attributeOffsets.has(offset);(literalApi&&stringStarts.has(offset-1)||selector&&(inCss(offset)||inString(offset))||markup)&&report(offset,review)}const datasetName=review.name.slice(5).replace(/-([a-z])/g,(_match,letter)=>letter.toUpperCase()),dataset=new RegExp(`\\bdataset\\s*(?:\\.\\s*${regexEscape(datasetName)}\\b|\\[\\s*(['"])${regexEscape(datasetName)}\\1\\s*\\])`,"g");for(const match of text.matchAll(dataset))!inComment(match.index)&&!inLiteral(match.index)&&report(match.index,review)}}const GLOBAL_REVIEW="GLOBAL_REVIEW",LYRA_PACKAGE="@aceshooting/lyra-ui",NODE_MODULES_LEAD=/(?:^|\/)node_modules\/$/,JSON_FILE=/\.json$/i,IDENTIFIER="[$A-Za-z_][$\\w]*";function applyGlobals(text,file,entries,{inComment,inCss,openingTokens,rewrite,warn}){const modules=entries.filter(entry=>entry.kind==="module"),exported=entries.filter(entry=>entry.kind==="export"),localeKeys=entries.filter(entry=>entry.kind==="locale-key"),review=(offset,entry,member,message)=>warn(offset,{member,code:GLOBAL_REVIEW,target:entry.to,message});if(modules.length){const inMarkup=offset=>openingTokens.some(token=>offset>=token.nameEnd&&offset<token.end),handle=(entry,specifierStart,specifier,safe)=>{safe?rewrite(specifierStart,specifierStart+entry.from.length,entry.to,{tag:null,member:specifier,action:"rewrite-module",target:entry.to,message:`Rewrite ${entry.from} to ${entry.to}: ${entry.summary}`}):review(specifierStart,entry,specifier,`${specifier} is not provably a module specifier here (or is computed): ${entry.summary} Use ${entry.to}${entry.prefix?"...":""} instead.`)},entryFor=specifier=>modules.find(entry=>entry.prefix?specifier.startsWith(entry.from)&&!(entry.except??[]).some(prefix=>specifier.startsWith(prefix)):specifier===entry.from);for(const match of text.matchAll(/(['"`])([^'"`\n]*?@aceshooting\/lyra-ui\/[^'"`\n]*)\1/g)){if(inComment(match.index))continue;const at=match[2].indexOf("@aceshooting/"),lead=match[2].slice(0,at);if(lead&&!NODE_MODULES_LEAD.test(lead))continue;const specifier=match[2].slice(at),entry=entryFor(specifier);if(!entry)continue;const specifierStart=match.index+1+at,before=text.slice(Math.max(0,match.index-500),match.index),context=moduleSpecifierContext(text,match.index),cssImport=inCss(match.index)&&/@import\s+(?:url\(\s*)?$/.test(before),resource=inMarkup(match.index)&&/\b(?:href|src)\s*=\s*$/.test(before),safe=!specifier.includes("${")&&!!(lead||JSON_FILE.test(file)||context||cssImport||resource);handle(entry,specifierStart,specifier,safe)}for(const match of text.matchAll(/@import\s+url\(\s*(@aceshooting\/lyra-ui\/[^\s)'";]+)\s*\)/g)){const entry=entryFor(match[1]);inComment(match.index)||!inCss(match.index)||!entry||handle(entry,match.index+match[0].indexOf(match[1]),match[1],!0)}}if(exported.length){const bindingsPattern=new RegExp(`\\b(?:import|export)\\s+(?:type\\s+)?(?:${IDENTIFIER}\\s*,\\s*)?\\{(?<body>[^{};]*)\\}\\s*from\\s*(?<quote>['"])(?<source>${regexEscape(LYRA_PACKAGE)}(?:\\/[^'"\\s]+)?)\\k<quote>`,"g"),segment=new RegExp(`^(\\s*(?:type\\s+)?)(${IDENTIFIER})(\\s+as\\s+${IDENTIFIER})?\\s*$`,"d");for(const match of text.matchAll(bindingsPattern)){if(inComment(match.index))continue;const bodyStart=match.index+match[0].indexOf("{")+1;for(const part of match.groups.body.matchAll(/[^,]+/g)){const parsed=segment.exec(part[0]),entry=parsed&&exported.find(candidate=>candidate.from===parsed[2]);if(!entry)continue;const nameStart=bodyStart+part.index+parsed.indices[2][0];inComment(nameStart)||(match.groups.source===LYRA_PACKAGE?rewrite(nameStart,nameStart+entry.from.length,parsed[3]?entry.to:`${entry.to} as ${entry.from}`,{tag:null,member:entry.from,action:"rewrite-export",target:entry.to,message:`${entry.from} no longer exists; import ${entry.to}${parsed[3]?"":` as ${entry.from}`}: ${entry.summary}`}):review(nameStart,entry,entry.from,`${entry.from} is not exported by ${match.groups.source} any more: ${entry.summary} Import ${entry.to} from ${LYRA_PACKAGE}.`))}}const receivers=[...[...text.matchAll(new RegExp(`import\\s+(?:type\\s+)?\\*\\s+as\\s+(${IDENTIFIER})\\s+from\\s*(['"])${regexEscape(LYRA_PACKAGE)}\\2`,"g"))].map(match=>match[1]).map(regexEscape),`import\\(\\s*['"]${regexEscape(LYRA_PACKAGE)}['"]\\s*\\)`];for(const entry of exported)for(const match of text.matchAll(new RegExp(`(?<![$\\w.])(?:${receivers.join("|")})\\s*\\.\\s*${entry.from}(?![$\\w])`,"g")))inComment(match.index)||review(match.index+match[0].lastIndexOf(entry.from),entry,entry.from,`${entry.from} no longer exists: ${entry.summary} Use ${entry.to}.`)}for(const entry of entries.filter(candidate=>candidate.kind==="css-property")){const pattern=new RegExp(`${regexEscape(entry.from)}${entry.prefix?"[\\w-]*":"(?![\\w-])"}`,"g");for(const match of text.matchAll(pattern))inComment(match.index)||review(match.index,entry,match[0],`The custom property ${match[0]} was removed: ${entry.summary} Use ${entry.to}.`)}const parts=entries.filter(candidate=>candidate.kind==="part");if(parts.length)for(const match of text.matchAll(/::part\(([^)]*)\)/g)){if(inComment(match.index))continue;const names=match[1].trim().split(/\s+/),type=compoundTypeBefore(text,match.index);for(const entry of parts)!names.includes(entry.from)||!(type===entry.tag||!type&&text.includes(entry.tag))||review(match.index+match[0].indexOf(entry.from),entry,entry.from,`The ${entry.tag} part ${entry.from} changed: ${entry.summary} ${entry.to}`)}if(localeKeys.length&&/registerLyraLocale|bridgeLyraLocale|\.strings\b|@aceshooting\/lyra-ui/.test(text))for(const entry of localeKeys)for(const match of text.matchAll(new RegExp(`(?<![$\\w.-])${entry.from}(?![$\\w-])`,"g"))){const before=text[match.index-1]??"",after=text.slice(match.index+entry.from.length,match.index+entry.from.length+12),quoted=/['"`]/.test(before)&&/^['"`]/.test(after);inComment(match.index)||!(quoted||/^\s*:/.test(after))||review(match.index,entry,entry.from,`The localization key ${entry.from} was removed; use ${entry.to}: ${entry.summary}`)}}function migrateRenameText(original,contract,options){const file=options.file??"<memory>",origin=options.origin,profile=contract.renameProfiles.get(origin);invariant(profile,`unknown migration origin ${String(origin)}`);const result={content:original,changes:[],warnings:[],acknowledged:0,usage:{webawesome:{automatic:0,manual:0},shoelace:{automatic:0,manual:0}},blockedMappings:new Set,blockedEcosystems:new Set,bareImportEcosystems:new Set,blockedLocalMigrations:new Set,constructedEvents:new Set};if(profile.isEmpty)return result;const starts=lineStarts(original),ignoredRanges=renameIgnoredRanges(original,file),inComment=rangeTester(ignoredRanges),openingTokens=scanAllOpeningTags(original,ignoredRanges,inComment),acknowledgements=scanReviewAcknowledgements(original,ignoredRanges,starts,openingTokens),litTemplates=LIT_TEMPLATE_FILE.test(file)?rangeTester(taggedTemplateRanges(original,["html","svg"],inComment)):()=>!1,inLiteral=rangeTester(mergeRanges([...quotedStringRanges(original,inComment),...templateLiteralRanges(original,inComment)])),inCss=rangeTester(stylesheetRanges(original,file,inComment)),attributeSemantics=offset=>ATTRIBUTE_SEMANTICS_FILE.test(file)||litTemplates(offset),release=`Lyra ${profile.toMajor}`,removal=`${profile.aliasRemovalMajor}.0.0`;for(const match of original.matchAll(EVENT_CONSTRUCTION))!inComment(match.index)&&profile.renamesNamed("event",match[2]).length&&result.constructedEvents.add(match[2]);const constructedEvents=new Set([...options.constructedEvents??[],...result.constructedEvents]),listenerIdentity=(quote,name)=>{const receiver=LISTENER_RECEIVER_BEFORE.exec(original.slice(Math.max(0,quote-200),quote))?.[1],handler=LISTENER_HANDLER_AFTER.exec(original.slice(quote+name.length+2,quote+name.length+202))?.[1];return receiver&&handler?`${receiver.replace(/\s+/g,"")}\0${handler.replace(/\s+/g,"")}`:null},listenedNames=new Map;if(profile.data.renames.some(entry=>entry.kind==="event"))for(const match of original.matchAll(/(['"`])(lr-[a-z0-9]+(?:-[a-z0-9]+)*)\1/g)){if(inComment(match.index)||!LISTENER_CALL_BEFORE.test(original.slice(Math.max(0,match.index-120),match.index)))continue;const identity=listenerIdentity(match.index,match[2]);identity&&listenedNames.set(identity,new Set([...listenedNames.get(identity)??[],match[2]]))}const sameHandlerListens=(quote,name)=>{if(!listenedNames.size)return!1;const names=listenedNames.get(listenerIdentity(quote,name));return!!names&&profile.renamesNamed("event",name).some(entry=>names.has(entry.to))},edits=[],seenWarnings=new Set,handledStrings=new Set,handledMembers=new Set,unique=values=>[...new Set(values)],list=values=>unique(values).join(", "),soleTag=entries=>unique(entries.map(entry=>entry.tag)).length===1?entries[0].tag:null,hint=(code,member)=>`After review, mark the site with a "lyra-migrate-reviewed: ${code}:${ackName(member)}" comment.`,rewrite=(start,end,replacement,{tag,member,action,target,message})=>{edits.push({start,end,replacement}),result.changes.push(reportEntry({textStarts:starts,file,offset:start,origin,upstreamTag:tag,upstreamMember:member,action,target,message}))},warn=(offset,{tag=null,member,code,target=null,message})=>{const key=`${offset}:${code}:${member}`;if(!seenWarnings.has(key)){if(seenWarnings.add(key),acknowledgements.consume(locationAt(starts,offset).line,code,member)){result.acknowledged+=1;return}result.warnings.push(reportEntry({textStarts:starts,file,offset,origin,upstreamTag:tag,upstreamMember:member,action:"manual-review",target,warningCode:code,message:`${message} ${hint(code,member)}`}))}},reviewMessage=review=>`${review.kind==="component"?`<${review.tag}>`:review.kind==="slot"&&review.name===""?`Content in the default slot of ${review.tag}`:`The ${review.tag} ${review.kind} ${review.name}`} ${review.removedIn?`was removed in ${review.removedIn}`:`is deprecated and scheduled for removal in ${review.removalNotBefore}`}; migrate to ${review.replacement} by hand.`,reportReview=(offset,review)=>warn(offset,{tag:review.tag,member:review.name,code:DEPRECATED_MEMBER_REVIEW,target:review.replacement,message:reviewMessage(review)}),reportPropertyChange=(offset,entry)=>warn(offset,{tag:entry.tag,member:entry.property,code:"PROPERTY_CHANGE_REVIEW",target:entry.property,message:`Review ${entry.tag}.${entry.property} for ${release}: ${entry.summary}`});if(reportModuleReviews(original,file,profile.data.moduleReviews,openingTokens,inComment,warn),applyGlobals(original,file,profile.data.globals,{inComment,inCss,openingTokens,rewrite,warn}),profile.data.rules.includes("theme-scopes")){const analysis=analyzeThemeScopes(original,{file});for(const{offset,change}of analysis.insertions)rewrite(offset,offset,analysis.marker,{tag:change.upstreamTag,member:change.upstreamMember,action:change.action,target:change.target,message:change.message});for(const entry of analysis.warnings)warn(starts[entry.line-1]+entry.column-1,{tag:entry.upstreamTag,member:entry.upstreamMember??entry.upstreamTag??entry.target,code:entry.warningCode,target:entry.target,message:entry.message})}const unownedReviews=(kind,name,offset,owner)=>{const own=owner?profile.reviewFor(owner,kind,name):null;if(own)reportReview(offset,own);else if(!profile.exposes(kind,name,owner))for(const review of profile.reviewsNamed(kind,name))reportReview(offset,review)},label=kind=>kind==="css-property"?"custom property":kind,detailNote=name=>{const details=profile.detailsNamed(name);return details.length?` Its ${release} detail also changed: ${details.map(entry=>`${entry.tag}: ${entry.summary}`).join(" ")}`:""},unownedMove=({kind,name,start,context,rewritable,action})=>{const renames=profile.renamesNamed(kind,name),targets=unique(renames.map(entry=>entry.to)),constructed=kind==="event"&&constructedEvents.has(name);if(rewritable&&!constructed&&profile.isGlobal(kind,name))return rewrite(start,start+name.length,targets[0],{tag:soleTag(renames),member:name,action,target:targets[0],message:`Rename ${name} to ${targets[0]}; every component exposing it renamed it, and no other component uses ${targets[0]}.`}),targets[0];const sourceKeepers=unique(targets.flatMap(to=>profile.sourceKeepers(kind,name,to))).filter(tag=>!renames.some(entry=>entry.tag===tag)),targetKeepers=unique(targets.flatMap(to=>profile.targetKeepers(kind,name,to))),shared=targets.length===1&&!sourceKeepers.length&&targetKeepers.length>0&&!renames.some(entry=>entry.polarity);return warn(start,{tag:soleTag(renames),member:name,code:shared?RENAME_TARGET_SHARED_REVIEW:RENAME_REVIEW,target:targets.join(" | "),message:(kind==="css-property"?"Custom properties inherit into nested components. ":context==="listener"?"This listener does not prove which element it listens to. ":"This string may name an event of any component. ")+`${list(renames.map(entry=>entry.tag))} renamed the ${label(kind)} ${name} to ${targets.join(" or ")}`+(sourceKeepers.length?`, while ${list(sourceKeepers)} still ${sourceKeepers.length===1?"uses":"use"} ${name}`:"")+(targetKeepers.length?`; ${list(targetKeepers)} already ${targetKeepers.length===1?"uses":"use"} ${targets.join(" and ")}, which this site would start reaching`:"")+(constructed?`; the scanned code also dispatches ${name} itself, so its listeners and dispatches must move together`:"")+`. Update it by hand for the components it is meant for; ${name} keeps working until ${removal}.`+(kind==="event"?detailNote(targets[0]):"")}),null},eventMove=(name,owner,rewritable=!0)=>{if(constructedEvents.has(name))return null;const own=owner?profile.renameFor(owner,"event",name):null;return own?profile.targetKeepers("event",name,own.to).length?null:own.to:!rewritable||!profile.renamesNamed("event",name).length||profile.exposes("event",name,owner)?null:profile.isGlobal("event",name)?profile.renamesNamed("event",name)[0].to:null},conflictMessage=(conflict,subject,to)=>conflict==="same-handler"?`${subject} already listens to ${to} with this same handler; renamed, the two identical registrations would collapse into one, so the handler would run once per activation instead of twice. Rename or remove this call, and its add or remove counterpart, together by hand.`:`${subject} already listens to ${to}; merge the two handlers by hand.`,eventSite=({name,start,owner,context,rewritable=!0,conflict=!1})=>{const retired=owner?profile.retiredEventFor(owner,name):null,retiredCandidates=retired?[retired]:profile.exposes("event",name,owner)?[]:profile.retiredEventsNamed(name);retiredCandidates.length&&warn(start,{tag:retired?owner:soleTag(retiredCandidates),member:name,code:"RETIRED_EVENT_REVIEW",target:unique(retiredCandidates.map(entry=>entry.replacement)).join(", "),message:`${name} is no longer dispatched by ${list(retiredCandidates.map(entry=>entry.tag))} in ${release}. `+retiredCandidates.map(entry=>`${entry.tag}: use ${entry.replacement}. ${entry.summary}`).join(" ")+" Review this listener and its matching removal together; keep unrelated events with the same spelling, check nested event targets, and merge any existing canonical listener without dropping or duplicating handler calls."});const own=owner?profile.renameFor(owner,"event",name):null;let current=name;if(own){const keepers=profile.targetKeepers("event",name,own.to);if(constructedEvents.has(name))warn(start,{tag:owner,member:name,code:RENAME_REVIEW,target:own.to,message:`Not renamed: the scanned code dispatches ${name} itself, so this listener would stop hearing it. Rename the dispatch and its listeners to ${own.to} together; ${name} keeps working until ${removal}.${detailNote(own.to)}`});else if(keepers.length)warn(start,{tag:owner,member:name,code:RENAME_TARGET_SHARED_REVIEW,target:own.to,message:`Not renamed: ${list(keepers)} also ${keepers.length===1?"dispatches":"dispatch"} ${own.to}, so this listener would start receiving their events when they are nested inside this ${owner}. Rename it by hand and ignore events whose target is not this ${owner}; ${name} keeps working until ${removal}.${detailNote(own.to)}`});else if(conflict)warn(start,{tag:owner,member:name,code:RENAME_CONFLICT_REVIEW,target:own.to,message:`${conflictMessage(conflict,`This ${owner}`,own.to)} ${name} keeps working until ${removal}.`});else{const narrowed=profile.sourceKeepers("event",name,own.to).filter(tag=>tag!==owner);rewrite(start,start+name.length,own.to,{tag:owner,member:name,action:"rewrite-event",target:own.to,message:`Rename the ${owner} event ${name} to ${own.to}.`+(narrowed.length?` ${list(narrowed)} still ${narrowed.length===1?"dispatches":"dispatch"} ${name}; this listener stops hearing theirs from nested elements.`:"")}),current=own.to}}else profile.renamesNamed("event",name).length&&!profile.exposes("event",name,owner)&&(conflict?warn(start,{tag:soleTag(profile.renamesNamed("event",name)),member:name,code:RENAME_CONFLICT_REVIEW,target:profile.renamesNamed("event",name)[0].to,message:conflictMessage(conflict,conflict==="same-handler"?"This receiver":"This element",profile.renamesNamed("event",name)[0].to)}):current=unownedMove({kind:"event",name,start,context,rewritable,action:"rewrite-event"})??name);const details=profile.detailsNamed(current),ownDetail=owner?profile.detailFor(owner,current):null;if(ownDetail||details.length&&!profile.exposes("event",current,owner)){const affected=ownDetail?[ownDetail]:details;warn(start,{tag:ownDetail?owner:soleTag(affected),member:current,code:DETAIL_SHAPE_REVIEW,target:current,message:`The ${current} event detail changed in ${release} and cannot be aliased: `+affected.map(entry=>`${entry.tag}: ${entry.summary}`).join(" ")+` Update this handler if it reads the detail of ${ownDetail?`the ${owner} event`:"one of these components"}.`})}const gained=current===name?profile.gainedOwners("event",name):[];gained.length&&!profile.exposes("event",name,owner)&&warn(start,{tag:soleTag(gained.map(tag=>({tag}))),member:name,code:NAME_GAINED_OWNER_REVIEW,target:name,message:`In ${release}, ${list(gained)} also ${gained.length===1?"dispatches":"dispatch"} ${name}. This ${context} does not prove which element it listens to, so it may start receiving those events; ignore them by event target if it should not.`}),unownedReviews("event",name,start,owner)},reportedDetailFieldOffsets=new Set,detailFieldAccess=/\b([A-Za-z_$][\w$]*)\s*(?:\?\.|\.)\s*detail\s*(?:\?\.|\.)\s*(open|collapsed)\b/g,reportDetailField=(field,start,owner=null,event=null)=>{if(reportedDetailFieldOffsets.has(start))return;const exact=owner&&event?profile.detailFieldFor(owner,event):null;if(exact&&exact.field===field){const target=exact.relation==="equal"?"detail.expanded":"!detail.expanded",relation=exact.relation==="equal"?"carries the same value as":"is the inverse of",removal2=exact.removedIn?` It was removed in ${exact.removedIn}.`:" This notice does not assert that the field was removed.";warn(start,{tag:owner,member:field,code:DETAIL_FIELD_REVIEW,target,message:`The ${owner} ${event} detail field ${field} is deprecated: it ${relation} detail.expanded (${exact.notice}). Read ${target} in this handler by hand; no field rewrite was applied.${removal2}`}),reportedDetailFieldOffsets.add(start);return}const candidates=event?profile.detailFieldsNamed(event).filter(entry=>entry.field===field):[],possible=candidates.length?candidates:(profile.data.detailFields??[]).filter(entry=>entry.field===field);if(!possible.length)return;const possibilities=[...new Set(possible.map(entry=>`${entry.tag}/${entry.event} (${entry.relation})`))];warn(start,{tag:null,member:field,code:DETAIL_FIELD_REVIEW,target:null,message:`This detail.${field} read has no proven Lyra tag and event. Matching published field contracts are ${possibilities.join(", ")}; identify the runtime detail type and migrate it by hand. No field rewrite was applied.`}),reportedDetailFieldOffsets.add(start)},inspectMarkupDetailFields=(owner,event,attribute)=>{if(attribute.valueStart===null||attribute.valueEnd===null)return;const value=original.slice(attribute.valueStart,attribute.valueEnd);for(const match of value.matchAll(detailFieldAccess)){const start=attribute.valueStart+match.index+match[0].lastIndexOf(match[2]);reportDetailField(match[2],start,owner,event)}};for(const token of openingTokens){const owner=token.tag.toLowerCase();for(const attribute of parseTagAttributes(original,token)){const event=markupEventName(attribute.rawName);event&&/^lr-/u.test(event.name)&&inspectMarkupDetailFields(owner,event.name,attribute)}}const memberSite=({owner,kind,name,start,forms,dynamic,removal:removalRange})=>{const propertyChange=forms.filter(([candidateKind])=>candidateKind==="property").map(([,candidate])=>profile.propertyChangeFor(owner,candidate)).find(Boolean);propertyChange&&reportPropertyChange(start,propertyChange);const review=forms.map(([candidateKind,candidate])=>profile.reviewFor(owner,candidateKind,candidate)).find(Boolean);review&&reportReview(start,review);const rule=forms.map(([candidateKind,candidate])=>profile.renameFor(owner,candidateKind,candidate)).find(Boolean);if(!rule)return null;if(rule.polarity==="inverted"&&(dynamic||!removalRange)){const target=kind==="binding"?memberStyle(name,rule.to):rule.to;return warn(start,{tag:owner,member:rule.from,code:POLARITY_REVIEW,target:rule.to,message:`${target} is the inverse of ${name} on ${owner}, and this ${kind==="binding"?"binding":kind==="property"?"property access":"attribute binding"} is not a static attribute. Bind the negated value to ${target} by hand; ${name} keeps working until ${removal}.`}),null}return rule},renamedMembers=owner=>unique([...profile.data.renames.filter(entry=>entry.tag===owner&&["attribute","property","event"].includes(entry.kind)).map(entry=>entry.from),...profile.data.reviews.filter(entry=>entry.tag===owner&&["attribute","property","event"].includes(entry.kind)).map(entry=>entry.name),...profile.data.retiredEvents.filter(entry=>entry.tag===owner).map(entry=>entry.event),...profile.data.propertyChanges.filter(entry=>entry.tag===owner).flatMap(entry=>[entry.property,...entry.former?[entry.former]:[]])]),defaultTokens=[];for(const token of openingTokens){const owner=token.tag.toLowerCase(),attributes=parseTagAttributes(original,token),lyraOwner=profile.tags.has(owner),bound=lyraOwner?boundMemberNames(attributes):null,finalNames=new Map,planned=attributes.map(attribute=>{const event=markupEventName(attribute.rawName);let finalRaw=attribute.rawName;if(event&&/^lr-/.test(event.name)){const to=eventMove(event.name,owner);to&&(finalRaw=attribute.rawName.slice(0,event.offset)+to+attribute.rawName.slice(event.offset+event.name.length))}else if(lyraOwner){const binding=markupMemberBinding(attribute),rule=binding&&!binding.form.startsWith("member")&&profile.renameFor(owner,binding.form,binding.name);rule&&!rule.polarity&&(finalRaw=attribute.rawName.slice(0,binding.offset)+rule.to+attribute.rawName.slice(binding.offset+binding.name.length))}const key=finalRaw.toLowerCase();return finalNames.set(key,(finalNames.get(key)??0)+1),{attribute,event,key,renamed:finalRaw!==attribute.rawName}});if(lyraOwner&&renamedMembers(owner).length)for(const group of openingTagBraceGroups(original,token)){const shorthand=/^[A-Za-z_$][\w$]*$/.exec(group.body)?.[0];if(!shorthand){warn(group.start,{tag:owner,member:owner,code:"DYNAMIC_VALUE_REVIEW",target:null,message:`This spread on ${owner} may carry renamed or deprecated members (${list(renamedMembers(owner))}); rename them where the object is built.`});continue}const forms=[["property",camelCase(shorthand)],["attribute",kebabCase(shorthand)]],review=forms.map(([kind,name])=>profile.reviewFor(owner,kind,name)).find(Boolean);review&&reportReview(group.start+1,review);const propertyChange=profile.propertyChangeFor(owner,camelCase(shorthand));propertyChange&&reportPropertyChange(group.start+1,propertyChange);const rule=forms.map(([kind,name])=>profile.renameFor(owner,kind,name)).find(Boolean);rule&&warn(group.start+1,{tag:owner,member:rule.from,code:rule.polarity?POLARITY_REVIEW:RENAME_REVIEW,target:rule.to,message:`The shorthand {${shorthand}} binds the deprecated ${owner} ${rule.kind} ${rule.from}; write ${memberStyle(shorthand,rule.to)}={${rule.polarity?`!${shorthand}`:shorthand}} by hand.`})}for(const{attribute,event,key,renamed}of planned){if(event){/^lr-/.test(event.name)&&(inspectMarkupDetailFields(owner,event.name,attribute),eventSite({name:event.name,start:attribute.nameStart+event.offset,owner,context:"listener",conflict:renamed&&finalNames.get(key)>1}));continue}if(!lyraOwner)continue;if(/^v-(?:bind|on)$/.test(attribute.rawName)||attribute.rawName.startsWith("${")&&!/^\$\{\s*ref\s*\(/.test(attribute.rawName)){renamedMembers(owner).length&&warn(attribute.nameStart,{tag:owner,member:owner,code:"DYNAMIC_VALUE_REVIEW",target:null,message:`This object binding on ${owner} may carry renamed or deprecated members (${list(renamedMembers(owner))}); rename them where the object is built.`});continue}if(attribute.rawName==="exportparts"){if(attribute.valueKind!=="literal"||/\$\{|\{\{/.test(attribute.value??""))continue;for(const match of(attribute.value??"").matchAll(/([^,\s:]+)(\s*:\s*[^,\s]+)?/g)){const inner=match[1],start2=attribute.valueStart+match.index,review=profile.reviewFor(owner,"part",inner);review&&reportReview(start2,review);const rule2=profile.renameFor(owner,"part",inner);rule2&&rewrite(start2,start2+inner.length,match[2]?rule2.to:`${rule2.to}:${inner}`,{tag:owner,member:inner,action:"rewrite-part",target:rule2.to,message:match[2]?`Forward the renamed ${owner} part ${rule2.to} under the same exported name.`:`Forward the renamed ${owner} part ${rule2.to} under its previous exported name ${inner}.`})}continue}const binding=markupMemberBinding(attribute);if(!binding)continue;const forms=binding.form==="member"?[["property",camelCase(binding.name)],["attribute",kebabCase(binding.name)]]:[[binding.form,binding.name]],start=attribute.nameStart+binding.offset,staticAttribute=binding.form==="attribute"&&binding.offset===0&&!binding.dynamic,rule=memberSite({owner,kind:binding.form==="member"?"binding":binding.form,name:binding.name,start,forms,dynamic:binding.dynamic,removal:staticAttribute});if(!rule)continue;if(bound.has(kebabCase(rule.to))||renamed&&finalNames.get(key)>1){warn(start,{tag:owner,member:rule.from,code:RENAME_CONFLICT_REVIEW,target:rule.to,message:`This ${owner} already binds ${rule.to}; remove the deprecated ${rule.from} binding by hand.`});continue}if(rule.polarity==="inverted"){if(!attributeSemantics(token.start)){warn(start,{tag:owner,member:rule.from,code:POLARITY_REVIEW,target:rule.to,message:`${rule.to} is the inverse of ${rule.from}. In this template syntax a static value may be assigned to the ${camelCase(rule.from)} property as a string, where "false" is truthy, so set ${rule.to} by hand.`});continue}if(profile.preservedDefaultsFor(owner).some(entry=>entry.attribute===rule.to&&entry.value===!0)){warn(start,{tag:owner,member:rule.from,code:POLARITY_REVIEW,target:rule.to,message:`${rule.from} has a preserved absent default, so removing an explicit attribute would let a later run insert ${rule.to}. Review this value using the old converter (a presence boolean treats even "false" as true), then migrate it by hand after the default migration is complete.`});continue}const value=attribute.value??"",end=attributeEnd(original,attribute);if(value===""||value==="true"||value===rule.from){let removeFrom=attribute.nameStart;for(;removeFrom>0&&/\s/.test(original[removeFrom-1]);)removeFrom-=1;rewrite(removeFrom,end,"",{tag:owner,member:rule.from,action:"remove-attribute",target:rule.to,message:`Remove ${rule.from}: it restated the ${owner} default, and ${rule.to} is off by default.`})}else value==="false"?rewrite(attribute.nameStart,end,rule.to,{tag:owner,member:rule.from,action:"rewrite-attribute",target:rule.to,message:`Replace ${rule.from}="false" with the presence of ${rule.to}.`}):warn(start,{tag:owner,member:rule.from,code:POLARITY_REVIEW,target:rule.to,message:`${rule.from}="${attribute.value}" is not a boolean literal; set ${rule.to} to its inverse by hand.`});continue}const target=binding.form==="member"?memberStyle(binding.name,rule.to):rule.to;rewrite(start,start+binding.name.length,target,{tag:owner,member:rule.from,action:`rewrite-${rule.kind}`,target:rule.to,message:`Rename the ${owner} ${rule.kind} ${rule.from} to ${rule.to}.`})}lyraOwner&&profile.defaultsFor(owner).length&&defaultTokens.push({token,owner,bound})}const slotTags=[...profile.tags].filter(tag=>profile.slotContentFor(tag).length||[...profile.data.renames,...profile.data.reviews].some(entry=>entry.tag===tag&&entry.kind==="slot"));for(const tag of slotTags)for(const pair of elementPairs(original,tag,inComment))for(const child of directChildTokens(original,pair.opening.end+1,pair.closingStart,inComment)){let slot="",start=child.nameStart;for(const attribute of parseTagAttributes(original,child))if(attribute.rawName==="slot")slot=attribute.valueKind==="literal"?attribute.value??"":null,start=attribute.valueStart??attribute.nameStart;else if(attribute.rawName==="v-slot")slot="";else{const prefix=["v-slot:","#"].find(candidate=>attribute.rawName.startsWith(candidate));prefix&&(slot=attribute.rawName.slice(prefix.length),start=attribute.nameStart+prefix.length,slot==="default"&&(slot=""))}if(slot===null)continue;const review=profile.reviewFor(tag,"slot",slot);review&&reportReview(start,review);const rule=slot===""?null:profile.renameFor(tag,"slot",slot);if(rule&&rewrite(start,start+slot.length,rule.to,{tag,member:slot,action:"rewrite-slot",target:rule.to,message:`Rename the ${tag} slot ${slot} to ${rule.to}.`}),child.tag!=="template")for(const content of profile.slotContentFor(tag)){if(content.slot!==slot)continue;const listed=(content.report??content.allow).includes(child.tag);(content.report?!listed:listed)||warn(child.nameStart,{tag,member:child.tag,code:DEPRECATED_CONTENT_REVIEW,target:null,message:`<${child.tag}> in ${slot===""?"the default slot":`the ${slot} slot`} of ${tag}: ${content.summary}`})}}for(const match of original.matchAll(/::part\(([^)]*)\)/g)){if(inComment(match.index))continue;const owner=compoundTypeBefore(original,match.index),listStart=match.index+7;for(const nameMatch of match[1].matchAll(/\S+/g)){const name=nameMatch[0],start=listStart+nameMatch.index,own=owner?profile.renameFor(owner,"part",name):null;if(own)rewrite(start,start+name.length,own.to,{tag:owner,member:name,action:"rewrite-part",target:own.to,message:`Rename the ${owner} part ${name} to ${own.to}.`});else if(profile.renamesNamed("part",name).length&&!profile.exposes("part",name,owner)){const renames=profile.renamesNamed("part",name),keepers=profile.exposers("part",name).filter(tag=>!renames.some(entry=>entry.tag===tag));warn(start,{tag:soleTag(renames),member:name,code:RENAME_REVIEW,target:list(renames.map(entry=>entry.to)),message:`This ::part() selector does not name the component that owns the part. ${list(renames.map(entry=>entry.tag))} renamed the part ${name} to ${list(renames.map(entry=>entry.to))}`+(keepers.length?`, while ${list(keepers)} still ${keepers.length===1?"exposes":"expose"} ${name}`:"")+". Rename it where the selector reaches a renamed component directly; a part forwarded through exportparts keeps its exported name."})}else if(profile.gainedOwners("part",name).length&&!owner?.startsWith("lr-")){const gained=profile.gainedOwners("part",name);warn(start,{tag:soleTag(gained.map(tag=>({tag}))),member:name,code:NAME_GAINED_OWNER_REVIEW,target:name,message:`In ${release}, ${list(gained)} also ${gained.length===1?"exposes":"expose"} the part ${name}, so this selector may start matching it.`})}unownedReviews("part",name,start,owner)}}const cssNames=new Set([...profile.data.renames.filter(entry=>entry.kind==="css-property").flatMap(entry=>[entry.from,entry.to]),...profile.data.reviews.filter(entry=>entry.kind==="css-property").map(entry=>entry.name)]);if(cssNames.size)for(const match of original.matchAll(/(?<![\w-])--[A-Za-z0-9_-]+/g)){const name=match[0];if(!cssNames.has(name)||inComment(match.index))continue;profile.renamesNamed("css-property",name).length&&unownedMove({kind:"css-property",name,start:match.index,context:"custom property",rewritable:!0,action:"rewrite-css-property"});const declaration=/^\s*['"]?\s*:/.test(original.slice(match.index+name.length,match.index+name.length+16))||/setProperty\s*\(\s*['"`]$/.test(original.slice(Math.max(0,match.index-24),match.index)),gained=profile.gainedOwners("css-property",name);declaration&&gained.length&&warn(match.index,{tag:soleTag(gained.map(tag=>({tag}))),member:name,code:NAME_GAINED_OWNER_REVIEW,target:name,message:`In ${release}, ${list(gained)} also ${gained.length===1?"reads":"read"} ${name}, so this declaration now reaches them when they are nested below it.`});for(const review of profile.reviewsNamed("css-property",name))reportReview(match.index,review)}for(const match of original.matchAll(/\[\s*([A-Za-z_][\w-]*)(?=\s*(?:[~|^$*]?=|\]))/g)){if(inComment(match.index))continue;const owner=compoundTypeBefore(original,match.index);if(!owner||!profile.tags.has(owner))continue;const name=match[1],start=match.index+match[0].length-name.length,review=profile.reviewFor(owner,"attribute",name);review&&reportReview(start,review);const rule=profile.renameFor(owner,"attribute",name);if(rule){if(rule.polarity==="inverted"){warn(start,{tag:owner,member:name,code:POLARITY_REVIEW,target:rule.to,message:`${rule.to} is the inverse of ${name}; rewrite this ${owner} selector to test the opposite state (for example :not([${rule.to}])).`});continue}if(!rule.reflects){warn(start,{tag:owner,member:name,code:RENAME_REVIEW,target:rule.to,message:`${owner} does not reflect ${rule.to}, so [${rule.to}] matches only where markup sets it. Rename this selector once every place that sets ${name} (markup, setAttribute) sets ${rule.to} instead.`});continue}rewrite(start,start+name.length,rule.to,{tag:owner,member:name,action:"rewrite-attribute",target:rule.to,message:`Rename the ${owner} attribute selector [${name}] to [${rule.to}]; ${owner} reflects ${rule.to}.`})}}for(const match of original.matchAll(/:state\(\s*([a-z][a-z0-9-]*)\s*\)/g)){if(inComment(match.index))continue;const owner=compoundTypeBefore(original,match.index),review=owner?profile.reviewFor(owner,"css-state",match[1]):null;review&&reportReview(match.index+match[0].indexOf(match[1]),review)}for(const review of profile.data.reviews.filter(entry=>entry.kind==="component"))for(const match of original.matchAll(new RegExp(`(?<![\\w-])${review.tag}(?![\\w-])`,"g")))inComment(match.index)||original.slice(match.index-2,match.index)==="</"||reportReview(match.index,review);const anchoredDetailListener=/(?:document\.)?querySelector\(\s*(['"])(lr-[a-z0-9-]+)\1\s*\)\s*!?\s*\.\s*addEventListener\(\s*(['"])(lr-[a-z0-9-]+)\3\s*,/g,unownedDetailListener=/[A-Za-z_$][\w$]*\s*\.\s*addEventListener\(\s*(['"])(lr-[a-z0-9-]+)\1\s*,/g,scriptListenerAt=offset=>{const start=Math.max(0,offset-4096),prefix=original.slice(start,offset);let result2=null;for(const pattern of[anchoredDetailListener,unownedDetailListener]){pattern.lastIndex=0;for(const match of prefix.matchAll(pattern)){const event=pattern===anchoredDetailListener?match[4]:match[2],callbackStart=match.index+match[0].length,callback=prefix.slice(callbackStart);!/=>|\bfunction\b/u.test(callback)||/\)\s*;/u.test(callback)||(!result2||match.index>=result2.index)&&(result2={owner:pattern===anchoredDetailListener?match[2]:null,event,index:match.index})}}return result2};for(const match of original.matchAll(detailFieldAccess)){const offset=match.index+match[0].lastIndexOf(match[2]);if(reportedDetailFieldOffsets.has(offset)||inComment(offset)||inLiteral(offset)||inCss(offset))continue;const listener=scriptListenerAt(offset);reportDetailField(match[2],offset,listener?.owner??null,listener?.event??null)}for(const match of original.matchAll(ANCHORED_MEMBER)){if(inComment(match.index))continue;const owner=match[2],member=match[3],start=match.index+match[0].length-member.length,after=start+member.length;if(handledMembers.add(start),LISTENER_METHODS.has(member)||ATTRIBUTE_METHODS.has(member)){const call=/^\s*\(\s*(['"`])([^'"`\n]+)\1/.exec(original.slice(after,after+200));if(!call)continue;const valueStart=after+call[0].length-1-call[2].length;if(handledStrings.add(valueStart-1),LISTENER_METHODS.has(member)){eventSite({name:call[2],start:valueStart,owner,context:"listener",conflict:sameHandlerListens(valueStart-1,call[2])&&"same-handler"});continue}const rule2=memberSite({owner,kind:"attribute",name:call[2],start:valueStart,forms:[["attribute",call[2]]],dynamic:!0});rule2&&rewrite(valueStart,valueStart+call[2].length,rule2.to,{tag:owner,member:rule2.from,action:"rewrite-attribute",target:rule2.to,message:`Rename the ${owner} attribute ${rule2.from} to ${rule2.to}.`});continue}if(!profile.tags.has(owner))continue;if(/^\s*\(/.test(original.slice(after,after+64))){const review=profile.reviewFor(owner,"method",member);review&&reportReview(start,review);continue}const rule=memberSite({owner,kind:"property",name:member,start,forms:[["property",member]],dynamic:!0});rule&&rewrite(start,after,rule.to,{tag:owner,member:rule.from,action:"rewrite-property",target:rule.to,message:`Rename the ${owner} property ${rule.from} to ${rule.to}.`})}const eventNameMatters=name=>profile.renamesNamed("event",name).length||profile.detailsNamed(name).length||profile.retiredEventsNamed(name).length||profile.reviewsNamed("event",name).length||profile.gainedOwners("event",name).length;for(const match of original.matchAll(/(['"`])(?:(window|document|body):)?(lr-[a-z0-9]+(?:-[a-z0-9]+)*)\1/g)){const name=match[3];if(handledStrings.has(match.index)||inComment(match.index)||!eventNameMatters(name))continue;const before=original.slice(Math.max(0,match.index-120),match.index);if(!match[2]&&TAG_API_CALL_BEFORE.test(before))continue;const listener=LISTENER_CALL_BEFORE.test(before);eventSite({name,start:match.index+1+(match[2]?match[2].length+1:0),owner:null,context:listener?"listener":"event name string",rewritable:listener,conflict:listener&&!match[2]&&sameHandlerListens(match.index,name)&&"same-handler"})}const mentioned=mentionedTags(original,profile.tags,inComment),accessRules=new Map,addAccess=(name,candidate)=>accessRules.set(name,[...accessRules.get(name)??[],candidate]);for(const entry of profile.data.renames)entry.kind==="property"&&mentioned.has(entry.tag)&&addAccess(entry.from,{tag:entry.tag,rule:entry,call:!1});for(const entry of profile.data.reviews)(entry.kind==="property"||entry.kind==="method")&&mentioned.has(entry.tag)&&addAccess(entry.name,{tag:entry.tag,review:entry,call:entry.kind==="method"});for(const entry of profile.data.propertyChanges)if(mentioned.has(entry.tag))for(const name of[entry.property,...entry.former?[entry.former]:[]])addAccess(name,{tag:entry.tag,propertyChange:entry,call:!1});if(accessRules.size){const inString=rangeTester(mergeRanges(quotedStringRanges(original,inComment))),inStylesheet=rangeTester(stylesheetRanges(original,file,inComment)),inToken=rangeTester(mergeRanges(openingTokens.map(token=>[token.start+1,token.end])));for(const match of original.matchAll(/(?<=[\w$)\]])\s*(?:\?\.|!?\.)\s*([A-Za-z_$][\w$]*)/g)){const name=match[1],candidates=accessRules.get(name);if(!candidates)continue;const start=match.index+match[0].length-name.length;if(handledMembers.has(start)||reportedDetailFieldOffsets.has(start)||inComment(start)||inString(start)||inStylesheet(start)||inToken(start))continue;const call=/^\s*\(/.test(original.slice(start+name.length,start+name.length+64));for(const candidate of candidates){if(candidate.call!==call)continue;if(candidate.propertyChange){reportPropertyChange(start,candidate.propertyChange);continue}if(candidate.review){reportReview(start,candidate.review);continue}const{rule}=candidate;warn(start,{tag:rule.tag,member:name,code:rule.polarity?POLARITY_REVIEW:RENAME_REVIEW,target:rule.to,message:`If this reads or writes an ${rule.tag}, ${rule.polarity?`use the inverse property .${rule.to}`:`rename .${name} to .${rule.to}`}; .${name} keeps working until ${removal}.`})}}}for(const match of original.matchAll(/\.\s*(?:set|get|has|remove|toggle)Attribute\s*\(\s*(['"`])([a-z][a-z0-9-]*)\1/g)){const name=match[2],start=match.index+match[0].length-1-name.length;if(!(handledStrings.has(start-1)||inComment(match.index)))for(const tag of mentioned){const review=profile.reviewFor(tag,"attribute",name);review&&reportReview(start,review);const rule=profile.renameFor(tag,"attribute",name);rule&&warn(start,{tag,member:name,code:rule.polarity?POLARITY_REVIEW:RENAME_REVIEW,target:rule.to,message:`If this element is an ${tag}, ${rule.polarity?`use the inverse attribute ${rule.to}`:`rename ${name} to ${rule.to}`}; ${name} keeps working until ${removal}.`})}}if(profile.data.defaults.length){const defaultProfiles=new Map([...new Set(profile.data.defaults.map(entry=>entry.tag))].map(tag=>[tag,{origin,tag,defaults:profile.defaultsFor(tag).map(entry=>({member:entry.attribute,value:entry.value}))}])),hazards=scanLocalMigrationHazards(original,defaultProfiles,ignoredRanges,defaultTokens.map(({token})=>({...token,tag:token.tag.toLowerCase()}))),blocked=new Set([...options.blockedLocalMigrations??[],...hazards.blocked]);result.blockedLocalMigrations=hazards.blocked;for(const use of hazards.uses)warn(use.offset,{tag:use.tag,member:use.tag,code:use.warningCode,target:use.tag,message:use.message});for(const{token,owner,bound}of defaultTokens){const missing=profile.defaultsFor(owner).filter(entry=>!profile.defaultAliasesFor(owner,entry.attribute).some(name=>bound.has(name)));if(!missing.length)continue;if(blocked.has(localMigrationKey(origin,owner))){warn(token.nameStart,{tag:owner,member:owner,code:"MAPPING_REVIEW_BLOCKED",target:owner,message:`${owner} did not receive its Lyra ${profile.fromMajor} defaults (${missing.map(entry=>`${entry.attribute}=${String(entry.value)}`).join(", ")}) because the scanned target set accesses it through a DOM alias or an opaque attribute spread. Add them by hand where the previous default matters.`});continue}const insertions=[];for(const entry of missing)insertions.push(serializeLocalDefault({member:entry.attribute,value:entry.value})),result.changes.push(reportEntry({textStarts:starts,file,offset:token.end,origin,upstreamTag:owner,upstreamMember:entry.attribute,action:"insert-default",target:`${entry.attribute}=${String(entry.value)}`,message:`Insert ${entry.attribute} to preserve the Lyra ${profile.fromMajor} default.`}));if(insertions.length){const insertionOffset=original[token.end-1]==="/"?token.end-1:token.end,replacement=/\s/.test(original[insertionOffset-1])?`${insertions.join(" ")} `:` ${insertions.join(" ")}`;edits.push({start:insertionOffset,end:insertionOffset,replacement})}}}if(!profile.skipped.length)for(const{offset,entry}of acknowledgements.unused()){const key=`${offset}:${UNUSED_ACKNOWLEDGEMENT}:${entry.token}`;seenWarnings.has(key)||(seenWarnings.add(key),result.warnings.push(reportEntry({textStarts:starts,file,offset,origin,upstreamTag:null,upstreamMember:entry.token,action:"manual-review",target:null,warningCode:UNUSED_ACKNOWLEDGEMENT,message:entry.code?`The acknowledgement ${entry.token} matches no report on the lines it covers; remove it.`:`The acknowledgement ${entry.token} is not of the form CODE:name, for example DETAIL_SHAPE_REVIEW:lr-close.`})))}return result.content=finalizeEdits(original,edits),sortReportEntries(result.changes,"action"),sortReportEntries(result.warnings,"warningCode"),result}export{migrateRenameText};
@@ -0,0 +1,3 @@
1
+ import{THEME_SCOPE_VOCABULARY}from"./theme-scope-vocabulary.generated.mjs";import{readDeclarations,splitTopLevel}from"./css-declarations.mjs";const THEME_SCOPE_RULE="theme-scopes",THEME_SCOPE_MARKER="data-lr-theme-scope",CONSUMED=new Set(THEME_SCOPE_VOCABULARY.consumedInputs),OUTPUTS=new Set(THEME_SCOPE_VOCABULARY.outputs),FEEDING=new Set(THEME_SCOPE_VOCABULARY.feedingOutputs),SCOPE_ATTRIBUTE=new RegExp(`(?:^|[\\s/])[?.:@]?(?:${THEME_SCOPE_VOCABULARY.scopeAttributes.join("|")})(?=[\\s=/>]|$)`),SCOPE_CLASS=new RegExp(`(?:^|[\\s"'\`{])(?:${THEME_SCOPE_VOCABULARY.scopeClasses.join("|")})(?=[\\s"'\`}]|$)`),MARKUP_EXTENSIONS=new Set(["html","htm","js","mjs","cjs","ts","mts","cts","jsx","tsx","vue","svelte","astro"]),CSS_EXTENSIONS=new Set(["css","scss","less","pcss","postcss"]),JSX_EXTENSIONS=new Set(["jsx","tsx"]),extensionOf=file=>/\.([a-z0-9]+)$/i.exec(file)?.[1]?.toLowerCase()??"";function lineColumn(text,offset){let line=1,lineStart=0;for(let index=text.indexOf(`
2
+ `);index!==-1&&index<offset;index=text.indexOf(`
3
+ `,index+1))line+=1,lineStart=index+1;return{line,column:offset-lineStart+1}}function*startTags(text){let index=0;for(;(index=text.indexOf("<",index))!==-1;){const name=/^<([a-zA-Z][\w:-]*)/.exec(text.slice(index,index+80));if(!name){index+=1;continue}let end=index+name[0].length,quote="",braces=0;for(;end<text.length;end++){const character=text[end];if(quote){character==="\\"?end+=1:character===quote&&(quote="");continue}if(braces){character==="{"?braces+=1:character==="}"?braces-=1:(character==='"'||character==="'"||character==="`")&&(quote=character);continue}if(character==='"'||character==="'")quote=character;else if(character==="{")braces=1;else if(character===">"||character==="<")break}if(text[end]!==">"){index+=1;continue}yield{start:index,tag:name[1],attributesStart:index+name[0].length,attributes:text.slice(index+name[0].length,end)},index=end+1}}function styleValue(attributes){const match=/(?:^|\s)[.:]?style\s*=\s*/.exec(attributes);if(!match)return null;const rest=attributes.slice(match.index+match[0].length),opener=rest[0];if(opener==='"'||opener==="'")return rest.slice(1,rest.indexOf(opener,1)===-1?void 0:rest.indexOf(opener,1));const start=opener==="$"&&rest[1]==="{"?2:opener==="{"?1:-1;if(start<0)return rest.split(/\s/)[0];let depth=1;for(let index=start;index<rest.length;index++)if(rest[index]==="{")depth+=1;else if(rest[index]==="}"&&--depth===0)return rest.slice(start,index);return rest.slice(start)}const declaredIn=value=>[...value.matchAll(/(--lr-(?:theme-)?[a-z0-9-]+)\s*['"`]?\s*:/g)].map(match=>match[1]),consumedIn=value=>[...new Set(declaredIn(value).filter(name=>CONSUMED.has(name)))],feedingIn=value=>[...new Set(declaredIn(value).filter(name=>FEEDING.has(name)))];function insideRepeat(text,offset){const before=text.slice(Math.max(0,offset-600),offset);return/\.map\(\s*(?:\([^)]*\)|[\w$]+)\s*=>|\brepeat\(|\bv-for=|\*ngFor=|\{#each\b|\.forEach\(/.test(before)}function selectorIsScope(selector){return isThemeScopeSelector(selector)}function withoutNegations(selector){let output="";for(let index=0;index<selector.length;index++){if(selector.startsWith(":not(",index)){let depth=0;for(index+=4;index<selector.length;index++)if(selector[index]==="(")depth+=1;else if(selector[index]===")"&&--depth===0)break;continue}output+=selector[index]}return output}function subjectCompound(selector){let depth=0,start=0;for(let index=0;index<selector.length;index++){const character=selector[index];character==="("||character==="["?depth+=1:character===")"||character==="]"?depth-=1:depth===0&&/[\s>+~]/.test(character)&&(start=index+1)}return selector.slice(start)}const SCOPE_FRAGMENTS=[":root","html",...THEME_SCOPE_VOCABULARY.scopeClasses.map(name=>`.${name}`),...THEME_SCOPE_VOCABULARY.scopeAttributes.map(name=>`[${name}`)];function isThemeScopeSelector(selector){const trimmed=withoutNegations(selector.trim()),subject=subjectCompound(trimmed);return SCOPE_FRAGMENTS.some(fragment=>subject.includes(fragment))?!0:/\.(?:light|dark)\b/.test(subject)&&trimmed.includes("[data-lr-look")}function cssReports(css,offset,text,file,warn){for(const declaration of readDeclarationsWithOffsets(css)){if(!declaration.selector)continue;const selectors=splitTopLevel(declaration.selector,",").map(selector=>selector.trim()).filter(selector=>!selectorIsScope(selector));if(!selectors.length)continue;const position=lineColumn(text,offset+declaration.offset);CONSUMED.has(declaration.property)?warn(position,{code:"THEME_SCOPE_CSS_INPUT_REVIEW",member:declaration.property,target:THEME_SCOPE_MARKER,message:`${selectors.join(", ")} sets ${declaration.property}, which the Lyra token layer consumes, but is not a theme scope: mark the matched elements with ${THEME_SCOPE_MARKER} (a :host or ::slotted() rule means the host or slotted element).`}):OUTPUTS.has(declaration.property)&&warn(position,{code:"THEME_SCOPE_OUTPUT_REVIEW",member:declaration.property,target:THEME_SCOPE_MARKER,message:FEEDING.has(declaration.property)?`${selectors.join(", ")} sets the shared output ${declaration.property}: it now reaches deeper (until the next theme scope), and the outputs derived from it no longer follow it. Set its --lr-theme-* input on a theme scope, or mark the element with ${THEME_SCOPE_MARKER}.`:`${selectors.join(", ")} sets the shared output ${declaration.property}: it now reaches deeper, until the next theme scope, instead of stopping at the first Lyra component.`})}}function readDeclarationsWithOffsets(css){const declarations=readDeclarations(css);let cursor=0;return declarations.map(declaration=>{const found=css.indexOf(declaration.property,cursor),offset=found===-1?cursor:found;return cursor=found===-1?cursor:found+declaration.property.length,{...declaration,offset}})}function analyzeThemeScopes(text,{file="input"}={}){const extension=extensionOf(file),warnings=[],marker=JSX_EXTENSIONS.has(extension)?` ${THEME_SCOPE_MARKER}=""`:` ${THEME_SCOPE_MARKER}`,warn=(position,{code,tag=null,member=null,target=null,message})=>warnings.push({file,...position,rule:THEME_SCOPE_RULE,upstreamTag:tag,upstreamMember:member,action:"manual-review",target,warningCode:code,message}),theme=/@aceshooting\/lyra-ui\/(?:dist\/)?theme\.css/.exec(text),tokensRoot=/@aceshooting\/lyra-ui\/(?:dist\/)?(?:styles\/)?tokens-root\.css/.exec(text);if(theme&&tokensRoot&&warn(lineColumn(text,tokensRoot.index),{code:"THEME_SCOPE_DOUBLE_LAYER_REVIEW",member:"tokens-root.css",message:"theme.css already carries the Lyra document token layer: remove the tokens-root.css import (it is the same layer alone, for pages without theme.css)."}),CSS_EXTENSIONS.has(extension))return cssReports(text,0,text,file,warn),{insertions:[],warnings,marker};if(!MARKUP_EXTENSIONS.has(extension)&&extension!=="")return{insertions:[],warnings,marker};const insertions=[];for(const tag of startTags(text)){const value=styleValue(tag.attributes);if(value===null)continue;const inputs=consumedIn(value),feeding=feedingIn(value);if(!inputs.length&&!feeding.length){/\.\.\.\s*[\w$.]+/.test(value)&&/style/.test(tag.attributes)&&warn(lineColumn(text,tag.start),{code:"THEME_SCOPE_DYNAMIC_INPUT_REVIEW",target:THEME_SCOPE_MARKER,message:`<${tag.tag}> spreads a style object; if it can carry a --lr-theme-* input the Lyra token layer consumes, mark the element with ${THEME_SCOPE_MARKER}.`});continue}if(/\sdata-lr-not-a-scope(?=[\s=>]|$)/.test(tag.attributes)||tag.tag.toLowerCase()==="html"||SCOPE_ATTRIBUTE.test(tag.attributes)||SCOPE_CLASS.test(classValue(tag.attributes)))continue;const position=lineColumn(text,tag.start),members=[...inputs,...feeding];insertions.push({offset:tag.attributesStart,change:{file,...position,rule:THEME_SCOPE_RULE,upstreamTag:tag.tag,upstreamMember:members.join(" "),action:"insert-theme-scope",target:THEME_SCOPE_MARKER,message:inputs.length?`Mark <${tag.tag}> with ${THEME_SCOPE_MARKER}: its inline ${inputs.join(", ")} must re-derive the Lyra token layer for the components below it.`:`Mark <${tag.tag}> with ${THEME_SCOPE_MARKER}: other shared outputs derive from its inline ${feeding.join(", ")}, and only a theme scope re-derives them.`}}),insideRepeat(text,tag.start)&&warn(position,{code:"THEME_SCOPE_REPEATED_REVIEW",tag:tag.tag,target:THEME_SCOPE_MARKER,message:`<${tag.tag}> is rendered in a loop: each instance is now a theme scope that re-derives the whole token layer. Prefer setting ${members.join(", ")} once on a common ancestor scope.`})}for(const match of text.matchAll(/\.setProperty\(\s*(['"`])(--lr-[a-z0-9-]+)\1/g))!CONSUMED.has(match[2])&&!FEEDING.has(match[2])||warn(lineColumn(text,match.index),{code:"THEME_SCOPE_DYNAMIC_INPUT_REVIEW",member:match[2],target:THEME_SCOPE_MARKER,message:CONSUMED.has(match[2])?`setProperty('${match[2]}') sets an input the Lyra token layer consumes: make sure the element is a theme scope (${THEME_SCOPE_MARKER}).`:`setProperty('${match[2]}') sets a shared output that other outputs derive from: they follow it only on a theme scope (${THEME_SCOPE_MARKER}).`});for(const match of text.matchAll(/\bcss`([^`]*)`/g))cssReports(match[1],match.index+4,text,file,warn);if(extension==="html"||extension==="htm"||extension==="vue"||extension==="svelte"||extension==="astro")for(const match of text.matchAll(/<style\b[^>]*>([\s\S]*?)<\/style>/gi))cssReports(match[1],match.index+match[0].indexOf(">")+1,text,file,warn);return{insertions,warnings,marker}}function migrateThemeScopes(text,{file="input"}={}){const{insertions,warnings,marker}=analyzeThemeScopes(text,{file});let content=text;for(const{offset}of[...insertions].sort((left,right)=>right.offset-left.offset))content=`${content.slice(0,offset)}${marker}${content.slice(offset)}`;return{content,changes:insertions.map(({change})=>change),warnings}}function classValue(attributes){const match=/(?:^|\s)[.:]?(?:class|className)\s*=\s*/.exec(attributes);return match?attributes.slice(match.index+match[0].length,match.index+match[0].length+400):""}export{THEME_SCOPE_RULE,analyzeThemeScopes,isThemeScopeSelector,migrateThemeScopes};
@@ -0,0 +1 @@
1
+ const THEME_SCOPE_VOCABULARY=Object.freeze({consumedInputs:["--lr-theme-border-radius-container","--lr-theme-border-radius-m","--lr-theme-border-radius-pill","--lr-theme-border-radius-xs","--lr-theme-border-width-medium","--lr-theme-border-width-thick","--lr-theme-border-width-thin","--lr-theme-color-border-strong","--lr-theme-color-brand-border-loud","--lr-theme-color-brand-border-normal","--lr-theme-color-brand-border-quiet","--lr-theme-color-brand-fill-loud","--lr-theme-color-brand-fill-normal","--lr-theme-color-brand-fill-quiet","--lr-theme-color-brand-on-loud","--lr-theme-color-brand-on-normal","--lr-theme-color-brand-on-quiet","--lr-theme-color-danger-border-loud","--lr-theme-color-danger-border-normal","--lr-theme-color-danger-border-quiet","--lr-theme-color-danger-fill-loud","--lr-theme-color-danger-fill-normal","--lr-theme-color-danger-fill-quiet","--lr-theme-color-danger-on-loud","--lr-theme-color-danger-on-normal","--lr-theme-color-danger-on-quiet","--lr-theme-color-focus","--lr-theme-color-mix-active","--lr-theme-color-mix-hover","--lr-theme-color-mix-partner","--lr-theme-color-neutral-border-loud","--lr-theme-color-neutral-border-normal","--lr-theme-color-neutral-border-quiet","--lr-theme-color-neutral-fill-loud","--lr-theme-color-neutral-fill-normal","--lr-theme-color-neutral-fill-quiet","--lr-theme-color-neutral-on-loud","--lr-theme-color-neutral-on-normal","--lr-theme-color-neutral-on-quiet","--lr-theme-color-no-data","--lr-theme-color-on-strong-overlay","--lr-theme-color-overlay","--lr-theme-color-overlay-strong","--lr-theme-color-shadow","--lr-theme-color-success-border-loud","--lr-theme-color-success-border-normal","--lr-theme-color-success-border-quiet","--lr-theme-color-success-fill-loud","--lr-theme-color-success-fill-normal","--lr-theme-color-success-fill-quiet","--lr-theme-color-success-on-loud","--lr-theme-color-success-on-normal","--lr-theme-color-success-on-quiet","--lr-theme-color-surface-border","--lr-theme-color-surface-border-subtle","--lr-theme-color-surface-container","--lr-theme-color-surface-container-high","--lr-theme-color-surface-container-highest","--lr-theme-color-surface-container-low","--lr-theme-color-surface-container-lowest","--lr-theme-color-surface-default","--lr-theme-color-surface-overlay","--lr-theme-color-surface-raised","--lr-theme-color-text-normal","--lr-theme-color-text-quiet","--lr-theme-color-warning-border-loud","--lr-theme-color-warning-border-normal","--lr-theme-color-warning-border-quiet","--lr-theme-color-warning-fill-loud","--lr-theme-color-warning-fill-normal","--lr-theme-color-warning-fill-quiet","--lr-theme-color-warning-on-loud","--lr-theme-color-warning-on-normal","--lr-theme-color-warning-on-quiet","--lr-theme-duration-fast","--lr-theme-duration-icon","--lr-theme-duration-normal","--lr-theme-duration-slow","--lr-theme-easing-emphasized","--lr-theme-easing-linear","--lr-theme-easing-standard","--lr-theme-focus-ring-offset","--lr-theme-focus-ring-width","--lr-theme-font-family-body","--lr-theme-font-family-heading","--lr-theme-font-family-mono","--lr-theme-font-size-2xl","--lr-theme-font-size-2xs","--lr-theme-font-size-3xl","--lr-theme-font-size-3xs","--lr-theme-font-size-lg","--lr-theme-font-size-m","--lr-theme-font-size-md-sm","--lr-theme-font-size-sm","--lr-theme-font-size-xl","--lr-theme-font-size-xs","--lr-theme-font-weight-bold","--lr-theme-font-weight-medium","--lr-theme-font-weight-normal","--lr-theme-font-weight-semibold","--lr-theme-hover-brightness","--lr-theme-line-break","--lr-theme-line-height-1-4","--lr-theme-line-height-compact","--lr-theme-line-height-loose","--lr-theme-line-height-none","--lr-theme-line-height-normal","--lr-theme-line-height-snug","--lr-theme-opacity-disabled","--lr-theme-opacity-muted","--lr-theme-otp-input-segment-size","--lr-theme-popover-viewport-clamp","--lr-theme-scroll-fade-size","--lr-theme-shadow-color","--lr-theme-shadow-l","--lr-theme-shadow-m","--lr-theme-shadow-s","--lr-theme-shadow-xl","--lr-theme-shadow-xs","--lr-theme-size-0-02em","--lr-theme-size-0-03em","--lr-theme-size-0-04em","--lr-theme-size-0-05rem","--lr-theme-size-0-0625rem","--lr-theme-size-0-09375rem","--lr-theme-size-0-125rem","--lr-theme-size-0-15rem","--lr-theme-size-0-1875rem","--lr-theme-size-0-1rem","--lr-theme-size-0-25rem","--lr-theme-size-0-3125rem","--lr-theme-size-0-35em","--lr-theme-size-0-375rem","--lr-theme-size-0-3em","--lr-theme-size-0-4375rem","--lr-theme-size-0-4em","--lr-theme-size-0-4rem","--lr-theme-size-0-5em","--lr-theme-size-0-5rem","--lr-theme-size-0-625rem","--lr-theme-size-0-6875rem","--lr-theme-size-0-6rem","--lr-theme-size-0-75em","--lr-theme-size-0-75rem","--lr-theme-size-0-7em","--lr-theme-size-0-875em","--lr-theme-size-0-8rem","--lr-theme-size-0-9375rem","--lr-theme-size-1-0625rem","--lr-theme-size-1-1rem","--lr-theme-size-1-25rem","--lr-theme-size-1-5em","--lr-theme-size-1-5rem","--lr-theme-size-1-75rem","--lr-theme-size-10px","--lr-theme-size-10rem","--lr-theme-size-12em","--lr-theme-size-12rem","--lr-theme-size-14px","--lr-theme-size-14rem","--lr-theme-size-15rem","--lr-theme-size-16px","--lr-theme-size-16rem","--lr-theme-size-18rem","--lr-theme-size-1em","--lr-theme-size-1px","--lr-theme-size-1rem","--lr-theme-size-2-25rem","--lr-theme-size-2-5ch","--lr-theme-size-2-5rem","--lr-theme-size-20rem","--lr-theme-size-22rem","--lr-theme-size-24px","--lr-theme-size-24rem","--lr-theme-size-280px","--lr-theme-size-28px","--lr-theme-size-28rem","--lr-theme-size-2px","--lr-theme-size-2rem","--lr-theme-size-3-5em","--lr-theme-size-3-5rem","--lr-theme-size-30rem","--lr-theme-size-32rem","--lr-theme-size-36rem","--lr-theme-size-38rem","--lr-theme-size-3ch","--lr-theme-size-3px","--lr-theme-size-3rem","--lr-theme-size-48rem","--lr-theme-size-4ch","--lr-theme-size-4px","--lr-theme-size-4rem","--lr-theme-size-5em","--lr-theme-size-5rem","--lr-theme-size-6ch","--lr-theme-size-6em","--lr-theme-size-6px","--lr-theme-size-6rem","--lr-theme-size-7rem","--lr-theme-size-8em","--lr-theme-size-8rem","--lr-theme-size-neg-0-15rem","--lr-theme-size-neg-0-25rem","--lr-theme-size-neg-1px","--lr-theme-size-neg-4px","--lr-theme-size-neg-6px","--lr-theme-size-neg-8px","--lr-theme-space-2xl","--lr-theme-space-2xs","--lr-theme-space-l","--lr-theme-space-m","--lr-theme-space-s","--lr-theme-space-xs","--lr-theme-table-row-height","--lr-theme-transition-fast","--lr-theme-transition-normal","--lr-theme-transition-slow","--lr-theme-word-break","--lr-theme-z-index-base","--lr-theme-z-index-content","--lr-theme-z-index-dropdown","--lr-theme-z-index-modal","--lr-theme-z-index-popover","--lr-theme-z-index-toast"],outputs:["--lr-border-width-medium","--lr-border-width-thick","--lr-border-width-thin","--lr-color-border","--lr-color-border-strong","--lr-color-border-subtle","--lr-color-brand","--lr-color-brand-border-loud","--lr-color-brand-border-normal","--lr-color-brand-border-quiet","--lr-color-brand-fill-loud","--lr-color-brand-fill-normal","--lr-color-brand-fill-quiet","--lr-color-brand-on-loud","--lr-color-brand-on-normal","--lr-color-brand-on-quiet","--lr-color-brand-quiet","--lr-color-danger","--lr-color-danger-border-loud","--lr-color-danger-border-normal","--lr-color-danger-border-quiet","--lr-color-danger-fill-loud","--lr-color-danger-fill-normal","--lr-color-danger-fill-quiet","--lr-color-danger-on-loud","--lr-color-danger-on-normal","--lr-color-danger-on-quiet","--lr-color-danger-quiet","--lr-color-mix-active","--lr-color-mix-hover","--lr-color-mix-partner","--lr-color-neutral","--lr-color-neutral-border-loud","--lr-color-neutral-border-normal","--lr-color-neutral-border-quiet","--lr-color-neutral-fill-loud","--lr-color-neutral-fill-normal","--lr-color-neutral-fill-quiet","--lr-color-neutral-on-loud","--lr-color-neutral-on-normal","--lr-color-neutral-on-quiet","--lr-color-no-data","--lr-color-on-brand","--lr-color-on-danger","--lr-color-on-neutral","--lr-color-on-strong-overlay","--lr-color-on-success","--lr-color-on-warning","--lr-color-overlay","--lr-color-overlay-strong","--lr-color-shadow","--lr-color-success","--lr-color-success-border-loud","--lr-color-success-border-normal","--lr-color-success-border-quiet","--lr-color-success-fill-loud","--lr-color-success-fill-normal","--lr-color-success-fill-quiet","--lr-color-success-on-loud","--lr-color-success-on-normal","--lr-color-success-on-quiet","--lr-color-success-quiet","--lr-color-surface","--lr-color-surface-container","--lr-color-surface-container-high","--lr-color-surface-container-highest","--lr-color-surface-container-low","--lr-color-surface-container-lowest","--lr-color-surface-overlay","--lr-color-surface-raised","--lr-color-text","--lr-color-text-quiet","--lr-color-warning","--lr-color-warning-border-loud","--lr-color-warning-border-normal","--lr-color-warning-border-quiet","--lr-color-warning-fill-loud","--lr-color-warning-fill-normal","--lr-color-warning-fill-quiet","--lr-color-warning-on-loud","--lr-color-warning-on-normal","--lr-color-warning-on-quiet","--lr-color-warning-quiet","--lr-duration-ambient","--lr-duration-base","--lr-duration-fast","--lr-duration-icon","--lr-easing-emphasized","--lr-easing-linear","--lr-easing-standard","--lr-focus-ring","--lr-focus-ring-color","--lr-focus-ring-offset","--lr-focus-ring-width","--lr-font","--lr-font-heading","--lr-font-mono","--lr-font-size-2xl","--lr-font-size-2xs","--lr-font-size-3xl","--lr-font-size-3xs","--lr-font-size-lg","--lr-font-size-m","--lr-font-size-md-sm","--lr-font-size-sm","--lr-font-size-xl","--lr-font-size-xs","--lr-font-weight-bold","--lr-font-weight-medium","--lr-font-weight-normal","--lr-font-weight-semibold","--lr-hover-brightness","--lr-layer-base","--lr-layer-content","--lr-layer-dropdown","--lr-layer-modal","--lr-layer-popover","--lr-layer-toast","--lr-line-break","--lr-line-height-1-4","--lr-line-height-compact","--lr-line-height-loose","--lr-line-height-none","--lr-line-height-normal","--lr-line-height-snug","--lr-mask-opaque","--lr-opacity-disabled","--lr-opacity-muted","--lr-otp-input-segment-size","--lr-popover-viewport-clamp","--lr-radius","--lr-radius-container","--lr-radius-pill","--lr-radius-xs","--lr-safe-area-bottom","--lr-safe-area-top","--lr-scroll-fade-size","--lr-shadow","--lr-shadow-color","--lr-shadow-l","--lr-shadow-m","--lr-shadow-s","--lr-shadow-xl","--lr-shadow-xs","--lr-size-0-02em","--lr-size-0-03em","--lr-size-0-04em","--lr-size-0-05rem","--lr-size-0-0625rem","--lr-size-0-09375rem","--lr-size-0-125rem","--lr-size-0-15rem","--lr-size-0-1875rem","--lr-size-0-1rem","--lr-size-0-25rem","--lr-size-0-3125rem","--lr-size-0-35em","--lr-size-0-375rem","--lr-size-0-3em","--lr-size-0-4375rem","--lr-size-0-4em","--lr-size-0-4rem","--lr-size-0-5em","--lr-size-0-5rem","--lr-size-0-625rem","--lr-size-0-6875rem","--lr-size-0-6rem","--lr-size-0-75em","--lr-size-0-75rem","--lr-size-0-7em","--lr-size-0-875em","--lr-size-0-8rem","--lr-size-0-9375rem","--lr-size-1-0625rem","--lr-size-1-1rem","--lr-size-1-25rem","--lr-size-1-5em","--lr-size-1-5rem","--lr-size-1-75rem","--lr-size-10px","--lr-size-10rem","--lr-size-12em","--lr-size-12rem","--lr-size-14px","--lr-size-14rem","--lr-size-15rem","--lr-size-16px","--lr-size-16rem","--lr-size-18rem","--lr-size-1em","--lr-size-1px","--lr-size-1rem","--lr-size-2-25rem","--lr-size-2-5ch","--lr-size-2-5rem","--lr-size-20rem","--lr-size-22rem","--lr-size-24px","--lr-size-24rem","--lr-size-280px","--lr-size-28px","--lr-size-28rem","--lr-size-2px","--lr-size-2rem","--lr-size-3-5em","--lr-size-3-5rem","--lr-size-30rem","--lr-size-32rem","--lr-size-36rem","--lr-size-38rem","--lr-size-3ch","--lr-size-3px","--lr-size-3rem","--lr-size-48rem","--lr-size-4ch","--lr-size-4px","--lr-size-4rem","--lr-size-5em","--lr-size-5rem","--lr-size-6ch","--lr-size-6em","--lr-size-6px","--lr-size-6rem","--lr-size-7rem","--lr-size-8em","--lr-size-8rem","--lr-size-neg-0-15rem","--lr-size-neg-0-25rem","--lr-size-neg-1px","--lr-size-neg-4px","--lr-size-neg-6px","--lr-size-neg-8px","--lr-space-2xl","--lr-space-2xs","--lr-space-l","--lr-space-m","--lr-space-s","--lr-space-xs","--lr-table-row-min-height","--lr-transition-ambient","--lr-transition-base","--lr-transition-fast","--lr-transition-interactive","--lr-word-break"],feedingOutputs:["--lr-color-border","--lr-color-brand","--lr-color-brand-fill-loud","--lr-color-brand-fill-quiet","--lr-color-brand-on-loud","--lr-color-danger","--lr-color-danger-fill-loud","--lr-color-danger-fill-quiet","--lr-color-danger-on-loud","--lr-color-neutral-fill-loud","--lr-color-neutral-on-loud","--lr-color-success-fill-loud","--lr-color-success-fill-quiet","--lr-color-success-on-loud","--lr-color-surface","--lr-color-surface-overlay","--lr-color-surface-raised","--lr-color-text","--lr-color-warning-fill-loud","--lr-color-warning-fill-quiet","--lr-color-warning-on-loud","--lr-focus-ring-color","--lr-focus-ring-width","--lr-radius","--lr-shadow-m","--lr-transition-fast"],scopeAttributes:["data-lr-theme","data-lr-theme-scope","data-lr-mode","data-lr-look","data-lr-accent","data-lr-density","data-lr-contrast","data-lr-motion","data-lr-design-token-mode"],scopeClasses:["lr-light","lr-dark","lr-token-light","lr-token-dark"]});export{THEME_SCOPE_VOCABULARY};
@@ -1,4 +1,4 @@
1
- import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property,query}from"lit/decorators.js";import{guard}from"lit/directives/guard.js";import{repeat}from"lit/directives/repeat.js";import{LyraElement}from"../../../internal/lyra-element.js";import{nextId}from"../../../internal/a11y.js";import{acquireResolvedAriaRelationship}from"../../../internal/aria-controls.js";import{applyComposedFocusRepair,captureComposedFocusRepair,repairComposedFocus}from"../../../internal/focus-navigation.js";import{chevronIcon}from"../../../internal/icons.js";import{formatTimeOfDay,getNumberFormat}from"../../../internal/intl-cache.js";import{finiteCount}from"../../../internal/numbers.js";import{styles}from"./activity-feed.styles.js";import{literalSetConverter,trueDefaultBooleanConverter}from"../../../internal/converters.js";import{firstByIdentityMemo}from"../collection-identity.js";import{LYRA_DEFAULT_activityFeedCompletedSteps,LYRA_DEFAULT_activityFeedLabel}from"../../../internal/default-strings.generated.js";const ACTIVITY_FEED_MODE=literalSetConverter(["live","post-hoc"],"live"),NEAR_BOTTOM_PX=48,entryId=entry=>entry.id;function variantDotPart(variant){return variant==="brand"?"variant-dot variant-dot-brand":variant==="success"?"variant-dot variant-dot-success":variant==="warning"?"variant-dot variant-dot-warning":variant==="danger"?"variant-dot variant-dot-danger":"variant-dot variant-dot-neutral"}class LyraActivityFeed extends LyraElement{constructor(){super(...arguments),this.entries=[],this._mode="live",this.follow=!0,this.expanded=!1,this.size="m",this.frame="card",this.withTimestamps=!1,this.virtualizeAt=199,this.headerId=nextId("activity-feed-header"),this.bodyId=nextId("activity-feed-body"),this.activityEntryKey=item=>item.id,this.isMounting=!0,this.anchoringVirtualTail=!1,this.ownerRealmGeneration=0,this.virtualAnchorRequest=0,this.relationshipSyncRequest=0,this.entryFocusRepairRequest=0,this.toggle=()=>{const expanded=!this.expanded;this.emit("lr-toggle-request",{expanded},{cancelable:!0}).defaultPrevented||(this.expanded=expanded,this.emit("lr-toggle",{expanded}))},this.onBodyScroll=e=>{if(this.isVirtualized||this.mode!=="live")return;const body=e.currentTarget,nearBottom=body.scrollHeight-body.scrollTop-body.clientHeight<=NEAR_BOTTOM_PX;this.setFollowFromUser(nearBottom)},this.onVirtualListRangeChanged=e=>{if(e.stopPropagation(),this.mode!=="live"||this.anchoringVirtualTail)return;const entries=this.normalizedEntries,atBottom=entries.length>0&&e.detail.end>=entries.length-1;this.setFollowFromUser(atBottom)},this.stopOwnedEvent=event=>{event.stopPropagation()}}static{this.defaultStrings={...super.defaultStrings,activityFeedCompletedSteps:LYRA_DEFAULT_activityFeedCompletedSteps,activityFeedLabel:LYRA_DEFAULT_activityFeedLabel}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["entries"])}static{this.identityCollectionProperties=Object.freeze(["entries"])}static{this.styles=[LyraElement.styles,styles]}get mode(){return this._mode}set mode(next){const normalized=ACTIVITY_FEED_MODE.normalizeReflected(this,"mode",next),old=this._mode;old!==normalized&&(this._mode=normalized,this.requestUpdate("mode",old))}connectedCallback(){super.connectedCallback(),this.hasUpdated&&(this.syncListRelationships(),this.scheduleListRelationshipSync()),this.hasUpdated&&this.shouldFollowLiveTail&&this.scrollToLatest()}disconnectedCallback(){this.releaseListRelationships(),this.resetOwnerRealmWork(),super.disconnectedCallback()}adoptedCallback(){super.adoptedCallback(),this.releaseListRelationships(),this.resetOwnerRealmWork(),this.isConnected&&this.hasUpdated&&(this.syncListRelationships(),this.scheduleListRelationshipSync()),this.isConnected&&this.shouldFollowLiveTail&&this.scrollToLatest()}get effectiveVirtualizeAt(){return finiteCount(this.virtualizeAt,199)}get normalizedEntries(){return firstByIdentityMemo(Array.isArray(this.entries)?this.entries:[],entryId)}get isVirtualized(){return this.normalizedEntries.length>this.effectiveVirtualizeAt}get shouldFollowLiveTail(){return this.expanded&&this.mode==="live"&&this.follow}cancelScrollFrame(){this.scrollRafId!==void 0&&this.scrollRafOwner?.cancelAnimationFrame(this.scrollRafId),this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0}cancelVirtualAnchorReleaseFrame(){this.virtualAnchorReleaseRafId!==void 0&&this.virtualAnchorReleaseRafOwner?.cancelAnimationFrame(this.virtualAnchorReleaseRafId),this.virtualAnchorReleaseRafId=void 0,this.virtualAnchorReleaseRafOwner=void 0,this.virtualAnchorReleaseRafDocument=void 0}resetOwnerRealmWork(){this.ownerRealmGeneration+=1,this.virtualAnchorRequest+=1,this.relationshipSyncRequest+=1,this.entryFocusRepairRequest+=1,this.pendingEntryFocusRepair=void 0,this.cancelScrollFrame(),this.cancelVirtualAnchorReleaseFrame(),this.anchoringVirtualTail=!1}willUpdate(changed){super.willUpdate(changed),(changed.has("expanded")||changed.has("mode"))&&this.expanded&&this.mode==="live"&&(this.follow=!0),changed.has("expanded")&&changed.get("expanded")===!0&&!this.expanded&&this.repairFocusOnCollapse(),changed.has("entries")&&this.captureEntryFocusRepair()}updated(changed){super.updated(changed),this.syncListRelationships(),this.scheduleListRelationshipSync();const wasMounting=this.isMounting;if(this.isMounting=!1,!wasMounting&&changed.has("mode")&&changed.get("mode")==="live"&&this.mode==="post-hoc"){const region=this.liveRegion;region&&(region.mode="polite",region.announce(this.completedStepsSummary(this.normalizedEntries.length),{force:!0}))}const justAnchored=(changed.has("expanded")||changed.has("mode"))&&this.expanded&&this.mode==="live",followingChangedRenderPath=changed.has("virtualizeAt")&&this.expanded&&this.mode==="live"&&this.follow;(justAnchored||followingChangedRenderPath||changed.has("entries")&&this.expanded&&this.mode==="live"&&this.follow)&&this.scrollToLatest(),changed.has("entries")&&this.pendingEntryFocusRepair&&this.settleEntryFocusRepair()}get headerElement(){return this.hasUpdated?this.renderRoot?.querySelector('[part="header"]')??null:null}repairFocusOnCollapse(){repairComposedFocus(this,()=>this.headerElement)}captureEntryFocusRepair(){this.pendingEntryFocusRepair=captureComposedFocusRepair(this,this.headerElement)??void 0}settleEntryFocusRepair(){const pending=this.pendingEntryFocusRepair;if(this.pendingEntryFocusRepair=void 0,!pending)return;const request=++this.entryFocusRepairRequest,generation=this.ownerRealmGeneration,settle=()=>{request!==this.entryFocusRepairRequest||generation!==this.ownerRealmGeneration||!this.isConnected||pending.activeElement.isConnected||applyComposedFocusRepair(pending,()=>this.headerElement)},list=this.virtualListEl;list?list.updateComplete.then(settle):settle()}scrollToLatest(){const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!ownerWindow||!this.isConnected||!this.shouldFollowLiveTail)return;const generation=this.ownerRealmGeneration;if(this.isVirtualized){this.cancelScrollFrame(),this.cancelVirtualAnchorReleaseFrame(),this.anchoringVirtualTail=!0;const request=++this.virtualAnchorRequest;this.updateComplete.then(()=>{const list=this.virtualListEl;if(request!==this.virtualAnchorRequest||generation!==this.ownerRealmGeneration||this.ownerDocument!==ownerDocument||!this.isConnected)return;if(!list||!this.isVirtualized||!this.shouldFollowLiveTail){this.anchoringVirtualTail=!1;return}list.scrollToIndex(this.normalizedEntries.length-1,{align:"end",behavior:"auto"});const firstHandle=ownerWindow.requestAnimationFrame(()=>{if(this.virtualAnchorReleaseRafId!==firstHandle||this.virtualAnchorReleaseRafOwner!==ownerWindow||this.virtualAnchorReleaseRafDocument!==ownerDocument||request!==this.virtualAnchorRequest||generation!==this.ownerRealmGeneration||!this.isConnected||this.ownerDocument!==ownerDocument)return;if(this.virtualAnchorReleaseRafId=void 0,this.virtualAnchorReleaseRafOwner=void 0,this.virtualAnchorReleaseRafDocument=void 0,!this.anchoringVirtualTail||!this.isVirtualized||!this.shouldFollowLiveTail){this.anchoringVirtualTail=!1;return}const secondHandle=ownerWindow.requestAnimationFrame(()=>{this.virtualAnchorReleaseRafId!==secondHandle||this.virtualAnchorReleaseRafOwner!==ownerWindow||this.virtualAnchorReleaseRafDocument!==ownerDocument||request!==this.virtualAnchorRequest||generation!==this.ownerRealmGeneration||!this.isConnected||this.ownerDocument!==ownerDocument||(this.virtualAnchorReleaseRafId=void 0,this.virtualAnchorReleaseRafOwner=void 0,this.virtualAnchorReleaseRafDocument=void 0,this.anchoringVirtualTail=!1)});this.virtualAnchorReleaseRafId=secondHandle,this.virtualAnchorReleaseRafOwner=ownerWindow,this.virtualAnchorReleaseRafDocument=ownerDocument});this.virtualAnchorReleaseRafId=firstHandle,this.virtualAnchorReleaseRafOwner=ownerWindow,this.virtualAnchorReleaseRafDocument=ownerDocument});return}if(this.virtualAnchorRequest+=1,this.cancelVirtualAnchorReleaseFrame(),this.anchoringVirtualTail=!1,this.scrollRafId!==void 0)return;const handle=ownerWindow.requestAnimationFrame(()=>{if(this.scrollRafId!==handle||this.scrollRafOwner!==ownerWindow||this.scrollRafDocument!==ownerDocument||generation!==this.ownerRealmGeneration||!this.isConnected||this.ownerDocument!==ownerDocument||(this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0,!this.shouldFollowLiveTail||this.isVirtualized))return;const body=this.renderRoot.querySelector('[part="body"]');body&&(body.scrollTop=body.scrollHeight)});this.scrollRafId=handle,this.scrollRafOwner=ownerWindow,this.scrollRafDocument=ownerDocument}completedStepsSummary(count){return this.localize("activityFeedCompletedSteps",void 0,{count:getNumberFormat(this.effectiveLocale).format(count),pluralCount:count})}get listSemanticOwner(){return this.isVirtualized?this.virtualListEl?.scrollContainer??null:this.renderRoot.querySelector('[part="body"][role="list"]')}syncListRelationships(){const target=this.listSemanticOwner;if(!target){this.releaseListRelationships();return}this.externalLabelledByLease?this.externalLabelledByLease.update(target):this.externalLabelledByLease=acquireResolvedAriaRelationship(this,target,"aria-labelledby"),this.externalDescribedByLease?this.externalDescribedByLease.update(target):this.externalDescribedByLease=acquireResolvedAriaRelationship(this,target,"aria-describedby")}scheduleListRelationshipSync(){const list=this.virtualListEl;if(!this.isVirtualized||!list||!this.isConnected){this.relationshipSyncRequest+=1;return}const request=++this.relationshipSyncRequest,ownerDocument=this.ownerDocument,generation=this.ownerRealmGeneration;list.updateComplete.then(()=>{request!==this.relationshipSyncRequest||generation!==this.ownerRealmGeneration||this.ownerDocument!==ownerDocument||!this.isConnected||!this.isVirtualized||this.virtualListEl!==list||this.syncListRelationships()})}releaseListRelationships(){this.externalLabelledByLease?.release(),this.externalLabelledByLease=void 0,this.externalDescribedByLease?.release(),this.externalDescribedByLease=void 0}setFollowFromUser(following){following!==this.follow&&(this.follow=following,this.emit("lr-follow-change",{following}))}normalizedTimestamp(value){if(value===void 0)return;const date=value instanceof Date?value:new Date(value);return Number.isNaN(date.getTime())?void 0:date}entryTemplate(entry,ownRole){const ts=this.normalizedTimestamp(entry.timestamp),formatter=this.formatTimestamp??(date=>formatTimeOfDay(date,this.effectiveLocale)),variant=entry.variant??"neutral",dotPart=variantDotPart(variant);return html`
1
+ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property,query}from"lit/decorators.js";import{guard}from"lit/directives/guard.js";import{repeat}from"lit/directives/repeat.js";import{LyraElement}from"../../../internal/lyra-element.js";import{nextId}from"../../../internal/a11y.js";import{acquireResolvedAriaRelationship}from"../../../internal/aria-controls.js";import{applyComposedFocusRepair,captureComposedFocusRepair,repairComposedFocus}from"../../../internal/focus-navigation.js";import{chevronIcon}from"../../../internal/icons.js";import{formatTimeOfDay,getNumberFormat}from"../../../internal/intl-cache.js";import{finiteCount}from"../../../internal/numbers.js";import{styles}from"./activity-feed.styles.js";import{literalSetConverter,trueDefaultBooleanConverter}from"../../../internal/converters.js";import{firstByIdentityMemo}from"../collection-identity.js";import{LYRA_DEFAULT_activityFeedCompletedSteps,LYRA_DEFAULT_activityFeedLabel}from"../../../internal/default-strings/agent-tools.generated.js";const ACTIVITY_FEED_MODE=literalSetConverter(["live","post-hoc"],"live"),NEAR_BOTTOM_PX=48,entryId=entry=>entry.id;function variantDotPart(variant){return variant==="brand"?"variant-dot variant-dot-brand":variant==="success"?"variant-dot variant-dot-success":variant==="warning"?"variant-dot variant-dot-warning":variant==="danger"?"variant-dot variant-dot-danger":"variant-dot variant-dot-neutral"}class LyraActivityFeed extends LyraElement{constructor(){super(...arguments),this.entries=[],this._mode="live",this.follow=!0,this.expanded=!1,this.size="m",this.frame="card",this.withTimestamps=!1,this.virtualizeAt=199,this.headerId=nextId("activity-feed-header"),this.bodyId=nextId("activity-feed-body"),this.activityEntryKey=item=>item.id,this.isMounting=!0,this.anchoringVirtualTail=!1,this.ownerRealmGeneration=0,this.virtualAnchorRequest=0,this.relationshipSyncRequest=0,this.entryFocusRepairRequest=0,this.toggle=()=>{const expanded=!this.expanded;this.emit("lr-toggle-request",{expanded},{cancelable:!0}).defaultPrevented||(this.expanded=expanded,this.emit("lr-toggle",{expanded}))},this.onBodyScroll=e=>{if(this.isVirtualized||this.mode!=="live")return;const body=e.currentTarget,nearBottom=body.scrollHeight-body.scrollTop-body.clientHeight<=NEAR_BOTTOM_PX;this.setFollowFromUser(nearBottom)},this.onVirtualListRangeChanged=e=>{if(e.stopPropagation(),this.mode!=="live"||this.anchoringVirtualTail)return;const entries=this.normalizedEntries,atBottom=entries.length>0&&e.detail.end>=entries.length-1;this.setFollowFromUser(atBottom)},this.stopOwnedEvent=event=>{event.stopPropagation()}}static{this.defaultStrings={...super.defaultStrings,activityFeedCompletedSteps:LYRA_DEFAULT_activityFeedCompletedSteps,activityFeedLabel:LYRA_DEFAULT_activityFeedLabel}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["entries"])}static{this.identityCollectionProperties=Object.freeze(["entries"])}static{this.styles=[LyraElement.styles,styles]}get mode(){return this._mode}set mode(next){const normalized=ACTIVITY_FEED_MODE.normalizeReflected(this,"mode",next),old=this._mode;old!==normalized&&(this._mode=normalized,this.requestUpdate("mode",old))}connectedCallback(){super.connectedCallback(),this.hasUpdated&&(this.syncListRelationships(),this.scheduleListRelationshipSync()),this.hasUpdated&&this.shouldFollowLiveTail&&this.scrollToLatest()}disconnectedCallback(){this.releaseListRelationships(),this.resetOwnerRealmWork(),super.disconnectedCallback()}adoptedCallback(){super.adoptedCallback(),this.releaseListRelationships(),this.resetOwnerRealmWork(),this.isConnected&&this.hasUpdated&&(this.syncListRelationships(),this.scheduleListRelationshipSync()),this.isConnected&&this.shouldFollowLiveTail&&this.scrollToLatest()}get effectiveVirtualizeAt(){return finiteCount(this.virtualizeAt,199)}get normalizedEntries(){return firstByIdentityMemo(Array.isArray(this.entries)?this.entries:[],entryId)}get isVirtualized(){return this.normalizedEntries.length>this.effectiveVirtualizeAt}get shouldFollowLiveTail(){return this.expanded&&this.mode==="live"&&this.follow}cancelScrollFrame(){this.scrollRafId!==void 0&&this.scrollRafOwner?.cancelAnimationFrame(this.scrollRafId),this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0}cancelVirtualAnchorReleaseFrame(){this.virtualAnchorReleaseRafId!==void 0&&this.virtualAnchorReleaseRafOwner?.cancelAnimationFrame(this.virtualAnchorReleaseRafId),this.virtualAnchorReleaseRafId=void 0,this.virtualAnchorReleaseRafOwner=void 0,this.virtualAnchorReleaseRafDocument=void 0}resetOwnerRealmWork(){this.ownerRealmGeneration+=1,this.virtualAnchorRequest+=1,this.relationshipSyncRequest+=1,this.entryFocusRepairRequest+=1,this.pendingEntryFocusRepair=void 0,this.cancelScrollFrame(),this.cancelVirtualAnchorReleaseFrame(),this.anchoringVirtualTail=!1}willUpdate(changed){super.willUpdate(changed),(changed.has("expanded")||changed.has("mode"))&&this.expanded&&this.mode==="live"&&(this.follow=!0),changed.has("expanded")&&changed.get("expanded")===!0&&!this.expanded&&this.repairFocusOnCollapse(),changed.has("entries")&&this.captureEntryFocusRepair()}updated(changed){super.updated(changed),this.syncListRelationships(),this.scheduleListRelationshipSync();const wasMounting=this.isMounting;if(this.isMounting=!1,!wasMounting&&changed.has("mode")&&changed.get("mode")==="live"&&this.mode==="post-hoc"){const region=this.liveRegion;region&&(region.mode="polite",region.announce(this.completedStepsSummary(this.normalizedEntries.length),{force:!0}))}const justAnchored=(changed.has("expanded")||changed.has("mode"))&&this.expanded&&this.mode==="live",followingChangedRenderPath=changed.has("virtualizeAt")&&this.expanded&&this.mode==="live"&&this.follow;(justAnchored||followingChangedRenderPath||changed.has("entries")&&this.expanded&&this.mode==="live"&&this.follow)&&this.scrollToLatest(),changed.has("entries")&&this.pendingEntryFocusRepair&&this.settleEntryFocusRepair()}get headerElement(){return this.hasUpdated?this.renderRoot?.querySelector('[part="header"]')??null:null}repairFocusOnCollapse(){repairComposedFocus(this,()=>this.headerElement)}captureEntryFocusRepair(){this.pendingEntryFocusRepair=captureComposedFocusRepair(this,this.headerElement)??void 0}settleEntryFocusRepair(){const pending=this.pendingEntryFocusRepair;if(this.pendingEntryFocusRepair=void 0,!pending)return;const request=++this.entryFocusRepairRequest,generation=this.ownerRealmGeneration,settle=()=>{request!==this.entryFocusRepairRequest||generation!==this.ownerRealmGeneration||!this.isConnected||pending.activeElement.isConnected||applyComposedFocusRepair(pending,()=>this.headerElement)},list=this.virtualListEl;list?list.updateComplete.then(settle):settle()}scrollToLatest(){const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!ownerWindow||!this.isConnected||!this.shouldFollowLiveTail)return;const generation=this.ownerRealmGeneration;if(this.isVirtualized){this.cancelScrollFrame(),this.cancelVirtualAnchorReleaseFrame(),this.anchoringVirtualTail=!0;const request=++this.virtualAnchorRequest;this.updateComplete.then(()=>{const list=this.virtualListEl;if(request!==this.virtualAnchorRequest||generation!==this.ownerRealmGeneration||this.ownerDocument!==ownerDocument||!this.isConnected)return;if(!list||!this.isVirtualized||!this.shouldFollowLiveTail){this.anchoringVirtualTail=!1;return}list.scrollToIndex(this.normalizedEntries.length-1,{align:"end",behavior:"auto"});const firstHandle=ownerWindow.requestAnimationFrame(()=>{if(this.virtualAnchorReleaseRafId!==firstHandle||this.virtualAnchorReleaseRafOwner!==ownerWindow||this.virtualAnchorReleaseRafDocument!==ownerDocument||request!==this.virtualAnchorRequest||generation!==this.ownerRealmGeneration||!this.isConnected||this.ownerDocument!==ownerDocument)return;if(this.virtualAnchorReleaseRafId=void 0,this.virtualAnchorReleaseRafOwner=void 0,this.virtualAnchorReleaseRafDocument=void 0,!this.anchoringVirtualTail||!this.isVirtualized||!this.shouldFollowLiveTail){this.anchoringVirtualTail=!1;return}const secondHandle=ownerWindow.requestAnimationFrame(()=>{this.virtualAnchorReleaseRafId!==secondHandle||this.virtualAnchorReleaseRafOwner!==ownerWindow||this.virtualAnchorReleaseRafDocument!==ownerDocument||request!==this.virtualAnchorRequest||generation!==this.ownerRealmGeneration||!this.isConnected||this.ownerDocument!==ownerDocument||(this.virtualAnchorReleaseRafId=void 0,this.virtualAnchorReleaseRafOwner=void 0,this.virtualAnchorReleaseRafDocument=void 0,this.anchoringVirtualTail=!1)});this.virtualAnchorReleaseRafId=secondHandle,this.virtualAnchorReleaseRafOwner=ownerWindow,this.virtualAnchorReleaseRafDocument=ownerDocument});this.virtualAnchorReleaseRafId=firstHandle,this.virtualAnchorReleaseRafOwner=ownerWindow,this.virtualAnchorReleaseRafDocument=ownerDocument});return}if(this.virtualAnchorRequest+=1,this.cancelVirtualAnchorReleaseFrame(),this.anchoringVirtualTail=!1,this.scrollRafId!==void 0)return;const handle=ownerWindow.requestAnimationFrame(()=>{if(this.scrollRafId!==handle||this.scrollRafOwner!==ownerWindow||this.scrollRafDocument!==ownerDocument||generation!==this.ownerRealmGeneration||!this.isConnected||this.ownerDocument!==ownerDocument||(this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0,!this.shouldFollowLiveTail||this.isVirtualized))return;const body=this.renderRoot.querySelector('[part="body"]');body&&(body.scrollTop=body.scrollHeight)});this.scrollRafId=handle,this.scrollRafOwner=ownerWindow,this.scrollRafDocument=ownerDocument}completedStepsSummary(count){return this.localize("activityFeedCompletedSteps",void 0,{count:getNumberFormat(this.effectiveLocale).format(count),pluralCount:count})}get listSemanticOwner(){return this.isVirtualized?this.virtualListEl?.scrollContainer??null:this.renderRoot.querySelector('[part="body"][role="list"]')}syncListRelationships(){const target=this.listSemanticOwner;if(!target){this.releaseListRelationships();return}this.externalLabelledByLease?this.externalLabelledByLease.update(target):this.externalLabelledByLease=acquireResolvedAriaRelationship(this,target,"aria-labelledby"),this.externalDescribedByLease?this.externalDescribedByLease.update(target):this.externalDescribedByLease=acquireResolvedAriaRelationship(this,target,"aria-describedby")}scheduleListRelationshipSync(){const list=this.virtualListEl;if(!this.isVirtualized||!list||!this.isConnected){this.relationshipSyncRequest+=1;return}const request=++this.relationshipSyncRequest,ownerDocument=this.ownerDocument,generation=this.ownerRealmGeneration;list.updateComplete.then(()=>{request!==this.relationshipSyncRequest||generation!==this.ownerRealmGeneration||this.ownerDocument!==ownerDocument||!this.isConnected||!this.isVirtualized||this.virtualListEl!==list||this.syncListRelationships()})}releaseListRelationships(){this.externalLabelledByLease?.release(),this.externalLabelledByLease=void 0,this.externalDescribedByLease?.release(),this.externalDescribedByLease=void 0}setFollowFromUser(following){following!==this.follow&&(this.follow=following,this.emit("lr-follow-change",{following}))}normalizedTimestamp(value){if(value===void 0)return;const date=value instanceof Date?value:new Date(value);return Number.isNaN(date.getTime())?void 0:date}entryTemplate(entry,ownRole){const ts=this.normalizedTimestamp(entry.timestamp),formatter=this.formatTimestamp??(date=>formatTimeOfDay(date,this.effectiveLocale)),variant=entry.variant??"neutral",dotPart=variantDotPart(variant);return html`
2
2
  <div part="entry" role=${ownRole?"listitem":nothing} data-variant=${variant}>
3
3
  <span part="entry-icon" aria-hidden="true"
4
4
  >${entry.icon?entry.icon:html`<span part=${dotPart} data-variant=${variant}></span>`}</span
@@ -1,4 +1,4 @@
1
- import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property}from"lit/decorators.js";import{repeat}from"lit/directives/repeat.js";import{LyraElement}from"../../../internal/lyra-element.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{formatShortDuration}from"../../../internal/duration.js";import{AGENT_STATUS_VARIANTS}from"../../../internal/agent-status-variants.js";import{styles}from"./agent-eval-dashboard.styles.js";import{finiteCount}from"../../../internal/numbers.js";import{agentStatusKind,agentStatusLabel,agentStatusMessage,agentStatusVariant}from"../agent-status-presentation.js";import{agentStatusText}from"../../../internal/agent-status-text.js";import{overallSemanticLabel}from"../semantic-owner.js";import{resolveHeadingLevel}from"../../../internal/heading-level.js";import{firstByIdentity}from"../collection-identity.js";import{AnnouncementSinkController}from"../../../internal/announcer.js";import{LYRA_DEFAULT_agentRunStatusCancelled,LYRA_DEFAULT_agentRunStatusCollecting,LYRA_DEFAULT_agentRunStatusDone,LYRA_DEFAULT_agentRunStatusIdle,LYRA_DEFAULT_agentRunStatusQueued,LYRA_DEFAULT_agentRunStatusWaitingApproval,LYRA_DEFAULT_agentRunStatusWaitingInput,LYRA_DEFAULT_chartValueLabel,LYRA_DEFAULT_collapse,LYRA_DEFAULT_copy,LYRA_DEFAULT_details,LYRA_DEFAULT_durationMilliseconds,LYRA_DEFAULT_durationSeconds,LYRA_DEFAULT_evaluationDashboardLabel,LYRA_DEFAULT_evaluationDashboardNoRuns,LYRA_DEFAULT_evaluationDashboardRunsLabel,LYRA_DEFAULT_loading,LYRA_DEFAULT_map,LYRA_DEFAULT_navigation,LYRA_DEFAULT_open,LYRA_DEFAULT_ragEvalDashboardRunsLimit,LYRA_DEFAULT_search,LYRA_DEFAULT_select,LYRA_DEFAULT_statusError,LYRA_DEFAULT_statusRunning}from"../../../internal/default-strings.generated.js";class LyraAgentEvalDashboard extends LyraElement{constructor(){super(...arguments),this.limitAnnouncements=new AnnouncementSinkController(this,{eager:["polite"]}),this.limitAnnouncementInitialized=!1,this.previouslyTruncated=!1,this.projectedRunsTruncated=!1,this.metrics=[],this.runs=[],this.metricId=null,this.currency="USD",this.headingLevel="2",this.withoutChart=!1,this.chartHeight="220px",this.maxRenderedRuns=100,this.metricsCache=[],this.runsCache=[],this.chartCache={labels:[],datasets:[]}}static{this.defaultStrings={...super.defaultStrings,agentRunStatusCancelled:LYRA_DEFAULT_agentRunStatusCancelled,agentRunStatusCollecting:LYRA_DEFAULT_agentRunStatusCollecting,agentRunStatusDone:LYRA_DEFAULT_agentRunStatusDone,agentRunStatusIdle:LYRA_DEFAULT_agentRunStatusIdle,agentRunStatusQueued:LYRA_DEFAULT_agentRunStatusQueued,agentRunStatusWaitingApproval:LYRA_DEFAULT_agentRunStatusWaitingApproval,agentRunStatusWaitingInput:LYRA_DEFAULT_agentRunStatusWaitingInput,chartValueLabel:LYRA_DEFAULT_chartValueLabel,collapse:LYRA_DEFAULT_collapse,copy:LYRA_DEFAULT_copy,details:LYRA_DEFAULT_details,durationMilliseconds:LYRA_DEFAULT_durationMilliseconds,durationSeconds:LYRA_DEFAULT_durationSeconds,evaluationDashboardLabel:LYRA_DEFAULT_evaluationDashboardLabel,evaluationDashboardNoRuns:LYRA_DEFAULT_evaluationDashboardNoRuns,evaluationDashboardRunsLabel:LYRA_DEFAULT_evaluationDashboardRunsLabel,loading:LYRA_DEFAULT_loading,map:LYRA_DEFAULT_map,navigation:LYRA_DEFAULT_navigation,open:LYRA_DEFAULT_open,ragEvalDashboardRunsLimit:LYRA_DEFAULT_ragEvalDashboardRunsLimit,search:LYRA_DEFAULT_search,select:LYRA_DEFAULT_select,statusError:LYRA_DEFAULT_statusError,statusRunning:LYRA_DEFAULT_statusRunning}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["metrics","runs"])}static{this.immutableEventDetails=Object.freeze(["lr-run-activate"])}static{this.styles=[LyraElement.styles,styles]}adoptedCallback(){super.adoptedCallback(),this.limitAnnouncements.adopted()}updated(changed){super.updated(changed),this.limitAnnouncementInitialized&&this.projectedRunsTruncated&&!this.previouslyTruncated&&this.limitAnnouncements.announcePolite(this.localize("ragEvalDashboardRunsLimit",void 0,{count:getNumberFormat(this.effectiveLocale).format(Math.max(1,finiteCount(this.maxRenderedRuns,100,500)))})),this.limitAnnouncementInitialized=!0,this.previouslyTruncated=this.projectedRunsTruncated}get normalizedMetrics(){return this.metricsFor!==this.metrics&&(this.metricsFor=this.metrics,this.metricsCache=firstByIdentity(Array.isArray(this.metrics)?this.metrics:[],metric=>metric.id)),this.metricsCache}get normalizedRuns(){return this.runsFor!==this.runs&&(this.runsFor=this.runs,this.runsCache=firstByIdentity(Array.isArray(this.runs)?this.runs:[],run=>run.id)),this.runsCache}chartInputs(runs,active){if(this.chartFor?.runs!==runs||this.chartFor.active!==active){this.chartFor={runs,active};const values=runs.map(run=>{const value=active?run.metrics?.[active.id]:void 0;return value!=null&&Number.isFinite(value)?value:null});this.chartCache={labels:runs.map(run=>run.label),datasets:active?[{label:active.label,data:values}]:[]}}return this.chartCache}get activeMetric(){const metrics=this.normalizedMetrics;return this.metricId===null?metrics[0]:metrics.find(metric=>metric.id===this.metricId)??metrics[0]}statusLabel(status){return agentStatusLabel(status)??agentStatusText(this.localize.bind(this),agentStatusKind(status))}formatMetric(metric,value=metric.value){const safe=Number.isFinite(value)?value:0;switch(metric.format){case"percent":return getNumberFormat(this.effectiveLocale,{style:"percent",maximumFractionDigits:1}).format(safe);case"milliseconds":return formatShortDuration(this.localize.bind(this),this.effectiveLocale,safe);case"currency":try{return getNumberFormat(this.effectiveLocale,{style:"currency",currency:this.currency,maximumFractionDigits:2}).format(safe)}catch{return getNumberFormat(this.effectiveLocale,{style:"currency",currency:"USD",maximumFractionDigits:2}).format(safe)}default:return getNumberFormat(this.effectiveLocale,{maximumFractionDigits:2}).format(safe)}}renderRuns(runs){if(!runs.length)return html`<p part="empty">${this.localize("evaluationDashboardNoRuns")}</p>`;const active=this.activeMetric,level=resolveHeadingLevel(this.headingLevel??"2"),runsLevel=level&&String(Math.min(6,Number(level)+1));return html`<section part="runs" aria-label=${this.localize("evaluationDashboardRunsLabel")}><div part="runs-heading" role=${runsLevel?"heading":nothing} aria-level=${runsLevel||nothing}>${this.localize("evaluationDashboardRunsLabel")}</div>${repeat(runs,run=>run.id,run=>{const kind=agentStatusKind(run.status),message=agentStatusMessage(run.status);return html`<button part="run" type="button" @click=${()=>this.emit("lr-run-activate",{runId:run.id,run})}><span part="run-label">${run.label}</span><span part="run-meta"><lr-badge part="run-status" variant=${agentStatusVariant(run.status,AGENT_STATUS_VARIANTS[kind]??"neutral")}>${this.statusLabel(run.status)}</lr-badge>${message!==void 0?html`<span part="run-status-message">${message}</span>`:nothing}${active&&run.metrics?.[active.id]!=null?html`<span>${this.formatMetric(active,run.metrics[active.id])}</span>`:nothing}</span></button>`})}</section>`}render(){const label=this.label==null?this.localize("evaluationDashboardLabel"):this.label,semanticLabel=overallSemanticLabel(this,label),active=this.activeMetric,allRuns=this.normalizedRuns,limit=Math.max(1,finiteCount(this.maxRenderedRuns,100,500));(this.slicedFor?.source!==allRuns||this.slicedFor.limit!==limit)&&(this.slicedFor={source:allRuns,limit,runs:allRuns.slice(0,limit)});const runs=this.slicedFor.runs;this.projectedRunsTruncated=allRuns.length>runs.length;const metrics=this.normalizedMetrics,level=resolveHeadingLevel(this.headingLevel??"2");return html`<section part="base" aria-label=${semanticLabel??nothing}>
1
+ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property}from"lit/decorators.js";import{repeat}from"lit/directives/repeat.js";import{LyraElement}from"../../../internal/lyra-element.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{formatShortDuration}from"../../../internal/duration.js";import{AGENT_STATUS_VARIANTS}from"../../../internal/agent-status-variants.js";import{styles}from"./agent-eval-dashboard.styles.js";import{finiteCount}from"../../../internal/numbers.js";import{agentStatusKind,agentStatusLabel,agentStatusMessage,agentStatusVariant}from"../agent-status-presentation.js";import{agentStatusText}from"../../../internal/agent-status-text.js";import{overallSemanticLabel}from"../semantic-owner.js";import{resolveHeadingLevel}from"../../../internal/heading-level.js";import{firstByIdentity}from"../collection-identity.js";import{AnnouncementSinkController}from"../../../internal/announcer.js";import{LYRA_DEFAULT_agentRunStatusCancelled,LYRA_DEFAULT_agentRunStatusCollecting,LYRA_DEFAULT_agentRunStatusDone,LYRA_DEFAULT_agentRunStatusIdle,LYRA_DEFAULT_agentRunStatusQueued,LYRA_DEFAULT_agentRunStatusWaitingApproval,LYRA_DEFAULT_agentRunStatusWaitingInput,LYRA_DEFAULT_evaluationDashboardLabel,LYRA_DEFAULT_evaluationDashboardNoRuns,LYRA_DEFAULT_evaluationDashboardRunsLabel}from"../../../internal/default-strings/agent-tools.generated.js";import{LYRA_DEFAULT_chartValueLabel,LYRA_DEFAULT_collapse,LYRA_DEFAULT_copy,LYRA_DEFAULT_date,LYRA_DEFAULT_details,LYRA_DEFAULT_durationMilliseconds,LYRA_DEFAULT_durationSeconds,LYRA_DEFAULT_loading,LYRA_DEFAULT_map,LYRA_DEFAULT_navigation,LYRA_DEFAULT_open,LYRA_DEFAULT_ragEvalDashboardRunsLimit,LYRA_DEFAULT_search,LYRA_DEFAULT_select,LYRA_DEFAULT_statusError,LYRA_DEFAULT_statusRunning}from"../../../internal/default-strings/shared.generated.js";class LyraAgentEvalDashboard extends LyraElement{constructor(){super(...arguments),this.limitAnnouncements=new AnnouncementSinkController(this,{eager:["polite"]}),this.limitAnnouncementInitialized=!1,this.previouslyTruncated=!1,this.projectedRunsTruncated=!1,this.metrics=[],this.runs=[],this.metricId=null,this.currency="USD",this.headingLevel="2",this.withoutChart=!1,this.chartHeight="220px",this.maxRenderedRuns=100,this.metricsCache=[],this.runsCache=[],this.chartCache={labels:[],datasets:[]}}static{this.defaultStrings={...super.defaultStrings,agentRunStatusCancelled:LYRA_DEFAULT_agentRunStatusCancelled,agentRunStatusCollecting:LYRA_DEFAULT_agentRunStatusCollecting,agentRunStatusDone:LYRA_DEFAULT_agentRunStatusDone,agentRunStatusIdle:LYRA_DEFAULT_agentRunStatusIdle,agentRunStatusQueued:LYRA_DEFAULT_agentRunStatusQueued,agentRunStatusWaitingApproval:LYRA_DEFAULT_agentRunStatusWaitingApproval,agentRunStatusWaitingInput:LYRA_DEFAULT_agentRunStatusWaitingInput,chartValueLabel:LYRA_DEFAULT_chartValueLabel,collapse:LYRA_DEFAULT_collapse,copy:LYRA_DEFAULT_copy,date:LYRA_DEFAULT_date,details:LYRA_DEFAULT_details,durationMilliseconds:LYRA_DEFAULT_durationMilliseconds,durationSeconds:LYRA_DEFAULT_durationSeconds,evaluationDashboardLabel:LYRA_DEFAULT_evaluationDashboardLabel,evaluationDashboardNoRuns:LYRA_DEFAULT_evaluationDashboardNoRuns,evaluationDashboardRunsLabel:LYRA_DEFAULT_evaluationDashboardRunsLabel,loading:LYRA_DEFAULT_loading,map:LYRA_DEFAULT_map,navigation:LYRA_DEFAULT_navigation,open:LYRA_DEFAULT_open,ragEvalDashboardRunsLimit:LYRA_DEFAULT_ragEvalDashboardRunsLimit,search:LYRA_DEFAULT_search,select:LYRA_DEFAULT_select,statusError:LYRA_DEFAULT_statusError,statusRunning:LYRA_DEFAULT_statusRunning}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["metrics","runs"])}static{this.immutableEventDetails=Object.freeze(["lr-run-activate"])}static{this.styles=[LyraElement.styles,styles]}adoptedCallback(){super.adoptedCallback(),this.limitAnnouncements.adopted()}updated(changed){super.updated(changed),this.limitAnnouncementInitialized&&this.projectedRunsTruncated&&!this.previouslyTruncated&&this.limitAnnouncements.announcePolite(this.localize("ragEvalDashboardRunsLimit",void 0,{count:getNumberFormat(this.effectiveLocale).format(Math.max(1,finiteCount(this.maxRenderedRuns,100,500)))})),this.limitAnnouncementInitialized=!0,this.previouslyTruncated=this.projectedRunsTruncated}get normalizedMetrics(){return this.metricsFor!==this.metrics&&(this.metricsFor=this.metrics,this.metricsCache=firstByIdentity(Array.isArray(this.metrics)?this.metrics:[],metric=>metric.id)),this.metricsCache}get normalizedRuns(){return this.runsFor!==this.runs&&(this.runsFor=this.runs,this.runsCache=firstByIdentity(Array.isArray(this.runs)?this.runs:[],run=>run.id)),this.runsCache}chartInputs(runs,active){if(this.chartFor?.runs!==runs||this.chartFor.active!==active){this.chartFor={runs,active};const values=runs.map(run=>{const value=active?run.metrics?.[active.id]:void 0;return value!=null&&Number.isFinite(value)?value:null});this.chartCache={labels:runs.map(run=>run.label),datasets:active?[{label:active.label,data:values}]:[]}}return this.chartCache}get activeMetric(){const metrics=this.normalizedMetrics;return this.metricId===null?metrics[0]:metrics.find(metric=>metric.id===this.metricId)??metrics[0]}statusLabel(status){return agentStatusLabel(status)??agentStatusText(this.localize.bind(this),agentStatusKind(status))}formatMetric(metric,value=metric.value){const safe=Number.isFinite(value)?value:0;switch(metric.format){case"percent":return getNumberFormat(this.effectiveLocale,{style:"percent",maximumFractionDigits:1}).format(safe);case"milliseconds":return formatShortDuration(this.localize.bind(this),this.effectiveLocale,safe);case"currency":try{return getNumberFormat(this.effectiveLocale,{style:"currency",currency:this.currency,maximumFractionDigits:2}).format(safe)}catch{return getNumberFormat(this.effectiveLocale,{style:"currency",currency:"USD",maximumFractionDigits:2}).format(safe)}default:return getNumberFormat(this.effectiveLocale,{maximumFractionDigits:2}).format(safe)}}renderRuns(runs){if(!runs.length)return html`<p part="empty">${this.localize("evaluationDashboardNoRuns")}</p>`;const active=this.activeMetric,level=resolveHeadingLevel(this.headingLevel??"2"),runsLevel=level&&String(Math.min(6,Number(level)+1));return html`<section part="runs" aria-label=${this.localize("evaluationDashboardRunsLabel")}><div part="runs-heading" role=${runsLevel?"heading":nothing} aria-level=${runsLevel||nothing}>${this.localize("evaluationDashboardRunsLabel")}</div>${repeat(runs,run=>run.id,run=>{const kind=agentStatusKind(run.status),message=agentStatusMessage(run.status);return html`<button part="run" type="button" @click=${()=>this.emit("lr-run-activate",{runId:run.id,run})}><span part="run-label">${run.label}</span><span part="run-meta"><lr-badge part="run-status" variant=${agentStatusVariant(run.status,AGENT_STATUS_VARIANTS[kind]??"neutral")}>${this.statusLabel(run.status)}</lr-badge>${message!==void 0?html`<span part="run-status-message">${message}</span>`:nothing}${active&&run.metrics?.[active.id]!=null?html`<span>${this.formatMetric(active,run.metrics[active.id])}</span>`:nothing}</span></button>`})}</section>`}render(){const label=this.label==null?this.localize("evaluationDashboardLabel"):this.label,semanticLabel=overallSemanticLabel(this,label),active=this.activeMetric,allRuns=this.normalizedRuns,limit=Math.max(1,finiteCount(this.maxRenderedRuns,100,500));(this.slicedFor?.source!==allRuns||this.slicedFor.limit!==limit)&&(this.slicedFor={source:allRuns,limit,runs:allRuns.slice(0,limit)});const runs=this.slicedFor.runs;this.projectedRunsTruncated=allRuns.length>runs.length;const metrics=this.normalizedMetrics,level=resolveHeadingLevel(this.headingLevel??"2");return html`<section part="base" aria-label=${semanticLabel??nothing}>
2
2
  ${label===""?nothing:html`<div part="heading" role=${level?"heading":nothing} aria-level=${level??nothing}>${label}</div>`}
3
3
  ${metrics.length?html`<div part="metrics">${repeat(metrics,metric=>metric.id,metric=>{const value=this.formatMetric(metric);return html`<button
4
4
  part="metric"
@@ -1,4 +1,4 @@
1
- import{__decorate}from"tslib";import{eventCollectionSupport}from"../../../internal/collection-snapshot.js";import{tag}from"../../../internal/prefix.js";import{html,nothing}from"lit";import{property}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{literalSetConverter}from"../../../internal/converters.js";import{snapshotFormValue}from"../tool-param-form/tool-param-snapshot.js";import{styles}from"./agent-question.styles.js";import{agentActionButtonStyles}from"../agent-action-button.styles.js";import{resolveHeadingLevel}from"../../../internal/heading-level.js";import{LYRA_DEFAULT_agentQuestionAccept,LYRA_DEFAULT_agentQuestionDecline,LYRA_DEFAULT_agentQuestionLabel,LYRA_DEFAULT_agentQuestionSubmitted,LYRA_DEFAULT_agentQuestionUnsupported,LYRA_DEFAULT_cancel}from"../../../internal/default-strings.generated.js";const QUESTION_STATUS=literalSetConverter(["pending","submitted"],"pending"),SCHEMA_KEYS=new Set(["type","properties","required","$schema"]),PROPERTY_KEYS=new Set(["type","enum","description","title","default","const","autocomplete","spellcheck","autocapitalize","autoCorrect","inputMode","enterKeyHint","minLength","maxLength","format","minimum","maximum","minItems","maxItems","oneOf","enumNames","items"]);class LyraAgentQuestion extends LyraElement{constructor(){super(...arguments),this.requestId="",this.requester="",this.message="",this.headingLevel="2",this._schema=Object.freeze({type:"object",properties:Object.freeze({})}),this.assignedSchema=this._schema,this.schemaInvalid=!1,this.valueInvalid=!1,this._value=Object.freeze({}),this.assignedValue=this._value,this.valueAssignedInCommit=!1,this.disabled=!1,this._status="pending",this.statusAssignedInCommit=!1,this.isMounting=!0,this.responseDispatching=!1}static{this.defaultStrings={...super.defaultStrings,agentQuestionAccept:LYRA_DEFAULT_agentQuestionAccept,agentQuestionDecline:LYRA_DEFAULT_agentQuestionDecline,agentQuestionLabel:LYRA_DEFAULT_agentQuestionLabel,agentQuestionSubmitted:LYRA_DEFAULT_agentQuestionSubmitted,agentQuestionUnsupported:LYRA_DEFAULT_agentQuestionUnsupported,cancel:LYRA_DEFAULT_cancel}}static{this.collectionSupport=eventCollectionSupport}static{this.immutableEventDetails=Object.freeze(["lr-question-input","lr-question-response"])}static{this.styles=[LyraElement.styles,styles,agentActionButtonStyles]}get schema(){return this._schema}set schema(value){if(value===this.assignedSchema)return;this.assignedSchema=value;const previous=this._schema,snapshot=snapshotFormValue(value);this.schemaInvalid=snapshot.invalid||snapshot.truncated,this._schema=snapshot.value,this.requestUpdate("schema",previous)}get value(){return this._value}set value(value){this.valueAssignedInCommit=!0,value!==this.assignedValue&&(this.assignedValue=value,this.setDraft(value))}setDraft(value){const previous=this._value,snapshot=snapshotFormValue(value);this.valueInvalid=snapshot.invalid||snapshot.truncated,this._value=snapshot.value,this.requestUpdate("value",previous)}get status(){return this._status}set status(value){this.statusAssignedInCommit=!0,this.setStatus(QUESTION_STATUS.normalize(value))}setStatus(value){const previous=this._status;this._status=value,this.requestUpdate("status",previous)}willUpdate(changed){super.willUpdate(changed),changed.has("requestId")&&this.hasUpdated&&(this.setDraft(this.valueAssignedInCommit?this.assignedValue:Object.freeze({})),this.statusAssignedInCommit||this.setStatus("pending")),this.valueAssignedInCommit=!1,this.statusAssignedInCommit=!1}connectedCallback(){super.connectedCallback(),this.isMounting=!0,this.announcements=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this})}disconnectedCallback(){this.announcements?.release(),this.announcements=void 0,super.disconnectedCallback()}updated(changed){super.updated(changed),!this.isMounting&&changed.has("status")&&this.status==="submitted"&&this.announcements?.announce(this.localize("agentQuestionSubmitted")),this.isMounting=!1}get supportedSchema(){if(this.schemaInvalid||!this.schema||typeof this.schema!="object"||Array.isArray(this.schema)||Object.keys(this.schema).some(key=>!SCHEMA_KEYS.has(key)))return!1;const properties=this.schema.properties;return!properties||typeof properties!="object"||Array.isArray(properties)?!1:Object.values(properties).every(field=>field&&typeof field=="object"&&!Array.isArray(field)&&Object.keys(field).every(key=>PROPERTY_KEYS.has(key)))}get inactive(){return this.disabled||this.status!=="pending"||typeof this.requestId!="string"||this.requestId.trim()===""}input(event,requestId){event.stopPropagation(),!(this.inactive||requestId!==this.requestId)&&(this.setDraft(event.detail.value),this.emit("lr-question-input",{requestId,value:this.value}))}respond(action,requestId){if(!(this.responseDispatching||this.inactive||requestId!==this.requestId)){this.responseDispatching=!0;try{let content;if(action==="accept"){if(!this.supportedSchema||this.valueInvalid)return;const form=this.renderRoot.querySelector(tag("tool-param-form"));if(!form)return;const schema=this.schema,value=this.value;if(form.schema=schema,form.value=value,!form.reportValidity()||this.inactive||requestId!==this.requestId||this.schema!==schema||this.value!==value)return;const effective=form.effectiveValue;content=Object.fromEntries(Object.keys(schema.properties).filter(key=>Object.prototype.hasOwnProperty.call(effective,key)&&effective[key]!==void 0).map(key=>[key,effective[key]]))}this.setStatus("submitted"),this.emit("lr-question-response",action==="accept"?{requestId,action,content}:{requestId,action})}finally{this.responseDispatching=!1}}}render(){const requestId=this.requestId,label=this.label??this.localize("agentQuestionLabel"),level=resolveHeadingLevel(this.headingLevel??"2");return html`<div part="base" role="group" aria-label=${this.getAttribute("aria-label")??label}>
1
+ import{__decorate}from"tslib";import{eventCollectionSupport}from"../../../internal/collection-snapshot.js";import{tag}from"../../../internal/prefix.js";import{html,nothing}from"lit";import{property}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{literalSetConverter}from"../../../internal/converters.js";import{snapshotFormValue}from"../tool-param-form/tool-param-snapshot.js";import{styles}from"./agent-question.styles.js";import{agentActionButtonStyles}from"../agent-action-button.styles.js";import{resolveHeadingLevel}from"../../../internal/heading-level.js";import{LYRA_DEFAULT_agentQuestionAccept,LYRA_DEFAULT_agentQuestionDecline,LYRA_DEFAULT_agentQuestionLabel,LYRA_DEFAULT_agentQuestionSubmitted,LYRA_DEFAULT_agentQuestionUnsupported}from"../../../internal/default-strings/agent-tools.generated.js";import{LYRA_DEFAULT_cancel}from"../../../internal/default-strings/shared.generated.js";const QUESTION_STATUS=literalSetConverter(["pending","submitted"],"pending"),SCHEMA_KEYS=new Set(["type","properties","required","$schema"]),PROPERTY_KEYS=new Set(["type","enum","description","title","default","const","autocomplete","spellcheck","autocapitalize","autoCorrect","inputMode","enterKeyHint","minLength","maxLength","format","minimum","maximum","minItems","maxItems","oneOf","enumNames","items"]);class LyraAgentQuestion extends LyraElement{constructor(){super(...arguments),this.requestId="",this.requester="",this.message="",this.headingLevel="2",this._schema=Object.freeze({type:"object",properties:Object.freeze({})}),this.assignedSchema=this._schema,this.schemaInvalid=!1,this.valueInvalid=!1,this._value=Object.freeze({}),this.assignedValue=this._value,this.valueAssignedInCommit=!1,this.disabled=!1,this._status="pending",this.statusAssignedInCommit=!1,this.isMounting=!0,this.responseDispatching=!1}static{this.defaultStrings={...super.defaultStrings,agentQuestionAccept:LYRA_DEFAULT_agentQuestionAccept,agentQuestionDecline:LYRA_DEFAULT_agentQuestionDecline,agentQuestionLabel:LYRA_DEFAULT_agentQuestionLabel,agentQuestionSubmitted:LYRA_DEFAULT_agentQuestionSubmitted,agentQuestionUnsupported:LYRA_DEFAULT_agentQuestionUnsupported,cancel:LYRA_DEFAULT_cancel}}static{this.collectionSupport=eventCollectionSupport}static{this.immutableEventDetails=Object.freeze(["lr-question-input","lr-question-response"])}static{this.styles=[LyraElement.styles,styles,agentActionButtonStyles]}get schema(){return this._schema}set schema(value){if(value===this.assignedSchema)return;this.assignedSchema=value;const previous=this._schema,snapshot=snapshotFormValue(value);this.schemaInvalid=snapshot.invalid||snapshot.truncated,this._schema=snapshot.value,this.requestUpdate("schema",previous)}get value(){return this._value}set value(value){this.valueAssignedInCommit=!0,value!==this.assignedValue&&(this.assignedValue=value,this.setDraft(value))}setDraft(value){const previous=this._value,snapshot=snapshotFormValue(value);this.valueInvalid=snapshot.invalid||snapshot.truncated,this._value=snapshot.value,this.requestUpdate("value",previous)}get status(){return this._status}set status(value){this.statusAssignedInCommit=!0,this.setStatus(QUESTION_STATUS.normalize(value))}setStatus(value){const previous=this._status;this._status=value,this.requestUpdate("status",previous)}willUpdate(changed){super.willUpdate(changed),changed.has("requestId")&&this.hasUpdated&&(this.setDraft(this.valueAssignedInCommit?this.assignedValue:Object.freeze({})),this.statusAssignedInCommit||this.setStatus("pending")),this.valueAssignedInCommit=!1,this.statusAssignedInCommit=!1}connectedCallback(){super.connectedCallback(),this.isMounting=!0,this.announcements=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this})}disconnectedCallback(){this.announcements?.release(),this.announcements=void 0,super.disconnectedCallback()}updated(changed){super.updated(changed),!this.isMounting&&changed.has("status")&&this.status==="submitted"&&this.announcements?.announce(this.localize("agentQuestionSubmitted")),this.isMounting=!1}get supportedSchema(){if(this.schemaInvalid||!this.schema||typeof this.schema!="object"||Array.isArray(this.schema)||Object.keys(this.schema).some(key=>!SCHEMA_KEYS.has(key)))return!1;const properties=this.schema.properties;return!properties||typeof properties!="object"||Array.isArray(properties)?!1:Object.values(properties).every(field=>field&&typeof field=="object"&&!Array.isArray(field)&&Object.keys(field).every(key=>PROPERTY_KEYS.has(key)))}get inactive(){return this.disabled||this.status!=="pending"||typeof this.requestId!="string"||this.requestId.trim()===""}input(event,requestId){event.stopPropagation(),!(this.inactive||requestId!==this.requestId)&&(this.setDraft(event.detail.value),this.emit("lr-question-input",{requestId,value:this.value}))}respond(action,requestId){if(!(this.responseDispatching||this.inactive||requestId!==this.requestId)){this.responseDispatching=!0;try{let content;if(action==="accept"){if(!this.supportedSchema||this.valueInvalid)return;const form=this.renderRoot.querySelector(tag("tool-param-form"));if(!form)return;const schema=this.schema,value=this.value;if(form.schema=schema,form.value=value,!form.reportValidity()||this.inactive||requestId!==this.requestId||this.schema!==schema||this.value!==value)return;const effective=form.effectiveValue;content=Object.fromEntries(Object.keys(schema.properties).filter(key=>Object.prototype.hasOwnProperty.call(effective,key)&&effective[key]!==void 0).map(key=>[key,effective[key]]))}this.setStatus("submitted"),this.emit("lr-question-response",action==="accept"?{requestId,action,content}:{requestId,action})}finally{this.responseDispatching=!1}}}render(){const requestId=this.requestId,label=this.label??this.localize("agentQuestionLabel"),level=resolveHeadingLevel(this.headingLevel??"2");return html`<div part="base" role="group" aria-label=${this.getAttribute("aria-label")??label}>
2
2
  ${label===""?nothing:html`<div part="heading" role=${level?"heading":nothing} aria-level=${level??nothing}>${label}</div>`}
3
3
  ${this.requester?html`<p part="requester">${this.requester}</p>`:nothing}
4
4
  ${this.message?html`<p part="message">${this.message}</p>`:nothing}
@@ -1,4 +1,4 @@
1
- import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property,state,query}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{spinnerIcon}from"../../../internal/icons.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{formatShortDuration}from"../../../internal/duration.js";import{finiteRange}from"../../../internal/numbers.js";import{srOnly}from"../../../internal/a11y.js";import{AGENT_STATUS_VARIANTS}from"../../../internal/agent-status-variants.js";import{styles}from"./agent-run.styles.js";import{agentActionButtonStyles}from"../agent-action-button.styles.js";import{firstByIdentity}from"../collection-identity.js";import{agentStatusKind,agentStatusMessage}from"../agent-status-presentation.js";import{agentStatusText}from"../../../internal/agent-status-text.js";import{LYRA_DEFAULT_agentRunCurrentStepLabel,LYRA_DEFAULT_agentRunStatusAnnounce,LYRA_DEFAULT_agentRunStatusCancelled,LYRA_DEFAULT_agentRunStatusCollecting,LYRA_DEFAULT_agentRunStatusDone,LYRA_DEFAULT_agentRunStatusIdle,LYRA_DEFAULT_agentRunStatusQueued,LYRA_DEFAULT_agentRunStatusWaitingApproval,LYRA_DEFAULT_agentRunStatusWaitingInput,LYRA_DEFAULT_cancel,LYRA_DEFAULT_collapse,LYRA_DEFAULT_copy,LYRA_DEFAULT_details,LYRA_DEFAULT_durationMilliseconds,LYRA_DEFAULT_durationSeconds,LYRA_DEFAULT_map,LYRA_DEFAULT_navigation,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_retry,LYRA_DEFAULT_search,LYRA_DEFAULT_select,LYRA_DEFAULT_statusError,LYRA_DEFAULT_statusRunning}from"../../../internal/default-strings.generated.js";const TICKING_KINDS=new Set(["running","collecting","waiting-input","waiting-approval"]),TERMINAL_KINDS=new Set(["done","error","cancelled"]),STEP_TO_TASK_STATUS={idle:"pending",running:"running",collecting:"running","waiting-input":"running","waiting-approval":"running",done:"success",error:"error",cancelled:"incomplete"};function toTaskItem(step){const kind=agentStatusKind(step.status);return{id:step.id,label:step.label,status:STEP_TO_TASK_STATUS[kind]??"pending",detail:agentStatusMessage(step.status)}}function runSteps(run){return Array.isArray(run?.steps)?run.steps:[]}class LyraAgentRun extends LyraElement{constructor(){super(...arguments),this.run=null,this.statusLabels={},this.statusVariants={},this.metrics=[],this.withoutCancel=!1,this.withoutRetry=!1,this.size="m",this.frame="card",this.retryAttempt=0,this.hasHeaderSlot=!1,this.hasSummarySlot=!1,this.onHeaderSlotChange=()=>{this.hasHeaderSlot=this.hasSlotted("header")},this.onSummarySlotChange=()=>{this.hasSummarySlot=this.hasSlotted("summary")},this.onCancelClick=()=>{const runId=this.run?.id??"";this.emit("lr-run-cancel",{runId}),this.emit("lr-cancel",{runId})},this.onRetryClick=()=>{this.retryAttempt+=1,this.emit("lr-run-retry",{runId:this.run?.id??"",attempt:this.retryAttempt})}}static{this.defaultStrings={...super.defaultStrings,agentRunCurrentStepLabel:LYRA_DEFAULT_agentRunCurrentStepLabel,agentRunStatusAnnounce:LYRA_DEFAULT_agentRunStatusAnnounce,agentRunStatusCancelled:LYRA_DEFAULT_agentRunStatusCancelled,agentRunStatusCollecting:LYRA_DEFAULT_agentRunStatusCollecting,agentRunStatusDone:LYRA_DEFAULT_agentRunStatusDone,agentRunStatusIdle:LYRA_DEFAULT_agentRunStatusIdle,agentRunStatusQueued:LYRA_DEFAULT_agentRunStatusQueued,agentRunStatusWaitingApproval:LYRA_DEFAULT_agentRunStatusWaitingApproval,agentRunStatusWaitingInput:LYRA_DEFAULT_agentRunStatusWaitingInput,cancel:LYRA_DEFAULT_cancel,collapse:LYRA_DEFAULT_collapse,copy:LYRA_DEFAULT_copy,details:LYRA_DEFAULT_details,durationMilliseconds:LYRA_DEFAULT_durationMilliseconds,durationSeconds:LYRA_DEFAULT_durationSeconds,map:LYRA_DEFAULT_map,navigation:LYRA_DEFAULT_navigation,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,retry:LYRA_DEFAULT_retry,search:LYRA_DEFAULT_search,select:LYRA_DEFAULT_select,statusError:LYRA_DEFAULT_statusError,statusRunning:LYRA_DEFAULT_statusRunning}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["run","statusLabels","statusVariants","metrics"])}static{this.styles=[LyraElement.styles,srOnly,styles,agentActionButtonStyles]}get normalizedMetrics(){return firstByIdentity(Array.isArray(this.metrics)?this.metrics:[],metric=>metric.id)}willUpdate(changed){super.willUpdate(changed),this.seedFirstRenderState(()=>{this.hasHeaderSlot=this.hasSlotted("header"),this.hasSummarySlot=this.hasSlotted("summary")}),changed.has("run")&&this.run?.id!==this.previousRunId&&(this.retryAttempt=0)}hasSlotted(name){return Array.from(this.children).some(element=>element.getAttribute("slot")===name)}updated(changed){super.updated(changed),changed.has("run")&&this.handleRunChange()}handleRunChange(){const runId=this.run?.id,kind=this.runKind;!(runId!==this.previousRunId)&&kind!==void 0&&kind!==this.previousStatusKind&&this.isAttentionKind(kind)&&this.announceStatus(kind),this.previousRunId=runId,this.previousStatusKind=kind}isAttentionKind(kind){return kind==="waiting-input"||kind==="waiting-approval"||TERMINAL_KINDS.has(kind)}announceStatus(kind){const region=this.liveRegion;region&&(region.mode=kind==="error"||kind==="waiting-input"||kind==="waiting-approval"?"assertive":"polite",region.announce(this.localize("agentRunStatusAnnounce",void 0,{status:this.statusLabel(kind)}),{force:!0}))}statusLabel(kind){return this.statusLabels[kind]||agentStatusText(this.localize.bind(this),kind)}get runKind(){return this.run?agentStatusKind(this.run.status):void 0}get currentStep(){const steps=runSteps(this.run);for(let i=steps.length-1;i>=0;i--)if(agentStatusKind(steps[i].status)==="running")return steps[i]}get isTicking(){const kind=this.runKind;return kind!==void 0&&TICKING_KINDS.has(kind)&&Number.isFinite(this.run?.startedAt)}get staticElapsedText(){const run=this.run;if(!run||!TERMINAL_KINDS.has(agentStatusKind(run.status)))return;const startedAt=run.startedAt,endedAt=run.endedAt;if(!(startedAt==null||endedAt==null||!Number.isFinite(startedAt)||!Number.isFinite(endedAt)))return formatShortDuration(this.localize.bind(this),this.effectiveLocale,endedAt-startedAt)}get costText(){const cost=this.run?.costEstimate;if(cost==null||!Number.isFinite(cost))return"";const value=finiteRange(cost,cost,0);return(this.formatCost??(c=>getNumberFormat(this.effectiveLocale,{maximumFractionDigits:4}).format(c)))(value)}get canCancel(){const kind=this.runKind;return!this.withoutCancel&&kind!==void 0&&TICKING_KINDS.has(kind)}get canRetry(){const kind=this.runKind;return!this.withoutRetry&&(kind==="error"||kind==="cancelled")}render(){const run=this.run;if(!run)return html`<div part="base"><lr-empty part="empty" heading=${this.localize("noData")}></lr-empty></div>`;const kind=agentStatusKind(run.status),message=agentStatusMessage(run.status),step=this.currentStep,ticking=this.isTicking,staticElapsed=this.staticElapsedText,cost=this.costText,metrics=this.normalizedMetrics,steps=runSteps(run),hasSummary=!!run.model||cost!==""||metrics.length>0;return html`
1
+ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property,state,query}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{spinnerIcon}from"../../../internal/icons.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{formatShortDuration}from"../../../internal/duration.js";import{finiteRange}from"../../../internal/numbers.js";import{srOnly}from"../../../internal/a11y.js";import{AGENT_STATUS_VARIANTS}from"../../../internal/agent-status-variants.js";import{styles}from"./agent-run.styles.js";import{agentActionButtonStyles}from"../agent-action-button.styles.js";import{firstByIdentity}from"../collection-identity.js";import{agentStatusKind,agentStatusMessage}from"../agent-status-presentation.js";import{agentStatusText}from"../../../internal/agent-status-text.js";import{LYRA_DEFAULT_agentRunCurrentStepLabel,LYRA_DEFAULT_agentRunStatusAnnounce,LYRA_DEFAULT_agentRunStatusCancelled,LYRA_DEFAULT_agentRunStatusCollecting,LYRA_DEFAULT_agentRunStatusDone,LYRA_DEFAULT_agentRunStatusIdle,LYRA_DEFAULT_agentRunStatusQueued,LYRA_DEFAULT_agentRunStatusWaitingApproval,LYRA_DEFAULT_agentRunStatusWaitingInput}from"../../../internal/default-strings/agent-tools.generated.js";import{LYRA_DEFAULT_cancel,LYRA_DEFAULT_collapse,LYRA_DEFAULT_copy,LYRA_DEFAULT_date,LYRA_DEFAULT_details,LYRA_DEFAULT_durationMilliseconds,LYRA_DEFAULT_durationSeconds,LYRA_DEFAULT_map,LYRA_DEFAULT_navigation,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_retry,LYRA_DEFAULT_search,LYRA_DEFAULT_select,LYRA_DEFAULT_statusError,LYRA_DEFAULT_statusRunning}from"../../../internal/default-strings/shared.generated.js";const TICKING_KINDS=new Set(["running","collecting","waiting-input","waiting-approval"]),TERMINAL_KINDS=new Set(["done","error","cancelled"]),STEP_TO_TASK_STATUS={idle:"pending",running:"running",collecting:"running","waiting-input":"running","waiting-approval":"running",done:"success",error:"error",cancelled:"incomplete"};function toTaskItem(step){const kind=agentStatusKind(step.status);return{id:step.id,label:step.label,status:STEP_TO_TASK_STATUS[kind]??"pending",detail:agentStatusMessage(step.status)}}function runSteps(run){return Array.isArray(run?.steps)?run.steps:[]}class LyraAgentRun extends LyraElement{constructor(){super(...arguments),this.run=null,this.statusLabels={},this.statusVariants={},this.metrics=[],this.withoutCancel=!1,this.withoutRetry=!1,this.size="m",this.frame="card",this.retryAttempt=0,this.hasHeaderSlot=!1,this.hasSummarySlot=!1,this.onHeaderSlotChange=()=>{this.hasHeaderSlot=this.hasSlotted("header")},this.onSummarySlotChange=()=>{this.hasSummarySlot=this.hasSlotted("summary")},this.onCancelClick=()=>{const runId=this.run?.id??"";this.emit("lr-run-cancel",{runId}),this.emit("lr-cancel",{runId})},this.onRetryClick=()=>{this.retryAttempt+=1,this.emit("lr-run-retry",{runId:this.run?.id??"",attempt:this.retryAttempt})}}static{this.defaultStrings={...super.defaultStrings,agentRunCurrentStepLabel:LYRA_DEFAULT_agentRunCurrentStepLabel,agentRunStatusAnnounce:LYRA_DEFAULT_agentRunStatusAnnounce,agentRunStatusCancelled:LYRA_DEFAULT_agentRunStatusCancelled,agentRunStatusCollecting:LYRA_DEFAULT_agentRunStatusCollecting,agentRunStatusDone:LYRA_DEFAULT_agentRunStatusDone,agentRunStatusIdle:LYRA_DEFAULT_agentRunStatusIdle,agentRunStatusQueued:LYRA_DEFAULT_agentRunStatusQueued,agentRunStatusWaitingApproval:LYRA_DEFAULT_agentRunStatusWaitingApproval,agentRunStatusWaitingInput:LYRA_DEFAULT_agentRunStatusWaitingInput,cancel:LYRA_DEFAULT_cancel,collapse:LYRA_DEFAULT_collapse,copy:LYRA_DEFAULT_copy,date:LYRA_DEFAULT_date,details:LYRA_DEFAULT_details,durationMilliseconds:LYRA_DEFAULT_durationMilliseconds,durationSeconds:LYRA_DEFAULT_durationSeconds,map:LYRA_DEFAULT_map,navigation:LYRA_DEFAULT_navigation,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,retry:LYRA_DEFAULT_retry,search:LYRA_DEFAULT_search,select:LYRA_DEFAULT_select,statusError:LYRA_DEFAULT_statusError,statusRunning:LYRA_DEFAULT_statusRunning}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["run","statusLabels","statusVariants","metrics"])}static{this.styles=[LyraElement.styles,srOnly,styles,agentActionButtonStyles]}get normalizedMetrics(){return firstByIdentity(Array.isArray(this.metrics)?this.metrics:[],metric=>metric.id)}willUpdate(changed){super.willUpdate(changed),this.seedFirstRenderState(()=>{this.hasHeaderSlot=this.hasSlotted("header"),this.hasSummarySlot=this.hasSlotted("summary")}),changed.has("run")&&this.run?.id!==this.previousRunId&&(this.retryAttempt=0)}hasSlotted(name){return Array.from(this.children).some(element=>element.getAttribute("slot")===name)}updated(changed){super.updated(changed),changed.has("run")&&this.handleRunChange()}handleRunChange(){const runId=this.run?.id,kind=this.runKind;!(runId!==this.previousRunId)&&kind!==void 0&&kind!==this.previousStatusKind&&this.isAttentionKind(kind)&&this.announceStatus(kind),this.previousRunId=runId,this.previousStatusKind=kind}isAttentionKind(kind){return kind==="waiting-input"||kind==="waiting-approval"||TERMINAL_KINDS.has(kind)}announceStatus(kind){const region=this.liveRegion;region&&(region.mode=kind==="error"||kind==="waiting-input"||kind==="waiting-approval"?"assertive":"polite",region.announce(this.localize("agentRunStatusAnnounce",void 0,{status:this.statusLabel(kind)}),{force:!0}))}statusLabel(kind){return this.statusLabels[kind]||agentStatusText(this.localize.bind(this),kind)}get runKind(){return this.run?agentStatusKind(this.run.status):void 0}get currentStep(){const steps=runSteps(this.run);for(let i=steps.length-1;i>=0;i--)if(agentStatusKind(steps[i].status)==="running")return steps[i]}get isTicking(){const kind=this.runKind;return kind!==void 0&&TICKING_KINDS.has(kind)&&Number.isFinite(this.run?.startedAt)}get staticElapsedText(){const run=this.run;if(!run||!TERMINAL_KINDS.has(agentStatusKind(run.status)))return;const startedAt=run.startedAt,endedAt=run.endedAt;if(!(startedAt==null||endedAt==null||!Number.isFinite(startedAt)||!Number.isFinite(endedAt)))return formatShortDuration(this.localize.bind(this),this.effectiveLocale,endedAt-startedAt)}get costText(){const cost=this.run?.costEstimate;if(cost==null||!Number.isFinite(cost))return"";const value=finiteRange(cost,cost,0);return(this.formatCost??(c=>getNumberFormat(this.effectiveLocale,{maximumFractionDigits:4}).format(c)))(value)}get canCancel(){const kind=this.runKind;return!this.withoutCancel&&kind!==void 0&&TICKING_KINDS.has(kind)}get canRetry(){const kind=this.runKind;return!this.withoutRetry&&(kind==="error"||kind==="cancelled")}render(){const run=this.run;if(!run)return html`<div part="base"><lr-empty part="empty" heading=${this.localize("noData")}></lr-empty></div>`;const kind=agentStatusKind(run.status),message=agentStatusMessage(run.status),step=this.currentStep,ticking=this.isTicking,staticElapsed=this.staticElapsedText,cost=this.costText,metrics=this.normalizedMetrics,steps=runSteps(run),hasSummary=!!run.model||cost!==""||metrics.length>0;return html`
2
2
  <div part="base">
3
3
  <div part="header">
4
4
  <slot name="header" @slotchange=${this.onHeaderSlotChange}></slot>