@morscherlab/mint-sdk 1.0.63 → 1.1.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/README.md +119 -6
  2. package/dist/EmptyState-DgBRoYAy.js +647 -0
  3. package/dist/EmptyState-DgBRoYAy.js.map +1 -0
  4. package/dist/{ExperimentPopover-BbPkIFsI.js → ExperimentPopover-BFw3QX8L.js} +10 -9
  5. package/dist/{ExperimentPopover-BbPkIFsI.js.map → ExperimentPopover-BFw3QX8L.js.map} +1 -1
  6. package/dist/{ExperimentSelectorModal-DZeSd-yr.js → ExperimentSelectorModal-BBWXC7KW.js} +12 -216
  7. package/dist/ExperimentSelectorModal-BBWXC7KW.js.map +1 -0
  8. package/dist/{SettingsModal-CJgLadsN.js → SettingsModal-Dpg-X1OM.js} +12 -9
  9. package/dist/{SettingsModal-CJgLadsN.js.map → SettingsModal-Dpg-X1OM.js.map} +1 -1
  10. package/dist/__tests__/components/BaseToggle.test.d.ts +1 -0
  11. package/dist/__tests__/components/GeneratedPathInput.test.d.ts +1 -0
  12. package/dist/__tests__/components/GeneratedPlotlyResult.test.d.ts +1 -0
  13. package/dist/__tests__/components/GeneratedPluginView.test.d.ts +1 -0
  14. package/dist/__tests__/components/GeneratedResultRenderer.test.d.ts +1 -0
  15. package/dist/__tests__/components/InstrumentAlertLog.test.d.ts +1 -0
  16. package/dist/__tests__/components/SectionCard.test.d.ts +1 -0
  17. package/dist/__tests__/composables/useGeneratedAnalysis.test.d.ts +1 -0
  18. package/dist/__tests__/generatedUi.test.d.ts +1 -0
  19. package/dist/__tests__/types/GeneratedJsonSchema.test.d.ts +1 -0
  20. package/dist/{analysisArtifactTypes-Cu40dzSG.js → analysisArtifactTypes-ejqR8MX3.js} +1 -1
  21. package/dist/{analysisArtifactTypes-Cu40dzSG.js.map → analysisArtifactTypes-ejqR8MX3.js.map} +1 -1
  22. package/dist/{auth-DZAwEeis.js → auth-B87xM--s.js} +1 -1
  23. package/dist/{auth-DZAwEeis.js.map → auth-B87xM--s.js.map} +1 -1
  24. package/dist/chunk-BoAXSpZd.js +33 -0
  25. package/dist/components/AppSidebar.vue.d.ts +1 -1
  26. package/dist/components/AutoGroupModal.vue.d.ts +2 -2
  27. package/dist/components/BaseSelect.vue.d.ts +1 -1
  28. package/dist/components/BaseToggle.vue.d.ts +2 -0
  29. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +2 -2
  30. package/dist/components/CollapsibleCard.vue.d.ts +1 -1
  31. package/dist/components/ComponentBindingRenderer.vue.d.ts +1 -1
  32. package/dist/components/ConfirmDialog.vue.d.ts +1 -1
  33. package/dist/components/ExperimentDataViewer.vue.d.ts +1 -1
  34. package/dist/components/ExperimentTimeline.vue.d.ts +1 -1
  35. package/dist/components/FileUploader.vue.d.ts +4 -2
  36. package/dist/components/FitPanel.vue.d.ts +2 -2
  37. package/dist/components/FormActions.vue.d.ts +1 -1
  38. package/dist/components/FormBuilder.vue.d.ts +1 -1
  39. package/dist/components/GeneratedPathInput.vue.d.ts +12 -0
  40. package/dist/components/GeneratedPlotlyResult.vue.d.ts +11 -0
  41. package/dist/components/GeneratedPluginView.vue.d.ts +10 -0
  42. package/dist/components/GeneratedResultRenderer.vue.d.ts +6 -0
  43. package/dist/components/JobsStatusTray.vue.d.ts +5 -1
  44. package/dist/components/LcmsSequenceTable.vue.d.ts +1 -1
  45. package/dist/components/PluginWorkspaceView.props.d.ts +1 -1
  46. package/dist/components/SampleLegend.vue.d.ts +1 -1
  47. package/dist/components/SampleSelector.vue.d.ts +2 -2
  48. package/dist/components/SectionCard.vue.d.ts +47 -0
  49. package/dist/components/SettingsModal.vue.d.ts +1 -1
  50. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +2 -2
  51. package/dist/components/index.d.ts +5 -0
  52. package/dist/components/index.js +8 -9
  53. package/dist/components/internal/PlateMapEditorToolbarInternal.vue.d.ts +2 -2
  54. package/dist/{components-DdzHh3a_.js → components-Ci_BTx00.js} +2322 -2292
  55. package/dist/components-Ci_BTx00.js.map +1 -0
  56. package/dist/composables/index.d.ts +3 -2
  57. package/dist/composables/index.js +10 -11
  58. package/dist/composables/useGeneratedAnalysis.d.ts +62 -0
  59. package/dist/composables/useJobsStatusTray.d.ts +48 -4
  60. package/dist/composables/usePlatformContext.d.ts +3 -0
  61. package/dist/composables/usePluginClient.d.ts +17 -8
  62. package/dist/{composables-BUUphBqg.js → composables-C0VEJ73O.js} +154 -38
  63. package/dist/composables-C0VEJ73O.js.map +1 -0
  64. package/dist/experiment-utils-CxkruZ3G.js +392 -0
  65. package/dist/experiment-utils-CxkruZ3G.js.map +1 -0
  66. package/dist/generated/schema.d.ts +7 -0
  67. package/dist/generated-ui/main.d.ts +0 -0
  68. package/dist/index.d.ts +1 -0
  69. package/dist/index.js +15 -18
  70. package/dist/index.js.map +1 -1
  71. package/dist/install.js +7 -8
  72. package/dist/install.js.map +1 -1
  73. package/dist/plotly.min-BR53hja4.js +180634 -0
  74. package/dist/plotly.min-BR53hja4.js.map +1 -0
  75. package/dist/stores/auth.d.ts +2 -2
  76. package/dist/stores/index.js +1 -1
  77. package/dist/styles.css +8657 -8217
  78. package/dist/tailwind.preset.d.ts +5 -0
  79. package/dist/tailwind.preset.js +7 -2
  80. package/dist/tailwind.preset.js.map +1 -1
  81. package/dist/templates/index.js +4 -3
  82. package/dist/templates/packs.d.ts +0 -1
  83. package/dist/{templates-CNbPQNID.js → templates-Cdj93S9C.js} +2 -4
  84. package/dist/templates-Cdj93S9C.js.map +1 -0
  85. package/dist/types/components.d.ts +2 -0
  86. package/dist/types/form-builder.d.ts +1 -1
  87. package/dist/types/generated-ui.d.ts +183 -0
  88. package/dist/types/index.d.ts +2 -1
  89. package/dist/types/index.js +1 -1
  90. package/dist/types/instrument.d.ts +1 -0
  91. package/dist/types/jobs.d.ts +7 -1
  92. package/dist/types/platform.d.ts +2 -0
  93. package/dist/{useControlSchema-BZNdalmL.js → useControlSchema-B_qgU4rW.js} +1882 -172
  94. package/dist/useControlSchema-B_qgU4rW.js.map +1 -0
  95. package/dist/{useDropdownState-Bb-c_PeE.js → useDropdownState-gVaMXtwW.js} +2 -2
  96. package/dist/{useDropdownState-Bb-c_PeE.js.map → useDropdownState-gVaMXtwW.js.map} +1 -1
  97. package/dist/{useExperimentSelector-DRbj6vse.js → useExperimentSelector-BuQZRgMt.js} +4 -255
  98. package/dist/useExperimentSelector-BuQZRgMt.js.map +1 -0
  99. package/dist/{useFormBuilder-DKekvXRs.js → useFormBuilder-D1G5J5Z5.js} +2 -2
  100. package/dist/{useFormBuilder-DKekvXRs.js.map → useFormBuilder-D1G5J5Z5.js.map} +1 -1
  101. package/dist/{useAnalysisArtifacts-C3l0a0vu.js → useProtocolTemplates-DeaOmMaw.js} +307 -475
  102. package/dist/useProtocolTemplates-DeaOmMaw.js.map +1 -0
  103. package/package.json +7 -3
  104. package/src/__tests__/components/BaseSelect.test.ts +52 -0
  105. package/src/__tests__/components/BaseToggle.test.ts +40 -0
  106. package/src/__tests__/components/GeneratedPathInput.test.ts +132 -0
  107. package/src/__tests__/components/GeneratedPlotlyResult.test.ts +117 -0
  108. package/src/__tests__/components/GeneratedPluginView.test.ts +240 -0
  109. package/src/__tests__/components/GeneratedResultRenderer.test.ts +93 -0
  110. package/src/__tests__/components/InstrumentAlertLog.test.ts +59 -0
  111. package/src/__tests__/components/PluginWorkspaceView.test.ts +68 -14
  112. package/src/__tests__/components/SectionCard.test.ts +181 -0
  113. package/src/__tests__/composables/formBuilderRegistry.test.ts +5 -1
  114. package/src/__tests__/composables/useApi.test.ts +8 -0
  115. package/src/__tests__/composables/useGeneratedAnalysis.test.ts +1742 -0
  116. package/src/__tests__/composables/useJobsStatusTray.test.ts +179 -1
  117. package/src/__tests__/composables/usePlatformContext.test.ts +28 -0
  118. package/src/__tests__/composables/usePluginClient.test.ts +402 -21
  119. package/src/__tests__/composables/usePluginConfig.test.ts +323 -7
  120. package/src/__tests__/docs/extractDocsTemplates.test.ts +0 -1
  121. package/src/__tests__/generatedUi.test.ts +119 -0
  122. package/src/__tests__/templates/templates.test.ts +1 -1
  123. package/src/__tests__/types/GeneratedJsonSchema.test.ts +62 -0
  124. package/src/components/BaseSelect.vue +16 -2
  125. package/src/components/BaseToggle.vue +3 -1
  126. package/src/components/FileUploader.vue +49 -11
  127. package/src/components/GeneratedPathInput.vue +218 -0
  128. package/src/components/GeneratedPlotlyResult.vue +87 -0
  129. package/src/components/GeneratedPluginView.vue +279 -0
  130. package/src/components/GeneratedResultRenderer.vue +137 -0
  131. package/src/components/InstrumentAlertLog.vue +2 -2
  132. package/src/components/JobsStatusTray.vue +14 -8
  133. package/src/components/PluginWorkspaceView.props.ts +1 -1
  134. package/src/components/PluginWorkspaceView.vue +1 -5
  135. package/src/components/SectionCard.story.vue +163 -0
  136. package/src/components/SectionCard.vue +98 -0
  137. package/src/components/index.ts +5 -0
  138. package/src/composables/formBuilderRegistry.ts +2 -0
  139. package/src/composables/index.ts +19 -0
  140. package/src/composables/useApi.ts +1 -0
  141. package/src/composables/useGeneratedAnalysis.ts +1270 -0
  142. package/src/composables/useJobsStatusTray.ts +234 -45
  143. package/src/composables/usePluginClient.ts +164 -30
  144. package/src/composables/usePluginConfig.ts +156 -20
  145. package/src/generated/schema.ts +130 -0
  146. package/src/generated-ui/main.ts +21 -0
  147. package/src/index.ts +3 -0
  148. package/src/jobs.ts +5 -0
  149. package/src/plotly-dist.d.ts +3 -0
  150. package/src/styles/components/section-card.css +161 -0
  151. package/src/styles/index.css +1 -0
  152. package/src/styles/variables.css +25 -0
  153. package/src/tailwind.preset.ts +5 -0
  154. package/src/templates/packs.ts +0 -3
  155. package/src/types/components.ts +12 -0
  156. package/src/types/form-builder.ts +1 -0
  157. package/src/types/generated-ui.ts +189 -0
  158. package/src/types/index.ts +4 -0
  159. package/src/types/instrument.ts +1 -0
  160. package/src/types/jobs.ts +10 -1
  161. package/src/types/platform.ts +2 -0
  162. package/dist/BaseButton-Dgqrze41.js +0 -74
  163. package/dist/BaseButton-Dgqrze41.js.map +0 -1
  164. package/dist/BaseModal-B9UA8Y_I.js +0 -165
  165. package/dist/BaseModal-B9UA8Y_I.js.map +0 -1
  166. package/dist/BaseSelect-ekgr9fDo.js +0 -179
  167. package/dist/BaseSelect-ekgr9fDo.js.map +0 -1
  168. package/dist/ExperimentPopover-Ryusjrhv.js +0 -4
  169. package/dist/ExperimentSelectorModal-Cg4-LXBD.js +0 -5
  170. package/dist/ExperimentSelectorModal-DZeSd-yr.js.map +0 -1
  171. package/dist/SettingsModal-Bl_9w2Y3.js +0 -5
  172. package/dist/components-DdzHh3a_.js.map +0 -1
  173. package/dist/composables-BUUphBqg.js.map +0 -1
  174. package/dist/experiment-utils-Bfa7CwPU.js +0 -108
  175. package/dist/experiment-utils-Bfa7CwPU.js.map +0 -1
  176. package/dist/templates-CNbPQNID.js.map +0 -1
  177. package/dist/useAnalysisArtifacts-C3l0a0vu.js.map +0 -1
  178. package/dist/useControlSchema-BZNdalmL.js.map +0 -1
  179. package/dist/useEventListener-CfVkP9Xz.js +0 -57
  180. package/dist/useEventListener-CfVkP9Xz.js.map +0 -1
  181. package/dist/useExperimentSelector-DRbj6vse.js.map +0 -1
@@ -1,9 +1,10 @@
1
- import { n as normalizeOptionInput, r as BaseInput_default, t as BaseSelect_default } from "./BaseSelect-ekgr9fDo.js";
2
- import { t as useEventListener } from "./useEventListener-CfVkP9Xz.js";
3
- import { t as useDropdownState } from "./useDropdownState-Bb-c_PeE.js";
4
- import { Fragment, Teleport, Transition, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createStaticVNode, createTextVNode, createVNode, defineComponent, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, onUnmounted, openBlock, reactive, ref, renderList, renderSlot, toDisplayString, toValue, unref, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
1
+ import { d as BaseModal_default, f as useEventListener, p as BaseButton_default, s as formatExperimentDate } from "./experiment-utils-CxkruZ3G.js";
2
+ import { c as BaseSelect_default, l as normalizeOptionInput, n as Skeleton_default, o as useApi, r as useRequestSyncState, s as BasePill_default, t as EmptyState_default, u as BaseInput_default } from "./EmptyState-DgBRoYAy.js";
3
+ import { t as useDropdownState } from "./useDropdownState-gVaMXtwW.js";
4
+ import { hasAllPermissions } from "./permissions.js";
5
+ import { Fragment, Teleport, Transition, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createStaticVNode, createTextVNode, createVNode, defineComponent, isRef, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, openBlock, reactive, ref, renderList, renderSlot, shallowRef, toDisplayString, toValue, unref, useSlots, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
5
6
  //#region src/components/BaseTextarea.vue?vue&type=script&setup=true&lang.ts
6
- var _hoisted_1$18 = [
7
+ var _hoisted_1$21 = [
7
8
  "value",
8
9
  "placeholder",
9
10
  "disabled",
@@ -71,7 +72,7 @@ var BaseTextarea_default = /* @__PURE__ */ defineComponent({
71
72
  onInput: handleInput,
72
73
  onFocus: _cache[0] || (_cache[0] = ($event) => emit("focus", $event)),
73
74
  onBlur: _cache[1] || (_cache[1] = ($event) => emit("blur", $event))
74
- }, null, 42, _hoisted_1$18);
75
+ }, null, 42, _hoisted_1$21);
75
76
  };
76
77
  }
77
78
  });
@@ -1062,9 +1063,9 @@ var computePosition = (reference, floating, options) => {
1062
1063
  };
1063
1064
  //#endregion
1064
1065
  //#region src/components/Tooltip.vue?vue&type=script&setup=true&lang.ts
1065
- var _hoisted_1$17 = ["aria-describedby"];
1066
- var _hoisted_2$16 = { class: "mint-tooltip__body" };
1067
- var _hoisted_3$15 = {
1066
+ var _hoisted_1$20 = ["aria-describedby"];
1067
+ var _hoisted_2$19 = { class: "mint-tooltip__body" };
1068
+ var _hoisted_3$17 = {
1068
1069
  key: 0,
1069
1070
  class: "mint-tooltip__shortcut"
1070
1071
  };
@@ -1159,13 +1160,13 @@ var Tooltip_default = /* @__PURE__ */ defineComponent({
1159
1160
  maxWidth: resolvedMaxWidth(__props.maxWidth)
1160
1161
  }),
1161
1162
  role: "tooltip"
1162
- }, [createElementVNode("span", _hoisted_2$16, toDisplayString(__props.text), 1), __props.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_3$15, toDisplayString(__props.shortcut), 1)) : createCommentVNode("", true)], 6)) : createCommentVNode("", true)]))], 40, _hoisted_1$17);
1163
+ }, [createElementVNode("span", _hoisted_2$19, toDisplayString(__props.text), 1), __props.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_3$17, toDisplayString(__props.shortcut), 1)) : createCommentVNode("", true)], 6)) : createCommentVNode("", true)]))], 40, _hoisted_1$20);
1163
1164
  };
1164
1165
  }
1165
1166
  });
1166
1167
  //#endregion
1167
1168
  //#region src/components/BaseCheckbox.vue?vue&type=script&setup=true&lang.ts
