@zendir/ui 0.1.0

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 (359) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +589 -0
  4. package/dist/index.d.ts +8 -0
  5. package/dist/index.js +421 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/react/3d/EarthViewer.d.ts +46 -0
  8. package/dist/react/3d/EarthViewer.js +836 -0
  9. package/dist/react/3d/EarthViewer.js.map +1 -0
  10. package/dist/react/3d/SolarSystemViewer.d.ts +43 -0
  11. package/dist/react/3d/SolarSystemViewer.js +372 -0
  12. package/dist/react/3d/SolarSystemViewer.js.map +1 -0
  13. package/dist/react/3d/ZenSpace3D.d.ts +16 -0
  14. package/dist/react/3d/ZenSpace3D.js +1253 -0
  15. package/dist/react/3d/ZenSpace3D.js.map +1 -0
  16. package/dist/react/3d/ZenSpace3DCesium.d.ts +9 -0
  17. package/dist/react/3d/ZenSpace3DCesium.js +186 -0
  18. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
  19. package/dist/react/3d/ZenSpace3DShaders.d.ts +78 -0
  20. package/dist/react/3d/ZenSpace3DShaders.js +94 -0
  21. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -0
  22. package/dist/react/3d/ZenSpace3DTypes.d.ts +614 -0
  23. package/dist/react/3d/ZenSpace3DUtils.d.ts +183 -0
  24. package/dist/react/3d/ZenSpace3DUtils.js +213 -0
  25. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -0
  26. package/dist/react/3d/index.d.ts +23 -0
  27. package/dist/react/3d/threeLoader.d.ts +22 -0
  28. package/dist/react/3d/threeLoader.js +18 -0
  29. package/dist/react/3d/threeLoader.js.map +1 -0
  30. package/dist/react/astro/ClassificationBanner.d.ts +25 -0
  31. package/dist/react/astro/ClassificationBanner.js +83 -0
  32. package/dist/react/astro/ClassificationBanner.js.map +1 -0
  33. package/dist/react/astro/GlobalStatusBar.d.ts +42 -0
  34. package/dist/react/astro/GlobalStatusBar.js +165 -0
  35. package/dist/react/astro/GlobalStatusBar.js.map +1 -0
  36. package/dist/react/astro/MissionClock.d.ts +169 -0
  37. package/dist/react/astro/MissionClock.js +411 -0
  38. package/dist/react/astro/MissionClock.js.map +1 -0
  39. package/dist/react/astro/MonitoringIcon.d.ts +60 -0
  40. package/dist/react/astro/MonitoringIcon.js +369 -0
  41. package/dist/react/astro/MonitoringIcon.js.map +1 -0
  42. package/dist/react/astro/Notification.d.ts +42 -0
  43. package/dist/react/astro/Notification.js +156 -0
  44. package/dist/react/astro/Notification.js.map +1 -0
  45. package/dist/react/astro/Progress.d.ts +39 -0
  46. package/dist/react/astro/Progress.js +149 -0
  47. package/dist/react/astro/Progress.js.map +1 -0
  48. package/dist/react/astro/SimulationControls.d.ts +136 -0
  49. package/dist/react/astro/SimulationControls.js +668 -0
  50. package/dist/react/astro/SimulationControls.js.map +1 -0
  51. package/dist/react/astro/StatusIndicator.d.ts +34 -0
  52. package/dist/react/astro/StatusIndicator.js +189 -0
  53. package/dist/react/astro/StatusIndicator.js.map +1 -0
  54. package/dist/react/astro/UnifiedTimeline.d.ts +106 -0
  55. package/dist/react/astro/UnifiedTimeline.js +1768 -0
  56. package/dist/react/astro/UnifiedTimeline.js.map +1 -0
  57. package/dist/react/astro/index.d.ts +63 -0
  58. package/dist/react/cards/AccessCard.d.ts +37 -0
  59. package/dist/react/cards/AccessCard.js +410 -0
  60. package/dist/react/cards/AccessCard.js.map +1 -0
  61. package/dist/react/cards/OrbitCard.d.ts +31 -0
  62. package/dist/react/cards/OrbitCard.js +372 -0
  63. package/dist/react/cards/OrbitCard.js.map +1 -0
  64. package/dist/react/cards/SpacecraftCard.d.ts +54 -0
  65. package/dist/react/cards/SpacecraftCard.js +941 -0
  66. package/dist/react/cards/SpacecraftCard.js.map +1 -0
  67. package/dist/react/cards/TelemetryCard.d.ts +40 -0
  68. package/dist/react/cards/TelemetryCard.js +742 -0
  69. package/dist/react/cards/TelemetryCard.js.map +1 -0
  70. package/dist/react/cards/TelemetryStreamCard.d.ts +59 -0
  71. package/dist/react/cards/TelemetryStreamCard.js +309 -0
  72. package/dist/react/cards/TelemetryStreamCard.js.map +1 -0
  73. package/dist/react/cards/index.d.ts +13 -0
  74. package/dist/react/charts/GroundTrackMap.d.ts +112 -0
  75. package/dist/react/charts/GroundTrackMap.js +1123 -0
  76. package/dist/react/charts/GroundTrackMap.js.map +1 -0
  77. package/dist/react/charts/GroundTrackMapLeaflet.d.ts +26 -0
  78. package/dist/react/charts/GroundTrackMapLeaflet.js +571 -0
  79. package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -0
  80. package/dist/react/charts/groundTrackMapLeafletTiles.d.ts +22 -0
  81. package/dist/react/charts/groundTrackMapLeafletTiles.js +11 -0
  82. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -0
  83. package/dist/react/charts/groundTrackMapLeafletUtils.d.ts +24 -0
  84. package/dist/react/charts/groundTrackMapLeafletUtils.js +109 -0
  85. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -0
  86. package/dist/react/charts/index.d.ts +10 -0
  87. package/dist/react/charts/unified/AstroChart.d.ts +24 -0
  88. package/dist/react/charts/unified/AstroChart.js +1405 -0
  89. package/dist/react/charts/unified/AstroChart.js.map +1 -0
  90. package/dist/react/charts/unified/PowerOverviewChart.d.ts +73 -0
  91. package/dist/react/charts/unified/PowerOverviewChart.js +488 -0
  92. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -0
  93. package/dist/react/charts/unified/domain.d.ts +845 -0
  94. package/dist/react/charts/unified/domain.js +3168 -0
  95. package/dist/react/charts/unified/domain.js.map +1 -0
  96. package/dist/react/charts/unified/generators.d.ts +276 -0
  97. package/dist/react/charts/unified/generators.js +518 -0
  98. package/dist/react/charts/unified/generators.js.map +1 -0
  99. package/dist/react/charts/unified/index.d.ts +55 -0
  100. package/dist/react/charts/unified/presets.d.ts +290 -0
  101. package/dist/react/charts/unified/presets.js +999 -0
  102. package/dist/react/charts/unified/presets.js.map +1 -0
  103. package/dist/react/charts/unified/sync.d.ts +69 -0
  104. package/dist/react/charts/unified/sync.js +219 -0
  105. package/dist/react/charts/unified/sync.js.map +1 -0
  106. package/dist/react/charts/unified/theme.d.ts +447 -0
  107. package/dist/react/charts/unified/theme.js +562 -0
  108. package/dist/react/charts/unified/theme.js.map +1 -0
  109. package/dist/react/charts/unified/types.d.ts +826 -0
  110. package/dist/react/charts/unified/useChartStream.d.ts +58 -0
  111. package/dist/react/charts/unified/useChartStream.js +226 -0
  112. package/dist/react/charts/unified/useChartStream.js.map +1 -0
  113. package/dist/react/chatgpt/AppCard.d.ts +59 -0
  114. package/dist/react/chatgpt/AppCard.js +306 -0
  115. package/dist/react/chatgpt/AppCard.js.map +1 -0
  116. package/dist/react/chatgpt/ChatGPTCard.d.ts +6 -0
  117. package/dist/react/chatgpt/index.d.ts +167 -0
  118. package/dist/react/chatgpt/index.js +166 -0
  119. package/dist/react/chatgpt/index.js.map +1 -0
  120. package/dist/react/context/DisplaySettingsContext.d.ts +107 -0
  121. package/dist/react/context/DisplaySettingsContext.js +169 -0
  122. package/dist/react/context/DisplaySettingsContext.js.map +1 -0
  123. package/dist/react/context/index.d.ts +5 -0
  124. package/dist/react/core/ActivityPlanner.d.ts +45 -0
  125. package/dist/react/core/ActivityPlanner.js +532 -0
  126. package/dist/react/core/ActivityPlanner.js.map +1 -0
  127. package/dist/react/core/AppBar.d.ts +71 -0
  128. package/dist/react/core/AppBar.js +817 -0
  129. package/dist/react/core/AppBar.js.map +1 -0
  130. package/dist/react/core/AstroIcon.d.ts +84 -0
  131. package/dist/react/core/AstroIcon.js +1243 -0
  132. package/dist/react/core/AstroIcon.js.map +1 -0
  133. package/dist/react/core/Badge.d.ts +27 -0
  134. package/dist/react/core/Badge.js +134 -0
  135. package/dist/react/core/Badge.js.map +1 -0
  136. package/dist/react/core/Button.d.ts +26 -0
  137. package/dist/react/core/Button.js +306 -0
  138. package/dist/react/core/Button.js.map +1 -0
  139. package/dist/react/core/CardHeader.d.ts +34 -0
  140. package/dist/react/core/CardHeader.js +316 -0
  141. package/dist/react/core/CardHeader.js.map +1 -0
  142. package/dist/react/core/ChatPanel.d.ts +627 -0
  143. package/dist/react/core/ChatPanel.js +1144 -0
  144. package/dist/react/core/ChatPanel.js.map +1 -0
  145. package/dist/react/core/Checkbox.d.ts +26 -0
  146. package/dist/react/core/Checkbox.js +130 -0
  147. package/dist/react/core/Checkbox.js.map +1 -0
  148. package/dist/react/core/ColorPickerPanel.d.ts +25 -0
  149. package/dist/react/core/ColorPickerPanel.js +293 -0
  150. package/dist/react/core/ColorPickerPanel.js.map +1 -0
  151. package/dist/react/core/CommandBuilder.d.ts +74 -0
  152. package/dist/react/core/CommandBuilder.js +518 -0
  153. package/dist/react/core/CommandBuilder.js.map +1 -0
  154. package/dist/react/core/ConfirmDialog.d.ts +45 -0
  155. package/dist/react/core/ConfirmDialog.js +315 -0
  156. package/dist/react/core/ConfirmDialog.js.map +1 -0
  157. package/dist/react/core/ConnectionForm.d.ts +57 -0
  158. package/dist/react/core/ConnectionForm.js +496 -0
  159. package/dist/react/core/ConnectionForm.js.map +1 -0
  160. package/dist/react/core/Container.d.ts +51 -0
  161. package/dist/react/core/Container.js +670 -0
  162. package/dist/react/core/Container.js.map +1 -0
  163. package/dist/react/core/CopyButton.d.ts +39 -0
  164. package/dist/react/core/CopyButton.js +105 -0
  165. package/dist/react/core/CopyButton.js.map +1 -0
  166. package/dist/react/core/DataTable.d.ts +113 -0
  167. package/dist/react/core/DataTable.js +446 -0
  168. package/dist/react/core/DataTable.js.map +1 -0
  169. package/dist/react/core/DataValue.d.ts +64 -0
  170. package/dist/react/core/DataValue.js +545 -0
  171. package/dist/react/core/DataValue.js.map +1 -0
  172. package/dist/react/core/Dialog.d.ts +32 -0
  173. package/dist/react/core/Dialog.js +201 -0
  174. package/dist/react/core/Dialog.js.map +1 -0
  175. package/dist/react/core/FileExplorer.d.ts +65 -0
  176. package/dist/react/core/FileExplorer.js +520 -0
  177. package/dist/react/core/FileExplorer.js.map +1 -0
  178. package/dist/react/core/GlassCard.d.ts +129 -0
  179. package/dist/react/core/GlassCard.js +375 -0
  180. package/dist/react/core/GlassCard.js.map +1 -0
  181. package/dist/react/core/HeaderIconWithStatus.d.ts +39 -0
  182. package/dist/react/core/HeaderIconWithStatus.js +157 -0
  183. package/dist/react/core/HeaderIconWithStatus.js.map +1 -0
  184. package/dist/react/core/HexViewer.d.ts +143 -0
  185. package/dist/react/core/HexViewer.js +1106 -0
  186. package/dist/react/core/HexViewer.js.map +1 -0
  187. package/dist/react/core/Icon.d.ts +32 -0
  188. package/dist/react/core/Icon.js +142 -0
  189. package/dist/react/core/Icon.js.map +1 -0
  190. package/dist/react/core/ImageGallery.d.ts +41 -0
  191. package/dist/react/core/ImageGallery.js +320 -0
  192. package/dist/react/core/ImageGallery.js.map +1 -0
  193. package/dist/react/core/Input.d.ts +38 -0
  194. package/dist/react/core/Input.js +288 -0
  195. package/dist/react/core/Input.js.map +1 -0
  196. package/dist/react/core/LimitsBar.d.ts +51 -0
  197. package/dist/react/core/LimitsBar.js +200 -0
  198. package/dist/react/core/LimitsBar.js.map +1 -0
  199. package/dist/react/core/LogViewer.d.ts +61 -0
  200. package/dist/react/core/LogViewer.js +599 -0
  201. package/dist/react/core/LogViewer.js.map +1 -0
  202. package/dist/react/core/MessageStream.d.ts +58 -0
  203. package/dist/react/core/MessageStream.js +455 -0
  204. package/dist/react/core/MessageStream.js.map +1 -0
  205. package/dist/react/core/MissionCalendar.d.ts +81 -0
  206. package/dist/react/core/MissionCalendar.js +1049 -0
  207. package/dist/react/core/MissionCalendar.js.map +1 -0
  208. package/dist/react/core/NumberInput.d.ts +85 -0
  209. package/dist/react/core/NumberInput.js +507 -0
  210. package/dist/react/core/NumberInput.js.map +1 -0
  211. package/dist/react/core/PacketViewer.d.ts +73 -0
  212. package/dist/react/core/PacketViewer.js +431 -0
  213. package/dist/react/core/PacketViewer.js.map +1 -0
  214. package/dist/react/core/Pagination.d.ts +30 -0
  215. package/dist/react/core/Pagination.js +190 -0
  216. package/dist/react/core/Pagination.js.map +1 -0
  217. package/dist/react/core/PinInput.d.ts +41 -0
  218. package/dist/react/core/PinInput.js +210 -0
  219. package/dist/react/core/PinInput.js.map +1 -0
  220. package/dist/react/core/Popover.d.ts +55 -0
  221. package/dist/react/core/Popover.js +288 -0
  222. package/dist/react/core/Popover.js.map +1 -0
  223. package/dist/react/core/Select.d.ts +42 -0
  224. package/dist/react/core/Select.js +303 -0
  225. package/dist/react/core/Select.js.map +1 -0
  226. package/dist/react/core/SideNav.d.ts +103 -0
  227. package/dist/react/core/SideNav.js +551 -0
  228. package/dist/react/core/SideNav.js.map +1 -0
  229. package/dist/react/core/SidePanel.d.ts +33 -0
  230. package/dist/react/core/SidePanel.js +199 -0
  231. package/dist/react/core/SidePanel.js.map +1 -0
  232. package/dist/react/core/Tabs.d.ts +47 -0
  233. package/dist/react/core/Tabs.js +129 -0
  234. package/dist/react/core/Tabs.js.map +1 -0
  235. package/dist/react/core/Toast.d.ts +56 -0
  236. package/dist/react/core/Toast.js +229 -0
  237. package/dist/react/core/Toast.js.map +1 -0
  238. package/dist/react/core/Toggle.d.ts +22 -0
  239. package/dist/react/core/Toggle.js +151 -0
  240. package/dist/react/core/Toggle.js.map +1 -0
  241. package/dist/react/core/Tooltip.d.ts +19 -0
  242. package/dist/react/core/Tooltip.js +179 -0
  243. package/dist/react/core/Tooltip.js.map +1 -0
  244. package/dist/react/core/Typography.d.ts +127 -0
  245. package/dist/react/core/Typography.js +187 -0
  246. package/dist/react/core/Typography.js.map +1 -0
  247. package/dist/react/core/index.d.ts +108 -0
  248. package/dist/react/core/layout/Box.d.ts +77 -0
  249. package/dist/react/core/layout/Box.js +126 -0
  250. package/dist/react/core/layout/Box.js.map +1 -0
  251. package/dist/react/core/layout/Center.d.ts +20 -0
  252. package/dist/react/core/layout/Center.js +34 -0
  253. package/dist/react/core/layout/Center.js.map +1 -0
  254. package/dist/react/core/layout/Divider.d.ts +16 -0
  255. package/dist/react/core/layout/Divider.js +108 -0
  256. package/dist/react/core/layout/Divider.js.map +1 -0
  257. package/dist/react/core/layout/Flex.d.ts +30 -0
  258. package/dist/react/core/layout/Flex.js +128 -0
  259. package/dist/react/core/layout/Flex.js.map +1 -0
  260. package/dist/react/core/layout/Grid.d.ts +36 -0
  261. package/dist/react/core/layout/Grid.js +142 -0
  262. package/dist/react/core/layout/Grid.js.map +1 -0
  263. package/dist/react/core/layout/Spacer.d.ts +8 -0
  264. package/dist/react/core/layout/Spacer.js +31 -0
  265. package/dist/react/core/layout/Spacer.js.map +1 -0
  266. package/dist/react/core/layout/Stack.d.ts +54 -0
  267. package/dist/react/core/layout/Stack.js +74 -0
  268. package/dist/react/core/layout/Stack.js.map +1 -0
  269. package/dist/react/core/layout/index.d.ts +38 -0
  270. package/dist/react/core/layout/responsive.d.ts +23 -0
  271. package/dist/react/core/layout/responsive.js +26 -0
  272. package/dist/react/core/layout/responsive.js.map +1 -0
  273. package/dist/react/core/layout/useBreakpoint.d.ts +77 -0
  274. package/dist/react/core/layout/useBreakpoint.js +73 -0
  275. package/dist/react/core/layout/useBreakpoint.js.map +1 -0
  276. package/dist/react/core/propertyConfig.d.ts +443 -0
  277. package/dist/react/core/propertyConfig.js +399 -0
  278. package/dist/react/core/propertyConfig.js.map +1 -0
  279. package/dist/react/hooks/index.d.ts +21 -0
  280. package/dist/react/hooks/useAccessWindows.d.ts +66 -0
  281. package/dist/react/hooks/useCompactMode.d.ts +82 -0
  282. package/dist/react/hooks/useCompactMode.js +62 -0
  283. package/dist/react/hooks/useCompactMode.js.map +1 -0
  284. package/dist/react/hooks/useLiveSelection.d.ts +57 -0
  285. package/dist/react/hooks/useSimulationPlayback.d.ts +97 -0
  286. package/dist/react/hooks/useSimulationTime.d.ts +61 -0
  287. package/dist/react/hooks/useSpacecraftPosition.d.ts +50 -0
  288. package/dist/react/hooks/useSpacecraftPosition.js +89 -0
  289. package/dist/react/hooks/useSpacecraftPosition.js.map +1 -0
  290. package/dist/react/hooks/useTelemetry.d.ts +55 -0
  291. package/dist/react/hooks/useTelemetry.js +73 -0
  292. package/dist/react/hooks/useTelemetry.js.map +1 -0
  293. package/dist/react/hooks/useZendirSession.d.ts +109 -0
  294. package/dist/react/hooks/useZendirSession.js +148 -0
  295. package/dist/react/hooks/useZendirSession.js.map +1 -0
  296. package/dist/react/index.d.ts +74 -0
  297. package/dist/react/shared/ErrorBoundary.d.ts +63 -0
  298. package/dist/react/shared/ErrorBoundary.js +142 -0
  299. package/dist/react/shared/ErrorBoundary.js.map +1 -0
  300. package/dist/react/shared/Skeleton.d.ts +110 -0
  301. package/dist/react/shared/Skeleton.js +324 -0
  302. package/dist/react/shared/Skeleton.js.map +1 -0
  303. package/dist/react/shared/index.d.ts +12 -0
  304. package/dist/react/theme/ThemeProvider.d.ts +385 -0
  305. package/dist/react/theme/ThemeProvider.js +1096 -0
  306. package/dist/react/theme/ThemeProvider.js.map +1 -0
  307. package/dist/react/theme/astro-tokens.d.ts +153 -0
  308. package/dist/react/theme/cardAccent.d.ts +75 -0
  309. package/dist/react/theme/cardAccent.js +137 -0
  310. package/dist/react/theme/cardAccent.js.map +1 -0
  311. package/dist/react/theme/config.d.ts +39 -0
  312. package/dist/react/theme/index.d.ts +9 -0
  313. package/dist/react/types.d.ts +360 -0
  314. package/dist/react/types.js +58 -0
  315. package/dist/react/types.js.map +1 -0
  316. package/dist/react/utils/index.d.ts +247 -0
  317. package/dist/react/utils/index.js +423 -0
  318. package/dist/react/utils/index.js.map +1 -0
  319. package/dist/react/visualizations/EclipseTimerCard.d.ts +17 -0
  320. package/dist/react/visualizations/EclipseTimerCard.js +250 -0
  321. package/dist/react/visualizations/EclipseTimerCard.js.map +1 -0
  322. package/dist/react/visualizations/LinkBudgetCard.d.ts +50 -0
  323. package/dist/react/visualizations/LinkBudgetCard.js +444 -0
  324. package/dist/react/visualizations/LinkBudgetCard.js.map +1 -0
  325. package/dist/react/visualizations/NavBallCard.d.ts +17 -0
  326. package/dist/react/visualizations/NavBallCard.js +243 -0
  327. package/dist/react/visualizations/NavBallCard.js.map +1 -0
  328. package/dist/react/visualizations/PropulsionCard.d.ts +37 -0
  329. package/dist/react/visualizations/PropulsionCard.js +298 -0
  330. package/dist/react/visualizations/PropulsionCard.js.map +1 -0
  331. package/dist/react/visualizations/SensorFootprintCard.d.ts +33 -0
  332. package/dist/react/visualizations/SensorFootprintCard.js +326 -0
  333. package/dist/react/visualizations/SensorFootprintCard.js.map +1 -0
  334. package/dist/react/visualizations/ThermalHeatmapCard.d.ts +38 -0
  335. package/dist/react/visualizations/ThermalHeatmapCard.js +372 -0
  336. package/dist/react/visualizations/ThermalHeatmapCard.js.map +1 -0
  337. package/dist/react/visualizations/index.d.ts +17 -0
  338. package/dist/react.d.ts +1 -0
  339. package/dist/react.js +421 -0
  340. package/dist/react.js.map +1 -0
  341. package/dist/shaders/atmosphere.frag.js +5 -0
  342. package/dist/shaders/atmosphere.frag.js.map +1 -0
  343. package/dist/shaders/atmosphere.vert.js +5 -0
  344. package/dist/shaders/atmosphere.vert.js.map +1 -0
  345. package/dist/shaders/stars.frag.js +5 -0
  346. package/dist/shaders/stars.frag.js.map +1 -0
  347. package/dist/shaders/stars.vert.js +5 -0
  348. package/dist/shaders/stars.vert.js.map +1 -0
  349. package/dist/style.css +143 -0
  350. package/dist/tokens/index.d.ts +296 -0
  351. package/dist/tokens/index.js +263 -0
  352. package/dist/tokens/index.js.map +1 -0
  353. package/dist/tokens/tokens.css +155 -0
  354. package/dist/types/index.d.ts +23 -0
  355. package/dist/types.d.ts +1 -0
  356. package/dist/types.js +2 -0
  357. package/dist/types.js.map +1 -0
  358. package/package.json +220 -0
  359. package/sdk-stub.js +22 -0
