Ver Fonte

chore: build

Sv443 há 10 meses atrás
pai
commit
3ae28b4ea0
1 ficheiros alterados com 123 adições e 104 exclusões
  1. 123 104
      dist/BetterYTM.user.js

+ 123 - 104
dist/BetterYTM.user.js

@@ -17,7 +17,7 @@
 // @license           AGPL-3.0-only
 // @license           AGPL-3.0-only
 // @author            Sv443
 // @author            Sv443
 // @copyright         Sv443 (https://github.com/Sv443)
 // @copyright         Sv443 (https://github.com/Sv443)
-// @icon              https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/images/logo/logo_dev_48.png
+// @icon              https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/images/logo/logo_dev_48.png
 // @match             https://music.youtube.com/*
 // @match             https://music.youtube.com/*
 // @match             https://www.youtube.com/*
 // @match             https://www.youtube.com/*
 // @run-at            document-start
 // @run-at            document-start
@@ -33,49 +33,49 @@
 // @grant             GM.openInTab
 // @grant             GM.openInTab
 // @grant             unsafeWindow
 // @grant             unsafeWindow
 // @noframes
 // @noframes
-// @resource          css-bundle              https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/dist/BetterYTM.css
-// @resource          css-above_queue_btns    https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/style/aboveQueueBtns.css
-// @resource          css-anchor_improvements https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/style/anchorImprovements.css
-// @resource          css-fix_hdr             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/style/fixHDR.css
-// @resource          css-fix_spacing         https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/style/fixSpacing.css
-// @resource          css-show_votes          https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/style/showVotes.css
-// @resource          css-vol_slider_size     https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/style/volSliderSize.css
-// @resource          doc-changelog           https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/changelog.md
-// @resource          icon-advanced_mode      https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/plus_circle_small.svg
-// @resource          icon-arrow_down         https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/arrow_down.svg
-// @resource          icon-auto_like_enabled  https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/auto_like_enabled.svg
-// @resource          icon-auto_like          https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/auto_like.svg
-// @resource          icon-clear_list         https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/clear_list.svg
-// @resource          icon-delete             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/delete.svg
-// @resource          icon-edit               https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/edit.svg
-// @resource          icon-error              https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/error.svg
-// @resource          icon-experimental       https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/beaker_small.svg
-// @resource          icon-globe_small        https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/globe_small.svg
-// @resource          icon-globe              https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/globe.svg
-// @resource          icon-help               https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/help.svg
-// @resource          icon-image_filled       https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/image_filled.svg
-// @resource          icon-image              https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/image.svg
-// @resource          icon-link               https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/link.svg
-// @resource          icon-lyrics             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/lyrics.svg
-// @resource          icon-reload             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/refresh.svg
-// @resource          icon-skip_to            https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/skip_to.svg
-// @resource          icon-spinner            https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/icons/spinner.svg
-// @resource          img-close               https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/images/close.png
-// @resource          img-discord             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/images/external/discord.png
-// @resource          img-github              https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/images/external/github.png
-// @resource          img-greasyfork          https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/images/external/greasyfork.png
-// @resource          img-logo_dev            https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/images/logo/logo_dev_48.png
-// @resource          img-logo                https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/images/logo/logo_48.png
-// @resource          img-openuserjs          https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/images/external/openuserjs.png
-// @resource          trans-de_DE             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/translations/de_DE.json
-// @resource          trans-en_US             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/translations/en_US.json
-// @resource          trans-en_UK             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/translations/en_UK.json
-// @resource          trans-es_ES             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/translations/es_ES.json
-// @resource          trans-fr_FR             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/translations/fr_FR.json
-// @resource          trans-hi_IN             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/translations/hi_IN.json
-// @resource          trans-ja_JA             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/translations/ja_JA.json
-// @resource          trans-pt_BR             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/translations/pt_BR.json
-// @resource          trans-zh_CN             https://raw.githubusercontent.com/Sv443/BetterYTM/5f7a1c2a/assets/translations/zh_CN.json
+// @resource          css-bundle              https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/dist/BetterYTM.css
+// @resource          css-above_queue_btns    https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/style/aboveQueueBtns.css
+// @resource          css-anchor_improvements https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/style/anchorImprovements.css
+// @resource          css-fix_hdr             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/style/fixHDR.css
+// @resource          css-fix_spacing         https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/style/fixSpacing.css
+// @resource          css-show_votes          https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/style/showVotes.css
+// @resource          css-vol_slider_size     https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/style/volSliderSize.css
+// @resource          doc-changelog           https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/changelog.md
+// @resource          icon-advanced_mode      https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/plus_circle_small.svg
+// @resource          icon-arrow_down         https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/arrow_down.svg
+// @resource          icon-auto_like_enabled  https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/auto_like_enabled.svg
+// @resource          icon-auto_like          https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/auto_like.svg
+// @resource          icon-clear_list         https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/clear_list.svg
+// @resource          icon-delete             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/delete.svg
+// @resource          icon-edit               https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/edit.svg
+// @resource          icon-error              https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/error.svg
+// @resource          icon-experimental       https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/beaker_small.svg
+// @resource          icon-globe_small        https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/globe_small.svg
+// @resource          icon-globe              https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/globe.svg
+// @resource          icon-help               https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/help.svg
+// @resource          icon-image_filled       https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/image_filled.svg
+// @resource          icon-image              https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/image.svg
+// @resource          icon-link               https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/link.svg
+// @resource          icon-lyrics             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/lyrics.svg
+// @resource          icon-reload             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/refresh.svg
+// @resource          icon-skip_to            https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/skip_to.svg
+// @resource          icon-spinner            https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/icons/spinner.svg
+// @resource          img-close               https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/images/close.png
+// @resource          img-discord             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/images/external/discord.png
+// @resource          img-github              https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/images/external/github.png
+// @resource          img-greasyfork          https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/images/external/greasyfork.png
+// @resource          img-logo_dev            https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/images/logo/logo_dev_48.png
+// @resource          img-logo                https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/images/logo/logo_48.png
+// @resource          img-openuserjs          https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/images/external/openuserjs.png
+// @resource          trans-de_DE             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/translations/de_DE.json
+// @resource          trans-en_US             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/translations/en_US.json
+// @resource          trans-en_UK             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/translations/en_UK.json
+// @resource          trans-es_ES             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/translations/es_ES.json
+// @resource          trans-fr_FR             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/translations/fr_FR.json
+// @resource          trans-hi_IN             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/translations/hi_IN.json
+// @resource          trans-ja_JA             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/translations/ja_JA.json
+// @resource          trans-pt_BR             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/translations/pt_BR.json
+// @resource          trans-zh_CN             https://raw.githubusercontent.com/Sv443/BetterYTM/339ef3d0/assets/translations/zh_CN.json
 // @require           https://cdn.jsdelivr.net/npm/@sv443-network/[email protected]/dist/index.global.js
 // @require           https://cdn.jsdelivr.net/npm/@sv443-network/[email protected]/dist/index.global.js
 // @require           https://cdn.jsdelivr.net/npm/[email protected]/dist/fuse.basic.js
 // @require           https://cdn.jsdelivr.net/npm/[email protected]/dist/fuse.basic.js
 // @require           https://cdn.jsdelivr.net/npm/[email protected]/lib/marked.umd.js
 // @require           https://cdn.jsdelivr.net/npm/[email protected]/lib/marked.umd.js
