selva-shared 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/components/AppLayout.svelte +439 -0
  4. package/dist/components/AppLayout.svelte.d.ts +17 -0
  5. package/dist/components/CollapsedPanelStrip.svelte +67 -0
  6. package/dist/components/CollapsedPanelStrip.svelte.d.ts +11 -0
  7. package/dist/components/ComputeMessages.svelte +172 -0
  8. package/dist/components/ComputeMessages.svelte.d.ts +7 -0
  9. package/dist/components/ErrorScreen.svelte +55 -0
  10. package/dist/components/ErrorScreen.svelte.d.ts +9 -0
  11. package/dist/components/StateManager.svelte +318 -0
  12. package/dist/components/StateManager.svelte.d.ts +9 -0
  13. package/dist/components/Viewer.svelte +207 -0
  14. package/dist/components/Viewer.svelte.d.ts +12 -0
  15. package/dist/components/layout/FooterItemRenderer.svelte +20 -0
  16. package/dist/components/layout/FooterItemRenderer.svelte.d.ts +7 -0
  17. package/dist/components/layout/PageContainer.svelte +36 -0
  18. package/dist/components/layout/PageContainer.svelte.d.ts +12 -0
  19. package/dist/components/layout/PageFooter.svelte +223 -0
  20. package/dist/components/layout/PageFooter.svelte.d.ts +9 -0
  21. package/dist/components/layout/PageHeader.svelte +89 -0
  22. package/dist/components/layout/PageHeader.svelte.d.ts +12 -0
  23. package/dist/components/layout/index.d.ts +3 -0
  24. package/dist/components/layout/index.js +4 -0
  25. package/dist/components/preview/ChartOutput.svelte +257 -0
  26. package/dist/components/preview/ChartOutput.svelte.d.ts +8 -0
  27. package/dist/components/preview/Group.svelte +121 -0
  28. package/dist/components/preview/Group.svelte.d.ts +23 -0
  29. package/dist/components/preview/InputControl.svelte +119 -0
  30. package/dist/components/preview/InputControl.svelte.d.ts +11 -0
  31. package/dist/components/preview/OutputDisplay.svelte +296 -0
  32. package/dist/components/preview/OutputDisplay.svelte.d.ts +9 -0
  33. package/dist/components/preview/TabBar.svelte +36 -0
  34. package/dist/components/preview/TabBar.svelte.d.ts +8 -0
  35. package/dist/components/preview/TabContent.svelte +124 -0
  36. package/dist/components/preview/TabContent.svelte.d.ts +13 -0
  37. package/dist/components/preview/TabLayout.svelte +109 -0
  38. package/dist/components/preview/TabLayout.svelte.d.ts +13 -0
  39. package/dist/components/preview/index.d.ts +3 -0
  40. package/dist/components/preview/index.js +4 -0
  41. package/dist/components/preview/inputs/CheckboxInput.svelte +29 -0
  42. package/dist/components/preview/inputs/CheckboxInput.svelte.d.ts +10 -0
  43. package/dist/components/preview/inputs/ColorInput.svelte +21 -0
  44. package/dist/components/preview/inputs/ColorInput.svelte.d.ts +7 -0
  45. package/dist/components/preview/inputs/DropdownInput.svelte +40 -0
  46. package/dist/components/preview/inputs/DropdownInput.svelte.d.ts +10 -0
  47. package/dist/components/preview/inputs/FileInput.svelte +358 -0
  48. package/dist/components/preview/inputs/FileInput.svelte.d.ts +10 -0
  49. package/dist/components/preview/inputs/NumberInput.svelte +152 -0
  50. package/dist/components/preview/inputs/NumberInput.svelte.d.ts +11 -0
  51. package/dist/components/preview/inputs/TextInput.svelte +74 -0
  52. package/dist/components/preview/inputs/TextInput.svelte.d.ts +11 -0
  53. package/dist/components/preview/inputs/index.d.ts +6 -0
  54. package/dist/components/preview/inputs/index.js +6 -0
  55. package/dist/components/ui/CalculateButton.svelte +56 -0
  56. package/dist/components/ui/CalculateButton.svelte.d.ts +9 -0
  57. package/dist/components/ui/SolvingIndicator.svelte +55 -0
  58. package/dist/components/ui/SolvingIndicator.svelte.d.ts +6 -0
  59. package/dist/components/ui/StateDisplay.svelte +106 -0
  60. package/dist/components/ui/StateDisplay.svelte.d.ts +10 -0
  61. package/dist/components/ui/alert/alert-description.svelte +23 -0
  62. package/dist/components/ui/alert/alert-description.svelte.d.ts +5 -0
  63. package/dist/components/ui/alert/alert-title.svelte +20 -0
  64. package/dist/components/ui/alert/alert-title.svelte.d.ts +5 -0
  65. package/dist/components/ui/alert/alert.svelte +44 -0
  66. package/dist/components/ui/alert/alert.svelte.d.ts +26 -0
  67. package/dist/components/ui/alert/index.d.ts +5 -0
  68. package/dist/components/ui/alert/index.js +7 -0
  69. package/dist/components/ui/alert-dialog/alert-dialog-action.svelte +18 -0
  70. package/dist/components/ui/alert-dialog/alert-dialog-action.svelte.d.ts +4 -0
  71. package/dist/components/ui/alert-dialog/alert-dialog-cancel.svelte +18 -0
  72. package/dist/components/ui/alert-dialog/alert-dialog-cancel.svelte.d.ts +4 -0
  73. package/dist/components/ui/alert-dialog/alert-dialog-content.svelte +27 -0
  74. package/dist/components/ui/alert-dialog/alert-dialog-content.svelte.d.ts +8 -0
  75. package/dist/components/ui/alert-dialog/alert-dialog-description.svelte +17 -0
  76. package/dist/components/ui/alert-dialog/alert-dialog-description.svelte.d.ts +4 -0
  77. package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte +20 -0
  78. package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte.d.ts +5 -0
  79. package/dist/components/ui/alert-dialog/alert-dialog-header.svelte +20 -0
  80. package/dist/components/ui/alert-dialog/alert-dialog-header.svelte.d.ts +5 -0
  81. package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte +20 -0
  82. package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte.d.ts +4 -0
  83. package/dist/components/ui/alert-dialog/alert-dialog-title.svelte +17 -0
  84. package/dist/components/ui/alert-dialog/alert-dialog-title.svelte.d.ts +4 -0
  85. package/dist/components/ui/alert-dialog/alert-dialog-trigger.svelte +7 -0
  86. package/dist/components/ui/alert-dialog/alert-dialog-trigger.svelte.d.ts +4 -0
  87. package/dist/components/ui/alert-dialog/index.d.ts +12 -0
  88. package/dist/components/ui/alert-dialog/index.js +15 -0
  89. package/dist/components/ui/badge/badge.svelte +50 -0
  90. package/dist/components/ui/badge/badge.svelte.d.ts +32 -0
  91. package/dist/components/ui/badge/index.d.ts +2 -0
  92. package/dist/components/ui/badge/index.js +2 -0
  93. package/dist/components/ui/button/button.svelte +83 -0
  94. package/dist/components/ui/button/button.svelte.d.ts +67 -0
  95. package/dist/components/ui/button/index.d.ts +2 -0
  96. package/dist/components/ui/button/index.js +4 -0
  97. package/dist/components/ui/button-group/button-group-separator.svelte +20 -0
  98. package/dist/components/ui/button-group/button-group-separator.svelte.d.ts +13 -0
  99. package/dist/components/ui/button-group/button-group-text.svelte +30 -0
  100. package/dist/components/ui/button-group/button-group-text.svelte.d.ts +11 -0
  101. package/dist/components/ui/button-group/button-group.svelte +46 -0
  102. package/dist/components/ui/button-group/button-group.svelte.d.ts +26 -0
  103. package/dist/components/ui/button-group/index.d.ts +4 -0
  104. package/dist/components/ui/button-group/index.js +6 -0
  105. package/dist/components/ui/card/card-action.svelte +20 -0
  106. package/dist/components/ui/card/card-action.svelte.d.ts +5 -0
  107. package/dist/components/ui/card/card-content.svelte +15 -0
  108. package/dist/components/ui/card/card-content.svelte.d.ts +5 -0
  109. package/dist/components/ui/card/card-description.svelte +20 -0
  110. package/dist/components/ui/card/card-description.svelte.d.ts +5 -0
  111. package/dist/components/ui/card/card-footer.svelte +20 -0
  112. package/dist/components/ui/card/card-footer.svelte.d.ts +5 -0
  113. package/dist/components/ui/card/card-header.svelte +23 -0
  114. package/dist/components/ui/card/card-header.svelte.d.ts +5 -0
  115. package/dist/components/ui/card/card-title.svelte +20 -0
  116. package/dist/components/ui/card/card-title.svelte.d.ts +5 -0
  117. package/dist/components/ui/card/card.svelte +23 -0
  118. package/dist/components/ui/card/card.svelte.d.ts +5 -0
  119. package/dist/components/ui/card/index.d.ts +8 -0
  120. package/dist/components/ui/card/index.js +10 -0
  121. package/dist/components/ui/checkbox/checkbox.svelte +36 -0
  122. package/dist/components/ui/checkbox/checkbox.svelte.d.ts +4 -0
  123. package/dist/components/ui/checkbox/index.d.ts +2 -0
  124. package/dist/components/ui/checkbox/index.js +4 -0
  125. package/dist/components/ui/collapsible/collapsible-content.svelte +7 -0
  126. package/dist/components/ui/collapsible/collapsible-content.svelte.d.ts +4 -0
  127. package/dist/components/ui/collapsible/collapsible-trigger.svelte +7 -0
  128. package/dist/components/ui/collapsible/collapsible-trigger.svelte.d.ts +4 -0
  129. package/dist/components/ui/collapsible/collapsible.svelte +11 -0
  130. package/dist/components/ui/collapsible/collapsible.svelte.d.ts +4 -0
  131. package/dist/components/ui/collapsible/index.d.ts +4 -0
  132. package/dist/components/ui/collapsible/index.js +6 -0
  133. package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte +38 -0
  134. package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte.d.ts +9 -0
  135. package/dist/components/ui/context-menu/context-menu-content.svelte +25 -0
  136. package/dist/components/ui/context-menu/context-menu-content.svelte.d.ts +7 -0
  137. package/dist/components/ui/context-menu/context-menu-group-heading.svelte +21 -0
  138. package/dist/components/ui/context-menu/context-menu-group-heading.svelte.d.ts +7 -0
  139. package/dist/components/ui/context-menu/context-menu-group.svelte +7 -0
  140. package/dist/components/ui/context-menu/context-menu-group.svelte.d.ts +4 -0
  141. package/dist/components/ui/context-menu/context-menu-item.svelte +27 -0
  142. package/dist/components/ui/context-menu/context-menu-item.svelte.d.ts +8 -0
  143. package/dist/components/ui/context-menu/context-menu-label.svelte +24 -0
  144. package/dist/components/ui/context-menu/context-menu-label.svelte.d.ts +8 -0
  145. package/dist/components/ui/context-menu/context-menu-radio-group.svelte +16 -0
  146. package/dist/components/ui/context-menu/context-menu-radio-group.svelte.d.ts +4 -0
  147. package/dist/components/ui/context-menu/context-menu-radio-item.svelte +31 -0
  148. package/dist/components/ui/context-menu/context-menu-radio-item.svelte.d.ts +4 -0
  149. package/dist/components/ui/context-menu/context-menu-separator.svelte +17 -0
  150. package/dist/components/ui/context-menu/context-menu-separator.svelte.d.ts +4 -0
  151. package/dist/components/ui/context-menu/context-menu-shortcut.svelte +20 -0
  152. package/dist/components/ui/context-menu/context-menu-shortcut.svelte.d.ts +5 -0
  153. package/dist/components/ui/context-menu/context-menu-sub-content.svelte +20 -0
  154. package/dist/components/ui/context-menu/context-menu-sub-content.svelte.d.ts +4 -0
  155. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte +29 -0
  156. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte.d.ts +8 -0
  157. package/dist/components/ui/context-menu/context-menu-trigger.svelte +7 -0
  158. package/dist/components/ui/context-menu/context-menu-trigger.svelte.d.ts +4 -0
  159. package/dist/components/ui/context-menu/index.d.ts +16 -0
  160. package/dist/components/ui/context-menu/index.js +19 -0
  161. package/dist/components/ui/dialog/dialog-close.svelte +7 -0
  162. package/dist/components/ui/dialog/dialog-close.svelte.d.ts +4 -0
  163. package/dist/components/ui/dialog/dialog-content.svelte +43 -0
  164. package/dist/components/ui/dialog/dialog-content.svelte.d.ts +11 -0
  165. package/dist/components/ui/dialog/dialog-description.svelte +17 -0
  166. package/dist/components/ui/dialog/dialog-description.svelte.d.ts +4 -0
  167. package/dist/components/ui/dialog/dialog-footer.svelte +20 -0
  168. package/dist/components/ui/dialog/dialog-footer.svelte.d.ts +5 -0
  169. package/dist/components/ui/dialog/dialog-header.svelte +20 -0
  170. package/dist/components/ui/dialog/dialog-header.svelte.d.ts +5 -0
  171. package/dist/components/ui/dialog/dialog-overlay.svelte +20 -0
  172. package/dist/components/ui/dialog/dialog-overlay.svelte.d.ts +4 -0
  173. package/dist/components/ui/dialog/dialog-title.svelte +17 -0
  174. package/dist/components/ui/dialog/dialog-title.svelte.d.ts +4 -0
  175. package/dist/components/ui/dialog/dialog-trigger.svelte +7 -0
  176. package/dist/components/ui/dialog/dialog-trigger.svelte.d.ts +4 -0
  177. package/dist/components/ui/dialog/index.d.ts +11 -0
  178. package/dist/components/ui/dialog/index.js +14 -0
  179. package/dist/components/ui/field/field-content.svelte +20 -0
  180. package/dist/components/ui/field/field-content.svelte.d.ts +5 -0
  181. package/dist/components/ui/field/field-description.svelte +25 -0
  182. package/dist/components/ui/field/field-description.svelte.d.ts +5 -0
  183. package/dist/components/ui/field/field-error.svelte +58 -0
  184. package/dist/components/ui/field/field-error.svelte.d.ts +12 -0
  185. package/dist/components/ui/field/field-group.svelte +23 -0
  186. package/dist/components/ui/field/field-group.svelte.d.ts +5 -0
  187. package/dist/components/ui/field/field-label.svelte +26 -0
  188. package/dist/components/ui/field/field-label.svelte.d.ts +10 -0
  189. package/dist/components/ui/field/field-legend.svelte +29 -0
  190. package/dist/components/ui/field/field-legend.svelte.d.ts +8 -0
  191. package/dist/components/ui/field/field-separator.svelte +38 -0
  192. package/dist/components/ui/field/field-separator.svelte.d.ts +9 -0
  193. package/dist/components/ui/field/field-set.svelte +24 -0
  194. package/dist/components/ui/field/field-set.svelte.d.ts +5 -0
  195. package/dist/components/ui/field/field-title.svelte +23 -0
  196. package/dist/components/ui/field/field-title.svelte.d.ts +5 -0
  197. package/dist/components/ui/field/field.svelte +53 -0
  198. package/dist/components/ui/field/field.svelte.d.ts +29 -0
  199. package/dist/components/ui/field/index.d.ts +11 -0
  200. package/dist/components/ui/field/index.js +13 -0
  201. package/dist/components/ui/index.d.ts +21 -0
  202. package/dist/components/ui/index.js +24 -0
  203. package/dist/components/ui/input/index.d.ts +2 -0
  204. package/dist/components/ui/input/index.js +4 -0
  205. package/dist/components/ui/input/input.svelte +52 -0
  206. package/dist/components/ui/input/input.svelte.d.ts +13 -0
  207. package/dist/components/ui/label/index.d.ts +2 -0
  208. package/dist/components/ui/label/index.js +4 -0
  209. package/dist/components/ui/label/label.svelte +20 -0
  210. package/dist/components/ui/label/label.svelte.d.ts +4 -0
  211. package/dist/components/ui/mode-toggle/index.d.ts +1 -0
  212. package/dist/components/ui/mode-toggle/index.js +1 -0
  213. package/dist/components/ui/mode-toggle/mode-toggle.svelte +16 -0
  214. package/dist/components/ui/mode-toggle/mode-toggle.svelte.d.ts +18 -0
  215. package/dist/components/ui/resizable/index.d.ts +4 -0
  216. package/dist/components/ui/resizable/index.js +6 -0
  217. package/dist/components/ui/resizable/resizable-handle.svelte +30 -0
  218. package/dist/components/ui/resizable/resizable-handle.svelte.d.ts +8 -0
  219. package/dist/components/ui/resizable/resizable-pane-group.svelte +20 -0
  220. package/dist/components/ui/resizable/resizable-pane-group.svelte.d.ts +7 -0
  221. package/dist/components/ui/scroll-area/index.d.ts +3 -0
  222. package/dist/components/ui/scroll-area/index.js +5 -0
  223. package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte +31 -0
  224. package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte.d.ts +4 -0
  225. package/dist/components/ui/scroll-area/scroll-area.svelte +43 -0
  226. package/dist/components/ui/scroll-area/scroll-area.svelte.d.ts +11 -0
  227. package/dist/components/ui/select/index.d.ts +11 -0
  228. package/dist/components/ui/select/index.js +14 -0
  229. package/dist/components/ui/select/select-content.svelte +40 -0
  230. package/dist/components/ui/select/select-content.svelte.d.ts +8 -0
  231. package/dist/components/ui/select/select-group-heading.svelte +21 -0
  232. package/dist/components/ui/select/select-group-heading.svelte.d.ts +10 -0
  233. package/dist/components/ui/select/select-group.svelte +7 -0
  234. package/dist/components/ui/select/select-group.svelte.d.ts +4 -0
  235. package/dist/components/ui/select/select-item.svelte +38 -0
  236. package/dist/components/ui/select/select-item.svelte.d.ts +4 -0
  237. package/dist/components/ui/select/select-label.svelte +20 -0
  238. package/dist/components/ui/select/select-label.svelte.d.ts +6 -0
  239. package/dist/components/ui/select/select-scroll-down-button.svelte +20 -0
  240. package/dist/components/ui/select/select-scroll-down-button.svelte.d.ts +4 -0
  241. package/dist/components/ui/select/select-scroll-up-button.svelte +20 -0
  242. package/dist/components/ui/select/select-scroll-up-button.svelte.d.ts +4 -0
  243. package/dist/components/ui/select/select-separator.svelte +18 -0
  244. package/dist/components/ui/select/select-separator.svelte.d.ts +4 -0
  245. package/dist/components/ui/select/select-trigger.svelte +29 -0
  246. package/dist/components/ui/select/select-trigger.svelte.d.ts +8 -0
  247. package/dist/components/ui/separator/index.d.ts +2 -0
  248. package/dist/components/ui/separator/index.js +4 -0
  249. package/dist/components/ui/separator/separator.svelte +21 -0
  250. package/dist/components/ui/separator/separator.svelte.d.ts +4 -0
  251. package/dist/components/ui/slider/index.d.ts +2 -0
  252. package/dist/components/ui/slider/index.js +4 -0
  253. package/dist/components/ui/slider/slider.svelte +52 -0
  254. package/dist/components/ui/slider/slider.svelte.d.ts +5 -0
  255. package/dist/components/ui/sonner/index.d.ts +2 -0
  256. package/dist/components/ui/sonner/index.js +2 -0
  257. package/dist/components/ui/sonner/sonner.svelte +13 -0
  258. package/dist/components/ui/sonner/sonner.svelte.d.ts +4 -0
  259. package/dist/components/ui/switch/index.d.ts +2 -0
  260. package/dist/components/ui/switch/index.js +4 -0
  261. package/dist/components/ui/switch/switch.svelte +29 -0
  262. package/dist/components/ui/switch/switch.svelte.d.ts +4 -0
  263. package/dist/components/ui/tabs/index.d.ts +5 -0
  264. package/dist/components/ui/tabs/index.js +7 -0
  265. package/dist/components/ui/tabs/tabs-content.svelte +17 -0
  266. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +4 -0
  267. package/dist/components/ui/tabs/tabs-list.svelte +16 -0
  268. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +4 -0
  269. package/dist/components/ui/tabs/tabs-trigger.svelte +20 -0
  270. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +4 -0
  271. package/dist/components/ui/tabs/tabs.svelte +19 -0
  272. package/dist/components/ui/tabs/tabs.svelte.d.ts +4 -0
  273. package/dist/components/ui/textarea/index.d.ts +2 -0
  274. package/dist/components/ui/textarea/index.js +4 -0
  275. package/dist/components/ui/textarea/textarea.svelte +23 -0
  276. package/dist/components/ui/textarea/textarea.svelte.d.ts +5 -0
  277. package/dist/components/ui/theme-switcher/ThemeSwitcher.svelte +39 -0
  278. package/dist/components/ui/theme-switcher/ThemeSwitcher.svelte.d.ts +3 -0
  279. package/dist/components/ui/theme-switcher/index.d.ts +1 -0
  280. package/dist/components/ui/theme-switcher/index.js +1 -0
  281. package/dist/composables/useFooterItem.svelte.d.ts +15 -0
  282. package/dist/composables/useFooterItem.svelte.js +31 -0
  283. package/dist/constants.d.ts +6 -0
  284. package/dist/constants.js +6 -0
  285. package/dist/contexts/FOOTER_USAGE.md +164 -0
  286. package/dist/contexts/footerContext.svelte.d.ts +17 -0
  287. package/dist/contexts/footerContext.svelte.js +24 -0
  288. package/dist/dummy-output-values.d.ts +3 -0
  289. package/dist/dummy-output-values.js +53 -0
  290. package/dist/dummy-surface-chart.json +13 -0
  291. package/dist/example-schema-left-only.json +367 -0
  292. package/dist/example-schema-right-only.json +322 -0
  293. package/dist/example-schema.json +1582 -0
  294. package/dist/features/preview/handlers.d.ts +55 -0
  295. package/dist/features/preview/handlers.js +175 -0
  296. package/dist/features/preview/index.d.ts +2 -0
  297. package/dist/features/preview/index.js +2 -0
  298. package/dist/features/preview/notifications.d.ts +11 -0
  299. package/dist/features/preview/notifications.js +41 -0
  300. package/dist/index.d.ts +29 -0
  301. package/dist/index.js +39 -0
  302. package/dist/stores/themeStore.svelte.d.ts +12 -0
  303. package/dist/stores/themeStore.svelte.js +42 -0
  304. package/dist/styles/base.css +142 -0
  305. package/dist/styles/themes/cyberpunk.css +98 -0
  306. package/dist/styles/themes/neutral.css +72 -0
  307. package/dist/styles/themes/ocean.css +75 -0
  308. package/dist/styles/themes/selva.css +105 -0
  309. package/dist/themes.d.ts +5 -0
  310. package/dist/themes.js +13 -0
  311. package/dist/types/generated/index.d.ts +6 -0
  312. package/dist/types/generated/index.js +6 -0
  313. package/dist/types/generated/preset.d.ts +80 -0
  314. package/dist/types/generated/preset.js +7 -0
  315. package/dist/types/generated/schema.d.ts +451 -0
  316. package/dist/types/generated/schema.js +48 -0
  317. package/dist/utils/computeThrottle.svelte.d.ts +28 -0
  318. package/dist/utils/computeThrottle.svelte.js +93 -0
  319. package/dist/utils/debounce.d.ts +14 -0
  320. package/dist/utils/debounce.js +25 -0
  321. package/dist/utils/file-download.d.ts +26 -0
  322. package/dist/utils/file-download.js +76 -0
  323. package/dist/utils/loadScript.d.ts +14 -0
  324. package/dist/utils/loadScript.js +41 -0
  325. package/dist/utils/param-exporter.d.ts +30 -0
  326. package/dist/utils/param-exporter.js +186 -0
  327. package/dist/utils/solving.svelte.d.ts +12 -0
  328. package/dist/utils/solving.svelte.js +86 -0
  329. package/dist/utils/utils-shared.d.ts +9 -0
  330. package/dist/utils/utils-shared.js +53 -0
  331. package/dist/utils/visibility-rules.d.ts +12 -0
  332. package/dist/utils/visibility-rules.js +52 -0
  333. package/dist/utils.d.ts +12 -0
  334. package/dist/utils.js +5 -0
  335. package/package.json +70 -0
  336. package/src/lib/components/AppLayout.svelte +439 -0
  337. package/src/lib/components/CollapsedPanelStrip.svelte +67 -0
  338. package/src/lib/components/ComputeMessages.svelte +172 -0
  339. package/src/lib/components/ErrorScreen.svelte +55 -0
  340. package/src/lib/components/StateManager.svelte +318 -0
  341. package/src/lib/components/Viewer.svelte +207 -0
  342. package/src/lib/components/layout/FooterItemRenderer.svelte +20 -0
  343. package/src/lib/components/layout/PageContainer.svelte +36 -0
  344. package/src/lib/components/layout/PageFooter.svelte +223 -0
  345. package/src/lib/components/layout/PageHeader.svelte +89 -0
  346. package/src/lib/components/layout/index.ts +4 -0
  347. package/src/lib/components/preview/ChartOutput.svelte +257 -0
  348. package/src/lib/components/preview/Group.svelte +121 -0
  349. package/src/lib/components/preview/InputControl.svelte +119 -0
  350. package/src/lib/components/preview/OutputDisplay.svelte +296 -0
  351. package/src/lib/components/preview/TabBar.svelte +36 -0
  352. package/src/lib/components/preview/TabContent.svelte +124 -0
  353. package/src/lib/components/preview/TabLayout.svelte +109 -0
  354. package/src/lib/components/preview/index.ts +4 -0
  355. package/src/lib/components/preview/inputs/CheckboxInput.svelte +29 -0
  356. package/src/lib/components/preview/inputs/ColorInput.svelte +21 -0
  357. package/src/lib/components/preview/inputs/DropdownInput.svelte +40 -0
  358. package/src/lib/components/preview/inputs/FileInput.svelte +358 -0
  359. package/src/lib/components/preview/inputs/NumberInput.svelte +152 -0
  360. package/src/lib/components/preview/inputs/TextInput.svelte +74 -0
  361. package/src/lib/components/preview/inputs/index.ts +6 -0
  362. package/src/lib/components/ui/CalculateButton.svelte +56 -0
  363. package/src/lib/components/ui/SolvingIndicator.svelte +55 -0
  364. package/src/lib/components/ui/StateDisplay.svelte +106 -0
  365. package/src/lib/components/ui/alert/alert-description.svelte +23 -0
  366. package/src/lib/components/ui/alert/alert-title.svelte +20 -0
  367. package/src/lib/components/ui/alert/alert.svelte +44 -0
  368. package/src/lib/components/ui/alert/index.ts +14 -0
  369. package/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte +18 -0
  370. package/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte +18 -0
  371. package/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte +27 -0
  372. package/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte +17 -0
  373. package/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte +20 -0
  374. package/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte +20 -0
  375. package/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte +20 -0
  376. package/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte +17 -0
  377. package/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte +7 -0
  378. package/src/lib/components/ui/alert-dialog/index.ts +39 -0
  379. package/src/lib/components/ui/badge/badge.svelte +50 -0
  380. package/src/lib/components/ui/badge/index.ts +2 -0
  381. package/src/lib/components/ui/button/button.svelte +83 -0
  382. package/src/lib/components/ui/button/index.ts +17 -0
  383. package/src/lib/components/ui/button-group/button-group-separator.svelte +20 -0
  384. package/src/lib/components/ui/button-group/button-group-text.svelte +30 -0
  385. package/src/lib/components/ui/button-group/button-group.svelte +46 -0
  386. package/src/lib/components/ui/button-group/index.ts +13 -0
  387. package/src/lib/components/ui/card/card-action.svelte +20 -0
  388. package/src/lib/components/ui/card/card-content.svelte +15 -0
  389. package/src/lib/components/ui/card/card-description.svelte +20 -0
  390. package/src/lib/components/ui/card/card-footer.svelte +20 -0
  391. package/src/lib/components/ui/card/card-header.svelte +23 -0
  392. package/src/lib/components/ui/card/card-title.svelte +20 -0
  393. package/src/lib/components/ui/card/card.svelte +23 -0
  394. package/src/lib/components/ui/card/index.ts +25 -0
  395. package/src/lib/components/ui/checkbox/checkbox.svelte +36 -0
  396. package/src/lib/components/ui/checkbox/index.ts +6 -0
  397. package/src/lib/components/ui/collapsible/collapsible-content.svelte +7 -0
  398. package/src/lib/components/ui/collapsible/collapsible-trigger.svelte +7 -0
  399. package/src/lib/components/ui/collapsible/collapsible.svelte +11 -0
  400. package/src/lib/components/ui/collapsible/index.ts +13 -0
  401. package/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte +38 -0
  402. package/src/lib/components/ui/context-menu/context-menu-content.svelte +25 -0
  403. package/src/lib/components/ui/context-menu/context-menu-group-heading.svelte +21 -0
  404. package/src/lib/components/ui/context-menu/context-menu-group.svelte +7 -0
  405. package/src/lib/components/ui/context-menu/context-menu-item.svelte +27 -0
  406. package/src/lib/components/ui/context-menu/context-menu-label.svelte +24 -0
  407. package/src/lib/components/ui/context-menu/context-menu-radio-group.svelte +16 -0
  408. package/src/lib/components/ui/context-menu/context-menu-radio-item.svelte +31 -0
  409. package/src/lib/components/ui/context-menu/context-menu-separator.svelte +17 -0
  410. package/src/lib/components/ui/context-menu/context-menu-shortcut.svelte +20 -0
  411. package/src/lib/components/ui/context-menu/context-menu-sub-content.svelte +20 -0
  412. package/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte +29 -0
  413. package/src/lib/components/ui/context-menu/context-menu-trigger.svelte +7 -0
  414. package/src/lib/components/ui/context-menu/index.ts +51 -0
  415. package/src/lib/components/ui/dialog/dialog-close.svelte +7 -0
  416. package/src/lib/components/ui/dialog/dialog-content.svelte +43 -0
  417. package/src/lib/components/ui/dialog/dialog-description.svelte +17 -0
  418. package/src/lib/components/ui/dialog/dialog-footer.svelte +20 -0
  419. package/src/lib/components/ui/dialog/dialog-header.svelte +20 -0
  420. package/src/lib/components/ui/dialog/dialog-overlay.svelte +20 -0
  421. package/src/lib/components/ui/dialog/dialog-title.svelte +17 -0
  422. package/src/lib/components/ui/dialog/dialog-trigger.svelte +7 -0
  423. package/src/lib/components/ui/dialog/index.ts +37 -0
  424. package/src/lib/components/ui/field/field-content.svelte +20 -0
  425. package/src/lib/components/ui/field/field-description.svelte +25 -0
  426. package/src/lib/components/ui/field/field-error.svelte +58 -0
  427. package/src/lib/components/ui/field/field-group.svelte +23 -0
  428. package/src/lib/components/ui/field/field-label.svelte +26 -0
  429. package/src/lib/components/ui/field/field-legend.svelte +29 -0
  430. package/src/lib/components/ui/field/field-separator.svelte +38 -0
  431. package/src/lib/components/ui/field/field-set.svelte +24 -0
  432. package/src/lib/components/ui/field/field-title.svelte +23 -0
  433. package/src/lib/components/ui/field/field.svelte +53 -0
  434. package/src/lib/components/ui/field/index.ts +33 -0
  435. package/src/lib/components/ui/index.ts +33 -0
  436. package/src/lib/components/ui/input/index.ts +7 -0
  437. package/src/lib/components/ui/input/input.svelte +52 -0
  438. package/src/lib/components/ui/label/index.ts +7 -0
  439. package/src/lib/components/ui/label/label.svelte +20 -0
  440. package/src/lib/components/ui/mode-toggle/index.ts +1 -0
  441. package/src/lib/components/ui/mode-toggle/mode-toggle.svelte +16 -0
  442. package/src/lib/components/ui/resizable/index.ts +13 -0
  443. package/src/lib/components/ui/resizable/resizable-handle.svelte +30 -0
  444. package/src/lib/components/ui/resizable/resizable-pane-group.svelte +20 -0
  445. package/src/lib/components/ui/scroll-area/index.ts +10 -0
  446. package/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte +31 -0
  447. package/src/lib/components/ui/scroll-area/scroll-area.svelte +43 -0
  448. package/src/lib/components/ui/select/index.ts +37 -0
  449. package/src/lib/components/ui/select/select-content.svelte +40 -0
  450. package/src/lib/components/ui/select/select-group-heading.svelte +21 -0
  451. package/src/lib/components/ui/select/select-group.svelte +7 -0
  452. package/src/lib/components/ui/select/select-item.svelte +38 -0
  453. package/src/lib/components/ui/select/select-label.svelte +20 -0
  454. package/src/lib/components/ui/select/select-scroll-down-button.svelte +20 -0
  455. package/src/lib/components/ui/select/select-scroll-up-button.svelte +20 -0
  456. package/src/lib/components/ui/select/select-separator.svelte +18 -0
  457. package/src/lib/components/ui/select/select-trigger.svelte +29 -0
  458. package/src/lib/components/ui/separator/index.ts +7 -0
  459. package/src/lib/components/ui/separator/separator.svelte +21 -0
  460. package/src/lib/components/ui/slider/index.ts +7 -0
  461. package/src/lib/components/ui/slider/slider.svelte +52 -0
  462. package/src/lib/components/ui/sonner/index.ts +2 -0
  463. package/src/lib/components/ui/sonner/sonner.svelte +13 -0
  464. package/src/lib/components/ui/switch/index.ts +7 -0
  465. package/src/lib/components/ui/switch/switch.svelte +29 -0
  466. package/src/lib/components/ui/tabs/index.ts +16 -0
  467. package/src/lib/components/ui/tabs/tabs-content.svelte +17 -0
  468. package/src/lib/components/ui/tabs/tabs-list.svelte +16 -0
  469. package/src/lib/components/ui/tabs/tabs-trigger.svelte +20 -0
  470. package/src/lib/components/ui/tabs/tabs.svelte +19 -0
  471. package/src/lib/components/ui/textarea/index.ts +7 -0
  472. package/src/lib/components/ui/textarea/textarea.svelte +23 -0
  473. package/src/lib/components/ui/theme-switcher/ThemeSwitcher.svelte +39 -0
  474. package/src/lib/components/ui/theme-switcher/index.ts +1 -0
  475. package/src/lib/composables/useFooterItem.svelte.ts +39 -0
  476. package/src/lib/constants.ts +6 -0
  477. package/src/lib/contexts/FOOTER_USAGE.md +164 -0
  478. package/src/lib/contexts/footerContext.svelte.ts +52 -0
  479. package/src/lib/dummy-output-values.ts +62 -0
  480. package/src/lib/dummy-surface-chart.json +13 -0
  481. package/src/lib/example-schema-left-only.json +367 -0
  482. package/src/lib/example-schema-right-only.json +322 -0
  483. package/src/lib/example-schema.json +1582 -0
  484. package/src/lib/features/preview/handlers.ts +243 -0
  485. package/src/lib/features/preview/index.ts +2 -0
  486. package/src/lib/features/preview/notifications.ts +52 -0
  487. package/src/lib/index.ts +52 -0
  488. package/src/lib/stores/themeStore.svelte.ts +54 -0
  489. package/src/lib/styles/base.css +142 -0
  490. package/src/lib/styles/themes/cyberpunk.css +98 -0
  491. package/src/lib/styles/themes/neutral.css +72 -0
  492. package/src/lib/styles/themes/ocean.css +75 -0
  493. package/src/lib/styles/themes/selva.css +105 -0
  494. package/src/lib/themes.ts +18 -0
  495. package/src/lib/types/generated/index.ts +6 -0
  496. package/src/lib/types/generated/preset.ts +82 -0
  497. package/src/lib/types/generated/schema.ts +527 -0
  498. package/src/lib/utils/computeThrottle.svelte.ts +117 -0
  499. package/src/lib/utils/debounce.ts +30 -0
  500. package/src/lib/utils/file-download.ts +88 -0
  501. package/src/lib/utils/loadScript.ts +52 -0
  502. package/src/lib/utils/param-exporter.ts +242 -0
  503. package/src/lib/utils/solving.svelte.ts +100 -0
  504. package/src/lib/utils/utils-shared.ts +57 -0
  505. package/src/lib/utils/visibility-rules.ts +97 -0
  506. package/src/lib/utils.ts +13 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Wrapper utilities for file downloads from Grasshopper outputs
