@morscherlab/mint-sdk 1.0.0-beta.3 → 1.0.0-beta.5

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 +9 -2
  2. package/dist/__tests__/composables/experiment-utils.test.d.ts +1 -0
  3. package/dist/__tests__/composables/useApi.test.d.ts +1 -0
  4. package/dist/components/AppContainer.vue.d.ts +1 -1
  5. package/dist/components/AppLayout.vue.d.ts +20 -1
  6. package/dist/components/AppSidebar.vue.d.ts +57 -5
  7. package/dist/components/AppTopBar.vue.d.ts +7 -25
  8. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +3 -1
  9. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +1 -0
  10. package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +5 -0
  11. package/dist/components/ComponentBindingRenderer.vue.d.ts +44 -0
  12. package/dist/components/ControlWorkspaceView.vue.d.ts +24 -7
  13. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +149 -0
  14. package/dist/components/ExperimentTimeline.vue.d.ts +1 -1
  15. package/dist/components/FormBuilder.vue.d.ts +9 -9
  16. package/dist/components/PlateMapEditor.vue.d.ts +1 -1
  17. package/dist/components/PluginWorkspaceView.vue.d.ts +310 -0
  18. package/dist/components/SettingsModal.vue.d.ts +1 -1
  19. package/dist/components/WellPlate.vue.d.ts +2 -2
  20. package/dist/components/index.d.ts +3 -12
  21. package/dist/components/index.js +3 -3
  22. package/dist/components/{AppPageSelector.vue.d.ts → internal/AppTopBarPageSelectorInternal.vue.d.ts} +1 -1
  23. package/dist/components/{AppPillNav.vue.d.ts → internal/AppTopBarPillNavInternal.vue.d.ts} +3 -1
  24. package/dist/components/{CalendarGridPanel.vue.d.ts → internal/CalendarGridPanelInternal.vue.d.ts} +1 -1
  25. package/dist/components/internal/FormSectionRenderer.vue.d.ts +4 -4
  26. package/dist/components/{WellEditPopup.vue.d.ts → internal/WellEditPopupInternal.vue.d.ts} +1 -1
  27. package/dist/{components-D_Sr0adg.js → components-DihbSJjU.js} +5932 -5408
  28. package/dist/components-DihbSJjU.js.map +1 -0
  29. package/dist/composables/experiment-utils.d.ts +8 -0
  30. package/dist/composables/index.d.ts +5 -7
  31. package/dist/composables/index.js +4 -4
  32. package/dist/composables/useAppExperiment.d.ts +31 -2
  33. package/dist/composables/useBioTemplateComponents.d.ts +5 -3
  34. package/dist/composables/useBioTemplatePackWorkspace.d.ts +3 -2
  35. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +6 -5
  36. package/dist/composables/useBioTemplateWorkspace.d.ts +5 -4
  37. package/dist/composables/useControlSchema.d.ts +43 -21
  38. package/dist/composables/usePluginClient.d.ts +5 -2
  39. package/dist/{composables-C3dpXQN5.js → composables-BcgZ6diz.js} +40 -28
  40. package/dist/composables-BcgZ6diz.js.map +1 -0
  41. package/dist/index.d.ts +5 -12
  42. package/dist/index.js +5 -5
  43. package/dist/install.js +2 -2
  44. package/dist/styles.css +5637 -5663
  45. package/dist/templates/adapters.d.ts +7 -1
  46. package/dist/templates/catalog.d.ts +5 -5
  47. package/dist/templates/componentBindings.d.ts +13 -0
  48. package/dist/templates/index.d.ts +5 -5
  49. package/dist/templates/index.js +2 -2
  50. package/dist/templates/presets.d.ts +4 -4
  51. package/dist/templates/types.d.ts +4 -1
  52. package/dist/{templates-50NPjaxL.js → templates-Cyt0Suwf.js} +322 -73
  53. package/dist/templates-Cyt0Suwf.js.map +1 -0
  54. package/dist/types/components.d.ts +6 -25
  55. package/dist/types/index.d.ts +1 -1
  56. package/dist/{useScheduleDrag-D4oWdh41.js → useExperimentData-CM6Y0u5L.js} +400 -357
  57. package/dist/useExperimentData-CM6Y0u5L.js.map +1 -0
  58. package/package.json +1 -1
  59. package/src/__tests__/components/ActionItem.test.ts +6 -6
  60. package/src/__tests__/components/AppLayout.test.ts +44 -0
  61. package/src/__tests__/components/AppSidebar.test.ts +130 -2
  62. package/src/__tests__/components/AppToastContainer.test.ts +0 -11
  63. package/src/__tests__/components/AppTopBar.test.ts +189 -120
  64. package/src/__tests__/components/{AppPageSelector.test.ts → AppTopBarPageSelector.test.ts} +8 -8
  65. package/src/__tests__/components/{AppPillNav.test.ts → AppTopBarPillNav.test.ts} +53 -6
  66. package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +7 -1
  67. package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +32 -1
  68. package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +48 -1
  69. package/src/__tests__/components/BioTemplateRenderer.test.ts +25 -0
  70. package/src/__tests__/components/CalendarGridPanel.test.ts +3 -3
  71. package/src/__tests__/components/ComponentBindingRenderer.test.ts +278 -0
  72. package/src/__tests__/components/ControlWorkspaceView.test.ts +134 -63
  73. package/src/__tests__/components/DateTimePicker.test.ts +2 -2
  74. package/src/__tests__/components/DoseDesignWorkspaceView.test.ts +185 -0
  75. package/src/__tests__/components/PluginWorkspaceView.test.ts +548 -0
  76. package/src/__tests__/composables/experiment-utils.test.ts +30 -0
  77. package/src/__tests__/composables/useApi.test.ts +30 -0
  78. package/src/__tests__/composables/useAppExperiment.test.ts +100 -1
  79. package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +7 -4
  80. package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +7 -7
  81. package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +6 -1
  82. package/src/__tests__/composables/useControlSchema.test.ts +151 -37
  83. package/src/__tests__/composables/usePluginClient.test.ts +99 -2
  84. package/src/__tests__/docs/frontendDocsCatalog.test.ts +120 -25
  85. package/src/__tests__/templates/templates.test.ts +56 -0
  86. package/src/components/AppAvatarMenu.vue +3 -3
  87. package/src/components/AppLayout.story.vue +39 -0
  88. package/src/components/AppLayout.vue +83 -2
  89. package/src/components/AppPluginSwitcher.vue +5 -5
  90. package/src/components/AppSidebar.story.vue +113 -5
  91. package/src/components/AppSidebar.vue +147 -27
  92. package/src/components/AppTopBar.story.vue +2 -5
  93. package/src/components/AppTopBar.vue +35 -425
  94. package/src/components/BioTemplateExperimentWorkspaceView.story.vue +2 -2
  95. package/src/components/BioTemplateExperimentWorkspaceView.vue +6 -0
  96. package/src/components/BioTemplatePackWorkspaceView.story.vue +4 -4
  97. package/src/components/BioTemplatePackWorkspaceView.vue +1 -0
  98. package/src/components/BioTemplatePresetWorkspaceView.story.vue +14 -2
  99. package/src/components/BioTemplatePresetWorkspaceView.vue +12 -3
  100. package/src/components/BioTemplateRenderer.story.vue +2 -2
  101. package/src/components/BioTemplateRenderer.vue +15 -227
  102. package/src/components/ComponentBindingRenderer.story.vue +87 -0
  103. package/src/components/ComponentBindingRenderer.vue +317 -0
  104. package/src/components/ControlWorkspaceView.story.vue +20 -9
  105. package/src/components/ControlWorkspaceView.vue +43 -12
  106. package/src/components/DatePicker.vue +2 -2
  107. package/src/components/DateTimePicker.vue +2 -2
  108. package/src/components/DoseDesignWorkspaceView.story.vue +77 -0
  109. package/src/components/DoseDesignWorkspaceView.vue +255 -0
  110. package/src/components/ExperimentPopover.story.vue +2 -2
  111. package/src/components/ExperimentPopover.vue +2 -6
  112. package/src/components/ExperimentSelectorModal.vue +6 -5
  113. package/src/components/FormBuilder.story.vue +190 -0
  114. package/src/components/PluginWorkspaceView.story.vue +334 -0
  115. package/src/components/PluginWorkspaceView.vue +708 -0
  116. package/src/components/SettingsModal.story.vue +87 -0
  117. package/src/components/WellPlate.vue +2 -2
  118. package/src/components/index.ts +3 -12
  119. package/src/components/{AppPageSelector.vue → internal/AppTopBarPageSelectorInternal.vue} +9 -9
  120. package/src/components/internal/AppTopBarPillNavInternal.vue +194 -0
  121. package/src/components/{CalendarGridPanel.vue → internal/CalendarGridPanelInternal.vue} +1 -1
  122. package/src/components/{WellEditPopup.vue → internal/WellEditPopupInternal.vue} +3 -3
  123. package/src/composables/experiment-utils.ts +26 -0
  124. package/src/composables/index.ts +21 -7
  125. package/src/composables/useApi.ts +9 -2
  126. package/src/composables/useAppExperiment.ts +85 -13
  127. package/src/composables/useBioTemplateComponents.ts +12 -0
  128. package/src/composables/useBioTemplatePackWorkspace.ts +6 -2
  129. package/src/composables/useBioTemplatePresetWorkspace.ts +10 -21
  130. package/src/composables/useBioTemplateWorkspace.ts +6 -4
  131. package/src/composables/useControlSchema.ts +157 -69
  132. package/src/composables/usePluginClient.ts +50 -9
  133. package/src/index.ts +6 -563
  134. package/src/styles/components/app-layout.css +82 -0
  135. package/src/styles/components/app-page-selector.css +1 -1
  136. package/src/styles/components/app-pill-nav.css +71 -1
  137. package/src/styles/components/app-sidebar.css +119 -0
  138. package/src/styles/components/app-top-bar.css +0 -235
  139. package/src/styles/components/experiment-popover.css +2 -2
  140. package/src/styles/index.css +0 -1
  141. package/src/templates/adapters.ts +193 -0
  142. package/src/templates/catalog.ts +5 -5
  143. package/src/templates/componentBindings.ts +90 -3
  144. package/src/templates/index.ts +10 -0
  145. package/src/templates/packs.ts +10 -1
  146. package/src/templates/presets.ts +14 -4
  147. package/src/templates/types.ts +4 -0
  148. package/src/types/components.ts +6 -31
  149. package/src/types/index.ts +2 -6
  150. package/dist/__tests__/composables/usePluginApi.test.d.ts +0 -13
  151. package/dist/components/FormFieldRenderer.vue.d.ts +0 -28
  152. package/dist/components/FormSection.vue.d.ts +0 -30
  153. package/dist/components/GroupingModal.vue.d.ts +0 -12
  154. package/dist/components/SettingsButton.vue.d.ts +0 -30
  155. package/dist/components/ToastNotification.vue.d.ts +0 -2
  156. package/dist/components-D_Sr0adg.js.map +0 -1
  157. package/dist/composables/usePluginApi.d.ts +0 -22
  158. package/dist/composables-C3dpXQN5.js.map +0 -1
  159. package/dist/templates-50NPjaxL.js.map +0 -1
  160. package/dist/useScheduleDrag-D4oWdh41.js.map +0 -1
  161. package/src/__tests__/components/FormCompatibility.test.ts +0 -94
  162. package/src/__tests__/components/GroupingModal.test.ts +0 -73
  163. package/src/__tests__/components/SettingsButton.test.ts +0 -44
  164. package/src/__tests__/composables/usePluginApi.test.ts +0 -81
  165. package/src/components/AppPillNav.vue +0 -71
  166. package/src/components/FormFieldRenderer.vue +0 -35
  167. package/src/components/FormSection.vue +0 -37
  168. package/src/components/GroupingModal.story.vue +0 -52
  169. package/src/components/GroupingModal.vue +0 -61
  170. package/src/components/SettingsButton.story.vue +0 -58
  171. package/src/components/SettingsButton.vue +0 -64
  172. package/src/components/ToastNotification.vue +0 -9
  173. package/src/composables/usePluginApi.ts +0 -32
  174. package/src/styles/components/settings-button.css +0 -31
  175. /package/dist/__tests__/components/{AppPageSelector.test.d.ts → AppTopBarPageSelector.test.d.ts} +0 -0
  176. /package/dist/__tests__/components/{AppPillNav.test.d.ts → AppTopBarPillNav.test.d.ts} +0 -0
  177. /package/dist/__tests__/components/{FormCompatibility.test.d.ts → ComponentBindingRenderer.test.d.ts} +0 -0
  178. /package/dist/__tests__/components/{GroupingModal.test.d.ts → DoseDesignWorkspaceView.test.d.ts} +0 -0
  179. /package/dist/__tests__/components/{SettingsButton.test.d.ts → PluginWorkspaceView.test.d.ts} +0 -0
  180. /package/dist/components/{ActionItem.vue.d.ts → internal/ActionItemInternal.vue.d.ts} +0 -0
  181. /package/src/components/{ActionItem.vue → internal/ActionItemInternal.vue} +0 -0
