@morscherlab/mint-sdk 1.3.11 → 1.4.0-beta.10

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 (1056) hide show
  1. package/README.md +152 -177
  2. package/dist/AlertBox-B2Bgr3ei.js +276 -0
  3. package/dist/AlertBox-B2Bgr3ei.js.map +1 -0
  4. package/dist/AppSidebar-mvm--GxN.js +3565 -0
  5. package/dist/AppSidebar-mvm--GxN.js.map +1 -0
  6. package/dist/ConfirmDialog-nbJj51is.js +102 -0
  7. package/dist/ConfirmDialog-nbJj51is.js.map +1 -0
  8. package/dist/ExperimentPopover-5T1fAq2L.js +337 -0
  9. package/dist/ExperimentPopover-5T1fAq2L.js.map +1 -0
  10. package/dist/ExperimentSelectorModal-65peG4Up.js +544 -0
  11. package/dist/ExperimentSelectorModal-65peG4Up.js.map +1 -0
  12. package/dist/SegmentedControl-BtnnjWzs.js +129 -0
  13. package/dist/SegmentedControl-BtnnjWzs.js.map +1 -0
  14. package/dist/SettingsModal-DO3IZ7qz.js +666 -0
  15. package/dist/SettingsModal-DO3IZ7qz.js.map +1 -0
  16. package/dist/analysisArtifactTypes-Cy3D0Ipg.js.map +1 -1
  17. package/dist/auth-SliLnFre.js +65 -0
  18. package/dist/auth-SliLnFre.js.map +1 -0
  19. package/dist/components/ActionMenu.vue.d.ts +1 -1
  20. package/dist/components/AdductText.vue.d.ts +1 -1
  21. package/dist/components/AlertBox.vue.d.ts +3 -3
  22. package/dist/components/AppContainer.vue.d.ts +1 -1
  23. package/dist/components/AppSidebar.vue.d.ts +15 -95
  24. package/dist/components/AppTopBar.vue.d.ts +16 -70
  25. package/dist/components/ArtifactSaveDialog.vue.d.ts +13 -5
  26. package/dist/components/ArtifactSelectorModal.vue.d.ts +4 -4
  27. package/dist/components/AuditTrail.vue.d.ts +2 -2
  28. package/dist/components/BaseButton.vue.d.ts +11 -4
  29. package/dist/components/BaseCheckbox.vue.d.ts +9 -3
  30. package/dist/components/BaseInput.vue.d.ts +13 -9
  31. package/dist/components/BaseModal.vue.d.ts +4 -4
  32. package/dist/components/BasePill.vue.d.ts +15 -8
  33. package/dist/components/BaseRadioGroup.vue.d.ts +2 -2
  34. package/dist/components/BaseSelect.vue.d.ts +51 -19
  35. package/dist/components/BaseTabs.vue.d.ts +6 -5
  36. package/dist/components/BatchProgressList.vue.d.ts +2 -2
  37. package/dist/components/ChartContainer.vue.d.ts +4 -2
  38. package/dist/components/ChemicalFormula.vue.d.ts +2 -2
  39. package/dist/components/CollapsibleCard.vue.d.ts +3 -3
  40. package/dist/components/ComponentBindingRenderer.vue.d.ts +2 -3
  41. package/dist/components/ConcentrationInput.vue.d.ts +2 -2
  42. package/dist/components/ConfirmDialog.vue.d.ts +8 -7
  43. package/dist/components/DataFrame.vue.d.ts +32 -74
  44. package/dist/components/DatePicker.vue.d.ts +24 -2
  45. package/dist/components/DoseCalculator.vue.d.ts +1 -1
  46. package/dist/components/DoseCalculatorVolumeField.vue.d.ts +1 -1
  47. package/dist/components/EmptyState.vue.d.ts +3 -2
  48. package/dist/components/ExperimentPopover.vue.d.ts +18 -0
  49. package/dist/components/ExperimentSelectorModal.vue.d.ts +3 -7
  50. package/dist/components/FilePicker.vue.d.ts +1 -1
  51. package/dist/components/FileUploader.vue.d.ts +2 -2
  52. package/dist/components/FormBuilder.vue.d.ts +17 -74
  53. package/dist/components/FormulaInput.vue.d.ts +2 -2
  54. package/dist/components/GeneratedPluginView.vue.d.ts +1 -1
  55. package/dist/components/GeneratedResultRenderer.vue.d.ts +5 -1
  56. package/dist/components/{StatusIndicator.vue.d.ts → InstrumentStatusPanels.vue.d.ts} +8 -9
  57. package/dist/components/JobsStatusTray.vue.d.ts +2 -9
  58. package/dist/components/LoadingSpinner.vue.d.ts +3 -3
  59. package/dist/components/MoleculeInput.vue.d.ts +2 -2
  60. package/dist/components/NumberInput.vue.d.ts +19 -5
  61. package/dist/components/PlateEditor.vue.d.ts +11 -61
  62. package/dist/components/PlotlyChart.vue.d.ts +2 -2
  63. package/dist/components/PluginIcon.vue.d.ts +5 -1
  64. package/dist/components/PluginWorkspaceView.controls.d.ts +2 -9
  65. package/dist/components/PluginWorkspaceView.navigation.d.ts +1 -7
  66. package/dist/components/PluginWorkspaceView.props.d.ts +18 -137
  67. package/dist/components/PluginWorkspaceView.shell.d.ts +2 -10
  68. package/dist/components/PluginWorkspaceView.vue.d.ts +14 -84
  69. package/dist/components/PresenceAvatars.vue.d.ts +31 -0
  70. package/dist/components/ProgressBar.vue.d.ts +3 -2
  71. package/dist/components/ProtocolStep.presentation.d.ts +0 -1
  72. package/dist/components/SampleHierarchyTree.vue.d.ts +3 -3
  73. package/dist/components/SampleSelector.vue.d.ts +8 -8
  74. package/dist/components/ScheduleCalendar.vue.d.ts +1 -1
  75. package/dist/components/ScientificNumber.vue.d.ts +1 -1
  76. package/dist/components/SecretInput.vue.d.ts +2 -2
  77. package/dist/components/SegmentedControl.vue.d.ts +2 -2
  78. package/dist/components/SequenceInput.vue.d.ts +2 -2
  79. package/dist/components/SequenceProgressBar.vue.d.ts +3 -0
  80. package/dist/components/SettingsModal.vue.d.ts +12 -20
  81. package/dist/components/SmartGroup.types.d.ts +0 -1
  82. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +1 -1
  83. package/dist/components/StaleFormBanner.vue.d.ts +20 -0
  84. package/dist/components/StepWizard.vue.d.ts +3 -0
  85. package/dist/components/TagsInput.vue.d.ts +4 -3
  86. package/dist/components/TimeRangeInput.vue.d.ts +2 -2
  87. package/dist/components/VersionConflictDialog.vue.d.ts +24 -0
  88. package/dist/components/WellPlate.geometry.d.ts +0 -6
  89. package/dist/components/WellPlate.rendering.d.ts +0 -2
  90. package/dist/components/WellPlate.vue.d.ts +7 -52
  91. package/dist/components/index.d.ts +0 -90
  92. package/dist/components/{AutoGroupModal.adapter.d.ts → internal/AutoGroupModalInternal.adapter.d.ts} +6 -6
  93. package/dist/components/{AutoGroupModal.vue.d.ts → internal/AutoGroupModalInternal.vue.d.ts} +6 -6
  94. package/dist/components/{BaseToggle.vue.d.ts → internal/CheckboxSwitchInternal.vue.d.ts} +2 -2
  95. package/dist/components/{MultiSelect.vue.d.ts → internal/DatePickerDateInternal.vue.d.ts} +11 -9
  96. package/dist/components/{DateTimePicker.vue.d.ts → internal/DatePickerDateTimeInternal.vue.d.ts} +2 -2
  97. package/dist/components/{TimePicker.vue.d.ts → internal/DatePickerTimeInternal.vue.d.ts} +4 -4
  98. package/dist/components/internal/FilePickerListInternal.vue.d.ts +2 -2
  99. package/dist/components/internal/FormSchemaInternal.vue.d.ts +95 -0
  100. package/dist/components/{UnitInput.vue.d.ts → internal/NumberUnitInputInternal.vue.d.ts} +6 -14
  101. package/dist/components/internal/PlateEditorBindingInternal.vue.d.ts +3 -2
  102. package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +5 -10
  103. package/dist/components/internal/SelectMultipleInternal.vue.d.ts +27 -0
  104. package/dist/components/{SearchableSelect.vue.d.ts → internal/SelectSearchableInternal.vue.d.ts} +5 -2
  105. package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +1 -15
  106. package/dist/components/internal/WorkspaceSidebarInternal.vue.d.ts +4 -4
  107. package/dist/{composables → components/internal}/autoGroup/classKey.d.ts +1 -1
  108. package/dist/{composables → components/internal}/autoGroup/classify.d.ts +1 -1
  109. package/dist/{composables → components/internal}/autoGroup/columns.d.ts +1 -1
  110. package/dist/{composables → components/internal}/autoGroup/compose.d.ts +1 -1
  111. package/dist/{composables → components/internal}/autoGroup/cooccurrence.d.ts +1 -1
  112. package/dist/{composables → components/internal}/autoGroup/csv-shim.d.ts +1 -1
  113. package/dist/{composables → components/internal}/autoGroup/fingerprint.d.ts +1 -1
  114. package/dist/{composables → components/internal}/autoGroup/template.d.ts +1 -1
  115. package/dist/{composables → components/internal}/autoGroup/tokenLength.d.ts +1 -1
  116. package/dist/components/internal/generatedJobsApi.d.ts +1 -1
  117. package/dist/{composables → components/internal}/useAutoGroup.d.ts +9 -18
  118. package/dist/composables/componentSpecs.d.ts +41 -0
  119. package/dist/composables/controlComponentBindings.d.ts +6 -0
  120. package/dist/composables/controlSchemaAdapters.d.ts +28 -2
  121. package/dist/composables/controlSchemaDoseDesign.d.ts +1 -1
  122. package/dist/composables/controlSchemaModel.d.ts +1 -1
  123. package/dist/composables/controlSchemaTypes.d.ts +35 -23
  124. package/dist/composables/{usePluginClient.d.ts → createClient.d.ts} +22 -49
  125. package/dist/composables/{useEventStream.d.ts → eventStream.d.ts} +2 -2
  126. package/dist/composables/experiment-utils.d.ts +1 -6
  127. package/dist/composables/index.d.ts +7 -59
  128. package/dist/composables/platformContextHelpers.d.ts +0 -11
  129. package/dist/composables/pluginEndpointBuilder.d.ts +2 -2
  130. package/dist/composables/pluginIdentity.d.ts +24 -0
  131. package/dist/composables/pluginWorkspaceModel.d.ts +16 -99
  132. package/dist/composables/useApi.d.ts +1 -3
  133. package/dist/composables/useAppExperiment.d.ts +9 -1
  134. package/dist/composables/{useAnalysisArtifacts.d.ts → useArtifacts.d.ts} +6 -6
  135. package/dist/composables/useCalendarGrid.d.ts +1 -1
  136. package/dist/composables/useExperiment.d.ts +30 -0
  137. package/dist/composables/useExperimentSelector.d.ts +6 -2
  138. package/dist/composables/useFilePicker.d.ts +2 -2
  139. package/dist/composables/useJobCenter.d.ts +63 -0
  140. package/dist/composables/{useGeneratedAnalysis.d.ts → useJobsEndpoint.d.ts} +22 -23
  141. package/dist/composables/useMenuKeyboard.d.ts +1 -1
  142. package/dist/composables/usePlatform.d.ts +64 -0
  143. package/dist/composables/usePluginWorkspace.d.ts +6 -11
  144. package/dist/composables/usePresence.d.ts +41 -0
  145. package/dist/composables/useRackEditor.d.ts +2 -2
  146. package/dist/composables/useRealtime.d.ts +71 -0
  147. package/dist/composables/{useRequestSyncState.d.ts → useRequest.d.ts} +12 -17
  148. package/dist/composables/useToast.d.ts +7 -5
  149. package/dist/composables/useVersionedSave.d.ts +76 -0
  150. package/dist/controlSchemaModel-B8CTXagP.js +95 -0
  151. package/dist/controlSchemaModel-B8CTXagP.js.map +1 -0
  152. package/dist/data-CgILxDLW.js +3865 -0
  153. package/dist/data-CgILxDLW.js.map +1 -0
  154. package/dist/data.d.ts +32 -0
  155. package/dist/data.js +10 -0
  156. package/dist/deprecatedRootExports.d.ts +191 -0
  157. package/dist/experiment-43OJtH7R.js +673 -0
  158. package/dist/experiment-43OJtH7R.js.map +1 -0
  159. package/dist/experimentStatus-Cqp6qNrR.js +60 -0
  160. package/dist/experimentStatus-Cqp6qNrR.js.map +1 -0
  161. package/dist/host.d.ts +10 -0
  162. package/dist/host.js +26 -0
  163. package/dist/host.js.map +1 -0
  164. package/dist/index.d.ts +1 -12
  165. package/dist/index.js +65 -277
  166. package/dist/index.js.map +1 -1
  167. package/dist/install-CsPFJSx3.js +669 -0
  168. package/dist/install-CsPFJSx3.js.map +1 -0
  169. package/dist/install.d.ts +2 -1
  170. package/dist/install.js +1 -21
  171. package/dist/instrument.d.ts +0 -6
  172. package/dist/lab-MHzp-_J8.js +7494 -0
  173. package/dist/lab-MHzp-_J8.js.map +1 -0
  174. package/dist/lab.d.ts +42 -0
  175. package/dist/lab.js +5 -0
  176. package/dist/permissions.d.ts +0 -4
  177. package/dist/permissions.js +1 -20
  178. package/dist/permissions.js.map +1 -1
  179. package/dist/records-B6gpM_3e.js +3268 -0
  180. package/dist/records-B6gpM_3e.js.map +1 -0
  181. package/dist/runtime-8bs8EogX.js +1491 -0
  182. package/dist/runtime-8bs8EogX.js.map +1 -0
  183. package/dist/runtime.d.ts +25 -0
  184. package/dist/runtime.js +8 -0
  185. package/dist/shell-CywENwBT.js +197 -0
  186. package/dist/shell-CywENwBT.js.map +1 -0
  187. package/dist/shell.d.ts +16 -0
  188. package/dist/shell.js +8 -0
  189. package/dist/stores/auth.d.ts +13 -35
  190. package/dist/stores/experiment.d.ts +4 -0
  191. package/dist/stores/index.js +2 -2
  192. package/dist/styles.css +12161 -15036
  193. package/dist/types/analysisArtifactTypes.d.ts +1 -1
  194. package/dist/types/auth.d.ts +0 -8
  195. package/dist/types/componentLabTypes.d.ts +98 -34
  196. package/dist/types/componentWorkflowTypes.d.ts +2 -27
  197. package/dist/types/components.d.ts +145 -74
  198. package/dist/types/form-builder.d.ts +4 -0
  199. package/dist/types/generated/platformContext.d.ts +53 -0
  200. package/dist/types/generated-ui.d.ts +6 -2
  201. package/dist/types/index.d.ts +4 -5
  202. package/dist/types/instrument.d.ts +41 -0
  203. package/dist/types/platform.d.ts +20 -58
  204. package/dist/useDebouncedWatch-BPwyl6eS.js +73 -0
  205. package/dist/useDebouncedWatch-BPwyl6eS.js.map +1 -0
  206. package/dist/{experiment-utils-DTANyVKV.js → useDropdownState-8yWMu-7_.js} +127 -144
  207. package/dist/useDropdownState-8yWMu-7_.js.map +1 -0
  208. package/dist/useExpansionSet-CvoNMZJi.js +68 -0
  209. package/dist/useExpansionSet-CvoNMZJi.js.map +1 -0
  210. package/dist/useExperimentSamples-DHnxKFAF.js +366 -0
  211. package/dist/useExperimentSamples-DHnxKFAF.js.map +1 -0
  212. package/dist/useListReorder-BitdUhxn.js +5294 -0
  213. package/dist/useListReorder-BitdUhxn.js.map +1 -0
  214. package/dist/useRackEditor-DiwCt77M.js +5930 -0
  215. package/dist/useRackEditor-DiwCt77M.js.map +1 -0
  216. package/dist/useRealtime-C3iy9QkU.js +699 -0
  217. package/dist/useRealtime-C3iy9QkU.js.map +1 -0
  218. package/dist/useRequest-D506eHi8.js +244 -0
  219. package/dist/useRequest-D506eHi8.js.map +1 -0
  220. package/dist/utils/color.d.ts +0 -5
  221. package/dist/{composables/useDoseCalculator.d.ts → utils/dose.d.ts} +10 -13
  222. package/dist/utils/experimentStatus.d.ts +9 -0
  223. package/dist/{composables/useChemicalFormula.d.ts → utils/formula.d.ts} +3 -6
  224. package/dist/utils/integrationHost.d.ts +18 -0
  225. package/dist/utils/plotlyTemplate.d.ts +2 -0
  226. package/dist/utils/pluginSecrets.d.ts +12 -12
  227. package/dist/utils/presenceAvatars.d.ts +30 -0
  228. package/dist/utils/records.d.ts +0 -2
  229. package/dist/{composables/useTimeUtils.d.ts → utils/time.d.ts} +7 -18
  230. package/package.json +20 -17
  231. package/src/__tests__/components/ActionMenu.test.ts +0 -13
  232. package/src/__tests__/components/AlertBox.test.ts +1 -1
  233. package/src/__tests__/components/AppSidebar.test.ts +119 -167
  234. package/src/__tests__/components/AppToastContainer.test.ts +2 -2
  235. package/src/__tests__/components/AppTopBar.test.ts +230 -176
  236. package/src/__tests__/components/AppTopBarPillNav.test.ts +35 -0
  237. package/src/__tests__/components/ArtifactSaveDialog.test.ts +83 -3
  238. package/src/__tests__/components/ArtifactSelectorModal.test.ts +6 -4
  239. package/src/__tests__/components/AuditTrail.test.ts +1 -1
  240. package/src/__tests__/components/AutoGroupModal.adapter.test.ts +1 -1
  241. package/src/__tests__/components/AutoGroupModal.anatomy.test.ts +2 -2
  242. package/src/__tests__/components/AutoGroupModal.wiring.test.ts +2 -2
  243. package/src/__tests__/components/BaseButton.test.ts +51 -0
  244. package/src/__tests__/components/{BaseToggle.test.ts → BaseCheckbox.switch.test.ts} +8 -6
  245. package/src/__tests__/components/BaseInput.test.ts +13 -34
  246. package/src/__tests__/components/BaseModal.test.ts +6 -6
  247. package/src/__tests__/components/BasePill.test.ts +33 -39
  248. package/src/__tests__/components/BaseSelect.multiple.test.ts +118 -0
  249. package/src/__tests__/components/{SearchableSelect.test.ts → BaseSelect.searchable.test.ts} +19 -9
  250. package/src/__tests__/components/BaseSelect.test.ts +11 -0
  251. package/src/__tests__/components/BaseTabs.test.ts +13 -13
  252. package/src/__tests__/components/BatchProgressList.test.ts +16 -0
  253. package/src/__tests__/components/CalendarGridPanel.test.ts +2 -2
  254. package/src/__tests__/components/ChartContainer.test.ts +11 -0
  255. package/src/__tests__/components/ChemicalFormula.test.ts +6 -3
  256. package/src/__tests__/components/CollapsibleCard.test.ts +1 -1
  257. package/src/__tests__/components/ComponentBindingRenderer.test.ts +25 -73
  258. package/src/__tests__/components/ConcentrationInput.test.ts +3 -3
  259. package/src/__tests__/components/ConfirmDialog.test.ts +23 -0
  260. package/src/__tests__/components/DataFrame.test.ts +140 -142
  261. package/src/__tests__/components/DataStates.test.ts +6 -22
  262. package/src/__tests__/components/{DateTimePicker.test.ts → DatePicker.datetime.test.ts} +15 -7
  263. package/src/__tests__/components/DatePicker.test.ts +21 -0
  264. package/src/__tests__/components/{TimePicker.test.ts → DatePicker.time.test.ts} +20 -19
  265. package/src/__tests__/components/DoseCalculator.test.ts +12 -7
  266. package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +6 -6
  267. package/src/__tests__/components/EmptyState.test.ts +1 -1
  268. package/src/__tests__/components/ExperimentPopover.test.ts +125 -16
  269. package/src/__tests__/components/ExperimentSelectorModal.test.ts +134 -28
  270. package/src/__tests__/components/FormBuilder.test.ts +49 -167
  271. package/src/__tests__/components/FormSchemaInternal.test.ts +91 -0
  272. package/src/__tests__/components/GeneratedPathInput.test.ts +18 -13
  273. package/src/__tests__/components/GeneratedPluginView.test.ts +60 -25
  274. package/src/__tests__/components/GeneratedResultRenderer.test.ts +6 -4
  275. package/src/__tests__/components/InstrumentStateBadge.test.ts +4 -4
  276. package/src/__tests__/components/InstrumentStatusPanels.test.ts +79 -0
  277. package/src/__tests__/components/JobsStatusTray.test.ts +4 -4
  278. package/src/__tests__/components/NumberInput.test.ts +28 -0
  279. package/src/__tests__/components/{UnitInput.test.ts → NumberInput.units.test.ts} +6 -6
  280. package/src/__tests__/components/PlateEditor.test.ts +108 -108
  281. package/src/__tests__/components/PlateEditorBindingInternal.test.ts +13 -13
  282. package/src/__tests__/components/PlotlyChart.test.ts +1 -1
  283. package/src/__tests__/components/PluginIcon.test.ts +9 -4
  284. package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +16 -29
  285. package/src/__tests__/components/PluginWorkspaceView.internal.test.ts +28 -34
  286. package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +4 -19
  287. package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +1 -6
  288. package/src/__tests__/components/PluginWorkspaceView.test.ts +183 -155
  289. package/src/__tests__/components/PresenceAvatars.test.ts +90 -0
  290. package/src/__tests__/components/ProtocolStep.presentation.test.ts +1 -3
  291. package/src/__tests__/components/ProtocolStepEditor.test.ts +10 -11
  292. package/src/__tests__/components/ProtocolStepParameterField.test.ts +8 -7
  293. package/src/__tests__/components/ResourcePickerListInternal.test.ts +2 -22
  294. package/src/__tests__/components/RetiredStyles.test.ts +0 -18
  295. package/src/__tests__/components/SampleSelector.test.ts +30 -25
  296. package/src/__tests__/components/SecretInput.test.ts +14 -19
  297. package/src/__tests__/components/SequenceProgressBar.test.ts +12 -0
  298. package/src/__tests__/components/SettingsModal.test.ts +76 -84
  299. package/src/__tests__/components/StaleFormBanner.test.ts +48 -0
  300. package/src/__tests__/components/StepWizard.test.ts +11 -0
  301. package/src/__tests__/components/ThemeToggle.test.ts +1 -1
  302. package/src/__tests__/components/WellPlate.decoration.test.ts +20 -11
  303. package/src/__tests__/components/WellPlate.interaction.test.ts +6 -7
  304. package/src/__tests__/components/WellPlate.keyboard.test.ts +2 -2
  305. package/src/__tests__/components/deprecationTags.test.ts +90 -0
  306. package/src/__tests__/composables/analysisArtifactTarget.test.ts +1 -12
  307. package/src/__tests__/composables/autoGroup/classKey.test.ts +1 -1
  308. package/src/__tests__/composables/autoGroup/classify.test.ts +1 -1
  309. package/src/__tests__/composables/autoGroup/columns.test.ts +1 -1
  310. package/src/__tests__/composables/autoGroup/compose.test.ts +1 -1
  311. package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +1 -1
  312. package/src/__tests__/composables/autoGroup/fieldEdits.test.ts +1 -1
  313. package/src/__tests__/composables/autoGroup/fingerprint.test.ts +1 -1
  314. package/src/__tests__/composables/autoGroup/golden.test.ts +1 -1
  315. package/src/__tests__/composables/autoGroup/groupByOrder.test.ts +1 -1
  316. package/src/__tests__/composables/autoGroup/groupTree.test.ts +1 -1
  317. package/src/__tests__/composables/autoGroup/integration.test.ts +1 -1
  318. package/src/__tests__/composables/autoGroup/template.test.ts +1 -1
  319. package/src/__tests__/composables/autoGroup/tokenLength.test.ts +1 -1
  320. package/src/__tests__/composables/autoGroup/tokenize.test.ts +1 -1
  321. package/src/__tests__/composables/{usePluginClient.test.ts → createClient.test.ts} +84 -222
  322. package/src/__tests__/composables/{useEventStream.test.ts → eventStream.test.ts} +6 -6
  323. package/src/__tests__/composables/experiment-utils.test.ts +13 -14
  324. package/src/__tests__/composables/useApi.test.ts +32 -21
  325. package/src/__tests__/composables/useAppExperiment.test.ts +46 -3
  326. package/src/__tests__/composables/{useAnalysisArtifacts.test.ts → useArtifacts.test.ts} +19 -27
  327. package/src/__tests__/composables/useAutoGroup.test.ts +3 -13
  328. package/src/__tests__/composables/useCalendarGrid.test.ts +4 -2
  329. package/src/__tests__/composables/useControlSchema.test.ts +41 -99
  330. package/src/__tests__/composables/useExperiment.test.ts +63 -0
  331. package/src/__tests__/composables/useExperimentSelector.test.ts +111 -0
  332. package/src/__tests__/composables/useFileBrowser.test.ts +4 -6
  333. package/src/__tests__/composables/{useJobsStatusTray.test.ts → useJobCenter.test.ts} +31 -31
  334. package/src/__tests__/composables/{useGeneratedAnalysis.test.ts → useJobsEndpoint.test.ts} +213 -139
  335. package/src/__tests__/composables/usePlatform.test.ts +102 -0
  336. package/src/__tests__/composables/usePresence.test.ts +164 -0
  337. package/src/__tests__/composables/useRackEditor.test.ts +2 -2
  338. package/src/__tests__/composables/useRealtime.test.ts +196 -0
  339. package/src/__tests__/composables/{useRequestSyncState.test.ts → useRequest.test.ts} +32 -47
  340. package/src/__tests__/composables/useVersionedSave.test.ts +194 -0
  341. package/src/__tests__/docs/extractDocsComponents.test.ts +36 -0
  342. package/src/__tests__/docs/extractDocsParsing.test.ts +2 -2
  343. package/src/__tests__/docs/extractDocsTheme.test.ts +1 -46
  344. package/src/__tests__/docs/frontendDocsCatalog.test.ts +164 -84
  345. package/src/__tests__/styles/baseControlsRules.test.ts +7 -3
  346. package/src/__tests__/styles/controlRefreshRules.test.ts +0 -6
  347. package/src/__tests__/styles/cssTokens.test.ts +2 -2
  348. package/src/__tests__/styles/darkModeRules.test.ts +0 -6
  349. package/src/__tests__/styles/menusShellRefresh.test.ts +14 -10
  350. package/src/__tests__/{composables/useChemicalFormula.test.ts → utils/formula.test.ts} +3 -5
  351. package/src/__tests__/utils/permissions.test.ts +1 -36
  352. package/src/__tests__/utils/plotlyTemplate.test.ts +20 -5
  353. package/src/__tests__/{composables/useTimeUtils.test.ts → utils/time.test.ts} +18 -8
  354. package/src/components/ActionMenu.vue +7 -13
  355. package/src/components/AdductText.story.vue +7 -0
  356. package/src/components/AdductText.vue +1 -1
  357. package/src/components/AlertBox.story.vue +27 -27
  358. package/src/components/AlertBox.vue +22 -20
  359. package/src/components/AppLayout.story.vue +33 -44
  360. package/src/components/AppLayout.vue +1 -1
  361. package/src/components/AppSidebar.story.vue +40 -101
  362. package/src/components/AppSidebar.vue +66 -147
  363. package/src/components/AppToastContainer.story.vue +1 -1
  364. package/src/components/AppTopBar.story.vue +97 -111
  365. package/src/components/AppTopBar.vue +170 -290
  366. package/src/components/ArtifactSaveDialog.story.vue +32 -9
  367. package/src/components/ArtifactSaveDialog.vue +125 -38
  368. package/src/components/ArtifactSelectorModal.story.vue +4 -4
  369. package/src/components/ArtifactSelectorModal.vue +10 -10
  370. package/src/components/AuditTrail.story.vue +6 -5
  371. package/src/components/AuditTrail.vue +5 -24
  372. package/src/components/Avatar.story.vue +2 -3
  373. package/src/components/Avatar.vue +11 -16
  374. package/src/components/BaseButton.story.vue +25 -0
  375. package/src/components/BaseButton.vue +39 -10
  376. package/src/components/BaseCheckbox.story.vue +2 -2
  377. package/src/components/{BaseToggle.story.vue → BaseCheckbox.switch.story.vue} +22 -19
  378. package/src/components/BaseCheckbox.vue +39 -7
  379. package/src/components/BaseInput.story.vue +3 -15
  380. package/src/components/{BaseTextarea.story.vue → BaseInput.textarea.story.vue} +14 -10
  381. package/src/components/BaseInput.vue +53 -26
  382. package/src/components/BaseModal.story.vue +11 -11
  383. package/src/components/BaseModal.vue +8 -8
  384. package/src/components/BasePill.story.vue +48 -28
  385. package/src/components/BasePill.vue +22 -11
  386. package/src/components/BaseRadioGroup.story.vue +4 -4
  387. package/src/components/BaseRadioGroup.vue +3 -3
  388. package/src/components/{MultiSelect.story.vue → BaseSelect.multiple.story.vue} +33 -16
  389. package/src/components/{SearchableSelect.story.vue → BaseSelect.searchable.story.vue} +4 -4
  390. package/src/components/BaseSelect.story.vue +2 -2
  391. package/src/components/BaseSelect.vue +118 -22
  392. package/src/components/BaseTabs.story.vue +20 -20
  393. package/src/components/BaseTabs.vue +17 -9
  394. package/src/components/BatchProgressList.vue +38 -28
  395. package/src/components/ChartContainer.story.vue +9 -13
  396. package/src/components/ChartContainer.vue +10 -8
  397. package/src/components/ChemicalFormula.vue +1 -2
  398. package/src/components/CollapsibleCard.vue +5 -4
  399. package/src/components/ComponentBindingRenderer.story.vue +0 -29
  400. package/src/components/ComponentBindingRenderer.vue +15 -39
  401. package/src/components/ConcentrationInput.story.vue +2 -2
  402. package/src/components/ConcentrationInput.vue +9 -9
  403. package/src/components/ConfirmDialog.story.vue +22 -22
  404. package/src/components/ConfirmDialog.vue +15 -14
  405. package/src/components/DataFrame.story.vue +28 -40
  406. package/src/components/DataFrame.vue +112 -128
  407. package/src/components/{DateTimePicker.story.vue → DatePicker.datetime.story.vue} +19 -14
  408. package/src/components/DatePicker.story.vue +2 -2
  409. package/src/components/{TimePicker.story.vue → DatePicker.time.story.vue} +15 -12
  410. package/src/components/DatePicker.vue +82 -220
  411. package/src/components/DoseCalculator.vue +13 -19
  412. package/src/components/DoseCalculatorVolumeField.vue +6 -6
  413. package/src/components/EmptyState.story.vue +17 -17
  414. package/src/components/EmptyState.vue +6 -5
  415. package/src/components/ExperimentPopover.story.vue +165 -53
  416. package/src/components/ExperimentPopover.vue +172 -190
  417. package/src/components/ExperimentSelectorModal.story.vue +43 -39
  418. package/src/components/ExperimentSelectorModal.vue +134 -122
  419. package/src/components/FilePicker.vue +1 -1
  420. package/src/components/FormBuilder.story.vue +9 -4
  421. package/src/components/FormBuilder.vue +46 -253
  422. package/src/components/FormField.story.vue +9 -50
  423. package/src/components/FormulaInput.story.vue +2 -2
  424. package/src/components/FormulaInput.vue +5 -6
  425. package/src/components/GeneratedPathInput.vue +8 -9
  426. package/src/components/GeneratedPluginView.story.vue +1 -1
  427. package/src/components/GeneratedPluginView.vue +29 -22
  428. package/src/components/GeneratedResultRenderer.vue +16 -17
  429. package/src/components/InstrumentStateBadge.vue +1 -1
  430. package/src/components/InstrumentStatusPanels.story.vue +64 -0
  431. package/src/components/InstrumentStatusPanels.vue +133 -0
  432. package/src/components/JobsStatusTray.story.vue +2 -2
  433. package/src/components/JobsStatusTray.vue +5 -20
  434. package/src/components/LoadingSpinner.story.vue +11 -11
  435. package/src/components/LoadingSpinner.vue +7 -5
  436. package/src/components/MoleculeInput.story.vue +2 -2
  437. package/src/components/MoleculeInput.vue +3 -3
  438. package/src/components/NumberInput.story.vue +55 -15
  439. package/src/components/NumberInput.vue +83 -24
  440. package/src/components/PlateEditor.story.vue +51 -43
  441. package/src/components/PlateEditor.vue +97 -128
  442. package/src/components/PlotlyChart.story.vue +1 -1
  443. package/src/components/PlotlyChart.vue +6 -4
  444. package/src/components/PluginIcon.story.vue +6 -11
  445. package/src/components/PluginIcon.vue +7 -2
  446. package/src/components/PluginWorkspaceView.controls.ts +9 -29
  447. package/src/components/PluginWorkspaceView.navigation.ts +2 -23
  448. package/src/components/PluginWorkspaceView.props.ts +17 -151
  449. package/src/components/PluginWorkspaceView.shell.ts +13 -24
  450. package/src/components/PluginWorkspaceView.story.vue +65 -63
  451. package/src/components/PluginWorkspaceView.vue +21 -78
  452. package/src/components/PresenceAvatars.story.vue +75 -0
  453. package/src/components/PresenceAvatars.vue +114 -0
  454. package/src/components/ProgressBar.story.vue +7 -7
  455. package/src/components/ProgressBar.vue +4 -3
  456. package/src/components/ProtocolStep.presentation.ts +0 -11
  457. package/src/components/ProtocolStepEditor.vue +6 -5
  458. package/src/components/ProtocolStepParameterField.vue +15 -12
  459. package/src/components/RuntimeUpdateNotice.vue +1 -1
  460. package/src/components/SampleSelector.colors.ts +1 -1
  461. package/src/components/SampleSelector.story.vue +1 -1
  462. package/src/components/SampleSelector.vue +33 -43
  463. package/src/components/SampleSelectorGroupNode.vue +1 -1
  464. package/src/components/ScheduleCalendar.vue +4 -4
  465. package/src/components/SecretInput.story.vue +1 -1
  466. package/src/components/SecretInput.vue +16 -25
  467. package/src/components/SectionCard.story.vue +2 -2
  468. package/src/components/SegmentedControl.story.vue +7 -7
  469. package/src/components/SegmentedControl.vue +5 -3
  470. package/src/components/SequenceInput.story.vue +2 -2
  471. package/src/components/SequenceInput.vue +3 -3
  472. package/src/components/SequenceProgressBar.story.vue +9 -0
  473. package/src/components/SequenceProgressBar.vue +6 -1
  474. package/src/components/SettingsModal.schema.ts +1 -1
  475. package/src/components/SettingsModal.story.vue +13 -14
  476. package/src/components/SettingsModal.vue +31 -49
  477. package/src/components/SmartGroup.types.ts +4 -6
  478. package/src/components/SmartGroupFieldRecipe.story.vue +1 -1
  479. package/src/components/SmartGroupFieldRecipe.vue +7 -5
  480. package/src/components/SmartGroupManual.story.vue +1 -1
  481. package/src/components/StaleFormBanner.story.vue +90 -0
  482. package/src/components/StaleFormBanner.vue +83 -0
  483. package/src/components/StepWizard.story.vue +33 -0
  484. package/src/components/StepWizard.vue +8 -1
  485. package/src/components/TagsInput.story.vue +7 -7
  486. package/src/components/TagsInput.vue +7 -6
  487. package/src/components/ThemeToggle.vue +5 -30
  488. package/src/components/TimeRangeInput.story.vue +1 -1
  489. package/src/components/TimeRangeInput.vue +10 -8
  490. package/src/components/VersionConflictDialog.story.vue +60 -0
  491. package/src/components/VersionConflictDialog.vue +79 -0
  492. package/src/components/WellPlate.geometry.ts +0 -38
  493. package/src/components/WellPlate.rendering.ts +0 -13
  494. package/src/components/WellPlate.story.vue +64 -51
  495. package/src/components/WellPlate.vue +68 -87
  496. package/src/components/index.ts +3 -105
  497. package/src/components/internal/AppTopBarPillNavInternal.vue +33 -2
  498. package/src/components/{AutoGroupModal.adapter.ts → internal/AutoGroupModalInternal.adapter.ts} +8 -8
  499. package/src/components/{AutoGroupModal.vue → internal/AutoGroupModalInternal.vue} +23 -23
  500. package/src/components/{BaseToggle.vue → internal/CheckboxSwitchInternal.vue} +8 -8
  501. package/src/components/internal/DataStateInternal.vue +1 -1
  502. package/src/components/internal/DatePickerDateInternal.vue +219 -0
  503. package/src/components/{DateTimePicker.vue → internal/DatePickerDateTimeInternal.vue} +12 -22
  504. package/src/components/{TimePicker.vue → internal/DatePickerTimeInternal.vue} +12 -15
  505. package/src/components/internal/FilePickerListInternal.vue +8 -14
  506. package/src/components/{FormActions.vue → internal/FormActionsInternal.vue} +2 -2
  507. package/src/components/internal/FormFieldRendererInternal.vue +1 -1
  508. package/src/components/internal/FormSchemaInternal.vue +253 -0
  509. package/src/components/{UnitInput.vue → internal/NumberUnitInputInternal.vue} +28 -28
  510. package/src/components/internal/PlateEditorBindingInternal.vue +8 -7
  511. package/src/components/internal/ResourcePickerListInternal.vue +48 -88
  512. package/src/components/internal/SelectMultipleInternal.vue +242 -0
  513. package/src/components/{SearchableSelect.vue → internal/SelectSearchableInternal.vue} +26 -11
  514. package/src/components/internal/WellEditPopupInternal.vue +4 -9
  515. package/src/components/internal/WorkspaceShellInternal.vue +3 -36
  516. package/src/components/internal/WorkspaceSidebarInternal.vue +4 -25
  517. package/src/{composables → components/internal}/autoGroup/classKey.ts +1 -1
  518. package/src/{composables → components/internal}/autoGroup/classify.ts +1 -1
  519. package/src/{composables → components/internal}/autoGroup/columns.ts +1 -1
  520. package/src/{composables → components/internal}/autoGroup/compose.ts +3 -3
  521. package/src/{composables → components/internal}/autoGroup/cooccurrence.ts +1 -1
  522. package/src/{composables → components/internal}/autoGroup/csv-shim.ts +1 -1
  523. package/src/{composables → components/internal}/autoGroup/fingerprint.ts +1 -1
  524. package/src/{composables → components/internal}/autoGroup/index.ts +1 -2
  525. package/src/{composables → components/internal}/autoGroup/template.ts +1 -1
  526. package/src/{composables → components/internal}/autoGroup/tokenLength.ts +1 -1
  527. package/src/components/internal/generatedJobsApi.ts +1 -1
  528. package/src/{composables → components/internal}/useAutoGroup.ts +3 -57
  529. package/src/composables/componentSpecs.ts +62 -0
  530. package/src/composables/controlComponentBindings.ts +7 -0
  531. package/src/composables/controlSchemaAdapters.ts +45 -7
  532. package/src/composables/controlSchemaDoseDesign.ts +16 -5
  533. package/src/composables/controlSchemaModel.ts +1 -1
  534. package/src/composables/controlSchemaTypes.ts +31 -22
  535. package/src/composables/{usePluginClient.ts → createClient.ts} +54 -190
  536. package/src/composables/{useEventStream.ts → eventStream.ts} +3 -3
  537. package/src/composables/experiment-utils.ts +1 -39
  538. package/src/composables/formBuilderRegistry.ts +6 -12
  539. package/src/composables/index.ts +17 -480
  540. package/src/composables/platformContextHelpers.ts +0 -57
  541. package/src/composables/pluginEndpointBuilder.ts +8 -10
  542. package/src/composables/pluginIdentity.ts +31 -0
  543. package/src/composables/pluginWorkspaceModel.ts +16 -107
  544. package/src/composables/useApi.ts +18 -30
  545. package/src/composables/useAppExperiment.ts +26 -5
  546. package/src/composables/{useAnalysisArtifacts.ts → useArtifacts.ts} +18 -19
  547. package/src/composables/useCalendarGrid.ts +4 -3
  548. package/src/composables/useControlSchema.ts +5 -9
  549. package/src/composables/useControlWorkspace.ts +4 -7
  550. package/src/composables/useExperiment.ts +49 -0
  551. package/src/composables/useExperimentData.ts +4 -4
  552. package/src/composables/useExperimentSelector.ts +82 -36
  553. package/src/composables/useFileBrowser.ts +5 -13
  554. package/src/composables/useFilePicker.ts +2 -2
  555. package/src/composables/useFormBuilder.ts +3 -4
  556. package/src/composables/useJobCenter.ts +324 -0
  557. package/src/composables/{useGeneratedAnalysis.ts → useJobsEndpoint.ts} +53 -67
  558. package/src/composables/useMenuKeyboard.ts +1 -1
  559. package/src/composables/usePlatform.ts +95 -0
  560. package/src/composables/usePlatformFilePickerAdapter.ts +2 -1
  561. package/src/composables/usePluginWorkspace.ts +62 -107
  562. package/src/composables/usePresence.ts +110 -0
  563. package/src/composables/useRackEditor.ts +3 -3
  564. package/src/composables/useRealtime.ts +194 -0
  565. package/src/composables/{useRequestSyncState.ts → useRequest.ts} +25 -48
  566. package/src/composables/useScheduleCalendarLayout.ts +1 -1
  567. package/src/composables/useToast.ts +14 -11
  568. package/src/composables/useVersionedSave.ts +165 -0
  569. package/src/data.ts +130 -0
  570. package/src/deprecatedRootExports.ts +226 -0
  571. package/src/generated/schema.ts +1 -0
  572. package/src/host.ts +27 -0
  573. package/src/index.ts +2 -71
  574. package/src/install.ts +15 -2
  575. package/src/instrument.ts +1 -6
  576. package/src/lab.ts +128 -0
  577. package/src/permissions.ts +0 -27
  578. package/src/runtime.ts +145 -0
  579. package/src/shell.ts +103 -0
  580. package/src/stores/auth.ts +26 -162
  581. package/src/stores/experiment.ts +27 -1
  582. package/src/styles/components/action-menu.css +0 -5
  583. package/src/styles/components/adduct-text.css +13 -5
  584. package/src/styles/components/alert-box.css +39 -40
  585. package/src/styles/components/app-layout.css +6 -5
  586. package/src/styles/components/app-page-selector.css +3 -1
  587. package/src/styles/components/app-pill-nav.css +11 -12
  588. package/src/styles/components/app-sidebar.css +9 -18
  589. package/src/styles/components/app-top-bar.css +64 -103
  590. package/src/styles/components/artifact-save-dialog.css +153 -2
  591. package/src/styles/components/audit-trail.css +16 -19
  592. package/src/styles/components/avatar.css +6 -4
  593. package/src/styles/components/batch-progress-list.css +38 -36
  594. package/src/styles/components/button.css +40 -59
  595. package/src/styles/components/calendar.css +12 -12
  596. package/src/styles/components/chart-container.css +34 -23
  597. package/src/styles/components/checkbox.css +3 -13
  598. package/src/styles/components/collapsible-card.css +28 -30
  599. package/src/styles/components/confirm-dialog.css +31 -16
  600. package/src/styles/components/dataframe.css +12 -4
  601. package/src/styles/components/date-picker.css +80 -92
  602. package/src/styles/components/datetime-picker.css +31 -43
  603. package/src/styles/components/divider.css +20 -20
  604. package/src/styles/components/dose-calculator.css +3 -3
  605. package/src/styles/components/empty-state.css +23 -18
  606. package/src/styles/components/experiment-code-badge.css +2 -0
  607. package/src/styles/components/experiment-popover.css +174 -329
  608. package/src/styles/components/experiment-selector-modal.css +75 -56
  609. package/src/styles/components/file-picker.css +4 -4
  610. package/src/styles/components/file-uploader.css +38 -49
  611. package/src/styles/components/form-builder.css +3 -3
  612. package/src/styles/components/formula-input.css +1 -1
  613. package/src/styles/components/icon-button.css +19 -25
  614. package/src/styles/components/input.css +5 -4
  615. package/src/styles/components/instrument-monitor.css +13 -15
  616. package/src/styles/components/jobs-status-tray.css +31 -25
  617. package/src/styles/components/loading-spinner.css +9 -12
  618. package/src/styles/components/modal.css +2 -4
  619. package/src/styles/components/molecule-input.css +2 -2
  620. package/src/styles/components/multi-select.css +65 -112
  621. package/src/styles/components/number-input.css +26 -19
  622. package/src/styles/components/pill.css +43 -37
  623. package/src/styles/components/plate-editor.css +0 -1
  624. package/src/styles/components/plugin-icon.css +34 -22
  625. package/src/styles/components/popover.css +2 -2
  626. package/src/styles/components/presence-avatars.css +194 -0
  627. package/src/styles/components/progress-bar.css +2 -0
  628. package/src/styles/components/protocol-step-editor.css +1 -3
  629. package/src/styles/components/resource-card.css +2 -2
  630. package/src/styles/components/resource-picker-list.css +6 -57
  631. package/src/styles/components/sample-hierarchy-tree.css +4 -4
  632. package/src/styles/components/sample-selector.css +95 -79
  633. package/src/styles/components/schedule-calendar.css +8 -8
  634. package/src/styles/components/searchable-select.css +15 -12
  635. package/src/styles/components/section-card.css +28 -47
  636. package/src/styles/components/segmented-control.css +18 -15
  637. package/src/styles/components/select.css +3 -3
  638. package/src/styles/components/sequence-input.css +2 -2
  639. package/src/styles/components/sequence-progress-bar.css +17 -8
  640. package/src/styles/components/smart-group.css +19 -24
  641. package/src/styles/components/step-wizard.css +52 -16
  642. package/src/styles/components/tabs.css +2 -2
  643. package/src/styles/components/textarea.css +4 -4
  644. package/src/styles/components/time-picker.css +36 -21
  645. package/src/styles/components/toast.css +12 -10
  646. package/src/styles/components/toggle.css +3 -13
  647. package/src/styles/components/tooltip.css +10 -9
  648. package/src/styles/components/unit-input.css +8 -7
  649. package/src/styles/components/version-conflict.css +122 -0
  650. package/src/styles/components/well-plate.css +8 -8
  651. package/src/styles/index.css +2 -11
  652. package/src/styles/variables.css +107 -602
  653. package/src/types/analysisArtifactTypes.ts +1 -1
  654. package/src/types/auth.ts +0 -10
  655. package/src/types/componentLabTypes.ts +103 -53
  656. package/src/types/componentWorkflowTypes.ts +4 -33
  657. package/src/types/components.ts +148 -114
  658. package/src/types/form-builder.ts +4 -0
  659. package/src/types/generated/platformContext.ts +60 -0
  660. package/src/types/generated-ui.ts +6 -2
  661. package/src/types/index.ts +15 -53
  662. package/src/types/instrument.ts +27 -0
  663. package/src/types/platform.ts +25 -89
  664. package/src/utils/color.ts +1 -12
  665. package/src/utils/dose.ts +335 -0
  666. package/src/utils/experimentStatus.ts +43 -0
  667. package/src/utils/formula.ts +292 -0
  668. package/src/utils/integrationHost.ts +27 -0
  669. package/src/utils/plotlyTemplate.ts +6 -0
  670. package/src/utils/pluginSecrets.ts +23 -23
  671. package/src/utils/presenceAvatars.ts +53 -0
  672. package/src/utils/records.ts +0 -5
  673. package/src/{composables/useTimeUtils.ts → utils/time.ts} +21 -21
  674. package/dist/ResourcePickerListInternal-CFAw4vTZ.js +0 -605
  675. package/dist/ResourcePickerListInternal-CFAw4vTZ.js.map +0 -1
  676. package/dist/__tests__/composables/useBioTemplatePackWorkspace.test.d.ts +0 -1
  677. package/dist/__tests__/composables/useBioTemplatePresetWorkspace.test.d.ts +0 -1
  678. package/dist/__tests__/composables/useBioTemplateWorkspace.test.d.ts +0 -1
  679. package/dist/__tests__/composables/useChemicalFormula.test.d.ts +0 -1
  680. package/dist/__tests__/composables/useEventStream.test.d.ts +0 -1
  681. package/dist/__tests__/composables/useExperimentSave.test.d.ts +0 -1
  682. package/dist/__tests__/composables/useGeneratedAnalysis.test.d.ts +0 -1
  683. package/dist/__tests__/composables/useGroupAssignment.test.d.ts +0 -1
  684. package/dist/__tests__/composables/useJobsStatusTray.test.d.ts +0 -1
  685. package/dist/__tests__/composables/useMobileSupportGate.test.d.ts +0 -1
  686. package/dist/__tests__/composables/usePlatformContext.test.d.ts +0 -1
  687. package/dist/__tests__/composables/usePluginClient.test.d.ts +0 -1
  688. package/dist/__tests__/composables/usePresenceHeartbeat.test.d.ts +0 -1
  689. package/dist/__tests__/composables/useRequestSyncState.test.d.ts +0 -1
  690. package/dist/__tests__/composables/useRuntimeAlignment.test.d.ts +0 -1
  691. package/dist/__tests__/composables/useTemplateCollection.test.d.ts +0 -1
  692. package/dist/__tests__/composables/useTimeUtils.test.d.ts +0 -1
  693. package/dist/__tests__/docs/extractDocsTemplates.test.d.ts +0 -1
  694. package/dist/__tests__/templates/templates.test.d.ts +0 -1
  695. package/dist/__tests__/templates/templatesDeprecation.test.d.ts +0 -1
  696. package/dist/__tests__/utils/lcms.test.d.ts +0 -1
  697. package/dist/__tests__/utils/rack.test.d.ts +0 -1
  698. package/dist/components/AppAvatarMenu.vue.d.ts +0 -47
  699. package/dist/components/AppTopBar.navigation.d.ts +0 -10
  700. package/dist/components/BaseTextarea.vue.d.ts +0 -31
  701. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +0 -112
  702. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +0 -86
  703. package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +0 -80
  704. package/dist/components/BioTemplateRenderer.vue.d.ts +0 -30
  705. package/dist/components/ControlWorkspaceView.vue.d.ts +0 -138
  706. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +0 -140
  707. package/dist/components/ExperimentDataViewer.vue.d.ts +0 -54
  708. package/dist/components/ExperimentTimeline.vue.d.ts +0 -70
  709. package/dist/components/FitPanel.vue.d.ts +0 -56
  710. package/dist/components/GroupAssigner.vue.d.ts +0 -26
  711. package/dist/components/IconButton.vue.d.ts +0 -30
  712. package/dist/components/MobileSupportGate.vue.d.ts +0 -32
  713. package/dist/components/ReagentEditor.vue.d.ts +0 -31
  714. package/dist/components/ReagentList.presentation.d.ts +0 -17
  715. package/dist/components/ReagentList.vue.d.ts +0 -58
  716. package/dist/components/SampleLegend.vue.d.ts +0 -33
  717. package/dist/components/SmartGroupModal.vue.d.ts +0 -29
  718. package/dist/components/index.js +0 -5
  719. package/dist/components-BOA5e7kb.js +0 -23137
  720. package/dist/components-BOA5e7kb.js.map +0 -1
  721. package/dist/composables/flattenWorkspaceBindings.d.ts +0 -61
  722. package/dist/composables/index.js +0 -7
  723. package/dist/composables/useBioTemplateComponents.d.ts +0 -34
  724. package/dist/composables/useBioTemplateControls.d.ts +0 -10
  725. package/dist/composables/useBioTemplatePackWorkspace.d.ts +0 -56
  726. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +0 -79
  727. package/dist/composables/useBioTemplateWorkspace.d.ts +0 -39
  728. package/dist/composables/useExperimentSave.d.ts +0 -69
  729. package/dist/composables/useGroupAssignment.d.ts +0 -35
  730. package/dist/composables/useJobsStatusTray.d.ts +0 -87
  731. package/dist/composables/useMobileSupportGate.d.ts +0 -14
  732. package/dist/composables/usePlatformContext.d.ts +0 -218
  733. package/dist/composables/usePresenceHeartbeat.d.ts +0 -49
  734. package/dist/composables/useRuntimeAlignment.d.ts +0 -44
  735. package/dist/composables/useTemplateCollection.d.ts +0 -62
  736. package/dist/composables/workspaceRecipes.d.ts +0 -189
  737. package/dist/composables-izSQH8Ky.js +0 -591
  738. package/dist/composables-izSQH8Ky.js.map +0 -1
  739. package/dist/experiment-D49y_Kro.js +0 -459
  740. package/dist/experiment-D49y_Kro.js.map +0 -1
  741. package/dist/experiment-utils-DTANyVKV.js.map +0 -1
  742. package/dist/install.js.map +0 -1
  743. package/dist/lcms.d.ts +0 -38
  744. package/dist/settings-BG6v13Zq.js +0 -341
  745. package/dist/settings-BG6v13Zq.js.map +0 -1
  746. package/dist/tailwind.preset.d.ts +0 -63
  747. package/dist/tailwind.preset.js +0 -71
  748. package/dist/tailwind.preset.js.map +0 -1
  749. package/dist/templates/adapters.d.ts +0 -19
  750. package/dist/templates/assayLookups.d.ts +0 -3
  751. package/dist/templates/assayMatrixAdapters.d.ts +0 -13
  752. package/dist/templates/assayMatrixBuilder.d.ts +0 -3
  753. package/dist/templates/assayNormalizers.d.ts +0 -4
  754. package/dist/templates/builderIdUtils.d.ts +0 -4
  755. package/dist/templates/builderPresetControls.d.ts +0 -11
  756. package/dist/templates/builderReadUtils.d.ts +0 -8
  757. package/dist/templates/builders.d.ts +0 -26
  758. package/dist/templates/calibrationCurveAdapters.d.ts +0 -7
  759. package/dist/templates/calibrationCurveBuilder.d.ts +0 -3
  760. package/dist/templates/calibrationNormalizers.d.ts +0 -5
  761. package/dist/templates/catalog.d.ts +0 -192
  762. package/dist/templates/componentBindingCatalog.d.ts +0 -25
  763. package/dist/templates/componentBindingHelpers.d.ts +0 -17
  764. package/dist/templates/componentBindings.d.ts +0 -97
  765. package/dist/templates/componentDoseResponseProps.d.ts +0 -3
  766. package/dist/templates/componentGenericProps.d.ts +0 -8
  767. package/dist/templates/componentPlateHelpers.d.ts +0 -11
  768. package/dist/templates/componentPlateMapProps.d.ts +0 -3
  769. package/dist/templates/componentPropsFactory.d.ts +0 -3
  770. package/dist/templates/componentQpcrPlateProps.d.ts +0 -3
  771. package/dist/templates/componentTargetResolvers.d.ts +0 -5
  772. package/dist/templates/componentTemplateProps.d.ts +0 -3
  773. package/dist/templates/controlSchemaClone.d.ts +0 -4
  774. package/dist/templates/controlSchemaConstants.d.ts +0 -10
  775. package/dist/templates/controlSchemaMerge.d.ts +0 -3
  776. package/dist/templates/controlSchemaTargets.d.ts +0 -17
  777. package/dist/templates/controlSchemaTypes.d.ts +0 -4
  778. package/dist/templates/controlSchemas.d.ts +0 -34
  779. package/dist/templates/defaultBioTemplateBuilder.d.ts +0 -3
  780. package/dist/templates/doseResponseAdapters.d.ts +0 -6
  781. package/dist/templates/doseResponseBuilder.d.ts +0 -3
  782. package/dist/templates/elisaAssayCollectionBuilder.d.ts +0 -3
  783. package/dist/templates/flowCytometryAssayCollectionBuilder.d.ts +0 -3
  784. package/dist/templates/flowCytometryPanelBuilder.d.ts +0 -3
  785. package/dist/templates/flowNormalizers.d.ts +0 -8
  786. package/dist/templates/flowPanelAdapters.d.ts +0 -7
  787. package/dist/templates/index.d.ts +0 -15
  788. package/dist/templates/index.js +0 -2
  789. package/dist/templates/instrumentRunAdapterHelpers.d.ts +0 -8
  790. package/dist/templates/instrumentRunAdapters.d.ts +0 -19
  791. package/dist/templates/instrumentRunBuilder.d.ts +0 -3
  792. package/dist/templates/lcmsBatchCollectionBuilder.d.ts +0 -3
  793. package/dist/templates/lookup.d.ts +0 -4
  794. package/dist/templates/packs.d.ts +0 -21
  795. package/dist/templates/plateMapAdapters.d.ts +0 -5
  796. package/dist/templates/plateMapBuilder.d.ts +0 -3
  797. package/dist/templates/presetControlSchemas.d.ts +0 -534
  798. package/dist/templates/presets.d.ts +0 -106
  799. package/dist/templates/protocolAdapters.d.ts +0 -9
  800. package/dist/templates/protocolNormalizers.d.ts +0 -6
  801. package/dist/templates/protocolStepsBuilder.d.ts +0 -3
  802. package/dist/templates/qpcrAdapters.d.ts +0 -9
  803. package/dist/templates/qpcrExpressionCollectionBuilder.d.ts +0 -3
  804. package/dist/templates/qpcrPlateBuilder.d.ts +0 -3
  805. package/dist/templates/reagentAdapters.d.ts +0 -9
  806. package/dist/templates/reagentListBuilder.d.ts +0 -3
  807. package/dist/templates/runNormalizers.d.ts +0 -10
  808. package/dist/templates/sampleNormalizers.d.ts +0 -4
  809. package/dist/templates/samplePrepAdapters.d.ts +0 -7
  810. package/dist/templates/samplePrepBuilder.d.ts +0 -3
  811. package/dist/templates/sampleSheetAdapters.d.ts +0 -9
  812. package/dist/templates/sampleSheetBuilder.d.ts +0 -3
  813. package/dist/templates/targetedMetabolomicsCollectionBuilder.d.ts +0 -3
  814. package/dist/templates/targetedMetabolomicsHelpers.d.ts +0 -5
  815. package/dist/templates/templateAdapterTypes.d.ts +0 -48
  816. package/dist/templates/templateControlSchemas.d.ts +0 -400
  817. package/dist/templates/templateCreateOptions.d.ts +0 -165
  818. package/dist/templates/templateEnvelopes.d.ts +0 -17
  819. package/dist/templates/templatePackCollectionBuilder.d.ts +0 -3
  820. package/dist/templates/templatePresetCollectionBuilder.d.ts +0 -20
  821. package/dist/templates/templateQpcrTypes.d.ts +0 -42
  822. package/dist/templates/templateValidators.d.ts +0 -25
  823. package/dist/templates/timeCourseAdapters.d.ts +0 -9
  824. package/dist/templates/timeCourseBuilder.d.ts +0 -3
  825. package/dist/templates/types.d.ts +0 -304
  826. package/dist/templates/wellPlateScreenCollectionBuilder.d.ts +0 -3
  827. package/dist/templates/westernBlotAssayCollectionBuilder.d.ts +0 -3
  828. package/dist/templates-B2DB0MCM.js +0 -12304
  829. package/dist/templates-B2DB0MCM.js.map +0 -1
  830. package/dist/utils/rack.d.ts +0 -63
  831. package/dist/validation-C_eH_vIg.js +0 -7999
  832. package/dist/validation-C_eH_vIg.js.map +0 -1
  833. package/src/__tests__/components/AppAvatarMenu.test.ts +0 -186
  834. package/src/__tests__/components/AppTopBar.navigation.test.ts +0 -68
  835. package/src/__tests__/components/AppTopBarPresence.test.ts +0 -47
  836. package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +0 -159
  837. package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +0 -192
  838. package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +0 -307
  839. package/src/__tests__/components/BioTemplateRenderer.test.ts +0 -96
  840. package/src/__tests__/components/ControlWorkspaceView.test.ts +0 -1100
  841. package/src/__tests__/components/DoseDesignWorkspaceView.test.ts +0 -183
  842. package/src/__tests__/components/ExperimentTimeline.test.ts +0 -108
  843. package/src/__tests__/components/FitPanel.test.ts +0 -96
  844. package/src/__tests__/components/GroupAssigner.test.ts +0 -101
  845. package/src/__tests__/components/MobileSupportGate.test.ts +0 -120
  846. package/src/__tests__/components/MultiSelect.test.ts +0 -54
  847. package/src/__tests__/components/ReagentList.presentation.test.ts +0 -73
  848. package/src/__tests__/components/ReagentList.test.ts +0 -167
  849. package/src/__tests__/components/SampleLegend.test.ts +0 -18
  850. package/src/__tests__/components/SmartGroupModal.test.ts +0 -69
  851. package/src/__tests__/components/WellPlate.sampleTypeIndicator.test.ts +0 -58
  852. package/src/__tests__/components/iconButtonIconSizing.test.ts +0 -18
  853. package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +0 -125
  854. package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +0 -199
  855. package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +0 -104
  856. package/src/__tests__/composables/useExperimentSave.test.ts +0 -542
  857. package/src/__tests__/composables/useGroupAssignment.test.ts +0 -73
  858. package/src/__tests__/composables/useMobileSupportGate.test.ts +0 -74
  859. package/src/__tests__/composables/usePlatformContext.test.ts +0 -148
  860. package/src/__tests__/composables/usePresenceHeartbeat.test.ts +0 -164
  861. package/src/__tests__/composables/useRuntimeAlignment.test.ts +0 -145
  862. package/src/__tests__/composables/useTemplateCollection.test.ts +0 -147
  863. package/src/__tests__/docs/extractDocsTemplates.test.ts +0 -53
  864. package/src/__tests__/fixtures/templates/dose-response.json +0 -81
  865. package/src/__tests__/fixtures/templates/plate-map.json +0 -54
  866. package/src/__tests__/fixtures/templates/qpcr-plate.json +0 -96
  867. package/src/__tests__/fixtures/templates/sample-sheet.json +0 -71
  868. package/src/__tests__/templates/templates.test.ts +0 -1235
  869. package/src/__tests__/templates/templatesDeprecation.test.ts +0 -78
  870. package/src/__tests__/utils/lcms.test.ts +0 -73
  871. package/src/__tests__/utils/rack.test.ts +0 -120
  872. package/src/components/AppAvatarMenu.story.vue +0 -155
  873. package/src/components/AppAvatarMenu.vue +0 -154
  874. package/src/components/AppTopBar.navigation.ts +0 -60
  875. package/src/components/AutoGroupModal.story.vue +0 -458
  876. package/src/components/BaseTextarea.vue +0 -58
  877. package/src/components/BioTemplateExperimentWorkspaceView.story.vue +0 -123
  878. package/src/components/BioTemplateExperimentWorkspaceView.vue +0 -339
  879. package/src/components/BioTemplatePackWorkspaceView.story.vue +0 -107
  880. package/src/components/BioTemplatePackWorkspaceView.vue +0 -180
  881. package/src/components/BioTemplatePresetWorkspaceView.story.vue +0 -163
  882. package/src/components/BioTemplatePresetWorkspaceView.vue +0 -403
  883. package/src/components/BioTemplateRenderer.story.vue +0 -57
  884. package/src/components/BioTemplateRenderer.vue +0 -64
  885. package/src/components/ControlWorkspaceView.story.vue +0 -347
  886. package/src/components/ControlWorkspaceView.vue +0 -370
  887. package/src/components/DoseDesignWorkspaceView.story.vue +0 -77
  888. package/src/components/DoseDesignWorkspaceView.vue +0 -243
  889. package/src/components/ExperimentDataViewer.story.vue +0 -177
  890. package/src/components/ExperimentDataViewer.vue +0 -313
  891. package/src/components/ExperimentTimeline.story.vue +0 -208
  892. package/src/components/ExperimentTimeline.vue +0 -383
  893. package/src/components/FitPanel.story.vue +0 -191
  894. package/src/components/FitPanel.vue +0 -168
  895. package/src/components/FormActions.story.vue +0 -96
  896. package/src/components/GroupAssigner.story.vue +0 -83
  897. package/src/components/GroupAssigner.vue +0 -319
  898. package/src/components/IconButton.story.vue +0 -140
  899. package/src/components/IconButton.vue +0 -69
  900. package/src/components/MobileSupportGate.story.vue +0 -52
  901. package/src/components/MobileSupportGate.vue +0 -111
  902. package/src/components/MultiSelect.vue +0 -119
  903. package/src/components/ReagentEditor.story.vue +0 -153
  904. package/src/components/ReagentEditor.vue +0 -414
  905. package/src/components/ReagentList.presentation.ts +0 -106
  906. package/src/components/ReagentList.story.vue +0 -155
  907. package/src/components/ReagentList.vue +0 -438
  908. package/src/components/SampleLegend.story.vue +0 -91
  909. package/src/components/SampleLegend.vue +0 -121
  910. package/src/components/SmartGroupModal.story.vue +0 -61
  911. package/src/components/SmartGroupModal.vue +0 -61
  912. package/src/components/StatusIndicator.story.vue +0 -99
  913. package/src/components/StatusIndicator.vue +0 -36
  914. package/src/components/UnitInput.story.vue +0 -194
  915. package/src/composables/flattenWorkspaceBindings.ts +0 -104
  916. package/src/composables/useBioTemplateComponents.ts +0 -117
  917. package/src/composables/useBioTemplateControls.ts +0 -45
  918. package/src/composables/useBioTemplatePackWorkspace.ts +0 -201
  919. package/src/composables/useBioTemplatePresetWorkspace.ts +0 -329
  920. package/src/composables/useBioTemplateWorkspace.ts +0 -120
  921. package/src/composables/useChemicalFormula.ts +0 -301
  922. package/src/composables/useDoseCalculator.ts +0 -370
  923. package/src/composables/useExperimentSave.ts +0 -348
  924. package/src/composables/useGroupAssignment.ts +0 -152
  925. package/src/composables/useJobsStatusTray.ts +0 -493
  926. package/src/composables/useMobileSupportGate.ts +0 -80
  927. package/src/composables/usePlatformContext.ts +0 -299
  928. package/src/composables/usePresenceHeartbeat.ts +0 -201
  929. package/src/composables/useRuntimeAlignment.ts +0 -184
  930. package/src/composables/useTemplateCollection.ts +0 -233
  931. package/src/composables/workspaceRecipes.ts +0 -268
  932. package/src/lcms.ts +0 -119
  933. package/src/styles/components/app-avatar-menu.css +0 -121
  934. package/src/styles/components/experiment-data-viewer.css +0 -138
  935. package/src/styles/components/experiment-timeline.css +0 -572
  936. package/src/styles/components/fit-panel.css +0 -153
  937. package/src/styles/components/group-assigner.css +0 -198
  938. package/src/styles/components/mobile-support-gate.css +0 -117
  939. package/src/styles/components/reagent-editor.css +0 -501
  940. package/src/styles/components/reagent-list.css +0 -408
  941. package/src/styles/components/sample-legend.css +0 -212
  942. package/src/styles/components/status-indicator.css +0 -66
  943. package/src/styles/components/theme-toggle.css +0 -6
  944. package/src/tailwind.preset.ts +0 -66
  945. package/src/templates/adapters.ts +0 -141
  946. package/src/templates/assayLookups.ts +0 -33
  947. package/src/templates/assayMatrixAdapters.ts +0 -85
  948. package/src/templates/assayMatrixBuilder.ts +0 -60
  949. package/src/templates/assayNormalizers.ts +0 -34
  950. package/src/templates/builderIdUtils.ts +0 -20
  951. package/src/templates/builderPresetControls.ts +0 -166
  952. package/src/templates/builderReadUtils.ts +0 -55
  953. package/src/templates/builders.ts +0 -122
  954. package/src/templates/calibrationCurveAdapters.ts +0 -62
  955. package/src/templates/calibrationCurveBuilder.ts +0 -100
  956. package/src/templates/calibrationNormalizers.ts +0 -60
  957. package/src/templates/catalog.ts +0 -249
  958. package/src/templates/componentBindingCatalog.ts +0 -90
  959. package/src/templates/componentBindingHelpers.ts +0 -93
  960. package/src/templates/componentBindings.ts +0 -279
  961. package/src/templates/componentDoseResponseProps.ts +0 -41
  962. package/src/templates/componentGenericProps.ts +0 -77
  963. package/src/templates/componentPlateHelpers.ts +0 -52
  964. package/src/templates/componentPlateMapProps.ts +0 -34
  965. package/src/templates/componentPropsFactory.ts +0 -21
  966. package/src/templates/componentQpcrPlateProps.ts +0 -27
  967. package/src/templates/componentTargetResolvers.ts +0 -67
  968. package/src/templates/componentTemplateProps.ts +0 -78
  969. package/src/templates/controlSchemaClone.ts +0 -32
  970. package/src/templates/controlSchemaConstants.ts +0 -11
  971. package/src/templates/controlSchemaMerge.ts +0 -40
  972. package/src/templates/controlSchemaTargets.ts +0 -85
  973. package/src/templates/controlSchemaTypes.ts +0 -20
  974. package/src/templates/controlSchemas.ts +0 -113
  975. package/src/templates/defaultBioTemplateBuilder.ts +0 -125
  976. package/src/templates/doseResponseAdapters.ts +0 -36
  977. package/src/templates/doseResponseBuilder.ts +0 -45
  978. package/src/templates/elisaAssayCollectionBuilder.ts +0 -63
  979. package/src/templates/flowCytometryAssayCollectionBuilder.ts +0 -42
  980. package/src/templates/flowCytometryPanelBuilder.ts +0 -54
  981. package/src/templates/flowNormalizers.ts +0 -58
  982. package/src/templates/flowPanelAdapters.ts +0 -61
  983. package/src/templates/index.ts +0 -330
  984. package/src/templates/instrumentRunAdapterHelpers.ts +0 -94
  985. package/src/templates/instrumentRunAdapters.ts +0 -174
  986. package/src/templates/instrumentRunBuilder.ts +0 -98
  987. package/src/templates/lcmsBatchCollectionBuilder.ts +0 -39
  988. package/src/templates/lookup.ts +0 -18
  989. package/src/templates/packs.ts +0 -166
  990. package/src/templates/plateMapAdapters.ts +0 -38
  991. package/src/templates/plateMapBuilder.ts +0 -44
  992. package/src/templates/presetControlSchemas.ts +0 -258
  993. package/src/templates/presets.ts +0 -183
  994. package/src/templates/protocolAdapters.ts +0 -73
  995. package/src/templates/protocolNormalizers.ts +0 -37
  996. package/src/templates/protocolStepsBuilder.ts +0 -37
  997. package/src/templates/qpcrAdapters.ts +0 -108
  998. package/src/templates/qpcrExpressionCollectionBuilder.ts +0 -34
  999. package/src/templates/qpcrPlateBuilder.ts +0 -97
  1000. package/src/templates/reagentAdapters.ts +0 -81
  1001. package/src/templates/reagentListBuilder.ts +0 -31
  1002. package/src/templates/runNormalizers.ts +0 -63
  1003. package/src/templates/sampleNormalizers.ts +0 -58
  1004. package/src/templates/samplePrepAdapters.ts +0 -66
  1005. package/src/templates/samplePrepBuilder.ts +0 -52
  1006. package/src/templates/sampleSheetAdapters.ts +0 -79
  1007. package/src/templates/sampleSheetBuilder.ts +0 -24
  1008. package/src/templates/targetedMetabolomicsCollectionBuilder.ts +0 -80
  1009. package/src/templates/targetedMetabolomicsHelpers.ts +0 -102
  1010. package/src/templates/templateAdapterTypes.ts +0 -58
  1011. package/src/templates/templateControlSchemas.ts +0 -320
  1012. package/src/templates/templateCreateOptions.ts +0 -208
  1013. package/src/templates/templateEnvelopes.ts +0 -145
  1014. package/src/templates/templatePackCollectionBuilder.ts +0 -24
  1015. package/src/templates/templatePresetCollectionBuilder.ts +0 -141
  1016. package/src/templates/templateQpcrTypes.ts +0 -48
  1017. package/src/templates/templateValidators.ts +0 -426
  1018. package/src/templates/timeCourseAdapters.ts +0 -77
  1019. package/src/templates/timeCourseBuilder.ts +0 -65
  1020. package/src/templates/types.ts +0 -493
  1021. package/src/templates/wellPlateScreenCollectionBuilder.ts +0 -37
  1022. package/src/templates/westernBlotAssayCollectionBuilder.ts +0 -69
  1023. package/src/utils/rack.ts +0 -225
  1024. /package/dist/__tests__/components/{AppAvatarMenu.test.d.ts → BaseButton.test.d.ts} +0 -0
  1025. /package/dist/__tests__/components/{AppTopBar.navigation.test.d.ts → BaseCheckbox.switch.test.d.ts} +0 -0
  1026. /package/dist/__tests__/components/{AppTopBarPresence.test.d.ts → BaseSelect.multiple.test.d.ts} +0 -0
  1027. /package/dist/__tests__/components/{BaseToggle.test.d.ts → BaseSelect.searchable.test.d.ts} +0 -0
  1028. /package/dist/__tests__/components/{BioTemplateExperimentWorkspaceView.test.d.ts → ConfirmDialog.test.d.ts} +0 -0
  1029. /package/dist/__tests__/components/{BioTemplatePackWorkspaceView.test.d.ts → DatePicker.datetime.test.d.ts} +0 -0
  1030. /package/dist/__tests__/components/{BioTemplatePresetWorkspaceView.test.d.ts → DatePicker.time.test.d.ts} +0 -0
  1031. /package/dist/__tests__/components/{BioTemplateRenderer.test.d.ts → FormSchemaInternal.test.d.ts} +0 -0
  1032. /package/dist/__tests__/components/{ControlWorkspaceView.test.d.ts → InstrumentStatusPanels.test.d.ts} +0 -0
  1033. /package/dist/__tests__/components/{DateTimePicker.test.d.ts → NumberInput.units.test.d.ts} +0 -0
  1034. /package/dist/__tests__/components/{DoseDesignWorkspaceView.test.d.ts → PresenceAvatars.test.d.ts} +0 -0
  1035. /package/dist/__tests__/components/{ExperimentTimeline.test.d.ts → StaleFormBanner.test.d.ts} +0 -0
  1036. /package/dist/__tests__/components/{FitPanel.test.d.ts → deprecationTags.test.d.ts} +0 -0
  1037. /package/dist/__tests__/{components/GroupAssigner.test.d.ts → composables/createClient.test.d.ts} +0 -0
  1038. /package/dist/__tests__/{components/MobileSupportGate.test.d.ts → composables/eventStream.test.d.ts} +0 -0
  1039. /package/dist/__tests__/{components/MultiSelect.test.d.ts → composables/useArtifacts.test.d.ts} +0 -0
  1040. /package/dist/__tests__/{components/ReagentList.presentation.test.d.ts → composables/useExperiment.test.d.ts} +0 -0
  1041. /package/dist/__tests__/{components/ReagentList.test.d.ts → composables/useJobCenter.test.d.ts} +0 -0
  1042. /package/dist/__tests__/{components/SampleLegend.test.d.ts → composables/useJobsEndpoint.test.d.ts} +0 -0
  1043. /package/dist/__tests__/{components/SearchableSelect.test.d.ts → composables/usePlatform.test.d.ts} +0 -0
  1044. /package/dist/__tests__/{components/SmartGroupModal.test.d.ts → composables/usePresence.test.d.ts} +0 -0
  1045. /package/dist/__tests__/{components/TimePicker.test.d.ts → composables/useRealtime.test.d.ts} +0 -0
  1046. /package/dist/__tests__/{components/UnitInput.test.d.ts → composables/useRequest.test.d.ts} +0 -0
  1047. /package/dist/__tests__/{components/WellPlate.sampleTypeIndicator.test.d.ts → composables/useVersionedSave.test.d.ts} +0 -0
  1048. /package/dist/__tests__/{components/iconButtonIconSizing.test.d.ts → utils/formula.test.d.ts} +0 -0
  1049. /package/dist/__tests__/{composables/useAnalysisArtifacts.test.d.ts → utils/time.test.d.ts} +0 -0
  1050. /package/dist/components/{FormActions.vue.d.ts → internal/FormActionsInternal.vue.d.ts} +0 -0
  1051. /package/dist/{composables → components/internal}/autoGroup/colors.d.ts +0 -0
  1052. /package/dist/{composables → components/internal}/autoGroup/index.d.ts +0 -0
  1053. /package/dist/{composables → components/internal}/autoGroup/tokenize.d.ts +0 -0
  1054. /package/src/{composables → components/internal}/autoGroup/colors.ts +0 -0
  1055. /package/src/{composables → components/internal}/autoGroup/tokenize.ts +0 -0
  1056. /package/src/{composables → components/internal}/autoGroup/vocab.json +0 -0
