summarylogtreecommitdiffstats
path: root/webpack.patch
diff options
context:
space:
mode:
Diffstat (limited to 'webpack.patch')
-rw-r--r--webpack.patch1658
1 files changed, 0 insertions, 1658 deletions
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);
-+}