@@ -1036,7 +1036,7 @@ function startOfDay(date) {
1036
1036
  return copy;
1037
1037
  }
1038
1038
  //#endregion
1039
- //#region src/components/CalendarGridPanel.vue?vue&type=script&setup=true&lang.ts
1039
+ //#region src/components/internal/CalendarGridPanelInternal.vue?vue&type=script&setup=true&lang.ts
1040
1040
  var _hoisted_1$11 = { class: "mint-calendar-grid-panel" };
1041
1041
  var _hoisted_2$10 = { class: "mint-date-picker__header" };
1042
1042
  var _hoisted_3$9 = ["aria-label"];
@@ -1051,9 +1051,9 @@ var _hoisted_8$5 = [
1051
1051
  "onClick"
1052
1052
  ];
1053
1053
  //#endregion
1054
- //#region src/components/CalendarGridPanel.vue
1055
- var CalendarGridPanel_default = /* @__PURE__ */ defineComponent({
1056
- __name: "CalendarGridPanel",
1054
+ //#region src/components/internal/CalendarGridPanelInternal.vue
1055
+ var CalendarGridPanelInternal_default = /* @__PURE__ */ defineComponent({
1056
+ __name: "CalendarGridPanelInternal",
1057
1057
  props: {
1058
1058
  weekDays: {},
1059
1059
  monthYear: {},
@@ -1286,7 +1286,7 @@ var DatePicker_default = /* @__PURE__ */ defineComponent({
1286
1286
  role: "dialog",
1287
1287
  "aria-modal": "true",
1288
1288
  "aria-label": "Date picker"
1289
- }, [createVNode(CalendarGridPanel_default, {
1289
+ }, [createVNode(CalendarGridPanelInternal_default, {
1290
1290
  "week-days": unref(weekDays),
1291
1291
  "month-year": unref(monthYear),
1292
1292
  days: unref(calendarDays),
@@ -1393,7 +1393,7 @@ function snapToSlot(time, stepMinutes) {
1393
1393
  const total = toMinutes(time);
1394
1394
  return fromMinutes(Math.round(total / stepMinutes) * stepMinutes);
1395
1395
  }
1396
- function addMinutes(time, minutes) {
1396
+ function addMinutes$1(time, minutes) {
1397
1397
  const total = toMinutes(time) + minutes;
1398
1398
  return fromMinutes(Math.max(0, Math.min(total, 1439)));
1399
1399
  }
@@ -1438,7 +1438,7 @@ function useTimeUtils() {
1438
1438
  isTimeInRange,
1439
1439
  findAvailableSlots,
1440
1440
  snapToSlot,
1441
- addMinutes,
1441
+ addMinutes: addMinutes$1,
1442
1442
  compareTime,
1443
1443
  findNearestTimeSlotIndex,
1444
1444
  toMinutes,
@@ -2643,7 +2643,7 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
2643
2643
  "leave-to-class": "mint-datetime-picker__dropdown-leave-to"
2644
2644
  }, {
2645
2645
  default: withCtx(() => [unref(isOpen) ? (openBlock(), createElementBlock("div", _hoisted_3$4, [
2646
- createElementVNode("div", _hoisted_4$4, [createVNode(CalendarGridPanel_default, {
2646
+ createElementVNode("div", _hoisted_4$4, [createVNode(CalendarGridPanelInternal_default, {
2647
2647
  "week-days": unref(weekDays),
2648
2648
  "month-year": unref(monthYear),
2649
2649
  days: unref(calendarDays),
@@ -4232,9 +4232,14 @@ function getTypeDefault(type) {
4232
4232
  function defineControls(controls) {
4233
4233
  return controls;
4234
4234
  }
4235
- /** Flatten a simple view/section control data model into ControlWorkspaceView props for generated forms and sidebars. */
4235
+ /** Preserve literal SDK component binding ids while marking an object as generated workspace component bindings. */
4236
+ function defineControlComponentBindings(bindings) {
4237
+ return bindings;
4238
+ }
4239
+ /** Create a complete workspace component binding from a simple controls data model for ControlWorkspaceView, generated forms, and sidebars. */
4236
4240
  function defineControlModel(model) {
4237
- const { controls: rootControls, sections: rootSections, views: modelViews, componentProps, componentPropsById, ...baseOptions } = model;
4241
+ const { controls: rootControls, sections: rootSections, views: modelViews, components, componentBindings, componentProps, componentPropsById, ...baseOptions } = model;
4242
+ const resolvedComponentBindings = componentBindings ?? components;
4238
4243
  const controls = {};
4239
4244
  const views = {};
4240
4245
  const sections = {};
@@ -4280,6 +4285,7 @@ function defineControlModel(model) {
4280
4285
  return {
4281
4286
  controls,
4282
4287
  controlOptions,
4288
+ ...resolvedComponentBindings === void 0 ? {} : { componentBindings: resolvedComponentBindings },
4283
4289
  ...componentProps === void 0 ? {} : { componentProps },
4284
4290
  ...componentPropsById === void 0 ? {} : { componentPropsById }
4285
4291
  };
@@ -4302,6 +4308,19 @@ function controlValuesToComponentProps(values, mapping) {
4302
4308
  for (const [prop, source] of Object.entries(mapping)) props[prop] = typeof source === "function" ? source(values) : values[source];
4303
4309
  return props;
4304
4310
  }
4311
+ /** Map control workspace values into named SDK component bindings for direct slot rendering. */
4312
+ function controlValuesToComponentBindings(values, bindings) {
4313
+ if (bindings === void 0) return [];
4314
+ return normalizeControlComponentBindingConfigs(bindings).map((binding) => ({
4315
+ id: binding.id,
4316
+ component: binding.component,
4317
+ props: controlValuesToComponentProps(values, binding.props)
4318
+ }));
4319
+ }
4320
+ /** Map control workspace values into SDK component bindings keyed by binding id. */
4321
+ function controlValuesToComponentBindingsById(values, bindings) {
4322
+ return Object.fromEntries(controlValuesToComponentBindings(values, bindings).map((binding) => [binding.id, binding]));
4323
+ }
4305
4324
  /** Return a default WellPlate prop mapping for generated control workspaces. */
4306
4325
  function defineWellPlateControlProps(options = {}) {
4307
4326
  const selectedWells = options.selectedWells ?? sourceKey("selectedWells");
@@ -4337,6 +4356,18 @@ function defineWellPlateDoseControlProps(options = {}) {
4337
4356
  [options.doseId ?? "dose"]: defineDoseCalculatorControlProps(options.dose)
4338
4357
  };
4339
4358
  }
4359
+ /** Return named WellPlate + DoseCalculator component bindings for one dose-design control model. */
4360
+ function defineWellPlateDoseComponentBindings(options = {}) {
4361
+ return [{
4362
+ id: options.plateId ?? "plate",
4363
+ component: "WellPlate",
4364
+ props: defineWellPlateControlProps(options.plate)
4365
+ }, {
4366
+ id: options.doseId ?? "dose",
4367
+ component: "DoseCalculator",
4368
+ props: defineDoseCalculatorControlProps(options.dose)
4369
+ }];
4370
+ }
4340
4371
  /** Return a complete ControlWorkspaceView model for WellPlate + DoseCalculator dose design. */
4341
4372
  function defineDoseDesignControlModel(options = {}) {
4342
4373
  const viewId = options.viewId ?? "design";
@@ -4372,14 +4403,16 @@ function defineDoseDesignControlModel(options = {}) {
4372
4403
  default: options.molecularWeight ?? 300,
4373
4404
  min: 0
4374
4405
  };
4406
+ const componentProps = {
4407
+ ...options.componentProps,
4408
+ dose: {
4409
+ ...options.componentProps?.dose ?? {},
4410
+ ...options.includeMolecularWeight && options.componentProps?.dose?.molecularWeight === void 0 ? { molecularWeight: "molecularWeight" } : {}
4411
+ }
4412
+ };
4375
4413
  return defineControlModel({
4376
- componentPropsById: defineWellPlateDoseControlProps({
4377
- ...options.componentProps,
4378
- dose: {
4379
- ...options.componentProps?.dose ?? {},
4380
- ...options.includeMolecularWeight && options.componentProps?.dose?.molecularWeight === void 0 ? { molecularWeight: "molecularWeight" } : {}
4381
- }
4382
- }),
4414
+ componentBindings: defineWellPlateDoseComponentBindings(componentProps),
4415
+ componentPropsById: defineWellPlateDoseControlProps(componentProps),
4383
4416
  views: { [viewId]: {
4384
4417
  label: options.viewLabel ?? "Design",
4385
4418
  sections: { [sectionId]: {
@@ -4483,14 +4516,10 @@ function controlsToTopBarSettingsConfig(controls, options = {}, config = {}) {
4483
4516
  function controlsToViewIds(controls, options = {}) {
4484
4517
  return controlsToViewItems(controls, options).map((item) => item.id);
4485
4518
  }
4486
- /** Return AppPillNav-compatible view items for switching generated control sidebars. */
4519
+ /** Return AppTopBar pillNav-compatible view items for switching generated control sidebars. */
4487
4520
  function controlsToViewItems(controls, options = {}) {
4488
4521
  return Object.entries(controlsToSidebarPanels(controls, options)).filter(([, sections]) => sections.length > 0).map(([id]) => controlViewItem(id, options));
4489
4522
  }
4490
- /** Return AppTopBar-compatible tabs for the same views that drive generated AppSidebar panels. */
4491
- function controlsToTopBarTabs(controls, options = {}) {
4492
- return Object.entries(controlsToSidebarPanels(controls, options)).filter(([, sections]) => sections.length > 0).map(([id]) => controlTopBarTab(id, options));
4493
- }
4494
4523
  /** Return the first generated sidebar view ID, or an empty string when controls render no sidebar panels. */
4495
4524
  function getDefaultControlView(controls, options = {}) {
4496
4525
  return controlsToViewIds(controls, options)[0] ?? "";
@@ -4533,7 +4562,6 @@ function useControlSchema(controls, options = {}) {
4533
4562
  const sidebarPanels = controlsToSidebarPanels(controls, options);
4534
4563
  const viewItems = controlsToViewItems(controls, options);
4535
4564
  const viewIds = viewItems.map((item) => item.id);
4536
- const topBarTabs = controlsToTopBarTabs(controls, options);
4537
4565
  const defaultView = viewIds[0] ?? "";
4538
4566
  const sectionSchemas = controlsToSectionFormSchemas(controls, options);
4539
4567
  return {
@@ -4551,7 +4579,6 @@ function useControlSchema(controls, options = {}) {
4551
4579
  sidebarPanels,
4552
4580
  viewIds,
4553
4581
  viewItems,
4554
- topBarTabs,
4555
4582
  defaultView,
4556
4583
  sectionSchemas,
4557
4584
  sidebar: {
@@ -4583,7 +4610,6 @@ function useControlWorkspace(controlsOrModel, options = {}) {
4583
4610
  if (!schema.viewIds.includes(viewId)) return;
4584
4611
  if (activeView.value !== viewId) activeView.value = viewId;
4585
4612
  if (sidebar.activeView !== viewId) sidebar.activeView = viewId;
4586
- if (topBar.currentTabId !== viewId) topBar.currentTabId = viewId;
4587
4613
  if (pillNav.currentItemId !== viewId) pillNav.currentItemId = viewId;
4588
4614
  }
4589
4615
  function setValues(nextValues) {
@@ -4602,8 +4628,16 @@ function useControlWorkspace(controlsOrModel, options = {}) {
4602
4628
  if (mappings === void 0) return {};
4603
4629
  return Object.fromEntries(Object.entries(mappings).map(([id, mapping]) => [id, controlValuesToComponentProps(values, mapping)]));
4604
4630
  }
4631
+ function getComponentBindings(bindings) {
4632
+ return controlValuesToComponentBindings(values, bindings);
4633
+ }
4634
+ function getComponentBindingsById(bindings) {
4635
+ return controlValuesToComponentBindingsById(values, bindings);
4636
+ }
4605
4637
  const componentProps = computed(() => model?.componentProps === void 0 ? {} : getComponentProps(model.componentProps));
4606
4638
  const componentPropsById = computed(() => getComponentPropsById(model?.componentPropsById));
4639
+ const componentBindings = computed(() => getComponentBindings(model?.componentBindings));
4640
+ const componentBindingsById = computed(() => getComponentBindingsById(model?.componentBindings));
4607
4641
  const form = {
4608
4642
  ...schema.form,
4609
4643
  modelValue: values,
@@ -4622,11 +4656,6 @@ function useControlWorkspace(controlsOrModel, options = {}) {
4622
4656
  values,
4623
4657
  "onUpdate:values": setValues
4624
4658
  });
4625
- const topBar = reactive({
4626
- tabs: schema.topBarTabs,
4627
- currentTabId: activeView.value,
4628
- onTabSelect: (tab) => setActiveView(tab.id)
4629
- });
4630
4659
  const pillNav = reactive({
4631
4660
  items: schema.viewItems,
4632
4661
  currentItemId: activeView.value,
@@ -4637,29 +4666,25 @@ function useControlWorkspace(controlsOrModel, options = {}) {
4637
4666
  settingsConfig: topBarSettingsConfig,
4638
4667
  onSettingsValuesChange: setValues
4639
4668
  };
4669
+ const topBarProps = computed(() => ({
4670
+ pillNav: pillNav.items,
4671
+ currentPillId: pillNav.currentItemId,
4672
+ onPillSelect: pillNav.onSelect,
4673
+ ...topBarSettingsBinding
4674
+ }));
4640
4675
  const bindings = {
4641
4676
  form,
4642
4677
  sidebar,
4643
- topBar: computed(() => ({
4644
- pillNav: pillNav.items,
4645
- currentPillId: pillNav.currentItemId,
4646
- onPillSelect: pillNav.onSelect,
4647
- ...topBarSettingsBinding
4648
- })),
4649
- topBarTabs: computed(() => ({
4650
- tabs: topBar.tabs,
4651
- currentTabId: topBar.currentTabId,
4652
- onTabSelect: topBar.onTabSelect,
4653
- ...topBarSettingsBinding
4654
- })),
4678
+ topBar: topBarProps,
4655
4679
  topBarSettings: topBarSettingsBinding,
4656
4680
  pillNav,
4681
+ componentBindings,
4682
+ componentBindingsById,
4657
4683
  componentProps,
4658
4684
  componentPropsById
4659
4685
  };
4660
4686
  watch(activeView, syncActiveView, { flush: "sync" });
4661
4687
  watch(() => sidebar.activeView, syncActiveView, { flush: "sync" });
4662
- watch(() => topBar.currentTabId, syncActiveView, { flush: "sync" });
4663
4688
  watch(() => pillNav.currentItemId, syncActiveView, { flush: "sync" });
4664
4689
  return {
4665
4690
  ...schema,
@@ -4669,17 +4694,21 @@ function useControlWorkspace(controlsOrModel, options = {}) {
4669
4694
  topBarSettingsConfig,
4670
4695
  form,
4671
4696
  sidebar,
4672
- topBar,
4697
+ topBar: topBarProps,
4673
4698
  pillNav,
4674
4699
  topBarSettings: topBarSettingsBinding,
4675
4700
  bindings,
4701
+ componentBindings,
4702
+ componentBindingsById,
4676
4703
  componentProps,
4677
4704
  componentPropsById,
4678
4705
  setActiveView,
4679
4706
  setValues,
4680
4707
  resetValues,
4681
4708
  getComponentProps,
4682
- getComponentPropsById
4709
+ getComponentPropsById,
4710
+ getComponentBindings,
4711
+ getComponentBindingsById
4683
4712
  };
4684
4713
  }
4685
4714
  function normalizeControls(controls, options = {}) {
@@ -4825,6 +4854,26 @@ function optionValue(option) {
4825
4854
  function compactComponentPropsMap(mapping) {
4826
4855
  return Object.fromEntries(Object.entries(mapping).filter((entry) => entry[1] !== void 0));
4827
4856
  }
4857
+ function normalizeControlComponentBindingConfigs(bindings) {
4858
+ if (Array.isArray(bindings)) {
4859
+ const usedIds = /* @__PURE__ */ new Map();
4860
+ return bindings.map((binding) => ({
4861
+ id: uniqueComponentBindingId(binding.id ?? binding.component, usedIds),
4862
+ component: binding.component,
4863
+ props: binding.props
4864
+ }));
4865
+ }
4866
+ return Object.entries(bindings).map(([id, binding]) => ({
4867
+ id,
4868
+ component: binding.component,
4869
+ props: binding.props
4870
+ }));
4871
+ }
4872
+ function uniqueComponentBindingId(id, usedIds) {
4873
+ const count = usedIds.get(id) ?? 0;
4874
+ usedIds.set(id, count + 1);
4875
+ return count === 0 ? id : `${id}-${count + 1}`;
4876
+ }
4828
4877
  function sourceKey(key) {
4829
4878
  return key;
4830
4879
  }
@@ -4880,17 +4929,6 @@ function controlViewItem(viewId, options) {
4880
4929
  ...config?.icon !== void 0 ? { icon: config.icon } : {},
4881
4930
  ...config?.to !== void 0 ? { to: config.to } : {},
4882
4931
  ...config?.href !== void 0 ? { href: config.href } : {},
4883
- ...config?.disabled !== void 0 ? { disabled: config.disabled } : {}
4884
- };
4885
- }
4886
- function controlTopBarTab(viewId, options) {
4887
- const config = options.views?.[viewId];
4888
- return {
4889
- id: viewId,
4890
- label: config?.label ?? humanize(viewId),
4891
- ...config?.to !== void 0 ? { to: config.to } : {},
4892
- ...config?.href !== void 0 ? { href: config.href } : {},
4893
- ...config?.icon !== void 0 ? { icon: config.icon } : {},
4894
4932
  ...config?.disabled !== void 0 ? { disabled: config.disabled } : {},
4895
4933
  ...config?.children !== void 0 ? { children: config.children } : {}
4896
4934
  };
@@ -5142,12 +5180,13 @@ var bioTemplateCatalog = [
5142
5180
  ],
5143
5181
  python_import: "from mint_sdk.templates import AssayMatrixTemplate, save_template",
5144
5182
  python_example: "AssayMatrixTemplate.create(samples=[\"S001\", \"S002\"], features=[\"Lactate\", \"Glucose\"])",
5145
- frontend_import: "import { toTemplateDataFrame } from '@morscherlab/mint-sdk/templates'",
5183
+ frontend_import: "import { toAssayMatrixSampleOptions, toTemplateDataFrame } from '@morscherlab/mint-sdk/templates'",
5146
5184
  frontend_adapters: [
5147
5185
  "toTemplateDataFrame",
5148
5186
  "toAssayMatrixDataFrame",
5149
5187
  "toAssayMatrixRows",
5150
- "toAssayMatrixColumns"
5188
+ "toAssayMatrixColumns",
5189
+ "toAssayMatrixSampleOptions"
5151
5190
  ],
5152
5191
  components: [
5153
5192
  "DataFrame",
@@ -5231,15 +5270,18 @@ var bioTemplateCatalog = [
5231
5270
  ],
5232
5271
  python_import: "from mint_sdk.templates import InstrumentRunTemplate, save_template",
5233
5272
  python_example: "InstrumentRunTemplate.create([\"S001\", \"S002\"], instrument=\"LC-MS\")",
5234
- frontend_import: "import { toInstrumentRunDataFrame, toTemplateDataFrame } from '@morscherlab/mint-sdk/templates'",
5273
+ frontend_import: "import { toInstrumentRunDataFrame, toInstrumentRunScheduleEvents, toInstrumentRunSteps, toTemplateDataFrame } from '@morscherlab/mint-sdk/templates'",
5235
5274
  frontend_adapters: [
5236
5275
  "toTemplateDataFrame",
5237
5276
  "toInstrumentRunDataFrame",
5238
5277
  "toInstrumentRunRows",
5239
- "toInstrumentRunColumns"
5278
+ "toInstrumentRunColumns",
5279
+ "toInstrumentRunSteps",
5280
+ "toInstrumentRunScheduleEvents"
5240
5281
  ],
5241
5282
  components: [
5242
5283
  "DataFrame",
5284
+ "ExperimentTimeline",
5243
5285
  "ScheduleCalendar",
5244
5286
  "SampleSelector"
5245
5287
  ],
@@ -5368,6 +5410,8 @@ var bioTemplatePacks = [
5368
5410
  aliases: [
5369
5411
  "omics",
5370
5412
  "metabolomics",
5413
+ "metabolism",
5414
+ "metabolite profiling",
5371
5415
  "proteomics",
5372
5416
  "assay matrix",
5373
5417
  "lcms",
@@ -5522,19 +5566,26 @@ var bioTemplatePresets = [
5522
5566
  "lc-ms",
5523
5567
  "mass spec batch",
5524
5568
  "omics batch",
5569
+ "metabolomics",
5570
+ "metabolism",
5571
+ "metabolite profiling",
5525
5572
  "run queue",
5526
5573
  "sequence table"
5527
5574
  ],
5528
5575
  python_import: "from mint_sdk.templates import create_lcms_batch_collection, save_template_collection",
5529
5576
  python_example: "create_lcms_batch_collection(samples=[\"S001\", \"S002\"], features=[\"Glucose\", \"Lactate\"], instrument=\"LC-MS\")",
5530
- frontend_import: "import { createLcmsBatchCollection, toInstrumentRunDataFrame, toTemplateDataFrame } from '@morscherlab/mint-sdk/templates'",
5577
+ frontend_import: "import { createLcmsBatchCollection, toAssayMatrixSampleOptions, toInstrumentRunDataFrame, toInstrumentRunScheduleEvents, toInstrumentRunSteps, toTemplateDataFrame } from '@morscherlab/mint-sdk/templates'",
5531
5578
  frontend_adapters: [
5532
5579
  "toTemplateDataFrame",
5533
5580
  "toInstrumentRunDataFrame",
5534
- "toAssayMatrixDataFrame"
5581
+ "toInstrumentRunSteps",
5582
+ "toInstrumentRunScheduleEvents",
5583
+ "toAssayMatrixDataFrame",
5584
+ "toAssayMatrixSampleOptions"
5535
5585
  ],
5536
5586
  components: [
5537
5587
  "DataFrame",
5588
+ "ExperimentTimeline",
5538
5589
  "ScheduleCalendar",
5539
5590
  "ChartContainer",
5540
5591
  "SampleSelector"
@@ -7641,6 +7692,16 @@ function toAssayMatrixDataFrame(template) {
7641
7692
  rowKey: "sampleId"
7642
7693
  };
7643
7694
  }
7695
+ /** Convert an assay-matrix template into SampleSelector options derived from assay samples. */
7696
+ function toAssayMatrixSampleOptions(template) {
7697
+ const data = getTemplateData(template, "assay-matrix");
7698
+ validateAssayMatrixData(data);
7699
+ return data.samples.map((sample) => ({
7700
+ value: sample.sampleId,
7701
+ label: sample.name ?? sample.sampleId,
7702
+ description: sample.group
7703
+ }));
7704
+ }
7644
7705
  function toReagentListItems(template) {
7645
7706
  const data = getTemplateData(template, "reagent-list");
7646
7707
  validateReagentListData(data);
@@ -7902,6 +7963,88 @@ function toInstrumentRunDataFrame(template) {
7902
7963
  rowKey: "id"
7903
7964
  };
7904
7965
  }
7966
+ /** Convert an instrument-run template into ExperimentTimeline protocol steps for acquisition queue previews. */
7967
+ function toInstrumentRunSteps(template) {
7968
+ const data = getTemplateData(template, "instrument-run");
7969
+ validateInstrumentRunData(data);
7970
+ const methods = new Map(data.methods.map((method) => [method.id, method]));
7971
+ return [...data.items].sort((a, b) => a.order - b.order).map((item) => {
7972
+ const method = methods.get(item.methodId);
7973
+ const name = item.name ?? item.sampleId ?? item.kind;
7974
+ return {
7975
+ id: item.id,
7976
+ type: instrumentRunStepType(item.kind),
7977
+ name,
7978
+ description: [
7979
+ item.kind,
7980
+ method?.name,
7981
+ item.vial ? `Vial ${item.vial}` : void 0,
7982
+ item.wellId ? `Well ${item.wellId}` : void 0
7983
+ ].filter(Boolean).join(" / "),
7984
+ duration: item.expectedDurationMin,
7985
+ status: instrumentRunStepStatus(item.status),
7986
+ parameters: {
7987
+ kind: item.kind,
7988
+ sampleId: item.sampleId,
7989
+ methodId: item.methodId,
7990
+ method: method?.name,
7991
+ vial: item.vial,
7992
+ plateId: item.plateId,
7993
+ wellId: item.wellId,
7994
+ injectionVolume: item.injectionVolume,
7995
+ instrument: data.instrument ?? method?.instrument
7996
+ },
7997
+ order: item.order
7998
+ };
7999
+ });
8000
+ }
8001
+ /** Convert an instrument-run template into readonly ScheduleCalendar events ordered by run queue timing. */
8002
+ function toInstrumentRunScheduleEvents(template) {
8003
+ const data = getTemplateData(template, "instrument-run");
8004
+ validateInstrumentRunData(data);
8005
+ const methods = new Map(data.methods.map((method) => [method.id, method]));
8006
+ let cursor = dateFromMetadata(data.metadata, [
8007
+ "scheduledStart",
8008
+ "runStart",
8009
+ "start",
8010
+ "startedAt"
8011
+ ]) ?? /* @__PURE__ */ new Date("2024-01-01T08:00:00.000Z");
8012
+ return [...data.items].sort((a, b) => a.order - b.order).map((item) => {
8013
+ const method = methods.get(item.methodId);
8014
+ const start = dateFromMetadata(item.metadata, [
8015
+ "scheduledStart",
8016
+ "start",
8017
+ "startedAt"
8018
+ ]) ?? cursor;
8019
+ const end = dateFromMetadata(item.metadata, [
8020
+ "scheduledEnd",
8021
+ "end",
8022
+ "completedAt"
8023
+ ]) ?? addMinutes(start, Math.max(item.expectedDurationMin ?? 10, 1));
8024
+ cursor = end;
8025
+ return {
8026
+ id: item.id,
8027
+ title: item.name ?? item.sampleId ?? item.kind,
8028
+ start: start.toISOString(),
8029
+ end: end.toISOString(),
8030
+ color: instrumentRunScheduleColor(item.kind),
8031
+ status: instrumentRunScheduleStatus(item.status),
8032
+ draggable: false,
8033
+ resizable: false,
8034
+ metadata: {
8035
+ kind: item.kind,
8036
+ sampleId: item.sampleId,
8037
+ methodId: item.methodId,
8038
+ method: method?.name,
8039
+ vial: item.vial,
8040
+ plateId: item.plateId,
8041
+ wellId: item.wellId,
8042
+ injectionVolume: item.injectionVolume,
8043
+ instrument: data.instrument ?? method?.instrument
8044
+ }
8045
+ };
8046
+ });
8047
+ }
7905
8048
  function toQpcrRows(template) {
7906
8049
  const data = getTemplateData(template, "qpcr-plate");
7907
8050
  validateQpcrPlateData(data);
@@ -8039,6 +8182,58 @@ function sampleColumnKey(columnId) {
8039
8182
  well_id: "wellId"
8040
8183
  }[columnId] ?? columnId;
8041
8184
  }
8185
+ function instrumentRunStepType(kind) {
8186
+ switch (kind) {
8187
+ case "wash": return "wash";
8188
+ case "blank":
8189
+ case "qc":
8190
+ case "standard":
8191
+ case "calibration":
8192
+ case "sample": return "measurement";
8193
+ default: return "custom";
8194
+ }
8195
+ }
8196
+ function instrumentRunStepStatus(status) {
8197
+ switch (status) {
8198
+ case "running": return "in_progress";
8199
+ case "completed": return "completed";
8200
+ case "failed": return "failed";
8201
+ case "skipped": return "skipped";
8202
+ default: return "pending";
8203
+ }
8204
+ }
8205
+ function instrumentRunScheduleStatus(status) {
8206
+ switch (status) {
8207
+ case "running": return "in-progress";
8208
+ case "completed": return "confirmed";
8209
+ case "failed":
8210
+ case "skipped": return "cancelled";
8211
+ default: return "pending";
8212
+ }
8213
+ }
8214
+ function instrumentRunScheduleColor(kind) {
8215
+ switch (kind) {
8216
+ case "blank": return "#64748b";
8217
+ case "qc": return "#8b5cf6";
8218
+ case "standard":
8219
+ case "calibration": return "#f59e0b";
8220
+ case "wash": return "#06b6d4";
8221
+ case "sample": return "#2563eb";
8222
+ default: return "#475569";
8223
+ }
8224
+ }
8225
+ function dateFromMetadata(metadata, keys) {
8226
+ if (!metadata) return void 0;
8227
+ for (const key of keys) {
8228
+ const value = metadata[key];
8229
+ if (!(typeof value === "string" || value instanceof Date)) continue;
8230
+ const date = new Date(value);
8231
+ if (!Number.isNaN(date.getTime())) return date;
8232
+ }
8233
+ }
8234
+ function addMinutes(date, minutes) {
8235
+ return new Date(date.getTime() + minutes * 6e4);
8236
+ }
8042
8237
  //#endregion
8043
8238
  //#region src/templates/componentBindings.ts
8044
8239
  var templateComponentBindings = {
@@ -8091,7 +8286,7 @@ var templateComponentBindings = {
8091
8286
  "data",
8092
8287
  "columns",
8093
8288
  "rowKey"
8094
- ], "Render sample-by-feature measurements.")],
8289
+ ], "Render sample-by-feature measurements."), binding("assay-matrix", "SampleSelector", ["toAssayMatrixSampleOptions"], ["samples", "modelValue"], "Select samples from assay-matrix records.")],
8095
8290
  "reagent-list": [binding("reagent-list", "ReagentList", ["toReagentListItems"], ["modelValue"], "Render reagents with lot, storage, and stock metadata."), binding("reagent-list", "DataFrame", ["toTemplateDataFrame"], [
8096
8291
  "data",
8097
8292
  "columns",
@@ -8102,11 +8297,27 @@ var templateComponentBindings = {
8102
8297
  "columns",
8103
8298
  "rowKey"
8104
8299
  ], "Render markers, fluorophores, detectors, and controls.")],
8105
- "instrument-run": [binding("instrument-run", "DataFrame", ["toTemplateDataFrame"], [
8106
- "data",
8107
- "columns",
8108
- "rowKey"
8109
- ], "Render acquisition queues, methods, QC, and run status.")],
8300
+ "instrument-run": [
8301
+ binding("instrument-run", "DataFrame", ["toTemplateDataFrame"], [
8302
+ "data",
8303
+ "columns",
8304
+ "rowKey"
8305
+ ], "Render acquisition queues, methods, QC, and run status."),
8306
+ binding("instrument-run", "ScheduleCalendar", ["toInstrumentRunScheduleEvents"], [
8307
+ "modelValue",
8308
+ "events",
8309
+ "view",
8310
+ "readonly",
8311
+ "showNavigation",
8312
+ "showViewToggle"
8313
+ ], "Render acquisition queues as a scheduled run calendar."),
8314
+ binding("instrument-run", "ExperimentTimeline", ["toInstrumentRunSteps"], [
8315
+ "modelValue",
8316
+ "orientation",
8317
+ "showDuration",
8318
+ "editable"
8319
+ ], "Render acquisition queues as an ordered run timeline.")
8320
+ ],
8110
8321
  "qpcr-plate": [binding("qpcr-plate", "WellPlate", ["toQpcrWellPlateWells"], [
8111
8322
  "format",
8112
8323
  "wells",
@@ -8129,6 +8340,14 @@ function toBioTemplateComponentProps(target) {
8129
8340
  const collection = extractTemplateCollection(target);
8130
8341
  return Object.values(collection).flatMap((template) => propsForTemplate(template));
8131
8342
  }
8343
+ /** Return resolved component bindings with concrete props for direct slot rendering. */
8344
+ function toBioTemplateComponentBindings(target) {
8345
+ return toBioTemplateComponentProps(target).map(toResolvedComponentBinding);
8346
+ }
8347
+ /** Return resolved component bindings keyed by stable template component id. */
8348
+ function toBioTemplateComponentBindingsById(target) {
8349
+ return Object.fromEntries(toBioTemplateComponentBindings(target).map((binding) => [binding.id, binding]));
8350
+ }
8132
8351
  /** Return component props keyed by stable binding id for direct `v-bind="componentPropsById[id]"` use. */
8133
8352
  function toBioTemplateComponentPropsById(target) {
8134
8353
  return Object.fromEntries(toBioTemplateComponentProps(target).map((binding) => [binding.id, binding.propsObject]));
@@ -8152,6 +8371,15 @@ function getBioTemplateComponentProps(target, component, options = {}) {
8152
8371
  return true;
8153
8372
  })?.propsObject;
8154
8373
  }
8374
+ function toResolvedComponentBinding(binding) {
8375
+ const { props: propNames, propsObject, ...rest } = binding;
8376
+ return {
8377
+ ...rest,
8378
+ propNames,
8379
+ props: propsObject,
8380
+ propsObject
8381
+ };
8382
+ }
8155
8383
  function toBioTemplateComponentImports(target) {
8156
8384
  const groups = /* @__PURE__ */ new Map();
8157
8385
  for (const binding of getBioTemplateComponentBindings(target)) {
@@ -8214,9 +8442,13 @@ function propsForTemplate(template) {
8214
8442
  case "sample-sheet": return [dataFrameProps(template), sampleSelectorProps(template)];
8215
8443
  case "sample-prep":
8216
8444
  case "calibration-curve":
8217
- case "assay-matrix":
8218
- case "flow-cytometry-panel":
8219
- case "instrument-run": return [dataFrameProps(template)];
8445
+ case "flow-cytometry-panel": return [dataFrameProps(template)];
8446
+ case "assay-matrix": return [dataFrameProps(template), assayMatrixSampleSelectorProps(template)];
8447
+ case "instrument-run": return [
8448
+ dataFrameProps(template),
8449
+ scheduleCalendarProps(template),
8450
+ timelineProps(template, toInstrumentRunSteps(template))
8451
+ ];
8220
8452
  case "dose-response": return doseResponseProps(template);
8221
8453
  case "time-course": return [timelineProps(template, toTimeCourseSteps(template)), dataFrameProps(template)];
8222
8454
  case "protocol-steps": return [timelineProps(template, toProtocolSteps(template), true), dataFrameProps(template)];
@@ -8297,6 +8529,12 @@ function sampleSelectorProps(template) {
8297
8529
  modelValue: []
8298
8530
  });
8299
8531
  }
8532
+ function assayMatrixSampleSelectorProps(template) {
8533
+ return propsBinding("assay-matrix", "SampleSelector", {
8534
+ samples: toAssayMatrixSampleOptions(template).map((option) => option.label),
8535
+ modelValue: []
8536
+ });
8537
+ }
8300
8538
  function timelineProps(template, steps, editable = false) {
8301
8539
  return propsBinding(template.template_id, "ExperimentTimeline", {
8302
8540
  modelValue: steps,
@@ -8304,6 +8542,17 @@ function timelineProps(template, steps, editable = false) {
8304
8542
  editable
8305
8543
  });
8306
8544
  }
8545
+ function scheduleCalendarProps(template) {
8546
+ const events = toInstrumentRunScheduleEvents(template);
8547
+ return propsBinding("instrument-run", "ScheduleCalendar", {
8548
+ modelValue: events[0]?.start,
8549
+ events,
8550
+ view: "day",
8551
+ readonly: true,
8552
+ showNavigation: false,
8553
+ showViewToggle: false
8554
+ });
8555
+ }
8307
8556
  function reagentListProps(template) {
8308
8557
  return propsBinding("reagent-list", "ReagentList", {
8309
8558
  modelValue: toReagentListItems(template),
@@ -9328,6 +9577,6 @@ function capitalize(value) {
9328
9577
  return value.charAt(0).toUpperCase() + value.slice(1);
9329
9578
  }
9330
9579
  //#endregion
9331
- export { toTemplateDataFrame as $, generateTimeSlots as $n, bioTemplatePacks as $t, toInstrumentRunColumns as A, ConcentrationInput_default as An, createTimeCourseTemplate as At, toQpcrRows as B, FileUploader_default as Bn, validateFlowCytometryPanelData as Bt, toCalibrationCurveDataFrame as C, getControlDefaults as Cn, createQpcrExpressionCollection as Ct, toFlowPanelColumns as D, useControlWorkspace as Dn, createSampleSheetTemplate as Dt, toDoseLayoutState as E, useControlSchema as En, createSamplePrepTemplate as Et, toProtocolDataFrame as F, useSequenceUtils as Fn, extractTemplateCollection as Ft, toReagentRows as G, compareTime as Gn, validateReagentListData as Gt, toReagentColumns as H, TagsInput_default as Hn, validatePlateMapData as Ht, toProtocolRows as I, FormulaInput_default as In, getTemplateData as It, toSampleOptions as J, findNearestTimeSlotIndex as Jn, validateTimeCourseData as Jt, toSampleColumns as K, durationMinutes as Kn, validateSamplePrepData as Kt, toProtocolSteps as L, ATOMIC_WEIGHTS as Ln, validateAssayMatrixData as Lt, toInstrumentRunRows as M, useConcentrationUnits as Mn, createWesternBlotAssayCollection as Mt, toPlateMapEditorState as N, MoleculeInput_default as Nn, ensureTemplateEnvelope as Nt, toFlowPanelDataFrame as O, getFieldRegistryEntry as On, createTemplateCollection as Ot, toProtocolColumns as P, SequenceInput_default as Pn, ensureTemplateFromCollection as Pt, toSampleRows as Q, fromMinutes as Qn, searchBioTemplatePresets as Qt, toQpcrColumns as R, useChemicalFormula as Rn, validateCalibrationCurveData as Rt, toCalibrationCurveColumns as S, defineWellPlateDoseControlProps as Sn, createProtocolStepsTemplate as St, toDoseConditions as T, mergeControlWorkspaceOptions as Tn, createReagentListTemplate as Tt, toReagentDataFrame as U, TimePicker_default as Un, validateProtocolStepsData as Ut, toQpcrWellPlateWells as V, NumberInput_default as Vn, validateInstrumentRunData as Vt, toReagentListItems as W, addMinutes as Wn, validateQpcrPlateData as Wt, toSamplePrepDataFrame as X, formatTime as Xn, getBioTemplatePresetInfo as Xt, toSamplePrepColumns as Y, formatDuration as Yn, bioTemplatePresets as Yt, toSamplePrepRows as Z, formatTimeSlot as Zn, listBioTemplatePresets as Zt, toBioTemplateComponentSnippets as _, defineControlModel as _n, normalizeOptionInput as _r, createFlowCytometryAssayCollection as _t, getBioTemplateControlDefaults as a, listBioTemplateCatalog as an, useTimeUtils as ar, toWellPlateWells as at, toAssayMatrixDataFrame as b, defineDoseDesignControlModel as bn, createLcmsBatchCollection as bt, listBioTemplatePresetControlSchemas as c, controlsToFormSchema as cn, MultiSelect_default as cr, bioTemplatePresetControlValuesToOptions as ct, getBioTemplateComponentProps as d, controlsToSettingsSchema as dn, useEventListener as dr, createBioTemplatePresetCollection as dt, getBioTemplatePackInfo as en, isTimeInRange as er, toTimeCourseColumns as et, listBioTemplateComponentBindings as f, controlsToSidebarPanels as fn, BaseSlider_default as fr, createBioTemplatePresetCollectionFromControls as ft, toBioTemplateComponentPropsById as g, controlsToViewItems as gn, BaseSelect_default as gr, createElisaAssayCollection as gt, toBioTemplateComponentPropsByComponent as h, controlsToViewIds as hn, BaseCheckbox_default as hr, createDoseResponseTemplate as ht, createBioTemplateControlToolkit as i, getBioTemplateInfo as in, toMinutes as ir, toWellMapArray as it, toInstrumentRunDataFrame as j, UnitInput_default as jn, createWellPlateScreenCollection as jt, toFlowPanelRows as k, getTypeDefault as kn, createTemplateEnvelope as kt, requireBioTemplateControlSchema as l, controlsToSectionFormSchema as ln, useListSelection as lr, createAssayMatrixTemplate as lt, toBioTemplateComponentProps as m, controlsToTopBarTabs as mn, BaseToggle_default as mr, createDefaultBioTemplate as mt, bioTemplateControlsToSectionFormSchemas as n, searchBioTemplatePacks as nn, rangesOverlap as nr, toTimeCourseRows as nt, getBioTemplateControlSchema as o, searchBioTemplateCatalog as on, DatePicker_default as or, TEMPLATE_COLLECTION_KEY as ot, toBioTemplateComponentImports as p, controlsToTopBarSettingsConfig as pn, BaseRadioGroup_default as pr, createCalibrationCurveTemplate as pt, toSampleDataFrame as q, findAvailableSlots as qn, validateSampleSheetData as qt, bioTemplateControlsToSidebarPanels as r, bioTemplateCatalog as rn, snapToSlot as rr, toTimeCourseSteps as rt, listBioTemplateControlSchemas as s, controlValuesToComponentProps as sn, useDropdownState as sr, assertTemplateEnvelope as st, bioTemplateControlsToFormSchema as t, listBioTemplatePacks as tn, parseTime as tr, toTimeCourseDataFrame as tt, getBioTemplateComponentBindings as u, controlsToSectionFormSchemas as un, useSelectionLimit as ur, createBioTemplatePackCollection as ut, toBioTemplateComponentUsage as v, defineControls as vn, BaseTextarea_default as vr, createFlowCytometryPanelTemplate as vt, toCalibrationCurveRows as w, getDefaultControlView as wn, createQpcrPlateTemplate as wt, toAssayMatrixRows as x, defineWellPlateControlProps as xn, createPlateMapTemplate as xt, toAssayMatrixColumns as y, defineDoseCalculatorControlProps as yn, BaseInput_default as yr, createInstrumentRunTemplate as yt, toQpcrDataFrame as z, DateTimePicker_default as zn, validateDoseResponseData as zt };
9580
+ export { toSampleOptions as $, compareTime as $n, validateTimeCourseData as $t, toFlowPanelColumns as A, defineWellPlateDoseControlProps as An, createReagentListTemplate as At, toProtocolDataFrame as B, useConcentrationUnits as Bn, extractTemplateCollection as Bt, toAssayMatrixRows as C, defineControlComponentBindings as Cn, BaseCheckbox_default as Cr, createFlowCytometryPanelTemplate as Ct, toCalibrationCurveRows as D, defineDoseDesignControlModel as Dn, BaseInput_default as Dr, createProtocolStepsTemplate as Dt, toCalibrationCurveDataFrame as E, defineDoseCalculatorControlProps as En, BaseTextarea_default as Er, createPlateMapTemplate as Et, toInstrumentRunRows as F, useControlWorkspace as Fn, createTimeCourseTemplate as Ft, toQpcrRows as G, ATOMIC_WEIGHTS as Gn, validateFlowCytometryPanelData as Gt, toProtocolSteps as H, SequenceInput_default as Hn, validateAssayMatrixData as Ht, toInstrumentRunScheduleEvents as I, getFieldRegistryEntry as In, createWellPlateScreenCollection as It, toReagentDataFrame as J, FileUploader_default as Jn, validateProtocolStepsData as Jt, toQpcrWellPlateWells as K, useChemicalFormula as Kn, validateInstrumentRunData as Kt, toInstrumentRunSteps as L, getTypeDefault as Ln, createWesternBlotAssayCollection as Lt, toFlowPanelRows as M, getDefaultControlView as Mn, createSampleSheetTemplate as Mt, toInstrumentRunColumns as N, mergeControlWorkspaceOptions as Nn, createTemplateCollection as Nt, toDoseConditions as O, defineWellPlateControlProps as On, createQpcrExpressionCollection as Ot, toInstrumentRunDataFrame as P, useControlSchema as Pn, createTemplateEnvelope as Pt, toSampleDataFrame as Q, addMinutes$1 as Qn, validateSampleSheetData as Qt, toPlateMapEditorState as R, ConcentrationInput_default as Rn, ensureTemplateEnvelope as Rt, toAssayMatrixDataFrame as S, controlsToViewItems as Sn, BaseToggle_default as Sr, createFlowCytometryAssayCollection as St, toCalibrationCurveColumns as T, defineControls as Tn, normalizeOptionInput as Tr, createLcmsBatchCollection as Tt, toQpcrColumns as U, useSequenceUtils as Un, validateCalibrationCurveData as Ut, toProtocolRows as V, MoleculeInput_default as Vn, getTemplateData as Vt, toQpcrDataFrame as W, FormulaInput_default as Wn, validateDoseResponseData as Wt, toReagentRows as X, TagsInput_default as Xn, validateReagentListData as Xt, toReagentListItems as Y, NumberInput_default as Yn, validateQpcrPlateData as Yt, toSampleColumns as Z, TimePicker_default as Zn, validateSamplePrepData as Zt, toBioTemplateComponentPropsByComponent as _, controlsToSectionFormSchemas as _n, useListSelection as _r, createBioTemplatePresetCollectionFromControls as _t, getBioTemplateControlDefaults as a, getBioTemplatePackInfo as an, formatTimeSlot as ar, toTimeCourseColumns as at, toBioTemplateComponentUsage as b, controlsToTopBarSettingsConfig as bn, BaseSlider_default as br, createDoseResponseTemplate as bt, listBioTemplatePresetControlSchemas as c, bioTemplateCatalog as cn, isTimeInRange as cr, toTimeCourseSteps as ct, getBioTemplateComponentProps as d, searchBioTemplateCatalog as dn, snapToSlot as dr, TEMPLATE_COLLECTION_KEY as dt, bioTemplatePresets as en, durationMinutes as er, toSamplePrepColumns as et, listBioTemplateComponentBindings as f, controlValuesToComponentBindings as fn, toMinutes as fr, assertTemplateEnvelope as ft, toBioTemplateComponentProps as g, controlsToSectionFormSchema as gn, MultiSelect_default as gr, createBioTemplatePresetCollection as gt, toBioTemplateComponentImports as h, controlsToFormSchema as hn, useDropdownState as hr, createBioTemplatePackCollection as ht, createBioTemplateControlToolkit as i, bioTemplatePacks as in, formatTime as ir, toTemplateDataFrame as it, toFlowPanelDataFrame as j, getControlDefaults as jn, createSamplePrepTemplate as jt, toDoseLayoutState as k, defineWellPlateDoseComponentBindings as kn, createQpcrPlateTemplate as kt, requireBioTemplateControlSchema as l, getBioTemplateInfo as ln, parseTime as lr, toWellMapArray as lt, toBioTemplateComponentBindingsById as m, controlValuesToComponentProps as mn, DatePicker_default as mr, createAssayMatrixTemplate as mt, bioTemplateControlsToSectionFormSchemas as n, listBioTemplatePresets as nn, findNearestTimeSlotIndex as nr, toSamplePrepRows as nt, getBioTemplateControlSchema as o, listBioTemplatePacks as on, fromMinutes as or, toTimeCourseDataFrame as ot, toBioTemplateComponentBindings as p, controlValuesToComponentBindingsById as pn, useTimeUtils as pr, bioTemplatePresetControlValuesToOptions as pt, toReagentColumns as q, DateTimePicker_default as qn, validatePlateMapData as qt, bioTemplateControlsToSidebarPanels as r, searchBioTemplatePresets as rn, formatDuration as rr, toSampleRows as rt, listBioTemplateControlSchemas as s, searchBioTemplatePacks as sn, generateTimeSlots as sr, toTimeCourseRows as st, bioTemplateControlsToFormSchema as t, getBioTemplatePresetInfo as tn, findAvailableSlots as tr, toSamplePrepDataFrame as tt, getBioTemplateComponentBindings as u, listBioTemplateCatalog as un, rangesOverlap as ur, toWellPlateWells as ut, toBioTemplateComponentPropsById as v, controlsToSettingsSchema as vn, useSelectionLimit as vr, createCalibrationCurveTemplate as vt, toAssayMatrixSampleOptions as w, defineControlModel as wn, BaseSelect_default as wr, createInstrumentRunTemplate as wt, toAssayMatrixColumns as x, controlsToViewIds as xn, BaseRadioGroup_default as xr, createElisaAssayCollection as xt, toBioTemplateComponentSnippets as y, controlsToSidebarPanels as yn, useEventListener as yr, createDefaultBioTemplate as yt, toProtocolColumns as z, UnitInput_default as zn, ensureTemplateFromCollection as zt };
9332
9581
 
9333
- //# sourceMappingURL=templates-50NPjaxL.js.map
9582
+ //# sourceMappingURL=templates-Cyt0Suwf.js.map