@@ -186,7 +186,7 @@ var PluginIntent;
 })(PluginIntent || (PluginIntent = {}));const modeRaw = "development";
 })(PluginIntent || (PluginIntent = {}));const modeRaw = "development";
 const branchRaw = "develop";
 const branchRaw = "develop";
 const hostRaw = "github";
 const hostRaw = "github";
-const buildNumberRaw = "5f7a1c2a";
+const buildNumberRaw = "339ef3d0";
 /** The mode in which the script was built (production or development) */
 /** The mode in which the script was built (production or development) */
 const mode = (modeRaw.match(/^#{{.+}}$/) ? "production" : modeRaw);
 const mode = (modeRaw.match(/^#{{.+}}$/) ? "production" : modeRaw);
 /** The branch to use in various URLs that point to the GitHub repo */
 /** The branch to use in various URLs that point to the GitHub repo */
@@ -3201,25 +3201,6 @@ function addConfigMenuOptionYT(container) {
             return error("Couldn't add config menu option to YT titlebar - couldn't find container element");
             return error("Couldn't add config menu option to YT titlebar - couldn't find container element");
     });
     });
 }
 }
-//#region upgrade tab
-/** Removes the "Upgrade" / YT Music Premium tab from the sidebar */
-function removeUpgradeTab() {
-    return __awaiter(this, void 0, void 0, function* () {
-        addSelectorListener("sideBar", "#contentContainer #guide-content #items ytmusic-guide-entry-renderer:nth-of-type(4)", {
-            listener: (tabElemLarge) => {
-                tabElemLarge.remove();
-                log("Removed large upgrade tab");
-            },
-        });
-        // TODO:FIXME: see https://github.com/Sv443/BetterYTM/issues/91
-        addSelectorListener("sideBarMini", "#sections ytmusic-guide-section-renderer[is-primary] #items ytmusic-guide-entry-renderer:nth-of-type(4)", {
-            listener: (tabElemSmall) => {
-                tabElemSmall.remove();
-                log("Removed small upgrade tab");
-            },
-        });
-    });
-}
 //#region anchor impr.
 //#region anchor impr.
 /** Adds anchors around elements and tweaks existing ones so songs are easier to open in a new tab */
 /** Adds anchors around elements and tweaks existing ones so songs are easier to open in a new tab */
 function addAnchorImprovements() {
 function addAnchorImprovements() {
@@ -3710,15 +3691,22 @@ function initShowVotes() {
             },
             },
         });
         });
         siteEvents.on("watchIdChanged", (watchId) => __awaiter(this, void 0, void 0, function* () {
         siteEvents.on("watchIdChanged", (watchId) => __awaiter(this, void 0, void 0, function* () {
-            const voteObj = yield fetchVideoVotes(watchId);
-            if (!voteObj || !("likes" in voteObj) || !("dislikes" in voteObj) || !("rating" in voteObj))
-                return error("Couldn't fetch votes from ReturnYouTubeDislikes API");
+            var _a, _b;
             const labelLikes = document.querySelector("ytmusic-like-button-renderer .bytm-vote-label.likes");
             const labelLikes = document.querySelector("ytmusic-like-button-renderer .bytm-vote-label.likes");
             const labelDislikes = document.querySelector("ytmusic-like-button-renderer .bytm-vote-label.dislikes");
             const labelDislikes = document.querySelector("ytmusic-like-button-renderer .bytm-vote-label.dislikes");
             if (!labelLikes || !labelDislikes)
             if (!labelLikes || !labelDislikes)
                 return error("Couldn't find vote label elements while updating like and dislike counts");
                 return error("Couldn't find vote label elements while updating like and dislike counts");
-            labelLikes.textContent = voteObj.likes.toLocaleString(undefined, getVoteNumberFormat());
-            labelDislikes.textContent = voteObj.dislikes.toLocaleString(undefined, getVoteNumberFormat());
+            if (labelLikes.dataset.watchId === watchId && labelDislikes.dataset.watchId === watchId)
+                return log("Vote labels already updated for this video");
+            const voteObj = yield fetchVideoVotes(watchId);
+            if (!voteObj || !("likes" in voteObj) || !("dislikes" in voteObj) || !("rating" in voteObj))
+                return error("Couldn't fetch votes from ReturnYouTubeDislikes API");
+            labelLikes.dataset.watchId = (_a = getWatchId()) !== null && _a !== void 0 ? _a : "";
+            labelLikes.textContent = formatVoteNumber(voteObj.likes);
+            labelLikes.title = labelLikes.ariaLabel = t("vote_label_likes", voteObj.likes);
+            labelDislikes.textContent = formatVoteNumber(voteObj.dislikes);
+            labelDislikes.title = labelDislikes.ariaLabel = t("vote_label_dislikes", voteObj.dislikes);
+            labelDislikes.dataset.watchId = (_b = getWatchId()) !== null && _b !== void 0 ? _b : "";
         }));
         }));
     });
     });
 }
 }
