Repository: anuraghazra/github-readme-stats
Pull request #3363 (2023-10-14 20:12:52)

docs: add top issues dashboard notice

vercel[bot]: [vc]: #ynLOLepN+S8fnwAsxX3GVG6fUvimxlqi2TCEevtc4MU=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJnaXRodWItcmVhZG1lLXN0YXRzIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL2dpdGh1Yi1yZWFkbWUtc3RhdHMtdGVhbS9naXRodWItcmVhZG1lLXN0YXRzLzVuVXYxcW5zaWdZR253bU1yNjJacmVGMUtzWDIiLCJwcmV2aWV3VXJsIjoiZ2l0aHViLXJlYWRtZS1zdGF0cy1naXQtZG9jc2FkZC05OWIzZTgtZ2l0aHViLXJlYWRtZS1zdGF0cy10ZWFtLnZlcmNlbC5hcHAiLCJuZXh0Q29tbWl0U3RhdHVzIjoiREVQTE9ZRUQifV19
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Updated (UTC) |
| :--- | :----- | :------ | :------ |
| **github-readme-stats** | ✅ Ready ([Inspect](https://vercel.com/github-readme-stats-team/github-readme-stats/5nUv1qnsigYGnwmMr62ZreF1KsX2)) | [Visit Preview](https://github-readme-stats-git-docsadd-99b3e8-github-readme-stats-team.vercel.app) | Oct 14, 2023 8:12pm |


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/anuraghazra/github-readme-stats/pull/3363?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra) Report
All modified lines are covered by tests :white_check_mark:
> Comparison is base [(`4fd52e6`)](https://app.codecov.io/gh/anuraghazra/github-readme-stats/commit/4fd52e6f64a579514e743ff2e7f7c9000075ed45?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra) 98.39% compared to head [(`57a36f5`)](https://app.codecov.io/gh/anuraghazra/github-readme-stats/pull/3363?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra) 98.39%.

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master    #3363   +/-   ##
=======================================
  Coverage   98.39%   98.39%           
=======================================
  Files          27       27           
  Lines        5979     5979           
  Branches      533      533           
=======================================
  Hits         5883     5883           
  Misses         93       93           
  Partials        3        3           
```




</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/anuraghazra/github-readme-stats/pull/3363?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Anurag+Hazra).


Patch:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8fdbf1f..d2244a1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -58,6 +58,12 @@ GitHub Readme Stats supports custom theming, and you can also contribute new the
 
 To contribute your theme you need to edit the [themes/index.js](./themes/index.js) file and add it at the end of the file.
 
+## Translations Contribution
+
+GitHub Readme Stats supports multiple languages, if we are missing your language, you can contribute it! You can check the currently supported languages [here](./readme.md#available-locales).
+
+To contribute your language you need to edit the [src/translations.js](./src/translations.js) file and add new property to each object where the key is the language code in [ISO 639-1 standard](https://www.andiamo.co.uk/resources/iso-language-codes/) and the value is the translated string.
+
 ## Any contributions you make will be under the MIT Software License
 
 In short, when you submit changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern.
diff --git a/readme.md b/readme.md
index 5015e14..ff826b3 100644
--- a/readme.md
+++ b/readme.md
@@ -24,6 +24,9 @@
     </a>
     <br />
     <br />
+    <a href="https://vercel.com?utm\_source=github\_readme\_stats\_team\&utm\_campaign=oss">
+      <img src="./powered-by-vercel.svg"/>
+    </a>
   </p>
 
   <p align="center">
@@ -118,13 +121,16 @@ Please visit [this link](https://give.do/fundraisers/stand-beside-the-victims-of
   - [Keep your fork up to date](#keep-your-fork-up-to-date)
 - [:sparkling\_heart: Support the project](#sparkling_heart-support-the-project)
 
-# Important Notice <!-- omit in toc -->
+# Important Notices <!-- omit in toc -->
 
 > [!IMPORTANT]\
 > Since the GitHub API only [allows 5k requests per hour per user account](https://docs.github.com/en/graphql/overview/resource-limitations), the public Vercel instance hosted on `https://github-readme-stats.vercel.app/api` could possibly hit the rate limiter (see [#1471](https://github.com/anuraghazra/github-readme-stats/issues/1471)). We use caching to prevent this from happening (see https://github.com/anuraghazra/github-readme-stats#common-options). You can turn off these rate limit protections by deploying [your own Vercel instance](#disable-rate-limit-protections).
 
 <img alt="Uptime Badge" src="https://img.shields.io/endpoint?url=https%3A%2F%2Fgithub-readme-stats-git-monitoring-github-readme-stats-team.vercel.app%2Fapi%2Fstatus%2Fup%3Ftype%3Dshields">
 
+> [!IMPORTANT]\
+> We're a small team, and to prioritize, we rely on upvotes :+1:. We use Top issues dashboard for tracking community demand (see [#1935](https://github.com/anuraghazra/github-readme-stats/issues/1935)). Do not hesitate to upvote the issues and pull requests you are interested in. We will work on the most upvoted first.
+
 # GitHub Stats Card
 
 Copy-paste this into your markdown content, and that is it. Simple!
diff --git a/scripts/generate-theme-doc.js b/scripts/generate-theme-doc.js
index 2d2458e..f39ef5c 100644
--- a/scripts/generate-theme-doc.js
+++ b/scripts/generate-theme-doc.js
@@ -22,7 +22,7 @@ Use \`?theme=THEME_NAME\` parameter like so:
 
 ## Stats
 
-> These themes work both for the Stats Card and Repo Card.
+> These themes works with all five our cards: Stats Card, Repo Card, Gist Card, Top languages Card and Wakatime Card.
 
 | | | |
 | :--: | :--: | :--: |
@@ -30,7 +30,7 @@ ${STAT_CARD_TABLE_FLAG}
 
 ## Repo Card
 
-> These themes work both for the Stats Card and Repo Card.
+> These themes works with all five our cards: Stats Card, Repo Card, Gist Card, Top languages Card and Wakatime Card.
 
 | | | |
 | :--: | :--: | :--: |
diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js
index dad81bb..88e7531 100644
--- a/src/cards/stats-card.js
+++ b/src/cards/stats-card.js
@@ -10,7 +10,6 @@ import {
   kFormatter,
   measureText,
 } from "../common/utils.js";
-import { getStyles } from "../getStyles.js";
 import { statCardLocales } from "../translations.js";
 
 const CARD_MIN_WIDTH = 287;
@@ -76,6 +75,118 @@ const createTextNode = ({
   `;
 };
 
+/**
+ * Calculates progress along the boundary of the circle i.e it's circumference.
+ *
+ * @param {number} value The rank value to calculate progress for.
+ * @returns {number} Progress value.
+ */
+const calculateCircleProgress = (value) => {
+  const radius = 40;
+  const c = Math.PI * (radius * 2);
+
+  if (value < 0) {
+    value = 0;
+  }
+  if (value > 100) {
+    value = 100;
+  }
+
+  return ((100 - value) / 100) * c;
+};
+
+/**
+ * Retrieves the animation to display progress along the circumference of circle
+ * from the beginning to the given value in a clockwise direction.
+ *
+ * @param {{progress: number}} progress The progress value to animate to.
+ * @returns {string} Progress animation css.
+ */
+const getProgressAnimation = ({ progress }) => {
+  return `
+    @keyframes rankAnimation {
+      from {
+        stroke-dashoffset: ${calculateCircleProgress(0)};
+      }
+      to {
+        stroke-dashoffset: ${calculateCircleProgress(progress)};
+      }
+    }
+  `;
+};
+
+/**
+ * Retrieves CSS styles for a card.
+ *
+ * @param {Object} colors The colors to use for the card.
+ * @param {string} colors.titleColor The title color.
+ * @param {string} colors.textColor The text color.
+ * @param {string} colors.iconColor The icon color.
+ * @param {string} colors.ringColor The ring color.
+ * @param {boolean} colors.show_icons Whether to show icons.
+ * @param {number} colors.progress The progress value to animate to.
+ * @returns {string} Card CSS styles.
+ */
+const getStyles = ({
+  // eslint-disable-next-line no-unused-vars
+  titleColor,
+  textColor,
+  iconColor,
+  ringColor,
+  show_icons,
+  progress,
+}) => {
+  return `
+    .stat {
+      font: 600 14px 'Segoe UI', Ubuntu, "Helvetica Neue", Sans-Serif; fill: ${textColor};
+    }
+    @supports(-moz-appearance: auto) {
+      /* Selector detects Firefox */
+      .stat { font-size:12px; }
+    }
+    .stagger {
+      opacity: 0;
+      animation: fadeInAnimation 0.3s ease-in-out forwards;
+    }
+    .rank-text {
+      font: 800 24px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor};
+      animation: scaleInAnimation 0.3s ease-in-out forwards;
+    }
+    .rank-percentile-header {
+      font-size: 14px;
+    }
+    .rank-percentile-text {
+      font-size: 16px;
+    }
+    
+    .not_bold { font-weight: 400 }
+    .bold { font-weight: 700 }
+    .icon {
+      fill: ${iconColor};
+      display: ${!!show_icons ? "block" : "none"};
+    }
+
+    .rank-circle-rim {
+      stroke: ${ringColor};
+      fill: none;
+      stroke-width: 6;
+      opacity: 0.2;
+    }
+    .rank-circle {
+      stroke: ${ringColor};
+      stroke-dasharray: 250;
+      fill: none;
+      stroke-width: 6;
+      stroke-linecap: round;
+      opacity: 0.8;
+      transform-origin: -10px 8px;
+      transform: rotate(-90deg);
+      animation: rankAnimation 1s forwards ease-in-out;
+    }
+    ${process.env.NODE_ENV === "test" ? "" : getProgressAnimation({ progress })}
+  `;
+};
+
 /**
  * @typedef {import('../fetchers/types').StatsData} StatsData
  * @typedef {import('./types').StatCardOptions} StatCardOptions
diff --git a/src/cards/wakatime-card.js b/src/cards/wakatime-card.js
index 187af7e..5dbee54 100644
--- a/src/cards/wakatime-card.js
+++ b/src/cards/wakatime-card.js
@@ -8,7 +8,6 @@ import {
   getCardColors,
   lowercaseTrim,
 } from "../common/utils.js";
-import { getStyles } from "../getStyles.js";
 import { wakatimeCardLocales } from "../translations.js";
 
 /** Import language colors.
@@ -158,6 +157,36 @@ const recalculatePercentages = (languages) => {
   });
 };
 
+/**
+ * Retrieves CSS styles for a card.
+ *
+ * @param {Object} colors The colors to use for the card.
+ * @param {string} colors.titleColor The title color.
+ * @param {string} colors.textColor The text color.
+ * @returns {string} Card CSS styles.
+ */
+const getStyles = ({
+  // eslint-disable-next-line no-unused-vars
+  titleColor,
+  textColor,
+}) => {
+  return `
+    .stat {
+      font: 600 14px 'Segoe UI', Ubuntu, "Helvetica Neue", Sans-Serif; fill: ${textColor};
+    }
+    @supports(-moz-appearance: auto) {
+      /* Selector detects Firefox */
+      .stat { font-size:12px; }
+    }
+    .stagger {
+      opacity: 0;
+      animation: fadeInAnimation 0.3s ease-in-out forwards;
+    }
+    .not_bold { font-weight: 400 }
+    .bold { font-weight: 700 }
+  `;
+};
+
 /**
  * @typedef {import('../fetchers/types').WakaTimeData} WakaTimeData
  * @typedef {import('./types').WakaTimeOptions} WakaTimeOptions
@@ -235,7 +264,6 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
   const cssStyles = getStyles({
     titleColor,
     textColor,
-    iconColor,
   });
 
   let finalLayout = "";
diff --git a/src/common/Card.js b/src/common/Card.js
index 33e6bb9..408ace9 100644
--- a/src/common/Card.js
+++ b/src/common/Card.js
@@ -1,4 +1,3 @@
-import { getAnimations } from "../getStyles.js";
 import { encodeHTML, flexLayout } from "./utils.js";
 
 class Card {
@@ -173,6 +172,33 @@ class Card {
       : "";
   }
 
+  /**
+   * Retrieves css animations for a card.
+   *
+   * @returns {string} Animation css.
+   */
+  getAnimations = () => {
+    return `
+      /* Animations */
+      @keyframes scaleInAnimation {
+        from {
+          transform: translate(-5px, 5px) scale(0);
+        }
+        to {
+          transform: translate(-5px, 5px) scale(1);
+        }
+      }
+      @keyframes fadeInAnimation {
+        from {
+          opacity: 0;
+        }
+        to {
+          opacity: 1;
+        }
+      }
+    `;
+  };
+
   /**
    * @param {string} body The inner body of the card.
    * @returns {string} The rendered card.
@@ -202,7 +228,7 @@ class Card {
           }
           ${this.css}
 
-          ${process.env.NODE_ENV === "test" ? "" : getAnimations()}
+          ${process.env.NODE_ENV === "test" ? "" : this.getAnimations()}
           ${
             this.animations === false
               ? `* { animation-duration: 0s !important; animation-delay: 0s !important; }`
diff --git a/src/getStyles.js b/src/getStyles.js
deleted file mode 100644
index c621ba1..0000000
--- a/src/getStyles.js
+++ /dev/null
@@ -1,142 +0,0 @@
-// @ts-check
-
-/**
- * Calculates progress along the boundary of the circle i.e it's circumference.
- *
- * @param {number} value The rank value to calculate progress for.
- * @returns {number} Progress value.
- */
-const calculateCircleProgress = (value) => {
-  const radius = 40;
-  const c = Math.PI * (radius * 2);
-
-  if (value < 0) {
-    value = 0;
-  }
-  if (value > 100) {
-    value = 100;
-  }
-
-  return ((100 - value) / 100) * c;
-};
-
-/**
- * Retrieves the animation to display progress along the circumference of circle
- * from the beginning to the given value in a clockwise direction.
- *
- * @param {{progress: number}} progress The progress value to animate to.
- * @returns {string} Progress animation css.
- */
-const getProgressAnimation = ({ progress }) => {
-  return `
-    @keyframes rankAnimation {
-      from {
-        stroke-dashoffset: ${calculateCircleProgress(0)};
-      }
-      to {
-        stroke-dashoffset: ${calculateCircleProgress(progress)};
-      }
-    }
-  `;
-};
-
-/**
- * Retrieves css animations for a card.
- *
- * @returns {string} Animation css.
- */
-const getAnimations = () => {
-  return `
-    /* Animations */
-    @keyframes scaleInAnimation {
-      from {
-        transform: translate(-5px, 5px) scale(0);
-      }
-      to {
-        transform: translate(-5px, 5px) scale(1);
-      }
-    }
-    @keyframes fadeInAnimation {
-      from {
-        opacity: 0;
-      }
-      to {
-        opacity: 1;
-      }
-    }
-  `;
-};
-
-/**
- * Retrieves CSS styles for a card.
- *
- * @param {Object} colors The colors to use for the card.
- * @param {string} colors.titleColor The title color.
- * @param {string} colors.textColor The text color.
- * @param {string} colors.iconColor The icon color.
- * @param {string} colors.ringColor The ring color.
- * @param {boolean} colors.show_icons Whether to show icons.
- * @param {number} colors.progress The progress value to animate to.
- * @returns {string} Card CSS styles.
- */
-const getStyles = ({
-  // eslint-disable-next-line no-unused-vars
-  titleColor,
-  textColor,
-  iconColor,
-  ringColor,
-  show_icons,
-  progress,
-}) => {
-  return `
-    .stat {
-      font: 600 14px 'Segoe UI', Ubuntu, "Helvetica Neue", Sans-Serif; fill: ${textColor};
-    }
-    @supports(-moz-appearance: auto) {
-      /* Selector detects Firefox */
-      .stat { font-size:12px; }
-    }
-    .stagger {
-      opacity: 0;
-      animation: fadeInAnimation 0.3s ease-in-out forwards;
-    }
-    .rank-text {
-      font: 800 24px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor};
-      animation: scaleInAnimation 0.3s ease-in-out forwards;
-    }
-    .rank-percentile-header {
-      font-size: 14px;
-    }
-    .rank-percentile-text {
-      font-size: 16px;
-    }
-    
-    .not_bold { font-weight: 400 }
-    .bold { font-weight: 700 }
-    .icon {
-      fill: ${iconColor};
-      display: ${!!show_icons ? "block" : "none"};
-    }
-
-    .rank-circle-rim {
-      stroke: ${ringColor};
-      fill: none;
-      stroke-width: 6;
-      opacity: 0.2;
-    }
-    .rank-circle {
-      stroke: ${ringColor};
-      stroke-dasharray: 250;
-      fill: none;
-      stroke-width: 6;
-      stroke-linecap: round;
-      opacity: 0.8;
-      transform-origin: -10px 8px;
-      transform: rotate(-90deg);
-      animation: rankAnimation 1s forwards ease-in-out;
-    }
-    ${process.env.NODE_ENV === "test" ? "" : getProgressAnimation({ progress })}
-  `;
-};
-
-export { getAnimations, getStyles };
diff --git a/src/index.js b/src/index.js
index 27577f8..ca8d586 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,3 +1,2 @@
 export * from "./common/index.js";
 export * from "./cards/index.js";
-export { getStyles, getAnimations } from "./getStyles.js";


Test patch:
diff --git a/tests/__snapshots__/renderWakatimeCard.test.js.snap b/tests/__snapshots__/renderWakatimeCard.test.js.snap
index 2050be0..69bd8ce 100644
--- a/tests/__snapshots__/renderWakatimeCard.test.js.snap
+++ b/tests/__snapshots__/renderWakatimeCard.test.js.snap
@@ -38,42 +38,8 @@ exports[`Test Render Wakatime Card should render correctly with compact layout 1
       opacity: 0;
       animation: fadeInAnimation 0.3s ease-in-out forwards;
     }
-    .rank-text {
-      font: 800 24px 'Segoe UI', Ubuntu, Sans-Serif; fill: #434d58;
-      animation: scaleInAnimation 0.3s ease-in-out forwards;
-    }
-    .rank-percentile-header {
-      font-size: 14px;
-    }
-    .rank-percentile-text {
-      font-size: 16px;
-    }
-    
     .not_bold { font-weight: 400 }
     .bold { font-weight: 700 }
-    .icon {
-      fill: #4c71f2;
-      display: none;
-    }
-
-    .rank-circle-rim {
-      stroke: undefined;
-      fill: none;
-      stroke-width: 6;
-      opacity: 0.2;
-    }
-    .rank-circle {
-      stroke: undefined;
-      stroke-dasharray: 250;
-      fill: none;
-      stroke-width: 6;
-      stroke-linecap: round;
-      opacity: 0.8;
-      transform-origin: -10px 8px;
-      transform: rotate(-90deg);
-      animation: rankAnimation 1s forwards ease-in-out;
-    }
-    
   
     @keyframes slideInAnimation {
       from {
@@ -224,42 +190,8 @@ exports[`Test Render Wakatime Card should render correctly with compact layout w
       opacity: 0;
       animation: fadeInAnimation 0.3s ease-in-out forwards;
     }
-    .rank-text {
-      font: 800 24px 'Segoe UI', Ubuntu, Sans-Serif; fill: #434d58;
-      animation: scaleInAnimation 0.3s ease-in-out forwards;
-    }
-    .rank-percentile-header {
-      font-size: 14px;
-    }
-    .rank-percentile-text {
-      font-size: 16px;
-    }
-    
     .not_bold { font-weight: 400 }
     .bold { font-weight: 700 }
-    .icon {
-      fill: #4c71f2;
-      display: none;
-    }
-
-    .rank-circle-rim {
-      stroke: undefined;
-      fill: none;
-      stroke-width: 6;
-      opacity: 0.2;
-    }
-    .rank-circle {
-      stroke: undefined;
-      stroke-dasharray: 250;
-      fill: none;
-      stroke-width: 6;
-      stroke-linecap: round;
-      opacity: 0.8;
-      transform-origin: -10px 8px;
-      transform: rotate(-90deg);
-      animation: rankAnimation 1s forwards ease-in-out;
-    }
-    
   
     @keyframes slideInAnimation {
       from {