1168
- var _hoisted_1$16 = {
1169
+ var _hoisted_1$19 = {
1169
1170
  key: 0,
1170
1171
  class: "mint-checkbox__row-svg",
1171
1172
  viewBox: "0 0 24 24",
@@ -1175,18 +1176,18 @@ var _hoisted_1$16 = {
1175
1176
  "stroke-linecap": "round",
1176
1177
  "stroke-linejoin": "round"
1177
1178
  };
1178
- var _hoisted_2$15 = ["d"];
1179
- var _hoisted_3$14 = ["d"];
1180
- var _hoisted_4$13 = {
1179
+ var _hoisted_2$18 = ["d"];
1180
+ var _hoisted_3$16 = ["d"];
1181
+ var _hoisted_4$15 = {
1181
1182
  key: 1,
1182
1183
  class: "mint-checkbox__row-text-icon"
1183
1184
  };
1184
- var _hoisted_5$11 = {
1185
+ var _hoisted_5$13 = {
1185
1186
  key: 1,
1186
1187
  class: "mint-checkbox__copy"
1187
1188
  };
1188
- var _hoisted_6$11 = { class: "mint-checkbox__input-wrapper" };
1189
- var _hoisted_7$9 = [
1189
+ var _hoisted_6$13 = { class: "mint-checkbox__input-wrapper" };
1190
+ var _hoisted_7$11 = [
1190
1191
  "checked",
1191
1192
  "disabled",
1192
1193
  "aria-label"
@@ -1240,16 +1241,16 @@ var BaseCheckbox_default = /* @__PURE__ */ defineComponent({
1240
1241
  class: "mint-checkbox__row-icon",
1241
1242
  style: normalizeStyle(iconStyle()),
1242
1243
  "aria-hidden": "true"
1243
- }, [isSvgIcon(props.icon) ? (openBlock(), createElementBlock("svg", _hoisted_1$16, [Array.isArray(props.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.icon, (d, i) => {
1244
+ }, [isSvgIcon(props.icon) ? (openBlock(), createElementBlock("svg", _hoisted_1$19, [Array.isArray(props.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.icon, (d, i) => {
1244
1245
  return openBlock(), createElementBlock("path", {
1245
1246
  key: i,
1246
1247
  d
1247
- }, null, 8, _hoisted_2$15);
1248
+ }, null, 8, _hoisted_2$18);
1248
1249
  }), 128)) : (openBlock(), createElementBlock("path", {
1249
1250
  key: 1,
1250
1251
  d: props.icon
1251
- }, null, 8, _hoisted_3$14))])) : (openBlock(), createElementBlock("span", _hoisted_4$13, toDisplayString(props.icon), 1))], 4)) : createCommentVNode("", true),
1252
- props.variant === "row" && props.label ? (openBlock(), createElementBlock("span", _hoisted_5$11, [props.description ? (openBlock(), createBlock(Tooltip_default, {
1252
+ }, null, 8, _hoisted_3$16))])) : (openBlock(), createElementBlock("span", _hoisted_4$15, toDisplayString(props.icon), 1))], 4)) : createCommentVNode("", true),
1253
+ props.variant === "row" && props.label ? (openBlock(), createElementBlock("span", _hoisted_5$13, [props.description ? (openBlock(), createBlock(Tooltip_default, {
1253
1254
  key: 0,
1254
1255
  text: props.description,
1255
1256
  position: "right",
@@ -1265,14 +1266,14 @@ var BaseCheckbox_default = /* @__PURE__ */ defineComponent({
1265
1266
  key: 1,
1266
1267
  class: normalizeClass(["mint-checkbox__label", `mint-checkbox__label--${props.size}`])
1267
1268
  }, toDisplayString(props.label), 3))])) : createCommentVNode("", true),
1268
- createElementVNode("div", _hoisted_6$11, [createElementVNode("input", {
1269
+ createElementVNode("div", _hoisted_6$13, [createElementVNode("input", {
1269
1270
  type: "checkbox",
1270
1271
  checked: props.modelValue,
1271
1272
  disabled: props.disabled,
1272
1273
  "aria-label": props.label || "Checkbox",
1273
1274
  class: "mint-checkbox__native",
1274
1275
  onChange: handleChange
1275
- }, null, 40, _hoisted_7$9), createElementVNode("div", { class: normalizeClass([
1276
+ }, null, 40, _hoisted_7$11), createElementVNode("div", { class: normalizeClass([
1276
1277
  "mint-checkbox__box",
1277
1278
  `mint-checkbox__box--${props.size}`,
1278
1279
  props.modelValue ? "mint-checkbox__box--checked" : ""
@@ -1299,7 +1300,7 @@ var BaseCheckbox_default = /* @__PURE__ */ defineComponent({
1299
1300
  });
1300
1301
  //#endregion
1301
1302
  //#region src/components/BaseToggle.vue?vue&type=script&setup=true&lang.ts
1302
- var _hoisted_1$15 = {
1303
+ var _hoisted_1$18 = {
1303
1304
  key: 0,
1304
1305
  class: "mint-toggle__row-svg",
1305
1306
  viewBox: "0 0 24 24",
@@ -1309,17 +1310,17 @@ var _hoisted_1$15 = {
1309
1310
  "stroke-linecap": "round",
1310
1311
  "stroke-linejoin": "round"
1311
1312
  };
1312
- var _hoisted_2$14 = ["d"];
1313
- var _hoisted_3$13 = ["d"];
1314
- var _hoisted_4$12 = {
1313
+ var _hoisted_2$17 = ["d"];
1314
+ var _hoisted_3$15 = ["d"];
1315
+ var _hoisted_4$14 = {
1315
1316
  key: 1,
1316
1317
  class: "mint-toggle__row-text-icon"
1317
1318
  };
1318
- var _hoisted_5$10 = {
1319
+ var _hoisted_5$12 = {
1319
1320
  key: 1,
1320
1321
  class: "mint-toggle__copy"
1321
1322
  };
1322
- var _hoisted_6$10 = [
1323
+ var _hoisted_6$12 = [
1323
1324
  "tabindex",
1324
1325
  "aria-checked",
1325
1326
  "aria-label"
@@ -1334,6 +1335,7 @@ var BaseToggle_default = /* @__PURE__ */ defineComponent({
1334
1335
  default: false
1335
1336
  },
1336
1337
  label: {},
1338
+ ariaLabel: {},
1337
1339
  description: {},
1338
1340
  icon: {},
1339
1341
  iconColor: {},
@@ -1386,16 +1388,16 @@ var BaseToggle_default = /* @__PURE__ */ defineComponent({
1386
1388
  class: "mint-toggle__row-icon",
1387
1389
  style: normalizeStyle(iconStyle()),
1388
1390
  "aria-hidden": "true"
1389
- }, [isSvgIcon(__props.icon) ? (openBlock(), createElementBlock("svg", _hoisted_1$15, [Array.isArray(__props.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(__props.icon, (d, i) => {
1391
+ }, [isSvgIcon(__props.icon) ? (openBlock(), createElementBlock("svg", _hoisted_1$18, [Array.isArray(__props.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(__props.icon, (d, i) => {
1390
1392
  return openBlock(), createElementBlock("path", {
1391
1393
  key: i,
1392
1394
  d
1393
- }, null, 8, _hoisted_2$14);
1395
+ }, null, 8, _hoisted_2$17);
1394
1396
  }), 128)) : (openBlock(), createElementBlock("path", {
1395
1397
  key: 1,
1396
1398
  d: __props.icon
1397
- }, null, 8, _hoisted_3$13))])) : (openBlock(), createElementBlock("span", _hoisted_4$12, toDisplayString(__props.icon), 1))], 4)) : createCommentVNode("", true),
1398
- __props.variant === "row" && __props.label ? (openBlock(), createElementBlock("span", _hoisted_5$10, [__props.description ? (openBlock(), createBlock(Tooltip_default, {
1399
+ }, null, 8, _hoisted_3$15))])) : (openBlock(), createElementBlock("span", _hoisted_4$14, toDisplayString(__props.icon), 1))], 4)) : createCommentVNode("", true),
1400
+ __props.variant === "row" && __props.label ? (openBlock(), createElementBlock("span", _hoisted_5$12, [__props.description ? (openBlock(), createBlock(Tooltip_default, {
1399
1401
  key: 0,
1400
1402
  text: __props.description,
1401
1403
  position: "right",
@@ -1415,7 +1417,7 @@ var BaseToggle_default = /* @__PURE__ */ defineComponent({
1415
1417
  role: "switch",
1416
1418
  tabindex: __props.disabled ? -1 : 0,
1417
1419
  "aria-checked": __props.modelValue,
1418
- "aria-label": __props.label || "Toggle",
1420
+ "aria-label": __props.ariaLabel || __props.label || "Toggle",
1419
1421
  class: normalizeClass([
1420
1422
  "mint-toggle__track",
1421
1423
  `mint-toggle__track--${__props.size}`,
@@ -1426,7 +1428,7 @@ var BaseToggle_default = /* @__PURE__ */ defineComponent({
1426
1428
  "mint-toggle__knob",
1427
1429
  `mint-toggle__knob--${__props.size}`,
1428
1430
  __props.modelValue ? `mint-toggle__knob--on-${__props.size}` : "mint-toggle__knob--off"
1429
- ]) }, null, 2)], 42, _hoisted_6$10),
1431
+ ]) }, null, 2)], 42, _hoisted_6$12),
1430
1432
  __props.label && __props.variant !== "row" ? (openBlock(), createElementBlock("span", {
1431
1433
  key: 2,
1432
1434
  class: normalizeClass(["mint-toggle__label", `mint-toggle__label--${__props.size}`])
@@ -1437,7 +1439,7 @@ var BaseToggle_default = /* @__PURE__ */ defineComponent({
1437
1439
  });
1438
1440
  //#endregion
1439
1441
  //#region src/components/BaseRadioGroup.vue?vue&type=script&setup=true&lang.ts
1440
- var _hoisted_1$14 = [
1442
+ var _hoisted_1$17 = [
1441
1443
  "name",
1442
1444
  "value",
1443
1445
  "checked",
@@ -1445,9 +1447,9 @@ var _hoisted_1$14 = [
1445
1447
  "aria-describedby",
1446
1448
  "onChange"
1447
1449
  ];
1448
- var _hoisted_2$13 = { class: "mint-radio-option__content" };
1449
- var _hoisted_3$12 = ["id"];
1450
- var _hoisted_4$11 = [
1450
+ var _hoisted_2$16 = { class: "mint-radio-option__content" };
1451
+ var _hoisted_3$14 = ["id"];
1452
+ var _hoisted_4$13 = [
1451
1453
  "name",
1452
1454
  "value",
1453
1455
  "checked",
@@ -1455,9 +1457,9 @@ var _hoisted_4$11 = [
1455
1457
  "aria-describedby",
1456
1458
  "onChange"
1457
1459
  ];
1458
- var _hoisted_5$9 = { class: "mint-radio-option__head" };
1459
- var _hoisted_6$9 = { class: "mint-radio-option__title" };
1460
- var _hoisted_7$8 = ["id"];
1460
+ var _hoisted_5$11 = { class: "mint-radio-option__head" };
1461
+ var _hoisted_6$11 = { class: "mint-radio-option__title" };
1462
+ var _hoisted_7$10 = ["id"];
1461
1463
  //#endregion
1462
1464
  //#region src/components/BaseRadioGroup.vue
1463
1465
  var BaseRadioGroup_default = /* @__PURE__ */ defineComponent({
@@ -1508,18 +1510,18 @@ var BaseRadioGroup_default = /* @__PURE__ */ defineComponent({
1508
1510
  "aria-describedby": option.description ? `${props.name}-${option.value}-desc` : void 0,
1509
1511
  class: "mint-radio-option__native",
1510
1512
  onChange: ($event) => handleChange(option.value)
1511
- }, null, 40, _hoisted_1$14), createElementVNode("div", { class: normalizeClass([
1513
+ }, null, 40, _hoisted_1$17), createElementVNode("div", { class: normalizeClass([
1512
1514
  "mint-radio-option__circle",
1513
1515
  `mint-radio-option__circle--${props.size}`,
1514
1516
  props.modelValue === option.value ? "mint-radio-option__circle--checked" : ""
1515
1517
  ]) }, [props.modelValue === option.value ? (openBlock(), createElementBlock("div", {
1516
1518
  key: 0,
1517
1519
  class: normalizeClass(["mint-radio-option__dot", `mint-radio-option__dot--${props.size}`])
1518
- }, null, 2)) : createCommentVNode("", true)], 2)], 2), createElementVNode("div", _hoisted_2$13, [createElementVNode("span", { class: normalizeClass(["mint-radio-option__label", `mint-radio-option__label--${props.size}`]) }, toDisplayString(option.label), 3), option.description ? (openBlock(), createElementBlock("span", {
1520
+ }, null, 2)) : createCommentVNode("", true)], 2)], 2), createElementVNode("div", _hoisted_2$16, [createElementVNode("span", { class: normalizeClass(["mint-radio-option__label", `mint-radio-option__label--${props.size}`]) }, toDisplayString(option.label), 3), option.description ? (openBlock(), createElementBlock("span", {
1519
1521
  key: 0,
1520
1522
  id: `${props.name}-${option.value}-desc`,
1521
1523
  class: normalizeClass(["mint-radio-option__description", `mint-radio-option__description--${props.size}`])
1522
- }, toDisplayString(option.description), 11, _hoisted_3$12)) : createCommentVNode("", true)])], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
1524
+ }, toDisplayString(option.description), 11, _hoisted_3$14)) : createCommentVNode("", true)])], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
1523
1525
  createElementVNode("input", {
1524
1526
  type: "radio",
1525
1527
  name: props.name,
@@ -1529,20 +1531,20 @@ var BaseRadioGroup_default = /* @__PURE__ */ defineComponent({
1529
1531
  "aria-describedby": option.description ? `${props.name}-${option.value}-desc` : void 0,
1530
1532
  class: "mint-radio-option__native",
1531
1533
  onChange: ($event) => handleChange(option.value)
1532
- }, null, 40, _hoisted_4$11),
1533
- createElementVNode("div", _hoisted_5$9, [createElementVNode("div", { class: normalizeClass([
1534
+ }, null, 40, _hoisted_4$13),
1535
+ createElementVNode("div", _hoisted_5$11, [createElementVNode("div", { class: normalizeClass([
1534
1536
  "mint-radio-option__circle",
1535
1537
  `mint-radio-option__circle--${props.size}`,
1536
1538
  props.modelValue === option.value ? "mint-radio-option__circle--checked" : ""
1537
1539
  ]) }, [props.modelValue === option.value ? (openBlock(), createElementBlock("div", {
1538
1540
  key: 0,
1539
1541
  class: normalizeClass(["mint-radio-option__dot", `mint-radio-option__dot--${props.size}`])
1540
- }, null, 2)) : createCommentVNode("", true)], 2), createElementVNode("span", _hoisted_6$9, toDisplayString(option.label), 1)]),
1542
+ }, null, 2)) : createCommentVNode("", true)], 2), createElementVNode("span", _hoisted_6$11, toDisplayString(option.label), 1)]),
1541
1543
  option.description ? (openBlock(), createElementBlock("span", {
1542
1544
  key: 0,
1543
1545
  id: `${props.name}-${option.value}-desc`,
1544
1546
  class: "mint-radio-option__description"
1545
- }, toDisplayString(option.description), 9, _hoisted_7$8)) : createCommentVNode("", true)
1547
+ }, toDisplayString(option.description), 9, _hoisted_7$10)) : createCommentVNode("", true)
1546
1548
  ], 64))], 2);
1547
1549
  }), 128))], 2);
1548
1550
  };
@@ -1550,8 +1552,8 @@ var BaseRadioGroup_default = /* @__PURE__ */ defineComponent({
1550
1552
  });
1551
1553
  //#endregion
1552
1554
  //#region src/components/BaseSlider.vue?vue&type=script&setup=true&lang.ts
1553
- var _hoisted_1$13 = { class: "mint-slider__container" };
1554
- var _hoisted_2$12 = [
1555
+ var _hoisted_1$16 = { class: "mint-slider__container" };
1556
+ var _hoisted_2$15 = [
1555
1557
  "value",
1556
1558
  "min",
1557
1559
  "max",
@@ -1562,7 +1564,7 @@ var _hoisted_2$12 = [
1562
1564
  "aria-valuemax",
1563
1565
  "aria-valuenow"
1564
1566
  ];
1565
- var _hoisted_3$11 = {
1567
+ var _hoisted_3$13 = {
1566
1568
  key: 0,
1567
1569
  class: "mint-slider__value"
1568
1570
  };
@@ -1624,7 +1626,7 @@ var BaseSlider_default = /* @__PURE__ */ defineComponent({
1624
1626
  emit("update:modelValue", Number(target.value));
1625
1627
  }
1626
1628
  return (_ctx, _cache) => {
1627
- return openBlock(), createElementBlock("div", { class: normalizeClass(["mint-slider", { "mint-slider--disabled": __props.disabled }]) }, [createElementVNode("div", _hoisted_1$13, [
1629
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["mint-slider", { "mint-slider--disabled": __props.disabled }]) }, [createElementVNode("div", _hoisted_1$16, [
1628
1630
  createElementVNode("div", {
1629
1631
  class: "mint-slider__track",
1630
1632
  style: normalizeStyle({ height: `${sizeConfig.value.height}px` })
@@ -1653,7 +1655,7 @@ var BaseSlider_default = /* @__PURE__ */ defineComponent({
1653
1655
  onMouseup: _cache[1] || (_cache[1] = ($event) => isDragging.value = false),
1654
1656
  onTouchstartPassive: _cache[2] || (_cache[2] = ($event) => isDragging.value = true),
1655
1657
  onTouchend: _cache[3] || (_cache[3] = ($event) => isDragging.value = false)
1656
- }, null, 40, _hoisted_2$12),
1658
+ }, null, 40, _hoisted_2$15),
1657
1659
  createElementVNode("div", {
1658
1660
  class: normalizeClass(["mint-slider__thumb", { "mint-slider__thumb--dragging": isDragging.value }]),
1659
1661
  style: normalizeStyle({
@@ -1662,7 +1664,7 @@ var BaseSlider_default = /* @__PURE__ */ defineComponent({
1662
1664
  left: thumbPosition.value
1663
1665
  })
1664
1666
  }, null, 6)
1665
- ]), __props.showValue ? (openBlock(), createElementBlock("span", _hoisted_3$11, toDisplayString(currentValue.value), 1)) : createCommentVNode("", true)], 2);
1667
+ ]), __props.showValue ? (openBlock(), createElementBlock("span", _hoisted_3$13, toDisplayString(currentValue.value), 1)) : createCommentVNode("", true)], 2);
1666
1668
  };
1667
1669
  }
1668
1670
  });
@@ -1788,22 +1790,22 @@ function uniqueValues(values) {
1788
1790
  }
1789
1791
  //#endregion
1790
1792
  //#region src/components/MultiSelect.vue?vue&type=script&setup=true&lang.ts
1791
- var _hoisted_1$12 = {
1793
+ var _hoisted_1$15 = {
1792
1794
  key: 0,
1793
1795
  class: "mint-multi-select__placeholder"
1794
1796
  };
1795
- var _hoisted_2$11 = {
1797
+ var _hoisted_2$14 = {
1796
1798
  class: "mint-multi-select__options",
1797
1799
  role: "group"
1798
1800
  };
1799
- var _hoisted_3$10 = [
1801
+ var _hoisted_3$12 = [
1800
1802
  "aria-checked",
1801
1803
  "disabled",
1802
1804
  "onClick",
1803
1805
  "onKeydown"
1804
1806
  ];
1805
- var _hoisted_4$10 = { class: "mint-multi-select__chip-label" };
1806
- var _hoisted_5$8 = {
1807
+ var _hoisted_4$12 = { class: "mint-multi-select__chip-label" };
1808
+ var _hoisted_5$10 = {
1807
1809
  key: 0,
1808
1810
  class: "mint-multi-select__chip-check",
1809
1811
  viewBox: "0 0 24 24",
@@ -1813,7 +1815,7 @@ var _hoisted_5$8 = {
1813
1815
  "stroke-linecap": "round",
1814
1816
  "stroke-linejoin": "round"
1815
1817
  };
1816
- var _hoisted_6$8 = {
1818
+ var _hoisted_6$10 = {
1817
1819
  key: 1,
1818
1820
  class: "mint-multi-select__summary"
1819
1821
  };
@@ -1868,8 +1870,8 @@ var MultiSelect_default = /* @__PURE__ */ defineComponent({
1868
1870
  `mint-multi-select--${__props.size}`,
1869
1871
  __props.disabled ? "mint-multi-select--disabled" : ""
1870
1872
  ]) }, [
1871
- __props.modelValue.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$12, toDisplayString(__props.placeholder), 1)) : createCommentVNode("", true),
1872
- createElementVNode("div", _hoisted_2$11, [(openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option) => {
1873
+ __props.modelValue.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$15, toDisplayString(__props.placeholder), 1)) : createCommentVNode("", true),
1874
+ createElementVNode("div", _hoisted_2$14, [(openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option) => {
1873
1875
  return openBlock(), createElementBlock("button", {
1874
1876
  key: String(option.value),
1875
1877
  type: "button",
@@ -1885,9 +1887,9 @@ var MultiSelect_default = /* @__PURE__ */ defineComponent({
1885
1887
  ]),
1886
1888
  onClick: ($event) => toggleOption(option),
1887
1889
  onKeydown: ($event) => handleKeydown($event, option)
1888
- }, [createElementVNode("span", _hoisted_4$10, toDisplayString(option.label), 1), isSelected(option.value) ? (openBlock(), createElementBlock("svg", _hoisted_5$8, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "M20 6 9 17l-5-5" }, null, -1)])])) : createCommentVNode("", true)], 42, _hoisted_3$10);
1890
+ }, [createElementVNode("span", _hoisted_4$12, toDisplayString(option.label), 1), isSelected(option.value) ? (openBlock(), createElementBlock("svg", _hoisted_5$10, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "M20 6 9 17l-5-5" }, null, -1)])])) : createCommentVNode("", true)], 42, _hoisted_3$12);
1889
1891
  }), 128))]),
1890
- __props.modelValue.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_6$8, toDisplayString(selectedLabels.value.join(", ")), 1)) : createCommentVNode("", true)
1892
+ __props.modelValue.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_6$10, toDisplayString(selectedLabels.value.join(", ")), 1)) : createCommentVNode("", true)
1891
1893
  ], 2);
1892
1894
  };
1893
1895
  }
@@ -1998,14 +2000,14 @@ function startOfDay(date) {
1998
2000
  }
1999
2001
  //#endregion
2000
2002
  //#region src/components/internal/CalendarGridPanelInternal.vue?vue&type=script&setup=true&lang.ts
2001
- var _hoisted_1$11 = { class: "mint-calendar-grid-panel" };
2002
- var _hoisted_2$10 = { class: "mint-date-picker__header" };
2003
- var _hoisted_3$9 = ["aria-label"];
2004
- var _hoisted_4$9 = { class: "mint-date-picker__month-year" };
2005
- var _hoisted_5$7 = ["aria-label"];
2006
- var _hoisted_6$7 = { class: "mint-date-picker__weekdays" };
2007
- var _hoisted_7$7 = { class: "mint-date-picker__grid" };
2008
- var _hoisted_8$5 = [
2003
+ var _hoisted_1$14 = { class: "mint-calendar-grid-panel" };
2004
+ var _hoisted_2$13 = { class: "mint-date-picker__header" };
2005
+ var _hoisted_3$11 = ["aria-label"];
2006
+ var _hoisted_4$11 = { class: "mint-date-picker__month-year" };
2007
+ var _hoisted_5$9 = ["aria-label"];
2008
+ var _hoisted_6$9 = { class: "mint-date-picker__weekdays" };
2009
+ var _hoisted_7$9 = { class: "mint-date-picker__grid" };
2010
+ var _hoisted_8$7 = [
2009
2011
  "disabled",
2010
2012
  "aria-label",
2011
2013
  "aria-selected",
@@ -2049,8 +2051,8 @@ var CalendarGridPanelInternal_default = /* @__PURE__ */ defineComponent({
2049
2051
  });
2050
2052
  }
2051
2053
  return (_ctx, _cache) => {
2052
- return openBlock(), createElementBlock("div", _hoisted_1$11, [
2053
- createElementVNode("div", _hoisted_2$10, [
2054
+ return openBlock(), createElementBlock("div", _hoisted_1$14, [
2055
+ createElementVNode("div", _hoisted_2$13, [
2054
2056
  createElementVNode("button", {
2055
2057
  type: "button",
2056
2058
  class: "mint-date-picker__nav-btn",
@@ -2064,8 +2066,8 @@ var CalendarGridPanelInternal_default = /* @__PURE__ */ defineComponent({
2064
2066
  "stroke-linecap": "round",
2065
2067
  "stroke-linejoin": "round",
2066
2068
  "aria-hidden": "true"
2067
- }, [createElementVNode("path", { d: "m15 18-6-6 6-6" })], -1)])], 8, _hoisted_3$9),
2068
- createElementVNode("span", _hoisted_4$9, toDisplayString(__props.monthYear), 1),
2069
+ }, [createElementVNode("path", { d: "m15 18-6-6 6-6" })], -1)])], 8, _hoisted_3$11),
2070
+ createElementVNode("span", _hoisted_4$11, toDisplayString(__props.monthYear), 1),
2069
2071
  createElementVNode("button", {
2070
2072
  type: "button",
2071
2073
  class: "mint-date-picker__nav-btn",
@@ -2079,15 +2081,15 @@ var CalendarGridPanelInternal_default = /* @__PURE__ */ defineComponent({
2079
2081
  "stroke-linecap": "round",
2080
2082
  "stroke-linejoin": "round",
2081
2083
  "aria-hidden": "true"
2082
- }, [createElementVNode("path", { d: "m9 18 6-6-6-6" })], -1)])], 8, _hoisted_5$7)
2084
+ }, [createElementVNode("path", { d: "m9 18 6-6-6-6" })], -1)])], 8, _hoisted_5$9)
2083
2085
  ]),
