From ea7451bcdc7b2ed21c1dbac5e3c4f574df87f868 Mon Sep 17 00:00:00 2001 From: thororen <78185467+thororen1234@users.noreply.github.com> Date: Wed, 17 Apr 2024 14:29:47 -0400 Subject: [PATCH] forked!! --- .eslintrc.json | 168 +- .github/ISSUE_TEMPLATE/blank.yml | 2 +- .github/ISSUE_TEMPLATE/bug_report.yml | 8 +- .github/ISSUE_TEMPLATE/config.yml | 12 +- .github/workflows/build.yml | 121 +- .github/workflows/codeberg-mirror.yml | 52 +- .github/workflows/publish.yml | 45 - .github/workflows/reportBrokenPlugins.yml | 97 +- .github/workflows/test.yml | 96 +- .vscode/settings.json | 3 +- CONTRIBUTING.md | 2 +- README.md | 98 +- browser/VencordNativeStub.ts | 6 +- browser/icon.png | Bin 1091 -> 7720 bytes browser/manifest.json | 37 +- browser/manifestv2.json | 35 +- browser/monacoWin.html | 64 +- docs/1_INSTALLING.md | 40 +- docs/2_PLUGINS.md | 8 +- package.json | 30 +- patches/@types__less@3.0.6.patch | 13 + patches/eslint-plugin-path-alias@1.0.0.patch | 13 - pnpm-lock.yaml | 701 +-- scripts/build/build.mjs | 2 +- scripts/build/common.mjs | 2 +- scripts/generateReport.ts | 295 +- scripts/runInstaller.mjs | 4 +- src/Vencord.ts | 12 +- src/VencordNative.ts | 5 +- src/api/MessageEvents.ts | 2 + src/api/Settings.ts | 14 +- src/components/DonateButton.tsx | 2 +- src/components/ExpandableHeader.css | 5 +- src/components/Icons.tsx | 19 + src/components/ThemeSettings/OnlineThemes.tsx | 258 + src/components/ThemeSettings/ThemesTab.tsx | 431 ++ src/components/ThemeSettings/UserCSSModal.tsx | 114 + .../components/SettingBooleanComponent.tsx | 39 + .../components/SettingColorComponent.tsx | 56 + .../components/SettingNumberComponent.tsx | 36 + .../components/SettingRangeComponent.tsx | 56 + .../components/SettingSelectComponent.tsx | 55 + .../components/SettingTextComponent.tsx | 34 + .../ThemeSettings/components/colorStyles.css | 19 + .../ThemeSettings/components/index.ts | 12 + src/components/ThemeSettings/themesStyles.css | 47 + src/components/VencordSettings/AddonCard.tsx | 7 +- .../VencordSettings/BackupAndRestoreTab.tsx | 2 +- .../VencordSettings/PatchHelperTab.tsx | 12 +- src/components/VencordSettings/ThemesTab.tsx | 356 -- src/components/VencordSettings/UpdaterTab.tsx | 6 +- src/components/VencordSettings/VencordTab.tsx | 6 +- src/components/VencordSettings/shared.tsx | 1 - .../VencordSettings/themesStyles.css | 18 + src/equicordplugins/VCSupport/index.ts | 14 + src/equicordplugins/allCallTimers/Timer.tsx | 38 + .../allCallTimers/TimerIcon.tsx | 26 + src/equicordplugins/allCallTimers/index.tsx | 267 + .../allCallTimers/timerText.tsx | 15 + .../allowedMentions/AllowedMentions.css | 5 + .../allowedMentions/AllowedMentions.tsx | 386 ++ src/equicordplugins/allowedMentions/index.tsx | 274 + src/equicordplugins/altKrispSwitch/index.tsx | 33 + src/equicordplugins/annamox/index.ts | 106 + .../betterQuickReact/index.tsx | 84 + .../betterQuickReact/style.css | 30 + .../blockKrisp.discordDesktop/index.ts | 23 + src/equicordplugins/bypassDND/index.tsx | 149 + src/equicordplugins/cleanChannelName/index.ts | 31 + src/equicordplugins/colorMessage/index.ts | 62 + src/equicordplugins/colorMessage/style.css | 14 + .../copyEmojiAsFormattedString/index.tsx | 78 + src/equicordplugins/copyUserMention/index.tsx | 53 + .../customAppIcons/AppIconModal.tsx | 104 + src/equicordplugins/customAppIcons/index.tsx | 110 + .../customScreenShare.desktop/goofs.tsx | 45 + .../customScreenShare.desktop/index.tsx | 221 + .../customScreenShare.desktop/utils.ts | 34 + src/equicordplugins/deadMembers/index.tsx | 62 + src/equicordplugins/doNotLeak/index.ts | 89 + src/equicordplugins/doNotLeak/style.css | 50 + .../doubleCounterVerifyBypass/index.tsx | 82 + src/equicordplugins/emojiDumper/index.tsx | 68 + src/equicordplugins/encryptcord/index.tsx | 457 ++ src/equicordplugins/encryptcord/rsa-utils.tsx | 121 + src/equicordplugins/exportContacts/index.tsx | 127 + src/equicordplugins/exportContacts/styles.css | 27 + .../findReply/ReplyNavigator.tsx | 73 + src/equicordplugins/findReply/index.tsx | 133 + src/equicordplugins/findReply/styles.css | 8 + .../gifCollections/CollectionManager.ts | 112 + .../gifCollections/constants.ts | 21 + src/equicordplugins/gifCollections/index.tsx | 365 ++ src/equicordplugins/gifCollections/types.ts | 44 + .../gifCollections/utils/cleanUrl.ts | 23 + .../gifCollections/utils/getFormat.ts | 27 + .../gifCollections/utils/getGif.ts | 137 + .../gifCollections/utils/getUrlExtension.ts | 23 + .../gifCollections/utils/isAudio.ts | 27 + .../gifCollections/utils/settingsUtils.ts | 131 + .../gifCollections/utils/uuidv4.ts | 29 + src/equicordplugins/globalBadges/index.tsx | 133 + src/equicordplugins/hideMessage/EyeIcon.tsx | 14 + src/equicordplugins/hideMessage/HideIcon.tsx | 14 + .../hideMessage/HideMessageAccessory.tsx | 20 + src/equicordplugins/hideMessage/index.tsx | 163 + src/equicordplugins/hideMessage/styles.css | 21 + src/equicordplugins/holyNotes/NoteHandler.ts | 213 + .../holyNotes/components/icons/HelpIcon.tsx | 23 + .../holyNotes/components/icons/NoteButton.tsx | 17 + .../components/icons/overFlowIcon.tsx | 31 + .../holyNotes/components/modals/Error.tsx | 51 + .../holyNotes/components/modals/HelpModal.tsx | 89 + .../modals/ManageNotebookButton.tsx | 28 + .../components/modals/NoteBookTab.tsx | 185 + .../holyNotes/components/modals/Notebook.tsx | 174 + .../components/modals/NotebookCreateModal.tsx | 40 + .../components/modals/NotebookDeleteModal.tsx | 57 + .../components/modals/RenderMessage.tsx | 188 + src/equicordplugins/holyNotes/index.tsx | 132 + src/equicordplugins/holyNotes/style.css | 136 + src/equicordplugins/holyNotes/types.ts | 47 + src/equicordplugins/holyNotes/utils.ts | 106 + src/equicordplugins/hopOn/index.tsx | 48 + src/equicordplugins/iRememberYou/index.tsx | 403 ++ src/equicordplugins/ignoreTerms/index.ts | 29 + src/equicordplugins/imageLink/index.ts | 24 + src/equicordplugins/keyboardSounds/index.ts | 60 + .../keyboardSounds/sounds/backspace.wav | Bin 0 -> 7778 bytes .../keyboardSounds/sounds/click1.wav | Bin 0 -> 9086 bytes .../keyboardSounds/sounds/click2.wav | Bin 0 -> 9086 bytes .../keyboardSounds/sounds/click3.wav | Bin 0 -> 7970 bytes src/equicordplugins/keywordNotify/index.tsx | 127 + src/equicordplugins/keywordNotify/style.css | 9 + src/equicordplugins/messageLatency/index.tsx | 147 + .../messageLinkTooltip/index.tsx | 126 + .../messageLinkTooltip/style.css | 4 + .../LoggedMessageManager.ts | 268 + .../components/LogsButton.tsx | 60 + .../components/LogsModal.tsx | 492 ++ .../messageLoggerEnhanced/index.tsx | 756 +++ .../messageLoggerEnhanced/native/index.ts | 139 + .../messageLoggerEnhanced/native/settings.ts | 49 + .../messageLoggerEnhanced/native/utils.ts | 26 + .../messageLoggerEnhanced/styles.css | 82 + .../messageLoggerEnhanced/types.ts | 124 + .../messageLoggerEnhanced/utils/LimitedMap.ts | 36 + .../messageLoggerEnhanced/utils/cleanUp.ts | 116 + .../messageLoggerEnhanced/utils/constants.ts | 19 + .../utils/freedom/importMeToPreload.ts | 19 + .../messageLoggerEnhanced/utils/index.ts | 184 + .../messageLoggerEnhanced/utils/memoize.ts | 41 + .../messageLoggerEnhanced/utils/misc.ts | 156 + .../messageLoggerEnhanced/utils/parseQuery.ts | 101 + .../utils/saveImage/ImageManager.ts | 80 + .../utils/saveImage/index.ts | 115 + .../utils/settingsUtils.ts | 51 + src/equicordplugins/noModalAnimation/index.ts | 30 + src/equicordplugins/noNitroUpsell/index.ts | 57 + .../components/NotificationsOffIcon.tsx | 11 + .../components/NotificationsOnIcon.tsx | 11 + .../notifyUserChanges/index.tsx | 344 ++ .../onePingPerDM/README.md | 0 .../onePingPerDM/index.ts | 0 src/equicordplugins/platformSpoofer/index.ts | 53 + src/equicordplugins/purgeMessages/index.ts | 93 + .../questionMarkReplacement/index.tsx | 47 + src/equicordplugins/quoter/index.tsx | 267 + src/equicordplugins/replyPingControl/index.ts | 90 + src/equicordplugins/replyTimestamp/index.tsx | 69 + src/equicordplugins/replyTimestamp/style.css | 3 + .../screenRecorder.vencordDesktop/index.tsx | 69 + .../screenShareStreamerMode/index.ts | 66 + src/equicordplugins/search/index.ts | 84 + src/equicordplugins/searchFix/index.tsx | 46 + .../sekaiStickers/Components/Canvas.tsx | 27 + .../sekaiStickers/Components/Picker.tsx | 51 + .../Components/SekaiStickersModal.tsx | 138 + .../sekaiStickers/characters.json.ts | 5035 +++++++++++++++++ src/equicordplugins/sekaiStickers/index.tsx | 54 + .../sekaiStickers/kanade.svg.tsx | 21 + .../serverProfilesToolBox/index.tsx | 94 + .../showBadgesInChat/index.tsx | 131 + .../showBadgesInChat/settings.tsx | 166 + .../showBadgesInChat/styles.css | 21 + src/equicordplugins/slap/index.ts | 30 + .../components/CloneSoundModal.tsx | 193 + .../soundBoardLogger/components/Icons.tsx | 57 + .../components/MoreUsersModal.tsx | 62 + .../components/SoundBoardLog.tsx | 192 + .../soundBoardLogger/components/UserModal.tsx | 104 + .../soundBoardLogger/index.tsx | 67 + .../soundBoardLogger/settings.tsx | 93 + .../soundBoardLogger/store.tsx | 62 + .../soundBoardLogger/styles.css | 125 + src/equicordplugins/soundBoardLogger/utils.ts | 81 + src/equicordplugins/title/index.ts | 50 + .../unlimitedAccounts/index.ts | 35 + src/equicordplugins/usrpfp/index.tsx | 70 + src/equicordplugins/validReply/index.ts | 70 + src/equicordplugins/vencordRPC/index.ts | 440 ++ src/equicordplugins/voiceChatUtils/index.tsx | 132 + src/equicordplugins/voiceDownload/index.tsx | 53 + src/equicordplugins/voiceDownload/style.css | 12 + src/equicordplugins/whosWatching/index.tsx | 80 + src/main/ipcMain.ts | 24 +- src/main/monacoWin.html | 114 +- src/main/patchWin32Updater.ts | 2 - src/main/updater/http.ts | 30 +- src/main/utils/extensions.ts | 9 +- src/plugins/_api/badges.tsx | 22 +- src/plugins/_api/chatButtons.ts | 6 +- src/plugins/_api/messageEvents.ts | 6 +- src/plugins/_core/settings.tsx | 8 +- src/plugins/_core/supportHelper.tsx | 35 +- src/plugins/betterRoleContext/README.md | 6 - src/plugins/betterSettings/README.md | 9 - src/plugins/callTimer/index.tsx | 26 +- src/plugins/clearURLs/defaultRules.ts | 3 + src/plugins/clientTheme/README.md | 7 - src/plugins/clientTheme/clientTheme.css | 4 +- src/plugins/dearrow/index.tsx | 6 +- src/plugins/decor/README.md | 17 - src/plugins/decor/index.tsx | 3 +- src/plugins/decor/lib/constants.ts | 24 +- src/plugins/decor/settings.tsx | 8 +- .../decor/ui/modals/GuidelinesModal.tsx | 2 +- .../index.tsx | 0 .../equicordCSS/css/betterauthapps.css | 80 + .../equicordCSS/css/betterstatuspicker.css | 56 + src/plugins/equicordCSS/css/equicord.css | 69 + .../equicordCSS/css/graidentbuttons.css | 100 + src/plugins/equicordCSS/css/main.min.css | 10 + .../equicordCSS/css/nitrothemesfix.css | 1 + src/plugins/equicordCSS/css/settingsicons.css | 21 + .../equicordCSS/css/userreimagined.css | 82 + src/plugins/equicordCSS/index.ts | 133 + .../index.css | 0 .../index.tsx | 6 +- src/plugins/fakeNitro/index.tsx | 14 +- .../components/BuilderButton.tsx | 62 + .../components/ColorPickerModal.tsx | 95 + .../components/ProfileEffectModal.tsx | 103 + src/plugins/fakeProfileThemes/index.tsx | 633 ++- src/plugins/fakeProfileThemes/types.ts | 68 + src/plugins/favGifSearch/index.tsx | 1 - src/plugins/fixCodeblockGap/index.ts | 18 +- .../fixSpotifyEmbeds.desktop/native.ts | 2 +- .../fixYoutubeEmbeds.desktop/README.md | 5 - .../fixYoutubeEmbeds.desktop/native.ts | 2 +- src/plugins/friendsSince/README.md | 5 - src/plugins/friendsSince/index.tsx | 3 +- src/plugins/imageZoom/index.tsx | 2 +- src/plugins/imageZoom/styles.css | 4 +- src/plugins/invisibleChat.desktop/index.tsx | 41 +- .../components/SpotifyIcon.tsx | 11 + .../components/TwitchIcon.tsx | 11 + src/plugins/memberListActivites/index.tsx | 290 + src/plugins/memberListActivites/styles.css | 20 + src/plugins/messageLinkEmbeds/index.tsx | 3 +- src/plugins/messageLogger/index.tsx | 20 +- src/plugins/messageTags/index.ts | 14 + src/plugins/mutualGroupDMs/index.tsx | 2 +- src/plugins/newGuildSettings/index.tsx | 2 +- src/plugins/notificationVolume/README.md | 3 - .../{index.ts => index.tsx} | 0 src/plugins/oneko/index.ts | 62 +- src/plugins/petpet/index.ts | 3 +- .../pinDms/components/CreateCategoryModal.tsx | 1 - src/plugins/pronoundb/index.ts | 3 +- src/plugins/pronoundb/pronoundbUtils.ts | 55 +- src/plugins/pronoundb/types.ts | 45 +- .../readAllNotificationsButton/index.tsx | 2 +- src/plugins/resurrectHome/README.md | 5 - .../reviewDB/components/MessageButton.tsx | 22 + .../reviewDB/components/ReviewComponent.tsx | 154 +- .../reviewDB/components/ReviewsView.tsx | 12 +- src/plugins/reviewDB/entities.ts | 1 + src/plugins/reviewDB/settings.tsx | 1 - src/plugins/reviewDB/style.css | 63 +- src/plugins/sendTimestamps/styles.css | 5 +- src/plugins/serverListIndicators/index.tsx | 91 +- src/plugins/serverListIndicators/styles.css | 74 + src/plugins/shikiCodeblocks.desktop/index.ts | 2 +- src/plugins/showConnections/index.tsx | 2 +- src/plugins/showMeYourName/index.tsx | 53 +- src/plugins/spotifyControls/index.tsx | 4 +- src/plugins/spotifyControls/spotifyStyles.css | 1 + src/plugins/themeAttributes/index.ts | 1 + src/plugins/translate/styles.css | 5 +- src/plugins/typingIndicator/index.tsx | 2 +- src/plugins/unlockedAvatarZoom/README.md | 5 - src/plugins/urbanDictionary/README.md | 13 - src/plugins/userVoiceShow/index.tsx | 2 +- src/plugins/vcNarrator/index.tsx | 15 +- src/plugins/xsOverlay.desktop/README.md | 2 +- src/shared/vencordUserAgent.ts | 3 +- src/utils/constants.ts | 262 +- src/utils/dependencies.ts | 18 + src/utils/patches.ts | 10 +- src/utils/quickCss.ts | 38 +- src/utils/react.tsx | 19 + src/utils/settingsSync.ts | 4 +- src/utils/text.ts | 33 + src/{main/themes => utils/themes/bd}/LICENSE | 0 src/{main/themes => utils/themes/bd}/index.ts | 0 src/utils/themes/index.ts | 17 + src/utils/themes/usercss/compiler.ts | 109 + src/utils/themes/usercss/index.ts | 44 + src/utils/themes/usercss/usercss-meta.d.ts | 134 + src/webpack/common/components.ts | 1 - src/webpack/common/internal.tsx | 1 - src/webpack/common/menu.ts | 2 - src/webpack/common/react.ts | 1 - src/webpack/common/settingsStores.ts | 1 - src/webpack/common/stores.ts | 2 +- src/webpack/common/types/components.d.ts | 11 +- src/webpack/common/types/fluxEvents.d.ts | 2 +- src/webpack/common/types/index.d.ts | 3 + src/webpack/common/types/menu.d.ts | 9 +- .../common/types/passiveupdatestate.d.ts | 41 + src/webpack/common/types/voicestate.d.ts | 21 + src/webpack/common/utils.ts | 2 - src/webpack/patchWebpack.ts | 354 +- src/webpack/webpack.ts | 34 +- tsconfig.json | 36 +- 326 files changed, 24876 insertions(+), 2280 deletions(-) delete mode 100644 .github/workflows/publish.yml create mode 100644 patches/@types__less@3.0.6.patch delete mode 100644 patches/eslint-plugin-path-alias@1.0.0.patch create mode 100644 src/components/ThemeSettings/OnlineThemes.tsx create mode 100644 src/components/ThemeSettings/ThemesTab.tsx create mode 100644 src/components/ThemeSettings/UserCSSModal.tsx create mode 100644 src/components/ThemeSettings/components/SettingBooleanComponent.tsx create mode 100644 src/components/ThemeSettings/components/SettingColorComponent.tsx create mode 100644 src/components/ThemeSettings/components/SettingNumberComponent.tsx create mode 100644 src/components/ThemeSettings/components/SettingRangeComponent.tsx create mode 100644 src/components/ThemeSettings/components/SettingSelectComponent.tsx create mode 100644 src/components/ThemeSettings/components/SettingTextComponent.tsx create mode 100644 src/components/ThemeSettings/components/colorStyles.css create mode 100644 src/components/ThemeSettings/components/index.ts create mode 100644 src/components/ThemeSettings/themesStyles.css delete mode 100644 src/components/VencordSettings/ThemesTab.tsx create mode 100644 src/equicordplugins/VCSupport/index.ts create mode 100644 src/equicordplugins/allCallTimers/Timer.tsx create mode 100644 src/equicordplugins/allCallTimers/TimerIcon.tsx create mode 100644 src/equicordplugins/allCallTimers/index.tsx create mode 100644 src/equicordplugins/allCallTimers/timerText.tsx create mode 100644 src/equicordplugins/allowedMentions/AllowedMentions.css create mode 100644 src/equicordplugins/allowedMentions/AllowedMentions.tsx create mode 100644 src/equicordplugins/allowedMentions/index.tsx create mode 100644 src/equicordplugins/altKrispSwitch/index.tsx create mode 100644 src/equicordplugins/annamox/index.ts create mode 100644 src/equicordplugins/betterQuickReact/index.tsx create mode 100644 src/equicordplugins/betterQuickReact/style.css create mode 100644 src/equicordplugins/blockKrisp.discordDesktop/index.ts create mode 100644 src/equicordplugins/bypassDND/index.tsx create mode 100644 src/equicordplugins/cleanChannelName/index.ts create mode 100644 src/equicordplugins/colorMessage/index.ts create mode 100644 src/equicordplugins/colorMessage/style.css create mode 100644 src/equicordplugins/copyEmojiAsFormattedString/index.tsx create mode 100644 src/equicordplugins/copyUserMention/index.tsx create mode 100644 src/equicordplugins/customAppIcons/AppIconModal.tsx create mode 100644 src/equicordplugins/customAppIcons/index.tsx create mode 100644 src/equicordplugins/customScreenShare.desktop/goofs.tsx create mode 100644 src/equicordplugins/customScreenShare.desktop/index.tsx create mode 100644 src/equicordplugins/customScreenShare.desktop/utils.ts create mode 100644 src/equicordplugins/deadMembers/index.tsx create mode 100644 src/equicordplugins/doNotLeak/index.ts create mode 100644 src/equicordplugins/doNotLeak/style.css create mode 100644 src/equicordplugins/doubleCounterVerifyBypass/index.tsx create mode 100644 src/equicordplugins/emojiDumper/index.tsx create mode 100644 src/equicordplugins/encryptcord/index.tsx create mode 100644 src/equicordplugins/encryptcord/rsa-utils.tsx create mode 100644 src/equicordplugins/exportContacts/index.tsx create mode 100644 src/equicordplugins/exportContacts/styles.css create mode 100644 src/equicordplugins/findReply/ReplyNavigator.tsx create mode 100644 src/equicordplugins/findReply/index.tsx create mode 100644 src/equicordplugins/findReply/styles.css create mode 100644 src/equicordplugins/gifCollections/CollectionManager.ts create mode 100644 src/equicordplugins/gifCollections/constants.ts create mode 100644 src/equicordplugins/gifCollections/index.tsx create mode 100644 src/equicordplugins/gifCollections/types.ts create mode 100644 src/equicordplugins/gifCollections/utils/cleanUrl.ts create mode 100644 src/equicordplugins/gifCollections/utils/getFormat.ts create mode 100644 src/equicordplugins/gifCollections/utils/getGif.ts create mode 100644 src/equicordplugins/gifCollections/utils/getUrlExtension.ts create mode 100644 src/equicordplugins/gifCollections/utils/isAudio.ts create mode 100644 src/equicordplugins/gifCollections/utils/settingsUtils.ts create mode 100644 src/equicordplugins/gifCollections/utils/uuidv4.ts create mode 100644 src/equicordplugins/globalBadges/index.tsx create mode 100644 src/equicordplugins/hideMessage/EyeIcon.tsx create mode 100644 src/equicordplugins/hideMessage/HideIcon.tsx create mode 100644 src/equicordplugins/hideMessage/HideMessageAccessory.tsx create mode 100644 src/equicordplugins/hideMessage/index.tsx create mode 100644 src/equicordplugins/hideMessage/styles.css create mode 100644 src/equicordplugins/holyNotes/NoteHandler.ts create mode 100644 src/equicordplugins/holyNotes/components/icons/HelpIcon.tsx create mode 100644 src/equicordplugins/holyNotes/components/icons/NoteButton.tsx create mode 100644 src/equicordplugins/holyNotes/components/icons/overFlowIcon.tsx create mode 100644 src/equicordplugins/holyNotes/components/modals/Error.tsx create mode 100644 src/equicordplugins/holyNotes/components/modals/HelpModal.tsx create mode 100644 src/equicordplugins/holyNotes/components/modals/ManageNotebookButton.tsx create mode 100644 src/equicordplugins/holyNotes/components/modals/NoteBookTab.tsx create mode 100644 src/equicordplugins/holyNotes/components/modals/Notebook.tsx create mode 100644 src/equicordplugins/holyNotes/components/modals/NotebookCreateModal.tsx create mode 100644 src/equicordplugins/holyNotes/components/modals/NotebookDeleteModal.tsx create mode 100644 src/equicordplugins/holyNotes/components/modals/RenderMessage.tsx create mode 100644 src/equicordplugins/holyNotes/index.tsx create mode 100644 src/equicordplugins/holyNotes/style.css create mode 100644 src/equicordplugins/holyNotes/types.ts create mode 100644 src/equicordplugins/holyNotes/utils.ts create mode 100644 src/equicordplugins/hopOn/index.tsx create mode 100644 src/equicordplugins/iRememberYou/index.tsx create mode 100644 src/equicordplugins/ignoreTerms/index.ts create mode 100644 src/equicordplugins/imageLink/index.ts create mode 100644 src/equicordplugins/keyboardSounds/index.ts create mode 100644 src/equicordplugins/keyboardSounds/sounds/backspace.wav create mode 100644 src/equicordplugins/keyboardSounds/sounds/click1.wav create mode 100644 src/equicordplugins/keyboardSounds/sounds/click2.wav create mode 100644 src/equicordplugins/keyboardSounds/sounds/click3.wav create mode 100644 src/equicordplugins/keywordNotify/index.tsx create mode 100644 src/equicordplugins/keywordNotify/style.css create mode 100644 src/equicordplugins/messageLatency/index.tsx create mode 100644 src/equicordplugins/messageLinkTooltip/index.tsx create mode 100644 src/equicordplugins/messageLinkTooltip/style.css create mode 100644 src/equicordplugins/messageLoggerEnhanced/LoggedMessageManager.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/components/LogsButton.tsx create mode 100644 src/equicordplugins/messageLoggerEnhanced/components/LogsModal.tsx create mode 100644 src/equicordplugins/messageLoggerEnhanced/index.tsx create mode 100644 src/equicordplugins/messageLoggerEnhanced/native/index.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/native/settings.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/native/utils.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/styles.css create mode 100644 src/equicordplugins/messageLoggerEnhanced/types.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/utils/LimitedMap.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/utils/cleanUp.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/utils/constants.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/utils/freedom/importMeToPreload.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/utils/index.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/utils/memoize.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/utils/misc.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/utils/parseQuery.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/utils/saveImage/ImageManager.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/utils/saveImage/index.ts create mode 100644 src/equicordplugins/messageLoggerEnhanced/utils/settingsUtils.ts create mode 100644 src/equicordplugins/noModalAnimation/index.ts create mode 100644 src/equicordplugins/noNitroUpsell/index.ts create mode 100644 src/equicordplugins/notifyUserChanges/components/NotificationsOffIcon.tsx create mode 100644 src/equicordplugins/notifyUserChanges/components/NotificationsOnIcon.tsx create mode 100644 src/equicordplugins/notifyUserChanges/index.tsx rename src/{plugins => equicordplugins}/onePingPerDM/README.md (100%) rename src/{plugins => equicordplugins}/onePingPerDM/index.ts (100%) create mode 100644 src/equicordplugins/platformSpoofer/index.ts create mode 100644 src/equicordplugins/purgeMessages/index.ts create mode 100644 src/equicordplugins/questionMarkReplacement/index.tsx create mode 100644 src/equicordplugins/quoter/index.tsx create mode 100644 src/equicordplugins/replyPingControl/index.ts create mode 100644 src/equicordplugins/replyTimestamp/index.tsx create mode 100644 src/equicordplugins/replyTimestamp/style.css create mode 100644 src/equicordplugins/screenRecorder.vencordDesktop/index.tsx create mode 100644 src/equicordplugins/screenShareStreamerMode/index.ts create mode 100644 src/equicordplugins/search/index.ts create mode 100644 src/equicordplugins/searchFix/index.tsx create mode 100644 src/equicordplugins/sekaiStickers/Components/Canvas.tsx create mode 100644 src/equicordplugins/sekaiStickers/Components/Picker.tsx create mode 100644 src/equicordplugins/sekaiStickers/Components/SekaiStickersModal.tsx create mode 100644 src/equicordplugins/sekaiStickers/characters.json.ts create mode 100644 src/equicordplugins/sekaiStickers/index.tsx create mode 100644 src/equicordplugins/sekaiStickers/kanade.svg.tsx create mode 100644 src/equicordplugins/serverProfilesToolBox/index.tsx create mode 100644 src/equicordplugins/showBadgesInChat/index.tsx create mode 100644 src/equicordplugins/showBadgesInChat/settings.tsx create mode 100644 src/equicordplugins/showBadgesInChat/styles.css create mode 100644 src/equicordplugins/slap/index.ts create mode 100644 src/equicordplugins/soundBoardLogger/components/CloneSoundModal.tsx create mode 100644 src/equicordplugins/soundBoardLogger/components/Icons.tsx create mode 100644 src/equicordplugins/soundBoardLogger/components/MoreUsersModal.tsx create mode 100644 src/equicordplugins/soundBoardLogger/components/SoundBoardLog.tsx create mode 100644 src/equicordplugins/soundBoardLogger/components/UserModal.tsx create mode 100644 src/equicordplugins/soundBoardLogger/index.tsx create mode 100644 src/equicordplugins/soundBoardLogger/settings.tsx create mode 100644 src/equicordplugins/soundBoardLogger/store.tsx create mode 100644 src/equicordplugins/soundBoardLogger/styles.css create mode 100644 src/equicordplugins/soundBoardLogger/utils.ts create mode 100644 src/equicordplugins/title/index.ts create mode 100644 src/equicordplugins/unlimitedAccounts/index.ts create mode 100644 src/equicordplugins/usrpfp/index.tsx create mode 100644 src/equicordplugins/validReply/index.ts create mode 100644 src/equicordplugins/vencordRPC/index.ts create mode 100644 src/equicordplugins/voiceChatUtils/index.tsx create mode 100644 src/equicordplugins/voiceDownload/index.tsx create mode 100644 src/equicordplugins/voiceDownload/style.css create mode 100644 src/equicordplugins/whosWatching/index.tsx delete mode 100644 src/plugins/betterRoleContext/README.md delete mode 100644 src/plugins/betterSettings/README.md delete mode 100644 src/plugins/clientTheme/README.md delete mode 100644 src/plugins/decor/README.md rename src/plugins/{devCompanion.dev => devCompanion}/index.tsx (100%) create mode 100644 src/plugins/equicordCSS/css/betterauthapps.css create mode 100644 src/plugins/equicordCSS/css/betterstatuspicker.css create mode 100644 src/plugins/equicordCSS/css/equicord.css create mode 100644 src/plugins/equicordCSS/css/graidentbuttons.css create mode 100644 src/plugins/equicordCSS/css/main.min.css create mode 100644 src/plugins/equicordCSS/css/nitrothemesfix.css create mode 100644 src/plugins/equicordCSS/css/settingsicons.css create mode 100644 src/plugins/equicordCSS/css/userreimagined.css create mode 100644 src/plugins/equicordCSS/index.ts rename src/plugins/{vencordToolbox => equicordToolbox}/index.css (100%) rename src/plugins/{vencordToolbox => equicordToolbox}/index.tsx (97%) create mode 100644 src/plugins/fakeProfileThemes/components/BuilderButton.tsx create mode 100644 src/plugins/fakeProfileThemes/components/ColorPickerModal.tsx create mode 100644 src/plugins/fakeProfileThemes/components/ProfileEffectModal.tsx create mode 100644 src/plugins/fakeProfileThemes/types.ts delete mode 100644 src/plugins/fixYoutubeEmbeds.desktop/README.md delete mode 100644 src/plugins/friendsSince/README.md create mode 100644 src/plugins/memberListActivites/components/SpotifyIcon.tsx create mode 100644 src/plugins/memberListActivites/components/TwitchIcon.tsx create mode 100644 src/plugins/memberListActivites/index.tsx create mode 100644 src/plugins/memberListActivites/styles.css delete mode 100644 src/plugins/notificationVolume/README.md rename src/plugins/notificationVolume/{index.ts => index.tsx} (100%) delete mode 100644 src/plugins/resurrectHome/README.md create mode 100644 src/plugins/serverListIndicators/styles.css delete mode 100644 src/plugins/unlockedAvatarZoom/README.md delete mode 100644 src/plugins/urbanDictionary/README.md rename src/{main/themes => utils/themes/bd}/LICENSE (100%) rename src/{main/themes => utils/themes/bd}/index.ts (100%) create mode 100644 src/utils/themes/index.ts create mode 100644 src/utils/themes/usercss/compiler.ts create mode 100644 src/utils/themes/usercss/index.ts create mode 100644 src/utils/themes/usercss/usercss-meta.d.ts create mode 100644 src/webpack/common/types/passiveupdatestate.d.ts create mode 100644 src/webpack/common/types/voicestate.d.ts diff --git a/.eslintrc.json b/.eslintrc.json index 2ee24e8b..c422d22f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,23 +1,40 @@ { "root": true, "parser": "@typescript-eslint/parser", - "ignorePatterns": ["dist", "browser"], + "ignorePatterns": [ + "dist", + "browser" + ], "plugins": [ "@typescript-eslint", "simple-header", "simple-import-sort", - "unused-imports", - "path-alias" + "unused-imports" ], "settings": { "import/resolver": { "alias": { "map": [ - ["@webpack", "./src/webpack"], - ["@webpack/common", "./src/webpack/common"], - ["@utils", "./src/utils"], - ["@api", "./src/api"], - ["@components", "./src/components"] + [ + "@webpack", + "./src/webpack" + ], + [ + "@webpack/common", + "./src/webpack/common" + ], + [ + "@utils", + "./src/utils" + ], + [ + "@api", + "./src/api" + ], + [ + "@components", + "./src/components" + ] ] } } @@ -29,37 +46,120 @@ "simple-header/header": [ "error", { - "files": ["scripts/header-new.txt", "scripts/header-old.txt"], - "templates": { "author": [".*", "Vendicated and contributors"] } + "files": [ + "scripts/header-new.txt", + "scripts/header-old.txt" + ], + "templates": { + "author": [ + ".*", + "Vendicated and contributors" + ] + } } ], - "quotes": ["error", "double", { "avoidEscape": true }], - "jsx-quotes": ["error", "prefer-double"], + "quotes": [ + "error", + "double", + { + "avoidEscape": true + } + ], + "jsx-quotes": [ + "error", + "prefer-double" + ], "no-mixed-spaces-and-tabs": "error", - "indent": ["error", 4, { "SwitchCase": 1 }], - "arrow-parens": ["error", "as-needed"], - "eol-last": ["error", "always"], - "@typescript-eslint/func-call-spacing": ["error", "never"], + "indent": [ + "error", + 4, + { + "SwitchCase": 1 + } + ], + "arrow-parens": [ + "error", + "as-needed" + ], + "eol-last": [ + "error", + "always" + ], + "@typescript-eslint/func-call-spacing": [ + "error", + "never" + ], "no-multi-spaces": "error", "no-trailing-spaces": "error", "no-whitespace-before-property": "error", - "semi": ["error", "always"], - "semi-style": ["error", "last"], - "space-in-parens": ["error", "never"], - "block-spacing": ["error", "always"], - "object-curly-spacing": ["error", "always"], - "eqeqeq": ["error", "always", { "null": "ignore" }], - "spaced-comment": ["error", "always", { "markers": ["!"] }], + "semi": [ + "error", + "always" + ], + "semi-style": [ + "error", + "last" + ], + "space-in-parens": [ + "error", + "never" + ], + "block-spacing": [ + "error", + "always" + ], + "object-curly-spacing": [ + "error", + "always" + ], + "eqeqeq": [ + "error", + "always", + { + "null": "ignore" + } + ], + "spaced-comment": [ + "error", + "always", + { + "markers": [ + "!" + ] + } + ], "yoda": "error", - "prefer-destructuring": ["error", { - "VariableDeclarator": { "array": false, "object": true }, - "AssignmentExpression": { "array": false, "object": false } - }], - "operator-assignment": ["error", "always"], + "prefer-destructuring": [ + "error", + { + "VariableDeclarator": { + "array": false, + "object": true + }, + "AssignmentExpression": { + "array": false, + "object": false + } + } + ], + "operator-assignment": [ + "error", + "always" + ], "no-useless-computed-key": "error", - "no-unneeded-ternary": ["error", { "defaultAssignment": false }], + "no-unneeded-ternary": [ + "error", + { + "defaultAssignment": false + } + ], "no-invalid-regexp": "error", - "no-constant-condition": ["error", { "checkLoops": false }], + "no-constant-condition": [ + "error", + { + "checkLoops": false + } + ], "no-duplicate-imports": "error", "no-extra-semi": "error", "dot-notation": "error", @@ -87,12 +187,8 @@ "use-isnan": "error", "prefer-const": "error", "prefer-spread": "error", - "simple-import-sort/imports": "error", "simple-import-sort/exports": "error", - - "unused-imports/no-unused-imports": "error", - - "path-alias/no-relative": "error" + "unused-imports/no-unused-imports": "error" } -} +} \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/blank.yml b/.github/ISSUE_TEMPLATE/blank.yml index e8ca246d..94432f22 100644 --- a/.github/ISSUE_TEMPLATE/blank.yml +++ b/.github/ISSUE_TEMPLATE/blank.yml @@ -10,7 +10,7 @@ body: This form is ONLY FOR DEVELOPERS. YOUR ISSUE WILL BE CLOSED AND YOU WILL POSSIBLY BE BLOCKED FROM THE REPOSITORY IF YOU IGNORE THIS. DO NOT USE THIS FORM, unless - - you are a vencord contributor + - you are a equicord/vencord contributor - you were given explicit permission to use this form by a moderator in our support server - you are filing a security related report diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index d79f5e49..17a50fa1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,5 +1,5 @@ name: Bug/Crash Report -description: Create a bug or crash report for Vencord. ALWAYS FIRST USE OUR SUPPORT CHANNEL! ONLY USE THIS FORM IF YOU ARE A CONTRIBUTOR OR WERE TOLD TO DO SO IN THE SUPPORT CHANNEL. +description: Create a bug or crash report for Equicord. ALWAYS FIRST USE OUR SUPPORT CHANNEL! ONLY USE THIS FORM IF YOU ARE A CONTRIBUTOR OR WERE TOLD TO DO SO IN THE SUPPORT CHANNEL. labels: [bug] title: "[Bug] " @@ -12,10 +12,10 @@ body: This form is ONLY FOR DEVELOPERS. YOUR ISSUE WILL BE CLOSED AND YOU WILL POSSIBLY BE BLOCKED FROM THE REPOSITORY IF YOU IGNORE THIS. DO NOT USE THIS FORM, unless - - you are a vencord contributor + - you are a equicord/vencord contributor - you were given explicit permission to use this form by a moderator in our support server - DO NOT USE THIS FORM FOR SECURITY RELATED ISSUES. [CREATE A SECURITY ADVISORY INSTEAD.](https://github.com/Vendicated/Vencord/security/advisories/new) + DO NOT USE THIS FORM FOR SECURITY RELATED ISSUES. [CREATE A SECURITY ADVISORY INSTEAD.](https://github.com/Equicord/Equicord/security/advisories/new) - type: input id: discord @@ -40,7 +40,7 @@ body: attributes: label: What is the expected behaviour? description: Simply detail what the expected behaviour is. - placeholder: I expect Vencord/Discord to open the ... page instead of ..., it prevents me from doing ... + placeholder: I expect Equicord/Discord to open the ... page instead of ..., it prevents me from doing ... validations: required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index bc5d9766..56216d2a 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,8 @@ blank_issues_enabled: false contact_links: - - name: Vencord Support Server - url: https://discord.gg/D9uwnFnqmd - about: If you need help regarding Vencord, please join our support server! - - name: Vencord Installer - url: https://github.com/Vencord/Installer - about: You can find the Vencord Installer here + - name: Equicord Support Server + url: https://discord.gg/XVAwhj6Z6c + about: If you need help regarding Equicord, please join our support server! + - name: Equicord Installer + url: https://github.com/Equicord/Installer + about: You can find the Equicord Installer here diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9ed7d5ca..d1543380 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,80 +1,71 @@ name: Build DevBuild on: - push: - branches: - - main - paths: - - .github/workflows/build.yml - - src/** - - browser/** - - scripts/build/** - - package.json - - pnpm-lock.yaml + push: + branches: + - main + paths: + - .github/workflows/build.yml + - src/** + - browser/** + - scripts/build/** + - package.json + - pnpm-lock.yaml env: - FORCE_COLOR: true + FORCE_COLOR: true jobs: - Build: - runs-on: ubuntu-latest + DetermineRunner: + name: Determine Runner + runs-on: ubuntu-latest + outputs: + runner: ${{ steps.set-runner.outputs.runner }} + steps: + - name: Determine which runner to use + id: set-runner + uses: benjaminmichaelis/get-soonest-available-runner@v1.1.0 + with: + primary-runner: "self-hosted" + fallback-runner: "ubuntu-latest" + min-available-runners: 1 + github-token: ${{ env.GITHUB_TOKEN }} + env: + GITHUB_TOKEN: ${{ secrets.ETOKEN }} - steps: - - uses: actions/checkout@v3 + Build: + name: Build Equicord + needs: DetermineRunner + runs-on: ${{ needs.DetermineRunner.outputs.runner}} - - uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json + steps: + - uses: actions/checkout@v4 - - name: Use Node.js 19 - uses: actions/setup-node@v3 - with: - node-version: 19 - cache: "pnpm" + - uses: pnpm/action-setup@v3 - - name: Install dependencies - run: pnpm install --frozen-lockfile + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "pnpm" - - name: Build web - run: pnpm buildWeb --standalone + - name: Install dependencies + run: pnpm install --frozen-lockfile - - name: Build - run: pnpm build --standalone + - name: Build web + run: pnpm buildWeb --standalone - - name: Generate plugin list - run: pnpm generatePluginJson dist/plugins.json dist/plugin-readmes.json + - name: Build + run: pnpm build --standalone - - name: Clean up obsolete files - run: | - rm -rf dist/*-unpacked dist/monaco Vencord.user.css vencordDesktopRenderer.css vencordDesktopRenderer.css.map + - name: Generate plugin list + run: pnpm generatePluginJson dist/plugins.json dist/plugin-readmes.json - - name: Get some values needed for the release - id: release_values - run: | - echo "release_tag=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + - name: Clean up obsolete files + run: | + rm -rf dist/*-unpacked dist/monaco Vencord.user.css vencordDesktopRenderer.css vencordDesktopRenderer.css.map - - name: Upload DevBuild as release - if: github.repository == 'Vendicated/Vencord' - run: | - gh release upload devbuild --clobber dist/* - gh release edit devbuild --title "DevBuild $RELEASE_TAG" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ env.release_tag }} - - - name: Upload DevBuild to builds repo - if: github.repository == 'Vendicated/Vencord' - run: | - git config --global user.name "$USERNAME" - git config --global user.email actions@github.com - - git clone https://$USERNAME:$API_TOKEN@github.com/$GH_REPO.git upload - cd upload - - GLOBIGNORE=.git:.gitignore:README.md:LICENSE - rm -rf * - cp -r ../dist/* . - - git add -A - git commit -m "Builds for https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" - git push --force https://$USERNAME:$API_TOKEN@github.com/$GH_REPO.git - env: - API_TOKEN: ${{ secrets.BUILDS_TOKEN }} - GH_REPO: Vencord/builds - USERNAME: GitHub-Actions + - name: Upload DevBuild as release + if: github.repository == 'Equicord/Equicord' + run: | + gh release upload latest --clobber dist/* + env: + GITHUB_TOKEN: ${{ secrets.ETOKEN }} diff --git a/.github/workflows/codeberg-mirror.yml b/.github/workflows/codeberg-mirror.yml index 1b2266ee..fc4b4a09 100644 --- a/.github/workflows/codeberg-mirror.yml +++ b/.github/workflows/codeberg-mirror.yml @@ -1,22 +1,40 @@ name: Sync to Codeberg concurrency: - group: ${{ github.ref }} - cancel-in-progress: true + group: ${{ github.ref }} + cancel-in-progress: true on: - push: - workflow_dispatch: - schedule: - - cron: "0 */6 * * *" + push: + workflow_dispatch: + schedule: + - cron: "0 */6 * * *" jobs: - codeberg: - if: github.repository == 'Vendicated/Vencord' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: pixta-dev/repository-mirroring-action@674e65a7d483ca28dafaacba0d07351bdcc8bd75 # v1.1.1 - with: - target_repo_url: "git@codeberg.org:Vee/cord.git" - ssh_private_key: ${{ secrets.CODEBERG_SSH_PRIVATE_KEY }} + DetermineRunner: + name: Determine Runner + runs-on: ubuntu-latest + outputs: + runner: ${{ steps.set-runner.outputs.runner }} + steps: + - name: Determine which runner to use + id: set-runner + uses: benjaminmichaelis/get-soonest-available-runner@v1.1.0 + with: + primary-runner: "self-hosted" + fallback-runner: "ubuntu-latest" + min-available-runners: 1 + github-token: ${{ env.GITHUB_TOKEN }} + env: + GITHUB_TOKEN: ${{ secrets.ETOKEN }} + + codeberg: + if: github.repository == 'Equicord/Equicord' + needs: DetermineRunner + runs-on: ${{ needs.DetermineRunner.outputs.runner }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: pixta-dev/repository-mirroring-action@674e65a7d483ca28dafaacba0d07351bdcc8bd75 # v1.1.1 + with: + target_repo_url: "git@codeberg.org:thororen/Equicord.git" + ssh_private_key: ${{ secrets.CODEBERG }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 83236c11..00000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Release Browser Extension -on: - push: - tags: - - v* - -jobs: - Publish: - if: github.repository == 'Vendicated/Vencord' - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: check that tag matches package.json version - run: | - pkg_version="v$(jq -r .version < package.json)" - if [[ "${{ github.ref_name }}" != "$pkg_version" ]]; then - echo "Tag ${{ github.ref_name }} does not match package.json version $pkg_version" >&2 - exit 1 - fi - - - uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json - - - name: Use Node.js 19 - uses: actions/setup-node@v3 - with: - node-version: 19 - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build web - run: pnpm buildWeb --standalone - - - name: Publish extension - run: | - cd dist/chromium-unpacked - pnpx chrome-webstore-upload-cli@2.1.0 upload --auto-publish - env: - EXTENSION_ID: ${{ secrets.CHROME_EXTENSION_ID }} - CLIENT_ID: ${{ secrets.CHROME_CLIENT_ID }} - CLIENT_SECRET: ${{ secrets.CHROME_CLIENT_SECRET }} - REFRESH_TOKEN: ${{ secrets.CHROME_REFRESH_TOKEN }} diff --git a/.github/workflows/reportBrokenPlugins.yml b/.github/workflows/reportBrokenPlugins.yml index 4b09463e..677ae3c5 100644 --- a/.github/workflows/reportBrokenPlugins.yml +++ b/.github/workflows/reportBrokenPlugins.yml @@ -1,64 +1,63 @@ name: Test Patches on: - workflow_dispatch: - schedule: - # Every day at midnight - - cron: 0 0 * * * + workflow_dispatch: + schedule: + # Every day at midnight + - cron: 0 0 * * * jobs: - TestPlugins: - if: github.repository == 'Vendicated/Vencord' - runs-on: ubuntu-latest + TestPlugins: + name: Test Patches + if: github.repository == 'Equicord/Equicord' + runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - if: ${{ github.event_name == 'schedule' }} - with: - ref: dev + steps: + - uses: actions/checkout@v4 + if: ${{ github.event_name == 'schedule' }} - - uses: actions/checkout@v3 - if: ${{ github.event_name == 'workflow_dispatch' }} + - uses: actions/checkout@v4 + if: ${{ github.event_name == 'workflow_dispatch' }} - - uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json + - uses: pnpm/action-setup@v3 # Install pnpm using packageManager key in package.json - - name: Use Node.js 19 - uses: actions/setup-node@v3 - with: - node-version: 19 - cache: "pnpm" + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "pnpm" - - name: Install dependencies - run: | - pnpm install --frozen-lockfile - pnpm add puppeteer + - name: Install dependencies + run: | + pnpm install --frozen-lockfile + pnpm add puppeteer - sudo apt-get install -y chromium-browser + sudo apt-get install -y chromium-browser - - name: Build web - run: pnpm buildWeb --standalone --dev + - name: Build web + run: pnpm buildWeb --standalone --dev - - name: Create Report - timeout-minutes: 10 - run: | - export PATH="$PWD/node_modules/.bin:$PATH" - export CHROMIUM_BIN=$(which chromium-browser) + - name: Create Report + timeout-minutes: 10 + run: | + export PATH="$PWD/node_modules/.bin:$PATH" + export CHROMIUM_BIN=$(which chromium-browser) - esbuild scripts/generateReport.ts > dist/report.mjs - node dist/report.mjs >> $GITHUB_STEP_SUMMARY - env: - DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }} - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + esbuild scripts/generateReport.ts > dist/report.mjs + node dist/report.mjs >> $GITHUB_STEP_SUMMARY + env: + DISCORD_TOKEN: ${{ secrets.DTOKEN }} + DISCORD_WEBHOOK: ${{ secrets.WEBHOOK }} - - name: Create Report (Canary) - timeout-minutes: 10 - if: success() || failure() # even run if previous one failed - run: | - export PATH="$PWD/node_modules/.bin:$PATH" - export CHROMIUM_BIN=$(which chromium-browser) - export USE_CANARY=true + - name: Create Report (Canary) + timeout-minutes: 10 + if: success() || failure() # even run if previous one failed + run: | + export PATH="$PWD/node_modules/.bin:$PATH" + export CHROMIUM_BIN=$(which chromium-browser) + export USE_CANARY=true - esbuild scripts/generateReport.ts > dist/report.mjs - node dist/report.mjs >> $GITHUB_STEP_SUMMARY - env: - DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }} - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + esbuild scripts/generateReport.ts > dist/report.mjs + node dist/report.mjs >> $GITHUB_STEP_SUMMARY + env: + DISCORD_TOKEN: ${{ secrets.DTOKEN }} + DISCORD_WEBHOOK: ${{ secrets.WEBHOOK }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d4746d67..07e9ea65 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,32 +1,82 @@ name: test on: - push: - pull_request: - branches: - - main - - dev + push: + branches: + - main + pull_request: + branches: + - main + jobs: - test: - runs-on: ubuntu-latest + DetermineRunner: + name: Determine Runner + if: ${{ github.event_name == 'push' }} + runs-on: ubuntu-latest + outputs: + runner: ${{ steps.set-runner.outputs.runner }} + steps: + - name: Determine which runner to use + id: set-runner + uses: benjaminmichaelis/get-soonest-available-runner@v1.1.0 + with: + primary-runner: "self-hosted" + fallback-runner: "ubuntu-latest" + min-available-runners: 1 + github-token: ${{ env.GITHUB_TOKEN }} + env: + GITHUB_TOKEN: ${{ secrets.ETOKEN }} - steps: - - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json + Test: + name: Test For Pushes + needs: DetermineRunner + if: ${{ github.event_name == 'push' }} + runs-on: ${{ needs.DetermineRunner.outputs.runner}} - - name: Use Node.js 18 - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: "pnpm" + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v3 # Install pnpm using packageManager key in package.json - - name: Install dependencies - run: pnpm install --frozen-lockfile + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "pnpm" - - name: Lint & Test if desktop version compiles - run: pnpm test + - name: Install dependencies + run: pnpm install --frozen-lockfile - - name: Test if web version compiles - run: pnpm buildWeb + - name: Lint & Test if desktop version compiles + run: pnpm test - - name: Test if plugin structure is valid - run: pnpm generatePluginJson + - name: Test if web version compiles + run: pnpm buildWeb + + - name: Test if plugin structure is valid + run: pnpm generatePluginJson + + TestForPRs: + name: Test For Pull Requests + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v3 # Install pnpm using packageManager key in package.json + + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "pnpm" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Lint & Test if desktop version compiles + run: pnpm test + + - name: Test if web version compiles + run: pnpm buildWeb + + - name: Test if plugin structure is valid + run: pnpm generatePluginJson diff --git a/.vscode/settings.json b/.vscode/settings.json index fa543b38..e0164363 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,11 +13,10 @@ "typescript.format.semicolons": "insert", "typescript.preferences.quoteStyle": "double", "javascript.preferences.quoteStyle": "double", - "gitlens.remotes": [ { "domain": "codeberg.org", "type": "Gitea" } ] -} +} \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 680f8375..c0c1c8f8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,7 @@ For a friendly introduction to plugins, see [Megu's Plugin Guide!](docs/2_PLUGIN Because plugins modify code directly, incompatibilities are a problem. -Thus, 3rd party plugins are not supported, instead all plugins are part of Vencord itself. +Thus, 3rd party plugins are not supported, instead all plugins are part of Equicord itself. This way we can ensure compatibility and high quality patches. Follow the below guide to make your first plugin! diff --git a/README.md b/README.md index a43c9f83..45f04fb7 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,99 @@ -# Vencord +# Equicord (Vencord+) -[![Codeberg Mirror](https://img.shields.io/static/v1?style=for-the-badge&label=Codeberg%20Mirror&message=codeberg.org/Vee/cord&color=2185D0&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABmJLR0QA/wD/AP+gvaeTAAAKbUlEQVR4nNVae3AV5RX/nW/3Pva+b24e5HHzIICQKGoiYiW8NFBFgohaa6ctglpbFSujSGurzUinohWsOij/gGX6R2fqOK0d1FYTEZXaTrWCBbEikJCEyCvkeXNvkrunf+zdkJDkPnex/c3cmd29+53v/M6e73znnF2Cydj4Tntldzi6qrN/qKqzf2jy6b7BnL4B1dI7oMp9AyoRAIdVsNMqhlxWMZjtspzyK/Jhr036OMsm//bh2vzPzNSPzBD6xFutd7R0Dq758ky4orkjYuc05RCAkixbeEq2/UCJ1/LczxcX/c5IPfU5DMHmxpbCpu7o1k/b+xc1n43YjJI7EqV+W2RmvuPt0oDjB2vn5bQbITNjAzzdeKK8qTO0bU9T77zucNQUjzofHrvENWWu3aUBZfW6+ZOOZiIrbYXrmUXo9daX3v6i667O/iGRiRLpwqtIvKDc+0efJ3hb/UIaSkdGWgZ4sqGt9r2m3lc/P9HvSWe80ZiRp3TPL/UsX1+bvyvVsSkb4NE3WjbuPNj5SM8Fcvdk4bAKrqvwv7DxhuCPUxmXNIn6XSy3nWr6R8OhrqrU1btwqJ3m/bgwu/SqZJdEUgbYsuuka09b9/4Pm3tLMlPvwuAbpe6m+RcplfdcURBKdG9CA2zZddLV2Nx1+JO2vlxj1LswqCpynlxc6SxLZIS40bueWfy9vXvv/xt5APhXa1/u7v+EPqvfxXK8++IaoO2Vpn9+cLS33FjVLhw+bOotOX7q6N/i3TOhAX7y+rHN/+sBLxm8fah71k93tjw/0f/jGuDJxtZrdh7setA8tS4sdn7eef+v3mmfP95/Ywxw6x9Yev9I35/6Iubv83WVfl5a6Uu3VkoavZEo7TnS/Vo98xi+Yy6UKC3bDp7sd5ut1OWFDjyzNMib6oq5Oug0ezp8dqLfG3r92Nbzr48ywNONJ8obDnV/z2xlAk4ZW1aUqhaJIAvCb5YVqwFn3GBtCBoO9dz5TOPxUbnMKAM0dYa2d5lc2AgCNi8r5klui3aBgWynjE11QZbI3FV3NjQkjnYNbB+lj36wubGlcE9T71xTNQDw0Px8nlvmHl73GmfCrKCL19Tkmh4P9jT1LHz2vVP5+vmwAZq71a1m1/PXTPXwD68eS5KIEVUZd1yZwwumeEw1Qld/lJrPhF7Sz4cNsO+rUK2ZExd6rfj10iCPZ2GJCCoAZuCJxQUc9FvNVAX72kPX6ccC0Hp4zR0Ru1kT2mTCSzeXqn5l/EAniMAqoDLDYZWwqa5EVSzmhaKmsxHbLxvbbgdiBmjpHFxj2mwANlxXxBdPUib8nwgQgqAyEFUZxT4L1i/MN3UpHDsTWQvEDHDoTLjCrIluuyzAt8zMSkhGFhp5hrYUFk3z8IqZftOMcKRj4GIAEM80tFccM8n9Z+Qq+MXigqRIWCQCMzQvYIbKwH1X53FFnjkr88iZsLKpoXWa6BiIrjbDzF67hK23lKp2Obm1LAstPEZVjTwDkAio/2ZQ9dolw/VjAB0DfKfoCg9WGy2cADy1NMhBX2rR3CIRGICq8rAhAg4Jj9UWsDBhg+4MR6vF2VC0zGjB99fk8eJp3pQdyyrRMHF9KURVxswCB6+alWO4o3b2RyeLU32D2UYKnVPm5gfm5qWlrF0Wo4hzbCmoDNw0089XlboNNcLpvsFc0RtRDXuNle+x4Lkbi9PO6WWJIBFGEY+qjGjswtq5eVzosRilLnoiUavoH1INiTCyIDy/vETNcmRW1dl0L4gRVxmx3YFhlwnrry1QrZIxASE0yJIIDaiGSHt8UQFXF2Ve1zusYgzxkXGhyGvFvePUE+mgfyAqhGqAqKWVPv5udbYhSjmtkpYWq6OJqzFjqCpjTpmbl1Rk3klSGRBWmTISNC3Hjo1LgoYFJ0GA1aIVR+cTVxlQoS2Pb18a4PLszMKXzSJYuCySmq4Al03CiytKVYfBhYvLKk1IXE+XLRLhwZp81WlNf26HTFHhd0jhdAYTgKduCPLkgPHfQjitYkLiAIEZBDBlu2R6aF7euCV2Mgg45bDw2qWOdAavnp3D109PPdlJBvpTnYg4kVY3MDMuylVw62WJi63x4LHLZ0TAIR9OdWBVodPUclUQwWmT4hLXfgCIUDfDi6oiR8rzBJzyl8LnkD9KZVCOU8aLN5eoshnJ+Qh4bFJC4gztmEjgrtk5anaKnWWfXfpIuBTLjmSpSILw/E0laq7LuGxsIngVCYmIa96hLRG3TaZ1C/KTfjAEQLFIO8TPFk7aH/RZI8kMWrdgEs8udqXLKSUoMkEW4ETEQTRsoHyPlVZfmVw+Uuy3hR9bVHBQAMD0XPu/Ew24dqqH777K/La1DiKCxyYlRRzQymgG4+oyDxZOTdxZnp5r3wvEWmJ5btuL8W4uzbJh87LitLebdOFVpKSJx4IlwIzbL81CcYLO8iSX/IImGQCYae6Wg/2tXQNjNnW7LPDKyilqZd7ETU2zEBlifNTSS4i9PNFIx44x4jh2nZlBsUr0dN8QP/6XVhEaHJvnlfhtkXd/NF0BUextKRFXFznfGk+JDdcX8tdBHtDa6YpFsB4I9ac88omf8wbEgqa2XAIOme6bM35foqrQ+QZIKwGG80ifVbrXZZNGDfhOVYBvviS9JMMoaP3AEcQpPnHdOxiMGXkKbrx4dGfZY5c4T8H9+vmwAeqXFLXOKXW9r59fWuDA44sKv1byAOBzyCkTH+kdS2f4MLPgXJI0p9T17vrFxcf181GVxEUB+0qfIqt+RcKWFSWGNR4ygd4RTpW4HiCJgFWzstmnSPA7ZLU827pypPwxDB/687GXl1X6Vs6bbGz/LRN80hZCT+yLFZ0cgHED4egACeiXm89GsP9EePuzy4rvGil7jAGYmQDsBjDHUBYZ4GhHBMfORigd4rpnyIS9u6d4rqgnGrUtjCmmSYuOqwB0GcwjbWh9xviurpNnxnDA1IspMPe6bOL755MHJvhKjIgOA7jbJD4pw22Thj+kSIW47h2KRaydVezeP57sCdspRPQqgGeNJJIuBAE+ReJUiOv32mXaXjPZs21C2QnmXgdghyEsMoRfkVMiDgCywF/by9z3xJMb1wCxeHAPgDczZpAh/Iq+HSYmDjCsstgThmf5t4ii8eQm7CgS0SCA5QBezoRApnBaBSyCEhIHCLJEb4ZUd+2SqZSwzE+qpUpEQ9CC4qb01M8cRIQsh8zxiKsMtsn08nvlnrpkyAPj5AGJwMw3AtgGwJ/q2ExxvHsQB74KxfKBMblAyGmTHq4pc4/5GjQeUm6qE9FrAK4E8H6ie41GlkN/jTk6F5Ak2ueUpNmpkgfSMAAAENERAAsB3AHgZDoy0oFdFnBYpXPEBfU4beLRD6Z4qmumug+kIzPjaoeZfQDWAHgAQFam8hLh4MkwWjsHemyS2OF08IYrCjynzZ4zKTCzi5nXMvOnzBw16bevIxR95JOj7DNKb1PqXWa+HMDtAGoBXII0lxq0N2OfAmgA8Hsi2muMhudgesHPzNkA5gKoADADwFRoS8UHQO+x9wLoBNAB4AsAnwM4AOADIjLVxf8L9kdXUOE0IskAAAAASUVORK5CYII=)](https://codeberg.org/Vee/cord) +An enhanced version of [Vencord](https://github.com/Vendicated/Vencord) by [Vendicated](https://github.com/Vendicated) called Equicord -The cutest Discord client mod - -| ![image](https://github.com/Vendicated/Vencord/assets/45497981/706722b1-32de-4d99-bee9-93993b504334) | -|:--:| -| A screenshot of vencord showcasing the [vencord-theme](https://github.com/synqat/vencord-theme) | +![image](https://i.ibb.co/xgNr2gq/image-2023-11-24-122019133.png) ## Features -- Super easy to install (Download Installer, open, click install button, done) -- 100+ plugins built in: [See a list](https://vencord.dev/plugins) - - Some highlights: SpotifyControls, MessageLogger, Experiments, GameActivityToggle, Translate, NoTrack, QuickReply, Free Emotes/Stickers, PermissionsViewer, CustomCommands, ShowHiddenChannels, PronounDB +- Third-party plugins implemented into the main build. +- 100+ plugins built-in. + - Some highlights: SpotifyControls, MessageLogger, Experiments, GameActivityToggle, Translate, NoTrack, QuickReply, Free Emotes/Stickers, PermissionsViewer, + CustomCommands, ShowHiddenChannels, PronounDB - Fairly lightweight despite the many inbuilt plugins -- Excellent Browser Support: Run Vencord in your Browser via extension or UserScript -- Works on any Discord branch: Stable, Canary or PTB all work (though for the best experience I recommend stable!) -- Custom CSS and Themes: Inbuilt css editor with support to import any css files (including BetterDiscord themes) +- Works on any Discord branch: Stable, Canary or PTB all work (though for the best experience, I recommend stable!) +- Custom CSS and Themes: Inbuilt CSS editor with support to import any CSS files (including BetterDiscord themes) - Privacy friendly, blocks Discord analytics & crash reporting out of the box and has no telemetry - Maintained very actively, broken plugins are usually fixed within 12 hours -- Settings sync: Keep your plugins and their settings synchronised between devices / apps (optional) +- Able to update inside of Equicord through the update tab. +- Same supporter badges as on Vencord (Don't lose your benefits) +- Easy to install third-party plugins through the plugin page in Discord. +- Request for plugins from Discord. ## Installing / Uninstalling -Visit https://vencord.dev/download +### Dependencies +[Git](https://git-scm.com/download) and [Node.JS LTS](https://nodejs.dev/en/) are required. + +### Installing Equicord + +Install `pnpm`: + +> :exclamation: This next command may need to be run as admin/root depending on your system, and you may need to close and reopen your terminal for pnpm to be in your PATH. + +```shell +npm i -g pnpm +``` + +> :exclamation: **IMPORTANT** Make sure you aren't using an admin/root terminal from here onwards. It **will** mess up your Discord/Equicord instance and you **will** most likely have to reinstall. + +Clone Equicord: + +```shell +git clone https://github.com/Equicord/Equicord +cd Equicord +``` + +Install dependencies: + +```shell +pnpm install --frozen-lockfile +``` + +Build Equicord: + +```shell +pnpm build +``` +Inject Equicord into your client: + +```shell +pnpm inject +``` +After you have done this command, it will look like you are just installing Equicord but it will say it is a development build. If it doesn't say it is a development build, please reach out for support in the [Discord Server](https://discord.gg/5Xh2W87egW) ## Join our Support/Community Server -https://discord.gg/D9uwnFnqmd - -## Sponsors - -| **Thanks a lot to all Vencord [sponsors](https://github.com/sponsors/Vendicated)!!** | -|:--:| -| [![](https://meow.vendicated.dev/sponsors.png)](https://github.com/sponsors/Vendicated) | -| *generated using [github-sponsor-graph](https://github.com/Vendicated/github-sponsor-graph)* | - +https://discord.gg/5Xh2W87egW ## Star History -<a href="https://star-history.com/#Vendicated/Vencord&Timeline"> +<a href="https://star-history.com/#Equicord/Equicord&Timeline"> <picture> - <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Vendicated/Vencord&type=Timeline&theme=dark" /> - <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Vendicated/Vencord&type=Timeline" /> - <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Vendicated/Vencord&type=Timeline" /> + <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Equicord/Equicord&type=Timeline&theme=dark" /> + <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Equicord/Equicord&type=Timeline" /> + <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Equicord/Equicord&type=Timeline" /> </picture> </a> ## Disclaimer Discord is trademark of Discord Inc. and solely mentioned for the sake of descriptivity. -Mention of it does not imply any affiliation with or endorsement by Discord Inc. +Mentioning it does not imply any affiliation with or endorsement by Discord Inc. +Vencord is not connected to Equicord and as such, all donation links go to Vendicated's donation link. <details> -<summary>Using Vencord violates Discord's terms of service</summary> +<summary>Using Equicord (Vencord+) violates Discord's terms of service</summary> Client modifications are against Discord’s Terms of Service. -However, Discord is pretty indifferent about them and there are no known cases of users getting banned for using client mods! So you should generally be fine as long as you don’t use any plugins that implement abusive behaviour. But no worries, all inbuilt plugins are safe to use! +However, Discord is pretty indifferent about them and there are no known cases of users getting banned for using client mods! So you should generally be fine if you don’t use plugins that implement abusive behaviour. But no worries, all inbuilt plugins are safe to use! -Regardless, if your account is very important to you and it getting disabled would be a disaster for you, you should probably not use any client mods (not exclusive to Vencord), just to be safe +Regardless, if your account is essential to you and getting disabled would be a disaster for you, you should probably not use any client mods (not exclusive to Equicord), just to be safe -Additionally, make sure not to post screenshots with Vencord in a server where you might get banned for it +Additionally, make sure not to post screenshots with Equicord in a server where you might get banned for it </details> + +Plugins may take time to be added as I am not on all of the time because of school and stuff. diff --git a/browser/VencordNativeStub.ts b/browser/VencordNativeStub.ts index 77c72369..ea3d1cb5 100644 --- a/browser/VencordNativeStub.ts +++ b/browser/VencordNativeStub.ts @@ -25,7 +25,7 @@ import * as DataStore from "../src/api/DataStore"; import { debounce } from "../src/utils"; import { EXTENSION_BASE_URL } from "../src/utils/web-metadata"; import { getTheme, Theme } from "../src/utils/discord"; -import { getThemeInfo } from "../src/main/themes"; +import { getThemeInfo } from "../src/utils/themes/bd"; import { Settings } from "../src/Vencord"; // Discord deletes this so need to store in variable @@ -47,7 +47,7 @@ window.VencordNative = { deleteTheme: (fileName: string) => DataStore.del(fileName, themeStore), getThemesDir: async () => "", getThemesList: () => DataStore.entries(themeStore).then(entries => - entries.map(([name, css]) => getThemeInfo(css, name.toString())) + entries.map(([name, css]) => ({ fileName: name as string, content: css })) ), getThemeData: (fileName: string) => DataStore.get(fileName, themeStore), getSystemValues: async () => ({}), @@ -59,7 +59,7 @@ window.VencordNative = { }, updater: { - getRepo: async () => ({ ok: true, value: "https://github.com/Vendicated/Vencord" }), + getRepo: async () => ({ ok: true, value: "https://github.com/Equicord/Equicord" }), getUpdates: async () => ({ ok: true, value: [] }), update: async () => ({ ok: true, value: false }), rebuild: async () => ({ ok: true, value: true }), diff --git a/browser/icon.png b/browser/icon.png index dae93c6194119ffd532ba990e73d2be4c64cdce2..15ec35a4662daaec824816925b2cfce432519169 100644 GIT binary patch literal 7720 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 literal 1091 zcmV-J1ibr+P)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP<VFdsH1K3GKK~#7F?VP)g z)G!o=9Yg_Q1y6xQ2NDeh^UOQ~#cV?j1&BwWKnTH7;oX_o8QT-bcc0k)KWUX6k8?Zr zf6lSv3}XNQ00000006*9OaXOy#$&}0a(?bvkDSM>LpZ;-|1?eK^3!%t_*~8TZq{x} zJJ99Ea^GRf`MLPah4J@g{RbYgjuDNvTjQVT(gjI8+|HV;sy0;53Rrr+&3&E9<)8dq zn_d-gwxsC!TyDj8mtb*`2AP{0CJT}nHs(gT4BFM`vH^U1vMpV$N!LNxg-1gbS47uo zXd+yuv8*7YH-OE!yjDguas$|UIIo$Gjv50@BfBhKEEbHU051Pj<C}x9wccMc7L3pU zi_y16#I}S;epjjydUruuZ&wVtR&nbf#l{CnLy75rGOomNSw?zofUL%s?x#e94&{PW zUw+!U{JN}Da$GR%T#z)X+6cY@n`Imq3>SpWj7EJZ<7$i&Y8WyLvZa-#DpVI#Dh+Mc z1-YK{x_Yb2sOtVDgK+l`<=3!HJ8U(`TFl5na}6L3@cYwoE|5-ilHaq<@@KCPn?}6* zIv@AxE4`lj|G)1?_T=T^>KStk!(~B#KF<bT>}fWb;O?8KS2#*G+W^vgO#elJFx1j5 z9pzk<FWuKt&P92thQM49G1(NL1gR{(k-64{a&6PB5}*KLvd4f7O3=EzHI+1aWNjtb zu2;Qu<^dEyOz;~rp`*co_Xe~B|NM9>_Sg4be6SSQRr$Pm{_en1`1|Fk9Zz;u>-88s zj1!n%a~&vvn2;E7Zb|9eeU;!56Sz@tE_G%jle+s>mJ$_%xGu0_*%1^#OiUJ(O9^aq ze_0%<gk&m>6QBTMQpN#EN^sXxPI4kp38|QKO$p<KO`rf`a*Twdl;9-V2PZ!;IUnHW z%^~$hFcNNooO3~WmEg#Na{1s5lBMJW6hKUgCt_KY;F|?m%Nqd-Ag1Iq;UFbk&HIP; zc%!@(pa5cOtcuW-;Ht;W*~myGv;q`BOwDycVF`+5)dR91kd^(ej7wa_&<aohF}qcO z@7m9TSrBGJM_|7(AaLzx#w_T3=wG+`x}YiWJ%pRLe(w)J0mSTB0mf<v@yS;S+0P%i z7S$IhfSCQiArq;D<kNbtz_VSCFHit6?Ytuvs04LS7Ii+ciB*CpPyjJ|o;=*_xj#P4 z?+^Iq<+k<xq2;p2zc{>S4lojKfj!3nTMrUWIBlE|yV_!9-BFSkfdYtW|ECIwl#mN3 zfS7)MtfR6LasdSp)7l~emDDFzsbsMo6aWAK00000004lB+yiyg8!#VHJx>4t002ov JPDHLkV1fj&>l*+7 diff --git a/browser/manifest.json b/browser/manifest.json index 69bf0cec..731a7879 100644 --- a/browser/manifest.json +++ b/browser/manifest.json @@ -1,38 +1,43 @@ { "manifest_version": 3, "minimum_chrome_version": "91", - - "name": "Vencord Web", - "description": "The cutest Discord mod now in your browser", - "author": "Vendicated", - "homepage_url": "https://github.com/Vendicated/Vencord", + "name": "Equicord Web", + "description": "The other cutest Discord mod now in your browser", + "author": "Thororen", + "homepage_url": "https://github.com/Equicord/Equicord", "icons": { "128": "icon.png" }, - "host_permissions": [ "*://*.discord.com/*", "https://raw.githubusercontent.com/*" ], - - "permissions": ["declarativeNetRequest"], - + "permissions": [ + "declarativeNetRequest" + ], "content_scripts": [ { "run_at": "document_start", - "matches": ["*://*.discord.com/*"], - "js": ["content.js"], + "matches": [ + "*://*.discord.com/*" + ], + "js": [ + "content.js" + ], "all_frames": true } ], - "web_accessible_resources": [ { - "resources": ["dist/*", "third-party/*"], - "matches": ["*://*.discord.com/*"] + "resources": [ + "dist/*", + "third-party/*" + ], + "matches": [ + "*://*.discord.com/*" + ] } ], - "declarative_net_request": { "rule_resources": [ { @@ -42,4 +47,4 @@ } ] } -} +} \ No newline at end of file diff --git a/browser/manifestv2.json b/browser/manifestv2.json index 3cac9450..8d2d17e7 100644 --- a/browser/manifestv2.json +++ b/browser/manifestv2.json @@ -1,41 +1,44 @@ { "manifest_version": 2, "minimum_chrome_version": "91", - - "name": "Vencord Web", - "description": "The cutest Discord mod now in your browser", - "author": "Vendicated", - "homepage_url": "https://github.com/Vendicated/Vencord", + "name": "Equicord Web", + "description": "The other cutest Discord mod now in your browser", + "author": "Thororen", + "homepage_url": "https://github.com/Equicord/Equicord", "icons": { "128": "icon.png" }, - "permissions": [ "webRequest", "webRequestBlocking", "*://*.discord.com/*", "https://raw.githubusercontent.com/*" ], - "content_scripts": [ { "run_at": "document_start", - "matches": ["*://*.discord.com/*"], - "js": ["content.js"], + "matches": [ + "*://*.discord.com/*" + ], + "js": [ + "content.js" + ], "all_frames": true } ], - "background": { - "scripts": ["background.js"] + "scripts": [ + "background.js" + ] }, - - "web_accessible_resources": ["dist/Vencord.js", "dist/Vencord.css"], - + "web_accessible_resources": [ + "dist/Vencord.js", + "dist/Vencord.css" + ], "browser_specific_settings": { "gecko": { - "id": "vencord-firefox@vendicated.dev", + "id": "Equicord@equicord.patrickdk.com", "strict_min_version": "91.0" } } -} +} \ No newline at end of file diff --git a/browser/monacoWin.html b/browser/monacoWin.html index a55b0e54..3a6eaa57 100644 --- a/browser/monacoWin.html +++ b/browser/monacoWin.html @@ -1,37 +1,39 @@ <!DOCTYPE html> <html lang="en"> - <head> - <meta charset="utf-8" /> - <title>Vencord QuickCSS Editor - - - -
+ + + Equicord QuickCSS Editor + + - - - + const style = document.createElement("link"); + style.type = "text/css"; + style.rel = "stylesheet"; + style.href = new URL("/dist/monaco/index.css", baseUrl); + + document.body.append(style, script); + + + + \ No newline at end of file diff --git a/docs/1_INSTALLING.md b/docs/1_INSTALLING.md index edeed4eb..d80b41b0 100644 --- a/docs/1_INSTALLING.md +++ b/docs/1_INSTALLING.md @@ -1,26 +1,26 @@ -> [!WARNING] -> These instructions are only for advanced users. If you're not a Developer, you should use our [graphical installer](https://github.com/Vendicated/VencordInstaller#usage) instead. -> No support will be provided for installing in this fashion. If you cannot figure it out, you should just stick to a regular install. +> [!WARNING] +> These instructions are only for advanced users. If you're not a Developer, you should use our [graphical installer](https://github.com/Equicord/Installer#usage) instead. +> No support will be provided for installing in this fashion. If you cannot figure it out, you should just stick to a regular install. # Installation Guide -Welcome to Megu's Installation Guide! In this file, you will learn about how to download, install, and uninstall Vencord! +Welcome to Megu's Installation Guide! In this file, you will learn about how to download, install, and uninstall Equicord! ## Sections - [Installation Guide](#installation-guide) - [Sections](#sections) - [Dependencies](#dependencies) - - [Installing Vencord](#installing-vencord) - - [Updating Vencord](#updating-vencord) - - [Uninstalling Vencord](#uninstalling-vencord) + - [Installing Equicord](#installing-equicord) + - [Updating Equicord](#updating-equicord) + - [Uninstalling Equicord](#uninstalling-equicord) ## Dependencies - Install Git from https://git-scm.com/download - Install Node.JS LTS from here: https://nodejs.dev/en/ -## Installing Vencord +## Installing Equicord Install `pnpm`: @@ -30,13 +30,13 @@ Install `pnpm`: npm i -g pnpm ``` -> :exclamation: **IMPORTANT** Make sure you aren't using an admin/root terminal from here onwards. It **will** mess up your Discord/Vencord instance and you **will** most likely have to reinstall. +> :exclamation: **IMPORTANT** Make sure you aren't using an admin/root terminal from here onwards. It **will** mess up your Discord/Equicord instance and you **will** most likely have to reinstall. -Clone Vencord: +Clone Equicord: ```shell -git clone https://github.com/Vendicated/Vencord -cd Vencord +git clone https://github.com/Equicord/Equicord +cd Equicord ``` Install dependencies: @@ -45,21 +45,19 @@ Install dependencies: pnpm install --frozen-lockfile ``` -Build Vencord: +Build Equicord: ```shell pnpm build ``` -Inject vencord into your client: +Inject Equicord into your client: ```shell pnpm inject ``` -Then fully close Discord from your taskbar or task manager, and restart it. Vencord should be injected - you can check this by looking for the Vencord section in Discord settings. - -## Updating Vencord +Then fully close Discord from your taskbar or task manager, and restart it. Equicord should be injected - you can check this by looking for the Equicord section in Discord settings. If you're using Discord already, go into the `Updater` tab in settings. @@ -71,9 +69,9 @@ To pull latest changes: git pull ``` -If this fails, you likely need to reset your local changes to vencord to resolve merge errors: +If this fails, you likely need to reset your local changes to equicord to resolve merge errors: -> :exclamation: This command will remove any local changes you've made to vencord. Make sure you back up if you made any code changes you don't want to lose! +> :exclamation: This command will remove any local changes you've made to equicord. Make sure you back up if you made any code changes you don't want to lose! ```shell git reset --hard @@ -88,10 +86,12 @@ pnpm build Then just refresh your client -## Uninstalling Vencord +## Uninstalling Equicord Simply run: ```shell pnpm uninject ``` + +If you need more help, ask in the support channel in our [Discord Server](https://discord.gg/D9uwnFnqmd). diff --git a/docs/2_PLUGINS.md b/docs/2_PLUGINS.md index 705ea89d..d794bc03 100644 --- a/docs/2_PLUGINS.md +++ b/docs/2_PLUGINS.md @@ -2,7 +2,7 @@ Welcome to Megu's Plugin Guide! In this file, you will learn about how to write your own plugin! -You don't need to run `pnpm build` every time you make a change. Instead, use `pnpm watch` - this will auto-compile Vencord whenever you make a change. If using code patches (recommended), you will need to CTRL+R to load the changes. +You don't need to run `pnpm build` every time you make a change. Instead, use `pnpm watch` - this will auto-compile Equicord whenever you make a change. If using code patches (recommended), you will need to CTRL+R to load the changes. ## Plugin Entrypoint @@ -37,9 +37,9 @@ Change the name, description, and authors to your own information. Replace `12345n` with your user ID ending in `n` (e.g., `545581357812678656n`). If you don't want to share your Discord account, use `0n` instead! -## How Plugins Work In Vencord +## How Plugins Work In Equicord -Vencord uses a different way of making mods than you're used to. +Equicord uses a different way of making mods than you're used to. Instead of monkeypatching webpack, we directly modify the code before Discord loads it. This is _significantly_ more efficient than monkeypatching webpack, and is surprisingly easy, but it may be confusing at first. @@ -103,7 +103,7 @@ The match value _can_ be a string, rather than regex, however usually regex will Once you've made your plugin, make sure you run `pnpm test` and make sure your code is nice and clean! -If you want to publish your plugin into the Vencord repo, move your plugin from `src/userplugins` into the `src/plugins` folder and open a PR! +If you want to publish your plugin into the Equicord repo, move your plugin from `src/userplugins` into the `src/plugins` folder and open a PR! > **Warning** > Make sure you've read [CONTRIBUTING.md](../CONTRIBUTING.md) before opening a PR diff --git a/package.json b/package.json index 723a40cb..12c223b0 100644 --- a/package.json +++ b/package.json @@ -2,17 +2,22 @@ "name": "vencord", "private": "true", "version": "1.7.7", - "description": "The cutest Discord client mod", - "homepage": "https://github.com/Vendicated/Vencord#readme", + "description": "The cutest Discord client mod with extras", + "homepage": "https://github.com/Equicord/Equicord#readme", "bugs": { - "url": "https://github.com/Vendicated/Vencord/issues" + "url": "https://github.com/Equicord/Equicord/issues" }, "repository": { "type": "git", - "url": "git+https://github.com/Vendicated/Vencord.git" + "url": "git+https://github.com/Equicord/Equicord.git" }, "license": "GPL-3.0-or-later", "author": "Vendicated", + "contributors": [ + "Equicord", + "Thororen1234", + "Yeetov" + ], "directories": { "doc": "docs" }, @@ -24,7 +29,7 @@ "lint": "eslint . --ext .js,.jsx,.ts,.tsx --ignore-pattern src/userplugins", "lint-styles": "stylelint \"src/**/*.css\" --ignore-pattern src/userplugins", "lint:fix": "pnpm lint --fix", - "test": "pnpm build && pnpm lint && pnpm lint-styles && pnpm testTsc && pnpm generatePluginJson", + "test": "pnpm build && pnpm lint:fix && pnpm lint-styles && pnpm testTsc && pnpm generatePluginJson", "testWeb": "pnpm lint && pnpm buildWeb && pnpm testTsc", "testTsc": "tsc --noEmit", "uninject": "node scripts/runInstaller.mjs", @@ -32,16 +37,21 @@ }, "dependencies": { "@sapphi-red/web-noise-suppressor": "0.3.3", + "@types/less": "^3.0.6", + "@types/stylus": "^0.48.42", + "@types/tinycolor2": "^1.4.6", "@vap/core": "0.0.12", "@vap/shiki": "0.10.5", - "eslint-plugin-simple-header": "^1.0.2", + "axios": "^1.6.8", "fflate": "^0.7.4", "gifenc": "github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3", "monaco-editor": "^0.43.0", "nanoid": "^4.0.2", + "usercss-meta": "^0.12.0", "virtual-merge": "^1.0.1" }, "devDependencies": { + "@react-spring/web": "^9.7.3", "@types/chrome": "^0.0.246", "@types/diff": "^5.0.3", "@types/lodash": "^4.14.194", @@ -56,7 +66,7 @@ "esbuild": "^0.15.18", "eslint": "^8.46.0", "eslint-import-resolver-alias": "^1.1.2", - "eslint-plugin-path-alias": "^1.0.0", + "eslint-plugin-simple-header": "^1.0.2", "eslint-plugin-simple-import-sort": "^10.0.0", "eslint-plugin-unused-imports": "^2.0.0", "highlight.js": "10.6.0", @@ -74,8 +84,8 @@ "packageManager": "pnpm@8.10.2", "pnpm": { "patchedDependencies": { - "eslint-plugin-path-alias@1.0.0": "patches/eslint-plugin-path-alias@1.0.0.patch", - "eslint@8.46.0": "patches/eslint@8.46.0.patch" + "eslint@8.46.0": "patches/eslint@8.46.0.patch", + "@types/less@3.0.6": "patches/@types__less@3.0.6.patch" }, "peerDependencyRules": { "ignoreMissing": [ @@ -101,4 +111,4 @@ "node": ">=18", "pnpm": ">=8" } -} +} \ No newline at end of file diff --git a/patches/@types__less@3.0.6.patch b/patches/@types__less@3.0.6.patch new file mode 100644 index 00000000..b9791284 --- /dev/null +++ b/patches/@types__less@3.0.6.patch @@ -0,0 +1,13 @@ +diff --git a/index.d.ts b/index.d.ts +index eb4f07d47b932fb9cc8c8cd451ab107f648bd013..18a3e15a1997734e1773718e5be55d252ed9478c 100644 +--- a/index.d.ts ++++ b/index.d.ts +@@ -306,7 +306,5 @@ interface LessStatic { + } + + declare module "less" { +- export = less; ++ export = LessStatic; + } +- +-declare var less: LessStatic; \ No newline at end of file diff --git a/patches/eslint-plugin-path-alias@1.0.0.patch b/patches/eslint-plugin-path-alias@1.0.0.patch deleted file mode 100644 index 49c46b3d..00000000 --- a/patches/eslint-plugin-path-alias@1.0.0.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/lib/rules/no-relative.js b/lib/rules/no-relative.js -index 71594c83f1f4f733ffcc6047d7f7084348335dbe..d8623d87c89499c442171db3272cba07c9efabbe 100644 ---- a/lib/rules/no-relative.js -+++ b/lib/rules/no-relative.js -@@ -41,7 +41,7 @@ module.exports = { - ImportDeclaration(node) { - const importPath = node.source.value; - -- if (!/^(\.?\.\/)/.test(importPath)) { -+ if (!/^(\.\.\/)/.test(importPath)) { - return; - } - \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 43866f50..96562d57 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,9 +1,13 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + patchedDependencies: - eslint-plugin-path-alias@1.0.0: - hash: m6sma4g6bh67km3q6igf6uxaja - path: patches/eslint-plugin-path-alias@1.0.0.patch + '@types/less@3.0.6': + hash: krcufrsfhsuxuoj7hocqugs6zi + path: patches/@types__less@3.0.6.patch eslint@8.46.0: hash: xm46kqcmdgzlmm4aifkfpxaho4 path: patches/eslint@8.46.0.patch @@ -12,15 +16,24 @@ dependencies: '@sapphi-red/web-noise-suppressor': specifier: 0.3.3 version: 0.3.3 + '@types/less': + specifier: ^3.0.6 + version: 3.0.6(patch_hash=krcufrsfhsuxuoj7hocqugs6zi) + '@types/stylus': + specifier: ^0.48.42 + version: 0.48.42 + '@types/tinycolor2': + specifier: ^1.4.6 + version: 1.4.6 '@vap/core': specifier: 0.0.12 version: 0.0.12 '@vap/shiki': specifier: 0.10.5 version: 0.10.5 - eslint-plugin-simple-header: - specifier: ^1.0.2 - version: 1.0.2 + axios: + specifier: ^1.6.8 + version: 1.6.8 fflate: specifier: ^0.7.4 version: 0.7.4 @@ -33,11 +46,17 @@ dependencies: nanoid: specifier: ^4.0.2 version: 4.0.2 + usercss-meta: + specifier: ^0.12.0 + version: 0.12.0 virtual-merge: specifier: ^1.0.1 version: 1.0.1 devDependencies: + '@react-spring/web': + specifier: ^9.7.3 + version: 9.7.3(react-dom@18.2.0)(react@18.2.0) '@types/chrome': specifier: ^0.0.246 version: 0.0.246 @@ -80,9 +99,9 @@ devDependencies: eslint-import-resolver-alias: specifier: ^1.1.2 version: 1.1.2 - eslint-plugin-path-alias: - specifier: ^1.0.0 - version: 1.0.0(patch_hash=m6sma4g6bh67km3q6igf6uxaja)(eslint@8.46.0) + eslint-plugin-simple-header: + specifier: ^1.0.2 + version: 1.0.2 eslint-plugin-simple-import-sort: specifier: ^10.0.0 version: 10.0.0(eslint@8.46.0) @@ -121,7 +140,7 @@ devDependencies: version: 0.3.5 zustand: specifier: ^3.7.2 - version: 3.7.2 + version: 3.7.2(react@18.2.0) packages: @@ -531,6 +550,54 @@ packages: - supports-color dev: true + /@react-spring/animated@9.7.3(react@18.2.0): + resolution: {integrity: sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@react-spring/shared': 9.7.3(react@18.2.0) + '@react-spring/types': 9.7.3 + react: 18.2.0 + dev: true + + /@react-spring/core@9.7.3(react@18.2.0): + resolution: {integrity: sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@react-spring/animated': 9.7.3(react@18.2.0) + '@react-spring/shared': 9.7.3(react@18.2.0) + '@react-spring/types': 9.7.3 + react: 18.2.0 + dev: true + + /@react-spring/shared@9.7.3(react@18.2.0): + resolution: {integrity: sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@react-spring/types': 9.7.3 + react: 18.2.0 + dev: true + + /@react-spring/types@9.7.3: + resolution: {integrity: sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw==} + dev: true + + /@react-spring/web@9.7.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@react-spring/animated': 9.7.3(react@18.2.0) + '@react-spring/core': 9.7.3(react@18.2.0) + '@react-spring/shared': 9.7.3(react@18.2.0) + '@react-spring/types': 9.7.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + /@sapphi-red/web-noise-suppressor@0.3.3: resolution: {integrity: sha512-gAC33DCXYwNTI/k1PxOVHmbbzakUSMbb/DHpoV6rn4pKZtPI1dduULSmAAm/y1ipgIlArnk2JcnQzw4n2tCZHw==} dev: false @@ -564,6 +631,11 @@ packages: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} dev: true + /@types/less@3.0.6(patch_hash=krcufrsfhsuxuoj7hocqugs6zi): + resolution: {integrity: sha512-PecSzorDGdabF57OBeQO/xFbAkYWo88g4Xvnsx7LRwqLC17I7OoKtA3bQB9uXkY6UkMWCOsA8HSVpaoitscdXw==} + dev: false + patched: true + /@types/lodash@4.14.194: resolution: {integrity: sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g==} dev: true @@ -574,7 +646,6 @@ packages: /@types/node@18.16.3: resolution: {integrity: sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==} - dev: true /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -613,6 +684,16 @@ packages: resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} dev: true + /@types/stylus@0.48.42: + resolution: {integrity: sha512-CPGlr5teL4sqdap+EOowMifLuNGeIoLwc0VQ7u/BPxo+ocqiNa5jeVt0H0IVBblEh6ZwX1sGpIQIFnSSr8NBQA==} + dependencies: + '@types/node': 18.16.3 + dev: false + + /@types/tinycolor2@1.4.6: + resolution: {integrity: sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==} + dev: false + /@types/yauzl@2.10.0: resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} requiresBuild: true @@ -844,36 +925,16 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true - /arr-diff@4.0.0: - resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} - engines: {node: '>=0.10.0'} - dev: true - - /arr-union@3.1.0: - resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} - engines: {node: '>=0.10.0'} - dev: true - /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true - /array-unique@0.3.2: - resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} - engines: {node: '>=0.10.0'} - dev: true - /arrify@1.0.1: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} dev: true - /assign-symbols@1.0.0: - resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} - engines: {node: '>=0.10.0'} - dev: true - /astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -883,11 +944,19 @@ packages: resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} dev: true - /atob@2.1.2: - resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} - engines: {node: '>= 4.5.0'} - hasBin: true - dev: true + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /axios@1.6.8: + resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -901,19 +970,6 @@ packages: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: true - /base@0.11.2: - resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} - engines: {node: '>=0.10.0'} - dependencies: - cache-base: 1.0.1 - class-utils: 0.3.6 - component-emitter: 1.3.0 - define-property: 1.0.0 - isobject: 3.0.1 - mixin-deep: 1.3.2 - pascalcase: 0.1.1 - dev: true - /bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} dependencies: @@ -951,21 +1007,6 @@ packages: ieee754: 1.2.1 dev: true - /cache-base@1.0.1: - resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} - engines: {node: '>=0.10.0'} - dependencies: - collection-visit: 1.0.0 - component-emitter: 1.3.0 - get-value: 2.0.6 - has-value: 1.0.0 - isobject: 3.0.1 - set-value: 2.0.1 - to-object-path: 0.3.0 - union-value: 1.0.1 - unset-value: 1.0.0 - dev: true - /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1015,16 +1056,6 @@ packages: mitt: 3.0.0 dev: true - /class-utils@0.3.6: - resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-union: 3.1.0 - define-property: 0.2.5 - isobject: 3.0.1 - static-extend: 0.1.2 - dev: true - /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -1034,14 +1065,6 @@ packages: wrap-ansi: 7.0.0 dev: true - /collection-visit@1.0.0: - resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} - engines: {node: '>=0.10.0'} - dependencies: - map-visit: 1.0.0 - object-visit: 1.0.1 - dev: true - /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -1067,19 +1090,17 @@ packages: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} dev: true - /component-emitter@1.3.0: - resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} - dev: true + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true - /copy-descriptor@0.1.1: - resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} - engines: {node: '>=0.10.0'} - dev: true - /cosmiconfig@8.1.3: resolution: {integrity: sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==} engines: {node: '>=14'} @@ -1130,17 +1151,6 @@ packages: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} dev: true - /debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - dev: true - /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -1166,36 +1176,14 @@ packages: engines: {node: '>=0.10.0'} dev: true - /decode-uri-component@0.2.0: - resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} - engines: {node: '>=0.10'} - dev: true - /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true - /define-property@0.2.5: - resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 0.1.6 - dev: true - - /define-property@1.0.0: - resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - dev: true - - /define-property@2.0.2: - resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - isobject: 3.0.1 - dev: true + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false /devtools-protocol@0.0.1107588: resolution: {integrity: sha512-yIR+pG9x65Xko7bErCUSQaDLrO/P1p3JUzEk7JCU4DowPcGHkTGUGQapcfcLc4qj0UaALwZ+cr0riFgiqpixcg==} @@ -1508,24 +1496,9 @@ packages: optional: true dev: true - /eslint-plugin-path-alias@1.0.0(patch_hash=m6sma4g6bh67km3q6igf6uxaja)(eslint@8.46.0): - resolution: {integrity: sha512-FXus57yC+Zd3sMv46pbloXYwFeNVNHJqlACr9V68FG/IzGFBBokGJpmjDbEjpt8ZCeVSndUubeDWWl2A8sCNVQ==} - peerDependencies: - eslint: ^7 - peerDependenciesMeta: - eslint: - optional: true - dependencies: - eslint: 8.46.0(patch_hash=xm46kqcmdgzlmm4aifkfpxaho4) - nanomatch: 1.2.13 - transitivePeerDependencies: - - supports-color - dev: true - patched: true - /eslint-plugin-simple-header@1.0.2: resolution: {integrity: sha512-K1EJ/ueBIjPRA8qR44Ymo+GDmPYYmfoODtainGxVr7PSbX6QiaY+pTuGCrOhO+AtVsYJs8GLSVdGUTXyAxAtOA==} - dev: false + dev: true /eslint-plugin-simple-import-sort@10.0.0(eslint@8.46.0): resolution: {integrity: sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==} @@ -1675,21 +1648,6 @@ packages: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} dev: false - /extend-shallow@2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - dependencies: - is-extendable: 0.1.1 - dev: true - - /extend-shallow@3.0.2: - resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} - engines: {node: '>=0.10.0'} - dependencies: - assign-symbols: 1.0.0 - is-extendable: 1.0.1 - dev: true - /extract-zip@2.0.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} engines: {node: '>= 10.17.0'} @@ -1790,17 +1748,24 @@ packages: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} dev: true - /for-in@1.0.2: - resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} - engines: {node: '>=0.10.0'} - dev: true + /follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false - /fragment-cache@0.2.1: - resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} - engines: {node: '>=0.10.0'} + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} dependencies: - map-cache: 0.2.2 - dev: true + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false /fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -1838,11 +1803,6 @@ packages: resolution: {integrity: sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==} dev: true - /get-value@2.0.6: - resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} - engines: {node: '>=0.10.0'} - dev: true - /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1934,37 +1894,6 @@ packages: engines: {node: '>=8'} dev: true - /has-value@0.3.1: - resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} - engines: {node: '>=0.10.0'} - dependencies: - get-value: 2.0.6 - has-values: 0.1.4 - isobject: 2.1.0 - dev: true - - /has-value@1.0.0: - resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} - engines: {node: '>=0.10.0'} - dependencies: - get-value: 2.0.6 - has-values: 1.0.0 - isobject: 3.0.1 - dev: true - - /has-values@0.1.4: - resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} - engines: {node: '>=0.10.0'} - dev: true - - /has-values@1.0.0: - resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 3.0.0 - kind-of: 4.0.0 - dev: true - /has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} @@ -2049,78 +1978,16 @@ packages: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: true - /is-accessor-descriptor@0.1.6: - resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-accessor-descriptor@1.0.0: - resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 - dev: true - /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} dev: true - /is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: true - /is-core-module@2.12.0: resolution: {integrity: sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==} dependencies: has: 1.0.3 dev: true - /is-data-descriptor@0.1.4: - resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-data-descriptor@1.0.0: - resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 - dev: true - - /is-descriptor@0.1.6: - resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 0.1.6 - is-data-descriptor: 0.1.4 - kind-of: 5.1.0 - dev: true - - /is-descriptor@1.0.2: - resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 1.0.0 - is-data-descriptor: 1.0.0 - kind-of: 6.0.3 - dev: true - - /is-extendable@0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - dev: true - - /is-extendable@1.0.1: - resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} - engines: {node: '>=0.10.0'} - dependencies: - is-plain-object: 2.0.4 - dev: true - /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2138,13 +2005,6 @@ packages: is-extglob: 2.1.1 dev: true - /is-number@3.0.0: - resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -2160,43 +2020,15 @@ packages: engines: {node: '>=0.10.0'} dev: true - /is-plain-object@2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - /is-plain-object@5.0.0: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} dev: true - /is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - dev: true - - /isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - dev: true - /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /isobject@2.1.0: - resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} - engines: {node: '>=0.10.0'} - dependencies: - isarray: 1.0.0 - dev: true - - /isobject@3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - dev: true - /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true @@ -2234,25 +2066,6 @@ packages: pako: 1.0.11 dev: true - /kind-of@3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: true - - /kind-of@4.0.0: - resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: true - - /kind-of@5.1.0: - resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} - engines: {node: '>=0.10.0'} - dev: true - /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -2296,6 +2109,13 @@ packages: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} dev: true + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -2303,11 +2123,6 @@ packages: yallist: 4.0.0 dev: true - /map-cache@0.2.2: - resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} - engines: {node: '>=0.10.0'} - dev: true - /map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -2318,13 +2133,6 @@ packages: engines: {node: '>=8'} dev: true - /map-visit@1.0.0: - resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} - engines: {node: '>=0.10.0'} - dependencies: - object-visit: 1.0.1 - dev: true - /mathml-tag-names@2.1.3: resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} dev: true @@ -2364,6 +2172,18 @@ packages: picomatch: 2.3.1 dev: true + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + /min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -2388,14 +2208,6 @@ packages: resolution: {integrity: sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==} dev: true - /mixin-deep@1.3.2: - resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} - engines: {node: '>=0.10.0'} - dependencies: - for-in: 1.0.2 - is-extendable: 1.0.1 - dev: true - /mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} dev: true @@ -2408,10 +2220,6 @@ packages: resolution: {integrity: sha512-cnoqwQi/9fml2Szamv1XbSJieGJ1Dc8tENVMD26Kcfl7xGQWp7OBKMjlwKVGYFJ3/AXJjSOGvcqK7Ry/j9BM1Q==} dev: false - /ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - dev: true - /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true @@ -2428,25 +2236,6 @@ packages: hasBin: true dev: false - /nanomatch@1.2.13: - resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} - engines: {node: '>=0.10.0'} - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - fragment-cache: 0.2.1 - is-windows: 1.0.2 - kind-of: 6.0.3 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true @@ -2491,29 +2280,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /object-copy@0.1.0: - resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} - engines: {node: '>=0.10.0'} - dependencies: - copy-descriptor: 0.1.1 - define-property: 0.2.5 - kind-of: 3.2.2 - dev: true - - /object-visit@1.0.1: - resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - - /object.pick@1.3.0: - resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -2586,11 +2352,6 @@ packages: lines-and-columns: 1.2.4 dev: true - /pascalcase@0.1.1: - resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} - engines: {node: '>=0.10.0'} - dev: true - /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2678,7 +2439,6 @@ packages: /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: true /pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} @@ -2734,6 +2494,23 @@ packages: engines: {node: '>=8'} dev: true + /react-dom@18.2.0(react@18.2.0): + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + peerDependencies: + react: ^18.2.0 + dependencies: + loose-envify: 1.4.0 + react: 18.2.0 + scheduler: 0.23.0 + dev: true + + /react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + dev: true + /read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -2770,14 +2547,6 @@ packages: strip-indent: 3.0.0 dev: true - /regex-not@1.0.2: - resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 3.0.2 - safe-regex: 1.1.0 - dev: true - /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -2798,11 +2567,6 @@ packages: engines: {node: '>=8'} dev: true - /resolve-url@0.2.1: - resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} - deprecated: https://github.com/lydell/resolve-url#deprecated - dev: true - /resolve@1.22.2: resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} hasBin: true @@ -2812,11 +2576,6 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true - /ret@0.1.15: - resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} - engines: {node: '>=0.12'} - dev: true - /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -2839,10 +2598,10 @@ packages: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: true - /safe-regex@1.1.0: - resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + /scheduler@0.23.0: + resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} dependencies: - ret: 0.1.15 + loose-envify: 1.4.0 dev: true /semver@5.7.1: @@ -2858,16 +2617,6 @@ packages: lru-cache: 6.0.0 dev: true - /set-value@2.0.1: - resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 2.0.1 - is-extendable: 0.1.1 - is-plain-object: 2.0.4 - split-string: 3.1.0 - dev: true - /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2899,38 +2648,11 @@ packages: is-fullwidth-code-point: 3.0.0 dev: true - /snapdragon@0.8.2: - resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} - engines: {node: '>=0.10.0'} - dependencies: - base: 0.11.2 - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - map-cache: 0.2.2 - source-map: 0.5.7 - source-map-resolve: 0.5.3 - use: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} dev: true - /source-map-resolve@0.5.3: - resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} - deprecated: See https://github.com/lydell/source-map-resolve#deprecated - dependencies: - atob: 2.1.2 - decode-uri-component: 0.2.0 - resolve-url: 0.2.1 - source-map-url: 0.4.1 - urix: 0.1.0 - dev: true - /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -2938,16 +2660,6 @@ packages: source-map: 0.6.1 dev: true - /source-map-url@0.4.1: - resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} - deprecated: See https://github.com/lydell/source-map-url#deprecated - dev: true - - /source-map@0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} - dev: true - /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} @@ -2975,27 +2687,12 @@ packages: resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} dev: true - /split-string@3.1.0: - resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 3.0.2 - dev: true - /standalone-electron-types@1.0.0: resolution: {integrity: sha512-0HOi/tlTz3mjWhsAz4uRbpQcHMZ+ifj1JzWW9nugykOHClBBG77ps8QinrzX1eow4Iw2pnC+RFaSYRgufF4BOg==} dependencies: '@types/node': 18.16.3 dev: true - /static-extend@0.1.2: - resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 0.2.5 - object-copy: 0.1.0 - dev: true - /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -3172,13 +2869,6 @@ packages: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true - /to-object-path@0.3.0: - resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -3186,16 +2876,6 @@ packages: is-number: 7.0.0 dev: true - /to-regex@3.0.2: - resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 2.0.2 - extend-shallow: 3.0.2 - regex-not: 1.0.2 - safe-regex: 1.1.0 - dev: true - /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: true @@ -3275,39 +2955,16 @@ packages: through: 2.3.8 dev: true - /union-value@1.0.1: - resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-union: 3.1.0 - get-value: 2.0.6 - is-extendable: 0.1.1 - set-value: 2.0.1 - dev: true - - /unset-value@1.0.0: - resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} - engines: {node: '>=0.10.0'} - dependencies: - has-value: 0.3.1 - isobject: 3.0.1 - dev: true - /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.1.1 dev: true - /urix@0.1.0: - resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} - deprecated: Please see https://github.com/lydell/urix#deprecated - dev: true - - /use@3.1.1: - resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} - engines: {node: '>=0.10.0'} - dev: true + /usercss-meta@0.12.0: + resolution: {integrity: sha512-zKrXCKdpeIwtVe87omxGo9URf+7mbozduMZEg79dmT4KB3XJwfIkEi/Uk0PcTwR/nZLtAK1+k7isgbGB/g6E7Q==} + engines: {node: '>=8.3'} + dev: false /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -3449,7 +3106,7 @@ packages: q: 1.5.1 dev: true - /zustand@3.7.2: + /zustand@3.7.2(react@18.2.0): resolution: {integrity: sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==} engines: {node: '>=12.7.0'} peerDependencies: @@ -3457,6 +3114,8 @@ packages: peerDependenciesMeta: react: optional: true + dependencies: + react: 18.2.0 dev: true github.com/mattdesl/gifenc/64842fca317b112a8590f8fef2bf3825da8f6fe3: @@ -3464,7 +3123,3 @@ packages: name: gifenc version: 1.0.3 dev: false - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false diff --git a/scripts/build/build.mjs b/scripts/build/build.mjs index 0c2a930a..0776c093 100755 --- a/scripts/build/build.mjs +++ b/scripts/build/build.mjs @@ -67,7 +67,7 @@ const globNativesPlugin = { }); build.onLoad({ filter, namespace: "import-natives" }, async () => { - const pluginDirs = ["plugins", "userplugins"]; + const pluginDirs = ["plugins", "userplugins", "equicordplugins"]; let code = ""; let natives = "\n"; let i = 0; diff --git a/scripts/build/common.mjs b/scripts/build/common.mjs index 5c34ad03..f50cc2ea 100644 --- a/scripts/build/common.mjs +++ b/scripts/build/common.mjs @@ -81,7 +81,7 @@ export const globPlugins = kind => ({ }); build.onLoad({ filter, namespace: "import-plugins" }, async () => { - const pluginDirs = ["plugins/_api", "plugins/_core", "plugins", "userplugins"]; + const pluginDirs = ["plugins/_api", "plugins/_core", "plugins", "userplugins", "equicordplugins"]; let code = ""; let plugins = "\n"; let i = 0; diff --git a/scripts/generateReport.ts b/scripts/generateReport.ts index 41e38429..5d745d99 100644 --- a/scripts/generateReport.ts +++ b/scripts/generateReport.ts @@ -79,7 +79,7 @@ function toCodeBlock(s: string) { async function printReport() { console.log(); - console.log("# Vencord Report" + (CANARY ? " (Canary)" : "")); + console.log("# Equicord Report" + (CANARY ? " (Canary)" : "")); console.log(); @@ -136,9 +136,9 @@ async function printReport() { "Content-Type": "application/json" }, body: JSON.stringify({ - description: "Here's the latest Vencord Report!", - username: "Vencord Reporter" + (CANARY ? " (Canary)" : ""), - avatar_url: "https://cdn.discordapp.com/avatars/1017176847865352332/c312b6b44179ae6817de7e4b09e9c6af.webp?size=512", + description: "Here's the latest Equicord Report!", + username: "Equicord Reporter" + (CANARY ? " (Canary)" : ""), + avatar_url: "https://avatars.githubusercontent.com/u/150590884?s=48&v=4", embeds: [ { title: "Bad Patches", @@ -269,7 +269,7 @@ page.on("pageerror", e => console.error("[Page Error]", e)); await page.setBypassCSP(true); -function runTime(token: string) { +async function runtime(token: string) { console.log("[PUP_DEBUG]", "Starting test..."); try { @@ -282,9 +282,13 @@ function runTime(token: string) { // Monkey patch Logger to not log with custom css // @ts-ignore + const originalLog = Vencord.Util.Logger.prototype._log; + // @ts-ignore Vencord.Util.Logger.prototype._log = function (level, levelColor, args) { if (level === "warn" || level === "error") - console[level]("[Vencord]", this.name + ":", ...args); + return console[level]("[Vencord]", this.name + ":", ...args); + + return originalLog.call(this, level, levelColor, args); }; // Force enable all plugins and patches @@ -299,6 +303,9 @@ function runTime(token: string) { delete patch.predicate; delete patch.group; + if (!Array.isArray(patch.find)) + patch.find = [patch.find]; + if (!Array.isArray(patch.replacement)) patch.replacement = [patch.replacement]; @@ -310,45 +317,30 @@ function runTime(token: string) { }); }); - Vencord.Webpack.waitFor( - "loginToken", - m => { - console.log("[PUP_DEBUG]", "Logging in with token..."); - m.loginToken(token); - } - ); + let wreq: typeof Vencord.Webpack.wreq; - // Force load all chunks - Vencord.Webpack.onceReady.then(() => setTimeout(async () => { - console.log("[PUP_DEBUG]", "Webpack is ready!"); + const { canonicalizeMatch, Logger } = Vencord.Util; - const { wreq } = Vencord.Webpack; + const validChunks = new Set(); + const invalidChunks = new Set(); - console.log("[PUP_DEBUG]", "Loading all chunks..."); + let chunksSearchingResolve: (value: void | PromiseLike) => void; + const chunksSearchingDone = new Promise(r => chunksSearchingResolve = r); - let chunks = null as Record | null; - const sym = Symbol("Vencord.chunksExtract"); + // True if resolved, false otherwise + const chunksSearchPromises = [] as Array<() => boolean>; + const lazyChunkRegex = canonicalizeMatch(/Promise\.all\((\[\i\.\i\(".+?"\).+?\])\).then\(\i\.bind\(\i,"(.+?)"\)\)/g); + const chunkIdsRegex = canonicalizeMatch(/\("(.+?)"\)/g); - Object.defineProperty(Object.prototype, sym, { - get() { - chunks = this; - }, - set() { }, - configurable: true, - }); + async function searchAndLoadLazyChunks(factoryCode: string) { + const lazyChunks = factoryCode.matchAll(lazyChunkRegex); + const validChunkGroups = new Set<[chunkIds: string[], entryPoint: string]>(); - await (wreq as any).el(sym); - delete Object.prototype[sym]; + await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => { + const chunkIds = Array.from(rawChunkIds.matchAll(chunkIdsRegex)).map(m => m[1]); + if (chunkIds.length === 0) return; - const validChunksEntryPoints = new Set(); - const validChunks = new Set(); - const invalidChunks = new Set(); - - if (!chunks) throw new Error("Failed to get chunks"); - - for (const entryPoint in chunks) { - const chunkIds = chunks[entryPoint]; - let invalidEntryPoint = false; + let invalidChunkGroup = false; for (const id of chunkIds) { if (wreq.u(id) == null || wreq.u(id) === "undefined.js") continue; @@ -359,56 +351,28 @@ function runTime(token: string) { if (isWasm) { invalidChunks.add(id); - invalidEntryPoint = true; + invalidChunkGroup = true; continue; } validChunks.add(id); } - if (!invalidEntryPoint) - validChunksEntryPoints.add(entryPoint); - } + if (!invalidChunkGroup) { + validChunkGroups.add([chunkIds, entryPoint]); + } + })); - for (const entryPoint of validChunksEntryPoints) { - try { - // Loads all chunks required for an entry point - await (wreq as any).el(entryPoint); - } catch (err) { } - } + // Loads all found valid chunk groups + await Promise.all( + Array.from(validChunkGroups) + .map(([chunkIds]) => + Promise.all(chunkIds.map(id => wreq.e(id as any).catch(() => { }))) + ) + ); - // Matches "id" or id: - const chunkIdRegex = /(?:"(\d+?)")|(?:(\d+?):)/g; - const wreqU = wreq.u.toString(); - - const allChunks = [] as string[]; - let currentMatch: RegExpExecArray | null; - - while ((currentMatch = chunkIdRegex.exec(wreqU)) != null) { - const id = currentMatch[1] ?? currentMatch[2]; - if (id == null) continue; - - allChunks.push(id); - } - - if (allChunks.length === 0) throw new Error("Failed to get all chunks"); - const chunksLeft = allChunks.filter(id => { - return !(validChunks.has(id) || invalidChunks.has(id)); - }); - - for (const id of chunksLeft) { - const isWasm = await fetch(wreq.p + wreq.u(id)) - .then(r => r.text()) - .then(t => t.includes(".module.wasm") || !t.includes("(this.webpackChunkdiscord_app=this.webpackChunkdiscord_app||[]).push")); - - // Loads a chunk - if (!isWasm) await wreq.e(id as any); - } - - // Make sure every chunk has finished loading - await new Promise(r => setTimeout(r, 1000)); - - for (const entryPoint of validChunksEntryPoints) { + // Requires the entry points for all valid chunk groups + for (const [, entryPoint] of validChunkGroups) { try { if (wreq.m[entryPoint]) wreq(entryPoint as any); } catch (err) { @@ -416,54 +380,139 @@ function runTime(token: string) { } } - console.log("[PUP_DEBUG]", "Finished loading all chunks!"); + // setImmediate to only check if all chunks were loaded after this function resolves + // We check if all chunks were loaded every time a factory is loaded + // If we are still looking for chunks in the other factories, the array will have that factory's chunk search promise not resolved + // But, if all chunk search promises are resolved, this means we found every lazy chunk loaded by Discord code and manually loaded them + setTimeout(() => { + let allResolved = true; - for (const patch of Vencord.Plugins.patches) { - if (!patch.all) { - new Vencord.Util.Logger("WebpackInterceptor").warn(`Patch by ${patch.plugin} found no module (Module id is -): ${patch.find}`); - } - } + for (let i = 0; i < chunksSearchPromises.length; i++) { + const isResolved = chunksSearchPromises[i](); - for (const [searchType, args] of Vencord.Webpack.lazyWebpackSearchHistory) { - let method = searchType; - - if (searchType === "findComponent") method = "find"; - if (searchType === "findExportedComponent") method = "findByProps"; - if (searchType === "waitFor" || searchType === "waitForComponent") { - if (typeof args[0] === "string") method = "findByProps"; - else method = "find"; - } - if (searchType === "waitForStore") method = "findStore"; - - try { - let result: any; - - if (method === "proxyLazyWebpack" || method === "LazyComponentWebpack") { - const [factory] = args; - result = factory(); - } else if (method === "extractAndLoadChunks") { - const [code, matcher] = args; - - const module = Vencord.Webpack.findModuleFactory(...code); - if (module) result = module.toString().match(Vencord.Util.canonicalizeMatch(matcher)); + if (isResolved) { + // Remove finished promises to avoid having to iterate through a huge array everytime + chunksSearchPromises.splice(i--, 1); } else { - // @ts-ignore - result = Vencord.Webpack[method](...args); + allResolved = false; } - - if (result == null || ("$$vencordInternal" in result && result.$$vencordInternal() == null)) throw "a rock at ben shapiro"; - } catch (e) { - let logMessage = searchType; - if (method === "find" || method === "proxyLazyWebpack" || method === "LazyComponentWebpack") logMessage += `(${args[0].toString().slice(0, 147)}...)`; - else if (method === "extractAndLoadChunks") logMessage += `([${args[0].map(arg => `"${arg}"`).join(", ")}], ${args[1].toString()})`; - else logMessage += `(${args.map(arg => `"${arg}"`).join(", ")})`; - - console.log("[PUP_WEBPACK_FIND_FAIL]", logMessage); } - } - setTimeout(() => console.log("[PUPPETEER_TEST_DONE_SIGNAL]"), 1000); - }, 1000)); + if (allResolved) chunksSearchingResolve(); + }, 0); + } + + Vencord.Webpack.waitFor( + "loginToken", + m => { + console.log("[PUP_DEBUG]", "Logging in with token..."); + m.loginToken(token); + } + ); + + Vencord.Webpack.beforeInitListeners.add(async webpackRequire => { + console.log("[PUP_DEBUG]", "Loading all chunks..."); + + wreq = webpackRequire; + + Vencord.Webpack.factoryListeners.add(factory => { + let isResolved = false; + searchAndLoadLazyChunks(factory.toString()).then(() => isResolved = true); + + chunksSearchPromises.push(() => isResolved); + }); + + // setImmediate to only search the initial factories after Discord initialized the app + // our beforeInitListeners are called before Discord initializes the app + setTimeout(() => { + for (const factoryId in wreq.m) { + let isResolved = false; + searchAndLoadLazyChunks(wreq.m[factoryId].toString()).then(() => isResolved = true); + + chunksSearchPromises.push(() => isResolved); + } + }, 0); + }); + + await chunksSearchingDone; + + // All chunks Discord has mapped to asset files, even if they are not used anymore + const allChunks = [] as string[]; + + // Matches "id" or id: + for (const currentMatch of wreq!.u.toString().matchAll(/(?:"(\d+?)")|(?:(\d+?):)/g)) { + const id = currentMatch[1] ?? currentMatch[2]; + if (id == null) continue; + + allChunks.push(id); + } + + if (allChunks.length === 0) throw new Error("Failed to get all chunks"); + + // Chunks that are not loaded (not used) by Discord code anymore + const chunksLeft = allChunks.filter(id => { + return !(validChunks.has(id) || invalidChunks.has(id)); + }); + + await Promise.all(chunksLeft.map(async id => { + const isWasm = await fetch(wreq.p + wreq.u(id)) + .then(r => r.text()) + .then(t => t.includes(".module.wasm") || !t.includes("(this.webpackChunkdiscord_app=this.webpackChunkdiscord_app||[]).push")); + + // Loads and requires a chunk + if (!isWasm) { + await wreq.e(id as any); + if (wreq.m[id]) wreq(id as any); + } + })); + + console.log("[PUP_DEBUG]", "Finished loading all chunks!"); + + for (const patch of Vencord.Plugins.patches) { + if (!patch.all) { + new Logger("WebpackInterceptor").warn(`Patch by ${patch.plugin} found no module (Module id is -): ${patch.find}`); + } + } + + for (const [searchType, args] of Vencord.Webpack.lazyWebpackSearchHistory) { + let method = searchType; + + if (searchType === "findComponent") method = "find"; + if (searchType === "findExportedComponent") method = "findByProps"; + if (searchType === "waitFor" || searchType === "waitForComponent") { + if (typeof args[0] === "string") method = "findByProps"; + else method = "find"; + } + if (searchType === "waitForStore") method = "findStore"; + + try { + let result: any; + + if (method === "proxyLazyWebpack" || method === "LazyComponentWebpack") { + const [factory] = args; + result = factory(); + } else if (method === "extractAndLoadChunks") { + const [code, matcher] = args; + + const module = Vencord.Webpack.findModuleFactory(...code); + if (module) result = module.toString().match(canonicalizeMatch(matcher)); + } else { + // @ts-ignore + result = Vencord.Webpack[method](...args); + } + + if (result == null || ("$$vencordInternal" in result && result.$$vencordInternal() == null)) throw "a rock at ben shapiro"; + } catch (e) { + let logMessage = searchType; + if (method === "find" || method === "proxyLazyWebpack" || method === "LazyComponentWebpack") logMessage += `(${args[0].toString().slice(0, 147)}...)`; + else if (method === "extractAndLoadChunks") logMessage += `([${args[0].map(arg => `"${arg}"`).join(", ")}], ${args[1].toString()})`; + else logMessage += `(${args.map(arg => `"${arg}"`).join(", ")})`; + + console.log("[PUP_WEBPACK_FIND_FAIL]", logMessage); + } + } + + setTimeout(() => console.log("[PUPPETEER_TEST_DONE_SIGNAL]"), 1000); } catch (e) { console.log("[PUP_DEBUG]", "A fatal error occurred:", e); process.exit(1); @@ -473,7 +522,7 @@ function runTime(token: string) { await page.evaluateOnNewDocument(` ${readFileSync("./dist/browser.js", "utf-8")} - ;(${runTime.toString()})(${JSON.stringify(process.env.DISCORD_TOKEN)}); + ;(${runtime.toString()})(${JSON.stringify(process.env.DISCORD_TOKEN)}); `); await page.goto(CANARY ? "https://canary.discord.com/login" : "https://discord.com/login"); diff --git a/scripts/runInstaller.mjs b/scripts/runInstaller.mjs index 145ea5a5..a616326d 100644 --- a/scripts/runInstaller.mjs +++ b/scripts/runInstaller.mjs @@ -35,11 +35,11 @@ const ETAG_FILE = join(FILE_DIR, "etag.txt"); function getFilename() { switch (process.platform) { case "win32": - return "VencordInstallerCli.exe"; + return "VencordInstaller.exe"; case "darwin": return "VencordInstaller.MacOS.zip"; case "linux": - return "VencordInstallerCli-linux"; + return "VencordInstaller-" + (process.env.WAYLAND_DISPLAY ? "wayland" : "x11"); default: throw new Error("Unsupported platform: " + process.platform); } diff --git a/src/Vencord.ts b/src/Vencord.ts index 29e965fa..08e3dd69 100644 --- a/src/Vencord.ts +++ b/src/Vencord.ts @@ -81,6 +81,7 @@ async function syncSettings() { async function init() { await onceReady; + startAllPlugins(StartAt.WebpackReady); syncSettings(); @@ -132,16 +133,13 @@ async function init() { } } -startAllPlugins(StartAt.Init); init(); -document.addEventListener("DOMContentLoaded", () => { - startAllPlugins(StartAt.DOMContentLoaded); - - if (IS_DISCORD_DESKTOP && Settings.winNativeTitleBar && navigator.platform.toLowerCase().startsWith("win")) { +if (IS_DISCORD_DESKTOP && Settings.winNativeTitleBar && navigator.platform.toLowerCase().startsWith("win")) { + document.addEventListener("DOMContentLoaded", () => { document.head.append(Object.assign(document.createElement("style"), { id: "vencord-native-titlebar-style", textContent: "[class*=titleBar]{display: none!important}" })); - } -}, { once: true }); + }, { once: true }); +} diff --git a/src/VencordNative.ts b/src/VencordNative.ts index 42e69745..b8f7019d 100644 --- a/src/VencordNative.ts +++ b/src/VencordNative.ts @@ -4,12 +4,11 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -import { PluginIpcMappings } from "@main/ipcPlugins"; -import type { UserThemeHeader } from "@main/themes"; import { IpcEvents } from "@shared/IpcEvents"; import { IpcRes } from "@utils/types"; import type { Settings } from "api/Settings"; import { ipcRenderer } from "electron"; +import { PluginIpcMappings } from "main/ipcPlugins"; function invoke(event: IpcEvents, ...args: any[]) { return ipcRenderer.invoke(event, ...args) as Promise; @@ -34,7 +33,7 @@ export default { uploadTheme: (fileName: string, fileData: string) => invoke(IpcEvents.UPLOAD_THEME, fileName, fileData), deleteTheme: (fileName: string) => invoke(IpcEvents.DELETE_THEME, fileName), getThemesDir: () => invoke(IpcEvents.GET_THEMES_DIR), - getThemesList: () => invoke>(IpcEvents.GET_THEMES_LIST), + getThemesList: () => invoke>(IpcEvents.GET_THEMES_LIST), getThemeData: (fileName: string) => invoke(IpcEvents.GET_THEME_DATA, fileName), getSystemValues: () => invoke>(IpcEvents.GET_THEME_SYSTEM_VALUES), }, diff --git a/src/api/MessageEvents.ts b/src/api/MessageEvents.ts index d6eba748..bcca6003 100644 --- a/src/api/MessageEvents.ts +++ b/src/api/MessageEvents.ts @@ -59,6 +59,8 @@ export interface MessageReplyOptions { messageReference: Message["messageReference"]; allowedMentions?: { parse: Array; + users?: Array; + roles?: Array; repliedUser: boolean; }; } diff --git a/src/api/Settings.ts b/src/api/Settings.ts index 0b797530..49f84d7d 100644 --- a/src/api/Settings.ts +++ b/src/api/Settings.ts @@ -35,6 +35,7 @@ export interface Settings { useQuickCss: boolean; enableReactDevtools: boolean; themeLinks: string[]; + disabledThemeLinks: string[]; enabledThemes: string[]; frameless: boolean; transparent: boolean; @@ -75,6 +76,12 @@ export interface Settings { settingsSync: boolean; settingsSyncVersion: number; }; + + userCssVars: { + [themeId: string]: { + [varName: string]: string; + }; + }; } const DefaultSettings: Settings = { @@ -83,6 +90,7 @@ const DefaultSettings: Settings = { autoUpdateNotification: true, useQuickCss: true, themeLinks: [], + disabledThemeLinks: [], enabledThemes: [], enableReactDevtools: false, frameless: false, @@ -102,10 +110,12 @@ const DefaultSettings: Settings = { cloud: { authenticated: false, - url: "https://api.vencord.dev/", + url: "https://equicord.patrickdk.com/", settingsSync: false, settingsSyncVersion: 0 - } + }, + + userCssVars: {} }; const settings = VencordNative.settings.get(); diff --git a/src/components/DonateButton.tsx b/src/components/DonateButton.tsx index c027fcf2..8984384b 100644 --- a/src/components/DonateButton.tsx +++ b/src/components/DonateButton.tsx @@ -26,7 +26,7 @@ export default function DonateButton(props: any) { {...props} look={Button.Looks.LINK} color={Button.Colors.TRANSPARENT} - onClick={() => VencordNative.native.openExternal("https://github.com/sponsors/Vendicated")} + onClick={() => VencordNative.native.openExternal("https://github.com/sponsors/vendicated")} > Donate diff --git a/src/components/ExpandableHeader.css b/src/components/ExpandableHeader.css index 14e291b0..951b9a10 100644 --- a/src/components/ExpandableHeader.css +++ b/src/components/ExpandableHeader.css @@ -1,7 +1,6 @@ .vc-expandableheader-center-flex { display: flex; - justify-items: center; - align-items: center; + place-content: center; } .vc-expandableheader-btn { @@ -9,4 +8,4 @@ cursor: pointer; width: 24px; height: 24px; -} +} \ No newline at end of file diff --git a/src/components/Icons.tsx b/src/components/Icons.tsx index 2eb83d4e..a3618822 100644 --- a/src/components/Icons.tsx +++ b/src/components/Icons.tsx @@ -256,6 +256,25 @@ export function DeleteIcon(props: IconProps) { ); } +/** + * A plugin icon, created by CorellanStoma. https://github.com/CreArts-Community/Settings-Icons + */ +export function PluginIcon(props: IconProps) { + return ( + + + + ); +} + + export function PlusIcon(props: IconProps) { return ( whatever/index.html + */ +function trimThemeUrl(url: string) { + let urlObj: URL; + + try { + urlObj = new URL(url); + } catch (e) { + return url; + } + + return urlObj.pathname.split("/").slice(-2).join("/"); +} + +async function FetchTheme(link: string) { + const theme: OnlineTheme = await fetch(link, { redirect: "follow" }) + .then(res => { + if (res.status >= 400) throw `${res.status} ${res.statusText}`; + + const contentType = res.headers.get("Content-Type"); + if (!contentType?.startsWith("text/css") && !contentType?.startsWith("text/plain")) + throw "Not a CSS file. Remember to use the raw link!"; + + return res.text(); + }) + .then(text => { + const headers = getThemeInfo(text, trimThemeUrl(link)); + return { link, headers }; + }).catch(e => { + return { link, error: e.toString() }; + }); + + return theme; +} + +export function OnlineThemes() { + const settings = useSettings(["themeLinks", "disabledThemeLinks"]); + const [themes, setThemes] = useState([]); + + async function fetchThemes() { + const themes = await Promise.all(settings.themeLinks.map(link => FetchTheme(link))); + setThemes(themes); + } + + async function addTheme(link: string) { + settings.disabledThemeLinks = [...settings.disabledThemeLinks, link]; + settings.themeLinks = [...settings.themeLinks, link]; + setThemes([...themes, await FetchTheme(link)]); + } + + async function removeTheme(link: string) { + settings.disabledThemeLinks = settings.disabledThemeLinks.filter(l => l !== link); + settings.themeLinks = settings.themeLinks.filter(l => l !== link); + setThemes(themes.filter(t => t.link !== link)); + } + + function setThemeEnabled(link: string, enabled: boolean) { + if (enabled) { + settings.disabledThemeLinks = settings.disabledThemeLinks.filter(l => l !== link); + } else { + settings.disabledThemeLinks = [...settings.disabledThemeLinks, link]; + } + settings.themeLinks = [...settings.themeLinks]; + } + + useEffect(() => { + fetchThemes(); + }, []); + + function AddThemeModal({ transitionState, onClose }: ModalProps) { + const [disabled, setDisabled] = useState(true); + const [error, setError] = useState(null); + const [url, setUrl] = useState(""); + + async function checkUrl() { + if (!url) { + setDisabled(true); + setError(null); + return; + } + + if (themes.some(t => t.link === url)) { + setError("Theme already added"); + setDisabled(true); + return; + } + + let urlObj: URL | undefined = undefined; + try { + urlObj = new URL(url); + } catch (e) { + setDisabled(true); + setError("Invalid URL"); + return; + } + + if (urlObj.hostname !== "raw.githubusercontent.com" && !urlObj.hostname.endsWith("github.io")) { + setError("Only raw.githubusercontent.com and github.io URLs are allowed, otherwise the theme will not work"); + setDisabled(true); + return; + } + + if (!urlObj.pathname.endsWith(".css")) { + setError("Not a CSS file. Remember to use the raw link!"); + setDisabled(true); + return; + } + + let success = true; + await fetch(url).then(res => { + if (!res.ok) { + setError(`Could not fetch theme: ${res.status} ${res.statusText}`); + setDisabled(true); + success = false; + } + }).catch(e => { + setError(`Could not fetch theme: ${e}`); + setDisabled(true); + success = false; + }); + + if (!success) return; + + setDisabled(false); + setError(null); + } + + return + + Add Online Theme + + + + Only raw.githubusercontent.com and github.io URLs will work + + + {error} + + + + + + ; + } + + return ( + <> + + Find Themes: + + Find a theme you like and press "Add Theme" to add it. + To get a raw link to a theme, go to it's GitHub repository, + find the CSS file, and press the "Raw" button, then copy the URL. + + + + + + + +
+ {themes.length === 0 && ( + Add themes with the "Add Theme" button above + )} + {themes.map(theme => ( + (!theme.error && { + setThemeEnabled(theme.link, value); + }} + onDelete={() => removeTheme(theme.link)} + theme={theme.headers!} + showDelete={true} + extraButtons={ +
copyWithToast(theme.link, "Link copied to clipboard!")} + > + +
+ } + /> + ) || ( + { }} + hideSwitch={true} + infoButton={<> +
copyWithToast(theme.link, "Link copied to clipboard!")} + > + +
+
removeTheme(theme.link)} + > + +
+ + } + /> + ) + ))} +
+
+ + ); +} diff --git a/src/components/ThemeSettings/ThemesTab.tsx b/src/components/ThemeSettings/ThemesTab.tsx new file mode 100644 index 00000000..0b17ed7c --- /dev/null +++ b/src/components/ThemeSettings/ThemesTab.tsx @@ -0,0 +1,431 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import "./themesStyles.css"; + +import { Settings, useSettings } from "@api/Settings"; +import { classNameFactory } from "@api/Styles"; +import { Flex } from "@components/Flex"; +import { CogWheel, DeleteIcon, PluginIcon } from "@components/Icons"; +import { Link } from "@components/Link"; +import PluginModal from "@components/PluginSettings/PluginModal"; +import { AddonCard } from "@components/VencordSettings/AddonCard"; +import { SettingsTab, wrapTab } from "@components/VencordSettings/shared"; +import { openInviteModal } from "@utils/discord"; +import { openModal } from "@utils/modal"; +import { showItemInFolder } from "@utils/native"; +import { useAwaiter } from "@utils/react"; +import type { ThemeHeader } from "@utils/themes"; +import { getThemeInfo, stripBOM, type UserThemeHeader } from "@utils/themes/bd"; +import { usercssParse } from "@utils/themes/usercss"; +import { findByCodeLazy } from "@webpack"; +import { Button, Card, Forms, React, showToast, TabBar, Tooltip, useEffect, useMemo, useRef, useState } from "@webpack/common"; +import type { ComponentType, Ref, SyntheticEvent } from "react"; +import type { UserstyleHeader } from "usercss-meta"; + +import { isPluginEnabled } from "../../plugins"; +import { OnlineThemes } from "./OnlineThemes"; +import { UserCSSSettingsModal } from "./UserCSSModal"; + +type FileInput = ComponentType<{ + ref: Ref; + onChange: (e: SyntheticEvent) => void; + multiple?: boolean; + filters?: { name?: string; extensions: string[]; }[]; +}>; + +const FileInput: FileInput = findByCodeLazy("activateUploadDialogue="); + +const cl = classNameFactory("vc-settings-theme-"); + +interface ThemeCardProps { + theme: UserThemeHeader; + enabled: boolean; + onChange: (enabled: boolean) => void; + onDelete: () => void; + showDelete?: boolean; + extraButtons?: React.ReactNode; +} + +interface OtherThemeCardProps { + theme: UserThemeHeader; + enabled: boolean; + onChange: (enabled: boolean) => void; + onDelete: () => void; + showDelete?: boolean; + extraButtons?: React.ReactNode; +} + +interface UserCSSCardProps { + theme: UserstyleHeader; + enabled: boolean; + onChange: (enabled: boolean) => void; + onDelete: () => void; +} + +export function ThemeCard({ theme, enabled, onChange, onDelete, showDelete, extraButtons }: ThemeCardProps) { + return ( + + {extraButtons} +
+ +
+ + ) + } + footer={ + + {!!theme.website && Website} + {!!(theme.website && theme.invite) && " • "} + {!!theme.invite && ( + { + e.preventDefault(); + theme.invite != null && openInviteModal(theme.invite).catch(() => showToast("Invalid or expired invite")); + }} + > + Discord Server + + )} + + } + /> + ); +} + +function UserCSSThemeCard({ theme, enabled, onChange, onDelete }: UserCSSCardProps) { + const missingPlugins = useMemo(() => + theme.requiredPlugins?.filter(p => !isPluginEnabled(p)), [theme]); + + return ( + + {missingPlugins && missingPlugins.length > 0 && ( + + {({ onMouseLeave, onMouseEnter }) => ( +
+ +
+ )} +
+ )} + {theme.vars && ( +
openModal(modalProps => + ) + }> + +
+ )} + {IS_WEB && ( +
+ +
+ )} + + } + footer={ + + {!!theme.homepageURL && Homepage} + {!!(theme.homepageURL && theme.supportURL) && " • "} + {!!theme.supportURL && Support} + + } + /> + ); +} + +function OtherThemeCard({ theme, enabled, onChange, onDelete, showDelete, extraButtons }: OtherThemeCardProps) { + return ( + + {extraButtons} +
+ +
+ + ) + } + footer={ + + {!!theme.website && Website} + {!!(theme.website && theme.invite) && " • "} + {!!theme.invite && ( + { + e.preventDefault(); + theme.invite != null && openInviteModal(theme.invite).catch(() => showToast("Invalid or expired invite")); + }} + > + Discord Server + + )} + + } + /> + ); +} + +enum ThemeTab { + LOCAL, + ONLINE, + REPO +} + +function ThemesTab() { + const settings = useSettings(["themeLinks", "disabledThemeLinks", "enabledThemes"]); + + const fileInputRef = useRef(null); + const [currentTab, setCurrentTab] = useState(ThemeTab.LOCAL); + const [userThemes, setUserThemes] = useState(null); + const [themeDir, , themeDirPending] = useAwaiter(VencordNative.themes.getThemesDir); + + useEffect(() => { + refreshLocalThemes(); + }, [settings.themeLinks]); + + async function refreshLocalThemes() { + const themes = await VencordNative.themes.getThemesList(); + + const themeInfo: ThemeHeader[] = []; + + for (const { fileName, content } of themes) { + if (!fileName.endsWith(".css")) continue; + + if ((!IS_WEB || "armcord" in window) && fileName.endsWith(".user.css")) { + // handle it as usercss + const header = await usercssParse(content, fileName); + + themeInfo.push({ + type: "usercss", + header + }); + + Settings.userCssVars[header.id] ??= {}; + + for (const [name, varInfo] of Object.entries(header.vars ?? {})) { + let normalizedValue = ""; + + switch (varInfo.type) { + case "text": + case "color": + normalizedValue = varInfo.default; + break; + case "select": + normalizedValue = varInfo.options.find(v => v.name === varInfo.default)!.value; + break; + case "checkbox": + normalizedValue = varInfo.default ? "1" : "0"; + break; + case "range": + normalizedValue = `${varInfo.default}${varInfo.units}`; + break; + case "number": + normalizedValue = String(varInfo.default); + break; + } + + Settings.userCssVars[header.id][name] ??= normalizedValue; + } + } else { + // presumably BD but could also be plain css + themeInfo.push({ + type: "other", + header: getThemeInfo(stripBOM(content), fileName) + }); + } + } + + setUserThemes(themeInfo); + } + + // When a local theme is enabled/disabled, update the settings + function onLocalThemeChange(fileName: string, value: boolean) { + if (value) { + if (settings.enabledThemes.includes(fileName)) return; + settings.enabledThemes = [...settings.enabledThemes, fileName]; + } else { + settings.enabledThemes = settings.enabledThemes.filter(f => f !== fileName); + } + } + + async function onFileUpload(e: SyntheticEvent) { + e.stopPropagation(); + e.preventDefault(); + if (!e.currentTarget?.files?.length) return; + const { files } = e.currentTarget; + + const uploads = Array.from(files, file => { + const { name } = file; + if (!name.endsWith(".css")) return; + + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => { + VencordNative.themes + .uploadTheme(name, reader.result as string) + .then(resolve) + .catch(reject); + }; + reader.readAsText(file); + }); + }); + + await Promise.all(uploads); + refreshLocalThemes(); + } + + function renderLocalThemes() { + return ( + <> + + Find Themes: +
+ + BetterDiscord Themes + + GitHub +
+ + If using the BD site, click on "Download" and place the downloaded + .theme.css file into your themes folder. + +
+ + + + <> + {IS_WEB ? ( + + ) : ( + + )} + + + + {Vencord.Settings.plugins.ClientTheme.enabled && ( + + )} + + + +
+ {userThemes?.map(({ type, header: theme }: ThemeHeader) => ( + type === "other" ? ( + onLocalThemeChange(theme.fileName, enabled)} + onDelete={async () => { + onLocalThemeChange(theme.fileName, false); + await VencordNative.themes.deleteTheme(theme.fileName); + refreshLocalThemes(); + }} + theme={theme as UserThemeHeader} + /> + ) : ( + onLocalThemeChange(theme.fileName, enabled)} + onDelete={async () => { + onLocalThemeChange(theme.fileName, false); + await VencordNative.themes.deleteTheme(theme.fileName); + refreshLocalThemes(); + }} + theme={theme as UserstyleHeader} + /> + )))} +
+
+ + ); + } + + return ( + + + + Local Themes + + + Online Themes + + + + {currentTab === ThemeTab.LOCAL && renderLocalThemes()} + {currentTab === ThemeTab.ONLINE && } + + ); +} + +export default wrapTab(ThemesTab, "Themes"); diff --git a/src/components/ThemeSettings/UserCSSModal.tsx b/src/components/ThemeSettings/UserCSSModal.tsx new file mode 100644 index 00000000..9880c3b2 --- /dev/null +++ b/src/components/ThemeSettings/UserCSSModal.tsx @@ -0,0 +1,114 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { useSettings } from "@api/Settings"; +import { Flex } from "@components/Flex"; +import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot } from "@utils/modal"; +import { Text } from "@webpack/common"; +import type { ReactNode } from "react"; +import { UserstyleHeader } from "usercss-meta"; + +import { SettingBooleanComponent, SettingColorComponent, SettingNumberComponent, SettingRangeComponent, SettingSelectComponent, SettingTextComponent } from "./components"; + +interface UserCSSSettingsModalProps { + modalProps: ModalProps; + theme: UserstyleHeader; +} + +export function UserCSSSettingsModal({ modalProps, theme }: UserCSSSettingsModalProps) { + // @ts-expect-error UseSettings<> can't determine this is a valid key + const themeSettings = useSettings(["userCssVars"], false).userCssVars[theme.id]; + + const controls: ReactNode[] = []; + + for (const [name, varInfo] of Object.entries(theme.vars)) { + switch (varInfo.type) { + case "text": { + controls.push( + + ); + break; + } + + case "checkbox": { + controls.push( + + ); + break; + } + + case "color": { + controls.push( + + ); + break; + } + + case "number": { + controls.push( + + ); + break; + } + + case "select": { + controls.push( + + ); + break; + } + + case "range": { + controls.push( + + ); + break; + } + } + } + + return ( + + + Settings for {theme.name} + + + + {controls} + + + ); +} diff --git a/src/components/ThemeSettings/components/SettingBooleanComponent.tsx b/src/components/ThemeSettings/components/SettingBooleanComponent.tsx new file mode 100644 index 00000000..a0d3239b --- /dev/null +++ b/src/components/ThemeSettings/components/SettingBooleanComponent.tsx @@ -0,0 +1,39 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { Forms, Switch, useState } from "@webpack/common"; + +interface Props { + label: string; + name: string; + themeSettings: Record; +} + +export function SettingBooleanComponent({ label, name, themeSettings }: Props) { + const [value, setValue] = useState(themeSettings[name]); + + function handleChange(value: boolean) { + const corrected = value ? "1" : "0"; + + setValue(corrected); + + themeSettings[name] = corrected; + } + + return ( + + + {label} + + + ); +} diff --git a/src/components/ThemeSettings/components/SettingColorComponent.tsx b/src/components/ThemeSettings/components/SettingColorComponent.tsx new file mode 100644 index 00000000..2414c604 --- /dev/null +++ b/src/components/ThemeSettings/components/SettingColorComponent.tsx @@ -0,0 +1,56 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import "./colorStyles.css"; + +import { classNameFactory } from "@api/Styles"; +import { findByCodeLazy, findComponentByCodeLazy } from "@webpack"; +import { Forms, useMemo, useState } from "@webpack/common"; + +interface ColorPickerProps { + color: number | null; + showEyeDropper?: boolean; + onChange(value: number | null): void; +} +const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); + +// TinyColor is completely unmangled and it's duplicated in two modules! Fun! +const TinyColor: tinycolor.Constructor = findByCodeLazy("this._gradientType="); + +const cl = classNameFactory("vc-usercss-settings-color-"); + +interface Props { + label: string; + name: string; + themeSettings: Record; +} + +export function SettingColorComponent({ label, name, themeSettings }: Props) { + const [value, setValue] = useState(themeSettings[name]); + + function handleChange(value: number) { + const corrected = "#" + (value?.toString(16).padStart(6, "0") ?? "000000"); + + setValue(corrected); + + themeSettings[name] = corrected; + } + + const normalizedValue = useMemo(() => parseInt(TinyColor(value).toHex(), 16), [value]); + + return ( + +
+ {label} + +
+
+ ); +} diff --git a/src/components/ThemeSettings/components/SettingNumberComponent.tsx b/src/components/ThemeSettings/components/SettingNumberComponent.tsx new file mode 100644 index 00000000..35f57ed4 --- /dev/null +++ b/src/components/ThemeSettings/components/SettingNumberComponent.tsx @@ -0,0 +1,36 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { Forms, TextInput, useState } from "@webpack/common"; + +interface Props { + label: string; + name: string; + themeSettings: Record; +} + +export function SettingNumberComponent({ label, name, themeSettings }: Props) { + const [value, setValue] = useState(themeSettings[name]); + + function handleChange(value: string) { + setValue(value); + + themeSettings[name] = value; + } + + return ( + + {label} + + + ); +} diff --git a/src/components/ThemeSettings/components/SettingRangeComponent.tsx b/src/components/ThemeSettings/components/SettingRangeComponent.tsx new file mode 100644 index 00000000..6bb15ff8 --- /dev/null +++ b/src/components/ThemeSettings/components/SettingRangeComponent.tsx @@ -0,0 +1,56 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { Forms, Slider, useMemo, useState } from "@webpack/common"; + +interface Props { + label: string; + name: string; + default: number; + min?: number; + max?: number; + step?: number; + themeSettings: Record; +} + +export function SettingRangeComponent({ label, name, default: def, min, max, step, themeSettings }: Props) { + const [value, setValue] = useState(themeSettings[name]); + + function handleChange(value: number) { + const corrected = value.toString(); + + setValue(corrected); + + themeSettings[name] = corrected; + } + + const markers = useMemo(() => { + const markers: number[] = []; + + // defaults taken from https://github.com/openstyles/stylus/wiki/Writing-UserCSS#default-value + for (let i = (min ?? 0); i <= (max ?? 10); i += (step ?? 1)) { + markers.push(i); + } + + return markers; + }, [min, max, step]); + + return ( + + {label} + + + ); +} diff --git a/src/components/ThemeSettings/components/SettingSelectComponent.tsx b/src/components/ThemeSettings/components/SettingSelectComponent.tsx new file mode 100644 index 00000000..07085dc3 --- /dev/null +++ b/src/components/ThemeSettings/components/SettingSelectComponent.tsx @@ -0,0 +1,55 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2023 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { identity } from "@utils/misc"; +import { ComponentTypes, Forms, Select, useMemo, useState } from "@webpack/common"; + +interface Props { + label: string; + name: string; + options: { + name: string; + label: string; + value: string; + }[]; + default: string; + themeSettings: Record; +} + +export function SettingSelectComponent({ label, name, options, default: def, themeSettings }: Props) { + const [value, setValue] = useState(themeSettings[name]); + + function handleChange(value: string) { + setValue(value); + + themeSettings[name] = value; + } + + const opts = useMemo(() => options.map(option => ({ + disabled: false, + + key: option.name, + value: option.value, + default: def === option.name, + label: option.label + } satisfies ComponentTypes.SelectOption)), [options, def]); + + return ( + + {label} +