+4
-8
.github/workflows/browser.yml
+4
-8
.github/workflows/browser.yml
···
10
name: Browser extension builds
11
runs-on: ubuntu-latest
12
steps:
13
-
- uses: actions/checkout@v3
14
-
15
-
- uses: pnpm/action-setup@v2
16
-
with:
17
-
version: 9
18
-
run_install: false
19
-
- uses: actions/setup-node@v3
20
with:
21
-
node-version: 18
22
cache: pnpm
23
24
- name: Install dependencies
+4
-8
.github/workflows/lint.yml
+4
-8
.github/workflows/lint.yml
+4
-8
.github/workflows/nightly.yml
+4
-8
.github/workflows/nightly.yml
···
15
name: Nightly builds on GitHub Pages
16
runs-on: ubuntu-latest
17
steps:
18
-
- uses: actions/checkout@v3
19
-
20
-
- uses: pnpm/action-setup@v2
21
-
with:
22
-
version: 9
23
-
run_install: false
24
-
- uses: actions/setup-node@v3
25
with:
26
-
node-version: 18
27
cache: pnpm
28
29
- name: Install dependencies
+16
.github/workflows/nix.yml
+16
.github/workflows/nix.yml
···
···
1
+
name: Check Nix flake
2
+
on: [push, pull_request]
3
+
4
+
permissions:
5
+
checks: write
6
+
7
+
jobs:
8
+
nix:
9
+
name: Check Nix flake
10
+
runs-on: ubuntu-latest
11
+
steps:
12
+
- uses: actions/checkout@v4
13
+
- uses: DeterminateSystems/nix-installer-action@main
14
+
15
+
- name: Build default flake output
16
+
run: nix build
+4
-8
.github/workflows/release.yml
+4
-8
.github/workflows/release.yml
···
13
name: Release builds to GitHub Releases
14
runs-on: ubuntu-latest
15
steps:
16
-
- uses: actions/checkout@v3
17
-
18
-
- uses: pnpm/action-setup@v2
19
-
with:
20
-
version: 9
21
-
run_install: false
22
-
- uses: actions/setup-node@v3
23
with:
24
-
node-version: 18
25
cache: pnpm
26
27
- name: Install dependencies
+5
-11
.github/workflows/types.yml
+5
-11
.github/workflows/types.yml
···
11
name: Publish types on npm
12
runs-on: ubuntu-latest
13
steps:
14
-
- uses: actions/checkout@v3
15
-
16
-
- uses: pnpm/action-setup@v2
17
-
with:
18
-
version: 9
19
-
run_install: false
20
-
- uses: actions/setup-node@v3
21
with:
22
-
node-version: 18
23
cache: pnpm
24
registry-url: https://registry.npmjs.org
25
···
31
run: pnpm run build
32
33
- name: Publish types
34
-
run: |
35
-
cd packages/types
36
-
pnpm publish --access public --no-git-checks
37
env:
38
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
···
11
name: Publish types on npm
12
runs-on: ubuntu-latest
13
steps:
14
+
- uses: actions/checkout@v4
15
+
- uses: pnpm/action-setup@v4
16
+
- uses: actions/setup-node@v4
17
with:
18
+
node-version: 22
19
cache: pnpm
20
registry-url: https://registry.npmjs.org
21
···
27
run: pnpm run build
28
29
- name: Publish types
30
+
run: pnpm publish --filter=./packages/types --access public --no-git-checks
31
env:
32
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+1
-1
.gitignore
+1
-1
.gitignore
+4
-4
.prettierrc
+4
-4
.prettierrc
+4
-3
CHANGELOG.md
+4
-3
CHANGELOG.md
+1
-1
README.md
+1
-1
README.md
···
23
24
moonlight is heavily inspired by hh3 (a private client mod) and the projects before it that it is inspired by, namely EndPwn. All core code is original or used with permission from their respective authors where not copyleft.
25
26
-
**_This is an experimental passion project._** Anything and everything is subject to change, but it is stable enough for tinkerers and developers to experiment with.
27
28
moonlight is licensed under the [GNU Lesser General Public License](https://www.gnu.org/licenses/lgpl-3.0.html) (`LGPL-3.0-or-later`). See [the documentation](https://moonlight-mod.github.io/) for more information.
···
23
24
moonlight is heavily inspired by hh3 (a private client mod) and the projects before it that it is inspired by, namely EndPwn. All core code is original or used with permission from their respective authors where not copyleft.
25
26
+
moonlight is a **_passion project_** - things may break from time to time, but we try our best to keep things working in a timely manner.
27
28
moonlight is licensed under the [GNU Lesser General Public License](https://www.gnu.org/licenses/lgpl-3.0.html) (`LGPL-3.0-or-later`). See [the documentation](https://moonlight-mod.github.io/) for more information.
+4
-73
flake.lock
+4
-73
flake.lock
···
18
"type": "github"
19
}
20
},
21
-
"flake-utils_2": {
22
-
"inputs": {
23
-
"systems": "systems_2"
24
-
},
25
-
"locked": {
26
-
"lastModified": 1701680307,
27
-
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
28
-
"owner": "numtide",
29
-
"repo": "flake-utils",
30
-
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
31
-
"type": "github"
32
-
},
33
-
"original": {
34
-
"owner": "numtide",
35
-
"repo": "flake-utils",
36
-
"type": "github"
37
-
}
38
-
},
39
"nixpkgs": {
40
"locked": {
41
-
"lastModified": 1728067476,
42
-
"narHash": "sha256-/uJcVXuBt+VFCPQIX+4YnYrHaubJSx4HoNsJVNRgANM=",
43
"owner": "NixOS",
44
"repo": "nixpkgs",
45
-
"rev": "6e6b3dd395c3b1eb9be9f2d096383a8d05add030",
46
"type": "github"
47
},
48
"original": {
49
"owner": "NixOS",
50
-
"ref": "nixos-24.05",
51
-
"repo": "nixpkgs",
52
-
"type": "github"
53
-
}
54
-
},
55
-
"nixpkgs_2": {
56
-
"locked": {
57
-
"lastModified": 1736344531,
58
-
"narHash": "sha256-8YVQ9ZbSfuUk2bUf2KRj60NRraLPKPS0Q4QFTbc+c2c=",
59
-
"owner": "nixos",
60
-
"repo": "nixpkgs",
61
-
"rev": "bffc22eb12172e6db3c5dde9e3e5628f8e3e7912",
62
-
"type": "github"
63
-
},
64
-
"original": {
65
-
"owner": "nixos",
66
"ref": "nixos-unstable",
67
"repo": "nixpkgs",
68
"type": "github"
69
}
70
},
71
-
"pnpm2nix": {
72
-
"inputs": {
73
-
"flake-utils": "flake-utils_2",
74
-
"nixpkgs": "nixpkgs_2"
75
-
},
76
-
"locked": {
77
-
"lastModified": 1736457458,
78
-
"narHash": "sha256-eiw+hAsxavEgBfhwrktNI2hwvgeVDzBDYClx/yqka78=",
79
-
"owner": "NotNite",
80
-
"repo": "pnpm2nix-nzbr",
81
-
"rev": "4ac61c6a50623da937dca005e3dbcb8862aafb83",
82
-
"type": "github"
83
-
},
84
-
"original": {
85
-
"owner": "NotNite",
86
-
"repo": "pnpm2nix-nzbr",
87
-
"type": "github"
88
-
}
89
-
},
90
"root": {
91
"inputs": {
92
"flake-utils": "flake-utils",
93
-
"nixpkgs": "nixpkgs",
94
-
"pnpm2nix": "pnpm2nix"
95
}
96
},
97
"systems": {
98
-
"locked": {
99
-
"lastModified": 1681028828,
100
-
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
101
-
"owner": "nix-systems",
102
-
"repo": "default",
103
-
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
104
-
"type": "github"
105
-
},
106
-
"original": {
107
-
"owner": "nix-systems",
108
-
"repo": "default",
109
-
"type": "github"
110
-
}
111
-
},
112
-
"systems_2": {
113
"locked": {
114
"lastModified": 1681028828,
115
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
···
18
"type": "github"
19
}
20
},
21
"nixpkgs": {
22
"locked": {
23
+
"lastModified": 1744232761,
24
+
"narHash": "sha256-gbl9hE39nQRpZaLjhWKmEu5ejtQsgI5TWYrIVVJn30U=",
25
"owner": "NixOS",
26
"repo": "nixpkgs",
27
+
"rev": "f675531bc7e6657c10a18b565cfebd8aa9e24c14",
28
"type": "github"
29
},
30
"original": {
31
"owner": "NixOS",
32
"ref": "nixos-unstable",
33
"repo": "nixpkgs",
34
"type": "github"
35
}
36
},
37
"root": {
38
"inputs": {
39
"flake-utils": "flake-utils",
40
+
"nixpkgs": "nixpkgs"
41
}
42
},
43
"systems": {
44
"locked": {
45
"lastModified": 1681028828,
46
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+3
-4
flake.nix
+3
-4
flake.nix
···
2
description = "Yet another Discord mod";
3
4
inputs = {
5
-
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
6
flake-utils.url = "github:numtide/flake-utils";
7
-
pnpm2nix.url = "github:NotNite/pnpm2nix-nzbr";
8
};
9
10
-
outputs = { self, nixpkgs, flake-utils, pnpm2nix }:
11
-
let overlay = import ./nix/overlay.nix { inherit pnpm2nix; };
12
in flake-utils.lib.eachDefaultSystem (system:
13
let
14
pkgs = import nixpkgs {
···
2
description = "Yet another Discord mod";
3
4
inputs = {
5
+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
6
flake-utils.url = "github:numtide/flake-utils";
7
};
8
9
+
outputs = { self, nixpkgs, flake-utils }:
10
+
let overlay = import ./nix/overlay.nix { };
11
in flake-utils.lib.eachDefaultSystem (system:
12
let
13
pkgs = import nixpkgs {
+40
-17
nix/default.nix
+40
-17
nix/default.nix
···
1
-
{ pkgs, mkPnpmPackage }:
2
3
-
mkPnpmPackage rec {
4
-
workspace = ./..;
5
src = ./..;
6
7
-
# Work around a bug with how it expects dist
8
-
components = [
9
-
"packages/core"
10
-
"packages/core-extensions"
11
-
"packages/injector"
12
-
"packages/node-preload"
13
-
"packages/types"
14
-
"packages/web-preload"
15
];
16
-
distDirs = [ "dist" ];
17
18
-
copyNodeModules = true;
19
-
buildPhase = "pnpm run build";
20
-
installPhase = "cp -r dist $out";
21
22
-
meta = with pkgs.lib; {
23
description = "Yet another Discord mod";
24
homepage = "https://moonlight-mod.github.io/";
25
license = licenses.lgpl3;
26
maintainers = with maintainers; [ notnite ];
27
};
28
-
}
···
1
+
{
2
+
lib,
3
+
stdenv,
4
+
nodejs_22,
5
+
pnpm_10,
6
+
}:
7
+
8
+
stdenv.mkDerivation (finalAttrs: {
9
+
pname = "moonlight";
10
+
version = (builtins.fromJSON (builtins.readFile ./../package.json)).version;
11
12
src = ./..;
13
14
+
nativeBuildInputs = [
15
+
nodejs_22
16
+
pnpm_10.configHook
17
];
18
+
19
+
pnpmDeps = pnpm_10.fetchDeps {
20
+
inherit (finalAttrs) pname version src;
21
+
hash = "sha256-I+zRCUqJabpGJRFBGW0NrM9xzyzeCjioF54zlCpynBU=";
22
+
};
23
24
+
env = {
25
+
NODE_ENV = "production";
26
+
MOONLIGHT_VERSION = "v${finalAttrs.version}";
27
+
};
28
+
29
+
buildPhase = ''
30
+
runHook preBuild
31
32
+
pnpm run build
33
+
34
+
runHook postBuild
35
+
'';
36
+
37
+
installPhase = ''
38
+
runHook preInstall
39
+
40
+
cp -r dist $out
41
+
42
+
runHook postInstall
43
+
'';
44
+
45
+
meta = with lib; {
46
description = "Yet another Discord mod";
47
homepage = "https://moonlight-mod.github.io/";
48
license = licenses.lgpl3;
49
maintainers = with maintainers; [ notnite ];
50
};
51
+
})
+3
-6
nix/overlay.nix
+3
-6
nix/overlay.nix
···
1
-
{ pnpm2nix }:
2
3
let
4
nameTable = {
···
29
'';
30
31
packageJson = ''
32
-
{"name":"discord","main":"./injector.js","private":true}
33
'';
34
35
in old.installPhase + "\n" + ''
···
49
'';
50
});
51
in final: prev: rec {
52
-
moonlight-mod = final.callPackage ./default.nix {
53
-
pkgs = final;
54
-
mkPnpmPackage = pnpm2nix.packages.${final.system}.mkPnpmPackage;
55
-
};
56
discord = mkOverride prev moonlight-mod "discord";
57
discord-ptb = mkOverride prev moonlight-mod "discord-ptb";
58
discord-canary = mkOverride prev moonlight-mod "discord-canary";
···
1
+
{ ... }:
2
3
let
4
nameTable = {
···
29
'';
30
31
packageJson = ''
32
+
{"name":"${name}","main":"./injector.js","private":true}
33
'';
34
35
in old.installPhase + "\n" + ''
···
49
'';
50
});
51
in final: prev: rec {
52
+
moonlight-mod = final.callPackage ./default.nix { };
53
discord = mkOverride prev moonlight-mod "discord";
54
discord-ptb = mkOverride prev moonlight-mod "discord-ptb";
55
discord-canary = mkOverride prev moonlight-mod "discord-canary";
+23
-12
package.json
+23
-12
package.json
···
1
{
2
"name": "moonlight",
3
-
"version": "1.3.1",
4
"description": "Yet another Discord mod",
5
-
"homepage": "https://moonlight-mod.github.io/",
6
"license": "LGPL-3.0-or-later",
7
"repository": {
8
"type": "git",
9
"url": "git+https://github.com/moonlight-mod/moonlight.git"
···
11
"bugs": {
12
"url": "https://github.com/moonlight-mod/moonlight/issues"
13
},
14
"scripts": {
15
"build": "node build.mjs",
16
"dev": "node build.mjs --watch",
···
18
"browser": "node build.mjs --browser",
19
"browser-mv2": "node build.mjs --browser --mv2",
20
"lint": "eslint packages",
21
-
"lint:fix": "eslint packages --fix",
22
-
"lint:report": "eslint --output-file eslint_report.json --format json packages",
23
"typecheck": "tsc --noEmit",
24
"check": "pnpm run lint && pnpm run typecheck",
25
-
"prepare": "husky install"
26
},
27
"devDependencies": {
28
-
"esbuild": "^0.19.3",
29
-
"esbuild-copy-static-files": "^0.1.0",
30
-
"eslint": "^9.12.0",
31
-
"@moonlight-mod/eslint-config": "github:moonlight-mod/eslint-config",
32
-
"husky": "^8.0.3",
33
-
"prettier": "^3.1.0",
34
-
"typescript": "^5.3.2"
35
}
36
}
···
1
{
2
"name": "moonlight",
3
+
"version": "1.3.14",
4
+
"packageManager": "pnpm@10.7.1",
5
"description": "Yet another Discord mod",
6
"license": "LGPL-3.0-or-later",
7
+
"homepage": "https://moonlight-mod.github.io/",
8
"repository": {
9
"type": "git",
10
"url": "git+https://github.com/moonlight-mod/moonlight.git"
···
12
"bugs": {
13
"url": "https://github.com/moonlight-mod/moonlight/issues"
14
},
15
+
"engineStrict": true,
16
+
"engines": {
17
+
"node": ">=22",
18
+
"pnpm": ">=10",
19
+
"npm": "pnpm",
20
+
"yarn": "pnpm"
21
+
},
22
"scripts": {
23
"build": "node build.mjs",
24
"dev": "node build.mjs --watch",
···
26
"browser": "node build.mjs --browser",
27
"browser-mv2": "node build.mjs --browser --mv2",
28
"lint": "eslint packages",
29
+
"lint:fix": "pnpm lint --fix",
30
+
"lint:report": "pnpm lint --output-file eslint_report.json --format json",
31
"typecheck": "tsc --noEmit",
32
"check": "pnpm run lint && pnpm run typecheck",
33
+
"prepare": "husky install",
34
+
"updates": "pnpm taze -r"
35
},
36
"devDependencies": {
37
+
"@moonlight-mod/eslint-config": "catalog:dev",
38
+
"@types/node": "catalog:dev",
39
+
"esbuild": "catalog:dev",
40
+
"esbuild-copy-static-files": "catalog:dev",
41
+
"eslint": "catalog:dev",
42
+
"husky": "catalog:dev",
43
+
"prettier": "catalog:dev",
44
+
"taze": "catalog:dev",
45
+
"typescript": "catalog:dev"
46
}
47
}
+2
-1
packages/browser/blockLoading.json
+2
-1
packages/browser/blockLoading.json
+10
-4
packages/browser/manifest.json
+10
-4
packages/browser/manifest.json
···
1
{
2
"manifest_version": 3,
3
"name": "moonlight",
4
"description": "Yet another Discord mod",
5
-
"version": "1.3.1",
6
"permissions": ["declarativeNetRequestWithHostAccess", "webRequest", "scripting", "webNavigation"],
7
-
"host_permissions": ["https://moonlight-mod.github.io/*", "https://api.github.com/*", "https://*.discord.com/*"],
8
"content_scripts": [
9
{
10
"js": ["index.js"],
11
-
"matches": ["https://*.discord.com/*"],
12
"run_at": "document_start",
13
"world": "MAIN"
14
}
···
34
"web_accessible_resources": [
35
{
36
"resources": ["index.js"],
37
-
"matches": ["https://*.discord.com/*"]
38
}
39
]
40
}
···
1
{
2
+
"$schema": "https://json.schemastore.org/chrome-manifest",
3
"manifest_version": 3,
4
"name": "moonlight",
5
"description": "Yet another Discord mod",
6
+
"version": "1.3.14",
7
"permissions": ["declarativeNetRequestWithHostAccess", "webRequest", "scripting", "webNavigation"],
8
+
"host_permissions": [
9
+
"https://moonlight-mod.github.io/*",
10
+
"https://api.github.com/*",
11
+
"https://*.discord.com/*",
12
+
"https://*.discordapp.com/*"
13
+
],
14
"content_scripts": [
15
{
16
"js": ["index.js"],
17
+
"matches": ["https://*.discord.com/*", "https://*.discordapp.com/*"],
18
"run_at": "document_start",
19
"world": "MAIN"
20
}
···
40
"web_accessible_resources": [
41
{
42
"resources": ["index.js"],
43
+
"matches": ["https://*.discord.com/*", "https://*.discordapp.com/*"]
44
}
45
]
46
}
+6
-5
packages/browser/manifestv2.json
+6
-5
packages/browser/manifestv2.json
···
1
{
2
"manifest_version": 2,
3
"name": "moonlight",
4
"description": "Yet another Discord mod",
5
-
"version": "1.3.1",
6
"permissions": [
7
"webRequest",
8
"webRequestBlocking",
9
"scripting",
10
"webNavigation",
11
-
"https://*.discord.com/assets/*.js",
12
"https://moonlight-mod.github.io/*",
13
-
"https://api.github.com/*",
14
-
"https://*.discord.com/*"
15
],
16
"background": {
17
"scripts": ["background.js"]
···
19
"content_scripts": [
20
{
21
"js": ["index.js"],
22
-
"matches": ["https://*.discord.com/*"],
23
"run_at": "document_start",
24
"world": "MAIN"
25
}
···
1
{
2
+
"$schema": "https://json.schemastore.org/chrome-manifest",
3
"manifest_version": 2,
4
"name": "moonlight",
5
"description": "Yet another Discord mod",
6
+
"version": "1.3.14",
7
"permissions": [
8
"webRequest",
9
"webRequestBlocking",
10
"scripting",
11
"webNavigation",
12
+
"https://*.discord.com/*",
13
+
"https://*.discordapp.com/*",
14
"https://moonlight-mod.github.io/*",
15
+
"https://api.github.com/*"
16
],
17
"background": {
18
"scripts": ["background.js"]
···
20
"content_scripts": [
21
{
22
"js": ["index.js"],
23
+
"matches": ["https://*.discord.com/*", "https://*.discordapp.com/*"],
24
"run_at": "document_start",
25
"world": "MAIN"
26
}
+12
-2
packages/browser/package.json
+12
-2
packages/browser/package.json
···
1
{
2
"name": "@moonlight-mod/browser",
3
"private": true,
4
+
"engines": {
5
+
"node": ">=22",
6
+
"pnpm": ">=10",
7
+
"npm": "pnpm",
8
+
"yarn": "pnpm"
9
+
},
10
"dependencies": {
11
"@moonlight-mod/core": "workspace:*",
12
"@moonlight-mod/types": "workspace:*",
13
"@moonlight-mod/web-preload": "workspace:*",
14
+
"@zenfs/core": "catalog:prod",
15
+
"@zenfs/dom": "catalog:prod"
16
+
},
17
+
"engineStrict": true,
18
+
"devDependencies": {
19
+
"@types/chrome": "catalog:dev"
20
}
21
}
+55
-70
packages/browser/src/background-mv2.js
+55
-70
packages/browser/src/background-mv2.js
···
1
/* eslint-disable no-console */
2
/* eslint-disable no-undef */
3
4
-
const starterUrls = ["web.", "sentry."];
5
-
let blockLoading = true;
6
-
let doing = false;
7
-
let collectedUrls = new Set();
8
9
-
chrome.webNavigation.onBeforeNavigate.addListener(async (details) => {
10
-
const url = new URL(details.url);
11
-
if (!blockLoading && url.hostname.endsWith("discord.com")) {
12
-
console.log("Blocking", details.url);
13
-
blockLoading = true;
14
-
collectedUrls.clear();
15
-
}
16
-
});
17
18
-
async function doTheThing(urls, tabId) {
19
-
console.log("Doing", urls, tabId);
20
21
-
blockLoading = false;
22
23
-
try {
24
-
await chrome.scripting.executeScript({
25
-
target: { tabId },
26
-
world: "MAIN",
27
-
args: [urls],
28
-
func: async (urls) => {
29
-
try {
30
-
await window._moonlightBrowserInit();
31
-
} catch (e) {
32
-
console.log(e);
33
-
}
34
35
-
const scripts = [...document.querySelectorAll("script")].filter(
36
-
(script) => script.src && urls.some((url) => url.includes(script.src))
37
-
);
38
39
-
// backwards
40
-
urls.reverse();
41
-
for (const url of urls) {
42
-
const script = scripts.find((script) => url.includes(script.src));
43
-
console.log("adding new script", script);
44
45
-
const newScript = document.createElement("script");
46
-
for (const { name, value } of script.attributes) {
47
-
newScript.setAttribute(name, value);
48
}
49
-
50
-
script.remove();
51
-
document.documentElement.appendChild(newScript);
52
-
}
53
-
}
54
-
});
55
-
} catch (e) {
56
-
console.log(e);
57
-
}
58
-
59
-
doing = false;
60
-
collectedUrls.clear();
61
-
}
62
-
63
-
chrome.webRequest.onBeforeRequest.addListener(
64
-
async (details) => {
65
-
if (starterUrls.some((url) => details.url.includes(url))) {
66
-
console.log("Adding", details.url);
67
-
collectedUrls.add(details.url);
68
}
69
70
-
if (collectedUrls.size === starterUrls.length) {
71
-
if (doing) return;
72
-
if (!blockLoading) return;
73
-
doing = true;
74
-
const urls = [...collectedUrls];
75
-
const tabId = details.tabId;
76
-
77
-
// yes this is a load-bearing sleep
78
-
setTimeout(() => doTheThing(urls, tabId), 0);
79
-
}
80
-
81
-
if (blockLoading) return { cancel: true };
82
},
83
{
84
-
urls: ["https://*.discord.com/assets/*.js"]
85
},
86
["blocking"]
87
);
···
94
)
95
};
96
},
97
-
{ urls: ["https://*.discord.com/*"] },
98
["blocking", "responseHeaders"]
99
);
···
1
/* eslint-disable no-console */
2
/* eslint-disable no-undef */
3
4
+
const scriptUrls = ["web.", "sentry."];
5
+
let blockedScripts = new Set();
6
7
+
chrome.webRequest.onBeforeRequest.addListener(
8
+
async (details) => {
9
+
if (details.tabId === -1) return;
10
11
+
const url = new URL(details.url);
12
+
const hasUrl = scriptUrls.some((scriptUrl) => {
13
+
return (
14
+
details.url.includes(scriptUrl) &&
15
+
!url.searchParams.has("inj") &&
16
+
(url.host.endsWith("discord.com") || url.host.endsWith("discordapp.com"))
17
+
);
18
+
});
19
+
if (hasUrl) blockedScripts.add(details.url);
20
21
+
if (blockedScripts.size === scriptUrls.length) {
22
+
const blockedScriptsCopy = Array.from(blockedScripts);
23
+
blockedScripts.clear();
24
25
+
setTimeout(async () => {
26
+
console.log("Starting moonlight");
27
+
await chrome.scripting.executeScript({
28
+
target: { tabId: details.tabId },
29
+
world: "MAIN",
30
+
args: [blockedScriptsCopy],
31
+
func: async (blockedScripts) => {
32
+
console.log("Initializing moonlight");
33
+
try {
34
+
await window._moonlightBrowserInit();
35
+
} catch (e) {
36
+
console.error(e);
37
+
}
38
39
+
console.log("Readding scripts");
40
+
try {
41
+
const scripts = [...document.querySelectorAll("script")].filter(
42
+
(script) => script.src && blockedScripts.some((url) => url.includes(script.src))
43
+
);
44
45
+
blockedScripts.reverse();
46
+
for (const url of blockedScripts) {
47
+
if (url.includes("/sentry.")) continue;
48
49
+
const script = scripts.find((script) => url.includes(script.src));
50
+
const newScript = document.createElement("script");
51
+
for (const attr of script.attributes) {
52
+
if (attr.name === "src") attr.value += "?inj";
53
+
newScript.setAttribute(attr.name, attr.value);
54
+
}
55
+
script.remove();
56
+
document.documentElement.appendChild(newScript);
57
+
}
58
+
} catch (e) {
59
+
console.error(e);
60
+
}
61
}
62
+
});
63
+
}, 0);
64
}
65
66
+
if (hasUrl) return { cancel: true };
67
},
68
{
69
+
urls: ["https://*.discord.com/assets/*.js", "https://*.discordapp.com/assets/*.js"]
70
},
71
["blocking"]
72
);
···
79
)
80
};
81
},
82
+
{ urls: ["https://*.discord.com/*", "https://*.discordapp.com/*"] },
83
["blocking", "responseHeaders"]
84
);
+37
-39
packages/browser/src/background.js
+37
-39
packages/browser/src/background.js
···
1
/* eslint-disable no-console */
2
/* eslint-disable no-undef */
3
4
-
const starterUrls = ["web.", "sentry."];
5
-
let blockLoading = true;
6
-
let doing = false;
7
-
let collectedUrls = new Set();
8
9
chrome.webNavigation.onBeforeNavigate.addListener(async (details) => {
10
const url = new URL(details.url);
11
-
if (!blockLoading && url.hostname.endsWith("discord.com")) {
12
await chrome.declarativeNetRequest.updateEnabledRulesets({
13
enableRulesetIds: ["modifyResponseHeaders", "blockLoading"]
14
});
15
-
blockLoading = true;
16
-
collectedUrls.clear();
17
}
18
});
19
20
chrome.webRequest.onBeforeRequest.addListener(
21
async (details) => {
22
if (details.tabId === -1) return;
23
-
if (starterUrls.some((url) => details.url.includes(url))) {
24
-
console.log("Adding", details.url);
25
-
collectedUrls.add(details.url);
26
-
}
27
28
-
if (collectedUrls.size === starterUrls.length) {
29
-
if (doing) return;
30
-
if (!blockLoading) return;
31
-
doing = true;
32
-
const urls = [...collectedUrls];
33
-
console.log("Doing", urls);
34
35
console.log("Running moonlight script");
36
try {
···
40
files: ["index.js"]
41
});
42
} catch (e) {
43
-
console.log(e);
44
}
45
46
console.log("Initializing moonlight");
···
52
try {
53
await window._moonlightBrowserInit();
54
} catch (e) {
55
-
console.log(e);
56
}
57
}
58
});
···
60
console.log(e);
61
}
62
63
-
console.log("Updating rulesets");
64
try {
65
-
blockLoading = false;
66
await chrome.declarativeNetRequest.updateEnabledRulesets({
67
disableRulesetIds: ["blockLoading"],
68
enableRulesetIds: ["modifyResponseHeaders"]
69
});
70
} catch (e) {
71
-
console.log(e);
72
}
73
74
console.log("Readding scripts");
···
76
await chrome.scripting.executeScript({
77
target: { tabId: details.tabId },
78
world: "MAIN",
79
-
args: [urls],
80
-
func: async (urls) => {
81
const scripts = [...document.querySelectorAll("script")].filter(
82
-
(script) => script.src && urls.some((url) => url.includes(script.src))
83
);
84
85
-
// backwards
86
-
urls.reverse();
87
-
for (const url of urls) {
88
-
const script = scripts.find((script) => url.includes(script.src));
89
-
console.log("adding new script", script);
90
91
const newScript = document.createElement("script");
92
-
for (const { name, value } of script.attributes) {
93
-
newScript.setAttribute(name, value);
94
}
95
-
96
script.remove();
97
document.documentElement.appendChild(newScript);
98
}
99
}
100
});
101
} catch (e) {
102
-
console.log(e);
103
}
104
-
105
-
console.log("Done");
106
-
doing = false;
107
-
collectedUrls.clear();
108
}
109
},
110
{
111
-
urls: ["*://*.discord.com/assets/*.js"]
112
}
113
);
···
1
/* eslint-disable no-console */
2
/* eslint-disable no-undef */
3
4
+
const scriptUrls = ["web.", "sentry."];
5
+
let blockedScripts = new Set();
6
7
chrome.webNavigation.onBeforeNavigate.addListener(async (details) => {
8
const url = new URL(details.url);
9
+
if (
10
+
!url.searchParams.has("inj") &&
11
+
(url.hostname.endsWith("discord.com") || url.hostname.endsWith("discordapp.com"))
12
+
) {
13
+
console.log("Enabling block ruleset");
14
await chrome.declarativeNetRequest.updateEnabledRulesets({
15
enableRulesetIds: ["modifyResponseHeaders", "blockLoading"]
16
});
17
}
18
});
19
20
chrome.webRequest.onBeforeRequest.addListener(
21
async (details) => {
22
if (details.tabId === -1) return;
23
24
+
const url = new URL(details.url);
25
+
const hasUrl = scriptUrls.some((scriptUrl) => {
26
+
return (
27
+
details.url.includes(scriptUrl) &&
28
+
!url.searchParams.has("inj") &&
29
+
(url.hostname.endsWith("discord.com") || url.hostname.endsWith("discordapp.com"))
30
+
);
31
+
});
32
+
33
+
if (hasUrl) blockedScripts.add(details.url);
34
+
35
+
if (blockedScripts.size === scriptUrls.length) {
36
+
const blockedScriptsCopy = Array.from(blockedScripts);
37
+
blockedScripts.clear();
38
39
console.log("Running moonlight script");
40
try {
···
44
files: ["index.js"]
45
});
46
} catch (e) {
47
+
console.error(e);
48
}
49
50
console.log("Initializing moonlight");
···
56
try {
57
await window._moonlightBrowserInit();
58
} catch (e) {
59
+
console.error(e);
60
}
61
}
62
});
···
64
console.log(e);
65
}
66
67
+
console.log("Disabling block ruleset");
68
try {
69
await chrome.declarativeNetRequest.updateEnabledRulesets({
70
disableRulesetIds: ["blockLoading"],
71
enableRulesetIds: ["modifyResponseHeaders"]
72
});
73
} catch (e) {
74
+
console.error(e);
75
}
76
77
console.log("Readding scripts");
···
79
await chrome.scripting.executeScript({
80
target: { tabId: details.tabId },
81
world: "MAIN",
82
+
args: [blockedScriptsCopy],
83
+
func: async (blockedScripts) => {
84
const scripts = [...document.querySelectorAll("script")].filter(
85
+
(script) => script.src && blockedScripts.some((url) => url.includes(script.src))
86
);
87
88
+
blockedScripts.reverse();
89
+
for (const url of blockedScripts) {
90
+
if (url.includes("/sentry.")) continue;
91
92
+
const script = scripts.find((script) => url.includes(script.src));
93
const newScript = document.createElement("script");
94
+
for (const attr of script.attributes) {
95
+
if (attr.name === "src") attr.value += "?inj";
96
+
newScript.setAttribute(attr.name, attr.value);
97
}
98
script.remove();
99
document.documentElement.appendChild(newScript);
100
}
101
}
102
});
103
} catch (e) {
104
+
console.error(e);
105
}
106
}
107
},
108
{
109
+
urls: ["*://*.discord.com/assets/*.js", "*://*.discordapp.com/assets/*.js"]
110
}
111
);
+10
-12
packages/browser/src/index.ts
+10
-12
packages/browser/src/index.ts
···
6
import { MoonlightBranch, MoonlightNode } from "@moonlight-mod/types";
7
import { getConfig, getConfigOption, getManifest, setConfigOption } from "@moonlight-mod/core/util/config";
8
import { IndexedDB } from "@zenfs/dom";
9
-
import { configure } from "@zenfs/core";
10
import * as fs from "@zenfs/core/promises";
11
12
function getParts(path: string) {
13
if (path.startsWith("/")) path = path.substring(1);
···
18
delete window._moonlightBrowserInit;
19
20
// Set up a virtual filesystem with IndexedDB
21
-
await configure({
22
-
mounts: {
23
-
"/": {
24
-
backend: IndexedDB,
25
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
26
-
// @ts-ignore tsc tweaking
27
-
storeName: "moonlight-fs"
28
-
}
29
-
}
30
});
31
32
window.moonlightNodeSandboxed = {
···
116
processedExtensions,
117
nativesCache: {},
118
isBrowser: true,
119
120
version: MOONLIGHT_VERSION,
121
branch: MOONLIGHT_BRANCH as MoonlightBranch,
···
127
const manifest = getManifest(extensions, ext);
128
return getConfigOption(ext, name, config, manifest?.settings);
129
},
130
-
setConfigOption(ext, name, value) {
131
setConfigOption(config, ext, name, value);
132
-
this.writeConfig(config);
133
},
134
135
getNatives: () => {},
···
147
async writeConfig(newConfig) {
148
await writeConfig(newConfig);
149
config = newConfig;
150
}
151
};
152
···
6
import { MoonlightBranch, MoonlightNode } from "@moonlight-mod/types";
7
import { getConfig, getConfigOption, getManifest, setConfigOption } from "@moonlight-mod/core/util/config";
8
import { IndexedDB } from "@zenfs/dom";
9
+
import { configureSingle } from "@zenfs/core";
10
import * as fs from "@zenfs/core/promises";
11
+
import { NodeEventPayloads, NodeEventType } from "@moonlight-mod/types/core/event";
12
+
import { createEventEmitter } from "@moonlight-mod/core/util/event";
13
14
function getParts(path: string) {
15
if (path.startsWith("/")) path = path.substring(1);
···
20
delete window._moonlightBrowserInit;
21
22
// Set up a virtual filesystem with IndexedDB
23
+
await configureSingle({
24
+
backend: IndexedDB,
25
+
storeName: "moonlight-fs"
26
});
27
28
window.moonlightNodeSandboxed = {
···
112
processedExtensions,
113
nativesCache: {},
114
isBrowser: true,
115
+
events: createEventEmitter<NodeEventType, NodeEventPayloads>(),
116
117
version: MOONLIGHT_VERSION,
118
branch: MOONLIGHT_BRANCH as MoonlightBranch,
···
124
const manifest = getManifest(extensions, ext);
125
return getConfigOption(ext, name, config, manifest?.settings);
126
},
127
+
async setConfigOption(ext, name, value) {
128
setConfigOption(config, ext, name, value);
129
+
await this.writeConfig(config);
130
},
131
132
getNatives: () => {},
···
144
async writeConfig(newConfig) {
145
await writeConfig(newConfig);
146
config = newConfig;
147
+
this.events.dispatchEvent(NodeEventType.ConfigSaved, newConfig);
148
}
149
};
150
+1
packages/browser/tsconfig.json
+1
packages/browser/tsconfig.json
+7
packages/core/package.json
+7
packages/core/package.json
+5
-5
packages/core/src/extension/loader.ts
+5
-5
packages/core/src/extension/loader.ts
···
13
import calculateDependencies from "../util/dependency";
14
import { createEventEmitter } from "../util/event";
15
import { registerStyles } from "../styles";
16
-
import { EventPayloads, EventType } from "@moonlight-mod/types/core/event";
17
18
const logger = new Logger("core/extension/loader");
19
···
202
}
203
204
export async function loadProcessedExtensions({ extensions, dependencyGraph }: ProcessedExtensions) {
205
-
const eventEmitter = createEventEmitter<EventType, EventPayloads>();
206
const finished: Set<string> = new Set();
207
208
logger.trace(
···
224
}
225
226
function done() {
227
-
eventEmitter.removeEventListener(EventType.ExtensionLoad, cb);
228
r();
229
}
230
231
-
eventEmitter.addEventListener(EventType.ExtensionLoad, cb);
232
if (finished.has(dep)) done();
233
})
234
);
···
242
await loadExt(ext);
243
244
finished.add(ext.id);
245
-
eventEmitter.dispatchEvent(EventType.ExtensionLoad, ext.id);
246
logger.debug(`Loaded "${ext.id}"`);
247
}
248
···
13
import calculateDependencies from "../util/dependency";
14
import { createEventEmitter } from "../util/event";
15
import { registerStyles } from "../styles";
16
+
import { WebEventPayloads, WebEventType } from "@moonlight-mod/types/core/event";
17
18
const logger = new Logger("core/extension/loader");
19
···
202
}
203
204
export async function loadProcessedExtensions({ extensions, dependencyGraph }: ProcessedExtensions) {
205
+
const eventEmitter = createEventEmitter<WebEventType, WebEventPayloads>();
206
const finished: Set<string> = new Set();
207
208
logger.trace(
···
224
}
225
226
function done() {
227
+
eventEmitter.removeEventListener(WebEventType.ExtensionLoad, cb);
228
r();
229
}
230
231
+
eventEmitter.addEventListener(WebEventType.ExtensionLoad, cb);
232
if (finished.has(dep)) done();
233
})
234
);
···
242
await loadExt(ext);
243
244
finished.add(ext.id);
245
+
eventEmitter.dispatchEvent(WebEventType.ExtensionLoad, ext.id);
246
logger.debug(`Loaded "${ext.id}"`);
247
}
248
+1
-4
packages/core/src/extension.ts
+1
-4
packages/core/src/extension.ts
···
129
const ret: DetectedExtension[] = [];
130
const seen = new Set<string>();
131
132
-
const coreExtensionsFs: Record<string, string> = JSON.parse(
133
-
// @ts-expect-error shut up
134
-
_moonlight_coreExtensionsStr
135
-
);
136
const coreExtensions = Array.from(new Set(Object.keys(coreExtensionsFs).map((x) => x.split("/")[0])));
137
138
for (const ext of coreExtensions) {
···
129
const ret: DetectedExtension[] = [];
130
const seen = new Set<string>();
131
132
+
const coreExtensionsFs: Record<string, string> = JSON.parse(_moonlight_coreExtensionsStr);
133
const coreExtensions = Array.from(new Set(Object.keys(coreExtensionsFs).map((x) => x.split("/")[0])));
134
135
for (const ext of coreExtensions) {
+57
-33
packages/core/src/patch.ts
+57
-33
packages/core/src/patch.ts
···
11
} from "@moonlight-mod/types";
12
import Logger from "./util/logger";
13
import calculateDependencies, { Dependency } from "./util/dependency";
14
-
import { EventType } from "@moonlight-mod/types/core/event";
15
import { processFind, processReplace, testFind } from "./util/patch";
16
17
const logger = new Logger("core/patch");
···
66
const moduleCache: Record<string, string> = {};
67
const patched: Record<string, Array<string>> = {};
68
69
-
function patchModules(entry: WebpackJsonpEntry[1]) {
70
-
function patchModule(id: string, patchId: string, replaced: string) {
71
-
// Store what extensions patched what modules for easier debugging
72
-
patched[id] = patched[id] || [];
73
-
patched[id].push(patchId);
74
75
-
// Webpack module arguments are minified, so we replace them with consistent names
76
-
// We have to wrap it so things don't break, though
77
-
const patchedStr = patched[id].sort().join(", ");
78
79
-
const wrapped =
80
-
`(${replaced}).apply(this, arguments)\n` +
81
-
`// Patched by moonlight: ${patchedStr}\n` +
82
-
`//# sourceURL=Webpack-Module-${id}`;
83
84
-
try {
85
-
const func = new Function("module", "exports", "require", wrapped) as WebpackModuleFunc;
86
-
entry[id] = func;
87
-
entry[id].__moonlight = true;
88
-
return true;
89
-
} catch (e) {
90
-
logger.warn("Error constructing function for patch", patchId, e);
91
-
patched[id].pop();
92
-
return false;
93
-
}
94
}
95
96
// Populate the module cache
97
for (const [id, func] of Object.entries(entry)) {
98
if (!Object.hasOwn(moduleCache, id) && func.__moonlight !== true) {
···
108
const origModuleString = moduleCache[id];
109
let moduleString = origModuleString;
110
const patchedStr = [];
111
-
const mappedName = moonlight.moonmap.modules[id];
112
let modified = false;
113
114
const exts = new Set<string>();
115
116
for (let i = 0; i < patches.length; i++) {
117
const patch = patches[i];
118
if (patch.prerequisite != null && !patch.prerequisite()) {
119
continue;
120
}
121
···
135
// We ensured normal PatchReplace objects get turned into arrays on register
136
const replaces = patch.replace as PatchReplace[];
137
138
for (let i = 0; i < replaces.length; i++) {
139
const replace = replaces[i];
140
let patchId = `${patch.ext}#${patch.id}`;
···
151
}
152
153
if (replaced === moduleString) {
154
-
logger.warn("Patch replacement failed", id, patch);
155
if (patch.hardFail) {
156
hardFailed = true;
157
break;
···
164
const newModule = replace.replacement(replaced);
165
entry[id] = newModule;
166
entry[id].__moonlight = true;
167
-
replaced = replaced.toString().replace(/\n/g, "") + `//# sourceURL=Webpack-Module-${id}`;
168
}
169
}
170
···
174
exts.add(patch.ext);
175
}
176
177
-
moonlight.unpatched.delete(patch);
178
if (shouldRemove) patches.splice(i--, 1);
179
}
180
}
181
182
if (modified) {
183
-
patchModule(id, patchedStr.join(", "), moduleString);
184
-
moduleCache[id] = moduleString;
185
moonlight.patched.set(id, exts);
186
}
187
···
189
const parsed = moonlight.lunast.parseScript(id, moduleString);
190
if (parsed != null) {
191
for (const [parsedId, parsedScript] of Object.entries(parsed)) {
192
-
if (patchModule(parsedId, "lunast", parsedScript)) {
193
moduleCache[parsedId] = parsedScript;
194
}
195
}
···
200
201
if (moonlightNode.config.patchAll === true) {
202
if ((typeof id !== "string" || !id.includes("_")) && !entry[id].__moonlight) {
203
-
const wrapped = `(${moduleCache[id]}).apply(this, arguments)\n` + `//# sourceURL=Webpack-Module-${id}`;
204
entry[id] = new Function("module", "exports", "require", wrapped) as WebpackModuleFunc;
205
entry[id].__moonlight = true;
206
}
···
308
if (wpModule.run) {
309
modules[id] = wpModule.run;
310
wpModule.run.__moonlight = true;
311
if (wpModule.entrypoint) entrypoints.push(id);
312
}
313
}
···
315
}
316
317
for (const [name, func] of Object.entries(moonlight.moonmap.getWebpackModules("window.moonlight.moonmap"))) {
318
injectedWpModules.push({ id: name, run: func });
319
modules[name] = func;
320
inject = true;
···
392
const realPush = jsonp.push;
393
if (jsonp.push.__moonlight !== true) {
394
jsonp.push = (items) => {
395
-
moonlight.events.dispatchEvent(EventType.ChunkLoad, {
396
chunkId: items[0],
397
modules: items[1],
398
require: items[2]
···
440
set(modules: any) {
441
const { stack } = new Error();
442
if (stack!.includes("/assets/") && !Array.isArray(modules)) {
443
-
moonlight.events.dispatchEvent(EventType.ChunkLoad, {
444
modules: modules
445
});
446
patchModules(modules);
···
11
} from "@moonlight-mod/types";
12
import Logger from "./util/logger";
13
import calculateDependencies, { Dependency } from "./util/dependency";
14
+
import { WebEventType } from "@moonlight-mod/types/core/event";
15
import { processFind, processReplace, testFind } from "./util/patch";
16
17
const logger = new Logger("core/patch");
···
66
const moduleCache: Record<string, string> = {};
67
const patched: Record<string, Array<string>> = {};
68
69
+
function createSourceURL(id: string) {
70
+
const remapped = Object.entries(moonlight.moonmap.modules).find((m) => m[1] === id)?.[0];
71
+
72
+
if (remapped) {
73
+
return `// Webpack Module: ${id}\n//# sourceURL=${remapped}`;
74
+
}
75
76
+
return `//# sourceURL=Webpack-Module/${id.slice(0, 3)}/${id}`;
77
+
}
78
+
79
+
function patchModule(id: string, patchId: string, replaced: string, entry: WebpackJsonpEntry[1]) {
80
+
// Store what extensions patched what modules for easier debugging
81
+
patched[id] = patched[id] ?? [];
82
+
patched[id].push(patchId);
83
+
84
+
// Webpack module arguments are minified, so we replace them with consistent names
85
+
// We have to wrap it so things don't break, though
86
+
const patchedStr = patched[id].sort().join(", ");
87
88
+
const wrapped =
89
+
`(${replaced}).apply(this, arguments)\n` + `// Patched by moonlight: ${patchedStr}\n` + createSourceURL(id);
90
91
+
try {
92
+
const func = new Function("module", "exports", "require", wrapped) as WebpackModuleFunc;
93
+
entry[id] = func;
94
+
entry[id].__moonlight = true;
95
+
return true;
96
+
} catch (e) {
97
+
logger.warn("Error constructing function for patch", patchId, e);
98
+
patched[id].pop();
99
+
return false;
100
}
101
+
}
102
103
+
function patchModules(entry: WebpackJsonpEntry[1]) {
104
// Populate the module cache
105
for (const [id, func] of Object.entries(entry)) {
106
if (!Object.hasOwn(moduleCache, id) && func.__moonlight !== true) {
···
116
const origModuleString = moduleCache[id];
117
let moduleString = origModuleString;
118
const patchedStr = [];
119
+
const mappedName = Object.entries(moonlight.moonmap.modules).find((m) => m[1] === id)?.[0];
120
let modified = false;
121
+
let swappedModule = false;
122
123
const exts = new Set<string>();
124
125
for (let i = 0; i < patches.length; i++) {
126
const patch = patches[i];
127
if (patch.prerequisite != null && !patch.prerequisite()) {
128
+
moonlight.unpatched.delete(patch);
129
continue;
130
}
131
···
145
// We ensured normal PatchReplace objects get turned into arrays on register
146
const replaces = patch.replace as PatchReplace[];
147
148
+
let isPatched = true;
149
for (let i = 0; i < replaces.length; i++) {
150
const replace = replaces[i];
151
let patchId = `${patch.ext}#${patch.id}`;
···
162
}
163
164
if (replaced === moduleString) {
165
+
logger.warn("Patch replacement failed", id, patchId, patch);
166
+
isPatched = false;
167
if (patch.hardFail) {
168
hardFailed = true;
169
break;
···
176
const newModule = replace.replacement(replaced);
177
entry[id] = newModule;
178
entry[id].__moonlight = true;
179
+
replaced = newModule.toString().replace(/\n/g, "");
180
+
swappedModule = true;
181
}
182
}
183
···
187
exts.add(patch.ext);
188
}
189
190
+
if (isPatched) moonlight.unpatched.delete(patch);
191
if (shouldRemove) patches.splice(i--, 1);
192
}
193
}
194
195
if (modified) {
196
+
let shouldCache = true;
197
+
if (!swappedModule) shouldCache = patchModule(id, patchedStr.join(", "), moduleString, entry);
198
+
if (shouldCache) moduleCache[id] = moduleString;
199
moonlight.patched.set(id, exts);
200
}
201
···
203
const parsed = moonlight.lunast.parseScript(id, moduleString);
204
if (parsed != null) {
205
for (const [parsedId, parsedScript] of Object.entries(parsed)) {
206
+
if (patchModule(parsedId, "lunast", parsedScript, entry)) {
207
moduleCache[parsedId] = parsedScript;
208
}
209
}
···
214
215
if (moonlightNode.config.patchAll === true) {
216
if ((typeof id !== "string" || !id.includes("_")) && !entry[id].__moonlight) {
217
+
const wrapped = `(${moduleCache[id]}).apply(this, arguments)\n` + createSourceURL(id);
218
entry[id] = new Function("module", "exports", "require", wrapped) as WebpackModuleFunc;
219
entry[id].__moonlight = true;
220
}
···
322
if (wpModule.run) {
323
modules[id] = wpModule.run;
324
wpModule.run.__moonlight = true;
325
+
// @ts-expect-error hacks
326
+
wpModule.run.call = function (self, module, exports, require) {
327
+
try {
328
+
wpModule.run!.apply(self, [module, exports, require]);
329
+
} catch (err) {
330
+
logger.error(`Failed to run module "${id}":`, err);
331
+
}
332
+
};
333
if (wpModule.entrypoint) entrypoints.push(id);
334
}
335
}
···
337
}
338
339
for (const [name, func] of Object.entries(moonlight.moonmap.getWebpackModules("window.moonlight.moonmap"))) {
340
+
// @ts-expect-error probably should fix the type on this idk
341
+
func.__moonlight = true;
342
injectedWpModules.push({ id: name, run: func });
343
modules[name] = func;
344
inject = true;
···
416
const realPush = jsonp.push;
417
if (jsonp.push.__moonlight !== true) {
418
jsonp.push = (items) => {
419
+
moonlight.events.dispatchEvent(WebEventType.ChunkLoad, {
420
chunkId: items[0],
421
modules: items[1],
422
require: items[2]
···
464
set(modules: any) {
465
const { stack } = new Error();
466
if (stack!.includes("/assets/") && !Array.isArray(modules)) {
467
+
moonlight.events.dispatchEvent(WebEventType.ChunkLoad, {
468
modules: modules
469
});
470
patchModules(modules);
+4
-1
packages/core/tsconfig.json
+4
-1
packages/core/tsconfig.json
+9
-2
packages/core-extensions/package.json
+9
-2
packages/core-extensions/package.json
···
1
{
2
"name": "@moonlight-mod/core-extensions",
3
"private": true,
4
+
"engineStrict": true,
5
+
"engines": {
6
+
"node": ">=22",
7
+
"pnpm": ">=10",
8
+
"npm": "pnpm",
9
+
"yarn": "pnpm"
10
+
},
11
"dependencies": {
12
"@moonlight-mod/core": "workspace:*",
13
"@moonlight-mod/types": "workspace:*",
14
+
"microdiff": "catalog:prod",
15
+
"nanotar": "catalog:prod"
16
}
17
}
+85
packages/core-extensions/src/commands/index.ts
+85
packages/core-extensions/src/commands/index.ts
···
···
1
+
import { Patch, ExtensionWebpackModule } from "@moonlight-mod/types";
2
+
import { APPLICATION_ID } from "@moonlight-mod/types/coreExtensions/commands";
3
+
4
+
export const patches: Patch[] = [
5
+
{
6
+
find: ".fI5MTU)", // COMMAND_SECTION_BUILT_IN_NAME
7
+
replace: [
8
+
// inject commands
9
+
{
10
+
match: /return (\i)\.filter/,
11
+
replacement: (orig, commands) =>
12
+
`return [...${commands},...require("commands_commands").default._getCommands()].filter`
13
+
},
14
+
15
+
// section
16
+
{
17
+
match: /(?<=\i={)(?=\[\i\.\i\.BUILT_IN]:{id:\i\.\i\.BUILT_IN,type:(\i.\i\.BUILT_IN))/,
18
+
replacement: (_, type) =>
19
+
`"${APPLICATION_ID}":{id:"${APPLICATION_ID}",type:${type},get name(){return "moonlight"}},`
20
+
}
21
+
]
22
+
},
23
+
24
+
// index our section
25
+
{
26
+
find: '"ApplicationCommandIndexStore"',
27
+
replace: {
28
+
match: /(?<=let \i=(\i)\((\i\.\i)\[\i\.\i\.BUILT_IN\],(\i),!0,!0,(\i)\);)null!=(\i)&&(\i)\.push\(\i\)/,
29
+
replacement: (_, createSection, sections, deny, props, section, commands) =>
30
+
`null!=${section}&&(${section}.data=${section}.data.filter(c=>c.applicationId=="-1"));
31
+
null!=${section}&&${commands}.push(${section});
32
+
const moonlightCommands=${createSection}(${sections}["${APPLICATION_ID}"],${deny},!0,!0,${props});
33
+
null!=moonlightCommands&&(moonlightCommands.data=moonlightCommands.data.filter(c=>c.applicationId=="${APPLICATION_ID}"));
34
+
null!=moonlightCommands&&${commands}.push(moonlightCommands)`
35
+
}
36
+
},
37
+
38
+
// grab legacy commands (needed for adding actions that act like sed/plus reacting)
39
+
{
40
+
find: "={tts:{action:",
41
+
replace: {
42
+
match: /Object\.setPrototypeOf\((\i),null\)/,
43
+
replacement: (_, legacyCommands) => `require("commands_commands")._getLegacyCommands(${legacyCommands})`
44
+
}
45
+
},
46
+
47
+
// add icon
48
+
{
49
+
find: ",hasSpaceTerminator:",
50
+
replace: {
51
+
match: /(\i)\.type===/,
52
+
replacement: (orig, section) => `${section}.id!=="${APPLICATION_ID}"&&${orig}`
53
+
}
54
+
},
55
+
{
56
+
find: ".icon,bot:null==",
57
+
replace: {
58
+
match: /(\.useMemo\(\(\)=>{(var \i;)?)((return |if\()(\i)\.type)/,
59
+
replacement: (_, before, beforeVar, after, afterIf, section) => `${before}
60
+
if (${section}.id==="${APPLICATION_ID}") return "https://moonlight-mod.github.io/favicon.png";
61
+
${after}`
62
+
}
63
+
},
64
+
// fix icon sizing because they expect built in to be 24 and others to be 32
65
+
{
66
+
find: ".builtInSeparator}):null]",
67
+
replace: {
68
+
match: /(\i)\.type===\i\.\i\.BUILT_IN/,
69
+
replacement: (orig, section) => `${section}.id!=="${APPLICATION_ID}"&&${orig}`
70
+
}
71
+
},
72
+
73
+
// tell it this app id is authorized
74
+
{
75
+
find: /let{customInstallUrl:\i,installParams:\i,integrationTypesConfig:\i}/,
76
+
replace: {
77
+
match: /\|\|(\i)===\i\.\i\.BUILT_IN/,
78
+
replacement: (orig, id) => `${orig}||${id}==="${APPLICATION_ID}"`
79
+
}
80
+
}
81
+
];
82
+
83
+
export const webpackModules: Record<string, ExtensionWebpackModule> = {
84
+
commands: {}
85
+
};
+11
packages/core-extensions/src/commands/manifest.json
+11
packages/core-extensions/src/commands/manifest.json
+71
packages/core-extensions/src/commands/webpackModules/commands.ts
+71
packages/core-extensions/src/commands/webpackModules/commands.ts
···
···
1
+
import {
2
+
APPLICATION_ID,
3
+
Commands,
4
+
LegacyCommand,
5
+
RegisteredCommand
6
+
} from "@moonlight-mod/types/coreExtensions/commands";
7
+
8
+
type LegacyCommands = Record<string, LegacyCommand>;
9
+
let legacyCommands: LegacyCommands | undefined;
10
+
let queuedLegacyCommands: Record<string, LegacyCommand> | null = {};
11
+
12
+
const registeredCommands: RegisteredCommand[] = [];
13
+
14
+
export function _getLegacyCommands(commands: LegacyCommands) {
15
+
legacyCommands = commands;
16
+
if (queuedLegacyCommands != null) {
17
+
for (const [key, value] of Object.entries(queuedLegacyCommands)) {
18
+
legacyCommands[key] = value;
19
+
}
20
+
queuedLegacyCommands = null;
21
+
}
22
+
}
23
+
24
+
export const commands: Commands = {
25
+
registerCommand(command) {
26
+
const registered: RegisteredCommand = {
27
+
...command,
28
+
untranslatedName: command.id,
29
+
displayName: command.id,
30
+
applicationId: APPLICATION_ID,
31
+
untranslatedDescription: command.description,
32
+
displayDescription: command.description,
33
+
options: command.options?.map((o) => ({
34
+
...o,
35
+
displayName: o.name,
36
+
displayDescription: o.description
37
+
}))
38
+
};
39
+
registeredCommands.push(registered);
40
+
},
41
+
42
+
registerLegacyCommand(id, command) {
43
+
if (command.match) {
44
+
if (command.match instanceof RegExp) {
45
+
command.match = this.anyScopeRegex(command.match);
46
+
} else if (command.match.regex && typeof command.match !== "function") {
47
+
command.match = this.anyScopeRegex(command.match.regex);
48
+
}
49
+
}
50
+
51
+
if (!legacyCommands) {
52
+
queuedLegacyCommands![id] = command;
53
+
} else {
54
+
legacyCommands[id] = command;
55
+
}
56
+
},
57
+
58
+
anyScopeRegex(regex) {
59
+
const out = function (str: string) {
60
+
return regex.exec(str);
61
+
};
62
+
out.regex = regex;
63
+
return out;
64
+
},
65
+
66
+
_getCommands() {
67
+
return [...registeredCommands];
68
+
}
69
+
};
70
+
71
+
export default commands;
+7
-5
packages/core-extensions/src/common/index.ts
+7
-5
packages/core-extensions/src/common/index.ts
···
2
3
export const webpackModules: ExtensionWebExports["webpackModules"] = {
4
stores: {
5
+
dependencies: [{ id: "discord/packages/flux" }]
6
+
},
7
+
ErrorBoundary: {
8
+
dependencies: [{ id: "react" }]
9
+
},
10
+
icons: {
11
+
dependencies: [{ id: "react" }, { id: "discord/components/common/index" }]
12
}
13
};
+1
-1
packages/core-extensions/src/common/manifest.json
+1
-1
packages/core-extensions/src/common/manifest.json
+27
packages/core-extensions/src/common/style.css
+27
packages/core-extensions/src/common/style.css
···
···
1
+
.moonlight-error-boundary {
2
+
margin: 0 0 15px;
3
+
padding: 10px;
4
+
border-radius: 5px;
5
+
font-size: 1rem;
6
+
font-weight: 300;
7
+
line-height: 22px;
8
+
color: var(--text-normal, white);
9
+
background: hsl(var(--red-400-hsl) / 0.1);
10
+
border: 2px solid hsl(var(--red-400-hsl) / 0.5);
11
+
12
+
.theme-light & {
13
+
color: var(--text-normal, black) !important;
14
+
}
15
+
16
+
& > h3 {
17
+
margin-bottom: 0.25rem;
18
+
}
19
+
20
+
& > .hljs {
21
+
background: var(--background-secondary);
22
+
border: 1px solid var(--background-tertiary);
23
+
white-space: pre-wrap;
24
+
font-family: var(--font-code);
25
+
user-select: text;
26
+
}
27
+
}
+47
packages/core-extensions/src/common/webpackModules/ErrorBoundary.tsx
+47
packages/core-extensions/src/common/webpackModules/ErrorBoundary.tsx
···
···
1
+
import React from "@moonlight-mod/wp/react";
2
+
import { ErrorBoundaryProps, ErrorBoundaryState } from "@moonlight-mod/types/coreExtensions/common";
3
+
4
+
const logger = moonlight.getLogger("ErrorBoundary");
5
+
6
+
class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
7
+
constructor(props: ErrorBoundaryProps) {
8
+
super(props);
9
+
this.state = {
10
+
errored: false,
11
+
error: undefined,
12
+
componentStack: undefined
13
+
};
14
+
}
15
+
16
+
static getDerivedStateFromError(error: Error) {
17
+
return {
18
+
errored: true,
19
+
error
20
+
};
21
+
}
22
+
23
+
componentDidCatch(error: Error, { componentStack }: { componentStack: string }) {
24
+
logger.error(`${error}\n\nComponent stack:\n${componentStack}`);
25
+
this.setState({ error, componentStack });
26
+
}
27
+
28
+
render() {
29
+
const { noop, fallback: FallbackComponent, children, message } = this.props;
30
+
const { errored, error, componentStack } = this.state;
31
+
32
+
if (FallbackComponent) return <FallbackComponent children={children} {...this.state} />;
33
+
34
+
if (errored) {
35
+
return noop ? null : (
36
+
<div className={`moonlight-error-boundary`}>
37
+
<h3>{message ?? "An error occurred rendering this component:"}</h3>
38
+
<code className="hljs">{`${error}\n\nComponent stack:\n${componentStack}`}</code>
39
+
</div>
40
+
);
41
+
}
42
+
43
+
return children;
44
+
}
45
+
}
46
+
47
+
export default ErrorBoundary;
+31
packages/core-extensions/src/common/webpackModules/icons.ts
+31
packages/core-extensions/src/common/webpackModules/icons.ts
···
···
1
+
import { Icons, IconSize } from "@moonlight-mod/types/coreExtensions/common";
2
+
import { tokens } from "@moonlight-mod/wp/discord/components/common/index";
3
+
4
+
// This is defined in a Webpack module but we copy it here to be less breakage-prone
5
+
const sizes: Partial<Record<IconSize, number>> = {
6
+
xxs: 12,
7
+
xs: 16,
8
+
sm: 18,
9
+
md: 24,
10
+
lg: 32,
11
+
refresh_sm: 20
12
+
};
13
+
14
+
export const icons: Icons = {
15
+
parseProps(props) {
16
+
// NOTE: var() fallback is non-standard behavior, just for safety reasons
17
+
const color = props?.color ?? tokens?.colors?.["INTERACTIVE_NORMAL"] ?? "var(--interactive-normal)";
18
+
19
+
const size = sizes[props?.size ?? "md"];
20
+
21
+
return {
22
+
// note: this default size is also non-standard behavior, just for safety
23
+
width: size ?? props?.width ?? sizes.md!,
24
+
height: size ?? props?.width ?? sizes.md!,
25
+
26
+
fill: typeof color === "string" ? color : color.css,
27
+
className: props?.colorClass ?? ""
28
+
};
29
+
}
30
+
};
31
+
export default icons;
+83
packages/core-extensions/src/componentEditor/index.ts
+83
packages/core-extensions/src/componentEditor/index.ts
···
···
1
+
import { ExtensionWebpackModule, Patch } from "@moonlight-mod/types";
2
+
3
+
export const patches: Patch[] = [
4
+
// dm list
5
+
{
6
+
find: ".interactiveSystemDM]:",
7
+
replace: [
8
+
{
9
+
match: /decorators:(\i\.isSystemDM\(\)\?\(0,\i\.jsx\)\(.+?verified:!0}\):null)/,
10
+
replacement: (_, decorators) =>
11
+
`decorators:require("componentEditor_dmList").default._patchDecorators([${decorators}],arguments[0])`
12
+
},
13
+
{
14
+
match: /(?<=selected:\i,)children:\[/,
15
+
replacement: 'children:require("componentEditor_dmList").default._patchItems(['
16
+
},
17
+
{
18
+
match: /(?<=(onMouseDown|nameplate):\i}\))]/,
19
+
replacement: "],arguments[0])"
20
+
}
21
+
],
22
+
hardFail: true
23
+
},
24
+
25
+
// member list
26
+
{
27
+
find: ".lostPermission",
28
+
replace: [
29
+
{
30
+
match: /(?<=\(0,\i\.jsxs\)\(\i\.Fragment,{)children:(\[\i\(\),.+?\i\(\)])/,
31
+
replacement: (_, decorators) =>
32
+
`children:require("componentEditor_memberList").default._patchDecorators(${decorators},arguments[0])`
33
+
},
34
+
{
35
+
match: /name:null==\i\?\(0,\i\.jsx\)\("span"/,
36
+
replacement: (orig: string) =>
37
+
`children:require("componentEditor_memberList").default._patchItems([],arguments[0]),${orig}`
38
+
}
39
+
]
40
+
},
41
+
42
+
// messages
43
+
{
44
+
find: '},"new-member")),',
45
+
replace: [
46
+
{
47
+
match: /(?<=\.BADGES](=|:))(\i)(;|})/,
48
+
replacement: (_, leading, badges, trailing) =>
49
+
`require("componentEditor_messages").default._patchUsernameBadges(${badges},arguments[0])${trailing}`
50
+
},
51
+
{
52
+
match: /(?<=className:\i,)badges:(\i)/,
53
+
replacement: (_, badges) =>
54
+
`badges:require("componentEditor_messages").default._patchBadges(${badges},arguments[0])`
55
+
},
56
+
{
57
+
match: /(?<=username:\(0,\i\.jsxs\)\(\i\.Fragment,{)children:(\[.+?])}\),usernameSpanId:/,
58
+
replacement: (_, elements) =>
59
+
`children:require("componentEditor_messages").default._patchUsername(${elements},arguments[0])}),usernameSpanId:`
60
+
}
61
+
]
62
+
},
63
+
{
64
+
find: '.provider&&"Discord"===',
65
+
replace: {
66
+
match: /(?<=\.container\),)children:(\[.+?this\.renderSuppressConfirmModal\(\),.+?\])}\)/,
67
+
replacement: (_, elements) =>
68
+
`children:require("componentEditor_messages").default._patchAccessories(${elements},this.props)})`
69
+
}
70
+
}
71
+
];
72
+
73
+
export const webpackModules: Record<string, ExtensionWebpackModule> = {
74
+
dmList: {
75
+
dependencies: [{ id: "react" }]
76
+
},
77
+
memberList: {
78
+
dependencies: [{ id: "react" }]
79
+
},
80
+
messages: {
81
+
dependencies: [{ id: "react" }]
82
+
}
83
+
};
+11
packages/core-extensions/src/componentEditor/manifest.json
+11
packages/core-extensions/src/componentEditor/manifest.json
···
···
1
+
{
2
+
"$schema": "https://moonlight-mod.github.io/manifest.schema.json",
3
+
"id": "componentEditor",
4
+
"apiLevel": 2,
5
+
"meta": {
6
+
"name": "Component Editor",
7
+
"tagline": "A library to add to commonly patched components",
8
+
"authors": ["Cynosphere"],
9
+
"tags": ["library"]
10
+
}
11
+
}
+61
packages/core-extensions/src/componentEditor/webpackModules/dmList.tsx
+61
packages/core-extensions/src/componentEditor/webpackModules/dmList.tsx
···
···
1
+
import {
2
+
DMList,
3
+
DMListItem,
4
+
DMListDecorator,
5
+
DMListAnchorIndicies,
6
+
DMListDecoratorAnchorIndicies
7
+
} from "@moonlight-mod/types/coreExtensions/componentEditor";
8
+
import React from "@moonlight-mod/wp/react";
9
+
10
+
const items: Record<string, DMListItem> = {};
11
+
const decorators: Record<string, DMListDecorator> = {};
12
+
13
+
function addEntries(
14
+
elements: React.ReactNode[],
15
+
entries: Record<string, DMListItem | DMListDecorator>,
16
+
indicies: Partial<Record<keyof typeof DMListAnchorIndicies | keyof typeof DMListDecoratorAnchorIndicies, number>>,
17
+
props: any
18
+
) {
19
+
const originalElements = [...elements];
20
+
for (const [id, entry] of Object.entries(entries)) {
21
+
const component = <entry.component {...props} key={id} />;
22
+
23
+
if (entry.anchor === undefined) {
24
+
if (entry.before) {
25
+
elements.splice(0, 0, component);
26
+
} else {
27
+
elements.push(component);
28
+
}
29
+
} else {
30
+
const index = elements.indexOf(originalElements[indicies[entry.anchor]!]);
31
+
elements.splice(index! + (entry.before ? 0 : 1), 0, component);
32
+
}
33
+
}
34
+
}
35
+
36
+
export const dmList: DMList = {
37
+
addItem(id, component, anchor, before = false) {
38
+
items[id] = {
39
+
component,
40
+
anchor,
41
+
before
42
+
};
43
+
},
44
+
addDecorator(id, component, anchor, before = false) {
45
+
decorators[id] = {
46
+
component,
47
+
anchor,
48
+
before
49
+
};
50
+
},
51
+
_patchItems(elements, props) {
52
+
addEntries(elements, items, DMListAnchorIndicies, props);
53
+
return elements;
54
+
},
55
+
_patchDecorators(elements, props) {
56
+
addEntries(elements, decorators, DMListDecoratorAnchorIndicies, props);
57
+
return elements;
58
+
}
59
+
};
60
+
61
+
export default dmList;
+50
packages/core-extensions/src/componentEditor/webpackModules/memberList.tsx
+50
packages/core-extensions/src/componentEditor/webpackModules/memberList.tsx
···
···
1
+
import {
2
+
MemberList,
3
+
MemberListDecorator,
4
+
MemberListDecoratorAnchorIndicies
5
+
} from "@moonlight-mod/types/coreExtensions/componentEditor";
6
+
import React from "@moonlight-mod/wp/react";
7
+
8
+
const items: Record<string, React.FC<any>> = {};
9
+
const decorators: Record<string, MemberListDecorator> = {};
10
+
11
+
export const memberList: MemberList = {
12
+
addItem(id, component) {
13
+
items[id] = component;
14
+
},
15
+
addDecorator(id, component, anchor, before = false) {
16
+
decorators[id] = {
17
+
component,
18
+
anchor,
19
+
before
20
+
};
21
+
},
22
+
_patchItems(elements, props) {
23
+
for (const [id, Component] of Object.entries(items)) {
24
+
elements.push(<Component {...props} key={id} />);
25
+
}
26
+
27
+
return elements;
28
+
},
29
+
_patchDecorators(elements, props) {
30
+
const originalElements = [...elements];
31
+
for (const [id, entry] of Object.entries(decorators)) {
32
+
const component = <entry.component {...props} key={id} />;
33
+
34
+
if (entry.anchor === undefined) {
35
+
if (entry.before) {
36
+
elements.splice(0, 0, component);
37
+
} else {
38
+
elements.push(component);
39
+
}
40
+
} else {
41
+
const index = elements.indexOf(originalElements[MemberListDecoratorAnchorIndicies[entry.anchor]!]);
42
+
elements.splice(index! + (entry.before ? 0 : 1), 0, component);
43
+
}
44
+
}
45
+
46
+
return elements;
47
+
}
48
+
};
49
+
50
+
export default memberList;
+97
packages/core-extensions/src/componentEditor/webpackModules/messages.tsx
+97
packages/core-extensions/src/componentEditor/webpackModules/messages.tsx
···
···
1
+
import {
2
+
MessageBadge,
3
+
MessageBadgeIndicies,
4
+
Messages,
5
+
MessageUsername,
6
+
MessageUsernameBadge,
7
+
MessageUsernameBadgeIndicies,
8
+
MessageUsernameIndicies
9
+
} from "@moonlight-mod/types/coreExtensions/componentEditor";
10
+
import React from "@moonlight-mod/wp/react";
11
+
12
+
const username: Record<string, MessageUsername> = {};
13
+
const usernameBadges: Record<string, MessageUsernameBadge> = {};
14
+
const badges: Record<string, MessageBadge> = {};
15
+
const accessories: Record<string, React.FC<any>> = {};
16
+
17
+
function addEntries(
18
+
elements: React.ReactNode[],
19
+
entries: Record<string, MessageUsername | MessageUsernameBadge | MessageBadge>,
20
+
indicies: Partial<
21
+
Record<
22
+
| keyof typeof MessageUsernameIndicies
23
+
| keyof typeof MessageUsernameBadgeIndicies
24
+
| keyof typeof MessageBadgeIndicies,
25
+
number
26
+
>
27
+
>,
28
+
props: any
29
+
) {
30
+
const originalElements = [...elements];
31
+
for (const [id, entry] of Object.entries(entries)) {
32
+
const component = <entry.component {...props} key={id} />;
33
+
34
+
if (entry.anchor === undefined) {
35
+
if (entry.before) {
36
+
elements.splice(0, 0, component);
37
+
} else {
38
+
elements.push(component);
39
+
}
40
+
} else {
41
+
const index = elements.indexOf(originalElements[indicies[entry.anchor]!]);
42
+
elements.splice(index! + (entry.before ? 0 : 1), 0, component);
43
+
}
44
+
}
45
+
}
46
+
47
+
function addComponents(elements: React.ReactNode[], components: Record<string, React.FC<any>>, props: any) {
48
+
for (const [id, Component] of Object.entries(components)) {
49
+
const component = <Component {...props} key={id} />;
50
+
elements.push(component);
51
+
}
52
+
}
53
+
54
+
export const messages: Messages = {
55
+
addToUsername(id, component, anchor, before = false) {
56
+
username[id] = {
57
+
component,
58
+
anchor,
59
+
before
60
+
};
61
+
},
62
+
addUsernameBadge(id, component, anchor, before = false) {
63
+
usernameBadges[id] = {
64
+
component,
65
+
anchor,
66
+
before
67
+
};
68
+
},
69
+
addBadge(id, component, anchor, before = false) {
70
+
badges[id] = {
71
+
component,
72
+
anchor,
73
+
before
74
+
};
75
+
},
76
+
addAccessory(id, component) {
77
+
accessories[id] = component;
78
+
},
79
+
_patchUsername(elements, props) {
80
+
addEntries(elements, username, MessageUsernameIndicies, props);
81
+
return elements;
82
+
},
83
+
_patchUsernameBadges(elements, props) {
84
+
addEntries(elements, usernameBadges, MessageUsernameBadgeIndicies, props);
85
+
return elements;
86
+
},
87
+
_patchBadges(elements, props) {
88
+
addEntries(elements, badges, MessageBadgeIndicies, props);
89
+
return elements;
90
+
},
91
+
_patchAccessories(elements, props) {
92
+
addComponents(elements, accessories, props);
93
+
return elements;
94
+
}
95
+
};
96
+
97
+
export default messages;
+1
packages/core-extensions/src/contextMenu/webpackModules/contextMenu.ts
+1
packages/core-extensions/src/contextMenu/webpackModules/contextMenu.ts
+2
-1
packages/core-extensions/src/contextMenu/webpackModules/evilMenu.ts
+2
-1
packages/core-extensions/src/contextMenu/webpackModules/evilMenu.ts
···
1
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
2
3
let code =
4
spacepack.require.m[
5
spacepack.findByCode("Menu API only allows Items and groups of Items as children.")[0].id
···
7
8
const parserSym = code.match(/(?<=_patchMenu\(.,).+?(?=\()/)![0];
9
10
-
code = code.replace(/(?<=function\(\){return ).(?=})/, parserSym);
11
const mod = new Function("module", "exports", "require", `(${code}).apply(this, arguments)`);
12
13
const exp: any = {};
···
1
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
2
3
+
// spacepack.require.m[moonlight.moonmap.modules["discord/modules/menus/web/Menu"]].toString();
4
let code =
5
spacepack.require.m[
6
spacepack.findByCode("Menu API only allows Items and groups of Items as children.")[0].id
···
8
9
const parserSym = code.match(/(?<=_patchMenu\(.,).+?(?=\()/)![0];
10
11
+
code = code.replace(/{(.):\(\)=>./, (orig, e) => `{${e}:()=>${parserSym}`);
12
const mod = new Function("module", "exports", "require", `(${code}).apply(this, arguments)`);
13
14
const exp: any = {};
+2
-2
packages/core-extensions/src/disableSentry/index.ts
+2
-2
packages/core-extensions/src/disableSentry/index.ts
+4
-1
packages/core-extensions/src/disableSentry/manifest.json
+4
-1
packages/core-extensions/src/disableSentry/manifest.json
···
12
"https://*.sentry.io/*",
13
"https://*.discord.com/error-reporting-proxy/*",
14
"https://discord.com/assets/sentry.*.js",
15
+
"https://*.discord.com/assets/sentry.*.js",
16
+
"https://*.discordapp.com/error-reporting-proxy/*",
17
+
"https://discordapp.com/assets/sentry.*.js",
18
+
"https://*.discordapp.com/assets/sentry.*.js"
19
]
20
}
+19
-2
packages/core-extensions/src/experiments/index.ts
+19
-2
packages/core-extensions/src/experiments/index.ts
···
11
{
12
find: '"scientist:triggered"', // Scientist? Triggered.
13
replace: {
14
-
match: /(?<=personal_connection_id\|\|)!1/,
15
-
replacement: "!0"
16
}
17
},
18
···
23
match: /&&\((.)\?\(0,/,
24
replacement: (_, isStaff) =>
25
`&&(((moonlight.getConfigOption("experiments","devtools")??false)?true:${isStaff})?(0,`
26
}
27
},
28
···
11
{
12
find: '"scientist:triggered"', // Scientist? Triggered.
13
replace: {
14
+
match: ".personal_connection_id",
15
+
replacement: ".personal_connection_id || true"
16
}
17
},
18
···
23
match: /&&\((.)\?\(0,/,
24
replacement: (_, isStaff) =>
25
`&&(((moonlight.getConfigOption("experiments","devtools")??false)?true:${isStaff})?(0,`
26
+
}
27
+
},
28
+
// staff help menu - visual refresh
29
+
{
30
+
find: '("AppTitleBar")',
31
+
replace: {
32
+
match: /{hasBugReporterAccess:(\i)}=\i\.\i\.useExperiment\({location:"HeaderBar"},{autoTrackExposure:!1}\);/,
33
+
replacement: (orig, isStaff) =>
34
+
`${orig}if(moonlight.getConfigOption("experiments","devtools")??false)${isStaff}=true;`
35
+
}
36
+
},
37
+
{
38
+
find: 'navId:"staff-help-popout",',
39
+
replace: {
40
+
match: /isDiscordDeveloper:(\i)}\),/,
41
+
replacement: (_, isStaff) =>
42
+
`isDiscordDeveloper:(moonlight.getConfigOption("experiments","devtools")??false)||${isStaff}}),`
43
}
44
},
45
+38
-7
packages/core-extensions/src/moonbase/host.ts
+38
-7
packages/core-extensions/src/moonbase/host.ts
···
2
import * as fs from "node:fs/promises";
3
import * as path from "node:path";
4
import getNatives from "./native";
5
6
const natives = getNatives();
7
···
50
electron.app.exit(0);
51
}
52
53
function showAbout() {
54
electron.dialog.showMessageBox({
55
title: "About moonlight",
···
63
const i = entries.findIndex((e) => e.label === "Check for Updates...");
64
if (i === -1) return original.call(this, entries);
65
66
-
entries.splice(i + 1, 0, {
67
-
label: "moonlight",
68
-
submenu: [
69
{ label: "Update and restart", click: updateAndRestart },
70
-
{ label: "Reset config", click: resetConfig },
71
-
{ label: "About", click: showAbout }
72
-
]
73
-
});
74
75
return original.call(this, entries);
76
};
···
2
import * as fs from "node:fs/promises";
3
import * as path from "node:path";
4
import getNatives from "./native";
5
+
import { MoonlightBranch } from "@moonlight-mod/types";
6
7
const natives = getNatives();
8
···
51
electron.app.exit(0);
52
}
53
54
+
async function changeBranch(branch: MoonlightBranch) {
55
+
if (moonlightHost.branch === branch) return;
56
+
if (!(await confirm("switch branches"))) return;
57
+
try {
58
+
await natives.updateMoonlight(branch);
59
+
await electron.dialog.showMessageBox({ message: "Branch switch successful, restarting Discord." });
60
+
electron.app.relaunch();
61
+
electron.app.exit(0);
62
+
} catch (e) {
63
+
await electron.dialog.showMessageBox({ message: "Failed to switch branches:\n" + e, type: "error" });
64
+
}
65
+
}
66
+
67
function showAbout() {
68
electron.dialog.showMessageBox({
69
title: "About moonlight",
···
77
const i = entries.findIndex((e) => e.label === "Check for Updates...");
78
if (i === -1) return original.call(this, entries);
79
80
+
if (!entries.find((e) => e.label === "moonlight")) {
81
+
const options: Electron.MenuItemConstructorOptions[] = [
82
{ label: "Update and restart", click: updateAndRestart },
83
+
{ label: "Reset config", click: resetConfig }
84
+
];
85
+
86
+
if (moonlightHost.branch !== MoonlightBranch.DEV) {
87
+
options.push({
88
+
label: "Switch branch",
89
+
submenu: [MoonlightBranch.STABLE, MoonlightBranch.NIGHTLY].map((branch) => ({
90
+
label: branch,
91
+
type: "radio",
92
+
checked: moonlightHost.branch === branch,
93
+
click: () => changeBranch(branch)
94
+
}))
95
+
});
96
+
}
97
+
98
+
options.push({ label: "About", click: showAbout });
99
+
100
+
entries.splice(i + 1, 0, {
101
+
label: "moonlight",
102
+
submenu: options
103
+
});
104
+
}
105
106
return original.call(this, entries);
107
};
+13
-4
packages/core-extensions/src/moonbase/index.tsx
+13
-4
packages/core-extensions/src/moonbase/index.tsx
···
8
{
9
// CvQlAA mapped to ERRORS_ACTION_TO_TAKE
10
// FIXME: Better patch find?
11
-
match: /,(\(0,(.)\.jsx\))\("p",{children:.\.intl\.string\(.\..\.CvQlAA\)}\)/,
12
replacement: (_, createElement, ReactJSX) =>
13
`,${createElement}(require("moonbase_crashScreen")?.UpdateText??${ReactJSX}.Fragment,{state:this.state,setState:this.setState.bind(this)})`
14
},
15
16
// wrap actions field to display error details
17
{
18
-
match: /(?<=return(\(0,(.)\.jsx\))\(.+?,)action:(.),className:/,
19
replacement: (_, createElement, ReactJSX, action) =>
20
`action:require("moonbase_crashScreen")?.wrapAction?${createElement}(require("moonbase_crashScreen").wrapAction,{action:${action},state:this.state}):${action},className:`
21
},
···
23
// add update button
24
// +hivLS -> ERRORS_RELOAD
25
{
26
-
match: /(?<=\["\+hivLS"\]\)}\),(\(0,(.)\.jsx\))\(.,{}\))/,
27
replacement: (_, createElement, ReactJSX) =>
28
`,${createElement}(require("moonbase_crashScreen")?.UpdateButton??${ReactJSX}.Fragment,{state:this.state,setState:this.setState.bind(this)})`
29
}
···
42
{ id: "react" },
43
{ id: "discord/components/common/index" },
44
{ ext: "moonbase", id: "stores" },
45
-
{ id: "discord/modules/guild_settings/IntegrationCard.css" },
46
"Masks.PANEL_BUTTON",
47
'"Missing channel in Channel.openChannelContextMenu"',
48
".forumOrHome]:"
49
]
50
},
51
52
settings: {
53
dependencies: [
54
{ ext: "spacepack", id: "spacepack" },
55
{ ext: "settings", id: "settings" },
56
{ id: "react" },
57
{ ext: "moonbase", id: "ui" },
58
':"USER_SETTINGS_MODAL_SET_SECTION"'
59
],
60
entrypoint: true
···
64
dependencies: [
65
{ id: "react" },
66
{ ext: "moonbase", id: "stores" },
67
{ ext: "notices", id: "notices" },
68
{
69
ext: "spacepack",
···
8
{
9
// CvQlAA mapped to ERRORS_ACTION_TO_TAKE
10
// FIXME: Better patch find?
11
+
match: /,(\(0,(\i)\.jsx\))\("p",{children:\i\.\i\.string\(\i\.\i\.CvQlAA\)}\)/,
12
replacement: (_, createElement, ReactJSX) =>
13
`,${createElement}(require("moonbase_crashScreen")?.UpdateText??${ReactJSX}.Fragment,{state:this.state,setState:this.setState.bind(this)})`
14
},
15
16
// wrap actions field to display error details
17
{
18
+
match: /(?<=return(\(0,(\i)\.jsx\))\(.+?,)action:(\i),className:/,
19
replacement: (_, createElement, ReactJSX, action) =>
20
`action:require("moonbase_crashScreen")?.wrapAction?${createElement}(require("moonbase_crashScreen").wrapAction,{action:${action},state:this.state}):${action},className:`
21
},
···
23
// add update button
24
// +hivLS -> ERRORS_RELOAD
25
{
26
+
match: /(?<=\["\+hivLS"\]\)}\),(\(0,(\i)\.jsx\))\(\i,{}\))/,
27
replacement: (_, createElement, ReactJSX) =>
28
`,${createElement}(require("moonbase_crashScreen")?.UpdateButton??${ReactJSX}.Fragment,{state:this.state,setState:this.setState.bind(this)})`
29
}
···
42
{ id: "react" },
43
{ id: "discord/components/common/index" },
44
{ ext: "moonbase", id: "stores" },
45
+
{ ext: "moonbase", id: "ThemeDarkIcon" },
46
+
{ id: "discord/modules/guild_settings/web/AppCard.css" },
47
+
{ ext: "contextMenu", id: "contextMenu" },
48
+
{ id: "discord/modules/modals/Modals" },
49
"Masks.PANEL_BUTTON",
50
'"Missing channel in Channel.openChannelContextMenu"',
51
".forumOrHome]:"
52
]
53
},
54
55
+
ThemeDarkIcon: {
56
+
dependencies: [{ ext: "common", id: "icons" }, { id: "react" }]
57
+
},
58
+
59
settings: {
60
dependencies: [
61
{ ext: "spacepack", id: "spacepack" },
62
{ ext: "settings", id: "settings" },
63
{ id: "react" },
64
{ ext: "moonbase", id: "ui" },
65
+
{ ext: "contextMenu", id: "contextMenu" },
66
':"USER_SETTINGS_MODAL_SET_SECTION"'
67
],
68
entrypoint: true
···
72
dependencies: [
73
{ id: "react" },
74
{ ext: "moonbase", id: "stores" },
75
+
{ ext: "moonbase", id: "ThemeDarkIcon" },
76
{ ext: "notices", id: "notices" },
77
{
78
ext: "spacepack",
+11
-3
packages/core-extensions/src/moonbase/manifest.json
+11
-3
packages/core-extensions/src/moonbase/manifest.json
···
7
"tagline": "The official settings UI for moonlight",
8
"authors": ["Cynosphere", "NotNite", "redstonekasi"]
9
},
10
-
"dependencies": ["spacepack", "settings", "common", "notices"],
11
"settings": {
12
"sections": {
13
"advice": "reload",
14
"displayName": "Split into sections",
15
"description": "Show the Moonbase tabs as separate sections",
16
-
"type": "boolean"
17
},
18
"saveFilter": {
19
"advice": "none",
20
"displayName": "Persist filter",
21
"description": "Save extension filter in config",
22
-
"type": "boolean"
23
},
24
"updateChecking": {
25
"advice": "none",
···
7
"tagline": "The official settings UI for moonlight",
8
"authors": ["Cynosphere", "NotNite", "redstonekasi"]
9
},
10
+
"dependencies": ["spacepack", "settings", "common", "notices", "contextMenu"],
11
"settings": {
12
"sections": {
13
"advice": "reload",
14
"displayName": "Split into sections",
15
"description": "Show the Moonbase tabs as separate sections",
16
+
"type": "boolean",
17
+
"default": false
18
+
},
19
+
"oldLocation": {
20
+
"advice": "reload",
21
+
"displayName": "Put Moonbase back at the bottom",
22
+
"type": "boolean",
23
+
"default": false
24
},
25
"saveFilter": {
26
"advice": "none",
27
"displayName": "Persist filter",
28
"description": "Save extension filter in config",
29
+
"type": "boolean",
30
+
"default": false
31
},
32
"updateChecking": {
33
"advice": "none",
+17
-24
packages/core-extensions/src/moonbase/native.ts
+17
-24
packages/core-extensions/src/moonbase/native.ts
···
15
16
export const userAgent = `moonlight/${moonlightGlobal.version} (https://github.com/moonlight-mod/moonlight)`;
17
18
async function getStableRelease(): Promise<{
19
name: string;
20
assets: {
···
24
}> {
25
const req = await fetch(githubApiUrl, {
26
cache: "no-store",
27
-
headers: {
28
-
"User-Agent": userAgent
29
-
}
30
});
31
return await req.json();
32
}
···
43
} else if (moonlightGlobal.branch === MoonlightBranch.NIGHTLY) {
44
const req = await fetch(nightlyRefUrl, {
45
cache: "no-store",
46
-
headers: {
47
-
"User-Agent": userAgent
48
-
}
49
});
50
const ref = (await req.text()).split("\n")[0];
51
return ref !== moonlightGlobal.version ? ref : null;
···
58
}
59
},
60
61
-
async updateMoonlight() {
62
// Note: this won't do anything on browser, we should probably disable it
63
// entirely when running in browser.
64
async function downloadStable(): Promise<[ArrayBuffer, string]> {
···
69
logger.debug(`Downloading ${asset.browser_download_url}`);
70
const req = await fetch(asset.browser_download_url, {
71
cache: "no-store",
72
-
headers: {
73
-
"User-Agent": userAgent
74
-
}
75
});
76
77
return [await req.arrayBuffer(), json.name];
···
81
logger.debug(`Downloading ${nightlyZipUrl}`);
82
const zipReq = await fetch(nightlyZipUrl, {
83
cache: "no-store",
84
-
headers: {
85
-
"User-Agent": userAgent
86
-
}
87
});
88
89
const refReq = await fetch(nightlyRefUrl, {
90
cache: "no-store",
91
-
headers: {
92
-
"User-Agent": userAgent
93
-
}
94
});
95
const ref = (await refReq.text()).split("\n")[0];
96
···
98
}
99
100
const [tar, ref] =
101
-
moonlightGlobal.branch === MoonlightBranch.STABLE
102
? await downloadStable()
103
-
: moonlightGlobal.branch === MoonlightBranch.NIGHTLY
104
? await downloadNightly()
105
: [null, null];
106
···
137
try {
138
const req = await fetch(repo, {
139
cache: "no-store",
140
-
headers: {
141
-
"User-Agent": userAgent
142
-
}
143
});
144
const json = await req.json();
145
ret[repo] = json;
···
154
async installExtension(manifest, url, repo) {
155
const req = await fetch(url, {
156
cache: "no-store",
157
-
headers: {
158
-
"User-Agent": userAgent
159
-
}
160
});
161
162
const dir = moonlightGlobal.getExtensionDir(manifest.id);
···
15
16
export const userAgent = `moonlight/${moonlightGlobal.version} (https://github.com/moonlight-mod/moonlight)`;
17
18
+
// User-Agent header causes trouble on Firefox
19
+
const isBrowser = globalThis.moonlightNode != null && globalThis.moonlightNode.isBrowser;
20
+
const sharedHeaders: Record<string, string> = {};
21
+
if (!isBrowser) sharedHeaders["User-Agent"] = userAgent;
22
+
23
async function getStableRelease(): Promise<{
24
name: string;
25
assets: {
···
29
}> {
30
const req = await fetch(githubApiUrl, {
31
cache: "no-store",
32
+
headers: sharedHeaders
33
});
34
return await req.json();
35
}
···
46
} else if (moonlightGlobal.branch === MoonlightBranch.NIGHTLY) {
47
const req = await fetch(nightlyRefUrl, {
48
cache: "no-store",
49
+
headers: sharedHeaders
50
});
51
const ref = (await req.text()).split("\n")[0];
52
return ref !== moonlightGlobal.version ? ref : null;
···
59
}
60
},
61
62
+
async updateMoonlight(overrideBranch?: MoonlightBranch) {
63
+
const branch = overrideBranch ?? moonlightGlobal.branch;
64
+
65
// Note: this won't do anything on browser, we should probably disable it
66
// entirely when running in browser.
67
async function downloadStable(): Promise<[ArrayBuffer, string]> {
···
72
logger.debug(`Downloading ${asset.browser_download_url}`);
73
const req = await fetch(asset.browser_download_url, {
74
cache: "no-store",
75
+
headers: sharedHeaders
76
});
77
78
return [await req.arrayBuffer(), json.name];
···
82
logger.debug(`Downloading ${nightlyZipUrl}`);
83
const zipReq = await fetch(nightlyZipUrl, {
84
cache: "no-store",
85
+
headers: sharedHeaders
86
});
87
88
const refReq = await fetch(nightlyRefUrl, {
89
cache: "no-store",
90
+
headers: sharedHeaders
91
});
92
const ref = (await refReq.text()).split("\n")[0];
93
···
95
}
96
97
const [tar, ref] =
98
+
branch === MoonlightBranch.STABLE
99
? await downloadStable()
100
+
: branch === MoonlightBranch.NIGHTLY
101
? await downloadNightly()
102
: [null, null];
103
···
134
try {
135
const req = await fetch(repo, {
136
cache: "no-store",
137
+
headers: sharedHeaders
138
});
139
const json = await req.json();
140
ret[repo] = json;
···
149
async installExtension(manifest, url, repo) {
150
const req = await fetch(url, {
151
cache: "no-store",
152
+
headers: sharedHeaders
153
});
154
155
const dir = moonlightGlobal.getExtensionDir(manifest.id);
+63
packages/core-extensions/src/moonbase/style.css
+63
packages/core-extensions/src/moonbase/style.css
···
16
resize: vertical;
17
}
18
19
/* Update notice at the top of the client */
20
.moonbase-updates-notice {
21
background-color: var(--moonbase-bg);
···
73
display: flex;
74
flex-direction: row;
75
gap: 8px;
76
}
77
78
.moonbase-update-divider {
79
margin: 32px 0;
80
}
81
82
/* Crash screen */
···
204
line-height: 1.286;
205
font-weight: 400;
206
}
···
16
resize: vertical;
17
}
18
19
+
.moonbase-link-buttons {
20
+
border-bottom: 2px solid var(--background-modifier-accent);
21
+
margin-bottom: -2px;
22
+
margin-left: 0 !important;
23
+
padding-right: 20px;
24
+
gap: 1rem;
25
+
}
26
+
27
+
.moonbase-speen {
28
+
animation: moonbase-speen-animation 0.25s linear infinite;
29
+
}
30
+
31
+
@keyframes moonbase-speen-animation {
32
+
from {
33
+
transform: rotate(0deg);
34
+
}
35
+
to {
36
+
transform: rotate(360deg);
37
+
}
38
+
}
39
+
40
/* Update notice at the top of the client */
41
.moonbase-updates-notice {
42
background-color: var(--moonbase-bg);
···
94
display: flex;
95
flex-direction: row;
96
gap: 8px;
97
+
align-items: center;
98
}
99
100
.moonbase-update-divider {
101
margin: 32px 0;
102
+
}
103
+
104
+
.moonlight-card-info-header {
105
+
margin-bottom: 0.25rem;
106
+
}
107
+
108
+
.moonlight-card-badge {
109
+
border-radius: 0.1875rem;
110
+
padding: 0 0.275rem;
111
+
margin-right: 0.4em;
112
+
background-color: var(--badge-color, var(--bg-mod-strong));
113
}
114
115
/* Crash screen */
···
237
line-height: 1.286;
238
font-weight: 400;
239
}
240
+
241
+
/* About page */
242
+
.moonbase-wordmark {
243
+
width: 100%;
244
+
}
245
+
246
+
.moonbase-devs {
247
+
width: 100%;
248
+
display: flex;
249
+
justify-content: center;
250
+
gap: 0rem 0.5rem;
251
+
padding-top: 0.5rem;
252
+
}
253
+
254
+
.moonbase-dev {
255
+
height: 4rem;
256
+
}
257
+
258
+
.moonbase-dev-avatar {
259
+
width: 2rem;
260
+
border-radius: 50%;
261
+
}
262
+
263
+
.moonbase-gap {
264
+
gap: 0.5rem;
265
+
}
266
+
267
+
.moonbase-about-page {
268
+
gap: 1rem;
269
+
}
+2
-2
packages/core-extensions/src/moonbase/types.ts
+2
-2
packages/core-extensions/src/moonbase/types.ts
···
1
import { ExtensionCompat } from "@moonlight-mod/core/extension/loader";
2
-
import { DetectedExtension, ExtensionManifest } from "@moonlight-mod/types";
3
4
export type MoonbaseNatives = {
5
checkForMoonlightUpdate(): Promise<string | null>;
6
-
updateMoonlight(): Promise<void>;
7
8
fetchRepositories(repos: string[]): Promise<Record<string, RepositoryManifest[]>>;
9
installExtension(manifest: RepositoryManifest, url: string, repo: string): Promise<void>;
···
1
import { ExtensionCompat } from "@moonlight-mod/core/extension/loader";
2
+
import { DetectedExtension, ExtensionManifest, MoonlightBranch } from "@moonlight-mod/types";
3
4
export type MoonbaseNatives = {
5
checkForMoonlightUpdate(): Promise<string | null>;
6
+
updateMoonlight(overrideBranch?: MoonlightBranch): Promise<void>;
7
8
fetchRepositories(repos: string[]): Promise<Record<string, RepositoryManifest[]>>;
9
installExtension(manifest: RepositoryManifest, url: string, repo: string): Promise<void>;
+36
packages/core-extensions/src/moonbase/webpackModules/ThemeDarkIcon.tsx
+36
packages/core-extensions/src/moonbase/webpackModules/ThemeDarkIcon.tsx
···
···
1
+
// RIP to ThemeDarkIcon ????-2025
2
+
// <Cynthia> Failed to remap "ThemeDarkIcon" in "discord/components/common/index"
3
+
// <NotNite> bro are you fucking kidding me
4
+
// <NotNite> that's literally the icon we use for the update banner
5
+
6
+
import React from "@moonlight-mod/wp/react";
7
+
import icons from "@moonlight-mod/wp/common_icons";
8
+
import type { IconProps } from "@moonlight-mod/types/coreExtensions/common";
9
+
10
+
export default function ThemeDarkIcon(props?: IconProps) {
11
+
const parsed = icons.parseProps(props);
12
+
13
+
return (
14
+
<svg
15
+
aria-hidden="true"
16
+
role="img"
17
+
xmlns="http://www.w3.org/2000/svg"
18
+
width={parsed.width}
19
+
height={parsed.height}
20
+
fill="none"
21
+
viewBox="0 0 24 24"
22
+
>
23
+
<path
24
+
fill={parsed.fill}
25
+
className={parsed.className}
26
+
d="M20.52 18.96c.32-.4-.01-.96-.52-.96A11 11 0 0 1 9.77 2.94c.31-.78-.3-1.68-1.1-1.43a11 11 0 1 0 11.85 17.45Z"
27
+
/>
28
+
29
+
<path
30
+
fill={parsed.fill}
31
+
className={parsed.className}
32
+
d="m17.73 9.27-.76-2.02a.5.5 0 0 0-.94 0l-.76 2.02-2.02.76a.5.5 0 0 0 0 .94l2.02.76.76 2.02a.5.5 0 0 0 .94 0l.76-2.02 2.02-.76a.5.5 0 0 0 0-.94l-2.02-.76ZM19.73 2.62l.45 1.2 1.2.45c.21.08.21.38 0 .46l-1.2.45-.45 1.2a.25.25 0 0 1-.46 0l-.45-1.2-1.2-.45a.25.25 0 0 1 0-.46l1.2-.45.45-1.2a.25.25 0 0 1 .46 0Z"
33
+
/>
34
+
</svg>
35
+
);
36
+
}
+25
-12
packages/core-extensions/src/moonbase/webpackModules/crashScreen.tsx
+25
-12
packages/core-extensions/src/moonbase/webpackModules/crashScreen.tsx
···
1
import React from "@moonlight-mod/wp/react";
2
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
3
import { useStateFromStores, useStateFromStoresObject } from "@moonlight-mod/wp/discord/packages/flux";
4
-
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
5
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
6
import { RepositoryManifest, UpdateState } from "../types";
7
import { ConfigExtension, DetectedExtension } from "@moonlight-mod/types";
8
9
-
const { Button, TabBar } = Components;
10
-
const TabBarClasses = spacepack.findByCode(/tabBar:"tabBar_[a-z0-9]+",tabBarItem:"tabBarItem_[a-z0-9]+"/)[0].exports;
11
-
12
-
const MODULE_REGEX = /Webpack-Module-(\d+)/g;
13
14
const logger = moonlight.getLogger("moonbase/crashScreen");
15
···
142
const causes = React.useMemo(() => {
143
const causes = new Set<string>();
144
if (state.error.stack) {
145
-
for (const [, id] of state.error.stack.matchAll(MODULE_REGEX))
146
for (const ext of moonlight.patched.get(id) ?? []) causes.add(ext);
147
}
148
-
for (const [, id] of state.info.componentStack.matchAll(MODULE_REGEX))
149
for (const ext of moonlight.patched.get(id) ?? []) causes.add(ext);
150
return [...causes];
151
}, []);
152
···
154
<div className="moonbase-crash-wrapper">
155
{action}
156
<TabBar
157
-
className={`${TabBarClasses.tabBar} moonbase-crash-tabs`}
158
type="top"
159
selectedItem={tab}
160
onItemSelect={(v) => setTab(v)}
161
>
162
-
<TabBar.Item className={TabBarClasses.tabBarItem} id="crash">
163
Crash details
164
</TabBar.Item>
165
-
<TabBar.Item className={TabBarClasses.tabBarItem} id="extensions" disabled={updateCount === 0}>
166
{`Extension updates (${updateCount})`}
167
</TabBar.Item>
168
-
<TabBar.Item className={TabBarClasses.tabBarItem} id="causes" disabled={causes.length === 0}>
169
{`Possible causes (${causes.length})`}
170
</TabBar.Item>
171
</TabBar>
···
1
import React from "@moonlight-mod/wp/react";
2
+
import { Button, TabBar } from "@moonlight-mod/wp/discord/components/common/index";
3
import { useStateFromStores, useStateFromStoresObject } from "@moonlight-mod/wp/discord/packages/flux";
4
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
5
import { RepositoryManifest, UpdateState } from "../types";
6
import { ConfigExtension, DetectedExtension } from "@moonlight-mod/types";
7
+
import DiscoveryClasses from "@moonlight-mod/wp/discord/modules/discovery/web/Discovery.css";
8
9
+
const MODULE_REGEX = /Webpack-Module\/(\d+)\/(\d+)/g;
10
11
const logger = moonlight.getLogger("moonbase/crashScreen");
12
···
139
const causes = React.useMemo(() => {
140
const causes = new Set<string>();
141
if (state.error.stack) {
142
+
for (const [, , id] of state.error.stack.matchAll(MODULE_REGEX))
143
for (const ext of moonlight.patched.get(id) ?? []) causes.add(ext);
144
}
145
+
for (const [, , id] of state.info.componentStack.matchAll(MODULE_REGEX))
146
for (const ext of moonlight.patched.get(id) ?? []) causes.add(ext);
147
+
148
+
for (const [path, id] of Object.entries(moonlight.moonmap.modules)) {
149
+
const MAPPING_REGEX = new RegExp(
150
+
// @ts-expect-error Only Firefox has RegExp.escape
151
+
`(${RegExp.escape ? RegExp.escape(path) : path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`,
152
+
"g"
153
+
);
154
+
155
+
if (state.error.stack) {
156
+
for (const match of state.error.stack.matchAll(MAPPING_REGEX))
157
+
if (match) for (const ext of moonlight.patched.get(id) ?? []) causes.add(ext);
158
+
}
159
+
for (const match of state.info.componentStack.matchAll(MAPPING_REGEX))
160
+
if (match) for (const ext of moonlight.patched.get(id) ?? []) causes.add(ext);
161
+
}
162
+
163
return [...causes];
164
}, []);
165
···
167
<div className="moonbase-crash-wrapper">
168
{action}
169
<TabBar
170
+
className={`${DiscoveryClasses.tabBar} moonbase-crash-tabs`}
171
type="top"
172
selectedItem={tab}
173
onItemSelect={(v) => setTab(v)}
174
>
175
+
<TabBar.Item className={DiscoveryClasses.tabBarItem} id="crash">
176
Crash details
177
</TabBar.Item>
178
+
<TabBar.Item className={DiscoveryClasses.tabBarItem} id="extensions" disabled={updateCount === 0}>
179
{`Extension updates (${updateCount})`}
180
</TabBar.Item>
181
+
<TabBar.Item className={DiscoveryClasses.tabBarItem} id="causes" disabled={causes.length === 0}>
182
{`Possible causes (${causes.length})`}
183
</TabBar.Item>
184
</TabBar>
+25
-15
packages/core-extensions/src/moonbase/webpackModules/settings.tsx
+25
-15
packages/core-extensions/src/moonbase/webpackModules/settings.tsx
···
2
import React from "@moonlight-mod/wp/react";
3
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
4
import { Moonbase, pages, RestartAdviceMessage, Update } from "@moonlight-mod/wp/moonbase_ui";
5
-
6
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
7
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
8
-
9
-
const { MenuItem, Text, Breadcrumbs } = Components;
10
-
11
-
const Margins = spacepack.require("discord/styles/shared/Margins.css");
12
-
13
-
const { open } = spacepack.findByCode(':"USER_SETTINGS_MODAL_SET_SECTION"')[0].exports.Z;
14
15
-
let SettingsNotice;
16
const notice = {
17
stores: [MoonbaseSettingsStore],
18
element: () => {
19
// Require it here because lazy loading SUX
20
-
SettingsNotice ??= spacepack.findByCode("onSaveButtonColor", "FocusRingScope")[0].exports.Z;
21
return (
22
<SettingsNotice
23
submitting={MoonbaseSettingsStore.submitting}
···
32
}
33
};
34
35
function addSection(id: string, name: string, element: React.FunctionComponent) {
36
-
settings.addSection(`moonbase-${id}`, name, element, null, -2, notice);
37
}
38
39
// FIXME: move to component types
···
50
);
51
}
52
53
if (MoonbaseSettingsStore.getExtensionConfigRaw<boolean>("moonbase", "sections", false)) {
54
-
settings.addHeader("Moonbase", -2);
55
56
-
for (const page of pages) {
57
addSection(page.id, page.name, () => {
58
const breadcrumbs = [
59
{ id: "moonbase", label: "Moonbase" },
···
78
);
79
});
80
}
81
} else {
82
-
settings.addSection("moonbase", "Moonbase", Moonbase, null, -2, notice);
83
84
settings.addSectionMenuItems(
85
"moonbase",
86
...pages.map((page, i) => (
87
-
<MenuItem key={page.id} id={`moonbase-${page.id}`} label={page.name} action={() => open("moonbase", i)} />
88
))
89
);
90
}
···
2
import React from "@moonlight-mod/wp/react";
3
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
4
import { Moonbase, pages, RestartAdviceMessage, Update } from "@moonlight-mod/wp/moonbase_ui";
5
+
import UserSettingsModalActionCreators from "@moonlight-mod/wp/discord/actions/UserSettingsModalActionCreators";
6
+
import Margins from "@moonlight-mod/wp/discord/styles/shared/Margins.css";
7
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
8
+
import { Text, Breadcrumbs } from "@moonlight-mod/wp/discord/components/common/index";
9
+
import { MenuItem } from "@moonlight-mod/wp/contextMenu_contextMenu";
10
11
const notice = {
12
stores: [MoonbaseSettingsStore],
13
element: () => {
14
// Require it here because lazy loading SUX
15
+
const SettingsNotice = spacepack.require("discord/components/common/SettingsNotice").default;
16
return (
17
<SettingsNotice
18
submitting={MoonbaseSettingsStore.submitting}
···
27
}
28
};
29
30
+
const oldLocation = MoonbaseSettingsStore.getExtensionConfigRaw<boolean>("moonbase", "oldLocation", false);
31
+
const position = oldLocation ? -2 : -9999;
32
+
33
function addSection(id: string, name: string, element: React.FunctionComponent) {
34
+
settings.addSection(`moonbase-${id}`, name, element, null, position, notice);
35
}
36
37
// FIXME: move to component types
···
48
);
49
}
50
51
+
if (!oldLocation) {
52
+
settings.addDivider(position);
53
+
}
54
+
55
if (MoonbaseSettingsStore.getExtensionConfigRaw<boolean>("moonbase", "sections", false)) {
56
+
if (oldLocation) settings.addHeader("Moonbase", position);
57
58
+
const _pages = oldLocation ? pages : pages.reverse();
59
+
for (const page of _pages) {
60
addSection(page.id, page.name, () => {
61
const breadcrumbs = [
62
{ id: "moonbase", label: "Moonbase" },
···
81
);
82
});
83
}
84
+
85
+
if (!oldLocation) settings.addHeader("Moonbase", position);
86
} else {
87
+
settings.addSection("moonbase", "Moonbase", Moonbase, null, position, notice);
88
89
settings.addSectionMenuItems(
90
"moonbase",
91
...pages.map((page, i) => (
92
+
<MenuItem
93
+
key={page.id}
94
+
id={`moonbase-${page.id}`}
95
+
label={page.name}
96
+
action={() => UserSettingsModalActionCreators.open("moonbase", i.toString())}
97
+
/>
98
))
99
);
100
}
+56
-15
packages/core-extensions/src/moonbase/webpackModules/stores.ts
+56
-15
packages/core-extensions/src/moonbase/webpackModules/stores.ts
···
1
import { Config, ExtensionEnvironment, ExtensionLoadSource, ExtensionSettingsAdvice } from "@moonlight-mod/types";
2
-
import { ExtensionState, MoonbaseExtension, MoonbaseNatives, RepositoryManifest, RestartAdvice } from "../types";
3
import { Store } from "@moonlight-mod/wp/discord/packages/flux";
4
import Dispatcher from "@moonlight-mod/wp/discord/Dispatcher";
5
import getNatives from "../native";
···
25
submitting: boolean;
26
installing: boolean;
27
28
newVersion: string | null;
29
shouldShowNotice: boolean;
30
-
31
-
#showOnlyUpdateable = false;
32
-
set showOnlyUpdateable(v: boolean) {
33
-
this.#showOnlyUpdateable = v;
34
-
this.emitChange();
35
-
}
36
-
get showOnlyUpdateable() {
37
-
return this.#showOnlyUpdateable;
38
-
}
39
40
restartAdvice = RestartAdvice.NotNeeded;
41
···
254
this.emitChange();
255
}
256
257
async installExtension(uniqueId: number) {
258
const ext = this.getExtension(uniqueId);
259
if (!("download" in ext.manifest)) {
···
274
existing.settingsOverride = update.updateManifest.settings;
275
existing.compat = checkExtensionCompat(update.updateManifest);
276
existing.manifest = update.updateManifest;
277
-
existing.hasUpdate = false;
278
existing.changelog = update.updateManifest.meta?.changelog;
279
}
280
···
346
}
347
348
async updateMoonlight() {
349
-
await natives.updateMoonlight();
350
}
351
352
getConfigOption<K extends keyof Config>(key: K): Config[K] {
···
374
}
375
376
#computeRestartAdvice() {
377
const i = this.initialConfig; // Initial config, from startup
378
const n = this.config; // New config about to be saved
379
···
403
// If it's enabled but not detected yet, restart.
404
if (newEnabled && !detected) {
405
return updateAdvice(RestartAdvice.RestartNeeded);
406
-
continue;
407
}
408
409
// Toggling extensions specifically wants to rely on the initial state,
···
431
}
432
}
433
434
-
const initConfig = typeof initState === "boolean" ? {} : initState.config ?? {};
435
-
const newConfig = typeof newState === "boolean" ? {} : newState.config ?? {};
436
437
const def = ext.manifest.settings;
438
if (!def) continue;
439
440
const changedKeys = diff(initConfig, newConfig, { cyclesFix: false }).map((c) => c.path[0]);
441
for (const key in def) {
442
if (!changedKeys.includes(key)) continue;
···
464
writeConfig() {
465
this.submitting = true;
466
this.restartAdvice = this.#computeRestartAdvice();
467
468
moonlightNode.writeConfig(this.config);
469
this.savedConfig = this.clone(this.config);
···
471
this.submitting = false;
472
this.modified = false;
473
this.emitChange();
474
}
475
476
reset() {
···
1
import { Config, ExtensionEnvironment, ExtensionLoadSource, ExtensionSettingsAdvice } from "@moonlight-mod/types";
2
+
import {
3
+
ExtensionState,
4
+
MoonbaseExtension,
5
+
MoonbaseNatives,
6
+
RepositoryManifest,
7
+
RestartAdvice,
8
+
UpdateState
9
+
} from "../types";
10
import { Store } from "@moonlight-mod/wp/discord/packages/flux";
11
import Dispatcher from "@moonlight-mod/wp/discord/Dispatcher";
12
import getNatives from "../native";
···
32
submitting: boolean;
33
installing: boolean;
34
35
+
#updateState = UpdateState.Ready;
36
+
get updateState() {
37
+
return this.#updateState;
38
+
}
39
newVersion: string | null;
40
shouldShowNotice: boolean;
41
42
restartAdvice = RestartAdvice.NotNeeded;
43
···
256
this.emitChange();
257
}
258
259
+
dismissAllExtensionUpdates() {
260
+
for (const id in this.extensions) {
261
+
this.extensions[id].hasUpdate = false;
262
+
}
263
+
this.emitChange();
264
+
}
265
+
266
+
async updateAllExtensions() {
267
+
for (const id of Object.keys(this.updates)) {
268
+
try {
269
+
await this.installExtension(parseInt(id));
270
+
} catch (e) {
271
+
logger.error("Error bulk updating extension", id, e);
272
+
}
273
+
}
274
+
}
275
+
276
async installExtension(uniqueId: number) {
277
const ext = this.getExtension(uniqueId);
278
if (!("download" in ext.manifest)) {
···
293
existing.settingsOverride = update.updateManifest.settings;
294
existing.compat = checkExtensionCompat(update.updateManifest);
295
existing.manifest = update.updateManifest;
296
existing.changelog = update.updateManifest.meta?.changelog;
297
}
298
···
364
}
365
366
async updateMoonlight() {
367
+
this.#updateState = UpdateState.Working;
368
+
this.emitChange();
369
+
370
+
await natives
371
+
.updateMoonlight()
372
+
.then(() => (this.#updateState = UpdateState.Installed))
373
+
.catch((e) => {
374
+
logger.error(e);
375
+
this.#updateState = UpdateState.Failed;
376
+
});
377
+
378
+
this.emitChange();
379
}
380
381
getConfigOption<K extends keyof Config>(key: K): Config[K] {
···
403
}
404
405
#computeRestartAdvice() {
406
+
// If moonlight update needs a restart, always hide advice.
407
+
if (this.#updateState === UpdateState.Installed) return RestartAdvice.NotNeeded;
408
+
409
const i = this.initialConfig; // Initial config, from startup
410
const n = this.config; // New config about to be saved
411
···
435
// If it's enabled but not detected yet, restart.
436
if (newEnabled && !detected) {
437
return updateAdvice(RestartAdvice.RestartNeeded);
438
}
439
440
// Toggling extensions specifically wants to rely on the initial state,
···
462
}
463
}
464
465
+
const initConfig = typeof initState === "boolean" ? {} : { ...initState?.config };
466
+
const newConfig = typeof newState === "boolean" ? {} : { ...newState?.config };
467
468
const def = ext.manifest.settings;
469
if (!def) continue;
470
471
+
for (const key in def) {
472
+
const defaultValue = def[key].default;
473
+
474
+
initConfig[key] ??= defaultValue;
475
+
newConfig[key] ??= defaultValue;
476
+
}
477
+
478
const changedKeys = diff(initConfig, newConfig, { cyclesFix: false }).map((c) => c.path[0]);
479
for (const key in def) {
480
if (!changedKeys.includes(key)) continue;
···
502
writeConfig() {
503
this.submitting = true;
504
this.restartAdvice = this.#computeRestartAdvice();
505
+
const modifiedRepos = diff(this.savedConfig.repositories, this.config.repositories);
506
507
moonlightNode.writeConfig(this.config);
508
this.savedConfig = this.clone(this.config);
···
510
this.submitting = false;
511
this.modified = false;
512
this.emitChange();
513
+
514
+
if (modifiedRepos.length !== 0) this.checkUpdates();
515
}
516
517
reset() {
+2
-4
packages/core-extensions/src/moonbase/webpackModules/ui/HelpMessage.tsx
+2
-4
packages/core-extensions/src/moonbase/webpackModules/ui/HelpMessage.tsx
···
1
import React from "@moonlight-mod/wp/react";
2
-
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
3
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
4
import { Text } from "@moonlight-mod/wp/discord/components/common/index";
5
-
6
-
const Margins = spacepack.require("discord/styles/shared/Margins.css");
7
-
const HelpMessageClasses = spacepack.findByCode("positive:", "iconDiv:")[0].exports;
8
9
// reimpl of HelpMessage but with a custom icon
10
export default function HelpMessage({
···
1
import React from "@moonlight-mod/wp/react";
2
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
3
import { Text } from "@moonlight-mod/wp/discord/components/common/index";
4
+
import HelpMessageClasses from "@moonlight-mod/wp/discord/components/common/HelpMessage.css";
5
+
import Margins from "@moonlight-mod/wp/discord/styles/shared/Margins.css";
6
7
// reimpl of HelpMessage but with a custom icon
8
export default function HelpMessage({
+1
-5
packages/core-extensions/src/moonbase/webpackModules/ui/RestartAdvice.tsx
+1
-5
packages/core-extensions/src/moonbase/webpackModules/ui/RestartAdvice.tsx
···
1
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
2
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
3
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
4
import React from "@moonlight-mod/wp/react";
5
import { RestartAdvice } from "../../types";
6
import HelpMessage from "./HelpMessage";
7
-
8
-
const { Button } = Components;
9
10
const strings: Record<RestartAdvice, string> = {
11
[RestartAdvice.NotNeeded]: "how did you even",
···
27
[RestartAdvice.ReloadNeeded]: () => window.location.reload(),
28
[RestartAdvice.RestartNeeded]: () => MoonbaseSettingsStore.restartDiscord()
29
};
30
-
31
-
const { CircleWarningIcon } = Components;
32
33
export default function RestartAdviceMessage() {
34
const restartAdvice = useStateFromStores([MoonbaseSettingsStore], () => MoonbaseSettingsStore.restartAdvice);
···
1
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
2
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
3
+
import { Button, CircleWarningIcon } from "@moonlight-mod/wp/discord/components/common/index";
4
import React from "@moonlight-mod/wp/react";
5
import { RestartAdvice } from "../../types";
6
import HelpMessage from "./HelpMessage";
7
8
const strings: Record<RestartAdvice, string> = {
9
[RestartAdvice.NotNeeded]: "how did you even",
···
25
[RestartAdvice.ReloadNeeded]: () => window.location.reload(),
26
[RestartAdvice.RestartNeeded]: () => MoonbaseSettingsStore.restartDiscord()
27
};
28
29
export default function RestartAdviceMessage() {
30
const restartAdvice = useStateFromStores([MoonbaseSettingsStore], () => MoonbaseSettingsStore.restartAdvice);
+110
packages/core-extensions/src/moonbase/webpackModules/ui/about.tsx
+110
packages/core-extensions/src/moonbase/webpackModules/ui/about.tsx
···
···
1
+
import {
2
+
Text,
3
+
useThemeContext,
4
+
Button,
5
+
AngleBracketsIcon,
6
+
BookCheckIcon,
7
+
ClydeIcon
8
+
} from "@moonlight-mod/wp/discord/components/common/index";
9
+
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
10
+
import React from "@moonlight-mod/wp/react";
11
+
import MarkupUtils from "@moonlight-mod/wp/discord/modules/markup/MarkupUtils";
12
+
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
13
+
14
+
const wordmark = "https://raw.githubusercontent.com/moonlight-mod/moonlight/refs/heads/main/img/wordmark.png";
15
+
const wordmarkLight =
16
+
"https://raw.githubusercontent.com/moonlight-mod/moonlight/refs/heads/main/img/wordmark-light.png";
17
+
18
+
function parse(str: string) {
19
+
return MarkupUtils.parse(str, true, {
20
+
allowHeading: true,
21
+
allowLinks: true,
22
+
allowList: true
23
+
});
24
+
}
25
+
26
+
function Dev({ name, picture, link }: { name: string; picture: string; link: string }) {
27
+
return (
28
+
<Button onClick={() => window.open(link)} color={Button.Colors.PRIMARY} className="moonbase-dev">
29
+
<Flex direction={Flex.Direction.HORIZONTAL} align={Flex.Align.CENTER} className="moonbase-gap">
30
+
<img src={picture} alt={name} className="moonbase-dev-avatar" />
31
+
32
+
<Text variant="text-md/semibold">{name}</Text>
33
+
</Flex>
34
+
</Button>
35
+
);
36
+
}
37
+
38
+
function IconButton({
39
+
text,
40
+
link,
41
+
icon,
42
+
openInClient
43
+
}: {
44
+
text: string;
45
+
link: string;
46
+
icon: React.FC<any>;
47
+
openInClient?: boolean;
48
+
}) {
49
+
return (
50
+
<Button
51
+
onClick={() => {
52
+
if (openInClient) {
53
+
try {
54
+
const { handleClick } = spacepack.require("discord/utils/MaskedLinkUtils");
55
+
handleClick({ href: link });
56
+
} catch {
57
+
window.open(link);
58
+
}
59
+
} else {
60
+
// Will open externally in the user's browser
61
+
window.open(link);
62
+
}
63
+
}}
64
+
>
65
+
<Flex direction={Flex.Direction.HORIZONTAL} align={Flex.Align.CENTER} className="moonbase-gap">
66
+
{React.createElement(icon, {
67
+
size: "sm",
68
+
color: "currentColor"
69
+
})}
70
+
{text}
71
+
</Flex>
72
+
</Button>
73
+
);
74
+
}
75
+
76
+
export default function AboutPage() {
77
+
const darkTheme = useThemeContext()?.theme !== "light";
78
+
79
+
return (
80
+
<Flex direction={Flex.Direction.VERTICAL} align={Flex.Align.CENTER} className="moonbase-about-page">
81
+
<img src={darkTheme ? wordmarkLight : wordmark} alt="moonlight wordmark" className="moonbase-wordmark" />
82
+
83
+
<Text variant="heading-lg/medium">created by:</Text>
84
+
<div className="moonbase-devs">
85
+
<Dev name="Cynosphere" picture="https://github.com/Cynosphere.png" link="https://github.com/Cynosphere" />
86
+
<Dev name="NotNite" picture="https://github.com/NotNite.png" link="https://github.com/NotNite" />
87
+
<Dev name="adryd" picture="https://github.com/adryd325.png" link="https://github.com/adryd325" />
88
+
<Dev name="redstonekasi" picture="https://github.com/redstonekasi.png" link="https://github.com/redstonekasi" />
89
+
</div>
90
+
91
+
<Flex direction={Flex.Direction.HORIZONTAL} align={Flex.Align.CENTER} className="moonbase-gap">
92
+
<IconButton text="View source" icon={AngleBracketsIcon} link="https://github.com/moonlight-mod/moonlight" />
93
+
<IconButton text="Open the docs" icon={BookCheckIcon} link="https://moonlight-mod.github.io/" />
94
+
<IconButton text="Join the server" icon={ClydeIcon} link="https://discord.gg/FdZBTFCP6F" openInClient={true} />
95
+
</Flex>
96
+
97
+
<Flex direction={Flex.Direction.VERTICAL} align={Flex.Align.START}>
98
+
<Text variant="text-sm/normal">
99
+
{parse(`moonlight \`${window.moonlight.version}\` on \`${window.moonlight.branch}\``)}
100
+
</Text>
101
+
102
+
<Text variant="text-sm/normal">
103
+
{parse(
104
+
"moonlight is licensed under the [GNU Lesser General Public License](https://www.gnu.org/licenses/lgpl-3.0.html) (`LGPL-3.0-or-later`)."
105
+
)}
106
+
</Text>
107
+
</Flex>
108
+
</Flex>
109
+
);
110
+
}
+14
-13
packages/core-extensions/src/moonbase/webpackModules/ui/config/index.tsx
+14
-13
packages/core-extensions/src/moonbase/webpackModules/ui/config/index.tsx
···
16
Clickable
17
} from "@moonlight-mod/wp/discord/components/common/index";
18
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
19
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
20
21
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
22
23
-
const FormClasses = spacepack.findByCode("dividerDefault:")[0].exports;
24
-
const Margins = spacepack.findByCode("marginCenterHorz:")[0].exports;
25
-
26
-
let RemoveButtonClasses: any;
27
spacepack
28
.lazyLoad(
29
"renderArtisanalHack",
30
/\[(?:.\.e\("\d+?"\),?)+\][^}]+?webpackId:\d+,name:"GuildSettings"/,
31
/webpackId:(\d+),name:"GuildSettings"/
32
)
33
-
.then(() => (RemoveButtonClasses = spacepack.findByCode("removeButtonContainer")[0].exports));
34
-
35
-
// FIXME: type component keys
36
-
const { CircleXIcon } = Components;
37
38
function RemoveEntryButton({ onClick }: { onClick: () => void }) {
39
return (
40
-
<div className={RemoveButtonClasses.removeButtonContainer}>
41
<Tooltip text="Remove entry" position="top">
42
{(props: any) => (
43
-
<Clickable {...props} className={RemoveButtonClasses.removeButton} onClick={onClick}>
44
<CircleXIcon width={24} height={24} />
45
</Clickable>
46
)}
···
121
<FormText className={Margins.marginBottom4}>A list of remote repositories to display extensions from</FormText>
122
<ArrayFormItem config="repositories" />
123
</FormItem>
124
-
<FormDivider className={FormClasses.dividerDefault} />
125
<FormItem title="Extension search paths" className={Margins.marginTop20}>
126
<FormText className={Margins.marginBottom4}>
127
A list of local directories to search for built extensions
128
</FormText>
129
<ArrayFormItem config="devSearchPaths" />
130
</FormItem>
131
-
<FormDivider className={FormClasses.dividerDefault} />
132
<FormSwitch
133
className={Margins.marginTop20}
134
value={MoonbaseSettingsStore.getConfigOption("patchAll") ?? false}
···
16
Clickable
17
} from "@moonlight-mod/wp/discord/components/common/index";
18
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
19
+
import { CircleXIcon } from "@moonlight-mod/wp/discord/components/common/index";
20
+
import Margins from "@moonlight-mod/wp/discord/styles/shared/Margins.css";
21
+
import FormSwitchClasses from "@moonlight-mod/wp/discord/components/common/FormSwitch.css";
22
23
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
24
25
+
let GuildSettingsRoleEditClasses: any;
26
spacepack
27
.lazyLoad(
28
"renderArtisanalHack",
29
/\[(?:.\.e\("\d+?"\),?)+\][^}]+?webpackId:\d+,name:"GuildSettings"/,
30
/webpackId:(\d+),name:"GuildSettings"/
31
)
32
+
.then(
33
+
() =>
34
+
(GuildSettingsRoleEditClasses = spacepack.require(
35
+
"discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"
36
+
))
37
+
);
38
39
function RemoveEntryButton({ onClick }: { onClick: () => void }) {
40
return (
41
+
<div className={GuildSettingsRoleEditClasses.removeButtonContainer}>
42
<Tooltip text="Remove entry" position="top">
43
{(props: any) => (
44
+
<Clickable {...props} className={GuildSettingsRoleEditClasses.removeButton} onClick={onClick}>
45
<CircleXIcon width={24} height={24} />
46
</Clickable>
47
)}
···
122
<FormText className={Margins.marginBottom4}>A list of remote repositories to display extensions from</FormText>
123
<ArrayFormItem config="repositories" />
124
</FormItem>
125
+
<FormDivider className={FormSwitchClasses.dividerDefault} />
126
<FormItem title="Extension search paths" className={Margins.marginTop20}>
127
<FormText className={Margins.marginBottom4}>
128
A list of local directories to search for built extensions
129
</FormText>
130
<ArrayFormItem config="devSearchPaths" />
131
</FormItem>
132
+
<FormDivider className={FormSwitchClasses.dividerDefault} />
133
<FormSwitch
134
className={Margins.marginTop20}
135
value={MoonbaseSettingsStore.getConfigOption("patchAll") ?? false}
+138
-75
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/card.tsx
+138
-75
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/card.tsx
···
1
import { ExtensionState } from "../../../types";
2
import { constants, ExtensionLoadSource, ExtensionTag } from "@moonlight-mod/types";
3
import { ExtensionCompat } from "@moonlight-mod/core/extension/loader";
4
-
5
-
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
6
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
7
import React from "@moonlight-mod/wp/react";
8
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
9
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
10
import MarkupUtils from "@moonlight-mod/wp/discord/modules/markup/MarkupUtils";
11
-
import IntegrationCard from "@moonlight-mod/wp/discord/modules/guild_settings/IntegrationCard.css";
12
-
13
import ExtensionInfo from "./info";
14
import Settings from "./settings";
15
import { doGenericExtensionPopup, doMissingExtensionPopup } from "./popup";
···
21
Settings
22
}
23
24
-
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
25
-
26
-
const { BeakerIcon, DownloadIcon, TrashIcon, AngleBracketsIcon, Tooltip } = Components;
27
-
28
-
const PanelButton = spacepack.findByCode("Masks.PANEL_BUTTON")[0].exports.Z;
29
-
const TabBarClasses = spacepack.findByCode("tabBar:", "tabBarItem:", "headerContentWrapper:")[0].exports;
30
-
const MarkupClasses = spacepack.findByCode("markup:", "inlineFormat:")[0].exports;
31
-
32
-
const BuildOverrideClasses = spacepack.findByCode("disabledButtonOverride:")[0].exports;
33
-
34
const COMPAT_TEXT_MAP: Record<ExtensionCompat, string> = {
35
[ExtensionCompat.Compatible]: "huh?",
36
[ExtensionCompat.InvalidApiLevel]: "Incompatible API level",
···
38
};
39
const CONFLICTING_TEXT = "This extension is already installed from another source.";
40
41
-
export default function ExtensionCard({ uniqueId }: { uniqueId: number }) {
42
-
const [tab, setTab] = React.useState(ExtensionPage.Info);
43
44
const { ext, enabled, busy, update, conflicting } = useStateFromStores([MoonbaseSettingsStore], () => {
45
return {
46
ext: MoonbaseSettingsStore.getExtension(uniqueId),
···
51
};
52
});
53
54
-
// Why it work like that :sob:
55
-
if (ext == null) return <></>;
56
-
57
-
const { Card, Text, FormSwitch, TabBar, Button } = Components;
58
59
const tagline = ext.manifest?.meta?.tagline;
60
const settings = ext.settingsOverride ?? ext.manifest?.settings;
61
const description = ext.manifest?.meta?.description;
62
const changelog = ext.changelog;
63
const enabledDependants = useStateFromStores([MoonbaseSettingsStore], () =>
64
Object.keys(MoonbaseSettingsStore.extensions)
65
.filter((uniqueId) => {
66
const potentialDependant = MoonbaseSettingsStore.getExtension(parseInt(uniqueId));
67
68
return (
69
-
potentialDependant.manifest.dependencies?.includes(ext.id) &&
70
MoonbaseSettingsStore.getExtensionEnabled(parseInt(uniqueId))
71
);
72
})
···
74
);
75
const implicitlyEnabled = enabledDependants.length > 0;
76
77
-
return (
78
-
<Card editable={true} className={IntegrationCard.card}>
79
-
<div className={IntegrationCard.cardHeader}>
80
<Flex direction={Flex.Direction.VERTICAL}>
81
<Flex direction={Flex.Direction.HORIZONTAL} align={Flex.Align.CENTER}>
82
<Text variant="text-md/semibold">{ext.manifest?.meta?.name ?? ext.id}</Text>
83
{ext.source.type === ExtensionLoadSource.Developer && (
84
<Tooltip text="This is a local extension" position="top">
85
-
{(props: any) => <BeakerIcon {...props} class={BuildOverrideClasses.infoIcon} size="xs" />}
86
</Tooltip>
87
)}
88
</Flex>
···
99
gap: "1rem"
100
}}
101
>
102
-
{ext.manifest.meta?.source != null && (
103
-
<PanelButton
104
-
icon={AngleBracketsIcon}
105
-
tooltipText="View source"
106
-
onClick={() => {
107
-
window.open(ext.manifest.meta!.source);
108
-
}}
109
-
/>
110
-
)}
111
-
112
{ext.state === ExtensionState.NotDownloaded ? (
113
<Tooltip
114
text={conflicting ? CONFLICTING_TEXT : COMPAT_TEXT_MAP[ext.compat]}
···
164
disabled={implicitlyEnabled || ext.compat !== ExtensionCompat.Compatible}
165
hideBorder={true}
166
style={{ marginBottom: "0px" }}
167
tooltipNote={
168
-
ext.compat !== ExtensionCompat.Compatible
169
-
? COMPAT_TEXT_MAP[ext.compat]
170
-
: implicitlyEnabled
171
-
? `This extension is a dependency of the following enabled extension${
172
-
enabledDependants.length > 1 ? "s" : ""
173
-
}: ${enabledDependants.map((a) => a.manifest.meta?.name ?? a.id).join(", ")}`
174
-
: undefined
175
}
176
onChange={() => {
177
const toggle = () => {
···
204
</div>
205
206
<div>
207
-
{(description != null || changelog != null || settings != null) && (
208
-
<TabBar
209
-
selectedItem={tab}
210
-
type="top"
211
-
onItemSelect={setTab}
212
-
className={TabBarClasses.tabBar}
213
-
style={{
214
-
padding: "0 20px"
215
-
}}
216
-
>
217
-
<TabBar.Item className={TabBarClasses.tabBarItem} id={ExtensionPage.Info}>
218
-
Info
219
-
</TabBar.Item>
220
-
221
-
{description != null && (
222
-
<TabBar.Item className={TabBarClasses.tabBarItem} id={ExtensionPage.Description}>
223
-
Description
224
</TabBar.Item>
225
-
)}
226
227
-
{changelog != null && (
228
-
<TabBar.Item className={TabBarClasses.tabBarItem} id={ExtensionPage.Changelog}>
229
-
Changelog
230
-
</TabBar.Item>
231
-
)}
232
233
-
{settings != null && (
234
-
<TabBar.Item className={TabBarClasses.tabBarItem} id={ExtensionPage.Settings}>
235
-
Settings
236
-
</TabBar.Item>
237
-
)}
238
-
</TabBar>
239
)}
240
241
<Flex
242
justify={Flex.Justify.START}
243
wrap={Flex.Wrap.WRAP}
244
style={{
245
-
padding: "16px 16px"
246
}}
247
>
248
-
{tab === ExtensionPage.Info && <ExtensionInfo ext={ext} />}
249
{tab === ExtensionPage.Description && (
250
<Text variant="text-md/normal" className={MarkupClasses.markup} style={{ width: "100%" }}>
251
{MarkupUtils.parse(description ?? "*No description*", true, {
···
264
})}
265
</Text>
266
)}
267
-
{tab === ExtensionPage.Settings && <Settings ext={ext} />}
268
</Flex>
269
</div>
270
</Card>
···
1
import { ExtensionState } from "../../../types";
2
import { constants, ExtensionLoadSource, ExtensionTag } from "@moonlight-mod/types";
3
+
4
import { ExtensionCompat } from "@moonlight-mod/core/extension/loader";
5
+
import {
6
+
ScienceIcon,
7
+
DownloadIcon,
8
+
TrashIcon,
9
+
AngleBracketsIcon,
10
+
Tooltip,
11
+
Card,
12
+
Text,
13
+
FormSwitch,
14
+
TabBar,
15
+
Button,
16
+
ChannelListIcon,
17
+
HeartIcon,
18
+
WindowTopOutlineIcon,
19
+
WarningIcon
20
+
} from "@moonlight-mod/wp/discord/components/common/index";
21
import React from "@moonlight-mod/wp/react";
22
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
23
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
24
import MarkupUtils from "@moonlight-mod/wp/discord/modules/markup/MarkupUtils";
25
+
import AppCardClasses from "@moonlight-mod/wp/discord/modules/guild_settings/web/AppCard.css";
26
+
import PanelButton from "@moonlight-mod/wp/discord/components/common/PanelButton";
27
+
import DiscoveryClasses from "@moonlight-mod/wp/discord/modules/discovery/web/Discovery.css";
28
+
import MarkupClasses from "@moonlight-mod/wp/discord/modules/messages/web/Markup.css";
29
+
import BuildOverrideClasses from "@moonlight-mod/wp/discord/modules/build_overrides/web/BuildOverride.css";
30
+
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
31
+
import ErrorBoundary from "@moonlight-mod/wp/common_ErrorBoundary";
32
import ExtensionInfo from "./info";
33
import Settings from "./settings";
34
import { doGenericExtensionPopup, doMissingExtensionPopup } from "./popup";
···
40
Settings
41
}
42
43
const COMPAT_TEXT_MAP: Record<ExtensionCompat, string> = {
44
[ExtensionCompat.Compatible]: "huh?",
45
[ExtensionCompat.InvalidApiLevel]: "Incompatible API level",
···
47
};
48
const CONFLICTING_TEXT = "This extension is already installed from another source.";
49
50
+
function PanelLinkButton({ icon, tooltip, link }: { icon: React.ReactNode; tooltip: string; link: string }) {
51
+
return (
52
+
<PanelButton
53
+
icon={icon}
54
+
tooltipText={tooltip}
55
+
onClick={() => {
56
+
window.open(link);
57
+
}}
58
+
/>
59
+
);
60
+
}
61
62
+
export default function ExtensionCard({ uniqueId, selectTag }: { uniqueId: number; selectTag: (tag: string) => void }) {
63
const { ext, enabled, busy, update, conflicting } = useStateFromStores([MoonbaseSettingsStore], () => {
64
return {
65
ext: MoonbaseSettingsStore.getExtension(uniqueId),
···
70
};
71
});
72
73
+
const [tab, setTab] = React.useState(
74
+
update != null && ext?.changelog != null ? ExtensionPage.Changelog : ExtensionPage.Info
75
+
);
76
77
const tagline = ext.manifest?.meta?.tagline;
78
const settings = ext.settingsOverride ?? ext.manifest?.settings;
79
const description = ext.manifest?.meta?.description;
80
const changelog = ext.changelog;
81
+
const linkButtons = [
82
+
ext?.manifest?.meta?.source && (
83
+
<PanelLinkButton icon={<AngleBracketsIcon />} tooltip="View source" link={ext.manifest.meta.source} />
84
+
),
85
+
ext?.source?.url && <PanelLinkButton icon={<ChannelListIcon />} tooltip="View repository" link={ext.source.url} />,
86
+
ext?.manifest?.meta?.donate && (
87
+
<PanelLinkButton icon={<HeartIcon />} tooltip="Donate" link={ext.manifest.meta.donate} />
88
+
)
89
+
].filter((x) => x != null);
90
+
91
const enabledDependants = useStateFromStores([MoonbaseSettingsStore], () =>
92
Object.keys(MoonbaseSettingsStore.extensions)
93
.filter((uniqueId) => {
94
const potentialDependant = MoonbaseSettingsStore.getExtension(parseInt(uniqueId));
95
96
return (
97
+
potentialDependant.manifest.dependencies?.includes(ext?.id) &&
98
MoonbaseSettingsStore.getExtensionEnabled(parseInt(uniqueId))
99
);
100
})
···
102
);
103
const implicitlyEnabled = enabledDependants.length > 0;
104
105
+
const hasDuplicateEntry = useStateFromStores([MoonbaseSettingsStore], () =>
106
+
Object.entries(MoonbaseSettingsStore.extensions).some(
107
+
([otherUniqueId, otherExt]) =>
108
+
otherExt != null && otherExt?.id === ext?.id && parseInt(otherUniqueId) !== uniqueId
109
+
)
110
+
);
111
+
112
+
return ext == null ? (
113
+
<></>
114
+
) : (
115
+
<Card editable={true} className={AppCardClasses.card}>
116
+
<div className={AppCardClasses.cardHeader}>
117
<Flex direction={Flex.Direction.VERTICAL}>
118
<Flex direction={Flex.Direction.HORIZONTAL} align={Flex.Align.CENTER}>
119
<Text variant="text-md/semibold">{ext.manifest?.meta?.name ?? ext.id}</Text>
120
{ext.source.type === ExtensionLoadSource.Developer && (
121
<Tooltip text="This is a local extension" position="top">
122
+
{(props: any) => <ScienceIcon {...props} class={BuildOverrideClasses.infoIcon} size="xs" />}
123
+
</Tooltip>
124
+
)}
125
+
126
+
{hasDuplicateEntry && ext?.source?.url && (
127
+
<Tooltip text={`This extension is from the following repository: ${ext.source.url}`} position="top">
128
+
{(props: any) => <WindowTopOutlineIcon {...props} class={BuildOverrideClasses.infoIcon} size="xs" />}
129
+
</Tooltip>
130
+
)}
131
+
132
+
{ext.manifest?.meta?.deprecated && (
133
+
<Tooltip text="This extension is deprecated" position="top">
134
+
{(props: any) => <WarningIcon {...props} class={BuildOverrideClasses.infoIcon} size="xs" />}
135
</Tooltip>
136
)}
137
</Flex>
···
148
gap: "1rem"
149
}}
150
>
151
{ext.state === ExtensionState.NotDownloaded ? (
152
<Tooltip
153
text={conflicting ? CONFLICTING_TEXT : COMPAT_TEXT_MAP[ext.compat]}
···
203
disabled={implicitlyEnabled || ext.compat !== ExtensionCompat.Compatible}
204
hideBorder={true}
205
style={{ marginBottom: "0px" }}
206
+
// @ts-expect-error fix type later
207
tooltipNote={
208
+
ext.compat !== ExtensionCompat.Compatible ? (
209
+
COMPAT_TEXT_MAP[ext.compat]
210
+
) : implicitlyEnabled ? (
211
+
<div style={{ display: "flex", flexDirection: "column" }}>
212
+
<div>{`This extension is a dependency of the following enabled extension${
213
+
enabledDependants.length > 1 ? "s" : ""
214
+
}:`}</div>
215
+
{enabledDependants.map((dep) => (
216
+
<div>{"โข " + (dep.manifest.meta?.name ?? dep.id)}</div>
217
+
))}
218
+
</div>
219
+
) : undefined
220
}
221
onChange={() => {
222
const toggle = () => {
···
249
</div>
250
251
<div>
252
+
{(description != null || changelog != null || settings != null || linkButtons.length > 0) && (
253
+
<Flex>
254
+
<TabBar
255
+
selectedItem={tab}
256
+
type="top"
257
+
onItemSelect={setTab}
258
+
className={DiscoveryClasses.tabBar}
259
+
style={{
260
+
padding: "0 20px"
261
+
}}
262
+
>
263
+
<TabBar.Item className={DiscoveryClasses.tabBarItem} id={ExtensionPage.Info}>
264
+
Info
265
</TabBar.Item>
266
+
267
+
{description != null && (
268
+
<TabBar.Item className={DiscoveryClasses.tabBarItem} id={ExtensionPage.Description}>
269
+
Description
270
+
</TabBar.Item>
271
+
)}
272
+
273
+
{changelog != null && (
274
+
<TabBar.Item className={DiscoveryClasses.tabBarItem} id={ExtensionPage.Changelog}>
275
+
Changelog
276
+
</TabBar.Item>
277
+
)}
278
279
+
{settings != null && (
280
+
<TabBar.Item className={DiscoveryClasses.tabBarItem} id={ExtensionPage.Settings}>
281
+
Settings
282
+
</TabBar.Item>
283
+
)}
284
+
</TabBar>
285
286
+
<Flex
287
+
align={Flex.Align.CENTER}
288
+
justify={Flex.Justify.END}
289
+
direction={Flex.Direction.HORIZONTAL}
290
+
grow={1}
291
+
className="moonbase-link-buttons"
292
+
>
293
+
{linkButtons.length > 0 && linkButtons}
294
+
</Flex>
295
+
</Flex>
296
)}
297
298
<Flex
299
justify={Flex.Justify.START}
300
wrap={Flex.Wrap.WRAP}
301
style={{
302
+
padding: "16px 16px",
303
+
// This looks wonky in the settings tab
304
+
rowGap: tab === ExtensionPage.Info ? "16px" : undefined
305
}}
306
>
307
+
{tab === ExtensionPage.Info && <ExtensionInfo ext={ext} selectTag={selectTag} />}
308
{tab === ExtensionPage.Description && (
309
<Text variant="text-md/normal" className={MarkupClasses.markup} style={{ width: "100%" }}>
310
{MarkupUtils.parse(description ?? "*No description*", true, {
···
323
})}
324
</Text>
325
)}
326
+
{tab === ExtensionPage.Settings && (
327
+
<ErrorBoundary>
328
+
<Settings ext={ext} />
329
+
</ErrorBoundary>
330
+
)}
331
</Flex>
332
</div>
333
</Card>
+67
-52
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/filterBar.tsx
+67
-52
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/filterBar.tsx
···
1
import { tagNames } from "./info";
2
-
3
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
4
import * as React from "@moonlight-mod/wp/react";
5
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
···
11
Popout,
12
Dialog,
13
Menu,
14
-
MenuGroup,
15
-
MenuCheckboxItem,
16
-
MenuItem
17
} from "@moonlight-mod/wp/discord/components/common/index";
18
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
19
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
20
21
export enum Filter {
22
Core = 1 << 0,
···
26
Disabled = 1 << 4,
27
Installed = 1 << 5,
28
Repository = 1 << 6,
29
-
Incompatible = 1 << 7
30
}
31
export const defaultFilter = 127 as Filter;
32
33
-
const Margins = spacepack.findByCode("marginCenterHorz:")[0].exports;
34
-
const SortMenuClasses = spacepack.findByCode("container:", "clearText:")[0].exports;
35
-
36
-
let FilterDialogClasses: any;
37
-
let FilterBarClasses: any;
38
spacepack
39
.lazyLoad('"Missing channel in Channel.openChannelContextMenu"', /e\("(\d+)"\)/g, /webpackId:(\d+?),/)
40
.then(() => {
41
-
FilterBarClasses = spacepack.findByCode("tagsButtonWithCount:")[0].exports;
42
-
FilterDialogClasses = spacepack.findByCode("countContainer:", "tagContainer:")[0].exports;
43
});
44
45
-
const TagItem = spacepack.findByCode('"forum-tag-"')[0].exports.Z;
46
-
47
-
// FIXME: type component keys
48
-
const { ChevronSmallDownIcon, ChevronSmallUpIcon, ArrowsUpDownIcon, RetryIcon, Tooltip } = Components;
49
-
50
function toggleTag(selectedTags: Set<string>, setSelectedTags: (tags: Set<string>) => void, tag: string) {
51
const newState = new Set(selectedTags);
52
if (newState.has(tag)) newState.delete(tag);
···
123
checked={(filter & Filter.Incompatible) === Filter.Incompatible}
124
action={() => toggleFilter(Filter.Incompatible)}
125
/>
126
<MenuItem
127
id="reset-all"
128
className={SortMenuClasses.clearText}
···
140
141
function TagButtonPopout({ selectedTags, setSelectedTags, setPopoutRef, closePopout }: any) {
142
return (
143
-
<Dialog ref={setPopoutRef} className={FilterDialogClasses.container}>
144
-
<div className={FilterDialogClasses.header}>
145
-
<div className={FilterDialogClasses.headerLeft}>
146
-
<Heading color="interactive-normal" variant="text-xs/bold" className={FilterDialogClasses.headerText}>
147
Select tags
148
</Heading>
149
-
<div className={FilterDialogClasses.countContainer}>
150
-
<Text className={FilterDialogClasses.countText} color="none" variant="text-xs/medium">
151
{selectedTags.size}
152
</Text>
153
</div>
154
</div>
155
</div>
156
-
<div className={FilterDialogClasses.tagContainer}>
157
{Object.keys(tagNames).map((tag) => (
158
<TagItem
159
key={tag}
160
-
className={FilterDialogClasses.tag}
161
-
tag={{ name: tagNames[tag as keyof typeof tagNames] }}
162
onClick={() => toggleTag(selectedTags, setSelectedTags, tag)}
163
selected={selectedTags.has(tag)}
164
/>
165
))}
166
</div>
167
-
<div className={FilterDialogClasses.separator} />
168
<Button
169
look={Button.Looks.LINK}
170
size={Button.Sizes.MIN}
171
color={Button.Colors.CUSTOM}
172
-
className={FilterDialogClasses.clear}
173
onClick={() => {
174
setSelectedTags(new Set());
175
closePopout();
···
199
const tagsContainer = React.useRef<HTMLDivElement>(null);
200
const tagListInner = React.useRef<HTMLDivElement>(null);
201
const [tagsButtonOffset, setTagsButtonOffset] = React.useState(0);
202
React.useLayoutEffect(() => {
203
if (tagsContainer.current === null || tagListInner.current === null) return;
204
const { left: containerX, top: containerY } = tagsContainer.current.getBoundingClientRect();
···
220
style={{
221
paddingTop: "12px"
222
}}
223
-
className={`${FilterBarClasses.tagsContainer} ${Margins.marginBottom8}`}
224
>
225
<Tooltip text="Refresh updates" position="top">
226
{(props: any) => (
···
228
{...props}
229
size={Button.Sizes.MIN}
230
color={Button.Colors.CUSTOM}
231
-
className={`${FilterBarClasses.sortDropdown} moonbase-retry-button`}
232
-
innerClassName={FilterBarClasses.sortDropdownInner}
233
-
onClick={() => MoonbaseSettingsStore.checkUpdates()}
234
>
235
-
<RetryIcon size={"custom"} width={16} />
236
</Button>
237
)}
238
</Tooltip>
···
248
{...props}
249
size={Button.Sizes.MIN}
250
color={Button.Colors.CUSTOM}
251
-
className={FilterBarClasses.sortDropdown}
252
-
innerClassName={FilterBarClasses.sortDropdownInner}
253
>
254
<ArrowsUpDownIcon size="xs" />
255
-
<Text className={FilterBarClasses.sortDropdownText} variant="text-sm/medium" color="interactive-normal">
256
Sort & filter
257
</Text>
258
{isShown ? (
···
263
</Button>
264
)}
265
</Popout>
266
-
<div className={FilterBarClasses.divider} />
267
-
<div className={FilterBarClasses.tagList}>
268
-
<div ref={tagListInner} className={FilterBarClasses.tagListInner}>
269
{Object.keys(tagNames).map((tag) => (
270
<TagItem
271
key={tag}
272
-
className={FilterBarClasses.tag}
273
-
tag={{ name: tagNames[tag as keyof typeof tagNames] }}
274
onClick={() => toggleTag(selectedTags, setSelectedTags, tag)}
275
selected={selectedTags.has(tag)}
276
/>
···
298
left: tagsButtonOffset
299
}}
300
// TODO: Use Discord's class name utility
301
-
className={`${FilterBarClasses.tagsButton} ${
302
-
selectedTags.size > 0 ? FilterBarClasses.tagsButtonWithCount : ""
303
-
}`}
304
-
innerClassName={FilterBarClasses.tagsButtonInner}
305
>
306
{selectedTags.size > 0 ? (
307
-
<div style={{ boxSizing: "content-box" }} className={FilterBarClasses.countContainer}>
308
-
<Text className={FilterBarClasses.countText} color="none" variant="text-xs/medium">
309
{selectedTags.size}
310
</Text>
311
</div>
···
323
<Button
324
size={Button.Sizes.MIN}
325
color={Button.Colors.CUSTOM}
326
-
className={`${FilterBarClasses.tagsButton} ${FilterBarClasses.tagsButtonPlaceholder}`}
327
-
innerClassName={FilterBarClasses.tagsButtonInner}
328
>
329
{selectedTags.size > 0 ? (
330
-
<div style={{ boxSizing: "content-box" }} className={FilterBarClasses.countContainer}>
331
-
<Text className={FilterBarClasses.countText} color="none" variant="text-xs/medium">
332
{selectedTags.size}
333
</Text>
334
</div>
···
1
import { tagNames } from "./info";
2
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
3
import * as React from "@moonlight-mod/wp/react";
4
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
···
10
Popout,
11
Dialog,
12
Menu,
13
+
ChevronSmallDownIcon,
14
+
ChevronSmallUpIcon,
15
+
ArrowsUpDownIcon,
16
+
RetryIcon,
17
+
Tooltip
18
} from "@moonlight-mod/wp/discord/components/common/index";
19
+
import { MenuGroup, MenuCheckboxItem, MenuItem } from "@moonlight-mod/wp/contextMenu_contextMenu";
20
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
21
+
import Margins from "@moonlight-mod/wp/discord/styles/shared/Margins.css";
22
+
import TagItem from "@moonlight-mod/wp/discord/modules/forums/web/Tag";
23
24
export enum Filter {
25
Core = 1 << 0,
···
29
Disabled = 1 << 4,
30
Installed = 1 << 5,
31
Repository = 1 << 6,
32
+
Incompatible = 1 << 7,
33
+
Deprecated = 1 << 8
34
}
35
export const defaultFilter = 127 as Filter;
36
37
+
let HeaderClasses: any;
38
+
let ForumsClasses: any;
39
+
let SortMenuClasses: any;
40
spacepack
41
.lazyLoad('"Missing channel in Channel.openChannelContextMenu"', /e\("(\d+)"\)/g, /webpackId:(\d+?),/)
42
.then(() => {
43
+
ForumsClasses = spacepack.require("discord/modules/forums/web/Forums.css");
44
+
HeaderClasses = spacepack.require("discord/modules/forums/web/Header.css");
45
+
SortMenuClasses = spacepack.require("discord/modules/forums/web/SortMenu.css");
46
});
47
48
function toggleTag(selectedTags: Set<string>, setSelectedTags: (tags: Set<string>) => void, tag: string) {
49
const newState = new Set(selectedTags);
50
if (newState.has(tag)) newState.delete(tag);
···
121
checked={(filter & Filter.Incompatible) === Filter.Incompatible}
122
action={() => toggleFilter(Filter.Incompatible)}
123
/>
124
+
<MenuCheckboxItem
125
+
id="l-deprecated"
126
+
label="Show deprecated"
127
+
checked={(filter & Filter.Deprecated) === Filter.Deprecated}
128
+
action={() => toggleFilter(Filter.Deprecated)}
129
+
/>
130
<MenuItem
131
id="reset-all"
132
className={SortMenuClasses.clearText}
···
144
145
function TagButtonPopout({ selectedTags, setSelectedTags, setPopoutRef, closePopout }: any) {
146
return (
147
+
<Dialog ref={setPopoutRef} className={HeaderClasses.container}>
148
+
<div className={HeaderClasses.header}>
149
+
<div className={HeaderClasses.headerLeft}>
150
+
<Heading color="interactive-normal" variant="text-xs/bold" className={HeaderClasses.headerText}>
151
Select tags
152
</Heading>
153
+
<div className={HeaderClasses.countContainer}>
154
+
<Text className={HeaderClasses.countText} color="none" variant="text-xs/medium">
155
{selectedTags.size}
156
</Text>
157
</div>
158
</div>
159
</div>
160
+
<div className={HeaderClasses.tagContainer}>
161
{Object.keys(tagNames).map((tag) => (
162
<TagItem
163
key={tag}
164
+
className={HeaderClasses.tag}
165
+
tag={{ name: tagNames[tag as keyof typeof tagNames], id: tagNames[tag as keyof typeof tagNames] }}
166
onClick={() => toggleTag(selectedTags, setSelectedTags, tag)}
167
selected={selectedTags.has(tag)}
168
/>
169
))}
170
</div>
171
+
<div className={HeaderClasses.separator} />
172
<Button
173
look={Button.Looks.LINK}
174
size={Button.Sizes.MIN}
175
color={Button.Colors.CUSTOM}
176
+
className={HeaderClasses.clear}
177
onClick={() => {
178
setSelectedTags(new Set());
179
closePopout();
···
203
const tagsContainer = React.useRef<HTMLDivElement>(null);
204
const tagListInner = React.useRef<HTMLDivElement>(null);
205
const [tagsButtonOffset, setTagsButtonOffset] = React.useState(0);
206
+
const [checkingUpdates, setCheckingUpdates] = React.useState(false);
207
+
208
React.useLayoutEffect(() => {
209
if (tagsContainer.current === null || tagListInner.current === null) return;
210
const { left: containerX, top: containerY } = tagsContainer.current.getBoundingClientRect();
···
226
style={{
227
paddingTop: "12px"
228
}}
229
+
className={`${ForumsClasses.tagsContainer} ${Margins.marginBottom8}`}
230
>
231
<Tooltip text="Refresh updates" position="top">
232
{(props: any) => (
···
234
{...props}
235
size={Button.Sizes.MIN}
236
color={Button.Colors.CUSTOM}
237
+
className={`${ForumsClasses.sortDropdown} moonbase-retry-button`}
238
+
innerClassName={ForumsClasses.sortDropdownInner}
239
+
onClick={() => {
240
+
(async () => {
241
+
try {
242
+
setCheckingUpdates(true);
243
+
await MoonbaseSettingsStore.checkUpdates();
244
+
} finally {
245
+
// artificial delay because the spin is fun
246
+
await new Promise((r) => setTimeout(r, 500));
247
+
setCheckingUpdates(false);
248
+
}
249
+
})();
250
+
}}
251
>
252
+
<RetryIcon size={"custom"} width={16} className={checkingUpdates ? "moonbase-speen" : ""} />
253
</Button>
254
)}
255
</Tooltip>
···
265
{...props}
266
size={Button.Sizes.MIN}
267
color={Button.Colors.CUSTOM}
268
+
className={ForumsClasses.sortDropdown}
269
+
innerClassName={ForumsClasses.sortDropdownInner}
270
>
271
<ArrowsUpDownIcon size="xs" />
272
+
<Text className={ForumsClasses.sortDropdownText} variant="text-sm/medium" color="interactive-normal">
273
Sort & filter
274
</Text>
275
{isShown ? (
···
280
</Button>
281
)}
282
</Popout>
283
+
<div className={ForumsClasses.divider} />
284
+
<div className={ForumsClasses.tagList}>
285
+
<div ref={tagListInner} className={ForumsClasses.tagListInner}>
286
{Object.keys(tagNames).map((tag) => (
287
<TagItem
288
key={tag}
289
+
className={ForumsClasses.tag}
290
+
tag={{ name: tagNames[tag as keyof typeof tagNames], id: tag }}
291
onClick={() => toggleTag(selectedTags, setSelectedTags, tag)}
292
selected={selectedTags.has(tag)}
293
/>
···
315
left: tagsButtonOffset
316
}}
317
// TODO: Use Discord's class name utility
318
+
className={`${ForumsClasses.tagsButton} ${selectedTags.size > 0 ? ForumsClasses.tagsButtonWithCount : ""}`}
319
+
innerClassName={ForumsClasses.tagsButtonInner}
320
>
321
{selectedTags.size > 0 ? (
322
+
<div style={{ boxSizing: "content-box" }} className={ForumsClasses.countContainer}>
323
+
<Text className={ForumsClasses.countText} color="none" variant="text-xs/medium">
324
{selectedTags.size}
325
</Text>
326
</div>
···
338
<Button
339
size={Button.Sizes.MIN}
340
color={Button.Colors.CUSTOM}
341
+
className={`${ForumsClasses.tagsButton} ${ForumsClasses.tagsButtonPlaceholder}`}
342
+
innerClassName={ForumsClasses.tagsButtonInner}
343
>
344
{selectedTags.size > 0 ? (
345
+
<div style={{ boxSizing: "content-box" }} className={ForumsClasses.countContainer}>
346
+
<Text className={ForumsClasses.countText} color="none" variant="text-xs/medium">
347
{selectedTags.size}
348
</Text>
349
</div>
+49
-15
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/index.tsx
+49
-15
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/index.tsx
···
6
import React from "@moonlight-mod/wp/react";
7
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
8
import { useStateFromStoresObject } from "@moonlight-mod/wp/discord/packages/flux";
9
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
10
11
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
12
import { ExtensionCompat } from "@moonlight-mod/core/extension/loader";
13
import HelpMessage from "../HelpMessage";
14
15
-
const SearchBar: any = Object.values(spacepack.findByCode("hideSearchIcon")[0].exports)[0];
16
-
const { FormDivider, CircleInformationIcon, XSmallIcon } = Components;
17
-
const PanelButton = spacepack.findByCode("Masks.PANEL_BUTTON")[0].exports.Z;
18
19
export default function ExtensionsPage() {
20
-
const { extensions, savedFilter, showOnlyUpdateable } = useStateFromStoresObject([MoonbaseSettingsStore], () => {
21
return {
22
extensions: MoonbaseSettingsStore.extensions,
23
-
savedFilter: MoonbaseSettingsStore.getExtensionConfigRaw<number>("moonbase", "filter", defaultFilter),
24
-
showOnlyUpdateable: MoonbaseSettingsStore.showOnlyUpdateable
25
};
26
});
27
28
const [query, setQuery] = React.useState("");
29
30
const filterState = React.useState(defaultFilter);
31
···
37
filter = filterState[0];
38
setFilter = filterState[1];
39
}
40
const [selectedTags, setSelectedTags] = React.useState(new Set<string>());
41
const sorted = Object.values(extensions).sort((a, b) => {
42
const aName = a.manifest.meta?.name ?? a.id;
43
const bName = b.manifest.meta?.name ?? b.id;
···
72
) &&
73
(filter & Filter.Incompatible ||
74
ext.compat === ExtensionCompat.Compatible ||
75
-
(ext.compat === ExtensionCompat.InvalidApiLevel && ext.hasUpdate))
76
);
77
78
// Prioritize extensions with updates
79
const filteredWithUpdates = filtered.filter((ext) => ext!.hasUpdate);
80
-
const filterUpdates = showOnlyUpdateable && filteredWithUpdates.length > 0;
81
-
const filteredWithoutUpdates = filterUpdates ? [] : filtered.filter((ext) => !ext!.hasUpdate);
82
83
return (
84
<>
···
97
/>
98
<FilterBar filter={filter} setFilter={setFilter} selectedTags={selectedTags} setSelectedTags={setSelectedTags} />
99
100
-
{filterUpdates && (
101
<HelpMessage
102
icon={CircleInformationIcon}
103
-
text="Only displaying updates"
104
className="moonbase-extension-update-section"
105
>
106
<div className="moonbase-help-message-buttons">
107
<PanelButton
108
icon={XSmallIcon}
109
onClick={() => {
110
-
MoonbaseSettingsStore.showOnlyUpdateable = false;
111
}}
112
/>
113
</div>
···
115
)}
116
117
{filteredWithUpdates.map((ext) => (
118
-
<ExtensionCard uniqueId={ext.uniqueId} key={ext.uniqueId} />
119
))}
120
{filteredWithUpdates.length > 0 && filteredWithoutUpdates.length > 0 && (
121
<FormDivider className="moonbase-update-divider" />
122
)}
123
{filteredWithoutUpdates.map((ext) => (
124
-
<ExtensionCard uniqueId={ext.uniqueId} key={ext.uniqueId} />
125
))}
126
</>
127
);
···
6
import React from "@moonlight-mod/wp/react";
7
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
8
import { useStateFromStoresObject } from "@moonlight-mod/wp/discord/packages/flux";
9
+
import {
10
+
FormDivider,
11
+
CircleInformationIcon,
12
+
XSmallIcon,
13
+
Button
14
+
} from "@moonlight-mod/wp/discord/components/common/index";
15
+
import PanelButton from "@moonlight-mod/wp/discord/components/common/PanelButton";
16
17
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
18
+
import ErrorBoundary from "@moonlight-mod/wp/common_ErrorBoundary";
19
import { ExtensionCompat } from "@moonlight-mod/core/extension/loader";
20
import HelpMessage from "../HelpMessage";
21
22
+
const SearchBar = spacepack.require("discord/uikit/search/SearchBar").default;
23
+
24
+
const validTags: string[] = Object.values(ExtensionTag);
25
26
export default function ExtensionsPage() {
27
+
const { extensions, savedFilter } = useStateFromStoresObject([MoonbaseSettingsStore], () => {
28
return {
29
extensions: MoonbaseSettingsStore.extensions,
30
+
savedFilter: MoonbaseSettingsStore.getExtensionConfigRaw<number>("moonbase", "filter", defaultFilter)
31
};
32
});
33
34
const [query, setQuery] = React.useState("");
35
+
const [hitUpdateAll, setHitUpdateAll] = React.useState(false);
36
37
const filterState = React.useState(defaultFilter);
38
···
44
filter = filterState[0];
45
setFilter = filterState[1];
46
}
47
+
48
const [selectedTags, setSelectedTags] = React.useState(new Set<string>());
49
+
const selectTag = React.useCallback(
50
+
(tag: string) => {
51
+
const newState = new Set(selectedTags);
52
+
if (validTags.includes(tag)) newState.add(tag);
53
+
setSelectedTags(newState);
54
+
},
55
+
[selectedTags]
56
+
);
57
+
58
const sorted = Object.values(extensions).sort((a, b) => {
59
const aName = a.manifest.meta?.name ?? a.id;
60
const bName = b.manifest.meta?.name ?? b.id;
···
89
) &&
90
(filter & Filter.Incompatible ||
91
ext.compat === ExtensionCompat.Compatible ||
92
+
(ext.compat === ExtensionCompat.InvalidApiLevel && ext.hasUpdate)) &&
93
+
(filter & Filter.Deprecated ||
94
+
ext.manifest?.meta?.deprecated !== true ||
95
+
ext.state !== ExtensionState.NotDownloaded)
96
);
97
98
// Prioritize extensions with updates
99
const filteredWithUpdates = filtered.filter((ext) => ext!.hasUpdate);
100
+
const filteredWithoutUpdates = filtered.filter((ext) => !ext!.hasUpdate);
101
102
return (
103
<>
···
116
/>
117
<FilterBar filter={filter} setFilter={setFilter} selectedTags={selectedTags} setSelectedTags={setSelectedTags} />
118
119
+
{filteredWithUpdates.length > 0 && (
120
<HelpMessage
121
icon={CircleInformationIcon}
122
+
text="Extension updates are available"
123
className="moonbase-extension-update-section"
124
>
125
<div className="moonbase-help-message-buttons">
126
+
<Button
127
+
color={Button.Colors.BRAND}
128
+
size={Button.Sizes.TINY}
129
+
disabled={hitUpdateAll}
130
+
onClick={() => {
131
+
setHitUpdateAll(true);
132
+
MoonbaseSettingsStore.updateAllExtensions();
133
+
}}
134
+
>
135
+
Update all
136
+
</Button>
137
<PanelButton
138
icon={XSmallIcon}
139
onClick={() => {
140
+
MoonbaseSettingsStore.dismissAllExtensionUpdates();
141
}}
142
/>
143
</div>
···
145
)}
146
147
{filteredWithUpdates.map((ext) => (
148
+
<ErrorBoundary>
149
+
<ExtensionCard uniqueId={ext.uniqueId} key={ext.uniqueId} selectTag={selectTag} />
150
+
</ErrorBoundary>
151
))}
152
{filteredWithUpdates.length > 0 && filteredWithoutUpdates.length > 0 && (
153
<FormDivider className="moonbase-update-divider" />
154
)}
155
{filteredWithoutUpdates.map((ext) => (
156
+
<ErrorBoundary>
157
+
<ExtensionCard uniqueId={ext.uniqueId} key={ext.uniqueId} selectTag={selectTag} />
158
+
</ErrorBoundary>
159
))}
160
</>
161
);
+55
-26
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/info.tsx
+55
-26
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/info.tsx
···
2
import { MoonbaseExtension } from "../../../types";
3
4
import React from "@moonlight-mod/wp/react";
5
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
6
-
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
7
8
type Dependency = {
9
id: string;
···
34
[ExtensionTag.Library]: "Library"
35
};
36
37
-
const UserInfoClasses = spacepack.findByCode("infoScroller", "userInfoSection", "userInfoSectionHeader")[0].exports;
38
-
39
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
40
-
41
-
// FIXME: type component keys
42
-
const { Text } = Components;
43
44
function InfoSection({ title, children }: { title: string; children: React.ReactNode }) {
45
return (
···
48
marginRight: "1em"
49
}}
50
>
51
-
<Text variant="eyebrow" className={UserInfoClasses.userInfoSectionHeader}>
52
{title}
53
</Text>
54
···
57
);
58
}
59
60
-
function Badge({ color, children }: { color: string; children: React.ReactNode }) {
61
return (
62
<span
63
-
style={{
64
-
borderRadius: ".1875rem",
65
-
padding: "0 0.275rem",
66
-
marginRight: "0.4em",
67
-
backgroundColor: color,
68
-
color: "#fff"
69
-
}}
70
>
71
{children}
72
</span>
73
);
74
}
75
76
-
export default function ExtensionInfo({ ext }: { ext: MoonbaseExtension }) {
77
const authors = ext.manifest?.meta?.authors;
78
const tags = ext.manifest?.meta?.tags;
79
const version = ext.manifest?.version;
80
81
const dependencies: Dependency[] = [];
82
if (ext.manifest.dependencies != null) {
83
dependencies.push(
84
...ext.manifest.dependencies.map((dep) => ({
···
98
}
99
100
if (ext.manifest.incompatible != null) {
101
-
dependencies.push(
102
...ext.manifest.incompatible.map((dep) => ({
103
id: dep,
104
type: DependencyType.Incompatible
···
136
<InfoSection title="Tags">
137
{tags.map((tag, i) => {
138
const name = tagNames[tag];
139
140
return (
141
-
<Badge key={i} color={tag === ExtensionTag.DangerZone ? "var(--red-400)" : "var(--brand-500)"}>
142
{name}
143
</Badge>
144
);
···
149
{dependencies.length > 0 && (
150
<InfoSection title="Dependencies">
151
{dependencies.map((dep) => {
152
-
const colors = {
153
-
[DependencyType.Dependency]: "var(--brand-500)",
154
-
[DependencyType.Optional]: "var(--orange-400)",
155
-
[DependencyType.Incompatible]: "var(--red-400)"
156
-
};
157
-
const color = colors[dep.type];
158
const name = MoonbaseSettingsStore.tryGetExtensionName(dep.id);
159
160
return (
161
-
<Badge color={color} key={dep.id}>
162
{name}
163
</Badge>
164
);
···
2
import { MoonbaseExtension } from "../../../types";
3
4
import React from "@moonlight-mod/wp/react";
5
+
import { Text } from "@moonlight-mod/wp/discord/components/common/index";
6
7
type Dependency = {
8
id: string;
···
33
[ExtensionTag.Library]: "Library"
34
};
35
36
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
37
38
function InfoSection({ title, children }: { title: string; children: React.ReactNode }) {
39
return (
···
42
marginRight: "1em"
43
}}
44
>
45
+
<Text variant="eyebrow" className="moonlight-card-info-header">
46
{title}
47
</Text>
48
···
51
);
52
}
53
54
+
function Badge({
55
+
color,
56
+
children,
57
+
style = {},
58
+
onClick
59
+
}: {
60
+
color: string;
61
+
children: React.ReactNode;
62
+
style?: React.CSSProperties;
63
+
onClick?: () => void;
64
+
}) {
65
+
if (onClick) style.cursor ??= "pointer";
66
return (
67
<span
68
+
className="moonlight-card-badge"
69
+
style={
70
+
{
71
+
"--badge-color": color,
72
+
...style
73
+
} as React.CSSProperties
74
+
}
75
+
onClick={onClick}
76
>
77
{children}
78
</span>
79
);
80
}
81
82
+
export default function ExtensionInfo({
83
+
ext,
84
+
selectTag
85
+
}: {
86
+
ext: MoonbaseExtension;
87
+
selectTag: (tag: string) => void;
88
+
}) {
89
const authors = ext.manifest?.meta?.authors;
90
const tags = ext.manifest?.meta?.tags;
91
const version = ext.manifest?.version;
92
93
const dependencies: Dependency[] = [];
94
+
const incompatible: Dependency[] = [];
95
+
96
if (ext.manifest.dependencies != null) {
97
dependencies.push(
98
...ext.manifest.dependencies.map((dep) => ({
···
112
}
113
114
if (ext.manifest.incompatible != null) {
115
+
incompatible.push(
116
...ext.manifest.incompatible.map((dep) => ({
117
id: dep,
118
type: DependencyType.Incompatible
···
150
<InfoSection title="Tags">
151
{tags.map((tag, i) => {
152
const name = tagNames[tag];
153
+
let color = "var(--bg-mod-strong)";
154
+
let style;
155
+
if (tag === ExtensionTag.DangerZone) {
156
+
color = "var(--red-460)";
157
+
style = { color: "var(--primary-230)" };
158
+
}
159
160
return (
161
+
<Badge key={i} color={color} style={style} onClick={() => selectTag(tag)}>
162
{name}
163
</Badge>
164
);
···
169
{dependencies.length > 0 && (
170
<InfoSection title="Dependencies">
171
{dependencies.map((dep) => {
172
const name = MoonbaseSettingsStore.tryGetExtensionName(dep.id);
173
174
+
// TODO: figure out a decent way to distinguish suggested
175
return (
176
+
<Badge color="var(--bg-mod-strong)" key={dep.id}>
177
+
{name}
178
+
</Badge>
179
+
);
180
+
})}
181
+
</InfoSection>
182
+
)}
183
+
184
+
{incompatible.length > 0 && (
185
+
<InfoSection title="Incompatible">
186
+
{incompatible.map((dep) => {
187
+
const name = MoonbaseSettingsStore.tryGetExtensionName(dep.id);
188
+
189
+
return (
190
+
<Badge color="var(--bg-mod-strong)" key={dep.id}>
191
{name}
192
</Badge>
193
);
+15
-11
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/popup.tsx
+15
-11
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/popup.tsx
···
1
// TODO: clean up the styling here
2
-
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
3
import React from "@moonlight-mod/wp/react";
4
import { MoonbaseExtension } from "core-extensions/src/moonbase/types";
5
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
6
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
7
import { ExtensionLoadSource } from "@moonlight-mod/types";
8
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
9
10
-
const { openModalLazy, useModalsStore, closeModal } = Components;
11
-
const Popup = spacepack.findByCode(".minorContainer", "secondaryAction")[0].exports.default;
12
13
function close() {
14
const ModalStore = useModalsStore.getState();
15
closeModal(ModalStore.default[0].key);
16
}
17
18
const presentableLoadSources: Record<ExtensionLoadSource, string> = {
19
[ExtensionLoadSource.Developer]: "Local extension", // should never show up
20
[ExtensionLoadSource.Core]: "Core extension",
···
32
option: string | undefined;
33
setOption: (pick: string | undefined) => void;
34
}) {
35
-
const { SingleSelect } = Components;
36
-
37
return (
38
<SingleSelect
39
key={id}
···
61
deps: Record<string, MoonbaseExtension[]>;
62
transitionState: number | null;
63
}) {
64
-
const { Text } = Components;
65
-
66
const amountNotAvailable = Object.values(deps).filter((candidates) => candidates.length === 0).length;
67
68
const [options, setOptions] = React.useState<Record<string, string | undefined>>(
···
75
);
76
77
return (
78
-
<Popup
79
body={
80
<Flex
81
style={{
···
168
uniqueId: number;
169
cb: () => void;
170
}) {
171
-
const { Text } = Components;
172
173
return (
174
-
<Popup
175
title={title}
176
body={
177
<Flex>
···
1
// TODO: clean up the styling here
2
import React from "@moonlight-mod/wp/react";
3
import { MoonbaseExtension } from "core-extensions/src/moonbase/types";
4
+
import { openModalLazy, useModalsStore, closeModal } from "@moonlight-mod/wp/discord/modules/modals/Modals";
5
+
import { SingleSelect, Text } from "@moonlight-mod/wp/discord/components/common/index";
6
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
7
import { ExtensionLoadSource } from "@moonlight-mod/types";
8
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
9
+
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
10
11
+
let ConfirmModal: typeof import("@moonlight-mod/wp/discord/components/modals/ConfirmModal").default;
12
13
function close() {
14
const ModalStore = useModalsStore.getState();
15
closeModal(ModalStore.default[0].key);
16
}
17
18
+
// do this to avoid a hard dependency
19
+
function lazyLoad() {
20
+
if (!ConfirmModal) {
21
+
ConfirmModal = spacepack.require("discord/components/modals/ConfirmModal").default;
22
+
}
23
+
}
24
+
25
const presentableLoadSources: Record<ExtensionLoadSource, string> = {
26
[ExtensionLoadSource.Developer]: "Local extension", // should never show up
27
[ExtensionLoadSource.Core]: "Core extension",
···
39
option: string | undefined;
40
setOption: (pick: string | undefined) => void;
41
}) {
42
return (
43
<SingleSelect
44
key={id}
···
66
deps: Record<string, MoonbaseExtension[]>;
67
transitionState: number | null;
68
}) {
69
+
lazyLoad();
70
const amountNotAvailable = Object.values(deps).filter((candidates) => candidates.length === 0).length;
71
72
const [options, setOptions] = React.useState<Record<string, string | undefined>>(
···
79
);
80
81
return (
82
+
<ConfirmModal
83
body={
84
<Flex
85
style={{
···
172
uniqueId: number;
173
cb: () => void;
174
}) {
175
+
lazyLoad();
176
177
return (
178
+
<ConfirmModal
179
title={title}
180
body={
181
<Flex>
+84
-50
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/settings.tsx
+84
-50
packages/core-extensions/src/moonbase/webpackModules/ui/extensions/settings.tsx
···
11
12
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
13
import React from "@moonlight-mod/wp/react";
14
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
15
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
16
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
17
18
type SettingsProps = {
19
ext: MoonbaseExtension;
···
21
setting: ExtensionSettingsManifest;
22
disabled: boolean;
23
};
24
-
25
type SettingsComponent = React.ComponentType<SettingsProps>;
26
27
-
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
28
const Margins = spacepack.require("discord/styles/shared/Margins.css");
29
30
function useConfigEntry<T>(uniqueId: number, name: string) {
31
return useStateFromStores(
32
[MoonbaseSettingsStore],
···
42
}
43
44
function Boolean({ ext, name, setting, disabled }: SettingsProps) {
45
-
const { FormSwitch } = Components;
46
const { value, displayName, description } = useConfigEntry<boolean>(ext.uniqueId, name);
47
48
return (
···
53
onChange={(value: boolean) => {
54
MoonbaseSettingsStore.setExtensionConfig(ext.id, name, value);
55
}}
56
-
note={description}
57
className={`${Margins.marginReset} ${Margins.marginTop20}`}
58
>
59
{displayName}
···
62
}
63
64
function Number({ ext, name, setting, disabled }: SettingsProps) {
65
-
const { FormItem, FormText, Slider } = Components;
66
const { value, displayName, description } = useConfigEntry<number>(ext.uniqueId, name);
67
68
const castedSetting = setting as NumberSettingType;
69
-
const min = castedSetting.min ?? 0;
70
-
const max = castedSetting.max ?? 100;
71
72
return (
73
<FormItem className={Margins.marginTop20} title={displayName}>
74
-
{description && <FormText>{description}</FormText>}
75
-
<Slider
76
-
initialValue={value ?? 0}
77
-
disabled={disabled}
78
-
minValue={castedSetting.min ?? 0}
79
-
maxValue={castedSetting.max ?? 100}
80
-
onValueChange={(value: number) => {
81
-
const rounded = Math.max(min, Math.min(max, Math.round(value)));
82
-
MoonbaseSettingsStore.setExtensionConfig(ext.id, name, rounded);
83
-
}}
84
-
/>
85
</FormItem>
86
);
87
}
88
89
function String({ ext, name, setting, disabled }: SettingsProps) {
90
-
const { FormItem, FormText, TextInput } = Components;
91
const { value, displayName, description } = useConfigEntry<string>(ext.uniqueId, name);
92
93
return (
94
<FormItem className={Margins.marginTop20} title={displayName}>
95
-
{description && <FormText className={Margins.marginBottom8}>{description}</FormText>}
96
<TextInput
97
value={value ?? ""}
98
-
onChange={(value: string) => {
99
-
if (disabled) return;
100
-
MoonbaseSettingsStore.setExtensionConfig(ext.id, name, value);
101
-
}}
102
/>
103
</FormItem>
104
);
105
}
106
107
function MultilineString({ ext, name, setting, disabled }: SettingsProps) {
108
-
const { FormItem, FormText, TextArea } = Components;
109
const { value, displayName, description } = useConfigEntry<string>(ext.uniqueId, name);
110
111
return (
112
<FormItem className={Margins.marginTop20} title={displayName}>
113
-
{description && <FormText className={Margins.marginBottom8}>{description}</FormText>}
114
<TextArea
115
rows={5}
116
value={value ?? ""}
117
className={"moonbase-resizeable"}
118
-
onChange={(value: string) => {
119
-
if (disabled) return;
120
-
MoonbaseSettingsStore.setExtensionConfig(ext.id, name, value);
121
-
}}
122
/>
123
</FormItem>
124
);
125
}
126
127
function Select({ ext, name, setting, disabled }: SettingsProps) {
128
-
const { FormItem, FormText, SingleSelect } = Components;
129
const { value, displayName, description } = useConfigEntry<string>(ext.uniqueId, name);
130
131
const castedSetting = setting as SelectSettingType;
···
133
134
return (
135
<FormItem className={Margins.marginTop20} title={displayName}>
136
-
{description && <FormText className={Margins.marginBottom8}>{description}</FormText>}
137
<SingleSelect
138
autofocus={false}
139
clearable={false}
···
149
}
150
151
function MultiSelect({ ext, name, setting, disabled }: SettingsProps) {
152
-
const { FormItem, FormText, Select, useVariableSelect, multiSelect } = Components;
153
const { value, displayName, description } = useConfigEntry<string | string[]>(ext.uniqueId, name);
154
155
const castedSetting = setting as MultiSelectSettingType;
···
157
158
return (
159
<FormItem className={Margins.marginTop20} title={displayName}>
160
-
{description && <FormText className={Margins.marginBottom8}>{description}</FormText>}
161
-
<Select
162
autofocus={false}
163
clearable={false}
164
closeOnSelect={false}
···
175
</FormItem>
176
);
177
}
178
-
179
-
const RemoveButtonClasses = spacepack.findByCode("removeButtonContainer")[0].exports;
180
-
181
-
// FIXME: type component keys
182
-
const { CircleXIcon } = Components;
183
184
function RemoveEntryButton({ onClick, disabled }: { onClick: () => void; disabled: boolean }) {
185
-
const { Tooltip, Clickable } = Components;
186
return (
187
-
<div className={RemoveButtonClasses.removeButtonContainer}>
188
<Tooltip text="Remove entry" position="top">
189
{(props: any) => (
190
-
<Clickable {...props} className={RemoveButtonClasses.removeButton} onClick={onClick}>
191
<CircleXIcon width={16} height={16} />
192
</Clickable>
193
)}
···
197
}
198
199
function List({ ext, name, setting, disabled }: SettingsProps) {
200
-
const { FormItem, FormText, TextInput, Button } = Components;
201
const { value, displayName, description } = useConfigEntry<string[]>(ext.uniqueId, name);
202
203
const entries = value ?? [];
···
205
206
return (
207
<FormItem className={Margins.marginTop20} title={displayName}>
208
-
{description && <FormText className={Margins.marginBottom4}>{description}</FormText>}
209
<Flex direction={Flex.Direction.VERTICAL}>
210
{entries.map((val, i) => (
211
// FIXME: stylesheets
···
257
}
258
259
function Dictionary({ ext, name, setting, disabled }: SettingsProps) {
260
-
const { FormItem, FormText, TextInput, Button } = Components;
261
const { value, displayName, description } = useConfigEntry<Record<string, string>>(ext.uniqueId, name);
262
263
const entries = Object.entries(value ?? {});
···
265
266
return (
267
<FormItem className={Margins.marginTop20} title={displayName}>
268
-
{description && <FormText className={Margins.marginBottom4}>{description}</FormText>}
269
<Flex direction={Flex.Direction.VERTICAL}>
270
{entries.map(([key, val], i) => (
271
// FIXME: stylesheets
···
339
);
340
341
if (Component == null) {
342
-
const { Text } = Components;
343
return (
344
<Text variant="text-md/normal">{`Custom setting "${displayName}" is missing a component. Perhaps the extension is not installed?`}</Text>
345
);
346
}
347
348
return (
349
-
<Component value={value} setValue={(value) => MoonbaseSettingsStore.setExtensionConfig(ext.id, name, value)} />
350
);
351
}
352
···
11
12
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
13
import React from "@moonlight-mod/wp/react";
14
+
import {
15
+
FormSwitch,
16
+
FormItem,
17
+
FormText,
18
+
TextInput,
19
+
Slider,
20
+
TextArea,
21
+
Tooltip,
22
+
Clickable,
23
+
CircleXIcon,
24
+
Text,
25
+
SingleSelect,
26
+
Button,
27
+
useVariableSelect,
28
+
multiSelect,
29
+
Select as DiscordSelect,
30
+
NumberInputStepper
31
+
} from "@moonlight-mod/wp/discord/components/common/index";
32
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
33
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
34
+
import MarkupUtils from "@moonlight-mod/wp/discord/modules/markup/MarkupUtils";
35
+
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
36
+
import ErrorBoundary from "@moonlight-mod/wp/common_ErrorBoundary";
37
+
38
+
let GuildSettingsRoleEditClasses: any;
39
+
spacepack
40
+
.lazyLoad(
41
+
"renderArtisanalHack",
42
+
/\[(?:.\.e\("\d+?"\),?)+\][^}]+?webpackId:\d+,name:"GuildSettings"/,
43
+
/webpackId:(\d+),name:"GuildSettings"/
44
+
)
45
+
.then(
46
+
() =>
47
+
(GuildSettingsRoleEditClasses = spacepack.require(
48
+
"discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"
49
+
))
50
+
);
51
52
type SettingsProps = {
53
ext: MoonbaseExtension;
···
55
setting: ExtensionSettingsManifest;
56
disabled: boolean;
57
};
58
type SettingsComponent = React.ComponentType<SettingsProps>;
59
60
const Margins = spacepack.require("discord/styles/shared/Margins.css");
61
62
+
function markdownify(str: string) {
63
+
return MarkupUtils.parse(str, true, {
64
+
hideSimpleEmbedContent: true,
65
+
allowLinks: true
66
+
});
67
+
}
68
+
69
function useConfigEntry<T>(uniqueId: number, name: string) {
70
return useStateFromStores(
71
[MoonbaseSettingsStore],
···
81
}
82
83
function Boolean({ ext, name, setting, disabled }: SettingsProps) {
84
const { value, displayName, description } = useConfigEntry<boolean>(ext.uniqueId, name);
85
86
return (
···
91
onChange={(value: boolean) => {
92
MoonbaseSettingsStore.setExtensionConfig(ext.id, name, value);
93
}}
94
+
note={description != null ? markdownify(description) : undefined}
95
className={`${Margins.marginReset} ${Margins.marginTop20}`}
96
>
97
{displayName}
···
100
}
101
102
function Number({ ext, name, setting, disabled }: SettingsProps) {
103
const { value, displayName, description } = useConfigEntry<number>(ext.uniqueId, name);
104
105
const castedSetting = setting as NumberSettingType;
106
+
const min = castedSetting.min;
107
+
const max = castedSetting.max;
108
+
109
+
const onChange = (value: number) => {
110
+
const rounded = min == null || max == null ? Math.round(value) : Math.max(min, Math.min(max, Math.round(value)));
111
+
MoonbaseSettingsStore.setExtensionConfig(ext.id, name, rounded);
112
+
};
113
114
return (
115
<FormItem className={Margins.marginTop20} title={displayName}>
116
+
{min == null || max == null ? (
117
+
<Flex justify={Flex.Justify.BETWEEN} direction={Flex.Direction.HORIZONTAL}>
118
+
{description && <FormText>{markdownify(description)}</FormText>}
119
+
<NumberInputStepper value={value ?? 0} onChange={onChange} />
120
+
</Flex>
121
+
) : (
122
+
<>
123
+
{description && <FormText>{markdownify(description)}</FormText>}
124
+
<Slider
125
+
initialValue={value ?? 0}
126
+
disabled={disabled}
127
+
minValue={min}
128
+
maxValue={max}
129
+
onValueChange={onChange}
130
+
onValueRender={(value: number) => `${Math.round(value)}`}
131
+
/>
132
+
</>
133
+
)}
134
</FormItem>
135
);
136
}
137
138
function String({ ext, name, setting, disabled }: SettingsProps) {
139
const { value, displayName, description } = useConfigEntry<string>(ext.uniqueId, name);
140
141
return (
142
<FormItem className={Margins.marginTop20} title={displayName}>
143
+
{description && <FormText className={Margins.marginBottom8}>{markdownify(description)}</FormText>}
144
<TextInput
145
value={value ?? ""}
146
+
disabled={disabled}
147
+
onChange={(value: string) => MoonbaseSettingsStore.setExtensionConfig(ext.id, name, value)}
148
/>
149
</FormItem>
150
);
151
}
152
153
function MultilineString({ ext, name, setting, disabled }: SettingsProps) {
154
const { value, displayName, description } = useConfigEntry<string>(ext.uniqueId, name);
155
156
return (
157
<FormItem className={Margins.marginTop20} title={displayName}>
158
+
{description && <FormText className={Margins.marginBottom8}>{markdownify(description)}</FormText>}
159
<TextArea
160
rows={5}
161
value={value ?? ""}
162
+
disabled={disabled}
163
className={"moonbase-resizeable"}
164
+
onChange={(value: string) => MoonbaseSettingsStore.setExtensionConfig(ext.id, name, value)}
165
/>
166
</FormItem>
167
);
168
}
169
170
function Select({ ext, name, setting, disabled }: SettingsProps) {
171
const { value, displayName, description } = useConfigEntry<string>(ext.uniqueId, name);
172
173
const castedSetting = setting as SelectSettingType;
···
175
176
return (
177
<FormItem className={Margins.marginTop20} title={displayName}>
178
+
{description && <FormText className={Margins.marginBottom8}>{markdownify(description)}</FormText>}
179
<SingleSelect
180
autofocus={false}
181
clearable={false}
···
191
}
192
193
function MultiSelect({ ext, name, setting, disabled }: SettingsProps) {
194
const { value, displayName, description } = useConfigEntry<string | string[]>(ext.uniqueId, name);
195
196
const castedSetting = setting as MultiSelectSettingType;
···
198
199
return (
200
<FormItem className={Margins.marginTop20} title={displayName}>
201
+
{description && <FormText className={Margins.marginBottom8}>{markdownify(description)}</FormText>}
202
+
<DiscordSelect
203
autofocus={false}
204
clearable={false}
205
closeOnSelect={false}
···
216
</FormItem>
217
);
218
}
219
220
function RemoveEntryButton({ onClick, disabled }: { onClick: () => void; disabled: boolean }) {
221
return (
222
+
<div className={GuildSettingsRoleEditClasses.removeButtonContainer}>
223
<Tooltip text="Remove entry" position="top">
224
{(props: any) => (
225
+
<Clickable {...props} className={GuildSettingsRoleEditClasses.removeButton} onClick={onClick}>
226
<CircleXIcon width={16} height={16} />
227
</Clickable>
228
)}
···
232
}
233
234
function List({ ext, name, setting, disabled }: SettingsProps) {
235
const { value, displayName, description } = useConfigEntry<string[]>(ext.uniqueId, name);
236
237
const entries = value ?? [];
···
239
240
return (
241
<FormItem className={Margins.marginTop20} title={displayName}>
242
+
{description && <FormText className={Margins.marginBottom4}>{markdownify(description)}</FormText>}
243
<Flex direction={Flex.Direction.VERTICAL}>
244
{entries.map((val, i) => (
245
// FIXME: stylesheets
···
291
}
292
293
function Dictionary({ ext, name, setting, disabled }: SettingsProps) {
294
const { value, displayName, description } = useConfigEntry<Record<string, string>>(ext.uniqueId, name);
295
296
const entries = Object.entries(value ?? {});
···
298
299
return (
300
<FormItem className={Margins.marginTop20} title={displayName}>
301
+
{description && <FormText className={Margins.marginBottom4}>{markdownify(description)}</FormText>}
302
<Flex direction={Flex.Direction.VERTICAL}>
303
{entries.map(([key, val], i) => (
304
// FIXME: stylesheets
···
372
);
373
374
if (Component == null) {
375
return (
376
<Text variant="text-md/normal">{`Custom setting "${displayName}" is missing a component. Perhaps the extension is not installed?`}</Text>
377
);
378
}
379
380
return (
381
+
<ErrorBoundary>
382
+
<Component value={value} setValue={(value) => MoonbaseSettingsStore.setExtensionConfig(ext.id, name, value)} />
383
+
</ErrorBoundary>
384
);
385
}
386
+22
-15
packages/core-extensions/src/moonbase/webpackModules/ui/index.tsx
+22
-15
packages/core-extensions/src/moonbase/webpackModules/ui/index.tsx
···
1
import React from "@moonlight-mod/wp/react";
2
-
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
3
import { Text, TabBar } from "@moonlight-mod/wp/discord/components/common/index";
4
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
5
import { UserSettingsModalStore } from "@moonlight-mod/wp/common_stores";
6
7
import ExtensionsPage from "./extensions";
8
import ConfigPage from "./config";
9
import Update from "./update";
10
-
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
11
import RestartAdviceMessage from "./RestartAdvice";
12
-
13
-
const { Divider } = spacepack.findByCode(".forumOrHome]:")[0].exports.Z;
14
-
const TitleBarClasses = spacepack.findByCode("iconWrapper:", "children:")[0].exports;
15
-
const TabBarClasses = spacepack.findByCode("nowPlayingColumn:")[0].exports;
16
-
const { setSection, clearSubsection } = spacepack.findByCode(':"USER_SETTINGS_MODAL_SET_SECTION"')[0].exports.Z;
17
-
const Margins = spacepack.require("discord/styles/shared/Margins.css");
18
19
export const pages: {
20
id: string;
···
30
id: "config",
31
name: "Config",
32
element: ConfigPage
33
}
34
];
35
···
37
const subsection = useStateFromStores([UserSettingsModalStore], () => UserSettingsModalStore.getSubsection() ?? 0);
38
const setSubsection = React.useCallback(
39
(to: string) => {
40
-
if (subsection !== to) setSection("moonbase", to);
41
},
42
[subsection]
43
);
···
45
React.useEffect(
46
() => () => {
47
// Normally there's an onSettingsClose prop you can set but we don't expose it and I don't care enough to add support for it right now
48
-
clearSubsection("moonbase");
49
-
MoonbaseSettingsStore.showOnlyUpdateable = false;
50
},
51
[]
52
);
53
54
return (
55
<>
56
-
<div className={`${TitleBarClasses.children} ${Margins.marginBottom20}`}>
57
-
<Text className={TitleBarClasses.titleWrapper} variant="heading-lg/semibold" tag="h2">
58
Moonbase
59
</Text>
60
<Divider />
61
-
<TabBar selectedItem={subsection} onItemSelect={setSubsection} type="top-pill" className={TabBarClasses.tabBar}>
62
{pages.map((page, i) => (
63
-
<TabBar.Item key={page.id} id={i} className={TabBarClasses.item}>
64
{page.name}
65
</TabBar.Item>
66
))}
···
1
import React from "@moonlight-mod/wp/react";
2
import { Text, TabBar } from "@moonlight-mod/wp/discord/components/common/index";
3
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
4
import { UserSettingsModalStore } from "@moonlight-mod/wp/common_stores";
5
6
import ExtensionsPage from "./extensions";
7
import ConfigPage from "./config";
8
+
import AboutPage from "./about";
9
import Update from "./update";
10
import RestartAdviceMessage from "./RestartAdvice";
11
+
import { Divider } from "@moonlight-mod/wp/discord/components/common/BaseHeaderBar";
12
+
import HeaderBarClasses from "@moonlight-mod/wp/discord/components/common/HeaderBar.css";
13
+
import PeoplePageClasses from "@moonlight-mod/wp/discord/modules/people/web/PeoplePage.css";
14
+
import UserSettingsModalActionCreators from "@moonlight-mod/wp/discord/actions/UserSettingsModalActionCreators";
15
+
import Margins from "@moonlight-mod/wp/discord/styles/shared/Margins.css";
16
17
export const pages: {
18
id: string;
···
28
id: "config",
29
name: "Config",
30
element: ConfigPage
31
+
},
32
+
{
33
+
id: "about",
34
+
name: "About",
35
+
element: AboutPage
36
}
37
];
38
···
40
const subsection = useStateFromStores([UserSettingsModalStore], () => UserSettingsModalStore.getSubsection() ?? 0);
41
const setSubsection = React.useCallback(
42
(to: string) => {
43
+
if (subsection !== to) UserSettingsModalActionCreators.setSection("moonbase", to);
44
},
45
[subsection]
46
);
···
48
React.useEffect(
49
() => () => {
50
// Normally there's an onSettingsClose prop you can set but we don't expose it and I don't care enough to add support for it right now
51
+
UserSettingsModalActionCreators.clearSubsection("moonbase");
52
},
53
[]
54
);
55
56
return (
57
<>
58
+
<div className={`${HeaderBarClasses.children} ${Margins.marginBottom20}`}>
59
+
<Text className={HeaderBarClasses.titleWrapper} variant="heading-lg/semibold" tag="h2">
60
Moonbase
61
</Text>
62
<Divider />
63
+
<TabBar
64
+
selectedItem={subsection}
65
+
onItemSelect={setSubsection}
66
+
type="top-pill"
67
+
className={PeoplePageClasses.tabBar}
68
+
>
69
{pages.map((page, i) => (
70
+
<TabBar.Item key={page.id} id={i} className={PeoplePageClasses.item}>
71
{page.name}
72
</TabBar.Item>
73
))}
+77
-15
packages/core-extensions/src/moonbase/webpackModules/ui/update.tsx
+77
-15
packages/core-extensions/src/moonbase/webpackModules/ui/update.tsx
···
1
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
2
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
3
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
4
import React from "@moonlight-mod/wp/react";
5
import { UpdateState } from "../../types";
6
import HelpMessage from "./HelpMessage";
7
-
8
-
const { ThemeDarkIcon, Button } = Components;
9
-
10
-
const logger = moonlight.getLogger("moonbase/ui/update");
11
12
const strings: Record<UpdateState, string> = {
13
[UpdateState.Ready]: "A new version of moonlight is available.",
···
16
[UpdateState.Failed]: "Failed to update moonlight. Please use the installer instead."
17
};
18
19
export default function Update() {
20
-
const [state, setState] = React.useState(UpdateState.Ready);
21
-
const newVersion = useStateFromStores([MoonbaseSettingsStore], () => MoonbaseSettingsStore.newVersion);
22
23
if (newVersion == null) return null;
24
25
return (
26
<HelpMessage text={strings[state]} className="moonbase-update-section" icon={ThemeDarkIcon}>
27
<div className="moonbase-help-message-buttons">
28
{state === UpdateState.Installed && (
29
<Button
30
look={Button.Looks.OUTLINED}
···
44
size={Button.Sizes.TINY}
45
disabled={state !== UpdateState.Ready}
46
onClick={() => {
47
-
setState(UpdateState.Working);
48
-
49
-
MoonbaseSettingsStore.updateMoonlight()
50
-
.then(() => setState(UpdateState.Installed))
51
-
.catch((e) => {
52
-
logger.error(e);
53
-
setState(UpdateState.Failed);
54
-
});
55
}}
56
>
57
Update
···
1
import { useStateFromStores } from "@moonlight-mod/wp/discord/packages/flux";
2
import { MoonbaseSettingsStore } from "@moonlight-mod/wp/moonbase_stores";
3
import React from "@moonlight-mod/wp/react";
4
import { UpdateState } from "../../types";
5
import HelpMessage from "./HelpMessage";
6
+
import { MoonlightBranch } from "@moonlight-mod/types";
7
+
import MarkupUtils from "@moonlight-mod/wp/discord/modules/markup/MarkupUtils";
8
+
import Flex from "@moonlight-mod/wp/discord/uikit/Flex";
9
+
import {
10
+
Button,
11
+
Text,
12
+
ModalRoot,
13
+
ModalSize,
14
+
ModalContent,
15
+
ModalHeader,
16
+
Heading,
17
+
ModalCloseButton,
18
+
openModal
19
+
} from "@moonlight-mod/wp/discord/components/common/index";
20
+
import MarkupClasses from "@moonlight-mod/wp/discord/modules/messages/web/Markup.css";
21
+
import ThemeDarkIcon from "@moonlight-mod/wp/moonbase_ThemeDarkIcon";
22
23
const strings: Record<UpdateState, string> = {
24
[UpdateState.Ready]: "A new version of moonlight is available.",
···
27
[UpdateState.Failed]: "Failed to update moonlight. Please use the installer instead."
28
};
29
30
+
function MoonlightChangelog({
31
+
changelog,
32
+
version,
33
+
transitionState,
34
+
onClose
35
+
}: {
36
+
changelog: string;
37
+
version: string;
38
+
transitionState: number | null;
39
+
onClose: () => void;
40
+
}) {
41
+
return (
42
+
<ModalRoot transitionState={transitionState} size={ModalSize.DYNAMIC}>
43
+
<ModalHeader>
44
+
<Flex.Child grow={1} shrink={1}>
45
+
<Heading variant="heading-lg/semibold">moonlight</Heading>
46
+
<Text variant="text-xs/normal">{version}</Text>
47
+
</Flex.Child>
48
+
49
+
<Flex.Child grow={0}>
50
+
<ModalCloseButton onClick={onClose} />
51
+
</Flex.Child>
52
+
</ModalHeader>
53
+
54
+
<ModalContent>
55
+
<Text variant="text-md/normal" className={MarkupClasses.markup} style={{ padding: "1rem" }}>
56
+
{MarkupUtils.parse(changelog, true, {
57
+
allowHeading: true,
58
+
allowList: true,
59
+
allowLinks: true
60
+
})}
61
+
</Text>
62
+
</ModalContent>
63
+
</ModalRoot>
64
+
);
65
+
}
66
+
67
export default function Update() {
68
+
const [newVersion, state] = useStateFromStores([MoonbaseSettingsStore], () => [
69
+
MoonbaseSettingsStore.newVersion,
70
+
MoonbaseSettingsStore.updateState
71
+
]);
72
73
if (newVersion == null) return null;
74
75
return (
76
<HelpMessage text={strings[state]} className="moonbase-update-section" icon={ThemeDarkIcon}>
77
<div className="moonbase-help-message-buttons">
78
+
{moonlight.branch === MoonlightBranch.STABLE && (
79
+
<Button
80
+
look={Button.Looks.OUTLINED}
81
+
color={Button.Colors.CUSTOM}
82
+
size={Button.Sizes.TINY}
83
+
onClick={() => {
84
+
fetch(`https://raw.githubusercontent.com/moonlight-mod/moonlight/refs/tags/${newVersion}/CHANGELOG.md`)
85
+
.then((r) => r.text())
86
+
.then((changelog) =>
87
+
openModal((modalProps) => {
88
+
return <MoonlightChangelog {...modalProps} changelog={changelog} version={newVersion} />;
89
+
})
90
+
);
91
+
}}
92
+
>
93
+
View changelog
94
+
</Button>
95
+
)}
96
+
97
{state === UpdateState.Installed && (
98
<Button
99
look={Button.Looks.OUTLINED}
···
113
size={Button.Sizes.TINY}
114
disabled={state !== UpdateState.Ready}
115
onClick={() => {
116
+
MoonbaseSettingsStore.updateMoonlight();
117
}}
118
>
119
Update
+3
-6
packages/core-extensions/src/moonbase/webpackModules/updates.tsx
+3
-6
packages/core-extensions/src/moonbase/webpackModules/updates.tsx
···
3
import Notices from "@moonlight-mod/wp/notices_notices";
4
import { MoonlightBranch } from "@moonlight-mod/types";
5
import React from "@moonlight-mod/wp/react";
6
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
7
-
8
-
const { ThemeDarkIcon } = Components;
9
10
function plural(str: string, num: number) {
11
return `${str}${num > 1 ? "s" : ""}`;
···
59
{
60
name: "Open Moonbase",
61
onClick: () => {
62
-
const { open } = spacepack.findByCode(':"USER_SETTINGS_MODAL_SET_SECTION"')[0].exports.Z;
63
if (MoonbaseSettingsStore.getExtensionConfigRaw<boolean>("moonbase", "sections", false)) {
64
open("moonbase-extensions");
65
} else {
66
-
MoonbaseSettingsStore.showOnlyUpdateable = true;
67
-
open("moonbase", 0);
68
}
69
return true;
70
}
···
3
import Notices from "@moonlight-mod/wp/notices_notices";
4
import { MoonlightBranch } from "@moonlight-mod/types";
5
import React from "@moonlight-mod/wp/react";
6
+
import ThemeDarkIcon from "@moonlight-mod/wp/moonbase_ThemeDarkIcon";
7
8
function plural(str: string, num: number) {
9
return `${str}${num > 1 ? "s" : ""}`;
···
57
{
58
name: "Open Moonbase",
59
onClick: () => {
60
+
const { open } = spacepack.require("discord/actions/UserSettingsModalActionCreators").default;
61
if (MoonbaseSettingsStore.getExtensionConfigRaw<boolean>("moonbase", "sections", false)) {
62
open("moonbase-extensions");
63
} else {
64
+
open("moonbase", "0");
65
}
66
return true;
67
}
+5
packages/core-extensions/src/moonbase/wp.d.ts
+5
packages/core-extensions/src/moonbase/wp.d.ts
···
5
declare module "@moonlight-mod/wp/moonbase_stores" {
6
export * from "core-extensions/src/moonbase/webpackModules/stores";
7
}
8
+
9
+
declare module "@moonlight-mod/wp/moonbase_ThemeDarkIcon" {
10
+
import ThemeDarkIcon from "core-extensions/src/moonbase/webpackModules/ThemeDarkIcon";
11
+
export = ThemeDarkIcon;
12
+
}
+141
-1
packages/core-extensions/src/nativeFixes/host.ts
+141
-1
packages/core-extensions/src/nativeFixes/host.ts
···
1
import { app, nativeTheme } from "electron";
2
3
const enabledFeatures = app.commandLine.getSwitchValue("enable-features").split(",");
4
5
moonlightHost.events.on("window-created", function (browserWindow) {
···
22
23
// already added on Windows, but not on other operating systems
24
app.commandLine.appendSwitch("disable-background-timer-throttling");
25
}
26
27
if (process.platform === "linux") {
···
32
if (moonlightHost.getConfigOption<boolean>("nativeFixes", "linuxSpeechDispatcher") ?? true) {
33
app.commandLine.appendSwitch("enable-speech-dispatcher");
34
}
35
}
36
37
// NOTE: Only tested if this appears on Windows, it should appear on all when
38
// hardware acceleration is disabled
39
const noAccel = app.commandLine.hasSwitch("disable-gpu-compositing");
40
if ((moonlightHost.getConfigOption<boolean>("nativeFixes", "vaapi") ?? true) && !noAccel) {
41
-
if (process.platform === "linux")
42
// These will eventually be renamed https://source.chromium.org/chromium/chromium/src/+/5482210941a94d70406b8da962426e4faca7fce4
43
enabledFeatures.push("VaapiVideoEncoder", "VaapiVideoDecoder", "VaapiVideoDecodeLinuxGL");
44
}
45
46
app.commandLine.appendSwitch("enable-features", [...new Set(enabledFeatures)].join(","));
···
1
import { app, nativeTheme } from "electron";
2
+
import * as path from "node:path";
3
+
import * as fs from "node:fs/promises";
4
+
import * as fsSync from "node:fs";
5
+
import { parseTarGzip } from "nanotar";
6
7
+
const logger = moonlightHost.getLogger("nativeFixes/host");
8
const enabledFeatures = app.commandLine.getSwitchValue("enable-features").split(",");
9
10
moonlightHost.events.on("window-created", function (browserWindow) {
···
27
28
// already added on Windows, but not on other operating systems
29
app.commandLine.appendSwitch("disable-background-timer-throttling");
30
+
}
31
+
32
+
if (moonlightHost.getConfigOption<boolean>("nativeFixes", "vulkan") ?? false) {
33
+
enabledFeatures.push("Vulkan", "DefaultANGLEVulkan", "VulkanFromANGLE");
34
}
35
36
if (process.platform === "linux") {
···
41
if (moonlightHost.getConfigOption<boolean>("nativeFixes", "linuxSpeechDispatcher") ?? true) {
42
app.commandLine.appendSwitch("enable-speech-dispatcher");
43
}
44
+
45
+
if (moonlightHost.getConfigOption<boolean>("nativeFixes", "linuxHevcSupport") ?? true) {
46
+
enabledFeatures.push("PlatformHEVCDecoderSupport");
47
+
}
48
}
49
50
// NOTE: Only tested if this appears on Windows, it should appear on all when
51
// hardware acceleration is disabled
52
const noAccel = app.commandLine.hasSwitch("disable-gpu-compositing");
53
if ((moonlightHost.getConfigOption<boolean>("nativeFixes", "vaapi") ?? true) && !noAccel) {
54
+
if (process.platform === "linux") {
55
// These will eventually be renamed https://source.chromium.org/chromium/chromium/src/+/5482210941a94d70406b8da962426e4faca7fce4
56
enabledFeatures.push("VaapiVideoEncoder", "VaapiVideoDecoder", "VaapiVideoDecodeLinuxGL");
57
+
58
+
if (moonlightHost.getConfigOption<boolean>("nativeFixes", "vaapiIgnoreDriverChecks") ?? false)
59
+
enabledFeatures.push("VaapiIgnoreDriverChecks");
60
+
}
61
}
62
63
app.commandLine.appendSwitch("enable-features", [...new Set(enabledFeatures)].join(","));
64
+
65
+
if (process.platform === "linux" && moonlightHost.getConfigOption<boolean>("nativeFixes", "linuxUpdater")) {
66
+
const exePath = app.getPath("exe");
67
+
const appName = path.basename(exePath);
68
+
const targetDir = path.dirname(exePath);
69
+
const { releaseChannel }: { releaseChannel: string } = JSON.parse(
70
+
fsSync.readFileSync(path.join(targetDir, "resources", "build_info.json"), "utf8")
71
+
);
72
+
73
+
const updaterModule = require(path.join(moonlightHost.asarPath, "app_bootstrap", "hostUpdater.js"));
74
+
const updater = updaterModule.constructor;
75
+
76
+
async function doUpdate(cb: (percent: number) => void) {
77
+
logger.debug("Extracting to", targetDir);
78
+
79
+
const exists = (path: string) =>
80
+
fs
81
+
.stat(path)
82
+
.then(() => true)
83
+
.catch(() => false);
84
+
85
+
const url = `https://discord.com/api/download/${releaseChannel}?platform=linux&format=tar.gz`;
86
+
const resp = await fetch(url, {
87
+
cache: "no-store"
88
+
});
89
+
90
+
const reader = resp.body!.getReader();
91
+
const contentLength = parseInt(resp.headers.get("Content-Length") ?? "0");
92
+
logger.info(`Expecting ${contentLength} bytes for the update`);
93
+
const bytes = new Uint8Array(contentLength);
94
+
let pos = 0;
95
+
let lastPercent = 0;
96
+
97
+
while (true) {
98
+
const { done, value } = await reader.read();
99
+
if (done) {
100
+
break;
101
+
} else {
102
+
bytes.set(value, pos);
103
+
pos += value.length;
104
+
105
+
const newPercent = Math.floor((pos / contentLength) * 100);
106
+
if (lastPercent !== newPercent) {
107
+
lastPercent = newPercent;
108
+
cb(newPercent);
109
+
}
110
+
}
111
+
}
112
+
113
+
const files = await parseTarGzip(bytes);
114
+
115
+
for (const file of files) {
116
+
if (!file.data) continue;
117
+
// @ts-expect-error What do you mean their own types are wrong
118
+
if (file.type !== "file") continue;
119
+
120
+
// Discord update files are inside of a main "Discord(PTB|Canary)" folder
121
+
const filePath = file.name.replace(`${appName}/`, "");
122
+
logger.info("Extracting", filePath);
123
+
124
+
let targetFilePath = path.join(targetDir, filePath);
125
+
if (filePath === "resources/app.asar") {
126
+
// You tried
127
+
targetFilePath = path.join(targetDir, "resources", "_app.asar");
128
+
} else if (filePath === appName || filePath === "chrome_crashpad_handler") {
129
+
// Can't write over the executable? Just move it! 4head
130
+
if (await exists(targetFilePath)) {
131
+
await fs.rename(targetFilePath, targetFilePath + ".bak");
132
+
await fs.unlink(targetFilePath + ".bak");
133
+
}
134
+
}
135
+
const targetFileDir = path.dirname(targetFilePath);
136
+
137
+
if (!(await exists(targetFileDir))) await fs.mkdir(targetFileDir, { recursive: true });
138
+
await fs.writeFile(targetFilePath, file.data);
139
+
140
+
const mode = file.attrs?.mode;
141
+
if (mode != null) {
142
+
// Not sure why this slice is needed
143
+
await fs.chmod(targetFilePath, mode.slice(-3));
144
+
}
145
+
}
146
+
147
+
logger.debug("Done updating");
148
+
}
149
+
150
+
const realEmit = updater.prototype.emit;
151
+
updater.prototype.emit = function (event: string, ...args: any[]) {
152
+
// Arrow functions don't bind `this` :D
153
+
const call = (event: string, ...args: any[]) => realEmit.call(this, event, ...args);
154
+
155
+
if (event === "update-manually") {
156
+
const latestVerStr: string = args[0];
157
+
logger.debug("update-manually called, intercepting", latestVerStr);
158
+
call("update-available");
159
+
160
+
(async () => {
161
+
try {
162
+
await doUpdate((progress) => {
163
+
call("update-progress", progress);
164
+
});
165
+
// Copied from the win32 updater
166
+
this.updateVersion = latestVerStr;
167
+
call(
168
+
"update-downloaded",
169
+
{},
170
+
releaseChannel,
171
+
latestVerStr,
172
+
new Date(),
173
+
this.updateUrl,
174
+
this.quitAndInstall.bind(this)
175
+
);
176
+
} catch (e) {
177
+
logger.error("Error updating", e);
178
+
}
179
+
})();
180
+
181
+
return this;
182
+
} else {
183
+
return realEmit.call(this, event, ...args);
184
+
}
185
+
};
186
+
}
+29
-1
packages/core-extensions/src/nativeFixes/manifest.json
+29
-1
packages/core-extensions/src/nativeFixes/manifest.json
···
4
"meta": {
5
"name": "Native Fixes",
6
"tagline": "Various configurable fixes for Discord and Electron",
7
-
"authors": ["Cynosphere", "adryd"],
8
"tags": ["fixes"]
9
},
10
"environment": "desktop",
···
23
"type": "boolean",
24
"default": true
25
},
26
"linuxAutoscroll": {
27
"advice": "restart",
28
"displayName": "Enable middle click autoscroll on Linux",
···
41
"advice": "restart",
42
"displayName": "Enable VAAPI features on Linux",
43
"description": "Provides hardware accelerated video encode and decode. Has no effect on other operating systems",
44
"type": "boolean",
45
"default": true
46
}
···
4
"meta": {
5
"name": "Native Fixes",
6
"tagline": "Various configurable fixes for Discord and Electron",
7
+
"authors": ["Cynosphere", "adryd", "NotNite"],
8
"tags": ["fixes"]
9
},
10
"environment": "desktop",
···
23
"type": "boolean",
24
"default": true
25
},
26
+
"vulkan": {
27
+
"advice": "restart",
28
+
"displayName": "Enable Vulkan renderer",
29
+
"description": "Uses the Vulkan backend for rendering",
30
+
"type": "boolean",
31
+
"default": false
32
+
},
33
"linuxAutoscroll": {
34
"advice": "restart",
35
"displayName": "Enable middle click autoscroll on Linux",
···
48
"advice": "restart",
49
"displayName": "Enable VAAPI features on Linux",
50
"description": "Provides hardware accelerated video encode and decode. Has no effect on other operating systems",
51
+
"type": "boolean",
52
+
"default": true
53
+
},
54
+
"vaapiIgnoreDriverChecks": {
55
+
"advice": "restart",
56
+
"displayName": "Ignore VAAPI driver checks on Linux",
57
+
"description": "Forces hardware video acceleration on some graphics drivers at the cost of stability. Has no effect on other operating systems",
58
+
"type": "boolean",
59
+
"default": false
60
+
},
61
+
"linuxUpdater": {
62
+
"advice": "restart",
63
+
"displayName": "Linux Updater",
64
+
"description": "Actually implements updating Discord on Linux. Has no effect on other operating systems",
65
+
"type": "boolean",
66
+
"default": false
67
+
},
68
+
"linuxHevcSupport": {
69
+
"advice": "restart",
70
+
"displayName": "HEVC support on Linux",
71
+
"description": "You might also need to enable Vulkan renderer. Has no effect on other operating systems",
72
"type": "boolean",
73
"default": true
74
}
+3
-3
packages/core-extensions/src/noHideToken/index.ts
+3
-3
packages/core-extensions/src/noHideToken/index.ts
+3
-3
packages/core-extensions/src/noTrack/index.ts
+3
-3
packages/core-extensions/src/noTrack/index.ts
+3
-1
packages/core-extensions/src/noTrack/manifest.json
+3
-1
packages/core-extensions/src/noTrack/manifest.json
+3
-6
packages/core-extensions/src/notices/webpackModules/component.tsx
+3
-6
packages/core-extensions/src/notices/webpackModules/component.tsx
···
1
import React from "@moonlight-mod/wp/react";
2
import Dispatcher from "@moonlight-mod/wp/discord/Dispatcher";
3
-
import * as Components from "@moonlight-mod/wp/discord/components/common/index";
4
import { useStateFromStoresObject } from "@moonlight-mod/wp/discord/packages/flux";
5
import NoticesStore from "@moonlight-mod/wp/notices_notices";
6
-
import type { Notice } from "@moonlight-mod/types/coreExtensions/notices";
7
8
-
// FIXME: types
9
-
const { Notice, NoticeCloseButton, PrimaryCTANoticeButton } = Components;
10
-
11
-
function popAndDismiss(notice: Notice) {
12
NoticesStore.popNotice();
13
if (notice?.onDismiss) {
14
notice.onDismiss();
···
1
import React from "@moonlight-mod/wp/react";
2
import Dispatcher from "@moonlight-mod/wp/discord/Dispatcher";
3
+
import { Notice, NoticeCloseButton, PrimaryCTANoticeButton } from "@moonlight-mod/wp/discord/components/common/index";
4
import { useStateFromStoresObject } from "@moonlight-mod/wp/discord/packages/flux";
5
import NoticesStore from "@moonlight-mod/wp/notices_notices";
6
+
import type { Notice as NoticeType } from "@moonlight-mod/types/coreExtensions/notices";
7
8
+
function popAndDismiss(notice: NoticeType) {
9
NoticesStore.popNotice();
10
if (notice?.onDismiss) {
11
notice.onDismiss();
+22
-2
packages/core-extensions/src/quietLoggers/index.ts
+22
-2
packages/core-extensions/src/quietLoggers/index.ts
···
3
const notXssDefensesOnly = () =>
4
(moonlight.getConfigOption<boolean>("quietLoggers", "xssDefensesOnly") ?? false) === false;
5
6
// These patches MUST run before the simple patches, these are to remove loggers
7
// that end up causing syntax errors by the normal patch
8
const loggerFixes: Patch[] = [
···
28
// Patches to simply remove a logger call
29
const stubPatches = [
30
// "sh" is not a valid locale.
31
-
["is not a valid locale", /(.)\.error\(""\.concat\((.)," is not a valid locale\."\)\)/g],
32
['"[BUILD INFO] Release Channel: "', /new .{1,2}\.Z\(\)\.log\("\[BUILD INFO\] Release Channel: ".+?\)\),/],
33
['.APP_NATIVE_CRASH,"Storage"', /console\.log\("AppCrashedFatalReport lastCrash:",.,.\);/],
34
-
['.APP_NATIVE_CRASH,"Storage"', 'console.log("AppCrashedFatalReport: getLastCrash not supported.");'],
35
['"[NATIVE INFO] ', /new .{1,2}\.Z\(\)\.log\("\[NATIVE INFO] .+?\)\);/],
36
['"Spellchecker"', /.\.info\("Switching to ".+?"\(unavailable\)"\);?/g],
37
['throw Error("Messages are still loading.");', /console\.warn\("Unsupported Locale",.\),/],
···
57
match: /\(null!=.{1,2}&&"0\.0\.0"===.{1,2}\.remoteApp\.getVersion\(\)\)/,
58
replacement: "(true)"
59
}
60
},
61
...loggerFixes,
62
...stubPatches.map((patch) => ({
···
3
const notXssDefensesOnly = () =>
4
(moonlight.getConfigOption<boolean>("quietLoggers", "xssDefensesOnly") ?? false) === false;
5
6
+
const silenceDiscordLogger = moonlight.getConfigOption<boolean>("quietLoggers", "silenceDiscordLogger") ?? false;
7
+
8
// These patches MUST run before the simple patches, these are to remove loggers
9
// that end up causing syntax errors by the normal patch
10
const loggerFixes: Patch[] = [
···
30
// Patches to simply remove a logger call
31
const stubPatches = [
32
// "sh" is not a valid locale.
33
+
["is not a valid locale", /void (.)\.error\(""\.concat\((.)," is not a valid locale\."\)\)/g],
34
['"[BUILD INFO] Release Channel: "', /new .{1,2}\.Z\(\)\.log\("\[BUILD INFO\] Release Channel: ".+?\)\),/],
35
['.APP_NATIVE_CRASH,"Storage"', /console\.log\("AppCrashedFatalReport lastCrash:",.,.\);/],
36
+
['.APP_NATIVE_CRASH,"Storage"', 'void console.log("AppCrashedFatalReport: getLastCrash not supported.")'],
37
['"[NATIVE INFO] ', /new .{1,2}\.Z\(\)\.log\("\[NATIVE INFO] .+?\)\);/],
38
['"Spellchecker"', /.\.info\("Switching to ".+?"\(unavailable\)"\);?/g],
39
['throw Error("Messages are still loading.");', /console\.warn\("Unsupported Locale",.\),/],
···
59
match: /\(null!=.{1,2}&&"0\.0\.0"===.{1,2}\.remoteApp\.getVersion\(\)\)/,
60
replacement: "(true)"
61
}
62
+
},
63
+
// Highlight.js deprecation warnings
64
+
{
65
+
find: "Deprecated as of",
66
+
replace: {
67
+
match: /console\./g,
68
+
replacement: "false&&console."
69
+
},
70
+
prerequisite: notXssDefensesOnly
71
+
},
72
+
// Discord's logger
73
+
{
74
+
find: "ฮฃ:",
75
+
replace: {
76
+
match: "for",
77
+
replacement: "return;for"
78
+
},
79
+
prerequisite: () => silenceDiscordLogger && notXssDefensesOnly()
80
},
81
...loggerFixes,
82
...stubPatches.map((patch) => ({
+7
packages/core-extensions/src/quietLoggers/manifest.json
+7
packages/core-extensions/src/quietLoggers/manifest.json
···
15
"description": "Only disable self XSS prevention log",
16
"type": "boolean",
17
"default": false
18
+
},
19
+
"silenceDiscordLogger": {
20
+
"advice": "reload",
21
+
"displayName": "Silence Discord logger",
22
+
"description": "Hides all messages from Discord's logger (the logs that start with purple text in brackets)",
23
+
"type": "boolean",
24
+
"default": false
25
}
26
}
27
}
+2
-1
packages/core-extensions/src/rocketship/manifest.json
+2
-1
packages/core-extensions/src/rocketship/manifest.json
···
7
"name": "Rocketship",
8
"tagline": "Adds new features when using rocketship",
9
"description": "**This extension only works on Linux when using rocketship:**\nhttps://github.com/moonlight-mod/rocketship\n\nAdds new features to the Discord Linux client with rocketship, such as a better screensharing experience.",
10
-
"authors": ["NotNite", "Cynosphere", "adryd"]
11
}
12
}
···
7
"name": "Rocketship",
8
"tagline": "Adds new features when using rocketship",
9
"description": "**This extension only works on Linux when using rocketship:**\nhttps://github.com/moonlight-mod/rocketship\n\nAdds new features to the Discord Linux client with rocketship, such as a better screensharing experience.",
10
+
"authors": ["NotNite", "Cynosphere", "adryd"],
11
+
"deprecated": true
12
}
13
}
+1
-1
packages/core-extensions/src/settings/index.ts
+1
-1
packages/core-extensions/src/settings/index.ts
+8
-2
packages/core-extensions/src/settings/webpackModules/settings.ts
+8
-2
packages/core-extensions/src/settings/webpackModules/settings.ts
···
1
import { SettingsSection, Settings as SettingsType } from "@moonlight-mod/types/coreExtensions/settings";
2
3
export const Settings: SettingsType = {
4
ourSections: [],
5
sectionNames: [],
6
sectionMenuItems: {},
7
8
-
addSection: (section, label, element, color = null, pos, notice) => {
9
const data: SettingsSection = {
10
section,
11
label,
12
color,
13
element,
14
pos: pos ?? -4,
15
-
notice: notice
16
};
17
18
Settings.ourSections.push(data);
···
43
44
_mutateSections: (sections) => {
45
for (const section of Settings.ourSections) {
46
sections.splice(section.pos < 0 ? sections.length + section.pos : section.pos, 0, section);
47
}
48
···
1
import { SettingsSection, Settings as SettingsType } from "@moonlight-mod/types/coreExtensions/settings";
2
+
import UserSettingsModalActionCreators from "@moonlight-mod/wp/discord/actions/UserSettingsModalActionCreators";
3
4
export const Settings: SettingsType = {
5
ourSections: [],
6
sectionNames: [],
7
sectionMenuItems: {},
8
9
+
addSection: (section, label, element, color = null, pos, notice, onClick) => {
10
const data: SettingsSection = {
11
section,
12
label,
13
color,
14
element,
15
pos: pos ?? -4,
16
+
notice: notice,
17
+
onClick: onClick ?? (() => UserSettingsModalActionCreators.open(section))
18
};
19
20
Settings.ourSections.push(data);
···
45
46
_mutateSections: (sections) => {
47
for (const section of Settings.ourSections) {
48
+
// Discord's `pos` only supports numbers, so lets call the function to get the position.
49
+
if (typeof section.pos === "function") {
50
+
section.pos = section.pos(sections);
51
+
}
52
sections.splice(section.pos < 0 ? sections.length + section.pos : section.pos, 0, section);
53
}
54
+73
-16
packages/core-extensions/src/spacepack/webpackModules/spacepack.ts
+73
-16
packages/core-extensions/src/spacepack/webpackModules/spacepack.ts
···
37
"module",
38
"exports",
39
"require",
40
-
`(${funcStr}).apply(this, arguments)\n` + `//# sourceURL=Webpack-Module-${module}`
41
) as WebpackModuleFunc;
42
},
43
44
findByCode: (...args: (string | RegExp)[]) => {
45
-
return Object.entries(modules)
46
.filter(([id, mod]) => !args.some((item) => !testFind(mod.toString(), processFind(item))))
47
.map(([id]) => {
48
//if (!(id in cache)) require(id);
···
52
try {
53
exports = require(id);
54
} catch (e) {
55
-
logger.error(`Error requiring module "${id}": `, e);
56
}
57
58
return {
···
61
};
62
})
63
.filter((item) => item !== null);
64
},
65
66
findByExports: (...args: string[]) => {
···
84
},
85
86
findObjectFromKey: (exports: Record<string, any>, key: string) => {
87
let subKey;
88
if (key.indexOf(".") > -1) {
89
const splitKey = key.split(".");
···
94
const obj = exports[exportKey];
95
if (obj && obj[key] !== undefined) {
96
if (subKey) {
97
-
if (obj[key][subKey]) return obj;
98
} else {
99
-
return obj;
100
}
101
}
102
}
103
-
return null;
104
},
105
106
findObjectFromValue: (exports: Record<string, any>, value: any) => {
107
for (const exportKey in exports) {
108
const obj = exports[exportKey];
109
// eslint-disable-next-line eqeqeq
110
-
if (obj == value) return obj;
111
for (const subKey in obj) {
112
// eslint-disable-next-line eqeqeq
113
if (obj && obj[subKey] == value) {
114
-
return obj;
115
}
116
}
117
}
118
-
return null;
119
},
120
121
findObjectFromKeyValuePair: (exports: Record<string, any>, key: string, value: any) => {
122
for (const exportKey in exports) {
123
const obj = exports[exportKey];
124
// eslint-disable-next-line eqeqeq
125
if (obj && obj[key] == value) {
126
-
return obj;
127
}
128
}
129
return null;
130
},
131
132
findFunctionByStrings: (exports: Record<string, any>, ...strings: (string | RegExp)[]) => {
133
-
return (
134
Object.entries(exports).filter(
135
([index, func]) =>
136
typeof func === "function" && !strings.some((query) => !testFind(func.toString(), processFind(query)))
137
-
)?.[0]?.[1] ?? null
138
-
);
139
},
140
141
lazyLoad: (find: string | RegExp | (string | RegExp)[], chunk: RegExp, module: RegExp) => {
142
const mod = Array.isArray(find) ? spacepack.findByCode(...find) : spacepack.findByCode(find);
143
-
if (mod.length < 1) return Promise.reject("Module find failed");
144
145
const findId = mod[0].id;
146
const findCode = webpackRequire.m[findId].toString().replace(/\n/g, "");
···
153
if (match) chunkIds = [...match[0].matchAll(/"(\d+)"/g)].map(([, id]) => id);
154
}
155
156
-
if (!chunkIds || chunkIds.length === 0) return Promise.reject("Chunk ID match failed");
157
158
const moduleId = findCode.match(module)?.[1];
159
-
if (!moduleId) return Promise.reject("Module ID match failed");
160
161
return Promise.all(chunkIds.map((c) => webpackRequire.e(c))).then(() => webpackRequire(moduleId));
162
},
···
37
"module",
38
"exports",
39
"require",
40
+
`(${funcStr}).apply(this, arguments)\n` + `//# sourceURL=Webpack-Module/${module.slice(0, 3)}/${module}`
41
) as WebpackModuleFunc;
42
},
43
44
findByCode: (...args: (string | RegExp)[]) => {
45
+
const ret = Object.entries(modules)
46
.filter(([id, mod]) => !args.some((item) => !testFind(mod.toString(), processFind(item))))
47
.map(([id]) => {
48
//if (!(id in cache)) require(id);
···
52
try {
53
exports = require(id);
54
} catch (e) {
55
+
logger.error(`findByCode: Error requiring module "${id}": `, args, e);
56
}
57
58
return {
···
61
};
62
})
63
.filter((item) => item !== null);
64
+
65
+
if (ret.length === 0) {
66
+
logger.warn("findByCode: Got zero results for", args, new Error().stack!.substring(5));
67
+
}
68
+
69
+
return ret;
70
},
71
72
findByExports: (...args: string[]) => {
···
90
},
91
92
findObjectFromKey: (exports: Record<string, any>, key: string) => {
93
+
let ret = null;
94
let subKey;
95
if (key.indexOf(".") > -1) {
96
const splitKey = key.split(".");
···
101
const obj = exports[exportKey];
102
if (obj && obj[key] !== undefined) {
103
if (subKey) {
104
+
if (obj[key][subKey]) {
105
+
ret = obj;
106
+
break;
107
+
}
108
} else {
109
+
ret = obj;
110
+
break;
111
}
112
}
113
}
114
+
115
+
if (ret == null) {
116
+
logger.warn("Failed to find object by key", key, "in", exports, new Error().stack!.substring(5));
117
+
}
118
+
119
+
return ret;
120
},
121
122
findObjectFromValue: (exports: Record<string, any>, value: any) => {
123
+
let ret = null;
124
for (const exportKey in exports) {
125
const obj = exports[exportKey];
126
// eslint-disable-next-line eqeqeq
127
+
if (obj == value) {
128
+
ret = obj;
129
+
break;
130
+
}
131
for (const subKey in obj) {
132
// eslint-disable-next-line eqeqeq
133
if (obj && obj[subKey] == value) {
134
+
ret = obj;
135
+
break;
136
}
137
}
138
}
139
+
140
+
if (ret == null) {
141
+
logger.warn("Failed to find object by value", value, "in", exports, new Error().stack!.substring(5));
142
+
}
143
+
144
+
return ret;
145
},
146
147
findObjectFromKeyValuePair: (exports: Record<string, any>, key: string, value: any) => {
148
+
let ret = null;
149
for (const exportKey in exports) {
150
const obj = exports[exportKey];
151
// eslint-disable-next-line eqeqeq
152
if (obj && obj[key] == value) {
153
+
ret = obj;
154
+
break;
155
}
156
}
157
+
158
+
if (ret == null) {
159
+
logger.warn(
160
+
"Failed to find object by key value pair",
161
+
key,
162
+
value,
163
+
"in",
164
+
exports,
165
+
new Error().stack!.substring(5)
166
+
);
167
+
}
168
+
169
return null;
170
},
171
172
findFunctionByStrings: (exports: Record<string, any>, ...strings: (string | RegExp)[]) => {
173
+
const ret =
174
Object.entries(exports).filter(
175
([index, func]) =>
176
typeof func === "function" && !strings.some((query) => !testFind(func.toString(), processFind(query)))
177
+
)?.[0]?.[1] ?? null;
178
+
179
+
if (ret == null) {
180
+
logger.warn("Failed to find function by strings", strings, "in", exports, new Error().stack!.substring(5));
181
+
}
182
+
183
+
return ret;
184
},
185
186
lazyLoad: (find: string | RegExp | (string | RegExp)[], chunk: RegExp, module: RegExp) => {
187
+
chunk = processFind(chunk);
188
+
module = processFind(module);
189
+
190
const mod = Array.isArray(find) ? spacepack.findByCode(...find) : spacepack.findByCode(find);
191
+
if (mod.length < 1) {
192
+
logger.warn("lazyLoad: Module find failed", find, chunk, module, new Error().stack!.substring(5));
193
+
return Promise.reject("Module find failed");
194
+
}
195
196
const findId = mod[0].id;
197
const findCode = webpackRequire.m[findId].toString().replace(/\n/g, "");
···
204
if (match) chunkIds = [...match[0].matchAll(/"(\d+)"/g)].map(([, id]) => id);
205
}
206
207
+
if (!chunkIds || chunkIds.length === 0) {
208
+
logger.warn("lazyLoad: Chunk ID match failed", find, chunk, module, new Error().stack!.substring(5));
209
+
return Promise.reject("Chunk ID match failed");
210
+
}
211
212
const moduleId = findCode.match(module)?.[1];
213
+
if (!moduleId) {
214
+
logger.warn("lazyLoad: Module ID match failed", find, chunk, module, new Error().stack!.substring(5));
215
+
return Promise.reject("Module ID match failed");
216
+
}
217
218
return Promise.all(chunkIds.map((c) => webpackRequire.e(c))).then(() => webpackRequire(moduleId));
219
},
+4
-1
packages/core-extensions/tsconfig.json
+4
-1
packages/core-extensions/tsconfig.json
+10
-3
packages/injector/package.json
+10
-3
packages/injector/package.json
···
1
{
2
"name": "@moonlight-mod/injector",
3
"private": true,
4
+
"engines": {
5
+
"node": ">=22",
6
+
"pnpm": ">=10",
7
+
"npm": "pnpm",
8
+
"yarn": "pnpm"
9
+
},
10
"dependencies": {
11
+
"@moonlight-mod/core": "workspace:*",
12
+
"@moonlight-mod/types": "workspace:*"
13
+
},
14
+
"engineStrict": true
15
}
+37
-14
packages/injector/src/index.ts
+37
-14
packages/injector/src/index.ts
···
76
blockedUrls = compiled;
77
});
78
79
-
function patchCsp(headers: Record<string, string[]>) {
80
-
const directives = [
81
-
"script-src",
82
-
"style-src",
83
-
"connect-src",
84
-
"img-src",
85
-
"font-src",
86
-
"media-src",
87
-
"worker-src",
88
-
"prefetch-src"
89
-
];
90
const values = ["*", "blob:", "data:", "'unsafe-inline'", "'unsafe-eval'", "disclip:"];
91
92
const csp = "content-security-policy";
···
106
parts[directive] = values;
107
}
108
109
const stringified = Object.entries<string[]>(parts)
110
.map(([key, value]) => {
111
return `${key} ${value.join(" ")}`;
···
131
// Event for when a window is created
132
moonlightHost.events.emit("window-created", this, isMainWindow);
133
134
this.webContents.session.webRequest.onHeadersReceived((details, cb) => {
135
if (details.responseHeaders != null) {
136
// Patch CSP so things can use externally hosted assets
137
if (details.resourceType === "mainFrame") {
138
-
patchCsp(details.responseHeaders);
139
}
140
141
// Allow plugins to bypass CORS for specific URLs
142
if (corsAllow.some((x) => details.url.startsWith(x))) {
143
-
details.responseHeaders["access-control-allow-origin"] = ["*"];
144
}
145
146
cb({ cancel: false, responseHeaders: details.responseHeaders });
147
}
···
160
with esbuild someday).
161
*/
162
if (details.resourceType === "script" && isMainWindow) {
163
-
const hasUrl = scriptUrls.some((url) => details.url.includes(url) && !details.url.includes("?inj"));
164
if (hasUrl) blockedScripts.add(details.url);
165
166
if (blockedScripts.size === scriptUrls.length) {
···
76
blockedUrls = compiled;
77
});
78
79
+
function patchCsp(headers: Record<string, string[]>, extensionCspOverrides: Record<string, string[]>) {
80
+
const directives = ["script-src", "style-src", "connect-src", "img-src", "font-src", "media-src", "worker-src"];
81
const values = ["*", "blob:", "data:", "'unsafe-inline'", "'unsafe-eval'", "disclip:"];
82
83
const csp = "content-security-policy";
···
97
parts[directive] = values;
98
}
99
100
+
for (const [directive, urls] of Object.entries(extensionCspOverrides)) {
101
+
parts[directive] ??= [];
102
+
parts[directive].push(...urls);
103
+
}
104
+
105
const stringified = Object.entries<string[]>(parts)
106
.map(([key, value]) => {
107
return `${key} ${value.join(" ")}`;
···
127
// Event for when a window is created
128
moonlightHost.events.emit("window-created", this, isMainWindow);
129
130
+
const extensionCspOverrides: Record<string, string[]> = {};
131
+
132
+
{
133
+
const extCsps = moonlightHost.processedExtensions.extensions.map((x) => x.manifest.csp ?? {});
134
+
for (const csp of extCsps) {
135
+
for (const [directive, urls] of Object.entries(csp)) {
136
+
extensionCspOverrides[directive] ??= [];
137
+
extensionCspOverrides[directive].push(...urls);
138
+
}
139
+
}
140
+
}
141
+
142
this.webContents.session.webRequest.onHeadersReceived((details, cb) => {
143
if (details.responseHeaders != null) {
144
// Patch CSP so things can use externally hosted assets
145
if (details.resourceType === "mainFrame") {
146
+
patchCsp(details.responseHeaders, extensionCspOverrides);
147
}
148
149
// Allow plugins to bypass CORS for specific URLs
150
if (corsAllow.some((x) => details.url.startsWith(x))) {
151
+
if (!details.responseHeaders) details.responseHeaders = {};
152
+
153
+
// Work around HTTP header case sensitivity by reusing the header name if it exists
154
+
// https://github.com/moonlight-mod/moonlight/issues/201
155
+
const fallback = "access-control-allow-origin";
156
+
const key = Object.keys(details.responseHeaders).find((h) => h.toLowerCase() === fallback) ?? fallback;
157
+
details.responseHeaders[key] = ["*"];
158
}
159
+
160
+
moonlightHost.events.emit("headers-received", details, isMainWindow);
161
162
cb({ cancel: false, responseHeaders: details.responseHeaders });
163
}
···
176
with esbuild someday).
177
*/
178
if (details.resourceType === "script" && isMainWindow) {
179
+
const url = new URL(details.url);
180
+
const hasUrl = scriptUrls.some((scriptUrl) => {
181
+
return (
182
+
details.url.includes(scriptUrl) &&
183
+
!url.searchParams.has("inj") &&
184
+
(url.host.endsWith("discord.com") || url.host.endsWith("discordapp.com"))
185
+
);
186
+
});
187
if (hasUrl) blockedScripts.add(details.url);
188
189
if (blockedScripts.size === scriptUrls.length) {
+8
-1
packages/node-preload/package.json
+8
-1
packages/node-preload/package.json
···
1
{
2
"name": "@moonlight-mod/node-preload",
3
"private": true,
4
+
"engines": {
5
+
"node": ">=22",
6
+
"pnpm": ">=10",
7
+
"npm": "pnpm",
8
+
"yarn": "pnpm"
9
+
},
10
"dependencies": {
11
"@moonlight-mod/core": "workspace:*",
12
"@moonlight-mod/types": "workspace:*"
13
+
},
14
+
"engineStrict": true
15
}
+52
-37
packages/node-preload/src/index.ts
+52
-37
packages/node-preload/src/index.ts
···
11
import createFS from "@moonlight-mod/core/fs";
12
import { registerCors, registerBlocked, getDynamicCors } from "@moonlight-mod/core/cors";
13
import { getConfig, getConfigOption, getManifest, setConfigOption } from "@moonlight-mod/core/util/config";
14
15
let initialized = false;
16
let logger: Logger;
···
51
processedExtensions,
52
nativesCache: {},
53
isBrowser: false,
54
55
version: MOONLIGHT_VERSION,
56
branch: MOONLIGHT_BRANCH as MoonlightBranch,
···
62
const manifest = getManifest(extensions, ext);
63
return getConfigOption(ext, name, config, manifest?.settings);
64
},
65
-
setConfigOption(ext, name, value) {
66
setConfigOption(config, ext, name, value);
67
-
this.writeConfig(config);
68
},
69
async writeConfig(newConfig) {
70
await writeConfig(newConfig);
71
config = newConfig;
72
},
73
74
getNatives: (ext: string) => global.moonlightNode.nativesCache[ext],
···
129
}
130
}
131
132
-
ipcRenderer.on(constants.ipcNodePreloadKickoff, (_, blockedScripts: string[]) => {
133
-
(async () => {
134
-
try {
135
-
await init();
136
-
logger.debug("Blocked scripts:", blockedScripts);
137
138
-
const oldPreloadPath: string = ipcRenderer.sendSync(constants.ipcGetOldPreloadPath);
139
-
logger.debug("Old preload path:", oldPreloadPath);
140
-
if (oldPreloadPath) require(oldPreloadPath);
141
142
-
// Do this to get global.DiscordNative assigned
143
-
// @ts-expect-error Lying to discord_desktop_core
144
-
process.emit("loaded");
145
146
-
function replayScripts() {
147
-
const scripts = [...document.querySelectorAll("script")].filter(
148
-
(script) => script.src && blockedScripts.some((url) => url.includes(script.src))
149
-
);
150
151
-
blockedScripts.reverse();
152
-
for (const url of blockedScripts) {
153
-
if (url.includes("/sentry.")) continue;
154
155
-
const script = scripts.find((script) => url.includes(script.src))!;
156
-
const newScript = document.createElement("script");
157
-
for (const attr of script.attributes) {
158
-
if (attr.name === "src") attr.value += "?inj";
159
-
newScript.setAttribute(attr.name, attr.value);
160
}
161
-
script.remove();
162
-
document.documentElement.appendChild(newScript);
163
}
164
-
}
165
166
-
if (document.readyState === "complete") {
167
-
replayScripts();
168
-
} else {
169
-
window.addEventListener("load", replayScripts);
170
}
171
-
} catch (e) {
172
-
logger.error("Error restoring original scripts:", e);
173
-
}
174
-
})();
175
-
});
···
11
import createFS from "@moonlight-mod/core/fs";
12
import { registerCors, registerBlocked, getDynamicCors } from "@moonlight-mod/core/cors";
13
import { getConfig, getConfigOption, getManifest, setConfigOption } from "@moonlight-mod/core/util/config";
14
+
import { NodeEventPayloads, NodeEventType } from "@moonlight-mod/types/core/event";
15
+
import { createEventEmitter } from "@moonlight-mod/core/util/event";
16
17
let initialized = false;
18
let logger: Logger;
···
53
processedExtensions,
54
nativesCache: {},
55
isBrowser: false,
56
+
events: createEventEmitter<NodeEventType, NodeEventPayloads>(),
57
58
version: MOONLIGHT_VERSION,
59
branch: MOONLIGHT_BRANCH as MoonlightBranch,
···
65
const manifest = getManifest(extensions, ext);
66
return getConfigOption(ext, name, config, manifest?.settings);
67
},
68
+
async setConfigOption(ext, name, value) {
69
setConfigOption(config, ext, name, value);
70
+
await this.writeConfig(config);
71
},
72
async writeConfig(newConfig) {
73
await writeConfig(newConfig);
74
config = newConfig;
75
+
this.events.dispatchEvent(NodeEventType.ConfigSaved, newConfig);
76
},
77
78
getNatives: (ext: string) => global.moonlightNode.nativesCache[ext],
···
133
}
134
}
135
136
+
const oldPreloadPath: string = ipcRenderer.sendSync(constants.ipcGetOldPreloadPath);
137
+
const isOverlay = window.location.href.indexOf("discord_overlay") > -1;
138
+
139
+
if (isOverlay) {
140
+
// The overlay has an inline script tag to call to DiscordNative, so we'll
141
+
// just load it immediately. Somehow moonlight still loads in this env, I
142
+
// have no idea why - so I suspect it's just forwarding render calls or
143
+
// something from the original process
144
+
require(oldPreloadPath);
145
+
} else {
146
+
ipcRenderer.on(constants.ipcNodePreloadKickoff, (_, blockedScripts: string[]) => {
147
+
(async () => {
148
+
try {
149
+
await init();
150
+
logger.debug("Blocked scripts:", blockedScripts);
151
152
+
const oldPreloadPath: string = ipcRenderer.sendSync(constants.ipcGetOldPreloadPath);
153
+
logger.debug("Old preload path:", oldPreloadPath);
154
+
if (oldPreloadPath) require(oldPreloadPath);
155
156
+
// Do this to get global.DiscordNative assigned
157
+
// @ts-expect-error Lying to discord_desktop_core
158
+
process.emit("loaded");
159
160
+
function replayScripts() {
161
+
const scripts = [...document.querySelectorAll("script")].filter(
162
+
(script) => script.src && blockedScripts.some((url) => url.includes(script.src))
163
+
);
164
165
+
blockedScripts.reverse();
166
+
for (const url of blockedScripts) {
167
+
if (url.includes("/sentry.")) continue;
168
169
+
const script = scripts.find((script) => url.includes(script.src))!;
170
+
const newScript = document.createElement("script");
171
+
for (const attr of script.attributes) {
172
+
if (attr.name === "src") attr.value += "?inj";
173
+
newScript.setAttribute(attr.name, attr.value);
174
+
}
175
+
script.remove();
176
+
document.documentElement.appendChild(newScript);
177
}
178
}
179
180
+
if (document.readyState === "complete") {
181
+
replayScripts();
182
+
} else {
183
+
window.addEventListener("load", replayScripts);
184
+
}
185
+
} catch (e) {
186
+
logger.error("Error restoring original scripts:", e);
187
}
188
+
})();
189
+
});
190
+
}
+4
-1
packages/node-preload/tsconfig.json
+4
-1
packages/node-preload/tsconfig.json
+14
-7
packages/types/package.json
+14
-7
packages/types/package.json
···
1
{
2
"name": "@moonlight-mod/types",
3
-
"version": "1.3.5",
4
-
"main": "./src/index.ts",
5
-
"types": "./src/index.ts",
6
"exports": {
7
".": "./src/index.ts",
8
"./import": "./src/import.d.ts",
9
"./*": "./src/*.ts"
10
},
11
"dependencies": {
12
-
"@moonlight-mod/lunast": "^1.0.0",
13
-
"@moonlight-mod/mappings": "^1.0.10",
14
-
"@moonlight-mod/moonmap": "^1.0.3",
15
"@types/react": "^18.3.10",
16
-
"csstype": "^3.1.2",
17
"standalone-electron-types": "^1.0.0"
18
}
19
}
···
1
{
2
"name": "@moonlight-mod/types",
3
+
"version": "1.3.17",
4
"exports": {
5
".": "./src/index.ts",
6
"./import": "./src/import.d.ts",
7
"./*": "./src/*.ts"
8
},
9
+
"main": "./src/index.ts",
10
+
"types": "./src/index.ts",
11
+
"engineStrict": false,
12
+
"engines": {
13
+
"node": ">=22",
14
+
"pnpm": ">=10",
15
+
"npm": "pnpm",
16
+
"yarn": "pnpm"
17
+
},
18
"dependencies": {
19
+
"@moonlight-mod/lunast": "^1.0.1",
20
+
"@moonlight-mod/mappings": "^1.1.25",
21
+
"@moonlight-mod/moonmap": "^1.0.5",
22
"@types/react": "^18.3.10",
23
+
"csstype": "^3.1.3",
24
"standalone-electron-types": "^1.0.0"
25
}
26
}
+41
packages/types/src/config.ts
+41
packages/types/src/config.ts
···
33
};
34
35
export type BooleanSettingType = {
36
type: ExtensionSettingType.Boolean;
37
default?: boolean;
38
};
39
40
export type NumberSettingType = {
41
type: ExtensionSettingType.Number;
42
default?: number;
43
min?: number;
···
45
};
46
47
export type StringSettingType = {
48
type: ExtensionSettingType.String;
49
default?: string;
50
};
51
52
export type MultilineTextInputSettingType = {
53
type: ExtensionSettingType.MultilineString;
54
default?: string;
55
};
56
57
export type SelectSettingType = {
58
type: ExtensionSettingType.Select;
59
options: SelectOption[];
60
default?: string;
61
};
62
63
export type MultiSelectSettingType = {
64
type: ExtensionSettingType.MultiSelect;
65
options: string[];
66
default?: string[];
67
};
68
69
export type ListSettingType = {
70
type: ExtensionSettingType.List;
71
default?: string[];
72
};
73
74
export type DictionarySettingType = {
75
type: ExtensionSettingType.Dictionary;
76
default?: Record<string, string>;
77
};
78
79
export type CustomSettingType = {
80
type: ExtensionSettingType.Custom;
81
default?: any;
82
};
···
88
}
89
90
export type ExtensionSettingsManifest = {
91
displayName?: string;
92
description?: string;
93
advice?: ExtensionSettingsAdvice;
94
} & (
95
| BooleanSettingType
···
33
};
34
35
export type BooleanSettingType = {
36
+
/**
37
+
* Displays as a simple switch.
38
+
*/
39
type: ExtensionSettingType.Boolean;
40
default?: boolean;
41
};
42
43
export type NumberSettingType = {
44
+
/**
45
+
* Displays as a simple slider.
46
+
*/
47
type: ExtensionSettingType.Number;
48
default?: number;
49
min?: number;
···
51
};
52
53
export type StringSettingType = {
54
+
/**
55
+
* Displays as a single line string input.
56
+
*/
57
type: ExtensionSettingType.String;
58
default?: string;
59
};
60
61
export type MultilineTextInputSettingType = {
62
+
/**
63
+
* Displays as a multiple line string input.
64
+
*/
65
type: ExtensionSettingType.MultilineString;
66
default?: string;
67
};
68
69
export type SelectSettingType = {
70
+
/**
71
+
* A dropdown to pick between one of many values.
72
+
*/
73
type: ExtensionSettingType.Select;
74
options: SelectOption[];
75
default?: string;
76
};
77
78
export type MultiSelectSettingType = {
79
+
/**
80
+
* A dropdown to pick multiple values.
81
+
*/
82
type: ExtensionSettingType.MultiSelect;
83
options: string[];
84
default?: string[];
85
};
86
87
export type ListSettingType = {
88
+
/**
89
+
* A list of strings that the user can add or remove from.
90
+
*/
91
type: ExtensionSettingType.List;
92
default?: string[];
93
};
94
95
export type DictionarySettingType = {
96
+
/**
97
+
* A dictionary (key-value pair) that the user can add or remove from.
98
+
*/
99
type: ExtensionSettingType.Dictionary;
100
default?: Record<string, string>;
101
};
102
103
export type CustomSettingType = {
104
+
/**
105
+
* A custom component.
106
+
* You can use the registerConfigComponent function in the Moonbase API to register a React component to render here.
107
+
*/
108
type: ExtensionSettingType.Custom;
109
default?: any;
110
};
···
116
}
117
118
export type ExtensionSettingsManifest = {
119
+
/**
120
+
* A human friendly name for the setting.
121
+
*/
122
displayName?: string;
123
+
124
+
/**
125
+
* A longer description for the setting.
126
+
* Markdown is not supported.
127
+
*/
128
description?: string;
129
+
130
+
/**
131
+
* The "advice" to give upon changing this setting.
132
+
* Can be configured to reload the client, restart the client, or do nothing.
133
+
*/
134
advice?: ExtensionSettingsAdvice;
135
} & (
136
| BooleanSettingType
+13
-4
packages/types/src/core/event.ts
+13
-4
packages/types/src/core/event.ts
···
1
import { WebpackModuleFunc, WebpackRequireType } from "../discord";
2
3
export interface MoonlightEventEmitter<EventId extends string = string, EventData = Record<EventId, any>> {
···
6
removeEventListener: <Id extends keyof EventData>(id: Id, cb: (data: EventData[Id]) => void) => void;
7
}
8
9
-
export enum EventType {
10
ChunkLoad = "chunkLoad",
11
ExtensionLoad = "extensionLoad"
12
}
13
14
-
export type EventPayloads = {
15
-
[EventType.ChunkLoad]: {
16
chunkId?: number[];
17
modules: { [id: string]: WebpackModuleFunc };
18
require?: (require: WebpackRequireType) => any;
19
};
20
-
[EventType.ExtensionLoad]: string;
21
};
···
1
+
import { Config } from "../config";
2
import { WebpackModuleFunc, WebpackRequireType } from "../discord";
3
4
export interface MoonlightEventEmitter<EventId extends string = string, EventData = Record<EventId, any>> {
···
7
removeEventListener: <Id extends keyof EventData>(id: Id, cb: (data: EventData[Id]) => void) => void;
8
}
9
10
+
export enum WebEventType {
11
ChunkLoad = "chunkLoad",
12
ExtensionLoad = "extensionLoad"
13
}
14
15
+
export type WebEventPayloads = {
16
+
[WebEventType.ChunkLoad]: {
17
chunkId?: number[];
18
modules: { [id: string]: WebpackModuleFunc };
19
require?: (require: WebpackRequireType) => any;
20
};
21
+
[WebEventType.ExtensionLoad]: string;
22
+
};
23
+
24
+
export enum NodeEventType {
25
+
ConfigSaved = "configSaved"
26
+
}
27
+
28
+
export type NodeEventPayloads = {
29
+
[NodeEventType.ConfigSaved]: Config;
30
};
+204
packages/types/src/coreExtensions/commands.ts
+204
packages/types/src/coreExtensions/commands.ts
···
···
1
+
export const APPLICATION_ID = "-3";
2
+
3
+
export enum CommandType {
4
+
CHAT = 1,
5
+
MESSAGE = 3,
6
+
PRIMARY_ENTRY_POINT = 4,
7
+
USER = 2
8
+
}
9
+
10
+
export enum InputType {
11
+
BOT = 3,
12
+
BUILT_IN = 0,
13
+
BUILT_IN_INTEGRATION = 2,
14
+
BUILT_IN_TEXT = 1,
15
+
PLACEHOLDER = 4
16
+
}
17
+
18
+
export enum OptionType {
19
+
SUB_COMMAND = 1,
20
+
SUB_COMMAND_GROUP = 2,
21
+
STRING = 3,
22
+
INTEGER = 4,
23
+
BOOLEAN = 5,
24
+
USER = 6,
25
+
CHANNEL = 7,
26
+
ROLE = 8,
27
+
MENTIONABLE = 9,
28
+
NUMBER = 10,
29
+
ATTACHMENT = 11
30
+
}
31
+
32
+
export enum ChannelType {
33
+
GUILD_TEXT = 0,
34
+
DM = 1,
35
+
GUILD_VOICE = 2,
36
+
GROUP_DM = 3,
37
+
GUILD_CATEGORY = 4,
38
+
GUILD_ANNOUNCEMENT = 5,
39
+
GUILD_STORE = 6,
40
+
ANNOUNCEMENT_THREAD = 10,
41
+
PUBLIC_THREAD = 11,
42
+
PRIVATE_THREAD = 12,
43
+
GUILD_STAGE_VOICE = 13,
44
+
GUILD_DIRECTORY = 14,
45
+
GUILD_FORUM = 15,
46
+
GUILD_MEDIA = 16,
47
+
LOBBY = 17,
48
+
DM_SDK = 18
49
+
}
50
+
51
+
export type RegisteredCommandOption = MoonlightCommandOption & {
52
+
displayName: string;
53
+
displayDescription: string;
54
+
};
55
+
56
+
export type CommandOptionChoice<T> = {
57
+
name: string;
58
+
value: T;
59
+
};
60
+
61
+
type CommandOptionBase<T> = {
62
+
type: T;
63
+
name: string;
64
+
description: string;
65
+
required?: T extends OptionType.SUB_COMMAND
66
+
? never
67
+
: T extends OptionType.SUB_COMMAND_GROUP
68
+
? never
69
+
: boolean | undefined;
70
+
choices?: T extends OptionType.STRING
71
+
? CommandOptionChoice<string>[]
72
+
: T extends OptionType.INTEGER
73
+
? CommandOptionChoice<number>[]
74
+
: T extends OptionType.NUMBER
75
+
? CommandOptionChoice<number>[]
76
+
: never;
77
+
options?: T extends OptionType.SUB_COMMAND
78
+
? MoonlightCommandOption[]
79
+
: T extends OptionType.SUB_COMMAND_GROUP
80
+
? MoonlightCommandOption[]
81
+
: never;
82
+
channelTypes?: T extends OptionType.CHANNEL ? ChannelType[] : never;
83
+
minValue?: T extends OptionType.INTEGER ? number : T extends OptionType.NUMBER ? number : never;
84
+
maxValue?: T extends OptionType.INTEGER ? number : T extends OptionType.NUMBER ? number : never;
85
+
minLength?: T extends OptionType.STRING ? number : never;
86
+
maxLength?: T extends OptionType.STRING ? number : never;
87
+
};
88
+
89
+
// This is bad lol
90
+
export type MoonlightCommandOption =
91
+
| CommandOptionBase<OptionType.SUB_COMMAND>
92
+
| CommandOptionBase<OptionType.SUB_COMMAND_GROUP>
93
+
| CommandOptionBase<OptionType.STRING>
94
+
| CommandOptionBase<OptionType.INTEGER>
95
+
| CommandOptionBase<OptionType.BOOLEAN>
96
+
| CommandOptionBase<OptionType.USER>
97
+
| CommandOptionBase<OptionType.CHANNEL>
98
+
| CommandOptionBase<OptionType.ROLE>
99
+
| CommandOptionBase<OptionType.MENTIONABLE>
100
+
| CommandOptionBase<OptionType.NUMBER>
101
+
| CommandOptionBase<OptionType.ATTACHMENT>;
102
+
103
+
// TODO: types
104
+
export type CommandPredicateState = {
105
+
channel: any;
106
+
guild: any;
107
+
};
108
+
109
+
export type RegisteredCommand = {
110
+
id: string;
111
+
untranslatedName: string;
112
+
displayName: string;
113
+
type: CommandType;
114
+
inputType: InputType;
115
+
applicationId: string; // set to -3!
116
+
untranslatedDescription: string;
117
+
displayDescription: string;
118
+
options?: RegisteredCommandOption[];
119
+
predicate?: (state: CommandPredicateState) => boolean;
120
+
execute: (options: CommandOption[]) => void;
121
+
};
122
+
123
+
export type MoonlightCommand = {
124
+
id: string;
125
+
description: string;
126
+
127
+
/**
128
+
* You likely want CHAT
129
+
*/
130
+
type: CommandType;
131
+
132
+
/**
133
+
* You likely want BUILT_IN (or BUILT_IN_TEXT if usable with replies)
134
+
*/
135
+
inputType: InputType;
136
+
options?: MoonlightCommandOption[];
137
+
predicate?: (state: CommandPredicateState) => boolean;
138
+
execute: (options: CommandOption[]) => void;
139
+
};
140
+
141
+
export type CommandOption = {
142
+
name: string;
143
+
} & ( // TODO: more of these
144
+
| {
145
+
type: Exclude<OptionType, OptionType.STRING>;
146
+
value: any;
147
+
}
148
+
| {
149
+
type: OptionType.STRING;
150
+
value: string;
151
+
}
152
+
| {
153
+
type: OptionType.NUMBER | OptionType.INTEGER;
154
+
value: number;
155
+
}
156
+
| {
157
+
type: OptionType.BOOLEAN;
158
+
value: boolean;
159
+
}
160
+
| {
161
+
type: OptionType.SUB_COMMAND | OptionType.SUB_COMMAND_GROUP;
162
+
options: CommandOption[];
163
+
}
164
+
);
165
+
166
+
export type AnyScopeRegex = RegExp["exec"] & {
167
+
regex: RegExp;
168
+
};
169
+
170
+
export type Commands = {
171
+
/**
172
+
* Register a command in the internal slash command system
173
+
*/
174
+
registerCommand: (command: MoonlightCommand) => void;
175
+
176
+
/**
177
+
* Register a legacy command that works via regex
178
+
*/
179
+
registerLegacyCommand: (id: string, command: LegacyCommand) => void;
180
+
181
+
/**
182
+
* Creates a regular expression that legacy commands can understand
183
+
*/
184
+
anyScopeRegex: (regex: RegExp) => AnyScopeRegex;
185
+
186
+
/**
187
+
* @private
188
+
*/
189
+
_getCommands: () => RegisteredCommand[];
190
+
};
191
+
192
+
export type LegacyContext = {
193
+
channel: any;
194
+
isEdit: boolean;
195
+
};
196
+
197
+
export type LegacyReturn = {
198
+
content: string;
199
+
};
200
+
201
+
export type LegacyCommand = {
202
+
match?: RegExp | { regex: RegExp } | AnyScopeRegex;
203
+
action: (content: string, context: LegacyContext) => LegacyReturn;
204
+
};
+33
packages/types/src/coreExtensions/common.ts
+33
packages/types/src/coreExtensions/common.ts
···
···
1
+
import type { IconProps, IconSize } from "@moonlight-mod/mappings/discord/components/common/index";
2
+
3
+
export type ErrorBoundaryProps = React.PropsWithChildren<{
4
+
noop?: boolean;
5
+
fallback?: React.FC<any>;
6
+
message?: string;
7
+
}>;
8
+
9
+
export type ErrorBoundaryState = {
10
+
errored: boolean;
11
+
error?: Error;
12
+
componentStack?: string;
13
+
};
14
+
15
+
export type ErrorBoundary = React.ComponentClass<ErrorBoundaryProps, ErrorBoundaryState>;
16
+
17
+
export type ParsedIconProps = {
18
+
width: number;
19
+
height: number;
20
+
fill: string;
21
+
className: string;
22
+
};
23
+
24
+
export interface Icons {
25
+
/**
26
+
* Parse icon props into their actual width/height.
27
+
* @param props The icon props
28
+
*/
29
+
parseProps(props?: IconProps): ParsedIconProps;
30
+
}
31
+
32
+
// Re-export so extension developers don't need to depend on mappings
33
+
export type { IconProps, IconSize };
+162
packages/types/src/coreExtensions/componentEditor.ts
+162
packages/types/src/coreExtensions/componentEditor.ts
···
···
1
+
type Patcher<T> = (elements: React.ReactNode[], props: T) => React.ReactNode[];
2
+
3
+
//#region DM List
4
+
export type DMListAnchors =
5
+
| "content"
6
+
| "favorite-server-indicator"
7
+
| "ignored-indicator"
8
+
| "blocked-indicator"
9
+
| "close-button"
10
+
| undefined;
11
+
export type DMListDecoratorAnchors = "system-tag" | undefined;
12
+
13
+
export enum DMListAnchorIndicies {
14
+
content = 0,
15
+
"favorite-server-indicator",
16
+
"ignored-indicator",
17
+
"blocked-indicator",
18
+
"close-button"
19
+
}
20
+
export enum DMListDecoratorAnchorIndicies {
21
+
"system-tag" = 0
22
+
}
23
+
24
+
export type DMListItem = {
25
+
component: React.FC<any>;
26
+
anchor: DMListAnchors;
27
+
before: boolean;
28
+
};
29
+
export type DMListDecorator = {
30
+
component: React.FC<any>;
31
+
anchor: DMListDecoratorAnchors;
32
+
before: boolean;
33
+
};
34
+
35
+
export type DMList = {
36
+
addItem: (id: string, component: React.FC<any>, anchor?: DMListAnchors, before?: boolean) => void;
37
+
addDecorator: (id: string, component: React.FC<any>, anchor?: DMListDecoratorAnchors, before?: boolean) => void;
38
+
//TODO: fix props type
39
+
/**
40
+
* @private
41
+
*/
42
+
_patchItems: Patcher<any>;
43
+
/**
44
+
* @private
45
+
*/
46
+
_patchDecorators: Patcher<any>;
47
+
};
48
+
//#endregion
49
+
50
+
//#region Member List
51
+
export type MemberListDecoratorAnchors = "bot-tag" | "owner-crown" | "boost-icon" | undefined;
52
+
53
+
export enum MemberListDecoratorAnchorIndicies {
54
+
"bot-tag" = 0,
55
+
"owner-crown",
56
+
"boost-icon"
57
+
}
58
+
59
+
export type MemberListDecorator = {
60
+
component: React.FC<any>;
61
+
anchor: MemberListDecoratorAnchors;
62
+
before: boolean;
63
+
};
64
+
65
+
export type MemberList = {
66
+
addItem: (id: string, component: React.FC<any>) => void;
67
+
addDecorator: (id: string, component: React.FC<any>, anchor?: MemberListDecoratorAnchors, before?: boolean) => void;
68
+
//TODO: fix props type
69
+
/**
70
+
* @private
71
+
*/
72
+
_patchItems: Patcher<any>;
73
+
/**
74
+
* @private
75
+
*/
76
+
_patchDecorators: Patcher<any>;
77
+
};
78
+
//#endregion
79
+
80
+
//#region Messages
81
+
export type MessageUsernameAnchors = "communication-disabled" | "username" | undefined;
82
+
export type MessageUsernameBadgeAnchors =
83
+
| "nitro-author"
84
+
| "role-icon"
85
+
| "new-member"
86
+
| "leaderboard-champion"
87
+
| "connections"
88
+
| undefined;
89
+
export type MessageBadgeAnchors = "silent" | "potion" | undefined;
90
+
91
+
export type MessageUsername = {
92
+
component: React.FC<any>;
93
+
anchor: MessageUsernameAnchors;
94
+
before: boolean;
95
+
};
96
+
export type MessageUsernameBadge = {
97
+
component: React.FC<any>;
98
+
anchor: MessageUsernameBadgeAnchors;
99
+
before: boolean;
100
+
};
101
+
export type MessageBadge = {
102
+
component: React.FC<any>;
103
+
anchor: MessageBadgeAnchors;
104
+
before: boolean;
105
+
};
106
+
107
+
export enum MessageUsernameIndicies {
108
+
"communication-disabled" = 0,
109
+
username
110
+
}
111
+
export enum MessageUsernameBadgeIndicies {
112
+
"nitro-author" = 0,
113
+
"role-icon",
114
+
"new-member",
115
+
"leaderboard-champion",
116
+
connections
117
+
}
118
+
export enum MessageBadgeIndicies {
119
+
silent = 0,
120
+
potion
121
+
}
122
+
123
+
export type Messages = {
124
+
/**
125
+
* Adds a component to the username of a message
126
+
*/
127
+
addToUsername: (id: string, component: React.FC<any>, anchor?: MessageUsernameAnchors, before?: boolean) => void;
128
+
/**
129
+
* Adds a component to the username badge area of a message (e.g. where role icons/new member badge is)
130
+
*/
131
+
addUsernameBadge: (
132
+
id: string,
133
+
component: React.FC<any>,
134
+
anchor?: MessageUsernameBadgeAnchors,
135
+
before?: boolean
136
+
) => void;
137
+
/**
138
+
* Adds a component to the end of a message header (e.g. silent indicator)
139
+
*/
140
+
addBadge: (id: string, component: React.FC<any>, anchor?: MessageBadgeAnchors, before?: boolean) => void;
141
+
/**
142
+
* Adds a component to message accessories (e.g. embeds)
143
+
*/
144
+
addAccessory: (id: string, component: React.FC<any>) => void;
145
+
/**
146
+
* @private
147
+
*/
148
+
_patchUsername: Patcher<any>;
149
+
/**
150
+
* @private
151
+
*/
152
+
_patchUsernameBadges: Patcher<any>;
153
+
/**
154
+
* @private
155
+
*/
156
+
_patchBadges: Patcher<any>;
157
+
/**
158
+
* @private
159
+
*/
160
+
_patchAccessories: Patcher<any>;
161
+
};
162
+
//#endregion
+1
-1
packages/types/src/coreExtensions/notices.ts
+1
-1
packages/types/src/coreExtensions/notices.ts
+11
-8
packages/types/src/coreExtensions/settings.ts
+11
-8
packages/types/src/coreExtensions/settings.ts
···
1
import React, { ReactElement } from "react";
2
-
import type { Store } from "@moonlight-mod/mappings/discord/packages/flux";
3
4
export type NoticeProps = {
5
stores: Store<any>[];
···
7
};
8
9
export type SettingsSection =
10
-
| { section: "DIVIDER"; pos: number }
11
-
| { section: "HEADER"; label: string; pos: number }
12
| {
13
section: string;
14
label: string;
15
color: string | null;
16
element: React.FunctionComponent;
17
-
pos: number;
18
notice?: NoticeProps;
19
_moonlight_submenu?: () => ReactElement | ReactElement[];
20
};
21
···
32
* @param color A color to use for the section
33
* @param pos The position in the settings menu to place the section
34
* @param notice A notice to display when in the section
35
*/
36
addSection: (
37
section: string,
38
label: string,
39
element: React.FunctionComponent,
40
color?: string | null,
41
-
pos?: number,
42
-
notice?: NoticeProps
43
) => void;
44
45
/**
···
53
* Places a divider in the settings menu.
54
* @param pos The position in the settings menu to place the divider
55
*/
56
-
addDivider: (pos: number | null) => void;
57
58
/**
59
* Places a header in the settings menu.
60
* @param pos The position in the settings menu to place the header
61
*/
62
-
addHeader: (label: string, pos: number | null) => void;
63
64
/**
65
* @private
···
1
import React, { ReactElement } from "react";
2
+
import type { Store } from "@moonlight-mod/mappings/discord/packages/flux/Store";
3
4
export type NoticeProps = {
5
stores: Store<any>[];
···
7
};
8
9
export type SettingsSection =
10
+
| { section: "DIVIDER"; pos: number | ((sections: SettingsSection[]) => number) }
11
+
| { section: "HEADER"; label: string; pos: number | ((sections: SettingsSection[]) => number) }
12
| {
13
section: string;
14
label: string;
15
color: string | null;
16
element: React.FunctionComponent;
17
+
pos: number | ((sections: SettingsSection[]) => number);
18
notice?: NoticeProps;
19
+
onClick?: () => void;
20
_moonlight_submenu?: () => ReactElement | ReactElement[];
21
};
22
···
33
* @param color A color to use for the section
34
* @param pos The position in the settings menu to place the section
35
* @param notice A notice to display when in the section
36
+
* @param onClick A custom action to execute when clicked from the context menu
37
*/
38
addSection: (
39
section: string,
40
label: string,
41
element: React.FunctionComponent,
42
color?: string | null,
43
+
pos?: number | ((sections: SettingsSection[]) => number),
44
+
notice?: NoticeProps,
45
+
onClick?: () => void
46
) => void;
47
48
/**
···
56
* Places a divider in the settings menu.
57
* @param pos The position in the settings menu to place the divider
58
*/
59
+
addDivider: (pos: number | ((sections: SettingsSection[]) => number) | null) => void;
60
61
/**
62
* Places a header in the settings menu.
63
* @param pos The position in the settings menu to place the header
64
*/
65
+
addHeader: (label: string, pos: number | ((sections: SettingsSection[]) => number) | null) => void;
66
67
/**
68
* @private
+1
packages/types/src/coreExtensions/spacepack.ts
+1
packages/types/src/coreExtensions/spacepack.ts
+3
packages/types/src/coreExtensions.ts
+3
packages/types/src/coreExtensions.ts
···
5
export * as Notices from "./coreExtensions/notices";
6
export * as Moonbase from "./coreExtensions/moonbase";
7
export * as AppPanels from "./coreExtensions/appPanels";
8
+
export * as Commands from "./coreExtensions/commands";
9
+
export * as ComponentEditor from "./coreExtensions/componentEditor";
10
+
export * as Common from "./coreExtensions/common";
+12
packages/types/src/discord/require.ts
+12
packages/types/src/discord/require.ts
···
1
import { AppPanels } from "../coreExtensions/appPanels";
2
import { ContextMenu, EvilItemParser } from "../coreExtensions/contextMenu";
3
import { Markdown } from "../coreExtensions/markdown";
4
import { Moonbase } from "../coreExtensions/moonbase";
···
9
declare function WebpackRequire(id: string): any;
10
11
declare function WebpackRequire(id: "appPanels_appPanels"): AppPanels;
12
13
declare function WebpackRequire(id: "contextMenu_evilMenu"): EvilItemParser;
14
declare function WebpackRequire(id: "contextMenu_contextMenu"): ContextMenu;
···
1
import { AppPanels } from "../coreExtensions/appPanels";
2
+
import { Commands } from "../coreExtensions/commands";
3
+
import { ErrorBoundary, Icons } from "../coreExtensions/common";
4
+
import { DMList, MemberList, Messages } from "../coreExtensions/componentEditor";
5
import { ContextMenu, EvilItemParser } from "../coreExtensions/contextMenu";
6
import { Markdown } from "../coreExtensions/markdown";
7
import { Moonbase } from "../coreExtensions/moonbase";
···
12
declare function WebpackRequire(id: string): any;
13
14
declare function WebpackRequire(id: "appPanels_appPanels"): AppPanels;
15
+
16
+
declare function WebpackRequire(id: "commands_commands"): Commands;
17
+
18
+
declare function WebpackRequire(id: "common_ErrorBoundary"): ErrorBoundary;
19
+
declare function WebpackRequire(id: "common_icons"): Icons;
20
+
21
+
declare function WebpackRequire(id: "componentEditor_dmList"): DMList;
22
+
declare function WebpackRequire(id: "componentEditor_memberList"): MemberList;
23
+
declare function WebpackRequire(id: "componentEditor_messages"): Messages;
24
25
declare function WebpackRequire(id: "contextMenu_evilMenu"): EvilItemParser;
26
declare function WebpackRequire(id: "contextMenu_contextMenu"): ContextMenu;
+101
-1
packages/types/src/extension.ts
+101
-1
packages/types/src/extension.ts
···
28
};
29
30
export type ExtensionManifest = {
31
id: string;
32
version?: string;
33
apiLevel?: number;
34
environment?: ExtensionEnvironment;
35
36
meta?: {
37
name?: string;
38
tagline?: string;
39
description?: string;
40
authors?: ExtensionAuthor[];
41
-
deprecated?: boolean;
42
tags?: ExtensionTag[];
43
source?: string;
44
changelog?: string;
45
};
46
47
dependencies?: string[];
48
suggested?: string[];
49
incompatible?: string[];
50
51
settings?: Record<string, ExtensionSettingsManifest>;
52
53
cors?: string[];
54
blocked?: string[];
55
};
56
57
export enum ExtensionEnvironment {
58
Both = "both",
59
Desktop = "desktop",
60
Web = "web"
61
}
62
···
28
};
29
30
export type ExtensionManifest = {
31
+
$schema?: string;
32
+
33
+
/**
34
+
* A unique identifier for your extension.
35
+
*/
36
id: string;
37
+
38
+
/**
39
+
* A version string for your extension - doesn't need to follow a specific format. Required for publishing.
40
+
*/
41
version?: string;
42
+
43
+
/**
44
+
* The API level this extension targets. If it does not match the current version, the extension will not be loaded.
45
+
*/
46
apiLevel?: number;
47
+
48
+
/**
49
+
* Which environment this extension is capable of running in.
50
+
*/
51
environment?: ExtensionEnvironment;
52
53
+
/**
54
+
* Metadata about your extension for use in Moonbase.
55
+
*/
56
meta?: {
57
+
/**
58
+
* A human friendly name for your extension as a proper noun.
59
+
*/
60
name?: string;
61
+
62
+
/**
63
+
* A short tagline that appears below the name.
64
+
*/
65
tagline?: string;
66
+
67
+
/**
68
+
* A longer description that can use Markdown.
69
+
*/
70
description?: string;
71
+
72
+
/**
73
+
* List of authors that worked on this extension - accepts string or object with ID.
74
+
*/
75
authors?: ExtensionAuthor[];
76
+
77
+
/**
78
+
* A list of tags that are relevant to the extension.
79
+
*/
80
tags?: ExtensionTag[];
81
+
82
+
/**
83
+
* The URL to the source repository.
84
+
*/
85
source?: string;
86
+
87
+
/**
88
+
* A donation link (or other method of support). If you don't want financial contributions, consider putting your favorite charity here!
89
+
*/
90
+
donate?: string;
91
+
92
+
/**
93
+
* A changelog to show in Moonbase.
94
+
* Moonbase will show the changelog for the latest version, even if it is not installed.
95
+
*/
96
changelog?: string;
97
+
98
+
/**
99
+
* Whether the extension is deprecated and no longer receiving updates.
100
+
*/
101
+
deprecated?: boolean;
102
};
103
104
+
/**
105
+
* A list of extension IDs that are required for the extension to load.
106
+
*/
107
dependencies?: string[];
108
+
109
+
/**
110
+
* A list of extension IDs that the user may want to install.
111
+
*/
112
suggested?: string[];
113
+
114
+
/**
115
+
* A list of extension IDs that the extension is incompatible with.
116
+
* If two incompatible extensions are enabled, one of them will not load.
117
+
*/
118
incompatible?: string[];
119
120
+
/**
121
+
* A list of settings for your extension, where the key is the settings ID.
122
+
*/
123
settings?: Record<string, ExtensionSettingsManifest>;
124
125
+
/**
126
+
* A list of URLs to bypass CORS for.
127
+
* This is implemented by checking if the start of the URL matches.
128
+
* @example https://moonlight-mod.github.io/
129
+
*/
130
cors?: string[];
131
+
132
+
/**
133
+
* A list of URLs to block all requests to.
134
+
* This is implemented by checking if the start of the URL matches.
135
+
* @example https://moonlight-mod.github.io/
136
+
*/
137
blocked?: string[];
138
+
139
+
/**
140
+
* A mapping from CSP directives to URLs to allow.
141
+
* @example { "script-src": ["https://example.com"] }
142
+
*/
143
+
csp?: Record<string, string[]>;
144
};
145
146
export enum ExtensionEnvironment {
147
+
/**
148
+
* The extension will run on both platforms, the host/native modules MAY be loaded
149
+
*/
150
Both = "both",
151
+
152
+
/**
153
+
* Extension will run on desktop only, the host/native modules are guaranteed to load
154
+
*/
155
Desktop = "desktop",
156
+
157
+
/**
158
+
* Currently equivalent to Both
159
+
*/
160
Web = "web"
161
}
162
+11
-4
packages/types/src/globals.ts
+11
-4
packages/types/src/globals.ts
···
4
import type EventEmitter from "events";
5
import type LunAST from "@moonlight-mod/lunast";
6
import type Moonmap from "@moonlight-mod/moonmap";
7
-
import type { EventPayloads, EventType, MoonlightEventEmitter } from "./core/event";
8
-
import { MoonlightFS } from "./fs";
9
10
export type MoonlightHost = {
11
config: Config;
···
34
processedExtensions: ProcessedExtensions;
35
nativesCache: Record<string, any>;
36
isBrowser: boolean;
37
38
version: string;
39
branch: MoonlightBranch;
40
41
getConfig: (ext: string) => ConfigExtension["config"];
42
getConfigOption: <T>(ext: string, name: string) => T | undefined;
43
-
setConfigOption: <T>(ext: string, name: string, value: T) => void;
44
writeConfig: (config: Config) => Promise<void>;
45
46
getNatives: (ext: string) => any | undefined;
···
60
unpatched: Set<IdentifiedPatch>;
61
pendingModules: Set<IdentifiedWebpackModule>;
62
enabledExtensions: Set<string>;
63
-
events: MoonlightEventEmitter<EventType, EventPayloads>;
64
patchingInternals: {
65
onModuleLoad: (moduleId: string | string[], callback: (moduleId: string) => void) => void;
66
registerPatch: (patch: IdentifiedPatch) => void;
···
4
import type EventEmitter from "events";
5
import type LunAST from "@moonlight-mod/lunast";
6
import type Moonmap from "@moonlight-mod/moonmap";
7
+
import type {
8
+
WebEventPayloads,
9
+
WebEventType,
10
+
MoonlightEventEmitter,
11
+
NodeEventType,
12
+
NodeEventPayloads
13
+
} from "./core/event";
14
+
import type { MoonlightFS } from "./fs";
15
16
export type MoonlightHost = {
17
config: Config;
···
40
processedExtensions: ProcessedExtensions;
41
nativesCache: Record<string, any>;
42
isBrowser: boolean;
43
+
events: MoonlightEventEmitter<NodeEventType, NodeEventPayloads>;
44
45
version: string;
46
branch: MoonlightBranch;
47
48
getConfig: (ext: string) => ConfigExtension["config"];
49
getConfigOption: <T>(ext: string, name: string) => T | undefined;
50
+
setConfigOption: <T>(ext: string, name: string, value: T) => Promise<void>;
51
writeConfig: (config: Config) => Promise<void>;
52
53
getNatives: (ext: string) => any | undefined;
···
67
unpatched: Set<IdentifiedPatch>;
68
pendingModules: Set<IdentifiedWebpackModule>;
69
enabledExtensions: Set<string>;
70
+
events: MoonlightEventEmitter<WebEventType, WebEventPayloads>;
71
patchingInternals: {
72
onModuleLoad: (moduleId: string | string[], callback: (moduleId: string) => void) => void;
73
registerPatch: (patch: IdentifiedPatch) => void;
+32
packages/types/src/import.d.ts
+32
packages/types/src/import.d.ts
···
4
export = AppPanels;
5
}
6
7
+
declare module "@moonlight-mod/wp/commands_commands" {
8
+
import { CoreExtensions } from "@moonlight-mod/types";
9
+
export const commands: CoreExtensions.Commands.Commands;
10
+
export default commands;
11
+
}
12
+
13
+
declare module "@moonlight-mod/wp/common_ErrorBoundary" {
14
+
import { CoreExtensions } from "@moonlight-mod/types";
15
+
const ErrorBoundary: CoreExtensions.Common.ErrorBoundary;
16
+
export = ErrorBoundary;
17
+
}
18
+
declare module "@moonlight-mod/wp/common_icons" {
19
+
import { CoreExtensions } from "@moonlight-mod/types";
20
+
export const icons: CoreExtensions.Common.Icons;
21
+
export default icons;
22
+
}
23
declare module "@moonlight-mod/wp/common_stores";
24
+
25
+
declare module "@moonlight-mod/wp/componentEditor_dmList" {
26
+
import { CoreExtensions } from "@moonlight-mod/types";
27
+
export const dmList: CoreExtensions.ComponentEditor.DMList;
28
+
export default dmList;
29
+
}
30
+
declare module "@moonlight-mod/wp/componentEditor_memberList" {
31
+
import { CoreExtensions } from "@moonlight-mod/types";
32
+
export const memberList: CoreExtensions.ComponentEditor.MemberList;
33
+
export default memberList;
34
+
}
35
+
declare module "@moonlight-mod/wp/componentEditor_messages" {
36
+
import { CoreExtensions } from "@moonlight-mod/types";
37
+
export const message: CoreExtensions.ComponentEditor.Messages;
38
+
export default message;
39
+
}
40
41
declare module "@moonlight-mod/wp/contextMenu_evilMenu" {
42
import { CoreExtensions } from "@moonlight-mod/types";
+1
packages/types/src/index.ts
+1
packages/types/src/index.ts
···
32
var moonlightNode: MoonlightNode;
33
var moonlightNodeSandboxed: MoonlightNodeSandboxed;
34
var moonlight: MoonlightWeb;
35
+
var _moonlight_coreExtensionsStr: string;
36
37
var _moonlightBrowserInit: undefined | (() => Promise<void>);
38
var _moonlightWebLoad: undefined | (() => Promise<void>);
+841
-25
packages/types/src/mappings.d.ts
+841
-25
packages/types/src/mappings.d.ts
···
1
// auto-generated
2
declare module "@moonlight-mod/wp/discord/Dispatcher" {
3
import { MappedModules } from "@moonlight-mod/mappings";
4
-
const _: MappedModules["discord/Dispatcher"];
5
-
export = _;
6
}
7
8
declare module "@moonlight-mod/wp/discord/actions/ContextMenuActionCreators" {
9
import { MappedModules } from "@moonlight-mod/mappings";
10
-
const _: MappedModules["discord/actions/ContextMenuActionCreators"];
11
-
export = _;
12
}
13
14
declare module "@moonlight-mod/wp/discord/components/common/index" {
15
import { MappedModules } from "@moonlight-mod/mappings";
16
-
const _: MappedModules["discord/components/common/index"];
17
-
export = _;
18
}
19
20
-
declare module "@moonlight-mod/wp/discord/modules/guild_settings/IntegrationCard.css" {
21
import { MappedModules } from "@moonlight-mod/mappings";
22
-
const _: MappedModules["discord/modules/guild_settings/IntegrationCard.css"];
23
-
export = _;
24
}
25
26
declare module "@moonlight-mod/wp/discord/modules/markup/MarkupUtils" {
27
import { MappedModules } from "@moonlight-mod/mappings";
28
-
const _: MappedModules["discord/modules/markup/MarkupUtils"];
29
-
export = _;
30
}
31
32
-
declare module "@moonlight-mod/wp/discord/modules/user_settings/web/openUserSettings" {
33
import { MappedModules } from "@moonlight-mod/mappings";
34
-
const _: MappedModules["discord/modules/user_settings/web/openUserSettings"];
35
-
export = _;
36
}
37
38
declare module "@moonlight-mod/wp/discord/packages/flux" {
39
import { MappedModules } from "@moonlight-mod/mappings";
40
-
const _: MappedModules["discord/packages/flux"];
41
-
export = _;
42
}
43
44
declare module "@moonlight-mod/wp/discord/uikit/Flex" {
45
import { MappedModules } from "@moonlight-mod/mappings";
46
-
const _: MappedModules["discord/uikit/Flex"];
47
-
export = _;
48
}
49
50
declare module "@moonlight-mod/wp/discord/utils/ClipboardUtils" {
51
import { MappedModules } from "@moonlight-mod/mappings";
52
-
const _: MappedModules["discord/utils/ClipboardUtils"];
53
-
export = _;
54
}
55
56
declare module "@moonlight-mod/wp/discord/utils/HTTPUtils" {
57
import { MappedModules } from "@moonlight-mod/mappings";
58
-
const _: MappedModules["discord/utils/HTTPUtils"];
59
-
export = _;
60
}
61
62
declare module "@moonlight-mod/wp/discord/utils/NativeUtils" {
63
import { MappedModules } from "@moonlight-mod/mappings";
64
-
const _: MappedModules["discord/utils/NativeUtils"];
65
-
export = _;
66
}
67
68
declare module "@moonlight-mod/wp/react" {
69
import { MappedModules } from "@moonlight-mod/mappings";
70
-
const _: MappedModules["react"];
71
export = _;
72
}
···
1
// auto-generated
2
+
declare module "@moonlight-mod/wp/chroma-js" {}
3
+
4
+
declare module "@moonlight-mod/wp/classnames" {
5
+
import { MappedModules } from "@moonlight-mod/mappings";
6
+
const _default: MappedModules["classnames"]["default"];
7
+
export default _default;
8
+
}
9
+
10
+
declare module "@moonlight-mod/wp/dependency-graph" {
11
+
import { MappedModules } from "@moonlight-mod/mappings";
12
+
export const DepGraph: MappedModules["dependency-graph"]["DepGraph"];
13
+
}
14
+
15
+
declare module "@moonlight-mod/wp/discord/Constants" {
16
+
import { MappedModules } from "@moonlight-mod/mappings";
17
+
export const ActivityFlags: MappedModules["discord/Constants"]["ActivityFlags"];
18
+
export const ActivityTypes: MappedModules["discord/Constants"]["ActivityTypes"];
19
+
export const AnalyticsLocations: MappedModules["discord/Constants"]["AnalyticsLocations"];
20
+
export const ChannelLayouts: MappedModules["discord/Constants"]["ChannelLayouts"];
21
+
export const ChannelModes: MappedModules["discord/Constants"]["ChannelModes"];
22
+
export const ChannelTypes: MappedModules["discord/Constants"]["ChannelTypes"];
23
+
export const ChannelStreamTypes: MappedModules["discord/Constants"]["ChannelStreamTypes"];
24
+
export const ComponentActions: MappedModules["discord/Constants"]["ComponentActions"];
25
+
export const DEFAULT_ROLE_COLOR: MappedModules["discord/Constants"]["DEFAULT_ROLE_COLOR"];
26
+
export const Endpoints: MappedModules["discord/Constants"]["Endpoints"];
27
+
export const MessageFlags: MappedModules["discord/Constants"]["MessageFlags"];
28
+
export const MessageTypes: MappedModules["discord/Constants"]["MessageTypes"];
29
+
export const Permissions: MappedModules["discord/Constants"]["Permissions"];
30
+
export const PlatformTypes: MappedModules["discord/Constants"]["PlatformTypes"];
31
+
export const RelationshipTypes: MappedModules["discord/Constants"]["RelationshipTypes"];
32
+
export const Routes: MappedModules["discord/Constants"]["Routes"];
33
+
export const StatusTypes: MappedModules["discord/Constants"]["StatusTypes"];
34
+
export const Themes: MappedModules["discord/Constants"]["Themes"];
35
+
export const UserSettingsSections: MappedModules["discord/Constants"]["UserSettingsSections"];
36
+
export const UserFlags: MappedModules["discord/Constants"]["UserFlags"];
37
+
}
38
+
39
declare module "@moonlight-mod/wp/discord/Dispatcher" {
40
import { MappedModules } from "@moonlight-mod/mappings";
41
+
const _default: MappedModules["discord/Dispatcher"]["default"];
42
+
export default _default;
43
}
44
45
declare module "@moonlight-mod/wp/discord/actions/ContextMenuActionCreators" {
46
import { MappedModules } from "@moonlight-mod/mappings";
47
+
export const closeContextMenu: MappedModules["discord/actions/ContextMenuActionCreators"]["closeContextMenu"];
48
+
export const openContextMenu: MappedModules["discord/actions/ContextMenuActionCreators"]["openContextMenu"];
49
+
export const openContextMenuLazy: MappedModules["discord/actions/ContextMenuActionCreators"]["openContextMenuLazy"];
50
+
}
51
+
52
+
declare module "@moonlight-mod/wp/discord/actions/UserSettingsModalActionCreators" {
53
+
import { MappedModules } from "@moonlight-mod/mappings";
54
+
const _default: MappedModules["discord/actions/UserSettingsModalActionCreators"]["default"];
55
+
export default _default;
56
+
}
57
+
58
+
declare module "@moonlight-mod/wp/discord/common/AppStartPerformance" {
59
+
import { MappedModules } from "@moonlight-mod/mappings";
60
+
const _default: MappedModules["discord/common/AppStartPerformance"]["default"];
61
+
export default _default;
62
+
}
63
+
64
+
declare module "@moonlight-mod/wp/discord/components/common/Alerts" {
65
+
import { MappedModules } from "@moonlight-mod/mappings";
66
+
const _default: MappedModules["discord/components/common/Alerts"]["default"];
67
+
export default _default;
68
+
}
69
+
70
+
declare module "@moonlight-mod/wp/discord/components/common/BaseHeaderBar" {
71
+
import { MappedModules } from "@moonlight-mod/mappings";
72
+
export const Icon: MappedModules["discord/components/common/BaseHeaderBar"]["Icon"];
73
+
export const Divider: MappedModules["discord/components/common/BaseHeaderBar"]["Divider"];
74
+
const _default: MappedModules["discord/components/common/BaseHeaderBar"]["default"];
75
+
export default _default;
76
+
}
77
+
78
+
declare module "@moonlight-mod/wp/discord/components/common/Card" {
79
+
import { MappedModules } from "@moonlight-mod/mappings";
80
+
const _default: MappedModules["discord/components/common/Card"]["default"];
81
+
export default _default;
82
+
export const Types: MappedModules["discord/components/common/Card"]["Types"];
83
+
}
84
+
85
+
declare module "@moonlight-mod/wp/discord/components/common/FileUpload" {
86
+
import { MappedModules } from "@moonlight-mod/mappings";
87
+
const _default: MappedModules["discord/components/common/FileUpload"]["default"];
88
+
export default _default;
89
+
}
90
+
91
+
declare module "@moonlight-mod/wp/discord/components/common/FormSwitch.css" {
92
+
import { MappedModules } from "@moonlight-mod/mappings";
93
+
export const container: MappedModules["discord/components/common/FormSwitch.css"]["container"];
94
+
export const labelRow: MappedModules["discord/components/common/FormSwitch.css"]["labelRow"];
95
+
export const control: MappedModules["discord/components/common/FormSwitch.css"]["control"];
96
+
export const disabled: MappedModules["discord/components/common/FormSwitch.css"]["disabled"];
97
+
export const title: MappedModules["discord/components/common/FormSwitch.css"]["title"];
98
+
export const note: MappedModules["discord/components/common/FormSwitch.css"]["note"];
99
+
export const disabledText: MappedModules["discord/components/common/FormSwitch.css"]["disabledText"];
100
+
export const dividerDefault: MappedModules["discord/components/common/FormSwitch.css"]["dividerDefault"];
101
+
}
102
+
103
+
declare module "@moonlight-mod/wp/discord/components/common/HeaderBar.css" {
104
+
import { MappedModules } from "@moonlight-mod/mappings";
105
+
export const caret: MappedModules["discord/components/common/HeaderBar.css"]["caret"];
106
+
export const children: MappedModules["discord/components/common/HeaderBar.css"]["children"];
107
+
export const clickable: MappedModules["discord/components/common/HeaderBar.css"]["clickable"];
108
+
export const container: MappedModules["discord/components/common/HeaderBar.css"]["container"];
109
+
export const divider: MappedModules["discord/components/common/HeaderBar.css"]["divider"];
110
+
export const dot: MappedModules["discord/components/common/HeaderBar.css"]["dot"];
111
+
export const hamburger: MappedModules["discord/components/common/HeaderBar.css"]["hamburger"];
112
+
export const icon: MappedModules["discord/components/common/HeaderBar.css"]["icon"];
113
+
export const iconBadge: MappedModules["discord/components/common/HeaderBar.css"]["iconBadge"];
114
+
export const iconBadgeBottom: MappedModules["discord/components/common/HeaderBar.css"]["iconBadgeBottom"];
115
+
export const iconBadgeTop: MappedModules["discord/components/common/HeaderBar.css"]["iconBadgeTop"];
116
+
export const iconWrapper: MappedModules["discord/components/common/HeaderBar.css"]["iconWrapper"];
117
+
export const scrollable: MappedModules["discord/components/common/HeaderBar.css"]["scrollable"];
118
+
export const selected: MappedModules["discord/components/common/HeaderBar.css"]["selected"];
119
+
export const themed: MappedModules["discord/components/common/HeaderBar.css"]["themed"];
120
+
export const themedMobile: MappedModules["discord/components/common/HeaderBar.css"]["themedMobile"];
121
+
export const title: MappedModules["discord/components/common/HeaderBar.css"]["title"];
122
+
export const titleWrapper: MappedModules["discord/components/common/HeaderBar.css"]["titleWrapper"];
123
+
export const toolbar: MappedModules["discord/components/common/HeaderBar.css"]["toolbar"];
124
+
export const transparent: MappedModules["discord/components/common/HeaderBar.css"]["transparent"];
125
+
export const upperContainer: MappedModules["discord/components/common/HeaderBar.css"]["upperContainer"];
126
+
}
127
+
128
+
declare module "@moonlight-mod/wp/discord/components/common/HelpMessage.css" {
129
+
import { MappedModules } from "@moonlight-mod/mappings";
130
+
export const container: MappedModules["discord/components/common/HelpMessage.css"]["container"];
131
+
export const icon: MappedModules["discord/components/common/HelpMessage.css"]["icon"];
132
+
export const iconDiv: MappedModules["discord/components/common/HelpMessage.css"]["iconDiv"];
133
+
export const text: MappedModules["discord/components/common/HelpMessage.css"]["text"];
134
+
export const positive: MappedModules["discord/components/common/HelpMessage.css"]["positive"];
135
+
export const warning: MappedModules["discord/components/common/HelpMessage.css"]["warning"];
136
+
export const info: MappedModules["discord/components/common/HelpMessage.css"]["info"];
137
+
export const error: MappedModules["discord/components/common/HelpMessage.css"]["error"];
138
+
}
139
+
140
+
declare module "@moonlight-mod/wp/discord/components/common/Image" {}
141
+
142
+
declare module "@moonlight-mod/wp/discord/components/common/PanelButton" {
143
+
import { MappedModules } from "@moonlight-mod/mappings";
144
+
const _default: MappedModules["discord/components/common/PanelButton"]["default"];
145
+
export default _default;
146
+
}
147
+
148
+
declare module "@moonlight-mod/wp/discord/components/common/Scroller.css" {
149
+
import { MappedModules } from "@moonlight-mod/mappings";
150
+
export const auto: MappedModules["discord/components/common/Scroller.css"]["auto"];
151
+
export const content: MappedModules["discord/components/common/Scroller.css"]["content"];
152
+
export const customTheme: MappedModules["discord/components/common/Scroller.css"]["customTheme"];
153
+
export const disableScrollAnchor: MappedModules["discord/components/common/Scroller.css"]["disableScrollAnchor"];
154
+
export const fade: MappedModules["discord/components/common/Scroller.css"]["fade"];
155
+
export const managedReactiveScroller: MappedModules["discord/components/common/Scroller.css"]["managedReactiveScroller"];
156
+
export const none: MappedModules["discord/components/common/Scroller.css"]["none"];
157
+
export const pointerCover: MappedModules["discord/components/common/Scroller.css"]["pointerCover"];
158
+
export const scrolling: MappedModules["discord/components/common/Scroller.css"]["scrolling"];
159
+
export const thin: MappedModules["discord/components/common/Scroller.css"]["thin"];
160
}
161
162
declare module "@moonlight-mod/wp/discord/components/common/index" {
163
import { MappedModules } from "@moonlight-mod/mappings";
164
+
export const Clickable: MappedModules["discord/components/common/index"]["Clickable"];
165
+
export const TextInput: MappedModules["discord/components/common/index"]["TextInput"];
166
+
export const TextArea: MappedModules["discord/components/common/index"]["TextArea"];
167
+
export const FormDivider: MappedModules["discord/components/common/index"]["FormDivider"];
168
+
export const FormSection: MappedModules["discord/components/common/index"]["FormSection"];
169
+
export const FormText: MappedModules["discord/components/common/index"]["FormText"];
170
+
export const FormTitle: MappedModules["discord/components/common/index"]["FormTitle"];
171
+
export const FormSwitch: MappedModules["discord/components/common/index"]["FormSwitch"];
172
+
export const FormItem: MappedModules["discord/components/common/index"]["FormItem"];
173
+
export const Slider: MappedModules["discord/components/common/index"]["Slider"];
174
+
export const Switch: MappedModules["discord/components/common/index"]["Switch"];
175
+
export const Button: MappedModules["discord/components/common/index"]["Button"];
176
+
export const Tooltip: MappedModules["discord/components/common/index"]["Tooltip"];
177
+
export const Avatar: MappedModules["discord/components/common/index"]["Avatar"];
178
+
export const AvatarSizes: MappedModules["discord/components/common/index"]["AvatarSizes"];
179
+
export const AvatarSizeSpecs: MappedModules["discord/components/common/index"]["AvatarSizeSpecs"];
180
+
export const Scroller: MappedModules["discord/components/common/index"]["Scroller"];
181
+
export const Text: MappedModules["discord/components/common/index"]["Text"];
182
+
export const Heading: MappedModules["discord/components/common/index"]["Heading"];
183
+
export const Card: MappedModules["discord/components/common/index"]["Card"];
184
+
export const Popout: MappedModules["discord/components/common/index"]["Popout"];
185
+
export const Dialog: MappedModules["discord/components/common/index"]["Dialog"];
186
+
export const Menu: MappedModules["discord/components/common/index"]["Menu"];
187
+
export const TabBar: MappedModules["discord/components/common/index"]["TabBar"];
188
+
export const SingleSelect: MappedModules["discord/components/common/index"]["SingleSelect"];
189
+
export const Select: MappedModules["discord/components/common/index"]["Select"];
190
+
export const NoticeColors: MappedModules["discord/components/common/index"]["NoticeColors"];
191
+
export const Notice: MappedModules["discord/components/common/index"]["Notice"];
192
+
export const NoticeCloseButton: MappedModules["discord/components/common/index"]["NoticeCloseButton"];
193
+
export const PrimaryCTANoticeButton: MappedModules["discord/components/common/index"]["PrimaryCTANoticeButton"];
194
+
export const Breadcrumbs: MappedModules["discord/components/common/index"]["Breadcrumbs"];
195
+
export const Image: MappedModules["discord/components/common/index"]["Image"];
196
+
export const tokens: MappedModules["discord/components/common/index"]["tokens"];
197
+
export const useVariableSelect: MappedModules["discord/components/common/index"]["useVariableSelect"];
198
+
export const useMultiSelect: MappedModules["discord/components/common/index"]["useMultiSelect"];
199
+
export const multiSelect: MappedModules["discord/components/common/index"]["multiSelect"];
200
+
export const openModal: MappedModules["discord/components/common/index"]["openModal"];
201
+
export const openModalLazy: MappedModules["discord/components/common/index"]["openModalLazy"];
202
+
export const closeModal: MappedModules["discord/components/common/index"]["closeModal"];
203
+
export const AngleBracketsIcon: MappedModules["discord/components/common/index"]["AngleBracketsIcon"];
204
+
export const ArrowAngleLeftUpIcon: MappedModules["discord/components/common/index"]["ArrowAngleLeftUpIcon"];
205
+
export const ArrowAngleRightUpIcon: MappedModules["discord/components/common/index"]["ArrowAngleRightUpIcon"];
206
+
export const ArrowsUpDownIcon: MappedModules["discord/components/common/index"]["ArrowsUpDownIcon"];
207
+
export const BookCheckIcon: MappedModules["discord/components/common/index"]["BookCheckIcon"];
208
+
export const ChannelListIcon: MappedModules["discord/components/common/index"]["ChannelListIcon"];
209
+
export const ChevronSmallDownIcon: MappedModules["discord/components/common/index"]["ChevronSmallDownIcon"];
210
+
export const ChevronSmallUpIcon: MappedModules["discord/components/common/index"]["ChevronSmallUpIcon"];
211
+
export const CircleInformationIcon: MappedModules["discord/components/common/index"]["CircleInformationIcon"];
212
+
export const CircleWarningIcon: MappedModules["discord/components/common/index"]["CircleWarningIcon"];
213
+
export const CircleXIcon: MappedModules["discord/components/common/index"]["CircleXIcon"];
214
+
export const ClydeIcon: MappedModules["discord/components/common/index"]["ClydeIcon"];
215
+
export const CopyIcon: MappedModules["discord/components/common/index"]["CopyIcon"];
216
+
export const DownloadIcon: MappedModules["discord/components/common/index"]["DownloadIcon"];
217
+
export const FullscreenEnterIcon: MappedModules["discord/components/common/index"]["FullscreenEnterIcon"];
218
+
export const GameControllerIcon: MappedModules["discord/components/common/index"]["GameControllerIcon"];
219
+
export const GlobeEarthIcon: MappedModules["discord/components/common/index"]["GlobeEarthIcon"];
220
+
export const HeartIcon: MappedModules["discord/components/common/index"]["HeartIcon"];
221
+
export const LinkIcon: MappedModules["discord/components/common/index"]["LinkIcon"];
222
+
export const MaximizeIcon: MappedModules["discord/components/common/index"]["MaximizeIcon"];
223
+
export const MinusIcon: MappedModules["discord/components/common/index"]["MinusIcon"];
224
+
export const MobilePhoneIcon: MappedModules["discord/components/common/index"]["MobilePhoneIcon"];
225
+
export const PauseIcon: MappedModules["discord/components/common/index"]["PauseIcon"];
226
+
export const PlayIcon: MappedModules["discord/components/common/index"]["PlayIcon"];
227
+
export const PlusLargeIcon: MappedModules["discord/components/common/index"]["PlusLargeIcon"];
228
+
export const RetryIcon: MappedModules["discord/components/common/index"]["RetryIcon"];
229
+
export const ScienceIcon: MappedModules["discord/components/common/index"]["ScienceIcon"];
230
+
export const ScreenIcon: MappedModules["discord/components/common/index"]["ScreenIcon"];
231
+
export const StarIcon: MappedModules["discord/components/common/index"]["StarIcon"];
232
+
export const TrashIcon: MappedModules["discord/components/common/index"]["TrashIcon"];
233
+
export const WarningIcon: MappedModules["discord/components/common/index"]["WarningIcon"];
234
+
export const WindowLaunchIcon: MappedModules["discord/components/common/index"]["WindowLaunchIcon"];
235
+
export const WindowTopOutlineIcon: MappedModules["discord/components/common/index"]["WindowTopOutlineIcon"];
236
+
export const XLargeIcon: MappedModules["discord/components/common/index"]["XLargeIcon"];
237
+
export const XSmallIcon: MappedModules["discord/components/common/index"]["XSmallIcon"];
238
+
export const ConfirmModal: MappedModules["discord/components/common/index"]["ConfirmModal"];
239
+
export const H: MappedModules["discord/components/common/index"]["H"];
240
+
export const HelpMessage: MappedModules["discord/components/common/index"]["HelpMessage"];
241
+
export const ModalCloseButton: MappedModules["discord/components/common/index"]["ModalCloseButton"];
242
+
export const ModalContent: MappedModules["discord/components/common/index"]["ModalContent"];
243
+
export const ModalFooter: MappedModules["discord/components/common/index"]["ModalFooter"];
244
+
export const ModalHeader: MappedModules["discord/components/common/index"]["ModalHeader"];
245
+
export const ModalRoot: MappedModules["discord/components/common/index"]["ModalRoot"];
246
+
export const NumberInputStepper: MappedModules["discord/components/common/index"]["NumberInputStepper"];
247
+
export const SearchableSelect: MappedModules["discord/components/common/index"]["SearchableSelect"];
248
+
export const createToast: MappedModules["discord/components/common/index"]["createToast"];
249
+
export const popToast: MappedModules["discord/components/common/index"]["popToast"];
250
+
export const showToast: MappedModules["discord/components/common/index"]["showToast"];
251
+
export const useThemeContext: MappedModules["discord/components/common/index"]["useThemeContext"];
252
+
export const AccessibilityAnnouncer: MappedModules["discord/components/common/index"]["AccessibilityAnnouncer"];
253
+
export const BackdropStyles: MappedModules["discord/components/common/index"]["BackdropStyles"];
254
+
export const BadgeShapes: MappedModules["discord/components/common/index"]["BadgeShapes"];
255
+
export const CardTypes: MappedModules["discord/components/common/index"]["CardTypes"];
256
+
export const CircleIconButtonColors: MappedModules["discord/components/common/index"]["CircleIconButtonColors"];
257
+
export const CircleIconButtonSizes: MappedModules["discord/components/common/index"]["CircleIconButtonSizes"];
258
+
export const FormErrorBlockColors: MappedModules["discord/components/common/index"]["FormErrorBlockColors"];
259
+
export const FormNoticeImagePositions: MappedModules["discord/components/common/index"]["FormNoticeImagePositions"];
260
+
export const FormTitleTags: MappedModules["discord/components/common/index"]["FormTitleTags"];
261
+
export const HelpMessageTypes: MappedModules["discord/components/common/index"]["HelpMessageTypes"];
262
+
export const ModalSize: MappedModules["discord/components/common/index"]["ModalSize"];
263
+
export const ModalTransitionState: MappedModules["discord/components/common/index"]["ModalTransitionState"];
264
+
export const PRETTY_KEYS: MappedModules["discord/components/common/index"]["PRETTY_KEYS"];
265
+
export const SelectLooks: MappedModules["discord/components/common/index"]["SelectLooks"];
266
+
export const SpinnerTypes: MappedModules["discord/components/common/index"]["SpinnerTypes"];
267
+
export const StatusTypes: MappedModules["discord/components/common/index"]["StatusTypes"];
268
+
export const ToastPosition: MappedModules["discord/components/common/index"]["ToastPosition"];
269
+
export const ToastType: MappedModules["discord/components/common/index"]["ToastType"];
270
+
export const TransitionStates: MappedModules["discord/components/common/index"]["TransitionStates"];
271
+
export const DEFAULT_MODAL_CONTEXT: MappedModules["discord/components/common/index"]["DEFAULT_MODAL_CONTEXT"];
272
+
export const LOW_SATURATION_THRESHOLD: MappedModules["discord/components/common/index"]["LOW_SATURATION_THRESHOLD"];
273
+
export const LayerClassName: MappedModules["discord/components/common/index"]["LayerClassName"];
274
+
export const POPOUT_MODAL_CONTEXT: MappedModules["discord/components/common/index"]["POPOUT_MODAL_CONTEXT"];
275
}
276
277
+
declare module "@moonlight-mod/wp/discord/components/modals/ConfirmModal" {
278
import { MappedModules } from "@moonlight-mod/mappings";
279
+
const _default: MappedModules["discord/components/modals/ConfirmModal"]["default"];
280
+
export default _default;
281
+
}
282
+
283
+
declare module "@moonlight-mod/wp/discord/lib/BaseRecord" {
284
+
import { MappedModules } from "@moonlight-mod/mappings";
285
+
const _default: MappedModules["discord/lib/BaseRecord"]["default"];
286
+
export default _default;
287
+
}
288
+
289
+
declare module "@moonlight-mod/wp/discord/lib/web/Storage" {
290
+
import { MappedModules } from "@moonlight-mod/mappings";
291
+
export const ObjectStorage: MappedModules["discord/lib/web/Storage"]["ObjectStorage"];
292
+
export const impl: MappedModules["discord/lib/web/Storage"]["impl"];
293
+
}
294
+
295
+
declare module "@moonlight-mod/wp/discord/modules/build_overrides/web/BuildOverride.css" {
296
+
import { MappedModules } from "@moonlight-mod/mappings";
297
+
export const wrapper: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["wrapper"];
298
+
export const titleRegion: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["titleRegion"];
299
+
export const title: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["title"];
300
+
export const infoIcon: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["infoIcon"];
301
+
export const copyLink: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["copyLink"];
302
+
export const copied: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["copied"];
303
+
export const copyLinkIcon: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["copyLinkIcon"];
304
+
export const content: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["content"];
305
+
export const infoLink: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["infoLink"];
306
+
export const buildInfo: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["buildInfo"];
307
+
export const button: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["button"];
308
+
export const buttonSize: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["buttonSize"];
309
+
export const subHead: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["subHead"];
310
+
export const icon: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["icon"];
311
+
export const buildDetails: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["buildDetails"];
312
+
export const barLoader: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["barLoader"];
313
+
export const barTitle: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["barTitle"];
314
+
export const buttonLoader: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["buttonLoader"];
315
+
export const disabledButtonOverride: MappedModules["discord/modules/build_overrides/web/BuildOverride.css"]["disabledButtonOverride"];
316
+
}
317
+
318
+
declare module "@moonlight-mod/wp/discord/modules/discovery/web/Discovery.css" {
319
+
import { MappedModules } from "@moonlight-mod/mappings";
320
+
export const header: MappedModules["discord/modules/discovery/web/Discovery.css"]["header"];
321
+
export const headerImage: MappedModules["discord/modules/discovery/web/Discovery.css"]["headerImage"];
322
+
export const headerImageSimple: MappedModules["discord/modules/discovery/web/Discovery.css"]["headerImageSimple"];
323
+
export const headerImageBG: MappedModules["discord/modules/discovery/web/Discovery.css"]["headerImageBG"];
324
+
export const searchTitle: MappedModules["discord/modules/discovery/web/Discovery.css"]["searchTitle"];
325
+
export const searchSubtitle: MappedModules["discord/modules/discovery/web/Discovery.css"]["searchSubtitle"];
326
+
export const headerContentWrapper: MappedModules["discord/modules/discovery/web/Discovery.css"]["headerContentWrapper"];
327
+
export const headerContent: MappedModules["discord/modules/discovery/web/Discovery.css"]["headerContent"];
328
+
export const headerContentSmall: MappedModules["discord/modules/discovery/web/Discovery.css"]["headerContentSmall"];
329
+
export const searchBox: MappedModules["discord/modules/discovery/web/Discovery.css"]["searchBox"];
330
+
export const searchBoxInput: MappedModules["discord/modules/discovery/web/Discovery.css"]["searchBoxInput"];
331
+
export const closeIcon: MappedModules["discord/modules/discovery/web/Discovery.css"]["closeIcon"];
332
+
export const searchIcon: MappedModules["discord/modules/discovery/web/Discovery.css"]["searchIcon"];
333
+
export const tabBar: MappedModules["discord/modules/discovery/web/Discovery.css"]["tabBar"];
334
+
export const tabBarItem: MappedModules["discord/modules/discovery/web/Discovery.css"]["tabBarItem"];
335
+
export const sectionHeader: MappedModules["discord/modules/discovery/web/Discovery.css"]["sectionHeader"];
336
+
}
337
+
338
+
declare module "@moonlight-mod/wp/discord/modules/forums/web/Forums.css" {
339
+
import { MappedModules } from "@moonlight-mod/mappings";
340
+
export const container: MappedModules["discord/modules/forums/web/Forums.css"]["container"];
341
+
export const uploadArea: MappedModules["discord/modules/forums/web/Forums.css"]["uploadArea"];
342
+
export const label: MappedModules["discord/modules/forums/web/Forums.css"]["label"];
343
+
export const content: MappedModules["discord/modules/forums/web/Forums.css"]["content"];
344
+
export const noListContainer: MappedModules["discord/modules/forums/web/Forums.css"]["noListContainer"];
345
+
export const list: MappedModules["discord/modules/forums/web/Forums.css"]["list"];
346
+
export const grid: MappedModules["discord/modules/forums/web/Forums.css"]["grid"];
347
+
export const headerRow: MappedModules["discord/modules/forums/web/Forums.css"]["headerRow"];
348
+
export const card: MappedModules["discord/modules/forums/web/Forums.css"]["card"];
349
+
export const columnsSpan: MappedModules["discord/modules/forums/web/Forums.css"]["columnsSpan"];
350
+
export const emptyStateRow: MappedModules["discord/modules/forums/web/Forums.css"]["emptyStateRow"];
351
+
export const newMemberBanner: MappedModules["discord/modules/forums/web/Forums.css"]["newMemberBanner"];
352
+
export const gridViewBanner: MappedModules["discord/modules/forums/web/Forums.css"]["gridViewBanner"];
353
+
export const placeholder: MappedModules["discord/modules/forums/web/Forums.css"]["placeholder"];
354
+
export const mainCard: MappedModules["discord/modules/forums/web/Forums.css"]["mainCard"];
355
+
export const emptyMainCard: MappedModules["discord/modules/forums/web/Forums.css"]["emptyMainCard"];
356
+
export const outOfDate: MappedModules["discord/modules/forums/web/Forums.css"]["outOfDate"];
357
+
export const header: MappedModules["discord/modules/forums/web/Forums.css"]["header"];
358
+
export const matchingPostsRow: MappedModules["discord/modules/forums/web/Forums.css"]["matchingPostsRow"];
359
+
export const headerWithMatchingPosts: MappedModules["discord/modules/forums/web/Forums.css"]["headerWithMatchingPosts"];
360
+
export const noForm: MappedModules["discord/modules/forums/web/Forums.css"]["noForm"];
361
+
export const sortContainer: MappedModules["discord/modules/forums/web/Forums.css"]["sortContainer"];
362
+
export const sort: MappedModules["discord/modules/forums/web/Forums.css"]["sort"];
363
+
export const sortPopout: MappedModules["discord/modules/forums/web/Forums.css"]["sortPopout"];
364
+
export const archivedDividerRow: MappedModules["discord/modules/forums/web/Forums.css"]["archivedDividerRow"];
365
+
export const archivedDivider: MappedModules["discord/modules/forums/web/Forums.css"]["archivedDivider"];
366
+
export const newPostsButton: MappedModules["discord/modules/forums/web/Forums.css"]["newPostsButton"];
367
+
export const loadingCard: MappedModules["discord/modules/forums/web/Forums.css"]["loadingCard"];
368
+
export const enterIcon: MappedModules["discord/modules/forums/web/Forums.css"]["enterIcon"];
369
+
export const warnIcon: MappedModules["discord/modules/forums/web/Forums.css"]["warnIcon"];
370
+
export const searchIcon: MappedModules["discord/modules/forums/web/Forums.css"]["searchIcon"];
371
+
export const missingReadHistoryPermission: MappedModules["discord/modules/forums/web/Forums.css"]["missingReadHistoryPermission"];
372
+
export const divider: MappedModules["discord/modules/forums/web/Forums.css"]["divider"];
373
+
export const tagsContainer: MappedModules["discord/modules/forums/web/Forums.css"]["tagsContainer"];
374
+
export const filterIcon: MappedModules["discord/modules/forums/web/Forums.css"]["filterIcon"];
375
+
export const tagList: MappedModules["discord/modules/forums/web/Forums.css"]["tagList"];
376
+
export const tagListInner: MappedModules["discord/modules/forums/web/Forums.css"]["tagListInner"];
377
+
export const tag: MappedModules["discord/modules/forums/web/Forums.css"]["tag"];
378
+
export const tagsButton: MappedModules["discord/modules/forums/web/Forums.css"]["tagsButton"];
379
+
export const tagsButtonInner: MappedModules["discord/modules/forums/web/Forums.css"]["tagsButtonInner"];
380
+
export const tagsButtonPlaceholder: MappedModules["discord/modules/forums/web/Forums.css"]["tagsButtonPlaceholder"];
381
+
export const tagsButtonWithCount: MappedModules["discord/modules/forums/web/Forums.css"]["tagsButtonWithCount"];
382
+
export const sortDropdown: MappedModules["discord/modules/forums/web/Forums.css"]["sortDropdown"];
383
+
export const sortDropdownInner: MappedModules["discord/modules/forums/web/Forums.css"]["sortDropdownInner"];
384
+
export const sortDropdownText: MappedModules["discord/modules/forums/web/Forums.css"]["sortDropdownText"];
385
+
export const clear: MappedModules["discord/modules/forums/web/Forums.css"]["clear"];
386
+
export const matchingPosts: MappedModules["discord/modules/forums/web/Forums.css"]["matchingPosts"];
387
+
export const startPostHelp: MappedModules["discord/modules/forums/web/Forums.css"]["startPostHelp"];
388
+
export const tagsSpacer: MappedModules["discord/modules/forums/web/Forums.css"]["tagsSpacer"];
389
+
export const keyboardShortcut: MappedModules["discord/modules/forums/web/Forums.css"]["keyboardShortcut"];
390
+
export const key: MappedModules["discord/modules/forums/web/Forums.css"]["key"];
391
+
export const countContainer: MappedModules["discord/modules/forums/web/Forums.css"]["countContainer"];
392
+
export const countText: MappedModules["discord/modules/forums/web/Forums.css"]["countText"];
393
+
export const optInNotice: MappedModules["discord/modules/forums/web/Forums.css"]["optInNotice"];
394
+
}
395
+
396
+
declare module "@moonlight-mod/wp/discord/modules/forums/web/Header.css" {
397
+
import { MappedModules } from "@moonlight-mod/mappings";
398
+
export const container: MappedModules["discord/modules/forums/web/Header.css"]["container"];
399
+
export const header: MappedModules["discord/modules/forums/web/Header.css"]["header"];
400
+
export const headerLeft: MappedModules["discord/modules/forums/web/Header.css"]["headerLeft"];
401
+
export const headerText: MappedModules["discord/modules/forums/web/Header.css"]["headerText"];
402
+
export const countContainer: MappedModules["discord/modules/forums/web/Header.css"]["countContainer"];
403
+
export const countText: MappedModules["discord/modules/forums/web/Header.css"]["countText"];
404
+
export const tagContainer: MappedModules["discord/modules/forums/web/Header.css"]["tagContainer"];
405
+
export const tag: MappedModules["discord/modules/forums/web/Header.css"]["tag"];
406
+
export const clear: MappedModules["discord/modules/forums/web/Header.css"]["clear"];
407
+
export const row: MappedModules["discord/modules/forums/web/Header.css"]["row"];
408
+
export const separator: MappedModules["discord/modules/forums/web/Header.css"]["separator"];
409
+
}
410
+
411
+
declare module "@moonlight-mod/wp/discord/modules/forums/web/SortMenu.css" {
412
+
import { MappedModules } from "@moonlight-mod/mappings";
413
+
export const container: MappedModules["discord/modules/forums/web/SortMenu.css"]["container"];
414
+
export const clearText: MappedModules["discord/modules/forums/web/SortMenu.css"]["clearText"];
415
+
}
416
+
417
+
declare module "@moonlight-mod/wp/discord/modules/forums/web/Tag" {
418
+
import { MappedModules } from "@moonlight-mod/mappings";
419
+
const _default: MappedModules["discord/modules/forums/web/Tag"]["default"];
420
+
export default _default;
421
+
export const TagBar: MappedModules["discord/modules/forums/web/Tag"]["TagBar"];
422
+
}
423
+
424
+
declare module "@moonlight-mod/wp/discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css" {
425
+
import { MappedModules } from "@moonlight-mod/mappings";
426
+
export const addButton: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["addButton"];
427
+
export const container: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["container"];
428
+
export const emptyRowContainer: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["emptyRowContainer"];
429
+
export const emptyRowText: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["emptyRowText"];
430
+
export const headerContainer: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["headerContainer"];
431
+
export const list: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["list"];
432
+
export const memberDetails: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["memberDetails"];
433
+
export const memberRow: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["memberRow"];
434
+
export const removeButton: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["removeButton"];
435
+
export const removeButtonContainer: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["removeButtonContainer"];
436
+
export const removeButtonDisabled: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["removeButtonDisabled"];
437
+
export const removeTip: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["removeTip"];
438
+
export const searchContainer: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["searchContainer"];
439
+
export const searchWarning: MappedModules["discord/modules/guild_settings/roles/web/GuildSettingsRoleEdit.css"]["searchWarning"];
440
+
}
441
+
442
+
declare module "@moonlight-mod/wp/discord/modules/guild_settings/web/AppCard.css" {
443
+
import { MappedModules } from "@moonlight-mod/mappings";
444
+
export const card: MappedModules["discord/modules/guild_settings/web/AppCard.css"]["card"];
445
+
export const inModal: MappedModules["discord/modules/guild_settings/web/AppCard.css"]["inModal"];
446
+
export const cardHeader: MappedModules["discord/modules/guild_settings/web/AppCard.css"]["cardHeader"];
447
+
export const title: MappedModules["discord/modules/guild_settings/web/AppCard.css"]["title"];
448
+
}
449
+
450
+
declare module "@moonlight-mod/wp/discord/modules/guild_settings/web/AppCardItem.css" {
451
+
import { MappedModules } from "@moonlight-mod/mappings";
452
+
export const icon: MappedModules["discord/modules/guild_settings/web/AppCardItem.css"]["icon"];
453
+
export const identifier: MappedModules["discord/modules/guild_settings/web/AppCardItem.css"]["identifier"];
454
+
export const item: MappedModules["discord/modules/guild_settings/web/AppCardItem.css"]["item"];
455
+
export const statusContainer: MappedModules["discord/modules/guild_settings/web/AppCardItem.css"]["statusContainer"];
456
+
export const statusLine: MappedModules["discord/modules/guild_settings/web/AppCardItem.css"]["statusLine"];
457
+
export const statusIcon: MappedModules["discord/modules/guild_settings/web/AppCardItem.css"]["statusIcon"];
458
+
}
459
+
460
+
declare module "@moonlight-mod/wp/discord/modules/guild_settings/web/SearchSection.css" {
461
+
import { MappedModules } from "@moonlight-mod/mappings";
462
+
export const container: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["container"];
463
+
export const headerContainer: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["headerContainer"];
464
+
export const searchContainer: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["searchContainer"];
465
+
export const searchWarning: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["searchWarning"];
466
+
export const addButton: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["addButton"];
467
+
export const memberRow: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["memberRow"];
468
+
export const emptyRowContainer: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["emptyRowContainer"];
469
+
export const emptyRowText: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["emptyRowText"];
470
+
export const memberDetails: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["memberDetails"];
471
+
export const list: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["list"];
472
+
export const removeButtonContainer: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["removeButtonContainer"];
473
+
export const removeButton: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["removeButton"];
474
+
export const removeButtonDisabled: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["removeButtonDisabled"];
475
+
export const removeTip: MappedModules["discord/modules/guild_settings/web/SearchSection.css"]["removeTip"];
476
+
}
477
+
478
+
declare module "@moonlight-mod/wp/discord/modules/guild_sidebar/web/CategoryChannel.css" {
479
+
import { MappedModules } from "@moonlight-mod/mappings";
480
+
export const containerDefault: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["containerDefault"];
481
+
export const containerDragBefore: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["containerDragBefore"];
482
+
export const containerDragAfter: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["containerDragAfter"];
483
+
export const addButton: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["addButton"];
484
+
export const forceVisible: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["forceVisible"];
485
+
export const iconVisibility: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["iconVisibility"];
486
+
export const addButtonIcon: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["addButtonIcon"];
487
+
export const wrapper: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["wrapper"];
488
+
export const wrapperStatic: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["wrapperStatic"];
489
+
export const clickable: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["clickable"];
490
+
export const children: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["children"];
491
+
export const mainContent: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["mainContent"];
492
+
export const icon: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["icon"];
493
+
export const collapsed: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["collapsed"];
494
+
export const muted: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["muted"];
495
+
export const name: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["name"];
496
+
export const dismissWrapper: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["dismissWrapper"];
497
+
export const dismissButton: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["dismissButton"];
498
+
export const dismiss: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["dismiss"];
499
+
export const voiceChannelsButton: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["voiceChannelsButton"];
500
+
export const voiceChannelsToggleIcon: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["voiceChannelsToggleIcon"];
501
+
export const refreshVoiceChannelsButton: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["refreshVoiceChannelsButton"];
502
+
export const refreshVoiceChannelsButtonInner: MappedModules["discord/modules/guild_sidebar/web/CategoryChannel.css"]["refreshVoiceChannelsButtonInner"];
503
}
504
505
declare module "@moonlight-mod/wp/discord/modules/markup/MarkupUtils" {
506
import { MappedModules } from "@moonlight-mod/mappings";
507
+
const _default: MappedModules["discord/modules/markup/MarkupUtils"]["default"];
508
+
export default _default;
509
+
}
510
+
511
+
declare module "@moonlight-mod/wp/discord/modules/menus/web/Menu" {
512
+
import { MappedModules } from "@moonlight-mod/mappings";
513
+
export const MenuSpinner: MappedModules["discord/modules/menus/web/Menu"]["MenuSpinner"];
514
+
export const Menu: MappedModules["discord/modules/menus/web/Menu"]["Menu"];
515
+
}
516
+
517
+
declare module "@moonlight-mod/wp/discord/modules/messages/web/Markup.css" {
518
+
import { MappedModules } from "@moonlight-mod/mappings";
519
+
export const markup: MappedModules["discord/modules/messages/web/Markup.css"]["markup"];
520
+
export const inlineFormat: MappedModules["discord/modules/messages/web/Markup.css"]["inlineFormat"];
521
+
export const codeContainer: MappedModules["discord/modules/messages/web/Markup.css"]["codeContainer"];
522
+
export const codeActions: MappedModules["discord/modules/messages/web/Markup.css"]["codeActions"];
523
+
export const blockquoteContainer: MappedModules["discord/modules/messages/web/Markup.css"]["blockquoteContainer"];
524
+
export const blockquoteDivider: MappedModules["discord/modules/messages/web/Markup.css"]["blockquoteDivider"];
525
+
export const slateBlockquoteContainer: MappedModules["discord/modules/messages/web/Markup.css"]["slateBlockquoteContainer"];
526
+
export const roleMention: MappedModules["discord/modules/messages/web/Markup.css"]["roleMention"];
527
+
export const rolePopout: MappedModules["discord/modules/messages/web/Markup.css"]["rolePopout"];
528
+
export const roleHeader: MappedModules["discord/modules/messages/web/Markup.css"]["roleHeader"];
529
+
export const roleScroller: MappedModules["discord/modules/messages/web/Markup.css"]["roleScroller"];
530
+
export const timestamp: MappedModules["discord/modules/messages/web/Markup.css"]["timestamp"];
531
+
export const timestampTooltip: MappedModules["discord/modules/messages/web/Markup.css"]["timestampTooltip"];
532
+
}
533
+
534
+
declare module "@moonlight-mod/wp/discord/modules/messages/web/Message.css" {
535
+
import { MappedModules } from "@moonlight-mod/mappings";
536
+
export const wrapper: MappedModules["discord/modules/messages/web/Message.css"]["wrapper"];
537
+
export const compact: MappedModules["discord/modules/messages/web/Message.css"]["compact"];
538
+
export const cozy: MappedModules["discord/modules/messages/web/Message.css"]["cozy"];
539
+
export const contentOnly: MappedModules["discord/modules/messages/web/Message.css"]["contentOnly"];
540
+
export const repliedMessage: MappedModules["discord/modules/messages/web/Message.css"]["repliedMessage"];
541
+
export const threadMessageAccessory: MappedModules["discord/modules/messages/web/Message.css"]["threadMessageAccessory"];
542
+
export const executedCommand: MappedModules["discord/modules/messages/web/Message.css"]["executedCommand"];
543
+
export const latin12CompactTimeStamp: MappedModules["discord/modules/messages/web/Message.css"]["latin12CompactTimeStamp"];
544
+
export const latin24CompactTimeStamp: MappedModules["discord/modules/messages/web/Message.css"]["latin24CompactTimeStamp"];
545
+
export const asianCompactTimeStamp: MappedModules["discord/modules/messages/web/Message.css"]["asianCompactTimeStamp"];
546
+
export const contextCommandMessage: MappedModules["discord/modules/messages/web/Message.css"]["contextCommandMessage"];
547
+
export const messageSpine: MappedModules["discord/modules/messages/web/Message.css"]["messageSpine"];
548
+
export const repliedMessageClickableSpine: MappedModules["discord/modules/messages/web/Message.css"]["repliedMessageClickableSpine"];
549
+
export const repliedMessageContentHovered: MappedModules["discord/modules/messages/web/Message.css"]["repliedMessageContentHovered"];
550
+
export const threadMessageAccessoryAvatar: MappedModules["discord/modules/messages/web/Message.css"]["threadMessageAccessoryAvatar"];
551
+
export const replyAvatar: MappedModules["discord/modules/messages/web/Message.css"]["replyAvatar"];
552
+
export const replyBadge: MappedModules["discord/modules/messages/web/Message.css"]["replyBadge"];
553
+
export const executedCommandAvatar: MappedModules["discord/modules/messages/web/Message.css"]["executedCommandAvatar"];
554
+
export const replyChatIconContainer: MappedModules["discord/modules/messages/web/Message.css"]["replyChatIconContainer"];
555
+
export const replyIcon: MappedModules["discord/modules/messages/web/Message.css"]["replyIcon"];
556
+
export const clanTagChiplet: MappedModules["discord/modules/messages/web/Message.css"]["clanTagChiplet"];
557
+
export const userJoinSystemMessageIcon: MappedModules["discord/modules/messages/web/Message.css"]["userJoinSystemMessageIcon"];
558
+
export const ticketIcon: MappedModules["discord/modules/messages/web/Message.css"]["ticketIcon"];
559
+
export const commandIcon: MappedModules["discord/modules/messages/web/Message.css"]["commandIcon"];
560
+
export const username: MappedModules["discord/modules/messages/web/Message.css"]["username"];
561
+
export const roleDot: MappedModules["discord/modules/messages/web/Message.css"]["roleDot"];
562
+
export const commandName: MappedModules["discord/modules/messages/web/Message.css"]["commandName"];
563
+
export const appsIcon: MappedModules["discord/modules/messages/web/Message.css"]["appsIcon"];
564
+
export const appLauncherOnboardingCommandName: MappedModules["discord/modules/messages/web/Message.css"]["appLauncherOnboardingCommandName"];
565
+
export const targetUsername: MappedModules["discord/modules/messages/web/Message.css"]["targetUsername"];
566
+
export const executedCommandSeparator: MappedModules["discord/modules/messages/web/Message.css"]["executedCommandSeparator"];
567
+
export const repliedTextPreview: MappedModules["discord/modules/messages/web/Message.css"]["repliedTextPreview"];
568
+
export const threadMessageAccessoryPreview: MappedModules["discord/modules/messages/web/Message.css"]["threadMessageAccessoryPreview"];
569
+
export const repliedTextContent: MappedModules["discord/modules/messages/web/Message.css"]["repliedTextContent"];
570
+
export const clickable: MappedModules["discord/modules/messages/web/Message.css"]["clickable"];
571
+
export const repliedMessageClickableSpineHovered: MappedModules["discord/modules/messages/web/Message.css"]["repliedMessageClickableSpineHovered"];
572
+
export const threadMessageAccessoryContent: MappedModules["discord/modules/messages/web/Message.css"]["threadMessageAccessoryContent"];
573
+
export const repliedTextPlaceholder: MappedModules["discord/modules/messages/web/Message.css"]["repliedTextPlaceholder"];
574
+
export const threadMessageAccessoryPlaceholder: MappedModules["discord/modules/messages/web/Message.css"]["threadMessageAccessoryPlaceholder"];
575
+
export const repliedTextContentTrailingIcon: MappedModules["discord/modules/messages/web/Message.css"]["repliedTextContentTrailingIcon"];
576
+
export const threadMessageAccessoryContentTrailingIcon: MappedModules["discord/modules/messages/web/Message.css"]["threadMessageAccessoryContentTrailingIcon"];
577
+
export const repliedTextContentLeadingIcon: MappedModules["discord/modules/messages/web/Message.css"]["repliedTextContentLeadingIcon"];
578
+
export const threadMessageAccessoryContentLeadingIcon: MappedModules["discord/modules/messages/web/Message.css"]["threadMessageAccessoryContentLeadingIcon"];
579
+
export const contents: MappedModules["discord/modules/messages/web/Message.css"]["contents"];
580
+
export const zalgo: MappedModules["discord/modules/messages/web/Message.css"]["zalgo"];
581
+
export const messageContent: MappedModules["discord/modules/messages/web/Message.css"]["messageContent"];
582
+
export const header: MappedModules["discord/modules/messages/web/Message.css"]["header"];
583
+
export const buttonContainer: MappedModules["discord/modules/messages/web/Message.css"]["buttonContainer"];
584
+
export const avatar: MappedModules["discord/modules/messages/web/Message.css"]["avatar"];
585
+
export const avatarDecoration: MappedModules["discord/modules/messages/web/Message.css"]["avatarDecoration"];
586
+
export const roleIcon: MappedModules["discord/modules/messages/web/Message.css"]["roleIcon"];
587
+
export const timestamp: MappedModules["discord/modules/messages/web/Message.css"]["timestamp"];
588
+
export const timestampInline: MappedModules["discord/modules/messages/web/Message.css"]["timestampInline"];
589
+
export const alt: MappedModules["discord/modules/messages/web/Message.css"]["alt"];
590
+
export const timestampTooltip: MappedModules["discord/modules/messages/web/Message.css"]["timestampTooltip"];
591
+
export const timestampVisibleOnHover: MappedModules["discord/modules/messages/web/Message.css"]["timestampVisibleOnHover"];
592
+
export const nitroAuthorBadgeTootip: MappedModules["discord/modules/messages/web/Message.css"]["nitroAuthorBadgeTootip"];
593
+
export const headerText: MappedModules["discord/modules/messages/web/Message.css"]["headerText"];
594
+
export const hasRoleIcon: MappedModules["discord/modules/messages/web/Message.css"]["hasRoleIcon"];
595
+
export const hasBadges: MappedModules["discord/modules/messages/web/Message.css"]["hasBadges"];
596
+
export const botTagCompact: MappedModules["discord/modules/messages/web/Message.css"]["botTagCompact"];
597
+
export const botTagCozy: MappedModules["discord/modules/messages/web/Message.css"]["botTagCozy"];
598
+
export const nitroBadgeSvg: MappedModules["discord/modules/messages/web/Message.css"]["nitroBadgeSvg"];
599
+
export const nitroAuthorBadgeContainer: MappedModules["discord/modules/messages/web/Message.css"]["nitroAuthorBadgeContainer"];
600
+
export const separator: MappedModules["discord/modules/messages/web/Message.css"]["separator"];
601
+
export const hasThread: MappedModules["discord/modules/messages/web/Message.css"]["hasThread"];
602
+
export const isSystemMessage: MappedModules["discord/modules/messages/web/Message.css"]["isSystemMessage"];
603
+
export const hasReply: MappedModules["discord/modules/messages/web/Message.css"]["hasReply"];
604
+
export const markupRtl: MappedModules["discord/modules/messages/web/Message.css"]["markupRtl"];
605
+
export const isSending: MappedModules["discord/modules/messages/web/Message.css"]["isSending"];
606
+
export const isFailed: MappedModules["discord/modules/messages/web/Message.css"]["isFailed"];
607
+
export const isUnsupported: MappedModules["discord/modules/messages/web/Message.css"]["isUnsupported"];
608
+
export const edited: MappedModules["discord/modules/messages/web/Message.css"]["edited"];
609
+
export const communicationDisabled: MappedModules["discord/modules/messages/web/Message.css"]["communicationDisabled"];
610
+
export const compactCommunicationDisabled: MappedModules["discord/modules/messages/web/Message.css"]["compactCommunicationDisabled"];
611
+
export const communicationDisabledOpacity: MappedModules["discord/modules/messages/web/Message.css"]["communicationDisabledOpacity"];
612
+
export const badgesContainer: MappedModules["discord/modules/messages/web/Message.css"]["badgesContainer"];
613
}
614
615
+
declare module "@moonlight-mod/wp/discord/modules/modals/Modals" {
616
import { MappedModules } from "@moonlight-mod/mappings";
617
+
export const closeAllModals: MappedModules["discord/modules/modals/Modals"]["closeAllModals"];
618
+
export const closeAllModalsForContext: MappedModules["discord/modules/modals/Modals"]["closeAllModalsForContext"];
619
+
export const closeModal: MappedModules["discord/modules/modals/Modals"]["closeModal"];
620
+
export const getInteractingModalContext: MappedModules["discord/modules/modals/Modals"]["getInteractingModalContext"];
621
+
export const hasAnyModalOpen: MappedModules["discord/modules/modals/Modals"]["hasAnyModalOpen"];
622
+
export const hasAnyModalOpenSelector: MappedModules["discord/modules/modals/Modals"]["hasAnyModalOpenSelector"];
623
+
export const hasModalOpen: MappedModules["discord/modules/modals/Modals"]["hasModalOpen"];
624
+
export const hasModalOpenSelector: MappedModules["discord/modules/modals/Modals"]["hasModalOpenSelector"];
625
+
export const openModal: MappedModules["discord/modules/modals/Modals"]["openModal"];
626
+
export const openModalLazy: MappedModules["discord/modules/modals/Modals"]["openModalLazy"];
627
+
export const updateModal: MappedModules["discord/modules/modals/Modals"]["updateModal"];
628
+
export const useHasAnyModalOpen: MappedModules["discord/modules/modals/Modals"]["useHasAnyModalOpen"];
629
+
export const useIsModalAtTop: MappedModules["discord/modules/modals/Modals"]["useIsModalAtTop"];
630
+
export const useModalsStore: MappedModules["discord/modules/modals/Modals"]["useModalsStore"];
631
+
}
632
+
633
+
declare module "@moonlight-mod/wp/discord/modules/oauth2/index" {
634
+
import { MappedModules } from "@moonlight-mod/mappings";
635
+
export const OAuth2AuthorizeModal: MappedModules["discord/modules/oauth2/index"]["OAuth2AuthorizeModal"];
636
+
export const OAuth2AuthorizePage: MappedModules["discord/modules/oauth2/index"]["OAuth2AuthorizePage"];
637
+
export const getOAuth2AuthorizeProps: MappedModules["discord/modules/oauth2/index"]["getOAuth2AuthorizeProps"];
638
+
export const openOAuth2Modal: MappedModules["discord/modules/oauth2/index"]["openOAuth2Modal"];
639
+
export const openOAuth2ModalWithCreateGuildModal: MappedModules["discord/modules/oauth2/index"]["openOAuth2ModalWithCreateGuildModal"];
640
+
export const useOAuth2AuthorizeForm: MappedModules["discord/modules/oauth2/index"]["useOAuth2AuthorizeForm"];
641
+
}
642
+
643
+
declare module "@moonlight-mod/wp/discord/modules/people/web/PeoplePage.css" {
644
+
import { MappedModules } from "@moonlight-mod/mappings";
645
+
export const addFriend: MappedModules["discord/modules/people/web/PeoplePage.css"]["addFriend"];
646
+
export const badge: MappedModules["discord/modules/people/web/PeoplePage.css"]["badge"];
647
+
export const container: MappedModules["discord/modules/people/web/PeoplePage.css"]["container"];
648
+
export const inviteToolbar: MappedModules["discord/modules/people/web/PeoplePage.css"]["inviteToolbar"];
649
+
export const item: MappedModules["discord/modules/people/web/PeoplePage.css"]["item"];
650
+
export const nowPlayingColumn: MappedModules["discord/modules/people/web/PeoplePage.css"]["nowPlayingColumn"];
651
+
export const peopleColumn: MappedModules["discord/modules/people/web/PeoplePage.css"]["peopleColumn"];
652
+
export const tabBar: MappedModules["discord/modules/people/web/PeoplePage.css"]["tabBar"];
653
+
export const tabBody: MappedModules["discord/modules/people/web/PeoplePage.css"]["tabBody"];
654
+
}
655
+
656
+
declare module "@moonlight-mod/wp/discord/modules/user_profile/web/BiteSizeActivity.css" {
657
+
import { MappedModules } from "@moonlight-mod/mappings";
658
+
export const header: MappedModules["discord/modules/user_profile/web/BiteSizeActivity.css"]["header"];
659
+
export const headerTag: MappedModules["discord/modules/user_profile/web/BiteSizeActivity.css"]["headerTag"];
660
+
export const body: MappedModules["discord/modules/user_profile/web/BiteSizeActivity.css"]["body"];
661
+
export const footer: MappedModules["discord/modules/user_profile/web/BiteSizeActivity.css"]["footer"];
662
+
export const backdrop: MappedModules["discord/modules/user_profile/web/BiteSizeActivity.css"]["backdrop"];
663
+
export const toast: MappedModules["discord/modules/user_profile/web/BiteSizeActivity.css"]["toast"];
664
+
export const activity: MappedModules["discord/modules/user_profile/web/BiteSizeActivity.css"]["activity"];
665
+
export const upsell: MappedModules["discord/modules/user_profile/web/BiteSizeActivity.css"]["upsell"];
666
}
667
668
declare module "@moonlight-mod/wp/discord/packages/flux" {
669
import { MappedModules } from "@moonlight-mod/mappings";
670
+
export const BatchedStoreListener: MappedModules["discord/packages/flux"]["BatchedStoreListener"];
671
+
export const Dispatcher: MappedModules["discord/packages/flux"]["Dispatcher"];
672
+
export const Store: MappedModules["discord/packages/flux"]["Store"];
673
+
const _default: MappedModules["discord/packages/flux"]["default"];
674
+
export default _default;
675
+
export const statesWillNeverBeEqual: MappedModules["discord/packages/flux"]["statesWillNeverBeEqual"];
676
+
export const useStateFromStores: MappedModules["discord/packages/flux"]["useStateFromStores"];
677
+
export const useStateFromStoresArray: MappedModules["discord/packages/flux"]["useStateFromStoresArray"];
678
+
export const useStateFromStoresObject: MappedModules["discord/packages/flux"]["useStateFromStoresObject"];
679
+
}
680
+
681
+
declare module "@moonlight-mod/wp/discord/packages/flux/BatchedStoreListener" {
682
+
import { MappedModules } from "@moonlight-mod/mappings";
683
+
const _default: MappedModules["discord/packages/flux/BatchedStoreListener"]["default"];
684
+
export default _default;
685
+
}
686
+
687
+
declare module "@moonlight-mod/wp/discord/packages/flux/ChangeListeners" {
688
+
import { MappedModules } from "@moonlight-mod/mappings";
689
+
const _default: MappedModules["discord/packages/flux/ChangeListeners"]["default"];
690
+
export default _default;
691
+
}
692
+
693
+
declare module "@moonlight-mod/wp/discord/packages/flux/Dispatcher" {
694
+
import { MappedModules } from "@moonlight-mod/mappings";
695
+
export const Dispatcher: MappedModules["discord/packages/flux/Dispatcher"]["Dispatcher"];
696
+
}
697
+
698
+
declare module "@moonlight-mod/wp/discord/packages/flux/Emitter" {
699
+
import { MappedModules } from "@moonlight-mod/mappings";
700
+
const _default: MappedModules["discord/packages/flux/Emitter"]["default"];
701
+
export default _default;
702
+
}
703
+
704
+
declare module "@moonlight-mod/wp/discord/packages/flux/LoggingUtils" {
705
+
import { MappedModules } from "@moonlight-mod/mappings";
706
+
const _default: MappedModules["discord/packages/flux/LoggingUtils"]["default"];
707
+
export default _default;
708
+
}
709
+
710
+
declare module "@moonlight-mod/wp/discord/packages/flux/PersistedStore" {
711
+
import { MappedModules } from "@moonlight-mod/mappings";
712
+
export const PersistedStore: MappedModules["discord/packages/flux/PersistedStore"]["PersistedStore"];
713
+
}
714
+
715
+
declare module "@moonlight-mod/wp/discord/packages/flux/Store" {
716
+
import { MappedModules } from "@moonlight-mod/mappings";
717
+
export const Store: MappedModules["discord/packages/flux/Store"]["Store"];
718
+
}
719
+
720
+
declare module "@moonlight-mod/wp/discord/packages/flux/connectStores" {
721
+
import { MappedModules } from "@moonlight-mod/mappings";
722
+
const _default: MappedModules["discord/packages/flux/connectStores"]["default"];
723
+
export default _default;
724
+
}
725
+
726
+
declare module "@moonlight-mod/wp/discord/records/UserRecord" {
727
+
import { MappedModules } from "@moonlight-mod/mappings";
728
+
const _default: MappedModules["discord/records/UserRecord"]["default"];
729
+
export default _default;
730
+
}
731
+
732
+
declare module "@moonlight-mod/wp/discord/styles/shared/Margins.css" {
733
+
import { MappedModules } from "@moonlight-mod/mappings";
734
+
export const marginReset: MappedModules["discord/styles/shared/Margins.css"]["marginReset"];
735
+
export const marginTop4: MappedModules["discord/styles/shared/Margins.css"]["marginTop4"];
736
+
export const marginBottom4: MappedModules["discord/styles/shared/Margins.css"]["marginBottom4"];
737
+
export const marginTop8: MappedModules["discord/styles/shared/Margins.css"]["marginTop8"];
738
+
export const marginBottom8: MappedModules["discord/styles/shared/Margins.css"]["marginBottom8"];
739
+
export const marginTop20: MappedModules["discord/styles/shared/Margins.css"]["marginTop20"];
740
+
export const marginBottom20: MappedModules["discord/styles/shared/Margins.css"]["marginBottom20"];
741
+
export const marginTop40: MappedModules["discord/styles/shared/Margins.css"]["marginTop40"];
742
+
export const marginBottom40: MappedModules["discord/styles/shared/Margins.css"]["marginBottom40"];
743
+
export const marginTop60: MappedModules["discord/styles/shared/Margins.css"]["marginTop60"];
744
+
export const marginBottom60: MappedModules["discord/styles/shared/Margins.css"]["marginBottom60"];
745
+
export const marginCenterHorz: MappedModules["discord/styles/shared/Margins.css"]["marginCenterHorz"];
746
+
export const marginLeft8: MappedModules["discord/styles/shared/Margins.css"]["marginLeft8"];
747
}
748
749
declare module "@moonlight-mod/wp/discord/uikit/Flex" {
750
import { MappedModules } from "@moonlight-mod/mappings";
751
+
const _default: MappedModules["discord/uikit/Flex"]["default"];
752
+
export default _default;
753
}
754
755
declare module "@moonlight-mod/wp/discord/utils/ClipboardUtils" {
756
import { MappedModules } from "@moonlight-mod/mappings";
757
+
export const SUPPORTS_COPY: MappedModules["discord/utils/ClipboardUtils"]["SUPPORTS_COPY"];
758
+
export const copy: MappedModules["discord/utils/ClipboardUtils"]["copy"];
759
+
}
760
+
761
+
declare module "@moonlight-mod/wp/discord/utils/ComponentDispatchUtils" {
762
+
import { MappedModules } from "@moonlight-mod/mappings";
763
+
export const ComponentDispatcher: MappedModules["discord/utils/ComponentDispatchUtils"]["ComponentDispatcher"];
764
+
export const ComponentDispatch: MappedModules["discord/utils/ComponentDispatchUtils"]["ComponentDispatch"];
765
}
766
767
declare module "@moonlight-mod/wp/discord/utils/HTTPUtils" {
768
import { MappedModules } from "@moonlight-mod/mappings";
769
+
export const HTTP: MappedModules["discord/utils/HTTPUtils"]["HTTP"];
770
+
}
771
+
772
+
declare module "@moonlight-mod/wp/discord/utils/MaskedLinkUtils" {
773
+
import { MappedModules } from "@moonlight-mod/mappings";
774
+
export const isLinkTrusted: MappedModules["discord/utils/MaskedLinkUtils"]["isLinkTrusted"];
775
+
export const handleClick: MappedModules["discord/utils/MaskedLinkUtils"]["handleClick"];
776
}
777
778
declare module "@moonlight-mod/wp/discord/utils/NativeUtils" {
779
import { MappedModules } from "@moonlight-mod/mappings";
780
+
const _default: MappedModules["discord/utils/NativeUtils"]["default"];
781
+
export default _default;
782
+
}
783
+
784
+
declare module "@moonlight-mod/wp/highlight.js" {
785
+
import { MappedModules } from "@moonlight-mod/mappings";
786
+
export const highlight: MappedModules["highlight.js"]["highlight"];
787
+
export const highlightAuto: MappedModules["highlight.js"]["highlightAuto"];
788
+
export const fixMarkup: MappedModules["highlight.js"]["fixMarkup"];
789
+
export const highlightBlock: MappedModules["highlight.js"]["highlightBlock"];
790
+
export const configure: MappedModules["highlight.js"]["configure"];
791
+
export const initHighlighting: MappedModules["highlight.js"]["initHighlighting"];
792
+
export const initHighlightingOnLoad: MappedModules["highlight.js"]["initHighlightingOnLoad"];
793
+
export const registerLanguage: MappedModules["highlight.js"]["registerLanguage"];
794
+
export const listLanguages: MappedModules["highlight.js"]["listLanguages"];
795
+
export const getLanguage: MappedModules["highlight.js"]["getLanguage"];
796
+
export const inherit: MappedModules["highlight.js"]["inherit"];
797
+
export const COMMENT: MappedModules["highlight.js"]["COMMENT"];
798
+
export const IDENT_RE: MappedModules["highlight.js"]["IDENT_RE"];
799
+
export const UNDERSCORE_IDENT_RE: MappedModules["highlight.js"]["UNDERSCORE_IDENT_RE"];
800
+
export const NUMBER_RE: MappedModules["highlight.js"]["NUMBER_RE"];
801
+
export const C_NUMBER_RE: MappedModules["highlight.js"]["C_NUMBER_RE"];
802
+
export const BINARY_NUMBER_RE: MappedModules["highlight.js"]["BINARY_NUMBER_RE"];
803
+
export const RE_STARTERS_RE: MappedModules["highlight.js"]["RE_STARTERS_RE"];
804
+
export const BACKSLASH_ESCAPE: MappedModules["highlight.js"]["BACKSLASH_ESCAPE"];
805
+
export const APOS_STRING_MODE: MappedModules["highlight.js"]["APOS_STRING_MODE"];
806
+
export const QUOTE_STRING_MODE: MappedModules["highlight.js"]["QUOTE_STRING_MODE"];
807
+
export const PHRASAL_WORDS_MODE: MappedModules["highlight.js"]["PHRASAL_WORDS_MODE"];
808
+
export const C_LINE_COMMENT_MODE: MappedModules["highlight.js"]["C_LINE_COMMENT_MODE"];
809
+
export const C_BLOCK_COMMENT_MODE: MappedModules["highlight.js"]["C_BLOCK_COMMENT_MODE"];
810
+
export const HASH_COMMENT_MODE: MappedModules["highlight.js"]["HASH_COMMENT_MODE"];
811
+
export const NUMBER_MODE: MappedModules["highlight.js"]["NUMBER_MODE"];
812
+
export const C_NUMBER_MODE: MappedModules["highlight.js"]["C_NUMBER_MODE"];
813
+
export const BINARY_NUMBER_MODE: MappedModules["highlight.js"]["BINARY_NUMBER_MODE"];
814
+
export const CSS_NUMBER_MODE: MappedModules["highlight.js"]["CSS_NUMBER_MODE"];
815
+
export const REGEX_MODE: MappedModules["highlight.js"]["REGEX_MODE"];
816
+
export const TITLE_MODE: MappedModules["highlight.js"]["TITLE_MODE"];
817
+
export const UNDERSCORE_TITLE_MODE: MappedModules["highlight.js"]["UNDERSCORE_TITLE_MODE"];
818
+
const _default: MappedModules["highlight.js"]["default"];
819
+
export default _default;
820
+
export const HighlightJS: MappedModules["highlight.js"]["HighlightJS"];
821
+
}
822
+
823
+
declare module "@moonlight-mod/wp/highlight.js/lib/core" {
824
+
import { MappedModules } from "@moonlight-mod/mappings";
825
+
export const highlight: MappedModules["highlight.js/lib/core"]["highlight"];
826
+
export const highlightAuto: MappedModules["highlight.js/lib/core"]["highlightAuto"];
827
+
export const fixMarkup: MappedModules["highlight.js/lib/core"]["fixMarkup"];
828
+
export const highlightBlock: MappedModules["highlight.js/lib/core"]["highlightBlock"];
829
+
export const configure: MappedModules["highlight.js/lib/core"]["configure"];
830
+
export const initHighlighting: MappedModules["highlight.js/lib/core"]["initHighlighting"];
831
+
export const initHighlightingOnLoad: MappedModules["highlight.js/lib/core"]["initHighlightingOnLoad"];
832
+
export const registerLanguage: MappedModules["highlight.js/lib/core"]["registerLanguage"];
833
+
export const listLanguages: MappedModules["highlight.js/lib/core"]["listLanguages"];
834
+
export const getLanguage: MappedModules["highlight.js/lib/core"]["getLanguage"];
835
+
export const inherit: MappedModules["highlight.js/lib/core"]["inherit"];
836
+
export const COMMENT: MappedModules["highlight.js/lib/core"]["COMMENT"];
837
+
export const IDENT_RE: MappedModules["highlight.js/lib/core"]["IDENT_RE"];
838
+
export const UNDERSCORE_IDENT_RE: MappedModules["highlight.js/lib/core"]["UNDERSCORE_IDENT_RE"];
839
+
export const NUMBER_RE: MappedModules["highlight.js/lib/core"]["NUMBER_RE"];
840
+
export const C_NUMBER_RE: MappedModules["highlight.js/lib/core"]["C_NUMBER_RE"];
841
+
export const BINARY_NUMBER_RE: MappedModules["highlight.js/lib/core"]["BINARY_NUMBER_RE"];
842
+
export const RE_STARTERS_RE: MappedModules["highlight.js/lib/core"]["RE_STARTERS_RE"];
843
+
export const BACKSLASH_ESCAPE: MappedModules["highlight.js/lib/core"]["BACKSLASH_ESCAPE"];
844
+
export const APOS_STRING_MODE: MappedModules["highlight.js/lib/core"]["APOS_STRING_MODE"];
845
+
export const QUOTE_STRING_MODE: MappedModules["highlight.js/lib/core"]["QUOTE_STRING_MODE"];
846
+
export const PHRASAL_WORDS_MODE: MappedModules["highlight.js/lib/core"]["PHRASAL_WORDS_MODE"];
847
+
export const C_LINE_COMMENT_MODE: MappedModules["highlight.js/lib/core"]["C_LINE_COMMENT_MODE"];
848
+
export const C_BLOCK_COMMENT_MODE: MappedModules["highlight.js/lib/core"]["C_BLOCK_COMMENT_MODE"];
849
+
export const HASH_COMMENT_MODE: MappedModules["highlight.js/lib/core"]["HASH_COMMENT_MODE"];
850
+
export const NUMBER_MODE: MappedModules["highlight.js/lib/core"]["NUMBER_MODE"];
851
+
export const C_NUMBER_MODE: MappedModules["highlight.js/lib/core"]["C_NUMBER_MODE"];
852
+
export const BINARY_NUMBER_MODE: MappedModules["highlight.js/lib/core"]["BINARY_NUMBER_MODE"];
853
+
export const CSS_NUMBER_MODE: MappedModules["highlight.js/lib/core"]["CSS_NUMBER_MODE"];
854
+
export const REGEX_MODE: MappedModules["highlight.js/lib/core"]["REGEX_MODE"];
855
+
export const TITLE_MODE: MappedModules["highlight.js/lib/core"]["TITLE_MODE"];
856
+
export const UNDERSCORE_TITLE_MODE: MappedModules["highlight.js/lib/core"]["UNDERSCORE_TITLE_MODE"];
857
+
}
858
+
859
+
declare module "@moonlight-mod/wp/lodash" {}
860
+
861
+
declare module "@moonlight-mod/wp/murmurhash" {
862
+
import { MappedModules } from "@moonlight-mod/mappings";
863
+
export const v2: MappedModules["murmurhash"]["v2"];
864
+
export const v3: MappedModules["murmurhash"]["v3"];
865
+
}
866
+
867
+
declare module "@moonlight-mod/wp/platform.js" {
868
+
import { MappedModules } from "@moonlight-mod/mappings";
869
+
export const description: MappedModules["platform.js"]["description"];
870
+
export const layout: MappedModules["platform.js"]["layout"];
871
+
export const manufacturer: MappedModules["platform.js"]["manufacturer"];
872
+
export const name: MappedModules["platform.js"]["name"];
873
+
export const prerelease: MappedModules["platform.js"]["prerelease"];
874
+
export const product: MappedModules["platform.js"]["product"];
875
+
export const ua: MappedModules["platform.js"]["ua"];
876
+
export const version: MappedModules["platform.js"]["version"];
877
+
export const os: MappedModules["platform.js"]["os"];
878
+
export const parse: MappedModules["platform.js"]["parse"];
879
+
export const toString: MappedModules["platform.js"]["toString"];
880
}
881
882
declare module "@moonlight-mod/wp/react" {
883
import { MappedModules } from "@moonlight-mod/mappings";
884
+
const _: Omit<MappedModules["react"], "__mappings_exportEquals">;
885
export = _;
886
}
887
+
888
+
declare module "@moonlight-mod/wp/uuid/v4" {}
+7
-7
packages/types/tsconfig.json
+7
-7
packages/types/tsconfig.json
···
1
{
2
"compilerOptions": {
3
-
"target": "es2016",
4
-
"module": "es6",
5
-
"esModuleInterop": true,
6
-
"forceConsistentCasingInFileNames": true,
7
-
"strict": true,
8
-
"moduleResolution": "bundler",
9
"jsx": "react",
10
-
"declaration": true
11
},
12
"include": ["./src/**/*", "src/index.ts", "./src/import.d.ts"]
13
}
···
1
{
2
"compilerOptions": {
3
+
"target": "ES2016",
4
"jsx": "react",
5
+
"module": "ES6",
6
+
"moduleResolution": "bundler",
7
+
"strict": true,
8
+
"declaration": true,
9
+
"esModuleInterop": true,
10
+
"forceConsistentCasingInFileNames": true
11
},
12
"include": ["./src/**/*", "src/index.ts", "./src/import.d.ts"]
13
}
+10
-3
packages/web-preload/package.json
+10
-3
packages/web-preload/package.json
···
2
"name": "@moonlight-mod/web-preload",
3
"private": true,
4
"main": "src/index.ts",
5
"dependencies": {
6
"@moonlight-mod/core": "workspace:*",
7
-
"@moonlight-mod/lunast": "^1.0.0",
8
-
"@moonlight-mod/mappings": "^1.0.10",
9
-
"@moonlight-mod/moonmap": "^1.0.3",
10
"@moonlight-mod/types": "workspace:*"
11
}
12
}
···
2
"name": "@moonlight-mod/web-preload",
3
"private": true,
4
"main": "src/index.ts",
5
+
"engineStrict": true,
6
+
"engines": {
7
+
"node": ">=22",
8
+
"pnpm": ">=10",
9
+
"npm": "pnpm",
10
+
"yarn": "pnpm"
11
+
},
12
"dependencies": {
13
"@moonlight-mod/core": "workspace:*",
14
+
"@moonlight-mod/lunast": "catalog:prod",
15
+
"@moonlight-mod/mappings": "catalog:prod",
16
+
"@moonlight-mod/moonmap": "catalog:prod",
17
"@moonlight-mod/types": "workspace:*"
18
}
19
}
+2
-2
packages/web-preload/src/index.ts
+2
-2
packages/web-preload/src/index.ts
···
7
import Moonmap from "@moonlight-mod/moonmap";
8
import loadMappings from "@moonlight-mod/mappings";
9
import { createEventEmitter } from "@moonlight-mod/core/util/event";
10
-
import { EventPayloads, EventType } from "@moonlight-mod/types/core/event";
11
12
async function load() {
13
delete window._moonlightWebLoad;
···
20
pendingModules: new Set(),
21
enabledExtensions: new Set(),
22
23
-
events: createEventEmitter<EventType, EventPayloads>(),
24
patchingInternals: {
25
onModuleLoad,
26
registerPatch,
···
7
import Moonmap from "@moonlight-mod/moonmap";
8
import loadMappings from "@moonlight-mod/mappings";
9
import { createEventEmitter } from "@moonlight-mod/core/util/event";
10
+
import { WebEventPayloads, WebEventType } from "@moonlight-mod/types/core/event";
11
12
async function load() {
13
delete window._moonlightWebLoad;
···
20
pendingModules: new Set(),
21
enabledExtensions: new Set(),
22
23
+
events: createEventEmitter<WebEventType, WebEventPayloads>(),
24
patchingInternals: {
25
onModuleLoad,
26
registerPatch,
+4
-1
packages/web-preload/tsconfig.json
+4
-1
packages/web-preload/tsconfig.json
+1243
-729
pnpm-lock.yaml
+1243
-729
pnpm-lock.yaml
···
4
autoInstallPeers: true
5
excludeLinksFromLockfile: false
6
7
importers:
8
9
.:
10
devDependencies:
11
'@moonlight-mod/eslint-config':
12
-
specifier: github:moonlight-mod/eslint-config
13
-
version: https://codeload.github.com/moonlight-mod/eslint-config/tar.gz/e262ac24e1a0955a9b3e0d66da247a0a8c0446c9(eslint@9.12.0)(prettier@3.1.0)(typescript@5.3.2)
14
esbuild:
15
-
specifier: ^0.19.3
16
version: 0.19.3
17
esbuild-copy-static-files:
18
-
specifier: ^0.1.0
19
version: 0.1.0
20
eslint:
21
-
specifier: ^9.12.0
22
-
version: 9.12.0
23
husky:
24
-
specifier: ^8.0.3
25
version: 8.0.3
26
prettier:
27
-
specifier: ^3.1.0
28
version: 3.1.0
29
typescript:
30
-
specifier: ^5.3.2
31
-
version: 5.3.2
32
33
packages/browser:
34
dependencies:
···
42
specifier: workspace:*
43
version: link:../web-preload
44
'@zenfs/core':
45
-
specifier: ^1.0.2
46
-
version: 1.0.2
47
'@zenfs/dom':
48
-
specifier: ^0.2.16
49
-
version: 0.2.16(@zenfs/core@1.0.2)
50
51
packages/core:
52
dependencies:
···
63
specifier: workspace:*
64
version: link:../types
65
microdiff:
66
-
specifier: ^1.5.0
67
version: 1.5.0
68
nanotar:
69
-
specifier: ^0.1.1
70
version: 0.1.1
71
72
packages/injector:
···
90
packages/types:
91
dependencies:
92
'@moonlight-mod/lunast':
93
-
specifier: ^1.0.0
94
-
version: 1.0.0
95
'@moonlight-mod/mappings':
96
-
specifier: ^1.0.10
97
-
version: 1.0.10(@moonlight-mod/lunast@1.0.0)(@moonlight-mod/moonmap@1.0.3)
98
'@moonlight-mod/moonmap':
99
-
specifier: ^1.0.3
100
-
version: 1.0.3
101
'@types/react':
102
specifier: ^18.3.10
103
-
version: 18.3.10
104
csstype:
105
-
specifier: ^3.1.2
106
-
version: 3.1.2
107
standalone-electron-types:
108
specifier: ^1.0.0
109
version: 1.0.0
···
114
specifier: workspace:*
115
version: link:../core
116
'@moonlight-mod/lunast':
117
-
specifier: ^1.0.0
118
-
version: 1.0.0
119
'@moonlight-mod/mappings':
120
-
specifier: ^1.0.10
121
-
version: 1.0.10(@moonlight-mod/lunast@1.0.0)(@moonlight-mod/moonmap@1.0.3)
122
'@moonlight-mod/moonmap':
123
-
specifier: ^1.0.3
124
-
version: 1.0.3
125
'@moonlight-mod/types':
126
specifier: workspace:*
127
version: link:../types
···
131
'@aashutoshrathi/word-wrap@1.2.6':
132
resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
133
engines: {node: '>=0.10.0'}
134
135
'@esbuild/android-arm64@0.19.3':
136
resolution: {integrity: sha512-w+Akc0vv5leog550kjJV9Ru+MXMR2VuMrui3C61mnysim0gkFCPOUTAfzTP0qX+HpN9Syu3YA3p1hf3EPqObRw==}
···
264
cpu: [x64]
265
os: [win32]
266
267
-
'@eslint-community/eslint-utils@4.4.0':
268
-
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
269
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
270
peerDependencies:
271
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
272
273
-
'@eslint-community/regexpp@4.11.1':
274
-
resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==}
275
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
276
277
-
'@eslint/config-array@0.18.0':
278
-
resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==}
279
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
280
281
-
'@eslint/core@0.6.0':
282
-
resolution: {integrity: sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==}
283
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
284
285
-
'@eslint/eslintrc@3.1.0':
286
-
resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==}
287
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
288
289
-
'@eslint/js@9.12.0':
290
-
resolution: {integrity: sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==}
291
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
292
293
-
'@eslint/object-schema@2.1.4':
294
-
resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==}
295
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
296
297
-
'@eslint/plugin-kit@0.2.0':
298
-
resolution: {integrity: sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==}
299
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
300
301
-
'@humanfs/core@0.19.0':
302
-
resolution: {integrity: sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==}
303
engines: {node: '>=18.18.0'}
304
305
-
'@humanfs/node@0.16.5':
306
-
resolution: {integrity: sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==}
307
engines: {node: '>=18.18.0'}
308
309
'@humanwhocodes/module-importer@1.0.1':
···
314
resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==}
315
engines: {node: '>=18.18'}
316
317
'@moonlight-mod/eslint-config@https://codeload.github.com/moonlight-mod/eslint-config/tar.gz/e262ac24e1a0955a9b3e0d66da247a0a8c0446c9':
318
resolution: {tarball: https://codeload.github.com/moonlight-mod/eslint-config/tar.gz/e262ac24e1a0955a9b3e0d66da247a0a8c0446c9}
319
version: 1.0.1
···
321
eslint: '>= 9'
322
typescript: '>= 5.3'
323
324
-
'@moonlight-mod/lunast@1.0.0':
325
-
resolution: {integrity: sha512-kJgf41K12i6/2LbXK97CNO+pNO7ADGh9N4bCQcOPwosocKMcwKHDEZUgPqeihNshY3c3AEW1LiyXjlsl24PdDw==}
326
327
-
'@moonlight-mod/mappings@1.0.10':
328
-
resolution: {integrity: sha512-L04To4MhlxOWxvvfVIRwj7d8H5qHthjUfikSx9WMk60qt67+6dFzN9CoAG9uG5l1B27IIEG3voVXBr0oSkooYw==}
329
peerDependencies:
330
-
'@moonlight-mod/lunast': ^1.0.0
331
-
'@moonlight-mod/moonmap': ^1.0.0
332
333
-
'@moonlight-mod/moonmap@1.0.3':
334
-
resolution: {integrity: sha512-G7pwvrcVDimc388IX6VZFzBXpbuyvqbJ+w9/v+MUIc8P7dADJXQ9YkBWvobtRc6eaBBl1FWUwTeU8oobbxLVag==}
335
336
'@nodelib/fs.scandir@2.1.5':
337
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
···
345
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
346
engines: {node: '>= 8'}
347
348
-
'@pkgr/core@0.1.1':
349
-
resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
350
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
351
352
'@types/estree-jsx@1.0.5':
353
resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
···
355
'@types/estree@1.0.6':
356
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
357
358
'@types/fbemitter@2.0.35':
359
resolution: {integrity: sha512-Xem6d7qUfmouCHntCrRYgDBwbf+WWRd6G+7WEFlEZFZ67LZXiYRvT2LV8wcZa6mIaAil95+ABQdKgB6hPIsnng==}
360
361
'@types/flux@3.1.14':
362
resolution: {integrity: sha512-WRXN0kQPCnqxN0/PgNgc7WBF6c8rbSHsEep3/qBLpsQ824RONdOmTs0TV7XhIW2GDNRAHO2CqCgAFLR5PChosw==}
363
364
'@types/json-schema@7.0.15':
365
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
366
367
'@types/node@18.17.17':
368
resolution: {integrity: sha512-cOxcXsQ2sxiwkykdJqvyFS+MLQPLvIdwh5l6gNg8qF6s+C7XSkEWOZjK+XhUZd+mYvHV/180g2cnCcIl4l06Pw==}
369
370
-
'@types/node@20.16.10':
371
-
resolution: {integrity: sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==}
372
373
'@types/prop-types@15.7.13':
374
resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==}
375
376
-
'@types/react@18.3.10':
377
-
resolution: {integrity: sha512-02sAAlBnP39JgXwkAq3PeU9DVaaGpZyF3MGcC0MKgQVkZor5IiiDAipVaxQHtDJAmO4GIy/rVBy/LzVj76Cyqg==}
378
379
-
'@types/readable-stream@4.0.15':
380
-
resolution: {integrity: sha512-oAZ3kw+kJFkEqyh7xORZOku1YAKvsFTogRY8kVl4vHpEKiDkfnSA/My8haRE7fvmix5Zyy+1pwzOi7yycGLBJw==}
381
-
382
-
'@typescript-eslint/eslint-plugin@8.8.1':
383
-
resolution: {integrity: sha512-xfvdgA8AP/vxHgtgU310+WBnLB4uJQ9XdyP17RebG26rLtDrQJV3ZYrcopX91GrHmMoH8bdSwMRh2a//TiJ1jQ==}
384
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
385
peerDependencies:
386
'@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0
387
eslint: ^8.57.0 || ^9.0.0
388
-
typescript: '*'
389
-
peerDependenciesMeta:
390
-
typescript:
391
-
optional: true
392
393
-
'@typescript-eslint/parser@8.8.1':
394
-
resolution: {integrity: sha512-hQUVn2Lij2NAxVFEdvIGxT9gP1tq2yM83m+by3whWFsWC+1y8pxxxHUFE1UqDu2VsGi2i6RLcv4QvouM84U+ow==}
395
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
396
peerDependencies:
397
eslint: ^8.57.0 || ^9.0.0
398
-
typescript: '*'
399
-
peerDependenciesMeta:
400
-
typescript:
401
-
optional: true
402
403
-
'@typescript-eslint/scope-manager@8.8.1':
404
-
resolution: {integrity: sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA==}
405
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
406
407
-
'@typescript-eslint/type-utils@8.8.1':
408
-
resolution: {integrity: sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA==}
409
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
410
peerDependencies:
411
-
typescript: '*'
412
-
peerDependenciesMeta:
413
-
typescript:
414
-
optional: true
415
416
-
'@typescript-eslint/types@8.8.1':
417
-
resolution: {integrity: sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==}
418
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
419
420
-
'@typescript-eslint/typescript-estree@8.8.1':
421
-
resolution: {integrity: sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg==}
422
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
423
peerDependencies:
424
-
typescript: '*'
425
-
peerDependenciesMeta:
426
-
typescript:
427
-
optional: true
428
429
-
'@typescript-eslint/utils@8.8.1':
430
-
resolution: {integrity: sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==}
431
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
432
peerDependencies:
433
eslint: ^8.57.0 || ^9.0.0
434
435
-
'@typescript-eslint/visitor-keys@8.8.1':
436
-
resolution: {integrity: sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==}
437
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
438
439
-
'@zenfs/core@1.0.2':
440
-
resolution: {integrity: sha512-LMTD4ntn6Ag1y+IeOSVykDDvYC12dsGFtsX8M/54OQrLs7v+YnX4bpo0o2osbm8XFmU2MTNMX/G3PLsvzgWzrg==}
441
-
engines: {node: '>= 16'}
442
hasBin: true
443
444
-
'@zenfs/dom@0.2.16':
445
-
resolution: {integrity: sha512-6Ev+ol9hZIgQECNZR+xxjQ/a99EhhrWeiQttm/+U7YJK3HdTjiKfU39DsfGeH64vSqhpa5Vj+LWRx75SHkjw0Q==}
446
engines: {node: '>= 18'}
447
peerDependencies:
448
-
'@zenfs/core': ^1.0.0
449
450
abort-controller@3.0.0:
451
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
···
456
peerDependencies:
457
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
458
459
-
acorn@8.12.1:
460
-
resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
461
engines: {node: '>=0.4.0'}
462
hasBin: true
463
···
468
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
469
engines: {node: '>=8'}
470
471
argparse@2.0.1:
472
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
473
474
-
array-buffer-byte-length@1.0.1:
475
-
resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==}
476
engines: {node: '>= 0.4'}
477
478
array-includes@3.1.8:
···
483
resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
484
engines: {node: '>= 0.4'}
485
486
-
array.prototype.flat@1.3.2:
487
-
resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==}
488
engines: {node: '>= 0.4'}
489
490
-
array.prototype.flatmap@1.3.2:
491
-
resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==}
492
engines: {node: '>= 0.4'}
493
494
array.prototype.tosorted@1.1.4:
495
resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==}
496
engines: {node: '>= 0.4'}
497
498
-
arraybuffer.prototype.slice@1.0.3:
499
-
resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==}
500
engines: {node: '>= 0.4'}
501
502
astring@1.9.0:
503
resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
504
hasBin: true
505
506
available-typed-arrays@1.0.7:
507
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
···
526
buffer@6.0.3:
527
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
528
529
-
call-bind@1.0.7:
530
-
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
531
engines: {node: '>= 0.4'}
532
533
callsites@3.1.0:
···
548
concat-map@0.0.1:
549
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
550
551
-
cross-spawn@7.0.3:
552
-
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
553
engines: {node: '>= 8'}
554
555
-
csstype@3.1.2:
556
-
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
557
-
558
csstype@3.1.3:
559
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
560
561
-
data-view-buffer@1.0.1:
562
-
resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==}
563
engines: {node: '>= 0.4'}
564
565
-
data-view-byte-length@1.0.1:
566
-
resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==}
567
engines: {node: '>= 0.4'}
568
569
-
data-view-byte-offset@1.0.0:
570
-
resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==}
571
engines: {node: '>= 0.4'}
572
573
-
debug@4.3.4:
574
-
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
575
engines: {node: '>=6.0'}
576
peerDependencies:
577
supports-color: '*'
···
590
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
591
engines: {node: '>= 0.4'}
592
593
doctrine@2.1.0:
594
resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
595
engines: {node: '>=0.10.0'}
596
597
-
es-abstract@1.23.3:
598
-
resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==}
599
engines: {node: '>= 0.4'}
600
601
-
es-define-property@1.0.0:
602
-
resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
603
engines: {node: '>= 0.4'}
604
605
es-errors@1.3.0:
606
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
607
engines: {node: '>= 0.4'}
608
609
-
es-iterator-helpers@1.1.0:
610
-
resolution: {integrity: sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==}
611
engines: {node: '>= 0.4'}
612
613
-
es-object-atoms@1.0.0:
614
-
resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==}
615
engines: {node: '>= 0.4'}
616
617
-
es-set-tostringtag@2.0.3:
618
-
resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==}
619
engines: {node: '>= 0.4'}
620
621
-
es-shim-unscopables@1.0.2:
622
-
resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==}
623
624
-
es-to-primitive@1.2.1:
625
-
resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
626
engines: {node: '>= 0.4'}
627
628
esbuild-copy-static-files@0.1.0:
···
643
peerDependencies:
644
eslint: '>=7.0.0'
645
646
-
eslint-plugin-prettier@5.2.1:
647
-
resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==}
648
engines: {node: ^14.18.0 || >=16.0.0}
649
peerDependencies:
650
'@types/eslint': '>=8.0.0'
651
eslint: '>=8.0.0'
652
-
eslint-config-prettier: '*'
653
prettier: '>=3.0.0'
654
peerDependenciesMeta:
655
'@types/eslint':
···
657
eslint-config-prettier:
658
optional: true
659
660
-
eslint-plugin-react@7.37.1:
661
-
resolution: {integrity: sha512-xwTnwDqzbDRA8uJ7BMxPs/EXRB3i8ZfnOIp8BsxEQkT0nHPp+WWceqGgo6rKb9ctNi8GJLDT4Go5HAWELa/WMg==}
662
engines: {node: '>=4'}
663
peerDependencies:
664
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
665
666
-
eslint-scope@8.1.0:
667
-
resolution: {integrity: sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==}
668
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
669
670
eslint-visitor-keys@3.4.3:
671
resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
672
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
673
674
-
eslint-visitor-keys@4.1.0:
675
-
resolution: {integrity: sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==}
676
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
677
678
-
eslint@9.12.0:
679
-
resolution: {integrity: sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==}
680
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
681
hasBin: true
682
peerDependencies:
···
685
jiti:
686
optional: true
687
688
-
espree@10.2.0:
689
-
resolution: {integrity: sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==}
690
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
691
692
-
esquery@1.5.0:
693
-
resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
694
engines: {node: '>=0.10'}
695
696
esrecurse@4.3.0:
···
738
fastq@1.17.1:
739
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
740
741
file-entry-cache@8.0.0:
742
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
743
engines: {node: '>=16.0.0'}
···
746
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
747
engines: {node: '>=8'}
748
749
find-up@5.0.0:
750
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
751
engines: {node: '>=10'}
···
757
flatted@3.2.9:
758
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
759
760
-
for-each@0.3.3:
761
-
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
762
763
function-bind@1.1.2:
764
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
765
766
-
function.prototype.name@1.1.6:
767
-
resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==}
768
engines: {node: '>= 0.4'}
769
770
functions-have-names@1.2.3:
771
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
772
773
-
get-intrinsic@1.2.4:
774
-
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
775
engines: {node: '>= 0.4'}
776
777
-
get-symbol-description@1.0.2:
778
-
resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
779
engines: {node: '>= 0.4'}
780
781
glob-parent@5.1.2:
···
794
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
795
engines: {node: '>= 0.4'}
796
797
-
gopd@1.0.1:
798
-
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
799
800
graphemer@1.4.0:
801
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
802
803
-
has-bigints@1.0.2:
804
-
resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
805
806
has-flag@4.0.0:
807
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
···
810
has-property-descriptors@1.0.2:
811
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
812
813
-
has-proto@1.0.3:
814
-
resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
815
engines: {node: '>= 0.4'}
816
817
-
has-symbols@1.0.3:
818
-
resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
819
engines: {node: '>= 0.4'}
820
821
has-tostringtag@1.0.2:
···
834
ieee754@1.2.1:
835
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
836
837
-
ignore@5.3.0:
838
-
resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==}
839
-
engines: {node: '>= 4'}
840
-
841
ignore@5.3.2:
842
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
843
engines: {node: '>= 4'}
···
850
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
851
engines: {node: '>=0.8.19'}
852
853
-
internal-slot@1.0.7:
854
-
resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==}
855
engines: {node: '>= 0.4'}
856
857
-
is-array-buffer@3.0.4:
858
-
resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==}
859
engines: {node: '>= 0.4'}
860
861
-
is-async-function@2.0.0:
862
-
resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==}
863
engines: {node: '>= 0.4'}
864
865
-
is-bigint@1.0.4:
866
-
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
867
868
-
is-boolean-object@1.1.2:
869
-
resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
870
engines: {node: '>= 0.4'}
871
872
is-callable@1.2.7:
873
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
874
engines: {node: '>= 0.4'}
875
876
-
is-core-module@2.15.1:
877
-
resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==}
878
engines: {node: '>= 0.4'}
879
880
-
is-data-view@1.0.1:
881
-
resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==}
882
engines: {node: '>= 0.4'}
883
884
-
is-date-object@1.0.5:
885
-
resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
886
engines: {node: '>= 0.4'}
887
888
is-extglob@2.1.1:
889
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
890
engines: {node: '>=0.10.0'}
891
892
-
is-finalizationregistry@1.0.2:
893
-
resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==}
894
895
-
is-generator-function@1.0.10:
896
-
resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==}
897
engines: {node: '>= 0.4'}
898
899
is-glob@4.0.3:
···
904
resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
905
engines: {node: '>= 0.4'}
906
907
-
is-negative-zero@2.0.3:
908
-
resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
909
-
engines: {node: '>= 0.4'}
910
-
911
-
is-number-object@1.0.7:
912
-
resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
913
engines: {node: '>= 0.4'}
914
915
is-number@7.0.0:
916
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
917
engines: {node: '>=0.12.0'}
918
919
-
is-regex@1.1.4:
920
-
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
921
engines: {node: '>= 0.4'}
922
923
is-set@2.0.3:
924
resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
925
engines: {node: '>= 0.4'}
926
927
-
is-shared-array-buffer@1.0.3:
928
-
resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==}
929
engines: {node: '>= 0.4'}
930
931
-
is-string@1.0.7:
932
-
resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
933
engines: {node: '>= 0.4'}
934
935
-
is-symbol@1.0.4:
936
-
resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
937
engines: {node: '>= 0.4'}
938
939
-
is-typed-array@1.1.13:
940
-
resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==}
941
engines: {node: '>= 0.4'}
942
943
is-weakmap@2.0.2:
944
resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
945
engines: {node: '>= 0.4'}
946
947
-
is-weakref@1.0.2:
948
-
resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
949
950
-
is-weakset@2.0.3:
951
-
resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==}
952
engines: {node: '>= 0.4'}
953
954
isarray@2.0.5:
···
957
isexe@2.0.0:
958
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
959
960
-
iterator.prototype@1.1.3:
961
-
resolution: {integrity: sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==}
962
engines: {node: '>= 0.4'}
963
964
js-tokens@4.0.0:
965
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
966
···
999
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
1000
hasBin: true
1001
1002
merge2@1.4.1:
1003
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
1004
engines: {node: '>= 8'}
···
1014
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
1015
engines: {node: '>=8.6'}
1016
1017
minimatch@3.1.2:
1018
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
1019
···
1021
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
1022
engines: {node: '>=16 || 14 >=14.17'}
1023
1024
-
ms@2.1.2:
1025
-
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
1026
1027
nanotar@0.1.1:
1028
resolution: {integrity: sha512-AiJsGsSF3O0havL1BydvI4+wR76sKT+okKRwWIaK96cZUnXqH0uNBOsHlbwZq3+m2BR1VKqHDVudl3gO4mYjpQ==}
···
1030
natural-compare@1.4.0:
1031
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
1032
1033
object-assign@4.1.1:
1034
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
1035
engines: {node: '>=0.10.0'}
1036
1037
-
object-inspect@1.13.2:
1038
-
resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==}
1039
engines: {node: '>= 0.4'}
1040
1041
object-keys@1.1.1:
1042
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
1043
engines: {node: '>= 0.4'}
1044
1045
-
object.assign@4.1.5:
1046
-
resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==}
1047
engines: {node: '>= 0.4'}
1048
1049
-
object.entries@1.1.8:
1050
-
resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==}
1051
engines: {node: '>= 0.4'}
1052
1053
object.fromentries@2.0.8:
1054
resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==}
1055
engines: {node: '>= 0.4'}
1056
1057
-
object.values@1.2.0:
1058
-
resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==}
1059
engines: {node: '>= 0.4'}
1060
1061
optionator@0.9.3:
1062
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
1063
engines: {node: '>= 0.8.0'}
1064
1065
p-limit@3.1.0:
1066
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
1067
engines: {node: '>=10'}
···
1069
p-locate@5.0.0:
1070
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
1071
engines: {node: '>=10'}
1072
1073
parent-module@1.0.1:
1074
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
···
1085
path-parse@1.0.7:
1086
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
1087
1088
picomatch@2.3.1:
1089
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1090
engines: {node: '>=8.6'}
1091
1092
-
possible-typed-array-names@1.0.0:
1093
-
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
1094
engines: {node: '>= 0.4'}
1095
1096
prelude-ls@1.2.1:
···
1117
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
1118
engines: {node: '>=6'}
1119
1120
queue-microtask@1.2.3:
1121
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
1122
···
1127
resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==}
1128
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1129
1130
-
reflect.getprototypeof@1.0.6:
1131
-
resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==}
1132
engines: {node: '>= 0.4'}
1133
1134
-
regexp.prototype.flags@1.5.3:
1135
-
resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==}
1136
engines: {node: '>= 0.4'}
1137
1138
resolve-from@4.0.0:
···
1143
resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==}
1144
hasBin: true
1145
1146
reusify@1.0.4:
1147
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
1148
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
···
1150
run-parallel@1.2.0:
1151
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
1152
1153
-
safe-array-concat@1.1.2:
1154
-
resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==}
1155
engines: {node: '>=0.4'}
1156
1157
-
safe-buffer@5.1.2:
1158
-
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
1159
-
1160
safe-buffer@5.2.1:
1161
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
1162
1163
-
safe-regex-test@1.0.3:
1164
-
resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==}
1165
engines: {node: '>= 0.4'}
1166
1167
semver@6.3.1:
1168
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
1169
hasBin: true
1170
1171
-
semver@7.6.3:
1172
-
resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
1173
engines: {node: '>=10'}
1174
hasBin: true
1175
···
1181
resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
1182
engines: {node: '>= 0.4'}
1183
1184
shebang-command@2.0.0:
1185
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
1186
engines: {node: '>=8'}
···
1189
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
1190
engines: {node: '>=8'}
1191
1192
-
side-channel@1.0.6:
1193
-
resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
1194
engines: {node: '>= 0.4'}
1195
1196
standalone-electron-types@1.0.0:
1197
resolution: {integrity: sha512-0HOi/tlTz3mjWhsAz4uRbpQcHMZ+ifj1JzWW9nugykOHClBBG77ps8QinrzX1eow4Iw2pnC+RFaSYRgufF4BOg==}
1198
1199
-
string.prototype.matchall@4.0.11:
1200
-
resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==}
1201
engines: {node: '>= 0.4'}
1202
1203
string.prototype.repeat@1.0.0:
1204
resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==}
1205
1206
-
string.prototype.trim@1.2.9:
1207
-
resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==}
1208
engines: {node: '>= 0.4'}
1209
1210
-
string.prototype.trimend@1.0.8:
1211
-
resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==}
1212
1213
string.prototype.trimstart@1.0.8:
1214
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
···
1229
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
1230
engines: {node: '>= 0.4'}
1231
1232
-
synckit@0.9.2:
1233
-
resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==}
1234
engines: {node: ^14.18.0 || >=16.0.0}
1235
1236
-
text-table@0.2.0:
1237
-
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
1238
1239
to-regex-range@5.0.1:
1240
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
1241
engines: {node: '>=8.0'}
1242
1243
-
ts-api-utils@1.3.0:
1244
-
resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==}
1245
-
engines: {node: '>=16'}
1246
peerDependencies:
1247
-
typescript: '>=4.2.0'
1248
1249
-
tslib@2.7.0:
1250
-
resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
1251
1252
type-check@0.4.0:
1253
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
1254
engines: {node: '>= 0.8.0'}
1255
1256
-
typed-array-buffer@1.0.2:
1257
-
resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==}
1258
engines: {node: '>= 0.4'}
1259
1260
-
typed-array-byte-length@1.0.1:
1261
-
resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==}
1262
engines: {node: '>= 0.4'}
1263
1264
-
typed-array-byte-offset@1.0.2:
1265
-
resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==}
1266
engines: {node: '>= 0.4'}
1267
1268
-
typed-array-length@1.0.6:
1269
-
resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==}
1270
engines: {node: '>= 0.4'}
1271
1272
-
typescript-eslint@8.8.1:
1273
-
resolution: {integrity: sha512-R0dsXFt6t4SAFjUSKFjMh4pXDtq04SsFKCVGDP3ZOzNP7itF0jBcZYU4fMsZr4y7O7V7Nc751dDeESbe4PbQMQ==}
1274
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1275
peerDependencies:
1276
-
typescript: '*'
1277
-
peerDependenciesMeta:
1278
-
typescript:
1279
-
optional: true
1280
1281
-
typescript@5.3.2:
1282
-
resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==}
1283
engines: {node: '>=14.17'}
1284
hasBin: true
1285
1286
-
unbox-primitive@1.0.2:
1287
-
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
1288
1289
-
undici-types@6.19.8:
1290
-
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
1291
1292
uri-js@4.4.1:
1293
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
1294
1295
-
utilium@0.7.1:
1296
-
resolution: {integrity: sha512-2ocvTkI7U8LERmwxL0LhFUvEfN66UqcjF6tMiURvUwSyU7U1QC9gST+3iSUSiGccFfnP3f2EXwHNXOnOzx+lAg==}
1297
1298
-
which-boxed-primitive@1.0.2:
1299
-
resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
1300
1301
-
which-builtin-type@1.1.4:
1302
-
resolution: {integrity: sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==}
1303
engines: {node: '>= 0.4'}
1304
1305
which-collection@1.0.2:
1306
resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
1307
engines: {node: '>= 0.4'}
1308
1309
-
which-typed-array@1.1.15:
1310
-
resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==}
1311
engines: {node: '>= 0.4'}
1312
1313
which@2.0.2:
···
1315
engines: {node: '>= 8'}
1316
hasBin: true
1317
1318
yocto-queue@0.1.0:
1319
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
1320
engines: {node: '>=10'}
1321
1322
snapshots:
1323
1324
'@aashutoshrathi/word-wrap@1.2.6': {}
1325
1326
'@esbuild/android-arm64@0.19.3':
1327
optional: true
···
1389
'@esbuild/win32-x64@0.19.3':
1390
optional: true
1391
1392
-
'@eslint-community/eslint-utils@4.4.0(eslint@9.12.0)':
1393
dependencies:
1394
-
eslint: 9.12.0
1395
eslint-visitor-keys: 3.4.3
1396
1397
-
'@eslint-community/regexpp@4.11.1': {}
1398
1399
-
'@eslint/config-array@0.18.0':
1400
dependencies:
1401
-
'@eslint/object-schema': 2.1.4
1402
-
debug: 4.3.4
1403
minimatch: 3.1.2
1404
transitivePeerDependencies:
1405
- supports-color
1406
1407
-
'@eslint/core@0.6.0': {}
1408
1409
-
'@eslint/eslintrc@3.1.0':
1410
dependencies:
1411
ajv: 6.12.6
1412
-
debug: 4.3.4
1413
-
espree: 10.2.0
1414
globals: 14.0.0
1415
-
ignore: 5.3.0
1416
import-fresh: 3.3.0
1417
js-yaml: 4.1.0
1418
minimatch: 3.1.2
···
1420
transitivePeerDependencies:
1421
- supports-color
1422
1423
-
'@eslint/js@9.12.0': {}
1424
1425
-
'@eslint/object-schema@2.1.4': {}
1426
1427
-
'@eslint/plugin-kit@0.2.0':
1428
dependencies:
1429
levn: 0.4.1
1430
1431
-
'@humanfs/core@0.19.0': {}
1432
1433
-
'@humanfs/node@0.16.5':
1434
dependencies:
1435
-
'@humanfs/core': 0.19.0
1436
'@humanwhocodes/retry': 0.3.1
1437
1438
'@humanwhocodes/module-importer@1.0.1': {}
1439
1440
'@humanwhocodes/retry@0.3.1': {}
1441
1442
-
'@moonlight-mod/eslint-config@https://codeload.github.com/moonlight-mod/eslint-config/tar.gz/e262ac24e1a0955a9b3e0d66da247a0a8c0446c9(eslint@9.12.0)(prettier@3.1.0)(typescript@5.3.2)':
1443
dependencies:
1444
-
'@eslint/js': 9.12.0
1445
-
eslint: 9.12.0
1446
-
eslint-config-prettier: 9.1.0(eslint@9.12.0)
1447
-
eslint-plugin-prettier: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.12.0))(eslint@9.12.0)(prettier@3.1.0)
1448
-
eslint-plugin-react: 7.37.1(eslint@9.12.0)
1449
-
typescript: 5.3.2
1450
-
typescript-eslint: 8.8.1(eslint@9.12.0)(typescript@5.3.2)
1451
transitivePeerDependencies:
1452
- '@types/eslint'
1453
- prettier
1454
- supports-color
1455
1456
-
'@moonlight-mod/lunast@1.0.0':
1457
dependencies:
1458
astring: 1.9.0
1459
estree-toolkit: 1.7.8
1460
meriyah: 6.0.1
1461
1462
-
'@moonlight-mod/mappings@1.0.10(@moonlight-mod/lunast@1.0.0)(@moonlight-mod/moonmap@1.0.3)':
1463
dependencies:
1464
-
'@moonlight-mod/lunast': 1.0.0
1465
-
'@moonlight-mod/moonmap': 1.0.3
1466
'@types/flux': 3.1.14
1467
-
'@types/react': 18.3.10
1468
csstype: 3.1.3
1469
1470
-
'@moonlight-mod/moonmap@1.0.3': {}
1471
1472
'@nodelib/fs.scandir@2.1.5':
1473
dependencies:
···
1481
'@nodelib/fs.scandir': 2.1.5
1482
fastq: 1.17.1
1483
1484
-
'@pkgr/core@0.1.1': {}
1485
1486
'@types/estree-jsx@1.0.5':
1487
dependencies:
1488
'@types/estree': 1.0.6
1489
1490
'@types/estree@1.0.6': {}
1491
1492
'@types/fbemitter@2.0.35': {}
1493
1494
'@types/flux@3.1.14':
1495
dependencies:
1496
'@types/fbemitter': 2.0.35
1497
-
'@types/react': 18.3.10
1498
1499
'@types/json-schema@7.0.15': {}
1500
1501
'@types/node@18.17.17': {}
1502
1503
-
'@types/node@20.16.10':
1504
dependencies:
1505
-
undici-types: 6.19.8
1506
1507
'@types/prop-types@15.7.13': {}
1508
1509
-
'@types/react@18.3.10':
1510
dependencies:
1511
'@types/prop-types': 15.7.13
1512
csstype: 3.1.3
1513
1514
-
'@types/readable-stream@4.0.15':
1515
-
dependencies:
1516
-
'@types/node': 20.16.10
1517
-
safe-buffer: 5.1.2
1518
-
1519
-
'@typescript-eslint/eslint-plugin@8.8.1(@typescript-eslint/parser@8.8.1(eslint@9.12.0)(typescript@5.3.2))(eslint@9.12.0)(typescript@5.3.2)':
1520
dependencies:
1521
-
'@eslint-community/regexpp': 4.11.1
1522
-
'@typescript-eslint/parser': 8.8.1(eslint@9.12.0)(typescript@5.3.2)
1523
-
'@typescript-eslint/scope-manager': 8.8.1
1524
-
'@typescript-eslint/type-utils': 8.8.1(eslint@9.12.0)(typescript@5.3.2)
1525
-
'@typescript-eslint/utils': 8.8.1(eslint@9.12.0)(typescript@5.3.2)
1526
-
'@typescript-eslint/visitor-keys': 8.8.1
1527
-
eslint: 9.12.0
1528
graphemer: 1.4.0
1529
ignore: 5.3.2
1530
natural-compare: 1.4.0
1531
-
ts-api-utils: 1.3.0(typescript@5.3.2)
1532
-
optionalDependencies:
1533
-
typescript: 5.3.2
1534
transitivePeerDependencies:
1535
- supports-color
1536
1537
-
'@typescript-eslint/parser@8.8.1(eslint@9.12.0)(typescript@5.3.2)':
1538
dependencies:
1539
-
'@typescript-eslint/scope-manager': 8.8.1
1540
-
'@typescript-eslint/types': 8.8.1
1541
-
'@typescript-eslint/typescript-estree': 8.8.1(typescript@5.3.2)
1542
-
'@typescript-eslint/visitor-keys': 8.8.1
1543
-
debug: 4.3.4
1544
-
eslint: 9.12.0
1545
-
optionalDependencies:
1546
-
typescript: 5.3.2
1547
transitivePeerDependencies:
1548
- supports-color
1549
1550
-
'@typescript-eslint/scope-manager@8.8.1':
1551
dependencies:
1552
-
'@typescript-eslint/types': 8.8.1
1553
-
'@typescript-eslint/visitor-keys': 8.8.1
1554
1555
-
'@typescript-eslint/type-utils@8.8.1(eslint@9.12.0)(typescript@5.3.2)':
1556
dependencies:
1557
-
'@typescript-eslint/typescript-estree': 8.8.1(typescript@5.3.2)
1558
-
'@typescript-eslint/utils': 8.8.1(eslint@9.12.0)(typescript@5.3.2)
1559
-
debug: 4.3.4
1560
-
ts-api-utils: 1.3.0(typescript@5.3.2)
1561
-
optionalDependencies:
1562
-
typescript: 5.3.2
1563
transitivePeerDependencies:
1564
-
- eslint
1565
- supports-color
1566
1567
-
'@typescript-eslint/types@8.8.1': {}
1568
1569
-
'@typescript-eslint/typescript-estree@8.8.1(typescript@5.3.2)':
1570
dependencies:
1571
-
'@typescript-eslint/types': 8.8.1
1572
-
'@typescript-eslint/visitor-keys': 8.8.1
1573
-
debug: 4.3.4
1574
fast-glob: 3.3.2
1575
is-glob: 4.0.3
1576
minimatch: 9.0.5
1577
-
semver: 7.6.3
1578
-
ts-api-utils: 1.3.0(typescript@5.3.2)
1579
-
optionalDependencies:
1580
-
typescript: 5.3.2
1581
transitivePeerDependencies:
1582
- supports-color
1583
1584
-
'@typescript-eslint/utils@8.8.1(eslint@9.12.0)(typescript@5.3.2)':
1585
dependencies:
1586
-
'@eslint-community/eslint-utils': 4.4.0(eslint@9.12.0)
1587
-
'@typescript-eslint/scope-manager': 8.8.1
1588
-
'@typescript-eslint/types': 8.8.1
1589
-
'@typescript-eslint/typescript-estree': 8.8.1(typescript@5.3.2)
1590
-
eslint: 9.12.0
1591
transitivePeerDependencies:
1592
- supports-color
1593
-
- typescript
1594
1595
-
'@typescript-eslint/visitor-keys@8.8.1':
1596
dependencies:
1597
-
'@typescript-eslint/types': 8.8.1
1598
-
eslint-visitor-keys: 3.4.3
1599
1600
-
'@zenfs/core@1.0.2':
1601
dependencies:
1602
-
'@types/node': 20.16.10
1603
-
'@types/readable-stream': 4.0.15
1604
buffer: 6.0.3
1605
eventemitter3: 5.0.1
1606
-
minimatch: 9.0.5
1607
readable-stream: 4.5.2
1608
-
utilium: 0.7.1
1609
1610
-
'@zenfs/dom@0.2.16(@zenfs/core@1.0.2)':
1611
dependencies:
1612
-
'@zenfs/core': 1.0.2
1613
1614
abort-controller@3.0.0:
1615
dependencies:
1616
event-target-shim: 5.0.1
1617
1618
-
acorn-jsx@5.3.2(acorn@8.12.1):
1619
dependencies:
1620
-
acorn: 8.12.1
1621
1622
-
acorn@8.12.1: {}
1623
1624
ajv@6.12.6:
1625
dependencies:
···
1632
dependencies:
1633
color-convert: 2.0.1
1634
1635
argparse@2.0.1: {}
1636
1637
-
array-buffer-byte-length@1.0.1:
1638
dependencies:
1639
-
call-bind: 1.0.7
1640
-
is-array-buffer: 3.0.4
1641
1642
array-includes@3.1.8:
1643
dependencies:
1644
-
call-bind: 1.0.7
1645
define-properties: 1.2.1
1646
-
es-abstract: 1.23.3
1647
-
es-object-atoms: 1.0.0
1648
-
get-intrinsic: 1.2.4
1649
-
is-string: 1.0.7
1650
1651
array.prototype.findlast@1.2.5:
1652
dependencies:
1653
-
call-bind: 1.0.7
1654
define-properties: 1.2.1
1655
-
es-abstract: 1.23.3
1656
es-errors: 1.3.0
1657
-
es-object-atoms: 1.0.0
1658
-
es-shim-unscopables: 1.0.2
1659
1660
-
array.prototype.flat@1.3.2:
1661
dependencies:
1662
-
call-bind: 1.0.7
1663
define-properties: 1.2.1
1664
-
es-abstract: 1.23.3
1665
-
es-shim-unscopables: 1.0.2
1666
1667
-
array.prototype.flatmap@1.3.2:
1668
dependencies:
1669
-
call-bind: 1.0.7
1670
define-properties: 1.2.1
1671
-
es-abstract: 1.23.3
1672
-
es-shim-unscopables: 1.0.2
1673
1674
array.prototype.tosorted@1.1.4:
1675
dependencies:
1676
-
call-bind: 1.0.7
1677
define-properties: 1.2.1
1678
-
es-abstract: 1.23.3
1679
es-errors: 1.3.0
1680
-
es-shim-unscopables: 1.0.2
1681
1682
-
arraybuffer.prototype.slice@1.0.3:
1683
dependencies:
1684
-
array-buffer-byte-length: 1.0.1
1685
-
call-bind: 1.0.7
1686
define-properties: 1.2.1
1687
-
es-abstract: 1.23.3
1688
es-errors: 1.3.0
1689
-
get-intrinsic: 1.2.4
1690
-
is-array-buffer: 3.0.4
1691
-
is-shared-array-buffer: 1.0.3
1692
1693
astring@1.9.0: {}
1694
1695
available-typed-arrays@1.0.7:
1696
dependencies:
1697
-
possible-typed-array-names: 1.0.0
1698
1699
balanced-match@1.0.2: {}
1700
···
1718
base64-js: 1.5.1
1719
ieee754: 1.2.1
1720
1721
-
call-bind@1.0.7:
1722
dependencies:
1723
-
es-define-property: 1.0.0
1724
es-errors: 1.3.0
1725
function-bind: 1.1.2
1726
-
get-intrinsic: 1.2.4
1727
set-function-length: 1.2.2
1728
1729
callsites@3.1.0: {}
1730
1731
chalk@4.1.2:
···
1741
1742
concat-map@0.0.1: {}
1743
1744
-
cross-spawn@7.0.3:
1745
dependencies:
1746
path-key: 3.1.1
1747
shebang-command: 2.0.0
1748
which: 2.0.2
1749
1750
-
csstype@3.1.2: {}
1751
-
1752
csstype@3.1.3: {}
1753
1754
-
data-view-buffer@1.0.1:
1755
dependencies:
1756
-
call-bind: 1.0.7
1757
es-errors: 1.3.0
1758
-
is-data-view: 1.0.1
1759
1760
-
data-view-byte-length@1.0.1:
1761
dependencies:
1762
-
call-bind: 1.0.7
1763
es-errors: 1.3.0
1764
-
is-data-view: 1.0.1
1765
1766
-
data-view-byte-offset@1.0.0:
1767
dependencies:
1768
-
call-bind: 1.0.7
1769
es-errors: 1.3.0
1770
-
is-data-view: 1.0.1
1771
1772
-
debug@4.3.4:
1773
dependencies:
1774
-
ms: 2.1.2
1775
1776
deep-is@0.1.4: {}
1777
1778
define-data-property@1.1.4:
1779
dependencies:
1780
-
es-define-property: 1.0.0
1781
es-errors: 1.3.0
1782
-
gopd: 1.0.1
1783
1784
define-properties@1.2.1:
1785
dependencies:
···
1787
has-property-descriptors: 1.0.2
1788
object-keys: 1.1.1
1789
1790
doctrine@2.1.0:
1791
dependencies:
1792
esutils: 2.0.3
1793
1794
-
es-abstract@1.23.3:
1795
dependencies:
1796
-
array-buffer-byte-length: 1.0.1
1797
-
arraybuffer.prototype.slice: 1.0.3
1798
available-typed-arrays: 1.0.7
1799
-
call-bind: 1.0.7
1800
-
data-view-buffer: 1.0.1
1801
-
data-view-byte-length: 1.0.1
1802
-
data-view-byte-offset: 1.0.0
1803
-
es-define-property: 1.0.0
1804
es-errors: 1.3.0
1805
-
es-object-atoms: 1.0.0
1806
-
es-set-tostringtag: 2.0.3
1807
-
es-to-primitive: 1.2.1
1808
-
function.prototype.name: 1.1.6
1809
-
get-intrinsic: 1.2.4
1810
-
get-symbol-description: 1.0.2
1811
globalthis: 1.0.4
1812
-
gopd: 1.0.1
1813
has-property-descriptors: 1.0.2
1814
-
has-proto: 1.0.3
1815
-
has-symbols: 1.0.3
1816
hasown: 2.0.2
1817
-
internal-slot: 1.0.7
1818
-
is-array-buffer: 3.0.4
1819
is-callable: 1.2.7
1820
-
is-data-view: 1.0.1
1821
-
is-negative-zero: 2.0.3
1822
-
is-regex: 1.1.4
1823
-
is-shared-array-buffer: 1.0.3
1824
-
is-string: 1.0.7
1825
-
is-typed-array: 1.1.13
1826
-
is-weakref: 1.0.2
1827
-
object-inspect: 1.13.2
1828
object-keys: 1.1.1
1829
-
object.assign: 4.1.5
1830
-
regexp.prototype.flags: 1.5.3
1831
-
safe-array-concat: 1.1.2
1832
-
safe-regex-test: 1.0.3
1833
-
string.prototype.trim: 1.2.9
1834
-
string.prototype.trimend: 1.0.8
1835
string.prototype.trimstart: 1.0.8
1836
-
typed-array-buffer: 1.0.2
1837
-
typed-array-byte-length: 1.0.1
1838
-
typed-array-byte-offset: 1.0.2
1839
-
typed-array-length: 1.0.6
1840
-
unbox-primitive: 1.0.2
1841
-
which-typed-array: 1.1.15
1842
1843
-
es-define-property@1.0.0:
1844
-
dependencies:
1845
-
get-intrinsic: 1.2.4
1846
1847
es-errors@1.3.0: {}
1848
1849
-
es-iterator-helpers@1.1.0:
1850
dependencies:
1851
-
call-bind: 1.0.7
1852
define-properties: 1.2.1
1853
-
es-abstract: 1.23.3
1854
es-errors: 1.3.0
1855
-
es-set-tostringtag: 2.0.3
1856
function-bind: 1.1.2
1857
-
get-intrinsic: 1.2.4
1858
globalthis: 1.0.4
1859
has-property-descriptors: 1.0.2
1860
-
has-proto: 1.0.3
1861
-
has-symbols: 1.0.3
1862
-
internal-slot: 1.0.7
1863
-
iterator.prototype: 1.1.3
1864
-
safe-array-concat: 1.1.2
1865
1866
-
es-object-atoms@1.0.0:
1867
dependencies:
1868
es-errors: 1.3.0
1869
1870
-
es-set-tostringtag@2.0.3:
1871
dependencies:
1872
-
get-intrinsic: 1.2.4
1873
has-tostringtag: 1.0.2
1874
hasown: 2.0.2
1875
1876
-
es-shim-unscopables@1.0.2:
1877
dependencies:
1878
hasown: 2.0.2
1879
1880
-
es-to-primitive@1.2.1:
1881
dependencies:
1882
is-callable: 1.2.7
1883
-
is-date-object: 1.0.5
1884
-
is-symbol: 1.0.4
1885
1886
esbuild-copy-static-files@0.1.0: {}
1887
···
1912
1913
escape-string-regexp@4.0.0: {}
1914
1915
-
eslint-config-prettier@9.1.0(eslint@9.12.0):
1916
dependencies:
1917
-
eslint: 9.12.0
1918
1919
-
eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.12.0))(eslint@9.12.0)(prettier@3.1.0):
1920
dependencies:
1921
-
eslint: 9.12.0
1922
prettier: 3.1.0
1923
prettier-linter-helpers: 1.0.0
1924
-
synckit: 0.9.2
1925
optionalDependencies:
1926
-
eslint-config-prettier: 9.1.0(eslint@9.12.0)
1927
1928
-
eslint-plugin-react@7.37.1(eslint@9.12.0):
1929
dependencies:
1930
array-includes: 3.1.8
1931
array.prototype.findlast: 1.2.5
1932
-
array.prototype.flatmap: 1.3.2
1933
array.prototype.tosorted: 1.1.4
1934
doctrine: 2.1.0
1935
-
es-iterator-helpers: 1.1.0
1936
-
eslint: 9.12.0
1937
estraverse: 5.3.0
1938
hasown: 2.0.2
1939
jsx-ast-utils: 3.3.5
1940
minimatch: 3.1.2
1941
-
object.entries: 1.1.8
1942
object.fromentries: 2.0.8
1943
-
object.values: 1.2.0
1944
prop-types: 15.8.1
1945
resolve: 2.0.0-next.5
1946
semver: 6.3.1
1947
-
string.prototype.matchall: 4.0.11
1948
string.prototype.repeat: 1.0.0
1949
1950
-
eslint-scope@8.1.0:
1951
dependencies:
1952
esrecurse: 4.3.0
1953
estraverse: 5.3.0
1954
1955
eslint-visitor-keys@3.4.3: {}
1956
1957
-
eslint-visitor-keys@4.1.0: {}
1958
1959
-
eslint@9.12.0:
1960
dependencies:
1961
-
'@eslint-community/eslint-utils': 4.4.0(eslint@9.12.0)
1962
-
'@eslint-community/regexpp': 4.11.1
1963
-
'@eslint/config-array': 0.18.0
1964
-
'@eslint/core': 0.6.0
1965
-
'@eslint/eslintrc': 3.1.0
1966
-
'@eslint/js': 9.12.0
1967
-
'@eslint/plugin-kit': 0.2.0
1968
-
'@humanfs/node': 0.16.5
1969
'@humanwhocodes/module-importer': 1.0.1
1970
-
'@humanwhocodes/retry': 0.3.1
1971
'@types/estree': 1.0.6
1972
'@types/json-schema': 7.0.15
1973
ajv: 6.12.6
1974
chalk: 4.1.2
1975
-
cross-spawn: 7.0.3
1976
-
debug: 4.3.4
1977
escape-string-regexp: 4.0.0
1978
-
eslint-scope: 8.1.0
1979
-
eslint-visitor-keys: 4.1.0
1980
-
espree: 10.2.0
1981
-
esquery: 1.5.0
1982
esutils: 2.0.3
1983
fast-deep-equal: 3.1.3
1984
file-entry-cache: 8.0.0
1985
find-up: 5.0.0
1986
glob-parent: 6.0.2
1987
-
ignore: 5.3.0
1988
imurmurhash: 0.1.4
1989
is-glob: 4.0.3
1990
json-stable-stringify-without-jsonify: 1.0.1
···
1992
minimatch: 3.1.2
1993
natural-compare: 1.4.0
1994
optionator: 0.9.3
1995
-
text-table: 0.2.0
1996
transitivePeerDependencies:
1997
- supports-color
1998
1999
-
espree@10.2.0:
2000
dependencies:
2001
-
acorn: 8.12.1
2002
-
acorn-jsx: 5.3.2(acorn@8.12.1)
2003
-
eslint-visitor-keys: 4.1.0
2004
2005
-
esquery@1.5.0:
2006
dependencies:
2007
estraverse: 5.3.0
2008
···
2045
dependencies:
2046
reusify: 1.0.4
2047
2048
file-entry-cache@8.0.0:
2049
dependencies:
2050
flat-cache: 4.0.1
···
2053
dependencies:
2054
to-regex-range: 5.0.1
2055
2056
find-up@5.0.0:
2057
dependencies:
2058
locate-path: 6.0.0
···
2065
2066
flatted@3.2.9: {}
2067
2068
-
for-each@0.3.3:
2069
dependencies:
2070
is-callable: 1.2.7
2071
2072
function-bind@1.1.2: {}
2073
2074
-
function.prototype.name@1.1.6:
2075
dependencies:
2076
-
call-bind: 1.0.7
2077
define-properties: 1.2.1
2078
-
es-abstract: 1.23.3
2079
functions-have-names: 1.2.3
2080
2081
functions-have-names@1.2.3: {}
2082
2083
-
get-intrinsic@1.2.4:
2084
dependencies:
2085
es-errors: 1.3.0
2086
function-bind: 1.1.2
2087
-
has-proto: 1.0.3
2088
-
has-symbols: 1.0.3
2089
hasown: 2.0.2
2090
2091
-
get-symbol-description@1.0.2:
2092
dependencies:
2093
-
call-bind: 1.0.7
2094
es-errors: 1.3.0
2095
-
get-intrinsic: 1.2.4
2096
2097
glob-parent@5.1.2:
2098
dependencies:
···
2107
globalthis@1.0.4:
2108
dependencies:
2109
define-properties: 1.2.1
2110
-
gopd: 1.0.1
2111
2112
-
gopd@1.0.1:
2113
-
dependencies:
2114
-
get-intrinsic: 1.2.4
2115
2116
graphemer@1.4.0: {}
2117
2118
-
has-bigints@1.0.2: {}
2119
2120
has-flag@4.0.0: {}
2121
2122
has-property-descriptors@1.0.2:
2123
dependencies:
2124
-
es-define-property: 1.0.0
2125
2126
-
has-proto@1.0.3: {}
2127
2128
-
has-symbols@1.0.3: {}
2129
2130
has-tostringtag@1.0.2:
2131
dependencies:
2132
-
has-symbols: 1.0.3
2133
2134
hasown@2.0.2:
2135
dependencies:
···
2138
husky@8.0.3: {}
2139
2140
ieee754@1.2.1: {}
2141
-
2142
-
ignore@5.3.0: {}
2143
2144
ignore@5.3.2: {}
2145
···
2150
2151
imurmurhash@0.1.4: {}
2152
2153
-
internal-slot@1.0.7:
2154
dependencies:
2155
es-errors: 1.3.0
2156
hasown: 2.0.2
2157
-
side-channel: 1.0.6
2158
2159
-
is-array-buffer@3.0.4:
2160
dependencies:
2161
-
call-bind: 1.0.7
2162
-
get-intrinsic: 1.2.4
2163
2164
-
is-async-function@2.0.0:
2165
dependencies:
2166
has-tostringtag: 1.0.2
2167
2168
-
is-bigint@1.0.4:
2169
dependencies:
2170
-
has-bigints: 1.0.2
2171
2172
-
is-boolean-object@1.1.2:
2173
dependencies:
2174
-
call-bind: 1.0.7
2175
has-tostringtag: 1.0.2
2176
2177
is-callable@1.2.7: {}
2178
2179
-
is-core-module@2.15.1:
2180
dependencies:
2181
hasown: 2.0.2
2182
2183
-
is-data-view@1.0.1:
2184
dependencies:
2185
-
is-typed-array: 1.1.13
2186
2187
-
is-date-object@1.0.5:
2188
dependencies:
2189
has-tostringtag: 1.0.2
2190
2191
is-extglob@2.1.1: {}
2192
2193
-
is-finalizationregistry@1.0.2:
2194
dependencies:
2195
-
call-bind: 1.0.7
2196
2197
-
is-generator-function@1.0.10:
2198
dependencies:
2199
has-tostringtag: 1.0.2
2200
2201
is-glob@4.0.3:
2202
dependencies:
···
2204
2205
is-map@2.0.3: {}
2206
2207
-
is-negative-zero@2.0.3: {}
2208
-
2209
-
is-number-object@1.0.7:
2210
dependencies:
2211
has-tostringtag: 1.0.2
2212
2213
is-number@7.0.0: {}
2214
2215
-
is-regex@1.1.4:
2216
dependencies:
2217
-
call-bind: 1.0.7
2218
has-tostringtag: 1.0.2
2219
2220
is-set@2.0.3: {}
2221
2222
-
is-shared-array-buffer@1.0.3:
2223
dependencies:
2224
-
call-bind: 1.0.7
2225
2226
-
is-string@1.0.7:
2227
dependencies:
2228
has-tostringtag: 1.0.2
2229
2230
-
is-symbol@1.0.4:
2231
dependencies:
2232
-
has-symbols: 1.0.3
2233
2234
-
is-typed-array@1.1.13:
2235
dependencies:
2236
-
which-typed-array: 1.1.15
2237
2238
is-weakmap@2.0.2: {}
2239
2240
-
is-weakref@1.0.2:
2241
dependencies:
2242
-
call-bind: 1.0.7
2243
2244
-
is-weakset@2.0.3:
2245
dependencies:
2246
-
call-bind: 1.0.7
2247
-
get-intrinsic: 1.2.4
2248
2249
isarray@2.0.5: {}
2250
2251
isexe@2.0.0: {}
2252
2253
-
iterator.prototype@1.1.3:
2254
dependencies:
2255
-
define-properties: 1.2.1
2256
-
get-intrinsic: 1.2.4
2257
-
has-symbols: 1.0.3
2258
-
reflect.getprototypeof: 1.0.6
2259
set-function-name: 2.0.2
2260
2261
js-tokens@4.0.0: {}
2262
2263
js-yaml@4.1.0:
···
2273
jsx-ast-utils@3.3.5:
2274
dependencies:
2275
array-includes: 3.1.8
2276
-
array.prototype.flat: 1.3.2
2277
-
object.assign: 4.1.5
2278
-
object.values: 1.2.0
2279
2280
keyv@4.5.4:
2281
dependencies:
···
2296
dependencies:
2297
js-tokens: 4.0.0
2298
2299
merge2@1.4.1: {}
2300
2301
meriyah@6.0.1: {}
···
2306
dependencies:
2307
braces: 3.0.3
2308
picomatch: 2.3.1
2309
2310
minimatch@3.1.2:
2311
dependencies:
···
2315
dependencies:
2316
brace-expansion: 2.0.1
2317
2318
-
ms@2.1.2: {}
2319
2320
nanotar@0.1.1: {}
2321
2322
natural-compare@1.4.0: {}
2323
2324
object-assign@4.1.1: {}
2325
2326
-
object-inspect@1.13.2: {}
2327
2328
object-keys@1.1.1: {}
2329
2330
-
object.assign@4.1.5:
2331
dependencies:
2332
-
call-bind: 1.0.7
2333
define-properties: 1.2.1
2334
-
has-symbols: 1.0.3
2335
object-keys: 1.1.1
2336
2337
-
object.entries@1.1.8:
2338
dependencies:
2339
-
call-bind: 1.0.7
2340
define-properties: 1.2.1
2341
-
es-object-atoms: 1.0.0
2342
2343
object.fromentries@2.0.8:
2344
dependencies:
2345
-
call-bind: 1.0.7
2346
define-properties: 1.2.1
2347
-
es-abstract: 1.23.3
2348
-
es-object-atoms: 1.0.0
2349
2350
-
object.values@1.2.0:
2351
dependencies:
2352
-
call-bind: 1.0.7
2353
define-properties: 1.2.1
2354
-
es-object-atoms: 1.0.0
2355
2356
optionator@0.9.3:
2357
dependencies:
···
2361
levn: 0.4.1
2362
prelude-ls: 1.2.1
2363
type-check: 0.4.0
2364
2365
p-limit@3.1.0:
2366
dependencies:
···
2370
dependencies:
2371
p-limit: 3.1.0
2372
2373
parent-module@1.0.1:
2374
dependencies:
2375
callsites: 3.1.0
···
2380
2381
path-parse@1.0.7: {}
2382
2383
picomatch@2.3.1: {}
2384
2385
-
possible-typed-array-names@1.0.0: {}
2386
2387
prelude-ls@1.2.1: {}
2388
···
2402
2403
punycode@2.3.1: {}
2404
2405
queue-microtask@1.2.3: {}
2406
2407
react-is@16.13.1: {}
···
2414
process: 0.11.10
2415
string_decoder: 1.3.0
2416
2417
-
reflect.getprototypeof@1.0.6:
2418
dependencies:
2419
-
call-bind: 1.0.7
2420
define-properties: 1.2.1
2421
-
es-abstract: 1.23.3
2422
es-errors: 1.3.0
2423
-
get-intrinsic: 1.2.4
2424
-
globalthis: 1.0.4
2425
-
which-builtin-type: 1.1.4
2426
2427
-
regexp.prototype.flags@1.5.3:
2428
dependencies:
2429
-
call-bind: 1.0.7
2430
define-properties: 1.2.1
2431
es-errors: 1.3.0
2432
set-function-name: 2.0.2
2433
2434
resolve-from@4.0.0: {}
2435
2436
resolve@2.0.0-next.5:
2437
dependencies:
2438
-
is-core-module: 2.15.1
2439
path-parse: 1.0.7
2440
supports-preserve-symlinks-flag: 1.0.0
2441
2442
reusify@1.0.4: {}
2443
2444
run-parallel@1.2.0:
2445
dependencies:
2446
queue-microtask: 1.2.3
2447
2448
-
safe-array-concat@1.1.2:
2449
dependencies:
2450
-
call-bind: 1.0.7
2451
-
get-intrinsic: 1.2.4
2452
-
has-symbols: 1.0.3
2453
isarray: 2.0.5
2454
2455
-
safe-buffer@5.1.2: {}
2456
-
2457
safe-buffer@5.2.1: {}
2458
2459
-
safe-regex-test@1.0.3:
2460
dependencies:
2461
-
call-bind: 1.0.7
2462
es-errors: 1.3.0
2463
-
is-regex: 1.1.4
2464
2465
semver@6.3.1: {}
2466
2467
-
semver@7.6.3: {}
2468
2469
set-function-length@1.2.2:
2470
dependencies:
2471
define-data-property: 1.1.4
2472
es-errors: 1.3.0
2473
function-bind: 1.1.2
2474
-
get-intrinsic: 1.2.4
2475
-
gopd: 1.0.1
2476
has-property-descriptors: 1.0.2
2477
2478
set-function-name@2.0.2:
···
2482
functions-have-names: 1.2.3
2483
has-property-descriptors: 1.0.2
2484
2485
shebang-command@2.0.0:
2486
dependencies:
2487
shebang-regex: 3.0.0
2488
2489
shebang-regex@3.0.0: {}
2490
2491
-
side-channel@1.0.6:
2492
dependencies:
2493
-
call-bind: 1.0.7
2494
es-errors: 1.3.0
2495
-
get-intrinsic: 1.2.4
2496
-
object-inspect: 1.13.2
2497
2498
standalone-electron-types@1.0.0:
2499
dependencies:
2500
'@types/node': 18.17.17
2501
2502
-
string.prototype.matchall@4.0.11:
2503
dependencies:
2504
-
call-bind: 1.0.7
2505
define-properties: 1.2.1
2506
-
es-abstract: 1.23.3
2507
es-errors: 1.3.0
2508
-
es-object-atoms: 1.0.0
2509
-
get-intrinsic: 1.2.4
2510
-
gopd: 1.0.1
2511
-
has-symbols: 1.0.3
2512
-
internal-slot: 1.0.7
2513
-
regexp.prototype.flags: 1.5.3
2514
set-function-name: 2.0.2
2515
-
side-channel: 1.0.6
2516
2517
string.prototype.repeat@1.0.0:
2518
dependencies:
2519
define-properties: 1.2.1
2520
-
es-abstract: 1.23.3
2521
2522
-
string.prototype.trim@1.2.9:
2523
dependencies:
2524
-
call-bind: 1.0.7
2525
define-properties: 1.2.1
2526
-
es-abstract: 1.23.3
2527
-
es-object-atoms: 1.0.0
2528
2529
-
string.prototype.trimend@1.0.8:
2530
dependencies:
2531
-
call-bind: 1.0.7
2532
define-properties: 1.2.1
2533
-
es-object-atoms: 1.0.0
2534
2535
string.prototype.trimstart@1.0.8:
2536
dependencies:
2537
-
call-bind: 1.0.7
2538
define-properties: 1.2.1
2539
-
es-object-atoms: 1.0.0
2540
2541
string_decoder@1.3.0:
2542
dependencies:
···
2550
2551
supports-preserve-symlinks-flag@1.0.0: {}
2552
2553
-
synckit@0.9.2:
2554
dependencies:
2555
-
'@pkgr/core': 0.1.1
2556
-
tslib: 2.7.0
2557
2558
-
text-table@0.2.0: {}
2559
2560
to-regex-range@5.0.1:
2561
dependencies:
2562
is-number: 7.0.0
2563
2564
-
ts-api-utils@1.3.0(typescript@5.3.2):
2565
dependencies:
2566
-
typescript: 5.3.2
2567
2568
-
tslib@2.7.0: {}
2569
2570
type-check@0.4.0:
2571
dependencies:
2572
prelude-ls: 1.2.1
2573
2574
-
typed-array-buffer@1.0.2:
2575
dependencies:
2576
-
call-bind: 1.0.7
2577
es-errors: 1.3.0
2578
-
is-typed-array: 1.1.13
2579
2580
-
typed-array-byte-length@1.0.1:
2581
dependencies:
2582
-
call-bind: 1.0.7
2583
-
for-each: 0.3.3
2584
-
gopd: 1.0.1
2585
-
has-proto: 1.0.3
2586
-
is-typed-array: 1.1.13
2587
2588
-
typed-array-byte-offset@1.0.2:
2589
dependencies:
2590
available-typed-arrays: 1.0.7
2591
-
call-bind: 1.0.7
2592
-
for-each: 0.3.3
2593
-
gopd: 1.0.1
2594
-
has-proto: 1.0.3
2595
-
is-typed-array: 1.1.13
2596
2597
-
typed-array-length@1.0.6:
2598
dependencies:
2599
-
call-bind: 1.0.7
2600
-
for-each: 0.3.3
2601
-
gopd: 1.0.1
2602
-
has-proto: 1.0.3
2603
-
is-typed-array: 1.1.13
2604
-
possible-typed-array-names: 1.0.0
2605
2606
-
typescript-eslint@8.8.1(eslint@9.12.0)(typescript@5.3.2):
2607
dependencies:
2608
-
'@typescript-eslint/eslint-plugin': 8.8.1(@typescript-eslint/parser@8.8.1(eslint@9.12.0)(typescript@5.3.2))(eslint@9.12.0)(typescript@5.3.2)
2609
-
'@typescript-eslint/parser': 8.8.1(eslint@9.12.0)(typescript@5.3.2)
2610
-
'@typescript-eslint/utils': 8.8.1(eslint@9.12.0)(typescript@5.3.2)
2611
-
optionalDependencies:
2612
-
typescript: 5.3.2
2613
transitivePeerDependencies:
2614
-
- eslint
2615
- supports-color
2616
2617
-
typescript@5.3.2: {}
2618
2619
-
unbox-primitive@1.0.2:
2620
dependencies:
2621
-
call-bind: 1.0.7
2622
-
has-bigints: 1.0.2
2623
-
has-symbols: 1.0.3
2624
-
which-boxed-primitive: 1.0.2
2625
2626
-
undici-types@6.19.8: {}
2627
2628
uri-js@4.4.1:
2629
dependencies:
2630
punycode: 2.3.1
2631
2632
-
utilium@0.7.1:
2633
dependencies:
2634
eventemitter3: 5.0.1
2635
2636
-
which-boxed-primitive@1.0.2:
2637
dependencies:
2638
-
is-bigint: 1.0.4
2639
-
is-boolean-object: 1.1.2
2640
-
is-number-object: 1.0.7
2641
-
is-string: 1.0.7
2642
-
is-symbol: 1.0.4
2643
2644
-
which-builtin-type@1.1.4:
2645
dependencies:
2646
-
function.prototype.name: 1.1.6
2647
has-tostringtag: 1.0.2
2648
-
is-async-function: 2.0.0
2649
-
is-date-object: 1.0.5
2650
-
is-finalizationregistry: 1.0.2
2651
-
is-generator-function: 1.0.10
2652
-
is-regex: 1.1.4
2653
-
is-weakref: 1.0.2
2654
isarray: 2.0.5
2655
-
which-boxed-primitive: 1.0.2
2656
which-collection: 1.0.2
2657
-
which-typed-array: 1.1.15
2658
2659
which-collection@1.0.2:
2660
dependencies:
2661
is-map: 2.0.3
2662
is-set: 2.0.3
2663
is-weakmap: 2.0.2
2664
-
is-weakset: 2.0.3
2665
2666
-
which-typed-array@1.1.15:
2667
dependencies:
2668
available-typed-arrays: 1.0.7
2669
-
call-bind: 1.0.7
2670
-
for-each: 0.3.3
2671
-
gopd: 1.0.1
2672
has-tostringtag: 1.0.2
2673
2674
which@2.0.2:
2675
dependencies:
2676
isexe: 2.0.0
2677
2678
yocto-queue@0.1.0: {}
···
4
autoInstallPeers: true
5
excludeLinksFromLockfile: false
6
7
+
catalogs:
8
+
dev:
9
+
'@moonlight-mod/eslint-config':
10
+
specifier: github:moonlight-mod/eslint-config
11
+
version: 1.0.1
12
+
'@types/chrome':
13
+
specifier: ^0.0.313
14
+
version: 0.0.313
15
+
'@types/node':
16
+
specifier: ^22.14.0
17
+
version: 22.14.0
18
+
esbuild:
19
+
specifier: ^0.19.3
20
+
version: 0.19.3
21
+
esbuild-copy-static-files:
22
+
specifier: ^0.1.0
23
+
version: 0.1.0
24
+
eslint:
25
+
specifier: ^9.12.0
26
+
version: 9.23.0
27
+
husky:
28
+
specifier: ^8.0.3
29
+
version: 8.0.3
30
+
prettier:
31
+
specifier: ^3.1.0
32
+
version: 3.1.0
33
+
taze:
34
+
specifier: ^19.0.4
35
+
version: 19.0.4
36
+
typescript:
37
+
specifier: ^5.3.3
38
+
version: 5.8.2
39
+
prod:
40
+
'@moonlight-mod/lunast':
41
+
specifier: ^1.0.1
42
+
version: 1.0.1
43
+
'@moonlight-mod/mappings':
44
+
specifier: ^1.1.25
45
+
version: 1.1.25
46
+
'@moonlight-mod/moonmap':
47
+
specifier: ^1.0.5
48
+
version: 1.0.5
49
+
'@zenfs/core':
50
+
specifier: ^2.0.0
51
+
version: 2.0.0
52
+
'@zenfs/dom':
53
+
specifier: ^1.1.3
54
+
version: 1.1.6
55
+
microdiff:
56
+
specifier: ^1.5.0
57
+
version: 1.5.0
58
+
nanotar:
59
+
specifier: ^0.1.1
60
+
version: 0.1.1
61
+
62
importers:
63
64
.:
65
devDependencies:
66
'@moonlight-mod/eslint-config':
67
+
specifier: catalog:dev
68
+
version: https://codeload.github.com/moonlight-mod/eslint-config/tar.gz/e262ac24e1a0955a9b3e0d66da247a0a8c0446c9(@types/eslint@9.6.1)(eslint@9.23.0(jiti@2.4.2))(prettier@3.1.0)(typescript@5.8.2)
69
+
'@types/node':
70
+
specifier: catalog:dev
71
+
version: 22.14.0
72
esbuild:
73
+
specifier: catalog:dev
74
version: 0.19.3
75
esbuild-copy-static-files:
76
+
specifier: catalog:dev
77
version: 0.1.0
78
eslint:
79
+
specifier: catalog:dev
80
+
version: 9.23.0(jiti@2.4.2)
81
husky:
82
+
specifier: catalog:dev
83
version: 8.0.3
84
prettier:
85
+
specifier: catalog:dev
86
version: 3.1.0
87
+
taze:
88
+
specifier: catalog:dev
89
+
version: 19.0.4
90
typescript:
91
+
specifier: catalog:dev
92
+
version: 5.8.2
93
94
packages/browser:
95
dependencies:
···
103
specifier: workspace:*
104
version: link:../web-preload
105
'@zenfs/core':
106
+
specifier: catalog:prod
107
+
version: 2.0.0
108
'@zenfs/dom':
109
+
specifier: catalog:prod
110
+
version: 1.1.6(@zenfs/core@2.0.0)(utilium@1.10.1)
111
+
devDependencies:
112
+
'@types/chrome':
113
+
specifier: catalog:dev
114
+
version: 0.0.313
115
116
packages/core:
117
dependencies:
···
128
specifier: workspace:*
129
version: link:../types
130
microdiff:
131
+
specifier: catalog:prod
132
version: 1.5.0
133
nanotar:
134
+
specifier: catalog:prod
135
version: 0.1.1
136
137
packages/injector:
···
155
packages/types:
156
dependencies:
157
'@moonlight-mod/lunast':
158
+
specifier: ^1.0.1
159
+
version: 1.0.1
160
'@moonlight-mod/mappings':
161
+
specifier: ^1.1.25
162
+
version: 1.1.25(@moonlight-mod/lunast@1.0.1)(@moonlight-mod/moonmap@1.0.5)
163
'@moonlight-mod/moonmap':
164
+
specifier: ^1.0.5
165
+
version: 1.0.5
166
'@types/react':
167
specifier: ^18.3.10
168
+
version: 18.3.20
169
csstype:
170
+
specifier: ^3.1.3
171
+
version: 3.1.3
172
standalone-electron-types:
173
specifier: ^1.0.0
174
version: 1.0.0
···
179
specifier: workspace:*
180
version: link:../core
181
'@moonlight-mod/lunast':
182
+
specifier: catalog:prod
183
+
version: 1.0.1
184
'@moonlight-mod/mappings':
185
+
specifier: catalog:prod
186
+
version: 1.1.25(@moonlight-mod/lunast@1.0.1)(@moonlight-mod/moonmap@1.0.5)
187
'@moonlight-mod/moonmap':
188
+
specifier: catalog:prod
189
+
version: 1.0.5
190
'@moonlight-mod/types':
191
specifier: workspace:*
192
version: link:../types
···
196
'@aashutoshrathi/word-wrap@1.2.6':
197
resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
198
engines: {node: '>=0.10.0'}
199
+
200
+
'@antfu/ni@24.3.0':
201
+
resolution: {integrity: sha512-wBSav4mBxvHEW9RbdSo1SWLQ6MAlT0Dc423weC58yOWqW4OcMvtnNDdDrxOZeJ88fEIyPK93gDUWIelBxzSf8g==}
202
+
hasBin: true
203
204
'@esbuild/android-arm64@0.19.3':
205
resolution: {integrity: sha512-w+Akc0vv5leog550kjJV9Ru+MXMR2VuMrui3C61mnysim0gkFCPOUTAfzTP0qX+HpN9Syu3YA3p1hf3EPqObRw==}
···
333
cpu: [x64]
334
os: [win32]
335
336
+
'@eslint-community/eslint-utils@4.5.1':
337
+
resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==}
338
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
339
peerDependencies:
340
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
341
342
+
'@eslint-community/regexpp@4.12.1':
343
+
resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
344
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
345
346
+
'@eslint/config-array@0.19.2':
347
+
resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==}
348
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
349
350
+
'@eslint/config-helpers@0.2.1':
351
+
resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==}
352
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
353
354
+
'@eslint/core@0.12.0':
355
+
resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==}
356
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
357
+
358
+
'@eslint/core@0.13.0':
359
+
resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==}
360
+
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
361
+
362
+
'@eslint/eslintrc@3.3.1':
363
+
resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
364
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
365
366
+
'@eslint/js@9.23.0':
367
+
resolution: {integrity: sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==}
368
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
369
370
+
'@eslint/object-schema@2.1.6':
371
+
resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==}
372
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
373
374
+
'@eslint/plugin-kit@0.2.8':
375
+
resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==}
376
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
377
378
+
'@humanfs/core@0.19.1':
379
+
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
380
engines: {node: '>=18.18.0'}
381
382
+
'@humanfs/node@0.16.6':
383
+
resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==}
384
engines: {node: '>=18.18.0'}
385
386
'@humanwhocodes/module-importer@1.0.1':
···
391
resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==}
392
engines: {node: '>=18.18'}
393
394
+
'@humanwhocodes/retry@0.4.2':
395
+
resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==}
396
+
engines: {node: '>=18.18'}
397
+
398
'@moonlight-mod/eslint-config@https://codeload.github.com/moonlight-mod/eslint-config/tar.gz/e262ac24e1a0955a9b3e0d66da247a0a8c0446c9':
399
resolution: {tarball: https://codeload.github.com/moonlight-mod/eslint-config/tar.gz/e262ac24e1a0955a9b3e0d66da247a0a8c0446c9}
400
version: 1.0.1
···
402
eslint: '>= 9'
403
typescript: '>= 5.3'
404
405
+
'@moonlight-mod/lunast@1.0.1':
406
+
resolution: {integrity: sha512-K3vxzDlfFuYKjciIW2FMlcZ1qrrkAGDGpSBlNqYGtJ0sMt9bRCd2lpSpg6AX/giSljDtmAUXa/5mOfUoDQxjBA==}
407
408
+
'@moonlight-mod/mappings@1.1.25':
409
+
resolution: {integrity: sha512-bgnSN9H/IBdMGxGev6RQKXuzhQxwo1090NhIDHnflguZnjiu2pg/usPfh76bqyhxRuX4SS7tiZSNTwBoSflCLg==}
410
+
engines: {node: '>=22', npm: pnpm, pnpm: '>=10', yarn: pnpm}
411
peerDependencies:
412
+
'@moonlight-mod/lunast': ^1.0.1
413
+
'@moonlight-mod/moonmap': ^1.0.5
414
415
+
'@moonlight-mod/moonmap@1.0.5':
416
+
resolution: {integrity: sha512-Fdpxj8ghdulKB6TlTnchlCPey2YUKgEf1chuO1ofOIcvlqnVPBcQwSf2S80naOUQpXCDo4dQ+LWSE2fmhdDiiw==}
417
418
'@nodelib/fs.scandir@2.1.5':
419
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
···
427
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
428
engines: {node: '>= 8'}
429
430
+
'@pkgr/core@0.2.0':
431
+
resolution: {integrity: sha512-vsJDAkYR6qCPu+ioGScGiMYR7LvZYIXh/dlQeviqoTWNCVfKTLYD/LkNWH4Mxsv2a5vpIRc77FN5DnmK1eBggQ==}
432
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
433
+
434
+
'@quansync/fs@0.1.2':
435
+
resolution: {integrity: sha512-ezIadUb1aFhwJLd++WVqVpi9rnlX8vnd4ju7saPhwLHJN1mJgOv0puePTGV+FbtSnWtwoHDT8lAm4kagDZmpCg==}
436
+
engines: {node: '>=20.0.0'}
437
+
438
+
'@types/chroma-js@3.1.0':
439
+
resolution: {integrity: sha512-Uwl3SOtUkbQ6Ye6ZYu4q4xdLGBzmY839sEHYtOT7i691neeyd+7fXWT5VIkcUSfNwIFrIjQutNYQn9h4q5HFvg==}
440
+
441
+
'@types/chrome@0.0.313':
442
+
resolution: {integrity: sha512-9R5T7gTaYZhkxlu+Ho4wk9FL+y/werWQY2yjGWSqCuiTsqS7nL/BE5UMTP6rU7J+oIG2FRKqrEycHhJATeltVA==}
443
+
444
+
'@types/eslint@9.6.1':
445
+
resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==}
446
447
'@types/estree-jsx@1.0.5':
448
resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
···
450
'@types/estree@1.0.6':
451
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
452
453
+
'@types/estree@1.0.7':
454
+
resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
455
+
456
'@types/fbemitter@2.0.35':
457
resolution: {integrity: sha512-Xem6d7qUfmouCHntCrRYgDBwbf+WWRd6G+7WEFlEZFZ67LZXiYRvT2LV8wcZa6mIaAil95+ABQdKgB6hPIsnng==}
458
459
+
'@types/filesystem@0.0.36':
460
+
resolution: {integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==}
461
+
462
+
'@types/filewriter@0.0.33':
463
+
resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==}
464
+
465
'@types/flux@3.1.14':
466
resolution: {integrity: sha512-WRXN0kQPCnqxN0/PgNgc7WBF6c8rbSHsEep3/qBLpsQ824RONdOmTs0TV7XhIW2GDNRAHO2CqCgAFLR5PChosw==}
467
+
468
+
'@types/har-format@1.2.16':
469
+
resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==}
470
+
471
+
'@types/highlightjs@9.12.6':
472
+
resolution: {integrity: sha512-Qfd1DUrwE851Hc3tExADJY4qY8yeZMt06Xw9AJm/UtpneepJS3MZY29c33BY0wP899veaaHD4gZzYiSuQm84Fg==}
473
474
'@types/json-schema@7.0.15':
475
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
476
477
+
'@types/lodash@4.17.14':
478
+
resolution: {integrity: sha512-jsxagdikDiDBeIRaPYtArcT8my4tN1og7MtMRquFT3XNA6axxyHDRUemqDz/taRDdOUn0GnGHRCuff4q48sW9A==}
479
+
480
'@types/node@18.17.17':
481
resolution: {integrity: sha512-cOxcXsQ2sxiwkykdJqvyFS+MLQPLvIdwh5l6gNg8qF6s+C7XSkEWOZjK+XhUZd+mYvHV/180g2cnCcIl4l06Pw==}
482
483
+
'@types/node@22.13.6':
484
+
resolution: {integrity: sha512-GYmF65GI7417CpZXsEXMjT8goQQDnpRnJnDw6jIYa+le3V/lMazPZ4vZmK1B/9R17fh2VLr2zuy9d/h5xgrLAg==}
485
+
486
+
'@types/node@22.14.0':
487
+
resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==}
488
+
489
+
'@types/platform@1.3.6':
490
+
resolution: {integrity: sha512-ZmSaqHuvzv+jC232cFoz2QqPUkaj6EvMmCrWcx3WRr7xTPVFCMUOTcOq8m2d+Zw1iKRc1kDiaA+jtNrV0hkVew==}
491
492
'@types/prop-types@15.7.13':
493
resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==}
494
495
+
'@types/react@18.3.20':
496
+
resolution: {integrity: sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==}
497
498
+
'@typescript-eslint/eslint-plugin@8.29.0':
499
+
resolution: {integrity: sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==}
500
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
501
peerDependencies:
502
'@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0
503
eslint: ^8.57.0 || ^9.0.0
504
+
typescript: '>=4.8.4 <5.9.0'
505
506
+
'@typescript-eslint/parser@8.29.0':
507
+
resolution: {integrity: sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==}
508
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
509
peerDependencies:
510
eslint: ^8.57.0 || ^9.0.0
511
+
typescript: '>=4.8.4 <5.9.0'
512
513
+
'@typescript-eslint/scope-manager@8.29.0':
514
+
resolution: {integrity: sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==}
515
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
516
517
+
'@typescript-eslint/type-utils@8.29.0':
518
+
resolution: {integrity: sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q==}
519
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
520
peerDependencies:
521
+
eslint: ^8.57.0 || ^9.0.0
522
+
typescript: '>=4.8.4 <5.9.0'
523
524
+
'@typescript-eslint/types@8.29.0':
525
+
resolution: {integrity: sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==}
526
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
527
528
+
'@typescript-eslint/typescript-estree@8.29.0':
529
+
resolution: {integrity: sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==}
530
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
531
peerDependencies:
532
+
typescript: '>=4.8.4 <5.9.0'
533
534
+
'@typescript-eslint/utils@8.29.0':
535
+
resolution: {integrity: sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA==}
536
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
537
peerDependencies:
538
eslint: ^8.57.0 || ^9.0.0
539
+
typescript: '>=4.8.4 <5.9.0'
540
541
+
'@typescript-eslint/visitor-keys@8.29.0':
542
+
resolution: {integrity: sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==}
543
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
544
545
+
'@xterm/xterm@5.5.0':
546
+
resolution: {integrity: sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==}
547
+
548
+
'@zenfs/core@2.0.0':
549
+
resolution: {integrity: sha512-wOKNFTY1DJ1vdLqKdU7M8cRh0nVYZcDVu7WHuk/3u49hrSwTZVm4PzGxJUjFd8O9Wi3U5nYTbZoN7RX5mS2ldA==}
550
+
engines: {node: '>= 18'}
551
hasBin: true
552
553
+
'@zenfs/dom@1.1.6':
554
+
resolution: {integrity: sha512-7SBTWgA0esuEv/TE+N/xk6W/XJf8uBF+LhlPNHQdXds0H7aOy/UYsWv/8glvARe+meDMMidoeWFLzUWoMXfjlA==}
555
engines: {node: '>= 18'}
556
peerDependencies:
557
+
'@zenfs/core': ^2.0.0
558
+
utilium: ^1.9.0
559
560
abort-controller@3.0.0:
561
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
···
566
peerDependencies:
567
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
568
569
+
acorn@8.14.1:
570
+
resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==}
571
engines: {node: '>=0.4.0'}
572
hasBin: true
573
···
578
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
579
engines: {node: '>=8'}
580
581
+
ansis@3.17.0:
582
+
resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==}
583
+
engines: {node: '>=14'}
584
+
585
argparse@2.0.1:
586
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
587
588
+
array-buffer-byte-length@1.0.2:
589
+
resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
590
engines: {node: '>= 0.4'}
591
592
array-includes@3.1.8:
···
597
resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
598
engines: {node: '>= 0.4'}
599
600
+
array.prototype.flat@1.3.3:
601
+
resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==}
602
engines: {node: '>= 0.4'}
603
604
+
array.prototype.flatmap@1.3.3:
605
+
resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==}
606
engines: {node: '>= 0.4'}
607
608
array.prototype.tosorted@1.1.4:
609
resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==}
610
engines: {node: '>= 0.4'}
611
612
+
arraybuffer.prototype.slice@1.0.4:
613
+
resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
614
engines: {node: '>= 0.4'}
615
616
astring@1.9.0:
617
resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
618
hasBin: true
619
+
620
+
async-function@1.0.0:
621
+
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
622
+
engines: {node: '>= 0.4'}
623
624
available-typed-arrays@1.0.7:
625
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
···
644
buffer@6.0.3:
645
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
646
647
+
cac@6.7.14:
648
+
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
649
+
engines: {node: '>=8'}
650
+
651
+
call-bind-apply-helpers@1.0.2:
652
+
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
653
+
engines: {node: '>= 0.4'}
654
+
655
+
call-bind@1.0.8:
656
+
resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==}
657
+
engines: {node: '>= 0.4'}
658
+
659
+
call-bound@1.0.4:
660
+
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
661
engines: {node: '>= 0.4'}
662
663
callsites@3.1.0:
···
678
concat-map@0.0.1:
679
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
680
681
+
cross-spawn@7.0.6:
682
+
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
683
engines: {node: '>= 8'}
684
685
csstype@3.1.3:
686
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
687
688
+
data-view-buffer@1.0.2:
689
+
resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
690
engines: {node: '>= 0.4'}
691
692
+
data-view-byte-length@1.0.2:
693
+
resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==}
694
engines: {node: '>= 0.4'}
695
696
+
data-view-byte-offset@1.0.1:
697
+
resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
698
engines: {node: '>= 0.4'}
699
700
+
debug@4.4.0:
701
+
resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
702
engines: {node: '>=6.0'}
703
peerDependencies:
704
supports-color: '*'
···
717
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
718
engines: {node: '>= 0.4'}
719
720
+
defu@6.1.4:
721
+
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
722
+
723
+
destr@2.0.4:
724
+
resolution: {integrity: sha512-FCAorltMy7QwX0QU38jOkhrv20LBpsHA8ogzvMhhPHCCKVCaN6GxrB0GGaWEWBUYI4eEjjfJ95RdP6dk9IdMQA==}
725
+
726
doctrine@2.1.0:
727
resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
728
engines: {node: '>=0.10.0'}
729
730
+
dunder-proto@1.0.1:
731
+
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
732
engines: {node: '>= 0.4'}
733
734
+
es-abstract@1.23.9:
735
+
resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==}
736
+
engines: {node: '>= 0.4'}
737
+
738
+
es-define-property@1.0.1:
739
+
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
740
engines: {node: '>= 0.4'}
741
742
es-errors@1.3.0:
743
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
744
engines: {node: '>= 0.4'}
745
746
+
es-iterator-helpers@1.2.1:
747
+
resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==}
748
engines: {node: '>= 0.4'}
749
750
+
es-object-atoms@1.1.1:
751
+
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
752
engines: {node: '>= 0.4'}
753
754
+
es-set-tostringtag@2.1.0:
755
+
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
756
engines: {node: '>= 0.4'}
757
758
+
es-shim-unscopables@1.1.0:
759
+
resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==}
760
+
engines: {node: '>= 0.4'}
761
762
+
es-to-primitive@1.3.0:
763
+
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
764
engines: {node: '>= 0.4'}
765
766
esbuild-copy-static-files@0.1.0:
···
781
peerDependencies:
782
eslint: '>=7.0.0'
783
784
+
eslint-plugin-prettier@5.2.6:
785
+
resolution: {integrity: sha512-mUcf7QG2Tjk7H055Jk0lGBjbgDnfrvqjhXh9t2xLMSCjZVcw9Rb1V6sVNXO0th3jgeO7zllWPTNRil3JW94TnQ==}
786
engines: {node: ^14.18.0 || >=16.0.0}
787
peerDependencies:
788
'@types/eslint': '>=8.0.0'
789
eslint: '>=8.0.0'
790
+
eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0'
791
prettier: '>=3.0.0'
792
peerDependenciesMeta:
793
'@types/eslint':
···
795
eslint-config-prettier:
796
optional: true
797
798
+
eslint-plugin-react@7.37.5:
799
+
resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==}
800
engines: {node: '>=4'}
801
peerDependencies:
802
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
803
804
+
eslint-scope@8.3.0:
805
+
resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==}
806
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
807
808
eslint-visitor-keys@3.4.3:
809
resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
810
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
811
812
+
eslint-visitor-keys@4.2.0:
813
+
resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==}
814
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
815
816
+
eslint@9.23.0:
817
+
resolution: {integrity: sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==}
818
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
819
hasBin: true
820
peerDependencies:
···
823
jiti:
824
optional: true
825
826
+
espree@10.3.0:
827
+
resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==}
828
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
829
830
+
esquery@1.6.0:
831
+
resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
832
engines: {node: '>=0.10'}
833
834
esrecurse@4.3.0:
···
876
fastq@1.17.1:
877
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
878
879
+
fdir@6.4.3:
880
+
resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==}
881
+
peerDependencies:
882
+
picomatch: ^3 || ^4
883
+
peerDependenciesMeta:
884
+
picomatch:
885
+
optional: true
886
+
887
file-entry-cache@8.0.0:
888
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
889
engines: {node: '>=16.0.0'}
···
892
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
893
engines: {node: '>=8'}
894
895
+
find-up-simple@1.0.1:
896
+
resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==}
897
+
engines: {node: '>=18'}
898
+
899
find-up@5.0.0:
900
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
901
engines: {node: '>=10'}
···
907
flatted@3.2.9:
908
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
909
910
+
for-each@0.3.5:
911
+
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
912
+
engines: {node: '>= 0.4'}
913
914
function-bind@1.1.2:
915
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
916
917
+
function.prototype.name@1.1.8:
918
+
resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==}
919
engines: {node: '>= 0.4'}
920
921
functions-have-names@1.2.3:
922
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
923
924
+
fzf@0.5.2:
925
+
resolution: {integrity: sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==}
926
+
927
+
get-intrinsic@1.3.0:
928
+
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
929
engines: {node: '>= 0.4'}
930
931
+
get-proto@1.0.1:
932
+
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
933
+
engines: {node: '>= 0.4'}
934
+
935
+
get-symbol-description@1.1.0:
936
+
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
937
engines: {node: '>= 0.4'}
938
939
glob-parent@5.1.2:
···
952
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
953
engines: {node: '>= 0.4'}
954
955
+
gopd@1.2.0:
956
+
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
957
+
engines: {node: '>= 0.4'}
958
959
graphemer@1.4.0:
960
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
961
962
+
has-bigints@1.1.0:
963
+
resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
964
+
engines: {node: '>= 0.4'}
965
966
has-flag@4.0.0:
967
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
···
970
has-property-descriptors@1.0.2:
971
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
972
973
+
has-proto@1.2.0:
974
+
resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==}
975
engines: {node: '>= 0.4'}
976
977
+
has-symbols@1.1.0:
978
+
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
979
engines: {node: '>= 0.4'}
980
981
has-tostringtag@1.0.2:
···
994
ieee754@1.2.1:
995
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
996
997
ignore@5.3.2:
998
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
999
engines: {node: '>= 4'}
···
1006
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
1007
engines: {node: '>=0.8.19'}
1008
1009
+
internal-slot@1.1.0:
1010
+
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
1011
engines: {node: '>= 0.4'}
1012
1013
+
is-array-buffer@3.0.5:
1014
+
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
1015
engines: {node: '>= 0.4'}
1016
1017
+
is-async-function@2.1.1:
1018
+
resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
1019
engines: {node: '>= 0.4'}
1020
1021
+
is-bigint@1.1.0:
1022
+
resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==}
1023
+
engines: {node: '>= 0.4'}
1024
1025
+
is-boolean-object@1.2.2:
1026
+
resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==}
1027
engines: {node: '>= 0.4'}
1028
1029
is-callable@1.2.7:
1030
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
1031
engines: {node: '>= 0.4'}
1032
1033
+
is-core-module@2.16.1:
1034
+
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
1035
engines: {node: '>= 0.4'}
1036
1037
+
is-data-view@1.0.2:
1038
+
resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==}
1039
engines: {node: '>= 0.4'}
1040
1041
+
is-date-object@1.1.0:
1042
+
resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
1043
engines: {node: '>= 0.4'}
1044
1045
is-extglob@2.1.1:
1046
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
1047
engines: {node: '>=0.10.0'}
1048
1049
+
is-finalizationregistry@1.1.1:
1050
+
resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
1051
+
engines: {node: '>= 0.4'}
1052
1053
+
is-generator-function@1.1.0:
1054
+
resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==}
1055
engines: {node: '>= 0.4'}
1056
1057
is-glob@4.0.3:
···
1062
resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
1063
engines: {node: '>= 0.4'}
1064
1065
+
is-number-object@1.1.1:
1066
+
resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==}
1067
engines: {node: '>= 0.4'}
1068
1069
is-number@7.0.0:
1070
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
1071
engines: {node: '>=0.12.0'}
1072
1073
+
is-regex@1.2.1:
1074
+
resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
1075
engines: {node: '>= 0.4'}
1076
1077
is-set@2.0.3:
1078
resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
1079
engines: {node: '>= 0.4'}
1080
1081
+
is-shared-array-buffer@1.0.4:
1082
+
resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
1083
engines: {node: '>= 0.4'}
1084
1085
+
is-string@1.1.1:
1086
+
resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
1087
engines: {node: '>= 0.4'}
1088
1089
+
is-symbol@1.1.1:
1090
+
resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==}
1091
engines: {node: '>= 0.4'}
1092
1093
+
is-typed-array@1.1.15:
1094
+
resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
1095
engines: {node: '>= 0.4'}
1096
1097
is-weakmap@2.0.2:
1098
resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
1099
engines: {node: '>= 0.4'}
1100
1101
+
is-weakref@1.1.1:
1102
+
resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==}
1103
+
engines: {node: '>= 0.4'}
1104
1105
+
is-weakset@2.0.4:
1106
+
resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
1107
engines: {node: '>= 0.4'}
1108
1109
isarray@2.0.5:
···
1112
isexe@2.0.0:
1113
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
1114
1115
+
iterator.prototype@1.1.5:
1116
+
resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
1117
engines: {node: '>= 0.4'}
1118
1119
+
jiti@2.4.2:
1120
+
resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
1121
+
hasBin: true
1122
+
1123
js-tokens@4.0.0:
1124
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
1125
···
1158
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
1159
hasBin: true
1160
1161
+
math-intrinsics@1.1.0:
1162
+
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
1163
+
engines: {node: '>= 0.4'}
1164
+
1165
merge2@1.4.1:
1166
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
1167
engines: {node: '>= 8'}
···
1177
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
1178
engines: {node: '>=8.6'}
1179
1180
+
mimic-function@5.0.1:
1181
+
resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
1182
+
engines: {node: '>=18'}
1183
+
1184
minimatch@3.1.2:
1185
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
1186
···
1188
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
1189
engines: {node: '>=16 || 14 >=14.17'}
1190
1191
+
ms@2.1.3:
1192
+
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
1193
1194
nanotar@0.1.1:
1195
resolution: {integrity: sha512-AiJsGsSF3O0havL1BydvI4+wR76sKT+okKRwWIaK96cZUnXqH0uNBOsHlbwZq3+m2BR1VKqHDVudl3gO4mYjpQ==}
···
1197
natural-compare@1.4.0:
1198
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
1199
1200
+
node-fetch-native@1.6.6:
1201
+
resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==}
1202
+
1203
object-assign@4.1.1:
1204
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
1205
engines: {node: '>=0.10.0'}
1206
1207
+
object-inspect@1.13.4:
1208
+
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
1209
engines: {node: '>= 0.4'}
1210
1211
object-keys@1.1.1:
1212
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
1213
engines: {node: '>= 0.4'}
1214
1215
+
object.assign@4.1.7:
1216
+
resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==}
1217
engines: {node: '>= 0.4'}
1218
1219
+
object.entries@1.1.9:
1220
+
resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==}
1221
engines: {node: '>= 0.4'}
1222
1223
object.fromentries@2.0.8:
1224
resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==}
1225
engines: {node: '>= 0.4'}
1226
1227
+
object.values@1.2.1:
1228
+
resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==}
1229
engines: {node: '>= 0.4'}
1230
+
1231
+
ofetch@1.4.1:
1232
+
resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==}
1233
+
1234
+
onetime@7.0.0:
1235
+
resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
1236
+
engines: {node: '>=18'}
1237
1238
optionator@0.9.3:
1239
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
1240
engines: {node: '>= 0.8.0'}
1241
1242
+
own-keys@1.0.1:
1243
+
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
1244
+
engines: {node: '>= 0.4'}
1245
+
1246
p-limit@3.1.0:
1247
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
1248
engines: {node: '>=10'}
···
1250
p-locate@5.0.0:
1251
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
1252
engines: {node: '>=10'}
1253
+
1254
+
package-manager-detector@1.1.0:
1255
+
resolution: {integrity: sha512-Y8f9qUlBzW8qauJjd/eu6jlpJZsuPJm2ZAV0cDVd420o4EdpH5RPdoCv+60/TdJflGatr4sDfpAL6ArWZbM5tA==}
1256
1257
parent-module@1.0.1:
1258
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
···
1269
path-parse@1.0.7:
1270
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
1271
1272
+
pathe@2.0.3:
1273
+
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
1274
+
1275
picomatch@2.3.1:
1276
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1277
engines: {node: '>=8.6'}
1278
1279
+
picomatch@4.0.2:
1280
+
resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
1281
+
engines: {node: '>=12'}
1282
+
1283
+
pnpm-workspace-yaml@0.3.1:
1284
+
resolution: {integrity: sha512-3nW5RLmREmZ8Pm8MbPsO2RM+99RRjYd25ynj3NV0cFsN7CcEl4sDFzgoFmSyduFwxFQ2Qbu3y2UdCh6HlyUOeA==}
1285
+
1286
+
possible-typed-array-names@1.1.0:
1287
+
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
1288
engines: {node: '>= 0.4'}
1289
1290
prelude-ls@1.2.1:
···
1311
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
1312
engines: {node: '>=6'}
1313
1314
+
quansync@0.2.10:
1315
+
resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==}
1316
+
1317
queue-microtask@1.2.3:
1318
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
1319
···
1324
resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==}
1325
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1326
1327
+
reflect.getprototypeof@1.0.10:
1328
+
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
1329
engines: {node: '>= 0.4'}
1330
1331
+
regexp.prototype.flags@1.5.4:
1332
+
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
1333
engines: {node: '>= 0.4'}
1334
1335
resolve-from@4.0.0:
···
1340
resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==}
1341
hasBin: true
1342
1343
+
restore-cursor@5.1.0:
1344
+
resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==}
1345
+
engines: {node: '>=18'}
1346
+
1347
reusify@1.0.4:
1348
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
1349
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
···
1351
run-parallel@1.2.0:
1352
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
1353
1354
+
safe-array-concat@1.1.3:
1355
+
resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
1356
engines: {node: '>=0.4'}
1357
1358
safe-buffer@5.2.1:
1359
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
1360
1361
+
safe-push-apply@1.0.0:
1362
+
resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==}
1363
+
engines: {node: '>= 0.4'}
1364
+
1365
+
safe-regex-test@1.1.0:
1366
+
resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
1367
engines: {node: '>= 0.4'}
1368
1369
semver@6.3.1:
1370
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
1371
hasBin: true
1372
1373
+
semver@7.7.1:
1374
+
resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==}
1375
engines: {node: '>=10'}
1376
hasBin: true
1377
···
1383
resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
1384
engines: {node: '>= 0.4'}
1385
1386
+
set-proto@1.0.0:
1387
+
resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==}
1388
+
engines: {node: '>= 0.4'}
1389
+
1390
shebang-command@2.0.0:
1391
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
1392
engines: {node: '>=8'}
···
1395
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
1396
engines: {node: '>=8'}
1397
1398
+
side-channel-list@1.0.0:
1399
+
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
1400
+
engines: {node: '>= 0.4'}
1401
+
1402
+
side-channel-map@1.0.1:
1403
+
resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
1404
+
engines: {node: '>= 0.4'}
1405
+
1406
+
side-channel-weakmap@1.0.2:
1407
+
resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
1408
engines: {node: '>= 0.4'}
1409
1410
+
side-channel@1.1.0:
1411
+
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
1412
+
engines: {node: '>= 0.4'}
1413
+
1414
+
signal-exit@4.1.0:
1415
+
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
1416
+
engines: {node: '>=14'}
1417
+
1418
standalone-electron-types@1.0.0:
1419
resolution: {integrity: sha512-0HOi/tlTz3mjWhsAz4uRbpQcHMZ+ifj1JzWW9nugykOHClBBG77ps8QinrzX1eow4Iw2pnC+RFaSYRgufF4BOg==}
1420
1421
+
string.prototype.matchall@4.0.12:
1422
+
resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==}
1423
engines: {node: '>= 0.4'}
1424
1425
string.prototype.repeat@1.0.0:
1426
resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==}
1427
1428
+
string.prototype.trim@1.2.10:
1429
+
resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==}
1430
engines: {node: '>= 0.4'}
1431
1432
+
string.prototype.trimend@1.0.9:
1433
+
resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==}
1434
+
engines: {node: '>= 0.4'}
1435
1436
string.prototype.trimstart@1.0.8:
1437
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
···
1452
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
1453
engines: {node: '>= 0.4'}
1454
1455
+
synckit@0.11.1:
1456
+
resolution: {integrity: sha512-fWZqNBZNNFp/7mTUy1fSsydhKsAKJ+u90Nk7kOK5Gcq9vObaqLBLjWFDBkyVU9Vvc6Y71VbOevMuGhqv02bT+Q==}
1457
engines: {node: ^14.18.0 || >=16.0.0}
1458
1459
+
taze@19.0.4:
1460
+
resolution: {integrity: sha512-bviyNotzqcIWpVBCC4QYVb2yupzKyUDGQi2m/8GERdiPaudVMtgAqaE98+x0cDDaByYRMJCyhQWM04ikUL6+kQ==}
1461
+
hasBin: true
1462
+
1463
+
tinyexec@1.0.1:
1464
+
resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==}
1465
+
1466
+
tinyglobby@0.2.12:
1467
+
resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==}
1468
+
engines: {node: '>=12.0.0'}
1469
1470
to-regex-range@5.0.1:
1471
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
1472
engines: {node: '>=8.0'}
1473
1474
+
ts-api-utils@2.1.0:
1475
+
resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==}
1476
+
engines: {node: '>=18.12'}
1477
peerDependencies:
1478
+
typescript: '>=4.8.4'
1479
1480
+
tslib@2.8.1:
1481
+
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
1482
1483
type-check@0.4.0:
1484
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
1485
engines: {node: '>= 0.8.0'}
1486
1487
+
typed-array-buffer@1.0.3:
1488
+
resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
1489
engines: {node: '>= 0.4'}
1490
1491
+
typed-array-byte-length@1.0.3:
1492
+
resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==}
1493
engines: {node: '>= 0.4'}
1494
1495
+
typed-array-byte-offset@1.0.4:
1496
+
resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==}
1497
engines: {node: '>= 0.4'}
1498
1499
+
typed-array-length@1.0.7:
1500
+
resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==}
1501
engines: {node: '>= 0.4'}
1502
1503
+
typescript-eslint@8.29.0:
1504
+
resolution: {integrity: sha512-ep9rVd9B4kQsZ7ZnWCVxUE/xDLUUUsRzE0poAeNu+4CkFErLfuvPt/qtm2EpnSyfvsR0S6QzDFSrPCFBwf64fg==}
1505
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1506
peerDependencies:
1507
+
eslint: ^8.57.0 || ^9.0.0
1508
+
typescript: '>=4.8.4 <5.9.0'
1509
1510
+
typescript@5.8.2:
1511
+
resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==}
1512
engines: {node: '>=14.17'}
1513
hasBin: true
1514
1515
+
ufo@1.5.4:
1516
+
resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==}
1517
+
1518
+
unbox-primitive@1.1.0:
1519
+
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
1520
+
engines: {node: '>= 0.4'}
1521
+
1522
+
unconfig@7.3.1:
1523
+
resolution: {integrity: sha512-LH5WL+un92tGAzWS87k7LkAfwpMdm7V0IXG2FxEjZz/QxiIW5J5LkcrKQThj0aRz6+h/lFmKI9EUXmK/T0bcrw==}
1524
+
1525
+
undici-types@6.20.0:
1526
+
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
1527
1528
+
undici-types@6.21.0:
1529
+
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
1530
1531
uri-js@4.4.1:
1532
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
1533
1534
+
utilium@1.10.1:
1535
+
resolution: {integrity: sha512-GQINDTb/ocyz4acQj3GXAe0wipYxws6L+9ouqaq10KlInTk9DGvW9TJd0pYa/Xu3cppNnZuB4T/sBuSXpcN2ng==}
1536
1537
+
which-boxed-primitive@1.1.1:
1538
+
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
1539
+
engines: {node: '>= 0.4'}
1540
1541
+
which-builtin-type@1.2.1:
1542
+
resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==}
1543
engines: {node: '>= 0.4'}
1544
1545
which-collection@1.0.2:
1546
resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
1547
engines: {node: '>= 0.4'}
1548
1549
+
which-typed-array@1.1.19:
1550
+
resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==}
1551
engines: {node: '>= 0.4'}
1552
1553
which@2.0.2:
···
1555
engines: {node: '>= 8'}
1556
hasBin: true
1557
1558
+
yaml@2.7.1:
1559
+
resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==}
1560
+
engines: {node: '>= 14'}
1561
+
hasBin: true
1562
+
1563
yocto-queue@0.1.0:
1564
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
1565
engines: {node: '>=10'}
1566
1567
+
zustand@5.0.3:
1568
+
resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==}
1569
+
engines: {node: '>=12.20.0'}
1570
+
peerDependencies:
1571
+
'@types/react': '>=18.0.0'
1572
+
immer: '>=9.0.6'
1573
+
react: '>=18.0.0'
1574
+
use-sync-external-store: '>=1.2.0'
1575
+
peerDependenciesMeta:
1576
+
'@types/react':
1577
+
optional: true
1578
+
immer:
1579
+
optional: true
1580
+
react:
1581
+
optional: true
1582
+
use-sync-external-store:
1583
+
optional: true
1584
+
1585
snapshots:
1586
1587
'@aashutoshrathi/word-wrap@1.2.6': {}
1588
+
1589
+
'@antfu/ni@24.3.0':
1590
+
dependencies:
1591
+
ansis: 3.17.0
1592
+
fzf: 0.5.2
1593
+
package-manager-detector: 1.1.0
1594
+
tinyexec: 1.0.1
1595
1596
'@esbuild/android-arm64@0.19.3':
1597
optional: true
···
1659
'@esbuild/win32-x64@0.19.3':
1660
optional: true
1661
1662
+
'@eslint-community/eslint-utils@4.5.1(eslint@9.23.0(jiti@2.4.2))':
1663
dependencies:
1664
+
eslint: 9.23.0(jiti@2.4.2)
1665
eslint-visitor-keys: 3.4.3
1666
1667
+
'@eslint-community/regexpp@4.12.1': {}
1668
1669
+
'@eslint/config-array@0.19.2':
1670
dependencies:
1671
+
'@eslint/object-schema': 2.1.6
1672
+
debug: 4.4.0
1673
minimatch: 3.1.2
1674
transitivePeerDependencies:
1675
- supports-color
1676
1677
+
'@eslint/config-helpers@0.2.1': {}
1678
1679
+
'@eslint/core@0.12.0':
1680
+
dependencies:
1681
+
'@types/json-schema': 7.0.15
1682
+
1683
+
'@eslint/core@0.13.0':
1684
+
dependencies:
1685
+
'@types/json-schema': 7.0.15
1686
+
1687
+
'@eslint/eslintrc@3.3.1':
1688
dependencies:
1689
ajv: 6.12.6
1690
+
debug: 4.4.0
1691
+
espree: 10.3.0
1692
globals: 14.0.0
1693
+
ignore: 5.3.2
1694
import-fresh: 3.3.0
1695
js-yaml: 4.1.0
1696
minimatch: 3.1.2
···
1698
transitivePeerDependencies:
1699
- supports-color
1700
1701
+
'@eslint/js@9.23.0': {}
1702
1703
+
'@eslint/object-schema@2.1.6': {}
1704
1705
+
'@eslint/plugin-kit@0.2.8':
1706
dependencies:
1707
+
'@eslint/core': 0.13.0
1708
levn: 0.4.1
1709
1710
+
'@humanfs/core@0.19.1': {}
1711
1712
+
'@humanfs/node@0.16.6':
1713
dependencies:
1714
+
'@humanfs/core': 0.19.1
1715
'@humanwhocodes/retry': 0.3.1
1716
1717
'@humanwhocodes/module-importer@1.0.1': {}
1718
1719
'@humanwhocodes/retry@0.3.1': {}
1720
1721
+
'@humanwhocodes/retry@0.4.2': {}
1722
+
1723
+
'@moonlight-mod/eslint-config@https://codeload.github.com/moonlight-mod/eslint-config/tar.gz/e262ac24e1a0955a9b3e0d66da247a0a8c0446c9(@types/eslint@9.6.1)(eslint@9.23.0(jiti@2.4.2))(prettier@3.1.0)(typescript@5.8.2)':
1724
dependencies:
1725
+
'@eslint/js': 9.23.0
1726
+
eslint: 9.23.0(jiti@2.4.2)
1727
+
eslint-config-prettier: 9.1.0(eslint@9.23.0(jiti@2.4.2))
1728
+
eslint-plugin-prettier: 5.2.6(@types/eslint@9.6.1)(eslint-config-prettier@9.1.0(eslint@9.23.0(jiti@2.4.2)))(eslint@9.23.0(jiti@2.4.2))(prettier@3.1.0)
1729
+
eslint-plugin-react: 7.37.5(eslint@9.23.0(jiti@2.4.2))
1730
+
typescript: 5.8.2
1731
+
typescript-eslint: 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
1732
transitivePeerDependencies:
1733
- '@types/eslint'
1734
- prettier
1735
- supports-color
1736
1737
+
'@moonlight-mod/lunast@1.0.1':
1738
dependencies:
1739
astring: 1.9.0
1740
estree-toolkit: 1.7.8
1741
meriyah: 6.0.1
1742
1743
+
'@moonlight-mod/mappings@1.1.25(@moonlight-mod/lunast@1.0.1)(@moonlight-mod/moonmap@1.0.5)':
1744
dependencies:
1745
+
'@moonlight-mod/lunast': 1.0.1
1746
+
'@moonlight-mod/moonmap': 1.0.5
1747
+
'@types/chroma-js': 3.1.0
1748
'@types/flux': 3.1.14
1749
+
'@types/highlightjs': 9.12.6
1750
+
'@types/lodash': 4.17.14
1751
+
'@types/platform': 1.3.6
1752
+
'@types/react': 18.3.20
1753
csstype: 3.1.3
1754
+
zustand: 5.0.3(@types/react@18.3.20)
1755
+
transitivePeerDependencies:
1756
+
- immer
1757
+
- react
1758
+
- use-sync-external-store
1759
1760
+
'@moonlight-mod/moonmap@1.0.5': {}
1761
1762
'@nodelib/fs.scandir@2.1.5':
1763
dependencies:
···
1771
'@nodelib/fs.scandir': 2.1.5
1772
fastq: 1.17.1
1773
1774
+
'@pkgr/core@0.2.0': {}
1775
+
1776
+
'@quansync/fs@0.1.2':
1777
+
dependencies:
1778
+
quansync: 0.2.10
1779
+
1780
+
'@types/chroma-js@3.1.0': {}
1781
+
1782
+
'@types/chrome@0.0.313':
1783
+
dependencies:
1784
+
'@types/filesystem': 0.0.36
1785
+
'@types/har-format': 1.2.16
1786
+
1787
+
'@types/eslint@9.6.1':
1788
+
dependencies:
1789
+
'@types/estree': 1.0.7
1790
+
'@types/json-schema': 7.0.15
1791
+
optional: true
1792
1793
'@types/estree-jsx@1.0.5':
1794
dependencies:
1795
'@types/estree': 1.0.6
1796
1797
'@types/estree@1.0.6': {}
1798
+
1799
+
'@types/estree@1.0.7':
1800
+
optional: true
1801
1802
'@types/fbemitter@2.0.35': {}
1803
1804
+
'@types/filesystem@0.0.36':
1805
+
dependencies:
1806
+
'@types/filewriter': 0.0.33
1807
+
1808
+
'@types/filewriter@0.0.33': {}
1809
+
1810
'@types/flux@3.1.14':
1811
dependencies:
1812
'@types/fbemitter': 2.0.35
1813
+
'@types/react': 18.3.20
1814
+
1815
+
'@types/har-format@1.2.16': {}
1816
+
1817
+
'@types/highlightjs@9.12.6': {}
1818
1819
'@types/json-schema@7.0.15': {}
1820
1821
+
'@types/lodash@4.17.14': {}
1822
+
1823
'@types/node@18.17.17': {}
1824
1825
+
'@types/node@22.13.6':
1826
+
dependencies:
1827
+
undici-types: 6.20.0
1828
+
1829
+
'@types/node@22.14.0':
1830
dependencies:
1831
+
undici-types: 6.21.0
1832
+
1833
+
'@types/platform@1.3.6': {}
1834
1835
'@types/prop-types@15.7.13': {}
1836
1837
+
'@types/react@18.3.20':
1838
dependencies:
1839
'@types/prop-types': 15.7.13
1840
csstype: 3.1.3
1841
1842
+
'@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)':
1843
dependencies:
1844
+
'@eslint-community/regexpp': 4.12.1
1845
+
'@typescript-eslint/parser': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
1846
+
'@typescript-eslint/scope-manager': 8.29.0
1847
+
'@typescript-eslint/type-utils': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
1848
+
'@typescript-eslint/utils': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
1849
+
'@typescript-eslint/visitor-keys': 8.29.0
1850
+
eslint: 9.23.0(jiti@2.4.2)
1851
graphemer: 1.4.0
1852
ignore: 5.3.2
1853
natural-compare: 1.4.0
1854
+
ts-api-utils: 2.1.0(typescript@5.8.2)
1855
+
typescript: 5.8.2
1856
transitivePeerDependencies:
1857
- supports-color
1858
1859
+
'@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)':
1860
dependencies:
1861
+
'@typescript-eslint/scope-manager': 8.29.0
1862
+
'@typescript-eslint/types': 8.29.0
1863
+
'@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2)
1864
+
'@typescript-eslint/visitor-keys': 8.29.0
1865
+
debug: 4.4.0
1866
+
eslint: 9.23.0(jiti@2.4.2)
1867
+
typescript: 5.8.2
1868
transitivePeerDependencies:
1869
- supports-color
1870
1871
+
'@typescript-eslint/scope-manager@8.29.0':
1872
dependencies:
1873
+
'@typescript-eslint/types': 8.29.0
1874
+
'@typescript-eslint/visitor-keys': 8.29.0
1875
1876
+
'@typescript-eslint/type-utils@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)':
1877
dependencies:
1878
+
'@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2)
1879
+
'@typescript-eslint/utils': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
1880
+
debug: 4.4.0
1881
+
eslint: 9.23.0(jiti@2.4.2)
1882
+
ts-api-utils: 2.1.0(typescript@5.8.2)
1883
+
typescript: 5.8.2
1884
transitivePeerDependencies:
1885
- supports-color
1886
1887
+
'@typescript-eslint/types@8.29.0': {}
1888
1889
+
'@typescript-eslint/typescript-estree@8.29.0(typescript@5.8.2)':
1890
dependencies:
1891
+
'@typescript-eslint/types': 8.29.0
1892
+
'@typescript-eslint/visitor-keys': 8.29.0
1893
+
debug: 4.4.0
1894
fast-glob: 3.3.2
1895
is-glob: 4.0.3
1896
minimatch: 9.0.5
1897
+
semver: 7.7.1
1898
+
ts-api-utils: 2.1.0(typescript@5.8.2)
1899
+
typescript: 5.8.2
1900
transitivePeerDependencies:
1901
- supports-color
1902
1903
+
'@typescript-eslint/utils@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)':
1904
dependencies:
1905
+
'@eslint-community/eslint-utils': 4.5.1(eslint@9.23.0(jiti@2.4.2))
1906
+
'@typescript-eslint/scope-manager': 8.29.0
1907
+
'@typescript-eslint/types': 8.29.0
1908
+
'@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2)
1909
+
eslint: 9.23.0(jiti@2.4.2)
1910
+
typescript: 5.8.2
1911
transitivePeerDependencies:
1912
- supports-color
1913
1914
+
'@typescript-eslint/visitor-keys@8.29.0':
1915
dependencies:
1916
+
'@typescript-eslint/types': 8.29.0
1917
+
eslint-visitor-keys: 4.2.0
1918
1919
+
'@xterm/xterm@5.5.0':
1920
+
optional: true
1921
+
1922
+
'@zenfs/core@2.0.0':
1923
dependencies:
1924
+
'@types/node': 22.13.6
1925
buffer: 6.0.3
1926
eventemitter3: 5.0.1
1927
readable-stream: 4.5.2
1928
+
utilium: 1.10.1
1929
1930
+
'@zenfs/dom@1.1.6(@zenfs/core@2.0.0)(utilium@1.10.1)':
1931
dependencies:
1932
+
'@zenfs/core': 2.0.0
1933
+
utilium: 1.10.1
1934
1935
abort-controller@3.0.0:
1936
dependencies:
1937
event-target-shim: 5.0.1
1938
1939
+
acorn-jsx@5.3.2(acorn@8.14.1):
1940
dependencies:
1941
+
acorn: 8.14.1
1942
1943
+
acorn@8.14.1: {}
1944
1945
ajv@6.12.6:
1946
dependencies:
···
1953
dependencies:
1954
color-convert: 2.0.1
1955
1956
+
ansis@3.17.0: {}
1957
+
1958
argparse@2.0.1: {}
1959
1960
+
array-buffer-byte-length@1.0.2:
1961
dependencies:
1962
+
call-bound: 1.0.4
1963
+
is-array-buffer: 3.0.5
1964
1965
array-includes@3.1.8:
1966
dependencies:
1967
+
call-bind: 1.0.8
1968
define-properties: 1.2.1
1969
+
es-abstract: 1.23.9
1970
+
es-object-atoms: 1.1.1
1971
+
get-intrinsic: 1.3.0
1972
+
is-string: 1.1.1
1973
1974
array.prototype.findlast@1.2.5:
1975
dependencies:
1976
+
call-bind: 1.0.8
1977
define-properties: 1.2.1
1978
+
es-abstract: 1.23.9
1979
es-errors: 1.3.0
1980
+
es-object-atoms: 1.1.1
1981
+
es-shim-unscopables: 1.1.0
1982
1983
+
array.prototype.flat@1.3.3:
1984
dependencies:
1985
+
call-bind: 1.0.8
1986
define-properties: 1.2.1
1987
+
es-abstract: 1.23.9
1988
+
es-shim-unscopables: 1.1.0
1989
1990
+
array.prototype.flatmap@1.3.3:
1991
dependencies:
1992
+
call-bind: 1.0.8
1993
define-properties: 1.2.1
1994
+
es-abstract: 1.23.9
1995
+
es-shim-unscopables: 1.1.0
1996
1997
array.prototype.tosorted@1.1.4:
1998
dependencies:
1999
+
call-bind: 1.0.8
2000
define-properties: 1.2.1
2001
+
es-abstract: 1.23.9
2002
es-errors: 1.3.0
2003
+
es-shim-unscopables: 1.1.0
2004
2005
+
arraybuffer.prototype.slice@1.0.4:
2006
dependencies:
2007
+
array-buffer-byte-length: 1.0.2
2008
+
call-bind: 1.0.8
2009
define-properties: 1.2.1
2010
+
es-abstract: 1.23.9
2011
es-errors: 1.3.0
2012
+
get-intrinsic: 1.3.0
2013
+
is-array-buffer: 3.0.5
2014
2015
astring@1.9.0: {}
2016
+
2017
+
async-function@1.0.0: {}
2018
2019
available-typed-arrays@1.0.7:
2020
dependencies:
2021
+
possible-typed-array-names: 1.1.0
2022
2023
balanced-match@1.0.2: {}
2024
···
2042
base64-js: 1.5.1
2043
ieee754: 1.2.1
2044
2045
+
cac@6.7.14: {}
2046
+
2047
+
call-bind-apply-helpers@1.0.2:
2048
dependencies:
2049
es-errors: 1.3.0
2050
function-bind: 1.1.2
2051
+
2052
+
call-bind@1.0.8:
2053
+
dependencies:
2054
+
call-bind-apply-helpers: 1.0.2
2055
+
es-define-property: 1.0.1
2056
+
get-intrinsic: 1.3.0
2057
set-function-length: 1.2.2
2058
2059
+
call-bound@1.0.4:
2060
+
dependencies:
2061
+
call-bind-apply-helpers: 1.0.2
2062
+
get-intrinsic: 1.3.0
2063
+
2064
callsites@3.1.0: {}
2065
2066
chalk@4.1.2:
···
2076
2077
concat-map@0.0.1: {}
2078
2079
+
cross-spawn@7.0.6:
2080
dependencies:
2081
path-key: 3.1.1
2082
shebang-command: 2.0.0
2083
which: 2.0.2
2084
2085
csstype@3.1.3: {}
2086
2087
+
data-view-buffer@1.0.2:
2088
dependencies:
2089
+
call-bound: 1.0.4
2090
es-errors: 1.3.0
2091
+
is-data-view: 1.0.2
2092
2093
+
data-view-byte-length@1.0.2:
2094
dependencies:
2095
+
call-bound: 1.0.4
2096
es-errors: 1.3.0
2097
+
is-data-view: 1.0.2
2098
2099
+
data-view-byte-offset@1.0.1:
2100
dependencies:
2101
+
call-bound: 1.0.4
2102
es-errors: 1.3.0
2103
+
is-data-view: 1.0.2
2104
2105
+
debug@4.4.0:
2106
dependencies:
2107
+
ms: 2.1.3
2108
2109
deep-is@0.1.4: {}
2110
2111
define-data-property@1.1.4:
2112
dependencies:
2113
+
es-define-property: 1.0.1
2114
es-errors: 1.3.0
2115
+
gopd: 1.2.0
2116
2117
define-properties@1.2.1:
2118
dependencies:
···
2120
has-property-descriptors: 1.0.2
2121
object-keys: 1.1.1
2122
2123
+
defu@6.1.4: {}
2124
+
2125
+
destr@2.0.4: {}
2126
+
2127
doctrine@2.1.0:
2128
dependencies:
2129
esutils: 2.0.3
2130
2131
+
dunder-proto@1.0.1:
2132
+
dependencies:
2133
+
call-bind-apply-helpers: 1.0.2
2134
+
es-errors: 1.3.0
2135
+
gopd: 1.2.0
2136
+
2137
+
es-abstract@1.23.9:
2138
dependencies:
2139
+
array-buffer-byte-length: 1.0.2
2140
+
arraybuffer.prototype.slice: 1.0.4
2141
available-typed-arrays: 1.0.7
2142
+
call-bind: 1.0.8
2143
+
call-bound: 1.0.4
2144
+
data-view-buffer: 1.0.2
2145
+
data-view-byte-length: 1.0.2
2146
+
data-view-byte-offset: 1.0.1
2147
+
es-define-property: 1.0.1
2148
es-errors: 1.3.0
2149
+
es-object-atoms: 1.1.1
2150
+
es-set-tostringtag: 2.1.0
2151
+
es-to-primitive: 1.3.0
2152
+
function.prototype.name: 1.1.8
2153
+
get-intrinsic: 1.3.0
2154
+
get-proto: 1.0.1
2155
+
get-symbol-description: 1.1.0
2156
globalthis: 1.0.4
2157
+
gopd: 1.2.0
2158
has-property-descriptors: 1.0.2
2159
+
has-proto: 1.2.0
2160
+
has-symbols: 1.1.0
2161
hasown: 2.0.2
2162
+
internal-slot: 1.1.0
2163
+
is-array-buffer: 3.0.5
2164
is-callable: 1.2.7
2165
+
is-data-view: 1.0.2
2166
+
is-regex: 1.2.1
2167
+
is-shared-array-buffer: 1.0.4
2168
+
is-string: 1.1.1
2169
+
is-typed-array: 1.1.15
2170
+
is-weakref: 1.1.1
2171
+
math-intrinsics: 1.1.0
2172
+
object-inspect: 1.13.4
2173
object-keys: 1.1.1
2174
+
object.assign: 4.1.7
2175
+
own-keys: 1.0.1
2176
+
regexp.prototype.flags: 1.5.4
2177
+
safe-array-concat: 1.1.3
2178
+
safe-push-apply: 1.0.0
2179
+
safe-regex-test: 1.1.0
2180
+
set-proto: 1.0.0
2181
+
string.prototype.trim: 1.2.10
2182
+
string.prototype.trimend: 1.0.9
2183
string.prototype.trimstart: 1.0.8
2184
+
typed-array-buffer: 1.0.3
2185
+
typed-array-byte-length: 1.0.3
2186
+
typed-array-byte-offset: 1.0.4
2187
+
typed-array-length: 1.0.7
2188
+
unbox-primitive: 1.1.0
2189
+
which-typed-array: 1.1.19
2190
2191
+
es-define-property@1.0.1: {}
2192
2193
es-errors@1.3.0: {}
2194
2195
+
es-iterator-helpers@1.2.1:
2196
dependencies:
2197
+
call-bind: 1.0.8
2198
+
call-bound: 1.0.4
2199
define-properties: 1.2.1
2200
+
es-abstract: 1.23.9
2201
es-errors: 1.3.0
2202
+
es-set-tostringtag: 2.1.0
2203
function-bind: 1.1.2
2204
+
get-intrinsic: 1.3.0
2205
globalthis: 1.0.4
2206
+
gopd: 1.2.0
2207
has-property-descriptors: 1.0.2
2208
+
has-proto: 1.2.0
2209
+
has-symbols: 1.1.0
2210
+
internal-slot: 1.1.0
2211
+
iterator.prototype: 1.1.5
2212
+
safe-array-concat: 1.1.3
2213
2214
+
es-object-atoms@1.1.1:
2215
dependencies:
2216
es-errors: 1.3.0
2217
2218
+
es-set-tostringtag@2.1.0:
2219
dependencies:
2220
+
es-errors: 1.3.0
2221
+
get-intrinsic: 1.3.0
2222
has-tostringtag: 1.0.2
2223
hasown: 2.0.2
2224
2225
+
es-shim-unscopables@1.1.0:
2226
dependencies:
2227
hasown: 2.0.2
2228
2229
+
es-to-primitive@1.3.0:
2230
dependencies:
2231
is-callable: 1.2.7
2232
+
is-date-object: 1.1.0
2233
+
is-symbol: 1.1.1
2234
2235
esbuild-copy-static-files@0.1.0: {}
2236
···
2261
2262
escape-string-regexp@4.0.0: {}
2263
2264
+
eslint-config-prettier@9.1.0(eslint@9.23.0(jiti@2.4.2)):
2265
dependencies:
2266
+
eslint: 9.23.0(jiti@2.4.2)
2267
2268
+
eslint-plugin-prettier@5.2.6(@types/eslint@9.6.1)(eslint-config-prettier@9.1.0(eslint@9.23.0(jiti@2.4.2)))(eslint@9.23.0(jiti@2.4.2))(prettier@3.1.0):
2269
dependencies:
2270
+
eslint: 9.23.0(jiti@2.4.2)
2271
prettier: 3.1.0
2272
prettier-linter-helpers: 1.0.0
2273
+
synckit: 0.11.1
2274
optionalDependencies:
2275
+
'@types/eslint': 9.6.1
2276
+
eslint-config-prettier: 9.1.0(eslint@9.23.0(jiti@2.4.2))
2277
2278
+
eslint-plugin-react@7.37.5(eslint@9.23.0(jiti@2.4.2)):
2279
dependencies:
2280
array-includes: 3.1.8
2281
array.prototype.findlast: 1.2.5
2282
+
array.prototype.flatmap: 1.3.3
2283
array.prototype.tosorted: 1.1.4
2284
doctrine: 2.1.0
2285
+
es-iterator-helpers: 1.2.1
2286
+
eslint: 9.23.0(jiti@2.4.2)
2287
estraverse: 5.3.0
2288
hasown: 2.0.2
2289
jsx-ast-utils: 3.3.5
2290
minimatch: 3.1.2
2291
+
object.entries: 1.1.9
2292
object.fromentries: 2.0.8
2293
+
object.values: 1.2.1
2294
prop-types: 15.8.1
2295
resolve: 2.0.0-next.5
2296
semver: 6.3.1
2297
+
string.prototype.matchall: 4.0.12
2298
string.prototype.repeat: 1.0.0
2299
2300
+
eslint-scope@8.3.0:
2301
dependencies:
2302
esrecurse: 4.3.0
2303
estraverse: 5.3.0
2304
2305
eslint-visitor-keys@3.4.3: {}
2306
2307
+
eslint-visitor-keys@4.2.0: {}
2308
2309
+
eslint@9.23.0(jiti@2.4.2):
2310
dependencies:
2311
+
'@eslint-community/eslint-utils': 4.5.1(eslint@9.23.0(jiti@2.4.2))
2312
+
'@eslint-community/regexpp': 4.12.1
2313
+
'@eslint/config-array': 0.19.2
2314
+
'@eslint/config-helpers': 0.2.1
2315
+
'@eslint/core': 0.12.0
2316
+
'@eslint/eslintrc': 3.3.1
2317
+
'@eslint/js': 9.23.0
2318
+
'@eslint/plugin-kit': 0.2.8
2319
+
'@humanfs/node': 0.16.6
2320
'@humanwhocodes/module-importer': 1.0.1
2321
+
'@humanwhocodes/retry': 0.4.2
2322
'@types/estree': 1.0.6
2323
'@types/json-schema': 7.0.15
2324
ajv: 6.12.6
2325
chalk: 4.1.2
2326
+
cross-spawn: 7.0.6
2327
+
debug: 4.4.0
2328
escape-string-regexp: 4.0.0
2329
+
eslint-scope: 8.3.0
2330
+
eslint-visitor-keys: 4.2.0
2331
+
espree: 10.3.0
2332
+
esquery: 1.6.0
2333
esutils: 2.0.3
2334
fast-deep-equal: 3.1.3
2335
file-entry-cache: 8.0.0
2336
find-up: 5.0.0
2337
glob-parent: 6.0.2
2338
+
ignore: 5.3.2
2339
imurmurhash: 0.1.4
2340
is-glob: 4.0.3
2341
json-stable-stringify-without-jsonify: 1.0.1
···
2343
minimatch: 3.1.2
2344
natural-compare: 1.4.0
2345
optionator: 0.9.3
2346
+
optionalDependencies:
2347
+
jiti: 2.4.2
2348
transitivePeerDependencies:
2349
- supports-color
2350
2351
+
espree@10.3.0:
2352
dependencies:
2353
+
acorn: 8.14.1
2354
+
acorn-jsx: 5.3.2(acorn@8.14.1)
2355
+
eslint-visitor-keys: 4.2.0
2356
2357
+
esquery@1.6.0:
2358
dependencies:
2359
estraverse: 5.3.0
2360
···
2397
dependencies:
2398
reusify: 1.0.4
2399
2400
+
fdir@6.4.3(picomatch@4.0.2):
2401
+
optionalDependencies:
2402
+
picomatch: 4.0.2
2403
+
2404
file-entry-cache@8.0.0:
2405
dependencies:
2406
flat-cache: 4.0.1
···
2409
dependencies:
2410
to-regex-range: 5.0.1
2411
2412
+
find-up-simple@1.0.1: {}
2413
+
2414
find-up@5.0.0:
2415
dependencies:
2416
locate-path: 6.0.0
···
2423
2424
flatted@3.2.9: {}
2425
2426
+
for-each@0.3.5:
2427
dependencies:
2428
is-callable: 1.2.7
2429
2430
function-bind@1.1.2: {}
2431
2432
+
function.prototype.name@1.1.8:
2433
dependencies:
2434
+
call-bind: 1.0.8
2435
+
call-bound: 1.0.4
2436
define-properties: 1.2.1
2437
functions-have-names: 1.2.3
2438
+
hasown: 2.0.2
2439
+
is-callable: 1.2.7
2440
2441
functions-have-names@1.2.3: {}
2442
2443
+
fzf@0.5.2: {}
2444
+
2445
+
get-intrinsic@1.3.0:
2446
dependencies:
2447
+
call-bind-apply-helpers: 1.0.2
2448
+
es-define-property: 1.0.1
2449
es-errors: 1.3.0
2450
+
es-object-atoms: 1.1.1
2451
function-bind: 1.1.2
2452
+
get-proto: 1.0.1
2453
+
gopd: 1.2.0
2454
+
has-symbols: 1.1.0
2455
hasown: 2.0.2
2456
+
math-intrinsics: 1.1.0
2457
2458
+
get-proto@1.0.1:
2459
dependencies:
2460
+
dunder-proto: 1.0.1
2461
+
es-object-atoms: 1.1.1
2462
+
2463
+
get-symbol-description@1.1.0:
2464
+
dependencies:
2465
+
call-bound: 1.0.4
2466
es-errors: 1.3.0
2467
+
get-intrinsic: 1.3.0
2468
2469
glob-parent@5.1.2:
2470
dependencies:
···
2479
globalthis@1.0.4:
2480
dependencies:
2481
define-properties: 1.2.1
2482
+
gopd: 1.2.0
2483
2484
+
gopd@1.2.0: {}
2485
2486
graphemer@1.4.0: {}
2487
2488
+
has-bigints@1.1.0: {}
2489
2490
has-flag@4.0.0: {}
2491
2492
has-property-descriptors@1.0.2:
2493
dependencies:
2494
+
es-define-property: 1.0.1
2495
2496
+
has-proto@1.2.0:
2497
+
dependencies:
2498
+
dunder-proto: 1.0.1
2499
2500
+
has-symbols@1.1.0: {}
2501
2502
has-tostringtag@1.0.2:
2503
dependencies:
2504
+
has-symbols: 1.1.0
2505
2506
hasown@2.0.2:
2507
dependencies:
···
2510
husky@8.0.3: {}
2511
2512
ieee754@1.2.1: {}
2513
2514
ignore@5.3.2: {}
2515
···
2520
2521
imurmurhash@0.1.4: {}
2522
2523
+
internal-slot@1.1.0:
2524
dependencies:
2525
es-errors: 1.3.0
2526
hasown: 2.0.2
2527
+
side-channel: 1.1.0
2528
2529
+
is-array-buffer@3.0.5:
2530
dependencies:
2531
+
call-bind: 1.0.8
2532
+
call-bound: 1.0.4
2533
+
get-intrinsic: 1.3.0
2534
2535
+
is-async-function@2.1.1:
2536
dependencies:
2537
+
async-function: 1.0.0
2538
+
call-bound: 1.0.4
2539
+
get-proto: 1.0.1
2540
has-tostringtag: 1.0.2
2541
+
safe-regex-test: 1.1.0
2542
2543
+
is-bigint@1.1.0:
2544
dependencies:
2545
+
has-bigints: 1.1.0
2546
2547
+
is-boolean-object@1.2.2:
2548
dependencies:
2549
+
call-bound: 1.0.4
2550
has-tostringtag: 1.0.2
2551
2552
is-callable@1.2.7: {}
2553
2554
+
is-core-module@2.16.1:
2555
dependencies:
2556
hasown: 2.0.2
2557
2558
+
is-data-view@1.0.2:
2559
dependencies:
2560
+
call-bound: 1.0.4
2561
+
get-intrinsic: 1.3.0
2562
+
is-typed-array: 1.1.15
2563
2564
+
is-date-object@1.1.0:
2565
dependencies:
2566
+
call-bound: 1.0.4
2567
has-tostringtag: 1.0.2
2568
2569
is-extglob@2.1.1: {}
2570
2571
+
is-finalizationregistry@1.1.1:
2572
dependencies:
2573
+
call-bound: 1.0.4
2574
2575
+
is-generator-function@1.1.0:
2576
dependencies:
2577
+
call-bound: 1.0.4
2578
+
get-proto: 1.0.1
2579
has-tostringtag: 1.0.2
2580
+
safe-regex-test: 1.1.0
2581
2582
is-glob@4.0.3:
2583
dependencies:
···
2585
2586
is-map@2.0.3: {}
2587
2588
+
is-number-object@1.1.1:
2589
dependencies:
2590
+
call-bound: 1.0.4
2591
has-tostringtag: 1.0.2
2592
2593
is-number@7.0.0: {}
2594
2595
+
is-regex@1.2.1:
2596
dependencies:
2597
+
call-bound: 1.0.4
2598
+
gopd: 1.2.0
2599
has-tostringtag: 1.0.2
2600
+
hasown: 2.0.2
2601
2602
is-set@2.0.3: {}
2603
2604
+
is-shared-array-buffer@1.0.4:
2605
dependencies:
2606
+
call-bound: 1.0.4
2607
2608
+
is-string@1.1.1:
2609
dependencies:
2610
+
call-bound: 1.0.4
2611
has-tostringtag: 1.0.2
2612
2613
+
is-symbol@1.1.1:
2614
dependencies:
2615
+
call-bound: 1.0.4
2616
+
has-symbols: 1.1.0
2617
+
safe-regex-test: 1.1.0
2618
2619
+
is-typed-array@1.1.15:
2620
dependencies:
2621
+
which-typed-array: 1.1.19
2622
2623
is-weakmap@2.0.2: {}
2624
2625
+
is-weakref@1.1.1:
2626
dependencies:
2627
+
call-bound: 1.0.4
2628
2629
+
is-weakset@2.0.4:
2630
dependencies:
2631
+
call-bound: 1.0.4
2632
+
get-intrinsic: 1.3.0
2633
2634
isarray@2.0.5: {}
2635
2636
isexe@2.0.0: {}
2637
2638
+
iterator.prototype@1.1.5:
2639
dependencies:
2640
+
define-data-property: 1.1.4
2641
+
es-object-atoms: 1.1.1
2642
+
get-intrinsic: 1.3.0
2643
+
get-proto: 1.0.1
2644
+
has-symbols: 1.1.0
2645
set-function-name: 2.0.2
2646
2647
+
jiti@2.4.2: {}
2648
+
2649
js-tokens@4.0.0: {}
2650
2651
js-yaml@4.1.0:
···
2661
jsx-ast-utils@3.3.5:
2662
dependencies:
2663
array-includes: 3.1.8
2664
+
array.prototype.flat: 1.3.3
2665
+
object.assign: 4.1.7
2666
+
object.values: 1.2.1
2667
2668
keyv@4.5.4:
2669
dependencies:
···
2684
dependencies:
2685
js-tokens: 4.0.0
2686
2687
+
math-intrinsics@1.1.0: {}
2688
+
2689
merge2@1.4.1: {}
2690
2691
meriyah@6.0.1: {}
···
2696
dependencies:
2697
braces: 3.0.3
2698
picomatch: 2.3.1
2699
+
2700
+
mimic-function@5.0.1: {}
2701
2702
minimatch@3.1.2:
2703
dependencies:
···
2707
dependencies:
2708
brace-expansion: 2.0.1
2709
2710
+
ms@2.1.3: {}
2711
2712
nanotar@0.1.1: {}
2713
2714
natural-compare@1.4.0: {}
2715
2716
+
node-fetch-native@1.6.6: {}
2717
+
2718
object-assign@4.1.1: {}
2719
2720
+
object-inspect@1.13.4: {}
2721
2722
object-keys@1.1.1: {}
2723
2724
+
object.assign@4.1.7:
2725
dependencies:
2726
+
call-bind: 1.0.8
2727
+
call-bound: 1.0.4
2728
define-properties: 1.2.1
2729
+
es-object-atoms: 1.1.1
2730
+
has-symbols: 1.1.0
2731
object-keys: 1.1.1
2732
2733
+
object.entries@1.1.9:
2734
dependencies:
2735
+
call-bind: 1.0.8
2736
+
call-bound: 1.0.4
2737
define-properties: 1.2.1
2738
+
es-object-atoms: 1.1.1
2739
2740
object.fromentries@2.0.8:
2741
dependencies:
2742
+
call-bind: 1.0.8
2743
define-properties: 1.2.1
2744
+
es-abstract: 1.23.9
2745
+
es-object-atoms: 1.1.1
2746
2747
+
object.values@1.2.1:
2748
dependencies:
2749
+
call-bind: 1.0.8
2750
+
call-bound: 1.0.4
2751
define-properties: 1.2.1
2752
+
es-object-atoms: 1.1.1
2753
+
2754
+
ofetch@1.4.1:
2755
+
dependencies:
2756
+
destr: 2.0.4
2757
+
node-fetch-native: 1.6.6
2758
+
ufo: 1.5.4
2759
+
2760
+
onetime@7.0.0:
2761
+
dependencies:
2762
+
mimic-function: 5.0.1
2763
2764
optionator@0.9.3:
2765
dependencies:
···
2769
levn: 0.4.1
2770
prelude-ls: 1.2.1
2771
type-check: 0.4.0
2772
+
2773
+
own-keys@1.0.1:
2774
+
dependencies:
2775
+
get-intrinsic: 1.3.0
2776
+
object-keys: 1.1.1
2777
+
safe-push-apply: 1.0.0
2778
2779
p-limit@3.1.0:
2780
dependencies:
···
2784
dependencies:
2785
p-limit: 3.1.0
2786
2787
+
package-manager-detector@1.1.0: {}
2788
+
2789
parent-module@1.0.1:
2790
dependencies:
2791
callsites: 3.1.0
···
2796
2797
path-parse@1.0.7: {}
2798
2799
+
pathe@2.0.3: {}
2800
+
2801
picomatch@2.3.1: {}
2802
2803
+
picomatch@4.0.2: {}
2804
+
2805
+
pnpm-workspace-yaml@0.3.1:
2806
+
dependencies:
2807
+
yaml: 2.7.1
2808
+
2809
+
possible-typed-array-names@1.1.0: {}
2810
2811
prelude-ls@1.2.1: {}
2812
···
2826
2827
punycode@2.3.1: {}
2828
2829
+
quansync@0.2.10: {}
2830
+
2831
queue-microtask@1.2.3: {}
2832
2833
react-is@16.13.1: {}
···
2840
process: 0.11.10
2841
string_decoder: 1.3.0
2842
2843
+
reflect.getprototypeof@1.0.10:
2844
dependencies:
2845
+
call-bind: 1.0.8
2846
define-properties: 1.2.1
2847
+
es-abstract: 1.23.9
2848
es-errors: 1.3.0
2849
+
es-object-atoms: 1.1.1
2850
+
get-intrinsic: 1.3.0
2851
+
get-proto: 1.0.1
2852
+
which-builtin-type: 1.2.1
2853
2854
+
regexp.prototype.flags@1.5.4:
2855
dependencies:
2856
+
call-bind: 1.0.8
2857
define-properties: 1.2.1
2858
es-errors: 1.3.0
2859
+
get-proto: 1.0.1
2860
+
gopd: 1.2.0
2861
set-function-name: 2.0.2
2862
2863
resolve-from@4.0.0: {}
2864
2865
resolve@2.0.0-next.5:
2866
dependencies:
2867
+
is-core-module: 2.16.1
2868
path-parse: 1.0.7
2869
supports-preserve-symlinks-flag: 1.0.0
2870
2871
+
restore-cursor@5.1.0:
2872
+
dependencies:
2873
+
onetime: 7.0.0
2874
+
signal-exit: 4.1.0
2875
+
2876
reusify@1.0.4: {}
2877
2878
run-parallel@1.2.0:
2879
dependencies:
2880
queue-microtask: 1.2.3
2881
2882
+
safe-array-concat@1.1.3:
2883
dependencies:
2884
+
call-bind: 1.0.8
2885
+
call-bound: 1.0.4
2886
+
get-intrinsic: 1.3.0
2887
+
has-symbols: 1.1.0
2888
isarray: 2.0.5
2889
2890
safe-buffer@5.2.1: {}
2891
2892
+
safe-push-apply@1.0.0:
2893
dependencies:
2894
es-errors: 1.3.0
2895
+
isarray: 2.0.5
2896
+
2897
+
safe-regex-test@1.1.0:
2898
+
dependencies:
2899
+
call-bound: 1.0.4
2900
+
es-errors: 1.3.0
2901
+
is-regex: 1.2.1
2902
2903
semver@6.3.1: {}
2904
2905
+
semver@7.7.1: {}
2906
2907
set-function-length@1.2.2:
2908
dependencies:
2909
define-data-property: 1.1.4
2910
es-errors: 1.3.0
2911
function-bind: 1.1.2
2912
+
get-intrinsic: 1.3.0
2913
+
gopd: 1.2.0
2914
has-property-descriptors: 1.0.2
2915
2916
set-function-name@2.0.2:
···
2920
functions-have-names: 1.2.3
2921
has-property-descriptors: 1.0.2
2922
2923
+
set-proto@1.0.0:
2924
+
dependencies:
2925
+
dunder-proto: 1.0.1
2926
+
es-errors: 1.3.0
2927
+
es-object-atoms: 1.1.1
2928
+
2929
shebang-command@2.0.0:
2930
dependencies:
2931
shebang-regex: 3.0.0
2932
2933
shebang-regex@3.0.0: {}
2934
2935
+
side-channel-list@1.0.0:
2936
+
dependencies:
2937
+
es-errors: 1.3.0
2938
+
object-inspect: 1.13.4
2939
+
2940
+
side-channel-map@1.0.1:
2941
+
dependencies:
2942
+
call-bound: 1.0.4
2943
+
es-errors: 1.3.0
2944
+
get-intrinsic: 1.3.0
2945
+
object-inspect: 1.13.4
2946
+
2947
+
side-channel-weakmap@1.0.2:
2948
+
dependencies:
2949
+
call-bound: 1.0.4
2950
+
es-errors: 1.3.0
2951
+
get-intrinsic: 1.3.0
2952
+
object-inspect: 1.13.4
2953
+
side-channel-map: 1.0.1
2954
+
2955
+
side-channel@1.1.0:
2956
dependencies:
2957
es-errors: 1.3.0
2958
+
object-inspect: 1.13.4
2959
+
side-channel-list: 1.0.0
2960
+
side-channel-map: 1.0.1
2961
+
side-channel-weakmap: 1.0.2
2962
+
2963
+
signal-exit@4.1.0: {}
2964
2965
standalone-electron-types@1.0.0:
2966
dependencies:
2967
'@types/node': 18.17.17
2968
2969
+
string.prototype.matchall@4.0.12:
2970
dependencies:
2971
+
call-bind: 1.0.8
2972
+
call-bound: 1.0.4
2973
define-properties: 1.2.1
2974
+
es-abstract: 1.23.9
2975
es-errors: 1.3.0
2976
+
es-object-atoms: 1.1.1
2977
+
get-intrinsic: 1.3.0
2978
+
gopd: 1.2.0
2979
+
has-symbols: 1.1.0
2980
+
internal-slot: 1.1.0
2981
+
regexp.prototype.flags: 1.5.4
2982
set-function-name: 2.0.2
2983
+
side-channel: 1.1.0
2984
2985
string.prototype.repeat@1.0.0:
2986
dependencies:
2987
define-properties: 1.2.1
2988
+
es-abstract: 1.23.9
2989
2990
+
string.prototype.trim@1.2.10:
2991
dependencies:
2992
+
call-bind: 1.0.8
2993
+
call-bound: 1.0.4
2994
+
define-data-property: 1.1.4
2995
define-properties: 1.2.1
2996
+
es-abstract: 1.23.9
2997
+
es-object-atoms: 1.1.1
2998
+
has-property-descriptors: 1.0.2
2999
3000
+
string.prototype.trimend@1.0.9:
3001
dependencies:
3002
+
call-bind: 1.0.8
3003
+
call-bound: 1.0.4
3004
define-properties: 1.2.1
3005
+
es-object-atoms: 1.1.1
3006
3007
string.prototype.trimstart@1.0.8:
3008
dependencies:
3009
+
call-bind: 1.0.8
3010
define-properties: 1.2.1
3011
+
es-object-atoms: 1.1.1
3012
3013
string_decoder@1.3.0:
3014
dependencies:
···
3022
3023
supports-preserve-symlinks-flag@1.0.0: {}
3024
3025
+
synckit@0.11.1:
3026
+
dependencies:
3027
+
'@pkgr/core': 0.2.0
3028
+
tslib: 2.8.1
3029
+
3030
+
taze@19.0.4:
3031
dependencies:
3032
+
'@antfu/ni': 24.3.0
3033
+
cac: 6.7.14
3034
+
find-up-simple: 1.0.1
3035
+
ofetch: 1.4.1
3036
+
package-manager-detector: 1.1.0
3037
+
pathe: 2.0.3
3038
+
pnpm-workspace-yaml: 0.3.1
3039
+
restore-cursor: 5.1.0
3040
+
tinyexec: 1.0.1
3041
+
tinyglobby: 0.2.12
3042
+
unconfig: 7.3.1
3043
+
yaml: 2.7.1
3044
+
3045
+
tinyexec@1.0.1: {}
3046
3047
+
tinyglobby@0.2.12:
3048
+
dependencies:
3049
+
fdir: 6.4.3(picomatch@4.0.2)
3050
+
picomatch: 4.0.2
3051
3052
to-regex-range@5.0.1:
3053
dependencies:
3054
is-number: 7.0.0
3055
3056
+
ts-api-utils@2.1.0(typescript@5.8.2):
3057
dependencies:
3058
+
typescript: 5.8.2
3059
3060
+
tslib@2.8.1: {}
3061
3062
type-check@0.4.0:
3063
dependencies:
3064
prelude-ls: 1.2.1
3065
3066
+
typed-array-buffer@1.0.3:
3067
dependencies:
3068
+
call-bound: 1.0.4
3069
es-errors: 1.3.0
3070
+
is-typed-array: 1.1.15
3071
3072
+
typed-array-byte-length@1.0.3:
3073
dependencies:
3074
+
call-bind: 1.0.8
3075
+
for-each: 0.3.5
3076
+
gopd: 1.2.0
3077
+
has-proto: 1.2.0
3078
+
is-typed-array: 1.1.15
3079
3080
+
typed-array-byte-offset@1.0.4:
3081
dependencies:
3082
available-typed-arrays: 1.0.7
3083
+
call-bind: 1.0.8
3084
+
for-each: 0.3.5
3085
+
gopd: 1.2.0
3086
+
has-proto: 1.2.0
3087
+
is-typed-array: 1.1.15
3088
+
reflect.getprototypeof: 1.0.10
3089
3090
+
typed-array-length@1.0.7:
3091
dependencies:
3092
+
call-bind: 1.0.8
3093
+
for-each: 0.3.5
3094
+
gopd: 1.2.0
3095
+
is-typed-array: 1.1.15
3096
+
possible-typed-array-names: 1.1.0
3097
+
reflect.getprototypeof: 1.0.10
3098
3099
+
typescript-eslint@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2):
3100
dependencies:
3101
+
'@typescript-eslint/eslint-plugin': 8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
3102
+
'@typescript-eslint/parser': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
3103
+
'@typescript-eslint/utils': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
3104
+
eslint: 9.23.0(jiti@2.4.2)
3105
+
typescript: 5.8.2
3106
transitivePeerDependencies:
3107
- supports-color
3108
3109
+
typescript@5.8.2: {}
3110
+
3111
+
ufo@1.5.4: {}
3112
+
3113
+
unbox-primitive@1.1.0:
3114
+
dependencies:
3115
+
call-bound: 1.0.4
3116
+
has-bigints: 1.1.0
3117
+
has-symbols: 1.1.0
3118
+
which-boxed-primitive: 1.1.1
3119
3120
+
unconfig@7.3.1:
3121
dependencies:
3122
+
'@quansync/fs': 0.1.2
3123
+
defu: 6.1.4
3124
+
jiti: 2.4.2
3125
+
quansync: 0.2.10
3126
+
3127
+
undici-types@6.20.0: {}
3128
3129
+
undici-types@6.21.0: {}
3130
3131
uri-js@4.4.1:
3132
dependencies:
3133
punycode: 2.3.1
3134
3135
+
utilium@1.10.1:
3136
dependencies:
3137
eventemitter3: 5.0.1
3138
+
optionalDependencies:
3139
+
'@xterm/xterm': 5.5.0
3140
3141
+
which-boxed-primitive@1.1.1:
3142
dependencies:
3143
+
is-bigint: 1.1.0
3144
+
is-boolean-object: 1.2.2
3145
+
is-number-object: 1.1.1
3146
+
is-string: 1.1.1
3147
+
is-symbol: 1.1.1
3148
3149
+
which-builtin-type@1.2.1:
3150
dependencies:
3151
+
call-bound: 1.0.4
3152
+
function.prototype.name: 1.1.8
3153
has-tostringtag: 1.0.2
3154
+
is-async-function: 2.1.1
3155
+
is-date-object: 1.1.0
3156
+
is-finalizationregistry: 1.1.1
3157
+
is-generator-function: 1.1.0
3158
+
is-regex: 1.2.1
3159
+
is-weakref: 1.1.1
3160
isarray: 2.0.5
3161
+
which-boxed-primitive: 1.1.1
3162
which-collection: 1.0.2
3163
+
which-typed-array: 1.1.19
3164
3165
which-collection@1.0.2:
3166
dependencies:
3167
is-map: 2.0.3
3168
is-set: 2.0.3
3169
is-weakmap: 2.0.2
3170
+
is-weakset: 2.0.4
3171
3172
+
which-typed-array@1.1.19:
3173
dependencies:
3174
available-typed-arrays: 1.0.7
3175
+
call-bind: 1.0.8
3176
+
call-bound: 1.0.4
3177
+
for-each: 0.3.5
3178
+
get-proto: 1.0.1
3179
+
gopd: 1.2.0
3180
has-tostringtag: 1.0.2
3181
3182
which@2.0.2:
3183
dependencies:
3184
isexe: 2.0.0
3185
3186
+
yaml@2.7.1: {}
3187
+
3188
yocto-queue@0.1.0: {}
3189
+
3190
+
zustand@5.0.3(@types/react@18.3.20):
3191
+
optionalDependencies:
3192
+
'@types/react': 18.3.20
+31
-1
pnpm-workspace.yaml
+31
-1
pnpm-workspace.yaml
···
1
packages:
2
+
- packages/*
3
+
4
+
catalogs:
5
+
dev:
6
+
esbuild: ^0.19.3
7
+
esbuild-copy-static-files: ^0.1.0
8
+
"@types/node": ^22.14.0
9
+
"@moonlight-mod/eslint-config": "github:moonlight-mod/eslint-config"
10
+
eslint: ^9.12.0
11
+
"@types/chrome": ^0.0.313
12
+
husky: ^8.0.3
13
+
prettier: ^3.1.0
14
+
typescript: ^5.3.3
15
+
taze: ^19.0.4
16
+
prod:
17
+
"@moonlight-mod/lunast": ^1.0.1
18
+
"@moonlight-mod/mappings": ^1.1.25
19
+
"@moonlight-mod/moonmap": ^1.0.5
20
+
microdiff: ^1.5.0
21
+
nanotar: ^0.1.1
22
+
"@zenfs/core": ^2.0.0
23
+
"@zenfs/dom": ^1.1.3
24
+
25
+
onlyBuiltDependencies:
26
+
- esbuild
27
+
28
+
engineStrict: true
29
+
strictSsl: true
30
+
strictDepBuilds: true
31
+
packageManagerStrict: true
32
+
registry: https://registry.npmjs.org/
-78
scripts/link.js
-78
scripts/link.js
···
1
-
// Janky script to get around pnpm link issues
2
-
// Probably don't use this. Probably
3
-
/* eslint-disable no-console */
4
-
const fs = require("fs");
5
-
const path = require("path");
6
-
const child_process = require("child_process");
7
-
8
-
const cwd = process.cwd();
9
-
const onDisk = {
10
-
"@moonlight-mod/lunast": "../lunast",
11
-
"@moonlight-mod/moonmap": "../moonmap",
12
-
"@moonlight-mod/mappings": "../mappings"
13
-
};
14
-
15
-
function exec(cmd, dir) {
16
-
child_process.execSync(cmd, { cwd: dir, stdio: "inherit" });
17
-
}
18
-
19
-
function getDeps(packageJSON) {
20
-
const ret = {};
21
-
Object.assign(ret, packageJSON.dependencies || {});
22
-
Object.assign(ret, packageJSON.devDependencies || {});
23
-
Object.assign(ret, packageJSON.peerDependencies || {});
24
-
return ret;
25
-
}
26
-
27
-
function link(dir) {
28
-
const packageJSONPath = path.join(dir, "package.json");
29
-
if (!fs.existsSync(packageJSONPath)) return;
30
-
const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath, "utf8"));
31
-
const deps = getDeps(packageJSON);
32
-
33
-
for (const [dep, relativePath] of Object.entries(onDisk)) {
34
-
const fullPath = path.join(cwd, relativePath);
35
-
if (deps[dep]) {
36
-
exec(`pnpm link ${fullPath}`, dir);
37
-
}
38
-
}
39
-
}
40
-
41
-
function undo(dir) {
42
-
exec("pnpm unlink", dir);
43
-
try {
44
-
if (fs.existsSync(path.join(dir, "pnpm-lock.yaml"))) {
45
-
exec("git restore pnpm-lock.yaml", dir);
46
-
}
47
-
} catch {
48
-
// ignored
49
-
}
50
-
}
51
-
52
-
const shouldUndo = process.argv.includes("--undo");
53
-
const packages = fs.readdirSync("./packages");
54
-
55
-
for (const path of Object.values(onDisk)) {
56
-
console.log(path);
57
-
if (shouldUndo) {
58
-
undo(path);
59
-
} else {
60
-
link(path);
61
-
}
62
-
}
63
-
64
-
if (shouldUndo) {
65
-
console.log(cwd);
66
-
undo(cwd);
67
-
for (const pkg of packages) {
68
-
const dir = path.join(cwd, "packages", pkg);
69
-
console.log(dir);
70
-
undo(dir);
71
-
}
72
-
} else {
73
-
for (const pkg of packages) {
74
-
const dir = path.join(cwd, "packages", pkg);
75
-
console.log(dir);
76
-
link(dir);
77
-
}
78
-
}
···
+78
scripts/link.mjs
+78
scripts/link.mjs
···
···
1
+
// Janky script to get around pnpm link issues
2
+
// Probably don't use this. Probably
3
+
/* eslint-disable no-console */
4
+
const fs = require("fs");
5
+
const path = require("path");
6
+
const child_process = require("child_process");
7
+
8
+
const cwd = process.cwd();
9
+
const onDisk = {
10
+
//"@moonlight-mod/lunast": "../lunast",
11
+
//"@moonlight-mod/moonmap": "../moonmap",
12
+
"@moonlight-mod/mappings": "../mappings"
13
+
};
14
+
15
+
function exec(cmd, dir) {
16
+
child_process.execSync(cmd, { cwd: dir, stdio: "inherit" });
17
+
}
18
+
19
+
function getDeps(packageJSON) {
20
+
const ret = {};
21
+
Object.assign(ret, packageJSON.dependencies || {});
22
+
Object.assign(ret, packageJSON.devDependencies || {});
23
+
Object.assign(ret, packageJSON.peerDependencies || {});
24
+
return ret;
25
+
}
26
+
27
+
function link(dir) {
28
+
const packageJSONPath = path.join(dir, "package.json");
29
+
if (!fs.existsSync(packageJSONPath)) return;
30
+
const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath, "utf8"));
31
+
const deps = getDeps(packageJSON);
32
+
33
+
for (const [dep, relativePath] of Object.entries(onDisk)) {
34
+
const fullPath = path.join(cwd, relativePath);
35
+
if (deps[dep]) {
36
+
exec(`pnpm link ${fullPath}`, dir);
37
+
}
38
+
}
39
+
}
40
+
41
+
function undo(dir) {
42
+
exec("pnpm unlink", dir);
43
+
try {
44
+
if (fs.existsSync(path.join(dir, "pnpm-lock.yaml"))) {
45
+
exec("git restore pnpm-lock.yaml", dir);
46
+
}
47
+
} catch {
48
+
// ignored
49
+
}
50
+
}
51
+
52
+
const shouldUndo = process.argv.includes("--undo");
53
+
const packages = fs.readdirSync("./packages");
54
+
55
+
for (const path of Object.values(onDisk)) {
56
+
console.log(path);
57
+
if (shouldUndo) {
58
+
undo(path);
59
+
} else {
60
+
link(path);
61
+
}
62
+
}
63
+
64
+
if (shouldUndo) {
65
+
console.log(cwd);
66
+
undo(cwd);
67
+
for (const pkg of packages) {
68
+
const dir = path.join(cwd, "packages", pkg);
69
+
console.log(dir);
70
+
undo(dir);
71
+
}
72
+
} else {
73
+
for (const pkg of packages) {
74
+
const dir = path.join(cwd, "packages", pkg);
75
+
console.log(dir);
76
+
link(dir);
77
+
}
78
+
}
-29
scripts/update.js
-29
scripts/update.js
···
1
-
// Update dependencies in all packages
2
-
/* eslint-disable no-console */
3
-
const fs = require("fs");
4
-
const path = require("path");
5
-
const child_process = require("child_process");
6
-
7
-
const packageToUpdate = process.argv[2];
8
-
9
-
function getDeps(packageJSON) {
10
-
const ret = {};
11
-
Object.assign(ret, packageJSON.dependencies || {});
12
-
Object.assign(ret, packageJSON.devDependencies || {});
13
-
Object.assign(ret, packageJSON.peerDependencies || {});
14
-
return ret;
15
-
}
16
-
17
-
function exec(cmd, dir) {
18
-
child_process.execSync(cmd, { cwd: dir, stdio: "inherit" });
19
-
}
20
-
21
-
for (const package of fs.readdirSync("./packages")) {
22
-
const packageJSON = JSON.parse(fs.readFileSync(path.join("./packages", package, "package.json"), "utf8"));
23
-
24
-
const deps = getDeps(packageJSON);
25
-
if (Object.keys(deps).includes(packageToUpdate)) {
26
-
console.log(`Updating ${packageToUpdate} in ${package}`);
27
-
exec(`pnpm update ${packageToUpdate}`, path.join("./packages", package));
28
-
}
29
-
}
···
+35
tsconfig.base.json
+35
tsconfig.base.json
···
···
1
+
{
2
+
"$schema": "https://json.schemastore.org/tsconfig.json",
3
+
"display": "Base",
4
+
"_version": "1.0.0",
5
+
"compilerOptions": {
6
+
"incremental": true,
7
+
"target": "ES2022",
8
+
"jsx": "react",
9
+
"lib": ["ESNext", "ESNext.Disposable", "DOM", "DOM.Iterable"],
10
+
"module": "ES2020",
11
+
"moduleResolution": "Bundler",
12
+
"resolveJsonModule": true,
13
+
"allowArbitraryExtensions": false,
14
+
"allowImportingTsExtensions": true,
15
+
"allowJs": true,
16
+
"strict": true,
17
+
"strictNullChecks": true,
18
+
19
+
// disable unreachable code detection because it breaks with esbuild labels
20
+
"allowUnreachableCode": true,
21
+
"noFallthroughCasesInSwitch": true,
22
+
"noImplicitReturns": true,
23
+
"declaration": true,
24
+
"declarationMap": true,
25
+
"outDir": "dist",
26
+
"sourceMap": true,
27
+
"stripInternal": true,
28
+
"esModuleInterop": true,
29
+
"forceConsistentCasingInFileNames": true,
30
+
"noErrorTruncation": true,
31
+
"verbatimModuleSyntax": false,
32
+
// meriyah has a broken import lol
33
+
"skipLibCheck": true
34
+
}
35
+
}
+7
-16
tsconfig.json
+7
-16
tsconfig.json
···
1
{
2
"compilerOptions": {
3
-
"target": "es2022",
4
-
"module": "es2020",
5
-
"esModuleInterop": true,
6
-
"forceConsistentCasingInFileNames": true,
7
-
"strict": true,
8
-
"moduleResolution": "bundler",
9
"baseUrl": "./packages/",
10
-
"jsx": "react",
11
-
"noEmit": true,
12
-
13
-
// meriyah has a broken import lol
14
-
"skipLibCheck": true,
15
-
16
-
// disable unreachable code detection because it breaks with esbuild labels
17
-
"allowUnreachableCode": true
18
},
19
-
"include": ["./packages/**/*", "./env.d.ts"],
20
-
"exclude": ["node_modules"]
21
}