@@ -0,0 +1,3268 @@
1
+ import { a as BaseButton_default, i as useEventListener, o as __exportAll, t as useDropdownState } from "./useDropdownState-8yWMu-7_.js";
2
+ import { t as useExperimentStore } from "./experiment-43OJtH7R.js";
3
+ import { Fragment, Teleport, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, guardReactiveProps, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onBeforeUnmount, onScopeDispose, openBlock, provide, ref, renderList, renderSlot, toDisplayString, toValue, unref, useAttrs, useId, useSlots, useTemplateRef, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
4
+ import { Check, ChevronDown, ChevronsUpDown, X } from "lucide-vue-next";
5
+ import { computePosition, flip, offset, shift } from "@floating-ui/dom";
6
+ //#region src/components/BaseInput.vue?vue&type=script&setup=true&lang.ts
7
+ var _hoisted_1$12 = [
8
+ "value",
9
+ "placeholder",
10
+ "disabled",
11
+ "readonly",
12
+ "autofocus",
13
+ "rows",
14
+ "maxlength",
15
+ "aria-invalid",
16
+ "aria-describedby"
17
+ ];
18
+ var _hoisted_2$12 = {
19
+ key: 0,
20
+ class: "mint-input-group__prefix"
21
+ };
22
+ var _hoisted_3$12 = [
23
+ "type",
24
+ "value",
25
+ "placeholder",
26
+ "disabled",
27
+ "readonly",
28
+ "autocomplete",
29
+ "autofocus",
30
+ "maxlength",
31
+ "list",
32
+ "aria-invalid",
33
+ "aria-describedby"
34
+ ];
35
+ var _hoisted_4$9 = {
36
+ key: 1,
37
+ class: "mint-input-group__suffix"
38
+ };
39
+ var _hoisted_5$9 = [
40
+ "type",
41
+ "value",
42
+ "placeholder",
43
+ "disabled",
44
+ "readonly",
45
+ "autocomplete",
46
+ "autofocus",
47
+ "maxlength",
48
+ "list",
49
+ "aria-invalid",
50
+ "aria-describedby"
51
+ ];
52
+ //#endregion
53
+ //#region src/components/BaseInput.vue
54
+ var BaseInput_default = /* @__PURE__ */ defineComponent({
55
+ inheritAttrs: false,
56
+ __name: "BaseInput",
57
+ props: {
58
+ modelValue: {},
59
+ type: { default: "text" },
60
+ placeholder: {},
61
+ disabled: {
62
+ type: Boolean,
63
+ default: false
64
+ },
65
+ readonly: {
66
+ type: Boolean,
67
+ default: false
68
+ },
69
+ invalid: {
70
+ type: Boolean,
71
+ default: false
72
+ },
73
+ size: { default: "md" },
74
+ autocomplete: {},
75
+ autofocus: { type: Boolean },
76
+ maxlength: {},
77
+ list: {},
78
+ ariaDescribedby: {},
79
+ rows: { default: 3 },
80
+ resize: { default: "vertical" }
81
+ },
82
+ emits: [
83
+ "update:modelValue",
84
+ "focus",
85
+ "blur",
86
+ "keydown"
87
+ ],
88
+ setup(__props, { emit: __emit }) {
89
+ /**
90
+ * Renders a styled text `<input>`, or a `<textarea>` with `type="textarea"`; size, invalid, and readonly states.
91
+ * Optional `#prefix` (bare leading glyph, e.g. a search icon) and `#suffix` (neutral unit segment) slots sit inside the field border (input only).
92
+ * Numbers use NumberInput.
93
+ *
94
+ * @example
95
+ * ```vue
96
+ * <BaseInput v-model="name" :invalid="!!nameError" />
97
+ * <BaseInput v-model="notes" type="textarea" :rows="4" />
98
+ * ```
99
+ */
100
+ const props = __props;
101
+ const emit = __emit;
102
+ const attrs = useAttrs();
103
+ const slots = useSlots();
104
+ const wrapped = computed(() => props.type !== "textarea" && Boolean(slots.prefix || slots.suffix));
105
+ /** Wrapped: class/style style the group, every other attribute (id, name, aria-*) stays on the input. */
106
+ const inputAttrs = computed(() => {
107
+ if (!wrapped.value) return attrs;
108
+ const { class: _class, style: _style, ...rest } = attrs;
109
+ return rest;
110
+ });
111
+ function handleInput(event) {
112
+ emit("update:modelValue", event.target.value);
113
+ }
114
+ return (_ctx, _cache) => {
115
+ return __props.type === "textarea" ? (openBlock(), createElementBlock("textarea", mergeProps({ key: 0 }, inputAttrs.value, {
116
+ value: __props.modelValue,
117
+ placeholder: __props.placeholder,
118
+ disabled: __props.disabled,
119
+ readonly: __props.readonly,
120
+ autofocus: __props.autofocus,
121
+ rows: __props.rows,
122
+ maxlength: __props.maxlength,
123
+ "aria-invalid": __props.invalid || void 0,
124
+ "aria-describedby": __props.ariaDescribedby || void 0,
125
+ class: [
126
+ "mint-textarea",
127
+ `mint-textarea--${__props.size}`,
128
+ `mint-textarea--resize-${__props.resize}`,
129
+ __props.invalid ? "mint-textarea--error" : "",
130
+ __props.disabled ? "mint-textarea--disabled" : ""
131
+ ],
132
+ onInput: handleInput,
133
+ onFocus: _cache[0] || (_cache[0] = ($event) => emit("focus", $event)),
134
+ onBlur: _cache[1] || (_cache[1] = ($event) => emit("blur", $event)),
135
+ onKeydown: _cache[2] || (_cache[2] = ($event) => emit("keydown", $event))
136
+ }), null, 16, _hoisted_1$12)) : wrapped.value ? (openBlock(), createElementBlock("div", {
137
+ key: 1,
138
+ class: normalizeClass([
139
+ "mint-input-group",
140
+ `mint-input-group--${__props.size}`,
141
+ __props.invalid ? "mint-input-group--error" : "",
142
+ __props.disabled ? "mint-input-group--disabled" : "",
143
+ unref(attrs).class
144
+ ]),
145
+ style: normalizeStyle(unref(attrs).style)
146
+ }, [
147
+ unref(slots).prefix ? (openBlock(), createElementBlock("span", _hoisted_2$12, [renderSlot(_ctx.$slots, "prefix")])) : createCommentVNode("", true),
148
+ createElementVNode("input", mergeProps(inputAttrs.value, {
149
+ type: __props.type,
150
+ value: __props.modelValue,
151
+ placeholder: __props.placeholder,
152
+ disabled: __props.disabled,
153
+ readonly: __props.readonly,
154
+ autocomplete: __props.autocomplete,
155
+ autofocus: __props.autofocus,
156
+ maxlength: __props.maxlength,
157
+ list: __props.list,
158
+ "aria-invalid": __props.invalid || void 0,
159
+ "aria-describedby": __props.ariaDescribedby || void 0,
160
+ class: [
161
+ "mint-input",
162
+ `mint-input--${__props.size}`,
163
+ "mint-input-group__control"
164
+ ],
165
+ onInput: handleInput,
166
+ onFocus: _cache[3] || (_cache[3] = ($event) => emit("focus", $event)),
167
+ onBlur: _cache[4] || (_cache[4] = ($event) => emit("blur", $event)),
168
+ onKeydown: _cache[5] || (_cache[5] = ($event) => emit("keydown", $event))
169
+ }), null, 16, _hoisted_3$12),
170
+ unref(slots).suffix ? (openBlock(), createElementBlock("span", _hoisted_4$9, [renderSlot(_ctx.$slots, "suffix")])) : createCommentVNode("", true)
171
+ ], 6)) : (openBlock(), createElementBlock("input", mergeProps({ key: 2 }, inputAttrs.value, {
172
+ type: __props.type,
173
+ value: __props.modelValue,
174
+ placeholder: __props.placeholder,
175
+ disabled: __props.disabled,
176
+ readonly: __props.readonly,
177
+ autocomplete: __props.autocomplete,
178
+ autofocus: __props.autofocus,
179
+ maxlength: __props.maxlength,
180
+ list: __props.list,
181
+ "aria-invalid": __props.invalid || void 0,
182
+ "aria-describedby": __props.ariaDescribedby || void 0,
183
+ class: [
184
+ "mint-input",
185
+ `mint-input--${__props.size}`,
186
+ __props.invalid ? "mint-input--error" : "",
187
+ __props.disabled ? "mint-input--disabled" : ""
188
+ ],
189
+ onInput: handleInput,
190
+ onFocus: _cache[6] || (_cache[6] = ($event) => emit("focus", $event)),
191
+ onBlur: _cache[7] || (_cache[7] = ($event) => emit("blur", $event)),
192
+ onKeydown: _cache[8] || (_cache[8] = ($event) => emit("keydown", $event))
193
+ }), null, 16, _hoisted_5$9));
194
+ };
195
+ }
196
+ });
197
+ //#endregion
198
+ //#region src/utils/options.ts
199
+ function normalizeOptionInput(option) {
200
+ if (typeof option === "object") return option;
201
+ return {
202
+ value: option,
203
+ label: String(option)
204
+ };
205
+ }
206
+ function findOptionByDomValue(options, value) {
207
+ return options.find((option) => String(option.value) === value);
208
+ }
209
+ //#endregion
210
+ //#region src/composables/useSelectionLimit.ts
211
+ /** Shared cap logic for chip, tag, and multi-select controls. */
212
+ function useSelectionLimit(options) {
213
+ const count = computed(() => Math.max(0, Math.floor(toValue(options.count) || 0)));
214
+ const max = computed(() => normalizeMax(toValue(options.max)));
215
+ const isLimited = computed(() => max.value !== void 0);
216
+ const remaining = computed(() => {
217
+ if (max.value === void 0) return void 0;
218
+ return Math.max(0, max.value - count.value);
219
+ });
220
+ const isAtLimit = computed(() => remaining.value === 0);
221
+ const canAddMore = computed(() => canAdd(1));
222
+ function canAdd(amount = 1, fromCount = count.value) {
223
+ const normalizedAmount = Math.max(0, Math.floor(amount));
224
+ const normalizedCount = Math.max(0, Math.floor(fromCount));
225
+ if (max.value === void 0) return true;
226
+ return normalizedCount + normalizedAmount <= max.value;
227
+ }
228
+ return {
229
+ count,
230
+ max,
231
+ isLimited,
232
+ isAtLimit,
233
+ canAddMore,
234
+ remaining,
235
+ canAdd
236
+ };
237
+ }
238
+ function normalizeMax(value) {
239
+ if (value === null || value === void 0 || !Number.isFinite(value)) return void 0;
240
+ return Math.max(0, Math.floor(value));
241
+ }
242
+ //#endregion
243
+ //#region src/composables/useListSelection.ts
244
+ /** Shared list-selection state for checkbox lists, sample selectors, and chip selectors. */
245
+ function useListSelection(options) {
246
+ const disabled = computed(() => toValue(options.disabled) ?? false);
247
+ const selectedValues = computed(() => [...toValue(options.selected)]);
248
+ const selectedSet = computed(() => new Set(selectedValues.value));
249
+ const itemValues = computed(() => {
250
+ return (toValue(options.items) ?? []).map((item) => getItemValue(item, options.getValue));
251
+ });
252
+ const selectedCount = computed(() => selectedValues.value.length);
253
+ const itemCount = computed(() => itemValues.value.length);
254
+ const isAllSelected = computed(() => itemValues.value.length > 0 && itemValues.value.every((value) => selectedSet.value.has(value)));
255
+ const selectionLimit = useSelectionLimit({
256
+ count: selectedCount,
257
+ max: options.max
258
+ });
259
+ function isSelected(value) {
260
+ return selectedSet.value.has(value);
261
+ }
262
+ function isFullySelected(values) {
263
+ return values.length > 0 && values.every((value) => selectedSet.value.has(value));
264
+ }
265
+ function isPartiallySelected(values) {
266
+ if (values.length === 0) return false;
267
+ const selected = values.filter((value) => selectedSet.value.has(value)).length;
268
+ return selected > 0 && selected < values.length;
269
+ }
270
+ function selectValues(values) {
271
+ if (disabled.value) return selectedValues.value;
272
+ const missing = uniqueValues(values).filter((value) => !selectedSet.value.has(value));
273
+ if (!selectionLimit.canAdd(missing.length)) return selectedValues.value;
274
+ return [...selectedValues.value, ...missing];
275
+ }
276
+ function toggleValue(value) {
277
+ if (disabled.value) return selectedValues.value;
278
+ if (selectedSet.value.has(value)) return selectedValues.value.filter((selected) => selected !== value);
279
+ if (!selectionLimit.canAddMore.value) return selectedValues.value;
280
+ return [...selectedValues.value, value];
281
+ }
282
+ function toggleValues(values) {
283
+ if (disabled.value) return selectedValues.value;
284
+ const unique = uniqueValues(values);
285
+ if (isFullySelected(unique)) {
286
+ const remove = new Set(unique);
287
+ return selectedValues.value.filter((value) => !remove.has(value));
288
+ }
289
+ return selectValues(unique);
290
+ }
291
+ function selectAll() {
292
+ return selectValues(itemValues.value);
293
+ }
294
+ function toggleAll() {
295
+ if (isAllSelected.value) return clear();
296
+ return selectAll();
297
+ }
298
+ function clear() {
299
+ return disabled.value ? selectedValues.value : [];
300
+ }
301
+ return {
302
+ selectedValues,
303
+ selectedSet,
304
+ itemValues,
305
+ selectedCount,
306
+ itemCount,
307
+ isAllSelected,
308
+ isLimited: selectionLimit.isLimited,
309
+ isAtLimit: selectionLimit.isAtLimit,
310
+ canAddMore: selectionLimit.canAddMore,
311
+ remaining: selectionLimit.remaining,
312
+ isSelected,
313
+ isFullySelected,
314
+ isPartiallySelected,
315
+ selectValues,
316
+ toggleValue,
317
+ toggleValues,
318
+ selectAll,
319
+ toggleAll,
320
+ clear
321
+ };
322
+ }
323
+ function getItemValue(item, getValue) {
324
+ return getValue ? getValue(item) : item;
325
+ }
326
+ function uniqueValues(values) {
327
+ return [...new Set(values)];
328
+ }
329
+ //#endregion
330
+ //#region src/components/internal/SelectMultipleInternal.vue?vue&type=script&setup=true&lang.ts
331
+ var _hoisted_1$11 = [
332
+ "tabindex",
333
+ "aria-expanded",
334
+ "aria-disabled",
335
+ "aria-invalid",
336
+ "aria-labelledby",
337
+ "aria-describedby"
338
+ ];
339
+ var _hoisted_2$11 = { class: "mint-multi-select__chips" };
340
+ var _hoisted_3$11 = ["aria-label", "onClick"];
341
+ var _hoisted_4$8 = {
342
+ key: 0,
343
+ class: "mint-multi-select__placeholder"
344
+ };
345
+ var _hoisted_5$8 = {
346
+ key: 0,
347
+ class: "mint-popover mint-searchable-select__panel"
348
+ };
349
+ var _hoisted_6$8 = { class: "mint-searchable-select__search-wrap" };
350
+ var _hoisted_7$7 = ["aria-expanded", "aria-activedescendant"];
351
+ var _hoisted_8$3 = [
352
+ "id",
353
+ "aria-selected",
354
+ "aria-disabled",
355
+ "onMouseenter",
356
+ "onClick"
357
+ ];
358
+ var _hoisted_9$3 = { class: "mint-menu-item__label" };
359
+ var _hoisted_10$3 = {
360
+ key: 0,
361
+ class: "mint-searchable-select__empty"
362
+ };
363
+ //#endregion
364
+ //#region src/components/internal/SelectMultipleInternal.vue
365
+ var SelectMultipleInternal_default = /* @__PURE__ */ defineComponent({
366
+ inheritAttrs: false,
367
+ __name: "SelectMultipleInternal",
368
+ props: {
369
+ modelValue: {},
370
+ options: {},
371
+ placeholder: { default: "Select options..." },
372
+ disabled: {
373
+ type: Boolean,
374
+ default: false
375
+ },
376
+ invalid: {
377
+ type: Boolean,
378
+ default: false
379
+ },
380
+ max: { default: void 0 },
381
+ size: { default: "md" },
382
+ ariaLabelledby: { default: void 0 },
383
+ ariaDescribedby: { default: void 0 }
384
+ },
385
+ emits: ["update:modelValue"],
386
+ setup(__props, { emit: __emit }) {
387
+ /** BaseSelect with `multiple`: a field of removable chips that opens a filterable checkbox listbox, capped by `max`. */
388
+ const props = __props;
389
+ const attrs = useAttrs();
390
+ const fieldAttrs = computed(() => {
391
+ const { class: _class, style: _style, ...rest } = attrs;
392
+ return rest;
393
+ });
394
+ const emit = __emit;
395
+ const listboxId = `mint-multi-select-${useId().replace(/:/g, "")}`;
396
+ const root = ref(null);
397
+ const field = ref(null);
398
+ const search = ref(null);
399
+ const open = ref(false);
400
+ const query = ref("");
401
+ const activeIndex = ref(-1);
402
+ const normalizedOptions = computed(() => props.options.map(normalizeOptionInput));
403
+ const selection = useListSelection({
404
+ selected: () => props.modelValue,
405
+ items: normalizedOptions,
406
+ getValue: (option) => option.value,
407
+ disabled: () => props.disabled,
408
+ max: () => props.max
409
+ });
410
+ const chips = computed(() => props.modelValue.map((value) => ({
411
+ value,
412
+ label: normalizedOptions.value.find((option) => option.value === value)?.label ?? String(value)
413
+ })));
414
+ const visibleOptions = computed(() => {
415
+ const needle = query.value.trim().toLocaleLowerCase();
416
+ if (!needle) return normalizedOptions.value;
417
+ return normalizedOptions.value.filter((option) => option.label.toLocaleLowerCase().includes(needle));
418
+ });
419
+ const activeDescendant = computed(() => activeIndex.value >= 0 ? `${listboxId}-option-${activeIndex.value}` : void 0);
420
+ function isUnavailable(option) {
421
+ return !!option.disabled || !selection.isSelected(option.value) && !selection.canAddMore.value;
422
+ }
423
+ async function openPanel() {
424
+ if (props.disabled || open.value) return;
425
+ query.value = "";
426
+ open.value = true;
427
+ activeIndex.value = visibleOptions.value.length > 0 ? 0 : -1;
428
+ await nextTick();
429
+ search.value?.focus();
430
+ }
431
+ async function closePanel(restoreFocus = false) {
432
+ open.value = false;
433
+ query.value = "";
434
+ activeIndex.value = -1;
435
+ if (restoreFocus) {
436
+ await nextTick();
437
+ field.value?.focus();
438
+ }
439
+ }
440
+ function moveActive(direction) {
441
+ const count = visibleOptions.value.length;
442
+ if (count === 0) return;
443
+ const start = activeIndex.value < 0 ? direction === 1 ? -1 : count : activeIndex.value;
444
+ activeIndex.value = (start + direction + count) % count;
445
+ nextTick(() => document.getElementById(activeDescendant.value ?? "")?.scrollIntoView({ block: "nearest" }));
446
+ }
447
+ function toggle(option) {
448
+ if (props.disabled || isUnavailable(option)) return;
449
+ emit("update:modelValue", selection.toggleValue(option.value));
450
+ }
451
+ function remove(value) {
452
+ if (props.disabled) return;
453
+ emit("update:modelValue", props.modelValue.filter((selected) => selected !== value));
454
+ }
455
+ function handleFieldKeydown(event) {
456
+ if (event.key !== "Enter" && event.key !== " " && event.key !== "ArrowDown") return;
457
+ event.preventDefault();
458
+ openPanel();
459
+ }
460
+ function handleSearchKeydown(event) {
461
+ if (event.key === "ArrowDown") moveActive(1);
462
+ else if (event.key === "ArrowUp") moveActive(-1);
463
+ else if (event.key === "Enter") {
464
+ const option = visibleOptions.value[activeIndex.value];
465
+ if (option) toggle(option);
466
+ } else if (event.key === "Escape") closePanel(true);
467
+ else if (event.key === "Backspace" && query.value === "" && props.modelValue.length > 0) remove(props.modelValue[props.modelValue.length - 1]);
468
+ else return;
469
+ event.preventDefault();
470
+ }
471
+ watch(visibleOptions, (options) => {
472
+ activeIndex.value = options.length > 0 ? 0 : -1;
473
+ });
474
+ watch(() => props.disabled, (disabled) => {
475
+ if (disabled) closePanel();
476
+ });
477
+ useEventListener(() => document, "pointerdown", (event) => {
478
+ if (open.value && !root.value?.contains(event.target)) closePanel();
479
+ });
480
+ return (_ctx, _cache) => {
481
+ return openBlock(), createElementBlock("div", {
482
+ ref_key: "root",
483
+ ref: root,
484
+ class: normalizeClass([
485
+ "mint-multi-select",
486
+ `mint-multi-select--${__props.size}`,
487
+ _ctx.$attrs.class
488
+ ]),
489
+ style: normalizeStyle(_ctx.$attrs.style),
490
+ onFocusout: _cache[3] || (_cache[3] = ($event) => !root.value?.contains($event.relatedTarget) && closePanel())
491
+ }, [createElementVNode("div", mergeProps(fieldAttrs.value, {
492
+ ref_key: "field",
493
+ ref: field,
494
+ role: "combobox",
495
+ tabindex: __props.disabled ? void 0 : 0,
496
+ class: ["mint-multi-select__field", {
497
+ "mint-multi-select__field--open": open.value,
498
+ "mint-multi-select__field--error": __props.invalid,
499
+ "mint-multi-select__field--disabled": __props.disabled
500
+ }],
501
+ "aria-haspopup": "listbox",
502
+ "aria-expanded": open.value,
503
+ "aria-controls": listboxId,
504
+ "aria-disabled": __props.disabled || void 0,
505
+ "aria-invalid": __props.invalid || void 0,
506
+ "aria-labelledby": __props.ariaLabelledby || void 0,
507
+ "aria-describedby": __props.ariaDescribedby || void 0,
508
+ onClick: _cache[0] || (_cache[0] = ($event) => open.value ? closePanel() : openPanel()),
509
+ onKeydown: withModifiers(handleFieldKeydown, ["self"])
510
+ }), [createElementVNode("div", _hoisted_2$11, [(openBlock(true), createElementBlock(Fragment, null, renderList(chips.value, (chip) => {
511
+ return openBlock(), createElementBlock("span", {
512
+ key: String(chip.value),
513
+ class: "mint-multi-select__chip"
514
+ }, [createTextVNode(toDisplayString(chip.label) + " ", 1), !__props.disabled ? (openBlock(), createElementBlock("button", {
515
+ key: 0,
516
+ type: "button",
517
+ tabindex: "-1",
518
+ class: "mint-multi-select__chip-remove",
519
+ "aria-label": `Remove ${chip.label}`,
520
+ onClick: withModifiers(($event) => remove(chip.value), ["stop"])
521
+ }, [createVNode(unref(X), {
522
+ size: 11,
523
+ "stroke-width": 2.25,
524
+ "aria-hidden": "true"
525
+ })], 8, _hoisted_3$11)) : createCommentVNode("", true)]);
526
+ }), 128)), chips.value.length === 0 ? (openBlock(), createElementBlock("span", _hoisted_4$8, toDisplayString(__props.placeholder), 1)) : createCommentVNode("", true)]), createVNode(unref(ChevronDown), {
527
+ class: "mint-multi-select__icon",
528
+ size: 14,
529
+ "aria-hidden": "true"
530
+ })], 16, _hoisted_1$11), open.value ? (openBlock(), createElementBlock("div", _hoisted_5$8, [createElementVNode("div", _hoisted_6$8, [_cache[4] || (_cache[4] = createElementVNode("svg", {
531
+ viewBox: "0 0 20 20",
532
+ fill: "none",
533
+ stroke: "currentColor",
534
+ "aria-hidden": "true"
535
+ }, [createElementVNode("circle", {
536
+ cx: "8.5",
537
+ cy: "8.5",
538
+ r: "5.5"
539
+ }), createElementVNode("path", { d: "m13 13 4 4" })], -1)), withDirectives(createElementVNode("input", {
540
+ ref_key: "search",
541
+ ref: search,
542
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => query.value = $event),
543
+ role: "combobox",
544
+ type: "search",
545
+ class: "mint-searchable-select__search",
546
+ placeholder: "Filter…",
547
+ "aria-label": "Filter options",
548
+ "aria-expanded": open.value,
549
+ "aria-controls": listboxId,
550
+ "aria-activedescendant": activeDescendant.value,
551
+ "aria-autocomplete": "list",
552
+ onKeydown: handleSearchKeydown
553
+ }, null, 40, _hoisted_7$7), [[vModelText, query.value]])]), createElementVNode("ul", {
554
+ id: listboxId,
555
+ class: "mint-searchable-select__list",
556
+ role: "listbox",
557
+ "aria-multiselectable": "true"
558
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleOptions.value, (option, index) => {
559
+ return openBlock(), createElementBlock("li", {
560
+ id: `${listboxId}-option-${index}`,
561
+ key: String(option.value),
562
+ role: "option",
563
+ class: normalizeClass(["mint-menu-item mint-multi-select__option", { "mint-menu-item--active": activeIndex.value === index }]),
564
+ "aria-selected": unref(selection).isSelected(option.value),
565
+ "aria-disabled": isUnavailable(option) || void 0,
566
+ onMousedown: _cache[2] || (_cache[2] = withModifiers(() => {}, ["prevent"])),
567
+ onMouseenter: ($event) => !isUnavailable(option) && (activeIndex.value = index),
568
+ onClick: ($event) => toggle(option)
569
+ }, [createElementVNode("span", {
570
+ class: normalizeClass(["mint-multi-select__check", { "mint-multi-select__check--on": unref(selection).isSelected(option.value) }]),
571
+ "aria-hidden": "true"
572
+ }, [unref(selection).isSelected(option.value) ? (openBlock(), createBlock(unref(Check), {
573
+ key: 0,
574
+ size: 10,
575
+ "stroke-width": 3.5
576
+ })) : createCommentVNode("", true)], 2), createElementVNode("span", _hoisted_9$3, toDisplayString(option.label), 1)], 42, _hoisted_8$3);
577
+ }), 128)), visibleOptions.value.length === 0 ? (openBlock(), createElementBlock("li", _hoisted_10$3, "No matching options")) : createCommentVNode("", true)])])) : createCommentVNode("", true)], 38);
578
+ };
579
+ }
580
+ });
581
+ //#endregion
582
+ //#region src/components/internal/SelectSearchableInternal.vue?vue&type=script&setup=true&lang.ts
583
+ var _hoisted_1$10 = [
584
+ "aria-describedby",
585
+ "aria-labelledby",
586
+ "disabled",
587
+ "aria-invalid",
588
+ "aria-expanded"
589
+ ];
590
+ var _hoisted_2$10 = {
591
+ key: 0,
592
+ class: "mint-popover mint-searchable-select__panel"
593
+ };
594
+ var _hoisted_3$10 = { class: "mint-searchable-select__search-wrap" };
595
+ var _hoisted_4$7 = [
596
+ "placeholder",
597
+ "aria-label",
598
+ "aria-expanded",
599
+ "aria-activedescendant"
600
+ ];
601
+ var _hoisted_5$7 = [
602
+ "id",
603
+ "aria-selected",
604
+ "aria-disabled",
605
+ "onMouseenter",
606
+ "onClick"
607
+ ];
608
+ var _hoisted_6$7 = { class: "mint-menu-item__text mint-searchable-select__option-text" };
609
+ var _hoisted_7$6 = { class: "mint-menu-item__label mint-searchable-select__option-label" };
610
+ var _hoisted_8$2 = {
611
+ key: 0,
612
+ class: "mint-menu-item__description mint-searchable-select__option-description"
613
+ };
614
+ var _hoisted_9$2 = {
615
+ key: 0,
616
+ class: "mint-menu-item__meta mint-searchable-select__option-meta"
617
+ };
618
+ var _hoisted_10$2 = {
619
+ key: 0,
620
+ class: "mint-searchable-select__empty"
621
+ };
622
+ var _hoisted_11$2 = {
623
+ key: 0,
624
+ class: "mint-searchable-select__footer"
625
+ };
626
+ //#endregion
627
+ //#region src/components/internal/SelectSearchableInternal.vue
628
+ var SelectSearchableInternal_default = /* @__PURE__ */ defineComponent({
629
+ inheritAttrs: false,
630
+ __name: "SelectSearchableInternal",
631
+ props: {
632
+ modelValue: {},
633
+ options: {},
634
+ placeholder: { default: "Select an option" },
635
+ searchPlaceholder: { default: "Search options…" },
636
+ noResultsText: { default: "No matching options" },
637
+ size: { default: "md" },
638
+ disabled: {
639
+ type: Boolean,
640
+ default: false
641
+ },
642
+ invalid: {
643
+ type: Boolean,
644
+ default: false
645
+ },
646
+ ariaLabelledby: {},
647
+ ariaDescribedby: {}
648
+ },
649
+ emits: ["update:modelValue"],
650
+ setup(__props, { emit: __emit }) {
651
+ /** BaseSelect with `searchable`: a single-select listbox with a search field, descriptions, disabled reasons, and custom slots. */
652
+ const props = __props;
653
+ const attrs = useAttrs();
654
+ const triggerAttrs = computed(() => {
655
+ const { class: _class, style: _style, ...rest } = attrs;
656
+ return rest;
657
+ });
658
+ const emit = __emit;
659
+ const listboxId = `mint-searchable-select-${useId().replace(/:/g, "")}`;
660
+ const triggerId = `${listboxId}-trigger`;
661
+ const root = ref(null);
662
+ const trigger = ref(null);
663
+ const search = ref(null);
664
+ const open = ref(false);
665
+ const query = ref("");
666
+ const activeIndex = ref(-1);
667
+ const normalizedOptions = computed(() => props.options.map(normalizeOptionInput));
668
+ const selectedOption = computed(() => normalizedOptions.value.find((option) => option.value === props.modelValue));
669
+ const visibleOptions = computed(() => {
670
+ const needle = query.value.trim().toLocaleLowerCase();
671
+ if (!needle) return normalizedOptions.value;
672
+ return normalizedOptions.value.filter((option) => [
673
+ option.label,
674
+ option.description,
675
+ option.meta,
676
+ option.disabledReason
677
+ ].some((value) => value?.toLocaleLowerCase().includes(needle)));
678
+ });
679
+ const activeDescendant = computed(() => activeIndex.value >= 0 ? `${listboxId}-option-${activeIndex.value}` : void 0);
680
+ function firstEnabledIndex(options = visibleOptions.value) {
681
+ return options.findIndex((option) => !option.disabled);
682
+ }
683
+ async function openPanel() {
684
+ if (props.disabled) return;
685
+ query.value = "";
686
+ open.value = true;
687
+ activeIndex.value = firstEnabledIndex(normalizedOptions.value);
688
+ await nextTick();
689
+ search.value?.focus();
690
+ }
691
+ async function closePanel(restoreFocus = false) {
692
+ open.value = false;
693
+ query.value = "";
694
+ activeIndex.value = -1;
695
+ if (restoreFocus) {
696
+ await nextTick();
697
+ trigger.value?.focus();
698
+ }
699
+ }
700
+ function moveActive(direction) {
701
+ const enabled = visibleOptions.value.map((option, index) => ({
702
+ option,
703
+ index
704
+ })).filter(({ option }) => !option.disabled);
705
+ if (enabled.length === 0) return;
706
+ const current = enabled.findIndex(({ index }) => index === activeIndex.value);
707
+ const next = current < 0 ? direction === 1 ? 0 : enabled.length - 1 : (current + direction + enabled.length) % enabled.length;
708
+ activeIndex.value = enabled[next].index;
709
+ nextTick(() => document.getElementById(activeDescendant.value ?? "")?.scrollIntoView({ block: "nearest" }));
710
+ }
711
+ function select(option) {
712
+ if (option.disabled) return;
713
+ emit("update:modelValue", option.value);
714
+ closePanel(true);
715
+ }
716
+ function handleSearchKeydown(event) {
717
+ if (event.key === "ArrowDown") moveActive(1);
718
+ else if (event.key === "ArrowUp") moveActive(-1);
719
+ else if (event.key === "Home") activeIndex.value = firstEnabledIndex();
720
+ else if (event.key === "End") {
721
+ for (let index = visibleOptions.value.length - 1; index >= 0; index--) if (!visibleOptions.value[index]?.disabled) {
722
+ activeIndex.value = index;
723
+ break;
724
+ }
725
+ } else if (event.key === "Enter") {
726
+ const option = visibleOptions.value[activeIndex.value];
727
+ if (option) select(option);
728
+ } else if (event.key === "Escape") closePanel(true);
729
+ else return;
730
+ event.preventDefault();
731
+ }
732
+ function handleTriggerKeydown(event) {
733
+ if (event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
734
+ event.preventDefault();
735
+ openPanel().then(() => {
736
+ if (event.key === "ArrowUp") moveActive(-1);
737
+ });
738
+ }
739
+ watch(visibleOptions, (options) => {
740
+ activeIndex.value = firstEnabledIndex(options);
741
+ });
742
+ watch(() => props.disabled, (disabled) => {
743
+ if (disabled) closePanel();
744
+ });
745
+ useEventListener(() => document, "pointerdown", (event) => {
746
+ if (open.value && !root.value?.contains(event.target)) closePanel();
747
+ });
748
+ return (_ctx, _cache) => {
749
+ return openBlock(), createElementBlock("div", {
750
+ ref_key: "root",
751
+ ref: root,
752
+ class: normalizeClass([
753
+ "mint-searchable-select",
754
+ `mint-searchable-select--${__props.size}`,
755
+ _ctx.$attrs.class
756
+ ]),
757
+ style: normalizeStyle(_ctx.$attrs.style),
758
+ onFocusout: _cache[3] || (_cache[3] = ($event) => !root.value?.contains($event.relatedTarget) && closePanel())
759
+ }, [createElementVNode("button", mergeProps(triggerAttrs.value, {
760
+ id: triggerId,
761
+ ref_key: "trigger",
762
+ ref: trigger,
763
+ type: "button",
764
+ "aria-describedby": __props.ariaDescribedby || void 0,
765
+ "aria-labelledby": __props.ariaLabelledby ? `${__props.ariaLabelledby} ${triggerId}` : void 0,
766
+ class: ["mint-searchable-select__trigger", { "mint-searchable-select__trigger--error": __props.invalid }],
767
+ disabled: __props.disabled,
768
+ "aria-invalid": __props.invalid || void 0,
769
+ "aria-expanded": open.value,
770
+ "aria-controls": listboxId,
771
+ "aria-haspopup": "listbox",
772
+ onClick: _cache[0] || (_cache[0] = ($event) => open.value ? closePanel() : openPanel()),
773
+ onKeydown: handleTriggerKeydown
774
+ }), [createElementVNode("span", { class: normalizeClass(["mint-searchable-select__value", { "mint-searchable-select__value--placeholder": !selectedOption.value }]) }, toDisplayString(selectedOption.value?.label ?? __props.placeholder), 3), createVNode(unref(ChevronsUpDown), {
775
+ size: 14,
776
+ "aria-hidden": "true"
777
+ })], 16, _hoisted_1$10), open.value ? (openBlock(), createElementBlock("div", _hoisted_2$10, [
778
+ createElementVNode("div", _hoisted_3$10, [_cache[4] || (_cache[4] = createElementVNode("svg", {
779
+ viewBox: "0 0 20 20",
780
+ fill: "none",
781
+ stroke: "currentColor",
782
+ "aria-hidden": "true"
783
+ }, [createElementVNode("circle", {
784
+ cx: "8.5",
785
+ cy: "8.5",
786
+ r: "5.5"
787
+ }), createElementVNode("path", { d: "m13 13 4 4" })], -1)), withDirectives(createElementVNode("input", {
788
+ ref_key: "search",
789
+ ref: search,
790
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => query.value = $event),
791
+ role: "combobox",
792
+ type: "search",
793
+ class: "mint-searchable-select__search",
794
+ placeholder: __props.searchPlaceholder,
795
+ "aria-label": __props.searchPlaceholder,
796
+ "aria-expanded": open.value,
797
+ "aria-controls": listboxId,
798
+ "aria-activedescendant": activeDescendant.value,
799
+ "aria-autocomplete": "list",
800
+ onKeydown: handleSearchKeydown
801
+ }, null, 40, _hoisted_4$7), [[vModelText, query.value]])]),
802
+ createElementVNode("ul", {
803
+ id: listboxId,
804
+ class: "mint-searchable-select__list",
805
+ role: "listbox"
806
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleOptions.value, (option, index) => {
807
+ return openBlock(), createElementBlock("li", {
808
+ id: `${listboxId}-option-${index}`,
809
+ key: String(option.value),
810
+ role: "option",
811
+ class: normalizeClass(["mint-menu-item mint-searchable-select__option", {
812
+ "mint-menu-item--active mint-searchable-select__option--active": activeIndex.value === index,
813
+ "mint-menu-item--selected mint-searchable-select__option--selected": __props.modelValue === option.value,
814
+ "mint-searchable-select__option--disabled": option.disabled
815
+ }]),
816
+ "aria-selected": __props.modelValue === option.value,
817
+ "aria-disabled": option.disabled || void 0,
818
+ onMousedown: _cache[2] || (_cache[2] = withModifiers(() => {}, ["prevent"])),
819
+ onMouseenter: ($event) => !option.disabled && (activeIndex.value = index),
820
+ onClick: ($event) => select(option)
821
+ }, [renderSlot(_ctx.$slots, "option", {
822
+ option,
823
+ selected: __props.modelValue === option.value,
824
+ active: activeIndex.value === index
825
+ }, () => [
826
+ createElementVNode("span", _hoisted_6$7, [createElementVNode("span", _hoisted_7$6, toDisplayString(option.label), 1), (option.disabled ? option.disabledReason || option.description : option.description) ? (openBlock(), createElementBlock("span", _hoisted_8$2, toDisplayString(option.disabled ? option.disabledReason || option.description : option.description), 1)) : createCommentVNode("", true)]),
827
+ option.meta ? (openBlock(), createElementBlock("span", _hoisted_9$2, toDisplayString(option.meta), 1)) : createCommentVNode("", true),
828
+ _cache[5] || (_cache[5] = createElementVNode("svg", {
829
+ class: "mint-menu-item__check mint-searchable-select__check",
830
+ viewBox: "0 0 20 20",
831
+ fill: "none",
832
+ stroke: "currentColor",
833
+ "aria-hidden": "true"
834
+ }, [createElementVNode("path", {
835
+ "stroke-linecap": "round",
836
+ "stroke-linejoin": "round",
837
+ "stroke-width": "2",
838
+ d: "m5 10 3 3 7-7"
839
+ })], -1))
840
+ ])], 42, _hoisted_5$7);
841
+ }), 128)), visibleOptions.value.length === 0 ? (openBlock(), createElementBlock("li", _hoisted_10$2, toDisplayString(__props.noResultsText), 1)) : createCommentVNode("", true)]),
842
+ _ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_11$2, [renderSlot(_ctx.$slots, "footer")])) : createCommentVNode("", true)
843
+ ])) : createCommentVNode("", true)], 38);
844
+ };
845
+ }
846
+ });
847
+ //#endregion
848
+ //#region src/components/BaseSelect.vue?vue&type=script&setup=true&lang.ts
849
+ var _hoisted_1$9 = [
850
+ "value",
851
+ "disabled",
852
+ "aria-invalid",
853
+ "aria-describedby",
854
+ "aria-labelledby"
855
+ ];
856
+ var _hoisted_2$9 = {
857
+ key: 0,
858
+ value: "",
859
+ disabled: ""
860
+ };
861
+ var _hoisted_3$9 = ["value", "disabled"];
862
+ //#endregion
863
+ //#region src/components/BaseSelect.vue
864
+ var BaseSelect_default = /* @__PURE__ */ defineComponent({
865
+ inheritAttrs: false,
866
+ __name: "BaseSelect",
867
+ props: {
868
+ modelValue: { default: null },
869
+ options: {},
870
+ multiple: { default: void 0 },
871
+ searchable: {
872
+ type: Boolean,
873
+ default: false
874
+ },
875
+ max: { default: void 0 },
876
+ placeholder: { default: void 0 },
877
+ searchPlaceholder: { default: void 0 },
878
+ noResultsText: { default: void 0 },
879
+ disabled: {
880
+ type: Boolean,
881
+ default: false
882
+ },
883
+ invalid: {
884
+ type: Boolean,
885
+ default: false
886
+ },
887
+ size: { default: "md" },
888
+ ariaDescribedby: { default: void 0 },
889
+ ariaLabelledby: { default: void 0 }
890
+ },
891
+ emits: ["update:modelValue"],
892
+ setup(__props, { emit: __emit }) {
893
+ /**
894
+ * Select one or several options.
895
+ * Default: a native `<select>`. `searchable`: a listbox with a search field and the `#option` / `#footer` slots.
896
+ * `multiple`: a field of removable chips with a filterable checkbox listbox, bound to an array and capped by `max`.
897
+ *
898
+ * @example
899
+ * ```vue
900
+ * <BaseSelect v-model="method" :options="methods" />
901
+ * <BaseSelect v-model="template" :options="templates" searchable placeholder="Select template…" />
902
+ * <BaseSelect v-model="instrumentIds" :options="instruments" multiple :max="3" />
903
+ * ```
904
+ */
905
+ const props = __props;
906
+ const emit = __emit;
907
+ const attrs = useAttrs();
908
+ const controlAttrs = computed(() => {
909
+ const { class: _class, style: _style, ...nativeAttrs } = attrs;
910
+ return nativeAttrs;
911
+ });
912
+ const wrapperAttrs = computed(() => ({
913
+ class: attrs.class,
914
+ style: attrs.style
915
+ }));
916
+ const normalizedOptions = computed(() => props.options.map((option) => normalizeOptionInput(option)));
917
+ const isMultiple = computed(() => props.multiple === true || props.multiple === "");
918
+ const multipleValue = computed(() => {
919
+ const value = props.modelValue;
920
+ return Array.isArray(value) ? value : [];
921
+ });
922
+ const singleValue = computed(() => {
923
+ const value = props.modelValue;
924
+ return Array.isArray(value) ? null : value;
925
+ });
926
+ function update(value) {
927
+ emit("update:modelValue", value);
928
+ }
929
+ function handleChange(event) {
930
+ const target = event.target;
931
+ update(findOptionByDomValue(normalizedOptions.value, target.value)?.value ?? target.value);
932
+ }
933
+ return (_ctx, _cache) => {
934
+ return isMultiple.value ? (openBlock(), createBlock(SelectMultipleInternal_default, mergeProps({ key: 0 }, unref(attrs), {
935
+ "model-value": multipleValue.value,
936
+ options: __props.options,
937
+ placeholder: __props.placeholder,
938
+ disabled: __props.disabled,
939
+ invalid: __props.invalid,
940
+ max: __props.max,
941
+ size: __props.size,
942
+ "aria-labelledby": __props.ariaLabelledby,
943
+ "aria-describedby": __props.ariaDescribedby,
944
+ "onUpdate:modelValue": update
945
+ }), null, 16, [
946
+ "model-value",
947
+ "options",
948
+ "placeholder",
949
+ "disabled",
950
+ "invalid",
951
+ "max",
952
+ "size",
953
+ "aria-labelledby",
954
+ "aria-describedby"
955
+ ])) : __props.searchable ? (openBlock(), createBlock(SelectSearchableInternal_default, mergeProps({ key: 1 }, unref(attrs), {
956
+ "model-value": singleValue.value,
957
+ options: __props.options,
958
+ placeholder: __props.placeholder,
959
+ "search-placeholder": __props.searchPlaceholder,
960
+ "no-results-text": __props.noResultsText,
961
+ disabled: __props.disabled,
962
+ invalid: __props.invalid,
963
+ size: __props.size,
964
+ "aria-labelledby": __props.ariaLabelledby,
965
+ "aria-describedby": __props.ariaDescribedby,
966
+ "onUpdate:modelValue": update
967
+ }), createSlots({ _: 2 }, [_ctx.$slots.option ? {
968
+ name: "option",
969
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, "option", normalizeProps(guardReactiveProps(slotProps)))]),
970
+ key: "0"
971
+ } : void 0, _ctx.$slots.footer ? {
972
+ name: "footer",
973
+ fn: withCtx(() => [renderSlot(_ctx.$slots, "footer")]),
974
+ key: "1"
975
+ } : void 0]), 1040, [
976
+ "model-value",
977
+ "options",
978
+ "placeholder",
979
+ "search-placeholder",
980
+ "no-results-text",
981
+ "disabled",
982
+ "invalid",
983
+ "size",
984
+ "aria-labelledby",
985
+ "aria-describedby"
986
+ ])) : (openBlock(), createElementBlock("div", mergeProps({ key: 2 }, wrapperAttrs.value, { class: "mint-select" }), [createElementVNode("select", mergeProps(controlAttrs.value, {
987
+ value: singleValue.value ?? "",
988
+ disabled: __props.disabled,
989
+ "aria-invalid": __props.invalid || void 0,
990
+ "aria-describedby": __props.ariaDescribedby || void 0,
991
+ "aria-labelledby": __props.ariaLabelledby || void 0,
992
+ class: [
993
+ "mint-select__control",
994
+ `mint-select__control--${__props.size}`,
995
+ __props.invalid ? "mint-select__control--error" : "",
996
+ __props.disabled ? "mint-select__control--disabled" : ""
997
+ ],
998
+ onChange: handleChange
999
+ }), [__props.placeholder ? (openBlock(), createElementBlock("option", _hoisted_2$9, toDisplayString(__props.placeholder), 1)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option) => {
1000
+ return openBlock(), createElementBlock("option", {
1001
+ key: String(option.value),
1002
+ value: option.value,
1003
+ disabled: option.disabled
1004
+ }, toDisplayString(option.label), 9, _hoisted_3$9);
1005
+ }), 128))], 16, _hoisted_1$9), _cache[0] || (_cache[0] = createElementVNode("div", { class: "mint-select__icon" }, [createElementVNode("svg", {
1006
+ fill: "none",
1007
+ stroke: "currentColor",
1008
+ "stroke-width": "2",
1009
+ "stroke-linecap": "round",
1010
+ "stroke-linejoin": "round",
1011
+ viewBox: "0 0 24 24"
1012
+ }, [createElementVNode("path", { d: "m6 9 6 6 6-6" })])], -1))], 16));
1013
+ };
1014
+ }
1015
+ });
1016
+ //#endregion
1017
+ //#region src/components/Tooltip.vue?vue&type=script&setup=true&lang.ts
1018
+ var _hoisted_1$8 = ["aria-describedby"];
1019
+ var _hoisted_2$8 = { class: "mint-tooltip__body" };
1020
+ var _hoisted_3$8 = {
1021
+ key: 0,
1022
+ class: "mint-tooltip__shortcut"
1023
+ };
1024
+ //#endregion
1025
+ //#region src/components/Tooltip.vue
1026
+ var Tooltip_default = /* @__PURE__ */ defineComponent({
1027
+ __name: "Tooltip",
1028
+ props: {
1029
+ text: {},
1030
+ position: { default: "top" },
1031
+ delay: { default: 200 },
1032
+ shortcut: { default: void 0 },
1033
+ maxWidth: { default: void 0 }
1034
+ },
1035
+ setup(__props) {
1036
+ /** Floating tooltip using @floating-ui with auto-flip, delay, optional keyboard shortcut badge, and body Teleport. */
1037
+ const props = __props;
1038
+ const tooltipId = `mint-tooltip-${Math.random().toString(36).slice(2, 9)}`;
1039
+ const visible = ref(false);
1040
+ const actualPlacement = ref(props.position);
1041
+ const triggerRef = ref(null);
1042
+ const contentRef = ref(null);
1043
+ const coords = ref({
1044
+ top: "0px",
1045
+ left: "0px"
1046
+ });
1047
+ let timeoutId;
1048
+ async function updatePosition() {
1049
+ if (!triggerRef.value || !contentRef.value) return;
1050
+ const { x, y, placement } = await computePosition(triggerRef.value, contentRef.value, {
1051
+ placement: props.position,
1052
+ middleware: [
1053
+ offset(6),
1054
+ flip(),
1055
+ shift({ padding: 8 })
1056
+ ]
1057
+ });
1058
+ coords.value = {
1059
+ top: `${y}px`,
1060
+ left: `${x}px`
1061
+ };
1062
+ actualPlacement.value = placement;
1063
+ }
1064
+ useEventListener(() => window, "scroll", updatePosition, {
1065
+ passive: true,
1066
+ capture: true,
1067
+ enabled: visible
1068
+ });
1069
+ useEventListener(() => window, "resize", updatePosition, { enabled: visible });
1070
+ async function show() {
1071
+ timeoutId = setTimeout(async () => {
1072
+ visible.value = true;
1073
+ await nextTick();
1074
+ await updatePosition();
1075
+ }, props.delay);
1076
+ }
1077
+ function hide() {
1078
+ clearTimeout(timeoutId);
1079
+ timeoutId = void 0;
1080
+ visible.value = false;
1081
+ }
1082
+ onBeforeUnmount(() => {
1083
+ clearTimeout(timeoutId);
1084
+ });
1085
+ function resolvedMaxWidth(value) {
1086
+ if (value === void 0) return void 0;
1087
+ return typeof value === "number" ? `${value}px` : value;
1088
+ }
1089
+ return (_ctx, _cache) => {
1090
+ return openBlock(), createElementBlock("span", {
1091
+ ref_key: "triggerRef",
1092
+ ref: triggerRef,
1093
+ class: "mint-tooltip",
1094
+ "aria-describedby": visible.value ? tooltipId : void 0,
1095
+ onMouseenter: show,
1096
+ onMouseleave: hide,
1097
+ onFocusin: show,
1098
+ onFocusout: hide
1099
+ }, [renderSlot(_ctx.$slots, "default"), (openBlock(), createBlock(Teleport, { to: "body" }, [visible.value ? (openBlock(), createElementBlock("span", {
1100
+ key: 0,
1101
+ id: tooltipId,
1102
+ ref_key: "contentRef",
1103
+ ref: contentRef,
1104
+ class: normalizeClass([
1105
+ "mint-tooltip__content",
1106
+ `mint-tooltip__content--${actualPlacement.value}`,
1107
+ __props.maxWidth ? "mint-tooltip__content--multiline" : ""
1108
+ ]),
1109
+ style: normalizeStyle({
1110
+ top: coords.value.top,
1111
+ left: coords.value.left,
1112
+ maxWidth: resolvedMaxWidth(__props.maxWidth)
1113
+ }),
1114
+ role: "tooltip"
1115
+ }, [createElementVNode("span", _hoisted_2$8, toDisplayString(__props.text), 1), __props.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_3$8, toDisplayString(__props.shortcut), 1)) : createCommentVNode("", true)], 6)) : createCommentVNode("", true)]))], 40, _hoisted_1$8);
1116
+ };
1117
+ }
1118
+ });
1119
+ //#endregion
1120
+ //#region src/components/internal/CheckboxSwitchInternal.vue?vue&type=script&setup=true&lang.ts
1121
+ var _hoisted_1$7 = {
1122
+ key: 0,
1123
+ class: "mint-toggle__row-svg",
1124
+ viewBox: "0 0 24 24",
1125
+ fill: "none",
1126
+ stroke: "currentColor",
1127
+ "stroke-width": "2",
1128
+ "stroke-linecap": "round",
1129
+ "stroke-linejoin": "round"
1130
+ };
1131
+ var _hoisted_2$7 = ["d"];
1132
+ var _hoisted_3$7 = ["d"];
1133
+ var _hoisted_4$6 = {
1134
+ key: 1,
1135
+ class: "mint-toggle__row-text-icon"
1136
+ };
1137
+ var _hoisted_5$6 = {
1138
+ key: 1,
1139
+ class: "mint-toggle__copy"
1140
+ };
1141
+ var _hoisted_6$6 = [
1142
+ "tabindex",
1143
+ "aria-checked",
1144
+ "aria-label"
1145
+ ];
1146
+ //#endregion
1147
+ //#region src/components/internal/CheckboxSwitchInternal.vue
1148
+ var CheckboxSwitchInternal_default = /* @__PURE__ */ defineComponent({
1149
+ __name: "CheckboxSwitchInternal",
1150
+ props: {
1151
+ modelValue: {
1152
+ type: Boolean,
1153
+ default: false
1154
+ },
1155
+ label: {},
1156
+ ariaLabel: {},
1157
+ description: {},
1158
+ icon: {},
1159
+ iconColor: {},
1160
+ iconBg: {},
1161
+ disabled: {
1162
+ type: Boolean,
1163
+ default: false
1164
+ },
1165
+ size: { default: "md" },
1166
+ reverse: {
1167
+ type: Boolean,
1168
+ default: false
1169
+ },
1170
+ layout: { default: "inline" }
1171
+ },
1172
+ emits: ["update:modelValue"],
1173
+ setup(__props, { emit: __emit }) {
1174
+ /** BaseCheckbox with `type="switch"`: an on/off switch with label, size, and keyboard interaction support. */
1175
+ const props = __props;
1176
+ const emit = __emit;
1177
+ function toggle() {
1178
+ if (!props.disabled) emit("update:modelValue", !props.modelValue);
1179
+ }
1180
+ function handleKeydown(event) {
1181
+ if (event.key === " " || event.key === "Enter") {
1182
+ event.preventDefault();
1183
+ toggle();
1184
+ }
1185
+ }
1186
+ function isSvgIcon(icon) {
1187
+ if (!icon) return false;
1188
+ return Array.isArray(icon) || icon.startsWith("M") || icon.startsWith("m");
1189
+ }
1190
+ function iconStyle() {
1191
+ return { color: props.iconColor ?? (props.modelValue ? "var(--color-primary)" : "var(--text-muted)") };
1192
+ }
1193
+ return (_ctx, _cache) => {
1194
+ return openBlock(), createElementBlock("div", {
1195
+ class: normalizeClass([
1196
+ "mint-toggle",
1197
+ `mint-toggle--${__props.layout}`,
1198
+ __props.reverse ? "mint-toggle--reverse" : "",
1199
+ __props.disabled ? "mint-toggle--disabled" : "",
1200
+ __props.modelValue ? "mint-toggle--checked" : ""
1201
+ ]),
1202
+ onClick: toggle
1203
+ }, [
1204
+ __props.layout === "row" && __props.icon ? (openBlock(), createElementBlock("span", {
1205
+ key: 0,
1206
+ class: "mint-toggle__row-icon",
1207
+ style: normalizeStyle(iconStyle()),
1208
+ "aria-hidden": "true"
1209
+ }, [isSvgIcon(__props.icon) ? (openBlock(), createElementBlock("svg", _hoisted_1$7, [Array.isArray(__props.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(__props.icon, (d, i) => {
1210
+ return openBlock(), createElementBlock("path", {
1211
+ key: i,
1212
+ d
1213
+ }, null, 8, _hoisted_2$7);
1214
+ }), 128)) : (openBlock(), createElementBlock("path", {
1215
+ key: 1,
1216
+ d: __props.icon
1217
+ }, null, 8, _hoisted_3$7))])) : (openBlock(), createElementBlock("span", _hoisted_4$6, toDisplayString(__props.icon), 1))], 4)) : createCommentVNode("", true),
1218
+ __props.layout === "row" && __props.label ? (openBlock(), createElementBlock("span", _hoisted_5$6, [__props.description ? (openBlock(), createBlock(Tooltip_default, {
1219
+ key: 0,
1220
+ text: __props.description,
1221
+ position: "right",
1222
+ "max-width": "16rem"
1223
+ }, {
1224
+ default: withCtx(() => [createElementVNode("span", { class: normalizeClass([
1225
+ "mint-toggle__label",
1226
+ `mint-toggle__label--${__props.size}`,
1227
+ "mint-toggle__label--tooltip"
1228
+ ]) }, toDisplayString(__props.label), 3)]),
1229
+ _: 1
1230
+ }, 8, ["text"])) : (openBlock(), createElementBlock("span", {
1231
+ key: 1,
1232
+ class: normalizeClass(["mint-toggle__label", `mint-toggle__label--${__props.size}`])
1233
+ }, toDisplayString(__props.label), 3))])) : createCommentVNode("", true),
1234
+ createElementVNode("div", {
1235
+ role: "switch",
1236
+ tabindex: __props.disabled ? -1 : 0,
1237
+ "aria-checked": __props.modelValue,
1238
+ "aria-label": __props.ariaLabel || __props.label || "Toggle",
1239
+ class: normalizeClass([
1240
+ "mint-toggle__track",
1241
+ `mint-toggle__track--${__props.size}`,
1242
+ __props.modelValue ? "mint-toggle__track--on" : "mint-toggle__track--off"
1243
+ ]),
1244
+ onKeydown: handleKeydown
1245
+ }, [createElementVNode("span", { class: normalizeClass(["mint-toggle__knob", `mint-toggle__knob--${__props.size}`]) }, null, 2)], 42, _hoisted_6$6),
1246
+ __props.label && __props.layout !== "row" ? (openBlock(), createElementBlock("span", {
1247
+ key: 2,
1248
+ class: normalizeClass(["mint-toggle__label", `mint-toggle__label--${__props.size}`])
1249
+ }, toDisplayString(__props.label), 3)) : createCommentVNode("", true)
1250
+ ], 2);
1251
+ };
1252
+ }
1253
+ });
1254
+ //#endregion
1255
+ //#region src/components/BaseCheckbox.vue?vue&type=script&setup=true&lang.ts
1256
+ var _hoisted_1$6 = {
1257
+ key: 0,
1258
+ class: "mint-checkbox__row-svg",
1259
+ viewBox: "0 0 24 24",
1260
+ fill: "none",
1261
+ stroke: "currentColor",
1262
+ "stroke-width": "2",
1263
+ "stroke-linecap": "round",
1264
+ "stroke-linejoin": "round"
1265
+ };
1266
+ var _hoisted_2$6 = ["d"];
1267
+ var _hoisted_3$6 = ["d"];
1268
+ var _hoisted_4$5 = {
1269
+ key: 1,
1270
+ class: "mint-checkbox__row-text-icon"
1271
+ };
1272
+ var _hoisted_5$5 = {
1273
+ key: 1,
1274
+ class: "mint-checkbox__copy"
1275
+ };
1276
+ var _hoisted_6$5 = { class: "mint-checkbox__input-wrapper" };
1277
+ var _hoisted_7$5 = [
1278
+ "checked",
1279
+ "indeterminate",
1280
+ "aria-checked",
1281
+ "disabled",
1282
+ "aria-label"
1283
+ ];
1284
+ //#endregion
1285
+ //#region src/components/BaseCheckbox.vue
1286
+ var BaseCheckbox_default = /* @__PURE__ */ defineComponent({
1287
+ __name: "BaseCheckbox",
1288
+ props: {
1289
+ modelValue: {
1290
+ type: Boolean,
1291
+ default: false
1292
+ },
1293
+ type: { default: "checkbox" },
1294
+ indeterminate: {
1295
+ type: Boolean,
1296
+ default: false
1297
+ },
1298
+ ariaLabel: {},
1299
+ label: {},
1300
+ description: {},
1301
+ icon: {},
1302
+ iconColor: {},
1303
+ iconBg: {},
1304
+ disabled: {
1305
+ type: Boolean,
1306
+ default: false
1307
+ },
1308
+ size: { default: "md" },
1309
+ layout: { default: "inline" },
1310
+ reverse: {
1311
+ type: Boolean,
1312
+ default: false
1313
+ }
1314
+ },
1315
+ emits: ["update:modelValue"],
1316
+ setup(__props, { emit: __emit }) {
1317
+ /**
1318
+ * Renders a styled checkbox with an optional label, size variants, and disabled state.
1319
+ * `type="switch"` renders an on/off switch; `layout="row"` renders a full-width settings row.
1320
+ *
1321
+ * @example
1322
+ * ```vue
1323
+ * <BaseCheckbox v-model="agree" label="I agree" />
1324
+ * <BaseCheckbox v-model="enabled" type="switch" label="Enable auto-update" />
1325
+ * ```
1326
+ */
1327
+ const props = __props;
1328
+ const emit = __emit;
1329
+ function handleChange(event) {
1330
+ const target = event.target;
1331
+ emit("update:modelValue", target.checked);
1332
+ }
1333
+ function isSvgIcon(icon) {
1334
+ if (!icon) return false;
1335
+ return Array.isArray(icon) || icon.startsWith("M") || icon.startsWith("m");
1336
+ }
1337
+ function iconStyle() {
1338
+ return { color: props.iconColor ?? (props.modelValue ? "var(--color-primary)" : "var(--text-muted)") };
1339
+ }
1340
+ return (_ctx, _cache) => {
1341
+ return props.type === "switch" ? (openBlock(), createBlock(CheckboxSwitchInternal_default, {
1342
+ key: 0,
1343
+ "model-value": props.modelValue,
1344
+ label: props.label,
1345
+ "aria-label": props.ariaLabel,
1346
+ description: props.description,
1347
+ icon: props.icon,
1348
+ "icon-color": props.iconColor,
1349
+ "icon-bg": props.iconBg,
1350
+ disabled: props.disabled,
1351
+ size: props.size,
1352
+ reverse: props.reverse,
1353
+ layout: props.layout,
1354
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", $event))
1355
+ }, null, 8, [
1356
+ "model-value",
1357
+ "label",
1358
+ "aria-label",
1359
+ "description",
1360
+ "icon",
1361
+ "icon-color",
1362
+ "icon-bg",
1363
+ "disabled",
1364
+ "size",
1365
+ "reverse",
1366
+ "layout"
1367
+ ])) : (openBlock(), createElementBlock("label", {
1368
+ key: 1,
1369
+ class: normalizeClass([
1370
+ "mint-checkbox",
1371
+ `mint-checkbox--${props.layout}`,
1372
+ props.disabled ? "mint-checkbox--disabled" : "",
1373
+ props.modelValue ? "mint-checkbox--checked" : ""
1374
+ ])
1375
+ }, [
1376
+ props.layout === "row" && props.icon ? (openBlock(), createElementBlock("span", {
1377
+ key: 0,
1378
+ class: "mint-checkbox__row-icon",
1379
+ style: normalizeStyle(iconStyle()),
1380
+ "aria-hidden": "true"
1381
+ }, [isSvgIcon(props.icon) ? (openBlock(), createElementBlock("svg", _hoisted_1$6, [Array.isArray(props.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.icon, (d, i) => {
1382
+ return openBlock(), createElementBlock("path", {
1383
+ key: i,
1384
+ d
1385
+ }, null, 8, _hoisted_2$6);
1386
+ }), 128)) : (openBlock(), createElementBlock("path", {
1387
+ key: 1,
1388
+ d: props.icon
1389
+ }, null, 8, _hoisted_3$6))])) : (openBlock(), createElementBlock("span", _hoisted_4$5, toDisplayString(props.icon), 1))], 4)) : createCommentVNode("", true),
1390
+ props.layout === "row" && props.label ? (openBlock(), createElementBlock("span", _hoisted_5$5, [props.description ? (openBlock(), createBlock(Tooltip_default, {
1391
+ key: 0,
1392
+ text: props.description,
1393
+ position: "right",
1394
+ "max-width": "16rem"
1395
+ }, {
1396
+ default: withCtx(() => [createElementVNode("span", { class: normalizeClass([
1397
+ "mint-checkbox__label",
1398
+ `mint-checkbox__label--${props.size}`,
1399
+ "mint-checkbox__label--tooltip"
1400
+ ]) }, toDisplayString(props.label), 3)]),
1401
+ _: 1
1402
+ }, 8, ["text"])) : (openBlock(), createElementBlock("span", {
1403
+ key: 1,
1404
+ class: normalizeClass(["mint-checkbox__label", `mint-checkbox__label--${props.size}`])
1405
+ }, toDisplayString(props.label), 3))])) : createCommentVNode("", true),
1406
+ createElementVNode("div", _hoisted_6$5, [createElementVNode("input", {
1407
+ type: "checkbox",
1408
+ checked: props.modelValue,
1409
+ indeterminate: props.indeterminate,
1410
+ "aria-checked": props.indeterminate ? "mixed" : void 0,
1411
+ disabled: props.disabled,
1412
+ "aria-label": props.ariaLabel || props.label || "Checkbox",
1413
+ class: "mint-checkbox__native",
1414
+ onChange: handleChange
1415
+ }, null, 40, _hoisted_7$5), createElementVNode("div", { class: normalizeClass([
1416
+ "mint-checkbox__box",
1417
+ `mint-checkbox__box--${props.size}`,
1418
+ props.modelValue && !props.indeterminate ? "mint-checkbox__box--checked" : "",
1419
+ props.indeterminate ? "mint-checkbox__box--indeterminate" : ""
1420
+ ]) }, [props.indeterminate ? (openBlock(), createElementBlock("svg", {
1421
+ key: 0,
1422
+ class: normalizeClass(["mint-checkbox__icon", `mint-checkbox__icon--${props.size}`]),
1423
+ fill: "none",
1424
+ stroke: "currentColor",
1425
+ viewBox: "0 0 16 16",
1426
+ "aria-hidden": "true"
1427
+ }, [..._cache[1] || (_cache[1] = [createElementVNode("path", {
1428
+ "stroke-linecap": "round",
1429
+ "stroke-width": "2.2",
1430
+ d: "M4 8h8"
1431
+ }, null, -1)])], 2)) : props.modelValue ? (openBlock(), createElementBlock("svg", {
1432
+ key: 1,
1433
+ class: normalizeClass(["mint-checkbox__icon", `mint-checkbox__icon--${props.size}`]),
1434
+ fill: "none",
1435
+ stroke: "currentColor",
1436
+ viewBox: "0 0 24 24",
1437
+ "aria-hidden": "true"
1438
+ }, [..._cache[2] || (_cache[2] = [createElementVNode("path", {
1439
+ "stroke-linecap": "round",
1440
+ "stroke-linejoin": "round",
1441
+ "stroke-width": "3",
1442
+ d: "M5 13l4 4L19 7"
1443
+ }, null, -1)])], 2)) : createCommentVNode("", true)], 2)]),
1444
+ props.label && props.layout !== "row" ? (openBlock(), createElementBlock("span", {
1445
+ key: 2,
1446
+ class: normalizeClass(["mint-checkbox__label", `mint-checkbox__label--${props.size}`])
1447
+ }, toDisplayString(props.label), 3)) : createCommentVNode("", true)
1448
+ ], 2));
1449
+ };
1450
+ }
1451
+ });
1452
+ //#endregion
1453
+ //#region src/composables/useRovingFocus.ts
1454
+ /**
1455
+ * WAI-ARIA roving-tabindex navigation with automatic activation (the tabs pattern):
1456
+ * Left/Right (or Up/Down when `orientation` is `'vertical'`) move to the adjacent item
1457
+ * and activate it immediately, wrapping past the ends; Home/End jump to the first/last
1458
+ * item. Only the active item should carry `tabindex="0"`; give every other item
1459
+ * `tabindex="-1"`. Used by BaseTabs.
1460
+ */
1461
+ function useRovingFocus(options) {
1462
+ const orientation = options.orientation ?? "horizontal";
1463
+ const prevKey = orientation === "vertical" ? "ArrowUp" : "ArrowLeft";
1464
+ const nextKey = orientation === "vertical" ? "ArrowDown" : "ArrowRight";
1465
+ function moveTo(id) {
1466
+ if (id === void 0) return;
1467
+ options.activate(id);
1468
+ nextTick(() => options.getElement(id)?.focus());
1469
+ }
1470
+ function handleKeydown(event) {
1471
+ const ids = options.ids();
1472
+ if (ids.length === 0) return;
1473
+ const currentIndex = ids.indexOf(options.activeId() ?? "");
1474
+ if (event.key === "Home") {
1475
+ event.preventDefault();
1476
+ moveTo(ids[0]);
1477
+ return;
1478
+ }
1479
+ if (event.key === "End") {
1480
+ event.preventDefault();
1481
+ moveTo(ids[ids.length - 1]);
1482
+ return;
1483
+ }
1484
+ if (event.key === prevKey) {
1485
+ event.preventDefault();
1486
+ moveTo(ids[currentIndex <= 0 ? ids.length - 1 : currentIndex - 1]);
1487
+ return;
1488
+ }
1489
+ if (event.key === nextKey) {
1490
+ event.preventDefault();
1491
+ moveTo(ids[currentIndex === -1 || currentIndex >= ids.length - 1 ? 0 : currentIndex + 1]);
1492
+ }
1493
+ }
1494
+ return { handleKeydown };
1495
+ }
1496
+ //#endregion
1497
+ //#region src/components/EmptyState.vue?vue&type=script&setup=true&lang.ts
1498
+ var _hoisted_1$5 = ["d"];
1499
+ var _hoisted_2$5 = ["d"];
1500
+ var _hoisted_3$5 = { class: "mint-empty-state__body" };
1501
+ var _hoisted_4$4 = {
1502
+ key: 0,
1503
+ class: "mint-empty-state__title"
1504
+ };
1505
+ var _hoisted_5$4 = {
1506
+ key: 1,
1507
+ class: "mint-empty-state__description"
1508
+ };
1509
+ var _hoisted_6$4 = {
1510
+ key: 2,
1511
+ class: "mint-empty-state__content"
1512
+ };
1513
+ var _hoisted_7$4 = {
1514
+ key: 0,
1515
+ class: "mint-empty-state__action"
1516
+ };
1517
+ //#endregion
1518
+ //#region src/components/EmptyState.vue
1519
+ var EmptyState_default = /* @__PURE__ */ defineComponent({
1520
+ __name: "EmptyState",
1521
+ props: {
1522
+ title: {},
1523
+ description: {},
1524
+ iconPath: {},
1525
+ tone: { default: "neutral" },
1526
+ size: { default: "md" },
1527
+ variant: { default: "illustrated" },
1528
+ actionLabel: {}
1529
+ },
1530
+ emits: ["action"],
1531
+ setup(__props, { emit: __emit }) {
1532
+ /** Empty-state placeholder with icon badge, headline, description, default slot, and optional CTA button. */
1533
+ const emit = __emit;
1534
+ const defaultIconPaths = [
1535
+ "M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",
1536
+ "M7 11h10",
1537
+ "M7 15h6",
1538
+ "M7 7h8"
1539
+ ];
1540
+ return (_ctx, _cache) => {
1541
+ return openBlock(), createElementBlock("div", { class: normalizeClass([
1542
+ "mint-empty-state",
1543
+ `mint-empty-state--${__props.variant}`,
1544
+ `mint-empty-state--${__props.size}`
1545
+ ]) }, [
1546
+ createElementVNode("div", { class: normalizeClass(["mint-empty-state__icon-wrapper", `mint-empty-state__icon-wrapper--${__props.tone}`]) }, [renderSlot(_ctx.$slots, "icon", {}, () => [(openBlock(), createElementBlock("svg", {
1547
+ class: normalizeClass(["mint-empty-state__icon", `mint-empty-state__icon--${__props.tone}`]),
1548
+ viewBox: "0 0 24 24",
1549
+ fill: "none",
1550
+ stroke: "currentColor",
1551
+ "stroke-width": "2",
1552
+ "stroke-linecap": "round",
1553
+ "stroke-linejoin": "round"
1554
+ }, [__props.iconPath ? (openBlock(), createElementBlock("path", {
1555
+ key: 0,
1556
+ d: __props.iconPath
1557
+ }, null, 8, _hoisted_1$5)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, renderList(defaultIconPaths, (d, i) => {
1558
+ return createElementVNode("path", {
1559
+ key: i,
1560
+ d
1561
+ }, null, 8, _hoisted_2$5);
1562
+ }), 64))], 2))])], 2),
1563
+ createElementVNode("div", _hoisted_3$5, [
1564
+ __props.title ? (openBlock(), createElementBlock("h3", _hoisted_4$4, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
1565
+ __props.description ? (openBlock(), createElementBlock("p", _hoisted_5$4, toDisplayString(__props.description), 1)) : createCommentVNode("", true),
1566
+ _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_6$4, [renderSlot(_ctx.$slots, "default")])) : createCommentVNode("", true)
1567
+ ]),
1568
+ __props.actionLabel ? (openBlock(), createElementBlock("div", _hoisted_7$4, [createVNode(BaseButton_default, {
1569
+ variant: "secondary",
1570
+ size: "sm",
1571
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("action"))
1572
+ }, {
1573
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.actionLabel), 1)]),
1574
+ _: 1
1575
+ })])) : createCommentVNode("", true)
1576
+ ], 2);
1577
+ };
1578
+ }
1579
+ });
1580
+ //#endregion
1581
+ //#region src/components/FormField.vue?vue&type=script&setup=true&lang.ts
1582
+ var _hoisted_1$4 = {
1583
+ key: 0,
1584
+ class: "mint-form-field__label-row"
1585
+ };
1586
+ var _hoisted_2$4 = ["id", "for"];
1587
+ var _hoisted_3$4 = {
1588
+ key: 0,
1589
+ class: "mint-form-field__required",
1590
+ "aria-hidden": "true"
1591
+ };
1592
+ var _hoisted_4$3 = {
1593
+ key: 0,
1594
+ class: "mint-form-field__optional"
1595
+ };
1596
+ var _hoisted_5$3 = {
1597
+ key: 1,
1598
+ class: "mint-form-field__control"
1599
+ };
1600
+ var _hoisted_6$3 = ["id"];
1601
+ var _hoisted_7$3 = ["id"];
1602
+ //#endregion
1603
+ //#region src/components/FormField.vue
1604
+ var FormField_default = /* @__PURE__ */ defineComponent({
1605
+ __name: "FormField",
1606
+ props: {
1607
+ label: {},
1608
+ error: {},
1609
+ hint: {},
1610
+ required: { type: Boolean },
1611
+ showOptional: { type: Boolean },
1612
+ htmlFor: {},
1613
+ fieldId: {},
1614
+ layout: { default: "stacked" }
1615
+ },
1616
+ setup(__props) {
1617
+ /** Wraps a form control with a label, optional hint text, and validation error display. */
1618
+ const props = __props;
1619
+ const errorId = computed(() => props.error && props.fieldId ? `${props.fieldId}-error` : void 0);
1620
+ const hintId = computed(() => !props.error && props.hint && props.fieldId ? `${props.fieldId}-hint` : void 0);
1621
+ const describedBy = computed(() => errorId.value ?? hintId.value);
1622
+ return (_ctx, _cache) => {
1623
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["mint-form-field", __props.layout === "row" ? "mint-form-field--row" : ""]) }, [
1624
+ __props.label ? (openBlock(), createElementBlock("div", _hoisted_1$4, [createElementVNode("label", {
1625
+ id: __props.fieldId ? `${__props.fieldId}-label` : void 0,
1626
+ for: __props.htmlFor,
1627
+ class: "mint-form-field__label"
1628
+ }, [createTextVNode(toDisplayString(__props.label) + " ", 1), __props.required ? (openBlock(), createElementBlock("span", _hoisted_3$4, "*")) : createCommentVNode("", true)], 8, _hoisted_2$4), !__props.required && __props.showOptional ? (openBlock(), createElementBlock("span", _hoisted_4$3, " optional ")) : createCommentVNode("", true)])) : createCommentVNode("", true),
1629
+ __props.layout === "row" ? (openBlock(), createElementBlock("div", _hoisted_5$3, [renderSlot(_ctx.$slots, "default", { describedBy: describedBy.value })])) : renderSlot(_ctx.$slots, "default", { describedBy: describedBy.value }, void 0, void 0, 2),
1630
+ __props.error ? (openBlock(), createElementBlock("p", {
1631
+ key: 3,
1632
+ id: errorId.value,
1633
+ class: "mint-form-field__error",
1634
+ role: "alert"
1635
+ }, toDisplayString(__props.error), 9, _hoisted_6$3)) : __props.hint ? (openBlock(), createElementBlock("p", {
1636
+ key: 4,
1637
+ id: hintId.value,
1638
+ class: "mint-form-field__hint"
1639
+ }, toDisplayString(__props.hint), 9, _hoisted_7$3)) : createCommentVNode("", true)
1640
+ ], 2);
1641
+ };
1642
+ }
1643
+ });
1644
+ //#endregion
1645
+ //#region src/utils/time.ts
1646
+ var time_exports = /* @__PURE__ */ __exportAll({
1647
+ addMinutes: () => addMinutes,
1648
+ compareTime: () => compareTime,
1649
+ durationMinutes: () => durationMinutes,
1650
+ findAvailableSlots: () => findAvailableSlots,
1651
+ findNearestTimeSlotIndex: () => findNearestTimeSlotIndex,
1652
+ formatDuration: () => formatDuration,
1653
+ formatRelativeTime: () => formatRelativeTime,
1654
+ formatTime: () => formatTime,
1655
+ formatTimeSlot: () => formatTimeSlot,
1656
+ fromMinutes: () => fromMinutes,
1657
+ generateTimeSlots: () => generateTimeSlots,
1658
+ isTimeInRange: () => isTimeInRange,
1659
+ parseTime: () => parseTime,
1660
+ rangesOverlap: () => rangesOverlap,
1661
+ snapToSlot: () => snapToSlot,
1662
+ toMinutes: () => toMinutes
1663
+ });
1664
+ function parseTime(time) {
1665
+ const [h, m] = time.split(":").map(Number);
1666
+ return {
1667
+ hour: h,
1668
+ minute: m
1669
+ };
1670
+ }
1671
+ function formatTime(hour, minute, format = "24h") {
1672
+ if (format === "24h") return `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
1673
+ const period = hour >= 12 ? "PM" : "AM";
1674
+ return `${hour === 0 ? 12 : hour > 12 ? hour - 12 : hour}:${String(minute).padStart(2, "0")} ${period}`;
1675
+ }
1676
+ function formatTimeSlot(time, format = "24h") {
1677
+ const { hour, minute } = parseTime(time);
1678
+ return formatTime(hour, minute, format);
1679
+ }
1680
+ function generateTimeSlots(start, end, stepMinutes) {
1681
+ const slots = [];
1682
+ const s = parseTime(start);
1683
+ const e = parseTime(end);
1684
+ const startMin = s.hour * 60 + s.minute;
1685
+ const endMin = e.hour * 60 + e.minute;
1686
+ for (let m = startMin; m <= endMin; m += stepMinutes) {
1687
+ const hour = Math.floor(m / 60);
1688
+ const minute = m % 60;
1689
+ if (hour >= 24) break;
1690
+ slots.push(formatTime(hour, minute));
1691
+ }
1692
+ return slots;
1693
+ }
1694
+ function rangesOverlap(a, b) {
1695
+ const aStart = toMinutes(a.start);
1696
+ const aEnd = toMinutes(a.end);
1697
+ const bStart = toMinutes(b.start);
1698
+ return aStart < toMinutes(b.end) && bStart < aEnd;
1699
+ }
1700
+ function durationMinutes(start, end) {
1701
+ return toMinutes(end) - toMinutes(start);
1702
+ }
1703
+ function formatDuration(minutes) {
1704
+ if (minutes < 0) return "-" + formatDuration(-minutes);
1705
+ const h = Math.floor(minutes / 60);
1706
+ const m = minutes % 60;
1707
+ if (h === 0) return `${m}m`;
1708
+ if (m === 0) return `${h}h`;
1709
+ return `${h}h ${m}m`;
1710
+ }
1711
+ function isTimeInRange(time, start, end) {
1712
+ const t = toMinutes(time);
1713
+ return t >= toMinutes(start) && t <= toMinutes(end);
1714
+ }
1715
+ function findAvailableSlots(dayStart, dayEnd, occupied, minDuration) {
1716
+ const sorted = [...occupied].sort((a, b) => toMinutes(a.start) - toMinutes(b.start));
1717
+ const available = [];
1718
+ let cursor = toMinutes(dayStart);
1719
+ const end = toMinutes(dayEnd);
1720
+ for (const slot of sorted) {
1721
+ const slotStart = toMinutes(slot.start);
1722
+ const slotEnd = toMinutes(slot.end);
1723
+ if (slotStart > cursor && slotStart - cursor >= minDuration) available.push({
1724
+ start: fromMinutes(cursor),
1725
+ end: fromMinutes(slotStart)
1726
+ });
1727
+ cursor = Math.max(cursor, slotEnd);
1728
+ }
1729
+ if (end > cursor && end - cursor >= minDuration) available.push({
1730
+ start: fromMinutes(cursor),
1731
+ end: fromMinutes(end)
1732
+ });
1733
+ return available;
1734
+ }
1735
+ function snapToSlot(time, stepMinutes) {
1736
+ const total = toMinutes(time);
1737
+ return fromMinutes(Math.round(total / stepMinutes) * stepMinutes);
1738
+ }
1739
+ function addMinutes(time, minutes) {
1740
+ const total = toMinutes(time) + minutes;
1741
+ return fromMinutes(Math.max(0, Math.min(total, 1439)));
1742
+ }
1743
+ function compareTime(a, b) {
1744
+ const ma = toMinutes(a);
1745
+ const mb = toMinutes(b);
1746
+ if (ma < mb) return -1;
1747
+ if (ma > mb) return 1;
1748
+ return 0;
1749
+ }
1750
+ function findNearestTimeSlotIndex(time, slots) {
1751
+ if (slots.length === 0) return -1;
1752
+ const target = toMinutes(time);
1753
+ let bestIndex = 0;
1754
+ let bestDiff = Infinity;
1755
+ for (let index = 0; index < slots.length; index++) {
1756
+ const diff = Math.abs(toMinutes(slots[index]) - target);
1757
+ if (diff < bestDiff) {
1758
+ bestDiff = diff;
1759
+ bestIndex = index;
1760
+ }
1761
+ }
1762
+ return bestIndex;
1763
+ }
1764
+ var relativeTimeFormat = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
1765
+ /**
1766
+ * "in 5 minutes" / "2 hours ago" up to a week, then a locale date.
1767
+ * With `weeks`, times up to five weeks away read as a week count first.
1768
+ */
1769
+ function formatRelativeTime(value, { weeks = false } = {}) {
1770
+ const date = value instanceof Date ? value : new Date(value);
1771
+ const diffSec = Math.round((date.getTime() - Date.now()) / 1e3);
1772
+ const diffMin = Math.round(diffSec / 60);
1773
+ const diffHr = Math.round(diffMin / 60);
1774
+ const diffDay = Math.round(diffHr / 24);
1775
+ const diffWeek = Math.round(diffDay / 7);
1776
+ if (Math.abs(diffSec) < 60) return relativeTimeFormat.format(diffSec, "second");
1777
+ if (Math.abs(diffMin) < 60) return relativeTimeFormat.format(diffMin, "minute");
1778
+ if (Math.abs(diffHr) < 24) return relativeTimeFormat.format(diffHr, "hour");
1779
+ if (Math.abs(diffDay) < 7) return relativeTimeFormat.format(diffDay, "day");
1780
+ if (weeks && Math.abs(diffWeek) < 5) return relativeTimeFormat.format(diffWeek, "week");
1781
+ return date.toLocaleDateString();
1782
+ }
1783
+ function toMinutes(time) {
1784
+ const { hour, minute } = parseTime(time);
1785
+ return hour * 60 + minute;
1786
+ }
1787
+ function fromMinutes(total) {
1788
+ return formatTime(Math.floor(total / 60) % 24, total % 60);
1789
+ }
1790
+ //#endregion
1791
+ //#region src/composables/useMenuKeyboard.ts
1792
+ /**
1793
+ * Shared keyboard contract for menu- and listbox-style disclosure panels (the
1794
+ * WAI-ARIA menu button pattern). Used by ActionMenu and the platform account menu,
1795
+ * each pairing it with `useDropdownState` for the disclosure state itself.
1796
+ */
1797
+ function useMenuKeyboard(options) {
1798
+ function focusItem(position) {
1799
+ nextTick(() => {
1800
+ const items = options.items();
1801
+ (position === "first" ? items[0] : items[items.length - 1])?.focus();
1802
+ });
1803
+ }
1804
+ function handleTriggerKeydown(event) {
1805
+ if (options.isOpen()) return;
1806
+ if (event.key === "ArrowDown" || event.key === "Enter" || event.key === " ") {
1807
+ event.preventDefault();
1808
+ options.open();
1809
+ focusItem("first");
1810
+ return;
1811
+ }
1812
+ if (event.key === "ArrowUp") {
1813
+ event.preventDefault();
1814
+ options.open();
1815
+ focusItem("last");
1816
+ }
1817
+ }
1818
+ function handlePanelKeydown(event) {
1819
+ const items = options.items();
1820
+ const currentIndex = items.indexOf(document.activeElement);
1821
+ if (event.key === "Escape") {
1822
+ event.preventDefault();
1823
+ event.stopPropagation();
1824
+ options.close(true);
1825
+ return;
1826
+ }
1827
+ if (event.key === "Tab") {
1828
+ options.close();
1829
+ return;
1830
+ }
1831
+ if (event.key === "Home") {
1832
+ event.preventDefault();
1833
+ items[0]?.focus();
1834
+ return;
1835
+ }
1836
+ if (event.key === "End") {
1837
+ event.preventDefault();
1838
+ items[items.length - 1]?.focus();
1839
+ return;
1840
+ }
1841
+ if (event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
1842
+ event.preventDefault();
1843
+ const direction = event.key === "ArrowDown" ? 1 : -1;
1844
+ items[(Math.max(currentIndex, 0) + direction + items.length) % items.length]?.focus();
1845
+ }
1846
+ return {
1847
+ handleTriggerKeydown,
1848
+ handlePanelKeydown
1849
+ };
1850
+ }
1851
+ //#endregion
1852
+ //#region src/components/FileUploader.vue?vue&type=script&setup=true&lang.ts
1853
+ var _hoisted_1$3 = { class: "mint-file-uploader" };
1854
+ var _hoisted_2$3 = [
1855
+ "aria-label",
1856
+ "aria-disabled",
1857
+ "onKeydown"
1858
+ ];
1859
+ var _hoisted_3$3 = [
1860
+ "accept",
1861
+ "multiple",
1862
+ "disabled",
1863
+ "webkitdirectory"
1864
+ ];
1865
+ var _hoisted_4$2 = { class: "mint-file-uploader__content" };
1866
+ var _hoisted_5$2 = {
1867
+ key: 0,
1868
+ class: "mint-file-uploader__icon",
1869
+ fill: "none",
1870
+ stroke: "currentColor",
1871
+ "stroke-width": "1.5",
1872
+ "stroke-linecap": "round",
1873
+ "stroke-linejoin": "round",
1874
+ viewBox: "0 0 24 24"
1875
+ };
1876
+ var _hoisted_6$2 = {
1877
+ key: 1,
1878
+ class: "mint-file-uploader__icon",
1879
+ fill: "none",
1880
+ stroke: "currentColor",
1881
+ "stroke-width": "1.5",
1882
+ "stroke-linecap": "round",
1883
+ "stroke-linejoin": "round",
1884
+ viewBox: "0 0 24 24"
1885
+ };
1886
+ var _hoisted_7$2 = { class: "mint-file-uploader__text" };
1887
+ var _hoisted_8$1 = {
1888
+ key: 0,
1889
+ class: "mint-file-uploader__actions"
1890
+ };
1891
+ var _hoisted_9$1 = {
1892
+ key: 1,
1893
+ class: "mint-file-uploader__folder-summary"
1894
+ };
1895
+ var _hoisted_10$1 = { class: "mint-file-uploader__folder-info" };
1896
+ var _hoisted_11$1 = { class: "mint-file-uploader__folder-details" };
1897
+ var _hoisted_12$1 = { class: "mint-file-uploader__folder-name" };
1898
+ var _hoisted_13 = { class: "mint-file-uploader__folder-count" };
1899
+ var _hoisted_14 = { class: "mint-file-uploader__file-info" };
1900
+ var _hoisted_15 = { class: "mint-file-uploader__file-meta" };
1901
+ var _hoisted_16 = { class: "mint-file-uploader__file-name" };
1902
+ var _hoisted_17 = { class: "mint-file-uploader__file-size" };
1903
+ var _hoisted_18 = ["aria-label", "onClick"];
1904
+ //#endregion
1905
+ //#region src/components/FileUploader.vue
1906
+ var FileUploader_default = /* @__PURE__ */ defineComponent({
1907
+ __name: "FileUploader",
1908
+ props: {
1909
+ accept: {},
1910
+ multiple: {
1911
+ type: Boolean,
1912
+ default: false
1913
+ },
1914
+ maxSize: {},
1915
+ disabled: {
1916
+ type: Boolean,
1917
+ default: false
1918
+ },
1919
+ size: { default: "md" },
1920
+ mode: { default: "file" },
1921
+ showFiles: {
1922
+ type: Boolean,
1923
+ default: true
1924
+ },
1925
+ files: {},
1926
+ rootName: {}
1927
+ },
1928
+ emits: [
1929
+ "upload",
1930
+ "remove",
1931
+ "error"
1932
+ ],
1933
+ setup(__props, { emit: __emit }) {
1934
+ /** Drag-and-drop file upload zone with type filtering, size validation, and folder mode. */
1935
+ const props = __props;
1936
+ const emit = __emit;
1937
+ const isDragOver = ref(false);
1938
+ const inputRef = ref();
1939
+ const selectedFiles = ref([]);
1940
+ const folderName = ref(null);
1941
+ watch(() => [props.files, props.rootName], ([files, rootName]) => {
1942
+ if (files === void 0) return;
1943
+ selectedFiles.value = [...files];
1944
+ folderName.value = rootName ?? extractFolderName(files);
1945
+ }, { immediate: true });
1946
+ const isFolder = computed(() => props.mode === "folder");
1947
+ const isMixed = computed(() => props.mode === "file+folder");
1948
+ const acceptLabel = computed(() => {
1949
+ if (!props.accept) return isFolder.value ? "a folder" : "any file";
1950
+ return props.accept.split(",").map((a) => a.trim().replace(".", "").toUpperCase()).join(", ");
1951
+ });
1952
+ const maxSizeLabel = computed(() => {
1953
+ if (!props.maxSize) return null;
1954
+ if (props.maxSize >= 1073741824) return `${(props.maxSize / 1073741824).toFixed(1)} GB`;
1955
+ if (props.maxSize >= 1048576) return `${(props.maxSize / 1048576).toFixed(1)} MB`;
1956
+ if (props.maxSize >= 1024) return `${(props.maxSize / 1024).toFixed(1)} KB`;
1957
+ return `${props.maxSize} bytes`;
1958
+ });
1959
+ const fileTypeMap = {
1960
+ csv: {
1961
+ color: "#10B981",
1962
+ label: "CSV"
1963
+ },
1964
+ tsv: {
1965
+ color: "#10B981",
1966
+ label: "TSV"
1967
+ },
1968
+ xlsx: {
1969
+ color: "#10B981",
1970
+ label: "XLSX"
1971
+ },
1972
+ xls: {
1973
+ color: "#10B981",
1974
+ label: "XLS"
1975
+ },
1976
+ pdf: {
1977
+ color: "#EF4444",
1978
+ label: "PDF"
1979
+ },
1980
+ png: {
1981
+ color: "#8B5CF6",
1982
+ label: "PNG"
1983
+ },
1984
+ jpg: {
1985
+ color: "#8B5CF6",
1986
+ label: "JPG"
1987
+ },
1988
+ jpeg: {
1989
+ color: "#8B5CF6",
1990
+ label: "JPEG"
1991
+ },
1992
+ gif: {
1993
+ color: "#8B5CF6",
1994
+ label: "GIF"
1995
+ },
1996
+ svg: {
1997
+ color: "#8B5CF6",
1998
+ label: "SVG"
1999
+ },
2000
+ webp: {
2001
+ color: "#8B5CF6",
2002
+ label: "WEBP"
2003
+ },
2004
+ json: {
2005
+ color: "#F59E0B",
2006
+ label: "JSON"
2007
+ },
2008
+ xml: {
2009
+ color: "#F59E0B",
2010
+ label: "XML"
2011
+ },
2012
+ txt: {
2013
+ color: "#64748B",
2014
+ label: "TXT"
2015
+ },
2016
+ zip: {
2017
+ color: "#6366F1",
2018
+ label: "ZIP"
2019
+ },
2020
+ gz: {
2021
+ color: "#6366F1",
2022
+ label: "GZ"
2023
+ },
2024
+ py: {
2025
+ color: "#3B82F6",
2026
+ label: "PY"
2027
+ },
2028
+ js: {
2029
+ color: "#EAB308",
2030
+ label: "JS"
2031
+ },
2032
+ ts: {
2033
+ color: "#3B82F6",
2034
+ label: "TS"
2035
+ },
2036
+ fasta: {
2037
+ color: "#EC4899",
2038
+ label: "FASTA"
2039
+ },
2040
+ fastq: {
2041
+ color: "#EC4899",
2042
+ label: "FASTQ"
2043
+ },
2044
+ bam: {
2045
+ color: "#EC4899",
2046
+ label: "BAM"
2047
+ },
2048
+ vcf: {
2049
+ color: "#EC4899",
2050
+ label: "VCF"
2051
+ }
2052
+ };
2053
+ function getFileType(filename) {
2054
+ const ext = filename.split(".").pop()?.toLowerCase() || "";
2055
+ return fileTypeMap[ext] || {
2056
+ color: "#94A3B8",
2057
+ label: ext.toUpperCase() || "FILE"
2058
+ };
2059
+ }
2060
+ function validateFiles(files) {
2061
+ const validFiles = [];
2062
+ for (const file of Array.from(files)) {
2063
+ if (props.maxSize && file.size > props.maxSize) {
2064
+ emit("error", `File "${file.name}" exceeds maximum size of ${maxSizeLabel.value}`);
2065
+ continue;
2066
+ }
2067
+ if (props.accept) {
2068
+ const acceptedTypes = props.accept.split(",").map((t) => t.trim().toLowerCase());
2069
+ const fileExt = "." + file.name.split(".").pop()?.toLowerCase();
2070
+ const fileType = file.type.toLowerCase();
2071
+ if (!acceptedTypes.some((type) => {
2072
+ if (type.startsWith(".")) return fileExt === type;
2073
+ if (type.endsWith("/*")) return fileType.startsWith(type.replace("/*", "/"));
2074
+ return fileType === type;
2075
+ })) {
2076
+ emit("error", `File "${file.name}" is not an accepted file type`);
2077
+ continue;
2078
+ }
2079
+ }
2080
+ validFiles.push(file);
2081
+ }
2082
+ return validFiles;
2083
+ }
2084
+ function handleFiles(files, folder, explicitRelativePaths) {
2085
+ const candidates = Array.from(files);
2086
+ const validFiles = validateFiles(files);
2087
+ if (validFiles.length === 0) return;
2088
+ const relativePaths = validFiles.map((file) => {
2089
+ const candidateIndex = candidates.indexOf(file);
2090
+ return explicitRelativePaths?.[candidateIndex] || file.webkitRelativePath || (folder ? `${folder}/${file.name}` : file.name);
2091
+ });
2092
+ if (isFolder.value) {
2093
+ folderName.value = folder || extractFolderName(validFiles);
2094
+ selectedFiles.value = validFiles;
2095
+ emit("upload", validFiles, folderName.value ?? void 0, relativePaths);
2096
+ } else if (!props.multiple) {
2097
+ selectedFiles.value = [validFiles[0]];
2098
+ emit("upload", [validFiles[0]], void 0, [relativePaths[0]]);
2099
+ } else {
2100
+ selectedFiles.value = [...selectedFiles.value, ...validFiles];
2101
+ emit("upload", validFiles, void 0, relativePaths);
2102
+ }
2103
+ }
2104
+ function extractFolderName(files) {
2105
+ if (files.length === 0) return null;
2106
+ const firstPath = files[0].webkitRelativePath;
2107
+ if (firstPath) return firstPath.split("/")[0];
2108
+ return null;
2109
+ }
2110
+ async function handleDrop(event) {
2111
+ event.preventDefault();
2112
+ isDragOver.value = false;
2113
+ if (props.disabled) return;
2114
+ try {
2115
+ if (props.mode !== "file" && event.dataTransfer?.items?.length) await handleFolderDrop(event.dataTransfer.items);
2116
+ else if (event.dataTransfer?.files) handleFiles(event.dataTransfer.files);
2117
+ } catch (cause) {
2118
+ emit("error", cause instanceof Error ? cause.message : "Could not read the dropped folder.");
2119
+ }
2120
+ }
2121
+ async function handleFolderDrop(items) {
2122
+ const files = [];
2123
+ const relativePaths = [];
2124
+ let folderNameFromDrop;
2125
+ const dropped = Array.from(items, (item) => {
2126
+ const entry = item.webkitGetAsEntry?.();
2127
+ return {
2128
+ entry,
2129
+ file: entry ? null : item.getAsFile?.()
2130
+ };
2131
+ });
2132
+ for (const { entry, file: droppedFile } of dropped) if (entry?.isDirectory) {
2133
+ folderNameFromDrop = entry.name;
2134
+ await readDirectory(entry, files, relativePaths, entry.name);
2135
+ } else {
2136
+ const file = entry?.isFile ? await getFile(entry) : droppedFile;
2137
+ if (file) {
2138
+ files.push(file);
2139
+ relativePaths.push(file.name);
2140
+ }
2141
+ }
2142
+ if (files.length > 0) handleFiles(files, folderNameFromDrop, relativePaths);
2143
+ }
2144
+ async function readDirectory(directory, files, relativePaths, prefix) {
2145
+ const reader = directory.createReader();
2146
+ let batch;
2147
+ do {
2148
+ batch = await new Promise((resolve, reject) => {
2149
+ reader.readEntries(resolve, reject);
2150
+ });
2151
+ for (const entry of batch) if (entry.isFile) {
2152
+ const file = await getFile(entry);
2153
+ if (file) {
2154
+ files.push(file);
2155
+ relativePaths.push(`${prefix}/${file.name}`);
2156
+ }
2157
+ } else if (entry.isDirectory) await readDirectory(entry, files, relativePaths, `${prefix}/${entry.name}`);
2158
+ } while (batch.length > 0);
2159
+ }
2160
+ function getFile(entry) {
2161
+ return new Promise((resolve) => {
2162
+ entry.file(resolve, () => resolve(null));
2163
+ });
2164
+ }
2165
+ function handleDragOver(event) {
2166
+ event.preventDefault();
2167
+ if (!props.disabled) isDragOver.value = true;
2168
+ }
2169
+ function handleDragLeave() {
2170
+ isDragOver.value = false;
2171
+ }
2172
+ function handleInputChange(event) {
2173
+ const target = event.target;
2174
+ if (target.files) handleFiles(target.files);
2175
+ target.value = "";
2176
+ }
2177
+ function openFilePicker() {
2178
+ if (!props.disabled) inputRef.value?.click();
2179
+ }
2180
+ function removeFile(index) {
2181
+ const removed = selectedFiles.value[index];
2182
+ selectedFiles.value = selectedFiles.value.filter((_, i) => i !== index);
2183
+ if (isFolder.value && selectedFiles.value.length === 0) folderName.value = null;
2184
+ if (removed) emit("remove", [removed]);
2185
+ }
2186
+ function clearAll() {
2187
+ const removed = [...selectedFiles.value];
2188
+ selectedFiles.value = [];
2189
+ folderName.value = null;
2190
+ if (removed.length) emit("remove", removed);
2191
+ }
2192
+ function formatFileSize(bytes) {
2193
+ if (bytes >= 1048576) return `${(bytes / 1048576).toFixed(1)} MB`;
2194
+ if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;
2195
+ return `${bytes} bytes`;
2196
+ }
2197
+ return (_ctx, _cache) => {
2198
+ return openBlock(), createElementBlock("div", _hoisted_1$3, [
2199
+ createElementVNode("div", {
2200
+ role: "button",
2201
+ tabindex: "0",
2202
+ "aria-label": __props.disabled ? "File upload disabled" : isMixed.value ? "Drop files or a folder, or click to choose files" : isFolder.value ? "Click or drag a folder to upload" : "Click or drag files to upload",
2203
+ "aria-disabled": __props.disabled,
2204
+ class: normalizeClass([
2205
+ "mint-file-uploader__dropzone",
2206
+ `mint-file-uploader__dropzone--${__props.size}`,
2207
+ isDragOver.value ? "mint-file-uploader__dropzone--dragover" : "",
2208
+ __props.disabled ? "mint-file-uploader__dropzone--disabled" : "",
2209
+ selectedFiles.value.length > 0 ? "mint-file-uploader__dropzone--has-files" : ""
2210
+ ]),
2211
+ onClick: openFilePicker,
2212
+ onKeydown: [withKeys(openFilePicker, ["enter"]), withKeys(withModifiers(openFilePicker, ["prevent"]), ["space"])],
2213
+ onDrop: handleDrop,
2214
+ onDragover: handleDragOver,
2215
+ onDragleave: handleDragLeave
2216
+ }, [createElementVNode("input", {
2217
+ ref_key: "inputRef",
2218
+ ref: inputRef,
2219
+ type: "file",
2220
+ accept: __props.accept,
2221
+ multiple: isFolder.value || __props.multiple,
2222
+ disabled: __props.disabled,
2223
+ webkitdirectory: isFolder.value || void 0,
2224
+ class: "mint-file-uploader__input",
2225
+ onChange: handleInputChange
2226
+ }, null, 40, _hoisted_3$3), createElementVNode("div", _hoisted_4$2, [isFolder.value ? (openBlock(), createElementBlock("svg", _hoisted_5$2, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" }, null, -1)])])) : (openBlock(), createElementBlock("svg", _hoisted_6$2, [..._cache[1] || (_cache[1] = [
2227
+ createElementVNode("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" }, null, -1),
2228
+ createElementVNode("path", { d: "m16 16-4-4-4 4" }, null, -1),
2229
+ createElementVNode("path", { d: "M12 12v9" }, null, -1)
2230
+ ])])), createElementVNode("p", _hoisted_7$2, toDisplayString(isMixed.value ? "Drop files or a folder, or click to choose files" : `Drop ${acceptLabel.value} or click`), 1)])], 42, _hoisted_2$3),
2231
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_8$1, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true),
2232
+ __props.showFiles && isFolder.value && folderName.value && selectedFiles.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_9$1, [createElementVNode("div", _hoisted_10$1, [_cache[2] || (_cache[2] = createElementVNode("div", { class: "mint-file-uploader__folder-icon-wrapper" }, [createElementVNode("svg", {
2233
+ class: "mint-file-uploader__folder-icon",
2234
+ fill: "none",
2235
+ stroke: "currentColor",
2236
+ "stroke-width": "2",
2237
+ "stroke-linecap": "round",
2238
+ "stroke-linejoin": "round",
2239
+ viewBox: "0 0 24 24"
2240
+ }, [createElementVNode("path", { d: "m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2" })])], -1)), createElementVNode("div", _hoisted_11$1, [createElementVNode("span", _hoisted_12$1, toDisplayString(folderName.value), 1), createElementVNode("span", _hoisted_13, toDisplayString(selectedFiles.value.length) + " file" + toDisplayString(selectedFiles.value.length !== 1 ? "s" : ""), 1)])]), createElementVNode("button", {
2241
+ type: "button",
2242
+ "aria-label": "Clear folder",
2243
+ class: "mint-file-uploader__remove-btn",
2244
+ onClick: withModifiers(clearAll, ["stop"])
2245
+ }, [..._cache[3] || (_cache[3] = [createElementVNode("svg", {
2246
+ class: "mint-file-uploader__remove-icon",
2247
+ fill: "none",
2248
+ stroke: "currentColor",
2249
+ "stroke-width": "2",
2250
+ "stroke-linecap": "round",
2251
+ "stroke-linejoin": "round",
2252
+ viewBox: "0 0 24 24"
2253
+ }, [createElementVNode("path", { d: "M18 6 6 18" }), createElementVNode("path", { d: "m6 6 12 12" })], -1)])])])) : createCommentVNode("", true),
2254
+ __props.showFiles && !isFolder.value && selectedFiles.value.length > 0 ? (openBlock(), createBlock(TransitionGroup, {
2255
+ key: 2,
2256
+ tag: "ul",
2257
+ name: "mint-file-uploader-item",
2258
+ class: "mint-file-uploader__list"
2259
+ }, {
2260
+ default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(selectedFiles.value, (file, index) => {
2261
+ return openBlock(), createElementBlock("li", {
2262
+ key: `${file.name}-${file.size}-${index}`,
2263
+ class: "mint-file-uploader__file"
2264
+ }, [createElementVNode("div", _hoisted_14, [createElementVNode("span", {
2265
+ class: "mint-file-uploader__file-badge",
2266
+ style: normalizeStyle({ "--badge-color": getFileType(file.name).color })
2267
+ }, toDisplayString(getFileType(file.name).label), 5), createElementVNode("div", _hoisted_15, [createElementVNode("span", _hoisted_16, toDisplayString(file.name), 1), createElementVNode("span", _hoisted_17, toDisplayString(formatFileSize(file.size)), 1)])]), createElementVNode("button", {
2268
+ type: "button",
2269
+ "aria-label": `Remove ${file.name}`,
2270
+ class: "mint-file-uploader__remove-btn",
2271
+ onClick: withModifiers(($event) => removeFile(index), ["stop"])
2272
+ }, [..._cache[4] || (_cache[4] = [createElementVNode("svg", {
2273
+ class: "mint-file-uploader__remove-icon",
2274
+ fill: "none",
2275
+ stroke: "currentColor",
2276
+ "stroke-width": "2",
2277
+ "stroke-linecap": "round",
2278
+ "stroke-linejoin": "round",
2279
+ viewBox: "0 0 24 24"
2280
+ }, [createElementVNode("path", { d: "M18 6 6 18" }), createElementVNode("path", { d: "m6 6 12 12" })], -1)])], 8, _hoisted_18)]);
2281
+ }), 128))]),
2282
+ _: 1
2283
+ })) : createCommentVNode("", true)
2284
+ ]);
2285
+ };
2286
+ }
2287
+ });
2288
+ //#endregion
2289
+ //#region src/composables/experiment-utils.ts
2290
+ function formatExperimentDate(dateStr) {
2291
+ try {
2292
+ return new Date(dateStr).toLocaleDateString(void 0, {
2293
+ year: "numeric",
2294
+ month: "short",
2295
+ day: "numeric"
2296
+ });
2297
+ } catch {
2298
+ return dateStr;
2299
+ }
2300
+ }
2301
+ function datePresetToISO(preset) {
2302
+ const now = /* @__PURE__ */ new Date();
2303
+ const days = preset === "last_7_days" ? 7 : preset === "last_30_days" ? 30 : 90;
2304
+ return (/* @__PURE__ */ new Date(now.getTime() - days * 864e5)).toISOString();
2305
+ }
2306
+ function resolveExperimentCode(experiment) {
2307
+ if (experiment.experiment_code) return experiment.experiment_code;
2308
+ }
2309
+ /**
2310
+ * Reads the experiment id a deep link was opened with.
2311
+ *
2312
+ * Returns an id and never a label: a display name belongs to the platform, so
2313
+ * callers must resolve it (see `useExperimentStore().selectById`) rather than
2314
+ * derive one from the query or the id itself.
2315
+ */
2316
+ function experimentIdFromRoute(query) {
2317
+ const raw = query.experiment_id ?? query.experimentId;
2318
+ const value = Array.isArray(raw) ? raw.find((item) => typeof item === "string") : raw;
2319
+ if (typeof value !== "string" || !value) return null;
2320
+ const id = Number(value);
2321
+ return Number.isInteger(id) && id > 0 ? id : null;
2322
+ }
2323
+ var DATE_PRESET_OPTIONS = [
2324
+ {
2325
+ value: "",
2326
+ label: "Any time"
2327
+ },
2328
+ {
2329
+ value: "last_7_days",
2330
+ label: "Last 7 days"
2331
+ },
2332
+ {
2333
+ value: "last_30_days",
2334
+ label: "Last 30 days"
2335
+ },
2336
+ {
2337
+ value: "last_90_days",
2338
+ label: "Last 90 days"
2339
+ }
2340
+ ];
2341
+ var SORT_OPTIONS = [
2342
+ {
2343
+ value: "created_at:desc",
2344
+ label: "Newest first"
2345
+ },
2346
+ {
2347
+ value: "created_at:asc",
2348
+ label: "Oldest first"
2349
+ },
2350
+ {
2351
+ value: "updated_at:desc",
2352
+ label: "Recently updated"
2353
+ },
2354
+ {
2355
+ value: "name:asc",
2356
+ label: "Name A–Z"
2357
+ },
2358
+ {
2359
+ value: "name:desc",
2360
+ label: "Name Z–A"
2361
+ }
2362
+ ];
2363
+ //#endregion
2364
+ //#region src/composables/useAppExperiment.ts
2365
+ var APP_EXPERIMENT_KEY = Symbol("app-experiment");
2366
+ /**
2367
+ * Projects the current experiment from the shared store into an AppTopBar app
2368
+ * shell, and owns the shell-local concerns the store has no opinion on: the
2369
+ * selector modal's open state and the save flow.
2370
+ *
2371
+ * The composable never writes a selection of its own. `ExperimentSelectorModal`
2372
+ * commits to the store and this reads back, so a displayed name can only ever
2373
+ * have come from the platform.
2374
+ *
2375
+ * @example Recommended
2376
+ * ```ts
2377
+ * const appExperiment = useAppExperiment({
2378
+ * onSelect: experiment => loadExperiment(experiment.id),
2379
+ * })
2380
+ * ```
2381
+ */
2382
+ function useAppExperiment(options = {}) {
2383
+ const store = useExperimentStore();
2384
+ const showModal = ref(false);
2385
+ const saveLoading = ref(false);
2386
+ const saveSuccessMessage = ref();
2387
+ let successTimer = null;
2388
+ const experimentName = computed(() => store.current?.name);
2389
+ const experimentCode = computed(() => store.current ? resolveExperimentCode(store.current) : void 0);
2390
+ const experimentStatus = computed(() => store.current?.status);
2391
+ const experimentId = computed(() => store.currentId);
2392
+ const isResolving = computed(() => store.isResolving);
2393
+ const error = computed(() => store.error);
2394
+ const showSave = ref(!!options.onSave);
2395
+ const showDetach = computed(() => experimentId.value !== null);
2396
+ const saveDisabled = computed(() => toValue(options.saveDisabled) ?? false);
2397
+ const saveDisabledMessage = computed(() => toValue(options.saveDisabledMessage));
2398
+ const dirty = computed(() => toValue(options.dirty) ?? false);
2399
+ const experimentOwner = computed(() => {
2400
+ const owner = store.current?.created_by_user;
2401
+ return owner ? [owner.first_name, owner.last_name].filter(Boolean).join(" ") || owner.username : void 0;
2402
+ });
2403
+ const popover = computed(() => ({
2404
+ experimentName: experimentName.value,
2405
+ experimentCode: experimentCode.value,
2406
+ experimentStatus: experimentStatus.value,
2407
+ experimentId: experimentId.value,
2408
+ experimentProject: store.current?.project_name || store.current?.project || void 0,
2409
+ experimentOwner: experimentOwner.value,
2410
+ experimentUpdatedAt: store.current?.updated_at,
2411
+ isResolving: isResolving.value,
2412
+ error: error.value ?? void 0,
2413
+ showSave: showSave.value,
2414
+ showDetach: showDetach.value,
2415
+ saveDisabled: saveDisabled.value,
2416
+ saveDisabledMessage: saveDisabledMessage.value,
2417
+ saveLoading: saveLoading.value,
2418
+ saveSuccessMessage: saveSuccessMessage.value,
2419
+ dirty: dirty.value
2420
+ }));
2421
+ const selectorModal = computed(() => ({
2422
+ open: showModal.value,
2423
+ currentExperimentId: experimentId.value
2424
+ }));
2425
+ if (options.onSelect) watch(() => store.current?.id, (id) => {
2426
+ if (id !== void 0 && store.current) options.onSelect?.(store.current);
2427
+ });
2428
+ function openModal() {
2429
+ showModal.value = true;
2430
+ }
2431
+ function closeModal() {
2432
+ showModal.value = false;
2433
+ }
2434
+ async function handleSave() {
2435
+ if (!options.onSave || saveLoading.value) return;
2436
+ saveLoading.value = true;
2437
+ try {
2438
+ const message = await options.onSave();
2439
+ await store.refresh();
2440
+ if (message) {
2441
+ saveSuccessMessage.value = message;
2442
+ if (successTimer) clearTimeout(successTimer);
2443
+ successTimer = setTimeout(() => {
2444
+ saveSuccessMessage.value = void 0;
2445
+ successTimer = null;
2446
+ }, 3e3);
2447
+ }
2448
+ } finally {
2449
+ saveLoading.value = false;
2450
+ }
2451
+ }
2452
+ function handleDetach() {
2453
+ store.clear();
2454
+ options.onDetach?.();
2455
+ }
2456
+ onScopeDispose(() => {
2457
+ if (successTimer) clearTimeout(successTimer);
2458
+ });
2459
+ provide(APP_EXPERIMENT_KEY, {
2460
+ experimentName,
2461
+ experimentCode,
2462
+ experimentStatus,
2463
+ experimentId,
2464
+ isResolving,
2465
+ error,
2466
+ showModal,
2467
+ saveLoading,
2468
+ saveSuccessMessage,
2469
+ showSave,
2470
+ showDetach,
2471
+ saveDisabled,
2472
+ saveDisabledMessage,
2473
+ popover,
2474
+ selectorModal,
2475
+ openModal,
2476
+ closeModal,
2477
+ handleSave,
2478
+ handleDetach
2479
+ });
2480
+ return {
2481
+ experimentName,
2482
+ experimentCode,
2483
+ experimentStatus,
2484
+ experimentId,
2485
+ isResolving,
2486
+ error,
2487
+ popover,
2488
+ selectorModal,
2489
+ openModal,
2490
+ closeModal,
2491
+ handleSave,
2492
+ handleDetach
2493
+ };
2494
+ }
2495
+ //#endregion
2496
+ //#region src/utils/pluginSecrets.ts
2497
+ var pluginSecrets_exports = /* @__PURE__ */ __exportAll({
2498
+ FORMAT_KEY: () => FORMAT_KEY,
2499
+ FORMAT_REF: () => "ref",
2500
+ REF_KEY: () => REF_KEY,
2501
+ clear: () => clear,
2502
+ id: () => id,
2503
+ isLocked: () => isLocked,
2504
+ isRef: () => isRef$1,
2505
+ keep: () => keep,
2506
+ label: () => label,
2507
+ set: () => set,
2508
+ state: () => state,
2509
+ usesReferences: () => usesReferences
2510
+ });
2511
+ /**
2512
+ * Stable references for plugin secret settings.
2513
+ *
2514
+ * A settings response never carries a secret's value. Every secret leaf is a
2515
+ * marker instead:
2516
+ *
2517
+ * - `{ "$secret": "sec_…", "set": true }` — a stored secret, referenced by a
2518
+ * stable opaque id. Send the marker back unchanged to keep the stored value.
2519
+ * - `null` — nothing stored at that position.
2520
+ * - `{ "$secret": null, "locked": true }` — the effective value comes from the
2521
+ * environment and is never written back.
2522
+ *
2523
+ * On save each secret leaf accepts the reference, a plain string (a new value),
2524
+ * or `null` (clear). Payloads carry `secret_format: "ref"` so a `null` reads as
2525
+ * a deliberate clear rather than the deprecated "unchanged" placeholder.
2526
+ */
2527
+ /** Reserved marker key that references a stored secret. */
2528
+ var REF_KEY = "$secret";
2529
+ /** Reserved payload key declaring which secret wire format a client speaks. */
2530
+ var FORMAT_KEY = "secret_format";
2531
+ var MARKER_KEYS = /* @__PURE__ */ new Set([
2532
+ REF_KEY,
2533
+ "set",
2534
+ "locked"
2535
+ ]);
2536
+ /** Return whether one settings value is a `$secret` reference marker. */
2537
+ function isRef$1(value) {
2538
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
2539
+ const record = value;
2540
+ if (!("$secret" in record)) return false;
2541
+ return Object.keys(record).every((key) => MARKER_KEYS.has(key));
2542
+ }
2543
+ /** Return the stored secret id behind a marker, or `null` when nothing is stored. */
2544
+ function id(value) {
2545
+ if (!isRef$1(value)) return null;
2546
+ return typeof value.$secret === "string" ? value.$secret : null;
2547
+ }
2548
+ /** Classify one secret field for display: stored, unset, or environment-provided. */
2549
+ function state(value) {
2550
+ if (isRef$1(value)) {
2551
+ if (value.locked) return "environment";
2552
+ return typeof value.$secret === "string" ? "set" : "unset";
2553
+ }
2554
+ return typeof value === "string" && value.length > 0 ? "set" : "unset";
2555
+ }
2556
+ /** Human label for one secret field's state. */
2557
+ function label(value) {
2558
+ const current = state(value);
2559
+ if (current === "environment") return "Provided by environment";
2560
+ return current === "set" ? "Set" : "Not set";
2561
+ }
2562
+ /** Whether a secret field is read-only because the environment supplies it. */
2563
+ function isLocked(value) {
2564
+ return isRef$1(value) && value.locked === true;
2565
+ }
2566
+ /**
2567
+ * Value to submit for an untouched secret field: the reference, unchanged.
2568
+ *
2569
+ * A locked marker round-trips too, which is how the platform keeps a stored
2570
+ * value that an environment variable currently hides.
2571
+ */
2572
+ function keep(current) {
2573
+ if (isRef$1(current)) return { ...current };
2574
+ return null;
2575
+ }
2576
+ /** Value to submit when the user typed a new secret. */
2577
+ function set(value) {
2578
+ return value;
2579
+ }
2580
+ /** Value to submit when the user cleared a secret. */
2581
+ function clear() {
2582
+ return null;
2583
+ }
2584
+ /** Whether a settings response declares the `$secret` reference wire format. */
2585
+ function usesReferences(response) {
2586
+ if (!response || typeof response !== "object") return false;
2587
+ return response[FORMAT_KEY] === "ref";
2588
+ }
2589
+ //#endregion
2590
+ //#region src/components/SecretInput.vue?vue&type=script&setup=true&lang.ts
2591
+ var _hoisted_1$2 = { class: "mint-secret-input__status" };
2592
+ var _hoisted_2$2 = {
2593
+ key: 0,
2594
+ class: "mint-secret-input__hint"
2595
+ };
2596
+ var _hoisted_3$2 = { class: "mint-secret-input__actions" };
2597
+ //#endregion
2598
+ //#region src/components/SecretInput.vue
2599
+ var SecretInput_default = /* @__PURE__ */ defineComponent({
2600
+ __name: "SecretInput",
2601
+ props: {
2602
+ modelValue: { default: null },
2603
+ placeholder: { default: "Enter a new value" },
2604
+ disabled: {
2605
+ type: Boolean,
2606
+ default: false
2607
+ },
2608
+ invalid: {
2609
+ type: Boolean,
2610
+ default: false
2611
+ },
2612
+ size: { default: "md" },
2613
+ changeLabel: { default: "Change" },
2614
+ clearLabel: { default: "Clear" }
2615
+ },
2616
+ emits: ["update:modelValue"],
2617
+ setup(__props, { emit: __emit }) {
2618
+ /** Edits one plugin secret setting: shows set / not set / provided by environment, and submits a `$secret` reference, a new value, or `null`. */
2619
+ const props = __props;
2620
+ const emit = __emit;
2621
+ /** The reference this field started from, so an abandoned edit can restore it. */
2622
+ const storedReference = ref(keep(props.modelValue));
2623
+ const isEditing = ref(typeof props.modelValue === "string");
2624
+ watch(() => props.modelValue, (value) => {
2625
+ if (isRef$1(value)) {
2626
+ storedReference.value = keep(value);
2627
+ isEditing.value = false;
2628
+ }
2629
+ });
2630
+ const state$1 = computed(() => state(props.modelValue));
2631
+ const locked = computed(() => isLocked(props.modelValue) || isLocked(storedReference.value));
2632
+ const statusLabel = computed(() => isEditing.value ? "New value" : label(props.modelValue));
2633
+ const typedValue = computed(() => typeof props.modelValue === "string" ? props.modelValue : "");
2634
+ const canClear = computed(() => !locked.value && (state$1.value === "set" || isEditing.value));
2635
+ function startEditing() {
2636
+ if (props.disabled || locked.value) return;
2637
+ isEditing.value = true;
2638
+ emit("update:modelValue", set(""));
2639
+ }
2640
+ function updateTyped(value) {
2641
+ emit("update:modelValue", set(value == null ? "" : String(value)));
2642
+ }
2643
+ function cancelEditing() {
2644
+ isEditing.value = false;
2645
+ emit("update:modelValue", storedReference.value ? { ...storedReference.value } : null);
2646
+ }
2647
+ function clear$1() {
2648
+ if (props.disabled || locked.value) return;
2649
+ isEditing.value = false;
2650
+ storedReference.value = null;
2651
+ emit("update:modelValue", clear());
2652
+ }
2653
+ return (_ctx, _cache) => {
2654
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["mint-secret-input", { "mint-secret-input--error": __props.invalid }]) }, [
2655
+ createElementVNode("div", _hoisted_1$2, [createElementVNode("span", { class: normalizeClass(["mint-secret-input__badge", `mint-secret-input__badge--${isEditing.value ? "pending" : state$1.value}`]) }, [_cache[0] || (_cache[0] = createElementVNode("span", {
2656
+ class: "mint-secret-input__dot",
2657
+ "aria-hidden": "true"
2658
+ }, null, -1)), createTextVNode(toDisplayString(statusLabel.value), 1)], 2), locked.value ? (openBlock(), createElementBlock("span", _hoisted_2$2, " This value comes from the environment and cannot be edited here. ")) : createCommentVNode("", true)]),
2659
+ isEditing.value ? (openBlock(), createBlock(BaseInput_default, {
2660
+ key: 0,
2661
+ type: "password",
2662
+ autocomplete: "new-password",
2663
+ "model-value": typedValue.value,
2664
+ placeholder: __props.placeholder,
2665
+ disabled: __props.disabled,
2666
+ invalid: __props.invalid,
2667
+ size: __props.size,
2668
+ "onUpdate:modelValue": updateTyped
2669
+ }, null, 8, [
2670
+ "model-value",
2671
+ "placeholder",
2672
+ "disabled",
2673
+ "invalid",
2674
+ "size"
2675
+ ])) : createCommentVNode("", true),
2676
+ createElementVNode("div", _hoisted_3$2, [!isEditing.value ? (openBlock(), createBlock(BaseButton_default, {
2677
+ key: 0,
2678
+ type: "button",
2679
+ variant: "secondary",
2680
+ size: __props.size === "lg" ? "md" : "sm",
2681
+ disabled: __props.disabled || locked.value,
2682
+ onClick: startEditing
2683
+ }, {
2684
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.changeLabel), 1)]),
2685
+ _: 1
2686
+ }, 8, ["size", "disabled"])) : (openBlock(), createBlock(BaseButton_default, {
2687
+ key: 1,
2688
+ type: "button",
2689
+ variant: "ghost",
2690
+ size: __props.size === "lg" ? "md" : "sm",
2691
+ disabled: __props.disabled,
2692
+ onClick: cancelEditing
2693
+ }, {
2694
+ default: withCtx(() => [..._cache[1] || (_cache[1] = [createTextVNode(" Cancel ", -1)])]),
2695
+ _: 1
2696
+ }, 8, ["size", "disabled"])), canClear.value ? (openBlock(), createBlock(BaseButton_default, {
2697
+ key: 2,
2698
+ type: "button",
2699
+ variant: "ghost",
2700
+ size: __props.size === "lg" ? "md" : "sm",
2701
+ disabled: __props.disabled,
2702
+ onClick: clear$1
2703
+ }, {
2704
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.clearLabel), 1)]),
2705
+ _: 1
2706
+ }, 8, ["size", "disabled"])) : createCommentVNode("", true)])
2707
+ ], 2);
2708
+ };
2709
+ }
2710
+ });
2711
+ //#endregion
2712
+ //#region src/components/TagsInput.vue?vue&type=script&setup=true&lang.ts
2713
+ var _hoisted_1$1 = {
2714
+ key: 0,
2715
+ class: "mint-tags-input__categories"
2716
+ };
2717
+ var _hoisted_2$1 = ["disabled", "onClick"];
2718
+ var _hoisted_3$1 = ["aria-label", "onClick"];
2719
+ var _hoisted_4$1 = ["placeholder", "disabled"];
2720
+ var _hoisted_5$1 = {
2721
+ key: 0,
2722
+ class: "mint-tags-input__dropdown"
2723
+ };
2724
+ var _hoisted_6$1 = ["onMousedown"];
2725
+ var _hoisted_7$1 = {
2726
+ key: 0,
2727
+ class: "mint-tags-input__dropdown-count"
2728
+ };
2729
+ //#endregion
2730
+ //#region src/components/TagsInput.vue
2731
+ var TagsInput_default = /* @__PURE__ */ defineComponent({
2732
+ __name: "TagsInput",
2733
+ props: {
2734
+ modelValue: { default: () => [] },
2735
+ placeholder: {},
2736
+ disabled: {
2737
+ type: Boolean,
2738
+ default: false
2739
+ },
2740
+ invalid: {
2741
+ type: Boolean,
2742
+ default: false
2743
+ },
2744
+ size: { default: "md" },
2745
+ maxTags: {},
2746
+ allowDuplicates: {
2747
+ type: Boolean,
2748
+ default: false
2749
+ },
2750
+ suggestions: { default: () => [] },
2751
+ categories: { default: () => [] },
2752
+ activeCategory: {}
2753
+ },
2754
+ emits: ["update:modelValue", "update:activeCategory"],
2755
+ setup(__props, { emit: __emit }) {
2756
+ /** Lets users type and add tags with autocomplete suggestions, categories, and a max-tag cap. */
2757
+ const props = __props;
2758
+ const emit = __emit;
2759
+ const inputValue = ref("");
2760
+ const highlightedIndex = ref(-1);
2761
+ const { isOpen: dropdownOpen, triggerRef: inputRef, open: openDropdown, close: closeDropdown } = useDropdownState({
2762
+ rootRef: useTemplateRef("root"),
2763
+ onClose: () => {
2764
+ highlightedIndex.value = -1;
2765
+ }
2766
+ });
2767
+ const selectionLimit = useSelectionLimit({
2768
+ count: () => props.modelValue.length,
2769
+ max: () => props.maxTags
2770
+ });
2771
+ const canAddMore = selectionLimit.canAddMore;
2772
+ const normalizedSuggestions = computed(() => {
2773
+ return props.suggestions.map((s) => typeof s === "string" ? { value: s } : s);
2774
+ });
2775
+ const filteredSuggestions = computed(() => {
2776
+ const q = inputValue.value.trim().toLowerCase();
2777
+ if (!q) return [];
2778
+ return normalizedSuggestions.value.filter((s) => s.value.toLowerCase().startsWith(q) && !props.modelValue.includes(s.value)).slice(0, 8);
2779
+ });
2780
+ function categoryFor(tag) {
2781
+ const colonIdx = tag.indexOf(":");
2782
+ if (colonIdx === -1) return void 0;
2783
+ const prefix = tag.slice(0, colonIdx);
2784
+ return props.categories.find((c) => c.prefix === prefix);
2785
+ }
2786
+ const GROUP_COLORS = [
2787
+ "var(--mint-sample-1)",
2788
+ "var(--mint-sample-2)",
2789
+ "var(--mint-sample-3)",
2790
+ "var(--mint-sample-4)",
2791
+ "var(--mint-sample-5)",
2792
+ "var(--mint-sample-6)",
2793
+ "var(--mint-sample-7)",
2794
+ "var(--mint-sample-8)"
2795
+ ];
2796
+ function groupColor(category) {
2797
+ return GROUP_COLORS[props.categories.indexOf(category) % GROUP_COLORS.length];
2798
+ }
2799
+ function addTag(value) {
2800
+ const trimmed = value.trim();
2801
+ if (!trimmed) return;
2802
+ if (!selectionLimit.canAdd()) return;
2803
+ let final = trimmed;
2804
+ if (props.activeCategory && !trimmed.includes(":")) final = `${props.activeCategory}:${trimmed}`;
2805
+ if (!props.allowDuplicates && props.modelValue.includes(final)) return;
2806
+ emit("update:modelValue", [...props.modelValue, final]);
2807
+ inputValue.value = "";
2808
+ closeDropdown();
2809
+ }
2810
+ function removeTag(index) {
2811
+ if (props.disabled) return;
2812
+ const newTags = [...props.modelValue];
2813
+ newTags.splice(index, 1);
2814
+ emit("update:modelValue", newTags);
2815
+ }
2816
+ function handleKeydown(event) {
2817
+ if (event.key === "ArrowDown" && filteredSuggestions.value.length) {
2818
+ event.preventDefault();
2819
+ highlightedIndex.value = Math.min(highlightedIndex.value + 1, filteredSuggestions.value.length - 1);
2820
+ openDropdown();
2821
+ return;
2822
+ }
2823
+ if (event.key === "ArrowUp" && filteredSuggestions.value.length) {
2824
+ event.preventDefault();
2825
+ highlightedIndex.value = Math.max(highlightedIndex.value - 1, 0);
2826
+ return;
2827
+ }
2828
+ if (event.key === "Enter" || event.key === ",") {
2829
+ event.preventDefault();
2830
+ if (highlightedIndex.value >= 0 && filteredSuggestions.value[highlightedIndex.value]) addTag(filteredSuggestions.value[highlightedIndex.value].value);
2831
+ else addTag(inputValue.value);
2832
+ return;
2833
+ }
2834
+ if (event.key === "Escape") {
2835
+ closeDropdown(true);
2836
+ return;
2837
+ }
2838
+ if (event.key === "Backspace" && !inputValue.value && props.modelValue.length > 0) removeTag(props.modelValue.length - 1);
2839
+ }
2840
+ function handleFocus() {
2841
+ if (filteredSuggestions.value.length) openDropdown();
2842
+ }
2843
+ function handleBlur() {
2844
+ setTimeout(() => {
2845
+ closeDropdown();
2846
+ }, 120);
2847
+ }
2848
+ function handlePaste(event) {
2849
+ event.preventDefault();
2850
+ const text = event.clipboardData?.getData("text");
2851
+ if (!text) return;
2852
+ const tags = text.split(/[,\n]/).map((t) => t.trim()).filter(Boolean);
2853
+ const newTags = [...props.modelValue];
2854
+ for (const tag of tags) {
2855
+ if (!selectionLimit.canAdd(1, newTags.length)) break;
2856
+ if (!props.allowDuplicates && newTags.includes(tag)) continue;
2857
+ newTags.push(tag);
2858
+ }
2859
+ emit("update:modelValue", newTags);
2860
+ }
2861
+ function focusInput() {
2862
+ inputRef.value?.focus();
2863
+ }
2864
+ function setCategory(prefix) {
2865
+ emit("update:activeCategory", prefix === props.activeCategory ? "" : prefix);
2866
+ }
2867
+ function onInputEvent() {
2868
+ if (filteredSuggestions.value.length > 0) openDropdown();
2869
+ else closeDropdown();
2870
+ highlightedIndex.value = -1;
2871
+ }
2872
+ return (_ctx, _cache) => {
2873
+ return openBlock(), createElementBlock("div", {
2874
+ ref: "root",
2875
+ class: normalizeClass([
2876
+ "mint-tags-input",
2877
+ `mint-tags-input--${__props.size}`,
2878
+ __props.invalid ? "mint-tags-input--error" : "",
2879
+ __props.disabled ? "mint-tags-input--disabled" : "",
2880
+ __props.categories.length ? "mint-tags-input--categorized" : ""
2881
+ ])
2882
+ }, [__props.categories.length ? (openBlock(), createElementBlock("div", _hoisted_1$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.categories, (cat) => {
2883
+ return openBlock(), createElementBlock("button", {
2884
+ key: cat.prefix,
2885
+ type: "button",
2886
+ class: normalizeClass([
2887
+ "mint-tags-input__category",
2888
+ `mint-tags-input__category--${cat.tone ?? "neutral"}`,
2889
+ __props.activeCategory === cat.prefix ? "mint-tags-input__category--active" : ""
2890
+ ]),
2891
+ disabled: __props.disabled,
2892
+ onClick: ($event) => setCategory(cat.prefix)
2893
+ }, [createElementVNode("span", {
2894
+ class: "mint-tags-input__tag-dot",
2895
+ style: normalizeStyle({ background: groupColor(cat) }),
2896
+ "aria-hidden": "true"
2897
+ }, null, 4), createTextVNode(" " + toDisplayString(cat.name), 1)], 10, _hoisted_2$1);
2898
+ }), 128))])) : createCommentVNode("", true), createElementVNode("div", {
2899
+ class: "mint-tags-input__field",
2900
+ onClick: focusInput
2901
+ }, [
2902
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.modelValue, (tag, index) => {
2903
+ return openBlock(), createElementBlock("span", {
2904
+ key: `${tag}-${index}`,
2905
+ class: normalizeClass([
2906
+ "mint-tags-input__tag",
2907
+ `mint-tags-input__tag--${__props.size}`,
2908
+ categoryFor(tag) ? `mint-tags-input__tag--${categoryFor(tag)?.tone ?? "neutral"}` : ""
2909
+ ])
2910
+ }, [
2911
+ categoryFor(tag) ? (openBlock(), createElementBlock("span", {
2912
+ key: 0,
2913
+ class: "mint-tags-input__tag-dot",
2914
+ style: normalizeStyle({ background: groupColor(categoryFor(tag)) }),
2915
+ "aria-hidden": "true"
2916
+ }, null, 4)) : createCommentVNode("", true),
2917
+ createTextVNode(" " + toDisplayString(tag) + " ", 1),
2918
+ !__props.disabled ? (openBlock(), createElementBlock("button", {
2919
+ key: 1,
2920
+ type: "button",
2921
+ "aria-label": `Remove ${tag}`,
2922
+ class: "mint-tags-input__tag-remove",
2923
+ onClick: withModifiers(($event) => removeTag(index), ["stop"])
2924
+ }, [..._cache[1] || (_cache[1] = [createElementVNode("svg", {
2925
+ class: "mint-tags-input__tag-remove-icon",
2926
+ fill: "none",
2927
+ stroke: "currentColor",
2928
+ "stroke-width": "2",
2929
+ "stroke-linecap": "round",
2930
+ "stroke-linejoin": "round",
2931
+ viewBox: "0 0 24 24"
2932
+ }, [createElementVNode("path", { d: "M18 6 6 18" }), createElementVNode("path", { d: "m6 6 12 12" })], -1)])], 8, _hoisted_3$1)) : createCommentVNode("", true)
2933
+ ], 2);
2934
+ }), 128)),
2935
+ withDirectives(createElementVNode("input", {
2936
+ ref_key: "inputRef",
2937
+ ref: inputRef,
2938
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => inputValue.value = $event),
2939
+ type: "text",
2940
+ placeholder: __props.modelValue.length === 0 ? __props.placeholder : "",
2941
+ disabled: __props.disabled || !unref(canAddMore),
2942
+ class: normalizeClass(["mint-tags-input__input", `mint-tags-input__input--${__props.size}`]),
2943
+ onKeydown: handleKeydown,
2944
+ onPaste: handlePaste,
2945
+ onFocus: handleFocus,
2946
+ onBlur: handleBlur,
2947
+ onInput: onInputEvent
2948
+ }, null, 42, _hoisted_4$1), [[vModelText, inputValue.value]]),
2949
+ unref(dropdownOpen) && filteredSuggestions.value.length ? (openBlock(), createElementBlock("div", _hoisted_5$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(filteredSuggestions.value, (sug, i) => {
2950
+ return openBlock(), createElementBlock("button", {
2951
+ key: sug.value,
2952
+ type: "button",
2953
+ class: normalizeClass(["mint-tags-input__dropdown-item", i === highlightedIndex.value ? "mint-tags-input__dropdown-item--highlighted" : ""]),
2954
+ onMousedown: withModifiers(($event) => addTag(sug.value), ["prevent"])
2955
+ }, [createElementVNode("span", null, toDisplayString(sug.value), 1), sug.count !== void 0 ? (openBlock(), createElementBlock("span", _hoisted_7$1, toDisplayString(sug.count), 1)) : createCommentVNode("", true)], 42, _hoisted_6$1);
2956
+ }), 128))])) : createCommentVNode("", true)
2957
+ ])], 2);
2958
+ };
2959
+ }
2960
+ });
2961
+ //#endregion
2962
+ //#region src/jobs.ts
2963
+ var ACTIVE_JOB_STATUSES = /* @__PURE__ */ new Set([
2964
+ "awaiting_input",
2965
+ "queued",
2966
+ "running"
2967
+ ]);
2968
+ var TERMINAL_JOB_STATUSES = /* @__PURE__ */ new Set([
2969
+ "completed",
2970
+ "failed",
2971
+ "cancelled"
2972
+ ]);
2973
+ /** Resolve action support while retaining one-cycle legacy status inference. */
2974
+ function resolveJobCapabilities(job) {
2975
+ const legacyCanCancel = job.status === "queued" || job.status === "running";
2976
+ const legacyCanDelete = TERMINAL_JOB_STATUSES.has(job.status);
2977
+ return {
2978
+ can_cancel: typeof job.can_cancel === "boolean" ? job.can_cancel : legacyCanCancel,
2979
+ can_delete: typeof job.can_delete === "boolean" ? job.can_delete : legacyCanDelete
2980
+ };
2981
+ }
2982
+ /** Clamp invalid or out-of-range progress values for safe display. */
2983
+ function normalizeJobPercent(value) {
2984
+ if (!Number.isFinite(value)) return 0;
2985
+ return Math.min(100, Math.max(0, value));
2986
+ }
2987
+ /** Create a detached canonical state without changing the transport input. */
2988
+ function normalizeJobState(job) {
2989
+ const capabilities = resolveJobCapabilities(job);
2990
+ return {
2991
+ ...job,
2992
+ definition_id: job.definition_id ?? (typeof job.metadata.definition_id === "string" ? job.metadata.definition_id : null),
2993
+ result_status: job.result_status ?? (job.status === "completed" && job.metadata.has_result === true ? "available" : "none"),
2994
+ result_expires_at: job.result_expires_at ?? null,
2995
+ progress: {
2996
+ ...job.progress,
2997
+ percent: normalizeJobPercent(job.progress.percent)
2998
+ },
2999
+ warnings: [...job.warnings],
3000
+ folders: [...job.folders],
3001
+ metadata: { ...job.metadata },
3002
+ ...capabilities
3003
+ };
3004
+ }
3005
+ function isActiveJobStatus(status) {
3006
+ return ACTIVE_JOB_STATUSES.has(status);
3007
+ }
3008
+ function isTerminalJobStatus(status) {
3009
+ return TERMINAL_JOB_STATUSES.has(status);
3010
+ }
3011
+ function jobStatusLabel(status) {
3012
+ return {
3013
+ awaiting_input: "Waiting for input",
3014
+ queued: "Queued",
3015
+ running: "Running",
3016
+ completed: "Completed",
3017
+ failed: "Failed",
3018
+ cancelled: "Cancelled"
3019
+ }[status];
3020
+ }
3021
+ //#endregion
3022
+ //#region src/composables/platformContextHelpers.ts
3023
+ function getInjectedPlatformContext() {
3024
+ if (typeof window === "undefined") return void 0;
3025
+ return window.__MINT_PLATFORM__;
3026
+ }
3027
+ /** Return the platform's canonical plugin identity for the mounted frontend. */
3028
+ function resolveCurrentPluginId() {
3029
+ const pluginId = getInjectedPlatformContext()?.plugin?.id;
3030
+ return typeof pluginId === "string" && pluginId ? pluginId : void 0;
3031
+ }
3032
+ function parseExperimentId(value) {
3033
+ if (typeof value === "number" && Number.isFinite(value)) return value;
3034
+ if (typeof value === "string" && value.trim()) {
3035
+ const parsed = Number(value);
3036
+ return Number.isFinite(parsed) ? parsed : void 0;
3037
+ }
3038
+ if (value && typeof value === "object" && "id" in value) return parseExperimentId(value.id);
3039
+ }
3040
+ //#endregion
3041
+ //#region src/components/Skeleton.vue
3042
+ var Skeleton_default = /* @__PURE__ */ defineComponent({
3043
+ __name: "Skeleton",
3044
+ props: {
3045
+ variant: { default: "text" },
3046
+ width: {},
3047
+ height: {},
3048
+ animation: { default: "wave" }
3049
+ },
3050
+ setup(__props) {
3051
+ /** Animated loading placeholder in text, circular, rectangular, or rounded variants with pulse or wave animation. */
3052
+ const props = __props;
3053
+ const style = computed(() => {
3054
+ const s = {};
3055
+ if (props.width) s.width = typeof props.width === "number" ? `${props.width}px` : props.width;
3056
+ if (props.height) s.height = typeof props.height === "number" ? `${props.height}px` : props.height;
3057
+ return s;
3058
+ });
3059
+ const classes = computed(() => [
3060
+ "mint-skeleton",
3061
+ `mint-skeleton--${props.variant}`,
3062
+ props.animation === "none" ? "" : "skeleton-wave"
3063
+ ]);
3064
+ return (_ctx, _cache) => {
3065
+ return openBlock(), createElementBlock("div", {
3066
+ class: normalizeClass(classes.value),
3067
+ style: normalizeStyle(style.value)
3068
+ }, null, 6);
3069
+ };
3070
+ }
3071
+ });
3072
+ //#endregion
3073
+ //#region src/components/internal/ResourcePickerListInternal.vue?vue&type=script&setup=true&lang.ts
3074
+ var _hoisted_1 = { class: "mint-resource-picker__toolbar" };
3075
+ var _hoisted_2 = {
3076
+ key: 0,
3077
+ class: "mint-resource-picker__frame",
3078
+ "aria-busy": "true"
3079
+ };
3080
+ var _hoisted_3 = {
3081
+ key: 1,
3082
+ class: "mint-resource-picker__error",
3083
+ role: "alert"
3084
+ };
3085
+ var _hoisted_4 = ["aria-label"];
3086
+ var _hoisted_5 = [
3087
+ "id",
3088
+ "aria-selected",
3089
+ "onClick",
3090
+ "onMouseenter"
3091
+ ];
3092
+ var _hoisted_6 = { class: "mint-resource-picker__text" };
3093
+ var _hoisted_7 = { class: "mint-resource-picker__title" };
3094
+ var _hoisted_8 = {
3095
+ key: 0,
3096
+ class: "mint-resource-picker__meta"
3097
+ };
3098
+ var _hoisted_9 = {
3099
+ key: 0,
3100
+ class: "mint-resource-picker__code mint-exp-code mint-exp-code--sm"
3101
+ };
3102
+ var _hoisted_10 = { key: 1 };
3103
+ var _hoisted_11 = {
3104
+ key: 0,
3105
+ class: "mint-resource-picker__aside"
3106
+ };
3107
+ var _hoisted_12 = {
3108
+ key: 1,
3109
+ class: "mint-resource-picker__date"
3110
+ };
3111
+ //#endregion
3112
+ //#region src/components/internal/ResourcePickerListInternal.vue
3113
+ var ResourcePickerListInternal_default = /* @__PURE__ */ defineComponent({
3114
+ __name: "ResourcePickerListInternal",
3115
+ props: {
3116
+ items: {},
3117
+ itemKey: {},
3118
+ describe: {},
3119
+ selectedKey: { default: null },
3120
+ search: {},
3121
+ label: {},
3122
+ placeholder: { default: "Search…" },
3123
+ loading: {
3124
+ type: Boolean,
3125
+ default: false
3126
+ },
3127
+ error: { default: null },
3128
+ emptyTitle: { default: "Nothing found" },
3129
+ emptyDescription: { default: "Try adjusting your search or filters." },
3130
+ autofocusSearch: { type: Boolean }
3131
+ },
3132
+ emits: ["select", "update:search"],
3133
+ setup(__props, { emit: __emit }) {
3134
+ /**
3135
+ * Searchable single-select list shared by the experiment and
3136
+ * artifact selector modals: two-line rows (title, then code + meta) with status and date
3137
+ * in a right-hand column, a filled selected row, skeleton,
3138
+ * error and empty states, and the combobox keyboard model (↑ ↓ Enter).
3139
+ */
3140
+ const props = __props;
3141
+ const emit = __emit;
3142
+ const listId = `mint-resource-picker-${useId().replace(/:/g, "")}`;
3143
+ const activeIndex = ref(-1);
3144
+ const listRef = ref(null);
3145
+ const indexByKey = computed(() => new Map(props.items.map((item, i) => [props.itemKey(item), i])));
3146
+ const showList = computed(() => !props.loading && !props.error && props.items.length > 0);
3147
+ function optionId(item) {
3148
+ return `${listId}-${props.itemKey(item)}`;
3149
+ }
3150
+ const activeDescendant = computed(() => {
3151
+ const item = props.items[activeIndex.value];
3152
+ return item === void 0 ? void 0 : optionId(item);
3153
+ });
3154
+ function indexOf(item) {
3155
+ return indexByKey.value.get(props.itemKey(item)) ?? -1;
3156
+ }
3157
+ function keydown(event) {
3158
+ const target = event.target;
3159
+ if (target !== event.currentTarget && !target?.closest(".mint-resource-picker__search")) return;
3160
+ const rows = props.items;
3161
+ if (!rows.length) return;
3162
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
3163
+ event.preventDefault();
3164
+ activeIndex.value = event.key === "ArrowDown" ? Math.min(activeIndex.value + 1, rows.length - 1) : Math.max(activeIndex.value - 1, 0);
3165
+ nextTick(() => listRef.value?.querySelector(".mint-resource-picker__row--active")?.scrollIntoView({ block: "nearest" }));
3166
+ } else if (event.key === "Enter" && rows[activeIndex.value] !== void 0) {
3167
+ event.preventDefault();
3168
+ emit("select", rows[activeIndex.value]);
3169
+ }
3170
+ }
3171
+ watch(() => props.items, () => {
3172
+ activeIndex.value = -1;
3173
+ });
3174
+ return (_ctx, _cache) => {
3175
+ return openBlock(), createElementBlock("div", {
3176
+ class: "mint-resource-picker",
3177
+ onKeydown: keydown
3178
+ }, [createElementVNode("div", _hoisted_1, [createVNode(BaseInput_default, {
3179
+ class: "mint-resource-picker__search",
3180
+ "model-value": __props.search,
3181
+ placeholder: __props.placeholder,
3182
+ size: "sm",
3183
+ type: "search",
3184
+ autofocus: __props.autofocusSearch,
3185
+ role: "combobox",
3186
+ "aria-label": `Search ${__props.label.toLowerCase()}`,
3187
+ "aria-expanded": showList.value,
3188
+ "aria-controls": listId,
3189
+ "aria-activedescendant": activeDescendant.value,
3190
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("update:search", String($event ?? "")))
3191
+ }, {
3192
+ prefix: withCtx(() => [..._cache[2] || (_cache[2] = [createElementVNode("svg", {
3193
+ viewBox: "0 0 16 16",
3194
+ fill: "none",
3195
+ stroke: "currentColor",
3196
+ "stroke-width": "1.5",
3197
+ "aria-hidden": "true"
3198
+ }, [createElementVNode("path", { d: "M7 11.5a4.5 4.5 0 1 1 0-9 4.5 4.5 0 0 1 0 9zM10.5 10.5L14 14" })], -1)])]),
3199
+ _: 1
3200
+ }, 8, [
3201
+ "model-value",
3202
+ "placeholder",
3203
+ "autofocus",
3204
+ "aria-label",
3205
+ "aria-expanded",
3206
+ "aria-activedescendant"
3207
+ ]), renderSlot(_ctx.$slots, "filters")]), __props.loading ? (openBlock(), createElementBlock("div", _hoisted_2, [(openBlock(), createElementBlock(Fragment, null, renderList(4, (n) => {
3208
+ return createElementVNode("div", {
3209
+ key: n,
3210
+ class: "mint-resource-picker__skeleton-row"
3211
+ }, [createVNode(Skeleton_default, {
3212
+ width: `${40 + n * 10}%`,
3213
+ height: "0.75rem"
3214
+ }, null, 8, ["width"]), createVNode(Skeleton_default, {
3215
+ width: "30%",
3216
+ height: "0.625rem"
3217
+ })]);
3218
+ }), 64))])) : __props.error ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(__props.error), 1)) : !__props.items.length ? (openBlock(), createBlock(EmptyState_default, {
3219
+ key: 2,
3220
+ title: __props.emptyTitle,
3221
+ description: __props.emptyDescription,
3222
+ size: "sm"
3223
+ }, null, 8, ["title", "description"])) : (openBlock(), createElementBlock("div", {
3224
+ key: 3,
3225
+ id: listId,
3226
+ ref_key: "listRef",
3227
+ ref: listRef,
3228
+ class: "mint-resource-picker__frame mint-resource-picker__list",
3229
+ role: "listbox",
3230
+ "aria-label": __props.label
3231
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
3232
+ return openBlock(), createElementBlock("div", {
3233
+ id: optionId(item),
3234
+ key: __props.itemKey(item),
3235
+ role: "option",
3236
+ "aria-selected": __props.itemKey(item) === __props.selectedKey,
3237
+ class: normalizeClass(["mint-resource-picker__row", {
3238
+ "mint-resource-picker__row--selected": __props.itemKey(item) === __props.selectedKey,
3239
+ "mint-resource-picker__row--active": indexOf(item) === activeIndex.value
3240
+ }]),
3241
+ onClick: ($event) => emit("select", item),
3242
+ onMouseenter: ($event) => activeIndex.value = indexOf(item)
3243
+ }, [
3244
+ createElementVNode("span", _hoisted_6, [createElementVNode("span", _hoisted_7, toDisplayString(__props.describe(item).title), 1), __props.describe(item).code || __props.describe(item).meta?.length ? (openBlock(), createElementBlock("span", _hoisted_8, [__props.describe(item).code ? (openBlock(), createElementBlock("span", _hoisted_9, toDisplayString(__props.describe(item).code), 1)) : createCommentVNode("", true), __props.describe(item).meta?.length ? (openBlock(), createElementBlock("span", _hoisted_10, toDisplayString(__props.describe(item).meta.join(" · ")), 1)) : createCommentVNode("", true)])) : createCommentVNode("", true)]),
3245
+ __props.describe(item).status || __props.describe(item).date ? (openBlock(), createElementBlock("span", _hoisted_11, [__props.describe(item).status ? (openBlock(), createElementBlock("span", {
3246
+ key: 0,
3247
+ class: normalizeClass(["mint-resource-picker__status", `mint-resource-picker__status--${__props.describe(item).status.tone}`])
3248
+ }, toDisplayString(__props.describe(item).status.label), 3)) : createCommentVNode("", true), __props.describe(item).date ? (openBlock(), createElementBlock("span", _hoisted_12, toDisplayString(__props.describe(item).date), 1)) : createCommentVNode("", true)])) : createCommentVNode("", true),
3249
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("span", {
3250
+ key: 1,
3251
+ class: "mint-resource-picker__actions",
3252
+ onClick: _cache[1] || (_cache[1] = withModifiers(() => {}, ["stop"]))
3253
+ }, [renderSlot(_ctx.$slots, "actions", { item })])) : createCommentVNode("", true)
3254
+ ], 42, _hoisted_5);
3255
+ }), 128))], 8, _hoisted_4))], 32);
3256
+ };
3257
+ }
3258
+ });
3259
+ //#endregion
3260
+ //#region src/utils/records.ts
3261
+ /** Narrow an unknown value to a plain object (arrays and null excluded). */
3262
+ function isRecord(value) {
3263
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3264
+ }
3265
+ //#endregion
3266
+ export { formatRelativeTime as A, Tooltip_default as B, formatExperimentDate as C, compareTime as D, useMenuKeyboard as E, toMinutes as F, BaseInput_default as G, useListSelection as H, FormField_default as I, EmptyState_default as L, formatTimeSlot as M, generateTimeSlots as N, durationMinutes as O, time_exports as P, useRovingFocus as R, experimentIdFromRoute as S, FileUploader_default as T, useSelectionLimit as U, BaseSelect_default as V, normalizeOptionInput as W, APP_EXPERIMENT_KEY as _, parseExperimentId as a, SORT_OPTIONS as b, isTerminalJobStatus as c, normalizeJobState as d, resolveJobCapabilities as f, pluginSecrets_exports as g, FORMAT_KEY as h, getInjectedPlatformContext as i, formatTime as j, findNearestTimeSlotIndex as k, jobStatusLabel as l, SecretInput_default as m, ResourcePickerListInternal_default as n, resolveCurrentPluginId as o, TagsInput_default as p, Skeleton_default as r, isActiveJobStatus as s, isRecord as t, normalizeJobPercent as u, useAppExperiment as v, resolveExperimentCode as w, datePresetToISO as x, DATE_PRESET_OPTIONS as y, BaseCheckbox_default as z };
3267
+
3268
+ //# sourceMappingURL=records-B6gpM_3e.js.map