diff --git a/package-lock.json b/package-lock.json index 50335c2..48dfc17 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1511,6 +1511,7 @@ "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.20.7.tgz", "integrity": "sha512-dVbLMubpJJSLI4OYB+yWYNHGAhgc2bVevWuBjDj8jFUXIJOAnLwYP3vsmtcgoxNGUXoq0rHS5f7MFCsryb6nzg==", "license": "MIT", + "peer": true, "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^0.6.0", @@ -1541,6 +1542,7 @@ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-5.0.3.tgz", "integrity": "sha512-MCFS6CrQDu1yGwspm4qtli0e63vaPCehf6V7pIMP15AsWgMKrqDGCPFF/0kn4SP0ii4aySu4Pa62+fIRGFMjgw==", "license": "MIT", + "peer": true, "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", "debug": "^4.4.0", @@ -1875,6 +1877,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1922,6 +1925,7 @@ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.9.tgz", "integrity": "sha512-EyZ9wWKgpAU0fLJ43YAEIF8sr5F2W3LqbS40ZJyHIner2lY14ufqv2VMp69MAiZ2rpwxEUxEhIH/0U3xyRynxg==", "license": "MIT", + "peer": true, "dependencies": { "@kurkle/color": "^0.3.0" }, @@ -2071,6 +2075,7 @@ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", "license": "MIT", + "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/kossnocorp" @@ -2786,6 +2791,7 @@ "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -2802,6 +2808,7 @@ "integrity": "sha512-yViK9zqQ+H2qZD1w/bH7W8i+bVfKrD8GIFjkFe4Thl6kCT9SlAsXVNmt3jCvQOCsnOhcvYgsoVlRV/Eu6x5nNw==", "dev": true, "license": "MIT", + "peer": true, "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" @@ -2935,6 +2942,7 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.1.tgz", "integrity": "sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw==", "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.7" }, @@ -3129,6 +3137,7 @@ "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.28.2.tgz", "integrity": "sha512-FbWBxgWOpQfhKvoGJv/TFwzqb4EhJbwCD17dB0tEpQiw1XyUEKZJtgm4nA4xq3LLsMo7hu5UY/BOFmroAxKTMg==", "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.3.0", "@jridgewell/sourcemap-codec": "^1.5.0", @@ -3229,6 +3238,7 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3260,6 +3270,7 @@ "integrity": "sha512-Wj7/AMtE9MRnAXa6Su3Lk0LNCfqDYgfwVjwRFVum9U7wsto1imuHqk4kTm7Jni+5A0Hn7dttL6O/zjvUvoo+8A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "defu": "^6.1.4", "exsolve": "^1.0.7", @@ -3273,6 +3284,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.3.tgz", "integrity": "sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==", "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -3367,6 +3379,7 @@ "dev": true, "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "bin": { "workerd": "bin/workerd" }, @@ -3401,6 +3414,7 @@ "integrity": "sha512-2qM6bHw8l7r89Z9Y5A7Wn4L9U+dFoLjYgEUVpqy7CcmXpppL3QIYqU6rU5lre7/SRzBuPu/H93Vwfh538gZ3iw==", "dev": true, "license": "MIT OR Apache-2.0", + "peer": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.4.0", "@cloudflare/unenv-preset": "2.7.8", diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index a7ec783..f3dc306 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -113,6 +113,11 @@ } } + // mobile detection for chart options (small, local change; keeps desktop unchanged) + const isMobile = + typeof window !== 'undefined' && window.matchMedia('(max-width: 640px)').matches; + const pointHoverRadius = isMobile ? 6 : 16; + if (!discordStats.success || discordStats.data.length === 0) return; // Initialize charts @@ -128,7 +133,7 @@ fill: true, tension: 0.2, pointRadius: 1, - pointHoverRadius: 16, + pointHoverRadius, borderWidth: 3 } ] @@ -210,7 +215,7 @@ fill: false, tension: 0.2, pointRadius: 1, - pointHoverRadius: 16, + pointHoverRadius, borderWidth: 3 }, { @@ -222,7 +227,7 @@ fill: false, tension: 0, pointRadius: 1, - pointHoverRadius: 16, + pointHoverRadius, borderWidth: 2 } ] @@ -295,133 +300,133 @@ {:else} -
-
-

Current Users

-

{discordStats.data[discordStats.data.length - 1].value}

-
-
-

Daily Growth

-

{formatPercent(growthRate)}

-
-
-

Accuracy (R²)*

-

{formatPercent(modelFit.rSquared)}

