summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO12
-rw-r--r--PKGBUILD37
-rw-r--r--replugged.patch291
-rwxr-xr-xreplugged.sh7
-rw-r--r--webpack.patch1658
5 files changed, 35 insertions, 1970 deletions
diff --git a/.SRCINFO b/.SRCINFO
index c5268452cf2c..f5985c9d1a57 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,17 +1,15 @@
pkgbase = replugged-electron-git
pkgdesc = A fork of Powercord, the lightweight discord client mod focused on simplicity and performance.
- pkgver = r1784.e984d8fd
+ pkgver = r1997.4fa35914
pkgrel = 1
url = https://github.com/replugged-org/replugged
install = replugged.install
arch = any
license = MIT
makedepends = git
- makedepends = npm
+ makedepends = pnpm
depends = electron19
depends = discord-canary-electron-bin
- depends = curl
- depends = jq
provides = replugged
conflicts = replugged
source = git+https://github.com/replugged-org/replugged.git#branch=main
@@ -19,12 +17,10 @@ pkgbase = replugged-electron-git
source = replugged.desktop
source = replugged.png
source = replugged.patch
- source = webpack.patch
md5sums = SKIP
- md5sums = fa10b7595d4a5cb4a7735a6e36fc9e61
+ md5sums = a94b9b81f16f2743504d390c6c0f45a0
md5sums = 9698a7fbd4af735bee89e74fa0b03dfe
md5sums = 4ddcb11a1ec0a8a9585a6f0b685286b4
- md5sums = 80b126e9868616ba6c4caaebb716a62f
- md5sums = 410cd8ba30fb07064295c898c2e99be0
+ md5sums = 7705ffd25cebcc73277a1a957c1cbe63
pkgname = replugged-electron-git
diff --git a/PKGBUILD b/PKGBUILD
index e591db32cc8e..6d941ed49c28 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,14 +1,18 @@
# Maintainer: Łukasz Mariański <lmarianski at protonmail dot com>
+
+_electron='electron19'
+_discord='discord-canary'
+
pkgname=replugged-electron-git
_pkgname="${pkgname%-electron-*}"
-pkgver=r1784.e984d8fd
+pkgver=r1997.4fa35914
pkgrel=1
pkgdesc="A fork of Powercord, the lightweight discord client mod focused on simplicity and performance."
arch=('any')
url="https://github.com/${_pkgname}-org/${_pkgname}"
license=('MIT')
-depends=('electron19' 'discord-canary-electron-bin' 'curl' 'jq')
-makedepends=('git' 'npm')
+depends=("$_electron" 'discord-canary-electron-bin')
+makedepends=('git' 'pnpm')
provides=("$_pkgname")
conflicts=("$_pkgname")
install="$_pkgname.install"
@@ -17,14 +21,12 @@ source=("git+https://github.com/${_pkgname}-org/${_pkgname}.git#branch=${_branch
"$_pkgname.sh"
"$_pkgname.desktop"
"$_pkgname.png"
- "$_pkgname.patch"
- "webpack.patch")
+ "$_pkgname.patch")
md5sums=('SKIP'
- 'fa10b7595d4a5cb4a7735a6e36fc9e61'
+ 'a94b9b81f16f2743504d390c6c0f45a0'
'9698a7fbd4af735bee89e74fa0b03dfe'
'4ddcb11a1ec0a8a9585a6f0b685286b4'
- '80b126e9868616ba6c4caaebb716a62f'
- '410cd8ba30fb07064295c898c2e99be0')
+ '7705ffd25cebcc73277a1a957c1cbe63')
pkgver() {
cd "$srcdir/$_pkgname"
@@ -37,17 +39,17 @@ prepare() {
patch -p1 -i "$srcdir/$_pkgname.patch"
- sed -i "s:@PKG_UPSTREAM@:$_pkgname-org/$_pkgname:;s:@PKG_BRANCH@:${_branch}:;s:@PKG_REVISION@:$(git rev-parse ${_branch}):" src/Powercord/coremods/updater/index.js
+ sed -i "s/@ELECTRON@/$_electron/" "$srcdir/$_pkgname.sh"
+ sed -i "s/@DISCORD@/$_discord/" "$srcdir/$_pkgname/src/main/index.ts"
- # Bring back the "new" webpack backend, needed because of contextIsolation
- # git revert -X ours -n 8dbf24d9ec3cf0ea6589707230e1d2cd5285e187
- patch -p1 -i "$srcdir/webpack.patch"
+ # sed -i "s:@PKG_UPSTREAM@:$_pkgname-org/$_pkgname:;s:@PKG_BRANCH@:${_branch}:;s:@PKG_REVISION@:$(git rev-parse ${_branch}):" src/Powercord/coremods/updater/index.js
}
build() {
cd "$srcdir/$_pkgname"
- npm install --cache "${srcdir}/npm-cache" --omit=dev
+ pnpm i --store-dir "${srcdir}/pnpm-store"
+ pnpm build
}
package() {
@@ -58,13 +60,8 @@ package() {
install -dm755 "$pkgdir/usr/share/$_pkgname"
- cp -ar * "$pkgdir/usr/share/$_pkgname"
- rm -rf "$pkgdir/usr/share/$_pkgname/"{test,LICENSE,README.md,release.sh,jsconfig.json,injectors}
-
- ln -s "/usr/share/$_pkgname/src/fake_node_modules/powercord" "$pkgdir/usr/share/$_pkgname/node_modules/"
- ln -s "/usr/share/$_pkgname/src/fake_node_modules/keybindutils" "$pkgdir/usr/share/$_pkgname/node_modules/"
-
- echo "require('./src/patcher.js');" > "$pkgdir/usr/share/$_pkgname/index.js"
+ cp -ar dist/* "$pkgdir/usr/share/$_pkgname/"
+ echo "require('./main.js');" > "$pkgdir/usr/share/$_pkgname/index.js"
# chmod -R u+rwX,go+rX,go-w "$pkgdir/usr/share/$_pkgname"
diff --git a/replugged.patch b/replugged.patch
index a242ab6879a6..7d82a99f323f 100644
--- a/replugged.patch
+++ b/replugged.patch
@@ -1,278 +1,13 @@
-diff --git a/src/Powercord/coremods/moduleManager/components/manage/Base.jsx b/src/Powercord/coremods/moduleManager/components/manage/Base.jsx
-index 0b8a45d9..3e69cf77 100644
---- a/src/Powercord/coremods/moduleManager/components/manage/Base.jsx
-+++ b/src/Powercord/coremods/moduleManager/components/manage/Base.jsx
-@@ -3,6 +3,7 @@ const { shell } = require('electron');
- const { React, getModule, contextMenu, i18n: { Messages } } = require('powercord/webpack');
- const { Button, Tooltip, ContextMenu, Divider, Icons: { Overflow } } = require('powercord/components');
- const { TextInput } = require('powercord/components/settings');
-+const XDG_DATA_HOME = process.env.XDG_DATA_HOME || join(process.env.HOME, '.local', 'share');
-
- class Base extends React.Component {
- constructor () {
-@@ -91,7 +92,7 @@ class Base extends React.Component {
- {
- type: 'button',
- name: Messages[`REPLUGGED_${this.state.key}_OPEN_FOLDER`],
-- onClick: () => shell.openPath(join(__dirname, '..', '..', '..', '..', '..', '..', this.constructor.name.toLowerCase()))
-+ onClick: () => shell.openPath(join(XDG_DATA_HOME, 'replugged', this.constructor.name.toLowerCase()))
- },
- {
- type: 'button',
-diff --git a/src/Powercord/coremods/moduleManager/index.js b/src/Powercord/coremods/moduleManager/index.js
-index 2c3a2a9d..14b0f77a 100644
---- a/src/Powercord/coremods/moduleManager/index.js
-+++ b/src/Powercord/coremods/moduleManager/index.js
-@@ -6,7 +6,7 @@ const { React, getModule, i18n: { Messages } } = require('powercord/webpack');
- const { PopoutWindow } = require('powercord/components');
- const { inject, uninject } = require('powercord/injector');
- const { findInReactTree, forceUpdateElement } = require('powercord/util');
--const { SpecialChannels: { CSS_SNIPPETS, STORE_PLUGINS, STORE_THEMES }, WEBSITE } = require('powercord/constants');
-+const { SpecialChannels: { CSS_SNIPPETS, STORE_PLUGINS, STORE_THEMES }, WEBSITE, SETTINGS_FOLDER } = require('powercord/constants');
- const { join } = require('path');
- const commands = require('./commands');
- const deeplinks = require('./deeplinks');
-@@ -23,7 +23,7 @@ const { injectContextMenu } = require('powercord/util');
- const Menu = getModule([ 'MenuItem' ], false);
-
- let _quickCSS = '';
--const _quickCSSFile = join(__dirname, '..', '..', '..', '..', 'settings', 'quickcss', 'main.css');
-+const _quickCSSFile = join(SETTINGS_FOLDER, 'quickcss', 'main.css');
- let _quickCSSElement;
-
- async function _installerInjectCtxMenu () {
-diff --git a/src/Powercord/coremods/moduleManager/util/cloneRepo.js b/src/Powercord/coremods/moduleManager/util/cloneRepo.js
-index f015ea76..eb058858 100644
---- a/src/Powercord/coremods/moduleManager/util/cloneRepo.js
-+++ b/src/Powercord/coremods/moduleManager/util/cloneRepo.js
-@@ -4,16 +4,18 @@ const fs = require('fs');
- const { REPO_URL_REGEX } = require('./misc');
- const { i18n: { Messages } } = require('powercord/webpack');
-
-+const XDG_DATA_HOME = process.env.XDG_DATA_HOME || join(process.env.HOME, '.local', 'share');
-+
- module.exports = async function download (url, powercord, type) {
- return new Promise((resolve) => {
- // const dir = type === 'plugin' ? join(__dirname, '..', '..') : join(__dirname, '..', '..', 'themes');
- let dir;
- switch (type) {
- case 'plugin':
-- dir = join(__dirname, '..', '..', '..', '..', '..', 'plugins');
-+ dir = join(XDG_DATA_HOME, 'replugged', 'plugins');
- break;
- case 'theme':
-- dir = join(__dirname, '..', '..', '..', '..', '..', 'themes');
-+ dir = join(XDG_DATA_HOME, 'replugged', 'themes');
- break;
- }
-
-diff --git a/src/Powercord/coremods/updater/components/Settings.jsx b/src/Powercord/coremods/updater/components/Settings.jsx
-index b915af1c..fbe64da4 100644
---- a/src/Powercord/coremods/updater/components/Settings.jsx
-+++ b/src/Powercord/coremods/updater/components/Settings.jsx
-@@ -82,7 +82,7 @@ module.exports = class UpdaterSettings extends React.PureComponent {
- <div className="about">
- <div>
- <span>{Messages.REPLUGGED_UPDATES_UPSTREAM}</span>
-- <span>{powercord.gitInfos.upstream.replace(REPO_URL, Messages.REPLUGGED_UPDATES_UPSTREAM_OFFICIAL)}</span>
-+ <span>{powercord.gitInfos.upstream.replace(REPO_URL, Messages.REPLUGGED_UPDATES_UPSTREAM_OFFICIAL+' (AUR)')}</span>
- </div>
- <div>
- <span>{Messages.REPLUGGED_UPDATES_REVISION}</span>
-diff --git a/src/Powercord/coremods/updater/components/Update.jsx b/src/Powercord/coremods/updater/components/Update.jsx
-index 7d8fbcaa..ab5be0e9 100644
---- a/src/Powercord/coremods/updater/components/Update.jsx
-+++ b/src/Powercord/coremods/updater/components/Update.jsx
-@@ -28,6 +28,7 @@ module.exports = class Update extends React.PureComponent {
- </div>
- </div>
- <div className='summary'>
-+ {name === 'Powercord' ? <span>Note: Please download the update from the AUR!</span> : ''}
- {commits.map(commit => <div key={commit.id}>
- <a href={`https://github.com/${repo}/commit/${commit.id}`} target='_blank'>
- <code>{commit.id.substring(0, 7)}</code>
-diff --git a/src/Powercord/coremods/updater/index.js b/src/Powercord/coremods/updater/index.js
-index 770e195a..e542774c 100644
---- a/src/Powercord/coremods/updater/index.js
-+++ b/src/Powercord/coremods/updater/index.js
-@@ -44,9 +44,6 @@ class Updater {
- const themes = [ ...powercord.styleManager.themes.values() ];
-
- const entities = plugins.concat(themes).filter(e => !disabled.includes(e.updateIdentifier) && e.isUpdatable());
-- if (!disabled.includes(powercord.updateIdentifier)) {
-- entities.push(powercord);
-- }
-
- let done = 0;
- const updates = [];
-@@ -232,33 +229,10 @@ class Updater {
- }
-
- async getGitInfos () {
-- const branch = await PowercordNative.exec('git branch', this.cwd)
-- .then(({ stdout }) =>
-- stdout
-- .toString()
-- .split('\n')
-- .find(l => l.startsWith('*'))
-- .slice(2)
-- .trim()
-- );
--
-- const revision = await PowercordNative.exec(`git rev-parse ${branch}`, this.cwd)
-- .then(r => r.stdout.toString().trim());
--
-- let upstream = '???';
--
-- const remoteBranch = await powercord.getUpstreamBranch();
-- if (remoteBranch) {
-- const remote = remoteBranch.split('/')[0];
-- upstream = await PowercordNative.exec(`git remote get-url ${remote}`, this.cwd)
-- .then(r => r.stdout.toString().match(/github\.com[:/]([\w-_]+\/[\w-_]+)/)?.[1] ||
-- r.stdout.toString().trim().match(/(.*):(.*\/.*)/)[2]);
-- }
--
- return {
-- upstream,
-- branch,
-- revision
-+ upstream: "@PKG_UPSTREAM@",
-+ branch: "@PKG_BRANCH@",
-+ revision: "@PKG_REVISION@"
- };
- }
-
-diff --git a/src/Powercord/index.js b/src/Powercord/index.js
-index 019e304c..0de3d47e 100644
---- a/src/Powercord/index.js
-+++ b/src/Powercord/index.js
-@@ -253,6 +253,32 @@ class Powercord extends Updatable {
- }
- return success;
- }
-+
-+ async _getUpdateCommits () {
-+ return [];
-+ }
-+ async getBranch () {return this.gitInfos.branch;}
-+ async getGitRepo () {return this.gitInfos.upstream;}
-+ async _checkForUpdates () {
-+ const abort = new AbortController();
-+ const timeout = setTimeout(() => {
-+ abort.abort();
-+ throw new Error('Timed out.');
-+ }, 10000);
-+
-+ try {
-+ const latestCommitSha = await exec(`curl https://api.github.com/repos/${this.gitInfos.upstream}/commits/${this.gitInfos.branch} | jq -r .sha`, {
-+ cwd: this.entityPath,
-+ signal: abort.signal
-+ }).then(({ stdout }) => stdout.toString());
-+
-+ clearTimeout(timeout);
-+ return !latestCommitSha.includes(this.gitInfos.revision);
-+ } catch (e) {
-+ clearTimeout(timeout);
-+ return false;
-+ }
-+ }
- }
-
- module.exports = Powercord;
-diff --git a/src/Powercord/managers/plugins.js b/src/Powercord/managers/plugins.js
-index c45b34fe..f0cd4dea 100644
---- a/src/Powercord/managers/plugins.js
-+++ b/src/Powercord/managers/plugins.js
-@@ -1,10 +1,12 @@
--const { resolve } = require('path');
-+const { resolve, join } = require('path');
- const { readdirSync } = require('fs');
- const { rmdirRf } = require('powercord/util');
-
-+const XDG_DATA_HOME = process.env.XDG_DATA_HOME || join(process.env.HOME, '.local', 'share');
-+
- module.exports = class PluginManager {
- constructor () {
-- this.pluginDir = resolve(__dirname, '..', '..', '..', 'plugins');
-+ this.pluginDir = resolve(XDG_DATA_HOME, 'replugged', 'plugins');
- this.plugins = new Map();
-
- this.manifestKeys = [ 'name', 'version', 'description', 'author', 'license' ];
-diff --git a/src/Powercord/managers/styles.js b/src/Powercord/managers/styles.js
-index c5b184e4..118b5025 100644
---- a/src/Powercord/managers/styles.js
-+++ b/src/Powercord/managers/styles.js
-@@ -14,10 +14,12 @@ const ErrorTypes = Object.freeze({
- INVALID_MANIFEST: 'INVALID_MANIFEST'
- });
-
-+const XDG_DATA_HOME = process.env.XDG_DATA_HOME || join(process.env.HOME, '.local', 'share');
-+
- module.exports = class StyleManager {
- constructor () {
- this._coreStyles = [];
-- this.themesDir = join(__dirname, '..', '..', '..', 'themes');
-+ this.themesDir = join(XDG_DATA_HOME, 'replugged', 'themes');
- this.themes = new Map();
-
- if (!window.__SPLASH__) {
-diff --git a/src/browserWindow.js b/src/browserWindow.js
-index 82620e56..cafc41a0 100644
---- a/src/browserWindow.js
-+++ b/src/browserWindow.js
-@@ -28,7 +28,6 @@ class PatchedBrowserWindow extends BrowserWindow {
- if (opts.webPreferences.nativeWindowOpen) {
- // Discord Client
- opts.webPreferences.preload = join(__dirname, './preload.js');
-- opts.webPreferences.contextIsolation = false; // shrug
- } else {
- // Splash Screen on macOS (Host 0.0.262+) & Windows (Host 0.0.293 / 1.0.17+)
- opts.webPreferences.preload = join(__dirname, './preloadSplash.js');
-diff --git a/src/fake_node_modules/powercord/constants.js b/src/fake_node_modules/powercord/constants.js
-index 147e02e9..948f2b02 100644
---- a/src/fake_node_modules/powercord/constants.js
-+++ b/src/fake_node_modules/powercord/constants.js
-@@ -1,5 +1,9 @@
- const { join } = require('path');
-
-+const XDG_CONFIG_HOME = process.env.XDG_CONFIG_HOME || join(process.env.HOME, '.config');
-+const XDG_CACHE_HOME = process.env.XDG_CACHE_HOME || join(process.env.HOME, '.cache');
-+const XDG_DATA_HOME = process.env.XDG_DATA_HOME || join(process.env.HOME, '.local', 'share');
-+
- module.exports = Object.freeze({
- // Replugged
- WEBSITE: 'https://replugged.dev',
-@@ -7,9 +11,9 @@ module.exports = Object.freeze({
- REPO_URL: 'replugged-org/replugged',
-
- // Runtime
-- SETTINGS_FOLDER: join(__dirname, '..', '..', '..', 'settings'),
-- CACHE_FOLDER: join(__dirname, '..', '..', '..', '.cache'),
-- LOGS_FOLDER: join(__dirname, '..', '..', '..', '.logs'),
-+ SETTINGS_FOLDER: join(XDG_CONFIG_HOME, 'replugged'),
-+ CACHE_FOLDER: join(XDG_CACHE_HOME, 'replugged'),
-+ LOGS_FOLDER: join(XDG_DATA_HOME, 'replugged', 'logs'),
-
- // Discord Server
- DISCORD_INVITE: 'B2TcnXV9Rg',
-diff --git a/src/patcher.js b/src/patcher.js
-index 372e41f5..eaace1cf 100644
---- a/src/patcher.js
-+++ b/src/patcher.js
-@@ -7,7 +7,7 @@ const { existsSync, unlinkSync } = require('fs');
-
- // Restore the classic path; The updater relies on it and it makes Discord go corrupt
- const electronPath = require.resolve('electron');
--const discordPath = join(dirname(require.main.filename), '..', 'app.asar');
-+const discordPath = join('/', 'usr', 'lib', 'discord-canary', 'app.asar');
- require.main.filename = join(discordPath, 'app_bootstrap/index.js');
-
- const electron = require('electron');
-@@ -30,7 +30,6 @@ function setAppUserModelId (...args) {
- appSetAppUserModelId.apply(this, args);
- if (!_patched) {
- _patched = true;
-- require('./updater.win32');
- }
- }
-
+diff --git a/src/main/index.ts b/src/main/index.ts
+index f8f225ec..6a18ed4c 100644
+--- a/src/main/index.ts
++++ b/src/main/index.ts
+@@ -5,7 +5,7 @@ import type { RepluggedWebContents } from "../types";
+ import { CONFIG_PATHS } from "src/util";
+
+ const electronPath = require.resolve("electron");
+-const discordPath = join(dirname(require.main!.filename), "..", "app.orig.asar");
++const discordPath = join("/", "usr", "lib", "@DISCORD@", "app.asar");
+ // require.main!.filename = discordMain;
+
+ Object.defineProperty(global, "appSettings", {
diff --git a/replugged.sh b/replugged.sh
index d7f925555141..774cc2b4d2ba 100755
--- a/replugged.sh
+++ b/replugged.sh
@@ -1,8 +1,3 @@
#!/bin/sh
-XDG_DATA_HOME="${XDG_DATA_HOME:=$HOME/.local/share}"
-mkdir -p "$XDG_DATA_HOME/replugged/"{plugins,themes}
-
-ln -s "/usr/share/replugged/src/fake_node_modules" "$XDG_DATA_HOME/replugged/node_modules" &>/dev/null
-
-exec electron19 /usr/share/replugged "$@" \ No newline at end of file
+exec @ELECTRON@ /usr/share/replugged "$@" \ No newline at end of file
diff --git a/webpack.patch b/webpack.patch
deleted file mode 100644
index 6c048dfa0a3d..000000000000
--- a/webpack.patch
+++ /dev/null
@@ -1,1658 +0,0 @@
-diff --git a/src/fake_node_modules/powercord/webpack/index.js b/src/fake_node_modules/powercord/webpack/index.js
-index efe6bfe6..7a2e0e62 100644
---- a/src/fake_node_modules/powercord/webpack/index.js
-+++ b/src/fake_node_modules/powercord/webpack/index.js
-@@ -1,210 +1,212 @@
--const { sleep } = require('powercord/util');
--const moduleFilters = require('./modules.json');
--
--/**
--* @typedef WebpackInstance
--* @property {object} cache
--* @property {function} require
--* @property {function} loadChunk
--*/
--
--/**
--* @typedef ContextMenuModule
--* @property {function} openContextMenu
--* @property {function} closeContextMenu
--*/
--
--
--/**
-- * @typedef ModuleInfo
-- * @property {number} id The module's id.
-- * @property {boolean} loaded Whether the module is loaded
-- * @property {object} exports The module's exports
-- */
--
--/**
--* @typedef {number[]} chunkIds The chunk's ids.
--* @typedef {object.<number, function>} chunkMdls A map of module ids to module source functions.
--* @typedef {[chunkIds, chunkMdls]} Chunk
--*/
--
--/**
--* @property {ContextMenuModule} contextMenu
--* @property {WebpackInstance} instance
--*/
--const webpack = {
-- ...require('./lazy'),
--
-- /**
-- * Grabs a module from the Webpack store
-- * @param {function|string[]} filter Filter used to grab the module. Can be a function or an array of keys the object must have.
-- * @param {boolean} retry Whether or not to retry fetching if the module is not found. Each try will be delayed by 100ms and max retries is 20.
-- * @param {boolean} forever If Replugged should try to fetch the module forever. Should be used only if you're in early stages of startup.
-- * @returns {Promise<object>|object} The found module. A promise will always be returned, unless retry is false.
-- */
-- getModule (filter, retry = true, forever = false) {
-- if (Array.isArray(filter)) {
-- const keys = filter;
-- filter = m => keys.every(key => m.hasOwnProperty(key) || (m.__proto__ && m.__proto__.hasOwnProperty(key)));
-- }
--
-- if (!retry) {
-- return webpack._getModules(filter);
-- }
--
-- return new Promise(async (res) => {
-- let mdl;
-- for (let i = 0; i < 21; !forever && i++) {
-- mdl = webpack._getModules(filter);
-- if (mdl) {
-- return res(mdl);
-- }
-- await sleep(100);
-- }
--
-- res(mdl);
-- });
-- },
--
-- /**
-- * Grabs all found modules from the webpack store
-- * @param {function|string[]} filter Filter used to grab the module. Can be a function or an array of keys the object must have.
-- * @returns {object[]} The found modules.
-- */
-- getAllModules (filter) {
-- if (Array.isArray(filter)) {
-- const keys = filter;
-- filter = m => keys.every(key => m.hasOwnProperty(key) || (m.__proto__ && m.__proto__.hasOwnProperty(key)));
-- }
--
-- return webpack._getModules(filter, true);
-- },
--
-- /**
-- * Grabs a React component by its display name
-- * @param {string} displayName Component's display name.
-- * @param {boolean} retry Whether or not to retry fetching if the module is not found. Each try will be delayed by 100ms and max retries is 20.
-- * @param {boolean} forever If Replugged should try to fetch the module forever. Should be used only if you're in early stages of startup.
-- * @returns {Promise<object>|object} The component. A promise will always be returned, unless retry is false.
-- */
-- getModuleByDisplayName (displayName, retry = true, forever = false) {
-- return webpack.getModule(m => m.displayName && m.displayName.toLowerCase() === displayName.toLowerCase(), retry, forever);
-- },
--
-+if (!global.NEW_BACKEND) {
-+ module.exports = require('./old.webpack.js');
-+ return;
-+ }
-+
-+ const { join } = require('path');
-+ const { readFile } = require('fs').promises;
-+ const { webFrame, contextBridge } = require('electron');
-+ const { deserialize, freePointer, setCommandHandler } = require('./serialize.js');
-+ const moduleFilters = require('./modules.json');
-+ const MODULE_ID = Symbol.for('powercord.webpack.moduleId');
-+
- /**
-- * Grabs a React component's module info by its display name
-- * @param {string} displayName Component's display name.
-- * @returns {ModuleInfo} The module info.
-- */
-- getModuleInfoByDisplayName (displayName) {
-- return Object.values(webpack.instance.cache).find(m => m?.exports?.displayName === displayName || m?.exports?.default?.displayName === displayName);
-- },
--
-+ * @typedef WebpackInstance
-+ * @property {object} cache
-+ * @property {function} require
-+ */
-+
- /**
-- * Grabs a chunk by one of its modules' id
-- * @param {number} id The module id.
-- * @returns {Chunk} The chunk.
-- */
-- getChunkByModuleId (id) {
-- return webpackChunkdiscord_app.find((c) => id in c[1]);
-- },
--
-+ * @typedef ContextMenuModule
-+ * @property {function} openContextMenu
-+ * @property {function} closeContextMenu
-+ */
-+
-+ // --
-+ // Webpack interface
-+ // --
-+ let commandHandler = null;
-+ const DISPLAY_NAME_FN = /=>\s*(?:\w+\??.(\w+)(?:\?\.|\s*&&\s*\w+\.\1\.)displayName|_optionalChain\(\[\w+, 'optionalAccess', _2 => _2\.(\w+), 'optionalAccess', _3 => _3\.displayName]\))\s*={2,3}\s*['"](.*)['"]/;
-+
-+ function processResult (res, all) {
-+ if (!res) {
-+ return res;
-+ }
-+
-+ if (res instanceof Promise) {
-+ return res.then((r) => processResult(r, all));
-+ }
-+
-+ if (all) {
-+ return res.map((r) => processResult(r));
-+ }
-+
-+ const mdl = deserialize(res[1]);
-+ if (mdl && (typeof mdl === 'function' || typeof mdl === 'object')) {
-+ // eslint-disable-next-line prefer-destructuring
-+ mdl[MODULE_ID] = res[0];
-+ }
-+
-+ return mdl;
-+ }
-+
- /**
-- * Gets the source function of a module by its id
-- * @param {number} id The module id.
-- * @returns {function} The source function.
-- */
-- getModuleSourceById (id) {
-- const chunk = webpack.getChunkByModuleId(id);
-- return chunk?.[1][id] ?? null;
-- },
--
-+ * Grabs a module from the Webpack store
-+ * @param {function|string[]} filter Filter used to grab the module. Can be a function or an array of keys the object must have.
-+ * @param {boolean} retry Whether or not to retry fetching if the module is not found. Each try will be delayed by 100ms and max retries is 20.
-+ * @param {boolean} forever If Replugged should try to fetch the module forever. Should be used only if you're in early stages of startup.
-+ * @returns {Promise<object>|object} The found module. A promise will always be returned, unless retry is false.
-+ */
-+ function getModule (filter, retry = true, forever = false) {
-+ if (typeof filter === 'function') {
-+ const match = filter.toString().match(DISPLAY_NAME_FN);
-+ if (match) {
-+ const res = commandHandler('getModuleByDisplayNameRaw', match[1] || match[2], match[3], retry, forever);
-+ return processResult(res);
-+ }
-+
-+ const _filter = filter;
-+ filter = (e) => !!_filter(deserialize(e));
-+ }
-+
-+ const res = commandHandler('getModule', filter, retry, forever);
-+ return processResult(res);
-+ }
-+
- /**
-- * From a given module id, gets a list of chunk ids that said module might lazy load.
-- * @param {number} id The module id.
-- * @returns {number[]} The 'to be lazy-loaded' chunk ids
-- */
-- getLazyLoadedChunkIdsByModuleId (id) {
-- const srcStr = webpack.getModuleSourceById(id)?.toString();
-- if (!srcStr) {
-- return [];
-- }
-- const requireArgument = srcStr.match(/^\(.,.,(.)\)/)?.[1];
--
-- if (!requireArgument) {
-- return [];
-- }
--
-- const importPattern = new RegExp(`\\b${requireArgument}\\.e\\(\\d+\\)`, 'g');
-- const imports = srcStr.match(importPattern);
-- const ids = imports.map(e => e.slice(4, -1));
-- return ids;
-- },
--
--
-+ * Grabs all found modules from the webpack store
-+ * @param {function|string[]} filter Filter used to grab the module. Can be a function or an array of keys the object must have.
-+ * @returns {object[]} The found modules.
-+ */
-+ function getAllModules (filter) {
-+ if (typeof filter === 'function') {
-+ const _filter = filter;
-+ filter = (e) => !!_filter(deserialize(e));
-+ }
-+
-+ const res = commandHandler('getAllModules', filter);
-+ return processResult(res, true);
-+ }
-+
- /**
-- * Initializes the injection into Webpack
-- * @returns {Promise<void>}
-- */
-- async init () {
-- delete webpack.init;
--
-- // Wait until webpack is ready
-- while (!window.webpackChunkdiscord_app || !window._) {
-- await sleep(100);
-- }
--
-- // Extract values from webpack
-- webpack.instance = {};
-- webpackChunkdiscord_app.push([
-- [ [ '_powercord' ] ],
-- {},
-- (r) => {
-- webpack.instance.cache = r.c;
-- webpack.instance.require = (m) => r(m);
--
-- webpack.instance.loadChunk = (c) => r.e(c)
-- .then(() => {
-- // Get chunk
-- const chunk = webpackChunkdiscord_app.find(C => `${C[0][0]}` === c);
-- // Cache all the modules
-- Object.keys(chunk[1]).forEach(m => r(m));
-- });
-- }
-- ]);
-- webpackChunkdiscord_app.pop();
--
-- // Patch push to enable webpack chunk listeners
-- webpack._patchPush();
-- delete webpack._patchPush;
--
-- // Load modules pre-fetched
-- for (const mdl in moduleFilters) {
-- // noinspection JSUnfilteredForInLoop
-- this[mdl] = await webpack.getModule(moduleFilters[mdl]);
-- }
--
-- this.i18n = webpack.getAllModules([ 'Messages', 'getLanguages' ]).find((m) => m.Messages.ACCOUNT);
-- },
--
-- _getModules (filter, all = false) {
-- const moduleInstances = Object.values(webpack.instance.cache).filter(m => m.exports);
-- if (all) {
-- const exports = moduleInstances.filter(m => filter(m.exports)).map(m => m.exports);
-- const expDefault = moduleInstances.filter(m => m.exports.default && filter(m.exports.default)).map(m => m.exports.default);
-- return exports.concat(expDefault);
-- }
--
-- const exports = moduleInstances.find(m => filter(m.exports));
-- if (exports) {
-- return exports.exports;
-- }
-- const expDefault = moduleInstances.find(m => m.exports.default && filter(m.exports.default));
-- if (expDefault) {
-- return expDefault.exports.default;
-- }
-- return null;
-+ * Grabs a React component by its display name
-+ * @param {string} displayName Component's display name.
-+ * @param {boolean} retry Whether or not to retry fetching if the module is not found. Each try will be delayed by 100ms and max retries is 20.
-+ * @param {boolean} forever If Replugged should try to fetch the module forever. Should be used only if you're in early stages of startup.
-+ * @returns {Promise<object>|object} The component. A promise will always be returned, unless retry is false.
-+ */
-+ function getModuleByDisplayName (displayName, retry = true, forever = false) {
-+ const res = commandHandler('getModuleByDisplayName', displayName.toLowerCase(), retry, forever);
-+ return processResult(res);
-+ }
-+
-+ function getModuleById (id) {
-+ const res = commandHandler('getModuleById', id);
-+ return processResult(res);
- }
--};
--
--module.exports = webpack;
-+
-+ let elementPointer = 0;
-+ function lookupReactReference (element) {
-+ if (!element) {
-+ return;
-+ }
-+
-+ if (!('__reactFiber$' in element)) {
-+ Object.defineProperty(element, '__reactFiber$', {
-+ get: () => {
-+ element.dataset.powercordPointer = elementPointer;
-+ const res = commandHandler('lookupReactReference', elementPointer++);
-+ element.removeAttribute('data-powercord-pointer');
-+ return deserialize(res);
-+ }
-+ });
-+ }
-+ }
-+
-+ /**
-+ * @property {ContextMenuModule} contextMenu
-+ * @property {WebpackInstance} instance
-+ */
-+ const webpack = {
-+ getModule,
-+ getAllModules,
-+ getModuleByDisplayName,
-+ require: getModuleById,
-+
-+ // Internal tape stuff
-+ __lookupReactReference: lookupReactReference,
-+
-+ /**
-+ * Initializes the injection into Webpack
-+ * @returns {Promise<void>}
-+ */
-+ async init () {
-+ delete webpack.init;
-+
-+ // Init proxy script
-+ const serializeScript = await readFile(join(__dirname, 'serialize.js'), 'utf8');
-+ const proxyScript = await readFile(join(__dirname, 'proxy.js'), 'utf8');
-+ await webFrame.executeJavaScript(`(function () { ${serializeScript} ${proxyScript} return init() }())`);
-+
-+ // Load modules pre-fetched
-+ for (const mdl in moduleFilters) {
-+ // noinspection JSUnfilteredForInLoop
-+ this[mdl] = await getModule(moduleFilters[mdl]);
-+ }
-+
-+ this.i18n = getAllModules([ 'Messages', 'getLanguages' ]).find((m) => m.Messages.ACCOUNT);
-+
-+ // Expose window stuff
-+ this.proxiedWindow = await commandHandler('getWindowProps');
-+ this.proxiedWindow.DiscordSentry = deserialize(this.proxiedWindow.DiscordSentry);
-+ this.proxiedWindow.__SENTRY__ = deserialize(this.proxiedWindow.__SENTRY__);
-+ this.proxiedWindow._ = deserialize(this.proxiedWindow._);
-+ }
-+ };
-+
-+ contextBridge.exposeInMainWorld('__$$WebpackProxyIPC', {
-+ freePointer: (ptr) => freePointer(ptr),
-+ registerCommandHandler: (h) => {
-+ if (commandHandler) {
-+ throw new Error('no');
-+ }
-+
-+ commandHandler = h;
-+ setCommandHandler(h);
-+ }
-+ });
-+
-+ console.inspect = function (obj) {
-+ if ('__$$pointer' in obj) {
-+ commandHandler('inspect', obj.__$$pointer);
-+ return;
-+ }
-+
-+ console.log(obj);
-+ };
-+
-+ const remoteUrls = new Set();
-+ const cou = URL.createObjectURL;
-+ const rou = URL.revokeObjectURL;
-+ URL.createObjectURL = function (blob) {
-+ if ('__$$pointer' in blob) {
-+ const url = commandHandler('createUrlObject', blob.__$$pointer);
-+ remoteUrls.add(url);
-+ return url;
-+ }
-+
-+ return cou.call(URL, blob);
-+ };
-+
-+ URL.revokeObjectURL = function (url) {
-+ if (remoteUrls.has(url)) {
-+ remoteUrls.delete(url);
-+ webFrame.executeJavaScript(`URL.revokeObjectURL(${JSON.stringify(url)})`);
-+ return;
-+ }
-+
-+ rou.call(URL, url);
-+ };
-+
-+ module.exports = webpack;
-+
-\ No newline at end of file
-diff --git a/src/fake_node_modules/powercord/webpack/proxy.js b/src/fake_node_modules/powercord/webpack/proxy.js
-new file mode 100644
-index 00000000..50f3f972
---- /dev/null
-+++ b/src/fake_node_modules/powercord/webpack/proxy.js
-@@ -0,0 +1,318 @@
-+/* global serialize, deserialize */
-+/* global readPointer, freePointer */
-+/* global __$$WebpackProxyIPC */
-+
-+const LOCAL = Symbol('powercord.webpack.local');
-+const KEY = Symbol('powercord.webpack.key');
-+
-+// --
-+// Initialization & globals
-+// --
-+const webpackInstance = {};
-+const cache = {};
-+// eslint-disable-next-line no-unused-vars
-+async function init () {
-+ while (!window.webpackChunkdiscord_app || !window._) {
-+ await new Promise((resolve) => setTimeout(resolve, 100));
-+ }
-+
-+ // Extract values from webpack
-+ webpackChunkdiscord_app.push([
-+ [ [ '_powercord' ] ],
-+ {},
-+ (r) => {
-+ webpackInstance.cache = r.c;
-+ webpackInstance.require = (m) => r(m);
-+ }
-+ ]);
-+}
-+
-+
-+// --
-+// Module fetching (+ window globals)
-+// --
-+function _getModules (filter, all) {
-+ let key;
-+ if (Array.isArray(filter)) {
-+ const keys = filter;
-+ filter = (m) => keys.every((k) => m.hasOwnProperty(k) || (m.__proto__ && m.__proto__.hasOwnProperty(k)));
-+ key = `props:${keys.join(',')}`;
-+ } else if (!filter[LOCAL]) {
-+ const _filter = filter;
-+ filter = (m) => _filter(serialize(m));
-+ } else {
-+ key = filter[KEY];
-+ }
-+
-+ if (!all && cache[key]) {
-+ return cache[key];
-+ }
-+
-+ const moduleInstances = Object.values(webpackInstance.cache).filter((m) => m.exports);
-+ if (all) {
-+ const exports = moduleInstances.filter((m) => filter(m.exports)).map((m) => [ m.i, m.exports ]);
-+ const expDefault = moduleInstances.filter((m) => m.exports.default && filter(m.exports.default)).map((m) => [ m.i, m.exports.default ]);
-+ return exports.concat(expDefault);
-+ }
-+
-+ const exports = moduleInstances.find((m) => filter(m.exports));
-+ if (exports) {
-+ if (key) {
-+ cache[key] = [ exports.i, exports.exports ];
-+ }
-+
-+ return [ exports.i, exports.exports ];
-+ }
-+
-+ const expDefault = moduleInstances.find((m) => m.exports.default && filter(m.exports.default));
-+ if (expDefault) {
-+ if (key) {
-+ cache[key] = [ expDefault.i, expDefault.exports.default ];
-+ }
-+
-+ return [ expDefault.i, expDefault.exports.default ];
-+ }
-+
-+ return null;
-+}
-+
-+function getModule (filter, retry, forever) {
-+ if (!retry) {
-+ return _getModules(filter);
-+ }
-+
-+ return new Promise(async (res) => {
-+ let mdl;
-+ for (let i = 0; i < (forever ? 666 : 21); i++) {
-+ mdl = _getModules(filter);
-+ if (mdl) {
-+ return res(mdl);
-+ }
-+
-+ await new Promise((resolve) => setTimeout(resolve, 100));
-+ }
-+
-+ res(null);
-+ });
-+}
-+
-+function getModuleByDisplayName (displayName, retry, forever) {
-+ const filter = (m) => m.displayName?.toLowerCase() === displayName;
-+ filter[KEY] = `name:${displayName}`;
-+ filter[LOCAL] = true;
-+
-+ return getModule(filter, retry, forever);
-+}
-+
-+function getModuleByDisplayNameRaw (prop, displayName, retry, forever) {
-+ const filter = (m) => m[prop]?.displayName === displayName;
-+ filter[KEY] = `name:${prop},${displayName}`;
-+ filter[LOCAL] = true;
-+
-+ return getModule(filter, retry, forever);
-+}
-+
-+function getModuleById (id) {
-+ const mdl = webpackInstance.require(id);
-+ if (mdl) {
-+ return [ id, mdl ];
-+ }
-+}
-+
-+function getWindowProps () {
-+ return {
-+ platform: window.platform,
-+ GLOBAL_ENV: window.GLOBAL_ENV,
-+ DiscordSentry: serialize(window.DiscordSentry),
-+ __SENTRY__: serialize(window.__SENTRY__),
-+ _: serialize(window._)
-+ };
-+}
-+
-+function lookupReactReference (ptr) {
-+ const element = document.querySelector(`[data-powercord-pointer="${ptr}"]`);
-+ const key = Object.keys(element).find((k) => k.startsWith('__reactFiber') || k.startsWith('__reactInternalInstance'));
-+ const fiber = element[key];
-+ return serialize(fiber);
-+}
-+
-+
-+// --
-+// Pointer operatons (lookup, ...)
-+// --
-+function getObjectProperty (ptr, key) {
-+ const obj = readPointer(ptr);
-+ return serialize(obj[key]);
-+}
-+
-+function setObjectProperty (ptr, key, value) {
-+ const obj = readPointer(ptr);
-+ obj[key] = deserialize(value);
-+}
-+
-+function defineObjectProperty (ptr, key, desc) {
-+ const obj = readPointer(ptr);
-+ Object.defineProperty(obj, key, deserialize(desc));
-+}
-+
-+function deleteObjectProperty (ptr, key) {
-+ const obj = readPointer(ptr);
-+ delete obj[key];
-+}
-+
-+function getObjectOwnKeys (ptr) {
-+ const obj = readPointer(ptr);
-+ return Reflect.ownKeys(obj);
-+}
-+
-+function hasObjectKey (ptr, key) {
-+ const obj = readPointer(ptr);
-+ return Object.prototype.hasOwnProperty.call(obj, key);
-+}
-+
-+function getObjectPropertyDescriptor (ptr, key) {
-+ const obj = readPointer(ptr);
-+ let desc;
-+ let target = obj;
-+ while (!desc && target) {
-+ desc = Object.getOwnPropertyDescriptor(target, key);
-+ target = Object.getPrototypeOf(target);
-+ }
-+
-+ if (!desc) {
-+ return void 0;
-+ }
-+
-+ const res = {
-+ configurable: desc.configurable,
-+ enumerable: desc.enumerable,
-+ writable: desc.writable
-+ };
-+
-+ if ('value' in desc) {
-+ res.value = serialize(desc.value);
-+ }
-+
-+ if ('get' in desc) {
-+ res.get = serialize(desc.get);
-+ }
-+
-+ if ('set' in desc) {
-+ res.set = serialize(desc.set);
-+ }
-+
-+ return res;
-+}
-+
-+function invokeFunction (ptr, thisArg, args) {
-+ const fn = readPointer(ptr);
-+ const res = fn.call(deserialize(thisArg), ...deserialize(args));
-+ return serialize(res);
-+}
-+
-+function instantiateClass (ptr, args) {
-+ const Klass = readPointer(ptr);
-+ const instance = new Klass(...deserialize(args));
-+ return serialize(instance);
-+}
-+
-+function performArrayOperation (op, ptr, args) {
-+ const array = readPointer(ptr);
-+ if (op === 'set') {
-+ array[args[0]] = deserialize(args[1]);
-+ return;
-+ }
-+
-+ array[op](...deserialize(args));
-+}
-+
-+
-+// --
-+// Entry point
-+// --
-+function _serializeModuleRes (res, all) {
-+ if (!res) {
-+ return res;
-+ }
-+
-+ if (res instanceof Promise) {
-+ return res.then((r) => _serializeModuleRes(r, all));
-+ }
-+
-+ if (all) {
-+ return res.map((m) => _serializeModuleRes(m));
-+ }
-+
-+ return [ res[0], serialize(res[1]) ];
-+}
-+
-+function commandHandler (cmd, ...args) {
-+ switch (cmd) {
-+ case 'getModule':
-+ return _serializeModuleRes(getModule(args[0], args[1], args[2]));
-+ case 'getModuleByDisplayName':
-+ return _serializeModuleRes(getModuleByDisplayName(args[0], args[1], args[2]));
-+ case 'getModuleByDisplayNameRaw':
-+ return _serializeModuleRes(getModuleByDisplayNameRaw(args[0], args[1], args[2], args[3]));
-+ case 'getModuleById':
-+ return _serializeModuleRes(getModuleById(args[0]));
-+ case 'getAllModules':
-+ return _serializeModuleRes(_getModules(args[0], true), true);
-+ case 'getWindowProps':
-+ return getWindowProps();
-+
-+ case 'lookupReactReference':
-+ return lookupReactReference(args[0]);
-+
-+ case 'getObjectProperty':
-+ return getObjectProperty(args[0], args[1]);
-+ case 'setObjectProperty':
-+ return setObjectProperty(args[0], args[1], args[2]);
-+ case 'defineObjectProperty':
-+ return defineObjectProperty(args[0], args[1], args[2]);
-+ case 'deleteObjectProperty':
-+ return deleteObjectProperty(args[0], args[1]);
-+ case 'hasObjectKey':
-+ return hasObjectKey(args[0], args[1]);
-+ case 'getObjectOwnKeys':
-+ return getObjectOwnKeys(args[0]);
-+ case 'getObjectPropertyDescriptor':
-+ return getObjectPropertyDescriptor(args[0], args[1]);
-+
-+ case 'invokeFunction':
-+ return invokeFunction(args[0], args[1], args[2]);
-+ case 'instantiateClass':
-+ return instantiateClass(args[0], args[1]);
-+ case 'performArrayOperation':
-+ return performArrayOperation(args[0], args[1], args[2]);
-+
-+ case 'releasePointer':
-+ return freePointer(args[0]);
-+ case 'inspect':
-+ return console.log(readPointer(args[0]));
-+
-+ case 'createUrlObject':
-+ return URL.createObjectURL(readPointer(args[0]));
-+ }
-+
-+ console.log(cmd, args);
-+}
-+
-+__$$WebpackProxyIPC.registerCommandHandler(commandHandler);
-+// eslint-disable-next-line no-undef
-+_commandHandler = commandHandler;
-+
-+const mkfn = (fn) => (...args) => {
-+ if (typeof args[0] === 'function') {
-+ args[0][LOCAL] = true;
-+ }
-+
-+ return fn(...args)?.[1];
-+};
-+
-+window.$PowercordWebpack = {
-+ getModule: mkfn(getModule),
-+ getAllModules: mkfn((a) => _getModules(a, true)),
-+ getModuleByDisplayName: mkfn((a, b, c) => getModuleByDisplayName(a.toLowerCase(), b, c)),
-+ require: mkfn(getModuleById)
-+};
-diff --git a/src/fake_node_modules/powercord/webpack/serialize.js b/src/fake_node_modules/powercord/webpack/serialize.js
-new file mode 100644
-index 00000000..6f24e410
---- /dev/null
-+++ b/src/fake_node_modules/powercord/webpack/serialize.js
-@@ -0,0 +1,906 @@
-+/* global FinalizationRegistry, WeakRef, __$$WebpackProxyIPC */
-+
-+const EXPOSE_DEBUGGING_HELPER = false;
-+const PTR_MARKER = Symbol.for('powercord.serialize.pointer-marker');
-+const FUNCTION_ID = Symbol.for('powercord.serialize.function-id');
-+const MODULE_ID = Symbol.for('powercord.webpack.module-id');
-+const isMainWorld = typeof require === 'undefined';
-+let _commandHandler = () => void 0;
-+
-+// --
-+// Memory management
-+// MAIN WORLD SIDE
-+// --
-+let ptr = 0;
-+const memorySpace = new Map();
-+const pointerMap = new WeakMap();
-+const mainWorldPointers = new WeakMap();
-+
-+const pointerCache = new Map();
-+const functionCache = new Map();
-+
-+function allocatePointer (obj) {
-+ if (!pointerMap.has(obj)) {
-+ memorySpace.set(ptr, obj);
-+ pointerMap.set(obj, ptr++);
-+ }
-+
-+ return pointerMap.get(obj);
-+}
-+
-+function freePointer (ptr) {
-+ pointerMap.delete(memorySpace.get(ptr));
-+ memorySpace.delete(ptr);
-+ pointerCache.delete(ptr);
-+}
-+
-+function readPointer (ptr) {
-+ return memorySpace.get(ptr);
-+}
-+
-+
-+// --
-+// Memory management
-+// RENDERER WORLD SIDE
-+// --
-+const usedPointers = {};
-+const localPointerProperties = {};
-+const registry = new FinalizationRegistry((ptr) => {
-+ usedPointers[ptr]--;
-+ if (usedPointers[ptr] === 0) {
-+ delete usedPointers[ptr];
-+ pointerCache.delete(ptr);
-+ if (ptr in localPointerProperties) {
-+ delete localPointerProperties[ptr];
-+ }
-+
-+ if (isMainWorld) {
-+ __$$WebpackProxyIPC.freePointer(ptr);
-+ } else {
-+ _commandHandler('releasePointer', ptr);
-+ }
-+ }
-+});
-+
-+function usePointer (obj, ptr) {
-+ usedPointers[ptr] = (usedPointers[ptr] || 0) + 1;
-+ // if (usedPointers[ptr] > 1 && typeof ptr !== 'number') console.log('?????????');
-+ registry.register(obj, ptr);
-+}
-+
-+function cachePointer (ptr, val) {
-+ pointerCache.set(ptr, new WeakRef(val));
-+}
-+
-+function getCachedPointer (ptr) {
-+ return pointerCache.get(ptr)?.deref();
-+}
-+
-+function cacheFunction (ptr, val) {
-+ functionCache.set(ptr, new WeakRef(val));
-+}
-+
-+function getCachedFunction (ptr) {
-+ return functionCache.get(ptr)?.deref();
-+}
-+
-+
-+// --
-+// Real job
-+// --
-+function isCloneable (obj) {
-+ if (obj === null || obj === void 0) {
-+ return true;
-+ }
-+
-+ // Ref: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
-+ const type = typeof obj;
-+ if (type === 'object') {
-+ return obj instanceof Date ||
-+ obj instanceof RegExp ||
-+ obj instanceof Blob ||
-+ obj instanceof File ||
-+ obj instanceof FileList ||
-+ obj instanceof ArrayBuffer ||
-+ obj instanceof ImageBitmap ||
-+ obj instanceof ImageData;
-+ }
-+
-+ return type === 'boolean' ||
-+ type === 'string' ||
-+ type === 'number' ||
-+ type === 'bigint';
-+}
-+
-+let fnRefId = 0;
-+let classRefId = 0;
-+const classMap = new WeakMap();
-+let htmlSerialId = isMainWorld ? 0 : 1;
-+
-+function _serializeObjectData (obj, seen) {
-+ const res = {};
-+ let target = obj;
-+ while (target && target !== Object.prototype) {
-+ for (const key of Reflect.ownKeys(target)) {
-+ if (key in res || (typeof key === 'string' && key.startsWith('__$$'))) {
-+ continue;
-+ }
-+
-+ const desc = Reflect.getOwnPropertyDescriptor(target, key);
-+ if ('value' in desc) {
-+ // eslint-disable-next-line no-use-before-define
-+ res[key] = serialize(target[key], seen, false);
-+ } else if ('get' in desc) {
-+ const fakeDesc = {
-+ configurable: desc.configurable,
-+ enumerable: desc.enumerable,
-+ // eslint-disable-next-line no-use-before-define
-+ get: () => serialize(target[key])
-+ };
-+
-+ res[key] = {
-+ $$type: 'desc',
-+ desc: fakeDesc
-+ };
-+ }
-+ }
-+
-+ target = Reflect.getPrototypeOf(target);
-+ }
-+
-+ return res;
-+}
-+
-+function serialize (obj, seen = new WeakMap()) {
-+ if (isCloneable(obj)) {
-+ return obj;
-+ }
-+
-+ if (typeof obj === 'symbol') {
-+ return {
-+ $$type: '$symbol',
-+ value: Symbol.keyFor(obj)
-+ };
-+ }
-+
-+ if (obj instanceof Promise) {
-+ return obj.then((v) => serialize(v));
-+ }
-+
-+ if (obj === window) {
-+ return { $$type: '$window' };
-+ }
-+
-+ if (obj === document) {
-+ return { $$type: '$document' };
-+ }
-+
-+ if (obj instanceof Element) {
-+ obj.dataset.powercordSerializeId = htmlSerialId;
-+ const ptr = htmlSerialId;
-+ htmlSerialId += 2;
-+ return {
-+ $$type: '$html',
-+ ptr
-+ };
-+ }
-+
-+ if (mainWorldPointers.has(obj)) {
-+ return {
-+ $$type: '$pointerRender',
-+ ptr: mainWorldPointers.get(obj)
-+ };
-+ }
-+
-+ if (isMainWorld && !obj.__$$pure) {
-+ const ptr = allocatePointer(obj);
-+ if (Array.isArray(obj)) {
-+ return {
-+ $$type: '$array',
-+ data: obj.map((v) => serialize(v, seen)),
-+ ptr
-+ };
-+ }
-+
-+ const type = typeof obj === 'function'
-+ ? obj.prototype && Object.keys(obj.prototype).length ? 'class' : 'function'
-+ : 'object';
-+
-+ return {
-+ $$type: '$pointer',
-+ ptr,
-+ type
-+ };
-+ }
-+
-+ if ('__$$pointer' in obj) {
-+ if (obj.__$$pointerType === 'class' && !obj.prototype.constructor.__$$props) {
-+ const serializedProto = {};
-+ for (const mth of Reflect.ownKeys(obj.prototype)) {
-+ if ([ 'constructor', '__$$remotePrototype' ].includes(mth)) {
-+ continue;
-+ }
-+
-+ serializedProto[mth] = serialize(obj.prototype[mth]);
-+ }
-+
-+ function construct (args, ptr) {
-+ obj.prototype.__$$ptr = ptr;
-+ obj.prototype.__$$marker = PTR_MARKER;
-+ // eslint-disable-next-line new-cap, no-use-before-define
-+ const instance = new obj(...deserialize(args));
-+ usePointer(instance, ptr);
-+ return serialize(instance);
-+ }
-+
-+ const ref = classMap.get(obj) ?? classRefId++;
-+ classMap.set(obj, ref);
-+ return {
-+ $$type: '$pointer',
-+ type: 'class',
-+ ptr: obj.__$$pointer,
-+ props: serializedProto,
-+ construct,
-+ ref
-+ };
-+ }
-+
-+ return {
-+ $$type: '$pointer',
-+ ptr: obj.__$$pointer
-+ };
-+ }
-+
-+ if (seen.has(obj)) {
-+ return seen.get(obj);
-+ }
-+
-+ if (Array.isArray(obj)) {
-+ const res = [];
-+ seen.set(obj, res);
-+ for (const v of obj) {
-+ res.push(serialize(v, seen));
-+ }
-+
-+ return res;
-+ }
-+
-+ if (typeof obj === 'function') {
-+ const wrapper = (...args) => {
-+ // eslint-disable-next-line no-use-before-define
-+ const preparedArgs = deserialize(args);
-+ const res = obj.call(...preparedArgs);
-+ return serialize(res);
-+ };
-+
-+ if (!(FUNCTION_ID in obj)) {
-+ obj[FUNCTION_ID] = fnRefId++;
-+ }
-+
-+ const res = {
-+ $$type: '$function',
-+ fn: wrapper,
-+ ref: obj[FUNCTION_ID],
-+ str: obj.toString()
-+ };
-+
-+ seen.set(obj, res);
-+ return res;
-+ }
-+
-+ if (obj instanceof Set) {
-+ const res = new Set();
-+ seen.set(obj, res);
-+ for (const item of obj) {
-+ res.add(serialize(item, seen));
-+ }
-+
-+ return res;
-+ }
-+
-+ if (obj instanceof Map) {
-+ const res = new Map();
-+ seen.set(obj, res);
-+ for (const k in obj) {
-+ if (k in obj) {
-+ res.set(k, serialize(res[k], seen));
-+ }
-+ }
-+
-+ return res;
-+ }
-+
-+ const res = {};
-+ seen.set(obj, res);
-+ const objProto = Reflect.getPrototypeOf(obj);
-+ if (!objProto || objProto === Reflect.getPrototypeOf({})) {
-+ for (const k in obj) {
-+ if (k in obj) {
-+ res[k] = serialize(obj[k], seen);
-+ }
-+ }
-+
-+ return res;
-+ }
-+
-+ if (!isMainWorld) {
-+ res.__$$pointerRender = allocatePointer(obj);
-+ res.getData = () => _serializeObjectData(obj);
-+ } else {
-+ Object.assign(res, _serializeObjectData(obj));
-+ }
-+
-+ return res;
-+}
-+
-+const pointerProxyHandler = {
-+ get: (target, key) => {
-+ const props = target.__$$props || target;
-+ if (key === '__$$pointer') {
-+ return props.ptr;
-+ }
-+
-+ if (key === '__$$pointerType') {
-+ return props.type;
-+ }
-+
-+ if (key === 'prototype') {
-+ if (target.prototype) {
-+ const remote = _commandHandler('getObjectProperty', props.ptr, 'prototype');
-+ // eslint-disable-next-line no-use-before-define
-+ target.prototype.__$$remotePrototype = deserialize(remote);
-+ }
-+
-+ return target.prototype;
-+ }
-+
-+ if (key === 'remotePrototype') {
-+ key = 'prototype';
-+ }
-+
-+ if (typeof target === 'function' && [ 'bind', 'call', 'apply' ].includes(key)) {
-+ return target[key];
-+ }
-+
-+ if (props.ptr in localPointerProperties && key in localPointerProperties[props.ptr]) {
-+ return localPointerProperties[props.ptr][key];
-+ }
-+
-+ const res = _commandHandler('getObjectProperty', props.ptr, key);
-+ // eslint-disable-next-line no-use-before-define
-+ return deserialize(res);
-+ },
-+ set: (target, key, value) => {
-+ const props = target.__$$props || target;
-+ if (!localPointerProperties[props.ptr]) {
-+ localPointerProperties[props.ptr] = Object.create(null);
-+ }
-+
-+ if (key === MODULE_ID || (value && typeof value === 'object' && !('__$$pointer' in value))) {
-+ // Cache local objects to avoid unnecessary IPC roundtrips.
-+ if (key === MODULE_ID) {
-+ localPointerProperties[props.ptr][key] = value;
-+ }
-+ }
-+
-+ if (key === MODULE_ID) {
-+ return true;
-+ }
-+
-+ _commandHandler('setObjectProperty', props.ptr, key, serialize(value));
-+ return true;
-+ },
-+ defineProperty: (target, key, descriptor) => {
-+ const props = target.__$$props || target;
-+ _commandHandler('defineObjectProperty', props.ptr, key, serialize(descriptor));
-+ return true;
-+ },
-+ deleteProperty: (target, key) => {
-+ const props = target.__$$props || target;
-+ _commandHandler('deleteObjectProperty', props.ptr, key);
-+ return true;
-+ },
-+ has: (target, key) => {
-+ if ([ '__$$pointer', '__$$pointerType' ].includes(key)) {
-+ return true;
-+ }
-+
-+ const props = target.__$$props || target;
-+ return _commandHandler('hasObjectKey', props.ptr, key);
-+ },
-+ ownKeys: (target) => {
-+ const props = target.__$$props || target;
-+ const targetKeys = '$$type' in target ? [] : Reflect.ownKeys(target);
-+ const remoteKeys = _commandHandler('getObjectOwnKeys', props.ptr);
-+ for (const key of remoteKeys) {
-+ if (targetKeys.indexOf(key) === -1) {
-+ targetKeys.push(key);
-+ }
-+ }
-+
-+ return targetKeys;
-+ },
-+ getOwnPropertyDescriptor: (target, key) => {
-+ const props = target.__$$props || target;
-+ const targetDesc = Object.getOwnPropertyDescriptor(target, key);
-+ if (targetDesc && !targetDesc.configurable) {
-+ return targetDesc;
-+ }
-+
-+ if (!props.$$cachedDescriptors) {
-+ props.$$cachedDescriptors = Object.create(null);
-+ }
-+
-+ if (key in props.$$cachedDescriptors) {
-+ return props.$$cachedDescriptors[key];
-+ }
-+
-+ // eslint-disable-next-line no-use-before-define
-+ const desc = _commandHandler('getObjectPropertyDescriptor', props.ptr, key);
-+ if (!desc) {
-+ return void 0;
-+ }
-+
-+ const res = {
-+ configurable: true,
-+ enumerable: desc.enumerable
-+ };
-+
-+ if ('value' in desc) {
-+ res.writable = desc.writable;
-+ // eslint-disable-next-line no-use-before-define
-+ res.value = deserialize(desc.value);
-+ }
-+
-+ if ('get' in desc) {
-+ // eslint-disable-next-line no-use-before-define
-+ res.get = deserialize(desc.get);
-+ }
-+
-+ if ('set' in desc) {
-+ // eslint-disable-next-line no-use-before-define
-+ res.set = deserialize(desc.set);
-+ }
-+
-+ props.$$cachedDescriptors[key] = res;
-+ return res;
-+ },
-+ getPrototypeOf: (target) => {
-+ const props = target.__$$props || target;
-+ if (props.__$$proto) {
-+ return props.__$$proto;
-+ }
-+
-+ const res = _commandHandler('getObjectProperty', props.ptr, '__proto__');
-+ // eslint-disable-next-line no-use-before-define
-+ const dres = deserialize(res);
-+ props.__$$proto = dres;
-+ return dres;
-+ },
-+ apply: (target, thisArg, args) => {
-+ const props = target.__$$props || target;
-+ if (props.type === 'class') {
-+ // eslint-disable-next-line new-cap
-+ return new target(...args);
-+ }
-+
-+ return target.call(thisArg, ...args);
-+ }
-+};
-+
-+const classProxyHandler = {
-+ get: (target, key) => {
-+ if (key in target) {
-+ return target[key];
-+ }
-+
-+ if (key === '__$$pointer') {
-+ return target.__$$remotePtr;
-+ }
-+
-+ if (key === '__$$pointerType') {
-+ return 'object';
-+ }
-+
-+ const res = _commandHandler('getObjectProperty', target.__$$remotePtr, key);
-+ // eslint-disable-next-line no-use-before-define
-+ return deserialize(res);
-+ },
-+ set: (target, key, value) => {
-+ if (key in target || key.startsWith('__$$')) {
-+ target[key] = value;
-+ }
-+
-+ if (![ '__$$remotePtr', MODULE_ID ].includes(key)) {
-+ _commandHandler('setObjectProperty', target.__$$remotePtr, key, serialize(value));
-+ }
-+
-+ return true;
-+ },
-+ deleteProperty: (target, key) => {
-+ _commandHandler('deleteObjectProperty', target.__$$remotePtr, key);
-+ return true;
-+ },
-+ has: (target, key) => {
-+ if ([ '__$$pointer', '__$$pointerType' ].includes(key)) {
-+ return true;
-+ }
-+
-+ return _commandHandler('hasObjectKey', target.__$$remotePtr, key);
-+ },
-+ ownKeys: (target) => _commandHandler('getObjectOwnKeys', target.__$$remotePtr),
-+ getOwnPropertyDescriptor: (target, key) => {
-+ const desc = _commandHandler('getObjectPropertyDescriptor', target.__$$remotePtr, key);
-+ return {
-+ configurable: true,
-+ ...desc
-+ };
-+ }
-+};
-+
-+const arrayProxyHandler = {
-+ get: (target, key) => {
-+ if ([ 'pop', 'shift', 'push', 'unshift' ].includes(key)) {
-+ return (...args) => {
-+ _commandHandler('performArrayOperation', key, target.__$$pointer, serialize(args));
-+ return target[key](...args);
-+ };
-+ }
-+
-+ return target[key];
-+ },
-+ set: (target, key, value) => {
-+ _commandHandler('performArrayOperation', 'set', target.__$$pointer, [ key, serialize(value) ]);
-+ target[key] = value;
-+ return true;
-+ }
-+};
-+
-+const mainWorldClassMap = {};
-+function deserialize (obj, seen = new WeakMap()) {
-+ if (isCloneable(obj)) {
-+ return obj;
-+ }
-+
-+ if (obj.$$type === '$symbol') {
-+ return Symbol.for(obj.value);
-+ }
-+
-+ if (obj instanceof Promise) {
-+ return obj.then((v) => deserialize(v));
-+ }
-+
-+ if (obj.$$type === '$pointer') {
-+ if (isMainWorld) {
-+ const res = readPointer(obj.ptr);
-+ if (obj.type === 'class') {
-+ if (!mainWorldClassMap[obj.ref]) {
-+ class Klass extends res {
-+ constructor (...args) {
-+ super(...args);
-+ const ptr = allocatePointer(this);
-+ const res = obj.construct(serialize(args), ptr);
-+ Object.assign(this, deserialize(res));
-+ }
-+ }
-+
-+ for (const mth in obj.props) {
-+ if (mth in obj.props) {
-+ Klass.prototype[mth] = deserialize(obj.props[mth]);
-+ }
-+ }
-+
-+ mainWorldClassMap[obj.ref] = Klass;
-+ }
-+
-+ return mainWorldClassMap[obj.ref];
-+ }
-+
-+ return res;
-+ }
-+
-+ const { ptr } = obj;
-+ const cached = getCachedPointer(ptr);
-+ if (cached) {
-+ return cached;
-+ }
-+
-+ if (obj.type === 'function') {
-+ const props = obj;
-+ obj = function (...args) {
-+ const thisArg = serialize(this);
-+ const preparedArgs = serialize(args);
-+ const res = _commandHandler('invokeFunction', props.ptr, thisArg, preparedArgs);
-+ return deserialize(res);
-+ };
-+
-+ obj.__$$props = props;
-+ }
-+
-+ if (obj.type === 'class') {
-+ const props = obj;
-+ obj = class {
-+ constructor (...args) {
-+ if (this.__$$marker === PTR_MARKER) {
-+ // eslint-disable-next-line prefer-destructuring
-+ this.__$$remotePtr = this.__$$ptr;
-+ delete this.__$$marker;
-+ delete this.__$$ptr;
-+ } else {
-+ const preparedArgs = serialize(args);
-+ const res = _commandHandler('instantiateClass', props.ptr, preparedArgs);
-+ this.__$$remotePtr = res.ptr;
-+ }
-+
-+ const proxy = new Proxy(this, classProxyHandler);
-+ let proto = Reflect.getPrototypeOf(this);
-+ while (proto && proto !== Object.prototype) {
-+ for (const key of Reflect.ownKeys(proto)) {
-+ if ([ 'constructor', '__$$remotePrototype', '__$$remotePtr' ].includes(key)) {
-+ continue;
-+ }
-+
-+ proxy[key] = this[key];
-+ }
-+
-+ proto = Reflect.getPrototypeOf(proto);
-+ }
-+
-+ return proxy;
-+ }
-+ };
-+
-+ const prototype = deserialize(_commandHandler('getObjectProperty', props.ptr, 'prototype'));
-+ for (const mth of Reflect.ownKeys(prototype)) {
-+ if ([ 'constructor', '__$$remotePrototype' ].includes(mth)) {
-+ continue;
-+ }
-+
-+ if (!(mth in prototype)) {
-+ continue;
-+ }
-+
-+ Object.defineProperty(obj.prototype, mth, {
-+ configurable: true,
-+ enumerable: true,
-+ get: () => {
-+ const val = prototype[mth];
-+ if (typeof val === 'function') {
-+ const fn = function (...args) {
-+ const preparedArgs = serialize(args);
-+ const res = _commandHandler('invokeFunction', val.__$$pointer, serialize(this), preparedArgs);
-+ return deserialize(res);
-+ };
-+
-+ fn.toString = val.toString.bind(val);
-+ return fn;
-+ }
-+
-+ return val;
-+ },
-+ set: (val) => {
-+ if ('set' in Object.getOwnPropertyDescriptor(prototype, mth)) {
-+ prototype[mth] = val;
-+ }
-+ }
-+ });
-+ }
-+
-+ obj.__$$props = props;
-+ obj.__$$isRemote = true;
-+ }
-+
-+ const proxy = new Proxy(obj, pointerProxyHandler);
-+ cachePointer(ptr, proxy);
-+ usePointer(proxy, ptr);
-+ return proxy;
-+ }
-+
-+ if (obj.$$type === '$pointerRender') {
-+ return readPointer(obj.ptr);
-+ }
-+
-+ if (obj.$$type === '$array') {
-+ const { ptr } = obj;
-+ const cached = getCachedPointer(ptr);
-+ if (cached) {
-+ return cached;
-+ }
-+
-+ const res = obj.data.map((v) => deserialize(v, seen));
-+ res.__$$pointer = obj.ptr;
-+
-+ const proxy = new Proxy(res, arrayProxyHandler);
-+ cachePointer(ptr, proxy);
-+ usePointer(proxy, ptr);
-+ return proxy;
-+ }
-+
-+ if (obj.$$type === '$window') {
-+ return window;
-+ }
-+
-+ if (obj.$$type === '$document') {
-+ return document;
-+ }
-+
-+ if (obj.$$type === '$html') {
-+ const element = document.querySelector(`[data-powercord-serialize-id="${obj.ptr}"]`);
-+ element.removeAttribute('data-powercord-serialize-id');
-+ return element;
-+ }
-+
-+ if (obj.$$type === '$function') {
-+ const cached = getCachedFunction(obj.ref);
-+ if (cached) {
-+ return cached;
-+ }
-+
-+ const { fn, str } = obj;
-+ const wrapper = function (...args) {
-+ const thisArg = serialize(this);
-+ const preparedArgs = args.map((arg) => serialize(arg));
-+ const res = fn(thisArg, ...preparedArgs);
-+ return deserialize(res);
-+ };
-+
-+ wrapper.toString = () => str;
-+ cacheFunction(obj.ref, wrapper);
-+ return wrapper;
-+ }
-+
-+ if (typeof obj === 'function') {
-+ return function (...args) {
-+ const thisArg = serialize(this);
-+ const preparedArgs = args.map((arg) => serialize(arg));
-+ const res = obj(thisArg, ...preparedArgs);
-+ return deserialize(res);
-+ };
-+ }
-+
-+ if (Array.isArray(obj)) {
-+ const res = [];
-+ seen.set(obj, res);
-+ for (const v of obj) {
-+ res.push(deserialize(v, seen));
-+ }
-+
-+ Object.defineProperty(res, '__$$pure', {
-+ enumerable: false,
-+ configurable: false,
-+ writable: false,
-+ value: true
-+ });
-+
-+ return res;
-+ }
-+
-+ if (obj instanceof Set) {
-+ const res = new Set();
-+ for (const item of obj) {
-+ res.add(deserialize(item, seen));
-+ }
-+
-+ return res;
-+ }
-+
-+ if (obj instanceof Map) {
-+ const res = new Map();
-+ for (const k in obj) {
-+ if (k in obj) {
-+ res.set(k, deserialize(res[k], seen));
-+ }
-+ }
-+
-+ return res;
-+ }
-+
-+ if (seen.has(obj)) {
-+ return seen.get(obj);
-+ }
-+
-+ const res = {};
-+ let ptr = null;
-+ if (Reflect.has(obj, '__$$pointerRender')) {
-+ ptr = obj.__$$pointerRender;
-+ const cached = getCachedPointer(ptr);
-+ if (cached) {
-+ return cached;
-+ }
-+
-+ obj = obj.getData();
-+ mainWorldPointers.set(res, ptr);
-+ usePointer(res, ptr);
-+ }
-+
-+ seen.set(obj, res);
-+ for (const key of Reflect.ownKeys(obj)) {
-+ if (key === '__$$pointerRender') {
-+ continue;
-+ }
-+
-+ const val = obj[key];
-+ if (val?.$$type === 'desc') {
-+ const fakeDesc = {
-+ configurable: val.desc.configurable,
-+ enumerable: val.desc.enumerable,
-+ get: () => deserialize(val.desc.get())
-+ };
-+
-+ Object.defineProperty(res, key, fakeDesc);
-+ }
-+
-+ res[key] = deserialize(val, seen);
-+ }
-+
-+ Object.defineProperty(res, '__$$pure', {
-+ enumerable: false,
-+ configurable: false,
-+ writable: false,
-+ value: true
-+ });
-+
-+ if (ptr !== null) {
-+ cachePointer(ptr, res);
-+ }
-+
-+ return res;
-+}
-+
-+
-+// --
-+// Exports if in renderer
-+// --
-+if (!isMainWorld) {
-+ module.exports = {
-+ serialize,
-+ deserialize,
-+ usePointer,
-+ freePointer,
-+ setCommandHandler: (h) => (_commandHandler = h)
-+ };
-+
-+ if (EXPOSE_DEBUGGING_HELPER) {
-+ let passed = [];
-+ require('electron').contextBridge.exposeInMainWorld('0$$SerializeDebuggerHelper', {
-+ pass: (v) => passed.push(deserialize(v)),
-+ get: () => passed.map((v) => serialize(v)),
-+ eq: () => passed.every((v) => v === passed[0]),
-+ log: () => console.log(passed),
-+ clear: () => passed = []
-+ });
-+
-+ window.__$$SerializeDebuggerHelper = Object.create(null);
-+ window.__$$SerializeDebuggerHelper.push = (...args) => passed.push(...args);
-+ window.__$$SerializeDebuggerHelper.get = () => [ ...passed ];
-+ window.__$$SerializeDebuggerHelper.log = () => console.log(passed);
-+ window.__$$SerializeDebuggerHelper.eq = () => passed.every((v) => v === passed[0]);
-+ window.__$$SerializeDebuggerHelper.clear = () => passed = [];
-+ Object.freeze(window.__$$SerializeDebuggerHelper);
-+ }
-+}
-+
-+if (EXPOSE_DEBUGGING_HELPER) {
-+ if (isMainWorld) {
-+ window.__$$SerializeDebuggerHelper = Object.create(null);
-+ window.__$$SerializeDebuggerHelper.pass = (v) => window['0$$SerializeDebuggerHelper'].pass(serialize(v));
-+ window.__$$SerializeDebuggerHelper.get = () => window['0$$SerializeDebuggerHelper'].get().map((v) => deserialize(v));
-+ window.__$$SerializeDebuggerHelper.eq = () => window['0$$SerializeDebuggerHelper'].eq();
-+ window.__$$SerializeDebuggerHelper.log = () => window['0$$SerializeDebuggerHelper'].log();
-+ window.__$$SerializeDebuggerHelper.clear = () => window['0$$SerializeDebuggerHelper'].clear();
-+ window.__$$SerializeDebuggerHelper.leq = () => {
-+ const val = window.__$$SerializeDebuggerHelper.get();
-+ return val.every((v) => v === val[0]);
-+ };
-+
-+ Object.freeze(window.__$$SerializeDebuggerHelper);
-+ }
-+
-+ window.__$$SerializeMemoryArea = Object.create(null);
-+ window.__$$SerializeMemoryArea.memorySpace = memorySpace;
-+ window.__$$SerializeMemoryArea.usedPointers = usedPointers;
-+ window.__$$SerializeMemoryArea.localPointerProperties = localPointerProperties;
-+ window.__$$SerializeMemoryArea.pointerCache = pointerCache;
-+ window.__$$SerializeMemoryArea.functionWrappers = functionCache;
-+ Object.freeze(window.__$$SerializeMemoryArea);
-+}