{
"version": 3,
"sources": ["../scripts/build/inject/react.mjs", "../src/utils/Logger.ts", "../src/utils/margins.ts", "../src/utils/lazy.ts", "../src/utils/lazyReact.tsx", "../src/utils/patches.ts", "../src/debug/Tracer.ts", "../src/webpack/webpack.ts", "../src/webpack/common/classes.ts", "../src/webpack/common/internal.tsx", "../src/webpack/common/components.ts", "../src/webpack/common/menu.ts", "../src/webpack/common/react.ts", "../src/webpack/common/settingsStores.ts", "../src/webpack/common/stores.ts", "../src/webpack/common/types/components.d.ts", "../src/webpack/common/types/menu.d.ts", "../src/webpack/common/types/utils.d.ts", "../src/webpack/common/utils.ts", "../src/webpack/common/index.ts", "git-hash:~git-hash", "git-remote:~git-remote", "../src/utils/constants.ts", "../src/utils/misc.tsx", "../src/utils/react.tsx", "../src/components/ErrorCard.tsx", "../src/components/ErrorBoundary.tsx", "../src/components/Heart.tsx", "../src/components/DonateButton.tsx", "../src/components/Flex.tsx", "../src/utils/modal.tsx", "../src/utils/types.ts", "../src/plugins/_api/badges.tsx", "../src/plugins/_api/commands.ts", "../src/plugins/_api/contextMenu.ts", "../src/plugins/_api/memberListDecorators.ts", "../src/plugins/_api/messageAccessories.ts", "../src/plugins/_api/messageDecorations.ts", "../src/plugins/_api/messageEvents.ts", "../src/plugins/_api/messagePopover.ts", "../src/plugins/_api/notices.ts", "../src/plugins/_api/serverList.ts", "../src/plugins/_core/noTrack.ts", "../src/api/ContextMenu.ts", "../src/utils/debounce.ts", "../src/utils/localStorage.ts", "../src/utils/Queue.ts", "../src/api/Notifications/NotificationComponent.tsx", "../src/api/DataStore/index.ts", "../src/api/Styles.ts", "../node_modules/.pnpm/nanoid@4.0.2/node_modules/nanoid/index.browser.js", "../src/api/Notifications/notificationLog.tsx", "../src/api/Notifications/Notifications.tsx", "../src/api/Notifications/index.ts", "../node_modules/.pnpm/fflate@0.7.4/node_modules/fflate/esm/browser.js", "../src/utils/cloud.tsx", "../src/utils/native.ts", "../src/utils/web.ts", "../src/utils/settingsSync.ts", "../src/api/Settings.ts", "../src/utils/updater.ts", "../src/components/handleComponentFailed.ts", "../src/utils/onlyOnce.ts", "../src/components/VencordSettings/shared.tsx", "../src/components/VencordSettings/VencordTab.tsx", "../src/api/Notices.ts", "../src/components/Icons.tsx", "../src/utils/text.ts", "../src/api/Commands/commandHelpers.ts", "../src/api/Commands/types.ts", "../src/api/Commands/index.ts", "../src/components/Badge.tsx", "../src/components/PluginSettings/components/SettingBooleanComponent.tsx", "../src/components/PluginSettings/components/SettingCustomComponent.tsx", "../src/components/PluginSettings/components/SettingNumericComponent.tsx", "../src/components/PluginSettings/components/SettingSelectComponent.tsx", "../src/components/PluginSettings/components/SettingSliderComponent.tsx", "../src/components/PluginSettings/components/SettingTextComponent.tsx", "../src/components/PluginSettings/components/index.ts", "../src/utils/discord.tsx", "../src/components/PluginSettings/ContributorModal.tsx", "../src/components/PluginSettings/PluginModal.tsx", "../src/components/Switch.tsx", "../src/components/VencordSettings/AddonCard.tsx", "../src/utils/ChangeList.ts", "../src/plugins/index.ts", "../src/components/PluginSettings/index.tsx", "../src/components/VencordSettings/PluginsTab.tsx", "../src/components/Link.tsx", "../src/components/VencordSettings/ThemesTab.tsx", "../src/components/VencordSettings/UpdaterTab.tsx", "../src/components/CheckedTextInput.tsx", "../src/components/VencordSettings/CloudTab.tsx", "../src/components/VencordSettings/BackupAndRestoreTab.tsx", "../src/plugins/_core/settings.tsx", "../src/plugins/_core/supportHelper.tsx", "../src/plugins/alwaysAnimate/index.ts", "../src/plugins/alwaysTrust/index.ts", "../src/plugins/anonymiseFileNames/index.ts", "../src/plugins/arRPC.web/index.tsx", "../src/plugins/banger/index.ts", "../src/plugins/betterFolders/FolderSideBar.tsx", "../src/plugins/betterFolders/index.tsx", "../src/plugins/betterGifAltText/index.ts", "../src/plugins/betterNotes/index.tsx", "../src/plugins/betterRoleDot/index.ts", "../src/plugins/betterUploadButton/index.ts", "../src/plugins/biggerStreamPreview/webpack/stores.ts", "../src/plugins/biggerStreamPreview/index.tsx", "../src/plugins/blurNsfw/index.ts", "../src/plugins/callTimer/index.tsx", "../src/api/MessageEvents.ts", "../src/plugins/clearURLs/defaultRules.ts", "../src/plugins/clearURLs/index.ts", "../src/plugins/clientTheme/index.tsx", "../src/plugins/colorSighted/index.ts", "../src/plugins/consoleShortcuts/index.ts", "../src/plugins/copyUserURLs/index.tsx", "../src/plugins/crashHandler/index.ts", "../src/utils/guards.ts", "../src/plugins/customRPC/index.tsx", "../src/plugins/dearrow/index.tsx", "../src/plugins/decor/lib/constants.ts", "../src/plugins/decor/lib/stores/AuthorizationStore.tsx", "../src/plugins/decor/lib/api.ts", "../src/plugins/decor/lib/utils/decoration.ts", "../src/plugins/decor/lib/stores/UsersDecorationsStore.ts", "../src/plugins/decor/lib/stores/CurrentUserDecorationsStore.ts", "../src/plugins/decor/ui/index.ts", "../src/plugins/decor/ui/components/index.ts", "../src/plugins/decor/ui/components/DecorationGridCreate.tsx", "../src/plugins/decor/ui/components/DecorationGridNone.tsx", "../src/plugins/decor/ui/components/DecorationContextMenu.tsx", "../src/plugins/decor/ui/components/DecorDecorationGridDecoration.tsx", "../src/plugins/decor/ui/components/Grid.tsx", "../src/plugins/decor/ui/components/SectionedGridList.tsx", "../src/plugins/decor/ui/modals/CreateDecorationModal.tsx", "../src/plugins/decor/ui/modals/GuidelinesModal.tsx", "../src/plugins/decor/ui/modals/ChangeDecorationModal.tsx", "../src/plugins/decor/ui/components/DecorSection.tsx", "../src/plugins/decor/settings.tsx", "../src/plugins/decor/index.tsx", "../src/plugins/disableDMCallIdle/index.ts", "../src/plugins/emoteCloner/index.tsx", "../src/plugins/experiments/index.tsx", "../src/plugins/f8break/index.ts", "../src/utils/web-metadata.ts", "../src/utils/apng-canvas.js", "../src/utils/dependencies.ts", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/index.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/constants.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/stream.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/lzwEncode.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/rgb-packing.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/pnnquant2.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/color.js", "../node_modules/.pnpm/github.com+mattdesl+gifenc@64842fca317b112a8590f8fef2bf3825da8f6fe3/node_modules/gifenc/src/palettize.js", "../src/plugins/fakeNitro/index.ts", "../node_modules/.pnpm/virtual-merge@1.0.1/node_modules/virtual-merge/dist/index.mjs", "../src/plugins/fakeProfileThemes/index.tsx", "../src/plugins/favEmojiFirst/index.ts", "../src/plugins/favGifSearch/index.tsx", "../src/plugins/fixSpotifyEmbeds.desktop/index.ts", "../src/plugins/forceOwnerCrown/index.ts", "../src/plugins/friendInvites/index.ts", "managed-style:src/plugins/gameActivityToggle/style.css", "../src/plugins/gameActivityToggle/index.tsx", "../src/plugins/gifPaste/index.ts", "../src/plugins/greetStickerPicker/index.tsx", "../src/api/MessagePopover.ts", "../src/plugins/hideAttachments/index.tsx", "../src/plugins/iLoveSpam/index.ts", "../src/plugins/ignoreActivities/index.tsx", "../src/plugins/imageZoom/constants.ts", "../src/plugins/imageZoom/utils/waitFor.ts", "../src/plugins/imageZoom/components/Magnifier.tsx", "managed-style:src/plugins/imageZoom/styles.css", "../src/plugins/imageZoom/index.tsx", "../src/plugins/invisibleChat.desktop/components/DecryptionModal.tsx", "../src/plugins/invisibleChat.desktop/components/EncryptionModal.tsx", "../src/plugins/invisibleChat.desktop/index.tsx", "../src/plugins/keepCurrentChannel/index.ts", "../src/plugins/lastfm/index.tsx", "../src/plugins/loadingQuotes/index.ts", "../src/plugins/memberCount/index.tsx", "../src/plugins/messageClickActions/index.ts", "../src/api/MessageAccessories.ts", "../src/plugins/messageLinkEmbeds/index.tsx", "managed-style:src/plugins/messageLogger/deleteStyleOverlay.css", "managed-style:src/plugins/messageLogger/deleteStyleText.css", "../src/plugins/messageLogger/index.tsx", "../src/plugins/messageTags/index.ts", "../src/plugins/moreCommands/index.ts", "../src/plugins/moreKaomoji/index.ts", "../src/plugins/moreUserTags/index.tsx", "../src/plugins/moyai/index.ts", "../src/plugins/muteNewGuild/index.tsx", "../src/plugins/mutualGroupDMs/index.tsx", "../src/plugins/noBlockedMessages/index.ts", "../src/plugins/noDevtoolsWarning/index.ts", "../src/plugins/noF1/index.ts", "managed-style:src/plugins/noMosaic/styles.css", "../src/plugins/noMosaic/index.ts", "../src/plugins/noPendingCount/index.ts", "../src/plugins/noProfileThemes/index.ts", "../src/plugins/noReplyMention/index.tsx", "../src/plugins/noScreensharePreview/index.ts", "../src/plugins/noTypingAnimation/index.ts", "../src/plugins/noUnblockToJump/index.ts", "../src/plugins/normalizeMessageLinks/index.ts", "../src/plugins/notificationVolume/index.ts", "../src/plugins/nsfwGateBypass/index.ts", "../src/plugins/onePingPerDM/index.ts", "../src/plugins/oneko/index.ts", "../src/plugins/openInApp/index.ts", "../src/plugins/partyMode/index.ts", "../src/plugins/permissionFreeWill/index.ts", "../src/plugins/permissionsViewer/utils.ts", "../src/plugins/permissionsViewer/components/icons.tsx", "../src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx", "../src/components/ExpandableHeader.tsx", "../src/plugins/permissionsViewer/components/UserPermissions.tsx", "../src/plugins/permissionsViewer/index.tsx", "../src/plugins/petpet/index.ts", "../src/plugins/pictureInPicture/index.tsx", "../src/plugins/pinDms/settings.ts", "../src/plugins/pinDms/contextMenus.tsx", "../src/plugins/pinDms/index.tsx", "../src/plugins/plainFolderIcon/index.ts", "../src/api/MemberListDecorators.ts", "../src/api/MessageDecorations.ts", "../src/plugins/platformIndicators/index.tsx", "../src/plugins/previewMessage/index.tsx", "../src/plugins/pronoundb/components/PronounsAboutComponent.tsx", "../src/plugins/pronoundb/settings.ts", "../src/plugins/pronoundb/types.ts", "../src/plugins/pronoundb/pronoundbUtils.ts", "../src/plugins/pronoundb/components/PronounsChatComponent.tsx", "../src/plugins/pronoundb/index.ts", "../src/plugins/quickMention/index.tsx", "../src/plugins/quickReply/index.ts", "../src/plugins/reactErrorDecoder/index.ts", "../src/api/ServerList.ts", "../src/plugins/readAllNotificationsButton/index.tsx", "../src/plugins/relationshipNotifier/settings.ts", "../src/plugins/relationshipNotifier/types.ts", "../src/plugins/relationshipNotifier/utils.ts", "../src/plugins/relationshipNotifier/functions.ts", "../src/plugins/relationshipNotifier/index.ts", "../src/plugins/revealAllSpoilers/index.ts", "../src/plugins/reverseImageSearch/index.tsx", "../src/plugins/roleColorEverywhere/index.tsx", "../src/plugins/searchReply/index.tsx", "../src/plugins/secretRingTone/index.ts", "../src/plugins/sendTimestamps/index.tsx", "../src/plugins/serverListIndicators/index.tsx", "../src/plugins/serverProfile/GuildProfileModal.tsx", "../src/plugins/serverProfile/index.tsx", "include-file:~fileContent/previewExample.tsx", "../node_modules/.pnpm/eventemitter3@4.0.7/node_modules/eventemitter3/index.js", "../node_modules/.pnpm/@vap+core@0.0.12/node_modules/@vap/core/ipc/channel.js", "../node_modules/.pnpm/@vap+core@0.0.12/node_modules/@vap/core/ipc/rpc.js", "../node_modules/.pnpm/@vap+core@0.0.12/node_modules/@vap/core/ipc/worker.js", "../node_modules/.pnpm/@vap+core@0.0.12/node_modules/@vap/core/ipc/index.js", "../src/plugins/shikiCodeblocks.desktop/hooks/useTheme.ts", "../src/plugins/shikiCodeblocks.desktop/api/languages.ts", "../src/plugins/shikiCodeblocks.desktop/api/themes.ts", "../src/plugins/shikiCodeblocks.desktop/api/shiki.ts", "managed-style:src/plugins/shikiCodeblocks.desktop/devicon.css", "../src/plugins/shikiCodeblocks.desktop/types.ts", "../src/plugins/shikiCodeblocks.desktop/settings.ts", "../src/plugins/shikiCodeblocks.desktop/hooks/useShikiSettings.ts", "../src/plugins/shikiCodeblocks.desktop/utils/color.ts", "../src/plugins/shikiCodeblocks.desktop/utils/misc.ts", "../src/plugins/shikiCodeblocks.desktop/hooks/useCopyCooldown.ts", "../src/plugins/shikiCodeblocks.desktop/components/CopyButton.tsx", "../src/plugins/shikiCodeblocks.desktop/components/ButtonRow.tsx", "../src/plugins/shikiCodeblocks.desktop/components/Code.tsx", "../src/plugins/shikiCodeblocks.desktop/components/Header.tsx", "../src/plugins/shikiCodeblocks.desktop/components/Highlighter.tsx", "../src/plugins/shikiCodeblocks.desktop/utils/createStyle.ts", "../src/plugins/shikiCodeblocks.desktop/index.ts", "../src/plugins/showAllMessageButtons/index.ts", "../src/plugins/showConnections/VerifiedIcon.tsx", "../src/plugins/showConnections/index.tsx", "../src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx", "../src/plugins/showHiddenChannels/index.tsx", "../src/plugins/showMeYourName/index.tsx", "../src/plugins/showTimeouts/index.ts", "../src/plugins/silentMessageToggle/index.tsx", "../src/plugins/silentTyping/index.tsx", "../src/plugins/sortFriendRequests/index.tsx", "managed-style:src/plugins/spotifyControls/hoverOnly.css", "../src/plugins/spotifyControls/SpotifyStore.ts", "../src/plugins/spotifyControls/PlayerComponent.tsx", "../src/plugins/spotifyControls/index.tsx", "../src/plugins/spotifyCrack/index.ts", "../src/plugins/spotifyShareCommands/index.ts", "../src/plugins/startupTimings/StartupTimingPage.tsx", "../src/plugins/startupTimings/index.tsx", "../src/plugins/superReactionTweaks/index.ts", "../src/plugins/textReplace/index.tsx", "../src/plugins/themeAttributes/index.ts", "../src/plugins/timeBarAllActivities/index.ts", "../src/plugins/translate/settings.ts", "../src/plugins/translate/languages.ts", "../src/plugins/translate/utils.ts", "../src/plugins/translate/TranslateModal.tsx", "../src/plugins/translate/TranslateIcon.tsx", "../src/plugins/translate/TranslationAccessory.tsx", "../src/plugins/translate/index.tsx", "../src/plugins/typingTweaks/index.tsx", "../src/plugins/typingIndicator/index.tsx", "../src/plugins/unindent/index.ts", "../src/plugins/unsuppressEmbeds/index.tsx", "../src/plugins/urbanDictionary/index.ts", "../src/plugins/userVoiceShow/components/VoiceChannelSection.tsx", "../src/plugins/userVoiceShow/index.tsx", "managed-style:src/plugins/usrbg/index.css", "../src/plugins/usrbg/index.tsx", "../src/plugins/validUser/index.tsx", "../src/plugins/vcDoubleClick/index.ts", "../src/plugins/vcNarrator/index.tsx", "../src/plugins/vencordToolbox/index.tsx", "../src/plugins/viewIcons/index.tsx", "../src/components/CodeBlock.tsx", "../src/plugins/viewRaw/index.tsx", "../src/plugins/voiceMessages/settings.ts", "../src/plugins/voiceMessages/DesktopRecorder.tsx", "../src/plugins/voiceMessages/utils.ts", "../src/plugins/voiceMessages/VoicePreview.tsx", "../src/plugins/voiceMessages/WebRecorder.tsx", "../src/plugins/voiceMessages/index.tsx", "../src/plugins/webContextMenus.web/index.ts", "../src/plugins/webKeybinds.web/index.ts", "../src/plugins/whoReacted/index.tsx", "../src/plugins/wikisearch/index.ts", "../src/plugins/xsOverlay.desktop/index.ts", "import-plugins:~plugins", "../src/api/Badges.ts", "../src/api/index.ts", "../src/Vencord.ts", "../src/utils/index.ts", "../src/utils/onceDefined.ts", "../src/utils/quickCss.ts", "../src/webpack/index.ts", "../src/webpack/patchWebpack.ts"],
"sourcesContent": ["/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nexport const VencordFragment = /* #__PURE__*/ Symbol.for(\"react.fragment\");\nexport let VencordCreateElement =\n (...args) => (VencordCreateElement = Vencord.Webpack.Common.React.createElement)(...args);\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nexport class Logger {\n /**\n * Returns the console format args for a title with the specified background colour and black text\n * @param color Background colour\n * @param title Text\n * @returns Array. Destructure this into {@link Logger}.errorCustomFmt or console.log\n *\n * @example logger.errorCustomFmt(...Logger.makeTitleElements(\"white\", \"Hello\"), \"World\");\n */\n static makeTitle(color: string, title: string): [string, ...string[]] {\n return [\"%c %c %s \", \"\", `background: ${color}; color: black; font-weight: bold; border-radius: 5px;`, title];\n }\n\n constructor(public name: string, public color: string = \"white\") { }\n\n private _log(level: \"log\" | \"error\" | \"warn\" | \"info\" | \"debug\", levelColor: string, args: any[], customFmt = \"\") {\n console[level](\n `%c Vencord %c %c ${this.name} ${customFmt}`,\n `background: ${levelColor}; color: black; font-weight: bold; border-radius: 5px;`,\n \"\",\n `background: ${this.color}; color: black; font-weight: bold; border-radius: 5px;`\n , ...args\n );\n }\n\n public log(...args: any[]) {\n this._log(\"log\", \"#a6d189\", args);\n }\n\n public info(...args: any[]) {\n this._log(\"info\", \"#a6d189\", args);\n }\n\n public error(...args: any[]) {\n this._log(\"error\", \"#e78284\", args);\n }\n\n public errorCustomFmt(fmt: string, ...args: any[]) {\n this._log(\"error\", \"#e78284\", args, fmt);\n }\n\n public warn(...args: any[]) {\n this._log(\"warn\", \"#e5c890\", args);\n }\n\n public debug(...args: any[]) {\n this._log(\"debug\", \"#eebebe\", args);\n }\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nlet styleStr = \"\";\n\nexport const Margins: Record<`${\"top\" | \"bottom\" | \"left\" | \"right\"}${8 | 16 | 20}`, string> = {} as any;\n\nfor (const dir of [\"top\", \"bottom\", \"left\", \"right\"] as const) {\n for (const size of [8, 16, 20] as const) {\n const cl = `vc-m-${dir}-${size}`;\n Margins[`${dir}${size}`] = cl;\n styleStr += `.${cl}{margin-${dir}:${size}px;}`;\n }\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", () =>\n document.head.append(Object.assign(document.createElement(\"style\"), {\n textContent: styleStr,\n id: \"vencord-margins\"\n })), { once: true });\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nexport function makeLazy(factory: () => T, attempts = 5): () => T {\n let tries = 0;\n let cache: T;\n return () => {\n if (!cache && attempts > tries++) {\n cache = factory();\n if (!cache && attempts === tries)\n console.error(\"Lazy factory failed:\", factory);\n }\n return cache;\n };\n}\n\n// Proxies demand that these properties be unmodified, so proxyLazy\n// will always return the function default for them.\nconst unconfigurable = [\"arguments\", \"caller\", \"prototype\"];\n\nconst handler: ProxyHandler = {};\n\nconst kGET = Symbol.for(\"vencord.lazy.get\");\nconst kCACHE = Symbol.for(\"vencord.lazy.cached\");\n\nfor (const method of [\n \"apply\",\n \"construct\",\n \"defineProperty\",\n \"deleteProperty\",\n \"getOwnPropertyDescriptor\",\n \"getPrototypeOf\",\n \"has\",\n \"isExtensible\",\n \"ownKeys\",\n \"preventExtensions\",\n \"set\",\n \"setPrototypeOf\"\n]) {\n handler[method] =\n (target: any, ...args: any[]) => Reflect[method](target[kGET](), ...args);\n}\n\nhandler.ownKeys = target => {\n const v = target[kGET]();\n const keys = Reflect.ownKeys(v);\n for (const key of unconfigurable) {\n if (!keys.includes(key)) keys.push(key);\n }\n return keys;\n};\n\nhandler.getOwnPropertyDescriptor = (target, p) => {\n if (typeof p === \"string\" && unconfigurable.includes(p))\n return Reflect.getOwnPropertyDescriptor(target, p);\n\n const descriptor = Reflect.getOwnPropertyDescriptor(target[kGET](), p);\n\n if (descriptor) Object.defineProperty(target, p, descriptor);\n return descriptor;\n};\n\n/**\n * Wraps the result of {@link makeLazy} in a Proxy you can consume as if it wasn't lazy.\n * On first property access, the lazy is evaluated\n * @param factory lazy factory\n * @param attempts how many times to try to evaluate the lazy before giving up\n * @returns Proxy\n *\n * Note that the example below exists already as an api, see {@link findByPropsLazy}\n * @example const mod = proxyLazy(() => findByProps(\"blah\")); console.log(mod.blah);\n */\nexport function proxyLazy(factory: () => T, attempts = 5, isChild = false): T {\n let isSameTick = true;\n if (!isChild)\n setTimeout(() => isSameTick = false, 0);\n\n let tries = 0;\n const proxyDummy = Object.assign(function () { }, {\n [kCACHE]: void 0 as T | undefined,\n [kGET]() {\n if (!proxyDummy[kCACHE] && attempts > tries++) {\n proxyDummy[kCACHE] = factory();\n if (!proxyDummy[kCACHE] && attempts === tries)\n console.error(\"Lazy factory failed:\", factory);\n }\n return proxyDummy[kCACHE];\n }\n });\n\n return new Proxy(proxyDummy, {\n ...handler,\n get(target, p, receiver) {\n // if we're still in the same tick, it means the lazy was immediately used.\n // thus, we lazy proxy the get access to make things like destructuring work as expected\n // meow here will also be a lazy\n // `const { meow } = findByPropsLazy(\"meow\");`\n if (!isChild && isSameTick)\n return proxyLazy(\n () => Reflect.get(target[kGET](), p, receiver),\n attempts,\n true\n );\n\n return Reflect.get(target[kGET](), p, receiver);\n }\n }) as any;\n}\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { ComponentType } from \"react\";\n\nimport { makeLazy } from \"./lazy\";\n\nconst NoopComponent = () => null;\n\n/**\n * A lazy component. The factory method is called on first render.\n * @param factory Function returning a Component\n * @param attempts How many times to try to get the component before giving up\n * @returns Result of factory function\n */\nexport function LazyComponent(factory: () => React.ComponentType, attempts = 5) {\n const get = makeLazy(factory, attempts);\n const LazyComponent = (props: T) => {\n const Component = get() ?? NoopComponent;\n return ;\n };\n\n LazyComponent.$$vencordInternal = get;\n\n return LazyComponent as ComponentType;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nimport { PatchReplacement, ReplaceFn } from \"./types\";\n\nexport function canonicalizeMatch(match: RegExp | string) {\n if (typeof match === \"string\") return match;\n const canonSource = match.source\n .replaceAll(\"\\\\i\", \"[A-Za-z_$][\\\\w$]*\");\n return new RegExp(canonSource, match.flags);\n}\n\nexport function canonicalizeReplace(replace: string | ReplaceFn, pluginName: string): string | ReplaceFn {\n const self = `Vencord.Plugins.plugins[${JSON.stringify(pluginName)}]`;\n\n if (typeof replace !== \"function\")\n return replace.replaceAll(\"$self\", self);\n\n return (...args) => replace(...args).replaceAll(\"$self\", self);\n}\n\nexport function canonicalizeDescriptor(descriptor: TypedPropertyDescriptor, canonicalize: (value: T) => T) {\n if (descriptor.get) {\n const original = descriptor.get;\n descriptor.get = function () {\n return canonicalize(original.call(this));\n };\n } else if (descriptor.value) {\n descriptor.value = canonicalize(descriptor.value);\n }\n return descriptor;\n}\n\nexport function canonicalizeReplacement(replacement: Pick, plugin: string) {\n const descriptors = Object.getOwnPropertyDescriptors(replacement);\n descriptors.match = canonicalizeDescriptor(descriptors.match, canonicalizeMatch);\n descriptors.replace = canonicalizeDescriptor(\n descriptors.replace,\n replace => canonicalizeReplace(replace, plugin),\n );\n Object.defineProperties(replacement, descriptors);\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nimport { Logger } from \"@utils/Logger\";\n\nif (IS_DEV) {\n var traces = {} as Record;\n var logger = new Logger(\"Tracer\", \"#FFD166\");\n}\n\nconst noop = function () { };\n\nexport const beginTrace = !IS_DEV ? noop :\n function beginTrace(name: string, ...args: any[]) {\n if (name in traces)\n throw new Error(`Trace ${name} already exists!`);\n\n traces[name] = [performance.now(), args];\n };\n\nexport const finishTrace = !IS_DEV ? noop : function finishTrace(name: string) {\n const end = performance.now();\n\n const [start, args] = traces[name];\n delete traces[name];\n\n logger.debug(`${name} took ${end - start}ms`, args);\n};\n\ntype Func = (...args: any[]) => any;\ntype TraceNameMapper = (...args: Parameters) => string;\n\nconst noopTracer =\n (name: string, f: F, mapper?: TraceNameMapper) => f;\n\nexport const traceFunction = !IS_DEV\n ? noopTracer\n : function traceFunction(name: string, f: F, mapper?: TraceNameMapper): F {\n return function (this: any, ...args: Parameters) {\n const traceName = mapper?.(...args) ?? name;\n\n beginTrace(traceName, ...arguments);\n try {\n return f.apply(this, args);\n } finally {\n finishTrace(traceName);\n }\n } as F;\n };\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2022 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nimport { proxyLazy } from \"@utils/lazy\";\nimport { LazyComponent } from \"@utils/lazyReact\";\nimport { Logger } from \"@utils/Logger\";\nimport { canonicalizeMatch } from \"@utils/patches\";\nimport type { WebpackInstance } from \"discord-types/other\";\n\nimport { traceFunction } from \"../debug/Tracer\";\n\nconst logger = new Logger(\"Webpack\");\n\nexport let _resolveReady: () => void;\n/**\n * Fired once a gateway connection to Discord has been established.\n * This indicates that the core webpack modules have been initialised\n */\nexport const onceReady = new Promise(r => _resolveReady = r);\n\nexport let wreq: WebpackInstance;\nexport let cache: WebpackInstance[\"c\"];\n\nexport type FilterFn = (mod: any) => boolean;\n\nexport const filters = {\n byProps: (...props: string[]): FilterFn =>\n props.length === 1\n ? m => m[props[0]] !== void 0\n : m => props.every(p => m[p] !== void 0),\n\n byCode: (...code: string[]): FilterFn => m => {\n if (typeof m !== \"function\") return false;\n const s = Function.prototype.toString.call(m);\n for (const c of code) {\n if (!s.includes(c)) return false;\n }\n return true;\n },\n byStoreName: (name: string): FilterFn => m =>\n m.constructor?.displayName === name,\n\n componentByCode: (...code: string[]): FilterFn => {\n const filter = filters.byCode(...code);\n return m => {\n if (filter(m)) return true;\n if (!m.$$typeof) return false;\n if (m.type) return filter(m.type); // memos\n if (m.render) return filter(m.render); // forwardRefs\n return false;\n };\n }\n};\n\nexport const subscriptions = new Map();\nexport const listeners = new Set();\n\nexport type CallbackFn = (mod: any, id: string) => void;\n\nexport function _initWebpack(instance: typeof window.webpackChunkdiscord_app) {\n if (cache !== void 0) throw \"no.\";\n\n instance.push([[Symbol(\"Vencord\")], {}, r => wreq = r]);\n instance.pop();\n if (!wreq) return false;\n\n cache = wreq.c;\n return true;\n}\n\nif (IS_DEV && IS_DISCORD_DESKTOP) {\n var devToolsOpen = false;\n // At this point in time, DiscordNative has not been exposed yet, so setImmediate is needed\n setTimeout(() => {\n DiscordNative/* just to make sure */?.window.setDevtoolsCallbacks(() => devToolsOpen = true, () => devToolsOpen = false);\n }, 0);\n}\n\nfunction handleModuleNotFound(method: string, ...filter: unknown[]) {\n const err = new Error(`webpack.${method} found no module`);\n logger.error(err, \"Filter:\", filter);\n\n // Strict behaviour in DevBuilds to fail early and make sure the issue is found\n if (IS_DEV && !devToolsOpen)\n throw err;\n}\n\n/**\n * Find the first module that matches the filter\n */\nexport const find = traceFunction(\"find\", function find(filter: FilterFn, { isIndirect = false, isWaitFor = false }: { isIndirect?: boolean; isWaitFor?: boolean; } = {}) {\n if (typeof filter !== \"function\")\n throw new Error(\"Invalid filter. Expected a function got \" + typeof filter);\n\n for (const key in cache) {\n const mod = cache[key];\n if (!mod?.exports) continue;\n\n if (filter(mod.exports)) {\n return isWaitFor ? [mod.exports, key] : mod.exports;\n }\n\n if (mod.exports.default && filter(mod.exports.default)) {\n const found = mod.exports.default;\n return isWaitFor ? [found, key] : found;\n }\n }\n\n if (!isIndirect) {\n handleModuleNotFound(\"find\", filter);\n }\n\n return isWaitFor ? [null, null] : null;\n});\n\nexport function findAll(filter: FilterFn) {\n if (typeof filter !== \"function\")\n throw new Error(\"Invalid filter. Expected a function got \" + typeof filter);\n\n const ret = [] as any[];\n for (const key in cache) {\n const mod = cache[key];\n if (!mod?.exports) continue;\n\n if (filter(mod.exports))\n ret.push(mod.exports);\n\n if (mod.exports.default && filter(mod.exports.default))\n ret.push(mod.exports.default);\n }\n\n return ret;\n}\n\n/**\n * Same as {@link find} but in bulk\n * @param filterFns Array of filters. Please note that this array will be modified in place, so if you still\n * need it afterwards, pass a copy.\n * @returns Array of results in the same order as the passed filters\n */\nexport const findBulk = traceFunction(\"findBulk\", function findBulk(...filterFns: FilterFn[]) {\n if (!Array.isArray(filterFns))\n throw new Error(\"Invalid filters. Expected function[] got \" + typeof filterFns);\n\n const { length } = filterFns;\n\n if (length === 0)\n throw new Error(\"Expected at least two filters.\");\n\n if (length === 1) {\n if (IS_DEV) {\n throw new Error(\"bulk called with only one filter. Use find\");\n }\n return find(filterFns[0]);\n }\n\n const filters = filterFns as Array;\n\n let found = 0;\n const results = Array(length);\n\n outer:\n for (const key in cache) {\n const mod = cache[key];\n if (!mod?.exports) continue;\n\n for (let j = 0; j < length; j++) {\n const filter = filters[j];\n // Already done\n if (filter === undefined) continue;\n\n if (filter(mod.exports)) {\n results[j] = mod.exports;\n filters[j] = undefined;\n if (++found === length) break outer;\n break;\n }\n\n if (mod.exports.default && filter(mod.exports.default)) {\n results[j] = mod.exports.default;\n filters[j] = undefined;\n if (++found === length) break outer;\n break;\n }\n }\n }\n\n if (found !== length) {\n const err = new Error(`Got ${length} filters, but only found ${found} modules!`);\n if (IS_DEV) {\n if (!devToolsOpen)\n // Strict behaviour in DevBuilds to fail early and make sure the issue is found\n throw err;\n } else {\n logger.warn(err);\n }\n }\n\n return results;\n});\n\n/**\n * Find the id of the first module factory that includes all the given code\n * @returns string or null\n */\nexport const findModuleId = traceFunction(\"findModuleId\", function findModuleId(...code: string[]) {\n outer:\n for (const id in wreq.m) {\n const str = wreq.m[id].toString();\n\n for (const c of code) {\n if (!str.includes(c)) continue outer;\n }\n return id;\n }\n\n const err = new Error(\"Didn't find module with code(s):\\n\" + code.join(\"\\n\"));\n if (IS_DEV) {\n if (!devToolsOpen)\n // Strict behaviour in DevBuilds to fail early and make sure the issue is found\n throw err;\n } else {\n logger.warn(err);\n }\n\n return null;\n});\n\n/**\n * Find the first module factory that includes all the given code\n * @returns The module factory or null\n */\nexport function findModuleFactory(...code: string[]) {\n const id = findModuleId(...code);\n if (!id) return null;\n\n return wreq.m[id];\n}\n\nexport const lazyWebpackSearchHistory = [] as Array<[\"find\" | \"findByProps\" | \"findByCode\" | \"findStore\" | \"findComponent\" | \"findComponentByCode\" | \"findExportedComponent\" | \"waitFor\" | \"waitForComponent\" | \"waitForStore\" | \"proxyLazyWebpack\" | \"LazyComponentWebpack\" | \"extractAndLoadChunks\", any[]]>;\n\n/**\n * This is just a wrapper around {@link proxyLazy} to make our reporter test for your webpack finds.\n *\n * Wraps the result of {@link makeLazy} in a Proxy you can consume as if it wasn't lazy.\n * On first property access, the lazy is evaluated\n * @param factory lazy factory\n * @param attempts how many times to try to evaluate the lazy before giving up\n * @returns Proxy\n *\n * Note that the example below exists already as an api, see {@link findByPropsLazy}\n * @example const mod = proxyLazy(() => findByProps(\"blah\")); console.log(mod.blah);\n */\nexport function proxyLazyWebpack(factory: () => any, attempts?: number) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"proxyLazyWebpack\", [factory]]);\n\n return proxyLazy(factory, attempts);\n}\n\n/**\n * This is just a wrapper around {@link LazyComponent} to make our reporter test for your webpack finds.\n *\n * A lazy component. The factory method is called on first render.\n * @param factory Function returning a Component\n * @param attempts How many times to try to get the component before giving up\n * @returns Result of factory function\n */\nexport function LazyComponentWebpack(factory: () => any, attempts?: number) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"LazyComponentWebpack\", [factory]]);\n\n return LazyComponent(factory, attempts);\n}\n\n/**\n * Find the first module that matches the filter, lazily\n */\nexport function findLazy(filter: FilterFn) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"find\", [filter]]);\n\n return proxyLazy(() => find(filter));\n}\n\n/**\n * Find the first module that has the specified properties\n */\nexport function findByProps(...props: string[]) {\n const res = find(filters.byProps(...props), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findByProps\", ...props);\n return res;\n}\n\n/**\n * Find the first module that has the specified properties, lazily\n */\nexport function findByPropsLazy(...props: string[]) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findByProps\", props]);\n\n return proxyLazy(() => findByProps(...props));\n}\n\n/**\n * Find the first function that includes all the given code\n */\nexport function findByCode(...code: string[]) {\n const res = find(filters.byCode(...code), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findByCode\", ...code);\n return res;\n}\n\n/**\n * Find the first function that includes all the given code, lazily\n */\nexport function findByCodeLazy(...code: string[]) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findByCode\", code]);\n\n return proxyLazy(() => findByCode(...code));\n}\n\n/**\n * Find a store by its displayName\n */\nexport function findStore(name: string) {\n const res = find(filters.byStoreName(name), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findStore\", name);\n return res;\n}\n\n/**\n * Find a store by its displayName, lazily\n */\nexport function findStoreLazy(name: string) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findStore\", [name]]);\n\n return proxyLazy(() => findStore(name));\n}\n\n/**\n * Finds the component which includes all the given code. Checks for plain components, memos and forwardRefs\n */\nexport function findComponentByCode(...code: string[]) {\n const res = find(filters.componentByCode(...code), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findComponentByCode\", ...code);\n return res;\n}\n\n/**\n * Finds the first component that matches the filter, lazily.\n */\nexport function findComponentLazy(filter: FilterFn) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findComponent\", [filter]]);\n\n\n return LazyComponent(() => {\n const res = find(filter, { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findComponent\", filter);\n return res;\n });\n}\n\n/**\n * Finds the first component that includes all the given code, lazily\n */\nexport function findComponentByCodeLazy(...code: string[]) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findComponentByCode\", code]);\n\n return LazyComponent(() => {\n const res = find(filters.componentByCode(...code), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findComponentByCode\", ...code);\n return res;\n });\n}\n\n/**\n * Finds the first component that is exported by the first prop name, lazily\n */\nexport function findExportedComponentLazy(...props: string[]) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"findExportedComponent\", props]);\n\n return LazyComponent(() => {\n const res = find(filters.byProps(...props), { isIndirect: true });\n if (!res)\n handleModuleNotFound(\"findExportedComponent\", ...props);\n return res[props[0]];\n });\n}\n\n/**\n * Extract and load chunks using their entry point\n * @param code An array of all the code the module factory containing the entry point (as of using it to load chunks) must include\n * @param matcher A RegExp that returns the entry point id as the first capture group. Defaults to a matcher that captures the first entry point found in the module factory\n */\nexport async function extractAndLoadChunks(code: string[], matcher: RegExp = /\\.el\\(\"(.+?)\"\\)(?<=(\\i)\\.el.+?)\\.then\\(\\2\\.bind\\(\\2,\"\\1\"\\)\\)/) {\n const module = findModuleFactory(...code);\n if (!module) {\n const err = new Error(\"extractAndLoadChunks: Couldn't find module factory\");\n logger.warn(err, \"Code:\", code, \"Matcher:\", matcher);\n\n return;\n }\n\n const match = module.toString().match(canonicalizeMatch(matcher));\n if (!match) {\n const err = new Error(\"extractAndLoadChunks: Couldn't find entry point id in module factory code\");\n logger.warn(err, \"Code:\", code, \"Matcher:\", matcher);\n\n // Strict behaviour in DevBuilds to fail early and make sure the issue is found\n if (IS_DEV && !devToolsOpen)\n throw err;\n\n return;\n }\n\n const [, id] = match;\n if (!id || !Number(id)) {\n const err = new Error(\"extractAndLoadChunks: Matcher didn't return a capturing group with the entry point, or the entry point returned wasn't a number\");\n logger.warn(err, \"Code:\", code, \"Matcher:\", matcher);\n\n // Strict behaviour in DevBuilds to fail early and make sure the issue is found\n if (IS_DEV && !devToolsOpen)\n throw err;\n\n return;\n }\n\n await (wreq as any).el(id);\n return wreq(id as any);\n}\n\n/**\n * This is just a wrapper around {@link extractAndLoadChunks} to make our reporter test for your webpack finds.\n *\n * Extract and load chunks using their entry point\n * @param code An array of all the code the module factory containing the entry point (as of using it to load chunks) must include\n * @param matcher A RegExp that returns the entry point id as the first capture group. Defaults to a matcher that captures the first entry point found in the module factory\n * @returns A function that loads the chunks on first call\n */\nexport function extractAndLoadChunksLazy(code: string[], matcher: RegExp = /\\.el\\(\"(.+?)\"\\)(?<=(\\i)\\.el.+?)\\.then\\(\\2\\.bind\\(\\2,\"\\1\"\\)\\)/) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"extractAndLoadChunks\", [code, matcher]]);\n\n return () => extractAndLoadChunks(code, matcher);\n}\n\n/**\n * Wait for a module that matches the provided filter to be registered,\n * then call the callback with the module as the first argument\n */\nexport function waitFor(filter: string | string[] | FilterFn, callback: CallbackFn, { isIndirect = false }: { isIndirect?: boolean; } = {}) {\n if (IS_DEV && !isIndirect) lazyWebpackSearchHistory.push([\"waitFor\", Array.isArray(filter) ? filter : [filter]]);\n\n if (typeof filter === \"string\")\n filter = filters.byProps(filter);\n else if (Array.isArray(filter))\n filter = filters.byProps(...filter);\n else if (typeof filter !== \"function\")\n throw new Error(\"filter must be a string, string[] or function, got \" + typeof filter);\n\n const [existing, id] = find(filter!, { isIndirect: true, isWaitFor: true });\n if (existing) return void callback(existing, id);\n\n subscriptions.set(filter, callback);\n}\n\nexport function addListener(callback: CallbackFn) {\n listeners.add(callback);\n}\n\nexport function removeListener(callback: CallbackFn) {\n listeners.delete(callback);\n}\n\n/**\n * Search modules by keyword. This searches the factory methods,\n * meaning you can search all sorts of things, displayName, methodName, strings somewhere in the code, etc\n * @param filters One or more strings or regexes\n * @returns Mapping of found modules\n */\nexport function search(...filters: Array) {\n const results = {} as Record;\n const factories = wreq.m;\n outer:\n for (const id in factories) {\n const factory = factories[id].original ?? factories[id];\n const str: string = factory.toString();\n for (const filter of filters) {\n if (typeof filter === \"string\" && !str.includes(filter)) continue outer;\n if (filter instanceof RegExp && !filter.test(str)) continue outer;\n }\n results[id] = factory;\n }\n\n return results;\n}\n\n/**\n * Extract a specific module by id into its own Source File. This has no effect on\n * the code, it is only useful to be able to look at a specific module without having\n * to view a massive file. extract then returns the extracted module so you can jump to it.\n * As mentioned above, note that this extracted module is not actually used,\n * so putting breakpoints or similar will have no effect.\n * @param id The id of the module to extract\n */\nexport function extract(id: string | number) {\n const mod = wreq.m[id] as Function;\n if (!mod) return null;\n\n const code = `\n// [EXTRACTED] WebpackModule${id}\n// WARNING: This module was extracted to be more easily readable.\n// This module is NOT ACTUALLY USED! This means putting breakpoints will have NO EFFECT!!\n\n0,${mod.toString()}\n//# sourceURL=ExtractedWebpackModule${id}\n`;\n const extracted = (0, eval)(code);\n return extracted as Function;\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nimport { findByPropsLazy, findLazy } from \"@webpack\";\n\nimport * as t from \"./types/classes\";\n\nexport const ModalImageClasses: t.ImageModalClasses = findLazy(m => m.image && m.modal && !m.applicationIcon);\nexport const ButtonWrapperClasses: t.ButtonWrapperClasses = findByPropsLazy(\"buttonWrapper\", \"buttonContent\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nimport { LazyComponent } from \"@utils/react\";\n\n// eslint-disable-next-line path-alias/no-relative\nimport { FilterFn, filters, lazyWebpackSearchHistory, waitFor } from \"../webpack\";\n\nexport function waitForComponent = React.ComponentType & Record>(name: string, filter: FilterFn | string | string[]): T {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"waitForComponent\", Array.isArray(filter) ? filter : [filter]]);\n\n let myValue: T = function () {\n throw new Error(`Vencord could not find the ${name} Component`);\n } as any;\n\n const lazyComponent = LazyComponent(() => myValue) as T;\n waitFor(filter, (v: any) => {\n myValue = v;\n Object.assign(lazyComponent, v);\n }, { isIndirect: true });\n\n return lazyComponent;\n}\n\nexport function waitForStore(name: string, cb: (v: any) => void) {\n if (IS_DEV) lazyWebpackSearchHistory.push([\"waitForStore\", [name]]);\n\n waitFor(filters.byStoreName(name), cb, { isIndirect: true });\n}\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\n// eslint-disable-next-line path-alias/no-relative\nimport { filters, findByPropsLazy, waitFor } from \"@webpack\";\n\nimport { waitForComponent } from \"./internal\";\nimport * as t from \"./types/components\";\n\nexport let Forms = {} as {\n FormTitle: t.FormTitle,\n FormSection: t.FormSection,\n FormDivider: t.FormDivider,\n FormText: t.FormText,\n};\n\nexport let Card: t.Card;\nexport let Button: t.Button;\nexport let Switch: t.Switch;\nexport let Tooltip: t.Tooltip;\nexport let TextInput: t.TextInput;\nexport let TextArea: t.TextArea;\nexport let Text: t.Text;\nexport let Select: t.Select;\nexport let SearchableSelect: t.SearchableSelect;\nexport let Slider: t.Slider;\nexport let ButtonLooks: t.ButtonLooks;\nexport let Popout: t.Popout;\nexport let Dialog: t.Dialog;\nexport let TabBar: any;\nexport let Paginator: t.Paginator;\nexport let ScrollerThin: t.ScrollerThin;\nexport let Clickable: t.Clickable;\nexport let Avatar: t.Avatar;\n// token lagger real\n/** css colour resolver stuff, no clue what exactly this does, just copied usage from Discord */\nexport let useToken: t.useToken;\n\nexport const MaskedLink = waitForComponent(\"MaskedLink\", m => m?.type?.toString().includes(\"MASKED_LINK)\"));\nexport const Timestamp = waitForComponent(\"Timestamp\", filters.byCode(\".Messages.MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL.format\"));\nexport const Flex = waitForComponent(\"Flex\", [\"Justify\", \"Align\", \"Wrap\"]);\n\nexport const { OAuth2AuthorizeModal } = findByPropsLazy(\"OAuth2AuthorizeModal\");\n\nwaitFor([\"FormItem\", \"Button\"], m => {\n ({ useToken, Card, Button, FormSwitch: Switch, Tooltip, TextInput, TextArea, Text, Select, SearchableSelect, Slider, ButtonLooks, TabBar, Popout, Dialog, Paginator, ScrollerThin, Clickable, Avatar } = m);\n Forms = m;\n});\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\n// eslint-disable-next-line path-alias/no-relative\nimport { findByPropsLazy, waitFor } from \"../webpack\";\nimport type * as t from \"./types/menu\";\n\nexport let Menu = {} as t.Menu;\n\nwaitFor([\"MenuItem\", \"MenuSliderControl\"], m => Menu = m);\n\nexport const ContextMenuApi: t.ContextMenuApi = findByPropsLazy(\"closeContextMenu\", \"openContextMenu\");\n\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\n// eslint-disable-next-line path-alias/no-relative\nimport { findByPropsLazy, waitFor } from \"../webpack\";\n\nexport let React: typeof import(\"react\");\nexport let useState: typeof React.useState;\nexport let useEffect: typeof React.useEffect;\nexport let useMemo: typeof React.useMemo;\nexport let useRef: typeof React.useRef;\nexport let useReducer: typeof React.useReducer;\nexport let useCallback: typeof React.useCallback;\n\nexport const ReactDOM: typeof import(\"react-dom\") & typeof import(\"react-dom/client\") = findByPropsLazy(\"createPortal\", \"render\");\n\nwaitFor(\"useState\", m => {\n React = m;\n ({ useEffect, useState, useMemo, useRef, useReducer, useCallback } = React);\n});\n", "/*\n * Vencord, a Discord client mod\n * Copyright (c) 2023 Vendicated and contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { findByPropsLazy } from \"@webpack\";\n\nexport const TextAndImagesSettingsStores = findByPropsLazy(\"MessageDisplayCompact\");\nexport const StatusSettingsStores = findByPropsLazy(\"ShowCurrentGame\");\n\nexport const UserSettingsActionCreators = findByPropsLazy(\"PreloadedUserSettingsActionCreators\");\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nimport type * as Stores from \"discord-types/stores\";\n\n// eslint-disable-next-line path-alias/no-relative\nimport { findByPropsLazy } from \"../webpack\";\nimport { waitForStore } from \"./internal\";\nimport * as t from \"./types/stores\";\n\nexport const Flux: t.Flux = findByPropsLazy(\"connectStores\");\n\nexport type GenericStore = t.FluxStore & Record;\n\nexport enum DraftType {\n ChannelMessage = 0,\n ThreadSettings = 1,\n FirstThreadMessage = 2,\n ApplicationLauncherCommand = 3\n}\n\nexport let MessageStore: Omit & {\n getMessages(chanId: string): any;\n};\n\n// this is not actually a FluxStore\nexport const PrivateChannelsStore = findByPropsLazy(\"openPrivateChannel\");\nexport let PermissionStore: GenericStore;\nexport let GuildChannelStore: GenericStore;\nexport let ReadStateStore: GenericStore;\nexport let PresenceStore: GenericStore;\nexport let PoggerModeSettingsStore: GenericStore;\n\nexport let GuildStore: Stores.GuildStore & t.FluxStore;\nexport let UserStore: Stores.UserStore & t.FluxStore;\nexport let UserProfileStore: GenericStore;\nexport let SelectedChannelStore: Stores.SelectedChannelStore & t.FluxStore;\nexport let SelectedGuildStore: t.FluxStore & Record;\nexport let ChannelStore: Stores.ChannelStore & t.FluxStore;\nexport let GuildMemberStore: Stores.GuildMemberStore & t.FluxStore;\nexport let RelationshipStore: Stores.RelationshipStore & t.FluxStore & {\n /** Get the date (as a string) that the relationship was created */\n getSince(userId: string): string;\n};\n\nexport let EmojiStore: t.EmojiStore;\nexport let WindowStore: t.WindowStore;\nexport let DraftStore: t.DraftStore;\n\n/**\n * React hook that returns stateful data for one or more stores\n * You might need a custom comparator (4th argument) if your store data is an object\n *\n * @param stores The stores to listen to\n * @param mapper A function that returns the data you need\n * @param idk some thing, idk just pass null\n * @param isEqual A custom comparator for the data returned by mapper\n *\n * @example const user = useStateFromStores([UserStore], () => UserStore.getCurrentUser(), null, (old, current) => old.id === current.id);\n */\nexport const { useStateFromStores }: {\n useStateFromStores: (\n stores: t.FluxStore[],\n mapper: () => T,\n idk?: any,\n isEqual?: (old: T, newer: T) => boolean\n ) => T;\n}\n = findByPropsLazy(\"useStateFromStores\");\n\nwaitForStore(\"DraftStore\", s => DraftStore = s);\nwaitForStore(\"UserStore\", s => UserStore = s);\nwaitForStore(\"UserProfileStore\", m => UserProfileStore = m);\nwaitForStore(\"ChannelStore\", m => ChannelStore = m);\nwaitForStore(\"SelectedChannelStore\", m => SelectedChannelStore = m);\nwaitForStore(\"SelectedGuildStore\", m => SelectedGuildStore = m);\nwaitForStore(\"GuildStore\", m => GuildStore = m);\nwaitForStore(\"GuildMemberStore\", m => GuildMemberStore = m);\nwaitForStore(\"RelationshipStore\", m => RelationshipStore = m);\nwaitForStore(\"PermissionStore\", m => PermissionStore = m);\nwaitForStore(\"PresenceStore\", m => PresenceStore = m);\nwaitForStore(\"ReadStateStore\", m => ReadStateStore = m);\nwaitForStore(\"GuildChannelStore\", m => GuildChannelStore = m);\nwaitForStore(\"MessageStore\", m => MessageStore = m);\nwaitForStore(\"WindowStore\", m => WindowStore = m);\nwaitForStore(\"EmojiStore\", m => EmojiStore = m);\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nimport type { Moment } from \"moment\";\nimport type { ComponentType, CSSProperties, FunctionComponent, HtmlHTMLAttributes, HTMLProps, KeyboardEvent, MouseEvent, PropsWithChildren, PropsWithRef, ReactNode, Ref } from \"react\";\n\nexport type TextVariant = \"heading-sm/normal\" | \"heading-sm/medium\" | \"heading-sm/semibold\" | \"heading-sm/bold\" | \"heading-md/normal\" | \"heading-md/medium\" | \"heading-md/semibold\" | \"heading-md/bold\" | \"heading-lg/normal\" | \"heading-lg/medium\" | \"heading-lg/semibold\" | \"heading-lg/bold\" | \"heading-xl/normal\" | \"heading-xl/medium\" | \"heading-xl/bold\" | \"heading-xxl/normal\" | \"heading-xxl/medium\" | \"heading-xxl/bold\" | \"eyebrow\" | \"heading-deprecated-14/normal\" | \"heading-deprecated-14/medium\" | \"heading-deprecated-14/bold\" | \"text-xxs/normal\" | \"text-xxs/medium\" | \"text-xxs/semibold\" | \"text-xxs/bold\" | \"text-xs/normal\" | \"text-xs/medium\" | \"text-xs/semibold\" | \"text-xs/bold\" | \"text-sm/normal\" | \"text-sm/medium\" | \"text-sm/semibold\" | \"text-sm/bold\" | \"text-md/normal\" | \"text-md/medium\" | \"text-md/semibold\" | \"text-md/bold\" | \"text-lg/normal\" | \"text-lg/medium\" | \"text-lg/semibold\" | \"text-lg/bold\" | \"display-sm\" | \"display-md\" | \"display-lg\" | \"code\";\nexport type FormTextTypes = Record<\"DEFAULT\" | \"INPUT_PLACEHOLDER\" | \"DESCRIPTION\" | \"LABEL_BOLD\" | \"LABEL_SELECTED\" | \"LABEL_DESCRIPTOR\" | \"ERROR\" | \"SUCCESS\", string>;\nexport type Heading = `h${1 | 2 | 3 | 4 | 5 | 6}`;\n\nexport type Margins = Record<\"marginTop16\" | \"marginTop8\" | \"marginBottom8\" | \"marginTop20\" | \"marginBottom20\", string>;\nexport type ButtonLooks = Record<\"FILLED\" | \"INVERTED\" | \"OUTLINED\" | \"LINK\" | \"BLANK\", string>;\n\nexport type TextProps = PropsWithChildren & {\n variant?: TextVariant;\n tag?: \"div\" | \"span\" | \"p\" | \"strong\" | Heading;\n selectable?: boolean;\n lineClamp?: number;\n}>;\n\nexport type Text = ComponentType;\n\nexport type FormTitle = ComponentType & PropsWithChildren<{\n /** default is h5 */\n tag?: Heading;\n faded?: boolean;\n disabled?: boolean;\n required?: boolean;\n error?: ReactNode;\n}>>;\n\nexport type FormSection = ComponentType>;\n\nexport type FormDivider = ComponentType<{\n className?: string;\n style?: CSSProperties;\n}>;\n\n\nexport type FormText = ComponentType & TextProps> & { Types: FormTextTypes; };\n\nexport type Tooltip = ComponentType<{\n text: ReactNode;\n children: FunctionComponent<{\n onClick(): void;\n onMouseEnter(): void;\n onMouseLeave(): void;\n onContextMenu(): void;\n onFocus(): void;\n onBlur(): void;\n \"aria-label\"?: string;\n }>;\n \"aria-label\"?: string;\n\n allowOverflow?: boolean;\n forceOpen?: boolean;\n hide?: boolean;\n hideOnClick?: boolean;\n shouldShow?: boolean;\n spacing?: number;\n\n /** Tooltip.Colors.BLACK */\n color?: string;\n /** TooltipPositions.TOP */\n position?: string;\n\n tooltipClassName?: string;\n tooltipContentClassName?: string;\n}> & {\n Colors: Record<\"BLACK\" | \"BRAND\" | \"CUSTOM\" | \"GREEN\" | \"GREY\" | \"PRIMARY\" | \"RED\" | \"YELLOW\", string>;\n};\n\nexport type TooltipPositions = Record<\"BOTTOM\" | \"CENTER\" | \"LEFT\" | \"RIGHT\" | \"TOP\" | \"WINDOW_CENTER\", string>;\n\nexport type Card = ComponentType & {\n editable?: boolean;\n outline?: boolean;\n /** Card.Types.PRIMARY */\n type?: string;\n}>> & {\n Types: Record<\"BRAND\" | \"CUSTOM\" | \"DANGER\" | \"PRIMARY\" | \"SUCCESS\" | \"WARNING\", string>;\n};\n\nexport type Button = ComponentType, \"size\"> & {\n /** Button.Looks.FILLED */\n look?: string;\n /** Button.Colors.BRAND */\n color?: string;\n /** Button.Sizes.MEDIUM */\n size?: string;\n /** Button.BorderColors.BLACK */\n borderColor?: string;\n\n wrapperClassName?: string;\n className?: string;\n innerClassName?: string;\n\n buttonRef?: Ref;\n focusProps?: any;\n submitting?: boolean;\n\n submittingStartedLabel?: string;\n submittingFinishedLabel?: string;\n}>> & {\n BorderColors: Record<\"BLACK\" | \"BRAND\" | \"BRAND_NEW\" | \"GREEN\" | \"LINK\" | \"PRIMARY\" | \"RED\" | \"TRANSPARENT\" | \"WHITE\" | \"YELLOW\", string>;\n Colors: Record<\"BRAND\" | \"RED\" | \"GREEN\" | \"YELLOW\" | \"PRIMARY\" | \"LINK\" | \"WHITE\" | \"BLACK\" | \"TRANSPARENT\" | \"BRAND_NEW\" | \"CUSTOM\", string>;\n Hovers: Record<\"DEFAULT\" | \"BRAND\" | \"RED\" | \"GREEN\" | \"YELLOW\" | \"PRIMARY\" | \"LINK\" | \"WHITE\" | \"BLACK\" | \"TRANSPARENT\", string>;\n Looks: Record<\"FILLED\" | \"INVERTED\" | \"OUTLINED\" | \"LINK\" | \"BLANK\", string>;\n Sizes: Record<\"NONE\" | \"TINY\" | \"SMALL\" | \"MEDIUM\" | \"LARGE\" | \"XLARGE\" | \"MIN\" | \"MAX\" | \"ICON\", string>;\n\n Link: any;\n};\n\nexport type Switch = ComponentType>;\n\nexport type Timestamp = ComponentType>;\n\nexport type TextInput = ComponentType;\n prefixElement?: ReactNode;\n\n focusProps?: any;\n\n /** TextInput.Sizes.DEFAULT */\n size?: string;\n} & Omit, \"onChange\">>> & {\n Sizes: Record<\"DEFAULT\" | \"MINI\", string>;\n};\n\nexport type TextArea = ComponentType, \"onChange\"> & {\n onChange(v: string): void;\n}>>;\n\ninterface SelectOption {\n disabled?: boolean;\n value: any;\n label: string;\n key?: React.Key;\n default?: boolean;\n}\n\nexport type Select = ComponentType; // TODO\n\n /**\n * - 0 ~ Filled\n * - 1 ~ Custom\n */\n look?: 0 | 1;\n className?: string;\n popoutClassName?: string;\n popoutPosition?: \"top\" | \"left\" | \"right\" | \"bottom\" | \"center\" | \"window_center\";\n optionClassName?: string;\n\n autoFocus?: boolean;\n isDisabled?: boolean;\n clearable?: boolean;\n closeOnSelect?: boolean;\n hideIcon?: boolean;\n\n select(value: any): void;\n isSelected(value: any): boolean;\n serialize(value: any): string;\n clear?(): void;\n\n maxVisibleItems?: number;\n popoutWidth?: number;\n\n onClose?(): void;\n onOpen?(): void;\n\n renderOptionLabel?(option: SelectOption): ReactNode;\n /** discord stupid this gets all options instead of one yeah */\n renderOptionValue?(option: SelectOption[]): ReactNode;\n\n \"aria-label\"?: boolean;\n \"aria-labelledby\"?: boolean;\n}>>;\n\nexport type SearchableSelect = ComponentType; // TODO\n value?: SelectOption;\n\n /**\n * - 0 ~ Filled\n * - 1 ~ Custom\n */\n look?: 0 | 1;\n className?: string;\n popoutClassName?: string;\n wrapperClassName?: string;\n popoutPosition?: \"top\" | \"left\" | \"right\" | \"bottom\" | \"center\" | \"window_center\";\n optionClassName?: string;\n\n autoFocus?: boolean;\n isDisabled?: boolean;\n clearable?: boolean;\n closeOnSelect?: boolean;\n clearOnSelect?: boolean;\n multi?: boolean;\n\n onChange(value: any): void;\n onSearchChange?(value: string): void;\n\n onClose?(): void;\n onOpen?(): void;\n onBlur?(): void;\n\n renderOptionPrefix?(option: SelectOption): ReactNode;\n renderOptionSuffix?(option: SelectOption): ReactNode;\n\n filter?(option: SelectOption[], query: string): SelectOption[];\n\n centerCaret?: boolean;\n debounceTime?: number;\n maxVisibleItems?: number;\n popoutWidth?: number;\n\n \"aria-labelledby\"?: boolean;\n}>>;\n\nexport type Slider = ComponentType>;\n\n// TODO - type maybe idk probably not that useful other than the constants\nexport type Flex = ComponentType> & {\n Align: Record<\"START\" | \"END\" | \"CENTER\" | \"STRETCH\" | \"BASELINE\", string>;\n Direction: Record<\"VERTICAL\" | \"HORIZONTAL\" | \"HORIZONTAL_REVERSE\", string>;\n Justify: Record<\"START\" | \"END\" | \"CENTER\" | \"BETWEEN\" | \"AROUND\", string>;\n Wrap: Record<\"NO_WRAP\" | \"WRAP\" | \"WRAP_REVERSE\", string>;\n};\n\ndeclare enum PopoutAnimation {\n NONE = \"1\",\n TRANSLATE = \"2\",\n SCALE = \"3\",\n FADE = \"4\"\n}\n\nexport type Popout = ComponentType<{\n children(\n thing: {\n \"aria-controls\": string;\n \"aria-expanded\": boolean;\n onClick(event: MouseEvent): void;\n onKeyDown(event: KeyboardEvent): void;\n onMouseDown(event: MouseEvent): void;\n },\n data: {\n isShown: boolean;\n position: string;\n }\n ): ReactNode;\n shouldShow?: boolean;\n renderPopout(args: {\n closePopout(): void;\n isPositioned: boolean;\n nudge: number;\n position: string;\n setPopoutRef(ref: any): void;\n updatePosition(): void;\n }): ReactNode;\n\n onRequestOpen?(): void;\n onRequestClose?(): void;\n\n /** \"center\" and others */\n align?: string;\n /** Popout.Animation */\n animation?: PopoutAnimation;\n autoInvert?: boolean;\n nudgeAlignIntoViewport?: boolean;\n /** \"bottom\" and others */\n position?: string;\n positionKey?: string;\n spacing?: number;\n}> & {\n Animation: typeof PopoutAnimation;\n};\n\nexport type Dialog = ComponentType>;\n\ntype Resolve = (data: { theme: \"light\" | \"dark\", saturation: number; }) => {\n hex(): string;\n hsl(): string;\n int(): number;\n spring(): string;\n};\n\nexport type useToken = (color: {\n css: string;\n resolve: Resolve;\n}) => ReturnType;\n\nexport type Paginator = ComponentType<{\n currentPage: number;\n maxVisiblePages: number;\n pageSize: number;\n totalCount: number;\n\n onPageChange?(page: number): void;\n hideMaxPage?: boolean;\n}>;\n\nexport type MaskedLink = ComponentType>;\n\nexport type ScrollerThin = ComponentType>;\n\nexport type Clickable = ComponentType>;\n\nexport type Avatar = ComponentType>;\n", "/*\n * Vencord, a modification for Discord's desktop app\n * Copyright (c) 2023 Vendicated and contributors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see .\n*/\n\nimport type { ComponentType, CSSProperties, MouseEvent, PropsWithChildren, ReactNode, UIEvent } from \"react\";\n\ntype RC = ComponentType>>;\n\nexport interface Menu {\n Menu: RC<{\n navId: string;\n onClose(): void;\n className?: string;\n style?: CSSProperties;\n hideScroller?: boolean;\n onSelect?(): void;\n }>;\n MenuSeparator: ComponentType;\n MenuGroup: RC<{\n label?: string;\n }>;\n MenuItem: RC<{\n id: string;\n label: ReactNode;\n action?(e: MouseEvent): void;\n icon?: ComponentType;\n\n color?: string;\n render?: ComponentType;\n onChildrenScroll?: Function;\n childRowHeight?: number;\n listClassName?: string;\n disabled?: boolean;\n }>;\n MenuCheckboxItem: RC<{\n id: string;\n label: string;\n checked: boolean;\n action?(e: MouseEvent): void;\n disabled?: boolean;\n }>;\n MenuRadioItem: RC<{\n id: string;\n group: string;\n label: string;\n checked: boolean;\n action?(e: MouseEvent): void;\n disabled?: boolean;\n }>;\n MenuControlItem: RC<{\n id: string;\n interactive?: boolean;\n }>;\n MenuSliderControl: RC<{\n minValue: number,\n maxValue: number,\n value: number,\n onChange(value: number): void,\n renderValue?(value: number): string,\n }>;\n}\n\nexport interface ContextMenuApi {\n closeContextMenu(): void;\n openContextMenu(\n event: UIEvent,\n render?: Menu[\"Menu\"],\n options?: { enableSpellCheck?: boolean; },\n renderLazy?: () => Promise