@mudlet/mudlet-web 0.5.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/README.md +1 -1
  2. package/dist-lib/analytics.d.ts +27 -0
  3. package/dist-lib/assets/fonts/Vera.woff2 +0 -0
  4. package/dist-lib/assets/fonts/VeraBI.woff2 +0 -0
  5. package/dist-lib/assets/fonts/VeraBd.woff2 +0 -0
  6. package/dist-lib/assets/fonts/VeraIt.woff2 +0 -0
  7. package/dist-lib/assets/mapParser.worker-DrVZ3wg_.js +9 -0
  8. package/dist-lib/backupImport-wt8r7JXI.js +233 -0
  9. package/dist-lib/branding.d.ts +111 -13
  10. package/dist-lib/db/sqliteClient.d.ts +195 -7
  11. package/dist-lib/hooks/useAutoReconnect.d.ts +61 -0
  12. package/dist-lib/hooks/useDocumentFullscreen.d.ts +23 -0
  13. package/dist-lib/hooks/useKeyboardShortcuts.d.ts +37 -0
  14. package/dist-lib/hooks/useRecordLastPlayed.d.ts +10 -0
  15. package/dist-lib/import/applyMudletProfile.d.ts +35 -9
  16. package/dist-lib/import/backupImport.d.ts +118 -0
  17. package/dist-lib/import/collectProfileExport.d.ts +33 -2
  18. package/dist-lib/import/defaultPackages.d.ts +57 -14
  19. package/dist-lib/import/defaults/CF-loader/CF-loader.mpackage +0 -0
  20. package/dist-lib/import/defaults/MedBootstrap/MedBootstrap.mpackage +0 -0
  21. package/dist-lib/import/defaults/deleteOldProfiles/deleteOldProfiles.mpackage +0 -0
  22. package/dist-lib/import/defaults/echo/echo.mpackage +0 -0
  23. package/dist-lib/import/defaults/enable-accessibility/enable-accessibility.mpackage +0 -0
  24. package/dist-lib/import/defaults/generic_mapper/generic_mapper.mpackage +0 -0
  25. package/dist-lib/import/defaults/gui-drop/gui-drop.mpackage +0 -0
  26. package/dist-lib/import/defaults/icesus-loader/icesus-loader.mpackage +0 -0
  27. package/dist-lib/import/defaults/mg-loader/mg-loader.mpackage +0 -0
  28. package/dist-lib/import/defaults/mudlet-base-ui/mudlet-base-ui.mpackage +0 -0
  29. package/dist-lib/import/defaults/mudlet-mapper.xml +1215 -389
  30. package/dist-lib/import/mudletControlChars.d.ts +14 -0
  31. package/dist-lib/import/mudletHost.d.ts +73 -10
  32. package/dist-lib/import/mudletLink.d.ts +53 -2
  33. package/dist-lib/import/mudletProfileExport.d.ts +38 -5
  34. package/dist-lib/import/mudletProfileImport.d.ts +110 -12
  35. package/dist-lib/import/mudletVariables.d.ts +4 -3
  36. package/dist-lib/import/mudletWriteback.d.ts +15 -1
  37. package/dist-lib/import/mudletXmlImport.d.ts +46 -0
  38. package/dist-lib/import/packageFonts.d.ts +33 -0
  39. package/dist-lib/import/packageInstaller.d.ts +111 -7
  40. package/dist-lib/import/qtProfileData.d.ts +10 -0
  41. package/dist-lib/import/remotePackageInstall.d.ts +23 -7
  42. package/dist-lib/import/zipEntries.d.ts +45 -0
  43. package/dist-lib/index.d.ts +7 -3
  44. package/dist-lib/index.js +50508 -29836
  45. package/dist-lib/logging/SessionLogger.d.ts +75 -15
  46. package/dist-lib/map/MapSelectionOverlay.d.ts +2 -2
  47. package/dist-lib/map/MapStore.d.ts +387 -60
  48. package/dist-lib/map/MudletHighlightOverlay.d.ts +2 -2
  49. package/dist-lib/map/{MudixMapReader.d.ts → MudletMapReader.d.ts} +2 -2
  50. package/dist-lib/map/areaGraph.d.ts +120 -0
  51. package/dist-lib/map/environmentKit.d.ts +36 -0
  52. package/dist-lib/map/labelPixmap.d.ts +90 -0
  53. package/dist-lib/map/mapImageExport.d.ts +36 -2
  54. package/dist-lib/map/mapStyle.d.ts +11 -0
  55. package/dist-lib/map/mapVersion.d.ts +66 -0
  56. package/dist-lib/map/pathfinding.d.ts +2 -2
  57. package/dist-lib/mud/CharLoginController.d.ts +230 -0
  58. package/dist-lib/mud/ItemIdSequence.d.ts +1 -1
  59. package/dist-lib/mud/MudSession.d.ts +279 -22
  60. package/dist-lib/mud/PatternEngine.d.ts +153 -14
  61. package/dist-lib/mud/aliases/AliasEngine.d.ts +55 -9
  62. package/dist-lib/mud/autoLogin.d.ts +59 -0
  63. package/dist-lib/mud/commandSplit.d.ts +9 -0
  64. package/dist-lib/mud/connection/LineAssembler.d.ts +38 -11
  65. package/dist-lib/mud/connection/MudClient.d.ts +291 -53
  66. package/dist-lib/mud/connection/SubnegotiationRepair.d.ts +24 -0
  67. package/dist-lib/mud/connection/TelnetNegotiator.d.ts +208 -68
  68. package/dist-lib/mud/connection/telnetDebug.d.ts +8 -8
  69. package/dist-lib/mud/events.d.ts +102 -23
  70. package/dist-lib/mud/games/bundledGames.d.ts +12 -7
  71. package/dist-lib/mud/games/gameLinks.d.ts +40 -0
  72. package/dist-lib/mud/games/icons/3Kingdoms.png +0 -0
  73. package/dist-lib/mud/games/icons/3Scapes.png +0 -0
  74. package/dist-lib/mud/games/icons/achaea.png +0 -0
  75. package/dist-lib/mud/games/icons/aetolia.png +0 -0
  76. package/dist-lib/mud/games/icons/banner_astaria.png +0 -0
  77. package/dist-lib/mud/games/icons/banner_darkmists.png +0 -0
  78. package/dist-lib/mud/games/icons/banner_dreamland.png +0 -0
  79. package/dist-lib/mud/games/icons/banner_petria.jpg +0 -0
  80. package/dist-lib/mud/games/icons/banner_ropmud.png +0 -0
  81. package/dist-lib/mud/games/icons/blackmud.png +0 -0
  82. package/dist-lib/mud/games/icons/carrionfields.png +0 -0
  83. package/dist-lib/mud/games/icons/dragonfire_icon.png +0 -0
  84. package/dist-lib/mud/games/icons/fed2-logo.png +0 -0
  85. package/dist-lib/mud/games/icons/icesus_480x120.png +0 -0
  86. package/dist-lib/mud/games/icons/imperian.png +0 -0
  87. package/dist-lib/mud/games/icons/infinity_480x120.png +0 -0
  88. package/dist-lib/mud/games/icons/lusternia.png +0 -0
  89. package/dist-lib/mud/games/icons/morgengrauen_480x120.png +0 -0
  90. package/dist-lib/mud/games/icons/mudlet-tutorial.png +0 -0
  91. package/dist-lib/mud/games/icons/phoenixmud_480x120.png +0 -0
  92. package/dist-lib/mud/games/icons/starmourn.png +0 -0
  93. package/dist-lib/mud/games/icons/voidmud_icon.png +0 -0
  94. package/dist-lib/mud/games/icons/wotmudicon.png +0 -0
  95. package/dist-lib/mud/games/websiteLinks.d.ts +21 -0
  96. package/dist-lib/mud/keybindings/KeyEngine.d.ts +110 -4
  97. package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +2 -2
  98. package/dist-lib/mud/keybindings/keyEventTarget.d.ts +61 -0
  99. package/dist-lib/mud/keybindings/qtKeys.d.ts +91 -12
  100. package/dist-lib/mud/protocol/atcp.d.ts +19 -0
  101. package/dist-lib/mud/protocol/byteString.d.ts +24 -0
  102. package/dist-lib/mud/protocol/charLoginFlow.d.ts +243 -16
  103. package/dist-lib/mud/protocol/charset.d.ts +111 -46
  104. package/dist-lib/mud/protocol/codePages.d.ts +10 -0
  105. package/dist-lib/mud/protocol/constants.d.ts +17 -10
  106. package/dist-lib/mud/protocol/echo.d.ts +23 -27
  107. package/dist-lib/mud/protocol/gmcp.d.ts +36 -6
  108. package/dist-lib/mud/protocol/index.d.ts +3 -2
  109. package/dist-lib/mud/protocol/luaLiteral.d.ts +12 -0
  110. package/dist-lib/mud/protocol/mccp.d.ts +83 -1
  111. package/dist-lib/mud/protocol/mnes.d.ts +41 -58
  112. package/dist-lib/mud/protocol/msdp.d.ts +11 -4
  113. package/dist-lib/mud/protocol/msp.d.ts +3 -2
  114. package/dist-lib/mud/protocol/mssp.d.ts +9 -4
  115. package/dist-lib/mud/protocol/multiByte.d.ts +51 -0
  116. package/dist-lib/mud/protocol/multiByteEncode.d.ts +42 -0
  117. package/dist-lib/mud/protocol/mxp.d.ts +193 -14
  118. package/dist-lib/mud/protocol/oauthClientFlow.d.ts +128 -0
  119. package/dist-lib/mud/protocol/qtCodePages.generated.d.ts +1 -0
  120. package/dist-lib/mud/protocol/tlsCodes.d.ts +40 -3
  121. package/dist-lib/mud/replay/ReplayPlayer.d.ts +16 -1
  122. package/dist-lib/mud/replay/replayFormat.d.ts +29 -2
  123. package/dist-lib/mud/text/Console.d.ts +255 -49
  124. package/dist-lib/mud/text/FormatState.d.ts +137 -14
  125. package/dist-lib/mud/text/ansiEscapes.d.ts +32 -16
  126. package/dist-lib/mud/text/colorParsers.d.ts +14 -2
  127. package/dist-lib/mud/text/colorSpaceId.d.ts +2 -0
  128. package/dist-lib/mud/text/colors.d.ts +17 -10
  129. package/dist-lib/mud/text/controlCharacterMode.d.ts +1 -1
  130. package/dist-lib/mud/text/hyperlinkVisibility.d.ts +1 -1
  131. package/dist-lib/mud/text/lineBreak.d.ts +5 -0
  132. package/dist-lib/mud/text/serverWrap.d.ts +2 -2
  133. package/dist-lib/mud/text/textAnalyzer.d.ts +79 -0
  134. package/dist-lib/mud/text/unicodeRuns.d.ts +11 -0
  135. package/dist-lib/mud/text/unicodeTables.generated.d.ts +3 -0
  136. package/dist-lib/mud/text/wcwidth.d.ts +27 -22
  137. package/dist-lib/mud/timers/TimerEngine.d.ts +163 -11
  138. package/dist-lib/mud/timers/workerClock.d.ts +67 -0
  139. package/dist-lib/mud/triggers/TriggerEngine.d.ts +449 -47
  140. package/dist-lib/mud/triggers/legacyColorPatterns.d.ts +58 -0
  141. package/dist-lib/mud/triggers/pcre/Pcre2.d.ts +83 -1
  142. package/dist-lib/oauth-callback.html +94 -0
  143. package/dist-lib/pcre2Wasm.d.ts +54 -0
  144. package/dist-lib/pcre2Wasm.js +241 -0
  145. package/dist-lib/scripting/EngineHost.d.ts +45 -21
  146. package/dist-lib/scripting/IScriptingRuntime.d.ts +103 -27
  147. package/dist-lib/scripting/MxpFrameManager.d.ts +10 -1
  148. package/dist-lib/scripting/ScriptingAPI.d.ts +1030 -213
  149. package/dist-lib/scripting/ScriptingEngine.d.ts +727 -106
  150. package/dist-lib/scripting/StopwatchManager.d.ts +97 -36
  151. package/dist-lib/scripting/http/HttpService.d.ts +9 -1
  152. package/dist-lib/scripting/http/userUrl.d.ts +41 -0
  153. package/dist-lib/scripting/lua/LuaRuntime.d.ts +352 -77
  154. package/dist-lib/scripting/lua/argContracts.d.ts +71 -0
  155. package/dist-lib/scripting/lua/bindings/automation.d.ts +1 -1
  156. package/dist-lib/scripting/lua/bindings/commands.d.ts +13 -0
  157. package/dist-lib/scripting/lua/bindings/context.d.ts +20 -2
  158. package/dist-lib/scripting/lua/bindings/diagnostics.d.ts +1 -1
  159. package/dist-lib/scripting/lua/bindings/map.d.ts +1 -1
  160. package/dist-lib/scripting/lua/bindings/media.d.ts +2 -2
  161. package/dist-lib/scripting/lua/bindings/output.d.ts +1 -1
  162. package/dist-lib/scripting/lua/bindings/session.d.ts +2 -2
  163. package/dist-lib/scripting/lua/bindings/textEdit.d.ts +1 -1
  164. package/dist-lib/scripting/lua/bindings/userWindows.d.ts +1 -1
  165. package/dist-lib/scripting/lua/byteArmor.d.ts +36 -0
  166. package/dist-lib/scripting/lua/imageSize.d.ts +7 -0
  167. package/dist-lib/scripting/lua/rex.d.ts +4 -2
  168. package/dist-lib/scripting/lua/sqlRowEncoder.d.ts +6 -1
  169. package/dist-lib/scripting/lua/utf8CaseMap.d.ts +1 -0
  170. package/dist-lib/scripting/lua/utf8Patterns.d.ts +21 -1
  171. package/dist-lib/scripting/lua/wellFormedStrings.d.ts +40 -0
  172. package/dist-lib/scripting/lua/yajl.d.ts +43 -5
  173. package/dist-lib/scripting/profilesPresence.d.ts +20 -2
  174. package/dist-lib/scripting/vfs/ProfileVFS.d.ts +164 -10
  175. package/dist-lib/scripting/vfs/fsErrors.d.ts +28 -0
  176. package/dist-lib/scripting/vfs/idbCommit.d.ts +20 -0
  177. package/dist-lib/storage/appStore.d.ts +24 -9
  178. package/dist-lib/storage/hooks.d.ts +5 -1
  179. package/dist-lib/storage/index.d.ts +2 -2
  180. package/dist-lib/storage/mapStorage.d.ts +2 -0
  181. package/dist-lib/storage/persistentStorage.d.ts +3 -1
  182. package/dist-lib/storage/profileStorage.d.ts +15 -0
  183. package/dist-lib/storage/profileVfsData.d.ts +3 -3
  184. package/dist-lib/storage/schema.d.ts +512 -40
  185. package/dist-lib/storage/storageMigration.d.ts +82 -0
  186. package/dist-lib/storage-g5V1b-c1.js +2039 -0
  187. package/dist-lib/styles.css +1 -1
  188. package/dist-lib/ui/AboutModal.d.ts +1 -1
  189. package/dist-lib/ui/BrandLoginFields.d.ts +1 -1
  190. package/dist-lib/ui/BrowserSignInModal.d.ts +23 -0
  191. package/dist-lib/ui/CmdLineMenuRegistry.d.ts +14 -5
  192. package/dist-lib/ui/CommandBar.d.ts +8 -8
  193. package/dist-lib/ui/ConnectionFormModal.d.ts +20 -1
  194. package/dist-lib/ui/ConnectionScreen.d.ts +9 -1
  195. package/dist-lib/ui/GameLinkPrompt.d.ts +28 -0
  196. package/dist-lib/ui/HelpModal.d.ts +5 -1
  197. package/dist-lib/ui/MapSymbolUsageModal.d.ts +32 -0
  198. package/dist-lib/ui/MouseEventRegistry.d.ts +31 -4
  199. package/dist-lib/ui/NotepadModal.d.ts +22 -0
  200. package/dist-lib/ui/ResizableModal.d.ts +16 -1
  201. package/dist-lib/ui/SettingsModal.d.ts +10 -1
  202. package/dist-lib/ui/TlsAlertBanner.d.ts +3 -1
  203. package/dist-lib/ui/Toolbar.d.ts +22 -1
  204. package/dist-lib/ui/VaultManageButton.d.ts +10 -5
  205. package/dist-lib/ui/VaultModal.d.ts +3 -0
  206. package/dist-lib/ui/buttons/ButtonsBar.d.ts +3 -1
  207. package/dist-lib/ui/buttons/inactiveButtons.d.ts +25 -0
  208. package/dist-lib/ui/cmdline/CommandLineManager.d.ts +19 -0
  209. package/dist-lib/ui/cmdline/plainText.d.ts +16 -0
  210. package/dist-lib/ui/cmdline/subCommandLine.d.ts +78 -0
  211. package/dist-lib/ui/cmdline/useCmdLineSelection.d.ts +26 -0
  212. package/dist-lib/ui/cmdline/useSubCommandLineKeys.d.ts +33 -0
  213. package/dist-lib/ui/codemirror/lineParagraphMarks.d.ts +19 -0
  214. package/dist-lib/ui/codemirror/luaHover.d.ts +7 -0
  215. package/dist-lib/ui/codemirror/options.d.ts +33 -0
  216. package/dist-lib/ui/codemirror/theme.d.ts +29 -5
  217. package/dist-lib/ui/commands/addonCommands.d.ts +134 -0
  218. package/dist-lib/ui/commands/appShortcuts.d.ts +86 -0
  219. package/dist-lib/ui/commands/hostCommands.d.ts +88 -0
  220. package/dist-lib/ui/commands/keyMatch.d.ts +20 -0
  221. package/dist-lib/ui/commands/keySequence.d.ts +57 -0
  222. package/dist-lib/ui/components/ContextMenu.d.ts +21 -1
  223. package/dist-lib/ui/components/FontPicker.d.ts +5 -1
  224. package/dist-lib/ui/components/useModalFocus.d.ts +13 -1
  225. package/dist-lib/ui/helpTopics.d.ts +15 -0
  226. package/dist-lib/ui/labels/LabelManager.d.ts +172 -9
  227. package/dist-lib/ui/labels/LabelOverlay.d.ts +19 -0
  228. package/dist-lib/ui/labels/backgroundImageSize.d.ts +19 -0
  229. package/dist-lib/ui/labels/labelModel.d.ts +64 -0
  230. package/dist-lib/ui/labels/qColor.d.ts +13 -0
  231. package/dist-lib/ui/labels/qtCss.d.ts +12 -4
  232. package/dist-lib/ui/landmarks.d.ts +9 -0
  233. package/dist-lib/ui/launcher/ActionMenu.d.ts +19 -0
  234. package/dist-lib/ui/launcher/GameDetails.d.ts +21 -0
  235. package/dist-lib/ui/launcher/GameSection.d.ts +18 -0
  236. package/dist-lib/ui/launcher/LauncherSearch.d.ts +23 -0
  237. package/dist-lib/ui/launcher/ProfileArt.d.ts +20 -0
  238. package/dist-lib/ui/launcher/ProfileSection.d.ts +43 -0
  239. package/dist-lib/ui/launcher/launcherModel.d.ts +72 -0
  240. package/dist-lib/ui/layout/overlayLayerOrder.d.ts +2 -2
  241. package/dist-lib/ui/menu/MenuBar.d.ts +31 -0
  242. package/dist-lib/ui/menu/SplitButton.d.ts +39 -0
  243. package/dist-lib/ui/menu/anchoredPopup.d.ts +74 -0
  244. package/dist-lib/ui/menu/appMenus.d.ts +65 -0
  245. package/dist-lib/ui/menu/menuModel.d.ts +88 -0
  246. package/dist-lib/ui/menu/toolbarModel.d.ts +56 -0
  247. package/dist-lib/ui/notepad.d.ts +76 -0
  248. package/dist-lib/ui/openSignInPage.d.ts +14 -0
  249. package/dist-lib/ui/output/OutputContextMenu.d.ts +14 -1
  250. package/dist-lib/ui/output/OutputRenderer.d.ts +5 -0
  251. package/dist-lib/ui/output/OutputSearchBar.d.ts +5 -1
  252. package/dist-lib/ui/output/StickyOutputPanel.d.ts +17 -3
  253. package/dist-lib/ui/output/TextAnalyzerModal.d.ts +25 -0
  254. package/dist-lib/ui/output/caretMode.d.ts +3 -2
  255. package/dist-lib/ui/output/clearSplit.d.ts +11 -0
  256. package/dist-lib/ui/output/outputCopy.d.ts +41 -2
  257. package/dist-lib/ui/output/outputRows.d.ts +43 -0
  258. package/dist-lib/ui/output/selectionGesture.d.ts +35 -0
  259. package/dist-lib/ui/output/wordSelection.d.ts +33 -0
  260. package/dist-lib/ui/search/matcher.d.ts +14 -4
  261. package/dist-lib/ui/settings/SettingsShell.d.ts +91 -0
  262. package/dist-lib/ui/settings/ShortcutEditor.d.ts +13 -0
  263. package/dist-lib/ui/sound/SoundManager.d.ts +210 -44
  264. package/dist-lib/ui/sound/closedCaption.d.ts +4 -1
  265. package/dist-lib/ui/sound/mediaDirection.d.ts +35 -0
  266. package/dist-lib/ui/tabCompletion.d.ts +53 -0
  267. package/dist-lib/ui/textedit/TextEditManager.d.ts +11 -2
  268. package/dist-lib/ui/useOpenProfiles.d.ts +1 -1
  269. package/dist-lib/ui/video/VideoManager.d.ts +7 -0
  270. package/dist-lib/ui/windows/WindowManager.d.ts +452 -37
  271. package/dist-lib/ui/windows/panels/ScriptEditorPanel.d.ts +14 -0
  272. package/dist-lib/ui/windows/panels/ScriptSearch.d.ts +6 -1
  273. package/dist-lib/ui/windows/panels/TextPanel.d.ts +4 -1
  274. package/dist-lib/ui/windows/panels/VariablesView.d.ts +37 -7
  275. package/dist-lib/ui/windows/panels/WindowCmdLine.d.ts +4 -2
  276. package/dist-lib/ui/windows/panels/aliasLoop.d.ts +24 -0
  277. package/dist-lib/ui/windows/panels/editorClipboard.d.ts +45 -0
  278. package/dist-lib/ui/windows/panels/editorUndo.d.ts +79 -0
  279. package/dist-lib/ui/windows/panels/mapAreaChange.d.ts +10 -0
  280. package/dist-lib/utils/appShellCache.d.ts +25 -0
  281. package/dist-lib/utils/fontFamilyName.d.ts +13 -0
  282. package/dist-lib/utils/fontLoader.d.ts +31 -0
  283. package/dist-lib/utils/formatBytes.d.ts +4 -0
  284. package/dist-lib/utils/mustBeOneOf.d.ts +9 -0
  285. package/dist-lib/utils/profileLock.d.ts +1 -1
  286. package/dist-lib/utils/systemTheme.d.ts +24 -0
  287. package/dist-lib/utils/timeZone.d.ts +10 -0
  288. package/dist-lib/vault/CredentialVault.d.ts +51 -5
  289. package/dist-lib/vault/deviceUnlock.d.ts +47 -0
  290. package/dist-lib/vault/vaultAccess.d.ts +24 -2
  291. package/dist-lib/vault/vaultHelpTopic.d.ts +9 -0
  292. package/dist-lib/vault/vaultRecord.d.ts +33 -1
  293. package/dist-lib/vfs-sw.js +220 -11
  294. package/dist-lib/vite.d.ts +1 -1
  295. package/dist-lib/vite.js +66 -43
  296. package/package.json +23 -15
  297. package/dist-lib/assets/mapParser.worker-t-3rd1zR.js +0 -9
  298. package/dist-lib/mud/connection/PingTracker.d.ts +0 -41
  299. package/dist-lib/ui/BundledGameGrid.d.ts +0 -21
  300. package/dist-lib/ui/ConnectionGrid.d.ts +0 -21
  301. package/dist-lib/ui/bufferWords.d.ts +0 -38
