@zendir/ui 0.5.0 → 0.6.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 (391) hide show
  1. package/CHANGELOG.md +419 -386
  2. package/README.md +640 -631
  3. package/dist/_virtual/_rolldown/runtime.js +13 -0
  4. package/dist/index.js +17 -221
  5. package/dist/react/3d/CesiumCaptureSource.d.ts +0 -1
  6. package/dist/react/3d/CesiumCaptureSource.js +364 -283
  7. package/dist/react/3d/CesiumCaptureSource.js.map +1 -1
  8. package/dist/react/3d/ZenSpace3D.d.ts +2 -3
  9. package/dist/react/3d/ZenSpace3D.js +1681 -1237
  10. package/dist/react/3d/ZenSpace3D.js.map +1 -1
  11. package/dist/react/3d/ZenSpace3DCesium.d.ts +0 -1
  12. package/dist/react/3d/ZenSpace3DCesium.js +513 -560
  13. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -1
  14. package/dist/react/3d/ZenSpace3DShaders.js +61 -66
  15. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -1
  16. package/dist/react/3d/ZenSpace3DTypes.d.ts +19 -20
  17. package/dist/react/3d/ZenSpace3DUtils.d.ts +0 -1
  18. package/dist/react/3d/ZenSpace3DUtils.js +37 -24
  19. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -1
  20. package/dist/react/3d/capturePngAnalysis.js +42 -36
  21. package/dist/react/3d/capturePngAnalysis.js.map +1 -1
  22. package/dist/react/3d/index.d.ts +3 -3
  23. package/dist/react/3d/index.js +5 -53
  24. package/dist/react/3d/threeLoader.d.ts +1 -1
  25. package/dist/react/3d/threeLoader.js +23 -18
  26. package/dist/react/3d/threeLoader.js.map +1 -1
  27. package/dist/react/astro/ClassificationBanner.d.ts +2 -3
  28. package/dist/react/astro/ClassificationBanner.js +95 -79
  29. package/dist/react/astro/ClassificationBanner.js.map +1 -1
  30. package/dist/react/astro/GlobalStatusBar.d.ts +0 -1
  31. package/dist/react/astro/GlobalStatusBar.js +157 -163
  32. package/dist/react/astro/GlobalStatusBar.js.map +1 -1
  33. package/dist/react/astro/MissionClock.d.ts +7 -8
  34. package/dist/react/astro/MissionClock.js +377 -400
  35. package/dist/react/astro/MissionClock.js.map +1 -1
  36. package/dist/react/astro/MonitoringIcon.d.ts +1 -2
  37. package/dist/react/astro/MonitoringIcon.js +422 -358
  38. package/dist/react/astro/MonitoringIcon.js.map +1 -1
  39. package/dist/react/astro/Notification.d.ts +1 -2
  40. package/dist/react/astro/Notification.js +229 -126
  41. package/dist/react/astro/Notification.js.map +1 -1
  42. package/dist/react/astro/Progress.d.ts +0 -1
  43. package/dist/react/astro/Progress.js +199 -141
  44. package/dist/react/astro/Progress.js.map +1 -1
  45. package/dist/react/astro/SimulationControls.d.ts +3 -4
  46. package/dist/react/astro/SimulationControls.js +596 -650
  47. package/dist/react/astro/SimulationControls.js.map +1 -1
  48. package/dist/react/astro/StatusIndicator.d.ts +0 -1
  49. package/dist/react/astro/StatusIndicator.js +236 -170
  50. package/dist/react/astro/StatusIndicator.js.map +1 -1
  51. package/dist/react/astro/UnifiedTimeline.d.ts +9 -10
  52. package/dist/react/astro/UnifiedTimeline.js +2345 -2392
  53. package/dist/react/astro/UnifiedTimeline.js.map +1 -1
  54. package/dist/react/astro/index.d.ts +5 -5
  55. package/dist/react/astro/index.js +1 -25
  56. package/dist/react/cards/AccessCard.d.ts +0 -1
  57. package/dist/react/cards/AccessCard.js +471 -405
  58. package/dist/react/cards/AccessCard.js.map +1 -1
  59. package/dist/react/cards/OrbitCard.d.ts +0 -1
  60. package/dist/react/cards/OrbitCard.js +487 -364
  61. package/dist/react/cards/OrbitCard.js.map +1 -1
  62. package/dist/react/cards/SpacecraftCard.d.ts +0 -1
  63. package/dist/react/cards/SpacecraftCard.js +813 -925
  64. package/dist/react/cards/SpacecraftCard.js.map +1 -1
  65. package/dist/react/cards/TelemetryCard.d.ts +0 -1
  66. package/dist/react/cards/TelemetryCard.js +1055 -732
  67. package/dist/react/cards/TelemetryCard.js.map +1 -1
  68. package/dist/react/cards/TelemetryStreamCard.d.ts +0 -1
  69. package/dist/react/cards/TelemetryStreamCard.js +323 -297
  70. package/dist/react/cards/TelemetryStreamCard.js.map +1 -1
  71. package/dist/react/cards/index.d.ts +1 -1
  72. package/dist/react/cards/index.js +1 -8
  73. package/dist/react/charts/GroundTrackMap.d.ts +6 -7
  74. package/dist/react/charts/GroundTrackMap.js +1377 -1256
  75. package/dist/react/charts/GroundTrackMap.js.map +1 -1
  76. package/dist/react/charts/GroundTrackMapLeaflet.d.ts +1 -2
  77. package/dist/react/charts/GroundTrackMapLeaflet.js +1065 -987
  78. package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -1
  79. package/dist/react/charts/groundTrackMapLeafletTiles.js +34 -25
  80. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -1
  81. package/dist/react/charts/groundTrackMapLeafletUtils.js +70 -61
  82. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -1
  83. package/dist/react/charts/index.d.ts +1 -1
  84. package/dist/react/charts/index.js +7 -100
  85. package/dist/react/charts/unified/AstroChart.d.ts +1 -2
  86. package/dist/react/charts/unified/AstroChart.js +1331 -1411
  87. package/dist/react/charts/unified/AstroChart.js.map +1 -1
  88. package/dist/react/charts/unified/PowerOverviewChart.d.ts +3 -3
  89. package/dist/react/charts/unified/PowerOverviewChart.js +495 -478
  90. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -1
  91. package/dist/react/charts/unified/domain.d.ts +12 -13
  92. package/dist/react/charts/unified/domain.js +3999 -3145
  93. package/dist/react/charts/unified/domain.js.map +1 -1
  94. package/dist/react/charts/unified/generators.d.ts +3 -4
  95. package/dist/react/charts/unified/generators.js +561 -498
  96. package/dist/react/charts/unified/generators.js.map +1 -1
  97. package/dist/react/charts/unified/index.d.ts +1 -1
  98. package/dist/react/charts/unified/presets.d.ts +14 -15
  99. package/dist/react/charts/unified/presets.js +857 -994
  100. package/dist/react/charts/unified/presets.js.map +1 -1
  101. package/dist/react/charts/unified/sync.d.ts +2 -3
  102. package/dist/react/charts/unified/sync.js +229 -195
  103. package/dist/react/charts/unified/sync.js.map +1 -1
  104. package/dist/react/charts/unified/theme.d.ts +11 -12
  105. package/dist/react/charts/unified/theme.js +606 -642
  106. package/dist/react/charts/unified/theme.js.map +1 -1
  107. package/dist/react/charts/unified/types.d.ts +32 -33
  108. package/dist/react/charts/unified/useChartStream.d.ts +1 -2
  109. package/dist/react/charts/unified/useChartStream.js +203 -216
  110. package/dist/react/charts/unified/useChartStream.js.map +1 -1
  111. package/dist/react/chatgpt/AppCard.d.ts +1 -2
  112. package/dist/react/chatgpt/index.d.ts +7 -7
  113. package/dist/react/chatgpt/index.js +160 -139
  114. package/dist/react/chatgpt/index.js.map +1 -1
  115. package/dist/react/context/CategoryContext.d.ts +0 -1
  116. package/dist/react/context/CategoryContext.js +78 -29
  117. package/dist/react/context/CategoryContext.js.map +1 -1
  118. package/dist/react/context/DisplaySettingsContext.d.ts +1 -2
  119. package/dist/react/context/DisplaySettingsContext.js +205 -156
  120. package/dist/react/context/DisplaySettingsContext.js.map +1 -1
  121. package/dist/react/context/SpatialSelectionContext.d.ts +0 -1
  122. package/dist/react/context/SpatialSelectionContext.js +36 -7
  123. package/dist/react/context/SpatialSelectionContext.js.map +1 -1
  124. package/dist/react/core/data/DataTable.d.ts +3 -4
  125. package/dist/react/core/data/DataTable.js +473 -440
  126. package/dist/react/core/data/DataTable.js.map +1 -1
  127. package/dist/react/core/data/DataValue.d.ts +4 -5
  128. package/dist/react/core/data/DataValue.js +605 -571
  129. package/dist/react/core/data/DataValue.js.map +1 -1
  130. package/dist/react/core/data/propertyConfig.d.ts +1 -2
  131. package/dist/react/core/data/propertyConfig.js +446 -382
  132. package/dist/react/core/data/propertyConfig.js.map +1 -1
  133. package/dist/react/core/display/AstroIcon.d.ts +4 -5
  134. package/dist/react/core/display/AstroIcon.js +339 -429
  135. package/dist/react/core/display/AstroIcon.js.map +1 -1
  136. package/dist/react/core/display/Badge.d.ts +2 -3
  137. package/dist/react/core/display/Badge.js +131 -131
  138. package/dist/react/core/display/Badge.js.map +1 -1
  139. package/dist/react/core/display/CardHeader.d.ts +0 -1
  140. package/dist/react/core/display/CardHeader.js +398 -311
  141. package/dist/react/core/display/CardHeader.js.map +1 -1
  142. package/dist/react/core/display/Container.d.ts +2 -3
  143. package/dist/react/core/display/Container.js +640 -668
  144. package/dist/react/core/display/Container.js.map +1 -1
  145. package/dist/react/core/display/CopyButton.d.ts +1 -2
  146. package/dist/react/core/display/CopyButton.js +158 -101
  147. package/dist/react/core/display/CopyButton.js.map +1 -1
  148. package/dist/react/core/display/GlassCard.d.ts +3 -4
  149. package/dist/react/core/display/GlassCard.js +416 -369
  150. package/dist/react/core/display/GlassCard.js.map +1 -1
  151. package/dist/react/core/display/HeaderIconWithStatus.d.ts +0 -1
  152. package/dist/react/core/display/HeaderIconWithStatus.js +152 -152
  153. package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -1
  154. package/dist/react/core/display/Icon.d.ts +2 -3
  155. package/dist/react/core/display/Icon.js +172 -143
  156. package/dist/react/core/display/Icon.js.map +1 -1
  157. package/dist/react/core/display/Typography.d.ts +24 -25
  158. package/dist/react/core/display/Typography.js +360 -178
  159. package/dist/react/core/display/Typography.js.map +1 -1
  160. package/dist/react/core/feedback/ConfirmDialog.d.ts +1 -2
  161. package/dist/react/core/feedback/ConfirmDialog.js +343 -304
  162. package/dist/react/core/feedback/ConfirmDialog.js.map +1 -1
  163. package/dist/react/core/feedback/Dialog.d.ts +2 -3
  164. package/dist/react/core/feedback/Dialog.js +189 -197
  165. package/dist/react/core/feedback/Dialog.js.map +1 -1
  166. package/dist/react/core/feedback/Toast.d.ts +2 -3
  167. package/dist/react/core/feedback/Toast.js +346 -207
  168. package/dist/react/core/feedback/Toast.js.map +1 -1
  169. package/dist/react/core/index.d.ts +26 -26
  170. package/dist/react/core/index.js +7 -119
  171. package/dist/react/core/inputs/Button.d.ts +2 -3
  172. package/dist/react/core/inputs/Button.js +281 -304
  173. package/dist/react/core/inputs/Button.js.map +1 -1
  174. package/dist/react/core/inputs/Checkbox.d.ts +2 -3
  175. package/dist/react/core/inputs/Checkbox.js +139 -127
  176. package/dist/react/core/inputs/Checkbox.js.map +1 -1
  177. package/dist/react/core/inputs/Input.d.ts +3 -4
  178. package/dist/react/core/inputs/Input.js +277 -285
  179. package/dist/react/core/inputs/Input.js.map +1 -1
  180. package/dist/react/core/inputs/LimitsBar.d.ts +1 -2
  181. package/dist/react/core/inputs/LimitsBar.js +271 -196
  182. package/dist/react/core/inputs/LimitsBar.js.map +1 -1
  183. package/dist/react/core/inputs/NumberInput.d.ts +2 -3
  184. package/dist/react/core/inputs/NumberInput.js +531 -503
  185. package/dist/react/core/inputs/NumberInput.js.map +1 -1
  186. package/dist/react/core/inputs/PinInput.d.ts +2 -3
  187. package/dist/react/core/inputs/PinInput.js +224 -207
  188. package/dist/react/core/inputs/PinInput.js.map +1 -1
  189. package/dist/react/core/inputs/Select.d.ts +1 -2
  190. package/dist/react/core/inputs/Select.js +298 -299
  191. package/dist/react/core/inputs/Select.js.map +1 -1
  192. package/dist/react/core/inputs/Toggle.d.ts +2 -3
  193. package/dist/react/core/inputs/Toggle.js +142 -148
  194. package/dist/react/core/inputs/Toggle.js.map +1 -1
  195. package/dist/react/core/layout/Box.d.ts +3 -4
  196. package/dist/react/core/layout/Box.js +118 -122
  197. package/dist/react/core/layout/Box.js.map +1 -1
  198. package/dist/react/core/layout/Center.d.ts +0 -1
  199. package/dist/react/core/layout/Center.js +45 -32
  200. package/dist/react/core/layout/Center.js.map +1 -1
  201. package/dist/react/core/layout/Divider.d.ts +1 -2
  202. package/dist/react/core/layout/Divider.js +112 -106
  203. package/dist/react/core/layout/Divider.js.map +1 -1
  204. package/dist/react/core/layout/Flex.d.ts +4 -5
  205. package/dist/react/core/layout/Flex.js +120 -124
  206. package/dist/react/core/layout/Flex.js.map +1 -1
  207. package/dist/react/core/layout/Grid.d.ts +5 -6
  208. package/dist/react/core/layout/Grid.js +131 -138
  209. package/dist/react/core/layout/Grid.js.map +1 -1
  210. package/dist/react/core/layout/Spacer.d.ts +0 -1
  211. package/dist/react/core/layout/Spacer.js +36 -29
  212. package/dist/react/core/layout/Spacer.js.map +1 -1
  213. package/dist/react/core/layout/Stack.d.ts +4 -5
  214. package/dist/react/core/layout/Stack.js +127 -70
  215. package/dist/react/core/layout/Stack.js.map +1 -1
  216. package/dist/react/core/layout/responsive.d.ts +1 -2
  217. package/dist/react/core/layout/responsive.js +25 -19
  218. package/dist/react/core/layout/responsive.js.map +1 -1
  219. package/dist/react/core/layout/useBreakpoint.d.ts +1 -1
  220. package/dist/react/core/layout/useBreakpoint.js +119 -66
  221. package/dist/react/core/layout/useBreakpoint.js.map +1 -1
  222. package/dist/react/core/navigation/AppBar.d.ts +1 -2
  223. package/dist/react/core/navigation/AppBar.js +827 -805
  224. package/dist/react/core/navigation/AppBar.js.map +1 -1
  225. package/dist/react/core/navigation/Pagination.d.ts +2 -3
  226. package/dist/react/core/navigation/Pagination.js +207 -187
  227. package/dist/react/core/navigation/Pagination.js.map +1 -1
  228. package/dist/react/core/navigation/SideNav.d.ts +5 -6
  229. package/dist/react/core/navigation/SideNav.js +855 -629
  230. package/dist/react/core/navigation/SideNav.js.map +1 -1
  231. package/dist/react/core/navigation/Tabs.d.ts +0 -1
  232. package/dist/react/core/navigation/Tabs.js +113 -119
  233. package/dist/react/core/navigation/Tabs.js.map +1 -1
  234. package/dist/react/core/overlays/Popover.d.ts +2 -3
  235. package/dist/react/core/overlays/Popover.js +303 -282
  236. package/dist/react/core/overlays/Popover.js.map +1 -1
  237. package/dist/react/core/overlays/SidePanel.d.ts +1 -2
  238. package/dist/react/core/overlays/SidePanel.js +217 -212
  239. package/dist/react/core/overlays/SidePanel.js.map +1 -1
  240. package/dist/react/core/overlays/Tooltip.d.ts +1 -2
  241. package/dist/react/core/overlays/Tooltip.js +170 -176
  242. package/dist/react/core/overlays/Tooltip.js.map +1 -1
  243. package/dist/react/core/widgets/ActivityPlanner.d.ts +0 -1
  244. package/dist/react/core/widgets/ActivityPlanner.js +855 -517
  245. package/dist/react/core/widgets/ActivityPlanner.js.map +1 -1
  246. package/dist/react/core/widgets/Capture.d.ts +2 -3
  247. package/dist/react/core/widgets/Capture.js +965 -779
  248. package/dist/react/core/widgets/Capture.js.map +1 -1
  249. package/dist/react/core/widgets/ChatPanel.d.ts +16 -17
  250. package/dist/react/core/widgets/ChatPanel.js +1734 -1034
  251. package/dist/react/core/widgets/ChatPanel.js.map +1 -1
  252. package/dist/react/core/widgets/ColorPickerPanel.d.ts +0 -1
  253. package/dist/react/core/widgets/ColorPickerPanel.js +298 -287
  254. package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -1
  255. package/dist/react/core/widgets/CommandBuilder.d.ts +2 -3
  256. package/dist/react/core/widgets/CommandBuilder.js +624 -516
  257. package/dist/react/core/widgets/CommandBuilder.js.map +1 -1
  258. package/dist/react/core/widgets/ConnectionForm.d.ts +2 -3
  259. package/dist/react/core/widgets/ConnectionForm.js +528 -492
  260. package/dist/react/core/widgets/ConnectionForm.js.map +1 -1
  261. package/dist/react/core/widgets/FileExplorer.d.ts +3 -4
  262. package/dist/react/core/widgets/FileExplorer.js +617 -505
  263. package/dist/react/core/widgets/FileExplorer.js.map +1 -1
  264. package/dist/react/core/widgets/HexViewer.d.ts +2 -3
  265. package/dist/react/core/widgets/HexViewer.js +1353 -1091
  266. package/dist/react/core/widgets/HexViewer.js.map +1 -1
  267. package/dist/react/core/widgets/ImageFrame.d.ts +1 -2
  268. package/dist/react/core/widgets/ImageFrame.js +230 -193
  269. package/dist/react/core/widgets/ImageFrame.js.map +1 -1
  270. package/dist/react/core/widgets/ImageGallery.d.ts +2 -1
  271. package/dist/react/core/widgets/ImageGallery.js +380 -314
  272. package/dist/react/core/widgets/ImageGallery.js.map +1 -1
  273. package/dist/react/core/widgets/ImagePanel.d.ts +0 -1
  274. package/dist/react/core/widgets/ImagePanel.js +110 -101
  275. package/dist/react/core/widgets/ImagePanel.js.map +1 -1
  276. package/dist/react/core/widgets/LogViewer.d.ts +2 -3
  277. package/dist/react/core/widgets/LogViewer.js +711 -607
  278. package/dist/react/core/widgets/LogViewer.js.map +1 -1
  279. package/dist/react/core/widgets/MessageStream.d.ts +3 -4
  280. package/dist/react/core/widgets/MessageStream.js +514 -444
  281. package/dist/react/core/widgets/MessageStream.js.map +1 -1
  282. package/dist/react/core/widgets/MissionCalendar.d.ts +3 -4
  283. package/dist/react/core/widgets/MissionCalendar.js +1488 -1020
  284. package/dist/react/core/widgets/MissionCalendar.js.map +1 -1
  285. package/dist/react/core/widgets/PacketViewer.d.ts +2 -3
  286. package/dist/react/core/widgets/PacketViewer.js +550 -421
  287. package/dist/react/core/widgets/PacketViewer.js.map +1 -1
  288. package/dist/react/core/widgets/capture-placeholder.png.js +6 -5
  289. package/dist/react/core/widgets/capture-placeholder.png.js.map +1 -1
  290. package/dist/react/hooks/index.d.ts +5 -5
  291. package/dist/react/hooks/useAccessWindows.d.ts +0 -1
  292. package/dist/react/hooks/useCompactMode.d.ts +1 -1
  293. package/dist/react/hooks/useCompactMode.js +104 -58
  294. package/dist/react/hooks/useCompactMode.js.map +1 -1
  295. package/dist/react/hooks/useGroundTrackHistory.d.ts +0 -1
  296. package/dist/react/hooks/useSimulationScene.d.ts +1 -2
  297. package/dist/react/hooks/useSimulationScene.js +481 -374
  298. package/dist/react/hooks/useSimulationScene.js.map +1 -1
  299. package/dist/react/index.d.ts +3 -3
  300. package/dist/react/panels/LayerControlPanel.d.ts +1 -2
  301. package/dist/react/panels/LayerControlPanel.js +223 -180
  302. package/dist/react/panels/LayerControlPanel.js.map +1 -1
  303. package/dist/react/panels/ObjectInventoryPanel.d.ts +2 -3
  304. package/dist/react/panels/ObjectInventoryPanel.js +315 -250
  305. package/dist/react/panels/ObjectInventoryPanel.js.map +1 -1
  306. package/dist/react/panels/index.d.ts +1 -1
  307. package/dist/react/panels/index.js +1 -6
  308. package/dist/react/shared/ErrorBoundary.d.ts +1 -2
  309. package/dist/react/shared/ErrorBoundary.js +170 -139
  310. package/dist/react/shared/ErrorBoundary.js.map +1 -1
  311. package/dist/react/shared/Skeleton.d.ts +1 -2
  312. package/dist/react/shared/Skeleton.js +300 -301
  313. package/dist/react/shared/Skeleton.js.map +1 -1
  314. package/dist/react/theme/ThemeProvider.d.ts +2 -321
  315. package/dist/react/theme/ThemeProvider.js +313 -939
  316. package/dist/react/theme/ThemeProvider.js.map +1 -1
  317. package/dist/react/theme/cardAccent.d.ts +1 -2
  318. package/dist/react/theme/cardAccent.js +196 -126
  319. package/dist/react/theme/cardAccent.js.map +1 -1
  320. package/dist/react/theme/config.d.ts +0 -1
  321. package/dist/react/theme/config.js +47 -25
  322. package/dist/react/theme/config.js.map +1 -1
  323. package/dist/react/theme/index.d.ts +2 -2
  324. package/dist/react/theme/index.js +1 -16
  325. package/dist/react/theme/types.d.ts +332 -0
  326. package/dist/react/theme/types.js +39 -0
  327. package/dist/react/theme/types.js.map +1 -0
  328. package/dist/react/types.d.ts +8 -8
  329. package/dist/react/types.js +147 -47
  330. package/dist/react/types.js.map +1 -1
  331. package/dist/react/utils/categoryPalette.d.ts +0 -1
  332. package/dist/react/utils/categoryPalette.js +91 -102
  333. package/dist/react/utils/categoryPalette.js.map +1 -1
  334. package/dist/react/utils/index.d.ts +5 -5
  335. package/dist/react/utils/index.js +457 -371
  336. package/dist/react/utils/index.js.map +1 -1
  337. package/dist/react/visualizations/EclipseTimerCard.d.ts +0 -1
  338. package/dist/react/visualizations/LinkBudgetCard.d.ts +0 -1
  339. package/dist/react/visualizations/NavBallCard.d.ts +0 -1
  340. package/dist/react/visualizations/PropulsionCard.d.ts +1 -2
  341. package/dist/react/visualizations/SensorFootprintCard.d.ts +1 -2
  342. package/dist/react/visualizations/ThermalHeatmapCard.d.ts +0 -1
  343. package/dist/react/visualizations/index.d.ts +3 -3
  344. package/dist/react.d.ts +2 -1
  345. package/dist/react.js +17 -221
  346. package/dist/shaders/atmosphere.frag.js +6 -5
  347. package/dist/shaders/atmosphere.frag.js.map +1 -1
  348. package/dist/shaders/atmosphere.vert.js +6 -5
  349. package/dist/shaders/atmosphere.vert.js.map +1 -1
  350. package/dist/shaders/stars.frag.js +6 -5
  351. package/dist/shaders/stars.frag.js.map +1 -1
  352. package/dist/shaders/stars.vert.js +6 -5
  353. package/dist/shaders/stars.vert.js.map +1 -1
  354. package/dist/style.css +26 -3
  355. package/dist/tokens/core.d.ts +159 -0
  356. package/dist/tokens/core.js +144 -0
  357. package/dist/tokens/core.js.map +1 -0
  358. package/dist/tokens/css-vars.d.ts +213 -2
  359. package/dist/tokens/css-vars.js +590 -227
  360. package/dist/tokens/css-vars.js.map +1 -1
  361. package/dist/tokens/index.d.ts +31 -228
  362. package/dist/tokens/index.js +281 -366
  363. package/dist/tokens/index.js.map +1 -1
  364. package/dist/tokens/palettes/astro.d.ts +129 -0
  365. package/dist/tokens/palettes/astro.js +112 -0
  366. package/dist/tokens/palettes/astro.js.map +1 -0
  367. package/dist/tokens/palettes/index.d.ts +288 -0
  368. package/dist/tokens/palettes/index.js +35 -0
  369. package/dist/tokens/palettes/index.js.map +1 -0
  370. package/dist/tokens/palettes/tailwind.d.ts +324 -0
  371. package/dist/tokens/palettes/tailwind.js +201 -0
  372. package/dist/tokens/palettes/tailwind.js.map +1 -0
  373. package/dist/tokens/palettes/zendir.d.ts +126 -0
  374. package/dist/tokens/palettes/zendir.js +92 -0
  375. package/dist/tokens/palettes/zendir.js.map +1 -0
  376. package/dist/tokens/themes.d.ts +30 -0
  377. package/dist/tokens/themes.js +704 -0
  378. package/dist/tokens/themes.js.map +1 -0
  379. package/dist/tokens/tokens.css +533 -155
  380. package/dist/types/index.d.ts +2 -2
  381. package/package.json +310 -313
  382. package/dist/index.js.map +0 -1
  383. package/dist/react/3d/index.js.map +0 -1
  384. package/dist/react/astro/index.js.map +0 -1
  385. package/dist/react/cards/index.js.map +0 -1
  386. package/dist/react/charts/index.js.map +0 -1
  387. package/dist/react/core/index.js.map +0 -1
  388. package/dist/react/panels/index.js.map +0 -1
  389. package/dist/react/theme/astro-tokens.d.ts +0 -153
  390. package/dist/react/theme/index.js.map +0 -1
  391. package/dist/react.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/react/utils/index.ts"],"sourcesContent":["/**\n * @zendir/ui - Enterprise Utility Functions\n * \n * Shared utilities for null-safety, formatting, and defensive coding.\n * These utilities ensure components never crash due to undefined data.\n */\n\n// ============================================================================\n// NULL SAFETY UTILITIES\n// ============================================================================\n\n/**\n * Safely access a value with a fallback for null/undefined\n * @example withNullSafety(data?.temperature, 0) // Returns 0 if undefined\n */\nexport function withNullSafety<T>(value: T | null | undefined, fallback: T): T {\n return value ?? fallback;\n}\n\n/**\n * Safely format a number, returning '--' if undefined\n * @example safeNumber(data?.value, 2) // \"123.45\" or \"--\"\n */\nexport function safeNumber(\n value: number | null | undefined,\n decimals: number = 2,\n fallback: string = '--'\n): string {\n if (value === null || value === undefined || !Number.isFinite(value)) {\n return fallback;\n }\n return value.toFixed(decimals);\n}\n\n/**\n * Check if value is a valid finite number\n */\nexport function isValidNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\n// ============================================================================\n// NUMBER FORMATTING\n// ============================================================================\n\nexport interface FormatNumberOptions {\n decimals?: number;\n locale?: string;\n notation?: 'standard' | 'scientific' | 'engineering' | 'compact';\n unit?: string;\n signDisplay?: 'auto' | 'never' | 'always' | 'exceptZero';\n}\n\n/**\n * Format a number with locale-aware formatting and optional unit\n * @example formatNumber(1234567, { notation: 'compact' }) // \"1.2M\"\n */\nexport function formatNumber(\n value: number | null | undefined,\n options: FormatNumberOptions = {}\n): string {\n if (value === null || value === undefined || !Number.isFinite(value)) {\n return '--';\n }\n\n const {\n decimals = 2,\n locale = 'en-US',\n notation = 'standard',\n unit,\n signDisplay = 'auto',\n } = options;\n\n try {\n const formatted = new Intl.NumberFormat(locale, {\n notation,\n minimumFractionDigits: notation === 'compact' ? 0 : decimals,\n maximumFractionDigits: decimals,\n signDisplay,\n }).format(value);\n\n return unit ? `${formatted} ${unit}` : formatted;\n } catch {\n return value.toFixed(decimals);\n }\n}\n\n/**\n * Format a number with tabular (monospace) digits for alignment\n * Uses font-feature-settings: 'tnum' 1\n */\nexport function formatTabular(\n value: number | null | undefined,\n decimals: number = 2\n): string {\n return safeNumber(value, decimals);\n}\n\n// ============================================================================\n// UNIT-AWARE FORMATTING\n// ============================================================================\n\n/**\n * Format temperature with unit conversion\n * @example formatTemperature(25) // \"25.0°C\"\n * @example formatTemperature(25, 'fahrenheit') // \"77.0°F\"\n */\nexport function formatTemperature(\n celsius: number | null | undefined,\n unit: 'celsius' | 'fahrenheit' | 'kelvin' = 'celsius',\n decimals: number = 1\n): string {\n if (celsius === null || celsius === undefined || !Number.isFinite(celsius)) {\n return '--°C';\n }\n\n switch (unit) {\n case 'fahrenheit':\n return `${((celsius * 9) / 5 + 32).toFixed(decimals)}°F`;\n case 'kelvin':\n return `${(celsius + 273.15).toFixed(decimals)}K`;\n default:\n return `${celsius.toFixed(decimals)}°C`;\n }\n}\n\n/**\n * Format data rate with automatic unit scaling\n * @example formatDataRate(1500000) // \"1.50 Mbps\"\n */\nexport function formatDataRate(bitsPerSecond: number | null | undefined): string {\n if (bitsPerSecond === null || bitsPerSecond === undefined || !Number.isFinite(bitsPerSecond)) {\n return '-- bps';\n }\n\n const units = ['bps', 'Kbps', 'Mbps', 'Gbps', 'Tbps'];\n let unitIndex = 0;\n let value = bitsPerSecond;\n\n while (value >= 1000 && unitIndex < units.length - 1) {\n value /= 1000;\n unitIndex++;\n }\n\n return `${value.toFixed(2)} ${units[unitIndex]}`;\n}\n\n/**\n * Format distance with automatic unit scaling\n * @example formatDistance(1500) // \"1.50 km\"\n */\nexport function formatDistance(meters: number | null | undefined): string {\n if (meters === null || meters === undefined || !Number.isFinite(meters)) {\n return '-- m';\n }\n\n if (meters >= 1_000_000) {\n return `${(meters / 1_000_000).toFixed(2)} Mm`;\n } else if (meters >= 1_000) {\n return `${(meters / 1_000).toFixed(2)} km`;\n } else if (meters < 1) {\n return `${(meters * 100).toFixed(1)} cm`;\n }\n return `${meters.toFixed(1)} m`;\n}\n\n/**\n * Format altitude (always in km for space ops)\n * @example formatAltitude(418.2) // \"418.2 km\"\n */\nexport function formatAltitude(km: number | null | undefined): string {\n if (km === null || km === undefined || !Number.isFinite(km)) {\n return '-- km';\n }\n return `${km.toFixed(1)} km`;\n}\n\n/**\n * Format velocity\n * @example formatVelocity(7.66) // \"7.66 km/s\"\n */\nexport function formatVelocity(kmPerSec: number | null | undefined): string {\n if (kmPerSec === null || kmPerSec === undefined || !Number.isFinite(kmPerSec)) {\n return '-- km/s';\n }\n return `${kmPerSec.toFixed(2)} km/s`;\n}\n\n/**\n * Format percentage with bounds checking\n * @example formatPercentage(0.856) // \"85.6%\"\n * @example formatPercentage(85.6, false) // \"85.6%\" (already percentage)\n */\nexport function formatPercentage(\n value: number | null | undefined,\n isDecimal: boolean = false,\n decimals: number = 1\n): string {\n if (value === null || value === undefined || !Number.isFinite(value)) {\n return '--%';\n }\n\n const percentage = isDecimal ? value * 100 : value;\n return `${percentage.toFixed(decimals)}%`;\n}\n\n/**\n * Format power (watts) with auto-scaling\n * @example formatPower(1500) // \"1.50 kW\"\n */\nexport function formatPower(watts: number | null | undefined): string {\n if (watts === null || watts === undefined || !Number.isFinite(watts)) {\n return '-- W';\n }\n\n if (Math.abs(watts) >= 1_000_000) {\n return `${(watts / 1_000_000).toFixed(2)} MW`;\n } else if (Math.abs(watts) >= 1_000) {\n return `${(watts / 1_000).toFixed(2)} kW`;\n } else if (Math.abs(watts) < 1) {\n return `${(watts * 1000).toFixed(1)} mW`;\n }\n return `${watts.toFixed(1)} W`;\n}\n\n/**\n * Format frequency (Hz) with auto-scaling\n * @example formatFrequency(2400000000) // \"2.40 GHz\"\n */\nexport function formatFrequency(hz: number | null | undefined): string {\n if (hz === null || hz === undefined || !Number.isFinite(hz)) {\n return '-- Hz';\n }\n\n if (hz >= 1_000_000_000) {\n return `${(hz / 1_000_000_000).toFixed(2)} GHz`;\n } else if (hz >= 1_000_000) {\n return `${(hz / 1_000_000).toFixed(2)} MHz`;\n } else if (hz >= 1_000) {\n return `${(hz / 1_000).toFixed(2)} kHz`;\n }\n return `${hz.toFixed(0)} Hz`;\n}\n\n// ============================================================================\n// TIME FORMATTING\n// ============================================================================\n\n/**\n * Format duration in human-readable form\n * @example formatDuration(3661) // \"1h 1m 1s\"\n */\nexport function formatDuration(seconds: number | null | undefined): string {\n if (seconds === null || seconds === undefined || !Number.isFinite(seconds)) {\n return '--:--';\n }\n\n const absSeconds = Math.abs(seconds);\n const sign = seconds < 0 ? '-' : '';\n\n if (absSeconds < 60) {\n return `${sign}${absSeconds.toFixed(0)}s`;\n } else if (absSeconds < 3600) {\n const mins = Math.floor(absSeconds / 60);\n const secs = Math.floor(absSeconds % 60);\n return `${sign}${mins}m ${secs}s`;\n } else if (absSeconds < 86400) {\n const hours = Math.floor(absSeconds / 3600);\n const mins = Math.floor((absSeconds % 3600) / 60);\n return `${sign}${hours}h ${mins}m`;\n } else {\n const days = Math.floor(absSeconds / 86400);\n const hours = Math.floor((absSeconds % 86400) / 3600);\n return `${sign}${days}d ${hours}h`;\n }\n}\n\n/**\n * Format countdown timer (supports negative values for past events)\n * @example formatCountdown(125) // \"T-02:05\"\n * @example formatCountdown(-60) // \"T+01:00\"\n */\nexport function formatCountdown(seconds: number | null | undefined): string {\n if (seconds === null || seconds === undefined || !Number.isFinite(seconds)) {\n return 'T--:--';\n }\n\n const prefix = seconds >= 0 ? 'T-' : 'T+';\n const absSeconds = Math.abs(seconds);\n\n if (absSeconds >= 3600) {\n const hours = Math.floor(absSeconds / 3600);\n const mins = Math.floor((absSeconds % 3600) / 60);\n const secs = Math.floor(absSeconds % 60);\n return `${prefix}${hours}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;\n }\n\n const mins = Math.floor(absSeconds / 60);\n const secs = Math.floor(absSeconds % 60);\n return `${prefix}${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;\n}\n\n/**\n * Format UTC timestamp\n * @example formatUTC(new Date()) // \"2026-01-27 14:30:00Z\"\n */\nexport function formatUTC(date: Date | string | null | undefined): string {\n if (!date) return '--:--:-- UTC';\n\n try {\n const d = typeof date === 'string' ? new Date(date) : date;\n if (isNaN(d.getTime())) return '--:--:-- UTC';\n\n return d.toISOString().replace('T', ' ').slice(0, 19) + 'Z';\n } catch {\n return '--:--:-- UTC';\n }\n}\n\n/**\n * Format time only (HH:MM:SS)\n * @example formatTime(new Date()) // \"14:30:00\"\n */\nexport function formatTime(date: Date | string | null | undefined, includeSeconds = true): string {\n if (!date) return includeSeconds ? '--:--:--' : '--:--';\n\n try {\n const d = typeof date === 'string' ? new Date(date) : date;\n if (isNaN(d.getTime())) return includeSeconds ? '--:--:--' : '--:--';\n\n const hours = d.getUTCHours().toString().padStart(2, '0');\n const mins = d.getUTCMinutes().toString().padStart(2, '0');\n const secs = d.getUTCSeconds().toString().padStart(2, '0');\n\n return includeSeconds ? `${hours}:${mins}:${secs}` : `${hours}:${mins}`;\n } catch {\n return includeSeconds ? '--:--:--' : '--:--';\n }\n}\n\n// ============================================================================\n// COORDINATE FORMATTING\n// ============================================================================\n\n/**\n * Format latitude/longitude\n * @example formatCoordinate(32.4, 'lat') // \"32.40° N\"\n * @example formatCoordinate(-117.2, 'lon') // \"117.20° W\"\n */\nexport function formatCoordinate(\n value: number | null | undefined,\n type: 'lat' | 'lon'\n): string {\n if (value === null || value === undefined || !Number.isFinite(value)) {\n return '--°';\n }\n\n const absValue = Math.abs(value);\n let direction: string;\n\n if (type === 'lat') {\n direction = value >= 0 ? 'N' : 'S';\n } else {\n direction = value >= 0 ? 'E' : 'W';\n }\n\n return `${absValue.toFixed(2)}° ${direction}`;\n}\n\n/**\n * Format lat/lon pair\n * @example formatLatLon(32.4, -117.2) // \"32.40° N, 117.20° W\"\n */\nexport function formatLatLon(\n lat: number | null | undefined,\n lon: number | null | undefined\n): string {\n return `${formatCoordinate(lat, 'lat')}, ${formatCoordinate(lon, 'lon')}`;\n}\n\n// ============================================================================\n// ANGLE FORMATTING\n// ============================================================================\n\n/**\n * Format angle in degrees\n * @example formatDegrees(45.5) // \"45.5°\"\n */\nexport function formatDegrees(\n value: number | null | undefined,\n decimals: number = 1\n): string {\n if (value === null || value === undefined || !Number.isFinite(value)) {\n return '--°';\n }\n return `${value.toFixed(decimals)}°`;\n}\n\n/**\n * Format decibels\n * @example formatDecibels(3.5) // \"3.5 dB\"\n */\nexport function formatDecibels(\n value: number | null | undefined,\n decimals: number = 1\n): string {\n if (value === null || value === undefined || !Number.isFinite(value)) {\n return '-- dB';\n }\n return `${value.toFixed(decimals)} dB`;\n}\n\n// ============================================================================\n// VALUE UTILITIES\n// ============================================================================\n\n/**\n * Clamp a value between min and max\n * @example clamp(150, 0, 100) // 100\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Linear interpolation\n * @example lerp(0, 100, 0.5) // 50\n */\nexport function lerp(start: number, end: number, t: number): number {\n return start + (end - start) * clamp(t, 0, 1);\n}\n\n/**\n * Map a value from one range to another\n * @example mapRange(50, 0, 100, 0, 1) // 0.5\n */\nexport function mapRange(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number\n): number {\n const t = (value - inMin) / (inMax - inMin);\n return lerp(outMin, outMax, t);\n}\n\n// ============================================================================\n// STATUS UTILITIES\n// ============================================================================\n\nexport type StatusLevel = 'off' | 'standby' | 'normal' | 'caution' | 'serious' | 'critical';\n\n/**\n * Astro UX Design System status colors\n * These match the official Astro status semantics\n */\nexport const STATUS_COLORS: Record<StatusLevel, string> = {\n off: '#a4abb6',\n standby: '#2dccff',\n normal: '#56f000',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n};\n\n/**\n * Get status color from level\n * @example getStatusColor('normal') // '#56f000'\n */\nexport function getStatusColor(status: StatusLevel | null | undefined): string {\n return STATUS_COLORS[status ?? 'off'];\n}\n\n/**\n * Derive status for battery specifically (low is bad)\n * @example deriveBatteryStatus(25) // 'caution'\n */\nexport function deriveBatteryStatus(level: number | undefined | null): StatusLevel {\n if (level === undefined || level === null) return 'off';\n if (level <= 10) return 'critical';\n if (level <= 20) return 'serious';\n if (level <= 30) return 'caution';\n return 'normal';\n}\n\n/**\n * Determine status level from a value and thresholds\n * @example getStatusFromValue(85, { critical: 20, serious: 40, caution: 60, normal: 80 }) // 'normal'\n */\nexport function getStatusFromValue(\n value: number | null | undefined,\n thresholds: {\n critical?: number;\n serious?: number;\n caution?: number;\n normal?: number;\n },\n higherIsBetter: boolean = true\n): StatusLevel {\n if (value === null || value === undefined || !Number.isFinite(value)) {\n return 'off';\n }\n\n const { critical = 10, serious = 25, caution = 50, normal = 75 } = thresholds;\n\n if (higherIsBetter) {\n if (value <= critical) return 'critical';\n if (value <= serious) return 'serious';\n if (value <= caution) return 'caution';\n if (value <= normal) return 'standby';\n return 'normal';\n } else {\n if (value >= critical) return 'critical';\n if (value >= serious) return 'serious';\n if (value >= caution) return 'caution';\n if (value >= normal) return 'standby';\n return 'normal';\n }\n}\n\n// ============================================================================\n// STATUS NORMALIZATION\n// ============================================================================\n\n/**\n * Domain status terms that map to UI StatusLevel\n * This handles common backend/sensor terminology\n */\nconst STATUS_MAPPING: Record<string, StatusLevel> = {\n // → 'off'\n 'off': 'off',\n 'disabled': 'off',\n 'inactive': 'off',\n 'offline': 'off',\n 'unknown': 'off',\n 'null': 'off',\n 'none': 'off',\n \n // → 'standby'\n 'standby': 'standby',\n 'idle': 'standby',\n 'waiting': 'standby',\n 'ready': 'standby',\n 'pending': 'standby',\n 'queued': 'standby',\n \n // → 'normal'\n 'normal': 'normal',\n 'nominal': 'normal',\n 'healthy': 'normal',\n 'ok': 'normal',\n 'good': 'normal',\n 'success': 'normal',\n 'operational': 'normal',\n 'active': 'normal',\n 'online': 'normal',\n 'connected': 'normal',\n 'stable': 'normal',\n 'transmitting': 'normal',\n 'receiving': 'normal',\n \n // → 'caution'\n 'caution': 'caution',\n 'warning': 'caution',\n 'degraded': 'caution',\n 'elevated': 'caution',\n 'alert': 'caution',\n 'attention': 'caution',\n 'limited': 'caution',\n \n // → 'serious'\n 'serious': 'serious',\n 'unstable': 'serious',\n 'danger': 'serious',\n 'severe': 'serious',\n \n // → 'critical'\n 'critical': 'critical',\n 'error': 'critical',\n 'failed': 'critical',\n 'failure': 'critical',\n 'emergency': 'critical',\n 'fault': 'critical',\n 'alarm': 'critical',\n};\n\n/**\n * Normalize any status string to the 6-level StatusLevel system\n * \n * @param status - Any status string from domain/backend\n * @param defaultStatus - Fallback if status is not recognized (default: 'off')\n * @returns StatusLevel\n * \n * @example\n * ```typescript\n * normalizeStatus('degraded') // 'caution'\n * normalizeStatus('nominal') // 'normal'\n * normalizeStatus('transmitting') // 'normal'\n * normalizeStatus('warning') // 'caution'\n * normalizeStatus('error') // 'critical'\n * normalizeStatus(undefined) // 'off'\n * ```\n */\nexport function normalizeStatus(\n status: string | undefined | null,\n defaultStatus: StatusLevel = 'off'\n): StatusLevel {\n if (!status) return defaultStatus;\n \n const normalized = status.toLowerCase().trim();\n return STATUS_MAPPING[normalized] ?? defaultStatus;\n}\n\n/**\n * Check if a string is a valid StatusLevel\n */\nexport function isStatusLevel(value: string): value is StatusLevel {\n return ['off', 'standby', 'normal', 'caution', 'serious', 'critical'].includes(value);\n}\n\n/**\n * Get the severity order of a status (higher = more severe)\n * Useful for sorting or finding worst status\n */\nexport function getStatusSeverity(status: StatusLevel): number {\n const order: Record<StatusLevel, number> = {\n off: 0,\n standby: 1,\n normal: 2,\n caution: 3,\n serious: 4,\n critical: 5,\n };\n return order[status];\n}\n\n/**\n * Get the worst (most severe) status from an array\n * \n * @example\n * ```typescript\n * getWorstStatus(['normal', 'caution', 'normal']) // 'caution'\n * getWorstStatus(['normal', 'critical', 'caution']) // 'critical'\n * ```\n */\nexport function getWorstStatus(statuses: StatusLevel[]): StatusLevel {\n if (statuses.length === 0) return 'off';\n return statuses.reduce((worst, current) => \n getStatusSeverity(current) > getStatusSeverity(worst) ? current : worst\n );\n}\n\n// ============================================================================\n// COLOR UTILITIES\n// ============================================================================\n\n/**\n * Safely add alpha to any CSS color string.\n * Handles hex (#RRGGBB → #RRGGBBAA), rgb(), and rgba() formats.\n *\n * Avoids the common bug of appending a hex alpha string to an rgba() color,\n * which produces invalid CSS (e.g. \"rgba(15, 20, 35, 0.85)80\").\n *\n * @param color - CSS color string (hex, rgb, or rgba)\n * @param alpha - Alpha value 0–1\n * @returns Valid CSS color string with alpha applied\n *\n * @example\n * addAlpha('#1b2d3e', 0.5) // '#1b2d3e80'\n * addAlpha('rgba(15, 20, 35, 0.85)', 0.5) // 'rgba(15, 20, 35, 0.5)'\n * addAlpha('rgb(15, 20, 35)', 0.031) // 'rgba(15, 20, 35, 0.031)'\n */\nexport function addAlpha(color: string, alpha: number): string {\n if (!color) return color;\n const a = Math.max(0, Math.min(1, alpha));\n if (color.startsWith('rgba(')) {\n return color.replace(/,\\s*[\\d.]+\\)\\s*$/, `, ${a})`);\n }\n if (color.startsWith('rgb(')) {\n return color.replace(/^rgb\\(/, 'rgba(').replace(/\\)\\s*$/, `, ${a})`);\n }\n if (color.startsWith('#')) {\n const hexA = Math.round(a * 255).toString(16).padStart(2, '0');\n return `${color}${hexA}`;\n }\n return color;\n}\n\n// ============================================================================\n// COMPONENT STYLE UTILITIES\n// ============================================================================\n\n/**\n * Merge class names, filtering out falsy values\n * @example classNames('base', isActive && 'active', className) // \"base active custom\"\n */\nexport function classNames(...classes: (string | boolean | undefined | null)[]): string {\n return classes.filter(Boolean).join(' ');\n}\n\n/**\n * Generate CSS for tabular numbers (monospace digits)\n */\nexport const tabularNumsStyle: React.CSSProperties = {\n fontVariantNumeric: 'tabular-nums',\n fontFeatureSettings: '\"tnum\" 1',\n};\n\n/**\n * CSS transition presets\n */\nexport const transitions = {\n fast: 'all 150ms ease-out',\n normal: 'all 250ms ease-out',\n slow: 'all 400ms ease-out',\n spring: 'all 300ms cubic-bezier(0.34, 1.56, 0.64, 1)',\n} as const;\n\n/**\n * Focus ring styles for accessibility\n */\nexport const focusRingStyle: React.CSSProperties = {\n outline: '2px solid #4dc3ff',\n outlineOffset: '2px',\n};\n\n/**\n * Compute a WCAG AA safe version of an accent color for use as foreground text\n * on dark backgrounds. If the accent already passes 4.5:1 contrast on typical\n * dark surfaces (L ≈ 0.01), returns it unchanged. Otherwise lightens toward\n * white until the minimum contrast is met.\n *\n * @example safeAccentText('#8b5cf6') // '#a885f8' — lightened to pass 4.5:1\n */\nexport function safeAccentText(accent: string): string {\n const hex = accent.replace('#', '');\n if (hex.length < 6) return accent;\n\n const r = parseInt(hex.slice(0, 2), 16) / 255;\n const g = parseInt(hex.slice(2, 4), 16) / 255;\n const b = parseInt(hex.slice(4, 6), 16) / 255;\n const toLinear = (c: number) =>\n c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n const L = 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n\n // Threshold: on a dark surface with L≈0.01 we need text L ≥ 0.22 for 4.5:1\n if (L >= 0.22) return accent;\n\n // Lighten by mixing 25% toward white — reaches ~5.5:1 on typical dark bgs\n const mix = 0.25;\n const lr = Math.min(255, Math.round((r + (1 - r) * mix) * 255));\n const lg = Math.min(255, Math.round((g + (1 - g) * mix) * 255));\n const lb = Math.min(255, Math.round((b + (1 - b) * mix) * 255));\n return `#${lr.toString(16).padStart(2, '0')}${lg.toString(16).padStart(2, '0')}${lb.toString(16).padStart(2, '0')}`;\n}\n\n// =============================================================================\n// Category Palette\n// =============================================================================\n\nexport { CategoryPalette } from './categoryPalette';\n"],"names":["mins","secs"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/react/utils/index.ts"],"sourcesContent":["/**\r\n * @zendir/ui - Enterprise Utility Functions\r\n *\r\n * Shared utilities for null-safety, formatting, and defensive coding.\r\n * These utilities ensure components never crash due to undefined data.\r\n */\r\n\r\n// ============================================================================\r\n// NULL SAFETY UTILITIES\r\n// ============================================================================\r\n\r\n/**\r\n * Safely access a value with a fallback for null/undefined\r\n * @example withNullSafety(data?.temperature, 0) // Returns 0 if undefined\r\n */\r\nexport function withNullSafety<T>(value: T | null | undefined, fallback: T): T {\r\n return value ?? fallback;\r\n}\r\n\r\n/**\r\n * Safely format a number, returning '--' if undefined\r\n * @example safeNumber(data?.value, 2) // \"123.45\" or \"--\"\r\n */\r\nexport function safeNumber(\r\n value: number | null | undefined,\r\n decimals: number = 2,\r\n fallback: string = \"--\",\r\n): string {\r\n if (value === null || value === undefined || !Number.isFinite(value)) {\r\n return fallback;\r\n }\r\n return value.toFixed(decimals);\r\n}\r\n\r\n/**\r\n * Check if value is a valid finite number\r\n */\r\nexport function isValidNumber(value: unknown): value is number {\r\n return typeof value === \"number\" && Number.isFinite(value);\r\n}\r\n\r\n// ============================================================================\r\n// NUMBER FORMATTING\r\n// ============================================================================\r\n\r\nexport interface FormatNumberOptions {\r\n decimals?: number;\r\n locale?: string;\r\n notation?: \"standard\" | \"scientific\" | \"engineering\" | \"compact\";\r\n unit?: string;\r\n signDisplay?: \"auto\" | \"never\" | \"always\" | \"exceptZero\";\r\n}\r\n\r\n/**\r\n * Format a number with locale-aware formatting and optional unit\r\n * @example formatNumber(1234567, { notation: 'compact' }) // \"1.2M\"\r\n */\r\nexport function formatNumber(\r\n value: number | null | undefined,\r\n options: FormatNumberOptions = {},\r\n): string {\r\n if (value === null || value === undefined || !Number.isFinite(value)) {\r\n return \"--\";\r\n }\r\n\r\n const {\r\n decimals = 2,\r\n locale = \"en-US\",\r\n notation = \"standard\",\r\n unit,\r\n signDisplay = \"auto\",\r\n } = options;\r\n\r\n try {\r\n const formatted = new Intl.NumberFormat(locale, {\r\n notation,\r\n minimumFractionDigits: notation === \"compact\" ? 0 : decimals,\r\n maximumFractionDigits: decimals,\r\n signDisplay,\r\n }).format(value);\r\n\r\n return unit ? `${formatted} ${unit}` : formatted;\r\n } catch {\r\n return value.toFixed(decimals);\r\n }\r\n}\r\n\r\n/**\r\n * Format a number with tabular (monospace) digits for alignment\r\n * Uses font-feature-settings: 'tnum' 1\r\n */\r\nexport function formatTabular(\r\n value: number | null | undefined,\r\n decimals: number = 2,\r\n): string {\r\n return safeNumber(value, decimals);\r\n}\r\n\r\n// ============================================================================\r\n// UNIT-AWARE FORMATTING\r\n// ============================================================================\r\n\r\n/**\r\n * Format temperature with unit conversion\r\n * @example formatTemperature(25) // \"25.0°C\"\r\n * @example formatTemperature(25, 'fahrenheit') // \"77.0°F\"\r\n */\r\nexport function formatTemperature(\r\n celsius: number | null | undefined,\r\n unit: \"celsius\" | \"fahrenheit\" | \"kelvin\" = \"celsius\",\r\n decimals: number = 1,\r\n): string {\r\n if (celsius === null || celsius === undefined || !Number.isFinite(celsius)) {\r\n return \"--°C\";\r\n }\r\n\r\n switch (unit) {\r\n case \"fahrenheit\":\r\n return `${((celsius * 9) / 5 + 32).toFixed(decimals)}°F`;\r\n case \"kelvin\":\r\n return `${(celsius + 273.15).toFixed(decimals)}K`;\r\n default:\r\n return `${celsius.toFixed(decimals)}°C`;\r\n }\r\n}\r\n\r\n/**\r\n * Format data rate with automatic unit scaling\r\n * @example formatDataRate(1500000) // \"1.50 Mbps\"\r\n */\r\nexport function formatDataRate(\r\n bitsPerSecond: number | null | undefined,\r\n): string {\r\n if (\r\n bitsPerSecond === null ||\r\n bitsPerSecond === undefined ||\r\n !Number.isFinite(bitsPerSecond)\r\n ) {\r\n return \"-- bps\";\r\n }\r\n\r\n const units = [\"bps\", \"Kbps\", \"Mbps\", \"Gbps\", \"Tbps\"];\r\n let unitIndex = 0;\r\n let value = bitsPerSecond;\r\n\r\n while (value >= 1000 && unitIndex < units.length - 1) {\r\n value /= 1000;\r\n unitIndex++;\r\n }\r\n\r\n return `${value.toFixed(2)} ${units[unitIndex]}`;\r\n}\r\n\r\n/**\r\n * Format distance with automatic unit scaling\r\n * @example formatDistance(1500) // \"1.50 km\"\r\n */\r\nexport function formatDistance(meters: number | null | undefined): string {\r\n if (meters === null || meters === undefined || !Number.isFinite(meters)) {\r\n return \"-- m\";\r\n }\r\n\r\n if (meters >= 1_000_000) {\r\n return `${(meters / 1_000_000).toFixed(2)} Mm`;\r\n } else if (meters >= 1_000) {\r\n return `${(meters / 1_000).toFixed(2)} km`;\r\n } else if (meters < 1) {\r\n return `${(meters * 100).toFixed(1)} cm`;\r\n }\r\n return `${meters.toFixed(1)} m`;\r\n}\r\n\r\n/**\r\n * Format altitude (always in km for space ops)\r\n * @example formatAltitude(418.2) // \"418.2 km\"\r\n */\r\nexport function formatAltitude(km: number | null | undefined): string {\r\n if (km === null || km === undefined || !Number.isFinite(km)) {\r\n return \"-- km\";\r\n }\r\n return `${km.toFixed(1)} km`;\r\n}\r\n\r\n/**\r\n * Format velocity\r\n * @example formatVelocity(7.66) // \"7.66 km/s\"\r\n */\r\nexport function formatVelocity(kmPerSec: number | null | undefined): string {\r\n if (\r\n kmPerSec === null ||\r\n kmPerSec === undefined ||\r\n !Number.isFinite(kmPerSec)\r\n ) {\r\n return \"-- km/s\";\r\n }\r\n return `${kmPerSec.toFixed(2)} km/s`;\r\n}\r\n\r\n/**\r\n * Format percentage with bounds checking\r\n * @example formatPercentage(0.856) // \"85.6%\"\r\n * @example formatPercentage(85.6, false) // \"85.6%\" (already percentage)\r\n */\r\nexport function formatPercentage(\r\n value: number | null | undefined,\r\n isDecimal: boolean = false,\r\n decimals: number = 1,\r\n): string {\r\n if (value === null || value === undefined || !Number.isFinite(value)) {\r\n return \"--%\";\r\n }\r\n\r\n const percentage = isDecimal ? value * 100 : value;\r\n return `${percentage.toFixed(decimals)}%`;\r\n}\r\n\r\n/**\r\n * Format power (watts) with auto-scaling\r\n * @example formatPower(1500) // \"1.50 kW\"\r\n */\r\nexport function formatPower(watts: number | null | undefined): string {\r\n if (watts === null || watts === undefined || !Number.isFinite(watts)) {\r\n return \"-- W\";\r\n }\r\n\r\n if (Math.abs(watts) >= 1_000_000) {\r\n return `${(watts / 1_000_000).toFixed(2)} MW`;\r\n } else if (Math.abs(watts) >= 1_000) {\r\n return `${(watts / 1_000).toFixed(2)} kW`;\r\n } else if (Math.abs(watts) < 1) {\r\n return `${(watts * 1000).toFixed(1)} mW`;\r\n }\r\n return `${watts.toFixed(1)} W`;\r\n}\r\n\r\n/**\r\n * Format frequency (Hz) with auto-scaling\r\n * @example formatFrequency(2400000000) // \"2.40 GHz\"\r\n */\r\nexport function formatFrequency(hz: number | null | undefined): string {\r\n if (hz === null || hz === undefined || !Number.isFinite(hz)) {\r\n return \"-- Hz\";\r\n }\r\n\r\n if (hz >= 1_000_000_000) {\r\n return `${(hz / 1_000_000_000).toFixed(2)} GHz`;\r\n } else if (hz >= 1_000_000) {\r\n return `${(hz / 1_000_000).toFixed(2)} MHz`;\r\n } else if (hz >= 1_000) {\r\n return `${(hz / 1_000).toFixed(2)} kHz`;\r\n }\r\n return `${hz.toFixed(0)} Hz`;\r\n}\r\n\r\n// ============================================================================\r\n// TIME FORMATTING\r\n// ============================================================================\r\n\r\n/**\r\n * Format duration in human-readable form\r\n * @example formatDuration(3661) // \"1h 1m 1s\"\r\n */\r\nexport function formatDuration(seconds: number | null | undefined): string {\r\n if (seconds === null || seconds === undefined || !Number.isFinite(seconds)) {\r\n return \"--:--\";\r\n }\r\n\r\n const absSeconds = Math.abs(seconds);\r\n const sign = seconds < 0 ? \"-\" : \"\";\r\n\r\n if (absSeconds < 60) {\r\n return `${sign}${absSeconds.toFixed(0)}s`;\r\n } else if (absSeconds < 3600) {\r\n const mins = Math.floor(absSeconds / 60);\r\n const secs = Math.floor(absSeconds % 60);\r\n return `${sign}${mins}m ${secs}s`;\r\n } else if (absSeconds < 86400) {\r\n const hours = Math.floor(absSeconds / 3600);\r\n const mins = Math.floor((absSeconds % 3600) / 60);\r\n return `${sign}${hours}h ${mins}m`;\r\n } else {\r\n const days = Math.floor(absSeconds / 86400);\r\n const hours = Math.floor((absSeconds % 86400) / 3600);\r\n return `${sign}${days}d ${hours}h`;\r\n }\r\n}\r\n\r\n/**\r\n * Format countdown timer (supports negative values for past events)\r\n * @example formatCountdown(125) // \"T-02:05\"\r\n * @example formatCountdown(-60) // \"T+01:00\"\r\n */\r\nexport function formatCountdown(seconds: number | null | undefined): string {\r\n if (seconds === null || seconds === undefined || !Number.isFinite(seconds)) {\r\n return \"T--:--\";\r\n }\r\n\r\n const prefix = seconds >= 0 ? \"T-\" : \"T+\";\r\n const absSeconds = Math.abs(seconds);\r\n\r\n if (absSeconds >= 3600) {\r\n const hours = Math.floor(absSeconds / 3600);\r\n const mins = Math.floor((absSeconds % 3600) / 60);\r\n const secs = Math.floor(absSeconds % 60);\r\n return `${prefix}${hours}:${mins.toString().padStart(2, \"0\")}:${secs.toString().padStart(2, \"0\")}`;\r\n }\r\n\r\n const mins = Math.floor(absSeconds / 60);\r\n const secs = Math.floor(absSeconds % 60);\r\n return `${prefix}${mins.toString().padStart(2, \"0\")}:${secs.toString().padStart(2, \"0\")}`;\r\n}\r\n\r\n/**\r\n * Format UTC timestamp\r\n * @example formatUTC(new Date()) // \"2026-01-27 14:30:00Z\"\r\n */\r\nexport function formatUTC(date: Date | string | null | undefined): string {\r\n if (!date) return \"--:--:-- UTC\";\r\n\r\n try {\r\n const d = typeof date === \"string\" ? new Date(date) : date;\r\n if (isNaN(d.getTime())) return \"--:--:-- UTC\";\r\n\r\n return d.toISOString().replace(\"T\", \" \").slice(0, 19) + \"Z\";\r\n } catch {\r\n return \"--:--:-- UTC\";\r\n }\r\n}\r\n\r\n/**\r\n * Format time only (HH:MM:SS)\r\n * @example formatTime(new Date()) // \"14:30:00\"\r\n */\r\nexport function formatTime(\r\n date: Date | string | null | undefined,\r\n includeSeconds = true,\r\n): string {\r\n if (!date) return includeSeconds ? \"--:--:--\" : \"--:--\";\r\n\r\n try {\r\n const d = typeof date === \"string\" ? new Date(date) : date;\r\n if (isNaN(d.getTime())) return includeSeconds ? \"--:--:--\" : \"--:--\";\r\n\r\n const hours = d.getUTCHours().toString().padStart(2, \"0\");\r\n const mins = d.getUTCMinutes().toString().padStart(2, \"0\");\r\n const secs = d.getUTCSeconds().toString().padStart(2, \"0\");\r\n\r\n return includeSeconds ? `${hours}:${mins}:${secs}` : `${hours}:${mins}`;\r\n } catch {\r\n return includeSeconds ? \"--:--:--\" : \"--:--\";\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// COORDINATE FORMATTING\r\n// ============================================================================\r\n\r\n/**\r\n * Format latitude/longitude\r\n * @example formatCoordinate(32.4, 'lat') // \"32.40° N\"\r\n * @example formatCoordinate(-117.2, 'lon') // \"117.20° W\"\r\n */\r\nexport function formatCoordinate(\r\n value: number | null | undefined,\r\n type: \"lat\" | \"lon\",\r\n): string {\r\n if (value === null || value === undefined || !Number.isFinite(value)) {\r\n return \"--°\";\r\n }\r\n\r\n const absValue = Math.abs(value);\r\n let direction: string;\r\n\r\n if (type === \"lat\") {\r\n direction = value >= 0 ? \"N\" : \"S\";\r\n } else {\r\n direction = value >= 0 ? \"E\" : \"W\";\r\n }\r\n\r\n return `${absValue.toFixed(2)}° ${direction}`;\r\n}\r\n\r\n/**\r\n * Format lat/lon pair\r\n * @example formatLatLon(32.4, -117.2) // \"32.40° N, 117.20° W\"\r\n */\r\nexport function formatLatLon(\r\n lat: number | null | undefined,\r\n lon: number | null | undefined,\r\n): string {\r\n return `${formatCoordinate(lat, \"lat\")}, ${formatCoordinate(lon, \"lon\")}`;\r\n}\r\n\r\n// ============================================================================\r\n// ANGLE FORMATTING\r\n// ============================================================================\r\n\r\n/**\r\n * Format angle in degrees\r\n * @example formatDegrees(45.5) // \"45.5°\"\r\n */\r\nexport function formatDegrees(\r\n value: number | null | undefined,\r\n decimals: number = 1,\r\n): string {\r\n if (value === null || value === undefined || !Number.isFinite(value)) {\r\n return \"--°\";\r\n }\r\n return `${value.toFixed(decimals)}°`;\r\n}\r\n\r\n/**\r\n * Format decibels\r\n * @example formatDecibels(3.5) // \"3.5 dB\"\r\n */\r\nexport function formatDecibels(\r\n value: number | null | undefined,\r\n decimals: number = 1,\r\n): string {\r\n if (value === null || value === undefined || !Number.isFinite(value)) {\r\n return \"-- dB\";\r\n }\r\n return `${value.toFixed(decimals)} dB`;\r\n}\r\n\r\n// ============================================================================\r\n// VALUE UTILITIES\r\n// ============================================================================\r\n\r\n/**\r\n * Clamp a value between min and max\r\n * @example clamp(150, 0, 100) // 100\r\n */\r\nexport function clamp(value: number, min: number, max: number): number {\r\n return Math.min(Math.max(value, min), max);\r\n}\r\n\r\n/**\r\n * Linear interpolation\r\n * @example lerp(0, 100, 0.5) // 50\r\n */\r\nexport function lerp(start: number, end: number, t: number): number {\r\n return start + (end - start) * clamp(t, 0, 1);\r\n}\r\n\r\n/**\r\n * Map a value from one range to another\r\n * @example mapRange(50, 0, 100, 0, 1) // 0.5\r\n */\r\nexport function mapRange(\r\n value: number,\r\n inMin: number,\r\n inMax: number,\r\n outMin: number,\r\n outMax: number,\r\n): number {\r\n const t = (value - inMin) / (inMax - inMin);\r\n return lerp(outMin, outMax, t);\r\n}\r\n\r\n// ============================================================================\r\n// STATUS UTILITIES\r\n// ============================================================================\r\n\r\nexport type StatusLevel =\r\n | \"off\"\r\n | \"standby\"\r\n | \"normal\"\r\n | \"caution\"\r\n | \"serious\"\r\n | \"critical\";\r\n\r\n/**\r\n * Astro UX Design System status colors\r\n * These match the official Astro status semantics\r\n */\r\nexport const STATUS_COLORS: Record<StatusLevel, string> = {\r\n off: \"#a4abb6\",\r\n standby: \"#2dccff\",\r\n normal: \"#56f000\",\r\n caution: \"#fce83a\",\r\n serious: \"#ffb302\",\r\n critical: \"#ff3838\",\r\n};\r\n\r\n/**\r\n * Get status color from level\r\n * @example getStatusColor('normal') // '#56f000'\r\n */\r\nexport function getStatusColor(status: StatusLevel | null | undefined): string {\r\n return STATUS_COLORS[status ?? \"off\"];\r\n}\r\n\r\n/**\r\n * Derive status for battery specifically (low is bad)\r\n * @example deriveBatteryStatus(25) // 'caution'\r\n */\r\nexport function deriveBatteryStatus(\r\n level: number | undefined | null,\r\n): StatusLevel {\r\n if (level === undefined || level === null) return \"off\";\r\n if (level <= 10) return \"critical\";\r\n if (level <= 20) return \"serious\";\r\n if (level <= 30) return \"caution\";\r\n return \"normal\";\r\n}\r\n\r\n/**\r\n * Determine status level from a value and thresholds\r\n * @example getStatusFromValue(85, { critical: 20, serious: 40, caution: 60, normal: 80 }) // 'normal'\r\n */\r\nexport function getStatusFromValue(\r\n value: number | null | undefined,\r\n thresholds: {\r\n critical?: number;\r\n serious?: number;\r\n caution?: number;\r\n normal?: number;\r\n },\r\n higherIsBetter: boolean = true,\r\n): StatusLevel {\r\n if (value === null || value === undefined || !Number.isFinite(value)) {\r\n return \"off\";\r\n }\r\n\r\n const { critical = 10, serious = 25, caution = 50, normal = 75 } = thresholds;\r\n\r\n if (higherIsBetter) {\r\n if (value <= critical) return \"critical\";\r\n if (value <= serious) return \"serious\";\r\n if (value <= caution) return \"caution\";\r\n if (value <= normal) return \"standby\";\r\n return \"normal\";\r\n } else {\r\n if (value >= critical) return \"critical\";\r\n if (value >= serious) return \"serious\";\r\n if (value >= caution) return \"caution\";\r\n if (value >= normal) return \"standby\";\r\n return \"normal\";\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// STATUS NORMALIZATION\r\n// ============================================================================\r\n\r\n/**\r\n * Domain status terms that map to UI StatusLevel\r\n * This handles common backend/sensor terminology\r\n */\r\nconst STATUS_MAPPING: Record<string, StatusLevel> = {\r\n // → 'off'\r\n off: \"off\",\r\n disabled: \"off\",\r\n inactive: \"off\",\r\n offline: \"off\",\r\n unknown: \"off\",\r\n null: \"off\",\r\n none: \"off\",\r\n\r\n // → 'standby'\r\n standby: \"standby\",\r\n idle: \"standby\",\r\n waiting: \"standby\",\r\n ready: \"standby\",\r\n pending: \"standby\",\r\n queued: \"standby\",\r\n\r\n // → 'normal'\r\n normal: \"normal\",\r\n nominal: \"normal\",\r\n healthy: \"normal\",\r\n ok: \"normal\",\r\n good: \"normal\",\r\n success: \"normal\",\r\n operational: \"normal\",\r\n active: \"normal\",\r\n online: \"normal\",\r\n connected: \"normal\",\r\n stable: \"normal\",\r\n transmitting: \"normal\",\r\n receiving: \"normal\",\r\n\r\n // → 'caution'\r\n caution: \"caution\",\r\n warning: \"caution\",\r\n degraded: \"caution\",\r\n elevated: \"caution\",\r\n alert: \"caution\",\r\n attention: \"caution\",\r\n limited: \"caution\",\r\n\r\n // → 'serious'\r\n serious: \"serious\",\r\n unstable: \"serious\",\r\n danger: \"serious\",\r\n severe: \"serious\",\r\n\r\n // → 'critical'\r\n critical: \"critical\",\r\n error: \"critical\",\r\n failed: \"critical\",\r\n failure: \"critical\",\r\n emergency: \"critical\",\r\n fault: \"critical\",\r\n alarm: \"critical\",\r\n};\r\n\r\n/**\r\n * Normalize any status string to the 6-level StatusLevel system\r\n *\r\n * @param status - Any status string from domain/backend\r\n * @param defaultStatus - Fallback if status is not recognized (default: 'off')\r\n * @returns StatusLevel\r\n *\r\n * @example\r\n * ```typescript\r\n * normalizeStatus('degraded') // 'caution'\r\n * normalizeStatus('nominal') // 'normal'\r\n * normalizeStatus('transmitting') // 'normal'\r\n * normalizeStatus('warning') // 'caution'\r\n * normalizeStatus('error') // 'critical'\r\n * normalizeStatus(undefined) // 'off'\r\n * ```\r\n */\r\nexport function normalizeStatus(\r\n status: string | undefined | null,\r\n defaultStatus: StatusLevel = \"off\",\r\n): StatusLevel {\r\n if (!status) return defaultStatus;\r\n\r\n const normalized = status.toLowerCase().trim();\r\n return STATUS_MAPPING[normalized] ?? defaultStatus;\r\n}\r\n\r\n/**\r\n * Check if a string is a valid StatusLevel\r\n */\r\nexport function isStatusLevel(value: string): value is StatusLevel {\r\n return [\r\n \"off\",\r\n \"standby\",\r\n \"normal\",\r\n \"caution\",\r\n \"serious\",\r\n \"critical\",\r\n ].includes(value);\r\n}\r\n\r\n/**\r\n * Get the severity order of a status (higher = more severe)\r\n * Useful for sorting or finding worst status\r\n */\r\nexport function getStatusSeverity(status: StatusLevel): number {\r\n const order: Record<StatusLevel, number> = {\r\n off: 0,\r\n standby: 1,\r\n normal: 2,\r\n caution: 3,\r\n serious: 4,\r\n critical: 5,\r\n };\r\n return order[status];\r\n}\r\n\r\n/**\r\n * Get the worst (most severe) status from an array\r\n *\r\n * @example\r\n * ```typescript\r\n * getWorstStatus(['normal', 'caution', 'normal']) // 'caution'\r\n * getWorstStatus(['normal', 'critical', 'caution']) // 'critical'\r\n * ```\r\n */\r\nexport function getWorstStatus(statuses: StatusLevel[]): StatusLevel {\r\n if (statuses.length === 0) return \"off\";\r\n return statuses.reduce((worst, current) =>\r\n getStatusSeverity(current) > getStatusSeverity(worst) ? current : worst,\r\n );\r\n}\r\n\r\n// ============================================================================\r\n// COLOR UTILITIES\r\n// ============================================================================\r\n\r\n/**\r\n * Safely add alpha to any CSS color string.\r\n * Handles hex (#RRGGBB → #RRGGBBAA), rgb(), and rgba() formats.\r\n *\r\n * Avoids the common bug of appending a hex alpha string to an rgba() color,\r\n * which produces invalid CSS (e.g. \"rgba(15, 20, 35, 0.85)80\").\r\n *\r\n * @param color - CSS color string (hex, rgb, or rgba)\r\n * @param alpha - Alpha value 0–1\r\n * @returns Valid CSS color string with alpha applied\r\n *\r\n * @example\r\n * addAlpha('#1b2d3e', 0.5) // '#1b2d3e80'\r\n * addAlpha('rgba(15, 20, 35, 0.85)', 0.5) // 'rgba(15, 20, 35, 0.5)'\r\n * addAlpha('rgb(15, 20, 35)', 0.031) // 'rgba(15, 20, 35, 0.031)'\r\n */\r\nexport function addAlpha(color: string, alpha: number): string {\r\n if (!color) return color;\r\n const a = Math.max(0, Math.min(1, alpha));\r\n if (color.startsWith(\"rgba(\")) {\r\n return color.replace(/,\\s*[\\d.]+\\)\\s*$/, `, ${a})`);\r\n }\r\n if (color.startsWith(\"rgb(\")) {\r\n return color.replace(/^rgb\\(/, \"rgba(\").replace(/\\)\\s*$/, `, ${a})`);\r\n }\r\n if (color.startsWith(\"#\")) {\r\n const hexA = Math.round(a * 255)\r\n .toString(16)\r\n .padStart(2, \"0\");\r\n return `${color}${hexA}`;\r\n }\r\n return color;\r\n}\r\n\r\n// ============================================================================\r\n// COMPONENT STYLE UTILITIES\r\n// ============================================================================\r\n\r\n/**\r\n * Merge class names, filtering out falsy values\r\n * @example classNames('base', isActive && 'active', className) // \"base active custom\"\r\n */\r\nexport function classNames(\r\n ...classes: (string | boolean | undefined | null)[]\r\n): string {\r\n return classes.filter(Boolean).join(\" \");\r\n}\r\n\r\n/**\r\n * Generate CSS for tabular numbers (monospace digits)\r\n */\r\nexport const tabularNumsStyle: React.CSSProperties = {\r\n fontVariantNumeric: \"tabular-nums\",\r\n fontFeatureSettings: '\"tnum\" 1',\r\n};\r\n\r\n/**\r\n * CSS transition presets\r\n */\r\nexport const transitions = {\r\n fast: \"all 150ms ease-out\",\r\n normal: \"all 250ms ease-out\",\r\n slow: \"all 400ms ease-out\",\r\n spring: \"all 300ms cubic-bezier(0.34, 1.56, 0.64, 1)\",\r\n} as const;\r\n\r\n/**\r\n * Focus ring styles for accessibility\r\n */\r\nexport const focusRingStyle: React.CSSProperties = {\r\n outline: \"2px solid #4dc3ff\",\r\n outlineOffset: \"2px\",\r\n};\r\n\r\n/**\r\n * Compute a WCAG AA safe version of an accent color for use as foreground text\r\n * on dark backgrounds. If the accent already passes 4.5:1 contrast on typical\r\n * dark surfaces (L ≈ 0.01), returns it unchanged. Otherwise lightens toward\r\n * white until the minimum contrast is met.\r\n *\r\n * @example safeAccentText('#8b5cf6') // '#a885f8' — lightened to pass 4.5:1\r\n */\r\nexport function safeAccentText(accent: string): string {\r\n const hex = accent.replace(\"#\", \"\");\r\n if (hex.length < 6) return accent;\r\n\r\n const r = parseInt(hex.slice(0, 2), 16) / 255;\r\n const g = parseInt(hex.slice(2, 4), 16) / 255;\r\n const b = parseInt(hex.slice(4, 6), 16) / 255;\r\n const toLinear = (c: number) =>\r\n c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\r\n const L = 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\r\n\r\n // Threshold: on a dark surface with L≈0.01 we need text L ≥ 0.22 for 4.5:1\r\n if (L >= 0.22) return accent;\r\n\r\n // Lighten by mixing 25% toward white — reaches ~5.5:1 on typical dark bgs\r\n const mix = 0.25;\r\n const lr = Math.min(255, Math.round((r + (1 - r) * mix) * 255));\r\n const lg = Math.min(255, Math.round((g + (1 - g) * mix) * 255));\r\n const lb = Math.min(255, Math.round((b + (1 - b) * mix) * 255));\r\n return `#${lr.toString(16).padStart(2, \"0\")}${lg.toString(16).padStart(2, \"0\")}${lb.toString(16).padStart(2, \"0\")}`;\r\n}\r\n\r\n// =============================================================================\r\n// Category Palette\r\n// =============================================================================\r\n\r\nexport { CategoryPalette } from \"./categoryPalette\";\r\n"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { default as React } from 'react';
