@almadar/shell-web 0.0.0-stage → 1.0.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 (266) hide show
  1. package/bundling.d.mts +18 -0
  2. package/bundling.mjs +28 -0
  3. package/dist/ArbitraryClassCompiler-CO_iASBn.d.ts +195 -0
  4. package/dist/AvlGlyph-EPJKFEO3.js +6 -0
  5. package/dist/AvlStateMachine-RKZIKNGC.js +9 -0
  6. package/dist/AvlTransitionDetail-63SD6GZF.js +11 -0
  7. package/dist/AvlTransitionExplainer-ZBTLOM3T.js +12 -0
  8. package/dist/BehaviorView-YS5G4GNB.js +11 -0
  9. package/dist/Canvas3DHost-BkZQB5l2.d.ts +552 -0
  10. package/dist/EventBusProvider-BFFHfN4O.d.ts +296 -0
  11. package/dist/FileTree-BCFnBEuQ.d.ts +254 -0
  12. package/dist/FlowCanvas-3JRMNJLV.css +1756 -0
  13. package/dist/FlowCanvas-AUMTWMNG.js +26 -0
  14. package/dist/GameAudioProvider-ceM_n0ey.d.ts +90 -0
  15. package/dist/KaTeX_AMS-Regular-CYEKBG2K.woff +0 -0
  16. package/dist/KaTeX_AMS-Regular-JKX5W2C4.ttf +0 -0
  17. package/dist/KaTeX_AMS-Regular-U6PRYMIZ.woff2 +0 -0
  18. package/dist/KaTeX_Caligraphic-Bold-5QL5CMTE.woff2 +0 -0
  19. package/dist/KaTeX_Caligraphic-Bold-WZ3QSGD3.woff +0 -0
  20. package/dist/KaTeX_Caligraphic-Bold-ZTS3R3HK.ttf +0 -0
  21. package/dist/KaTeX_Caligraphic-Regular-3LKEU76G.woff +0 -0
  22. package/dist/KaTeX_Caligraphic-Regular-A7XRTZ5Q.ttf +0 -0
  23. package/dist/KaTeX_Caligraphic-Regular-KX5MEWCF.woff2 +0 -0
  24. package/dist/KaTeX_Fraktur-Bold-2QVFK6NQ.woff2 +0 -0
  25. package/dist/KaTeX_Fraktur-Bold-T4SWXBMT.woff +0 -0
  26. package/dist/KaTeX_Fraktur-Bold-WGHVTYOR.ttf +0 -0
  27. package/dist/KaTeX_Fraktur-Regular-2PEIFJSJ.woff2 +0 -0
  28. package/dist/KaTeX_Fraktur-Regular-5U4OPH2X.ttf +0 -0
  29. package/dist/KaTeX_Fraktur-Regular-PQMHCIK6.woff +0 -0
  30. package/dist/KaTeX_Main-Bold-2GA4IZIN.woff +0 -0
  31. package/dist/KaTeX_Main-Bold-W5FBVCZM.ttf +0 -0
  32. package/dist/KaTeX_Main-Bold-YP5VVQRP.woff2 +0 -0
  33. package/dist/KaTeX_Main-BoldItalic-4P4C7HJH.woff +0 -0
  34. package/dist/KaTeX_Main-BoldItalic-N4V3DX7S.woff2 +0 -0
  35. package/dist/KaTeX_Main-BoldItalic-ODMLBJJQ.ttf +0 -0
  36. package/dist/KaTeX_Main-Italic-I43T2HSR.ttf +0 -0
  37. package/dist/KaTeX_Main-Italic-RELBIK7M.woff2 +0 -0
  38. package/dist/KaTeX_Main-Italic-SASNQFN2.woff +0 -0
  39. package/dist/KaTeX_Main-Regular-ARRPAO67.woff2 +0 -0
  40. package/dist/KaTeX_Main-Regular-P5I74A2A.woff +0 -0
  41. package/dist/KaTeX_Main-Regular-W74P5G27.ttf +0 -0
  42. package/dist/KaTeX_Math-BoldItalic-6EBV3DK5.woff +0 -0
  43. package/dist/KaTeX_Math-BoldItalic-K4WTGH3J.woff2 +0 -0
  44. package/dist/KaTeX_Math-BoldItalic-VB447A4D.ttf +0 -0
  45. package/dist/KaTeX_Math-Italic-6KGCHLFN.woff2 +0 -0
  46. package/dist/KaTeX_Math-Italic-KKK3USB2.woff +0 -0
  47. package/dist/KaTeX_Math-Italic-SON4MRCA.ttf +0 -0
  48. package/dist/KaTeX_SansSerif-Bold-RRNVJFFW.woff2 +0 -0
  49. package/dist/KaTeX_SansSerif-Bold-STQ6RXC7.ttf +0 -0
  50. package/dist/KaTeX_SansSerif-Bold-X5M5EMOD.woff +0 -0
  51. package/dist/KaTeX_SansSerif-Italic-HMPFTM52.woff2 +0 -0
  52. package/dist/KaTeX_SansSerif-Italic-PSN4QKYX.woff +0 -0
  53. package/dist/KaTeX_SansSerif-Italic-WTBAZBGY.ttf +0 -0
  54. package/dist/KaTeX_SansSerif-Regular-2TL3USAE.ttf +0 -0
  55. package/dist/KaTeX_SansSerif-Regular-OQCII6EP.woff +0 -0
  56. package/dist/KaTeX_SansSerif-Regular-XIQ62X4E.woff2 +0 -0
  57. package/dist/KaTeX_Script-Regular-72OLXYNA.ttf +0 -0
  58. package/dist/KaTeX_Script-Regular-A5IFOEBS.woff +0 -0
  59. package/dist/KaTeX_Script-Regular-APUWIHLP.woff2 +0 -0
  60. package/dist/KaTeX_Size1-Regular-4HRHTS65.woff +0 -0
  61. package/dist/KaTeX_Size1-Regular-5LRUTBFT.woff2 +0 -0
  62. package/dist/KaTeX_Size1-Regular-7K6AASVL.ttf +0 -0
  63. package/dist/KaTeX_Size2-Regular-222HN3GT.ttf +0 -0
  64. package/dist/KaTeX_Size2-Regular-K5ZHAIS6.woff +0 -0
  65. package/dist/KaTeX_Size2-Regular-LELKET5D.woff2 +0 -0
  66. package/dist/KaTeX_Size3-Regular-TLFPAHDE.woff +0 -0
  67. package/dist/KaTeX_Size3-Regular-UFCO6WCA.ttf +0 -0
  68. package/dist/KaTeX_Size3-Regular-WQRQ47UD.woff2 +0 -0
  69. package/dist/KaTeX_Size4-Regular-7PGNVPQK.ttf +0 -0
  70. package/dist/KaTeX_Size4-Regular-CDMV7U5C.woff2 +0 -0
  71. package/dist/KaTeX_Size4-Regular-PKMWZHNC.woff +0 -0
  72. package/dist/KaTeX_Typewriter-Regular-3F5K6SQ6.ttf +0 -0
  73. package/dist/KaTeX_Typewriter-Regular-MJMFSK64.woff +0 -0
  74. package/dist/KaTeX_Typewriter-Regular-VBYJ4NRC.woff2 +0 -0
  75. package/dist/KernelEngineContext-CcxGYtlr.d.ts +33 -0
  76. package/dist/LayersPanel-M2LHWUFF.js +6 -0
  77. package/dist/ModuleCard-QHDGK5XK.js +7 -0
  78. package/dist/OrbInspector-MHLJ6OEE.css +1756 -0
  79. package/dist/OrbInspector-QCPEPUPH.js +26 -0
  80. package/dist/Select-B-iDdnvE.d.ts +185 -0
  81. package/dist/ServerBridge-Bqsj-lOU.d.ts +124 -0
  82. package/dist/ThemeContext-DJmO59xd.d.ts +147 -0
  83. package/dist/UISlotContext-Dl_ewwCI.d.ts +79 -0
  84. package/dist/UISlotRenderer-C7WWOK43.js +26 -0
  85. package/dist/UISlotRenderer-KVFO6J7R.css +1756 -0
  86. package/dist/auth/browser/index.d.ts +2 -0
  87. package/dist/auth/browser/index.js +2 -0
  88. package/dist/auth/react/index.d.ts +56 -0
  89. package/dist/auth/react/index.js +157 -0
  90. package/dist/avl/index.css +1756 -0
  91. package/dist/avl/index.d.ts +2248 -0
  92. package/dist/avl/index.js +2693 -0
  93. package/dist/avl-3d-context-BycmO6tG.d.ts +201 -0
  94. package/dist/avl-schema-parser-CtJxJ9KU.d.ts +132 -0
  95. package/dist/avl-zoom-state-CKMVuBFg.d.ts +17 -0
  96. package/dist/chunk-3BBUBJFF.js +339 -0
  97. package/dist/chunk-3S54FWRC.js +131 -0
  98. package/dist/chunk-3VZ36ZKO.js +775 -0
  99. package/dist/chunk-4T3P43NS.js +1133 -0
  100. package/dist/chunk-4YXBKHHM.js +11488 -0
  101. package/dist/chunk-57DC34LY.js +525 -0
  102. package/dist/chunk-5QTYQTPS.js +15 -0
  103. package/dist/chunk-A2LR6VQQ.js +349 -0
  104. package/dist/chunk-AB3X7QTE.js +505 -0
  105. package/dist/chunk-AE7VCQB6.js +561 -0
  106. package/dist/chunk-AGXD77SL.js +98 -0
  107. package/dist/chunk-AU7O65OX.js +66 -0
  108. package/dist/chunk-CPLN6NBQ.js +701 -0
  109. package/dist/chunk-DZBQA2OW.js +176 -0
  110. package/dist/chunk-E6KA4J6N.js +227 -0
  111. package/dist/chunk-EOWMARUB.js +16 -0
  112. package/dist/chunk-G7DCAZ22.js +19 -0
  113. package/dist/chunk-GFXCPUMX.js +1334 -0
  114. package/dist/chunk-HH5KSMH5.js +311 -0
  115. package/dist/chunk-ILQXJ2AR.js +280 -0
  116. package/dist/chunk-ILZ7ORX7.js +432 -0
  117. package/dist/chunk-K4MOPSEL.js +674 -0
  118. package/dist/chunk-LHP2TK7O.js +47587 -0
  119. package/dist/chunk-P4ZFUQFF.js +93 -0
  120. package/dist/chunk-PCR37T3U.js +296 -0
  121. package/dist/chunk-PRXQGGCO.js +580 -0
  122. package/dist/chunk-REXYVBUO.js +191 -0
  123. package/dist/chunk-ROICKAU7.js +24 -0
  124. package/dist/chunk-SP5CDJ6K.js +338 -0
  125. package/dist/chunk-TUPZWTRE.js +1051 -0
  126. package/dist/chunk-TXAUOLWZ.js +490 -0
  127. package/dist/chunk-TZZBINQY.js +82 -0
  128. package/dist/chunk-UTDC2NEA.js +14 -0
  129. package/dist/chunk-UU57VNS2.js +1053 -0
  130. package/dist/chunk-UXLE3IPR.js +421 -0
  131. package/dist/chunk-VO2TTLS5.js +94 -0
  132. package/dist/chunk-X3DMMX27.js +11 -0
  133. package/dist/chunk-YHMRX6YA.js +455 -0
  134. package/dist/components/index.css +1756 -0
  135. package/dist/components/index.d.ts +11299 -0
  136. package/dist/components/index.js +1110 -0
  137. package/dist/context/index.d.ts +8 -0
  138. package/dist/context/index.js +8 -0
  139. package/dist/core.d.ts +2599 -0
  140. package/dist/core.js +3 -0
  141. package/dist/design-classes/index.cjs +431 -0
  142. package/dist/design-classes/index.d.cts +165 -0
  143. package/dist/design-classes/index.d.ts +165 -0
  144. package/dist/design-classes/index.js +399 -0
  145. package/dist/emojiItems-QGSNAABW.js +20 -0
  146. package/dist/fx-CmQjnHmT.d.ts +371 -0
  147. package/dist/hooks/index.d.ts +971 -0
  148. package/dist/hooks/index.js +8 -0
  149. package/dist/index.d.ts +408 -0
  150. package/dist/index.js +178 -0
  151. package/dist/katexPlugin-FA7NX4PE.css +1161 -0
  152. package/dist/katexPlugin-NCDKOOQY.js +2 -0
  153. package/dist/kernel-client-TZKGHJRY.js +516 -0
  154. package/dist/kernel-wire-wNdAPfhJ.d.ts +88 -0
  155. package/dist/lib/index.d.ts +602 -0
  156. package/dist/lib/index.js +1289 -0
  157. package/dist/paintDispatch-CuJLsr9Y.d.ts +688 -0
  158. package/dist/parseLessonSegments-GpCeMrb2.d.ts +334 -0
  159. package/dist/perf-CKiBKbkw.d.ts +22 -0
  160. package/dist/perf-Dr28-AgT.d.ts +57 -0
  161. package/dist/prism-X5YWKXO5.js +136 -0
  162. package/dist/providers/index.css +1756 -0
  163. package/dist/providers/index.d.ts +355 -0
  164. package/dist/providers/index.js +29 -0
  165. package/dist/renderer/index.d.ts +465 -0
  166. package/dist/renderer/index.js +4 -0
  167. package/dist/runtime/index.css +1756 -0
  168. package/dist/runtime/index.d.ts +239 -0
  169. package/dist/runtime/index.js +28 -0
  170. package/dist/slot-host-CPzrxLo9.d.ts +48 -0
  171. package/dist/ssr/index.cjs +9739 -0
  172. package/dist/ssr/index.d.cts +464 -0
  173. package/dist/ssr/index.d.ts +464 -0
  174. package/dist/ssr/index.js +9703 -0
  175. package/dist/storage/browser/index.d.ts +1 -0
  176. package/dist/storage/browser/index.js +2 -0
  177. package/dist/test-support.d.ts +42 -0
  178. package/dist/test-support.js +181 -0
  179. package/dist/themeTokens-CRd8AEDF.d.ts +125 -0
  180. package/dist/three/index.css +503 -0
  181. package/dist/three/index.d.ts +1185 -0
  182. package/dist/three/index.js +3908 -0
  183. package/dist/useUISlots-CiobNFGb.d.ts +211 -0
  184. package/dist/verification-C5pTeMJv.d.ts +66 -0
  185. package/dist/verificationRegistry-CVrcxG1s.d.ts +122 -0
  186. package/dist/wrapCallbackForEvent-B9QLbhxX.d.ts +19 -0
  187. package/index.css +199 -0
  188. package/package.json +273 -3
  189. package/src/core/lib/band-shapes.json +7 -0
  190. package/src/core/locales/ar.json +1276 -0
  191. package/src/core/locales/en.json +1276 -0
  192. package/src/core/locales/index.ts +54 -0
  193. package/src/core/locales/sl.json +1276 -0
  194. package/src/core/tokens/native-tokens.json +369 -0
  195. package/tailwind-compile.cjs +29 -0
  196. package/tailwind-preset.cjs +1020 -0
  197. package/themes/_base.css +451 -0
  198. package/themes/_contract.md +307 -0
  199. package/themes/_fonts-kenney.css +11 -0
  200. package/themes/_fonts.css +12 -0
  201. package/themes/_foundation.css +105 -0
  202. package/themes/_head.css +22 -0
  203. package/themes/_presets.css +67 -0
  204. package/themes/almadar-heritage.css +455 -0
  205. package/themes/almadar-website.css +269 -0
  206. package/themes/almadar.css +269 -0
  207. package/themes/aqua.css +455 -0
  208. package/themes/arabesque.css +459 -0
  209. package/themes/art-deco.css +457 -0
  210. package/themes/art-nouveau.css +459 -0
  211. package/themes/atelier.css +463 -0
  212. package/themes/bauhaus.css +461 -0
  213. package/themes/bloomberg-dense.css +463 -0
  214. package/themes/blueprint.css +457 -0
  215. package/themes/clay.css +449 -0
  216. package/themes/comic.css +453 -0
  217. package/themes/constructivist.css +457 -0
  218. package/themes/corporate.css +449 -0
  219. package/themes/cyberpunk.css +453 -0
  220. package/themes/frutiger-aero.css +458 -0
  221. package/themes/game-adventure.css +201 -0
  222. package/themes/game-rpg.css +203 -0
  223. package/themes/game-sci-fi.css +201 -0
  224. package/themes/game-ui-pack.css +200 -0
  225. package/themes/gazette.css +449 -0
  226. package/themes/glass.css +457 -0
  227. package/themes/gothic.css +453 -0
  228. package/themes/index.css +21 -0
  229. package/themes/ink-wash.css +459 -0
  230. package/themes/kawaii.css +459 -0
  231. package/themes/kflow.css +310 -0
  232. package/themes/kiosk.css +449 -0
  233. package/themes/linear-clean.css +463 -0
  234. package/themes/luxury.css +451 -0
  235. package/themes/mac-classic.css +455 -0
  236. package/themes/material.css +463 -0
  237. package/themes/memphis.css +453 -0
  238. package/themes/mid-century.css +455 -0
  239. package/themes/minimalist.css +449 -0
  240. package/themes/mudcloth.css +459 -0
  241. package/themes/nata.css +310 -0
  242. package/themes/neon.css +453 -0
  243. package/themes/neumorphic.css +451 -0
  244. package/themes/newsprint.css +455 -0
  245. package/themes/notion-editorial.css +463 -0
  246. package/themes/orb.css +465 -0
  247. package/themes/pixel.css +449 -0
  248. package/themes/prism.css +309 -0
  249. package/themes/rawi.css +310 -0
  250. package/themes/retro.css +452 -0
  251. package/themes/risograph.css +463 -0
  252. package/themes/scandi.css +469 -0
  253. package/themes/sketch.css +455 -0
  254. package/themes/solarpunk.css +469 -0
  255. package/themes/steampunk.css +451 -0
  256. package/themes/swiss.css +455 -0
  257. package/themes/terminal.css +466 -0
  258. package/themes/trait-wars.css +487 -0
  259. package/themes/ukiyo-e.css +459 -0
  260. package/themes/vaporwave.css +455 -0
  261. package/themes/victorian.css +453 -0
  262. package/themes/wabi-sabi.css +459 -0
  263. package/themes/win95.css +455 -0
  264. package/themes/wireframe.css +439 -0
  265. package/themes/zine.css +455 -0
  266. package/README.md +0 -3