@@ -0,0 +1,72 @@
1
+ import type { BundledGame } from '../../mud/games/bundledGames';
2
+ import { type MudConnection } from '../../storage';
3
+ /**
4
+ * The launcher's non-visual logic: ordering profiles by when they were last
5
+ * played, the colours a profile with no icon is drawn in, and the "Where to?"
6
+ * search. Kept free of React so each rule is testable on its own.
7
+ */
8
+ /** Profiles most recently played first. Never-played profiles follow, in their
9
+ * stored order — so a player upgrading from the drag-ordered launcher sees
10
+ * their own arrangement until they start playing, rather than a shuffle. */
11
+ export declare function sortByLastPlayed(connections: readonly MudConnection[]): MudConnection[];
12
+ /** "just now", "5 minutes ago", "yesterday", "3 weeks ago" — coarse on purpose:
13
+ * it orients ("which one did I play last?"), it isn't a log. Null when the
14
+ * profile has never been played. */
15
+ export declare function formatLastPlayed(ts: number | undefined, now?: number): string | null;
16
+ export interface Aurora {
17
+ /** Near-black background tinted toward the main hue. */
18
+ base: string;
19
+ /** The swept colours: main hue, a neighbour, and a contrasting accent. */
20
+ colors: [string, string, string];
21
+ /** Where the conic sweep starts, in degrees. */
22
+ angle: number;
23
+ /** Centre of the sweep, as percentages of the box. */
24
+ at: [number, number];
25
+ }
26
+ /** The aurora a profile with no icon is drawn with. Derived from the name
27
+ * alone, so a profile looks the same on every visit and in every tab, and
28
+ * nothing has to be stored. */
29
+ export declare function auroraFor(name: string): Aurora;
30
+ /** CSS `background` for an aurora, ready for an inline style. */
31
+ export declare function auroraBackground(a: Aurora): string;
32
+ /** A server typed straight into the search box. */
33
+ export type TypedAddress = {
34
+ mode: 'mud';
35
+ host: string;
36
+ port: number;
37
+ label: string;
38
+ } | {
39
+ mode: 'websocket';
40
+ url: string;
41
+ label: string;
42
+ };
43
+ /**
44
+ * Read `host`, `host:port` or a `ws(s)://` URL out of the search box. A bare
45
+ * word is only taken as a host when it is `localhost` — otherwise every name
46
+ * typed while searching ("achaea") would also be offered as a server.
47
+ */
48
+ export declare function parseTypedAddress(query: string): TypedAddress | null;
49
+ export interface LauncherResults {
50
+ profiles: MudConnection[];
51
+ games: BundledGame[];
52
+ address: TypedAddress | null;
53
+ }
54
+ export declare const SEARCH_GROUP_LIMIT = 5;
55
+ /**
56
+ * What the "Where to?" box offers for `query`: the player's profiles, catalogue
57
+ * games, and the text itself as a server address when it reads as one.
58
+ * Descriptions are deliberately not searched — "dark" would match half the
59
+ * catalogue, and the box is for going somewhere, not browsing.
60
+ */
61
+ export declare function searchLauncher(query: string, connections: readonly MudConnection[], games: readonly BundledGame[]): LauncherResults;
62
+ /** The profile the "Continue playing" banner features: the one played most
63
+ * recently, or — before anything has been played — the first in the
64
+ * player's own order. */
65
+ export declare function pickHero(connections: readonly MudConnection[]): MudConnection | null;
66
+ /**
67
+ * Fold a new order of the grid's profiles back into the full stored order.
68
+ * The banner's profile isn't in the grid, so it keeps the slot it had —
69
+ * otherwise every drag would shove it to the end, and it would reappear
70
+ * there once another profile took the banner.
71
+ */
72
+ export declare function mergeGridOrder(allIds: readonly string[], gridIds: readonly string[]): string[];
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Flat per-viewport z-order for every kind of overlay content: nested windows /
3
3
  * mini-consoles (including the embedded mapper), labels, overlay command lines,
