@mudlet/mudlet-web 0.4.5 → 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.
- package/README.md +1 -1
- package/dist-lib/analytics.d.ts +27 -0
- package/dist-lib/assets/fonts/Vera.woff2 +0 -0
- package/dist-lib/assets/fonts/VeraBI.woff2 +0 -0
- package/dist-lib/assets/fonts/VeraBd.woff2 +0 -0
- package/dist-lib/assets/fonts/VeraIt.woff2 +0 -0
- package/dist-lib/assets/mapParser.worker-DrVZ3wg_.js +9 -0
- package/dist-lib/backupImport-wt8r7JXI.js +233 -0
- package/dist-lib/branding.d.ts +111 -13
- package/dist-lib/db/sqliteClient.d.ts +195 -7
- package/dist-lib/hooks/useAutoReconnect.d.ts +61 -0
- package/dist-lib/hooks/useDocumentFullscreen.d.ts +23 -0
- package/dist-lib/hooks/useKeyboardShortcuts.d.ts +37 -0
- package/dist-lib/hooks/useRecordLastPlayed.d.ts +10 -0
- package/dist-lib/import/applyMudletProfile.d.ts +35 -9
- package/dist-lib/import/backupImport.d.ts +118 -0
- package/dist-lib/import/collectProfileExport.d.ts +33 -2
- package/dist-lib/import/defaultPackages.d.ts +57 -14
- package/dist-lib/import/defaults/CF-loader/CF-loader.mpackage +0 -0
- package/dist-lib/import/defaults/MedBootstrap/MedBootstrap.mpackage +0 -0
- package/dist-lib/import/defaults/deleteOldProfiles/deleteOldProfiles.mpackage +0 -0
- package/dist-lib/import/defaults/echo/echo.mpackage +0 -0
- package/dist-lib/import/defaults/enable-accessibility/enable-accessibility.mpackage +0 -0
- package/dist-lib/import/defaults/generic_mapper/generic_mapper.mpackage +0 -0
- package/dist-lib/import/defaults/gui-drop/gui-drop.mpackage +0 -0
- package/dist-lib/import/defaults/icesus-loader/icesus-loader.mpackage +0 -0
- package/dist-lib/import/defaults/mg-loader/mg-loader.mpackage +0 -0
- package/dist-lib/import/defaults/mudlet-base-ui/mudlet-base-ui.mpackage +0 -0
- package/dist-lib/import/defaults/mudlet-mapper.xml +1215 -389
- package/dist-lib/import/mudletControlChars.d.ts +14 -0
- package/dist-lib/import/mudletHost.d.ts +73 -10
- package/dist-lib/import/mudletLink.d.ts +53 -2
- package/dist-lib/import/mudletProfileExport.d.ts +38 -5
- package/dist-lib/import/mudletProfileImport.d.ts +110 -12
- package/dist-lib/import/mudletVariables.d.ts +4 -3
- package/dist-lib/import/mudletWriteback.d.ts +15 -1
- package/dist-lib/import/mudletXmlImport.d.ts +46 -0
- package/dist-lib/import/packageFonts.d.ts +33 -0
- package/dist-lib/import/packageInstaller.d.ts +111 -7
- package/dist-lib/import/qtProfileData.d.ts +10 -0
- package/dist-lib/import/remotePackageInstall.d.ts +23 -7
- package/dist-lib/import/zipEntries.d.ts +45 -0
- package/dist-lib/index.d.ts +7 -3
- package/dist-lib/index.js +50660 -29735
- package/dist-lib/logging/SessionLogger.d.ts +75 -15
- package/dist-lib/map/MapSelectionOverlay.d.ts +2 -2
- package/dist-lib/map/MapStore.d.ts +432 -59
- package/dist-lib/map/MudletHighlightOverlay.d.ts +2 -2
- package/dist-lib/map/{MudixMapReader.d.ts → MudletMapReader.d.ts} +2 -2
- package/dist-lib/map/areaGraph.d.ts +120 -0
- package/dist-lib/map/environmentKit.d.ts +36 -0
- package/dist-lib/map/labelPixmap.d.ts +90 -0
- package/dist-lib/map/mapImageExport.d.ts +36 -2
- package/dist-lib/map/mapStyle.d.ts +11 -0
- package/dist-lib/map/mapVersion.d.ts +66 -0
- package/dist-lib/map/pathfinding.d.ts +2 -2
- package/dist-lib/mud/CharLoginController.d.ts +230 -0
- package/dist-lib/mud/ItemIdSequence.d.ts +1 -1
- package/dist-lib/mud/MudSession.d.ts +279 -22
- package/dist-lib/mud/PatternEngine.d.ts +153 -14
- package/dist-lib/mud/aliases/AliasEngine.d.ts +55 -9
- package/dist-lib/mud/autoLogin.d.ts +59 -0
- package/dist-lib/mud/commandSplit.d.ts +9 -0
- package/dist-lib/mud/connection/LineAssembler.d.ts +38 -11
- package/dist-lib/mud/connection/MudClient.d.ts +291 -53
- package/dist-lib/mud/connection/SubnegotiationRepair.d.ts +24 -0
- package/dist-lib/mud/connection/TelnetNegotiator.d.ts +208 -68
- package/dist-lib/mud/connection/telnetDebug.d.ts +8 -8
- package/dist-lib/mud/events.d.ts +102 -23
- package/dist-lib/mud/games/bundledGames.d.ts +12 -7
- package/dist-lib/mud/games/gameLinks.d.ts +40 -0
- package/dist-lib/mud/games/icons/3Kingdoms.png +0 -0
- package/dist-lib/mud/games/icons/3Scapes.png +0 -0
- package/dist-lib/mud/games/icons/achaea.png +0 -0
- package/dist-lib/mud/games/icons/aetolia.png +0 -0
- package/dist-lib/mud/games/icons/banner_astaria.png +0 -0
- package/dist-lib/mud/games/icons/banner_darkmists.png +0 -0
- package/dist-lib/mud/games/icons/banner_dreamland.png +0 -0
- package/dist-lib/mud/games/icons/banner_petria.jpg +0 -0
- package/dist-lib/mud/games/icons/banner_ropmud.png +0 -0
- package/dist-lib/mud/games/icons/blackmud.png +0 -0
- package/dist-lib/mud/games/icons/carrionfields.png +0 -0
- package/dist-lib/mud/games/icons/dragonfire_icon.png +0 -0
- package/dist-lib/mud/games/icons/fed2-logo.png +0 -0
- package/dist-lib/mud/games/icons/icesus_480x120.png +0 -0
- package/dist-lib/mud/games/icons/imperian.png +0 -0
- package/dist-lib/mud/games/icons/infinity_480x120.png +0 -0
- package/dist-lib/mud/games/icons/lusternia.png +0 -0
- package/dist-lib/mud/games/icons/morgengrauen_480x120.png +0 -0
- package/dist-lib/mud/games/icons/mudlet-tutorial.png +0 -0
- package/dist-lib/mud/games/icons/phoenixmud_480x120.png +0 -0
- package/dist-lib/mud/games/icons/starmourn.png +0 -0
- package/dist-lib/mud/games/icons/voidmud_icon.png +0 -0
- package/dist-lib/mud/games/icons/wotmudicon.png +0 -0
- package/dist-lib/mud/games/websiteLinks.d.ts +21 -0
- package/dist-lib/mud/keybindings/KeyEngine.d.ts +110 -4
- package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +2 -2
- package/dist-lib/mud/keybindings/keyEventTarget.d.ts +61 -0
- package/dist-lib/mud/keybindings/qtKeys.d.ts +91 -12
- package/dist-lib/mud/protocol/atcp.d.ts +19 -0
- package/dist-lib/mud/protocol/byteString.d.ts +24 -0
- package/dist-lib/mud/protocol/charLoginFlow.d.ts +243 -16
- package/dist-lib/mud/protocol/charset.d.ts +111 -46
- package/dist-lib/mud/protocol/codePages.d.ts +10 -0
- package/dist-lib/mud/protocol/constants.d.ts +17 -10
- package/dist-lib/mud/protocol/echo.d.ts +23 -27
- package/dist-lib/mud/protocol/gmcp.d.ts +36 -6
- package/dist-lib/mud/protocol/index.d.ts +3 -2
- package/dist-lib/mud/protocol/luaLiteral.d.ts +12 -0
- package/dist-lib/mud/protocol/mccp.d.ts +83 -1
- package/dist-lib/mud/protocol/mnes.d.ts +41 -58
- package/dist-lib/mud/protocol/msdp.d.ts +11 -4
- package/dist-lib/mud/protocol/msp.d.ts +3 -2
- package/dist-lib/mud/protocol/mssp.d.ts +9 -4
- package/dist-lib/mud/protocol/multiByte.d.ts +51 -0
- package/dist-lib/mud/protocol/multiByteEncode.d.ts +42 -0
- package/dist-lib/mud/protocol/mxp.d.ts +193 -14
- package/dist-lib/mud/protocol/oauthClientFlow.d.ts +128 -0
- package/dist-lib/mud/protocol/qtCodePages.generated.d.ts +1 -0
- package/dist-lib/mud/protocol/tlsCodes.d.ts +40 -3
- package/dist-lib/mud/replay/ReplayPlayer.d.ts +16 -1
- package/dist-lib/mud/replay/replayFormat.d.ts +29 -2
- package/dist-lib/mud/text/Console.d.ts +255 -49
- package/dist-lib/mud/text/FormatState.d.ts +137 -14
- package/dist-lib/mud/text/ansiEscapes.d.ts +32 -16
- package/dist-lib/mud/text/colorParsers.d.ts +14 -2
- package/dist-lib/mud/text/colorSpaceId.d.ts +2 -0
- package/dist-lib/mud/text/colors.d.ts +17 -10
- package/dist-lib/mud/text/controlCharacterMode.d.ts +1 -1
- package/dist-lib/mud/text/hyperlinkVisibility.d.ts +1 -1
- package/dist-lib/mud/text/lineBreak.d.ts +5 -0
- package/dist-lib/mud/text/serverWrap.d.ts +2 -2
- package/dist-lib/mud/text/textAnalyzer.d.ts +79 -0
- package/dist-lib/mud/text/unicodeRuns.d.ts +11 -0
- package/dist-lib/mud/text/unicodeTables.generated.d.ts +3 -0
- package/dist-lib/mud/text/wcwidth.d.ts +27 -22
- package/dist-lib/mud/timers/TimerEngine.d.ts +163 -11
- package/dist-lib/mud/timers/workerClock.d.ts +67 -0
- package/dist-lib/mud/triggers/TriggerEngine.d.ts +449 -47
- package/dist-lib/mud/triggers/legacyColorPatterns.d.ts +58 -0
- package/dist-lib/mud/triggers/pcre/Pcre2.d.ts +83 -1
- package/dist-lib/oauth-callback.html +94 -0
- package/dist-lib/pcre2Wasm.d.ts +54 -0
- package/dist-lib/pcre2Wasm.js +241 -0
- package/dist-lib/scripting/EngineHost.d.ts +54 -21
- package/dist-lib/scripting/IScriptingRuntime.d.ts +103 -27
- package/dist-lib/scripting/MxpFrameManager.d.ts +10 -1
- package/dist-lib/scripting/ScriptingAPI.d.ts +1039 -213
- package/dist-lib/scripting/ScriptingEngine.d.ts +753 -103
- package/dist-lib/scripting/StopwatchManager.d.ts +97 -36
- package/dist-lib/scripting/http/HttpService.d.ts +9 -1
- package/dist-lib/scripting/http/userUrl.d.ts +41 -0
- package/dist-lib/scripting/lua/LuaRuntime.d.ts +352 -77
- package/dist-lib/scripting/lua/argContracts.d.ts +71 -0
- package/dist-lib/scripting/lua/bindings/automation.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/commands.d.ts +13 -0
- package/dist-lib/scripting/lua/bindings/context.d.ts +20 -2
- package/dist-lib/scripting/lua/bindings/diagnostics.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/map.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/media.d.ts +2 -2
- package/dist-lib/scripting/lua/bindings/output.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/session.d.ts +2 -2
- package/dist-lib/scripting/lua/bindings/textEdit.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/userWindows.d.ts +1 -1
- package/dist-lib/scripting/lua/byteArmor.d.ts +36 -0
- package/dist-lib/scripting/lua/imageSize.d.ts +7 -0
- package/dist-lib/scripting/lua/rex.d.ts +4 -2
- package/dist-lib/scripting/lua/sqlRowEncoder.d.ts +6 -1
- package/dist-lib/scripting/lua/utf8CaseMap.d.ts +1 -0
- package/dist-lib/scripting/lua/utf8Patterns.d.ts +21 -1
- package/dist-lib/scripting/lua/wellFormedStrings.d.ts +40 -0
- package/dist-lib/scripting/lua/yajl.d.ts +43 -5
- package/dist-lib/scripting/profilesPresence.d.ts +20 -2
- package/dist-lib/scripting/vfs/ProfileVFS.d.ts +164 -10
- package/dist-lib/scripting/vfs/fsErrors.d.ts +28 -0
- package/dist-lib/scripting/vfs/idbCommit.d.ts +20 -0
- package/dist-lib/storage/appStore.d.ts +24 -9
- package/dist-lib/storage/hooks.d.ts +5 -1
- package/dist-lib/storage/index.d.ts +2 -2
- package/dist-lib/storage/mapStorage.d.ts +2 -0
- package/dist-lib/storage/persistentStorage.d.ts +3 -1
- package/dist-lib/storage/profileStorage.d.ts +15 -0
- package/dist-lib/storage/profileVfsData.d.ts +3 -3
- package/dist-lib/storage/schema.d.ts +521 -44
- package/dist-lib/storage/storageMigration.d.ts +82 -0
- package/dist-lib/storage-g5V1b-c1.js +2039 -0
- package/dist-lib/styles.css +1 -1
- package/dist-lib/ui/AboutModal.d.ts +1 -1
- package/dist-lib/ui/BrandLoginFields.d.ts +1 -1
- package/dist-lib/ui/BrowserSignInModal.d.ts +23 -0
- package/dist-lib/ui/CharLoginModal.d.ts +24 -15
- package/dist-lib/ui/CmdLineMenuRegistry.d.ts +14 -5
- package/dist-lib/ui/CommandBar.d.ts +8 -8
- package/dist-lib/ui/ConnectionFormModal.d.ts +25 -1
- package/dist-lib/ui/ConnectionScreen.d.ts +9 -1
- package/dist-lib/ui/GameLinkPrompt.d.ts +28 -0
- package/dist-lib/ui/HelpModal.d.ts +5 -1
- package/dist-lib/ui/MapSymbolUsageModal.d.ts +32 -0
- package/dist-lib/ui/MouseEventRegistry.d.ts +31 -4
- package/dist-lib/ui/NotepadModal.d.ts +22 -0
- package/dist-lib/ui/ResizableModal.d.ts +16 -1
- package/dist-lib/ui/SettingsModal.d.ts +10 -1
- package/dist-lib/ui/TlsAlertBanner.d.ts +3 -1
- package/dist-lib/ui/Toolbar.d.ts +22 -1
- package/dist-lib/ui/VaultManageButton.d.ts +20 -0
- package/dist-lib/ui/VaultModal.d.ts +5 -0
- package/dist-lib/ui/VaultUnlockPrompt.d.ts +15 -0
- package/dist-lib/ui/buttons/ButtonsBar.d.ts +3 -1
- package/dist-lib/ui/buttons/inactiveButtons.d.ts +25 -0
- package/dist-lib/ui/cmdline/CommandLineManager.d.ts +19 -0
- package/dist-lib/ui/cmdline/plainText.d.ts +16 -0
- package/dist-lib/ui/cmdline/subCommandLine.d.ts +78 -0
- package/dist-lib/ui/cmdline/useCmdLineSelection.d.ts +26 -0
- package/dist-lib/ui/cmdline/useSubCommandLineKeys.d.ts +33 -0
- package/dist-lib/ui/codemirror/lineParagraphMarks.d.ts +19 -0
- package/dist-lib/ui/codemirror/luaHover.d.ts +7 -0
- package/dist-lib/ui/codemirror/options.d.ts +33 -0
- package/dist-lib/ui/codemirror/theme.d.ts +29 -5
- package/dist-lib/ui/commands/addonCommands.d.ts +134 -0
- package/dist-lib/ui/commands/appShortcuts.d.ts +86 -0
- package/dist-lib/ui/commands/hostCommands.d.ts +88 -0
- package/dist-lib/ui/commands/keyMatch.d.ts +20 -0
- package/dist-lib/ui/commands/keySequence.d.ts +57 -0
- package/dist-lib/ui/components/ContextMenu.d.ts +21 -1
- package/dist-lib/ui/components/FontPicker.d.ts +5 -1
- package/dist-lib/ui/components/useModalFocus.d.ts +13 -1
- package/dist-lib/ui/helpTopics.d.ts +15 -0
- package/dist-lib/ui/labels/LabelManager.d.ts +172 -9
- package/dist-lib/ui/labels/LabelOverlay.d.ts +19 -0
- package/dist-lib/ui/labels/backgroundImageSize.d.ts +19 -0
- package/dist-lib/ui/labels/labelModel.d.ts +64 -0
- package/dist-lib/ui/labels/qColor.d.ts +13 -0
- package/dist-lib/ui/labels/qtCss.d.ts +12 -4
- package/dist-lib/ui/landmarks.d.ts +9 -0
- package/dist-lib/ui/launcher/ActionMenu.d.ts +19 -0
- package/dist-lib/ui/launcher/GameDetails.d.ts +21 -0
- package/dist-lib/ui/launcher/GameSection.d.ts +18 -0
- package/dist-lib/ui/launcher/LauncherSearch.d.ts +23 -0
- package/dist-lib/ui/launcher/ProfileArt.d.ts +20 -0
- package/dist-lib/ui/launcher/ProfileSection.d.ts +43 -0
- package/dist-lib/ui/launcher/launcherModel.d.ts +72 -0
- package/dist-lib/ui/layout/overlayLayerOrder.d.ts +2 -2
- package/dist-lib/ui/menu/MenuBar.d.ts +31 -0
- package/dist-lib/ui/menu/SplitButton.d.ts +39 -0
- package/dist-lib/ui/menu/anchoredPopup.d.ts +74 -0
- package/dist-lib/ui/menu/appMenus.d.ts +65 -0
- package/dist-lib/ui/menu/menuModel.d.ts +88 -0
- package/dist-lib/ui/menu/toolbarModel.d.ts +56 -0
- package/dist-lib/ui/notepad.d.ts +76 -0
- package/dist-lib/ui/openSignInPage.d.ts +14 -0
- package/dist-lib/ui/output/OutputContextMenu.d.ts +14 -1
- package/dist-lib/ui/output/OutputRenderer.d.ts +5 -0
- package/dist-lib/ui/output/OutputSearchBar.d.ts +5 -1
- package/dist-lib/ui/output/StickyOutputPanel.d.ts +17 -3
- package/dist-lib/ui/output/TextAnalyzerModal.d.ts +25 -0
- package/dist-lib/ui/output/caretMode.d.ts +3 -2
- package/dist-lib/ui/output/clearSplit.d.ts +11 -0
- package/dist-lib/ui/output/outputCopy.d.ts +41 -2
- package/dist-lib/ui/output/outputRows.d.ts +43 -0
- package/dist-lib/ui/output/selectionGesture.d.ts +35 -0
- package/dist-lib/ui/output/wordSelection.d.ts +33 -0
- package/dist-lib/ui/search/matcher.d.ts +14 -4
- package/dist-lib/ui/settings/SettingsShell.d.ts +91 -0
- package/dist-lib/ui/settings/ShortcutEditor.d.ts +13 -0
- package/dist-lib/ui/sound/SoundManager.d.ts +210 -44
- package/dist-lib/ui/sound/closedCaption.d.ts +4 -1
- package/dist-lib/ui/sound/mediaDirection.d.ts +35 -0
- package/dist-lib/ui/tabCompletion.d.ts +53 -0
- package/dist-lib/ui/textedit/TextEditManager.d.ts +11 -2
- package/dist-lib/ui/useOpenProfiles.d.ts +1 -1
- package/dist-lib/ui/useVaultSaver.d.ts +26 -0
- package/dist-lib/ui/video/VideoManager.d.ts +7 -0
- package/dist-lib/ui/windows/WindowManager.d.ts +452 -37
- package/dist-lib/ui/windows/panels/ScriptEditorPanel.d.ts +14 -0
- package/dist-lib/ui/windows/panels/ScriptSearch.d.ts +6 -1
- package/dist-lib/ui/windows/panels/TextPanel.d.ts +4 -1
- package/dist-lib/ui/windows/panels/VariablesView.d.ts +37 -7
- package/dist-lib/ui/windows/panels/WindowCmdLine.d.ts +4 -2
- package/dist-lib/ui/windows/panels/aliasLoop.d.ts +24 -0
- package/dist-lib/ui/windows/panels/editorClipboard.d.ts +45 -0
- package/dist-lib/ui/windows/panels/editorUndo.d.ts +79 -0
- package/dist-lib/ui/windows/panels/mapAreaChange.d.ts +10 -0
- package/dist-lib/utils/appShellCache.d.ts +25 -0
- package/dist-lib/utils/fontFamilyName.d.ts +13 -0
- package/dist-lib/utils/fontLoader.d.ts +31 -0
- package/dist-lib/utils/formatBytes.d.ts +4 -0
- package/dist-lib/utils/mustBeOneOf.d.ts +9 -0
- package/dist-lib/utils/profileLock.d.ts +1 -1
- package/dist-lib/utils/storedCredentials.d.ts +31 -0
- package/dist-lib/utils/systemTheme.d.ts +24 -0
- package/dist-lib/utils/timeZone.d.ts +10 -0
- package/dist-lib/vault/CredentialVault.d.ts +197 -0
- package/dist-lib/vault/deviceUnlock.d.ts +47 -0
- package/dist-lib/vault/passkeyPrf.d.ts +56 -0
- package/dist-lib/vault/useVault.d.ts +8 -0
- package/dist-lib/vault/vaultAccess.d.ts +80 -0
- package/dist-lib/vault/vaultCrypto.d.ts +56 -0
- package/dist-lib/vault/vaultHelpTopic.d.ts +9 -0
- package/dist-lib/vault/vaultRecord.d.ts +92 -0
- package/dist-lib/vfs-sw.js +220 -11
- package/dist-lib/vite.d.ts +1 -1
- package/dist-lib/vite.js +66 -43
- package/package.json +22 -14
- package/dist-lib/assets/mapParser.worker-t-3rd1zR.js +0 -9
- package/dist-lib/mud/connection/PingTracker.d.ts +0 -41
- package/dist-lib/ui/BundledGameGrid.d.ts +0 -21
- package/dist-lib/ui/ConnectionGrid.d.ts +0 -21
- package/dist-lib/ui/bufferWords.d.ts +0 -38
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Mudlet's `TTrigger::scmIgnored` — "any colour here". */
|
|
2
|
+
export declare const COLOR_IGNORED = -1;
|
|
3
|
+
/** Mudlet's `TTrigger::scmDefault` — the console's own colour, a colour to
|
|
4
|
+
* match rather than an "any". */
|
|
5
|
+
export declare const COLOR_DEFAULT = -2;
|
|
6
|
+
/**
|
|
7
|
+
* The modern pattern text for a colour pair.
|
|
8
|
+
*
|
|
9
|
+
* Both channels ignored yields the empty string, exactly as
|
|
10
|
+
* `createColorPatternText` does — desktop's comment calls it "equivalent to an
|
|
11
|
+
* empty other trigger type", and an empty pattern is compacted out of the list
|
|
12
|
+
* rather than matching everything.
|
|
13
|
+
*/
|
|
14
|
+
export declare function colorPatternText(fg: number, bg: number): string;
|
|
15
|
+
/**
|
|
16
|
+
* Rewrite a pre-3.17 `FG<n>BG<n>` colour pattern into the modern form, or
|
|
17
|
+
* return the text unchanged when it is not one.
|
|
18
|
+
*
|
|
19
|
+
* Deliberately narrow: anything that is already modern, or that is neither
|
|
20
|
+
* (`FG(4)BG(-2)`, a hand-typed string), is left exactly as it was, and the
|
|
21
|
+
* runtime refuses it. Desktop does the same — its regex does not match the
|
|
22
|
+
* parenthesised form either, which is why that form matches nothing on desktop.
|
|
23
|
+
*/
|
|
24
|
+
export declare function remapLegacyColorPattern(text: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Rewrite a modern `ANSI_COLORS_F{…}_B{…}` colour pattern back into the
|
|
27
|
+
* `FG<n>BG<n>` numbering a save file uses, or return the text unchanged when it
|
|
28
|
+
* is not one.
|
|
29
|
+
*
|
|
30
|
+
* The save-file numbers are NOT the ANSI ones the runtime matches on, and
|
|
31
|
+
* Mudlet converts in both directions — `remapColorsToAnsiNumber` on the way in
|
|
32
|
+
* (XMLimport.cpp:1425) and `remapAnsiToColorNumber` on the way out
|
|
33
|
+
* (XMLexport.cpp:1031, "Revert the first 16 ANSI colour codes back to the wrong
|
|
34
|
+
* values that are still used in the save files"). Mudlet Web had only the reading
|
|
35
|
+
* half, so an exported colour trigger carried the in-memory text into the file
|
|
36
|
+
* — where desktop's reader does not recognise it, and the trigger comes back as
|
|
37
|
+
* a colour pattern nothing can parse.
|
|
38
|
+
*/
|
|
39
|
+
export declare function toSaveFileColorPattern(text: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Parse a colour-trigger pattern into its `[fg, bg]` ANSI pair, in any of the
|
|
42
|
+
* three spellings one can arrive in:
|
|
43
|
+
*
|
|
44
|
+
* - `ANSI_COLORS_F{003}_B{IGNORE}` — the wire form desktop writes, and so what
|
|
45
|
+
* every imported package and profile carries;
|
|
46
|
+
* - `FG4BG0` — the pre-3.17 save-file numbering, remapped on the way through;
|
|
47
|
+
* - `3,-1` — the plain pair the editor writes.
|
|
48
|
+
*
|
|
49
|
+
* `IGNORE` and a missing/unparsable channel are {@link COLOR_IGNORED} ("any",
|
|
50
|
+
* -1); `DEFAULT` is {@link COLOR_DEFAULT} (-2), the console's own colour, which
|
|
51
|
+
* is a colour to match rather than an "any".
|
|
52
|
+
*
|
|
53
|
+
* Shared so the trigger engine and the editor cannot disagree about what a
|
|
54
|
+
* pattern says. They did: the editor read only the plain pair, so a colour
|
|
55
|
+
* trigger that came in with a package fired correctly but showed up in the
|
|
56
|
+
* pattern row as "any/any" (mudlet-web#158).
|
|
57
|
+
*/
|
|
58
|
+
export declare function parseColorPattern(text: string): [number, number];
|
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
/** pcre2_match option: the subject has already been checked for valid UTF, so
|
|
2
|
+
* don't scan it again. Only honoured by a patched wasm — see the header. */
|
|
3
|
+
export declare const PCRE2_NO_UTF_CHECK = 1073741824;
|
|
4
|
+
/**
|
|
5
|
+
* The match limit trigger and alias patterns are compiled with, as a
|
|
6
|
+
* start-of-pattern verb. PCRE2's default is 10 000 000, which desktop's JIT
|
|
7
|
+
* gets through in a blink; the wasm build here is the interpreter, at about
|
|
8
|
+
* 50 ns a step, so a nested quantifier like `^(\w+\s?)+$` failing on an
|
|
9
|
+
* ordinary 50-character line spent half a second to several seconds per line
|
|
10
|
+
* before giving up (#435) — the page frozen all the while, for a pattern that
|
|
11
|
+
* then counts as no match anyway (#361). Half a million steps gives up in
|
|
12
|
+
* tens of milliseconds, and is still more than ten times what an ordinary
|
|
13
|
+
* pattern needs on a 20 kB line (a few tens of thousands), so no line that
|
|
14
|
+
* matched before stops matching. A pattern carrying its own
|
|
15
|
+
* `(*LIMIT_MATCH=n)` comes after this one, and its value wins.
|
|
16
|
+
* Lua's `rex` keeps the library default: it is lrexlib, where a script can
|
|
17
|
+
* read the limit back (rex.config) and handle MATCHLIMIT itself.
|
|
18
|
+
*/
|
|
19
|
+
export declare const ENGINE_MATCH_LIMIT = 500000;
|
|
20
|
+
export declare const ENGINE_MATCH_LIMIT_VERB = "(*LIMIT_MATCH=500000)";
|
|
1
21
|
export type Pcre2MatchGroup = {
|
|
2
22
|
start: number;
|
|
3
23
|
end: number;
|
|
@@ -10,17 +30,79 @@ export type Pcre2Match = {
|
|
|
10
30
|
[k: number]: Pcre2MatchGroup;
|
|
11
31
|
[k: string]: Pcre2MatchGroup | number;
|
|
12
32
|
};
|
|
33
|
+
/** `subject` without its unpaired surrogates — what Mudlet's pcre2 sees. */
|
|
34
|
+
export declare function pcreSubject(subject: string): string;
|
|
13
35
|
/** Drop the cached line so the next match re-encodes. Used after teardown or
|
|
14
36
|
* when callers want to be sure a stale buffer can't be reused. */
|
|
15
37
|
export declare function resetLineBuffer(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Whether `pattern` (as compiled, with no flags) starts with a top-level `.+`,
|
|
40
|
+
* `.+?` or `.++` that PCRE2 may be told to match ANCHORED — see the note above.
|
|
41
|
+
* Conservative: anything the scan is unsure of is a no.
|
|
42
|
+
*/
|
|
43
|
+
export declare function leadingDotPlus(pattern: string): boolean;
|
|
16
44
|
export default class Pcre2 {
|
|
17
45
|
private codePtr;
|
|
18
46
|
private matchData;
|
|
47
|
+
/** {@link leadingDotPlus} of the pattern: match it ANCHORED, stretch by stretch. */
|
|
48
|
+
private readonly dotPlus;
|
|
19
49
|
private readonly nametable;
|
|
50
|
+
/** The name table in PCRE2's own order (sorted by name), duplicates kept. */
|
|
51
|
+
private readonly nameEntries;
|
|
52
|
+
/** Whether {@link init} has resolved, so a pattern can be compiled
|
|
53
|
+
* synchronously right now. */
|
|
54
|
+
static get ready(): boolean;
|
|
20
55
|
static init(): Promise<void>;
|
|
56
|
+
/** The PCRE2 library's own version string (`pcre2_config(PCRE2_CONFIG_VERSION)`),
|
|
57
|
+
* e.g. "10.42 2022-12-11" — what lrexlib's `rex.version()` reports. */
|
|
58
|
+
static version(): string;
|
|
21
59
|
constructor(pattern: string, flags?: string);
|
|
60
|
+
/** `[name, group number]` for each named group, in PCRE2's name-table
|
|
61
|
+
* order — what lrexlib walks to add named captures to a result table. */
|
|
62
|
+
get groupNames(): ReadonlyArray<[string, number]>;
|
|
63
|
+
/** The number of capturing groups (PCRE2_INFO_CAPTURECOUNT): the match
|
|
64
|
+
* data is sized from the pattern, one ovector pair more than that. */
|
|
65
|
+
get captureCount(): number;
|
|
22
66
|
destroy(): void;
|
|
23
67
|
match(subject: string, start?: number): Pcre2Match | null;
|
|
24
|
-
|
|
68
|
+
/**
|
|
69
|
+
* {@link match} without the end-of-subject guard: `startOffset` may equal
|
|
70
|
+
* `subject.length`, where a pattern that can match nothing still finds its
|
|
71
|
+
* empty match. That is where TAlias::match's global loop tries after a
|
|
72
|
+
* match that ran to the end of the command.
|
|
73
|
+
*/
|
|
74
|
+
matchFrom(subject: string, startOffset: number, options?: number): Pcre2Match | null;
|
|
75
|
+
private matchOnce;
|
|
76
|
+
/**
|
|
77
|
+
* {@link matchFrom} as Mudlet's trigger and alias code calls pcre2_match:
|
|
78
|
+
* any error is "no match". TTrigger::match_perl and TAlias::match treat a
|
|
79
|
+
* negative return from the first pcre2_match the same whatever it is, so a
|
|
80
|
+
* pattern that backtracks into the match limit (-47) is simply a pattern
|
|
81
|
+
* that did not match this line, and the triggers and aliases after it still
|
|
82
|
+
* run. Throwing here took the rest of the line's pass with it (#361).
|
|
83
|
+
*/
|
|
84
|
+
tryMatchFrom(subject: string, startOffset: number, options?: number): Pcre2Match | null;
|
|
85
|
+
/**
|
|
86
|
+
* Every match of the pattern in `subject`, by Mudlet's global-match loop
|
|
87
|
+
* (TTrigger::match_perl under "match all", and TAlias::match, which always
|
|
88
|
+
* runs it) — pcre2demo's loop:
|
|
89
|
+
*
|
|
90
|
+
* - resume at the end of the last match, even when that is the end of the
|
|
91
|
+
* subject, where a pattern that can match nothing still finds its empty
|
|
92
|
+
* match (`(\d*)` on a line gives one there);
|
|
93
|
+
* - after an EMPTY match, first ask again at the same offset with
|
|
94
|
+
* PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED, so a pattern that preferred
|
|
95
|
+
* nothing still reports the non-empty match it could make there (`a??`
|
|
96
|
+
* on "aa" gives "", "a", "", "a", ""); only when that fails step one
|
|
97
|
+
* code point on and match normally from there;
|
|
98
|
+
* - stop after an empty match at the end of the subject.
|
|
99
|
+
*
|
|
100
|
+
* `lenient` is how the trigger and alias engines call it: an error from
|
|
101
|
+
* pcre2_match (the match limit, say) ends the loop with what was found so
|
|
102
|
+
* far, and an error on the first call means no match — desktop's
|
|
103
|
+
* `if (rc < 0) goto END`. Without it the error is thrown, as
|
|
104
|
+
* {@link matchFrom} throws.
|
|
105
|
+
*/
|
|
106
|
+
matchAll(subject: string, lenient?: boolean): Pcre2Match[];
|
|
25
107
|
private getLastError;
|
|
26
108
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<meta name="referrer" content="no-referrer">
|
|
7
|
+
<title>Sign-in</title>
|
|
8
|
+
<!--
|
|
9
|
+
Redirect target for the client-driven GMCP Char.Login OAuth flow
|
|
10
|
+
(src/mud/protocol/oauthClientFlow.ts). The identity provider sends the
|
|
11
|
+
player here with ?code=…&state=… (or ?error=…). This page reports those
|
|
12
|
+
over a same-origin BroadcastChannel to the app tab that started the
|
|
13
|
+
sign-in, strips them from the address bar, and says how it went. It
|
|
14
|
+
never renders anything taken from the URL.
|
|
15
|
+
|
|
16
|
+
Desktop Mudlet's equivalent is the loopback listener in OAuthClientFlow.cpp,
|
|
17
|
+
whose response pages these messages follow.
|
|
18
|
+
-->
|
|
19
|
+
<style>
|
|
20
|
+
:root { color-scheme: light dark; --bg: #f6f6f4; --fg: #1f2328; --muted: #59636e; }
|
|
21
|
+
@media (prefers-color-scheme: dark) { :root { --bg: #16181d; --fg: #e6e6e6; --muted: #9aa4af; } }
|
|
22
|
+
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--fg);
|
|
23
|
+
font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
|
|
24
|
+
main { min-height: 100%; display: grid; place-items: center; padding: 16px; box-sizing: border-box; }
|
|
25
|
+
p { max-width: 32em; text-align: center; margin: 0; }
|
|
26
|
+
small { display: block; margin-top: 8px; color: var(--muted); }
|
|
27
|
+
</style>
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<main><p id="msg" role="status" aria-live="polite">Finishing your sign-in…</p></main>
|
|
31
|
+
<script>
|
|
32
|
+
(function () {
|
|
33
|
+
'use strict';
|
|
34
|
+
var CHANNEL = 'mudlet-web-oauth';
|
|
35
|
+
var msg = document.getElementById('msg');
|
|
36
|
+
function show(text, hint) {
|
|
37
|
+
msg.textContent = text;
|
|
38
|
+
if (hint) {
|
|
39
|
+
var s = document.createElement('small');
|
|
40
|
+
s.textContent = hint;
|
|
41
|
+
msg.appendChild(s);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Providers answer in the query (the default response_mode) and, rarely, the
|
|
46
|
+
// fragment. Read both, then take them out of the address bar and history.
|
|
47
|
+
var params = new URLSearchParams(location.search);
|
|
48
|
+
if (!params.has('state') && location.hash.length > 1) {
|
|
49
|
+
params = new URLSearchParams(location.hash.slice(1));
|
|
50
|
+
}
|
|
51
|
+
var state = params.get('state') || '';
|
|
52
|
+
var code = params.get('code') || '';
|
|
53
|
+
var error = params.get('error') || '';
|
|
54
|
+
try { history.replaceState(null, '', location.pathname); } catch (e) { /* ignore */ }
|
|
55
|
+
|
|
56
|
+
if (!state || (!code && !error)) {
|
|
57
|
+
show('There is no sign-in to finish here.', 'You can close this tab.');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (typeof BroadcastChannel === 'undefined') {
|
|
61
|
+
show('This browser cannot hand the sign-in back to Mudlet.', 'Please return to the game and try again.');
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
var channel = new BroadcastChannel(CHANNEL);
|
|
66
|
+
var settled = false;
|
|
67
|
+
function finish(ok) {
|
|
68
|
+
if (settled) return;
|
|
69
|
+
settled = true;
|
|
70
|
+
channel.close();
|
|
71
|
+
if (ok === true) {
|
|
72
|
+
show('You are signed in. You can close this tab and return to the game.');
|
|
73
|
+
setTimeout(function () { try { window.close(); } catch (e) { /* ignore */ } }, 1500);
|
|
74
|
+
} else if (ok === false) {
|
|
75
|
+
show(error ? 'The sign-in was not completed.' : 'The sign-in did not complete.',
|
|
76
|
+
'You can close this tab and return to the game.');
|
|
77
|
+
} else {
|
|
78
|
+
show('The game tab that started this sign-in did not answer.',
|
|
79
|
+
'If it is still open, return to it; otherwise reconnect and try again.');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
channel.onmessage = function (ev) {
|
|
83
|
+
var d = ev.data;
|
|
84
|
+
if (d && d.type === 'ack' && d.state === state) finish(d.ok === true);
|
|
85
|
+
};
|
|
86
|
+
var payload = { type: 'callback', state: state };
|
|
87
|
+
if (code) payload.code = code;
|
|
88
|
+
if (error) payload.error = error;
|
|
89
|
+
channel.postMessage(payload);
|
|
90
|
+
setTimeout(function () { finish(null); }, 4000);
|
|
91
|
+
})();
|
|
92
|
+
</script>
|
|
93
|
+
</body>
|
|
94
|
+
</html>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Give pcre2-wasm-universal's `_match` export an `options` argument.
|
|
3
|
+
*
|
|
4
|
+
* The library's C wrapper is
|
|
5
|
+
*
|
|
6
|
+
* int match(code, subject, length, startOffset, matchData)
|
|
7
|
+
* { return pcre2_match(code, subject, length, startOffset, 0, matchData, NULL); }
|
|
8
|
+
*
|
|
9
|
+
* and its `compile` always sets PCRE2_UTF. With options fixed at 0, every
|
|
10
|
+
* pcre2_match call checks that the subject is valid UTF-16 from the start
|
|
11
|
+
* offset to the END of the subject, so a global match — one call per match,
|
|
12
|
+
* each starting where the last one ended — costs the number of matches times
|
|
13
|
+
* the length of the line: quadratic. A 64 kB line of 13 000 words took twenty
|
|
14
|
+
* times as long as an 8 kB one. Mudlet (and pcre2_substitute itself) checks the
|
|
15
|
+
* subject once and passes PCRE2_NO_UTF_CHECK for the rest of the loop, which
|
|
16
|
+
* needs the options argument the wrapper doesn't pass through.
|
|
17
|
+
*
|
|
18
|
+
* The wrapper compiles to
|
|
19
|
+
*
|
|
20
|
+
* local.get 0 local.get 1 local.get 2 local.get 3
|
|
21
|
+
* i32.const 0 ;; options
|
|
22
|
+
* local.get 4
|
|
23
|
+
* call $pcre2_match_16
|
|
24
|
+
*
|
|
25
|
+
* so the patch retypes `_match` to take a sixth i32 (the module already
|
|
26
|
+
* declares that exact signature, for pcre2_match_16 itself) and swaps
|
|
27
|
+
* `i32.const 0` for `local.get 5`. Both edits are the same size as what they
|
|
28
|
+
* replace, so no section or body length moves. A caller passing five arguments
|
|
29
|
+
* still gets options 0 — JS fills the missing one with `undefined` → 0 — and a
|
|
30
|
+
* caller passing six to the unpatched module has the sixth dropped, so either
|
|
31
|
+
* side can be old without breaking the other; only the speed differs.
|
|
32
|
+
*
|
|
33
|
+
* Returns a patched copy, or null when the bytes aren't the build this patch
|
|
34
|
+
* was written against (anything unexpected, so the caller falls back to the
|
|
35
|
+
* module as shipped rather than a guess). Already-patched input comes back
|
|
36
|
+
* unchanged, so it is safe to apply twice.
|
|
37
|
+
*
|
|
38
|
+
* UPGRADING pcre2-wasm-universal. This was derived against 1.0.0's
|
|
39
|
+
* dist/libpcre2.wasm (sha256 5ea911ab…0dc99e). The fallback keeps a new build
|
|
40
|
+
* correct, but at runtime it is silent: the speed-up is simply gone, and long
|
|
41
|
+
* lines go back to quadratic. So a bump that changes the wasm must re-derive
|
|
42
|
+
* the patch: disassemble the new binary (e.g. `wasm2wat`), find `_match`'s
|
|
43
|
+
* export and body, check it is still the pass-through above with options
|
|
44
|
+
* hard-coded to 0 and that a 6×i32 → i32 signature still exists, and adjust
|
|
45
|
+
* what `patch`/`bodyMatches` expect. If upstream grew a real options argument,
|
|
46
|
+
* drop this patch (and the transform in vitest.config.ts) instead.
|
|
47
|
+
*
|
|
48
|
+
* The bump can't slip through unnoticed: tests/triggers/pcreMatchAllLinear.test.ts
|
|
49
|
+
* ("recognises the installed pcre2-wasm-universal build" and "runs the wasm
|
|
50
|
+
* this suite patched") fails in `yarn test` with "pcre2 wasm patch did not
|
|
51
|
+
* apply; see vite-plugin/pcre2Wasm.ts" when the installed binary isn't
|
|
52
|
+
* recognised or the loaded module ignores PCRE2_NO_UTF_CHECK.
|
|
53
|
+
*/
|
|
54
|
+
export declare function patchLibpcre2Wasm(input: Uint8Array): Uint8Array<ArrayBuffer> | null;
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Give pcre2-wasm-universal's `_match` export an `options` argument.
|
|
3
|
+
*
|
|
4
|
+
* The library's C wrapper is
|
|
5
|
+
*
|
|
6
|
+
* int match(code, subject, length, startOffset, matchData)
|
|
7
|
+
* { return pcre2_match(code, subject, length, startOffset, 0, matchData, NULL); }
|
|
8
|
+
*
|
|
9
|
+
* and its `compile` always sets PCRE2_UTF. With options fixed at 0, every
|
|
10
|
+
* pcre2_match call checks that the subject is valid UTF-16 from the start
|
|
11
|
+
* offset to the END of the subject, so a global match — one call per match,
|
|
12
|
+
* each starting where the last one ended — costs the number of matches times
|
|
13
|
+
* the length of the line: quadratic. A 64 kB line of 13 000 words took twenty
|
|
14
|
+
* times as long as an 8 kB one. Mudlet (and pcre2_substitute itself) checks the
|
|
15
|
+
* subject once and passes PCRE2_NO_UTF_CHECK for the rest of the loop, which
|
|
16
|
+
* needs the options argument the wrapper doesn't pass through.
|
|
17
|
+
*
|
|
18
|
+
* The wrapper compiles to
|
|
19
|
+
*
|
|
20
|
+
* local.get 0 local.get 1 local.get 2 local.get 3
|
|
21
|
+
* i32.const 0 ;; options
|
|
22
|
+
* local.get 4
|
|
23
|
+
* call $pcre2_match_16
|
|
24
|
+
*
|
|
25
|
+
* so the patch retypes `_match` to take a sixth i32 (the module already
|
|
26
|
+
* declares that exact signature, for pcre2_match_16 itself) and swaps
|
|
27
|
+
* `i32.const 0` for `local.get 5`. Both edits are the same size as what they
|
|
28
|
+
* replace, so no section or body length moves. A caller passing five arguments
|
|
29
|
+
* still gets options 0 — JS fills the missing one with `undefined` → 0 — and a
|
|
30
|
+
* caller passing six to the unpatched module has the sixth dropped, so either
|
|
31
|
+
* side can be old without breaking the other; only the speed differs.
|
|
32
|
+
*
|
|
33
|
+
* Returns a patched copy, or null when the bytes aren't the build this patch
|
|
34
|
+
* was written against (anything unexpected, so the caller falls back to the
|
|
35
|
+
* module as shipped rather than a guess). Already-patched input comes back
|
|
36
|
+
* unchanged, so it is safe to apply twice.
|
|
37
|
+
*
|
|
38
|
+
* UPGRADING pcre2-wasm-universal. This was derived against 1.0.0's
|
|
39
|
+
* dist/libpcre2.wasm (sha256 5ea911ab…0dc99e). The fallback keeps a new build
|
|
40
|
+
* correct, but at runtime it is silent: the speed-up is simply gone, and long
|
|
41
|
+
* lines go back to quadratic. So a bump that changes the wasm must re-derive
|
|
42
|
+
* the patch: disassemble the new binary (e.g. `wasm2wat`), find `_match`'s
|
|
43
|
+
* export and body, check it is still the pass-through above with options
|
|
44
|
+
* hard-coded to 0 and that a 6×i32 → i32 signature still exists, and adjust
|
|
45
|
+
* what `patch`/`bodyMatches` expect. If upstream grew a real options argument,
|
|
46
|
+
* drop this patch (and the transform in vitest.config.ts) instead.
|
|
47
|
+
*
|
|
48
|
+
* The bump can't slip through unnoticed: tests/triggers/pcreMatchAllLinear.test.ts
|
|
49
|
+
* ("recognises the installed pcre2-wasm-universal build" and "runs the wasm
|
|
50
|
+
* this suite patched") fails in `yarn test` with "pcre2 wasm patch did not
|
|
51
|
+
* apply; see vite-plugin/pcre2Wasm.ts" when the installed binary isn't
|
|
52
|
+
* recognised or the loaded module ignores PCRE2_NO_UTF_CHECK.
|
|
53
|
+
*/
|
|
54
|
+
export function patchLibpcre2Wasm(input) {
|
|
55
|
+
try {
|
|
56
|
+
return patch(input);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const SECTION_TYPE = 1;
|
|
63
|
+
const SECTION_IMPORT = 2;
|
|
64
|
+
const SECTION_FUNCTION = 3;
|
|
65
|
+
const SECTION_EXPORT = 7;
|
|
66
|
+
const SECTION_CODE = 10;
|
|
67
|
+
const I32 = 0x7f;
|
|
68
|
+
const LOCAL_GET = 0x20;
|
|
69
|
+
const I32_CONST = 0x41;
|
|
70
|
+
const CALL = 0x10;
|
|
71
|
+
const END = 0x0b;
|
|
72
|
+
function patch(input) {
|
|
73
|
+
const bytes = new Uint8Array(input);
|
|
74
|
+
if (bytes.length < 8 || bytes[0] !== 0 || bytes[1] !== 0x61 || bytes[2] !== 0x73 || bytes[3] !== 0x6d)
|
|
75
|
+
return null;
|
|
76
|
+
let pos = 8;
|
|
77
|
+
const readU32 = () => {
|
|
78
|
+
let result = 0;
|
|
79
|
+
let shift = 0;
|
|
80
|
+
for (;;) {
|
|
81
|
+
const b = bytes[pos++];
|
|
82
|
+
if (b === undefined)
|
|
83
|
+
throw new Error('truncated');
|
|
84
|
+
result |= (b & 0x7f) << shift;
|
|
85
|
+
if (!(b & 0x80))
|
|
86
|
+
return result >>> 0;
|
|
87
|
+
shift += 7;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const skipName = () => { const n = readU32(); pos += n; };
|
|
91
|
+
const readName = () => {
|
|
92
|
+
const n = readU32();
|
|
93
|
+
const s = new TextDecoder().decode(bytes.subarray(pos, pos + n));
|
|
94
|
+
pos += n;
|
|
95
|
+
return s;
|
|
96
|
+
};
|
|
97
|
+
/** param count of each i32-only signature returning one i32, else -1 */
|
|
98
|
+
let i32Sigs = [];
|
|
99
|
+
let importedFuncs = 0;
|
|
100
|
+
let functionSection = -1;
|
|
101
|
+
let codeSection = -1;
|
|
102
|
+
let matchFunc = -1;
|
|
103
|
+
while (pos < bytes.length) {
|
|
104
|
+
const id = bytes[pos++];
|
|
105
|
+
const size = readU32();
|
|
106
|
+
const start = pos;
|
|
107
|
+
const end = start + size;
|
|
108
|
+
if (id === SECTION_TYPE) {
|
|
109
|
+
const count = readU32();
|
|
110
|
+
i32Sigs = [];
|
|
111
|
+
for (let i = 0; i < count; i++) {
|
|
112
|
+
if (bytes[pos++] !== 0x60)
|
|
113
|
+
throw new Error('type form');
|
|
114
|
+
const params = readU32();
|
|
115
|
+
let allI32 = true;
|
|
116
|
+
for (let p = 0; p < params; p++)
|
|
117
|
+
if (bytes[pos++] !== I32)
|
|
118
|
+
allI32 = false;
|
|
119
|
+
const results = readU32();
|
|
120
|
+
for (let r = 0; r < results; r++)
|
|
121
|
+
if (bytes[pos++] !== I32)
|
|
122
|
+
allI32 = false;
|
|
123
|
+
i32Sigs.push(allI32 && results === 1 ? params : -1);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else if (id === SECTION_IMPORT) {
|
|
127
|
+
const count = readU32();
|
|
128
|
+
for (let i = 0; i < count; i++) {
|
|
129
|
+
skipName();
|
|
130
|
+
skipName();
|
|
131
|
+
const kind = bytes[pos++];
|
|
132
|
+
if (kind === 0) {
|
|
133
|
+
readU32();
|
|
134
|
+
importedFuncs++;
|
|
135
|
+
}
|
|
136
|
+
else if (kind === 1) {
|
|
137
|
+
pos++;
|
|
138
|
+
const flags = readU32();
|
|
139
|
+
readU32();
|
|
140
|
+
if (flags & 1)
|
|
141
|
+
readU32();
|
|
142
|
+
}
|
|
143
|
+
else if (kind === 2) {
|
|
144
|
+
const flags = readU32();
|
|
145
|
+
readU32();
|
|
146
|
+
if (flags & 1)
|
|
147
|
+
readU32();
|
|
148
|
+
}
|
|
149
|
+
else if (kind === 3) {
|
|
150
|
+
pos += 2;
|
|
151
|
+
}
|
|
152
|
+
else
|
|
153
|
+
throw new Error('import kind');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else if (id === SECTION_FUNCTION) {
|
|
157
|
+
functionSection = start;
|
|
158
|
+
}
|
|
159
|
+
else if (id === SECTION_EXPORT) {
|
|
160
|
+
const count = readU32();
|
|
161
|
+
for (let i = 0; i < count; i++) {
|
|
162
|
+
const name = readName();
|
|
163
|
+
const kind = bytes[pos++];
|
|
164
|
+
const index = readU32();
|
|
165
|
+
if (kind === 0 && name === '_match')
|
|
166
|
+
matchFunc = index;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else if (id === SECTION_CODE) {
|
|
170
|
+
codeSection = start;
|
|
171
|
+
}
|
|
172
|
+
pos = end;
|
|
173
|
+
}
|
|
174
|
+
if (functionSection < 0 || codeSection < 0 || matchFunc < importedFuncs)
|
|
175
|
+
return null;
|
|
176
|
+
const local = matchFunc - importedFuncs;
|
|
177
|
+
// The function section entry naming `_match`'s type.
|
|
178
|
+
pos = functionSection;
|
|
179
|
+
const funcCount = readU32();
|
|
180
|
+
if (local >= funcCount)
|
|
181
|
+
return null;
|
|
182
|
+
for (let i = 0; i < local; i++)
|
|
183
|
+
readU32();
|
|
184
|
+
const typeAt = pos;
|
|
185
|
+
const typeIndex = readU32();
|
|
186
|
+
if (pos - typeAt !== 1)
|
|
187
|
+
return null;
|
|
188
|
+
const sixArgs = i32Sigs.indexOf(6);
|
|
189
|
+
if (sixArgs < 0 || sixArgs > 0x7f)
|
|
190
|
+
return null;
|
|
191
|
+
if (typeIndex === sixArgs) {
|
|
192
|
+
// Already retyped — accept only if the body reads its sixth argument.
|
|
193
|
+
return bodyMatches(bytes, codeSection, local, LOCAL_GET, 5) ? bytes : null;
|
|
194
|
+
}
|
|
195
|
+
if (i32Sigs[typeIndex] !== 5)
|
|
196
|
+
return null;
|
|
197
|
+
const optionsAt = bodyMatches(bytes, codeSection, local, I32_CONST, 0);
|
|
198
|
+
if (optionsAt === false)
|
|
199
|
+
return null;
|
|
200
|
+
bytes[typeAt] = sixArgs;
|
|
201
|
+
bytes[optionsAt] = LOCAL_GET;
|
|
202
|
+
bytes[optionsAt + 1] = 5;
|
|
203
|
+
return bytes;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Whether `_match`'s body is the four-argument pass-through, `op arg`, the
|
|
207
|
+
* fifth argument and a call — returning the offset of `op`, or false.
|
|
208
|
+
*/
|
|
209
|
+
function bodyMatches(bytes, codeSection, local, op, arg) {
|
|
210
|
+
let pos = codeSection;
|
|
211
|
+
const readU32 = () => {
|
|
212
|
+
let result = 0;
|
|
213
|
+
let shift = 0;
|
|
214
|
+
for (;;) {
|
|
215
|
+
const b = bytes[pos++];
|
|
216
|
+
result |= (b & 0x7f) << shift;
|
|
217
|
+
if (!(b & 0x80))
|
|
218
|
+
return result >>> 0;
|
|
219
|
+
shift += 7;
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
const count = readU32();
|
|
223
|
+
if (local >= count)
|
|
224
|
+
return false;
|
|
225
|
+
for (let i = 0; i < local; i++) {
|
|
226
|
+
const size = readU32();
|
|
227
|
+
pos += size;
|
|
228
|
+
}
|
|
229
|
+
const size = readU32();
|
|
230
|
+
const body = pos;
|
|
231
|
+
const expectHead = [0, LOCAL_GET, 0, LOCAL_GET, 1, LOCAL_GET, 2, LOCAL_GET, 3, op, arg, LOCAL_GET, 4, CALL];
|
|
232
|
+
for (let i = 0; i < expectHead.length; i++)
|
|
233
|
+
if (bytes[body + i] !== expectHead[i])
|
|
234
|
+
return false;
|
|
235
|
+
// The call's function index, then the end of the body.
|
|
236
|
+
pos = body + expectHead.length;
|
|
237
|
+
readU32();
|
|
238
|
+
if (bytes[pos] !== END || pos + 1 !== body + size)
|
|
239
|
+
return false;
|
|
240
|
+
return body + 9;
|
|
241
|
+
}
|