3
+ * Uses the core package implementation for file handling
4
+ */
5
+
6
+ import { downloadFileData, type FileData } from 'selva-compute';
7
+
8
+ /**
9
+ * Download file(s) from Grasshopper outputs
10
+ * Single files are downloaded directly, multiple files are packaged as ZIP
11
+ */
12
+ export async function downloadFiles(
13
+ fileData: FileData | FileData[],
14
+ fileName: string = 'grasshopper-output'
15
+ ): Promise<void> {
16
+ try {
17
+ const filesArray = Array.isArray(fileData) ? fileData : [fileData];
18
+
19
+ if (filesArray.length === 0) {
20
+ console.warn('[FileDownload] No files to download');
21
+ return;
22
+ }
23
+
24
+ if (filesArray.length === 1) {
25
+ // Single file - download directly
26
+ await downloadSingleFile(filesArray[0]);
27
+ } else {
28
+ // Multiple files - use core's ZIP functionality
29
+ await downloadFileData(filesArray, fileName);
30
+ }
31
+ } catch (error) {
32
+ console.error('[FileDownload] Error downloading files:', error);
33
+ throw error;
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Download a single file directly
39
+ */
40
+ async function downloadSingleFile(fileData: FileData): Promise<void> {
41
+ try {
42
+ await downloadFileData([fileData], fileData.fileName.replace(/\.[^.]*$/, ''));
43
+ } catch (error) {
44
+ console.error('[FileDownload] Error downloading single file:', error);
45
+ throw error;
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Check if data is FileData
51
+ */
52
+ export function isFileData(data: unknown): data is FileData {
53
+ return (
54
+ typeof data === 'object' &&
55
+ data !== null &&
56
+ 'fileName' in data &&
57
+ 'data' in data &&
58
+ 'isBase64Encoded' in data
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Check if data is FileData array
64
+ */
65
+ export function isFileDataArray(data: unknown): data is FileData[] {
66
+ return Array.isArray(data) && data.length > 0 && isFileData(data[0]);
67
+ }
68
+
69
+ /**
70
+ * Format file size for display
71
+ */
72
+ export function formatFileSize(bytes: number): string {
73
+ if (bytes === 0) return '0 Bytes';
74
+
75
+ const k = 1024;
76
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
77
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
78
+
79
+ return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];
80
+ }
81
+
82
+ /**
83
+ * Get approximate file size from base64 string
84
+ */
85
+ export function getBase64FileSize(base64: string): number {
86
+ // Base64 encoded string is approximately 33% larger than original
87
+ return Math.ceil((base64.length * 3) / 4);
88
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Load an external script from a CDN with automatic deduplication.
3
+ * All calls to load the same script will share a single promise,
4
+ * preventing duplicate script tags and race conditions.
5
+ *
6
+ * @param src The script URL
7
+ * @param options Script attributes (crossOrigin, async, etc.)
8
+ * @returns Promise that resolves when script is loaded
9
+ */
10
+
11
+ const scriptLoaders = new Map<string, Promise<void>>();
12
+
13
+ export function loadScript(
14
+ src: string,
15
+ options?: {
16
+ crossOrigin?: string;
17
+ async?: boolean;
18
+ defer?: boolean;
19
+ }
20
+ ): Promise<void> {
21
+ // Return existing promise if already loading/loaded
22
+ if (scriptLoaders.has(src)) {
23
+ return scriptLoaders.get(src)!;
24
+ }
25
+
26
+ // Check if script already exists in DOM
27
+ if (document.querySelector(`script[src="${src}"]`)) {
28
+ const resolved = Promise.resolve();
29
+ scriptLoaders.set(src, resolved);
30
+ return resolved;
31
+ }
32
+
33
+ // Create and load script
34
+ const promise = new Promise<void>((resolve, reject) => {
35
+ const script = document.createElement('script');
36
+ script.src = src;
37
+ if (options?.crossOrigin) script.crossOrigin = options.crossOrigin;
38
+ if (options?.async !== undefined) script.async = options.async;
39
+ if (options?.defer !== undefined) script.defer = options.defer;
40
+
41
+ script.onload = () => resolve();
42
+ script.onerror = () => {
43
+ scriptLoaders.delete(src);
44
+ reject(new Error(`Failed to load script: ${src}`));
45
+ };
46
+
47
+ document.head.appendChild(script);
48
+ });
49
+
50
+ scriptLoaders.set(src, promise);
51
+ return promise;
52
+ }
@@ -0,0 +1,242 @@
1
+ import type {
2
+ UISchema,
3
+ ParameterPreset,
4
+ ParameterState,
5
+ ValidationIssueMessage,
6
+ GroupConfig
7
+ } from '../types/generated';
8
+
9
+ /**
10
+ * Generate a UUID v4 (with fallback for older environments)
11
+ */
12
+ function generateUUID(): string {
13
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
14
+ return crypto.randomUUID();
15
+ }
16
+ // Fallback for older browsers/environments
17
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
18
+ const r = (Math.random() * 16) | 0;
19
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
20
+ return v.toString(16);
21
+ });
22
+ }
23
+
24
+ /**
25
+ * Create a saved state from current schema and values
26
+ */
27
+ export function createSavedState(
28
+ schema: UISchema,
29
+ currentValues: Record<string, unknown>,
30
+ metadata: {
31
+ name: string;
32
+ description?: string;
33
+ author?: string;
34
+ tags?: string[];
35
+ }
36
+ ): ParameterPreset {
37
+ // Collect parameter states from schema
38
+ const parameters: ParameterState[] = [];
39
+
40
+ const processGroup = (group: GroupConfig) => {
41
+ for (const item of group.items || []) {
42
+ if (item.type === 'input') {
43
+ const value = currentValues[item.paramId];
44
+
45
+ // Find the input parameter definition for type info
46
+ const inputDef = schema.inputs.find((i) => i.id === item.paramId);
47
+
48
+ if (value !== undefined && inputDef) {
49
+ parameters.push({
50
+ paramId: item.paramId,
51
+ nickname: inputDef.nickname,
52
+ displayName: item.displayName || inputDef.nickname,
53
+ paramType: inputDef.paramType,
54
+ value,
55
+ groupName: group.label
56
+ });
57
+ }
58
+ }
59
+ }
60
+ };
61
+
62
+ if (schema.layout) {
63
+ if (schema.layout.type === 'tabbed') {
64
+ for (const tab of schema.layout.tabs) {
65
+ for (const group of tab.groups || []) {
66
+ processGroup(group);
67
+ }
68
+ }
69
+ } else if (schema.layout.type === 'flat') {
70
+ for (const group of schema.layout.groups || []) {
71
+ processGroup(group);
72
+ }
73
+ }
74
+ }
75
+
76
+ return {
77
+ id: generateUUID(),
78
+ name: metadata.name,
79
+ description: metadata.description,
80
+ timestamp: new Date().toISOString(),
81
+ schemaId: schema.id,
82
+ documentId: schema.documentId || '',
83
+ projectFileName: schema.projectFileName || '',
84
+ pluginVersion: schema.pluginVersion || '',
85
+ author: metadata.author,
86
+ tags: metadata.tags || [],
87
+ parameters
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Validate a saved state against the current schema
93
+ */
94
+ export function validateSavedState(
95
+ savedState: ParameterPreset,
96
+ currentSchema: UISchema
97
+ ): {
98
+ isValid: boolean;
99
+ issues: ValidationIssueMessage[];
100
+ canLoad: boolean; // Can we load despite issues?
101
+ } {
102
+ const issues: ValidationIssueMessage[] = [];
103
+
104
+ // Check document ID match
105
+ if (savedState.documentId !== (currentSchema.documentId || '')) {
106
+ issues.push({
107
+ paramId: '__document__',
108
+ severity: 'error',
109
+ message: 'Document ID mismatch - this state was saved for a different document',
110
+ details: {
111
+ expected: currentSchema.documentId || '',
112
+ actual: savedState.documentId
113
+ }
114
+ });
115
+ }
116
+
117
+ // Check schema ID match (warning only)
118
+ if (savedState.schemaId !== currentSchema.id) {
119
+ issues.push({
120
+ paramId: '__schema__',
121
+ severity: 'warning',
122
+ message: 'Schema has changed since this state was saved',
123
+ details: {
124
+ expected: currentSchema.id,
125
+ actual: savedState.schemaId
126
+ }
127
+ });
128
+ }
129
+
130
+ // Validate each parameter
131
+ for (const paramState of savedState.parameters) {
132
+ const inputDef = currentSchema.inputs.find((i) => i.id === paramState.paramId);
133
+
134
+ if (!inputDef) {
135
+ issues.push({
136
+ paramId: paramState.paramId,
137
+ severity: 'error',
138
+ message: `Parameter "${paramState.nickname}" no longer exists in the schema`
139
+ });
140
+ continue;
141
+ }
142
+
143
+ // Check nickname changed (warning)
144
+ if (inputDef.nickname !== paramState.nickname) {
145
+ issues.push({
146
+ paramId: paramState.paramId,
147
+ severity: 'warning',
148
+ message: `Parameter nickname changed`,
149
+ details: {
150
+ expected: paramState.nickname,
151
+ actual: inputDef.nickname
152
+ }
153
+ });
154
+ }
155
+ }
156
+
157
+ // Can load if no errors (warnings are ok)
158
+ const hasErrors = issues.some((i) => i.severity === 'error');
159
+ const canLoad = !hasErrors;
160
+
161
+ return {
162
+ isValid: issues.length === 0,
163
+ issues,
164
+ canLoad
165
+ };
166
+ }
167
+
168
+ /**
169
+ * Extract values from saved state that can be safely loaded
170
+ */
171
+ export function extractLoadableValues(
172
+ savedState: ParameterPreset,
173
+ currentSchema: UISchema,
174
+ validation: ReturnType<typeof validateSavedState>
175
+ ): Record<string, unknown> {
176
+ const values: Record<string, unknown> = {};
177
+
178
+ // Get param IDs with errors
179
+ const errorParamIds = new Set(
180
+ validation.issues
181
+ .filter(
182
+ (i) => i.severity === 'error' && i.paramId !== '__document__' && i.paramId !== '__schema__'
183
+ )
184
+ .map((i) => i.paramId)
185
+ );
186
+
187
+ // Extract values for parameters without errors
188
+ for (const paramState of savedState.parameters) {
189
+ if (!errorParamIds.has(paramState.paramId)) {
190
+ // Verify parameter still exists
191
+ const inputDef = currentSchema.inputs.find((i) => i.id === paramState.paramId);
192
+ if (inputDef) {
193
+ values[paramState.paramId] = paramState.value;
194
+ }
195
+ }
196
+ }
197
+
198
+ return values;
199
+ }
200
+
201
+ /**
202
+ * Export state as .sps (Selva Param State) file
203
+ */
204
+ export function exportStateAsJson(savedState: ParameterPreset): void {
205
+ const json = JSON.stringify(savedState, null, 2);
206
+ const blob = new Blob([json], { type: 'application/json' });
207
+ const url = URL.createObjectURL(blob);
208
+
209
+ // Use a more reliable method: add to DOM, trigger, then remove
210
+ const link = document.createElement('a');
211
+ link.href = url;
212
+ link.download = `${savedState.name.replace(/[^a-z0-9]/gi, '_')}_${savedState.timestamp.split('T')[0].replace(/-/g, '_')}.sps`;
213
+
214
+ // Ensure visibility for older browsers
215
+ link.style.display = 'none';
216
+ document.body.appendChild(link);
217
+
218
+ // Use setTimeout to ensure DOM is ready
219
+ setTimeout(() => {
220
+ link.click();
221
+ // Clean up after click
222
+ setTimeout(() => {
223
+ document.body.removeChild(link);
224
+ URL.revokeObjectURL(url);
225
+ }, 100);
226
+ }, 0);
227
+ }
228
+
229
+ /**
230
+ * Import state from .sps (Selva Param State) file
231
+ */
232
+ export async function importStateFromJson(file: File): Promise<ParameterPreset> {
233
+ const text = await file.text();
234
+ const state = JSON.parse(text) as ParameterPreset;
235
+
236
+ // Basic validation
237
+ if (!state.id || !state.name || !state.documentId || !state.parameters) {
238
+ throw new Error('Invalid saved state file format');
239
+ }
240
+
241
+ return state;
242
+ }
@@ -0,0 +1,100 @@
1
+ import { untrack } from 'svelte';
2
+
3
+ // How many solves to keep in history for averaging
4
+ const HISTORY_SIZE = 3;
5
+ // If expected solve time is below this, skip the indicator entirely
6
+ const FAST_THRESHOLD_MS = 200;
7
+ // If expected solve time is above this, show indicator immediately (no delay)
8
+ const SLOW_THRESHOLD_MS = 600;
9
+
10
+ /**
11
+ * Creates an adaptive solving indicator that measures actual solve durations
12
+ * and adjusts its visibility delay accordingly.
13
+ *
14
+ * - Fast solves (<200ms avg): indicator never shown (avoids flicker)
15
+ * - Slow solves (>600ms avg): indicator shown immediately
16
+ * - In between: indicator shown after a proportional delay
17
+ * - First solve: shows immediately (no history yet)
18
+ */
19
+ export function createSolvingIndicator(isSolving: () => boolean) {
20
+ let show = $state(false);
21
+ let timeout: ReturnType<typeof setTimeout> | null = null;
22
+
23
+ // Solve duration history
24
+ const solveHistory: number[] = [];
25
+ let solveStartTime: number | null = null;
26
+ let hasHistory = false;
27
+
28
+ function getExpectedDuration(): number {
29
+ if (solveHistory.length === 0) return Infinity; // unknown → show immediately
30
+ return solveHistory.reduce((a, b) => a + b, 0) / solveHistory.length;
31
+ }
32
+
33
+ function recordSolveEnd() {
34
+ if (solveStartTime !== null) {
35
+ const duration = performance.now() - solveStartTime;
36
+ solveHistory.push(duration);
37
+ if (solveHistory.length > HISTORY_SIZE) {
38
+ solveHistory.shift();
39
+ }
40
+ solveStartTime = null;
41
+ hasHistory = true;
42
+ }
43
+ }
44
+
45
+ $effect(() => {
46
+ const solving = isSolving();
47
+
48
+ untrack(() => {
49
+ if (solving) {
50
+ solveStartTime = performance.now();
51
+
52
+ const expected = getExpectedDuration();
53
+
54
+ // Skip indicator entirely for consistently fast solves
55
+ if (hasHistory && expected < FAST_THRESHOLD_MS) {
56
+ return;
57
+ }
58
+
59
+ // Delay: 0 for slow/unknown, proportional for mid-range
60
+ const delay =
61
+ expected === Infinity || expected >= SLOW_THRESHOLD_MS
62
+ ? 0
63
+ : Math.round(
64
+ ((expected - FAST_THRESHOLD_MS) / (SLOW_THRESHOLD_MS - FAST_THRESHOLD_MS)) * 300
65
+ );
66
+
67
+ if (!timeout) {
68
+ if (delay === 0) {
69
+ show = true;
70
+ } else {
71
+ timeout = setTimeout(() => {
72
+ show = true;
73
+ timeout = null;
74
+ }, delay);
75
+ }
76
+ }
77
+ } else {
78
+ recordSolveEnd();
79
+
80
+ if (timeout) {
81
+ clearTimeout(timeout);
82
+ timeout = null;
83
+ }
84
+ show = false;
85
+ }
86
+ });
87
+
88
+ return () => {
89
+ if (timeout) {
90
+ clearTimeout(timeout);
91
+ }
92
+ };
93
+ });
94
+
95
+ return {
96
+ get show() {
97
+ return show;
98
+ }
99
+ };
100
+ }
@@ -0,0 +1,57 @@
1
+ import type { UISchema } from '$lib/types/generated';
2
+
3
+ /**
4
+ * Get default value for a parameter type
5
+ */
6
+ export function getDefaultValue(paramType: string): unknown {
7
+ switch (paramType) {
8
+ case 'number':
9
+ case 'integer':
10
+ return 0;
11
+ case 'boolean':
12
+ return false;
13
+ case 'text':
14
+ return '';
15
+ default:
16
+ return null;
17
+ }
18
+ }
19
+
20
+ /**
21
+ * Ensure schema has proper layout defaults
22
+ */
23
+ export function ensureSchemaLayoutDefaults(schema: UISchema | null): UISchema | null {
24
+ if (!schema) return null;
25
+
26
+ if (!schema.layout) {
27
+ schema.layout = {
28
+ type: 'tabbed',
29
+ gap: 16,
30
+ tabs: []
31
+ };
32
+ }
33
+
34
+ /**
35
+ * @deprecated v1 schema migration
36
+ * TODO(v2.0.0): Remove this block - all schemas should have layout.type
37
+ */
38
+ if (schema.layout && !schema.layout.type) {
39
+ if ('tabs' in schema.layout) {
40
+ (schema.layout as any).type = 'tabbed';
41
+ } else if ('groups' in schema.layout) {
42
+ (schema.layout as any).type = 'flat';
43
+ } else {
44
+ (schema.layout as any).type = 'tabbed';
45
+ }
46
+ }
47
+
48
+ if (schema.layout.type === 'tabbed' && !schema.layout.tabs) {
49
+ schema.layout.tabs = [];
50
+ }
51
+ // Ensure instanceSolve has a default value
52
+ if (schema.instanceSolve === undefined) {
53
+ schema.instanceSolve = true;
54
+ }
55
+
56
+ return schema;
57
+ }
@@ -0,0 +1,97 @@
1
+ import type {
2
+ LayoutItem,
3
+ VisibilityRule,
4
+ VisibilityCondition,
5
+ GroupVisibilityCondition
6
+ } from '$lib/types/generated';
7
+
8
+ // ---------------------------------------------------------------------------
9
+ // Types
10
+ // ---------------------------------------------------------------------------
11
+
12
+ export interface VisibilityResult {
13
+ visible: boolean;
14
+ disabled: boolean;
15
+ defaultValue?: unknown;
16
+ }
17
+
18
+ // ---------------------------------------------------------------------------
19
+ // Rule operators
20
+ // ---------------------------------------------------------------------------
21
+
22
+ type RuleOperatorFn = (a: unknown, b: unknown, values?: unknown[]) => boolean;
23
+
24
+ const RULE_OPERATORS: Record<string, RuleOperatorFn> = {
25
+ equals: (a, b) => a === b,
26
+ notEquals: (a, b) => a !== b,
27
+ greaterThan: (a, b) => Number(a) > Number(b),
28
+ lessThan: (a, b) => Number(a) < Number(b),
29
+ greaterThanOrEqual: (a, b) => Number(a) >= Number(b),
30
+ lessThanOrEqual: (a, b) => Number(a) <= Number(b),
31
+ between: (a, _, vals) =>
32
+ vals?.length === 2 && Number(a) >= Number(vals[0]) && Number(a) <= Number(vals[1]),
33
+ in: (a, _, vals) => vals?.includes(String(a)) ?? false,
34
+ notIn: (a, _, vals) => !(vals?.includes(String(a)) ?? false),
35
+ matches: (a, b) => {
36
+ try {
37
+ return new RegExp(String(b)).test(String(a));
38
+ } catch {
39
+ return false;
40
+ }
41
+ }
42
+ };
43
+
44
+ // ---------------------------------------------------------------------------
45
+ // Condition evaluation
46
+ // ---------------------------------------------------------------------------
47
+
48
+ export function evaluateRule(rule: VisibilityRule, values: Record<string, unknown>): boolean {
49
+ const fn = RULE_OPERATORS[rule.operator];
50
+ return fn ? fn(values[rule.paramId], rule.value, rule.values) : false;
51
+ }
52
+
53
+ export function evaluateCondition(
54
+ condition: VisibilityCondition | GroupVisibilityCondition,
55
+ values: Record<string, unknown>
56
+ ): boolean {
57
+ const results = condition.rules.map((rule) => evaluateRule(rule, values));
58
+ return condition.mode === 'any' ? results.some(Boolean) : results.every(Boolean);
59
+ }
60
+
61
+ // ---------------------------------------------------------------------------
62
+ // Item / group visibility
63
+ // ---------------------------------------------------------------------------
64
+
65
+ type ActionFn = (met: boolean, defaultValue?: unknown) => VisibilityResult;
66
+
67
+ const ACTIONS: Record<string, ActionFn> = {
68
+ show: (met) => ({ visible: met, disabled: false }),
69
+ hide: (met, dv) => ({ visible: !met, disabled: false, defaultValue: dv }),
70
+ disable: (met, dv) => ({ visible: true, disabled: met, defaultValue: met ? dv : undefined })
71
+ };
72
+
73
+ export function evaluateVisibility(
74
+ item: LayoutItem,
75
+ values: Record<string, unknown>
76
+ ): VisibilityResult {
77
+ if (item.type === 'linebreak') return { visible: true, disabled: false };
78
+ if (!item.visibilityCondition?.rules) return { visible: true, disabled: false };
79
+
80
+ const { action = 'show', defaultValue } = item.visibilityCondition;
81
+ const met = evaluateCondition(item.visibilityCondition, values);
82
+ const actionFn = ACTIONS[action] ?? ACTIONS.show;
83
+
84
+ return actionFn(met, defaultValue);
85
+ }
86
+
87
+ export function evaluateGroupVisibility(
88
+ group: { visibilityCondition?: GroupVisibilityCondition },
89
+ values: Record<string, unknown>
90
+ ): boolean {
91
+ if (!group.visibilityCondition?.rules) return true;
92
+
93
+ const { action = 'show' } = group.visibilityCondition;
94
+ const met = evaluateCondition(group.visibilityCondition, values);
95
+
96
+ return action === 'hide' ? !met : met;
97
+ }
@@ -0,0 +1,13 @@
1
+ import { clsx, type ClassValue } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ export type WithoutChild<T> = T extends { child?: any } ? Omit<T, 'child'> : T;
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ export type WithoutChildren<T> = T extends { children?: any } ? Omit<T, 'children'> : T;
12
+ export type WithoutChildrenOrChild<T> = WithoutChildren<WithoutChild<T>>;
13
+ export type WithElementRef<T, U extends HTMLElement = HTMLElement> = T & { ref?: U | null };