2084
- createElementVNode("div", _hoisted_6$7, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.weekDays, (day) => {
2086
+ createElementVNode("div", _hoisted_6$9, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.weekDays, (day) => {
2085
2087
  return openBlock(), createElementBlock("div", {
2086
2088
  key: day,
2087
2089
  class: "mint-date-picker__weekday"
2088
2090
  }, toDisplayString(day), 1);
2089
2091
  }), 128))]),
2090
- createElementVNode("div", _hoisted_7$7, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.days, (day, index) => {
2092
+ createElementVNode("div", _hoisted_7$9, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.days, (day, index) => {
2091
2093
  return openBlock(), createElementBlock("button", {
2092
2094
  key: index,
2093
2095
  type: "button",
@@ -2102,7 +2104,7 @@ var CalendarGridPanelInternal_default = /* @__PURE__ */ defineComponent({
2102
2104
  isToday(day.date) && !isSameDay(day.date, __props.selectedDate) ? "mint-date-picker__day--today" : ""
2103
2105
  ]),
2104
2106
  onClick: ($event) => emit("select", day)
2105
- }, toDisplayString(day.date.getDate()), 11, _hoisted_8$5);
2107
+ }, toDisplayString(day.date.getDate()), 11, _hoisted_8$7);
2106
2108
  }), 128))])
2107
2109
  ]);
2108
2110
  };
@@ -2110,12 +2112,12 @@ var CalendarGridPanelInternal_default = /* @__PURE__ */ defineComponent({
2110
2112
  });
2111
2113
  //#endregion
2112
2114
  //#region src/components/DatePicker.vue?vue&type=script&setup=true&lang.ts
2113
- var _hoisted_1$10 = [
2115
+ var _hoisted_1$13 = [
2114
2116
  "value",
2115
2117
  "placeholder",
2116
2118
  "disabled"
2117
2119
  ];
2118
- var _hoisted_2$9 = { class: "mint-date-picker__footer" };
2120
+ var _hoisted_2$12 = { class: "mint-date-picker__footer" };
2119
2121
  //#endregion
2120
2122
  //#region src/components/DatePicker.vue
2121
2123
  var DatePicker_default = /* @__PURE__ */ defineComponent({
@@ -2230,7 +2232,7 @@ var DatePicker_default = /* @__PURE__ */ defineComponent({
2230
2232
  __props.disabled ? "mint-date-picker__input--disabled" : ""
2231
2233
  ]),
2232
2234
  onClick: toggleCalendar
2233
- }, null, 10, _hoisted_1$10), _cache[0] || (_cache[0] = createStaticVNode("<div class=\"mint-date-picker__icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 2v4\"></path><path d=\"M16 2v4\"></path><rect width=\"18\" height=\"18\" x=\"3\" y=\"4\" rx=\"2\"></rect><path d=\"M3 10h18\"></path></svg></div>", 1))], 512), (openBlock(), createBlock(Teleport, { to: "body" }, [createVNode(Transition, {
2235
+ }, null, 10, _hoisted_1$13), _cache[0] || (_cache[0] = createStaticVNode("<div class=\"mint-date-picker__icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 2v4\"></path><path d=\"M16 2v4\"></path><rect width=\"18\" height=\"18\" x=\"3\" y=\"4\" rx=\"2\"></rect><path d=\"M3 10h18\"></path></svg></div>", 1))], 512), (openBlock(), createBlock(Teleport, { to: "body" }, [createVNode(Transition, {
2234
2236
  "enter-active-class": "mint-date-picker__dropdown-enter-active",
2235
2237
  "enter-from-class": "mint-date-picker__dropdown-enter-from",
2236
2238
  "enter-to-class": "mint-date-picker__dropdown-enter-to",
@@ -2262,7 +2264,7 @@ var DatePicker_default = /* @__PURE__ */ defineComponent({
2262
2264
  "selected-date",
2263
2265
  "onPreviousMonth",
2264
2266
  "onNextMonth"
2265
- ]), createElementVNode("div", _hoisted_2$9, [createElementVNode("button", {
2267
+ ]), createElementVNode("div", _hoisted_2$12, [createElementVNode("button", {
2266
2268
  type: "button",
2267
2269
  class: "mint-date-picker__footer-btn mint-date-picker__today-btn",
2268
2270
  onClick: goToToday
@@ -2408,18 +2410,18 @@ function useTimeUtils() {
2408
2410
  }
2409
2411
  //#endregion
2410
2412
  //#region src/components/TimePicker.vue?vue&type=script&setup=true&lang.ts
2411
- var _hoisted_1$9 = { class: "mint-time-picker__input-wrapper" };
2412
- var _hoisted_2$8 = [
2413
+ var _hoisted_1$12 = { class: "mint-time-picker__input-wrapper" };
2414
+ var _hoisted_2$11 = [
2413
2415
  "value",
2414
2416
  "placeholder",
2415
2417
  "disabled",
2416
2418
  "aria-expanded"
2417
2419
  ];
2418
- var _hoisted_3$8 = {
2420
+ var _hoisted_3$10 = {
2419
2421
  key: 0,
2420
2422
  class: "mint-time-picker__dropdown"
2421
2423
  };
2422
- var _hoisted_4$8 = [
2424
+ var _hoisted_4$10 = [
2423
2425
  "aria-selected",
2424
2426
  "aria-disabled",
2425
2427
  "onClick"
@@ -2561,7 +2563,7 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2561
2563
  ref: rootRef,
2562
2564
  class: "mint-time-picker",
2563
2565
  onKeydown: handleKeydown
2564
- }, [createElementVNode("div", _hoisted_1$9, [
2566
+ }, [createElementVNode("div", _hoisted_1$12, [
2565
2567
  createElementVNode("input", {
2566
2568
  type: "text",
2567
2569
  readonly: "",
@@ -2578,7 +2580,7 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2578
2580
  "aria-haspopup": "listbox",
2579
2581
  "aria-expanded": unref(isOpen),
2580
2582
  onClick: toggleDropdown
2581
- }, null, 10, _hoisted_2$8),
2583
+ }, null, 10, _hoisted_2$11),
2582
2584
  __props.clearable && __props.modelValue ? (openBlock(), createElementBlock("button", {
2583
2585
  key: 0,
2584
2586
  type: "button",
@@ -2613,7 +2615,7 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2613
2615
  "leave-from-class": "mint-time-picker__dropdown-leave-from",
2614
2616
  "leave-to-class": "mint-time-picker__dropdown-leave-to"
2615
2617
  }, {
2616
- default: withCtx(() => [unref(isOpen) ? (openBlock(), createElementBlock("div", _hoisted_3$8, [createElementVNode("ul", {
2618
+ default: withCtx(() => [unref(isOpen) ? (openBlock(), createElementBlock("div", _hoisted_3$10, [createElementVNode("ul", {
2617
2619
  ref_key: "listRef",
2618
2620
  ref: listRef,
2619
2621
  class: "mint-time-picker__list",
@@ -2632,7 +2634,7 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2632
2634
  index === highlightedIndex.value && !isSlotDisabled(slot) ? "mint-time-picker__slot--highlighted" : ""
2633
2635
  ]),
2634
2636
  onClick: ($event) => selectSlot(slot)
2635
- }, toDisplayString(unref(formatTimeSlot)(slot, __props.format)), 11, _hoisted_4$8);
2637
+ }, toDisplayString(unref(formatTimeSlot)(slot, __props.format)), 11, _hoisted_4$10);
2636
2638
  }), 128))], 512)])) : createCommentVNode("", true)]),
2637
2639
  _: 1
2638
2640
  })], 544);
@@ -2641,19 +2643,19 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2641
2643
  });
2642
2644
  //#endregion
2643
2645
  //#region src/components/TagsInput.vue?vue&type=script&setup=true&lang.ts
2644
- var _hoisted_1$8 = {
2646
+ var _hoisted_1$11 = {
2645
2647
  key: 0,
2646
2648
  class: "mint-tags-input__categories"
2647
2649
  };
2648
- var _hoisted_2$7 = ["disabled", "onClick"];
2649
- var _hoisted_3$7 = ["aria-label", "onClick"];
2650
- var _hoisted_4$7 = ["placeholder", "disabled"];
2651
- var _hoisted_5$6 = {
2650
+ var _hoisted_2$10 = ["disabled", "onClick"];
2651
+ var _hoisted_3$9 = ["aria-label", "onClick"];
2652
+ var _hoisted_4$9 = ["placeholder", "disabled"];
2653
+ var _hoisted_5$8 = {
2652
2654
  key: 0,
2653
2655
  class: "mint-tags-input__dropdown"
2654
2656
  };
2655
- var _hoisted_6$6 = ["onMousedown"];
2656
- var _hoisted_7$6 = {
2657
+ var _hoisted_6$8 = ["onMousedown"];
2658
+ var _hoisted_7$8 = {
2657
2659
  key: 0,
2658
2660
  class: "mint-tags-input__dropdown-count"
2659
2661
  };
@@ -2796,7 +2798,7 @@ var TagsInput_default = /* @__PURE__ */ defineComponent({
2796
2798
  __props.disabled ? "mint-tags-input--disabled" : "",
2797
2799
  __props.categories.length ? "mint-tags-input--categorized" : ""
2798
2800
  ])
2799
- }, [__props.categories.length ? (openBlock(), createElementBlock("div", _hoisted_1$8, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.categories, (cat) => {
2801
+ }, [__props.categories.length ? (openBlock(), createElementBlock("div", _hoisted_1$11, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.categories, (cat) => {
2800
2802
  return openBlock(), createElementBlock("button", {
2801
2803
  key: cat.prefix,
2802
2804
  type: "button",
@@ -2807,7 +2809,7 @@ var TagsInput_default = /* @__PURE__ */ defineComponent({
2807
2809
  ]),
2808
2810
  disabled: __props.disabled,
2809
2811
  onClick: ($event) => setCategory(cat.prefix)
2810
- }, toDisplayString(cat.name), 11, _hoisted_2$7);
2812
+ }, toDisplayString(cat.name), 11, _hoisted_2$10);
2811
2813
  }), 128))])) : createCommentVNode("", true), createElementVNode("div", {
2812
2814
  class: "mint-tags-input__field",
2813
2815
  onClick: focusInput
@@ -2834,7 +2836,7 @@ var TagsInput_default = /* @__PURE__ */ defineComponent({
2834
2836
  "stroke-linecap": "round",
2835
2837
  "stroke-linejoin": "round",
2836
2838
  viewBox: "0 0 24 24"
2837
- }, [createElementVNode("path", { d: "M18 6 6 18" }), createElementVNode("path", { d: "m6 6 12 12" })], -1)])], 8, _hoisted_3$7)) : createCommentVNode("", true)], 2);
2839
+ }, [createElementVNode("path", { d: "M18 6 6 18" }), createElementVNode("path", { d: "m6 6 12 12" })], -1)])], 8, _hoisted_3$9)) : createCommentVNode("", true)], 2);
2838
2840
  }), 128)),
2839
2841
  withDirectives(createElementVNode("input", {
2840
2842
  ref_key: "inputRef",
@@ -2849,14 +2851,14 @@ var TagsInput_default = /* @__PURE__ */ defineComponent({
2849
2851
  onFocus: handleFocus,
2850
2852
  onBlur: handleBlur,
2851
2853
  onInput: onInputEvent
2852
- }, null, 42, _hoisted_4$7), [[vModelText, inputValue.value]]),
2853
- unref(dropdownOpen) && filteredSuggestions.value.length ? (openBlock(), createElementBlock("div", _hoisted_5$6, [(openBlock(true), createElementBlock(Fragment, null, renderList(filteredSuggestions.value, (sug, i) => {
2854
+ }, null, 42, _hoisted_4$9), [[vModelText, inputValue.value]]),
2855
+ unref(dropdownOpen) && filteredSuggestions.value.length ? (openBlock(), createElementBlock("div", _hoisted_5$8, [(openBlock(true), createElementBlock(Fragment, null, renderList(filteredSuggestions.value, (sug, i) => {
2854
2856
  return openBlock(), createElementBlock("button", {
2855
2857
  key: sug.value,
2856
2858
  type: "button",
2857
2859
  class: normalizeClass(["mint-tags-input__dropdown-item", i === highlightedIndex.value ? "mint-tags-input__dropdown-item--highlighted" : ""]),
2858
2860
  onMousedown: withModifiers(($event) => addTag(sug.value), ["prevent"])
2859
- }, [createElementVNode("span", null, toDisplayString(sug.value), 1), sug.count !== void 0 ? (openBlock(), createElementBlock("span", _hoisted_7$6, toDisplayString(sug.count), 1)) : createCommentVNode("", true)], 42, _hoisted_6$6);
2861
+ }, [createElementVNode("span", null, toDisplayString(sug.value), 1), sug.count !== void 0 ? (openBlock(), createElementBlock("span", _hoisted_7$8, toDisplayString(sug.count), 1)) : createCommentVNode("", true)], 42, _hoisted_6$8);
2860
2862
  }), 128))])) : createCommentVNode("", true)
2861
2863
  ])], 2);
2862
2864
  };
@@ -2864,8 +2866,8 @@ var TagsInput_default = /* @__PURE__ */ defineComponent({
2864
2866
  });
2865
2867
  //#endregion
2866
2868
  //#region src/components/NumberInput.vue?vue&type=script&setup=true&lang.ts
2867
- var _hoisted_1$7 = { class: "mint-number-input__field" };
2868
- var _hoisted_2$6 = [
2869
+ var _hoisted_1$10 = { class: "mint-number-input__field" };
2870
+ var _hoisted_2$9 = [
2869
2871
  "value",
2870
2872
  "min",
2871
2873
  "max",
@@ -2873,17 +2875,17 @@ var _hoisted_2$6 = [
2873
2875
  "disabled",
2874
2876
  "placeholder"
2875
2877
  ];
2876
- var _hoisted_3$6 = {
2878
+ var _hoisted_3$8 = {
2877
2879
  key: 0,
2878
2880
  class: "mint-number-input__unit"
2879
2881
  };
2880
- var _hoisted_4$6 = {
2882
+ var _hoisted_4$8 = {
2881
2883
  class: "mint-number-input__steppers",
2882
2884
  "aria-hidden": "true"
2883
2885
  };
2884
- var _hoisted_5$5 = ["disabled"];
2885
- var _hoisted_6$5 = ["disabled"];
2886
- var _hoisted_7$5 = [
2886
+ var _hoisted_5$7 = ["disabled"];
2887
+ var _hoisted_6$7 = ["disabled"];
2888
+ var _hoisted_7$7 = [
2887
2889
  "value",
2888
2890
  "min",
2889
2891
  "max",
@@ -2967,7 +2969,7 @@ var NumberInput_default = /* @__PURE__ */ defineComponent({
2967
2969
  isSliderMode.value ? "mint-number-input--slider" : "mint-number-input--stepper",
2968
2970
  __props.error ? "mint-number-input--error" : "",
2969
2971
  __props.disabled ? "mint-number-input--disabled" : ""
2970
- ]) }, [createElementVNode("div", _hoisted_1$7, [
2972
+ ]) }, [createElementVNode("div", _hoisted_1$10, [
2971
2973
  createElementVNode("input", {
2972
2974
  type: "number",
2973
2975
  value: __props.modelValue,
@@ -2978,9 +2980,9 @@ var NumberInput_default = /* @__PURE__ */ defineComponent({
2978
2980
  placeholder: __props.placeholder,
2979
2981
  class: normalizeClass(["mint-number-input__input", `mint-number-input__input--${__props.size}`]),
2980
2982
  onInput: handleInput
2981
- }, null, 42, _hoisted_2$6),
2982
- __props.unit ? (openBlock(), createElementBlock("span", _hoisted_3$6, toDisplayString(__props.unit), 1)) : createCommentVNode("", true),
2983
- createElementVNode("div", _hoisted_4$6, [createElementVNode("button", {
2983
+ }, null, 42, _hoisted_2$9),
2984
+ __props.unit ? (openBlock(), createElementBlock("span", _hoisted_3$8, toDisplayString(__props.unit), 1)) : createCommentVNode("", true),
2985
+ createElementVNode("div", _hoisted_4$8, [createElementVNode("button", {
2984
2986
  type: "button",
2985
2987
  tabindex: "-1",
2986
2988
  "aria-label": "Increase value",
@@ -2994,7 +2996,7 @@ var NumberInput_default = /* @__PURE__ */ defineComponent({
2994
2996
  "stroke-width": "1.5",
2995
2997
  "stroke-linecap": "round",
2996
2998
  "stroke-linejoin": "round"
2997
- }, [createElementVNode("path", { d: "M1 5l4-4 4 4" })], -1)])], 8, _hoisted_5$5), createElementVNode("button", {
2999
+ }, [createElementVNode("path", { d: "M1 5l4-4 4 4" })], -1)])], 8, _hoisted_5$7), createElementVNode("button", {
2998
3000
  type: "button",
2999
3001
  tabindex: "-1",
3000
3002
  "aria-label": "Decrease value",
@@ -3008,7 +3010,7 @@ var NumberInput_default = /* @__PURE__ */ defineComponent({
3008
3010
  "stroke-width": "1.5",
3009
3011
  "stroke-linecap": "round",
3010
3012
  "stroke-linejoin": "round"
3011
- }, [createElementVNode("path", { d: "M1 1l4 4 4-4" })], -1)])], 8, _hoisted_6$5)])
3013
+ }, [createElementVNode("path", { d: "M1 1l4 4 4-4" })], -1)])], 8, _hoisted_6$7)])
3012
3014
  ]), isSliderMode.value ? (openBlock(), createElementBlock("input", {
3013
3015
  key: 0,
3014
3016
  type: "range",
@@ -3020,26 +3022,26 @@ var NumberInput_default = /* @__PURE__ */ defineComponent({
3020
3022
  style: normalizeStyle({ "--mint-slider-fill": `${sliderPercent.value}%` }),
3021
3023
  class: "mint-number-input__slider",
3022
3024
  onInput: handleSliderInput
3023
- }, null, 44, _hoisted_7$5)) : createCommentVNode("", true)], 2);
3025
+ }, null, 44, _hoisted_7$7)) : createCommentVNode("", true)], 2);
3024
3026
  };
3025
3027
  }
3026
3028
  });
3027
3029
  //#endregion
3028
3030
  //#region src/components/FileUploader.vue?vue&type=script&setup=true&lang.ts