-
-
-

Milestones

-

- {milestones.length} milestone{milestones.length > 1 ? 's' : ''} -

-
- {#if milestoneDates.length > 0} -
-

Milestone Time

-

- {milestoneDates[0].daysFromNow} days -

-
- {/if} -
- - -
-
-
- -
-
-
-
- -
-
-
- - - {#if milestoneDates.length > 0} -
-

Upcoming Milestones

-
- {#each milestoneDates as milestone} -
-
{milestone.title}
-
+
+
+

Current Users

+

{discordStats.data[discordStats.data.length - 1].value}

+
+
+

Daily Growth

+

{formatPercent(growthRate)}

+
+
+

Accuracy (R²)*

+

{formatPercent(modelFit.rSquared)}

+
+
+

Milestones

+

+ {milestones.length} milestone{milestones.length > 1 ? 's' : ''} +

+
+ {#if milestoneDates.length > 0} +
+

Milestone Time

+

+ {milestoneDates[0].daysFromNow} days +

+
+ {/if} +
+ + +
+
+
+ +
+
+
+
+ +
+
+
+ + + {#if milestoneDates.length > 0} +
+

Upcoming Milestones

+
+ {#each milestoneDates as milestone} +
+
{milestone.title}
+
~{formatPredictionDate(milestone.date)} - ({milestone.daysFromNow} days) -
-
- {/each} -
-
- {/if} - - -
-
-
-

Current Status

-

- Current Users: {discordStats.data[discordStats.data.length - 1].value} -

-

- Historical Period: {historicalPeriod} days -

-

- Data Points: {discordStats.data.length} measurements -

-

- Peak: {maxValue} -

-
-
-

Growth Projections

- {#if predictions.length > 0} -

- 7 days: {predictions[weekIndex]?.value || 'N/A'} - - (+{formatPercent( - predictions[weekIndex].value / - discordStats.data[discordStats.data.length - 1].value - - 1 - )}) - -

-

- {predictionDays} days: - {predictions[endIndex]?.value || 'N/A'} - - (+{formatPercent( - predictions[endIndex].value / - discordStats.data[discordStats.data.length - 1].value - - 1 - )}) - -

- {/if} -
-
-
- - -
-

API Endpoints

-
    -
  • GET /api/members: { success: boolean, data: Array<{ date: string, value: number }> }
  • -
  • GET /api/predictions?days=<number>: { success: boolean, currentUsers: number, predictions: Array<{ date: string, value: number }>, modelFit: { rSquared: number, slope: number, intercept: number }, dailyGrowthRate: number }
  • -
  • GET /api/info: { success: boolean, data: { message: string, timestamp: string } }
  • -
-
- - -
- Sponsored by accuratelinuxgraphs.
- *Based on weighted log-linear regression (R²: {formatPercent(modelFit.rSquared)}). - accuratelinuxgraphs does not guarantee 100% accuracy or even 50% accuracy due to external - factors affecting Discord user growth.
TLDR: Not our fault if this is wrong. If you still - think its our fault, thats something you can learn to grow on! Sparkle on! -
- {/if} -
+ ({milestone.daysFromNow} days) +
+
+ {/each} +
+ + {/if} + + +
+
+
+

Current Status

+

+ Current Users: {discordStats.data[discordStats.data.length - 1].value} +

+

+ Historical Period: {historicalPeriod} days +

+

+ Data Points: {discordStats.data.length} measurements +

+

+ Peak: {maxValue} +

+
+
+

Growth Projections

+ {#if predictions.length > 0} +

+ 7 days: {predictions[weekIndex]?.value || 'N/A'} + + (+{formatPercent( + predictions[weekIndex].value / + discordStats.data[discordStats.data.length - 1].value - + 1 + )}) + +

+

+ {predictionDays} days: + {predictions[endIndex]?.value || 'N/A'} + + (+{formatPercent( + predictions[endIndex].value / + discordStats.data[discordStats.data.length - 1].value - + 1 + )}) + +

+ {/if} +
+
+
+ + +
+

API Endpoints

+ +
+ + +
+ Sponsored by accuratelinuxgraphs.
+ *Based on weighted log-linear regression (R²: {formatPercent(modelFit.rSquared)}). + accuratelinuxgraphs does not guarantee 100% accuracy or even 50% accuracy due to external + factors affecting Discord user growth.
TLDR: Not our fault if this is wrong. If you still + think its our fault, thats something you can learn to grow on! Sparkle on! +
+ {/if} +