@@ -3728,10 +3716,12 @@ function addVoteNumbers(voteCont, voteObj) {
     if (!likeBtn || !dislikeBtn)
     if (!likeBtn || !dislikeBtn)
         return error("Couldn't find like or dislike button while adding vote numbers");
         return error("Couldn't find like or dislike button while adding vote numbers");
     const createLabel = (amount, type) => {
     const createLabel = (amount, type) => {
+        var _a;
         const label = document.createElement("span");
         const label = document.createElement("span");
         label.classList.add("bytm-vote-label", "bytm-no-select", type);
         label.classList.add("bytm-vote-label", "bytm-no-select", type);
-        label.textContent = amount.toLocaleString(undefined, getVoteNumberFormat());
+        label.textContent = String(formatVoteNumber(amount));
         label.title = label.ariaLabel = t(`vote_label_${type}`, amount);
         label.title = label.ariaLabel = t(`vote_label_${type}`, amount);
+        label.dataset.watchId = (_a = getWatchId()) !== null && _a !== void 0 ? _a : "";
         label.addEventListener("click", (e) => {
         label.addEventListener("click", (e) => {
             var _a;
             var _a;
             e.preventDefault();
             e.preventDefault();
@@ -3746,19 +3736,21 @@ function addVoteNumbers(voteCont, voteObj) {
     const dislikeLblEl = createLabel(voteObj.dislikes, "dislikes");
     const dislikeLblEl = createLabel(voteObj.dislikes, "dislikes");
     dislikeBtn.insertAdjacentElement("afterend", dislikeLblEl);
     dislikeBtn.insertAdjacentElement("afterend", dislikeLblEl);
 }
 }
-function getVoteNumberFormat() {
-    return getFeature("showVotesFormat") === "short"
+/** Formats a number with the notation based on the config */
+function formatVoteNumber(num) {
+    return num.toLocaleString(undefined, getFeature("showVotesFormat") === "short"
         ? {
         ? {
             notation: "compact",
             notation: "compact",
             compactDisplay: "short",
             compactDisplay: "short",
+            maximumFractionDigits: 1,
         }
         }
         : {
         : {
             style: "decimal",
             style: "decimal",
             maximumFractionDigits: 0,
             maximumFractionDigits: 0,
-        };
+        });
 }
 }
 function addVoteRatio(voteCont, voteObj) {
 function addVoteRatio(voteCont, voteObj) {
-    console.log("># TODO: addVoteRatio", voteCont, voteObj);
+    dbg("># TODO: addVoteRatio", voteCont, voteObj);
 }//#region beforeunload popup
 }//#region beforeunload popup
 let beforeUnloadEnabled = true;
 let beforeUnloadEnabled = true;
 /** Disables the popup before leaving the site */
 /** Disables the popup before leaving the site */
@@ -5102,12 +5094,6 @@ const featInfo = {
         advanced: true,
         advanced: true,
         textAdornment: () => combineAdornments([adornments.advanced, adornments.reloadRequired]),
         textAdornment: () => combineAdornments([adornments.advanced, adornments.reloadRequired]),
     },
     },
-    removeUpgradeTab: {
-        type: "toggle",
-        category: "layout",
-        default: true,
-        textAdornment: adornments.reloadRequired,
-    },
     thumbnailOverlayBehavior: {
     thumbnailOverlayBehavior: {
         type: "select",
         type: "select",
         category: "layout",
         category: "layout",
@@ -5699,18 +5685,22 @@ const migrations = {
         "closeToastsTimeout", "disableDarkReaderSites",
         "closeToastsTimeout", "disableDarkReaderSites",
     ]),
     ]),
     // 5 -> 6 (v2.1)
     // 5 -> 6 (v2.1)
-    6: (oldData) => useNewDefaultIfUnchanged(useDefaultConfig(oldData, [
-        "autoLikeChannels", "autoLikeChannelToggleBtn",
-        "autoLikeTimeout", "autoLikeShowToast",
-        "autoLikeOpenMgmtDialog", "showVotes",
-        "showVotesFormat", "showVoteRatio",
-        "toastDuration", "initTimeout",
-        // forgot to add this to the migration when adding the feature so now will have to do:
-        "volumeSliderLabel",
-    ]), [
-        { key: "rememberSongTimeSites", oldDefault: "ytm" },
-        { key: "volumeSliderScrollStep", oldDefault: 10 },
-    ]),
+    6: (oldData) => {
+        const newData = useNewDefaultIfUnchanged(useDefaultConfig(oldData, [
+            "autoLikeChannels", "autoLikeChannelToggleBtn",
+            "autoLikeTimeout", "autoLikeShowToast",
+            "autoLikeOpenMgmtDialog", "showVotes",
+            "showVotesFormat", "showVoteRatio",
+            "toastDuration", "initTimeout",
+            // forgot to add this to the migration when adding the feature so now will have to do:
+            "volumeSliderLabel",
+        ]), [
+            { key: "rememberSongTimeSites", oldDefault: "ytm" },
+            { key: "volumeSliderScrollStep", oldDefault: 10 },
+        ]);
+        "removeUpgradeTab" in newData && delete newData.removeUpgradeTab;
+        return newData;
+    },
     // TODO(v2.2): use default for "autoLikePlayerBarToggleBtn"
     // TODO(v2.2): use default for "autoLikePlayerBarToggleBtn"
     // TODO: once advanced filtering is fully implemented, clear cache on migration to fv6
     // TODO: once advanced filtering is fully implemented, clear cache on migration to fv6
     // 6 -> 7 (vX.X)
     // 6 -> 7 (vX.X)
@@ -5757,7 +5747,7 @@ function initConfig() {
         let data = yield cfgDataStore.loadData();
         let data = yield cfgDataStore.loadData();
         // since the config changes so much in development keys need to be fixed in this special way
         // since the config changes so much in development keys need to be fixed in this special way
         if (mode === "development") {
         if (mode === "development") {
-            yield cfgDataStore.setData(fixMissingCfgKeys(data));
+            yield cfgDataStore.setData(fixCfgKeys(data));
             data = cfgDataStore.getData();
             data = cfgDataStore.getData();
         }
         }
         log(`Initialized feature config DataStore (formatVersion = ${cfgDataStore.formatVersion})`);
         log(`Initialized feature config DataStore (formatVersion = ${cfgDataStore.formatVersion})`);
@@ -5765,7 +5755,7 @@ function initConfig() {
             info("  !- Config data was initialized with default values");
             info("  !- Config data was initialized with default values");
         else if (oldFmtVer !== cfgDataStore.formatVersion) {
         else if (oldFmtVer !== cfgDataStore.formatVersion) {
             try {
             try {
-                yield cfgDataStore.setData(data = fixMissingCfgKeys(data));
+                yield cfgDataStore.setData(data = fixCfgKeys(data));
                 info(`  !- Config data was migrated from version ${oldFmtVer} to ${cfgDataStore.formatVersion}`);
                 info(`  !- Config data was migrated from version ${oldFmtVer} to ${cfgDataStore.formatVersion}`);
             }
             }
             catch (err) {
             catch (err) {
@@ -5778,10 +5768,10 @@ function initConfig() {
     });
     });
 }
 }
 /**
 /**
- * Fixes missing keys in the passed config object with their default values and returns a copy of the fixed object.
+ * Fixes missing keys in the passed config object with their default values or removes extraneous keys and returns a copy of the fixed object.
  * Returns a copy of the originally passed object if nothing needs to be fixed.
  * Returns a copy of the originally passed object if nothing needs to be fixed.
  */
  */
-function fixMissingCfgKeys(cfg) {
+function fixCfgKeys(cfg) {
     const newCfg = Object.assign({}, cfg);
     const newCfg = Object.assign({}, cfg);
     const passedKeys = Object.keys(cfg);
     const passedKeys = Object.keys(cfg);
     const defaultKeys = Object.keys(defaultData);
     const defaultKeys = Object.keys(defaultData);
@@ -5790,6 +5780,11 @@ function fixMissingCfgKeys(cfg) {
         for (const key of missingKeys)
         for (const key of missingKeys)
             newCfg[key] = defaultData[key];
             newCfg[key] = defaultData[key];
     }
     }
+    const extraKeys = passedKeys.filter(k => !defaultKeys.includes(k));
+    if (extraKeys.length > 0) {
+        for (const key of extraKeys)
+            delete newCfg[key];
+    }
     return newCfg;
     return newCfg;
 }
 }
 /** Returns the current feature config from the in-memory cache as a copy */
 /** Returns the current feature config from the in-memory cache as a copy */
@@ -6422,7 +6417,7 @@ function onInteraction(elem, listener, listenerOptions) {
 }let curLogLevel = LogLevel.Info;
 }let curLogLevel = LogLevel.Info;
 /** Common prefix to be able to tell logged messages apart and filter them in devtools */
 /** Common prefix to be able to tell logged messages apart and filter them in devtools */
 const consPrefix = `[${scriptInfo.name}]`;
 const consPrefix = `[${scriptInfo.name}]`;
-`[${scriptInfo.name}/#DEBUG]`;
+const consPrefixDbg = `[${scriptInfo.name}/#DEBUG]`;
 /** Sets the current log level. 0 = Debug, 1 = Info */
 /** Sets the current log level. 0 = Debug, 1 = Info */
 function setLogLevel(level) {
 function setLogLevel(level) {
     curLogLevel = level;
     curLogLevel = level;
@@ -6460,6 +6455,10 @@ function warn(...args) {
 /** Logs all passed values to the console as an error, no matter the log level. */
 /** Logs all passed values to the console as an error, no matter the log level. */
 function error(...args) {
 function error(...args) {
     console.error(consPrefix, ...args);
     console.error(consPrefix, ...args);
+}
+/** Logs all passed values to the console with a debug-specific prefix */
+function dbg(...args) {
+    console.log(consPrefixDbg, ...args);
 }//#region misc
 }//#region misc
 let cachedDomain;
 let cachedDomain;
 /**
 /**
@@ -6715,17 +6714,41 @@ function fetchCss(key) {
         }
         }
     });
     });
 }
 }
+/** Cache for the vote data of YouTube videos to prevent unnecessary requests */
+const voteCache = new Map();
+/** Time-to-live for the vote cache in milliseconds */
+const voteCacheTTL = 1000 * 60 * 5;
 /**
 /**
- * Fetches the votes object for a YouTube video from the [Return YouTube Dislikes API.](https://returnyoutubedislike.com/docs)
+ * Fetches the votes object for a YouTube video from the [Return YouTube Dislike API.](https://returnyoutubedislike.com/docs)
  * @param watchId The watch ID of the video
  * @param watchId The watch ID of the video
  */
  */
 function fetchVideoVotes(watchId) {
 function fetchVideoVotes(watchId) {
     return __awaiter(this, void 0, void 0, function* () {
     return __awaiter(this, void 0, void 0, function* () {
         try {
         try {
-            return JSON.parse((yield sendRequest({
+            if (voteCache.has(watchId)) {
+                const cached = voteCache.get(watchId);
+                if (Date.now() - cached.timestamp < voteCacheTTL)
+                    return cached;
+                else
+                    voteCache.delete(watchId);
+            }
+            const votesRaw = JSON.parse((yield sendRequest({
                 method: "GET",
                 method: "GET",
                 url: `https://returnyoutubedislikeapi.com/votes?videoId=${watchId}`,
                 url: `https://returnyoutubedislikeapi.com/votes?videoId=${watchId}`,
             })).response);
             })).response);
+            if (!("id" in votesRaw) || !("likes" in votesRaw) || !("dislikes" in votesRaw) || !("rating" in votesRaw)) {
+                error("Couldn't parse video votes due to an error:", votesRaw);
+                return undefined;
+            }
+            const votesObj = {
+                id: votesRaw.id,
+                likes: votesRaw.likes,
+                dislikes: votesRaw.dislikes,
+                rating: votesRaw.rating,
+                timestamp: Date.now(),
+            };
+            voteCache.set(votesObj.id, votesObj);
+            return votesObj;
         }
         }
         catch (err) {
         catch (err) {
             error("Couldn't fetch video votes due to an error:", err);
             error("Couldn't fetch video votes due to an error:", err);
@@ -6737,7 +6760,6 @@ function fetchVideoVotes(watchId) {
     // console watermark with sexy gradient
     // console watermark with sexy gradient
     const styleGradient = "background: rgba(165, 38, 38, 1); background: linear-gradient(90deg, rgb(154, 31, 103) 0%, rgb(135, 31, 31) 40%, rgb(184, 64, 41) 100%);";
     const styleGradient = "background: rgba(165, 38, 38, 1); background: linear-gradient(90deg, rgb(154, 31, 103) 0%, rgb(135, 31, 31) 40%, rgb(184, 64, 41) 100%);";
     const styleCommon = "color: #fff; font-size: 1.3rem;";
     const styleCommon = "color: #fff; font-size: 1.3rem;";
-    console.log();
     console.log(`%c${scriptInfo.name}%c${scriptInfo.version}%c • ${scriptInfo.namespace}%c\n\nBuild #${buildNumber}`, `${styleCommon} ${styleGradient} font-weight: bold; padding-left: 6px; padding-right: 6px;`, `${styleCommon} background-color: #333; padding-left: 8px; padding-right: 8px;`, "color: #fff; font-size: 1.2rem;", "padding: initial;");
     console.log(`%c${scriptInfo.name}%c${scriptInfo.version}%c • ${scriptInfo.namespace}%c\n\nBuild #${buildNumber}`, `${styleCommon} ${styleGradient} font-weight: bold; padding-left: 6px; padding-right: 6px;`, `${styleCommon} background-color: #333; padding-left: 8px; padding-right: 8px;`, "color: #fff; font-size: 1.2rem;", "padding: initial;");
     console.log([
     console.log([
         "Powered by:",
         "Powered by:",
@@ -6749,7 +6771,6 @@ function fetchVideoVotes(watchId) {
         "─ This markdown parser library: https://github.com/markedjs/marked",
         "─ This markdown parser library: https://github.com/markedjs/marked",
         "─ This fuzzy search library: https://github.com/krisk/Fuse",
         "─ This fuzzy search library: https://github.com/krisk/Fuse",
     ].join("\n"));
     ].join("\n"));
-    console.log();
 }
 }
 //#region preInit
 //#region preInit
 /** Stuff that needs to be called ASAP, before anything async happens */
 /** Stuff that needs to be called ASAP, before anything async happens */
@@ -6828,8 +6849,6 @@ function onDomLoad() {
                     ftInit.push(["addWatermark", addWatermark()]);
                     ftInit.push(["addWatermark", addWatermark()]);
                 if (feats.fixSpacing)
                 if (feats.fixSpacing)
                     ftInit.push(["fixSpacing", fixSpacing()]);
                     ftInit.push(["fixSpacing", fixSpacing()]);
-                if (feats.removeUpgradeTab)
-                    ftInit.push(["removeUpgradeTab", removeUpgradeTab()]);
                 ftInit.push(["thumbnailOverlay", initThumbnailOverlay()]);
                 ftInit.push(["thumbnailOverlay", initThumbnailOverlay()]);
                 if (feats.hideCursorOnIdle)
                 if (feats.hideCursorOnIdle)
                     ftInit.push(["hideCursorOnIdle", initHideCursorOnIdle()]);
                     ftInit.push(["hideCursorOnIdle", initHideCursorOnIdle()]);
@@ -6939,7 +6958,7 @@ function registerDevMenuCommands() {
     }), "r");
     }), "r");
     GM.registerMenuCommand("Fix missing config values", () => __awaiter(this, void 0, void 0, function* () {
     GM.registerMenuCommand("Fix missing config values", () => __awaiter(this, void 0, void 0, function* () {
         const oldFeats = JSON.parse(JSON.stringify(getFeatures()));
         const oldFeats = JSON.parse(JSON.stringify(getFeatures()));
-        yield setFeatures(fixMissingCfgKeys(oldFeats));
+        yield setFeatures(fixCfgKeys(oldFeats));
         console.log("Fixed missing config values.\nFrom:", oldFeats, "\n\nTo:", getFeatures());
         console.log("Fixed missing config values.\nFrom:", oldFeats, "\n\nTo:", getFeatures());
         if (confirm("All missing or invalid config values were set to their default values.\nReload the page now?"))
         if (confirm("All missing or invalid config values were set to their default values.\nReload the page now?"))
             location.reload();
             location.reload();