@@ -0,0 +1,1106 @@
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
+ import React, { useMemo, useState, useCallback, useRef, useEffect, memo } from "react";
3
+ import { useTheme } from "../theme/ThemeProvider.js";
4
+ const REGION_COLORS = {
5
+ primary: "rgba(96, 165, 250, 0.15)",
6
+ secondary: "rgba(168, 85, 247, 0.15)",
7
+ tertiary: "rgba(251, 191, 36, 0.15)",
8
+ userData: "rgba(34, 197, 94, 0.15)",
9
+ error: "rgba(255, 56, 56, 0.15)"
10
+ };
11
+ const REGION_BORDER_COLORS = {
12
+ primary: "rgba(96, 165, 250, 0.5)",
13
+ secondary: "rgba(168, 85, 247, 0.5)",
14
+ tertiary: "rgba(251, 191, 36, 0.5)",
15
+ userData: "rgba(34, 197, 94, 0.5)",
16
+ error: "rgba(255, 56, 56, 0.5)"
17
+ };
18
+ function toUint8Array(data) {
19
+ return data instanceof Uint8Array ? data : new Uint8Array(data);
20
+ }
21
+ function byteToHex(byte) {
22
+ return byte.toString(16).padStart(2, "0").toUpperCase();
23
+ }
24
+ function byteToAscii(byte) {
25
+ return byte >= 32 && byte <= 126 ? String.fromCharCode(byte) : ".";
26
+ }
27
+ function formatOffset(offset, base, totalBytes) {
28
+ if (base === "hex") {
29
+ const width2 = Math.max(4, Math.ceil(Math.log2(Math.max(totalBytes, 1)) / 4) * 1);
30
+ return offset.toString(16).padStart(Math.max(width2, 4), "0").toUpperCase();
31
+ }
32
+ const width = Math.max(4, totalBytes.toString().length);
33
+ return offset.toString().padStart(width, " ");
34
+ }
35
+ function interpretBytes(data, offset, endianness) {
36
+ const result = {
37
+ u8: data[offset],
38
+ i8: data[offset] > 127 ? data[offset] - 256 : data[offset]
39
+ };
40
+ if (offset + 1 < data.length) {
41
+ const view = new DataView(data.buffer, data.byteOffset + offset, Math.min(8, data.length - offset));
42
+ const be = endianness === "big";
43
+ result.u16 = view.getUint16(0, !be);
44
+ result.i16 = view.getInt16(0, !be);
45
+ if (offset + 3 < data.length) {
46
+ result.u32 = view.getUint32(0, !be);
47
+ result.i32 = view.getInt32(0, !be);
48
+ result.f32 = view.getFloat32(0, !be);
49
+ }
50
+ if (offset + 7 < data.length) {
51
+ result.f64 = view.getFloat64(0, !be);
52
+ }
53
+ }
54
+ return result;
55
+ }
56
+ const HEX_ROW_HEIGHT = 22;
57
+ const HEX_OVERSCAN_ROWS = 16;
58
+ const MAX_RENDERED_SEARCH_HIGHLIGHTS = 400;
59
+ const HexRow = memo(function HexRow2({
60
+ offset,
61
+ bytes,
62
+ bytesPerRow,
63
+ byteGrouping,
64
+ offsetBase,
65
+ totalBytes,
66
+ showAscii,
67
+ showOffset,
68
+ highlights,
69
+ regions,
70
+ effectiveHighlight,
71
+ selectedStart,
72
+ selectedEnd,
73
+ cursorOffset,
74
+ onByteMouseDown,
75
+ onByteMouseEnter,
76
+ onByteClick,
77
+ handleByteHoverInternal,
78
+ handleByteLeaveInternal,
79
+ tokens
80
+ }) {
81
+ const hexCells = [];
82
+ const asciiCells = [];
83
+ for (let i = 0; i < bytesPerRow; i++) {
84
+ const byteIdx = offset + i;
85
+ const isValid = i < bytes.length;
86
+ const byte = isValid ? bytes[i] : 0;
87
+ let bgColor = "transparent";
88
+ let fgColor = tokens.colors.text.primary;
89
+ let borderBottom = "2px solid transparent";
90
+ const isSelected = byteIdx >= Math.min(selectedStart, selectedEnd) && byteIdx <= Math.max(selectedStart, selectedEnd) && selectedStart >= 0;
91
+ const isCursor = byteIdx === cursorOffset;
92
+ let regionColor = null;
93
+ for (let r = 0; r < regions.length; r++) {
94
+ const region = regions[r];
95
+ if (byteIdx < region.start) break;
96
+ if (byteIdx >= region.start && byteIdx < region.end) {
97
+ regionColor = region.color;
98
+ break;
99
+ }
100
+ }
101
+ if (regionColor) {
102
+ bgColor = regionColor;
103
+ }
104
+ for (const h of highlights) {
105
+ if (byteIdx >= h.start && byteIdx <= h.end) {
106
+ bgColor = `${h.color}33`;
107
+ fgColor = h.color;
108
+ break;
109
+ }
110
+ }
111
+ if (effectiveHighlight && byteIdx >= effectiveHighlight.start && byteIdx < effectiveHighlight.end) {
112
+ bgColor = `${tokens.colors.status.caution}4D`;
113
+ borderBottom = `2px solid ${tokens.colors.status.caution}`;
114
+ }
115
+ if (isSelected) {
116
+ bgColor = `${tokens.colors.interactive.default}4D`;
117
+ fgColor = tokens.colors.interactive.default;
118
+ }
119
+ const needsGroupSpace = i > 0 && i % byteGrouping === 0;
120
+ hexCells.push(
121
+ /* @__PURE__ */ jsx(
122
+ "span",
123
+ {
124
+ role: "button",
125
+ tabIndex: isValid ? 0 : -1,
126
+ onMouseDown: () => isValid && onByteMouseDown(byteIdx),
127
+ onMouseEnter: () => {
128
+ isValid && onByteMouseEnter(byteIdx);
129
+ isValid && handleByteHoverInternal(byteIdx);
130
+ },
131
+ onMouseLeave: () => isValid && handleByteLeaveInternal(),
132
+ onClick: () => isValid && onByteClick(byteIdx),
133
+ onKeyDown: (e) => {
134
+ if (isValid && (e.key === "Enter" || e.key === " ")) {
135
+ e.preventDefault();
136
+ onByteClick(byteIdx);
137
+ }
138
+ },
139
+ style: {
140
+ padding: "0 2px",
141
+ marginLeft: needsGroupSpace ? 6 : 0,
142
+ background: bgColor,
143
+ color: isValid ? fgColor : `${tokens.colors.text.muted}26`,
144
+ cursor: isValid ? "pointer" : "default",
145
+ borderBottom: isCursor ? `2px solid ${tokens.colors.status.normal}` : borderBottom,
146
+ borderRadius: tokens.borderRadius.sm,
147
+ userSelect: "none",
148
+ transition: "background 0.1s ease"
149
+ },
150
+ children: isValid ? byteToHex(byte) : " "
151
+ },
152
+ `hex-${i}`
153
+ )
154
+ );
155
+ if (showAscii) {
156
+ asciiCells.push(
157
+ /* @__PURE__ */ jsx(
158
+ "span",
159
+ {
160
+ role: "button",
161
+ tabIndex: isValid ? 0 : -1,
162
+ onMouseDown: () => isValid && onByteMouseDown(byteIdx),
163
+ onMouseEnter: () => {
164
+ isValid && onByteMouseEnter(byteIdx);
165
+ isValid && handleByteHoverInternal(byteIdx);
166
+ },
167
+ onMouseLeave: () => isValid && handleByteLeaveInternal(),
168
+ onClick: () => isValid && onByteClick(byteIdx),
169
+ onKeyDown: (e) => {
170
+ if (isValid && (e.key === "Enter" || e.key === " ")) {
171
+ e.preventDefault();
172
+ onByteClick(byteIdx);
173
+ }
174
+ },
175
+ style: {
176
+ background: bgColor,
177
+ color: isValid ? byte >= 32 && byte <= 126 ? fgColor : `${tokens.colors.text.muted}33` : "transparent",
178
+ cursor: isValid ? "pointer" : "default",
179
+ borderBottom: isCursor ? `2px solid ${tokens.colors.status.normal}` : borderBottom,
180
+ borderRadius: tokens.borderRadius.sm,
181
+ userSelect: "none",
182
+ width: 8,
183
+ textAlign: "center"
184
+ },
185
+ children: isValid ? byteToAscii(byte) : " "
186
+ },
187
+ `ascii-${i}`
188
+ )
189
+ );
190
+ }
191
+ }
192
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", height: HEX_ROW_HEIGHT, lineHeight: `${HEX_ROW_HEIGHT}px` }, children: [
193
+ showOffset && /* @__PURE__ */ jsx("span", { style: { color: tokens.colors.text.muted, marginRight: 12, minWidth: 60, textAlign: "right" }, children: formatOffset(offset, offsetBase, totalBytes) }),
194
+ /* @__PURE__ */ jsx("span", { style: { display: "flex", gap: 1, marginRight: showAscii ? 16 : 0, letterSpacing: "0.5px" }, children: hexCells }),
195
+ showAscii && /* @__PURE__ */ jsxs(Fragment, { children: [
196
+ /* @__PURE__ */ jsx("span", { style: { color: `${tokens.colors.border.muted}`, marginRight: 8 }, children: "│" }),
197
+ /* @__PURE__ */ jsx("span", { style: { display: "flex", letterSpacing: "1px" }, children: asciiCells })
198
+ ] })
199
+ ] });
200
+ });
201
+ function HexViewer({
202
+ data: rawData,
203
+ bytesPerRow = 16,
204
+ byteGrouping = 1,
205
+ offsetBase = "hex",
206
+ highlights = [],
207
+ regions = [],
208
+ decodedFields,
209
+ packetHeaders,
210
+ externalHighlight,
211
+ showAscii = true,
212
+ showOffset = true,
213
+ showStatusBar = true,
214
+ showSearch = true,
215
+ showToolbar = true,
216
+ showFieldsTable,
217
+ showHeaderSummary,
218
+ height = 400,
219
+ title,
220
+ streaming = false,
221
+ endianness = "big",
222
+ onSelectionChange,
223
+ onByteClick,
224
+ onByteHover,
225
+ onByteLeave,
226
+ className = "",
227
+ bordered = true,
228
+ style: styleProp
229
+ }) {
230
+ const { tokens } = useTheme();
231
+ const data = useMemo(() => toUint8Array(rawData), [rawData]);
232
+ const [hoveredFieldIdx, setHoveredFieldIdx] = useState(null);
233
+ const [fieldHighlight, setFieldHighlight] = useState(null);
234
+ const [showHeaders, setShowHeaders] = useState(true);
235
+ const [showFields, setShowFields] = useState(true);
236
+ const sortedRegions = useMemo(
237
+ () => [...regions].sort((a, b) => a.start - b.start),
238
+ [regions]
239
+ );
240
+ const fieldByteRanges = useMemo(() => {
241
+ if (!decodedFields) return [];
242
+ return decodedFields.map((f) => ({
243
+ start: f.byteOffset ?? 0,
244
+ end: (f.byteOffset ?? 0) + Math.ceil((f.sizeBits ?? 0) / 8),
245
+ name: f.name
246
+ }));
247
+ }, [decodedFields]);
248
+ const handleFieldHover = useCallback((fieldIdx) => {
249
+ setHoveredFieldIdx(fieldIdx);
250
+ const range = fieldByteRanges[fieldIdx];
251
+ if (range && range.end > range.start) setFieldHighlight(range);
252
+ }, [fieldByteRanges]);
253
+ const handleFieldLeave = useCallback(() => {
254
+ setHoveredFieldIdx(null);
255
+ setFieldHighlight(null);
256
+ }, []);
257
+ const handleByteHoverInternal = useCallback((byteIdx) => {
258
+ onByteHover == null ? void 0 : onByteHover(byteIdx);
259
+ const fi = fieldByteRanges.findIndex((r) => byteIdx >= r.start && byteIdx < r.end);
260
+ if (fi >= 0) {
261
+ setHoveredFieldIdx(fi);
262
+ setFieldHighlight(fieldByteRanges[fi]);
263
+ } else {
264
+ setHoveredFieldIdx(null);
265
+ setFieldHighlight({ start: byteIdx, end: byteIdx + 1 });
266
+ }
267
+ }, [fieldByteRanges, onByteHover]);
268
+ const handleByteLeaveInternal = useCallback(() => {
269
+ onByteLeave == null ? void 0 : onByteLeave();
270
+ setHoveredFieldIdx(null);
271
+ setFieldHighlight(null);
272
+ }, [onByteLeave]);
273
+ const effectiveHighlight = externalHighlight || fieldHighlight;
274
+ const shouldShowFieldsTable = showFieldsTable ?? (decodedFields && decodedFields.length > 0);
275
+ const shouldShowHeaderSummary = showHeaderSummary ?? (packetHeaders && packetHeaders.length > 0);
276
+ const scrollRef = useRef(null);
277
+ const hasConstrainedHeight = useMemo(() => {
278
+ if (height === void 0 || height === null) return false;
279
+ if (typeof height === "string") return height.trim().toLowerCase() !== "auto";
280
+ return true;
281
+ }, [height]);
282
+ const decodedFieldsMaxHeight = useMemo(() => {
283
+ if (typeof height === "number") {
284
+ return Math.min(220, Math.max(120, Math.floor(height * 0.32)));
285
+ }
286
+ return 200;
287
+ }, [height]);
288
+ const [cursorOffset, setCursorOffset] = useState(-1);
289
+ const [selectStart, setSelectStart] = useState(-1);
290
+ const [selectEnd, setSelectEnd] = useState(-1);
291
+ const [isDragging, setIsDragging] = useState(false);
292
+ const [searchQuery, setSearchQuery] = useState("");
293
+ const [searchType, setSearchType] = useState("hex");
294
+ const [searchResults, setSearchResults] = useState([]);
295
+ const [currentSearchIdx, setCurrentSearchIdx] = useState(-1);
296
+ const [localBytesPerRow, setLocalBytesPerRow] = useState(bytesPerRow);
297
+ const [localGrouping, setLocalGrouping] = useState(byteGrouping);
298
+ const [localOffsetBase, setLocalOffsetBase] = useState(offsetBase);
299
+ const [localEndianness, setLocalEndianness] = useState(endianness);
300
+ const [localShowAscii, setLocalShowAscii] = useState(showAscii);
301
+ const [scrollTop, setScrollTop] = useState(0);
302
+ const [viewportHeight, setViewportHeight] = useState(160);
303
+ useEffect(() => {
304
+ if (streaming && scrollRef.current) {
305
+ scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
306
+ }
307
+ }, [data, streaming]);
308
+ useEffect(() => {
309
+ const el = scrollRef.current;
310
+ if (!el) return void 0;
311
+ const updateViewportHeight = () => {
312
+ setViewportHeight(Math.max(120, el.clientHeight || 160));
313
+ };
314
+ updateViewportHeight();
315
+ if (typeof ResizeObserver !== "undefined") {
316
+ const observer = new ResizeObserver(updateViewportHeight);
317
+ observer.observe(el);
318
+ return () => observer.disconnect();
319
+ }
320
+ window.addEventListener("resize", updateViewportHeight);
321
+ return () => window.removeEventListener("resize", updateViewportHeight);
322
+ }, []);
323
+ const totalRows = Math.max(1, Math.ceil(data.length / localBytesPerRow));
324
+ const startRow = Math.max(0, Math.floor(scrollTop / HEX_ROW_HEIGHT) - HEX_OVERSCAN_ROWS);
325
+ const visibleRowCount = Math.ceil(viewportHeight / HEX_ROW_HEIGHT) + HEX_OVERSCAN_ROWS * 2;
326
+ const endRow = Math.min(totalRows, startRow + visibleRowCount);
327
+ const virtualRows = useMemo(() => {
328
+ const result = [];
329
+ for (let row = startRow; row < endRow; row++) {
330
+ const offset = row * localBytesPerRow;
331
+ const bytes = data.subarray(offset, Math.min(data.length, offset + localBytesPerRow));
332
+ result.push({ offset, bytes });
333
+ }
334
+ if (result.length === 0) {
335
+ result.push({ offset: 0, bytes: new Uint8Array(0) });
336
+ }
337
+ return result;
338
+ }, [data, localBytesPerRow, startRow, endRow]);
339
+ const doSearch = useCallback(() => {
340
+ if (!searchQuery.trim()) {
341
+ setSearchResults([]);
342
+ setCurrentSearchIdx(-1);
343
+ return;
344
+ }
345
+ const results = [];
346
+ if (searchType === "hex") {
347
+ const hexStr = searchQuery.replace(/\s+/g, "");
348
+ if (hexStr.length % 2 !== 0 || !/^[0-9a-fA-F]+$/.test(hexStr)) return;
349
+ const searchBytes = new Uint8Array(hexStr.length / 2);
350
+ for (let i = 0; i < searchBytes.length; i++) {
351
+ searchBytes[i] = parseInt(hexStr.slice(i * 2, i * 2 + 2), 16);
352
+ }
353
+ for (let i = 0; i <= data.length - searchBytes.length; i++) {
354
+ let match = true;
355
+ for (let j = 0; j < searchBytes.length; j++) {
356
+ if (data[i + j] !== searchBytes[j]) {
357
+ match = false;
358
+ break;
359
+ }
360
+ }
361
+ if (match) results.push(i);
362
+ }
363
+ } else {
364
+ const encoder = new TextEncoder();
365
+ const searchBytes = encoder.encode(searchQuery);
366
+ for (let i = 0; i <= data.length - searchBytes.length; i++) {
367
+ let match = true;
368
+ for (let j = 0; j < searchBytes.length; j++) {
369
+ if (data[i + j] !== searchBytes[j]) {
370
+ match = false;
371
+ break;
372
+ }
373
+ }
374
+ if (match) results.push(i);
375
+ }
376
+ }
377
+ setSearchResults(results);
378
+ setCurrentSearchIdx(results.length > 0 ? 0 : -1);
379
+ if (results.length > 0) {
380
+ setCursorOffset(results[0]);
381
+ if (scrollRef.current) {
382
+ const rowIdx = Math.floor(results[0] / localBytesPerRow);
383
+ scrollRef.current.scrollTop = Math.max(0, rowIdx * HEX_ROW_HEIGHT - 100);
384
+ }
385
+ }
386
+ }, [searchQuery, searchType, data, localBytesPerRow]);
387
+ const scrollToOffset = useCallback((offset) => {
388
+ if (!scrollRef.current) return;
389
+ const rowIdx = Math.floor(offset / localBytesPerRow);
390
+ scrollRef.current.scrollTop = Math.max(0, rowIdx * HEX_ROW_HEIGHT - 100);
391
+ }, [localBytesPerRow]);
392
+ const handleHexScroll = useCallback((event) => {
393
+ setScrollTop(event.currentTarget.scrollTop);
394
+ }, []);
395
+ const nextSearchResult = useCallback(() => {
396
+ if (searchResults.length === 0) return;
397
+ const nextIdx = (currentSearchIdx + 1) % searchResults.length;
398
+ setCurrentSearchIdx(nextIdx);
399
+ setCursorOffset(searchResults[nextIdx]);
400
+ scrollToOffset(searchResults[nextIdx]);
401
+ }, [searchResults, currentSearchIdx, scrollToOffset]);
402
+ const prevSearchResult = useCallback(() => {
403
+ if (searchResults.length === 0) return;
404
+ const prevIdx = (currentSearchIdx - 1 + searchResults.length) % searchResults.length;
405
+ setCurrentSearchIdx(prevIdx);
406
+ setCursorOffset(searchResults[prevIdx]);
407
+ scrollToOffset(searchResults[prevIdx]);
408
+ }, [searchResults, currentSearchIdx, scrollToOffset]);
409
+ const handleByteMouseDown = useCallback((idx) => {
410
+ setSelectStart(idx);
411
+ setSelectEnd(idx);
412
+ setCursorOffset(idx);
413
+ setIsDragging(true);
414
+ }, []);
415
+ const handleByteMouseEnter = useCallback((idx) => {
416
+ if (isDragging) {
417
+ setSelectEnd(idx);
418
+ }
419
+ }, [isDragging]);
420
+ const handleMouseUp = useCallback(() => {
421
+ if (isDragging) {
422
+ setIsDragging(false);
423
+ if (onSelectionChange && selectStart >= 0 && selectEnd >= 0) {
424
+ onSelectionChange(Math.min(selectStart, selectEnd), Math.max(selectStart, selectEnd));
425
+ }
426
+ }
427
+ }, [isDragging, selectStart, selectEnd, onSelectionChange]);
428
+ useEffect(() => {
429
+ window.addEventListener("mouseup", handleMouseUp);
430
+ return () => window.removeEventListener("mouseup", handleMouseUp);
431
+ }, [handleMouseUp]);
432
+ const handleByteClickCb = useCallback((idx) => {
433
+ setCursorOffset(idx);
434
+ if (onByteClick) {
435
+ onByteClick(idx, data[idx]);
436
+ }
437
+ }, [data, onByteClick]);
438
+ const copySelection = useCallback((format) => {
439
+ var _a;
440
+ if (selectStart < 0 || selectEnd < 0) return;
441
+ const start = Math.min(selectStart, selectEnd);
442
+ const end = Math.max(selectStart, selectEnd);
443
+ const selected = data.slice(start, end + 1);
444
+ let text;
445
+ if (format === "hex") {
446
+ text = Array.from(selected).map((b) => byteToHex(b)).join(" ");
447
+ } else if (format === "decimal") {
448
+ text = Array.from(selected).join(", ");
449
+ } else {
450
+ text = Array.from(selected).map((b) => byteToAscii(b)).join("");
451
+ }
452
+ (_a = navigator.clipboard) == null ? void 0 : _a.writeText(text);
453
+ }, [data, selectStart, selectEnd]);
454
+ const interpretation = useMemo(() => {
455
+ if (cursorOffset < 0 || cursorOffset >= data.length) return null;
456
+ return interpretBytes(data, cursorOffset, localEndianness);
457
+ }, [data, cursorOffset, localEndianness]);
458
+ const renderedSearchResultEntries = useMemo(() => {
459
+ if (searchResults.length <= MAX_RENDERED_SEARCH_HIGHLIGHTS) {
460
+ return searchResults.map((pos, idx) => ({ pos, idx }));
461
+ }
462
+ const halfWindow = Math.floor(MAX_RENDERED_SEARCH_HIGHLIGHTS / 2);
463
+ const anchor = currentSearchIdx >= 0 ? currentSearchIdx : 0;
464
+ const start = Math.max(0, anchor - halfWindow);
465
+ const end = Math.min(searchResults.length, start + MAX_RENDERED_SEARCH_HIGHLIGHTS);
466
+ const adjustedStart = Math.max(0, end - MAX_RENDERED_SEARCH_HIGHLIGHTS);
467
+ return searchResults.slice(adjustedStart, end).map((pos, i) => ({ pos, idx: adjustedStart + i }));
468
+ }, [searchResults, currentSearchIdx]);
469
+ const allHighlights = useMemo(() => {
470
+ const h = [...highlights];
471
+ const searchLen = searchType === "hex" ? searchQuery.replace(/\s+/g, "").length / 2 : searchQuery.length;
472
+ renderedSearchResultEntries.forEach(({ pos, idx }) => {
473
+ h.push({
474
+ start: pos,
475
+ end: pos + Math.max(0, searchLen - 1),
476
+ color: idx === currentSearchIdx ? tokens.colors.status.serious : tokens.colors.status.caution,
477
+ label: `Search match ${idx + 1}`
478
+ });
479
+ });
480
+ return h;
481
+ }, [highlights, renderedSearchResultEntries, currentSearchIdx, searchQuery, searchType, tokens]);
482
+ const containerStyle = {
483
+ fontFamily: tokens.typography.fontFamily.mono,
484
+ fontSize: 13,
485
+ lineHeight: "22px",
486
+ background: tokens.colors.background.base,
487
+ border: bordered ? `1px solid ${tokens.colors.border.muted}` : "none",
488
+ borderRadius: tokens.borderRadius.lg,
489
+ overflowX: "hidden",
490
+ overflowY: hasConstrainedHeight ? "auto" : "visible",
491
+ display: "flex",
492
+ flexDirection: "column",
493
+ minHeight: 0,
494
+ height: hasConstrainedHeight ? height : void 0,
495
+ color: tokens.colors.text.primary,
496
+ ...styleProp
497
+ };
498
+ return /* @__PURE__ */ jsxs(
499
+ "div",
500
+ {
501
+ className: `hex-viewer ${className}`,
502
+ style: containerStyle,
503
+ children: [
504
+ /* @__PURE__ */ jsxs("div", { style: {
505
+ position: "sticky",
506
+ top: 0,
507
+ zIndex: 10,
508
+ background: tokens.colors.background.surface,
509
+ flexShrink: 0
510
+ }, children: [
511
+ title && /* @__PURE__ */ jsxs("div", { style: {
512
+ padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
513
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
514
+ display: "flex",
515
+ alignItems: "center",
516
+ justifyContent: "space-between"
517
+ }, children: [
518
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: tokens.typography.fontWeight.medium, fontSize: tokens.typography.fontSize.base, fontFamily: tokens.typography.fontFamily.primary }, children: title }),
519
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: tokens.typography.fontSize.sm, color: tokens.colors.text.muted }, children: [
520
+ data.length.toLocaleString(),
521
+ " bytes"
522
+ ] })
523
+ ] }),
524
+ showToolbar && /* @__PURE__ */ jsxs("div", { role: "toolbar", "aria-label": "Hex viewer controls", style: {
525
+ padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
526
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
527
+ display: "flex",
528
+ alignItems: "center",
529
+ gap: tokens.spacing.sm,
530
+ flexWrap: "wrap",
531
+ fontSize: tokens.typography.fontSize.sm
532
+ }, children: [
533
+ /* @__PURE__ */ jsxs("label", { style: { display: "flex", alignItems: "center", gap: 4, color: tokens.colors.text.muted }, children: [
534
+ "Bytes/Row:",
535
+ /* @__PURE__ */ jsxs(
536
+ "select",
537
+ {
538
+ "aria-label": "Bytes per row",
539
+ value: localBytesPerRow,
540
+ onChange: (e) => setLocalBytesPerRow(Number(e.target.value)),
541
+ style: {
542
+ background: tokens.colors.background.base,
543
+ color: tokens.colors.text.primary,
544
+ border: `1px solid ${tokens.colors.border.muted}`,
545
+ borderRadius: tokens.borderRadius.md,
546
+ padding: "2px 4px",
547
+ fontSize: 11
548
+ },
549
+ children: [
550
+ /* @__PURE__ */ jsx("option", { value: 8, children: "8" }),
551
+ /* @__PURE__ */ jsx("option", { value: 16, children: "16" }),
552
+ /* @__PURE__ */ jsx("option", { value: 32, children: "32" })
553
+ ]
554
+ }
555
+ )
556
+ ] }),
557
+ /* @__PURE__ */ jsxs("label", { style: { display: "flex", alignItems: "center", gap: 4, color: tokens.colors.text.muted }, children: [
558
+ "Group:",
559
+ /* @__PURE__ */ jsxs(
560
+ "select",
561
+ {
562
+ "aria-label": "Byte grouping",
563
+ value: localGrouping,
564
+ onChange: (e) => setLocalGrouping(Number(e.target.value)),
565
+ style: {
566
+ background: tokens.colors.background.base,
567
+ color: tokens.colors.text.primary,
568
+ border: `1px solid ${tokens.colors.border.muted}`,
569
+ borderRadius: tokens.borderRadius.md,
570
+ padding: "2px 4px",
571
+ fontSize: 11
572
+ },
573
+ children: [
574
+ /* @__PURE__ */ jsx("option", { value: 1, children: "1" }),
575
+ /* @__PURE__ */ jsx("option", { value: 2, children: "2" }),
576
+ /* @__PURE__ */ jsx("option", { value: 4, children: "4" }),
577
+ /* @__PURE__ */ jsx("option", { value: 8, children: "8" })
578
+ ]
579
+ }
580
+ )
581
+ ] }),
582
+ /* @__PURE__ */ jsxs("label", { style: { display: "flex", alignItems: "center", gap: 4, color: tokens.colors.text.muted }, children: [
583
+ "Offset:",
584
+ /* @__PURE__ */ jsxs(
585
+ "select",
586
+ {
587
+ "aria-label": "Offset format",
588
+ value: localOffsetBase,
589
+ onChange: (e) => setLocalOffsetBase(e.target.value),
590
+ style: {
591
+ background: tokens.colors.background.base,
592
+ color: tokens.colors.text.primary,
593
+ border: `1px solid ${tokens.colors.border.muted}`,
594
+ borderRadius: tokens.borderRadius.md,
595
+ padding: "2px 4px",
596
+ fontSize: 11
597
+ },
598
+ children: [
599
+ /* @__PURE__ */ jsx("option", { value: "hex", children: "Hex" }),
600
+ /* @__PURE__ */ jsx("option", { value: "decimal", children: "Dec" })
601
+ ]
602
+ }
603
+ )
604
+ ] }),
605
+ /* @__PURE__ */ jsxs("label", { style: { display: "flex", alignItems: "center", gap: 4, color: tokens.colors.text.muted }, children: [
606
+ "Endian:",
607
+ /* @__PURE__ */ jsxs(
608
+ "select",
609
+ {
610
+ "aria-label": "Endianness",
611
+ value: localEndianness,
612
+ onChange: (e) => setLocalEndianness(e.target.value),
613
+ style: {
614
+ background: tokens.colors.background.base,
615
+ color: tokens.colors.text.primary,
616
+ border: `1px solid ${tokens.colors.border.muted}`,
617
+ borderRadius: tokens.borderRadius.md,
618
+ padding: "2px 4px",
619
+ fontSize: 11
620
+ },
621
+ children: [
622
+ /* @__PURE__ */ jsx("option", { value: "big", children: "Big" }),
623
+ /* @__PURE__ */ jsx("option", { value: "little", children: "Little" })
624
+ ]
625
+ }
626
+ )
627
+ ] }),
628
+ /* @__PURE__ */ jsxs("label", { style: { display: "flex", alignItems: "center", gap: 4, color: tokens.colors.text.muted, cursor: "pointer" }, children: [
629
+ /* @__PURE__ */ jsx(
630
+ "input",
631
+ {
632
+ type: "checkbox",
633
+ checked: localShowAscii,
634
+ onChange: (e) => setLocalShowAscii(e.target.checked),
635
+ style: { accentColor: tokens.colors.interactive.default }
636
+ }
637
+ ),
638
+ "ASCII"
639
+ ] }),
640
+ /* @__PURE__ */ jsx("div", { style: { flex: 1 } }),
641
+ selectStart >= 0 && selectEnd >= 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 4 }, children: ["hex", "decimal", "ascii"].map((fmt) => /* @__PURE__ */ jsxs(
642
+ "button",
643
+ {
644
+ onClick: () => copySelection(fmt),
645
+ style: {
646
+ background: tokens.colors.background.base,
647
+ color: tokens.colors.text.secondary,
648
+ border: `1px solid ${tokens.colors.border.muted}`,
649
+ borderRadius: tokens.borderRadius.md,
650
+ padding: "2px 8px",
651
+ fontSize: 10,
652
+ cursor: "pointer"
653
+ },
654
+ children: [
655
+ "Copy ",
656
+ fmt
657
+ ]
658
+ },
659
+ fmt
660
+ )) })
661
+ ] }),
662
+ showSearch && /* @__PURE__ */ jsxs("div", { role: "search", style: {
663
+ padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
664
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
665
+ display: "flex",
666
+ alignItems: "center",
667
+ gap: tokens.spacing.sm
668
+ }, children: [
669
+ /* @__PURE__ */ jsx(
670
+ "label",
671
+ {
672
+ htmlFor: "hex-search-type",
673
+ style: { position: "absolute", width: 1, height: 1, padding: 0, margin: -1, overflow: "hidden", clip: "rect(0, 0, 0, 0)", border: 0 },
674
+ children: "Search type"
675
+ }
676
+ ),
677
+ /* @__PURE__ */ jsxs(
678
+ "select",
679
+ {
680
+ id: "hex-search-type",
681
+ value: searchType,
682
+ onChange: (e) => setSearchType(e.target.value),
683
+ style: {
684
+ background: tokens.colors.background.base,
685
+ color: tokens.colors.text.primary,
686
+ border: `1px solid ${tokens.colors.border.muted}`,
687
+ borderRadius: tokens.borderRadius.md,
688
+ padding: `${tokens.spacing.xs} ${tokens.spacing.sm}`,
689
+ fontSize: tokens.typography.fontSize.sm
690
+ },
691
+ children: [
692
+ /* @__PURE__ */ jsx("option", { value: "hex", children: "Hex" }),
693
+ /* @__PURE__ */ jsx("option", { value: "ascii", children: "ASCII" })
694
+ ]
695
+ }
696
+ ),
697
+ /* @__PURE__ */ jsx(
698
+ "input",
699
+ {
700
+ type: "text",
701
+ value: searchQuery,
702
+ onChange: (e) => setSearchQuery(e.target.value),
703
+ onKeyDown: (e) => {
704
+ if (e.key === "Enter") doSearch();
705
+ },
706
+ placeholder: searchType === "hex" ? "e.g. 48 65 6C 6C 6F" : "Search ASCII...",
707
+ "aria-label": "Search hex data",
708
+ style: {
709
+ flex: 1,
710
+ background: tokens.colors.background.base,
711
+ color: tokens.colors.text.primary,
712
+ border: `1px solid ${tokens.colors.border.muted}`,
713
+ borderRadius: tokens.borderRadius.md,
714
+ padding: `${tokens.spacing.xs} ${tokens.spacing.sm}`,
715
+ fontSize: tokens.typography.fontSize.sm,
716
+ outline: "none",
717
+ fontFamily: "inherit"
718
+ }
719
+ }
720
+ ),
721
+ /* @__PURE__ */ jsx("button", { onClick: doSearch, "aria-label": "Find matches", style: {
722
+ background: tokens.colors.interactive.default,
723
+ color: tokens.colors.text.inverse,
724
+ border: "none",
725
+ borderRadius: tokens.borderRadius.md,
726
+ padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`,
727
+ fontSize: tokens.typography.fontSize.sm,
728
+ cursor: "pointer",
729
+ fontWeight: tokens.typography.fontWeight.medium
730
+ }, children: "Find" }),
731
+ searchResults.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
732
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: tokens.typography.fontSize.sm, color: tokens.colors.text.muted }, "aria-live": "polite", children: [
733
+ currentSearchIdx + 1,
734
+ "/",
735
+ searchResults.length
736
+ ] }),
737
+ /* @__PURE__ */ jsx("button", { onClick: prevSearchResult, "aria-label": "Previous match", style: { background: "none", border: "none", color: tokens.colors.text.secondary, cursor: "pointer", fontSize: tokens.typography.fontSize.base, padding: tokens.spacing.xs }, children: "▲" }),
738
+ /* @__PURE__ */ jsx("button", { onClick: nextSearchResult, "aria-label": "Next match", style: { background: "none", border: "none", color: tokens.colors.text.secondary, cursor: "pointer", fontSize: tokens.typography.fontSize.base, padding: tokens.spacing.xs }, children: "▼" })
739
+ ] })
740
+ ] })
741
+ ] }),
742
+ shouldShowHeaderSummary && packetHeaders && packetHeaders.length > 0 && /* @__PURE__ */ jsxs("div", { style: { flexShrink: 0 }, children: [
743
+ /* @__PURE__ */ jsxs(
744
+ "div",
745
+ {
746
+ role: "button",
747
+ tabIndex: 0,
748
+ "aria-expanded": showHeaders,
749
+ "aria-label": "Toggle packet headers",
750
+ onClick: () => setShowHeaders(!showHeaders),
751
+ onKeyDown: (e) => {
752
+ if (e.key === "Enter" || e.key === " ") {
753
+ e.preventDefault();
754
+ setShowHeaders(!showHeaders);
755
+ }
756
+ },
757
+ style: {
758
+ display: "flex",
759
+ alignItems: "center",
760
+ gap: tokens.spacing.sm,
761
+ padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
762
+ background: tokens.colors.background.surface,
763
+ cursor: "pointer",
764
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
765
+ userSelect: "none"
766
+ },
767
+ children: [
768
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { fontSize: tokens.typography.fontSize.micro, color: tokens.colors.text.muted, transition: "transform 150ms ease", transform: showHeaders ? "rotate(0deg)" : "rotate(-90deg)" }, children: "▼" }),
769
+ /* @__PURE__ */ jsx("span", { style: { fontSize: tokens.typography.fontSize.sm, color: tokens.colors.text.secondary, fontWeight: tokens.typography.fontWeight.medium }, children: "Packet Headers" })
770
+ ]
771
+ }
772
+ ),
773
+ showHeaders && /* @__PURE__ */ jsx("div", { style: {
774
+ padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
775
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
776
+ background: tokens.colors.background.base
777
+ }, children: /* @__PURE__ */ jsx("div", { style: {
778
+ display: "grid",
779
+ gridTemplateColumns: "auto 1fr",
780
+ gap: `${tokens.spacing.xxs} ${tokens.spacing.md}`,
781
+ fontSize: tokens.typography.fontSize.sm,
782
+ lineHeight: tokens.typography.lineHeight.tight
783
+ }, children: packetHeaders.map((entry, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
784
+ /* @__PURE__ */ jsx("span", { style: { color: tokens.colors.text.muted }, children: entry.label }),
785
+ /* @__PURE__ */ jsx("span", { style: {
786
+ color: tokens.colors.text.primary,
787
+ fontWeight: tokens.typography.fontWeight.medium,
788
+ fontFamily: entry.mono ? tokens.typography.fontFamily.mono : "inherit"
789
+ }, children: entry.value })
790
+ ] }, i)) }) })
791
+ ] }),
792
+ shouldShowFieldsTable && decodedFields && decodedFields.length > 0 && /* @__PURE__ */ jsxs("div", { style: { flexShrink: 0 }, children: [
793
+ /* @__PURE__ */ jsxs(
794
+ "div",
795
+ {
796
+ role: "button",
797
+ tabIndex: 0,
798
+ "aria-expanded": showFields,
799
+ "aria-label": "Toggle decoded fields",
800
+ onClick: () => setShowFields(!showFields),
801
+ onKeyDown: (e) => {
802
+ if (e.key === "Enter" || e.key === " ") {
803
+ e.preventDefault();
804
+ setShowFields(!showFields);
805
+ }
806
+ },
807
+ style: {
808
+ display: "flex",
809
+ alignItems: "center",
810
+ gap: tokens.spacing.sm,
811
+ padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
812
+ background: tokens.colors.background.surface,
813
+ cursor: "pointer",
814
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
815
+ userSelect: "none"
816
+ },
817
+ children: [
818
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { fontSize: tokens.typography.fontSize.micro, color: tokens.colors.text.muted, transition: "transform 150ms ease", transform: showFields ? "rotate(0deg)" : "rotate(-90deg)" }, children: "▼" }),
819
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: tokens.typography.fontSize.sm, color: tokens.colors.text.secondary, fontWeight: tokens.typography.fontWeight.medium }, children: [
820
+ "Decoded Fields (",
821
+ decodedFields.length,
822
+ ")"
823
+ ] })
824
+ ]
825
+ }
826
+ ),
827
+ showFields && /* @__PURE__ */ jsxs(
828
+ "div",
829
+ {
830
+ role: "table",
831
+ "aria-label": "Decoded packet fields",
832
+ style: {
833
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
834
+ maxHeight: decodedFieldsMaxHeight,
835
+ overflowY: "auto"
836
+ },
837
+ children: [
838
+ /* @__PURE__ */ jsxs("div", { role: "row", style: {
839
+ display: "flex",
840
+ alignItems: "center",
841
+ padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`,
842
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
843
+ gap: tokens.spacing.sm,
844
+ position: "sticky",
845
+ top: 0,
846
+ background: tokens.colors.background.surface,
847
+ zIndex: 1
848
+ }, children: [
849
+ /* @__PURE__ */ jsx("span", { role: "columnheader", style: { flex: 2, fontSize: tokens.typography.fontSize.xxs, color: tokens.colors.text.muted, textTransform: "uppercase", letterSpacing: "0.5px" }, children: "Field" }),
850
+ /* @__PURE__ */ jsx("span", { role: "columnheader", style: { flex: 2, fontSize: tokens.typography.fontSize.xxs, color: tokens.colors.text.muted, textTransform: "uppercase", letterSpacing: "0.5px", textAlign: "right" }, children: "Value" }),
851
+ /* @__PURE__ */ jsx("span", { role: "columnheader", style: { flex: 1, fontSize: tokens.typography.fontSize.xxs, color: tokens.colors.text.muted, textTransform: "uppercase", letterSpacing: "0.5px", textAlign: "right" }, children: "Unit" }),
852
+ /* @__PURE__ */ jsx("span", { role: "columnheader", style: { flex: 1, fontSize: tokens.typography.fontSize.xxs, color: tokens.colors.text.muted, textTransform: "uppercase", letterSpacing: "0.5px", textAlign: "right" }, children: "Offset" }),
853
+ /* @__PURE__ */ jsx("span", { role: "columnheader", style: { flex: 1, fontSize: tokens.typography.fontSize.xxs, color: tokens.colors.text.muted, textTransform: "uppercase", letterSpacing: "0.5px", textAlign: "right" }, children: "Size" })
854
+ ] }),
855
+ decodedFields.map((field, fi) => {
856
+ const isHovered = hoveredFieldIdx === fi;
857
+ return /* @__PURE__ */ jsxs(
858
+ "div",
859
+ {
860
+ onMouseEnter: () => handleFieldHover(fi),
861
+ onMouseLeave: handleFieldLeave,
862
+ title: field.description,
863
+ style: {
864
+ display: "flex",
865
+ alignItems: "center",
866
+ padding: `3px ${tokens.spacing.smd}`,
867
+ gap: tokens.spacing.sm,
868
+ background: isHovered ? `${tokens.colors.status.caution}14` : fi % 2 === 0 ? tokens.colors.background.base : "transparent",
869
+ transition: "background 0.15s ease",
870
+ cursor: "default",
871
+ minHeight: tokens.elementSize.sm
872
+ },
873
+ children: [
874
+ /* @__PURE__ */ jsx("span", { role: "cell", style: {
875
+ flex: 2,
876
+ fontSize: tokens.typography.fontSize.sm,
877
+ color: tokens.colors.text.secondary,
878
+ overflow: "hidden",
879
+ textOverflow: "ellipsis",
880
+ whiteSpace: "nowrap"
881
+ }, children: field.name }),
882
+ /* @__PURE__ */ jsx("span", { role: "cell", style: {
883
+ flex: 2,
884
+ fontSize: tokens.typography.fontSize.sm,
885
+ color: tokens.colors.text.primary,
886
+ fontWeight: tokens.typography.fontWeight.medium,
887
+ fontFamily: tokens.typography.fontFamily.mono,
888
+ textAlign: "right"
889
+ }, children: field.value === null || field.value === void 0 ? "—" : String(field.value) }),
890
+ /* @__PURE__ */ jsx("span", { role: "cell", style: {
891
+ flex: 1,
892
+ fontSize: tokens.typography.fontSize.xxs,
893
+ color: tokens.colors.text.muted,
894
+ textAlign: "right"
895
+ }, children: field.unit || "" }),
896
+ /* @__PURE__ */ jsx("span", { role: "cell", style: {
897
+ flex: 1,
898
+ fontSize: tokens.typography.fontSize.xxs,
899
+ color: tokens.colors.text.muted,
900
+ textAlign: "right",
901
+ fontFamily: tokens.typography.fontFamily.mono
902
+ }, children: field.byteOffset !== void 0 ? field.byteOffset : "" }),
903
+ /* @__PURE__ */ jsx("span", { role: "cell", style: {
904
+ flex: 1,
905
+ fontSize: tokens.typography.fontSize.xxs,
906
+ color: tokens.colors.text.muted,
907
+ textAlign: "right",
908
+ fontFamily: tokens.typography.fontFamily.mono
909
+ }, children: field.sizeBits ? `${field.sizeBits}b` : "" })
910
+ ]
911
+ },
912
+ fi
913
+ );
914
+ })
915
+ ]
916
+ }
917
+ )
918
+ ] }),
919
+ regions.length > 0 && /* @__PURE__ */ jsx(
920
+ "div",
921
+ {
922
+ role: "group",
923
+ "aria-label": "Packet structure regions",
924
+ style: {
925
+ padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`,
926
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
927
+ display: "flex",
928
+ alignItems: "center",
929
+ gap: tokens.spacing.smd,
930
+ flexWrap: "wrap",
931
+ fontSize: tokens.typography.fontSize.xxs,
932
+ background: tokens.colors.background.surface
933
+ },
934
+ children: regions.map((r, i) => /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: tokens.spacing.xs }, children: [
935
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: {
936
+ display: "inline-block",
937
+ width: 10,
938
+ height: 10,
939
+ borderRadius: tokens.borderRadius.sm,
940
+ background: r.color,
941
+ border: `1px solid ${r.borderColor || "transparent"}`
942
+ } }),
943
+ /* @__PURE__ */ jsxs("span", { style: { color: tokens.colors.text.muted }, children: [
944
+ r.label,
945
+ " (",
946
+ r.end - r.start,
947
+ "B)"
948
+ ] })
949
+ ] }, i))
950
+ }
951
+ ),
952
+ /* @__PURE__ */ jsxs("div", { role: "row", "aria-label": "Column headers", style: {
953
+ padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`,
954
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
955
+ display: "flex",
956
+ alignItems: "center",
957
+ fontSize: tokens.typography.fontSize.xxs,
958
+ color: tokens.colors.text.muted,
959
+ textTransform: "uppercase",
960
+ letterSpacing: "0.5px",
961
+ fontWeight: tokens.typography.fontWeight.medium,
962
+ background: tokens.colors.background.surface
963
+ }, children: [
964
+ showOffset && /* @__PURE__ */ jsx("span", { style: { marginRight: tokens.spacing.smd, minWidth: 60, textAlign: "right" }, children: "Offset" }),
965
+ /* @__PURE__ */ jsx("span", { style: { flex: 1 }, children: "Hex" }),
966
+ localShowAscii && /* @__PURE__ */ jsxs(Fragment, { children: [
967
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { color: `${tokens.colors.border.muted}`, marginRight: tokens.spacing.sm }, children: "|" }),
968
+ /* @__PURE__ */ jsx("span", { children: "ASCII" })
969
+ ] })
970
+ ] }),
971
+ /* @__PURE__ */ jsx(
972
+ "div",
973
+ {
974
+ ref: scrollRef,
975
+ role: "grid",
976
+ "aria-label": "Hex data",
977
+ tabIndex: 0,
978
+ onScroll: handleHexScroll,
979
+ style: {
980
+ flex: "1 1 160px",
981
+ minHeight: 160,
982
+ overflow: "auto",
983
+ padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`
984
+ },
985
+ children: /* @__PURE__ */ jsx("div", { style: { height: totalRows * HEX_ROW_HEIGHT, position: "relative" }, children: /* @__PURE__ */ jsx("div", { style: { position: "absolute", top: startRow * HEX_ROW_HEIGHT, left: 0, right: 0 }, children: virtualRows.map((row) => /* @__PURE__ */ jsx(
986
+ HexRow,
987
+ {
988
+ offset: row.offset,
989
+ bytes: row.bytes,
990
+ bytesPerRow: localBytesPerRow,
991
+ byteGrouping: localGrouping,
992
+ offsetBase: localOffsetBase,
993
+ totalBytes: data.length,
994
+ showAscii: localShowAscii,
995
+ showOffset,
996
+ highlights: allHighlights,
997
+ regions: sortedRegions,
998
+ effectiveHighlight,
999
+ selectedStart: selectStart,
1000
+ selectedEnd: selectEnd,
1001
+ cursorOffset,
1002
+ onByteMouseDown: handleByteMouseDown,
1003
+ onByteMouseEnter: handleByteMouseEnter,
1004
+ onByteClick: handleByteClickCb,
1005
+ handleByteHoverInternal,
1006
+ handleByteLeaveInternal,
1007
+ tokens
1008
+ },
1009
+ row.offset
1010
+ )) }) })
1011
+ }
1012
+ ),
1013
+ highlights.length > 0 && /* @__PURE__ */ jsx("div", { role: "group", "aria-label": "Search highlights", style: {
1014
+ padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`,
1015
+ borderTop: `1px solid ${tokens.colors.border.muted}`,
1016
+ display: "flex",
1017
+ alignItems: "center",
1018
+ gap: tokens.spacing.smd,
1019
+ flexWrap: "wrap",
1020
+ fontSize: tokens.typography.fontSize.xxs,
1021
+ background: tokens.colors.background.surface
1022
+ }, children: highlights.filter((h) => h.label).map((h, i) => /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.xs }, children: [
1023
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { width: 10, height: 10, borderRadius: tokens.borderRadius.sm, background: h.color, display: "inline-block" } }),
1024
+ /* @__PURE__ */ jsxs("span", { style: { color: tokens.colors.text.muted }, children: [
1025
+ h.label,
1026
+ " (0x",
1027
+ h.start.toString(16),
1028
+ "-0x",
1029
+ h.end.toString(16),
1030
+ ")"
1031
+ ] })
1032
+ ] }, i)) }),
1033
+ showStatusBar && /* @__PURE__ */ jsxs("div", { role: "status", "aria-live": "polite", style: {
1034
+ padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
1035
+ borderTop: `1px solid ${tokens.colors.border.muted}`,
1036
+ display: "flex",
1037
+ alignItems: "center",
1038
+ gap: tokens.spacing.md,
1039
+ fontSize: tokens.typography.fontSize.sm,
1040
+ background: tokens.colors.background.surface,
1041
+ color: tokens.colors.text.muted,
1042
+ flexWrap: "wrap"
1043
+ }, children: [
1044
+ /* @__PURE__ */ jsxs("span", { children: [
1045
+ "Size: ",
1046
+ data.length.toLocaleString(),
1047
+ " bytes"
1048
+ ] }),
1049
+ cursorOffset >= 0 && cursorOffset < data.length && /* @__PURE__ */ jsxs(Fragment, { children: [
1050
+ /* @__PURE__ */ jsxs("span", { children: [
1051
+ "Offset: 0x",
1052
+ cursorOffset.toString(16).toUpperCase(),
1053
+ " (",
1054
+ cursorOffset,
1055
+ ")"
1056
+ ] }),
1057
+ /* @__PURE__ */ jsxs("span", { children: [
1058
+ "Value: 0x",
1059
+ byteToHex(data[cursorOffset]),
1060
+ " (",
1061
+ data[cursorOffset],
1062
+ ")"
1063
+ ] })
1064
+ ] }),
1065
+ selectStart >= 0 && selectEnd >= 0 && selectStart !== selectEnd && /* @__PURE__ */ jsxs("span", { children: [
1066
+ "Selection: ",
1067
+ Math.abs(selectEnd - selectStart) + 1,
1068
+ " bytes (0x",
1069
+ Math.min(selectStart, selectEnd).toString(16).toUpperCase(),
1070
+ "-0x",
1071
+ Math.max(selectStart, selectEnd).toString(16).toUpperCase(),
1072
+ ")"
1073
+ ] }),
1074
+ interpretation && /* @__PURE__ */ jsxs("span", { style: { display: "flex", gap: tokens.spacing.sm, color: tokens.colors.text.secondary }, children: [
1075
+ /* @__PURE__ */ jsxs("span", { children: [
1076
+ "U8: ",
1077
+ interpretation.u8
1078
+ ] }),
1079
+ /* @__PURE__ */ jsxs("span", { children: [
1080
+ "I8: ",
1081
+ interpretation.i8
1082
+ ] }),
1083
+ interpretation.u16 !== void 0 && /* @__PURE__ */ jsxs("span", { children: [
1084
+ "U16: ",
1085
+ interpretation.u16
1086
+ ] }),
1087
+ interpretation.u32 !== void 0 && /* @__PURE__ */ jsxs("span", { children: [
1088
+ "U32: ",
1089
+ interpretation.u32
1090
+ ] }),
1091
+ interpretation.f32 !== void 0 && /* @__PURE__ */ jsxs("span", { children: [
1092
+ "F32: ",
1093
+ interpretation.f32.toFixed(6)
1094
+ ] })
1095
+ ] })
1096
+ ] })
1097
+ ]
1098
+ }
1099
+ );
1100
+ }
1101
+ export {
1102
+ HexViewer,
1103
+ REGION_BORDER_COLORS,
1104
+ REGION_COLORS
1105
+ };
1106
+ //# sourceMappingURL=HexViewer.js.map