3029
- var _hoisted_1$6 = { class: "mint-file-uploader" };
3030
- var _hoisted_2$5 = [
3031
+ var _hoisted_1$9 = { class: "mint-file-uploader" };
3032
+ var _hoisted_2$8 = [
3031
3033
  "aria-label",
3032
3034
  "aria-disabled",
3033
3035
  "onKeydown"
3034
3036
  ];
3035
- var _hoisted_3$5 = [
3037
+ var _hoisted_3$7 = [
3036
3038
  "accept",
3037
3039
  "multiple",
3038
3040
  "disabled",
3039
3041
  "webkitdirectory"
3040
3042
  ];
3041
- var _hoisted_4$5 = { class: "mint-file-uploader__content" };
3042
- var _hoisted_5$4 = {
3043
+ var _hoisted_4$7 = { class: "mint-file-uploader__content" };
3044
+ var _hoisted_5$6 = {
3043
3045
  key: 0,
3044
3046
  class: "mint-file-uploader__icon",
3045
3047
  fill: "none",
@@ -3049,7 +3051,7 @@ var _hoisted_5$4 = {
3049
3051
  "stroke-linejoin": "round",
3050
3052
  viewBox: "0 0 24 24"
3051
3053
  };
3052
- var _hoisted_6$4 = {
3054
+ var _hoisted_6$6 = {
3053
3055
  key: 1,
3054
3056
  class: "mint-file-uploader__icon",
3055
3057
  fill: "none",
@@ -3059,22 +3061,22 @@ var _hoisted_6$4 = {
3059
3061
  "stroke-linejoin": "round",
3060
3062
  viewBox: "0 0 24 24"
3061
3063
  };
3062
- var _hoisted_7$4 = { class: "mint-file-uploader__text" };
3063
- var _hoisted_8$4 = {
3064
+ var _hoisted_7$6 = { class: "mint-file-uploader__text" };
3065
+ var _hoisted_8$6 = {
3064
3066
  key: 0,
3065
3067
  class: "mint-file-uploader__actions"
3066
3068
  };
3067
- var _hoisted_9$2 = {
3069
+ var _hoisted_9$3 = {
3068
3070
  key: 1,
3069
3071
  class: "mint-file-uploader__folder-summary"
3070
3072
  };
3071
- var _hoisted_10$2 = { class: "mint-file-uploader__folder-info" };
3072
- var _hoisted_11$2 = { class: "mint-file-uploader__folder-details" };
3073
- var _hoisted_12$2 = { class: "mint-file-uploader__folder-name" };
3074
- var _hoisted_13$1 = { class: "mint-file-uploader__folder-count" };
3075
- var _hoisted_14$1 = { class: "mint-file-uploader__file-info" };
3076
- var _hoisted_15$1 = { class: "mint-file-uploader__file-meta" };
3077
- var _hoisted_16$1 = { class: "mint-file-uploader__file-name" };
3073
+ var _hoisted_10$3 = { class: "mint-file-uploader__folder-info" };
3074
+ var _hoisted_11$3 = { class: "mint-file-uploader__folder-details" };
3075
+ var _hoisted_12$3 = { class: "mint-file-uploader__folder-name" };
3076
+ var _hoisted_13$2 = { class: "mint-file-uploader__folder-count" };
3077
+ var _hoisted_14$2 = { class: "mint-file-uploader__file-info" };
3078
+ var _hoisted_15$2 = { class: "mint-file-uploader__file-meta" };
3079
+ var _hoisted_16$2 = { class: "mint-file-uploader__file-name" };
3078
3080
  var _hoisted_17$1 = { class: "mint-file-uploader__file-size" };
3079
3081
  var _hoisted_18$1 = ["aria-label", "onClick"];
3080
3082
  //#endregion
@@ -3095,7 +3097,11 @@ var FileUploader_default = /* @__PURE__ */ defineComponent({
3095
3097
  size: { default: "md" },
3096
3098
  mode: { default: "file" }
3097
3099
  },
3098
- emits: ["upload", "error"],
3100
+ emits: [
3101
+ "upload",
3102
+ "remove",
3103
+ "error"
3104
+ ],
3099
3105
  setup(__props, { emit: __emit }) {
3100
3106
  /** Drag-and-drop file upload zone with type filtering, size validation, and folder mode. */
3101
3107
  const props = __props;
@@ -3241,19 +3247,24 @@ var FileUploader_default = /* @__PURE__ */ defineComponent({
3241
3247
  }
3242
3248
  return validFiles;
3243
3249
  }
3244
- function handleFiles(files, folder) {
3250
+ function handleFiles(files, folder, explicitRelativePaths) {
3251
+ const candidates = Array.from(files);
3245
3252
  const validFiles = validateFiles(files);
3246
3253
  if (validFiles.length === 0) return;
3254
+ const relativePaths = validFiles.map((file) => {
3255
+ const candidateIndex = candidates.indexOf(file);
3256
+ return explicitRelativePaths?.[candidateIndex] || file.webkitRelativePath || (folder ? `${folder}/${file.name}` : file.name);
3257
+ });
3247
3258
  if (isFolder.value) {
3248
3259
  folderName.value = folder || extractFolderName(validFiles);
3249
3260
  selectedFiles.value = validFiles;
3250
- emit("upload", validFiles);
3261
+ emit("upload", validFiles, folderName.value ?? void 0, relativePaths);
3251
3262
  } else if (!props.multiple) {
3252
3263
  selectedFiles.value = [validFiles[0]];
3253
- emit("upload", [validFiles[0]]);
3264
+ emit("upload", [validFiles[0]], void 0, [relativePaths[0]]);
3254
3265
  } else {
3255
3266
  selectedFiles.value = [...selectedFiles.value, ...validFiles];
3256
- emit("upload", validFiles);
3267
+ emit("upload", validFiles, void 0, relativePaths);
3257
3268
  }
3258
3269
  }
3259
3270
  function extractFolderName(files) {
@@ -3271,20 +3282,24 @@ var FileUploader_default = /* @__PURE__ */ defineComponent({
3271
3282
  }
3272
3283
  async function handleFolderDrop(items) {
3273
3284
  const files = [];
3285
+ const relativePaths = [];
3274
3286
  let folderNameFromDrop;
3275
3287
  for (const item of Array.from(items)) {
3276
3288
  const entry = item.webkitGetAsEntry?.();
3277
3289
  if (entry?.isDirectory) {
3278
3290
  folderNameFromDrop = entry.name;
3279
- await readDirectory(entry, files);
3291
+ await readDirectory(entry, files, relativePaths, entry.name);
3280
3292
  } else if (entry?.isFile) {
3281
3293
  const file = await getFile(entry);
3282
- if (file) files.push(file);
3294
+ if (file) {
3295
+ files.push(file);
3296
+ relativePaths.push(file.name);
3297
+ }
3283
3298
  }
3284
3299
  }
3285
- if (files.length > 0) handleFiles(files, folderNameFromDrop);
3300
+ if (files.length > 0) handleFiles(files, folderNameFromDrop, relativePaths);
3286
3301
  }
3287
- async function readDirectory(directory, files) {
3302
+ async function readDirectory(directory, files, relativePaths, prefix) {
3288
3303
  const reader = directory.createReader();
3289
3304
  let batch;
3290
3305
  do {
@@ -3293,8 +3308,11 @@ var FileUploader_default = /* @__PURE__ */ defineComponent({
3293
3308
  });
3294
3309
  for (const entry of batch) if (entry.isFile) {
3295
3310
  const file = await getFile(entry);
3296
- if (file) files.push(file);
3297
- } else if (entry.isDirectory) await readDirectory(entry, files);
3311
+ if (file) {
3312
+ files.push(file);
3313
+ relativePaths.push(`${prefix}/${file.name}`);
3314
+ }
3315
+ } else if (entry.isDirectory) await readDirectory(entry, files, relativePaths, `${prefix}/${entry.name}`);
3298
3316
  } while (batch.length > 0);
3299
3317
  }
3300
3318
  function getFile(entry) {
@@ -3318,12 +3336,16 @@ var FileUploader_default = /* @__PURE__ */ defineComponent({
3318
3336
  if (!props.disabled) inputRef.value?.click();
3319
3337
  }
3320
3338
  function removeFile(index) {
3339
+ const removed = selectedFiles.value[index];
3321
3340
  selectedFiles.value = selectedFiles.value.filter((_, i) => i !== index);
3322
3341
  if (isFolder.value && selectedFiles.value.length === 0) folderName.value = null;
3342
+ if (removed) emit("remove", [removed]);
3323
3343
  }
3324
3344
  function clearAll() {
3345
+ const removed = [...selectedFiles.value];
3325
3346
  selectedFiles.value = [];
3326
3347
  folderName.value = null;
3348
+ if (removed.length) emit("remove", removed);
3327
3349
  }
3328
3350
  function formatFileSize(bytes) {
3329
3351
  if (bytes >= 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
@@ -3331,7 +3353,7 @@ var FileUploader_default = /* @__PURE__ */ defineComponent({
3331
3353
  return `${bytes} bytes`;
3332
3354
  }
3333
3355
  return (_ctx, _cache) => {
3334
- return openBlock(), createElementBlock("div", _hoisted_1$6, [
3356
+ return openBlock(), createElementBlock("div", _hoisted_1$9, [
3335
3357
  createElementVNode("div", {
3336
3358
  role: "button",
3337
3359
  tabindex: "0",
@@ -3359,13 +3381,13 @@ var FileUploader_default = /* @__PURE__ */ defineComponent({
3359
3381
  webkitdirectory: isFolder.value || void 0,
3360
3382
  class: "mint-file-uploader__input",
3361
3383
  onChange: handleInputChange
3362
- }, null, 40, _hoisted_3$5), createElementVNode("div", _hoisted_4$5, [isFolder.value ? (openBlock(), createElementBlock("svg", _hoisted_5$4, [..._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$4, [..._cache[1] || (_cache[1] = [
3384
+ }, null, 40, _hoisted_3$7), createElementVNode("div", _hoisted_4$7, [isFolder.value ? (openBlock(), createElementBlock("svg", _hoisted_5$6, [..._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$6, [..._cache[1] || (_cache[1] = [
3363
3385
  createElementVNode("path", { d: "M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" }, null, -1),
3364
3386
  createElementVNode("path", { d: "m16 16-4-4-4 4" }, null, -1),
3365
3387
  createElementVNode("path", { d: "M12 12v9" }, null, -1)
3366
- ])])), createElementVNode("p", _hoisted_7$4, " Drop " + toDisplayString(acceptLabel.value) + " or click ", 1)])], 42, _hoisted_2$5),
3367
- _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_8$4, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true),
3368
- isFolder.value && folderName.value && selectedFiles.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_9$2, [createElementVNode("div", _hoisted_10$2, [_cache[2] || (_cache[2] = createElementVNode("div", { class: "mint-file-uploader__folder-icon-wrapper" }, [createElementVNode("svg", {
3388
+ ])])), createElementVNode("p", _hoisted_7$6, " Drop " + toDisplayString(acceptLabel.value) + " or click ", 1)])], 42, _hoisted_2$8),
3389
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_8$6, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true),
3390
+ isFolder.value && folderName.value && selectedFiles.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_9$3, [createElementVNode("div", _hoisted_10$3, [_cache[2] || (_cache[2] = createElementVNode("div", { class: "mint-file-uploader__folder-icon-wrapper" }, [createElementVNode("svg", {
3369
3391
  class: "mint-file-uploader__folder-icon",
3370
3392
  fill: "none",
3371
3393
  stroke: "currentColor",
@@ -3373,7 +3395,7 @@ var FileUploader_default = /* @__PURE__ */ defineComponent({
3373
3395
  "stroke-linecap": "round",
3374
3396
  "stroke-linejoin": "round",
3375
3397
  viewBox: "0 0 24 24"
3376
- }, [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$2, [createElementVNode("span", _hoisted_12$2, toDisplayString(folderName.value), 1), createElementVNode("span", _hoisted_13$1, toDisplayString(selectedFiles.value.length) + " file" + toDisplayString(selectedFiles.value.length !== 1 ? "s" : ""), 1)])]), createElementVNode("button", {
3398
+ }, [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$3, [createElementVNode("span", _hoisted_12$3, toDisplayString(folderName.value), 1), createElementVNode("span", _hoisted_13$2, toDisplayString(selectedFiles.value.length) + " file" + toDisplayString(selectedFiles.value.length !== 1 ? "s" : ""), 1)])]), createElementVNode("button", {
3377
3399
  type: "button",
3378
3400
  "aria-label": "Clear folder",
3379
3401
  class: "mint-file-uploader__remove-btn",
@@ -3397,10 +3419,10 @@ var FileUploader_default = /* @__PURE__ */ defineComponent({
3397
3419
  return openBlock(), createElementBlock("li", {
3398
3420
  key: `${file.name}-${file.size}-${index}`,
3399
3421
  class: "mint-file-uploader__file"
3400
- }, [createElementVNode("div", _hoisted_14$1, [createElementVNode("span", {
3422
+ }, [createElementVNode("div", _hoisted_14$2, [createElementVNode("span", {
3401
3423
  class: "mint-file-uploader__file-badge",
3402
3424
  style: normalizeStyle({ "--badge-color": getFileType(file.name).color })
3403
- }, toDisplayString(getFileType(file.name).label), 5), createElementVNode("div", _hoisted_15$1, [createElementVNode("span", _hoisted_16$1, toDisplayString(file.name), 1), createElementVNode("span", _hoisted_17$1, toDisplayString(formatFileSize(file.size)), 1)])]), createElementVNode("button", {
3425
+ }, toDisplayString(getFileType(file.name).label), 5), createElementVNode("div", _hoisted_15$2, [createElementVNode("span", _hoisted_16$2, toDisplayString(file.name), 1), createElementVNode("span", _hoisted_17$1, toDisplayString(formatFileSize(file.size)), 1)])]), createElementVNode("button", {
3404
3426
  type: "button",
3405
3427
  "aria-label": `Remove ${file.name}`,
3406
3428
  class: "mint-file-uploader__remove-btn",
@@ -3422,25 +3444,152 @@ var FileUploader_default = /* @__PURE__ */ defineComponent({
3422
3444
  }
3423
3445
  });
3424
3446
  //#endregion
3447
+ //#region src/components/AlertBox.vue?vue&type=script&setup=true&lang.ts
3448
+ var _hoisted_1$8 = {
3449
+ key: 0,
3450
+ class: "mint-alert__icon mint-alert__icon--success",
3451
+ viewBox: "0 0 24 24",
3452
+ fill: "none",
3453
+ stroke: "currentColor",
3454
+ "stroke-width": "2",
3455
+ "stroke-linecap": "round",
3456
+ "stroke-linejoin": "round"
3457
+ };
3458
+ var _hoisted_2$7 = {
3459
+ key: 1,
3460
+ class: "mint-alert__icon mint-alert__icon--error",
3461
+ viewBox: "0 0 24 24",
3462
+ fill: "none",
3463
+ stroke: "currentColor",
3464
+ "stroke-width": "2",
3465
+ "stroke-linecap": "round",
3466
+ "stroke-linejoin": "round"
3467
+ };
3468
+ var _hoisted_3$6 = {
3469
+ key: 2,
3470
+ class: "mint-alert__icon mint-alert__icon--warning",
3471
+ viewBox: "0 0 24 24",
3472
+ fill: "none",
3473
+ stroke: "currentColor",
3474
+ "stroke-width": "2",
3475
+ "stroke-linecap": "round",
3476
+ "stroke-linejoin": "round"
3477
+ };
3478
+ var _hoisted_4$6 = {
3479
+ key: 3,
3480
+ class: "mint-alert__icon mint-alert__icon--info",
3481
+ viewBox: "0 0 24 24",
3482
+ fill: "none",
3483
+ stroke: "currentColor",
3484
+ "stroke-width": "2",
3485
+ "stroke-linecap": "round",
3486
+ "stroke-linejoin": "round"
3487
+ };
3488
+ var _hoisted_5$5 = { class: "mint-alert__content" };
3489
+ var _hoisted_6$5 = {
3490
+ key: 0,
3491
+ class: "mint-alert__title"
3492
+ };
3493
+ var _hoisted_7$5 = { class: "mint-alert__message" };
3494
+ var _hoisted_8$5 = {
3495
+ key: 4,
3496
+ class: "mint-alert__actions"
3497
+ };
3498
+ //#endregion
3499
+ //#region src/components/AlertBox.vue
3500
+ var AlertBox_default = /* @__PURE__ */ defineComponent({
3501
+ __name: "AlertBox",
3502
+ props: {
3503
+ type: { default: "info" },
3504
+ title: {},
3505
+ dismissible: {
3506
+ type: Boolean,
3507
+ default: false
3508
+ },
3509
+ actionLabel: {}
3510
+ },
3511
+ emits: ["dismiss", "action"],
3512
+ setup(__props, { emit: __emit }) {
3513
+ /** Inline alert banner with semantic icon, title, message slot, optional action button, and optional dismiss button. */
3514
+ const props = __props;
3515
+ const emit = __emit;
3516
+ const slots = useSlots();
3517
+ const hasActions = () => !!props.actionLabel || !!slots.actions;
3518
+ return (_ctx, _cache) => {
3519
+ return openBlock(), createElementBlock("div", {
3520
+ class: normalizeClass(["mint-alert", `mint-alert--${props.type}`]),
3521
+ role: "alert"
3522
+ }, [
3523
+ props.type === "success" ? (openBlock(), createElementBlock("svg", _hoisted_1$8, [..._cache[2] || (_cache[2] = [createElementVNode("circle", {
3524
+ cx: "12",
3525
+ cy: "12",
3526
+ r: "10"
3527
+ }, null, -1), createElementVNode("path", { d: "m9 12 2 2 4-4" }, null, -1)])])) : props.type === "error" ? (openBlock(), createElementBlock("svg", _hoisted_2$7, [..._cache[3] || (_cache[3] = [
3528
+ createElementVNode("circle", {
3529
+ cx: "12",
3530
+ cy: "12",
3531
+ r: "10"
3532
+ }, null, -1),
3533
+ createElementVNode("path", { d: "m15 9-6 6" }, null, -1),
3534
+ createElementVNode("path", { d: "m9 9 6 6" }, null, -1)
3535
+ ])])) : props.type === "warning" ? (openBlock(), createElementBlock("svg", _hoisted_3$6, [..._cache[4] || (_cache[4] = [
3536
+ createElementVNode("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }, null, -1),
3537
+ createElementVNode("path", { d: "M12 9v4" }, null, -1),
3538
+ createElementVNode("path", { d: "M12 17h.01" }, null, -1)
3539
+ ])])) : (openBlock(), createElementBlock("svg", _hoisted_4$6, [..._cache[5] || (_cache[5] = [
3540
+ createElementVNode("circle", {
3541
+ cx: "12",
3542
+ cy: "12",
3543
+ r: "10"
3544
+ }, null, -1),
3545
+ createElementVNode("path", { d: "M12 16v-4" }, null, -1),
3546
+ createElementVNode("path", { d: "M12 8h.01" }, null, -1)
3547
+ ])])),
3548
+ createElementVNode("div", _hoisted_5$5, [props.title ? (openBlock(), createElementBlock("h4", _hoisted_6$5, toDisplayString(props.title), 1)) : createCommentVNode("", true), createElementVNode("div", _hoisted_7$5, [renderSlot(_ctx.$slots, "default")])]),
3549
+ hasActions() ? (openBlock(), createElementBlock("div", _hoisted_8$5, [renderSlot(_ctx.$slots, "actions", {}, () => [createElementVNode("button", {
3550
+ type: "button",
3551
+ class: normalizeClass(["mint-alert__action-btn", `mint-alert__action-btn--${props.type}`]),
3552
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("action"))
3553
+ }, toDisplayString(props.actionLabel), 3)])])) : createCommentVNode("", true),
3554
+ props.dismissible ? (openBlock(), createElementBlock("button", {
3555
+ key: 5,
3556
+ type: "button",
3557
+ class: "mint-alert__dismiss",
3558
+ "aria-label": "Dismiss",
3559
+ onClick: _cache[1] || (_cache[1] = ($event) => emit("dismiss"))
3560
+ }, [..._cache[6] || (_cache[6] = [createElementVNode("svg", {
3561
+ class: "mint-alert__dismiss-icon",
3562
+ viewBox: "0 0 24 24",
3563
+ fill: "none",
3564
+ stroke: "currentColor",
3565
+ "stroke-width": "2",
3566
+ "stroke-linecap": "round",
3567
+ "stroke-linejoin": "round"
3568
+ }, [createElementVNode("path", { d: "M18 6 6 18" }), createElementVNode("path", { d: "m6 6 12 12" })], -1)])])) : createCommentVNode("", true)
3569
+ ], 2);
3570
+ };
3571
+ }
3572
+ });
3573
+ //#endregion
3425
3574
  //#region src/components/DateTimePicker.vue?vue&type=script&setup=true&lang.ts
3426
- var _hoisted_1$5 = { class: "mint-datetime-picker__input-wrapper" };
3427
- var _hoisted_2$4 = [
3575
+ var _hoisted_1$7 = { class: "mint-datetime-picker__input-wrapper" };
3576
+ var _hoisted_2$6 = [
3428
3577
  "value",
3429
3578
  "placeholder",
3430
3579
  "disabled"
3431
3580
  ];
3432
- var _hoisted_3$4 = {
3581
+ var _hoisted_3$5 = {
3433
3582
  key: 0,
3434
3583
  class: "mint-datetime-picker__dropdown",
3435
3584
  role: "dialog",
3436
3585
  "aria-modal": "true",
3437
3586
  "aria-label": "Date and time picker"
3438
3587
  };
3439
- var _hoisted_4$4 = { class: "mint-datetime-picker__calendar-section" };
3440
- var _hoisted_5$3 = { class: "mint-datetime-picker__time-section" };
3441
- var _hoisted_6$3 = { class: "mint-datetime-picker__time-grid" };
3442
- var _hoisted_7$3 = ["disabled", "onClick"];
3443
- var _hoisted_8$3 = { class: "mint-datetime-picker__footer" };
3588
+ var _hoisted_4$5 = { class: "mint-datetime-picker__calendar-section" };
3589
+ var _hoisted_5$4 = { class: "mint-datetime-picker__time-section" };
3590
+ var _hoisted_6$4 = { class: "mint-datetime-picker__time-grid" };
3591
+ var _hoisted_7$4 = ["disabled", "onClick"];
3592
+ var _hoisted_8$4 = { class: "mint-datetime-picker__footer" };
3444
3593
  //#endregion
3445
3594
  //#region src/components/DateTimePicker.vue
3446
3595
  var DateTimePicker_default = /* @__PURE__ */ defineComponent({
@@ -3561,7 +3710,7 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3561
3710
  ref_key: "rootRef",
3562
3711
  ref: rootRef,
3563
3712
  class: "mint-datetime-picker"
3564
- }, [createElementVNode("div", _hoisted_1$5, [
3713
+ }, [createElementVNode("div", _hoisted_1$7, [
3565
3714
  _cache[0] || (_cache[0] = createElementVNode("div", { class: "mint-datetime-picker__icon-calendar" }, [createElementVNode("svg", {
3566
3715
  fill: "none",
3567
3716
  stroke: "currentColor",
@@ -3586,7 +3735,7 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3586
3735
  ]),
3587
3736
  "aria-label": "Select date and time",
3588
3737
  onClick: toggleDropdown
3589
- }, null, 10, _hoisted_2$4),
3738
+ }, null, 10, _hoisted_2$6),
3590
3739
  _cache[1] || (_cache[1] = createElementVNode("div", { class: "mint-datetime-picker__icon-clock" }, [createElementVNode("svg", {
3591
3740
  fill: "none",
3592
3741
  stroke: "currentColor",
@@ -3605,8 +3754,8 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3605
3754
  "leave-from-class": "mint-datetime-picker__dropdown-leave-from",
3606
3755
  "leave-to-class": "mint-datetime-picker__dropdown-leave-to"
3607
3756
  }, {
3608
- default: withCtx(() => [unref(isOpen) ? (openBlock(), createElementBlock("div", _hoisted_3$4, [
3609
- createElementVNode("div", _hoisted_4$4, [createVNode(CalendarGridPanelInternal_default, {
3757
+ default: withCtx(() => [unref(isOpen) ? (openBlock(), createElementBlock("div", _hoisted_3$5, [
3758
+ createElementVNode("div", _hoisted_4$5, [createVNode(CalendarGridPanelInternal_default, {
3610
3759
  "week-days": unref(weekDays),
3611
3760
  "month-year": unref(monthYear),
3612
3761
  days: unref(calendarDays),
@@ -3625,7 +3774,7 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3625
3774
  "onNextMonth"
3626
3775
  ])]),
3627
3776
  _cache[3] || (_cache[3] = createElementVNode("div", { class: "mint-datetime-picker__divider" }, null, -1)),
3628
- createElementVNode("div", _hoisted_5$3, [_cache[2] || (_cache[2] = createElementVNode("div", { class: "mint-datetime-picker__time-label" }, "Time", -1)), createElementVNode("div", _hoisted_6$3, [(openBlock(true), createElementBlock(Fragment, null, renderList(timeSlots.value, (time) => {
3777
+ createElementVNode("div", _hoisted_5$4, [_cache[2] || (_cache[2] = createElementVNode("div", { class: "mint-datetime-picker__time-label" }, "Time", -1)), createElementVNode("div", _hoisted_6$4, [(openBlock(true), createElementBlock(Fragment, null, renderList(timeSlots.value, (time) => {
3629
3778
  return openBlock(), createElementBlock("button", {
3630
3779
  key: time,
3631
3780
  type: "button",
@@ -3636,9 +3785,9 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3636
3785
  isTimeDisabled(time) ? "mint-datetime-picker__time-chip--disabled" : ""
3637
3786
  ]),
3638
3787
  onClick: ($event) => selectTime(time)
3639
- }, toDisplayString(unref(formatTimeSlot)(time, __props.timeFormat)), 11, _hoisted_7$3);
3788
+ }, toDisplayString(unref(formatTimeSlot)(time, __props.timeFormat)), 11, _hoisted_7$4);
3640
3789
  }), 128))])]),
3641
- createElementVNode("div", _hoisted_8$3, [createElementVNode("div", null, [createElementVNode("button", {
3790
+ createElementVNode("div", _hoisted_8$4, [createElementVNode("div", null, [createElementVNode("button", {
3642
3791
  type: "button",
3643
3792
  class: "mint-datetime-picker__footer-btn",
3644
3793
  onClick: goToToday
@@ -3659,6 +3808,1562 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3659
3808
  }
3660
3809
  });
3661
3810
  //#endregion
3811
+ //#region src/jobs.ts
3812
+ var ACTIVE_JOB_STATUSES = new Set([
3813
+ "awaiting_input",
3814
+ "queued",
3815
+ "running"
3816
+ ]);
3817
+ var TERMINAL_JOB_STATUSES = new Set([
3818
+ "completed",
3819
+ "failed",
3820
+ "cancelled"
3821
+ ]);
3822
+ /** Resolve action support while retaining one-cycle legacy status inference. */
3823
+ function resolveJobCapabilities(job) {
3824
+ const legacyCanCancel = job.status === "queued" || job.status === "running";
3825
+ const legacyCanDelete = TERMINAL_JOB_STATUSES.has(job.status);
3826
+ return {
3827
+ can_cancel: typeof job.can_cancel === "boolean" ? job.can_cancel : legacyCanCancel,
3828
+ can_delete: typeof job.can_delete === "boolean" ? job.can_delete : legacyCanDelete
3829
+ };
3830
+ }
3831
+ /** Clamp invalid or out-of-range progress values for safe display. */
3832
+ function normalizeJobPercent(value) {
3833
+ if (!Number.isFinite(value)) return 0;
3834
+ return Math.min(100, Math.max(0, value));
3835
+ }
3836
+ /** Create a detached canonical state without changing the transport input. */
3837
+ function normalizeJobState(job) {
3838
+ const capabilities = resolveJobCapabilities(job);
3839
+ return {
3840
+ ...job,
3841
+ definition_id: job.definition_id ?? (typeof job.metadata.definition_id === "string" ? job.metadata.definition_id : null),
3842
+ result_status: job.result_status ?? (job.status === "completed" && job.metadata.has_result === true ? "available" : "none"),
3843
+ result_expires_at: job.result_expires_at ?? null,
3844
+ progress: {
3845
+ ...job.progress,
3846
+ percent: normalizeJobPercent(job.progress.percent)
3847
+ },
3848
+ warnings: [...job.warnings],
3849
+ folders: [...job.folders],
3850
+ metadata: { ...job.metadata },
3851
+ ...capabilities
3852
+ };
3853
+ }
3854
+ function isActiveJobStatus(status) {
3855
+ return ACTIVE_JOB_STATUSES.has(status);
3856
+ }
3857
+ function isTerminalJobStatus(status) {
3858
+ return TERMINAL_JOB_STATUSES.has(status);
3859
+ }
3860
+ function jobStatusLabel(status) {
3861
+ return {
3862
+ awaiting_input: "Waiting for input",
3863
+ queued: "Queued",
3864
+ running: "Running",
3865
+ completed: "Completed",
3866
+ failed: "Failed",
3867
+ cancelled: "Cancelled"
3868
+ }[status];
3869
+ }
3870
+ //#endregion
3871
+ //#region src/composables/useGeneratedAnalysis.ts
3872
+ var ACTIVE_STATUSES = new Set([
3873
+ "awaiting_input",
3874
+ "queued",
3875
+ "running"
3876
+ ]);
3877
+ var AUTH_TOKEN_KEY = "mint-auth-token";
3878
+ var SESSION_NOT_FOUND_DETAIL = "Session not found";
3879
+ var MAX_RESULT_CACHE_ENTRIES = 32;
3880
+ var MAX_RESULT_RETRIES = 3;
3881
+ var DOWNLOAD_URL_REFRESH_SKEW_MS = 3e4;
3882
+ var GeneratedAnalysisRequestError = class extends Error {
3883
+ constructor(status, detail) {
3884
+ super(typeof detail === "string" ? detail : `Request failed (${status})`);
3885
+ this.status = status;
3886
+ this.detail = detail;
3887
+ this.name = "GeneratedAnalysisRequestError";
3888
+ }
3889
+ };
3890
+ function createGeneratedAnalysisTransport(options = {}) {
3891
+ const fetcher = options.fetcher ?? globalThis.fetch.bind(globalThis);
3892
+ const getAccessToken = options.getAccessToken ?? readStoredAccessToken;
3893
+ return async (input, init = {}) => {
3894
+ const headers = new Headers(init.headers);
3895
+ const accessToken = getAccessToken();
3896
+ if (accessToken && !headers.has("Authorization")) headers.set("Authorization", `Bearer ${accessToken}`);
3897
+ return await fetcher(input, {
3898
+ credentials: "same-origin",
3899
+ ...init,
3900
+ headers
3901
+ });
3902
+ };
3903
+ }
3904
+ function useGeneratedAnalysis(options) {
3905
+ return createPluginJobs(options, "/generated/manifest");
3906
+ }
3907
+ function usePluginJobs(options) {
3908
+ return createPluginJobs(options);
3909
+ }
3910
+ function createPluginJobs(options, manifestPath) {
3911
+ const baseUrl = options.baseUrl.replace(/\/$/, "");
3912
+ const transport = options.transport ?? createGeneratedAnalysisTransport();
3913
+ const storage = createGeneratedSessionStorage(options.storage);
3914
+ const createId = options.createId ?? (() => globalThis.crypto.randomUUID());
3915
+ const pollInterval = options.pollInterval ?? 750;
3916
+ const streamEnabled = options.stream ?? true;
3917
+ const streamReconnectDelay = options.streamReconnectDelay ?? 1500;
3918
+ const tabKey = `mint:generated:${baseUrl}:tab`;
3919
+ const sessionKey = `mint:generated:${baseUrl}:session`;
3920
+ const manifest = shallowRef(null);
3921
+ const session = shallowRef(null);
3922
+ const jobs = shallowRef([]);
3923
+ const jobRevisions = /* @__PURE__ */ new Map();
3924
+ const pendingJobOperations = /* @__PURE__ */ new Map();
3925
+ const resultCache = shallowRef({});
3926
+ const isLoading = ref(false);
3927
+ const isSubmitting = ref(false);
3928
+ const error = shallowRef(null);
3929
+ const status = shallowRef("idle");
3930
+ let pollTimer;
3931
+ let streamReconnectTimer;
3932
+ let streamController;
3933
+ let streamConnected = false;
3934
+ let streamConnecting = false;
3935
+ let disposed = false;
3936
+ let paused = false;
3937
+ let initialized = false;
3938
+ let initializePromise;
3939
+ let refreshPromise;
3940
+ let initializeRefreshPromise;
3941
+ let jobsRevision = 0;
3942
+ let resultCacheOrder = [];
3943
+ const resultRequests = /* @__PURE__ */ new Map();
3944
+ const jobWaiters = /* @__PURE__ */ new Map();
3945
+ const resultRetryAttempts = /* @__PURE__ */ new Map();
3946
+ const resultRetryTimers = /* @__PURE__ */ new Map();
3947
+ const downloadRefreshTimers = /* @__PURE__ */ new Map();
3948
+ const latestResult = computed(() => {
3949
+ const job = currentCompletedJob();
3950
+ return job ? resultForJob(job.job_id) : null;
3951
+ });
3952
+ function initialize() {
3953
+ if (disposed) return Promise.reject(/* @__PURE__ */ new Error("Plugin jobs runtime is disposed"));
3954
+ if (initialized) return Promise.resolve();
3955
+ if (initializePromise) return initializePromise;
3956
+ isLoading.value = true;
3957
+ error.value = null;
3958
+ status.value = "initializing";
3959
+ const pending = (async () => {
3960
+ if (manifestPath) {
3961
+ const loadedManifest = await request(manifestPath, { method: "GET" });
3962
+ if (!disposed) manifest.value = loadedManifest;
3963
+ }
3964
+ const resolvedSession = await resolveSession();
3965
+ if (disposed) return;
3966
+ session.value = resolvedSession;
3967
+ await refreshJobs();
3968
+ if (disposed) return;
3969
+ initialized = true;
3970
+ status.value = paused ? "paused" : "ready";
3971
+ if (streamEnabled && !paused) connectJobStream();
3972
+ })().catch((cause) => {
3973
+ if (!disposed) {
3974
+ error.value = errorMessage(cause, "Failed to initialize generated analysis");
3975
+ status.value = "error";
3976
+ }
3977
+ throw cause;
3978
+ }).finally(() => {
3979
+ if (initializePromise === pending) initializePromise = void 0;
3980
+ if (!disposed) isLoading.value = false;
3981
+ });
3982
+ initializePromise = pending;
3983
+ return pending;
3984
+ }
3985
+ async function resolveSession() {
3986
+ let tabId = storage.getItem(tabKey);
3987
+ if (!tabId) {
3988
+ tabId = createId();
3989
+ storage.setItem(tabKey, tabId);
3990
+ }
3991
+ const storedSessionId = storage.getItem(sessionKey);
3992
+ const existing = (await request("/jobs/sessions", { method: "GET" })).sessions.find((candidate) => candidate.id === storedSessionId && candidate.tab_id === tabId);
3993
+ if (existing) return existing;
3994
+ const created = await request("/jobs/sessions", {
3995
+ method: "POST",
3996
+ body: JSON.stringify({ tab_id: tabId })
3997
+ });
3998
+ storage.setItem(sessionKey, created.id);
3999
+ return created;
4000
+ }
4001
+ async function submit(definitionId, inputs) {
4002
+ if (!session.value) throw new Error("Generated analysis session is not initialized");
4003
+ const clientRequestId = createId();
4004
+ isSubmitting.value = true;
4005
+ error.value = null;
4006
+ try {
4007
+ let jobInput;
4008
+ try {
4009
+ jobInput = await submitToSession(session.value.id, clientRequestId, await stagePathInputs(inputs, session.value.id, definitionId));
4010
+ } catch (cause) {
4011
+ if (!isSessionNotFoundError(cause)) throw cause;
4012
+ session.value = await resolveSession();
4013
+ jobInput = await submitToSession(session.value.id, clientRequestId, await stagePathInputs(inputs, session.value.id, definitionId));
4014
+ }
4015
+ const job = upsertJob(jobInput, definitionId);
4016
+ if (!streamConnected) schedulePoll();
4017
+ return job;
4018
+ } catch (cause) {
4019
+ error.value = errorMessage(cause, "Failed to submit analysis");
4020
+ throw cause;
4021
+ } finally {
4022
+ isSubmitting.value = false;
4023
+ }
4024
+ function submitToSession(sessionId, requestId, stagedInputs) {
4025
+ return request("/jobs", {
4026
+ method: "POST",
4027
+ body: JSON.stringify({
4028
+ definition_id: definitionId,
4029
+ inputs: stagedInputs,
4030
+ session_id: sessionId,
4031
+ client_request_id: requestId
4032
+ })
4033
+ });
4034
+ }
4035
+ }
4036
+ async function uploadPath(input, definitionId) {
4037
+ if (!session.value) throw new Error("Generated analysis session is not initialized");
4038
+ return uploadPathForSession(input, session.value.id, definitionId);
4039
+ }
4040
+ async function uploadStagedPart(input) {
4041
+ const jobId = jobIdFromReference(input.job);
4042
+ const body = new FormData();
4043
+ body.append("file", input.file);
4044
+ body.append("metadata", JSON.stringify(input.metadata));
4045
+ if (input.expectedSize !== void 0) body.append("expected_size", String(input.expectedSize));
4046
+ if (input.expectedSha256 !== void 0) body.append("expected_sha256", input.expectedSha256);
4047
+ return request(`/jobs/${encodeURIComponent(jobId)}/parts/${encodeStagedPartKey(input.key)}`, {
4048
+ method: "PUT",
4049
+ body,
4050
+ signal: input.signal
4051
+ });
4052
+ }
4053
+ function getJobStaging(job, pagination = {}) {
4054
+ const jobId = jobIdFromReference(job);
4055
+ const query = new URLSearchParams();
4056
+ if (pagination.offset !== void 0) query.set("offset", String(pagination.offset));
4057
+ if (pagination.limit !== void 0) query.set("limit", String(pagination.limit));
4058
+ const suffix = query.size > 0 ? `?${query}` : "";
4059
+ return request(`/jobs/${encodeURIComponent(jobId)}/staging${suffix}`, { method: "GET" });
4060
+ }
4061
+ async function sealJob(job) {
4062
+ const jobId = jobIdFromReference(job);
4063
+ const revision = beginJobOperation(jobId);
4064
+ try {
4065
+ return mergeJobResponse(await request(`/jobs/${encodeURIComponent(jobId)}/seal`, { method: "POST" }), revision);
4066
+ } finally {
4067
+ finishJobOperation(jobId);
4068
+ }
4069
+ }
4070
+ async function uploadPathForSession(input, sessionId, definitionId) {
4071
+ if (!input.files.length || input.files.length !== input.relativePaths.length) throw new Error("Path upload requires one relative path for each file");
4072
+ const body = new FormData();
4073
+ body.append("session_id", sessionId);
4074
+ if (input.rootName) body.append("root_name", input.rootName);
4075
+ for (let index = 0; index < input.files.length; index += 1) {
4076
+ body.append("files", input.files[index]);
4077
+ body.append("relative_paths", input.relativePaths[index]);
4078
+ }
4079
+ const headers = { "X-Mint-Job-Session": sessionId };
4080
+ if (definitionId) headers["X-Mint-Job-Definition"] = definitionId;
4081
+ return request("/jobs/uploads", {
4082
+ method: "POST",
4083
+ body,
4084
+ signal: input.signal,
4085
+ headers
4086
+ });
4087
+ }
4088
+ async function stagePathInputs(inputs, sessionId, definitionId) {
4089
+ return await stagePathValue(inputs, sessionId, definitionId);
4090
+ }
4091
+ async function stagePathValue(value, sessionId, definitionId) {
4092
+ if (typeof File !== "undefined" && value instanceof File) return { token: (await uploadPathForSession({
4093
+ kind: "path",
4094
+ files: [value],
4095
+ relativePaths: [value.name]
4096
+ }, sessionId, definitionId)).token };
4097
+ if (isPluginJobPathInput(value)) return { token: (await uploadPathForSession(value, sessionId, definitionId)).token };
4098
+ if (Array.isArray(value)) return await Promise.all(value.map((item) => stagePathValue(item, sessionId, definitionId)));
4099
+ if (value && typeof value === "object") {
4100
+ const entries = await Promise.all(Object.entries(value).map(async ([key, child]) => [key, await stagePathValue(child, sessionId, definitionId)]));
4101
+ return Object.fromEntries(entries);
4102
+ }
4103
+ return value;
4104
+ }
4105
+ function refreshJobs() {
4106
+ if (disposed) return Promise.resolve(jobs.value);
4107
+ if (refreshPromise) return refreshPromise;
4108
+ const revision = jobsRevision;
4109
+ const pending = request("/jobs", { method: "GET" }).then((payload) => {
4110
+ if (disposed || revision !== jobsRevision) return jobs.value;
4111
+ replaceJobs(payload.jobs);
4112
+ error.value = null;
4113
+ if (!paused && !streamConnected && jobs.value.some((job) => ACTIVE_STATUSES.has(job.status))) schedulePoll();
4114
+ return jobs.value;
4115
+ }).finally(() => {
4116
+ if (refreshPromise === pending) refreshPromise = void 0;
4117
+ });
4118
+ refreshPromise = pending;
4119
+ return pending;
4120
+ }
4121
+ function refresh() {
4122
+ if (disposed) return Promise.resolve(jobs.value);
4123
+ if (initialized) return refreshJobs();
4124
+ if (initializeRefreshPromise) return initializeRefreshPromise;
4125
+ const pending = initialize().then(() => jobs.value).finally(() => {
4126
+ if (initializeRefreshPromise === pending) initializeRefreshPromise = void 0;
4127
+ });
4128
+ initializeRefreshPromise = pending;
4129
+ return pending;
4130
+ }
4131
+ async function getJob(jobId, options = {}) {
4132
+ const revision = beginJobOperation(jobId);
4133
+ try {
4134
+ return mergeJobResponse(await request(`/jobs/${encodeURIComponent(jobId)}`, {
4135
+ method: "GET",
4136
+ signal: options.signal
4137
+ }), revision);
4138
+ } finally {
4139
+ finishJobOperation(jobId);
4140
+ }
4141
+ }
4142
+ function waitForJob(job, options = {}) {
4143
+ if (disposed) return Promise.reject(/* @__PURE__ */ new Error("Plugin jobs runtime is disposed"));
4144
+ if (options.signal?.aborted) return Promise.reject(pluginJobWaitAbort(options.signal));
4145
+ const jobId = jobIdFromReference(job);
4146
+ const current = typeof job === "string" ? jobs.value.find((candidate) => candidate.job_id === jobId) : jobs.value.find((candidate) => candidate.job_id === jobId) ?? job;
4147
+ if (current && !ACTIVE_STATUSES.has(current.status)) return terminalWaitResult(current, options.rejectOnFailure === true);
4148
+ if (paused) return Promise.reject(/* @__PURE__ */ new Error("Plugin jobs runtime is paused"));
4149
+ return new Promise((resolve, reject) => {
4150
+ const waiter = {
4151
+ resolve,
4152
+ reject,
4153
+ rejectOnFailure: options.rejectOnFailure === true,
4154
+ signal: options.signal
4155
+ };
4156
+ if (options.signal) {
4157
+ waiter.abort = () => {
4158
+ removeJobWaiter(jobId, waiter);
4159
+ reject(pluginJobWaitAbort(options.signal));
4160
+ };
4161
+ options.signal.addEventListener("abort", waiter.abort, { once: true });
4162
+ }
4163
+ const waiting = jobWaiters.get(jobId) ?? /* @__PURE__ */ new Set();
4164
+ waiting.add(waiter);
4165
+ jobWaiters.set(jobId, waiting);
4166
+ if (!paused) {
4167
+ if (streamEnabled) connectJobStream();
4168
+ if (!streamConnected) schedulePoll();
4169
+ }
4170
+ getJob(jobId, { signal: options.signal }).catch((cause) => {
4171
+ if (current && isRetryableJobLookupError(cause)) {
4172
+ if (!streamConnected) schedulePoll();
4173
+ return;
4174
+ }
4175
+ removeJobWaiter(jobId, waiter);
4176
+ reject(cause);
4177
+ });
4178
+ });
4179
+ }
4180
+ function settleJobWaiters(job) {
4181
+ if (ACTIVE_STATUSES.has(job.status)) return;
4182
+ const waiting = jobWaiters.get(job.job_id);
4183
+ if (!waiting) return;
4184
+ jobWaiters.delete(job.job_id);
4185
+ for (const waiter of waiting) {
4186
+ if (waiter.abort && waiter.signal) waiter.signal.removeEventListener("abort", waiter.abort);
4187
+ terminalWaitResult(job, waiter.rejectOnFailure).then(waiter.resolve, waiter.reject);
4188
+ }
4189
+ }
4190
+ function rejectJobWaiters(jobId, cause) {
4191
+ const waiting = jobWaiters.get(jobId);
4192
+ if (!waiting) return;
4193
+ jobWaiters.delete(jobId);
4194
+ for (const waiter of waiting) {
4195
+ if (waiter.abort && waiter.signal) waiter.signal.removeEventListener("abort", waiter.abort);
4196
+ waiter.reject(cause);
4197
+ }
4198
+ }
4199
+ function removeJobWaiter(jobId, waiter) {
4200
+ const waiting = jobWaiters.get(jobId);
4201
+ if (!waiting) return;
4202
+ waiting.delete(waiter);
4203
+ if (waiting.size === 0) jobWaiters.delete(jobId);
4204
+ if (waiter.abort && waiter.signal) waiter.signal.removeEventListener("abort", waiter.abort);
4205
+ }
4206
+ function jobsFor(definitionId) {
4207
+ return jobs.value.filter((job) => job.definition_id === definitionId);
4208
+ }
4209
+ function canonicalJob(input, fallbackDefinitionId) {
4210
+ const normalized = normalizeJobState(input);
4211
+ const definitionId = normalized.definition_id ?? fallbackDefinitionId ?? null;
4212
+ return {
4213
+ ...normalized,
4214
+ definition_id: definitionId,
4215
+ metadata: definitionId ? {
4216
+ ...normalized.metadata,
4217
+ definition_id: definitionId
4218
+ } : normalized.metadata
4219
+ };
4220
+ }
4221
+ function recordJobsMutation(jobIds) {
4222
+ jobsRevision += 1;
4223
+ for (const jobId of jobIds) jobRevisions.set(jobId, (jobRevisions.get(jobId) ?? 0) + 1);
4224
+ }
4225
+ function beginJobOperation(jobId) {
4226
+ pendingJobOperations.set(jobId, (pendingJobOperations.get(jobId) ?? 0) + 1);
4227
+ return jobRevisions.get(jobId) ?? 0;
4228
+ }
4229
+ function finishJobOperation(jobId) {
4230
+ const remaining = (pendingJobOperations.get(jobId) ?? 1) - 1;
4231
+ if (remaining > 0) pendingJobOperations.set(jobId, remaining);
4232
+ else pendingJobOperations.delete(jobId);
4233
+ pruneJobRevisions();
4234
+ }
4235
+ function pruneJobRevisions() {
4236
+ const retained = new Set([...jobs.value.map((job) => job.job_id), ...pendingJobOperations.keys()]);
4237
+ for (const jobId of jobRevisions.keys()) if (!retained.has(jobId)) jobRevisions.delete(jobId);
4238
+ }
4239
+ function replaceJobs(inputs) {
4240
+ const previousJobs = new Map(jobs.value.map((job) => [job.job_id, job]));
4241
+ const previousJobIds = new Set(jobs.value.map((job) => job.job_id));
4242
+ const nextJobs = inputs.map((input) => {
4243
+ const incoming = canonicalJob(input);
4244
+ const current = previousJobs.get(incoming.job_id);
4245
+ return current && shouldPreserveJobLifecycle(current, incoming) ? current : incoming;
4246
+ });
4247
+ const nextJobIds = new Set(nextJobs.map((job) => job.job_id));
4248
+ recordJobsMutation(new Set([...previousJobIds, ...nextJobIds]));
4249
+ jobs.value = nextJobs;
4250
+ for (const job of nextJobs) settleJobWaiters(job);
4251
+ for (const jobId of previousJobIds) if (!nextJobIds.has(jobId)) rejectJobWaiters(jobId, /* @__PURE__ */ new Error(`Job ${jobId} is no longer available`));
4252
+ pruneResultState();
4253
+ pruneJobRevisions();
4254
+ return nextJobs;
4255
+ }
4256
+ function upsertJob(input, fallbackDefinitionId) {
4257
+ const incoming = canonicalJob(input, fallbackDefinitionId);
4258
+ const current = jobs.value.find((candidate) => candidate.job_id === incoming.job_id);
4259
+ const job = current && shouldPreserveJobLifecycle(current, incoming) ? current : incoming;
4260
+ if (job === current) {
4261
+ settleJobWaiters(job);
4262
+ pruneResultState();
4263
+ pruneJobRevisions();
4264
+ return job;
4265
+ }
4266
+ jobs.value = [job, ...jobs.value.filter((candidate) => candidate.job_id !== job.job_id)];
4267
+ recordJobsMutation([job.job_id]);
4268
+ settleJobWaiters(job);
4269
+ pruneResultState();
4270
+ pruneJobRevisions();
4271
+ return job;
4272
+ }
4273
+ function mergeJobResponse(input, expectedRevision) {
4274
+ const incoming = canonicalJob(input);
4275
+ const current = jobs.value.find((candidate) => candidate.job_id === incoming.job_id);
4276
+ if (disposed) return current ?? incoming;
4277
+ if (current && shouldPreserveJobLifecycle(current, incoming)) return current;
4278
+ if (expectedRevision === (jobRevisions.get(incoming.job_id) ?? 0)) return upsertJob(incoming);
4279
+ if (current && jobLifecycleRank(incoming.status) > jobLifecycleRank(current.status)) return upsertJob(incoming);
4280
+ return current ?? incoming;
4281
+ }
4282
+ function currentCompletedJob() {
4283
+ const activeSessionId = session.value?.id;
4284
+ return jobs.value.find((candidate) => candidate.session_id === activeSessionId && candidate.status === "completed" && candidate.result_status === "available");
4285
+ }
4286
+ function resultForJob(jobId) {
4287
+ return resultCache.value[jobId] ?? null;
4288
+ }
4289
+ function loadResult(job) {
4290
+ return loadResultInternal(job);
4291
+ }
4292
+ function loadResultInternal(job, forceRefresh = false) {
4293
+ if (disposed || !isLoadableResultJob(job)) return Promise.resolve(null);
4294
+ const cached = resultForJob(job.job_id);
4295
+ if (cached && !forceRefresh && !managedDownloadNeedsRefresh(cached)) return Promise.resolve(cached);
4296
+ const pending = resultRequests.get(job.job_id);
4297
+ if (pending) return pending;
4298
+ const requestResult = request(`/jobs/${encodeURIComponent(job.job_id)}/result`, { method: "GET" }).then((result) => {
4299
+ if (!disposed && isCurrentResultJob(job.job_id)) {
4300
+ cacheResult(job.job_id, result);
4301
+ clearResultRetry(job.job_id);
4302
+ error.value = null;
4303
+ }
4304
+ return result;
4305
+ }).catch((cause) => {
4306
+ if (!disposed && isCurrentResultJob(job.job_id)) {
4307
+ error.value = errorMessage(cause, "Failed to load analysis result");
4308
+ if (cached && isManagedDownloadResult(cached)) handleManagedDownloadRefreshFailure(job, cause);
4309
+ else scheduleResultRetry(job, cause);
4310
+ }
4311
+ return null;
4312
+ }).finally(() => {
4313
+ resultRequests.delete(job.job_id);
4314
+ });
4315
+ resultRequests.set(job.job_id, requestResult);
4316
+ return requestResult;
4317
+ }
4318
+ function cacheResult(jobId, result) {
4319
+ resultCacheOrder = [jobId, ...resultCacheOrder.filter((candidate) => candidate !== jobId)].slice(0, MAX_RESULT_CACHE_ENTRIES);
4320
+ const retained = new Set(resultCacheOrder);
4321
+ resultCache.value = Object.fromEntries([...Object.entries(resultCache.value).filter(([candidate]) => retained.has(candidate) && candidate !== jobId), [jobId, result]]);
4322
+ for (const candidate of downloadRefreshTimers.keys()) if (!retained.has(candidate)) clearManagedDownloadRefresh(candidate);
4323
+ scheduleManagedDownloadRefresh(jobId, managedDownloadRefreshDelay(result));
4324
+ }
4325
+ function pruneResultState() {
4326
+ const loadableJobIds = new Set(jobs.value.filter((job) => isLoadableResultJob(job)).map((job) => job.job_id));
4327
+ resultCacheOrder = resultCacheOrder.filter((jobId) => loadableJobIds.has(jobId)).slice(0, MAX_RESULT_CACHE_ENTRIES);
4328
+ const retained = new Set(resultCacheOrder);
4329
+ resultCache.value = Object.fromEntries(Object.entries(resultCache.value).filter(([jobId]) => retained.has(jobId)));
4330
+ for (const jobId of resultRetryTimers.keys()) if (!loadableJobIds.has(jobId)) clearResultRetry(jobId);
4331
+ for (const jobId of resultRetryAttempts.keys()) if (!loadableJobIds.has(jobId)) clearResultRetry(jobId);
4332
+ for (const jobId of downloadRefreshTimers.keys()) if (!loadableJobIds.has(jobId) || !retained.has(jobId)) clearManagedDownloadRefresh(jobId);
4333
+ }
4334
+ function scheduleManagedDownloadRefresh(jobId, delay) {
4335
+ clearManagedDownloadRefresh(jobId);
4336
+ if (delay === null || disposed || paused) return;
4337
+ downloadRefreshTimers.set(jobId, setTimeout(() => {
4338
+ downloadRefreshTimers.delete(jobId);
4339
+ if (disposed || paused) return;
4340
+ const current = jobs.value.find((candidate) => candidate.job_id === jobId);
4341
+ if (current && isLoadableResultJob(current)) loadResultInternal(current, true);
4342
+ }, Math.max(0, delay)));
4343
+ }
4344
+ function clearManagedDownloadRefresh(jobId) {
4345
+ const timer = downloadRefreshTimers.get(jobId);
4346
+ if (timer !== void 0) clearTimeout(timer);
4347
+ downloadRefreshTimers.delete(jobId);
4348
+ }
4349
+ function handleManagedDownloadRefreshFailure(job, cause) {
4350
+ if (cause instanceof GeneratedAnalysisRequestError) {
4351
+ if (cause.status === 404 || cause.status === 410) {
4352
+ discardCachedResult(job.job_id);
4353
+ jobs.value = jobs.value.map((candidate) => candidate.job_id === job.job_id ? {
4354
+ ...candidate,
4355
+ result_status: "expired"
4356
+ } : candidate);
4357
+ recordJobsMutation([job.job_id]);
4358
+ return;
4359
+ }
4360
+ if (cause.status === 401 || cause.status === 403) {
4361
+ discardCachedResult(job.job_id);
4362
+ return;
4363
+ }
4364
+ }
4365
+ scheduleResultRetry(job, cause, true);
4366
+ }
4367
+ function discardCachedResult(jobId) {
4368
+ clearResultRetry(jobId);
4369
+ clearManagedDownloadRefresh(jobId);
4370
+ resultCacheOrder = resultCacheOrder.filter((candidate) => candidate !== jobId);
4371
+ const retainedResults = { ...resultCache.value };
4372
+ delete retainedResults[jobId];
4373
+ resultCache.value = retainedResults;
4374
+ }
4375
+ function isLoadableResultJob(job) {
4376
+ return job.status === "completed" && job.result_status === "available";
4377
+ }
4378
+ function isCurrentResultJob(jobId) {
4379
+ const job = jobs.value.find((candidate) => candidate.job_id === jobId);
4380
+ return job !== void 0 && isLoadableResultJob(job);
4381
+ }
4382
+ function scheduleResultRetry(job, cause, forceRefresh = false) {
4383
+ if (paused || !isRetryableResultError(cause) || resultRetryTimers.has(job.job_id)) return;
4384
+ const attempt = resultRetryAttempts.get(job.job_id) ?? 0;
4385
+ if (attempt >= MAX_RESULT_RETRIES) return;
4386
+ resultRetryAttempts.set(job.job_id, attempt + 1);
4387
+ resultRetryTimers.set(job.job_id, setTimeout(() => {
4388
+ resultRetryTimers.delete(job.job_id);
4389
+ const current = jobs.value.find((candidate) => candidate.job_id === job.job_id);
4390
+ if (!paused && current && isLoadableResultJob(current)) loadResultInternal(current, forceRefresh);
4391
+ }, pollInterval * 2 ** attempt));
4392
+ }
4393
+ function clearResultRetry(jobId) {
4394
+ const timer = resultRetryTimers.get(jobId);
4395
+ if (timer !== void 0) clearTimeout(timer);
4396
+ resultRetryTimers.delete(jobId);
4397
+ resultRetryAttempts.delete(jobId);
4398
+ }
4399
+ function schedulePoll() {
4400
+ if (disposed || paused || streamConnected || pollTimer !== void 0) return;
4401
+ pollTimer = setTimeout(async () => {
4402
+ pollTimer = void 0;
4403
+ if (disposed) return;
4404
+ try {
4405
+ await refreshJobs();
4406
+ } catch (cause) {
4407
+ error.value = errorMessage(cause, "Failed to refresh analysis jobs");
4408
+ if (jobs.value.some((job) => ACTIVE_STATUSES.has(job.status))) schedulePoll();
4409
+ }
4410
+ }, pollInterval);
4411
+ }
4412
+ async function connectJobStream() {
4413
+ if (disposed || paused || streamConnecting || streamConnected) return;
4414
+ streamConnecting = true;
4415
+ streamController = new AbortController();
4416
+ try {
4417
+ const response = await transport(`${baseUrl}/jobs/events`, {
4418
+ method: "GET",
4419
+ headers: { Accept: "text/event-stream" },
4420
+ signal: streamController.signal
4421
+ });
4422
+ if (!response.ok) throw new Error(`Job stream failed (${response.status})`);
4423
+ if (!response.body) throw new Error("Job stream response has no readable body");
4424
+ streamConnected = true;
4425
+ if (pollTimer !== void 0) {
4426
+ clearTimeout(pollTimer);
4427
+ pollTimer = void 0;
4428
+ }
4429
+ await consumeJobStream(response.body);
4430
+ } catch (cause) {
4431
+ if (!isAbortError(cause) && !disposed) {
4432
+ if (jobs.value.some((job) => ACTIVE_STATUSES.has(job.status))) schedulePoll();
4433
+ }
4434
+ } finally {
4435
+ streamConnected = false;
4436
+ streamConnecting = false;
4437
+ streamController = void 0;
4438
+ if (!disposed && !paused) scheduleStreamReconnect();
4439
+ }
4440
+ }
4441
+ async function consumeJobStream(body) {
4442
+ const reader = body.getReader();
4443
+ const decoder = new TextDecoder();
4444
+ let buffer = "";
4445
+ try {
4446
+ while (!disposed) {
4447
+ const { done, value } = await reader.read();
4448
+ buffer += decoder.decode(value, { stream: !done });
4449
+ const blocks = buffer.split(/\r?\n\r?\n/);
4450
+ buffer = blocks.pop() ?? "";
4451
+ for (const block of blocks) applyJobStreamEvent(block);
4452
+ if (done) {
4453
+ if (buffer.trim()) applyJobStreamEvent(buffer);
4454
+ return;
4455
+ }
4456
+ }
4457
+ } finally {
4458
+ reader.releaseLock();
4459
+ }
4460
+ }
4461
+ function applyJobStreamEvent(block) {
4462
+ let event = "message";
4463
+ const data = [];
4464
+ for (const line of block.split(/\r?\n/)) {
4465
+ if (!line || line.startsWith(":")) continue;
4466
+ if (line.startsWith("event:")) event = line.slice(6).trim();
4467
+ if (line.startsWith("data:")) data.push(line.slice(5).trimStart());
4468
+ }
4469
+ if (!data.length) return;
4470
+ const payload = JSON.parse(data.join("\n"));
4471
+ if (event === "snapshot" && "jobs" in payload) replaceJobs(payload.jobs);
4472
+ else if (event === "job" || event === "terminal") upsertJob(payload);
4473
+ error.value = null;
4474
+ }
4475
+ function scheduleStreamReconnect() {
4476
+ if (disposed || paused || streamReconnectTimer !== void 0) return;
4477
+ streamReconnectTimer = setTimeout(() => {
4478
+ streamReconnectTimer = void 0;
4479
+ connectJobStream();
4480
+ }, streamReconnectDelay);
4481
+ }
4482
+ async function cancelJob(job) {
4483
+ const jobId = typeof job === "string" ? job : job.job_id;
4484
+ const revision = beginJobOperation(jobId);
4485
+ try {
4486
+ return mergeJobResponse(await request(`/jobs/${encodeURIComponent(jobId)}/cancel`, { method: "POST" }), revision);
4487
+ } finally {
4488
+ finishJobOperation(jobId);
4489
+ }
4490
+ }
4491
+ async function deleteJob(job) {
4492
+ const jobId = typeof job === "string" ? job : job.job_id;
4493
+ await request(`/jobs/${encodeURIComponent(jobId)}`, { method: "DELETE" });
4494
+ jobs.value = jobs.value.filter((candidate) => candidate.job_id !== jobId);
4495
+ recordJobsMutation([jobId]);
4496
+ rejectJobWaiters(jobId, /* @__PURE__ */ new Error(`Job ${jobId} was deleted`));
4497
+ discardCachedResult(jobId);
4498
+ pruneJobRevisions();
4499
+ return true;
4500
+ }
4501
+ async function clearFinishedJobs(definitionId) {
4502
+ const payload = await request(`/jobs${definitionId === void 0 ? "" : `?definition_id=${encodeURIComponent(definitionId)}`}`, { method: "DELETE" });
4503
+ if (payload.deleted > 0) await refreshJobs();
4504
+ return payload.deleted;
4505
+ }
4506
+ const jobsAdapter = {
4507
+ listJobs: async () => ({ jobs: await refreshJobs() }),
4508
+ cancelJob: async (job) => cancelJob(job),
4509
+ deleteJob: async (job) => deleteJob(job),
4510
+ clearFinishedJobs: async () => clearFinishedJobs()
4511
+ };
4512
+ function pause() {
4513
+ if (disposed || paused) return;
4514
+ paused = true;
4515
+ status.value = "paused";
4516
+ if (pollTimer !== void 0) clearTimeout(pollTimer);
4517
+ if (streamReconnectTimer !== void 0) clearTimeout(streamReconnectTimer);
4518
+ pollTimer = void 0;
4519
+ streamReconnectTimer = void 0;
4520
+ for (const jobId of resultRetryTimers.keys()) clearResultRetry(jobId);
4521
+ for (const jobId of downloadRefreshTimers.keys()) clearManagedDownloadRefresh(jobId);
4522
+ streamController?.abort();
4523
+ }
4524
+ function resume() {
4525
+ if (disposed || !paused) return;
4526
+ paused = false;
4527
+ status.value = initialized ? "ready" : "idle";
4528
+ if (!initialized) return;
4529
+ for (const [jobId, result] of Object.entries(resultCache.value)) scheduleManagedDownloadRefresh(jobId, managedDownloadRefreshDelay(result));
4530
+ if (streamEnabled) connectJobStream();
4531
+ else if (jobs.value.some((job) => ACTIVE_STATUSES.has(job.status))) schedulePoll();
4532
+ }
4533
+ function dispose() {
4534
+ if (disposed) return;
4535
+ disposed = true;
4536
+ paused = true;
4537
+ status.value = "disposed";
4538
+ if (pollTimer !== void 0) clearTimeout(pollTimer);
4539
+ if (streamReconnectTimer !== void 0) clearTimeout(streamReconnectTimer);
4540
+ pollTimer = void 0;
4541
+ streamReconnectTimer = void 0;
4542
+ for (const timer of resultRetryTimers.values()) clearTimeout(timer);
4543
+ resultRetryTimers.clear();
4544
+ resultRetryAttempts.clear();
4545
+ for (const timer of downloadRefreshTimers.values()) clearTimeout(timer);
4546
+ downloadRefreshTimers.clear();
4547
+ const cause = /* @__PURE__ */ new Error("Plugin jobs runtime is disposed");
4548
+ for (const jobId of jobWaiters.keys()) rejectJobWaiters(jobId, cause);
4549
+ jobRevisions.clear();
4550
+ pendingJobOperations.clear();
4551
+ streamController?.abort();
4552
+ }
4553
+ async function request(path, init) {
4554
+ const response = await transport(`${baseUrl}${path}`, {
4555
+ ...init,
4556
+ headers: {
4557
+ Accept: "application/json",
4558
+ ...init.body && !(init.body instanceof FormData) ? { "Content-Type": "application/json" } : {},
4559
+ ...init.headers
4560
+ }
4561
+ });
4562
+ if (!response.ok) {
4563
+ const payload = await response.json().catch(() => null);
4564
+ throw new GeneratedAnalysisRequestError(response.status, payload?.detail);
4565
+ }
4566
+ return await response.json();
4567
+ }
4568
+ onScopeDispose(dispose);
4569
+ if (options.immediate) initialize().catch(() => void 0);
4570
+ return {
4571
+ manifest,
4572
+ session,
4573
+ jobs,
4574
+ latestResult,
4575
+ isLoading,
4576
+ isSubmitting,
4577
+ error,
4578
+ status,
4579
+ initialize,
4580
+ ready: initialize,
4581
+ uploadPath,
4582
+ uploadStagedPart,
4583
+ getJobStaging,
4584
+ sealJob,
4585
+ submit,
4586
+ loadResult,
4587
+ resultForJob,
4588
+ refreshJobs,
4589
+ refresh,
4590
+ getJob,
4591
+ waitForJob,
4592
+ jobsFor,
4593
+ cancelJob,
4594
+ deleteJob,
4595
+ clearFinishedJobs,
4596
+ pause,
4597
+ resume,
4598
+ dispose,
4599
+ jobsAdapter
4600
+ };
4601
+ }
4602
+ function jobIdFromReference(job) {
4603
+ return typeof job === "string" ? job : job.job_id;
4604
+ }
4605
+ function encodeStagedPartKey(key) {
4606
+ return key.split("/").map((segment) => encodeURIComponent(segment)).join("/");
4607
+ }
4608
+ function jobLifecycleRank(status) {
4609
+ if (status === "awaiting_input") return 0;
4610
+ if (status === "queued") return 1;
4611
+ if (status === "running") return 2;
4612
+ return 3;
4613
+ }
4614
+ function shouldPreserveJobLifecycle(current, incoming) {
4615
+ const currentRank = jobLifecycleRank(current.status);
4616
+ const incomingRank = jobLifecycleRank(incoming.status);
4617
+ return incomingRank < currentRank || currentRank === 3 && incomingRank === 3 && current.status !== incoming.status;
4618
+ }
4619
+ function terminalWaitResult(job, rejectOnFailure) {
4620
+ if (rejectOnFailure && (job.status === "failed" || job.status === "cancelled")) return Promise.reject(new Error(job.error ?? `Job ${job.job_id} ${job.status}`));
4621
+ return Promise.resolve(job);
4622
+ }
4623
+ function pluginJobWaitAbort(signal) {
4624
+ if (signal.reason !== void 0) return signal.reason;
4625
+ const cause = /* @__PURE__ */ new Error("Waiting for job was aborted");
4626
+ cause.name = "AbortError";
4627
+ return cause;
4628
+ }
4629
+ function isPluginJobPathInput(value) {
4630
+ return Boolean(value && typeof value === "object" && "kind" in value && value.kind === "path" && "files" in value && Array.isArray(value.files) && "relativePaths" in value && Array.isArray(value.relativePaths));
4631
+ }
4632
+ function readStoredAccessToken() {
4633
+ try {
4634
+ return globalThis.localStorage?.getItem(AUTH_TOKEN_KEY) ?? null;
4635
+ } catch {
4636
+ return null;
4637
+ }
4638
+ }
4639
+ function createGeneratedSessionStorage(candidate) {
4640
+ const fallback = /* @__PURE__ */ new Map();
4641
+ let delegate;
4642
+ let available = true;
4643
+ try {
4644
+ delegate = candidate ?? globalThis.sessionStorage;
4645
+ } catch {
4646
+ available = false;
4647
+ }
4648
+ return {
4649
+ getItem(key) {
4650
+ if (available && delegate) try {
4651
+ return delegate.getItem(key) ?? fallback.get(key) ?? null;
4652
+ } catch {
4653
+ available = false;
4654
+ }
4655
+ return fallback.get(key) ?? null;
4656
+ },
4657
+ setItem(key, value) {
4658
+ fallback.set(key, value);
4659
+ if (available && delegate) try {
4660
+ delegate.setItem(key, value);
4661
+ } catch {
4662
+ available = false;
4663
+ }
4664
+ }
4665
+ };
4666
+ }
4667
+ function isAbortError(error) {
4668
+ return error instanceof DOMException && error.name === "AbortError";
4669
+ }
4670
+ function isSessionNotFoundError(error) {
4671
+ return error instanceof GeneratedAnalysisRequestError && error.status === 404 && error.detail === SESSION_NOT_FOUND_DETAIL;
4672
+ }
4673
+ function isRetryableResultError(error) {
4674
+ return !(error instanceof GeneratedAnalysisRequestError) || error.status === 409 || error.status === 429 || error.status >= 500;
4675
+ }
4676
+ function isRetryableJobLookupError(error) {
4677
+ return !(error instanceof GeneratedAnalysisRequestError) || error.status === 408 || error.status === 429 || error.status >= 500;
4678
+ }
4679
+ function isManagedDownloadResult(result) {
4680
+ return result.kind === "artifact" && result.managed === true;
4681
+ }
4682
+ function managedDownloadNeedsRefresh(result) {
4683
+ if (!isManagedDownloadResult(result)) return false;
4684
+ if (!result.download_url || !result.download_expires_at) return true;
4685
+ const expiresAt = Date.parse(result.download_expires_at);
4686
+ return !Number.isFinite(expiresAt) || expiresAt <= Date.now() + DOWNLOAD_URL_REFRESH_SKEW_MS;
4687
+ }
4688
+ function managedDownloadRefreshDelay(result) {
4689
+ if (!isManagedDownloadResult(result)) return null;
4690
+ if (!result.download_url || !result.download_expires_at) return null;
4691
+ const expiresAt = Date.parse(result.download_expires_at);
4692
+ if (!Number.isFinite(expiresAt)) return null;
4693
+ const remaining = expiresAt - Date.now();
4694
+ return remaining <= DOWNLOAD_URL_REFRESH_SKEW_MS ? remaining : remaining - DOWNLOAD_URL_REFRESH_SKEW_MS;
4695
+ }
4696
+ function errorMessage(error, fallback) {
4697
+ return error instanceof Error ? error.message : fallback;
4698
+ }
4699
+ //#endregion
4700
+ //#region src/composables/platformContextHelpers.ts
4701
+ function getInjectedPlatformContext() {
4702
+ if (typeof window === "undefined") return void 0;
4703
+ return window.__MINT_PLATFORM__;
4704
+ }
4705
+ /** Return the platform's canonical plugin identity for the mounted frontend. */
4706
+ function resolveCurrentPluginId() {
4707
+ const pluginId = getInjectedPlatformContext()?.plugin?.id;
4708
+ return typeof pluginId === "string" && pluginId ? pluginId : void 0;
4709
+ }
4710
+ function getInjectedExperimentContext() {
4711
+ return getInjectedPlatformContext();
4712
+ }
4713
+ function currentExperimentFromContext(context = getInjectedExperimentContext()) {
4714
+ const candidate = context?.currentExperiment ?? context?.experiment;
4715
+ return candidate && typeof candidate === "object" ? candidate : void 0;
4716
+ }
4717
+ function currentExperimentIdFromContext(context = getInjectedExperimentContext()) {
4718
+ return parseExperimentId(context?.currentExperimentId ?? context?.experimentId ?? context?.currentExperiment ?? context?.experiment);
4719
+ }
4720
+ function currentExperimentIdFromUrl() {
4721
+ if (typeof window === "undefined") return void 0;
4722
+ const location = window.location;
4723
+ const params = new URLSearchParams(location?.search ?? "");
4724
+ return parseExperimentId(params.get("experimentId") ?? params.get("experiment_id")) ?? experimentIdFromPath(location?.pathname ?? "") ?? experimentIdFromPath((location?.hash ?? "").replace(/^#\/?/, "/"));
4725
+ }
4726
+ function resolveCurrentExperimentId(context = getInjectedExperimentContext()) {
4727
+ return currentExperimentIdFromContext(context) ?? currentExperimentIdFromUrl();
4728
+ }
4729
+ function parseExperimentId(value) {
4730
+ if (typeof value === "number" && Number.isFinite(value)) return value;
4731
+ if (typeof value === "string" && value.trim()) {
4732
+ const parsed = Number(value);
4733
+ return Number.isFinite(parsed) ? parsed : void 0;
4734
+ }
4735
+ if (value && typeof value === "object" && "id" in value) return parseExperimentId(value.id);
4736
+ }
4737
+ function experimentIdFromPath(path) {
4738
+ const segments = path.split("/").filter(Boolean);
4739
+ for (let index = 0; index < segments.length - 1; index += 1) {
4740
+ const segment = segments[index]?.toLowerCase();
4741
+ if (segment === "experiment" || segment === "experiments") return parseExperimentId(decodeURIComponent(segments[index + 1] ?? ""));
4742
+ }
4743
+ }
4744
+ //#endregion
4745
+ //#region src/composables/useAnalysisArtifacts.ts
4746
+ /** Lists and manages analysis artifacts through the user-facing platform API. */
4747
+ function useAnalysisArtifacts(options = {}) {
4748
+ const injectedContext = getInjectedPlatformContext();
4749
+ const api = useApi({ baseUrl: options.apiBaseUrl ?? injectedContext?.platformApiUrl });
4750
+ const currentExperimentId = computed(() => toValue(options.experimentId) ?? resolveCurrentExperimentId(injectedContext));
4751
+ const hasCurrentExperiment = computed(() => currentExperimentId.value !== void 0);
4752
+ const scopePluginId = computed(() => toValue(options.pluginId) ?? null);
4753
+ const request = useRequestSyncState("Analysis artifact request failed.");
4754
+ const fetchedArtifacts = ref([]);
4755
+ const selectedDetail = ref(null);
4756
+ const loadingCount = ref(0);
4757
+ const mutatingCount = ref(0);
4758
+ const isLoading = computed(() => loadingCount.value > 0);
4759
+ const isMutating = computed(() => mutatingCount.value > 0);
4760
+ const search = ref("");
4761
+ const statusFilter = ref("active");
4762
+ const pluginFilter = ref(null);
4763
+ const needsArchived = computed(() => Boolean(toValue(options.includeArchived)) || statusFilter.value !== "active");
4764
+ const artifacts = computed(() => scopePluginId.value ? fetchedArtifacts.value.filter((artifact) => artifact.plugin_id === scopePluginId.value) : fetchedArtifacts.value);
4765
+ const visibleArtifacts = computed(() => {
4766
+ const query = search.value.trim().toLowerCase();
4767
+ return artifacts.value.filter((artifact) => {
4768
+ if (statusFilter.value !== "all" && artifact.status !== statusFilter.value) return false;
4769
+ if (pluginFilter.value && artifact.plugin_id !== pluginFilter.value) return false;
4770
+ if (!query) return true;
4771
+ return artifact.display_name.toLowerCase().includes(query) || artifact.artifact_key.toLowerCase().includes(query);
4772
+ });
4773
+ });
4774
+ let listToken = 0;
4775
+ let detailToken = 0;
4776
+ const hasRequestedList = ref(false);
4777
+ function currentExperimentIdOrError(action) {
4778
+ const id = currentExperimentId.value;
4779
+ if (id === void 0) {
4780
+ request.setError(`No current experiment is selected for ${action}`);
4781
+ return;
4782
+ }
4783
+ return id;
4784
+ }
4785
+ function replaceArtifact(summary) {
4786
+ const index = fetchedArtifacts.value.findIndex((artifact) => artifact.id === summary.id);
4787
+ if (index >= 0) fetchedArtifacts.value.splice(index, 1, summary);
4788
+ }
4789
+ async function list() {
4790
+ const experimentId = currentExperimentIdOrError("listing analysis artifacts");
4791
+ if (experimentId === void 0) {
4792
+ fetchedArtifacts.value = [];
4793
+ return [];
4794
+ }
4795
+ const token = ++listToken;
4796
+ hasRequestedList.value = true;
4797
+ loadingCount.value += 1;
4798
+ request.clearError();
4799
+ try {
4800
+ const data = await api.get(`/experiments/${experimentId}/analysis-artifacts?include_archived=${needsArchived.value}`);
4801
+ if (token !== listToken) return artifacts.value;
4802
+ fetchedArtifacts.value = [...data?.artifacts ?? []];
4803
+ request.markLoaded();
4804
+ return artifacts.value;
4805
+ } catch (err) {
4806
+ if (token !== listToken) return [];
4807
+ request.setError(err);
4808
+ fetchedArtifacts.value = [];
4809
+ return [];
4810
+ } finally {
4811
+ loadingCount.value -= 1;
4812
+ }
4813
+ }
4814
+ async function getDetail(artifactId) {
4815
+ const experimentId = currentExperimentIdOrError("loading an analysis artifact");
4816
+ if (experimentId === void 0) return null;
4817
+ const token = ++detailToken;
4818
+ loadingCount.value += 1;
4819
+ request.clearError();
4820
+ try {
4821
+ const detail = await api.get(`/experiments/${experimentId}/analysis-artifacts/${artifactId}`);
4822
+ if (token !== detailToken) return null;
4823
+ selectedDetail.value = detail;
4824
+ request.markLoaded();
4825
+ return detail;
4826
+ } catch (err) {
4827
+ if (token !== detailToken) return null;
4828
+ request.setError(err);
4829
+ return null;
4830
+ } finally {
4831
+ loadingCount.value -= 1;
4832
+ }
4833
+ }
4834
+ async function resolveTarget(target) {
4835
+ const experimentId = currentExperimentId.value;
4836
+ if (experimentId !== target.experimentId) {
4837
+ request.setError(`Analysis artifact target belongs to experiment ${target.experimentId}, not ${experimentId ?? "the current selection"}.`);
4838
+ return null;
4839
+ }
4840
+ const summary = (await list()).find((artifact) => artifact.plugin_id === target.artifactPluginId && artifact.artifact_key === target.artifactKey && artifact.status === "active");
4841
+ if (!summary) {
4842
+ request.setError(`Analysis artifact ${target.artifactPluginId}/${target.artifactKey} is not available.`);
4843
+ return null;
4844
+ }
4845
+ const detail = await getDetail(summary.id);
4846
+ if (detail && (detail.experiment_id !== target.experimentId || detail.plugin_id !== target.artifactPluginId || detail.artifact_key !== target.artifactKey)) {
4847
+ selectedDetail.value = null;
4848
+ request.setError(`Analysis artifact ${target.artifactPluginId}/${target.artifactKey} did not match the requested identity.`);
4849
+ return null;
4850
+ }
4851
+ return detail;
4852
+ }
4853
+ async function mutate(action, operation) {
4854
+ const experimentId = currentExperimentIdOrError(action);
4855
+ if (experimentId === void 0) return null;
4856
+ mutatingCount.value += 1;
4857
+ request.clearError();
4858
+ try {
4859
+ const summary = await operation(experimentId);
4860
+ replaceArtifact(summary);
4861
+ request.markSaved();
4862
+ return summary;
4863
+ } catch (err) {
4864
+ request.setError(err);
4865
+ return null;
4866
+ } finally {
4867
+ mutatingCount.value -= 1;
4868
+ }
4869
+ }
4870
+ async function updateMetadata(artifactId, updates) {
4871
+ return mutate("updating artifact metadata", (experimentId) => api.patch(`/experiments/${experimentId}/analysis-artifacts/${artifactId}`, updates));
4872
+ }
4873
+ async function archive(artifactId) {
4874
+ return mutate("archiving an analysis artifact", (experimentId) => api.post(`/experiments/${experimentId}/analysis-artifacts/${artifactId}/archive`));
4875
+ }
4876
+ async function restore(artifactId) {
4877
+ return mutate("restoring an analysis artifact", (experimentId) => api.post(`/experiments/${experimentId}/analysis-artifacts/${artifactId}/restore`));
4878
+ }
4879
+ function hasArtifactKey(artifactKey) {
4880
+ return artifacts.value.some((artifact) => artifact.artifact_key === artifactKey);
4881
+ }
4882
+ /** Drop experiment-scoped state and orphan every in-flight response. */
4883
+ function clear() {
4884
+ listToken += 1;
4885
+ detailToken += 1;
4886
+ fetchedArtifacts.value = [];
4887
+ selectedDetail.value = null;
4888
+ request.clearError();
4889
+ }
4890
+ watch([currentExperimentId, needsArchived], ([experimentId], [previousExperimentId]) => {
4891
+ if (experimentId !== previousExperimentId) clear();
4892
+ if (experimentId === void 0) return;
4893
+ if (options.immediate || hasRequestedList.value) list();
4894
+ }, { immediate: options.immediate });
4895
+ return {
4896
+ artifacts,
4897
+ visibleArtifacts,
4898
+ selectedDetail,
4899
+ currentExperimentId,
4900
+ hasCurrentExperiment,
4901
+ isLoading,
4902
+ isMutating,
4903
+ error: request.error,
4904
+ lastLoadedAt: request.lastLoadedAt,
4905
+ search,
4906
+ statusFilter,
4907
+ pluginFilter,
4908
+ list,
4909
+ refresh: list,
4910
+ getDetail,
4911
+ resolveTarget,
4912
+ updateMetadata,
4913
+ archive,
4914
+ restore,
4915
+ hasArtifactKey,
4916
+ clear
4917
+ };
4918
+ }
4919
+ //#endregion
4920
+ //#region src/components/ArtifactSelectorModal.vue?vue&type=script&setup=true&lang.ts
4921
+ var _hoisted_1$6 = { class: "mint-artifact-selector__filters-row" };
4922
+ var _hoisted_2$5 = { class: "mint-artifact-selector__search" };
4923
+ var _hoisted_3$4 = { class: "mint-artifact-selector__filter-select" };
4924
+ var _hoisted_4$4 = {
4925
+ key: 0,
4926
+ class: "mint-artifact-selector__filter-select"
4927
+ };
4928
+ var _hoisted_5$3 = {
4929
+ key: 0,
4930
+ class: "mint-artifact-selector__skeleton"
4931
+ };
4932
+ var _hoisted_6$3 = { class: "mint-artifact-selector__skeleton-content" };
4933
+ var _hoisted_7$3 = {
4934
+ key: 1,
4935
+ class: "mint-artifact-selector__error"
4936
+ };
4937
+ var _hoisted_8$3 = [
4938
+ "id",
4939
+ "aria-selected",
4940
+ "onClick",
4941
+ "onMouseenter"
4942
+ ];
4943
+ var _hoisted_9$2 = { class: "mint-artifact-selector__row-content" };
4944
+ var _hoisted_10$2 = { class: "mint-artifact-selector__name" };
4945
+ var _hoisted_11$2 = { class: "mint-artifact-selector__key" };
4946
+ var _hoisted_12$2 = { class: "mint-artifact-selector__meta" };
4947
+ var _hoisted_13$1 = { class: "mint-artifact-selector__plugin" };
4948
+ var _hoisted_14$1 = { class: "mint-artifact-selector__row-side" };
4949
+ var _hoisted_15$1 = ["disabled", "onClick"];
4950
+ var _hoisted_16$1 = ["disabled", "onClick"];
4951
+ var LISTBOX_ID = "mint-artifact-selector-listbox";
4952
+ //#endregion
4953
+ //#region src/components/ArtifactSelectorModal.vue
4954
+ var ArtifactSelectorModal_default = /* @__PURE__ */ defineComponent({
4955
+ __name: "ArtifactSelectorModal",
4956
+ props: {
4957
+ modelValue: { type: Boolean },
4958
+ experimentId: { default: null },
4959
+ pluginId: { default: null },
4960
+ currentArtifactId: { default: null },
4961
+ includeArchived: {
4962
+ type: Boolean,
4963
+ default: false
4964
+ },
4965
+ fetchDetailOnSelect: {
4966
+ type: Boolean,
4967
+ default: false
4968
+ },
4969
+ title: { default: "Select Analysis Artifact" },
4970
+ size: { default: "full" }
4971
+ },
4972
+ emits: [
4973
+ "update:modelValue",
4974
+ "select",
4975
+ "selectDetail",
4976
+ "archive",
4977
+ "restore"
4978
+ ],
4979
+ setup(__props, { emit: __emit }) {
4980
+ /** Modal for browsing and selecting an analysis artifact of an experiment, with filters and keyboard nav. */
4981
+ const props = __props;
4982
+ const emit = __emit;
4983
+ const { artifacts, visibleArtifacts, isLoading, isMutating, error, search, statusFilter, pluginFilter, list, getDetail, archive, restore } = useAnalysisArtifacts({
4984
+ experimentId: () => props.experimentId ?? void 0,
4985
+ pluginId: () => props.pluginId,
4986
+ includeArchived: () => props.includeArchived
4987
+ });
4988
+ const injectedContext = getInjectedPlatformContext();
4989
+ const canManage = computed(() => {
4990
+ const user = injectedContext?.user;
4991
+ return user ? hasAllPermissions(user, ["experiments.edit"]) : true;
4992
+ });
4993
+ const STATUS_FILTER_OPTIONS = [
4994
+ {
4995
+ value: "active",
4996
+ label: "Active"
4997
+ },
4998
+ {
4999
+ value: "archived",
5000
+ label: "Archived"
5001
+ },
5002
+ {
5003
+ value: "all",
5004
+ label: "All statuses"
5005
+ }
5006
+ ];
5007
+ const pluginFilterOptions = computed(() => [{
5008
+ value: "",
5009
+ label: "All plugins"
5010
+ }, ...[...new Set(artifacts.value.map((artifact) => artifact.plugin_id))].sort().map((pluginId) => ({
5011
+ value: pluginId,
5012
+ label: pluginId
5013
+ }))]);
5014
+ const canChoosePlugin = computed(() => !props.pluginId && pluginFilterOptions.value.length > 2);
5015
+ const activeIndex = ref(-1);
5016
+ const listRef = ref(null);
5017
+ function optionId(artifact) {
5018
+ return `mint-artifact-option-${artifact.id}`;
5019
+ }
5020
+ const activeDescendantId = computed(() => {
5021
+ const artifact = visibleArtifacts.value[activeIndex.value];
5022
+ return activeIndex.value >= 0 && artifact ? optionId(artifact) : void 0;
5023
+ });
5024
+ const hasResults = computed(() => !isLoading.value && !error.value && visibleArtifacts.value.length > 0);
5025
+ function statusVariant(status) {
5026
+ return status === "archived" ? "warning" : "success";
5027
+ }
5028
+ function formatArtifactDate(artifact) {
5029
+ const date = artifact.updated_at ?? artifact.created_at;
5030
+ return date ? formatExperimentDate(date) : "";
5031
+ }
5032
+ async function handleSelect(artifact) {
5033
+ if (props.fetchDetailOnSelect) {
5034
+ const detail = await getDetail(artifact.id);
5035
+ if (!detail) return;
5036
+ emit("selectDetail", detail);
5037
+ }
5038
+ emit("select", artifact);
5039
+ emit("update:modelValue", false);
5040
+ }
5041
+ async function handleArchive(artifact) {
5042
+ const archived = await archive(artifact.id);
5043
+ if (archived) emit("archive", archived);
5044
+ }
5045
+ async function handleRestore(artifact) {
5046
+ const restored = await restore(artifact.id);
5047
+ if (restored) emit("restore", restored);
5048
+ }
5049
+ function handleKeydown(event) {
5050
+ const rows = visibleArtifacts.value;
5051
+ if (!rows.length) return;
5052
+ if (event.target?.closest(".mint-artifact-selector__action")) return;
5053
+ switch (event.key) {
5054
+ case "ArrowDown":
5055
+ event.preventDefault();
5056
+ activeIndex.value = Math.min(activeIndex.value + 1, rows.length - 1);
5057
+ scrollActiveIntoView();
5058
+ break;
5059
+ case "ArrowUp":
5060
+ event.preventDefault();
5061
+ activeIndex.value = Math.max(activeIndex.value - 1, 0);
5062
+ scrollActiveIntoView();
5063
+ break;
5064
+ case "Enter":
5065
+ event.preventDefault();
5066
+ if (activeIndex.value >= 0 && activeIndex.value < rows.length) handleSelect(rows[activeIndex.value]);
5067
+ break;
5068
+ }
5069
+ }
5070
+ function scrollActiveIntoView() {
5071
+ nextTick(() => {
5072
+ (listRef.value?.querySelector(".mint-artifact-selector__row--focused"))?.scrollIntoView({ block: "nearest" });
5073
+ });
5074
+ }
5075
+ watch(visibleArtifacts, () => {
5076
+ activeIndex.value = -1;
5077
+ });
5078
+ watch(() => props.modelValue, (isOpen) => {
5079
+ if (isOpen) {
5080
+ activeIndex.value = -1;
5081
+ statusFilter.value = props.includeArchived ? "all" : "active";
5082
+ list();
5083
+ }
5084
+ }, { immediate: true });
5085
+ return (_ctx, _cache) => {
5086
+ return openBlock(), createBlock(BaseModal_default, {
5087
+ "model-value": __props.modelValue,
5088
+ title: __props.title,
5089
+ size: __props.size,
5090
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => emit("update:modelValue", $event))
5091
+ }, {
5092
+ default: withCtx(() => [createElementVNode("div", {
5093
+ class: "mint-artifact-selector",
5094
+ onKeydown: handleKeydown
5095
+ }, [createElementVNode("div", _hoisted_1$6, [
5096
+ createElementVNode("div", _hoisted_2$5, [createVNode(BaseInput_default, {
5097
+ modelValue: unref(search),
5098
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(search) ? search.value = $event : null),
5099
+ placeholder: "Search artifacts...",
5100
+ size: "sm",
5101
+ type: "search",
5102
+ role: "combobox",
5103
+ "aria-label": "Search analysis artifacts",
5104
+ "aria-expanded": hasResults.value,
5105
+ "aria-controls": LISTBOX_ID,
5106
+ "aria-activedescendant": activeDescendantId.value
5107
+ }, null, 8, [
5108
+ "modelValue",
5109
+ "aria-expanded",
5110
+ "aria-activedescendant"
5111
+ ])]),
5112
+ createElementVNode("div", _hoisted_3$4, [createVNode(BaseSelect_default, {
5113
+ "model-value": unref(statusFilter),
5114
+ options: STATUS_FILTER_OPTIONS,
5115
+ size: "sm",
5116
+ "aria-label": "Filter by status",
5117
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = (v) => statusFilter.value = v)
5118
+ }, null, 8, ["model-value"])]),
5119
+ canChoosePlugin.value ? (openBlock(), createElementBlock("div", _hoisted_4$4, [createVNode(BaseSelect_default, {
5120
+ "model-value": unref(pluginFilter) ?? "",
5121
+ options: pluginFilterOptions.value,
5122
+ size: "sm",
5123
+ "aria-label": "Filter by plugin",
5124
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = (v) => pluginFilter.value = String(v) || null)
5125
+ }, null, 8, ["model-value", "options"])])) : createCommentVNode("", true)
5126
+ ]), unref(isLoading) ? (openBlock(), createElementBlock("div", _hoisted_5$3, [(openBlock(), createElementBlock(Fragment, null, renderList(4, (n) => {
5127
+ return createElementVNode("div", {
5128
+ key: n,
5129
+ class: "mint-artifact-selector__skeleton-row"
5130
+ }, [createElementVNode("div", _hoisted_6$3, [createVNode(Skeleton_default, {
5131
+ width: 120 + n * 20,
5132
+ height: "14px"
5133
+ }, null, 8, ["width"]), createVNode(Skeleton_default, {
5134
+ width: "80px",
5135
+ height: "10px"
5136
+ })]), createVNode(Skeleton_default, {
5137
+ width: "60px",
5138
+ height: "20px",
5139
+ variant: "rounded"
5140
+ })]);
5141
+ }), 64))])) : unref(error) ? (openBlock(), createElementBlock("div", _hoisted_7$3, toDisplayString(unref(error)), 1)) : unref(visibleArtifacts).length === 0 ? (openBlock(), createBlock(EmptyState_default, {
5142
+ key: 2,
5143
+ title: "No analysis artifacts found",
5144
+ description: "Artifacts appear here once an analysis saves results for this experiment.",
5145
+ size: "sm"
5146
+ })) : (openBlock(), createElementBlock("div", {
5147
+ key: 3,
5148
+ id: LISTBOX_ID,
5149
+ ref_key: "listRef",
5150
+ ref: listRef,
5151
+ class: "mint-artifact-selector__list",
5152
+ role: "listbox",
5153
+ "aria-label": "Analysis artifacts"
5154
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(visibleArtifacts), (artifact, idx) => {
5155
+ return openBlock(), createElementBlock("div", {
5156
+ id: optionId(artifact),
5157
+ key: artifact.id,
5158
+ class: normalizeClass(["mint-artifact-selector__row", {
5159
+ "mint-artifact-selector__row--active": artifact.id === __props.currentArtifactId,
5160
+ "mint-artifact-selector__row--focused": idx === activeIndex.value,
5161
+ "mint-artifact-selector__row--archived": artifact.status === "archived"
5162
+ }]),
5163
+ role: "option",
5164
+ "aria-selected": artifact.id === __props.currentArtifactId,
5165
+ onClick: ($event) => handleSelect(artifact),
5166
+ onMouseenter: ($event) => activeIndex.value = idx
5167
+ }, [createElementVNode("div", _hoisted_9$2, [createElementVNode("div", _hoisted_10$2, [createTextVNode(toDisplayString(artifact.display_name) + " ", 1), createElementVNode("code", _hoisted_11$2, toDisplayString(artifact.artifact_key), 1)]), createElementVNode("div", _hoisted_12$2, [
5168
+ createElementVNode("span", _hoisted_13$1, toDisplayString(artifact.plugin_id), 1),
5169
+ createElementVNode("span", null, toDisplayString(artifact.result_keys.length) + " result" + toDisplayString(artifact.result_keys.length === 1 ? "" : "s"), 1),
5170
+ createElementVNode("span", null, toDisplayString(formatArtifactDate(artifact)), 1)
5171
+ ])]), createElementVNode("div", _hoisted_14$1, [createVNode(BasePill_default, {
5172
+ variant: statusVariant(artifact.status),
5173
+ size: "sm"
5174
+ }, {
5175
+ default: withCtx(() => [createTextVNode(toDisplayString(artifact.status), 1)]),
5176
+ _: 2
5177
+ }, 1032, ["variant"]), canManage.value && artifact.status === "active" ? (openBlock(), createElementBlock("button", {
5178
+ key: 0,
5179
+ type: "button",
5180
+ class: "mint-artifact-selector__action",
5181
+ disabled: unref(isMutating),
5182
+ onClick: withModifiers(($event) => handleArchive(artifact), ["stop"])
5183
+ }, " Archive ", 8, _hoisted_15$1)) : canManage.value && artifact.status === "archived" ? (openBlock(), createElementBlock("button", {
5184
+ key: 1,
5185
+ type: "button",
5186
+ class: "mint-artifact-selector__action",
5187
+ disabled: unref(isMutating),
5188
+ onClick: withModifiers(($event) => handleRestore(artifact), ["stop"])
5189
+ }, " Restore ", 8, _hoisted_16$1)) : createCommentVNode("", true)])], 42, _hoisted_8$3);
5190
+ }), 128))], 512))], 32)]),
5191
+ _: 1
5192
+ }, 8, [
5193
+ "model-value",
5194
+ "title",
5195
+ "size"
5196
+ ]);
5197
+ };
5198
+ }
5199
+ });
5200
+ //#endregion
5201
+ //#region src/components/GeneratedPathInput.vue?vue&type=script&setup=true&lang.ts
5202
+ var _hoisted_1$5 = { class: "mint-generated-path-input" };
5203
+ var _hoisted_2$4 = {
5204
+ class: "mint-generated-path-input__modes",
5205
+ role: "group",
5206
+ "aria-label": "Path type"
5207
+ };
5208
+ var GeneratedPathInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5209
+ __name: "GeneratedPathInput",
5210
+ props: {
5211
+ modelValue: {},
5212
+ disabled: { type: Boolean },
5213
+ multiple: { type: Boolean }
5214
+ },
5215
+ emits: ["update:modelValue"],
5216
+ setup(__props, { emit: __emit }) {
5217
+ const props = __props;
5218
+ const emit = __emit;
5219
+ const mode = ref("file");
5220
+ const artifactOpen = ref(false);
5221
+ const artifactLoading = ref(false);
5222
+ const artifactError = ref("");
5223
+ const platform = getInjectedPlatformContext();
5224
+ const experimentId = resolveCurrentExperimentId(platform);
5225
+ const canSelectArtifact = computed(() => Boolean(platform?.isIntegrated && experimentId));
5226
+ const transport = createGeneratedAnalysisTransport();
5227
+ function selectMode(nextMode) {
5228
+ mode.value = nextMode;
5229
+ emit("update:modelValue", null);
5230
+ }
5231
+ function selectFiles(files, rootName, relativePaths) {
5232
+ const paths = relativePaths ?? files.map((file) => file.name);
5233
+ const selections = props.multiple && !rootName ? files.map((file, index) => ({
5234
+ kind: "path",
5235
+ files: [file],
5236
+ relativePaths: [paths[index] ?? file.name]
5237
+ })) : [{
5238
+ kind: "path",
5239
+ files,
5240
+ relativePaths: paths,
5241
+ ...rootName ? { rootName } : {}
5242
+ }];
5243
+ if (props.multiple) emit("update:modelValue", [...Array.isArray(props.modelValue) ? props.modelValue : [], ...selections]);
5244
+ else emit("update:modelValue", selections[0] ?? null);
5245
+ }
5246
+ function removeFiles(files) {
5247
+ const removed = new Set(files);
5248
+ const remaining = (Array.isArray(props.modelValue) ? props.modelValue : props.modelValue ? [props.modelValue] : []).flatMap((selection) => {
5249
+ const indexes = selection.files.map((file, index) => removed.has(file) ? -1 : index).filter((index) => index >= 0);
5250
+ if (!indexes.length) return [];
5251
+ return [{
5252
+ ...selection,
5253
+ files: indexes.map((index) => selection.files[index]),
5254
+ relativePaths: indexes.map((index) => selection.relativePaths[index])
5255
+ }];
5256
+ });
5257
+ emit("update:modelValue", props.multiple ? remaining : remaining[0] ?? null);
5258
+ }
5259
+ async function selectArtifact(detail) {
5260
+ artifactLoading.value = true;
5261
+ artifactError.value = "";
5262
+ try {
5263
+ const reference = artifactFileReference(detail);
5264
+ const resolvedExperimentId = reference.experiment_id ?? detail.experiment_id;
5265
+ const pluginId = reference.plugin_id ?? detail.plugin_id;
5266
+ const response = await transport(`${(platform?.platformApiUrl ?? "/api").replace(/\/$/, "")}/experiments/${resolvedExperimentId}/objects/${reference.key.split("/").map(encodeURIComponent).join("/")}?plugin_id=${encodeURIComponent(pluginId)}&format=raw`, { method: "GET" });
5267
+ if (!response.ok) throw new Error(`Artifact download failed (${response.status})`);
5268
+ const resultFilename = String(detail.result.filename ?? "");
5269
+ const keySegments = reference.key.split("/");
5270
+ const filename = reference.filename || resultFilename || keySegments[keySegments.length - 1] || "artifact.bin";
5271
+ const contentType = reference.content_type ?? response.headers.get("Content-Type") ?? "application/octet-stream";
5272
+ selectFiles([new File([await response.blob()], filename, { type: contentType })], void 0, [filename]);
5273
+ } catch (cause) {
5274
+ artifactError.value = cause instanceof Error ? cause.message : "Failed to load artifact";
5275
+ } finally {
5276
+ artifactLoading.value = false;
5277
+ }
5278
+ }
5279
+ function artifactFileReference(detail) {
5280
+ if (detail.result.schema_version !== "mint.analysis_file.v1") throw new Error("Only file-backed analysis artifacts can be used as a path");
5281
+ const reference = detail.result.file;
5282
+ if (!reference || typeof reference !== "object" || !("key" in reference)) throw new Error("The selected artifact has no file reference");
5283
+ const candidate = reference;
5284
+ if (typeof candidate.key !== "string" || !candidate.key) throw new Error("The selected artifact has no object key");
5285
+ return {
5286
+ key: candidate.key,
5287
+ ...typeof candidate.plugin_id === "string" ? { plugin_id: candidate.plugin_id } : {},
5288
+ ...typeof candidate.experiment_id === "number" ? { experiment_id: candidate.experiment_id } : {},
5289
+ ...typeof candidate.filename === "string" ? { filename: candidate.filename } : {},
5290
+ ...typeof candidate.content_type === "string" ? { content_type: candidate.content_type } : {}
5291
+ };
5292
+ }
5293
+ return (_ctx, _cache) => {
5294
+ return openBlock(), createElementBlock("div", _hoisted_1$5, [
5295
+ createElementVNode("div", _hoisted_2$4, [
5296
+ createVNode(BaseButton_default, {
5297
+ size: "sm",
5298
+ variant: mode.value === "file" ? "primary" : "secondary",
5299
+ disabled: __props.disabled,
5300
+ onClick: _cache[0] || (_cache[0] = ($event) => selectMode("file"))
5301
+ }, {
5302
+ default: withCtx(() => [..._cache[4] || (_cache[4] = [createTextVNode(" File ", -1)])]),
5303
+ _: 1
5304
+ }, 8, ["variant", "disabled"]),
5305
+ createVNode(BaseButton_default, {
5306
+ size: "sm",
5307
+ variant: mode.value === "folder" ? "primary" : "secondary",
5308
+ disabled: __props.disabled,
5309
+ onClick: _cache[1] || (_cache[1] = ($event) => selectMode("folder"))
5310
+ }, {
5311
+ default: withCtx(() => [..._cache[5] || (_cache[5] = [createTextVNode(" Folder ", -1)])]),
5312
+ _: 1
5313
+ }, 8, ["variant", "disabled"]),
5314
+ canSelectArtifact.value ? (openBlock(), createBlock(BaseButton_default, {
5315
+ key: 0,
5316
+ size: "sm",
5317
+ variant: "secondary",
5318
+ disabled: __props.disabled,
5319
+ loading: artifactLoading.value,
5320
+ onClick: _cache[2] || (_cache[2] = ($event) => artifactOpen.value = true)
5321
+ }, {
5322
+ default: withCtx(() => [..._cache[6] || (_cache[6] = [createTextVNode(" Existing artifact ", -1)])]),
5323
+ _: 1
5324
+ }, 8, ["disabled", "loading"])) : createCommentVNode("", true)
5325
+ ]),
5326
+ (openBlock(), createBlock(FileUploader_default, {
5327
+ key: mode.value,
5328
+ mode: mode.value,
5329
+ multiple: __props.multiple && mode.value === "file",
5330
+ disabled: __props.disabled,
5331
+ onUpload: selectFiles,
5332
+ onRemove: removeFiles
5333
+ }, null, 8, [
5334
+ "mode",
5335
+ "multiple",
5336
+ "disabled"
5337
+ ])),
5338
+ artifactError.value ? (openBlock(), createBlock(AlertBox_default, {
5339
+ key: 0,
5340
+ type: "error",
5341
+ message: artifactError.value
5342
+ }, null, 8, ["message"])) : createCommentVNode("", true),
5343
+ canSelectArtifact.value ? (openBlock(), createBlock(ArtifactSelectorModal_default, {
5344
+ key: 1,
5345
+ modelValue: artifactOpen.value,
5346
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => artifactOpen.value = $event),
5347
+ "experiment-id": unref(experimentId),
5348
+ "fetch-detail-on-select": true,
5349
+ title: "Select a file artifact",
5350
+ onSelectDetail: selectArtifact
5351
+ }, null, 8, ["modelValue", "experiment-id"])) : createCommentVNode("", true)
5352
+ ]);
5353
+ };
5354
+ }
5355
+ });
5356
+ //#endregion
5357
+ //#region \0plugin-vue:export-helper
5358
+ var _plugin_vue_export_helper_default = (sfc, props) => {
5359
+ const target = sfc.__vccOpts || sfc;
5360
+ for (const [key, val] of props) target[key] = val;
5361
+ return target;
5362
+ };
5363
+ //#endregion
5364
+ //#region src/components/GeneratedPathInput.vue
5365
+ var GeneratedPathInput_default = /* @__PURE__ */ _plugin_vue_export_helper_default(GeneratedPathInput_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-9011f2f2"]]);
5366
+ //#endregion
3662
5367
  //#region src/composables/useChemicalFormula.ts
3663
5368
  var ATOMIC_WEIGHTS = {
3664
5369
  H: 1.008,
@@ -5149,6 +6854,11 @@ var registry = {
5149
6854
  defaults: {},
5150
6855
  vModel: false
5151
6856
  },
6857
+ path: {
6858
+ component: GeneratedPathInput_default,
6859
+ defaults: {},
6860
+ vModel: true
6861
+ },
5152
6862
  formula: {
5153
6863
  component: FormulaInput_default,
5154
6864
  defaults: {},
@@ -5951,6 +7661,6 @@ function useControlSchema(controls, options = {}) {
5951
7661
  };
5952
7662
  }
5953
7663
  //#endregion
5954
- export { parseTime as $, useConcentrationUnits as A, TagsInput_default as B, controlsToViewIds as C, getTypeDefault as D, getFieldRegistryEntry as E, ATOMIC_WEIGHTS as F, findAvailableSlots as G, addMinutes as H, useChemicalFormula as I, formatTime as J, findNearestTimeSlotIndex as K, DateTimePicker_default as L, SequenceInput_default as M, useSequenceUtils as N, ConcentrationInput_default as O, FormulaInput_default as P, isTimeInRange as Q, FileUploader_default as R, controlsToTopBarSettingsConfig as S, getDefaultControlView as T, compareTime as U, TimePicker_default as V, durationMinutes as W, fromMinutes as X, formatTimeSlot as Y, generateTimeSlots as Z, controlsToFormSchema as _, defineDoseCalculatorControlProps as a, MultiSelect_default as at, controlsToSettingsSchema as b, defineWellPlateDoseComponentBindings as c, BaseSlider_default as ct, defineControlModel as d, BaseCheckbox_default as dt, rangesOverlap as et, resolveControlModel as f, Tooltip_default as ft, mergeControlWorkspaceOptions as g, controlValuesToComponentProps as h, useControlSchema as i, DatePicker_default as it, MoleculeInput_default as j, UnitInput_default as k, defineWellPlateDoseControlProps as l, BaseRadioGroup_default as lt, controlValuesToComponentBindingsById as m, defineControls as n, toMinutes as nt, defineDoseDesignControlModel as o, useListSelection as ot, controlValuesToComponentBindings as p, BaseTextarea_default as pt, formatDuration as q, getControlDefaults as r, useTimeUtils as rt, defineWellPlateControlProps as s, useSelectionLimit as st, defineControlComponentBindings as t, snapToSlot as tt, useControlWorkspace as u, BaseToggle_default as ut, controlsToSectionFormSchema as v, controlsToViewItems as w, controlsToSidebarPanels as x, controlsToSectionFormSchemas as y, NumberInput_default as z };
7664
+ export { normalizeJobState as $, useConcentrationUnits as A, BaseCheckbox_default as At, useAnalysisArtifacts as B, controlsToViewIds as C, DatePicker_default as Ct, getTypeDefault as D, BaseSlider_default as Dt, getFieldRegistryEntry as E, useSelectionLimit as Et, ATOMIC_WEIGHTS as F, resolveCurrentPluginId as G, getInjectedPlatformContext as H, useChemicalFormula as I, usePluginJobs as J, createGeneratedAnalysisTransport as K, GeneratedPathInput_default as L, SequenceInput_default as M, BaseTextarea_default as Mt, useSequenceUtils as N, ConcentrationInput_default as O, BaseRadioGroup_default as Ot, FormulaInput_default as P, normalizeJobPercent as Q, _plugin_vue_export_helper_default as R, controlsToTopBarSettingsConfig as S, useTimeUtils as St, getDefaultControlView as T, useListSelection as Tt, parseExperimentId as U, currentExperimentFromContext as V, resolveCurrentExperimentId as W, isTerminalJobStatus as X, isActiveJobStatus as Y, jobStatusLabel as Z, controlsToFormSchema as _, isTimeInRange as _t, defineDoseCalculatorControlProps as a, TagsInput_default as at, controlsToSettingsSchema as b, snapToSlot as bt, defineWellPlateDoseComponentBindings as c, compareTime as ct, defineControlModel as d, findNearestTimeSlotIndex as dt, resolveJobCapabilities as et, resolveControlModel as f, formatDuration as ft, mergeControlWorkspaceOptions as g, generateTimeSlots as gt, controlValuesToComponentProps as h, fromMinutes as ht, useControlSchema as i, NumberInput_default as it, MoleculeInput_default as j, Tooltip_default as jt, UnitInput_default as k, BaseToggle_default as kt, defineWellPlateDoseControlProps as l, durationMinutes as lt, controlValuesToComponentBindingsById as m, formatTimeSlot as mt, defineControls as n, AlertBox_default as nt, defineDoseDesignControlModel as o, TimePicker_default as ot, controlValuesToComponentBindings as p, formatTime as pt, useGeneratedAnalysis as q, getControlDefaults as r, FileUploader_default as rt, defineWellPlateControlProps as s, addMinutes as st, defineControlComponentBindings as t, DateTimePicker_default as tt, useControlWorkspace as u, findAvailableSlots as ut, controlsToSectionFormSchema as v, parseTime as vt, controlsToViewItems as w, MultiSelect_default as wt, controlsToSidebarPanels as x, toMinutes as xt, controlsToSectionFormSchemas as y, rangesOverlap as yt, ArtifactSelectorModal_default as z };
5955
7665
 
5956
- //# sourceMappingURL=useControlSchema-BZNdalmL.js.map
7666
+ //# sourceMappingURL=useControlSchema-B_qgU4rW.js.map