@morscherlab/mint-sdk 1.3.9 → 1.4.0-beta.1

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