@@ -0,0 +1,1110 @@
1
+ "use client";
2
+ export { assertUniqueSlotsPerHost } from '../chunk-5QTYQTPS.js';
3
+ export { BehaviorView } from '../chunk-ROICKAU7.js';
4
+ export { ModuleCard } from '../chunk-E6KA4J6N.js';
5
+ import { JsonTreeEditor } from '../chunk-ILQXJ2AR.js';
6
+ export { JsonTreeEditor } from '../chunk-ILQXJ2AR.js';
7
+ export { SharedEntityStoreContext, createSharedEntityStore, runTickFrame, useAgentChat, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, usePreview, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSharedEntityStoreContext, useTickVisibility, useTraitListens, useUIEvents, useValidation } from '../chunk-UU57VNS2.js';
8
+ import { resolveSheetDirection, frameRect, GridPicker, FormSection } from '../chunk-LHP2TK7O.js';
9
+ export { Card as ActionCard, ActionPalette, ActionTile, ActivationBlock, ActivityRail, AgentActivityFeed, AgentActivityRow, AgentChatFeed, AgentThinkingRow, Alert, AlgoGraphCanvas, AlgorithmCanvas, AnimatedCounter, AuthLayout, BiologyCanvas, BloomQuizBlock, BranchingLogicBuilder, Breadcrumb, ButtonGroup, COMPACT_MEDIA_QUERY, CalendarGrid, Canvas, Canvas2D, Carousel, ChangeList, Chart, ChartLegend, ChatBar, ChemistryCanvas, ChoiceButton, CodeBlock, CodeRunnerPanel, CommandPalette, CommitRow, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTION_KEYS, DEFAULT_MATRIX_COLUMN_KEYS, DIAMOND_TOP_Y, DashboardGrid, DashboardLayout, DataGrid, DataList, DateRangePicker, DateRangeSelector, DetailPanel, DialogueBubble, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DockLayout, DocumentDetails, DocumentPanel, DocumentViewer, StateMachineView as DomStateMachineVisualizer, DrawShapeLayer, DrawSprite, DrawSpriteLayer, DrawText, DrawTextLayer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EdgeDecoration, EmojiPicker, ErrorBoundary, ErrorState, FEATURE_COLORS, FLOOR_HEIGHT, FeatureCard, FeatureGrid, FilterGroup, Flex, FlipCard, FloatingActionButton, FloatingToolbar, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, FxOverlay, GameAudioContext, GameAudioCue, GameAudioProvider, GameAudioToggle, GameHud, GameMenu, GameShell, Gantt, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, GuestView, Header, HealthBar, IconButton, ImportPreviewTree, ImportProgress, ImportSourcePicker, InputGroup, JazariStateMachine, LearningCanvas, LearningScene3D, Lightbox, LikertScale, LineChart, LoadingState, MachinePanel, MapView, MarkdownContent, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, Modal, ModalSlot, Navigation, NumberStepper, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, PageHeader, PageTransition, Pagination, PhysicsCanvas, PositionedCanvas, ProgressDots, PullToRefresh, QrScanner, QuizBlock, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, RichTextEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SegmentRenderer, SequenceBar, SidePanel, Sidebar, SignaturePad, SimpleGrid, Skeleton, SkeletonTree, SlotContentRenderer, SocialProof, SortableList, Split, SplitPane, StarRating, StatBadge, StatCard, StatDisplay, StateGraph, StateJsonView, StateMachineView, SubagentTracePanel, SwipeableRow, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagInput, Timeline, TimerDisplay, Toast, ToastSlot, TopNavItem, TraitFrame, TraitSlot, TraitStateViewer, UISlotComponent, UISlotRenderer, UploadDropZone, VersionDiff, ViolationAlert, VoteStack, WizardContainer, WizardNavigation, WizardProgress, activityRowFacts, applyCompletion, applySuggestions, arrowBetween, billboardLabel, createUnitAnimationState, cylinderBetween, dispatchCommandPaletteCommand, get3DClickPayload, getCurrentFrame, groupIntoConversations, inferDirection, isoToScreen, meshSphere, parseEditFocus, preloadCodeHighlighter, registerCodeLanguageLoader, renderPatternValue, resolveFrame, resolveSheetDirection, sanitizeRichHtml, screenToIso, tickAnimationState, toCodeLanguage, transitionAnimation, useCamera, useCompactLayout, useDockLayout, useGameAudio, useGameAudioContext, useImageCache } from '../chunk-LHP2TK7O.js';
10
+ export { FileTree } from '../chunk-57DC34LY.js';
11
+ import '../chunk-SP5CDJ6K.js';
12
+ import '../chunk-CPLN6NBQ.js';
13
+ import '../chunk-HH5KSMH5.js';
14
+ export { Accordion } from '../chunk-REXYVBUO.js';
15
+ export { EmptyState } from '../chunk-AGXD77SL.js';
16
+ import '../chunk-TXAUOLWZ.js';
17
+ import { ThemedPortal } from '../chunk-AB3X7QTE.js';
18
+ export { Popover, Tooltip } from '../chunk-AB3X7QTE.js';
19
+ import '../chunk-DZBQA2OW.js';
20
+ export { parseLessonSegments, parseMarkdownWithCodeBlocks } from '../chunk-TUPZWTRE.js';
21
+ import '../chunk-TZZBINQY.js';
22
+ export { DrawFxLayer, DrawGroup, DrawMesh, DrawShape, DrawSkinnedMesh } from '../chunk-4T3P43NS.js';
23
+ import '../chunk-PCR37T3U.js';
24
+ import '../chunk-UXLE3IPR.js';
25
+ import '../chunk-ILZ7ORX7.js';
26
+ import '../chunk-3VZ36ZKO.js';
27
+ export { claimDelivery, keyChord, mergeCaptureTables, parseQueryBinding, useAuthContext, useCanvasGestures, useDragReorder, useKeyboardRouter, useLongPress, usePageHead, usePullToRefresh, useQuerySingleton, useSwipeGesture } from '../chunk-PRXQGGCO.js';
28
+ export { ALMADAR_DND_MIME, useDraggable, useDropZone } from '../chunk-VO2TTLS5.js';
29
+ import '../chunk-AE7VCQB6.js';
30
+ import '../chunk-3BBUBJFF.js';
31
+ export { DEFAULT_SLOTS, useUISlotManager } from '../chunk-YHMRX6YA.js';
32
+ import { VStack, Button, HStack, GameIcon, Typography, Box, useTranslate, Badge, Icon, cn, Select, domPassthrough, Switch, Input } from '../chunk-4YXBKHHM.js';
33
+ import { getKnownPatterns, getPatternDefinition } from '../chunk-A2LR6VQQ.js';
34
+ import '../chunk-P4ZFUQFF.js';
35
+ import '../chunk-G7DCAZ22.js';
36
+ import React4, { useRef, useState, useMemo, useEffect, useCallback, useLayoutEffect } from 'react';
37
+ import * as LucideIcons from 'lucide-react';
38
+ import { ChevronDown, ChevronRight } from 'lucide-react';
39
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
40
+ import { isSecretConfigType } from '@almadar/core';
41
+
42
+ // src/lib/game.ts
43
+ function createInitialGameState(width, height, units, defaultTerrain = "floorStone") {
44
+ const board = Array.from(
45
+ { length: height },
46
+ () => Array.from({ length: width }, () => ({
47
+ terrain: defaultTerrain
48
+ }))
49
+ );
50
+ const unitsMap = {};
51
+ for (const unit of units) {
52
+ unitsMap[unit.id] = unit;
53
+ if (unit.position.y < height && unit.position.x < width) {
54
+ board[unit.position.y][unit.position.x].unitId = unit.id;
55
+ }
56
+ }
57
+ return {
58
+ board,
59
+ units: unitsMap,
60
+ currentPhase: "observation",
61
+ currentTurn: 1,
62
+ activeTeam: "player",
63
+ validMoves: [],
64
+ attackTargets: []
65
+ };
66
+ }
67
+ function calculateValidMoves(state, unitId) {
68
+ const unit = state.units[unitId];
69
+ if (!unit) return [];
70
+ const moves = [];
71
+ const { x, y } = unit.position;
72
+ const range = unit.movement;
73
+ for (let dy = -range; dy <= range; dy++) {
74
+ for (let dx = -range; dx <= range; dx++) {
75
+ const nx = x + dx;
76
+ const ny = y + dy;
77
+ const distance = Math.abs(dx) + Math.abs(dy);
78
+ if (distance > 0 && distance <= range && ny >= 0 && ny < state.board.length && nx >= 0 && nx < state.board[0].length && !state.board[ny][nx].unitId && !state.board[ny][nx].isBlocked) {
79
+ moves.push({ x: nx, y: ny });
80
+ }
81
+ }
82
+ }
83
+ return moves;
84
+ }
85
+ function calculateAttackTargets(state, unitId) {
86
+ const unit = state.units[unitId];
87
+ if (!unit) return [];
88
+ const targets = [];
89
+ const { x, y } = unit.position;
90
+ const directions = [
91
+ { dx: -1, dy: 0 },
92
+ { dx: 1, dy: 0 },
93
+ { dx: 0, dy: -1 },
94
+ { dx: 0, dy: 1 }
95
+ ];
96
+ for (const { dx, dy } of directions) {
97
+ const nx = x + dx;
98
+ const ny = y + dy;
99
+ if (ny >= 0 && ny < state.board.length && nx >= 0 && nx < state.board[0].length) {
100
+ const targetTile = state.board[ny][nx];
101
+ if (targetTile.unitId) {
102
+ const targetUnit = state.units[targetTile.unitId];
103
+ if (targetUnit && targetUnit.team !== unit.team) {
104
+ targets.push({ x: nx, y: ny });
105
+ }
106
+ }
107
+ }
108
+ }
109
+ return targets;
110
+ }
111
+
112
+ // src/lib/boardEntity.ts
113
+ function boardEntity(entity) {
114
+ if (!entity) return void 0;
115
+ return Array.isArray(entity) ? entity[0] : entity;
116
+ }
117
+ function str(v) {
118
+ return v == null ? "" : String(v);
119
+ }
120
+ function num(v, fallback = 0) {
121
+ const n = Number(v);
122
+ return Number.isFinite(n) ? n : fallback;
123
+ }
124
+ function bool(v) {
125
+ return Boolean(v);
126
+ }
127
+ function rows(v) {
128
+ return Array.isArray(v) ? v : [];
129
+ }
130
+ function vec2(v) {
131
+ const o = v ?? {};
132
+ return { x: num(o.x), y: num(o.y) };
133
+ }
134
+ function unitPosition(u) {
135
+ return vec2(u.position);
136
+ }
137
+ function unitTeam(u) {
138
+ return str(u.team);
139
+ }
140
+ function unitHealth(u) {
141
+ return num(u.health);
142
+ }
143
+
144
+ // src/lib/makeAsset.ts
145
+ var ROLE_DEFAULTS = {
146
+ tile: { dimension: "2d", animations: ["static"], aspect: "1:1" },
147
+ decoration: { dimension: "2d", animations: ["static"], aspect: "1:1" },
148
+ effect: { dimension: "2d", animations: ["static"], aspect: "1:1" },
149
+ item: { dimension: "2d", animations: ["static"], aspect: "5:7" },
150
+ player: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
151
+ enemy: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
152
+ npc: { dimension: "2d", animations: ["idle", "walk", "attack", "hit", "death"], aspect: "1:1" },
153
+ projectile: { dimension: "2d", animations: ["static"], aspect: "1:1" },
154
+ vehicle: { dimension: "2d", animations: ["idle", "walk"], aspect: "1:1" },
155
+ ui: { dimension: "2d", animations: ["static"], aspect: "1:1" }
156
+ };
157
+ function makeAsset(url, role, overrides = {}) {
158
+ const defaults = ROLE_DEFAULTS[role] ?? { dimension: "2d", animations: ["static"], aspect: "1:1" };
159
+ return {
160
+ url,
161
+ role,
162
+ category: url.split("/").pop()?.replace(/\.[^.]+$/, "") ?? role,
163
+ ...defaults,
164
+ ...overrides
165
+ };
166
+ }
167
+ function makeAssetMap(record, role, overrides = {}) {
168
+ const result = {};
169
+ for (const [key, url] of Object.entries(record)) {
170
+ result[key] = makeAsset(url, role, overrides);
171
+ }
172
+ return result;
173
+ }
174
+ function unitAtlasUrl(unit) {
175
+ return unit.spriteSheet?.url ?? null;
176
+ }
177
+ function resolveSheetUrl(atlasUrl, relativeSheetPath) {
178
+ try {
179
+ return new URL(relativeSheetPath, atlasUrl).toString();
180
+ } catch {
181
+ const base = atlasUrl.slice(0, atlasUrl.lastIndexOf("/") + 1);
182
+ return `${base}${relativeSheetPath.replace(/^\.\//, "")}`;
183
+ }
184
+ }
185
+ function useUnitSpriteAtlas(units) {
186
+ const atlasCacheRef = useRef(/* @__PURE__ */ new Map());
187
+ const loadingRef = useRef(/* @__PURE__ */ new Set());
188
+ const [pendingCount, setPendingCount] = useState(0);
189
+ const [, forceTick] = useState(0);
190
+ const atlasUrls = useMemo(() => {
191
+ const set = /* @__PURE__ */ new Set();
192
+ for (const unit of units) {
193
+ const url = unitAtlasUrl(unit);
194
+ if (url) set.add(url);
195
+ }
196
+ return [...set];
197
+ }, [units]);
198
+ useEffect(() => {
199
+ const cache = atlasCacheRef.current;
200
+ const loading = loadingRef.current;
201
+ const toLoad = atlasUrls.filter((url) => !cache.has(url) && !loading.has(url));
202
+ if (toLoad.length === 0) return;
203
+ let cancelled = false;
204
+ setPendingCount((prev) => prev + toLoad.length);
205
+ for (const url of toLoad) {
206
+ loading.add(url);
207
+ fetch(url).then((res) => res.ok ? res.json() : Promise.reject(new Error(String(res.status)))).then((atlas) => {
208
+ if (cancelled) return;
209
+ cache.set(url, atlas);
210
+ }).catch(() => {
211
+ }).finally(() => {
212
+ if (cancelled) return;
213
+ loading.delete(url);
214
+ setPendingCount((prev) => Math.max(0, prev - 1));
215
+ forceTick((n) => n + 1);
216
+ });
217
+ }
218
+ return () => {
219
+ cancelled = true;
220
+ };
221
+ }, [atlasUrls]);
222
+ const sheetUrls = useMemo(() => {
223
+ const urls = /* @__PURE__ */ new Set();
224
+ for (const unit of units) {
225
+ const atlasUrl = unitAtlasUrl(unit);
226
+ if (!atlasUrl) continue;
227
+ const atlas = atlasCacheRef.current.get(atlasUrl);
228
+ if (!atlas) continue;
229
+ for (const rel of Object.values(atlas.sheets)) {
230
+ if (rel) urls.add(resolveSheetUrl(atlasUrl, rel));
231
+ }
232
+ }
233
+ return [...urls];
234
+ }, [units, pendingCount]);
235
+ const resolveUnitFrame = useCallback((unitId) => {
236
+ const unit = units.find((u) => u.id === unitId);
237
+ if (!unit) return null;
238
+ const atlasUrl = unitAtlasUrl(unit);
239
+ if (!atlasUrl) return null;
240
+ const atlas = atlasCacheRef.current.get(atlasUrl);
241
+ if (!atlas) return null;
242
+ const animation = unit.animation ?? "idle";
243
+ const frame = unit.frame ?? 0;
244
+ const def = atlas.animations[animation] ?? atlas.animations.idle;
245
+ if (!def) return null;
246
+ const { sheetDir, flipX } = resolveSheetDirection("se");
247
+ const rel = atlas.sheets[sheetDir] ?? atlas.sheets.se ?? atlas.sheets.sw;
248
+ if (!rel) return null;
249
+ const sheetUrl = resolveSheetUrl(atlasUrl, rel);
250
+ const rect = frameRect(frame, def.row, atlas.columns, atlas.frameWidth, atlas.frameHeight);
251
+ return {
252
+ sheetUrl,
253
+ sx: rect.sx,
254
+ sy: rect.sy,
255
+ sw: rect.sw,
256
+ sh: rect.sh,
257
+ flipX,
258
+ applyBreathing: animation === "idle"
259
+ };
260
+ }, [units]);
261
+ return { sheetUrls, resolveUnitFrame, pendingCount };
262
+ }
263
+ var MODE_LABEL_KEYS = {
264
+ select: "editor.modeSelect",
265
+ paint: "editor.modePaint",
266
+ unit: "editor.modeUnit",
267
+ feature: "editor.modeFeature",
268
+ erase: "editor.modeErase"
269
+ };
270
+ var TERRAIN_COLORS = {
271
+ grass: "#4a7c3f",
272
+ dirt: "#8b6c42",
273
+ stone: "#7a7a7a",
274
+ sand: "#c4a84d",
275
+ water: "#3a6ea5",
276
+ forest: "#2d5a1e",
277
+ mountain: "#5a4a3a",
278
+ lava: "#c44b2b",
279
+ ice: "#a0d2e8",
280
+ plains: "#6b8e4e",
281
+ fortress: "#4a4a5a",
282
+ castle: "#5a5a6a"
283
+ };
284
+ var FEATURE_TYPES = [
285
+ "goldMine",
286
+ "resonanceCrystal",
287
+ "traitCache",
288
+ "salvageYard",
289
+ "portal",
290
+ "battleMarker",
291
+ "treasure",
292
+ "castle"
293
+ ];
294
+ function CollapsibleSection({ title, expanded, onToggle, children, assetManifest, className }) {
295
+ const ui = assetManifest?.ui;
296
+ return /* @__PURE__ */ jsxs(VStack, { gap: "xs", className, children: [
297
+ /* @__PURE__ */ jsx(
298
+ Button,
299
+ {
300
+ variant: "ghost",
301
+ size: "sm",
302
+ onClick: onToggle,
303
+ className: "w-full justify-start text-left",
304
+ children: /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
305
+ /* @__PURE__ */ jsx(
306
+ GameIcon,
307
+ {
308
+ icon: expanded ? ChevronDown : ChevronRight,
309
+ assetUrl: expanded ? ui?.["collapse"] : ui?.["expand"],
310
+ size: 14
311
+ }
312
+ ),
313
+ /* @__PURE__ */ jsx(Typography, { variant: "label", weight: "semibold", children: title })
314
+ ] })
315
+ }
316
+ ),
317
+ expanded && /* @__PURE__ */ jsx(Box, { padding: "xs", paddingX: "sm", children })
318
+ ] });
319
+ }
320
+ CollapsibleSection.displayName = "CollapsibleSection";
321
+ function EditorSlider({ label, value, min, max, step = 0.1, onChange, className }) {
322
+ const { locale } = useTranslate();
323
+ return /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", className, children: [
324
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "min-w-[80px] text-muted-foreground", children: label }),
325
+ /* @__PURE__ */ jsx(Box, { className: "flex-1", children: /* @__PURE__ */ jsx(
326
+ "input",
327
+ {
328
+ type: "range",
329
+ min,
330
+ max,
331
+ step,
332
+ value,
333
+ onChange: (e) => onChange(parseFloat(e.target.value)),
334
+ className: "w-full h-1.5 bg-muted rounded-interactive appearance-none cursor-pointer accent-primary"
335
+ }
336
+ ) }),
337
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "min-w-[40px] text-right text-muted-foreground", children: typeof step === "number" && step < 1 ? new Intl.NumberFormat(locale, { minimumFractionDigits: 1, maximumFractionDigits: 1 }).format(value) : new Intl.NumberFormat(locale).format(value) })
338
+ ] });
339
+ }
340
+ EditorSlider.displayName = "EditorSlider";
341
+ function EditorSelect({ label, value, options, onChange, className }) {
342
+ return /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", className, children: [
343
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "min-w-[80px] text-muted-foreground", children: label }),
344
+ /* @__PURE__ */ jsx(Box, { className: "flex-1", children: /* @__PURE__ */ jsx(
345
+ "select",
346
+ {
347
+ value,
348
+ onChange: (e) => onChange(e.target.value),
349
+ className: "w-full px-2 py-1 text-xs bg-muted text-foreground border border-muted rounded cursor-pointer",
350
+ children: options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
351
+ }
352
+ ) })
353
+ ] });
354
+ }
355
+ EditorSelect.displayName = "EditorSelect";
356
+ function EditorCheckbox({ label, checked, onChange, className }) {
357
+ return /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", className, children: [
358
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "min-w-[80px] text-muted-foreground", children: label }),
359
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
360
+ "input",
361
+ {
362
+ type: "checkbox",
363
+ checked,
364
+ onChange: (e) => onChange(e.target.checked),
365
+ className: "w-4 h-4 accent-primary cursor-pointer"
366
+ }
367
+ ) })
368
+ ] });
369
+ }
370
+ EditorCheckbox.displayName = "EditorCheckbox";
371
+ function EditorTextInput({ label, value, onChange, placeholder, className }) {
372
+ return /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", className, children: [
373
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "min-w-[80px] text-muted-foreground", children: label }),
374
+ /* @__PURE__ */ jsx(Box, { className: "flex-1", children: /* @__PURE__ */ jsx(
375
+ "input",
376
+ {
377
+ type: "text",
378
+ value,
379
+ onChange: (e) => onChange(e.target.value),
380
+ placeholder,
381
+ className: "w-full px-2 py-1 text-xs bg-muted text-foreground border border-muted rounded"
382
+ }
383
+ ) })
384
+ ] });
385
+ }
386
+ EditorTextInput.displayName = "EditorTextInput";
387
+ function StatusBar({ hoveredTile, mode, gridSize, unitCount, featureCount, className }) {
388
+ const { t } = useTranslate();
389
+ return /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", className: `px-3 py-1.5 bg-background border-t border-border ${className ?? ""}`, children: [
390
+ /* @__PURE__ */ jsx(Badge, { variant: "info", size: "sm", children: t(MODE_LABEL_KEYS[mode]) }),
391
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("editor.tile", { position: hoveredTile ? `(${hoveredTile.x}, ${hoveredTile.y})` : "\u2014" }) }),
392
+ gridSize && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("editor.grid", { width: gridSize.width, height: gridSize.height }) }),
393
+ unitCount !== void 0 && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("editor.units", { count: unitCount }) }),
394
+ featureCount !== void 0 && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: t("editor.features", { count: featureCount }) })
395
+ ] });
396
+ }
397
+ StatusBar.displayName = "StatusBar";
398
+ function TerrainPalette({ terrains, selectedTerrain, onSelect, className }) {
399
+ return /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, className, children: terrains.map((terrain) => /* @__PURE__ */ jsx(
400
+ Box,
401
+ {
402
+ onClick: () => onSelect(terrain),
403
+ className: `w-8 h-8 rounded cursor-pointer border-2 transition-all ${selectedTerrain === terrain ? "border-foreground scale-110 shadow-lg" : "border-muted hover:border-muted-foreground"}`,
404
+ style: { backgroundColor: TERRAIN_COLORS[terrain] || "var(--color-muted)" },
405
+ title: terrain
406
+ },
407
+ terrain
408
+ )) });
409
+ }
410
+ TerrainPalette.displayName = "TerrainPalette";
411
+ function EditorToolbar({ mode, onModeChange, className }) {
412
+ const { t } = useTranslate();
413
+ const modes = ["select", "paint", "unit", "feature", "erase"];
414
+ return /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, className, children: modes.map((m) => /* @__PURE__ */ jsx(
415
+ Button,
416
+ {
417
+ variant: mode === m ? "primary" : "ghost",
418
+ size: "sm",
419
+ onClick: () => onModeChange(m),
420
+ children: t(MODE_LABEL_KEYS[m])
421
+ },
422
+ m
423
+ )) });
424
+ }
425
+ EditorToolbar.displayName = "EditorToolbar";
426
+
427
+ // src/lib/puzzleObject.ts
428
+ function objId(o) {
429
+ return o.id == null ? "" : String(o.id);
430
+ }
431
+ function objName(o) {
432
+ return o.name == null ? "" : String(o.name);
433
+ }
434
+ function objIcon(o) {
435
+ return o.icon == null ? "" : String(o.icon);
436
+ }
437
+ function objStates(o) {
438
+ return Array.isArray(o.states) ? o.states : [];
439
+ }
440
+ function objCurrentState(o) {
441
+ return o.currentState == null ? "" : String(o.currentState);
442
+ }
443
+ function objAvailableEvents(o) {
444
+ return Array.isArray(o.availableEvents) ? o.availableEvents : [];
445
+ }
446
+ function objAvailableActions(o) {
447
+ return Array.isArray(o.availableActions) ? o.availableActions : [];
448
+ }
449
+ function objRules(o) {
450
+ return Array.isArray(o.rules) ? o.rules : [];
451
+ }
452
+ function objMaxRules(o) {
453
+ const n = Number(o.maxRules);
454
+ return Number.isFinite(n) && n > 0 ? n : 3;
455
+ }
456
+
457
+ // src/lib/mechanics.ts
458
+ var projectileMotion = {
459
+ id: "mechanics-projectile",
460
+ nameKey: "physicsPreset.projectileMotion",
461
+ descriptionKey: "physicsPreset.projectileMotionDescription",
462
+ domain: "natural",
463
+ gravity: { x: 0, y: 9.81 },
464
+ bodies: [
465
+ { id: "ball", x: 50, y: 350, vx: 80, vy: -120, mass: 1, radius: 10, color: "#e94560", fixed: false },
466
+ { id: "ground", x: 300, y: 390, vx: 0, vy: 0, mass: 1e3, radius: 400, color: "#333", fixed: true }
467
+ ],
468
+ showVelocity: true,
469
+ parameters: {
470
+ angle: { value: 45, min: 0, max: 90, step: 1, labelKey: "physicsPreset.launchAngle" },
471
+ velocity: { value: 100, min: 10, max: 200, step: 5, labelKey: "physicsPreset.initialVelocity" },
472
+ gravity: { value: 9.81, min: 0, max: 20, step: 0.1, labelKey: "physicsPreset.gravity" }
473
+ }
474
+ };
475
+ var pendulum = {
476
+ id: "mechanics-pendulum",
477
+ nameKey: "physicsPreset.simplePendulum",
478
+ descriptionKey: "physicsPreset.simplePendulumDescription",
479
+ domain: "natural",
480
+ gravity: { x: 0, y: 9.81 },
481
+ bodies: [
482
+ { id: "pivot", x: 300, y: 50, vx: 0, vy: 0, mass: 1e3, radius: 5, color: "#888", fixed: true },
483
+ { id: "bob", x: 400, y: 200, vx: 0, vy: 0, mass: 5, radius: 15, color: "#e94560", fixed: false }
484
+ ],
485
+ constraints: [{ bodyA: 0, bodyB: 1, length: 180, stiffness: 1 }],
486
+ parameters: {
487
+ length: { value: 180, min: 50, max: 300, step: 10, labelKey: "physicsPreset.stringLength" },
488
+ mass: { value: 5, min: 1, max: 20, step: 0.5, labelKey: "physicsPreset.mass" },
489
+ gravity: { value: 9.81, min: 0, max: 20, step: 0.1, labelKey: "physicsPreset.gravity" }
490
+ }
491
+ };
492
+ var springOscillator = {
493
+ id: "mechanics-spring",
494
+ nameKey: "physicsPreset.springOscillator",
495
+ descriptionKey: "physicsPreset.springOscillatorDescription",
496
+ domain: "natural",
497
+ gravity: { x: 0, y: 0 },
498
+ bodies: [
499
+ { id: "anchor", x: 300, y: 50, vx: 0, vy: 0, mass: 1e3, radius: 8, color: "#888", fixed: true },
500
+ { id: "mass", x: 300, y: 250, vx: 0, vy: 0, mass: 2, radius: 20, color: "#0f3460", fixed: false }
501
+ ],
502
+ constraints: [{ bodyA: 0, bodyB: 1, length: 150, stiffness: 0.5 }],
503
+ parameters: {
504
+ stiffness: { value: 0.5, min: 0.1, max: 2, step: 0.05, labelKey: "physicsPreset.springStiffness" },
505
+ mass: { value: 2, min: 0.5, max: 10, step: 0.5, labelKey: "physicsPreset.mass" },
506
+ damping: { value: 0, min: 0, max: 0.5, step: 0.01, labelKey: "physicsPreset.damping" }
507
+ }
508
+ };
509
+
510
+ // src/lib/physicsPresets.ts
511
+ var ALL_PRESETS = [
512
+ projectileMotion,
513
+ pendulum,
514
+ springOscillator
515
+ ];
516
+ function pascalToKebab(name) {
517
+ return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
518
+ }
519
+ function kebabToPascal(name) {
520
+ return name.split("-").map((part) => /^\d+$/.test(part) ? part : part.charAt(0).toUpperCase() + part.slice(1)).join("");
521
+ }
522
+ var ICON_ITEMS = (() => {
523
+ const items = [];
524
+ for (const [exportName, candidate] of Object.entries(LucideIcons)) {
525
+ if (!/^[A-Z]/.test(exportName)) continue;
526
+ if (exportName.endsWith("Icon")) continue;
527
+ if (exportName.startsWith("Lucide")) continue;
528
+ const isComponent = candidate !== null && (typeof candidate === "object" || typeof candidate === "function") && "$$typeof" in candidate;
529
+ if (!isComponent) continue;
530
+ const kebab = pascalToKebab(exportName);
531
+ if (kebabToPascal(kebab) !== exportName) continue;
532
+ items.push({ id: kebab, label: kebab, category: "icons" });
533
+ }
534
+ return items;
535
+ })();
536
+ var IconPicker = ({ value, onChange, className }) => {
537
+ const { t } = useTranslate();
538
+ const items = useMemo(() => {
539
+ const category = t("iconPicker.category");
540
+ return ICON_ITEMS.map((item) => ({ ...item, category }));
541
+ }, [t]);
542
+ return /* @__PURE__ */ jsx(
543
+ GridPicker,
544
+ {
545
+ items,
546
+ value,
547
+ onChange,
548
+ searchPlaceholder: t("iconPicker.search"),
549
+ renderThumbnail: (it) => /* @__PURE__ */ jsx(Icon, { name: it.id }),
550
+ cellSize: 32,
551
+ className
552
+ }
553
+ );
554
+ };
555
+ IconPicker.displayName = "IconPicker";
556
+ var THUMB_PX = 32;
557
+ var IMAGE_KINDS = /* @__PURE__ */ new Set([
558
+ "image",
559
+ "spritesheet",
560
+ "scene",
561
+ "portrait"
562
+ ]);
563
+ function iconForKind(kind) {
564
+ if (kind === "audio") return "music";
565
+ if (kind === "model") return "box";
566
+ return "file";
567
+ }
568
+ var AssetPicker = ({
569
+ assets,
570
+ value,
571
+ onChange,
572
+ className
573
+ }) => {
574
+ const byUrl = useMemo(() => {
575
+ const map = /* @__PURE__ */ new Map();
576
+ for (const entry of assets) map.set(entry.url, entry);
577
+ return map;
578
+ }, [assets]);
579
+ const items = useMemo(
580
+ () => assets.map((entry) => ({
581
+ id: entry.url,
582
+ label: entry.name,
583
+ category: entry.category
584
+ })),
585
+ [assets]
586
+ );
587
+ const categories = useMemo(() => {
588
+ const seen = [];
589
+ for (const entry of assets) {
590
+ if (!seen.includes(entry.category)) seen.push(entry.category);
591
+ }
592
+ return seen;
593
+ }, [assets]);
594
+ const renderThumbnail = useCallback(
595
+ (item) => {
596
+ const entry = byUrl.get(item.id);
597
+ if (entry === void 0) return null;
598
+ if (IMAGE_KINDS.has(entry.kind)) {
599
+ return /* @__PURE__ */ jsx(
600
+ "img",
601
+ {
602
+ src: entry.thumbnailUrl ?? entry.url,
603
+ alt: entry.name,
604
+ loading: "lazy",
605
+ width: THUMB_PX,
606
+ height: THUMB_PX,
607
+ style: { width: THUMB_PX, height: THUMB_PX, objectFit: "cover" }
608
+ }
609
+ );
610
+ }
611
+ return /* @__PURE__ */ jsx(Icon, { name: iconForKind(entry.kind), size: "sm" });
612
+ },
613
+ [byUrl]
614
+ );
615
+ return /* @__PURE__ */ jsx(
616
+ GridPicker,
617
+ {
618
+ items,
619
+ value,
620
+ onChange,
621
+ categories,
622
+ renderThumbnail,
623
+ cellSize: THUMB_PX,
624
+ className
625
+ }
626
+ );
627
+ };
628
+ AssetPicker.displayName = "AssetPicker";
629
+ var TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
630
+ var TIER_LABEL_KEYS = {
631
+ presentation: "propertyInspector.tier.presentation",
632
+ domain: "propertyInspector.tier.domain",
633
+ policy: "propertyInspector.tier.policy",
634
+ infra: "propertyInspector.tier.infra",
635
+ internal: "propertyInspector.tier.internal"
636
+ };
637
+ function currentValue(decl, override) {
638
+ return override !== void 0 ? override : decl.default;
639
+ }
640
+ function TextLikeControl({
641
+ field,
642
+ numeric,
643
+ secret,
644
+ value,
645
+ onCommit
646
+ }) {
647
+ const initial = value === void 0 || value === null ? "" : String(value);
648
+ const [draft, setDraft] = React4.useState(initial);
649
+ React4.useEffect(() => setDraft(initial), [initial]);
650
+ const commit = () => {
651
+ if (numeric) {
652
+ const n = draft.trim() === "" ? 0 : Number(draft);
653
+ onCommit(field, Number.isNaN(n) ? 0 : n);
654
+ } else {
655
+ onCommit(field, draft);
656
+ }
657
+ };
658
+ return /* @__PURE__ */ jsx(
659
+ Input,
660
+ {
661
+ inputType: secret ? "password" : numeric ? "number" : "text",
662
+ value: draft,
663
+ onChange: (e) => setDraft(e.target.value),
664
+ onBlur: commit,
665
+ onKeyDown: (e) => {
666
+ if (e.key === "Enter") commit();
667
+ }
668
+ }
669
+ );
670
+ }
671
+ var SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset", "Asset", "secret", "event"]);
672
+ function isTraitConfigObject(v) {
673
+ return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
674
+ }
675
+ function isAssetObject(v) {
676
+ return isTraitConfigObject(v) && typeof v.url === "string";
677
+ }
678
+ function FieldControl({
679
+ name,
680
+ decl,
681
+ value,
682
+ onChange,
683
+ assets
684
+ }) {
685
+ const { t } = useTranslate();
686
+ let control;
687
+ const stringValue = typeof value === "string" ? value : void 0;
688
+ const effectiveValue = value ?? decl.default;
689
+ if (decl.type === "icon") {
690
+ control = /* @__PURE__ */ jsx(IconPicker, { value: stringValue, onChange: (icon) => onChange(name, icon) });
691
+ } else if (decl.type === "asset") {
692
+ control = /* @__PURE__ */ jsx(
693
+ AssetPicker,
694
+ {
695
+ assets: assets ?? [],
696
+ value: stringValue,
697
+ onChange: (url) => onChange(name, url)
698
+ }
699
+ );
700
+ } else if (decl.type === "Asset") {
701
+ const assetUrl = isAssetObject(effectiveValue) ? effectiveValue.url : "";
702
+ const baseAsset = isAssetObject(effectiveValue) ? effectiveValue : {};
703
+ control = /* @__PURE__ */ jsx(
704
+ AssetPicker,
705
+ {
706
+ assets: assets ?? [],
707
+ value: assetUrl,
708
+ onChange: (url) => onChange(name, { ...baseAsset, url })
709
+ }
710
+ );
711
+ } else if (decl.type === "boolean") {
712
+ control = /* @__PURE__ */ jsx(Switch, { checked: value === true, onChange: (c) => onChange(name, c) });
713
+ } else if (decl.type === "string" && decl.values !== void 0 && decl.values.length > 0) {
714
+ control = /* @__PURE__ */ jsx(
715
+ Select,
716
+ {
717
+ options: decl.values.map((v) => ({ value: v, label: v })),
718
+ value: typeof value === "string" ? value : "",
719
+ onValueChange: (v) => onChange(name, v)
720
+ }
721
+ );
722
+ } else if (decl.type === "number") {
723
+ control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: true, value, onCommit: onChange });
724
+ } else if (isSecretConfigType(decl.type)) {
725
+ control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: false, secret: true, value, onCommit: onChange });
726
+ } else if (decl.type === "event") {
727
+ control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
728
+ } else if (decl.type === "string") {
729
+ control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
730
+ } else if (decl.type === "node") {
731
+ control = /* @__PURE__ */ jsx(NodeSlotEditor, { value: effectiveValue, onChange: (next) => onChange(name, next) });
732
+ } else if (decl.type.startsWith("[") || Array.isArray(effectiveValue)) {
733
+ const arr = Array.isArray(effectiveValue) ? effectiveValue : [];
734
+ control = /* @__PURE__ */ jsx(JsonTreeEditor, { value: arr, onChange: (next) => onChange(name, next) });
735
+ } else if (decl.type === "object" || decl.type.startsWith("Map ") || !SCALAR_TYPES.has(decl.type) && isTraitConfigObject(effectiveValue)) {
736
+ const obj = isTraitConfigObject(effectiveValue) ? effectiveValue : {};
737
+ control = /* @__PURE__ */ jsx(JsonTreeEditor, { value: obj, onChange: (next) => onChange(name, next) });
738
+ } else {
739
+ control = /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: t("propertyInspector.editInSource", { type: decl.type }) });
740
+ }
741
+ return /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
742
+ /* @__PURE__ */ jsx(Typography, { variant: "label", children: decl.label ?? name }),
743
+ control,
744
+ decl.description !== void 0 && decl.description !== "" && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: decl.description })
745
+ ] });
746
+ }
747
+ var PropertyInspector = ({
748
+ config,
749
+ values,
750
+ onChange,
751
+ onReset,
752
+ title,
753
+ className,
754
+ assets,
755
+ tiers
756
+ }) => {
757
+ const { t } = useTranslate();
758
+ const allowedTiers = tiers ? new Set(tiers) : null;
759
+ const fields = Object.entries(config).filter(([, decl]) => {
760
+ if (!allowedTiers) return true;
761
+ return allowedTiers.has(decl.tier ?? "presentation");
762
+ });
763
+ const byTier = /* @__PURE__ */ new Map();
764
+ for (const [name, decl] of fields) {
765
+ const tier = decl.tier ?? "presentation";
766
+ const arr = byTier.get(tier) ?? [];
767
+ arr.push([name, decl]);
768
+ byTier.set(tier, arr);
769
+ }
770
+ const tierList = [...byTier.keys()].sort((a, b) => {
771
+ const ia = TIER_ORDER.indexOf(a);
772
+ const ib = TIER_ORDER.indexOf(b);
773
+ return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);
774
+ });
775
+ return /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: cn("w-full", className), children: [
776
+ /* @__PURE__ */ jsxs(HStack, { justify: "between", align: "center", children: [
777
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", weight: "bold", children: title ?? t("propertyInspector.config") }),
778
+ onReset !== void 0 && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", icon: "rotate-ccw", label: t("common.reset"), onClick: onReset })
779
+ ] }),
780
+ fields.length === 0 && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: t("propertyInspector.noProperties") }),
781
+ tierList.map((tier) => /* @__PURE__ */ jsx(FormSection, { title: TIER_LABEL_KEYS[tier] ? t(TIER_LABEL_KEYS[tier]) : tier, collapsible: true, defaultCollapsed: tier !== "presentation", children: /* @__PURE__ */ jsx(VStack, { gap: "sm", children: byTier.get(tier)?.map(([name, decl]) => /* @__PURE__ */ jsx(
782
+ FieldControl,
783
+ {
784
+ name,
785
+ decl,
786
+ value: currentValue(decl, values?.[name]),
787
+ onChange,
788
+ assets
789
+ },
790
+ name
791
+ )) }) }, tier))
792
+ ] });
793
+ };
794
+ var isObj = (v) => v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
795
+ function normalize(value) {
796
+ const wasArray = Array.isArray(value);
797
+ const pattern = wasArray ? value[0] : value;
798
+ const type = isObj(pattern) && typeof pattern["type"] === "string" ? pattern["type"] : "";
799
+ const props = {};
800
+ if (isObj(pattern)) {
801
+ for (const [k, v] of Object.entries(pattern)) if (k !== "type") props[k] = v;
802
+ }
803
+ return { type, props, wasArray };
804
+ }
805
+ var NodeSlotEditor = ({ value, onChange, className }) => {
806
+ const { t } = useTranslate();
807
+ const { type, props, wasArray } = normalize(value);
808
+ const patterns = React4.useMemo(() => {
809
+ try {
810
+ return [...getKnownPatterns()].sort();
811
+ } catch {
812
+ return [];
813
+ }
814
+ }, []);
815
+ const options = React4.useMemo(
816
+ () => [{ value: "", label: t("nodeSlot.none") }, ...patterns.map((p) => ({ value: p, label: p }))],
817
+ [patterns, t]
818
+ );
819
+ const emit = (nextType, nextProps) => {
820
+ if (!nextType) {
821
+ onChange(wasArray ? [] : {});
822
+ return;
823
+ }
824
+ const pattern = { type: nextType, ...nextProps };
825
+ onChange(wasArray || value === void 0 ? [pattern] : pattern);
826
+ };
827
+ const schemaEntries = React4.useMemo(() => {
828
+ if (!type) return [];
829
+ const def = getPatternDefinition(type);
830
+ if (!def?.propsSchema) return [];
831
+ return Object.entries(def.propsSchema).map(([propName, propDef]) => {
832
+ const decl = {
833
+ type: propDef.types?.[0] ?? "string",
834
+ description: propDef.description,
835
+ label: propName,
836
+ ...propDef.enumValues && propDef.enumValues.length > 0 ? { values: propDef.enumValues } : {}
837
+ };
838
+ return [propName, decl];
839
+ });
840
+ }, [type]);
841
+ const hasSchema = schemaEntries.length > 0;
842
+ return /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: cn("w-full", className), children: [
843
+ /* @__PURE__ */ jsx(
844
+ Select,
845
+ {
846
+ options,
847
+ value: type,
848
+ onValueChange: (v) => emit(v, props)
849
+ }
850
+ ),
851
+ type !== "" && /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "pl-1", children: [
852
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: t("nodeSlot.props") }),
853
+ hasSchema ? /* @__PURE__ */ jsx(VStack, { gap: "xs", children: schemaEntries.map(([propName, decl]) => /* @__PURE__ */ jsx(
854
+ FieldControl,
855
+ {
856
+ name: propName,
857
+ decl,
858
+ value: props[propName],
859
+ onChange: (field, val) => emit(type, { ...props, [field]: val })
860
+ },
861
+ propName
862
+ )) }) : /* @__PURE__ */ jsx(JsonTreeEditor, { value: props, onChange: (next) => emit(type, isObj(next) ? next : {}) })
863
+ ] })
864
+ ] });
865
+ };
866
+ var GAP = 10;
867
+ var EDGE = 8;
868
+ function resolveAnchorRect(anchor) {
869
+ if (typeof anchor === "string") {
870
+ return document.querySelector(anchor)?.getBoundingClientRect() ?? null;
871
+ }
872
+ if (anchor instanceof DOMRect) return anchor;
873
+ return anchor?.current?.getBoundingClientRect() ?? null;
874
+ }
875
+ function useAnchorRect(anchor, active) {
876
+ const [rect, setRect] = useState(null);
877
+ const read = useCallback(() => resolveAnchorRect(anchor), [anchor]);
878
+ useEffect(() => {
879
+ if (!active || typeof document === "undefined") {
880
+ setRect(null);
881
+ return;
882
+ }
883
+ const update = () => setRect(read());
884
+ update();
885
+ window.addEventListener("scroll", update, true);
886
+ window.addEventListener("resize", update);
887
+ let raf = 0;
888
+ let tries = 0;
889
+ const poll = () => {
890
+ const found = read();
891
+ if (found) {
892
+ setRect(found);
893
+ } else if (tries++ < 40) {
894
+ raf = requestAnimationFrame(poll);
895
+ }
896
+ };
897
+ if (!read()) raf = requestAnimationFrame(poll);
898
+ return () => {
899
+ window.removeEventListener("scroll", update, true);
900
+ window.removeEventListener("resize", update);
901
+ if (raf) cancelAnimationFrame(raf);
902
+ };
903
+ }, [active, read]);
904
+ return rect;
905
+ }
906
+ function placeCard(placement, rect, size) {
907
+ const vw = typeof window !== "undefined" ? window.innerWidth : 1024;
908
+ const vh = typeof window !== "undefined" ? window.innerHeight : 768;
909
+ let top = 0;
910
+ let left = 0;
911
+ switch (placement) {
912
+ case "top":
913
+ top = rect.top - size.h - GAP;
914
+ left = rect.left + rect.width / 2 - size.w / 2;
915
+ break;
916
+ case "left":
917
+ left = rect.left - size.w - GAP;
918
+ top = rect.top + rect.height / 2 - size.h / 2;
919
+ break;
920
+ case "right":
921
+ left = rect.right + GAP;
922
+ top = rect.top + rect.height / 2 - size.h / 2;
923
+ break;
924
+ case "bottom":
925
+ default:
926
+ top = rect.bottom + GAP;
927
+ left = rect.left + rect.width / 2 - size.w / 2;
928
+ break;
929
+ }
930
+ left = Math.max(EDGE, Math.min(left, vw - size.w - EDGE));
931
+ top = Math.max(EDGE, Math.min(top, vh - size.h - EDGE));
932
+ return { top, left };
933
+ }
934
+ var Coachmark = ({
935
+ open,
936
+ anchor,
937
+ placement = "bottom",
938
+ title,
939
+ children,
940
+ onDismiss,
941
+ onPrimary,
942
+ primaryLabel,
943
+ onSecondary,
944
+ secondaryLabel,
945
+ showBeacon = false,
946
+ fallbackCentered = false,
947
+ className,
948
+ ...rest
949
+ }) => {
950
+ const cardRef = useRef(null);
951
+ const { t } = useTranslate();
952
+ const rect = useAnchorRect(anchor, open);
953
+ const [pos, setPos] = useState(null);
954
+ const centered = open && !rect && fallbackCentered;
955
+ useLayoutEffect(() => {
956
+ if (!open || !rect || !cardRef.current) {
957
+ setPos(null);
958
+ return;
959
+ }
960
+ const size = {
961
+ w: cardRef.current.offsetWidth,
962
+ h: cardRef.current.offsetHeight
963
+ };
964
+ setPos(placeCard(placement, rect, size));
965
+ }, [open, rect, placement, children, title]);
966
+ useEffect(() => {
967
+ if (!open) return;
968
+ const onKey = (e) => {
969
+ if (e.key === "Escape") onDismiss();
970
+ };
971
+ window.addEventListener("keydown", onKey);
972
+ return () => window.removeEventListener("keydown", onKey);
973
+ }, [open, onDismiss]);
974
+ if (!open || typeof document === "undefined") return null;
975
+ if (!rect && !centered) return null;
976
+ const hasFooter = Boolean(onPrimary || onSecondary);
977
+ const cardStyle = centered ? { top: "50%", left: "50%", transform: "translate(-50%, -50%)" } : pos ? { top: pos.top, left: pos.left } : { top: -9999, left: -9999 };
978
+ const card = /* @__PURE__ */ jsxs(
979
+ Box,
980
+ {
981
+ ref: cardRef,
982
+ bg: "surface",
983
+ border: true,
984
+ rounded: "lg",
985
+ padding: "md",
986
+ ...domPassthrough(rest),
987
+ role: "dialog",
988
+ "aria-label": rest["aria-label"] ?? title,
989
+ className: cn(
990
+ "shadow-elevation-popover",
991
+ "fixed z-50 max-w-xs w-72 transition-opacity duration-fast",
992
+ centered || pos ? "opacity-100" : "opacity-0",
993
+ className
994
+ ),
995
+ style: cardStyle,
996
+ children: [
997
+ /* @__PURE__ */ jsx(
998
+ Button,
999
+ {
1000
+ variant: "ghost",
1001
+ size: "sm",
1002
+ icon: "close",
1003
+ "aria-label": t("aria.dismiss"),
1004
+ onClick: onDismiss,
1005
+ className: "absolute top-1 right-1 text-[var(--color-muted-foreground)] hover:text-[var(--color-foreground)]"
1006
+ }
1007
+ ),
1008
+ title && /* @__PURE__ */ jsx(Typography, { variant: "body1", weight: "semibold", className: "pr-6 mb-1", children: title }),
1009
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "muted", as: "div", children }),
1010
+ hasFooter && /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center justify-end gap-2", children: [
1011
+ onSecondary && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: onSecondary, children: secondaryLabel ?? t("coachmark.skip") }),
1012
+ onPrimary && /* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", onClick: onPrimary, children: primaryLabel ?? t("coachmark.gotIt") })
1013
+ ] })
1014
+ ]
1015
+ }
1016
+ );
1017
+ const beacon = showBeacon && rect ? /* @__PURE__ */ jsx(
1018
+ "div",
1019
+ {
1020
+ className: "fixed z-50 pointer-events-none",
1021
+ style: {
1022
+ top: rect.top + rect.height / 2 - 6,
1023
+ left: rect.left + rect.width / 2 - 6
1024
+ },
1025
+ "aria-hidden": "true",
1026
+ children: /* @__PURE__ */ jsxs("span", { className: "relative flex h-3 w-3", children: [
1027
+ /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-[var(--color-primary)] opacity-75" }),
1028
+ /* @__PURE__ */ jsx("span", { className: "relative inline-flex h-3 w-3 rounded-full bg-[var(--color-primary)]" })
1029
+ ] })
1030
+ }
1031
+ ) : null;
1032
+ return /* @__PURE__ */ jsx(ThemedPortal, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
1033
+ beacon,
1034
+ card
1035
+ ] }) });
1036
+ };
1037
+ Coachmark.displayName = "Coachmark";
1038
+ var DIM = "fixed z-[45] bg-scrim";
1039
+ var OnboardingSpotlight = ({
1040
+ steps,
1041
+ stepIndex,
1042
+ onNext,
1043
+ onSkip,
1044
+ onFinish,
1045
+ cutoutPadding = 6
1046
+ }) => {
1047
+ const { t } = useTranslate();
1048
+ const step = steps[stepIndex];
1049
+ const rect = useAnchorRect(step?.anchor ?? "", Boolean(step));
1050
+ if (!step || typeof document === "undefined") return null;
1051
+ const isLast = stepIndex >= steps.length - 1;
1052
+ const backdrop = rect ? (() => {
1053
+ const p = cutoutPadding;
1054
+ const top = Math.max(0, rect.top - p);
1055
+ const left = Math.max(0, rect.left - p);
1056
+ const right = rect.right + p;
1057
+ const bottom = rect.bottom + p;
1058
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1059
+ /* @__PURE__ */ jsx("div", { className: DIM, style: { top: 0, left: 0, right: 0, height: top } }),
1060
+ /* @__PURE__ */ jsx("div", { className: DIM, style: { top: bottom, left: 0, right: 0, bottom: 0 } }),
1061
+ /* @__PURE__ */ jsx("div", { className: DIM, style: { top, left: 0, width: left, height: bottom - top } }),
1062
+ /* @__PURE__ */ jsx("div", { className: DIM, style: { top, left: right, right: 0, height: bottom - top } })
1063
+ ] });
1064
+ })() : /* @__PURE__ */ jsx("div", { className: cn(DIM, "inset-0") });
1065
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1066
+ /* @__PURE__ */ jsx(ThemedPortal, { children: backdrop }),
1067
+ /* @__PURE__ */ jsxs(
1068
+ Coachmark,
1069
+ {
1070
+ open: true,
1071
+ anchor: step.anchor,
1072
+ placement: step.placement ?? "bottom",
1073
+ fallbackCentered: true,
1074
+ title: step.title,
1075
+ onDismiss: onSkip,
1076
+ onSecondary: onSkip,
1077
+ secondaryLabel: t("coachmark.skip"),
1078
+ onPrimary: isLast ? onFinish : onNext,
1079
+ primaryLabel: isLast ? t("common.done") : t("nav.next"),
1080
+ children: [
1081
+ /* @__PURE__ */ jsx("span", { children: step.body }),
1082
+ /* @__PURE__ */ jsx("span", { className: "mt-3 flex items-center gap-1.5", children: steps.map((_, i) => /* @__PURE__ */ jsx(
1083
+ "span",
1084
+ {
1085
+ className: cn(
1086
+ "h-1.5 w-1.5 rounded-full",
1087
+ i === stepIndex ? "bg-[var(--color-primary)]" : "bg-[var(--color-border)]"
1088
+ )
1089
+ },
1090
+ i
1091
+ )) })
1092
+ ]
1093
+ }
1094
+ )
1095
+ ] });
1096
+ };
1097
+ OnboardingSpotlight.displayName = "OnboardingSpotlight";
1098
+
1099
+ // src/components/core/organisms/types.ts
1100
+ var EntityDisplayEvents = {
1101
+ SORT: "SORT",
1102
+ PAGINATE: "PAGINATE",
1103
+ SEARCH: "SEARCH",
1104
+ FILTER: "FILTER",
1105
+ CLEAR_FILTERS: "CLEAR_FILTERS",
1106
+ SELECT: "SELECT",
1107
+ DESELECT: "DESELECT"
1108
+ };
1109
+
1110
+ export { ALL_PRESETS, AssetPicker, Coachmark, CollapsibleSection, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EntityDisplayEvents, FEATURE_TYPES, IconPicker, NodeSlotEditor, OnboardingSpotlight, PropertyInspector, StatusBar, TERRAIN_COLORS, TerrainPalette, boardEntity, bool, calculateAttackTargets, calculateValidMoves, createInitialGameState, makeAsset, makeAssetMap, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, pendulum, projectileMotion, rows, springOscillator, str, unitHealth, unitPosition, unitTeam, useAnchorRect, useUnitSpriteAtlas, vec2 };