4
- * and scroll boxes. This is the mudix analogue of Mudlet's Qt widget stack.
4
+ * and scroll boxes. This is the Mudlet Web analogue of Mudlet's Qt widget stack.
5
5
  *
6
6
  * ## Why flat (and not a container tree)
7
7
  *
@@ -17,7 +17,7 @@
17
17
  * an opened config menu rendered *under* a sibling mapper. Flat is correct.)
18
18
  *
19
19
  * Correct z-order alone is not enough: every overlay leaf must also render into
20
- * the SAME CSS stacking context for these ranks to take visual effect. mudix
20
+ * the SAME CSS stacking context for these ranks to take visual effect. Mudlet Web
21
21
  * ensures that by rendering all four overlay kinds under one wrapper per
22
22
  * viewport (`.main-overlay-root` for main; the panel viewport for a userwindow)
23
23
  * whose descendants' inline z-indices all compete directly. See
@@ -0,0 +1,31 @@
1
+ import type { MenuNode, TopMenu } from './menuModel';
2
+ import './MenuBar.css';
3
+ interface MenuListProps {
4
+ items: MenuNode[];
5
+ /** Dismiss the whole bar — what running an entry does. */
6
+ onCloseAll: () => void;
7
+ /** Dismiss this list only, handing focus back to whatever opened it.
8
+ * Absent on a top-level dropdown, where Escape belongs to the bar. */
9
+ onCloseSelf?: () => void;
10
+ /** Put focus on the first entry — set when the list was opened from the
11
+ * keyboard. A list opened by pointer leaves focus alone, as Qt does. */
12
+ autoFocus?: boolean;
13
+ /** A flyout opens beside its parent entry; a dropdown under its title. */
14
+ flyout?: boolean;
15
+ /**
16
+ * The control this list drops from — a menu title, a split button. Given
17
+ * one, the list is portaled to that element's document body and placed
18
+ * against its rect, the way Qt opens a menu as its own top-level window.
19
+ * Without it (a flyout, which opens inside a list that is already portaled)
20
+ * the list stays where it is written and positions itself in CSS.
21
+ */
22
+ anchor?: HTMLElement | null;
23
+ }
24
+ export declare function MenuList({ items, onCloseAll, onCloseSelf, autoFocus, flyout, anchor }: MenuListProps): import("react/jsx-runtime").JSX.Element;
25
+ interface MenuBarProps {
26
+ menus: TopMenu[];
27
+ /** Accessible name for the bar. */
28
+ label?: string;
29
+ }
30
+ export declare function MenuBar({ menus, label }: MenuBarProps): import("react/jsx-runtime").JSX.Element;
31
+ export {};
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Qt's `QToolButton::MenuButtonPopup` — a button with an arrow beside it.
3
+ *
4
+ * Mudlet's toolbar uses it for the things that are one action most of the time
5
+ * and a short list of related ones occasionally: Connect (with Disconnect and
6
+ * Close profile behind the arrow), Mute, the package managers. Pressing the
7
+ * button half runs the default action; pressing the arrow half opens the rest.
8
+ * The two halves are separate controls on purpose — a player reaching for
9
+ * Connect should never open a menu by accident.
10
+ */
11
+ import { type ReactNode } from 'react';
12
+ import type { MenuNode } from './menuModel';
13
+ interface SplitButtonProps {
14
+ /** The default action's face — icon and label, as any other toolbar button. */
15
+ children: ReactNode;
16
+ title?: string;
17
+ /** The default action: what the button half does. */
18
+ onClick: () => void;
19
+ /** Drawn pressed, for a default action that is a state rather than a verb
20
+ * (Mudlet's Mute button is its "Mute all media" action, checkable). */
21
+ checked?: boolean;
22
+ /** Everything behind the arrow, including the default action itself — Qt
23
+ * lists it there too, and a menu missing the thing the button does reads
24
+ * as if the button were something else. */
25
+ items: MenuNode[];
26
+ /** Accessible name for the arrow half, e.g. "Connection actions". */
27
+ menuLabel: string;
28
+ /**
29
+ * Lay the whole thing out as siblings instead: the default action, then
30
+ * each entry as its own full-width button. For the hamburger, where a popup
31
+ * inside a popup is not a menu anyone can drive.
32
+ */
33
+ stacked?: boolean;
34
+ /** Run after any of these actions — the hamburger closes itself with it.
35
+ * Stacked layout only; the popup closes on its own. */
36
+ onAnyAction?: () => void;
37
+ }
38
+ export declare function SplitButton({ children, title, onClick, checked, items, menuLabel, stacked, onAnyAction, }: SplitButtonProps): import("react/jsx-runtime").JSX.Element;
39
+ export {};
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Placing a popup against the control that opened it.
3
+ *
4
+ * In Qt a menu is its own top-level window: it is placed at a screen position
5
+ * and paints over everything, and nothing about the widget that opened it can
6
+ * trap it. The web has no such thing — a dropdown written inside the bar that
7
+ * owns it is stuck in that bar's stacking context, which is what forced the
8
+ * menu bar above the floating windows and cost every click on a window drawn
9
+ * in its strip (issue #145).
10
+ *
11
+ * So the popups portal to `<body>` and are placed here instead, against the
12
+ * rect of their anchor. Same idea as ResizableModal's portal, one step further:
13
+ * the modal only needed to escape, a menu also has to land somewhere.
14
+ */
15
+ import { type RefObject } from 'react';
16
+ export interface AnchorRect {
17
+ left: number;
18
+ top: number;
19
+ right: number;
20
+ bottom: number;
21
+ }
22
+ export interface PopupSize {
23
+ width: number;
24
+ height: number;
25
+ }
26
+ export interface ViewportSize {
27
+ width: number;
28
+ height: number;
29
+ }
30
+ export interface Placement {
31
+ left: number;
32
+ top: number;
33
+ }
34
+ /** Which of the popup's edges lines up with the same edge of its anchor. */
35
+ export type PopupAlign = 'start' | 'end';
36
+ /**
37
+ * Where a popup of `size` goes when hung off `anchor` inside `viewport`.
38
+ *
39
+ * Below the anchor by default, flipping above it when there is no room; aligned
40
+ * on the `align` edge, flipping to the other one when it would overrun. Always
41
+ * clamped into the viewport afterwards, because on a small enough window a
42
+ * popup overruns whichever way it is flipped and a menu half off the screen is
43
+ * a menu with entries nobody can reach.
44
+ *
45
+ * Pure, and in viewport coordinates — the popup is `position: fixed`.
46
+ */
47
+ export declare function placePopup(anchor: AnchorRect, size: PopupSize, viewport: ViewportSize, align?: PopupAlign): Placement;
48
+ /**
49
+ * Live placement for a portaled popup: null until it has been measured, so the
50
+ * caller can keep it out of sight for the one frame before it knows where it
51
+ * goes. Re-measures on resize and on any scroll (capture phase — the anchor may
52
+ * ride inside a scroller that is not the document).
53
+ *
54
+ * `deps` re-runs the measurement when the popup's own contents change size.
55
+ */
56
+ export declare function useAnchoredPopup(anchor: HTMLElement | null | undefined, popupRef: RefObject<HTMLElement | null>, align?: PopupAlign, deps?: unknown): Placement | null;
57
+ /**
58
+ * Style for a portaled popup, before and after it has been measured.
59
+ *
60
+ * Rendered hidden rather than not at all: it has to be in the document for its
61
+ * size to be measurable, and `useAnchoredPopup` measures in a layout effect, so
62
+ * the unplaced frame never reaches the screen.
63
+ */
64
+ export declare function anchoredStyle(placement: Placement | null): React.CSSProperties;
65
+ /**
66
+ * Did a pointer event land on the control or on a popup it opened?
67
+ *
68
+ * The dismiss-on-outside-click handlers used to answer this with
69
+ * `root.contains(target)`. A portaled popup is no longer a descendant of the
70
+ * control that owns it, so containment alone now reports every click on the
71
+ * menu's own entries as "outside" — the menu would unmount on pointerdown and
72
+ * the entry's click never fire.
73
+ */
74
+ export declare function inPopupSurface(root: HTMLElement | null | undefined, target: EventTarget | null): boolean;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The client's own menus — Mudlet's menu bar (main_window.ui) as far as a
3
+ * browser tab has anything to put under it.
4
+ *
5
+ * The titles and their order are Mudlet's: Games, Toolbox, Options, Window,
6
+ * Help, About. What hangs under them is not, and deliberately so — Mudlet's
7
+ * "Reattach detached windows", "Always on top" and "Minimize" describe a
8
+ * desktop window this client does not own, and an entry that cannot work is
9
+ * worse than an absent one. What is here is what the toolbar already does,
10
+ * reachable a second way, plus the two things the toolbar has no room for
11
+ * (timestamps, About).
12
+ *
13
+ * A brand can hide any stock toolbar button; the same decision hides the menu
14
+ * entry, so a brand that removed a feature does not find it again in a menu.
15
+ * Menus that empty out that way are dropped rather than drawn blank.
16
+ */
17
+ import type { StockToolbarButton } from '../../branding';
18
+ import type { AppCommandId } from '../commands/appShortcuts';
19
+ import type { MenuNode, TopMenu } from './menuModel';
20
+ export interface AppMenuContext {
21
+ /** The brand's stock-button filter, shared with the toolbar row. */
22
+ show: (id: StockToolbarButton) => boolean;
23
+ appName: string;
24
+ /** The Games menu's entries — the same list the toolbar's Connect split
25
+ * button holds, passed in rather than rebuilt here. The two are one
26
+ * control on two surfaces. */
27
+ connectionItems: MenuNode[];
28
+ replayRecording: boolean;
29
+ /** Playback speed of the running replay, or null when none is playing. */
30
+ replaySpeed: number | null;
31
+ /** The document is in real fullscreen, and whether the browser allows it. */
32
+ fullscreen: boolean;
33
+ fullscreenAvailable: boolean;
34
+ /** Mudlet's main-toolbar visibility. The menu bar's own switch is NOT here:
35
+ * an entry that hides the menu it is in leaves no way back to itself, so
36
+ * that one lives in the settings only. */
37
+ showToolbar: boolean;
38
+ showTimestamps: boolean;
39
+ /** Mudlet's three media mute entries — the same list the toolbar's Mute
40
+ * split button holds, passed in rather than rebuilt so the two surfaces
41
+ * cannot come to describe the gates differently. */
42
+ muteItems: MenuNode[];
43
+ /** The key bound to a command right now, for the menu to draw beside its
44
+ * label — the entry ids below ARE the command ids, so the lookup needs no
45
+ * second table to go wrong. */
46
+ shortcutFor: (id: AppCommandId) => string | undefined;
47
+ onOpenScripts: () => void;
48
+ onOpenMap: () => void;
49
+ /** setConfig("mapperButton", "disabled") is in force. */
50
+ mapDisabled?: boolean;
51
+ onOpenFiles: () => void;
52
+ onOpenNotepad: () => void;
53
+ onOpenLogs: () => void;
54
+ onToggleReplayRecording: () => void;
55
+ onReplayStop: () => void;
56
+ onOpenSettings: () => void;
57
+ onToggleTimestamps: () => void;
58
+ onToggleFullscreen: () => void;
59
+ onToggleToolbar: () => void;
60
+ onOpenDocs: () => void;
61
+ onOpenHelp: () => void;
62
+ onOpenAbout: () => void;
63
+ onReportBug: () => void;
64
+ }
65
+ export declare function buildAppMenus(ctx: AppMenuContext): TopMenu[];
@@ -0,0 +1,88 @@
1
+ /**
2
+ * The shape of the client's own menu bar, and where a package's menu commands
3
+ * land in it.
4
+ *
5
+ * Mudlet shows a command in two places: on the toolbar and on the menu bar. The
6
+ * toolbar half has been here since addCommand landed; this is the other half,
7
+ * and it is the reason `menuPath` exists at all — a path with nowhere to lead
8
+ * was accepted and then quietly dropped.
9
+ *
10
+ * The menus themselves mirror main_window.ui (Games, Toolbox, Options, Window,
11
+ * Help, About) as far as a browser tab has anything to put under them. Entries
12
+ * Mudlet has and a web client cannot (always-on-top, minimise, reattach
13
+ * detached windows, IRC) are absent rather than present-and-dead.
14
+ */
15
+ import type { ReactNode } from 'react';
16
+ /**
17
+ * A command asking to be placed, from whichever source. Packages place them
18
+ * with `addCommand` from Lua and a host app with the exported `commands`
19
+ * registry; by the time they reach here the difference is gone, which is the
20
+ * point — a white-label client's own command should sit in a menu exactly the
21
+ * way a package's does.
22
+ */
23
+ export interface PlacedCommand {
24
+ /** Unique across sources, so the two cannot collide: `lua:3`, `host:7`. */
25
+ id: string;
26
+ name: string;
27
+ /** An image URL from a package's setCommandIcon, or any node a host app
28
+ * passed. */
29
+ icon?: ReactNode;
30
+ tooltip?: string;
31
+ /** Where on the menu bar. Empty means {@link DEFAULT_ADDON_MENU}. */
32
+ menuPath?: string;
33
+ shortcut?: string;
34
+ enabled?: boolean;
35
+ checked?: boolean;
36
+ run: () => void;
37
+ }
38
+ export interface MenuAction {
39
+ kind: 'action';
40
+ /** Stable within its menu — the React key, and what the tests match on. */
41
+ id: string;
42
+ label: string;
43
+ /** Qt-style key sequence, drawn right-aligned. Display only: the registry
44
+ * reserves a package's key, but nothing dispatches it yet. */
45
+ shortcut?: string;
46
+ /** Drawn with a tick. `undefined` means the entry is not checkable at all,
47
+ * which is not the same as unchecked — only the first gets no tick column
48
+ * reserved by the screen reader. */
49
+ checked?: boolean;
50
+ disabled?: boolean;
51
+ /** A package's icon path, or a node from a host app or a brand. Sized to
52
+ * the label by the stylesheet either way. */
53
+ icon?: ReactNode;
54
+ run: () => void;
55
+ }
56
+ export interface MenuSeparator {
57
+ kind: 'separator';
58
+ id: string;
59
+ }
60
+ export interface MenuSubmenu {
61
+ kind: 'submenu';
62
+ id: string;
63
+ label: string;
64
+ items: MenuNode[];
65
+ }
66
+ export type MenuNode = MenuAction | MenuSeparator | MenuSubmenu;
67
+ export interface TopMenu {
68
+ id: string;
69
+ label: string;
70
+ items: MenuNode[];
71
+ }
72
+ /**
73
+ * Where a menu command with no path of its own goes. Toolbox is where Mudlet
74
+ * keeps the things packages bring (the package and module managers, the script
75
+ * editor), so a command that named no menu is at least among its own kind
76
+ * rather than opening a top-level menu holding one entry.
77
+ */
78
+ export declare const DEFAULT_ADDON_MENU = "Toolbox";
79
+ /**
80
+ * The menu bar with `commands` placed in it, leaving `menus` untouched.
81
+ *
82
+ * A path's first segment names a top-level menu — an existing one when the
83
+ * title matches, a new one at the end of the bar otherwise — and each further
84
+ * segment a submenu under it. Commands arrive in placement order, which is the
85
+ * order they are drawn in: a package that adds three commands gets them in the
86
+ * order it added them, under or beside whatever was already there.
87
+ */
88
+ export declare function placeCommands(menus: TopMenu[], commands: readonly PlacedCommand[]): TopMenu[];
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The button row as data, so a brand can rearrange it.
3
+ *
4
+ * The row used to be a fixed run of JSX with a `hide` list threaded through it,
5
+ * which let a brand subtract and append and nothing else — no reordering, no
6
+ * renaming, no putting its own command between two stock ones. A white-label
7
+ * client is somebody else's product wearing this client's engine, and the shape
8
+ * of its chrome is theirs to decide, so the row is now a list they are handed
9
+ * and hand back.
10
+ *
11
+ * The menu bar's counterpart is `TopMenu[]` in `menuModel.ts`; the two
12
+ * transforms in `BrandToolbarConfig` take and return these.
13
+ */
14
+ import type { ReactNode } from 'react';
15
+ import type { MenuNode } from './menuModel';
16
+ /** A plain button. */
17
+ export interface ToolbarButtonItem {
18
+ kind: 'button';
19
+ /** Stable across renders — the React key, and what a brand matches on to
20
+ * find an item in the stock list. Stock ids are the `StockToolbarButton`
21
+ * names; a package's are `lua:<n>`, a host app's `host:<n>`. */
22
+ id: string;
23
+ label: ReactNode;
24
+ icon?: ReactNode;
25
+ title?: string;
26
+ /** Drawn pressed. */
27
+ checked?: boolean;
28
+ disabled?: boolean;
29
+ /** Extra class, for the few stock buttons with a look of their own (the
30
+ * recorder's pulsing dot, a package command's pulse). */
31
+ className?: string;
32
+ /** Custom properties, for a package's `setCommandPulse` colours. */
33
+ style?: React.CSSProperties;
34
+ run: () => void;
35
+ }
36
+ /** Qt's split button: a default action with the rest behind an arrow. */
37
+ export interface ToolbarSplitItem {
38
+ kind: 'split';
39
+ id: string;
40
+ label: ReactNode;
41
+ icon?: ReactNode;
42
+ title?: string;
43
+ checked?: boolean;
44
+ /** Accessible name for the arrow half. */
45
+ menuLabel: string;
46
+ items: MenuNode[];
47
+ run: () => void;
48
+ }
49
+ /** Anything that is not a button — the replay speed controls, or whatever a
50
+ * brand wants to drop into the row. Rendered as given. */
51
+ export interface ToolbarCustomItem {
52
+ kind: 'custom';
53
+ id: string;
54
+ node: ReactNode;
55
+ }
56
+ export type ToolbarItem = ToolbarButtonItem | ToolbarSplitItem | ToolbarCustomItem;
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Mudlet's Notepad (`dlgNotepad`) — the per-profile scratch pad on the main
3
+ * toolbar, as a set of named tabs.
4
+ *
5
+ * Kept where and how desktop keeps it, so a profile moved between the two
6
+ * keeps its notes: `notes.json` in the profile's home directory
7
+ * (`getMudletHomeDir() .. "/notes.json"`), shaped
8
+ * `{ version: 1, tabs: [{ name, content }], activeTab }`. Before tabs, desktop
9
+ * kept one plain-text note in `notes_utf8.txt` (and before that `notes.txt`);
10
+ * with no `notes.json` the first of those found becomes a tab named "Notes",
11
+ * as `dlgNotepad::migrateOldNotesFile` does. The old file is left in place.
12
+ */
13
+ import type { ProfileVFS } from '../scripting/vfs/ProfileVFS';
14
+ export declare const NOTES_FILE = "notes.json";
15
+ /** Desktop's pre-tab files, newest first — the order `migrateOldNotesFile` tries them. */
16
+ export declare const LEGACY_NOTES_FILES: readonly ["notes_utf8.txt", "notes.txt"];
17
+ /** Name of the tab a fresh, unreadable or migrated notepad starts with. */
18
+ export declare const DEFAULT_TAB_NAME = "Notes";
19
+ /** Name of a tab added with + or Ctrl+T. */
20
+ export declare const NEW_TAB_NAME = "New Note";
21
+ /**
22
+ * How long typing must pause before the notes are written. Desktop saves on a
23
+ * two-minute timer and on close, which is safe there because closing the
24
+ * window is the only way out; a browser tab can be closed, reloaded or
25
+ * discarded with the dialog open, so the wait is short here.
26
+ */
27
+ export declare const NOTES_SAVE_DELAY_MS = 1000;
28
+ /** Desktop's `mSendTimer` interval: one line every 300ms, the first after the
29
+ * first tick, so a pasted list doesn't flood the game. */
30
+ export declare const NOTES_SEND_INTERVAL_MS = 300;
31
+ export interface NoteTab {
32
+ name: string;
33
+ content: string;
34
+ }
35
+ export interface NotepadData {
36
+ tabs: NoteTab[];
37
+ activeTab: number;
38
+ }
39
+ export declare function notesPath(vfs: ProfileVFS, file?: string): string;
40
+ /**
41
+ * `notes.json`'s text as a notepad, with desktop's `restore()` leniency: a
42
+ * file that is not JSON, not an object, or has no tabs opens as one empty
43
+ * "Notes" tab rather than failing, and an out-of-range `activeTab` is ignored.
44
+ */
45
+ export declare function parseNotepad(json: string): NotepadData;
46
+ /** What `dlgNotepad::save()` writes (Qt's indented JSON is four spaces). */
47
+ export declare function serializeNotepad(data: NotepadData): string;
48
+ /** The profile's notes: `notes.json`, else a migrated single note, else one empty tab. */
49
+ export declare function loadNotepad(vfs: ProfileVFS): NotepadData;
50
+ export declare function saveNotepad(vfs: ProfileVFS, data: NotepadData): void;
51
+ /** Moves the tab at `from` to `to` (tabs are drag-movable, as desktop's are),
52
+ * keeping the same tab active. */
53
+ export declare function moveTab(data: NotepadData, from: number, to: number): NotepadData;
54
+ /** Closes a tab; the last one cannot be closed (`dlgNotepad::closeTab`). */
55
+ export declare function closeTab(data: NotepadData, index: number): NotepadData;
56
+ /**
57
+ * The next case-insensitive occurrence of `query` from the selection, wrapping
58
+ * around the end (or the start, going backwards) — `QPlainTextEdit::find`,
59
+ * retried from the other end as `slot_findNext`/`slot_findPrevious` do.
60
+ * Forward search starts after the selection, so a repeated Find steps on
61
+ * rather than finding the match already selected. Null when there is none.
62
+ */
63
+ export declare function findInNotes(text: string, query: string, selStart: number, selEnd: number, backwards?: boolean): {
64
+ start: number;
65
+ end: number;
66
+ } | null;
67
+ /** How many times `query` occurs (case-insensitively), for the find bar. */
68
+ export declare function countInNotes(text: string, query: string): number;
69
+ /** The line the caret is on (`QTextCursor::LineUnderCursor`), without its newline. */
70
+ export declare function lineAt(text: string, caret: number): string;
71
+ /**
72
+ * What a send queue actually sends: each line with the prepend text in front,
73
+ * blank lines skipped (`slot_sendNextLine` passes over them, though they still
74
+ * take their 300ms turn — the caller keeps that pacing).
75
+ */
76
+ export declare function lineToSend(line: string, prepend: string): string | null;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Open a sign-in page in a new tab without asking, as Mudlet does with
3
+ * `QDesktopServices::openUrl`. A page may only open a tab while it holds
4
+ * transient user activation — a few seconds after a click or key press — and
5
+ * a GMCP `Char.Login.URL` usually lands well inside that window, because it
6
+ * answers the menu choice the player just typed. Outside it the browser would
7
+ * block the popup, so this returns false without trying and the caller falls
8
+ * back to the sign-in dialog, whose button is a gesture of its own.
9
+ *
10
+ * Opened blank first, so whether the browser allowed it is known (a
11
+ * `noopener` open always returns null), then cut off from us before it
12
+ * navigates: the provider's page gets no handle back on ours.
13
+ */
14
+ export declare function openSignInPage(url: string, win?: Window): boolean;
@@ -8,10 +8,20 @@ interface OutputContextMenuProps {
8
8
  y: number;
9
9
  /** Whether the selection touches this window (gates the copy actions). */
10
10
  hasSelection: boolean;
11
+ /** Whether this console holds any line at all. "Copy as image" needs only
12
+ * this, since it falls back to the visible area. */
13
+ hasContent: boolean;
11
14
  onSelectAll: () => void;
12
15
  onCopy: () => void;
13
16
  onCopyHtml: () => void;
14
17
  onCopyImage: () => void;
18
+ /** Display name of the configured web-search engine, e.g. "Google". */
19
+ searchEngine: string;
20
+ onSearchOnline: () => void;
21
+ /** Mudlet's "Analyse characters" — omitted unless the profile's "Enable
22
+ * text analyzer" preference is on, exactly as desktop gates it
23
+ * (TTextEdit::contextMenuEvent, src/TTextEdit.cpp:2482). */
24
+ onAnalyseText?: () => void;
15
25
  /** Opens the find bar — only the main console passes this. */
16
26
  onFind?: () => void;
17
27
  /** Timestamp toggle — only the main console passes these. */
@@ -19,7 +29,10 @@ interface OutputContextMenuProps {
19
29
  onToggleTimestamps?: () => void;
20
30
  /** Script-provided entries (Mudlet addMouseEvent). */
21
31
  extraItems?: OutputMenuExtraItem[];
32
+ /** Where focus goes when the menu closes — the command line, not the console
33
+ * that the right-click focused. See {@link ContextMenu}. */
34
+ returnFocusTo?: () => HTMLElement | null | undefined;
22
35
  onClose: () => void;
23
36
  }
24
- export declare function OutputContextMenu({ x, y, hasSelection, onSelectAll, onCopy, onCopyHtml, onCopyImage, onFind, showTimestamps, onToggleTimestamps, extraItems, onClose, }: OutputContextMenuProps): import("react/jsx-runtime").JSX.Element;
37
+ export declare function OutputContextMenu({ x, y, hasSelection, hasContent, onSelectAll, onCopy, onCopyHtml, onCopyImage, searchEngine, onSearchOnline, onAnalyseText, onFind, showTimestamps, onToggleTimestamps, extraItems, returnFocusTo, onClose, }: OutputContextMenuProps): import("react/jsx-runtime").JSX.Element;
25
38
  export {};
@@ -63,6 +63,11 @@ export type OutputRendererControls = {
63
63
  clearStickyArea: () => void;
64
64
  push: (message: string | AnsiAwareBuffer, type?: string, timestamp?: number) => void;
65
65
  clear: () => void;
66
+ /** True while a tail scroll is queued for the next frame — lines have
67
+ * landed that the view is about to follow. A scroll event seen in that
68
+ * window measures the view against content it has not caught up with
69
+ * yet, so it is not the reader scrolling away (#456). */
70
+ isTailScrollQueued: () => boolean;
66
71
  };
67
72
  export declare function setupOutputRenderer(source: MessageSource | null, { outputWrapper, sentinel, stickyArea, isSplitView, stickyLines, suppressSplitView, followTail, onCursorReady, }: OutputHandlerOptions): OutputRendererControls;
68
73
  export {};
@@ -9,6 +9,10 @@ interface OutputSearchBarProps {
9
9
  * output selection, so pressing the shortcut again behaves like the
10
10
  * browser's find rather than doing nothing. */
11
11
  focusNonce: number;
12
+ /** Whether that open moves focus into the box (default true). False for
13
+ * the F3 that `f3SearchEnabled` lets open the bar: it must leave focus on
14
+ * the command line, as desktop's toolbar search does. */
15
+ takeFocus?: boolean;
12
16
  onClose: () => void;
13
17
  /** Rebuilds the split-view panel from the (now highlighted) source lines —
14
18
  * its contents are clones, so marks only reach it via a re-populate. */
@@ -21,5 +25,5 @@ interface OutputSearchBarProps {
21
25
  * See docs/config-api.md. */
22
26
  a11ySearch?: boolean;
23
27
  }
24
- export declare function OutputSearchBar({ session, outputRef, focusNonce, onClose, refreshSticky, commandInputRef, a11ySearch, }: OutputSearchBarProps): import("react/jsx-runtime").JSX.Element;
28
+ export declare function OutputSearchBar({ session, outputRef, focusNonce, takeFocus, onClose, refreshSticky, commandInputRef, a11ySearch, }: OutputSearchBarProps): import("react/jsx-runtime").JSX.Element;
25
29
  export {};
@@ -1,5 +1,6 @@
1
1
  import type React from 'react';
2
2
  import { type OutputMenuExtraItem } from './OutputContextMenu';
3
+ import { type SelectionBounds } from './outputCopy';
3
4
  interface StickyOutputPanelProps {
4
5
  outputRef: React.RefObject<HTMLDivElement | null>;
5
6
  sentinelRef: React.RefObject<HTMLDivElement | null>;
@@ -15,10 +16,23 @@ interface StickyOutputPanelProps {
15
16
  onToggleTimestamps?: () => void;
16
17
  /** Opens the find bar from the right-click menu — main console only. */
17
18
  onFind?: () => void;
19
+ /** What to call this console in a copied HTML document's title — the
20
+ * profile name for the main console, the window name for a script one. */
21
+ sourceName?: string;
18
22
  /** Script-provided right-click entries (Mudlet addMouseEvent), evaluated
19
- * lazily when the menu opens since the registry can change. */
20
- getMenuExtraItems?: () => OutputMenuExtraItem[];
23
+ * lazily when the menu opens since the registry can change. Given the
24
+ * console's selection as it stood when the menu opened, which is what
25
+ * the entry's handler is passed. */
26
+ getMenuExtraItems?: (selection: SelectionBounds) => OutputMenuExtraItem[];
21
27
  commandInputRef?: React.RefObject<HTMLInputElement | HTMLTextAreaElement | null>;
28
+ /** When set, the scrollback becomes a named, Tab-reachable landmark — an id
29
+ * a skip link can target, a region role, and an explicit tab stop rather
30
+ * than Chrome's "focusable scrollable region" behaviour, which the other
31
+ * browsers do not all provide. Only the main console passes these: a script
32
+ * window already sits inside its own labelled region (TextPanel), and
33
+ * nesting a second one there would only add noise to the landmark list. */
34
+ regionId?: string;
35
+ regionLabel?: string;
22
36
  className?: string;
23
37
  fontSize?: number;
24
38
  fontFamily?: string;
@@ -28,5 +42,5 @@ interface StickyOutputPanelProps {
28
42
  wrapIndent?: number;
29
43
  wrapHangingIndent?: number;
30
44
  }
31
- export declare function StickyOutputPanel({ outputRef, sentinelRef, stickyAreaRef, isSplitView, scrollToBottom, background, backgroundExtra, foreground, showTimestamps, onToggleTimestamps, onFind, getMenuExtraItems, commandInputRef, className, fontSize, fontFamily, lineHeight, wrapAt, wrapIndent, wrapHangingIndent, }: StickyOutputPanelProps): import("react/jsx-runtime").JSX.Element;
45
+ export declare function StickyOutputPanel({ outputRef, sentinelRef, stickyAreaRef, isSplitView, scrollToBottom, background, backgroundExtra, foreground, showTimestamps, onToggleTimestamps, onFind, sourceName, getMenuExtraItems, commandInputRef, regionId, regionLabel, className, fontSize, fontFamily, lineHeight, wrapAt, wrapIndent, wrapHangingIndent, }: StickyOutputPanelProps): import("react/jsx-runtime").JSX.Element;
32
46
  export {};