2
2
  import { EclipseInfo } from '../types';
3
-
4
3
  export interface EclipseTimerCardProps {
5
4
  /** Eclipse information from API */
6
5
  eclipse: EclipseInfo;
@@ -1,5 +1,4 @@
1
1
  import { default as React } from 'react';
2
-
3
2
  export interface LinkBudgetData {
4
3
  /** Transmitter power in dBm */
5
4
  txPowerDbm: number;
@@ -1,6 +1,5 @@
1
1
  import { default as React } from 'react';
2
2
  import { AttitudeData, PointingMode } from '../types';
3
-
4
3
  export interface NavBallCardProps {
5
4
  /** Attitude data from API */
6
5
  attitude: AttitudeData;
@@ -1,5 +1,4 @@
1
1
  import { default as React } from 'react';
2
-
3
2
  export interface PropulsionTankData {
4
3
  id: string;
5
4
  name: string;
@@ -8,7 +7,7 @@ export interface PropulsionTankData {
8
7
  /** Maximum capacity in kg */
9
8
  maxMassKg: number;
10
9
  /** Propellant type */
11
- type: 'hydrazine' | 'xenon' | 'cold_gas' | 'bipropellant' | string;
10
+ type: "hydrazine" | "xenon" | "cold_gas" | "bipropellant" | string;
12
11
  }
13
12
  export interface ManeuverFeasibility {
14
13
  name: string;
@@ -1,5 +1,4 @@
1
1
  import { default as React } from 'react';
2
-
3
2
  export interface FootprintSensorConfig {
4
3
  id: string;
5
4
  name: string;
@@ -8,7 +7,7 @@ export interface FootprintSensorConfig {
8
7
  /** Along-track field of view in degrees */
9
8
  alongTrackFovDegrees?: number;
10
9
  /** Sensor type */
11
- type: 'camera' | 'radar' | 'lidar' | 'spectrometer' | string;
10
+ type: "camera" | "radar" | "lidar" | "spectrometer" | string;
12
11
  /** Whether sensor is active */
13
12
  isActive: boolean;
14
13
  }
@@ -1,5 +1,4 @@
1
1
  import { default as React } from 'react';
2
-
3
2
  export interface ComponentThermal {
4
3
  id: string;
5
4
  name: string;
@@ -10,8 +10,8 @@ export type { NavBallCardProps } from './NavBallCard';
10
10
  export { LinkBudgetCard } from './LinkBudgetCard';
11
11
  export type { LinkBudgetCardProps, LinkBudgetData } from './LinkBudgetCard';
12
12
  export { ThermalHeatmapCard } from './ThermalHeatmapCard';
13
- export type { ThermalHeatmapCardProps, ComponentThermal } from './ThermalHeatmapCard';
13
+ export type { ThermalHeatmapCardProps, ComponentThermal, } from './ThermalHeatmapCard';
14
14
  export { PropulsionCard } from './PropulsionCard';
15
- export type { PropulsionCardProps, PropulsionTankData, ManeuverFeasibility } from './PropulsionCard';
15
+ export type { PropulsionCardProps, PropulsionTankData, ManeuverFeasibility, } from './PropulsionCard';
16
16
  export { SensorFootprintCard } from './SensorFootprintCard';
17
- export type { SensorFootprintCardProps, FootprintSensorConfig } from './SensorFootprintCard';
17
+ export type { SensorFootprintCardProps, FootprintSensorConfig, } from './SensorFootprintCard';
package/dist/react.d.ts CHANGED
@@ -1 +1,2 @@
1
- export * from './react/index'
1
+ export * from './react/index.js'
2
+ export {}
package/dist/react.js CHANGED
@@ -1,5 +1,10 @@
1
+ import { ThemeProvider, useScrollbarStyles, useTheme, useThemeTokens } from "./react/theme/ThemeProvider.js";
2
+ import { CARD_ACCENT_COLORS, CardAccentProvider, SPACE_SYSTEM_COLORS, getAccentColorOptions, getSystemAccentColor, useCardAccent } from "./react/theme/cardAccent.js";
1
3
  import { Icon, getIconNames, isValidIconName } from "./react/core/display/Icon.js";
4
+ import { CategoryPalette } from "./react/utils/categoryPalette.js";
5
+ import { STATUS_COLORS, addAlpha, clamp, classNames, focusRingStyle, formatAltitude, formatCoordinate, formatCountdown, formatDataRate, formatDecibels, formatDegrees, formatDistance, formatDuration, formatFrequency, formatLatLon, formatNumber, formatPercentage, formatPower, formatTabular, formatTemperature, formatTime, formatUTC, formatVelocity, getStatusColor, getStatusFromValue, getStatusSeverity, getWorstStatus, isStatusLevel, isValidNumber, lerp, mapRange, normalizeStatus, safeAccentText, safeNumber, tabularNumsStyle, transitions, withNullSafety } from "./react/utils/index.js";
2
6
  import { Button } from "./react/core/inputs/Button.js";
7
+ import { BREAKPOINTS, useBreakpoint } from "./react/core/layout/useBreakpoint.js";
3
8
  import { Input } from "./react/core/inputs/Input.js";
4
9
  import { Select } from "./react/core/inputs/Select.js";
5
10
  import { Toggle } from "./react/core/inputs/Toggle.js";
@@ -8,21 +13,26 @@ import { Tooltip } from "./react/core/overlays/Tooltip.js";
8
13
  import { Dialog } from "./react/core/feedback/Dialog.js";
9
14
  import { Badge } from "./react/core/display/Badge.js";
10
15
  import { Tabs } from "./react/core/navigation/Tabs.js";
16
+ import { HeaderIconWithStatus } from "./react/core/display/HeaderIconWithStatus.js";
17
+ import { CardHeader } from "./react/core/display/CardHeader.js";
11
18
  import { Container } from "./react/core/display/Container.js";
12
19
  import { GLASS_COLOR_OVERLAYS, GlassCard } from "./react/core/display/GlassCard.js";
13
20
  import { Pagination } from "./react/core/navigation/Pagination.js";
14
- import { DataValue, DataValueGroup } from "./react/core/data/DataValue.js";
15
- import { HeaderIconWithStatus } from "./react/core/display/HeaderIconWithStatus.js";
16
- import { CardHeader } from "./react/core/display/CardHeader.js";
17
21
  import { CATEGORY_ICONS, CATEGORY_LABELS, PROPERTY_PRESETS, createPropertyConfig, deriveBatteryStatus, deriveStatus, formatPropertyLabel, formatPropertyValue, getPropertiesByCategory, getPropertyConfig } from "./react/core/data/propertyConfig.js";
22
+ import { DataValue, DataValueGroup } from "./react/core/data/DataValue.js";
23
+ import useSimulationScene from "./react/hooks/useSimulationScene.js";
24
+ import { DisplaySettingsProvider, GLASS_TINTS, PRESET_COLORS, getEffectiveCompactMode, useDisplaySettings, useDisplaySettingsOptional } from "./react/context/DisplaySettingsContext.js";
25
+ import { useCompactMode } from "./react/hooks/useCompactMode.js";
18
26
  import { MessageStream } from "./react/core/widgets/MessageStream.js";
19
- import { AppBar } from "./react/core/navigation/AppBar.js";
20
27
  import { ColorPickerPanel } from "./react/core/widgets/ColorPickerPanel.js";
28
+ import { AppBar } from "./react/core/navigation/AppBar.js";
21
29
  import { Body1, Body2, Body3, Compact, DataText, Display1, Display2, FONT_FAMILY_MONO, FONT_FAMILY_PRIMARY, FONT_WEIGHTS, H1, H2, H3, H4, H5, H6, Label, Micro, Mono, Typography } from "./react/core/display/Typography.js";
30
+ import { StatusIndicator } from "./react/astro/StatusIndicator.js";
22
31
  import { NumberInput } from "./react/core/inputs/NumberInput.js";
23
32
  import { SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX, SideNav } from "./react/core/navigation/SideNav.js";
24
33
  import { ToastProvider, useToast, useToastManager } from "./react/core/feedback/Toast.js";
25
34
  import { Menu, Popover } from "./react/core/overlays/Popover.js";
35
+ import { resolveResponsive, resolveSpacing } from "./react/core/layout/responsive.js";
26
36
  import { Box } from "./react/core/layout/Box.js";
27
37
  import { Flex } from "./react/core/layout/Flex.js";
28
38
  import { Grid } from "./react/core/layout/Grid.js";
@@ -30,8 +40,6 @@ import { HStack, Stack, VStack } from "./react/core/layout/Stack.js";
30
40
  import { Center } from "./react/core/layout/Center.js";
31
41
  import { Spacer } from "./react/core/layout/Spacer.js";
32
42
  import { Divider } from "./react/core/layout/Divider.js";
33
- import { BREAKPOINTS, useBreakpoint } from "./react/core/layout/useBreakpoint.js";
34
- import { resolveResponsive, resolveSpacing } from "./react/core/layout/responsive.js";
35
43
  import { ConfirmDialog, ConfirmProvider, useConfirm } from "./react/core/feedback/ConfirmDialog.js";
36
44
  import { PinInput } from "./react/core/inputs/PinInput.js";
37
45
  import { CopyButton, useCopyToClipboard } from "./react/core/display/CopyButton.js";
@@ -53,13 +61,9 @@ import { ActivityPlanner } from "./react/core/widgets/ActivityPlanner.js";
53
61
  import { Capture, loadCapturePlaceholderImage, useCapture } from "./react/core/widgets/Capture.js";
54
62
  import { ZenSpace3D } from "./react/3d/ZenSpace3D.js";
55
63
  import { ecefEulerXyzToHpr, ecefMetersToSdkPosition } from "./react/3d/CesiumCaptureSource.js";
56
- import { useSimulationScene } from "./react/hooks/useSimulationScene.js";
57
- import { ThemeProvider, useScrollbarStyles, useTheme, useThemeTokens } from "./react/theme/ThemeProvider.js";
58
- import { CARD_ACCENT_COLORS, CardAccentProvider, SPACE_SYSTEM_COLORS, getAccentColorOptions, getSystemAccentColor, useCardAccent } from "./react/theme/cardAccent.js";
64
+ import { CategoryProvider, useCategoryPalette, useCategoryPaletteRequired } from "./react/context/CategoryContext.js";
59
65
  import { ErrorBoundary, withErrorBoundary } from "./react/shared/ErrorBoundary.js";
60
66
  import { Skeleton3D, SkeletonBox, SkeletonCard, SkeletonChart, SkeletonCircle, SkeletonText } from "./react/shared/Skeleton.js";
61
- import { STATUS_COLORS, addAlpha, clamp, classNames, focusRingStyle, formatAltitude, formatCoordinate, formatCountdown, formatDataRate, formatDecibels, formatDegrees, formatDistance, formatDuration, formatFrequency, formatLatLon, formatNumber, formatPercentage, formatPower, formatTabular, formatTemperature, formatTime, formatUTC, formatVelocity, getStatusColor, getStatusFromValue, getStatusSeverity, getWorstStatus, isStatusLevel, isValidNumber, lerp, mapRange, normalizeStatus, safeAccentText, safeNumber, tabularNumsStyle, transitions, withNullSafety } from "./react/utils/index.js";
62
- import { StatusIndicator } from "./react/astro/StatusIndicator.js";
63
67
  import { ClassificationBanner } from "./react/astro/ClassificationBanner.js";
64
68
  import { GlobalStatusBar } from "./react/astro/GlobalStatusBar.js";
65
69
  import { MissionClock } from "./react/astro/MissionClock.js";
@@ -68,217 +72,9 @@ import { MonitoringIcon } from "./react/astro/MonitoringIcon.js";
68
72
  import { Progress } from "./react/astro/Progress.js";
69
73
  import { Notification } from "./react/astro/Notification.js";
70
74
  import { UnifiedTimeline } from "./react/astro/UnifiedTimeline.js";
75
+ import { AstroChart } from "./react/charts/unified/AstroChart.js";
71
76
  import { GroundTrackMap } from "./react/charts/GroundTrackMap.js";
72
- import { useCompactMode } from "./react/hooks/useCompactMode.js";
73
77
  import { ObjectInventoryPanel, recommendedFlyDistance } from "./react/panels/ObjectInventoryPanel.js";
74
78
  import { LayerControlPanel } from "./react/panels/LayerControlPanel.js";
75
79
  import { PLANETS, auToKm, estimateOrbitalPeriod, estimateOrbitalVelocity, getPlanet, normalizePlanetName } from "./react/types.js";
76
- import { AstroChart } from "./react/charts/unified/AstroChart.js";
77
- import { CategoryPalette } from "./react/utils/categoryPalette.js";
78
- import { CategoryProvider, useCategoryPalette, useCategoryPaletteRequired } from "./react/context/CategoryContext.js";
79
- import { DisplaySettingsProvider, GLASS_TINTS, PRESET_COLORS, getEffectiveCompactMode, useDisplaySettings, useDisplaySettingsOptional } from "./react/context/DisplaySettingsContext.js";
80
- export {
81
- ActivityPlanner,
82
- AppBar,
83
- AstroChart,
84
- BREAKPOINTS,
85
- Badge,
86
- Body1,
87
- Body2,
88
- Body3,
89
- Box,
90
- Button,
91
- CARD_ACCENT_COLORS,
92
- CATEGORY_ICONS,
93
- CATEGORY_LABELS,
94
- CHAT_RESPONSE_JSON_PROMPT,
95
- CHAT_RESPONSE_MCP_TOOL,
96
- CHAT_RESPONSE_TOOL_SCHEMA,
97
- CHAT_RESPONSE_YAML_PROMPT,
98
- CHAT_STATUS_RULES_PROMPT,
99
- Capture,
100
- CardAccentProvider,
101
- CardHeader,
102
- CategoryPalette,
103
- CategoryProvider,
104
- Center,
105
- ChatPanel,
106
- Checkbox,
107
- ClassificationBanner,
108
- ColorPickerPanel,
109
- CommandBuilder,
110
- Compact,
111
- ConfirmDialog,
112
- ConfirmProvider,
113
- ConnectionForm,
114
- Container,
115
- CopyButton,
116
- DataTable,
117
- DataTableRowDetail,
118
- DataText,
119
- DataValue,
120
- DataValueGroup,
121
- Dialog,
122
- Display1,
123
- Display2,
124
- DisplaySettingsProvider,
125
- Divider,
126
- ErrorBoundary,
127
- FONT_FAMILY_MONO,
128
- FONT_FAMILY_PRIMARY,
129
- FONT_WEIGHTS,
130
- FileExplorer,
131
- Flex,
132
- GLASS_COLOR_OVERLAYS,
133
- GLASS_TINTS,
134
- GlassCard,
135
- GlobalStatusBar,
136
- Grid,
137
- GroundTrackMap,
138
- H1,
139
- H2,
140
- H3,
141
- H4,
142
- H5,
143
- H6,
144
- HStack,
145
- HeaderIconWithStatus,
146
- HexViewer,
147
- Icon,
148
- ImageFrame,
149
- ImageGallery,
150
- ImagePanel,
151
- Input,
152
- Label,
153
- LayerControlPanel,
154
- LimitsBar,
155
- LogViewer,
156
- Menu,
157
- MessageStream,
158
- Micro,
159
- MiniSimulationControls,
160
- MissionCalendar,
161
- MissionClock,
162
- MonitoringIcon,
163
- Mono,
164
- Notification,
165
- NumberInput,
166
- ObjectInventoryPanel,
167
- PLANETS,
168
- PRESET_COLORS,
169
- PROPERTY_PRESETS,
170
- PacketViewer,
171
- Pagination,
172
- PinInput,
173
- Popover,
174
- Progress,
175
- REGION_BORDER_COLORS,
176
- REGION_COLORS,
177
- SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX,
178
- SPACE_SYSTEM_COLORS,
179
- STATUS_COLORS,
180
- Select,
181
- SideNav,
182
- SidePanel,
183
- SimulationControls,
184
- SimulationControlsWithClock,
185
- Skeleton3D,
186
- SkeletonBox,
187
- SkeletonCard,
188
- SkeletonChart,
189
- SkeletonCircle,
190
- SkeletonText,
191
- Spacer,
192
- Stack,
193
- StatusIndicator,
194
- Tabs,
195
- ThemeProvider,
196
- UnifiedTimeline as Timeline,
197
- ToastProvider,
198
- Toggle,
199
- Tooltip,
200
- Typography,
201
- VStack,
202
- ZenSpace3D,
203
- addAlpha,
204
- auToKm,
205
- clamp,
206
- classNames,
207
- createChatResponseParser,
208
- createPropertyConfig,
209
- decodeImage,
210
- deriveBatteryStatus,
211
- deriveStatus,
212
- ecefEulerXyzToHpr,
213
- ecefMetersToSdkPosition,
214
- estimateOrbitalPeriod,
215
- estimateOrbitalVelocity,
216
- focusRingStyle,
217
- formatAltitude,
218
- formatCoordinate,
219
- formatCountdown,
220
- formatDataRate,
221
- formatDecibels,
222
- formatDegrees,
223
- formatDistance,
224
- formatDuration,
225
- formatFrequency,
226
- formatLatLon,
227
- formatNumber,
228
- formatPercentage,
229
- formatPower,
230
- formatPropertyLabel,
231
- formatPropertyValue,
232
- formatTabular,
233
- formatTemperature,
234
- formatTime,
235
- formatUTC,
236
- formatVelocity,
237
- getAccentColorOptions,
238
- getEffectiveCompactMode,
239
- getIconNames,
240
- getPlanet,
241
- getPropertiesByCategory,
242
- getPropertyConfig,
243
- getStatusColor,
244
- getStatusFromValue,
245
- getStatusSeverity,
246
- getSystemAccentColor,
247
- getWorstStatus,
248
- isStatusLevel,
249
- isValidIconName,
250
- isValidNumber,
251
- lerp,
252
- loadCapturePlaceholderImage,
253
- mapRange,
254
- normalizePlanetName,
255
- normalizeStatus,
256
- parseChatResponse,
257
- parseMcpToolResult,
258
- recommendedFlyDistance,
259
- resolveResponsive,
260
- resolveSpacing,
261
- safeAccentText,
262
- safeNumber,
263
- tabularNumsStyle,
264
- transitions,
265
- useBreakpoint,
266
- useCapture,
267
- useCardAccent,
268
- useCategoryPalette,
269
- useCategoryPaletteRequired,
270
- useCompactMode,
271
- useConfirm,
272
- useCopyToClipboard,
273
- useDisplaySettings,
274
- useDisplaySettingsOptional,
275
- useScrollbarStyles,
276
- useSimulationScene,
277
- useTheme,
278
- useThemeTokens,
279
- useToast,
280
- useToastManager,
281
- withErrorBoundary,
282
- withNullSafety
283
- };
284
- //# sourceMappingURL=react.js.map
80
+ export { ActivityPlanner, AppBar, AstroChart, BREAKPOINTS, Badge, Body1, Body2, Body3, Box, Button, CARD_ACCENT_COLORS, CATEGORY_ICONS, CATEGORY_LABELS, CHAT_RESPONSE_JSON_PROMPT, CHAT_RESPONSE_MCP_TOOL, CHAT_RESPONSE_TOOL_SCHEMA, CHAT_RESPONSE_YAML_PROMPT, CHAT_STATUS_RULES_PROMPT, Capture, CardAccentProvider, CardHeader, CategoryPalette, CategoryProvider, Center, ChatPanel, Checkbox, ClassificationBanner, ColorPickerPanel, CommandBuilder, Compact, ConfirmDialog, ConfirmProvider, ConnectionForm, Container, CopyButton, DataTable, DataTableRowDetail, DataText, DataValue, DataValueGroup, Dialog, Display1, Display2, DisplaySettingsProvider, Divider, ErrorBoundary, FONT_FAMILY_MONO, FONT_FAMILY_PRIMARY, FONT_WEIGHTS, FileExplorer, Flex, GLASS_COLOR_OVERLAYS, GLASS_TINTS, GlassCard, GlobalStatusBar, Grid, GroundTrackMap, H1, H2, H3, H4, H5, H6, HStack, HeaderIconWithStatus, HexViewer, Icon, ImageFrame, ImageGallery, ImagePanel, Input, Label, LayerControlPanel, LimitsBar, LogViewer, Menu, MessageStream, Micro, MiniSimulationControls, MissionCalendar, MissionClock, MonitoringIcon, Mono, Notification, NumberInput, ObjectInventoryPanel, PLANETS, PRESET_COLORS, PROPERTY_PRESETS, PacketViewer, Pagination, PinInput, Popover, Progress, REGION_BORDER_COLORS, REGION_COLORS, SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX, SPACE_SYSTEM_COLORS, STATUS_COLORS, Select, SideNav, SidePanel, SimulationControls, SimulationControlsWithClock, Skeleton3D, SkeletonBox, SkeletonCard, SkeletonChart, SkeletonCircle, SkeletonText, Spacer, Stack, StatusIndicator, Tabs, ThemeProvider, UnifiedTimeline as Timeline, ToastProvider, Toggle, Tooltip, Typography, VStack, ZenSpace3D, addAlpha, auToKm, clamp, classNames, createChatResponseParser, createPropertyConfig, decodeImage, deriveBatteryStatus, deriveStatus, ecefEulerXyzToHpr, ecefMetersToSdkPosition, estimateOrbitalPeriod, estimateOrbitalVelocity, focusRingStyle, formatAltitude, formatCoordinate, formatCountdown, formatDataRate, formatDecibels, formatDegrees, formatDistance, formatDuration, formatFrequency, formatLatLon, formatNumber, formatPercentage, formatPower, formatPropertyLabel, formatPropertyValue, formatTabular, formatTemperature, formatTime, formatUTC, formatVelocity, getAccentColorOptions, getEffectiveCompactMode, getIconNames, getPlanet, getPropertiesByCategory, getPropertyConfig, getStatusColor, getStatusFromValue, getStatusSeverity, getSystemAccentColor, getWorstStatus, isStatusLevel, isValidIconName, isValidNumber, lerp, loadCapturePlaceholderImage, mapRange, normalizePlanetName, normalizeStatus, parseChatResponse, parseMcpToolResult, recommendedFlyDistance, resolveResponsive, resolveSpacing, safeAccentText, safeNumber, tabularNumsStyle, transitions, useBreakpoint, useCapture, useCardAccent, useCategoryPalette, useCategoryPaletteRequired, useCompactMode, useConfirm, useCopyToClipboard, useDisplaySettings, useDisplaySettingsOptional, useScrollbarStyles, useSimulationScene, useTheme, useThemeTokens, useToast, useToastManager, withErrorBoundary, withNullSafety };
@@ -1,5 +1,6 @@
1
- const atmosphereFragmentShader = "uniform vec3 uSunDirection;\n\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\n\nvoid main() {\n // Base atmospheric scattering\n float viewIntensity = pow(0.65 - dot(vNormal, vec3(0.0, 0.0, 1.0)), 2.0);\n \n // Sun-facing glow (brighter on the side facing the sun)\n vec3 worldNormal = normalize(vWorldPosition);\n float sunFacing = dot(worldNormal, normalize(uSunDirection));\n float sunGlow = max(0.0, sunFacing) * 0.6 + 0.4; // 0.4-1.0 range\n \n // Terminator enhancement (glow at day/night boundary)\n float terminator = 1.0 - abs(sunFacing);\n float terminatorGlow = pow(terminator, 3.0) * 0.3;\n \n // Combine effects\n float totalIntensity = viewIntensity * sunGlow + terminatorGlow;\n \n // Atmosphere color (blue with slight orange on sun side)\n vec3 dayColor = vec3(0.3, 0.6, 1.0);\n vec3 sunsetColor = vec3(1.0, 0.5, 0.2);\n vec3 atmosphereColor = mix(dayColor, sunsetColor, pow(max(0.0, terminator), 4.0) * 0.3);\n \n gl_FragColor = vec4(atmosphereColor, 1.0) * totalIntensity;\n}\n";
2
- export {
3
- atmosphereFragmentShader as default
4
- };
5
- //# sourceMappingURL=atmosphere.frag.js.map
1
+ //#region src/shaders/atmosphere.frag
2
+ var atmosphere_default = "uniform vec3 uSunDirection;\n\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\n\nvoid main() {\n // Base atmospheric scattering\n float viewIntensity = pow(0.65 - dot(vNormal, vec3(0.0, 0.0, 1.0)), 2.0);\n \n // Sun-facing glow (brighter on the side facing the sun)\n vec3 worldNormal = normalize(vWorldPosition);\n float sunFacing = dot(worldNormal, normalize(uSunDirection));\n float sunGlow = max(0.0, sunFacing) * 0.6 + 0.4; // 0.4-1.0 range\n \n // Terminator enhancement (glow at day/night boundary)\n float terminator = 1.0 - abs(sunFacing);\n float terminatorGlow = pow(terminator, 3.0) * 0.3;\n \n // Combine effects\n float totalIntensity = viewIntensity * sunGlow + terminatorGlow;\n \n // Atmosphere color (blue with slight orange on sun side)\n vec3 dayColor = vec3(0.3, 0.6, 1.0);\n vec3 sunsetColor = vec3(1.0, 0.5, 0.2);\n vec3 atmosphereColor = mix(dayColor, sunsetColor, pow(max(0.0, terminator), 4.0) * 0.3);\n \n gl_FragColor = vec4(atmosphereColor, 1.0) * totalIntensity;\n}\n";
3
+ //#endregion
4
+ export { atmosphere_default as default };
5
+
6
+ //# sourceMappingURL=atmosphere.frag.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"atmosphere.frag.js","sources":["../../src/shaders/atmosphere.frag?raw"],"sourcesContent":["export default \"uniform vec3 uSunDirection;\\n\\nvarying vec3 vNormal;\\nvarying vec3 vPosition;\\nvarying vec3 vWorldPosition;\\n\\nvoid main() {\\n // Base atmospheric scattering\\n float viewIntensity = pow(0.65 - dot(vNormal, vec3(0.0, 0.0, 1.0)), 2.0);\\n \\n // Sun-facing glow (brighter on the side facing the sun)\\n vec3 worldNormal = normalize(vWorldPosition);\\n float sunFacing = dot(worldNormal, normalize(uSunDirection));\\n float sunGlow = max(0.0, sunFacing) * 0.6 + 0.4; // 0.4-1.0 range\\n \\n // Terminator enhancement (glow at day/night boundary)\\n float terminator = 1.0 - abs(sunFacing);\\n float terminatorGlow = pow(terminator, 3.0) * 0.3;\\n \\n // Combine effects\\n float totalIntensity = viewIntensity * sunGlow + terminatorGlow;\\n \\n // Atmosphere color (blue with slight orange on sun side)\\n vec3 dayColor = vec3(0.3, 0.6, 1.0);\\n vec3 sunsetColor = vec3(1.0, 0.5, 0.2);\\n vec3 atmosphereColor = mix(dayColor, sunsetColor, pow(max(0.0, terminator), 4.0) * 0.3);\\n \\n gl_FragColor = vec4(atmosphereColor, 1.0) * totalIntensity;\\n}\\n\""],"names":[],"mappings":"AAAA,MAAA,2BAAe;"}
1
+ {"version":3,"file":"atmosphere.frag.js","names":[],"sources":["../../src/shaders/atmosphere.frag"],"sourcesContent":["export default \"uniform vec3 uSunDirection;\\n\\nvarying vec3 vNormal;\\nvarying vec3 vPosition;\\nvarying vec3 vWorldPosition;\\n\\nvoid main() {\\n // Base atmospheric scattering\\n float viewIntensity = pow(0.65 - dot(vNormal, vec3(0.0, 0.0, 1.0)), 2.0);\\n \\n // Sun-facing glow (brighter on the side facing the sun)\\n vec3 worldNormal = normalize(vWorldPosition);\\n float sunFacing = dot(worldNormal, normalize(uSunDirection));\\n float sunGlow = max(0.0, sunFacing) * 0.6 + 0.4; // 0.4-1.0 range\\n \\n // Terminator enhancement (glow at day/night boundary)\\n float terminator = 1.0 - abs(sunFacing);\\n float terminatorGlow = pow(terminator, 3.0) * 0.3;\\n \\n // Combine effects\\n float totalIntensity = viewIntensity * sunGlow + terminatorGlow;\\n \\n // Atmosphere color (blue with slight orange on sun side)\\n vec3 dayColor = vec3(0.3, 0.6, 1.0);\\n vec3 sunsetColor = vec3(1.0, 0.5, 0.2);\\n vec3 atmosphereColor = mix(dayColor, sunsetColor, pow(max(0.0, terminator), 4.0) * 0.3);\\n \\n gl_FragColor = vec4(atmosphereColor, 1.0) * totalIntensity;\\n}\\n\";"],"mappings":";AAAA,IAAA,qBAAe"}
@@ -1,5 +1,6 @@
1
- const atmosphereVertexShader = "varying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\n\nvoid main() {\n vNormal = normalize(mat3(modelViewMatrix) * normal);\n vPosition = position;\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n";
2
- export {
3
- atmosphereVertexShader as default
4
- };
5
- //# sourceMappingURL=atmosphere.vert.js.map
1
+ //#region src/shaders/atmosphere.vert
2
+ var atmosphere_default = "varying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec3 vWorldPosition;\n\nvoid main() {\n vNormal = normalize(mat3(modelViewMatrix) * normal);\n vPosition = position;\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n";
3
+ //#endregion
4
+ export { atmosphere_default as default };
5
+
6
+ //# sourceMappingURL=atmosphere.vert.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"atmosphere.vert.js","sources":["../../src/shaders/atmosphere.vert?raw"],"sourcesContent":["export default \"varying vec3 vNormal;\\nvarying vec3 vPosition;\\nvarying vec3 vWorldPosition;\\n\\nvoid main() {\\n vNormal = normalize(mat3(modelViewMatrix) * normal);\\n vPosition = position;\\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\n}\\n\""],"names":[],"mappings":"AAAA,MAAA,yBAAe;"}
1
+ {"version":3,"file":"atmosphere.vert.js","names":[],"sources":["../../src/shaders/atmosphere.vert"],"sourcesContent":["export default \"varying vec3 vNormal;\\nvarying vec3 vPosition;\\nvarying vec3 vWorldPosition;\\n\\nvoid main() {\\n vNormal = normalize(mat3(modelViewMatrix) * normal);\\n vPosition = position;\\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\n}\\n\";"],"mappings":";AAAA,IAAA,qBAAe"}
@@ -1,5 +1,6 @@
1
- const starsFragmentShader = "uniform float time;\r\nvarying float vOpacity;\r\n\r\nvoid main() {\r\n float dist = length(gl_PointCoord - vec2(0.5));\r\n if (dist > 0.5) discard;\r\n\r\n float twinkle = sin(time * vOpacity * 3.0 + vOpacity * 10.0) * 0.3 + 0.7;\r\n float alpha = (1.0 - dist * 2.0) * twinkle;\r\n\r\n gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);\r\n}\r\n\r\n\r\n\r\n\r\n";
2
- export {
3
- starsFragmentShader as default
4
- };
5
- //# sourceMappingURL=stars.frag.js.map
1
+ //#region src/shaders/stars.frag
2
+ var stars_default = "uniform float time;\r\nvarying float vOpacity;\r\n\r\nvoid main() {\r\n float dist = length(gl_PointCoord - vec2(0.5));\r\n if (dist > 0.5) discard;\r\n\r\n float twinkle = sin(time * vOpacity * 3.0 + vOpacity * 10.0) * 0.3 + 0.7;\r\n float alpha = (1.0 - dist * 2.0) * twinkle;\r\n\r\n gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);\r\n}\r\n\r\n\r\n\r\n\r\n";
3
+ //#endregion
4
+ export { stars_default as default };
5
+
6
+ //# sourceMappingURL=stars.frag.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stars.frag.js","sources":["../../src/shaders/stars.frag?raw"],"sourcesContent":["export default \"uniform float time;\\r\\nvarying float vOpacity;\\r\\n\\r\\nvoid main() {\\r\\n float dist = length(gl_PointCoord - vec2(0.5));\\r\\n if (dist > 0.5) discard;\\r\\n\\r\\n float twinkle = sin(time * vOpacity * 3.0 + vOpacity * 10.0) * 0.3 + 0.7;\\r\\n float alpha = (1.0 - dist * 2.0) * twinkle;\\r\\n\\r\\n gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);\\r\\n}\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n\""],"names":[],"mappings":"AAAA,MAAA,sBAAe;"}
1
+ {"version":3,"file":"stars.frag.js","names":[],"sources":["../../src/shaders/stars.frag"],"sourcesContent":["export default \"uniform float time;\\r\\nvarying float vOpacity;\\r\\n\\r\\nvoid main() {\\r\\n float dist = length(gl_PointCoord - vec2(0.5));\\r\\n if (dist > 0.5) discard;\\r\\n\\r\\n float twinkle = sin(time * vOpacity * 3.0 + vOpacity * 10.0) * 0.3 + 0.7;\\r\\n float alpha = (1.0 - dist * 2.0) * twinkle;\\r\\n\\r\\n gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);\\r\\n}\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n\";"],"mappings":";AAAA,IAAA,gBAAe"}
@@ -1,5 +1,6 @@
1
- const starsVertexShader = "attribute float opacity;\r\nvarying float vOpacity;\r\n\r\nvoid main() {\r\n vOpacity = opacity;\r\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\r\n gl_PointSize = 3.0;\r\n gl_Position = projectionMatrix * mvPosition;\r\n}\r\n\r\n\r\n\r\n\r\n";
2
- export {
3
- starsVertexShader as default
4
- };
5
- //# sourceMappingURL=stars.vert.js.map
1
+ //#region src/shaders/stars.vert
2
+ var stars_default = "attribute float opacity;\r\nvarying float vOpacity;\r\n\r\nvoid main() {\r\n vOpacity = opacity;\r\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\r\n gl_PointSize = 3.0;\r\n gl_Position = projectionMatrix * mvPosition;\r\n}\r\n\r\n\r\n\r\n\r\n";
3
+ //#endregion
4
+ export { stars_default as default };
5
+
6
+ //# sourceMappingURL=stars.vert.js.map