From 8cc11367ef38bab47415c3ab98dffcbd0694a632 Mon Sep 17 00:00:00 2001 From: wukko Date: Thu, 13 Jun 2024 15:32:17 +0600 Subject: [PATCH 001/334] web: project skeleton --- web/.gitignore | 10 + web/.npmrc | 1 + web/README.md | 2 + web/package-lock.json | 1959 +++++++++++++++++++++++++++++++++++ web/package.json | 32 + web/src/app.d.ts | 13 + web/src/app.html | 12 + web/src/lib/index.ts | 1 + web/src/routes/+page.svelte | 1 + web/static/favicon.png | Bin 0 -> 1391 bytes web/svelte.config.js | 18 + web/tsconfig.json | 19 + web/vite.config.ts | 6 + 13 files changed, 2074 insertions(+) create mode 100644 web/.gitignore create mode 100644 web/.npmrc create mode 100644 web/README.md create mode 100644 web/package-lock.json create mode 100644 web/package.json create mode 100644 web/src/app.d.ts create mode 100644 web/src/app.html create mode 100644 web/src/lib/index.ts create mode 100644 web/src/routes/+page.svelte create mode 100644 web/static/favicon.png create mode 100644 web/svelte.config.js create mode 100644 web/tsconfig.json create mode 100644 web/vite.config.ts diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 00000000..6635cf55 --- /dev/null +++ b/web/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/web/.npmrc b/web/.npmrc new file mode 100644 index 00000000..b6f27f13 --- /dev/null +++ b/web/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/web/README.md b/web/README.md new file mode 100644 index 00000000..930f5029 --- /dev/null +++ b/web/README.md @@ -0,0 +1,2 @@ +# cobalt web +wip diff --git a/web/package-lock.json b/web/package-lock.json new file mode 100644 index 00000000..614fe446 --- /dev/null +++ b/web/package-lock.json @@ -0,0 +1,1959 @@ +{ + "name": "cobalt-web", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "cobalt-web", + "version": "0.0.1", + "license": "AGPL-3.0", + "devDependencies": { + "@sveltejs/adapter-auto": "^3.0.0", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.2.7", + "svelte-check": "^3.6.0", + "tslib": "^2.4.1", + "typescript": "^5.0.0", + "vite": "^5.0.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.25", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", + "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", + "dev": true + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sveltejs/adapter-auto": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.1.tgz", + "integrity": "sha512-/3xx8ZFCD5UBc/7AbyXkFF3HNCzWAp2xncH8HA4doGjoGQEN7PmwiRx4Y9nOzi4mqDqYYUic0gaIAE2khWWU4Q==", + "dev": true, + "dependencies": { + "import-meta-resolve": "^4.1.0" + }, + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.5.10", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.10.tgz", + "integrity": "sha512-OqoyTmFG2cYmCFAdBfW+Qxbg8m23H4dv6KqwEt7ofr/ROcfcIl3Z/VT56L22H9f0uNZyr+9Bs1eh2gedOCK9kA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^0.6.0", + "devalue": "^5.0.0", + "esm-env": "^1.0.0", + "import-meta-resolve": "^4.1.0", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "sade": "^1.8.1", + "set-cookie-parser": "^2.6.0", + "sirv": "^2.0.4", + "tiny-glob": "^0.2.9" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.3" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.1.tgz", + "integrity": "sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==", + "dev": true, + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", + "debug": "^4.3.4", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.10", + "svelte-hmr": "^0.16.0", + "vitefu": "^0.2.5" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", + "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/pug": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", + "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/axobject-query": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", + "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/code-red": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", + "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1", + "acorn": "^8.10.0", + "estree-walker": "^3.0.3", + "periscopic": "^3.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.0.0.tgz", + "integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==", + "dev": true + }, + "node_modules/es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/esm-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", + "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", + "dev": true + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", + "dev": true + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dev": true, + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "dev": true + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rollup": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sander": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", + "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", + "dev": true, + "dependencies": { + "es6-promise": "^3.1.2", + "graceful-fs": "^4.1.3", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", + "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", + "dev": true + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sorcery": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.1.tgz", + "integrity": "sha512-o7npfeJE6wi6J9l0/5LKshFzZ2rMatRiCDwYeDQaOzqdzRJwALhX7mk/A/ecg6wjMu7wdZbmXfD2S/vpOg0bdQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.14", + "buffer-crc32": "^1.0.0", + "minimist": "^1.2.0", + "sander": "^0.5.0" + }, + "bin": { + "sorcery": "bin/sorcery" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/svelte": { + "version": "4.2.18", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", + "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@jridgewell/sourcemap-codec": "^1.4.15", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/estree": "^1.0.1", + "acorn": "^8.9.0", + "aria-query": "^5.3.0", + "axobject-query": "^4.0.0", + "code-red": "^1.0.3", + "css-tree": "^2.3.1", + "estree-walker": "^3.0.3", + "is-reference": "^3.0.1", + "locate-character": "^3.0.0", + "magic-string": "^0.30.4", + "periscopic": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/svelte-check": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.0.tgz", + "integrity": "sha512-7Nxn+3X97oIvMzYJ7t27w00qUf1Y52irE2RU2dQAd5PyvfGp4E7NLhFKVhb6PV2fx7dCRMpNKDIuazmGthjpSQ==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "chokidar": "^3.4.1", + "fast-glob": "^3.2.7", + "import-fresh": "^3.2.1", + "picocolors": "^1.0.0", + "sade": "^1.7.4", + "svelte-preprocess": "^5.1.3", + "typescript": "^5.0.3" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "peerDependencies": { + "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" + } + }, + "node_modules/svelte-hmr": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", + "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", + "dev": true, + "engines": { + "node": "^12.20 || ^14.13.1 || >= 16" + }, + "peerDependencies": { + "svelte": "^3.19.0 || ^4.0.0" + } + }, + "node_modules/svelte-preprocess": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz", + "integrity": "sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/pug": "^2.0.6", + "detect-indent": "^6.1.0", + "magic-string": "^0.30.5", + "sorcery": "^0.11.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">= 16.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.10.2", + "coffeescript": "^2.5.1", + "less": "^3.11.3 || ^4.0.0", + "postcss": "^7 || ^8", + "postcss-load-config": "^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", + "pug": "^3.0.0", + "sass": "^1.26.8", + "stylus": "^0.55.0", + "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "svelte": "^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0", + "typescript": ">=3.9.5 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "coffeescript": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "postcss-load-config": { + "optional": true + }, + "pug": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dev": true, + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "5.2.13", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz", + "integrity": "sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==", + "dev": true, + "dependencies": { + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "dev": true, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + } + } +} diff --git a/web/package.json b/web/package.json new file mode 100644 index 00000000..1762262f --- /dev/null +++ b/web/package.json @@ -0,0 +1,32 @@ +{ + "name": "cobalt-web", + "version": "0.0.1", + "type": "module", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" + }, + "license": "AGPL-3.0", + "repository": { + "type": "git", + "url": "git+https://github.com/imputnet/cobalt.git" + }, + "bugs": { + "url": "https://github.com/imputnet/cobalt/issues" + }, + "homepage": "https://cobalt.tools/", + "devDependencies": { + "@sveltejs/adapter-auto": "^3.0.0", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.2.7", + "svelte-check": "^3.6.0", + "tslib": "^2.4.1", + "typescript": "^5.0.0", + "vite": "^5.0.3" + } +} diff --git a/web/src/app.d.ts b/web/src/app.d.ts new file mode 100644 index 00000000..c7c0ed1d --- /dev/null +++ b/web/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/web/src/app.html b/web/src/app.html new file mode 100644 index 00000000..88592f7a --- /dev/null +++ b/web/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/web/src/lib/index.ts b/web/src/lib/index.ts new file mode 100644 index 00000000..856f2b6c --- /dev/null +++ b/web/src/lib/index.ts @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte new file mode 100644 index 00000000..b4488011 --- /dev/null +++ b/web/src/routes/+page.svelte @@ -0,0 +1 @@ +

hello world

diff --git a/web/static/favicon.png b/web/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c94ccce2e435172cf392a64433c2aa2c80f7f7f9 GIT binary patch literal 1391 zcmb7EdpOez822BJk5f7)mlHz5HV!t_S%3E5Ie)z0`@Qc!-}8Lm^M0%VKW}ZgJ{$l5ZC@YH zKsD391GZLOpSe;bYSK#b38n%70{I;vP*#Cen;$mdv98PKE`_=73T+XKMn{UU63yf zOuDl-Q)97?>=B)JZz9D$ImF^T!+Ck=T*q$8T)uQ{b;e4{19uTYX+KwEew{6Pmtp?E zOg%h6i*TX_l8(ygG2^b8IA>$?C0ua_(nkzWGlQzvw_XFd0-<|=Z319807xTV^kc# znqr)5@21vR@HAR=3?u=jISZLQWB1R*O1%2!3z_G1alZ&eaQ?({S?~C7`q%MaG@pn> zwaYrx*tg#Faiw-l754V?+|H_*{dbA+w5fkuW^zC6=K4_`Uo`-B@GbkH+^mH$h2q|* zlCXkl)H8aULtuY&ohvFLn&nKA6YNV%43Zn+b&nvW zY1EjKe%8@;FH! zg3xQbCrn5uKvI8wJm?W#Sb1$^n3_@G49j=TbAQoJg4uG!%SfCTWf^8G6ff)IPEbTJTd8;)gY%~N>jIu21@Q^`-TZ|>WtNXB}dtNUbrN5B*c{-RJ z{c>9SX2Qzhyt1b{0ZUIV|IeiSm@99MRCO3{z-2gSp?YKx41ehe-O}jJhlx6hYTB#( zQ~t0_=c9+S)`|)A>X54Ij#9H1a%^wb(p~m!x!G6d66RyB4wRPld)lNM?PtQ`!<~CN z{hiuK3bXEPWW19ePm77sWUpL2sc^8f8q>BXUptlk=uDJBgb_;6C$<@F>q*?+wNv{L wV+k8!eBA!L$0Bv>Xl#5~O3Lh5HsazpPy$B2ABqFS>i-D%diit91@)$4EdT%j literal 0 HcmV?d00001 diff --git a/web/svelte.config.js b/web/svelte.config.js new file mode 100644 index 00000000..6599b78a --- /dev/null +++ b/web/svelte.config.js @@ -0,0 +1,18 @@ +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://kit.svelte.dev/docs/integrations#preprocessors + // for more information about preprocessors + preprocess: vitePreprocess(), + + kit: { + // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. + // If your environment is not supported, or you settled on a specific environment, switch out the adapter. + // See https://kit.svelte.dev/docs/adapters for more information about adapters. + adapter: adapter() + } +}; + +export default config; diff --git a/web/tsconfig.json b/web/tsconfig.json new file mode 100644 index 00000000..471ad319 --- /dev/null +++ b/web/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias + // except $lib which is handled by https://kit.svelte.dev/docs/configuration#files + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/web/vite.config.ts b/web/vite.config.ts new file mode 100644 index 00000000..4a79a4b1 --- /dev/null +++ b/web/vite.config.ts @@ -0,0 +1,6 @@ +import { sveltekit } from "@sveltejs/kit/vite"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [sveltekit()], +}); From c5c0d44a2ebaec5a4ad956ab93f9b99342a218e7 Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 29 Jul 2024 15:26:04 +0600 Subject: [PATCH 002/334] web: add license --- web/LICENSE | 437 ++++++++++++++++++++++++++++++++++++++++++ web/package-lock.json | 2 +- web/package.json | 2 +- 3 files changed, 439 insertions(+), 2 deletions(-) create mode 100644 web/LICENSE diff --git a/web/LICENSE b/web/LICENSE new file mode 100644 index 00000000..bfef380b --- /dev/null +++ b/web/LICENSE @@ -0,0 +1,437 @@ +Attribution-NonCommercial-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International +Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-NonCommercial-ShareAlike 4.0 International Public License +("Public License"). To the extent this Public License may be +interpreted as a contract, You are granted the Licensed Rights in +consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the +Licensor receives from making the Licensed Material available under +these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-NC-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution, NonCommercial, and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. NonCommercial means not primarily intended for or directed towards + commercial advantage or monetary compensation. For purposes of + this Public License, the exchange of the Licensed Material for + other material subject to Copyright and Similar Rights by digital + file-sharing or similar means is NonCommercial provided there is + no payment of monetary compensation in connection with the + exchange. + + l. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + m. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + n. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part, for NonCommercial purposes only; and + + b. produce, reproduce, and Share Adapted Material for + NonCommercial purposes only. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties, including when + the Licensed Material is used other than for NonCommercial + purposes. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-NC-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database for NonCommercial purposes + only; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + including for purposes of Section 3(b); and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. \ No newline at end of file diff --git a/web/package-lock.json b/web/package-lock.json index 614fe446..a6857de2 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "cobalt-web", "version": "0.0.1", - "license": "AGPL-3.0", + "license": "CC-BY-NC-SA-4.0", "devDependencies": { "@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/kit": "^2.0.0", diff --git a/web/package.json b/web/package.json index 1762262f..1c319ab2 100644 --- a/web/package.json +++ b/web/package.json @@ -10,7 +10,7 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, - "license": "AGPL-3.0", + "license": "CC-BY-NC-SA-4.0", "repository": { "type": "git", "url": "git+https://github.com/imputnet/cobalt.git" From fa85a4c75cef234906cfda5be54f328c44d20529 Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 29 Jul 2024 15:29:13 +0600 Subject: [PATCH 003/334] readme: update license info --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d5fe8164..518e89e8 100644 --- a/README.md +++ b/README.md @@ -79,9 +79,9 @@ cobalt is a tool for easing content downloads from internet and takes ***zero li cobalt is ***NOT*** a piracy tool and cannot be used as such. it can only download free, publicly accessible content. such content can be easily downloaded through any browser's dev tools. pressing one button is easier, so i made a convenient, ad-less tool for such repeated actions. ## cobalt license -cobalt code is licensed under [AGPL-3.0](/LICENSE). +cobalt api code is licensed under [AGPL-3.0](/LICENSE). cobalt web code is licensed under [CC-BY-NC-SA-4.0](/web/LICENSE). -cobalt branding, mascots, and other related assets included in the repo are ***copyrighted*** and not covered by the AGPL-3.0 license. you ***cannot*** use them under same terms. +cobalt branding, mascots, and other related assets included in the repo are ***copyrighted*** and not covered by the license. you ***cannot*** use them under same terms. you are allowed to host an ***unmodified*** instance of cobalt with branding, but this ***does not*** give you permission to use it anywhere else, or make derivatives of it in any way. From 38d7add0a929b3d82cb019ce9dd8d99f8bc4307c Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 16:33:01 +0600 Subject: [PATCH 004/334] web: navigation & sidebar --- web/package-lock.json | 62 ++++++++++------- web/package.json | 4 ++ web/src/components/sidebar/CobaltLogo.svelte | 15 ++++ web/src/components/sidebar/Sidebar.svelte | 72 ++++++++++++++++++++ web/src/components/sidebar/SidebarTab.svelte | 40 +++++++++++ web/src/routes/+layout.svelte | 41 +++++++++++ web/src/routes/+page.svelte | 3 +- web/src/routes/about/+page.svelte | 2 + web/src/routes/convert/+page.svelte | 2 + web/src/routes/crop/+page.svelte | 2 + web/src/routes/donate/+page.svelte | 2 + web/src/routes/settings/+page.svelte | 2 + web/src/routes/trim/+page.svelte | 2 + web/src/routes/updates/+page.svelte | 2 + 14 files changed, 225 insertions(+), 26 deletions(-) create mode 100644 web/src/components/sidebar/CobaltLogo.svelte create mode 100644 web/src/components/sidebar/Sidebar.svelte create mode 100644 web/src/components/sidebar/SidebarTab.svelte create mode 100644 web/src/routes/+layout.svelte create mode 100644 web/src/routes/about/+page.svelte create mode 100644 web/src/routes/convert/+page.svelte create mode 100644 web/src/routes/crop/+page.svelte create mode 100644 web/src/routes/donate/+page.svelte create mode 100644 web/src/routes/settings/+page.svelte create mode 100644 web/src/routes/trim/+page.svelte create mode 100644 web/src/routes/updates/+page.svelte diff --git a/web/package-lock.json b/web/package-lock.json index a6857de2..318aedaa 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -8,6 +8,10 @@ "name": "cobalt-web", "version": "0.0.1", "license": "CC-BY-NC-SA-4.0", + "dependencies": { + "@fontsource/ibm-plex-mono": "^5.0.13", + "@tabler/icons-svelte": "^3.6.0" + }, "devDependencies": { "@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/kit": "^2.0.0", @@ -23,7 +27,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -400,11 +403,15 @@ "node": ">=12" } }, + "node_modules/@fontsource/ibm-plex-mono": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz", + "integrity": "sha512-gtlMmvk//2AgDEZDFsoL5z9mgW3ZZg/9SC7pIfDwNKp5DtZpApgqd1Fua3HhPwYRIHrT76IQ1tMTzQKLEGtJGQ==" + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -418,7 +425,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -427,7 +433,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -435,14 +440,12 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -780,6 +783,30 @@ "vite": "^5.0.0" } }, + "node_modules/@tabler/icons": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.6.0.tgz", + "integrity": "sha512-Zv0Ofc64RCMpZ2F8CvsWAphrSjerx5hEErt/RMmE+W8r4E5l5Lizi+My9KbbZQ4NyAtrtrOX80OY1oROZrRzEA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + } + }, + "node_modules/@tabler/icons-svelte": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-svelte/-/icons-svelte-3.6.0.tgz", + "integrity": "sha512-phI61t81MlWhodATjvQQdqw8vTL0srSW6GsHzJmuhIMJGB4rwFzAXB2Ec4Pkz0vWFzVQgkeSE/AsiOLIUKWkxA==", + "dependencies": { + "@tabler/icons": "3.6.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "peerDependencies": { + "svelte": ">=3 <5" + } + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -789,8 +816,7 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/pug": { "version": "2.0.10", @@ -802,7 +828,6 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -827,7 +852,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, "dependencies": { "dequal": "^2.0.3" } @@ -836,7 +860,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", - "dev": true, "dependencies": { "dequal": "^2.0.3" } @@ -927,7 +950,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", - "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "@types/estree": "^1.0.1", @@ -955,7 +977,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -994,7 +1015,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, "engines": { "node": ">=6" } @@ -1068,7 +1088,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -1270,7 +1289,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dev": true, "dependencies": { "@types/estree": "*" } @@ -1287,14 +1305,12 @@ "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", - "dev": true + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" }, "node_modules/magic-string": { "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", - "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } @@ -1302,8 +1318,7 @@ "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" }, "node_modules/merge2": { "version": "1.4.1", @@ -1454,7 +1469,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^3.0.0", @@ -1692,7 +1706,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1713,7 +1726,6 @@ "version": "4.2.18", "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", - "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", diff --git a/web/package.json b/web/package.json index 1c319ab2..a675b11d 100644 --- a/web/package.json +++ b/web/package.json @@ -28,5 +28,9 @@ "tslib": "^2.4.1", "typescript": "^5.0.0", "vite": "^5.0.3" + }, + "dependencies": { + "@fontsource/ibm-plex-mono": "^5.0.13", + "@tabler/icons-svelte": "^3.6.0" } } diff --git a/web/src/components/sidebar/CobaltLogo.svelte b/web/src/components/sidebar/CobaltLogo.svelte new file mode 100644 index 00000000..26d58efb --- /dev/null +++ b/web/src/components/sidebar/CobaltLogo.svelte @@ -0,0 +1,15 @@ + + + diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte new file mode 100644 index 00000000..ce5e6a7b --- /dev/null +++ b/web/src/components/sidebar/Sidebar.svelte @@ -0,0 +1,72 @@ + + + + + diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte new file mode 100644 index 00000000..9dfa051a --- /dev/null +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -0,0 +1,40 @@ + + + + + {tabName} + + + diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte new file mode 100644 index 00000000..b2917a1d --- /dev/null +++ b/web/src/routes/+layout.svelte @@ -0,0 +1,41 @@ + + +
+ +
+ +
+
+ + diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index b4488011..1b1b69e5 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -1 +1,2 @@ -

hello world

+ +
home
diff --git a/web/src/routes/about/+page.svelte b/web/src/routes/about/+page.svelte new file mode 100644 index 00000000..e6a55ff1 --- /dev/null +++ b/web/src/routes/about/+page.svelte @@ -0,0 +1,2 @@ + +
about
diff --git a/web/src/routes/convert/+page.svelte b/web/src/routes/convert/+page.svelte new file mode 100644 index 00000000..804a21ff --- /dev/null +++ b/web/src/routes/convert/+page.svelte @@ -0,0 +1,2 @@ + +
convert
diff --git a/web/src/routes/crop/+page.svelte b/web/src/routes/crop/+page.svelte new file mode 100644 index 00000000..3cb79e88 --- /dev/null +++ b/web/src/routes/crop/+page.svelte @@ -0,0 +1,2 @@ + +
crop
diff --git a/web/src/routes/donate/+page.svelte b/web/src/routes/donate/+page.svelte new file mode 100644 index 00000000..49f8a142 --- /dev/null +++ b/web/src/routes/donate/+page.svelte @@ -0,0 +1,2 @@ + +
donate
diff --git a/web/src/routes/settings/+page.svelte b/web/src/routes/settings/+page.svelte new file mode 100644 index 00000000..51f4f6c2 --- /dev/null +++ b/web/src/routes/settings/+page.svelte @@ -0,0 +1,2 @@ + +
settings
diff --git a/web/src/routes/trim/+page.svelte b/web/src/routes/trim/+page.svelte new file mode 100644 index 00000000..7dbcf323 --- /dev/null +++ b/web/src/routes/trim/+page.svelte @@ -0,0 +1,2 @@ + +
trim
diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte new file mode 100644 index 00000000..ff1b2d95 --- /dev/null +++ b/web/src/routes/updates/+page.svelte @@ -0,0 +1,2 @@ + +
updates
From b831dc82361aa9ae7a663a440c019d76130cce1c Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 16:38:10 +0600 Subject: [PATCH 005/334] web: space out css --- web/src/components/sidebar/Sidebar.svelte | 2 ++ web/src/components/sidebar/SidebarTab.svelte | 2 ++ web/src/routes/+layout.svelte | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index ce5e6a7b..a76ad5cb 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -58,12 +58,14 @@ display: flex; flex-direction: column; } + #sidebar { background: black; height: 100vh; position: sticky; width: var(--sidebar-width); } + #sidebar-tabs { height: 100%; justify-content: space-between; diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 9dfa051a..27676df0 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -29,11 +29,13 @@ font-size: var(--sidebar-font-size); opacity: 0.8; } + .sidebar-tab.active { color: var(--background); background: var(--accent); opacity: 1; } + .sidebar-tab:hover { opacity: 1; } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index b2917a1d..f91c7a01 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -19,21 +19,25 @@ --sidebar-font-size: 11px; --sidebar-padding: 12px; } + :global(html), :global(body) { font-family: "IBM Plex Mono", "Noto Sans Mono", monospace; margin: 0; } + :global(a) { text-decoration: none; text-decoration-line: none; } + #cobalt { height: 100vh; display: grid; grid-template-columns: var(--sidebar-width) 1fr; overflow: hidden; } + #content { display: flex; overflow: scroll; From 5399ee9a4cf76846dc29b12c7c1828e8d6fad060 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 16:47:13 +0600 Subject: [PATCH 006/334] web: make sidebar scrollable on vertical overflow --- web/src/components/sidebar/Sidebar.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index a76ad5cb..368eaac0 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -70,5 +70,6 @@ height: 100%; justify-content: space-between; padding-bottom: var(--sidebar-padding); + overflow: scroll; } From 92cccd720dedf97cb3b7100f631b6eb94556a804 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 17:33:33 +0600 Subject: [PATCH 007/334] web: mobile navigation --- web/src/components/sidebar/CobaltLogo.svelte | 5 +++ web/src/components/sidebar/Sidebar.svelte | 35 ++++++++++++++++++++ web/src/components/sidebar/SidebarTab.svelte | 10 ++++++ web/src/routes/+layout.svelte | 10 ++++++ 4 files changed, 60 insertions(+) diff --git a/web/src/components/sidebar/CobaltLogo.svelte b/web/src/components/sidebar/CobaltLogo.svelte index 26d58efb..aa269f20 100644 --- a/web/src/components/sidebar/CobaltLogo.svelte +++ b/web/src/components/sidebar/CobaltLogo.svelte @@ -12,4 +12,9 @@ align-items: center; padding: calc(var(--sidebar-padding) * 2 - 2px); } + @media screen and (max-width: 535px) { + #cobalt-logo { + display: none; + } + } diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index 368eaac0..43b4cf58 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -72,4 +72,39 @@ padding-bottom: var(--sidebar-padding); overflow: scroll; } + + @media screen and (max-width: 535px) { + #sidebar, + #sidebar-tabs, + .sidebar-inner-container { + flex-direction: row; + } + #sidebar { + width: 100%; + height: auto; + overflow: scroll; + position: fixed; + bottom: 0; + } + #sidebar::before { + content: ''; + z-index: 1; + width: 100%; + height: 100%; + display: block; + position: absolute; + pointer-events: none; + background: linear-gradient(90deg, + rgba(0, 0, 0, 0.9) 0%, + rgba(0, 0, 0, 0) 4%, + rgba(0, 0, 0, 0) 50%, + rgba(0, 0, 0, 0) 96%, + rgba(0, 0, 0, 0.9) 100% + ); + } + #sidebar-tabs { + justify-content: space-around; + padding-bottom: 0; + } + } diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 27676df0..cd86711e 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -39,4 +39,14 @@ .sidebar-tab:hover { opacity: 1; } + + @media screen and (max-width: 535px) { + .sidebar-tab { + padding: 5px var(--sidebar-padding); + min-width: calc(var(--sidebar-width) / 2); + } + .sidebar-tab.active { + z-index: 2; + } + } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index f91c7a01..56bed2d2 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -42,4 +42,14 @@ display: flex; overflow: scroll; } + @media screen and (max-width: 535px) { + #cobalt { + display: grid; + grid-template-columns: unset; + grid-template-rows: 1fr var(--sidebar-width); + } + #content { + order: -1; + } + } From 7cab37fc304ba9ee2a83952c493c9c89aeb763d6 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 17:34:14 +0600 Subject: [PATCH 008/334] web: disable tap highlighting & user selection --- web/src/routes/+layout.svelte | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 56bed2d2..0ef57b2a 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -24,6 +24,9 @@ :global(body) { font-family: "IBM Plex Mono", "Noto Sans Mono", monospace; margin: 0; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + user-select: none; + -webkit-user-select: none; } :global(a) { From e6ffa4864c51d69fb87044aeef5603c31a6fd612 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 14 Jun 2024 21:48:57 +0600 Subject: [PATCH 009/334] web: omnibox base with meowbalt --- web/package-lock.json | 6 + web/package.json | 1 + web/src/components/save/Omnibox.svelte | 111 ++++++++++++++++++ .../save/buttons/ClearButton.svelte | 15 +++ .../save/buttons/DownloadButton.svelte | 54 +++++++++ web/src/components/sidebar/CobaltLogo.svelte | 2 +- web/src/components/sidebar/Sidebar.svelte | 7 +- web/src/components/sidebar/SidebarTab.svelte | 10 +- web/src/routes/+layout.svelte | 44 ++++++- web/src/routes/+page.svelte | 52 +++++++- web/static/meowbalt/smile.png | Bin 0 -> 16660 bytes 11 files changed, 286 insertions(+), 16 deletions(-) create mode 100644 web/src/components/save/Omnibox.svelte create mode 100644 web/src/components/save/buttons/ClearButton.svelte create mode 100644 web/src/components/save/buttons/DownloadButton.svelte create mode 100644 web/static/meowbalt/smile.png diff --git a/web/package-lock.json b/web/package-lock.json index 318aedaa..fa609f93 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.1", "license": "CC-BY-NC-SA-4.0", "dependencies": { + "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", "@tabler/icons-svelte": "^3.6.0" }, @@ -403,6 +404,11 @@ "node": ">=12" } }, + "node_modules/@fontsource-variable/noto-sans-mono": { + "version": "5.0.20", + "resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-mono/-/noto-sans-mono-5.0.20.tgz", + "integrity": "sha512-Mik/wbKjiir7t+KBaDZnPZ5GjDnPOXpMF7obmFeyRa528ZsrKcFiSn4ZvArrn3sJMCp/k23wakOcXOWlGNc9cw==" + }, "node_modules/@fontsource/ibm-plex-mono": { "version": "5.0.13", "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz", diff --git a/web/package.json b/web/package.json index a675b11d..ad8cc3f1 100644 --- a/web/package.json +++ b/web/package.json @@ -30,6 +30,7 @@ "vite": "^5.0.3" }, "dependencies": { + "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", "@tabler/icons-svelte": "^3.6.0" } diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte new file mode 100644 index 00000000..5926135b --- /dev/null +++ b/web/src/components/save/Omnibox.svelte @@ -0,0 +1,111 @@ + + +
+
+ + + isFocused = true} + on:focus={() => isFocused = true} + on:blur={() => isFocused = false} + + spellcheck="false" + autocomplete="off" + autocapitalize="off" + maxlength="256" + + placeholder="paste the link here" + aria-label="link input area" + > + + {#if link.length > 0} + link = ""} /> + {/if} + {#if validLink(link)} + + {/if} +
+
+ + diff --git a/web/src/components/save/buttons/ClearButton.svelte b/web/src/components/save/buttons/ClearButton.svelte new file mode 100644 index 00000000..76f20d3e --- /dev/null +++ b/web/src/components/save/buttons/ClearButton.svelte @@ -0,0 +1,15 @@ + + + + + diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte new file mode 100644 index 00000000..a9b09945 --- /dev/null +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -0,0 +1,54 @@ + + + + + diff --git a/web/src/components/sidebar/CobaltLogo.svelte b/web/src/components/sidebar/CobaltLogo.svelte index aa269f20..9cb25ff2 100644 --- a/web/src/components/sidebar/CobaltLogo.svelte +++ b/web/src/components/sidebar/CobaltLogo.svelte @@ -10,7 +10,7 @@ display: flex; justify-content: center; align-items: center; - padding: calc(var(--sidebar-padding) * 2 - 2px); + padding: calc(var(--padding) * 2 - 2px); } @media screen and (max-width: 535px) { #cobalt-logo { diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index 43b4cf58..64671620 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -60,7 +60,7 @@ } #sidebar { - background: black; + background: var(--secondary); height: 100vh; position: sticky; width: var(--sidebar-width); @@ -69,7 +69,7 @@ #sidebar-tabs { height: 100%; justify-content: space-between; - padding-bottom: var(--sidebar-padding); + padding-bottom: var(--padding); overflow: scroll; } @@ -94,7 +94,8 @@ display: block; position: absolute; pointer-events: none; - background: linear-gradient(90deg, + background: linear-gradient( + 90deg, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0) 4%, rgba(0, 0, 0, 0) 50%, diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index cd86711e..c868295e 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -24,15 +24,15 @@ align-items: center; text-align: center; gap: 5px; - padding: var(--sidebar-padding) 5px; - color: var(--accent); + padding: var(--padding) 5px; + color: var(--primary); font-size: var(--sidebar-font-size); opacity: 0.8; } .sidebar-tab.active { - color: var(--background); - background: var(--accent); + color: var(--secondary); + background: var(--primary); opacity: 1; } @@ -42,7 +42,7 @@ @media screen and (max-width: 535px) { .sidebar-tab { - padding: 5px var(--sidebar-padding); + padding: 5px var(--padding); min-width: calc(var(--sidebar-width) / 2); } .sidebar-tab.active { diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 0ef57b2a..48bb34bd 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -13,20 +13,32 @@ diff --git a/web/static/meowbalt/smile.png b/web/static/meowbalt/smile.png new file mode 100644 index 0000000000000000000000000000000000000000..e4b1824e0eaddd9f358fdc50fb82e7fd5ac19e19 GIT binary patch literal 16660 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 literal 0 HcmV?d00001 From bf26988cde771e1b4c41a3cfac71cc9b85b6cb72 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 15 Jun 2024 20:39:34 +0600 Subject: [PATCH 010/334] web/save: add paste button & dummy mode buttons tuned default button look, moved custom icons to lib for easy access --- .../components/buttons/ActionButton.svelte | 10 ++++ web/src/components/save/Omnibox.svelte | 46 +++++++++++++++++++ .../save/buttons/DownloadButton.svelte | 3 ++ web/src/components/sidebar/CobaltLogo.svelte | 9 ++-- web/src/lib/icons/Clipboard.svelte | 11 +++++ web/src/lib/icons/Cobalt.svelte | 4 ++ web/src/lib/icons/Music.svelte | 5 ++ web/src/lib/icons/Sparkles.svelte | 5 ++ web/src/routes/+layout.svelte | 18 +++++--- 9 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 web/src/components/buttons/ActionButton.svelte create mode 100644 web/src/lib/icons/Clipboard.svelte create mode 100644 web/src/lib/icons/Cobalt.svelte create mode 100644 web/src/lib/icons/Music.svelte create mode 100644 web/src/lib/icons/Sparkles.svelte diff --git a/web/src/components/buttons/ActionButton.svelte b/web/src/components/buttons/ActionButton.svelte new file mode 100644 index 00000000..13c126bf --- /dev/null +++ b/web/src/components/buttons/ActionButton.svelte @@ -0,0 +1,10 @@ + + + diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 5926135b..7ec197e4 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -3,6 +3,11 @@ import DownloadButton from './buttons/DownloadButton.svelte'; import ClearButton from './buttons/ClearButton.svelte'; + import ActionButton from '../buttons/ActionButton.svelte'; + + import IconClipboard from '$lib/icons/Clipboard.svelte'; + import IconMusic from '$lib/icons/Music.svelte'; + import IconSparkles from '$lib/icons/Sparkles.svelte'; let link: string = ""; let isFocused = false; @@ -14,6 +19,15 @@ return false } } + + const pasteClipboard = () => { + navigator.clipboard.readText().then(text => { + let matchLink = text.match(/https:\/\/[^\s]+/g); + if (matchLink) { + link = matchLink[0]; + } + }); + }
@@ -44,6 +58,29 @@ {/if}
+
+
+ + + + + + +
+ + + +
diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index a9b09945..6e2f004c 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -17,7 +17,10 @@ border-radius: 0; padding: 0 12px; + background: none; + box-shadow: none; + transform: none; border-left: 1px var(--gray) solid; border-top-right-radius: 11px; diff --git a/web/src/components/sidebar/CobaltLogo.svelte b/web/src/components/sidebar/CobaltLogo.svelte index 9cb25ff2..891da1da 100644 --- a/web/src/components/sidebar/CobaltLogo.svelte +++ b/web/src/components/sidebar/CobaltLogo.svelte @@ -1,8 +1,9 @@ + + diff --git a/web/src/components/buttons/Switcher.svelte b/web/src/components/buttons/Switcher.svelte new file mode 100644 index 00000000..dd457177 --- /dev/null +++ b/web/src/components/buttons/Switcher.svelte @@ -0,0 +1,35 @@ + + +
+ +
+ + diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 7ec197e4..dabec6cb 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -1,13 +1,17 @@
-
+
isFocused = true} - on:focus={() => isFocused = true} - on:blur={() => isFocused = false} - + on:input={() => (isFocused = true)} + on:focus={() => (isFocused = true)} + on:blur={() => (isFocused = false)} spellcheck="false" autocomplete="off" autocapitalize="off" maxlength="256" - placeholder="paste the link here" aria-label="link input area" - > + /> {#if link.length > 0} - link = ""} /> + (link = "")} /> {/if} {#if validLink(link)} {/if}
+
-
- - + + + - + -
- + + + + +
@@ -100,7 +99,7 @@ align-items: center; gap: 10px; font-size: 14px; - flex: 1 + flex: 1; } #input-container.downloadable { @@ -143,14 +142,14 @@ } #link-area::placeholder { - color: var(--gray) + color: var(--gray); } - #action-container, - #mode-switcher { + #action-container { display: flex; flex-direction: row; } + #action-container { justify-content: space-between; } diff --git a/web/src/lib/icons/Mute.svelte b/web/src/lib/icons/Mute.svelte new file mode 100644 index 00000000..5b2644b1 --- /dev/null +++ b/web/src/lib/icons/Mute.svelte @@ -0,0 +1,5 @@ + + + + + From 1f2c28bd029ab7e989465ba53d6933a74fa0e809 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 18:22:44 +0600 Subject: [PATCH 012/334] web: basic api interaction & downloading download button now acts the way it should with various states --- web/src/components/save/Omnibox.svelte | 2 +- .../save/buttons/DownloadButton.svelte | 75 ++++++++++++++++++- web/src/lib/api.ts | 31 ++++++++ web/src/lib/index.ts | 1 - 4 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 web/src/lib/api.ts delete mode 100644 web/src/lib/index.ts diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index dabec6cb..cabff743 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -60,7 +60,7 @@ (link = "")} /> {/if} {#if validLink(link)} - + {/if}
diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 6e2f004c..9ebb2234 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -1,9 +1,78 @@ - - diff --git a/web/src/components/misc/Placeholder.svelte b/web/src/components/misc/Placeholder.svelte new file mode 100644 index 00000000..01dd78f1 --- /dev/null +++ b/web/src/components/misc/Placeholder.svelte @@ -0,0 +1,16 @@ + + +
+ +
{pageName} page is not ready yet!
+
+ + diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 5dd708fc..55040fea 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -80,6 +80,14 @@ background-color: var(--button-hover); } + :global(.center-column-container) { + display: flex; + width: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + } + #cobalt { height: 100vh; display: grid; diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 654698ef..bd364ec1 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -1,15 +1,11 @@ -
+
- black and white cat smiling and loafing +
@@ -18,12 +14,6 @@
From 2080a3e1ae31bac8d3908c783cbdf017b2173f09 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 20:39:23 +0600 Subject: [PATCH 025/334] web/sidebar: fix grid on mobile --- web/src/components/sidebar/Sidebar.svelte | 2 +- web/src/routes/+layout.svelte | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index e7b753bf..5ea169b2 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -81,7 +81,7 @@ #sidebar { width: 100%; - height: auto; + height: var(--sidebar-height-mobile); position: fixed; bottom: 0; } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 55040fea..d83aea9a 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -26,6 +26,7 @@ --border-radius: 11px; --sidebar-width: 80px; + --sidebar-height-mobile: 50px; --sidebar-font-size: 11px; } @@ -105,7 +106,7 @@ #cobalt { display: grid; grid-template-columns: unset; - grid-template-rows: 1fr var(--sidebar-width); + grid-template-rows: 1fr var(--sidebar-height-mobile); } #content { order: -1; From f8f248f399a04a681bacf46e09b77efe405ed507 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 21:45:24 +0600 Subject: [PATCH 026/334] web: dark theme & coloring, border, focus fixes --- web/src/components/save/Omnibox.svelte | 2 +- .../save/buttons/DownloadButton.svelte | 2 +- web/src/components/sidebar/Sidebar.svelte | 11 +--- web/src/components/sidebar/SidebarTab.svelte | 16 ++++-- web/src/routes/+layout.svelte | 53 +++++++++++++++++++ 5 files changed, 70 insertions(+), 14 deletions(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 78368e93..d876b208 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -93,7 +93,7 @@ #input-container { display: flex; - box-shadow: 0 0 0 1.5px var(--gray) inset; + box-shadow: 0 0 0 1.5px var(--input-border) inset; border-radius: var(--border-radius); padding: 0 12px; align-items: center; diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 62ef1e00..e4379c84 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -100,7 +100,7 @@ box-shadow: none; transform: none; - border-left: 1px var(--gray) solid; + border-left: 1.5px var(--input-border) solid; border-top-right-radius: var(--border-radius); border-bottom-right-radius: var(--border-radius); } diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index 5ea169b2..b73e392e 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -59,7 +59,7 @@ } #sidebar { - background: var(--secondary); + background: var(--sidebar-bg); height: 100vh; width: var(--sidebar-width); position: sticky; @@ -94,14 +94,7 @@ display: block; position: absolute; pointer-events: none; - background: linear-gradient( - 90deg, - rgba(0, 0, 0, 0.9) 0%, - rgba(0, 0, 0, 0) 4%, - rgba(0, 0, 0, 0) 50%, - rgba(0, 0, 0, 0) 96%, - rgba(0, 0, 0, 0.9) 100% - ); + background: var(--sidebar-mobile-gradient); } #sidebar-tabs { diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index c868295e..e2f8c9b8 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -25,14 +25,14 @@ text-align: center; gap: 5px; padding: var(--padding) 5px; - color: var(--primary); + color: var(--sidebar-highlight); font-size: var(--sidebar-font-size); opacity: 0.8; } .sidebar-tab.active { - color: var(--secondary); - background: var(--primary); + color: var(--sidebar-bg); + background: var(--sidebar-highlight); opacity: 1; } @@ -40,6 +40,16 @@ opacity: 1; } + .sidebar-tab:focus-visible { + box-shadow: 0 0 0 1.5px var(--sidebar-highlight) inset; + outline: none; + z-index: 1; + } + + .sidebar-tab.active:focus-visible { + box-shadow: 0 0 0 1.5px var(--sidebar-bg) inset; + } + @media screen and (max-width: 535px) { .sidebar-tab { padding: 5px var(--padding); diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index d83aea9a..25080a22 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -22,17 +22,62 @@ --button-hover-transparent: rgba(0, 0, 0, 0.03); --button-stroke: rgba(0, 0, 0, 0.08); + --sidebar-bg: #000000; + --sidebar-highlight: #ffffff; + + --input-border: #8d8d95; + --padding: 12px; --border-radius: 11px; --sidebar-width: 80px; --sidebar-height-mobile: 50px; --sidebar-font-size: 11px; + + --sidebar-mobile-gradient: linear-gradient( + 90deg, + rgba(0, 0, 0, 0.9) 0%, + rgba(0, 0, 0, 0) 4%, + rgba(0, 0, 0, 0) 50%, + rgba(0, 0, 0, 0) 96%, + rgba(0, 0, 0, 0.9) 100% + ); + } + + /* temporary switcher until theming is implemented, */ + /* just so my eyes don't burn at night */ + @media (prefers-color-scheme: dark) { + :global(:root) { + --primary: #000000; + --secondary: #e1e1e1; + --gray: #6e6e6e; + + --button: #191919; + --button-hover: #2a2a2a; + --button-hover-transparent: rgba(225, 225, 225, 0.04); + --button-stroke: rgba(255, 255, 255, 0.08); + + --sidebar-bg: #101010; + --sidebar-highlight: #f2f2f2; + + --input-border: #383838; + + --sidebar-mobile-gradient: linear-gradient( + 90deg, + rgba(16, 16, 16, 0.9) 0%, + rgba(16, 16, 16, 0) 4%, + rgba(16, 16, 16, 0) 50%, + rgba(16, 16, 16, 0) 96%, + rgba(16, 16, 16, 0.9) 100% + ); + } } :global(html), :global(body) { margin: 0; + background-color: var(--primary); + color: var(--secondary); } :global(*) { @@ -73,12 +118,19 @@ box-shadow: 0 0 0 1.5px var(--button-stroke) inset; } + :global(button:focus-visible) { + box-shadow: 0 0 0 1.5px var(--secondary) inset; + outline: none; + z-index: 1; + } + :global(button:active) { transform: scale(0.95); } :global(button:hover) { background-color: var(--button-hover); + z-index: 1; } :global(.center-column-container) { @@ -100,6 +152,7 @@ display: flex; overflow: scroll; padding: var(--padding); + background-color: var(--primary); } @media screen and (max-width: 535px) { From 66a1e9e953af000350e68611f99e1ec6d5384fcb Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 21:54:02 +0600 Subject: [PATCH 027/334] web/omnibox: prevent password manager autofill --- web/src/components/save/Omnibox.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index d876b208..f969590b 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -54,6 +54,7 @@ maxlength="256" placeholder="paste the link here" aria-label="link input area" + data-form-type="other" /> {#if link.length > 0} From 3fc7b99d05064ed477130510365e716caf60f1a1 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 22:00:26 +0600 Subject: [PATCH 028/334] web: add manifest, more icons, and some metadata --- web/src/app.html | 13 +++- web/static/icons/android-chrome-192x192.png | Bin 0 -> 3580 bytes web/static/icons/android-chrome-512x512.png | Bin 0 -> 9818 bytes web/static/icons/apple-touch-icon.png | Bin 0 -> 3278 bytes web/static/icons/generic.png | Bin 0 -> 9818 bytes web/static/icons/maskable/128.png | Bin 0 -> 815 bytes web/static/icons/maskable/192.png | Bin 0 -> 1014 bytes web/static/icons/maskable/384.png | Bin 0 -> 1856 bytes web/static/icons/maskable/48.png | Bin 0 -> 390 bytes web/static/icons/maskable/512.png | Bin 0 -> 2828 bytes web/static/icons/maskable/72.png | Bin 0 -> 569 bytes web/static/icons/maskable/96.png | Bin 0 -> 617 bytes web/static/manifest.json | 75 ++++++++++++++++++++ 13 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 web/static/icons/android-chrome-192x192.png create mode 100644 web/static/icons/android-chrome-512x512.png create mode 100644 web/static/icons/apple-touch-icon.png create mode 100644 web/static/icons/generic.png create mode 100644 web/static/icons/maskable/128.png create mode 100644 web/static/icons/maskable/192.png create mode 100644 web/static/icons/maskable/384.png create mode 100644 web/static/icons/maskable/48.png create mode 100644 web/static/icons/maskable/512.png create mode 100644 web/static/icons/maskable/72.png create mode 100644 web/static/icons/maskable/96.png create mode 100644 web/static/manifest.json diff --git a/web/src/app.html b/web/src/app.html index 8f8e1666..e4d684a2 100644 --- a/web/src/app.html +++ b/web/src/app.html @@ -2,8 +2,19 @@ - + + cobalt + + + + + + + + + + %sveltekit.head% diff --git a/web/static/icons/android-chrome-192x192.png b/web/static/icons/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..0d3ac83a24696f6d2e99ffe51177a583e01a6533 GIT binary patch literal 3580 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 literal 0 HcmV?d00001 diff --git a/web/static/icons/apple-touch-icon.png b/web/static/icons/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b2abfa63d553dc474982d8b3d36dee71f9ceb0ce GIT binary patch literal 3278 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 N(3fm4)*(HT{tc`e{yYEx literal 0 HcmV?d00001 diff --git a/web/static/icons/generic.png b/web/static/icons/generic.png new file mode 100644 index 0000000000000000000000000000000000000000..d1777d489d3824d04f6d6db9f1d7e167b5f4dbc7 GIT binary patch literal 9818 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 literal 0 HcmV?d00001 diff --git a/web/static/icons/maskable/128.png b/web/static/icons/maskable/128.png new file mode 100644 index 0000000000000000000000000000000000000000..e8213cfe5828cc4435d15e4da25d5e57b3f2c472 GIT binary patch literal 815 zcmV+~1JL}5P)C0002YP)t-s00030 z|Ns5{{T3D$`T6gwv<-QBdbw3CyQgoK2BeSJ7MIN;#m$jHdIx3{aStB{b8 ziHV7HbaZ89Wll~`OG`^dMMVh-3GD3b=H}+)SUnwoKOaadSbR8&+y zKR-J=J2EmdBqSvB^YiWP?Y+IdsHmuwm6d^kfm&KxK|w*<+S%6WNt=~O%#0006W zNkl~PJx+&|Ey*O!vMtM z0l3frw1Tc_06Oak7&-Xg;QW2S#V`+SP;tw7(*UgV-4J)bEL6tXHm_6jcfe)WL#2`C z^pvCxYQZOPnYnmjEe_e1R;e}afJxF`qSEYw&U<>KR%V+}`GZQW7=tcuQS(b4F!4$* zDxC`GqGF9MM9MbdR7Pdl&bDKpT4M}c!j*R4%@WWZmegL32{75OQCUy3Z4yxH&w)uY z_33g45$FmNq*kl|mydf?-m|GNtW)~{E|o1R*Dc>xsS14TfCgL(FF%k2Y<5N8IAGFq zmQjR!I-$qjFb%Erf4HCZ}!tI^jGABIgZQgf~3>jWYa&{Am z)r<5N26}69JOE|`)Ren=`+P;>w>VzNx{WH5lAQyxuj}pI0}e=@2iX(aNa~vycsO{` ziUCXmI(Z;01Kd&!U>NZ7^Zo literal 0 HcmV?d00001 diff --git a/web/static/icons/maskable/192.png b/web/static/icons/maskable/192.png new file mode 100644 index 0000000000000000000000000000000000000000..8268d89a58c3c6334d887d403c4a9a615343c5f3 GIT binary patch literal 1014 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 nv_N+M?+@W;^HqDlV&cz;Xd literal 0 HcmV?d00001 diff --git a/web/static/icons/maskable/48.png b/web/static/icons/maskable/48.png new file mode 100644 index 0000000000000000000000000000000000000000..02a5bca0fb8b6cf17cd1327fab8f337e61c79489 GIT binary patch literal 390 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 literal 0 HcmV?d00001 diff --git a/web/static/icons/maskable/72.png b/web/static/icons/maskable/72.png new file mode 100644 index 0000000000000000000000000000000000000000..903f6bd500691990bc32f79d2192de30a594dbac GIT binary patch literal 569 zcmV-90>=G`P)U1D4i4kv<4{mg+}zyK($d1h!nwJ*b8~YFMdNuC9rRiG+lN zczAdage<5vZq|SJIvoDZf)%Lvw2I#ZK=M#Qy;1d0m_2sQ#amIqLvuF=xisi6$UIuz; zb6ur&hh5M0l9dq)!pXaUZ^FLHW>XW;P5BP`aN`?s&5l?Pn9ZZe+0xgV$Q#-C<2SNj z3;m;=H+pQcu@HK-A3tRDYEO~S*LK?Rog}FBlPt2w6wIbv9YG6rk|gmb8~ZEUS3jCQtRvM z=jZ3-z?PPllarH=kB?<#Wkp3rKtMne5)uy&58B$=&CSij!^6VD!n?b>y1Kff zqoag`giA|HIyyQyI5;36AhcV!LI3~(b4f%&RA}Dq)<>IyFc5&@45AbfM5WogYu#S| z{}0 Date: Sun, 16 Jun 2024 22:26:06 +0600 Subject: [PATCH 029/334] web/sidebar: optimize tab bar for mobile --- web/src/components/sidebar/Sidebar.svelte | 9 +++++++++ web/src/components/sidebar/SidebarTab.svelte | 4 ++++ web/src/routes/+layout.svelte | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index b73e392e..11691748 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -84,6 +84,7 @@ height: var(--sidebar-height-mobile); position: fixed; bottom: 0; + padding: 4px 0; } #sidebar::before { @@ -103,5 +104,13 @@ overflow-x: scroll; padding-bottom: 0; } + + #sidebar :global(.sidebar-inner-container:first-child) { + padding-left: var(--padding); + } + + #sidebar :global(.sidebar-inner-container:last-child) { + padding-right: var(--padding); + } } diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index e2f8c9b8..13593f60 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -28,6 +28,8 @@ color: var(--sidebar-highlight); font-size: var(--sidebar-font-size); opacity: 0.8; + height: fit-content; + -webkit-touch-callout: none; } .sidebar-tab.active { @@ -55,8 +57,10 @@ padding: 5px var(--padding); min-width: calc(var(--sidebar-width) / 2); } + .sidebar-tab.active { z-index: 2; + border-radius: var(--border-radius); } } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 25080a22..f3c34353 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -31,7 +31,7 @@ --border-radius: 11px; --sidebar-width: 80px; - --sidebar-height-mobile: 50px; + --sidebar-height-mobile: calc(52px + env(safe-area-inset-bottom)); --sidebar-font-size: 11px; --sidebar-mobile-gradient: linear-gradient( From 5ba3231a1e847ff999593d5fde2fd69ba4d5203b Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 22:59:16 +0600 Subject: [PATCH 030/334] web: consistent tab bar style with rounded corners --- web/src/components/sidebar/Sidebar.svelte | 7 ++++--- web/src/components/sidebar/SidebarTab.svelte | 2 +- web/src/routes/+layout.svelte | 14 +++++++++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index 11691748..c54c316d 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -63,6 +63,7 @@ height: 100vh; width: var(--sidebar-width); position: sticky; + padding: 0 var(--sidebar-inner-padding); } #sidebar-tabs { @@ -84,7 +85,7 @@ height: var(--sidebar-height-mobile); position: fixed; bottom: 0; - padding: 4px 0; + padding: var(--sidebar-inner-padding) 0; } #sidebar::before { @@ -106,11 +107,11 @@ } #sidebar :global(.sidebar-inner-container:first-child) { - padding-left: var(--padding); + padding-left: calc(var(--border-radius) * 2); } #sidebar :global(.sidebar-inner-container:last-child) { - padding-right: var(--padding); + padding-right: calc(var(--border-radius) * 2); } } diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 13593f60..d6a2f5fc 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -29,6 +29,7 @@ font-size: var(--sidebar-font-size); opacity: 0.8; height: fit-content; + border-radius: var(--border-radius); -webkit-touch-callout: none; } @@ -60,7 +61,6 @@ .sidebar-tab.active { z-index: 2; - border-radius: var(--border-radius); } } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index f3c34353..70f4b214 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -33,6 +33,7 @@ --sidebar-width: 80px; --sidebar-height-mobile: calc(52px + env(safe-area-inset-bottom)); --sidebar-font-size: 11px; + --sidebar-inner-padding: 4px; --sidebar-mobile-gradient: linear-gradient( 90deg, @@ -76,7 +77,7 @@ :global(html), :global(body) { margin: 0; - background-color: var(--primary); + background-color: var(--sidebar-bg); color: var(--secondary); } @@ -144,7 +145,7 @@ #cobalt { height: 100vh; display: grid; - grid-template-columns: var(--sidebar-width) 1fr; + grid-template-columns: calc(var(--sidebar-width) + 8px) 1fr; overflow: hidden; } @@ -153,16 +154,23 @@ overflow: scroll; padding: var(--padding); background-color: var(--primary); + + border-top-left-radius: var(--border-radius); + border-bottom-left-radius: var(--border-radius); } @media screen and (max-width: 535px) { #cobalt { display: grid; grid-template-columns: unset; - grid-template-rows: 1fr var(--sidebar-height-mobile); + grid-template-rows: 1fr calc(var(--sidebar-height-mobile) + 8px); } #content { + padding-top: env(safe-area-inset-top); order: -1; + border-top-left-radius: 0; + border-bottom-left-radius: calc(var(--border-radius) * 2); + border-bottom-right-radius: calc(var(--border-radius) * 2); } } From ea830974b6309c226cb5aad2fa1f34b63a16922e Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 23:06:30 +0600 Subject: [PATCH 031/334] web: fix DownloadButton tab focus glow --- web/src/components/save/buttons/DownloadButton.svelte | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index e4379c84..86b56b15 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -105,6 +105,10 @@ border-bottom-right-radius: var(--border-radius); } + #download-button:focus-visible { + box-shadow: 0 0 0 1.5px var(--secondary) inset; + } + #download-state { font-size: 24px; font-family: "Noto Sans Mono Variable", "Noto Sans Mono", "IBM Plex Mono", monospace; From 65c14d41fa2acbd64c7a42085cf445fd71e7a88a Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 16 Jun 2024 23:30:10 +0600 Subject: [PATCH 032/334] web: make tab focus blue for better visibility --- web/src/components/save/Omnibox.svelte | 1 + web/src/components/save/buttons/DownloadButton.svelte | 2 +- web/src/components/sidebar/SidebarTab.svelte | 5 +++-- web/src/routes/+layout.svelte | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index f969590b..e986100b 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -115,6 +115,7 @@ #input-container.focused :global(#input-link-icon) { stroke: var(--secondary); } + #input-container.downloadable :global(#input-link-icon) { stroke: var(--secondary); } diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 86b56b15..2e0838cb 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -106,7 +106,7 @@ } #download-button:focus-visible { - box-shadow: 0 0 0 1.5px var(--secondary) inset; + box-shadow: 0 0 0 2px var(--blue) inset; } #download-state { diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index d6a2f5fc..36b50f6c 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -44,13 +44,14 @@ } .sidebar-tab:focus-visible { - box-shadow: 0 0 0 1.5px var(--sidebar-highlight) inset; + box-shadow: 0 0 0 3px var(--blue) inset; outline: none; z-index: 1; } .sidebar-tab.active:focus-visible { - box-shadow: 0 0 0 1.5px var(--sidebar-bg) inset; + background: var(--blue); + color: var(--sidebar-highlight); } @media screen and (max-width: 535px) { diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 70f4b214..bfc6deff 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -16,6 +16,7 @@ --primary: #ffffff; --secondary: #000000; --gray: #8d8d95; + --blue: #2f8af9; --button: #eeeeee; --button-hover: #e8e8e8; @@ -120,7 +121,7 @@ } :global(button:focus-visible) { - box-shadow: 0 0 0 1.5px var(--secondary) inset; + box-shadow: 0 0 0 2px var(--blue) inset; outline: none; z-index: 1; } From 2ea3ca1a07cff46f00e662c236d54c7d1f4ec61b Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 00:31:07 +0600 Subject: [PATCH 033/334] web/sidebar: automatically scroll to active tab --- web/src/components/sidebar/SidebarTab.svelte | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 36b50f6c..87bf8cd0 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -4,7 +4,19 @@ export let tabName: string; export let tabLink: string; + let tab: HTMLElement; + $: isTabActive = $page.url.pathname === tabLink; + + const showTab = (e: HTMLElement | undefined) => { + if (e) { + e.scrollIntoView({}); + } + } + + $: if (isTabActive) { + showTab(tab) + } showTab(tab)} > {tabName} From 95aeec3380f17f3361a136cc55752a7c4b8f3740 Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 01:00:18 +0600 Subject: [PATCH 034/334] web: tab bar pagination effect & smooth scroll --- web/src/components/sidebar/SidebarTab.svelte | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 87bf8cd0..563564f0 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -4,13 +4,23 @@ export let tabName: string; export let tabLink: string; + const firstTabs = [ + "save", + "trim", + "crop", + "convert" + ]; + let tab: HTMLElement; $: isTabActive = $page.url.pathname === tabLink; const showTab = (e: HTMLElement | undefined) => { if (e) { - e.scrollIntoView({}); + e.scrollIntoView({ + inline: firstTabs.includes(tabName) ? 'end' : 'start', + behavior: 'smooth' + }); } } From 5390415aa7d55e3c402753fa57f06d395cfdbe2d Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 01:12:59 +0600 Subject: [PATCH 035/334] web: use hover effects only when supported --- .../save/buttons/DownloadButton.svelte | 17 +++++++++-------- web/src/components/sidebar/SidebarTab.svelte | 10 ++++++---- web/src/routes/+layout.svelte | 8 +++++--- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 2e0838cb..655ea4b1 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -121,19 +121,20 @@ margin-bottom: 0.1rem; } - #download-button:hover { - background: var(--button-hover-transparent); - } - #download-button:disabled { cursor: unset; } - #download-button:disabled:hover { - background: none; - } - :global(#input-container.focused) #download-button { border-left: 2px var(--secondary) solid; } + + @media (hover: hover) { + #download-button:hover { + background: var(--button-hover-transparent); + } + #download-button:disabled:hover { + background: none; + } + } diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 563564f0..36e8db53 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -63,10 +63,6 @@ opacity: 1; } - .sidebar-tab:hover { - opacity: 1; - } - .sidebar-tab:focus-visible { box-shadow: 0 0 0 3px var(--blue) inset; outline: none; @@ -78,6 +74,12 @@ color: var(--sidebar-highlight); } + @media (hover: hover) { + .sidebar-tab:hover { + opacity: 1; + } + } + @media screen and (max-width: 535px) { .sidebar-tab { padding: 5px var(--padding); diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index bfc6deff..fc5609ce 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -130,9 +130,11 @@ transform: scale(0.95); } - :global(button:hover) { - background-color: var(--button-hover); - z-index: 1; + @media (hover: hover) { + :global(button:hover) { + background-color: var(--button-hover); + z-index: 1; + } } :global(.center-column-container) { From f2bacc703a351c9df3190f00ac341d9772ccec8b Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 01:18:39 +0600 Subject: [PATCH 036/334] web/omnibox: import only one tabler icon --- web/src/components/save/Omnibox.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index e986100b..defeedd3 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -1,5 +1,5 @@ From 838cc508de52df4a45f0a8f30b6d6a99bc6dec6b Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 19:10:10 +0600 Subject: [PATCH 041/334] web/save: reduce meowbalt padding --- web/src/routes/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 63f3fbda..050bce55 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -21,7 +21,7 @@ justify-content: center; width: 100%; height: 100%; - gap: 24px; + gap: 15px; } #terms-note { From 8ec4a528ef74d419aee353d36758aae362e5a5fc Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 17 Jun 2024 19:41:45 +0600 Subject: [PATCH 042/334] web/save: fix terms note padding on mobile --- web/src/routes/+page.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 050bce55..15fa7416 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -35,6 +35,7 @@ @media screen and (max-width: 535px) { #terms-note { font-size: 11px; + padding-bottom: 0; } } From 068af6a965650006e269a3f7e3cc27438e4eb8dc Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 15:28:36 +0600 Subject: [PATCH 043/334] web/types/api: add trailing commas --- web/src/lib/types/api.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/web/src/lib/types/api.ts b/web/src/lib/types/api.ts index 2a739f60..f3b81851 100644 --- a/web/src/lib/types/api.ts +++ b/web/src/lib/types/api.ts @@ -3,19 +3,21 @@ enum CobaltResponseType { RateLimit = 'rate-limit', Picker = 'picker', Redirect = 'redirect', - Stream = 'stream' + Stream = 'stream', } type CobaltErrorResponse = { status: CobaltResponseType.Error | CobaltResponseType.RateLimit, - text: string + text: string, }; -type CobaltPartialURLResponse = { url: string } +type CobaltPartialURLResponse = { + url: string, +} type CobaltPartialImagesPickerResponse = { pickerType: 'images', - picker: CobaltPartialURLResponse[] + picker: CobaltPartialURLResponse[], } type CobaltPartialVariousPickerResponse = { @@ -23,7 +25,7 @@ type CobaltPartialVariousPickerResponse = { picker: { type: 'photo' | 'video', url: string, - thumb: string + thumb: string, }[]; } @@ -33,11 +35,11 @@ type CobaltPickerResponse = { } & (CobaltPartialImagesPickerResponse | CobaltPartialVariousPickerResponse); type CobaltRedirectResponse = { - status: CobaltResponseType.Redirect + status: CobaltResponseType.Redirect, } & CobaltPartialURLResponse; type CobaltStreamResponse = { - status: CobaltResponseType.Stream + status: CobaltResponseType.Stream, } & CobaltPartialURLResponse; export type CobaltAPIResponse = CobaltErrorResponse From 21e03a407c66f1dc13b50be3ee1e8be6743db011 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 17:55:06 +0600 Subject: [PATCH 044/334] web: add eslint --- web/eslint.config.js | 9 + web/package-lock.json | 1276 ++++++++++++++++++++++++++++++++++++++++- web/package.json | 6 +- 3 files changed, 1289 insertions(+), 2 deletions(-) create mode 100644 web/eslint.config.js diff --git a/web/eslint.config.js b/web/eslint.config.js new file mode 100644 index 00000000..7d683070 --- /dev/null +++ b/web/eslint.config.js @@ -0,0 +1,9 @@ +// @ts-check + +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + eslint.configs.recommended, + ...tseslint.configs.recommended, +); diff --git a/web/package-lock.json b/web/package-lock.json index e4509d63..6907bcb2 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -14,13 +14,17 @@ "@tabler/icons-svelte": "^3.6.0" }, "devDependencies": { + "@eslint/js": "^9.5.0", "@sveltejs/adapter-static": "^3.0.2", "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", + "@types/eslint__js": "^8.42.3", + "eslint": "^8.57.0", "svelte": "^4.2.7", "svelte-check": "^3.6.0", "tslib": "^2.4.1", - "typescript": "^5.0.0", + "typescript": "^5.4.5", + "typescript-eslint": "^7.13.1", "vite": "^5.0.3" } }, @@ -404,6 +408,66 @@ "node": ">=12" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", + "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.5.0.tgz", + "integrity": "sha512-A7+AOT2ICkodvtsWnxZP4Xxk3NbZ3VMHd8oihydLRGrJgqqdEz1qSeEgXYyT/Cu8h1TWWsQRejIx48mtjZ5y1w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@fontsource-variable/noto-sans-mono": { "version": "5.0.20", "resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-mono/-/noto-sans-mono-5.0.20.tgz", @@ -414,6 +478,44 @@ "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz", "integrity": "sha512-gtlMmvk//2AgDEZDFsoL5z9mgW3ZZg/9SC7pIfDwNKp5DtZpApgqd1Fua3HhPwYRIHrT76IQ1tMTzQKLEGtJGQ==" }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -817,17 +919,271 @@ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", "dev": true }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint__js": { + "version": "8.42.3", + "resolved": "https://registry.npmjs.org/@types/eslint__js/-/eslint__js-8.42.3.tgz", + "integrity": "sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/pug": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", "dev": true }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", + "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/type-utils": "7.13.1", + "@typescript-eslint/utils": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", + "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/typescript-estree": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", + "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", + "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "7.13.1", + "@typescript-eslint/utils": "7.13.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", + "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", + "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", + "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/typescript-estree": "7.13.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", + "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true, + "license": "ISC" + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -839,6 +1195,59 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -852,6 +1261,13 @@ "node": ">= 8" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/aria-query": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", @@ -860,6 +1276,16 @@ "dequal": "^2.0.3" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/axobject-query": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", @@ -926,6 +1352,23 @@ "node": ">=6" } }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -962,6 +1405,26 @@ "periscopic": "^3.1.0" } }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -977,6 +1440,21 @@ "node": ">= 0.6" } }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/css-tree": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", @@ -1006,6 +1484,13 @@ } } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -1038,6 +1523,32 @@ "integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==", "dev": true }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", @@ -1082,12 +1593,188 @@ "@esbuild/win32-x64": "0.20.2" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/esm-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", "dev": true }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", @@ -1096,6 +1783,23 @@ "@types/estree": "^1.0.0" } }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -1112,6 +1816,20 @@ "node": ">=8.6.0" } }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -1121,6 +1839,19 @@ "reusify": "^1.0.4" } }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -1133,6 +1864,62 @@ "node": ">=8" } }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true, + "license": "ISC" + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1186,12 +1973,49 @@ "node": ">= 6" } }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globalyzer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", "dev": true }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globrex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", @@ -1204,6 +2028,33 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -1230,6 +2081,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1289,6 +2150,16 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-reference": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", @@ -1297,6 +2168,57 @@ "@types/estree": "*" } }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kleur": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", @@ -1306,11 +2228,48 @@ "node": ">=6" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/magic-string": { "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", @@ -1430,6 +2389,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1448,6 +2414,56 @@ "wrappy": "1" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -1460,6 +2476,16 @@ "node": ">=6" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1469,6 +2495,26 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/periscopic": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", @@ -1525,6 +2571,26 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -1671,12 +2737,48 @@ "rimraf": "^2.5.2" } }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/set-cookie-parser": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", "dev": true }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/sirv": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", @@ -1691,6 +2793,16 @@ "node": ">= 10" } }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/sorcery": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.1.tgz", @@ -1714,6 +2826,19 @@ "node": ">=0.10.0" } }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -1726,6 +2851,32 @@ "node": ">=8" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/svelte": { "version": "4.2.18", "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", @@ -1846,6 +2997,13 @@ } } }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, "node_modules/tiny-glob": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", @@ -1877,17 +3035,57 @@ "node": ">=6" } }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1896,6 +3094,43 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.1.tgz", + "integrity": "sha512-pvLEuRs8iS9s3Cnp/Wt//hpK8nKc8hVa3cLljHqzaJJQYP8oys8GUyIFqtlev+2lT/fqMPcyQko+HJ6iYK3nFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "7.13.1", + "@typescript-eslint/parser": "7.13.1", + "@typescript-eslint/utils": "7.13.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/vite": { "version": "5.2.13", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz", @@ -1965,11 +3200,50 @@ } } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/web/package.json b/web/package.json index 32a8f969..af5ab742 100644 --- a/web/package.json +++ b/web/package.json @@ -20,13 +20,17 @@ }, "homepage": "https://cobalt.tools/", "devDependencies": { + "@eslint/js": "^9.5.0", "@sveltejs/adapter-static": "^3.0.2", "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", + "@types/eslint__js": "^8.42.3", + "eslint": "^8.57.0", "svelte": "^4.2.7", "svelte-check": "^3.6.0", "tslib": "^2.4.1", - "typescript": "^5.0.0", + "typescript": "^5.4.5", + "typescript-eslint": "^7.13.1", "vite": "^5.0.3" }, "dependencies": { From 009a2cc8633564cd540b006d8c78f039376b910f Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 21:12:51 +0600 Subject: [PATCH 045/334] web: implement settings core this was a torture --- web/package-lock.json | 12 ++++++++- web/package.json | 3 ++- web/src/lib/settings.ts | 42 ++++++++++++++++++++++++++++++++ web/src/lib/settings/defaults.ts | 35 ++++++++++++++++++++++++++ web/src/lib/types/generic.ts | 8 ++++++ web/src/lib/types/settings.ts | 41 +++++++++++++++++++++++++++++++ 6 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 web/src/lib/settings.ts create mode 100644 web/src/lib/settings/defaults.ts create mode 100644 web/src/lib/types/generic.ts create mode 100644 web/src/lib/types/settings.ts diff --git a/web/package-lock.json b/web/package-lock.json index 6907bcb2..23441713 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -11,7 +11,8 @@ "dependencies": { "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", - "@tabler/icons-svelte": "^3.6.0" + "@tabler/icons-svelte": "^3.6.0", + "ts-deepmerge": "^7.0.0" }, "devDependencies": { "@eslint/js": "^9.5.0", @@ -3048,6 +3049,15 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-deepmerge": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-7.0.0.tgz", + "integrity": "sha512-WZ/iAJrKDhdINv1WG6KZIGHrZDar6VfhftG1QJFpVbOYZMYJLJOvZOo1amictRXVdBXZIgBHKswMTXzElngprA==", + "license": "ISC", + "engines": { + "node": ">=14.13.1" + } + }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", diff --git a/web/package.json b/web/package.json index af5ab742..eda7e04a 100644 --- a/web/package.json +++ b/web/package.json @@ -36,6 +36,7 @@ "dependencies": { "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", - "@tabler/icons-svelte": "^3.6.0" + "@tabler/icons-svelte": "^3.6.0", + "ts-deepmerge": "^7.0.0" } } diff --git a/web/src/lib/settings.ts b/web/src/lib/settings.ts new file mode 100644 index 00000000..cdbf607b --- /dev/null +++ b/web/src/lib/settings.ts @@ -0,0 +1,42 @@ +import { readable, type Updater } from 'svelte/store'; +import { merge } from 'ts-deepmerge'; + +import type { RecursivePartial } from './types/generic'; +import type { CobaltSettings } from './types/settings'; + +import defaultSettings from "$lib/settings/defaults"; + +const writeToStorage = (settings: CobaltSettings) => { + localStorage.setItem( + "settings", + JSON.stringify(settings) + ); + + return settings; +} + +const loadFromStorage = () => { + const settings = localStorage.getItem('settings'); + if (!settings) { + return writeToStorage(defaultSettings); + } + + return JSON.parse(settings) as CobaltSettings; +} + +let update: (_: Updater) => void; + +export default readable( + loadFromStorage(), + (_, _update) => { update = _update } +); + +// update settings from outside +export function updateSetting(settings: RecursivePartial) { + update((current) => { + // deep merge partial type into full CobaltSettings type + current = merge(current, settings) as CobaltSettings; + + return writeToStorage(current); + }); +} diff --git a/web/src/lib/settings/defaults.ts b/web/src/lib/settings/defaults.ts new file mode 100644 index 00000000..ddaa83be --- /dev/null +++ b/web/src/lib/settings/defaults.ts @@ -0,0 +1,35 @@ +import type { CobaltSettings } from "$lib/types/settings"; + +const defaultSettings: CobaltSettings = { + schemaVersion: 1, + accessibility: { + reduceAnimations: false, + reduceTransparency: false + }, + appearance: { + theme: "auto" + }, + general: { + customProcessingEndpoint: "", + seenOnboarding: false, + seenSafetyWarning: false + }, + save: { + audioFormat: "mp3", + disableMetadata: false, + downloadMode: "auto", + downloadPopup: true, + filenameStyle: "classic", + tiktokH265: false, + tiktokFullAudio: false, + twitterGif: false, + videoQuality: "720", + youtubeVideoCodec: "h264", + youtubeDubBrowserLang: false + }, + privacy: { + trafficAnalytics: true + } +} + +export default defaultSettings; diff --git a/web/src/lib/types/generic.ts b/web/src/lib/types/generic.ts new file mode 100644 index 00000000..c2927964 --- /dev/null +++ b/web/src/lib/types/generic.ts @@ -0,0 +1,8 @@ +// more readable version of recursive partial taken from stackoverflow: +// https://stackoverflow.com/a/51365037 +export type RecursivePartial = { + [Key in keyof Type]?: + Type[Key] extends (infer ElementType)[] ? RecursivePartial[] : + Type[Key] extends object | undefined ? RecursivePartial : + Type[Key]; +}; diff --git a/web/src/lib/types/settings.ts b/web/src/lib/types/settings.ts new file mode 100644 index 00000000..a65e7843 --- /dev/null +++ b/web/src/lib/types/settings.ts @@ -0,0 +1,41 @@ +type CobaltSettingsAccessibility = { + reduceAnimations: boolean, + reduceTransparency: boolean, +}; + +type CobaltSettingsAppearance = { + theme: "auto" | "light" | "dark", +}; + +type CobaltSettingsGeneral = { + customProcessingEndpoint: string, + seenOnboarding: boolean, + seenSafetyWarning: boolean, +}; + +type CobaltSettingsSave = { + audioFormat: "best" | "mp3" | "ogg" | "wav" | "opus", + disableMetadata: boolean, + downloadMode: "auto" | "audio" | "mute", + downloadPopup: boolean, + filenameStyle: "classic" | "basic" | "pretty" | "nerdy", + tiktokH265: boolean, + tiktokFullAudio: boolean, + twitterGif: boolean, + videoQuality: "max" | "2160" | "1440" | "1080" | "720" | "360" | "240" | "144", + youtubeVideoCodec: "h264" | "av1" | "vp9", + youtubeDubBrowserLang: boolean, +}; + +type CobaltSettingsPrivacy = { + trafficAnalytics: boolean, +}; + +export type CobaltSettings = { + schemaVersion: number, + accessibility: CobaltSettingsAccessibility, + appearance: CobaltSettingsAppearance, + general: CobaltSettingsGeneral, + save: CobaltSettingsSave, + privacy: CobaltSettingsPrivacy, +}; From b15b108fa93ca1d0ae39a6be43c6c1eafaee2957 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 21:20:18 +0600 Subject: [PATCH 046/334] web/package: add min engine versions --- web/package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/package.json b/web/package.json index eda7e04a..aa2eeeee 100644 --- a/web/package.json +++ b/web/package.json @@ -11,6 +11,10 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, "license": "CC-BY-NC-SA-4.0", + "engines": { + "node": ">=20.10.0", + "npm": ">=10.0.0" + }, "repository": { "type": "git", "url": "git+https://github.com/imputnet/cobalt.git" From 1cac70f79545f1d6a8af7044024385f373a748c3 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 21:26:13 +0600 Subject: [PATCH 047/334] web/package: lowball engine requirements --- web/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/package.json b/web/package.json index aa2eeeee..51a4ff45 100644 --- a/web/package.json +++ b/web/package.json @@ -12,8 +12,8 @@ }, "license": "CC-BY-NC-SA-4.0", "engines": { - "node": ">=20.10.0", - "npm": ">=10.0.0" + "node": ">=20", + "npm": ">=9" }, "repository": { "type": "git", From 0ce73e03d3aed2c2b57efb41b2200bedde978a28 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 21:30:56 +0600 Subject: [PATCH 048/334] web/package: update required node version to 20.9 --- web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/package.json b/web/package.json index 51a4ff45..6d2d17e2 100644 --- a/web/package.json +++ b/web/package.json @@ -12,7 +12,7 @@ }, "license": "CC-BY-NC-SA-4.0", "engines": { - "node": ">=20", + "node": ">=20.9", "npm": ">=9" }, "repository": { From 00cdb2121d7e7f06dc9b9808e867b69b6a36188c Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 23:04:09 +0600 Subject: [PATCH 049/334] web: data-driven switcher & save mode switcher also: - disabled ssr to enable localstorage - removed the workaround for hover, as it looks bad --- .../components/buttons/ActionButton.svelte | 9 +----- .../buttons/SettingsContextButton.svelte | 32 +++++++++++++++++++ web/src/components/buttons/Switcher.svelte | 9 ++---- web/src/components/save/Omnibox.svelte | 17 +++++----- web/src/lib/settings.ts | 2 +- web/src/routes/+layout.svelte | 6 +++- web/src/routes/+layout.ts | 1 + 7 files changed, 52 insertions(+), 24 deletions(-) create mode 100644 web/src/components/buttons/SettingsContextButton.svelte diff --git a/web/src/components/buttons/ActionButton.svelte b/web/src/components/buttons/ActionButton.svelte index 022e6784..3c2a4433 100644 --- a/web/src/components/buttons/ActionButton.svelte +++ b/web/src/components/buttons/ActionButton.svelte @@ -3,13 +3,6 @@ export let click = () => { alert('no function assigned') }; - - - diff --git a/web/src/components/buttons/SettingsContextButton.svelte b/web/src/components/buttons/SettingsContextButton.svelte new file mode 100644 index 00000000..a0a29e12 --- /dev/null +++ b/web/src/components/buttons/SettingsContextButton.svelte @@ -0,0 +1,32 @@ + + + diff --git a/web/src/components/buttons/Switcher.svelte b/web/src/components/buttons/Switcher.svelte index 06e794a5..afcfeba3 100644 --- a/web/src/components/buttons/Switcher.svelte +++ b/web/src/components/buttons/Switcher.svelte @@ -1,8 +1,4 @@ - - -
+
@@ -31,7 +27,8 @@ border-radius: 0; } + /* clumsy hack to get rid of double border in a list of switches */ .switcher > :global(:not(.button:first-child)) { - margin-left: -1.5px; /* hack to get rid of double border in a list of switches */ + margin-left: -1.5px; } diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 8cebdcad..5686764d 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -12,6 +12,7 @@ import IconMute from "$lib/icons/Mute.svelte"; import IconClipboard from "$lib/icons/Clipboard.svelte"; + import SettingsContextButton from "../buttons/SettingsContextButton.svelte"; let link: string = ""; let isFocused = false; @@ -66,18 +67,18 @@
- - + + auto - - + + audio - - + + mute - + - + paste paste and download diff --git a/web/src/lib/settings.ts b/web/src/lib/settings.ts index cdbf607b..f005ced4 100644 --- a/web/src/lib/settings.ts +++ b/web/src/lib/settings.ts @@ -18,7 +18,7 @@ const writeToStorage = (settings: CobaltSettings) => { const loadFromStorage = () => { const settings = localStorage.getItem('settings'); if (!settings) { - return writeToStorage(defaultSettings); + return defaultSettings; } return JSON.parse(settings) as CobaltSettings; diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 7d6ca8a0..34f362b1 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -133,10 +133,14 @@ transform: scale(0.95); } + :global(.button.selected) { + background: var(--secondary); + color: var(--primary); + } + @media (hover: hover) { :global(button:hover) { background-color: var(--button-hover); - z-index: 1; } } diff --git a/web/src/routes/+layout.ts b/web/src/routes/+layout.ts index 189f71e2..ceccaaf6 100644 --- a/web/src/routes/+layout.ts +++ b/web/src/routes/+layout.ts @@ -1 +1,2 @@ export const prerender = true; +export const ssr = false; From 3b2178fd1aaab77a7c4e2c7b16738537b132559b Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 23:29:26 +0600 Subject: [PATCH 050/334] web/api: full api request with user preferences --- web/src/lib/api.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/web/src/lib/api.ts b/web/src/lib/api.ts index 3719080c..7892dc8e 100644 --- a/web/src/lib/api.ts +++ b/web/src/lib/api.ts @@ -1,10 +1,29 @@ +import { get } from 'svelte/store'; +import settings from "$lib/settings"; import type { CobaltAPIResponse } from "$lib/types/api"; const apiURL = "https://api.cobalt.tools"; const request = async (url: string) => { + const saveSettings = get(settings).save; + const request = { - url + url, + + isAudioOnly: saveSettings.downloadMode === "audio", + isAudioMuted: saveSettings.downloadMode === "mute", + aFormat: saveSettings.audioFormat, + isTTFullAudio: saveSettings.tiktokFullAudio, + dubLang: saveSettings.youtubeDubBrowserLang, + + vCodec: saveSettings.youtubeVideoCodec, + vQuality: saveSettings.videoQuality, + + filenamePattern: saveSettings.filenameStyle, + disableMetadata: saveSettings.disableMetadata, + + twitterGif: saveSettings.twitterGif, + tiktokH265: saveSettings.tiktokH265, } const response: CobaltAPIResponse | undefined = await fetch(`${apiURL}/api/json`, { From 4564f409aa61c82faf314a31a2dd07db908057fa Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 19 Jun 2024 23:42:52 +0600 Subject: [PATCH 051/334] web/types/settings: add missing 480p video quality --- web/src/lib/types/settings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/lib/types/settings.ts b/web/src/lib/types/settings.ts index a65e7843..c17e65a1 100644 --- a/web/src/lib/types/settings.ts +++ b/web/src/lib/types/settings.ts @@ -22,7 +22,7 @@ type CobaltSettingsSave = { tiktokH265: boolean, tiktokFullAudio: boolean, twitterGif: boolean, - videoQuality: "max" | "2160" | "1440" | "1080" | "720" | "360" | "240" | "144", + videoQuality: "max" | "2160" | "1440" | "1080" | "720" | "480" | "360" | "240" | "144", youtubeVideoCodec: "h264" | "av1" | "vp9", youtubeDubBrowserLang: boolean, }; From f2e74b681b7d02742d07888b7524e019289fa797 Mon Sep 17 00:00:00 2001 From: wukko Date: Thu, 20 Jun 2024 13:46:01 +0600 Subject: [PATCH 052/334] web/sidebar: align tabbar to center on mobile --- web/src/components/sidebar/Sidebar.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index c54c316d..5888a32d 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -86,6 +86,7 @@ position: fixed; bottom: 0; padding: var(--sidebar-inner-padding) 0; + justify-content: center; } #sidebar::before { From b9e7661b6d0a5a8861c6a46bffd66f57766955f2 Mon Sep 17 00:00:00 2001 From: wukko Date: Thu, 20 Jun 2024 18:05:17 +0600 Subject: [PATCH 053/334] web: basic settings page needed for testing typescript cries about types but i don't care at this point --- ...extButton.svelte => SettingsButton.svelte} | 0 .../buttons/SettingsCheckbox.svelte | 31 ++++++++++++++ web/src/components/save/Omnibox.svelte | 14 +++---- web/src/lib/settings/defaults.ts | 13 +++++- web/src/routes/settings/+page.svelte | 42 +++++++++++++++++-- 5 files changed, 89 insertions(+), 11 deletions(-) rename web/src/components/buttons/{SettingsContextButton.svelte => SettingsButton.svelte} (100%) create mode 100644 web/src/components/buttons/SettingsCheckbox.svelte diff --git a/web/src/components/buttons/SettingsContextButton.svelte b/web/src/components/buttons/SettingsButton.svelte similarity index 100% rename from web/src/components/buttons/SettingsContextButton.svelte rename to web/src/components/buttons/SettingsButton.svelte diff --git a/web/src/components/buttons/SettingsCheckbox.svelte b/web/src/components/buttons/SettingsCheckbox.svelte new file mode 100644 index 00000000..81c8c00a --- /dev/null +++ b/web/src/components/buttons/SettingsCheckbox.svelte @@ -0,0 +1,31 @@ + + +
+ + updateSetting({ + [settingContext]: { + [settingId]: isChecked, + }, + })} + /> + +
diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 5686764d..3a4e6d58 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -12,7 +12,7 @@ import IconMute from "$lib/icons/Mute.svelte"; import IconClipboard from "$lib/icons/Clipboard.svelte"; - import SettingsContextButton from "../buttons/SettingsContextButton.svelte"; + import SettingsButton from "../buttons/SettingsButton.svelte"; let link: string = ""; let isFocused = false; @@ -68,15 +68,15 @@
- + auto - - + + audio - - + + mute - + diff --git a/web/src/lib/settings/defaults.ts b/web/src/lib/settings/defaults.ts index ddaa83be..124e8751 100644 --- a/web/src/lib/settings/defaults.ts +++ b/web/src/lib/settings/defaults.ts @@ -31,5 +31,16 @@ const defaultSettings: CobaltSettings = { trafficAnalytics: true } } - export default defaultSettings; + +export const settingArrays = { + appearance: { + theme: ["auto", "light", "dark"] + }, + save: { + audioFormat: ["best", "mp3", "ogg", "wav", "opus"], + filenameStyle: ["classic", "basic", "pretty", "nerdy"], + videoQuality: ["max", "2160", "1440", "1080", "720", "480", "360", "240", "144"], + youtubeVideoCodec: ["h264", "av1", "vp9"], + }, +} diff --git a/web/src/routes/settings/+page.svelte b/web/src/routes/settings/+page.svelte index d6a792fb..5f94bc32 100644 --- a/web/src/routes/settings/+page.svelte +++ b/web/src/routes/settings/+page.svelte @@ -1,5 +1,41 @@ - - +
+
settings (placeholder)
+
+ {#each Object.entries(switchers) as [context, settingIdParent]} +
+
{context} context:
+
+
+ {#each Object.entries(settingIdParent) as [settingId, settingValue]} + {#if settingValue instanceof Array} +
{settingId}
+ + {#each settingValue as value} + + {value} + + {/each} + +
+ {/if} + + {#if typeof settingValue === "boolean"} + + {settingId} + +
+ {/if} + {/each} + {/each} +
From 7e39bd78d7ef5e5abb993170f4b4e02334e05e48 Mon Sep 17 00:00:00 2001 From: wukko Date: Thu, 20 Jun 2024 19:19:57 +0600 Subject: [PATCH 054/334] web/settings: fix setting value name --- web/src/components/buttons/SettingsButton.svelte | 10 +++++----- web/src/components/save/Omnibox.svelte | 6 +++--- web/src/routes/settings/+page.svelte | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/web/src/components/buttons/SettingsButton.svelte b/web/src/components/buttons/SettingsButton.svelte index a0a29e12..bb2a6f13 100644 --- a/web/src/components/buttons/SettingsButton.svelte +++ b/web/src/components/buttons/SettingsButton.svelte @@ -3,7 +3,7 @@ generics=" Context extends Exclude, Id extends keyof CobaltSettings[Context], - Key extends CobaltSettings[Context][Id] + Value extends CobaltSettings[Context][Id] " > import settings, { updateSetting } from "$lib/settings"; @@ -11,20 +11,20 @@ export let settingContext: Context; export let settingId: Id; - export let settingKey: Key; + export let settingValue: Value; $: setting = $settings[settingContext][settingId]; - $: isSelected = setting === settingKey; + $: isSelected = setting === settingValue;
+ \ No newline at end of file + From 49e2df425dd275119bb94de955d4b521615d3829 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 25 Jun 2024 19:41:38 +0600 Subject: [PATCH 078/334] web: remove future feature placeholders --- web/src/components/sidebar/Sidebar.svelte | 12 ------------ web/src/components/sidebar/SidebarTab.svelte | 9 ++++----- web/src/routes/convert/+page.svelte | 5 ----- web/src/routes/crop/+page.svelte | 5 ----- web/src/routes/trim/+page.svelte | 5 ----- 5 files changed, 4 insertions(+), 32 deletions(-) delete mode 100644 web/src/routes/convert/+page.svelte delete mode 100644 web/src/routes/crop/+page.svelte delete mode 100644 web/src/routes/trim/+page.svelte diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index e6c7824d..e075da07 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -3,9 +3,6 @@ import SidebarTab from "$components/sidebar/SidebarTab.svelte"; import IconDownload from "@tabler/icons-svelte/IconDownload.svelte"; - import IconCut from "@tabler/icons-svelte/IconCut.svelte"; - import IconCrop from "@tabler/icons-svelte/IconCrop.svelte"; - import IconTransform from "@tabler/icons-svelte/IconTransform.svelte"; import IconSettings from "@tabler/icons-svelte/IconSettings.svelte"; import IconComet from "@tabler/icons-svelte/IconComet.svelte"; @@ -33,15 +30,6 @@ - - - - - - - - - diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index 67275a6b..c9657288 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -4,11 +4,10 @@ export let tabName: string; export let tabLink: string; - const firstTabs = [ + const firstTabPage = [ "save", - "trim", - "crop", - "convert" + "settings", + "updates" ]; let tab: HTMLElement; @@ -21,7 +20,7 @@ const showTab = (e: HTMLElement | undefined) => { if (e) { e.scrollIntoView({ - inline: firstTabs.includes(tabName) ? 'end' : 'start', + inline: firstTabPage.includes(tabName) ? 'end' : 'start', behavior: 'smooth' }); } diff --git a/web/src/routes/convert/+page.svelte b/web/src/routes/convert/+page.svelte deleted file mode 100644 index a26a5d64..00000000 --- a/web/src/routes/convert/+page.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/web/src/routes/crop/+page.svelte b/web/src/routes/crop/+page.svelte deleted file mode 100644 index 1e39a5b6..00000000 --- a/web/src/routes/crop/+page.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/web/src/routes/trim/+page.svelte b/web/src/routes/trim/+page.svelte deleted file mode 100644 index fbee1685..00000000 --- a/web/src/routes/trim/+page.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - From 7b289bfb1611ddc42000aa7fabcd00ccd24b1268 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 25 Jun 2024 20:59:25 +0600 Subject: [PATCH 079/334] web: mobile improvements - all buttons now reflect that they're pressed or hovered - settings feel way better on mobile - settings header has been completely remade --- .../buttons/SettingsCheckbox.svelte | 2 +- .../settings/SettingsSection.svelte | 12 ++++++ .../components/settings/SettingsTab.svelte | 1 + web/src/components/sidebar/SidebarTab.svelte | 8 +++- web/src/routes/+layout.svelte | 6 ++- web/src/routes/settings/+layout.svelte | 43 +++++++++++++------ 6 files changed, 54 insertions(+), 18 deletions(-) diff --git a/web/src/components/buttons/SettingsCheckbox.svelte b/web/src/components/buttons/SettingsCheckbox.svelte index b8f98afd..9cea6fa0 100644 --- a/web/src/components/buttons/SettingsCheckbox.svelte +++ b/web/src/components/buttons/SettingsCheckbox.svelte @@ -52,10 +52,10 @@ flex-direction: row; align-items: center; gap: 12px; - justify-content: start; text-align: left; transform: none; + padding: 6px 12px; } .checkbox-text { diff --git a/web/src/components/settings/SettingsSection.svelte b/web/src/components/settings/SettingsSection.svelte index ad5674fb..2c0abf0b 100644 --- a/web/src/components/settings/SettingsSection.svelte +++ b/web/src/components/settings/SettingsSection.svelte @@ -30,6 +30,18 @@ #settings-section-categories { background: var(--button); border-radius: var(--border-radius); + box-shadow: var(--button-box-shadow); + } + + #settings-section-categories > :global(:not(.settings-tab:last-child)) { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + box-shadow: 0 3px 0px -1.2px var(--button-stroke); + } + + #settings-section-categories > :global(:not(.settings-tab:first-child)) { + border-top-left-radius: 0; + border-top-right-radius: 0; } } diff --git a/web/src/components/settings/SettingsTab.svelte b/web/src/components/settings/SettingsTab.svelte index 28fc621c..607977b2 100644 --- a/web/src/components/settings/SettingsTab.svelte +++ b/web/src/components/settings/SettingsTab.svelte @@ -95,6 +95,7 @@ @media screen and (max-width: 750px) { .settings-tab { background: none; + padding: 9px; --small-padding: 5px; } diff --git a/web/src/components/sidebar/SidebarTab.svelte b/web/src/components/sidebar/SidebarTab.svelte index c9657288..9fd76c07 100644 --- a/web/src/components/sidebar/SidebarTab.svelte +++ b/web/src/components/sidebar/SidebarTab.svelte @@ -70,9 +70,15 @@ opacity: 1; } + .sidebar-tab:active:not(.active) { + opacity: 1; + background-color: var(--sidebar-hover); + } + @media (hover: hover) { - .sidebar-tab:hover { + .sidebar-tab:hover:not(.active) { opacity: 1; + background-color: var(--sidebar-hover); } } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 6a54a4f4..e66775a3 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -26,9 +26,11 @@ --button-hover-transparent: rgba(0, 0, 0, 0.06); --button-stroke: rgba(0, 0, 0, 0.05); --button-text: #282828; + --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; --sidebar-bg: #000000; --sidebar-highlight: #ffffff; + --sidebar-hover: rgba(255, 255, 255, 0.1); --input-border: #8d8d95; @@ -129,7 +131,7 @@ cursor: pointer; background-color: var(--button); color: var(--button-text); - box-shadow: 0 0 0 1.5px var(--button-stroke) inset; + box-shadow: var(--button-box-shadow); } :global(:focus-visible) { @@ -139,7 +141,7 @@ } :global(button:active) { - transform: scale(0.95); + background-color: var(--button-hover); } :global(.button.active) { diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index d58cb825..dfa96938 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -14,6 +14,8 @@ let screenWidth: number; + $: currentPageTitle = $page.url.pathname.split("/").at(-1); + $: isMobile = screenWidth <= 750; $: isHome = $page.url.pathname === `/settings`; @@ -23,11 +25,19 @@
- {#if !isHome && isMobile} - - -

settings

-
+ {#if isMobile} + {#if !isHome} + + + + {/if} +

+ settings + {#if !isHome} + / + {currentPageTitle} + {/if} +

{:else}

settings

{/if} @@ -77,7 +87,9 @@ #settings-page { --settings-nav-width: 250px; --settings-padding: 30px; - --settings-padding-small: calc(var(--settings-padding) - var(--padding)); + --settings-padding-small: calc( + var(--settings-padding) - var(--padding) + ); display: grid; width: 100%; grid-template-columns: var(--settings-nav-width) 1fr; @@ -110,11 +122,11 @@ } #settings-navigation { - gap: 12px; + gap: var(--padding); } #settings-header { - --back-padding: 6px; + --back-padding: calc(var(--padding) / 2); } .back-button { @@ -123,7 +135,9 @@ color: var(--secondary); gap: var(--back-padding); padding: var(--back-padding); - padding-right: calc(var(--back-padding) * 2); + + position: absolute; + left: var(--back-padding); } .back-button:active { @@ -166,10 +180,7 @@ position: sticky; padding: var(--padding); gap: 4px; - } - - #settings-header.back-visible { - padding: calc(var(--padding) - var(--back-padding)); + justify-content: center; } #settings-sidebar { @@ -178,7 +189,11 @@ #settings-page-title { text-align: center; - font-size: 16px; + letter-spacing: -0.3px; + } + + .title-slash { + color: var(--gray); } #settings-navigation { From 635561394cb3cd2e72cc41ec78da3a723a407064 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 25 Jun 2024 21:01:08 +0600 Subject: [PATCH 080/334] web: add dynamic page titles --- web/src/routes/+page.svelte | 4 ++++ web/src/routes/about/+page.svelte | 6 ++++++ web/src/routes/donate/+page.svelte | 6 ++++++ web/src/routes/settings/+layout.svelte | 8 ++++++++ web/src/routes/updates/+page.svelte | 6 ++++++ 5 files changed, 30 insertions(+) diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index a91c5c69..5d076ad2 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -3,6 +3,10 @@ import MeowbaltLoaf from "$components/meowbalt/MeowbaltLoaf.svelte"; + + cobalt + +
diff --git a/web/src/routes/about/+page.svelte b/web/src/routes/about/+page.svelte index 89a7710a..5d70e6dd 100644 --- a/web/src/routes/about/+page.svelte +++ b/web/src/routes/about/+page.svelte @@ -2,4 +2,10 @@ import Placeholder from "$components/misc/Placeholder.svelte"; + + + cobalt: about + + + diff --git a/web/src/routes/donate/+page.svelte b/web/src/routes/donate/+page.svelte index 1ce2815e..9959ebe0 100644 --- a/web/src/routes/donate/+page.svelte +++ b/web/src/routes/donate/+page.svelte @@ -2,4 +2,10 @@ import Placeholder from "$components/misc/Placeholder.svelte"; + + + cobalt: donate + + + diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index dfa96938..6ac82241 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -15,11 +15,19 @@ let screenWidth: number; $: currentPageTitle = $page.url.pathname.split("/").at(-1); + $: stringPageTitle = + currentPageTitle !== "settings" ? `/ ${currentPageTitle}` : ""; $: isMobile = screenWidth <= 750; $: isHome = $page.url.pathname === `/settings`; + + + cobalt: settings {stringPageTitle} + + +
diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 8140bcd2..e3cf1e20 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -2,4 +2,10 @@ import Placeholder from "$components/misc/Placeholder.svelte"; + + + cobalt: updates + + + From 98b0a2f10a95731d165a4c2236f2ba5a4452ab03 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 25 Jun 2024 21:06:07 +0600 Subject: [PATCH 081/334] web/SettingsCheckbox: remove yassing --- web/src/components/buttons/SettingsCheckbox.svelte | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/web/src/components/buttons/SettingsCheckbox.svelte b/web/src/components/buttons/SettingsCheckbox.svelte index 9cea6fa0..568bc41b 100644 --- a/web/src/components/buttons/SettingsCheckbox.svelte +++ b/web/src/components/buttons/SettingsCheckbox.svelte @@ -23,14 +23,13 @@ - - diff --git a/web/src/components/buttons/SettingsToggle.svelte b/web/src/components/buttons/SettingsToggle.svelte new file mode 100644 index 00000000..ef253ac2 --- /dev/null +++ b/web/src/components/buttons/SettingsToggle.svelte @@ -0,0 +1,72 @@ + + +
+ + + {#if description} +
{description}
+ {/if} +
+ + diff --git a/web/src/components/buttons/Switcher.svelte b/web/src/components/buttons/Switcher.svelte index b836105e..4b0cb333 100644 --- a/web/src/components/buttons/Switcher.svelte +++ b/web/src/components/buttons/Switcher.svelte @@ -28,16 +28,15 @@ } .switcher.big { - --switcher-inner-padding: 4px; - border-radius: calc(var(--border-radius) + var(--switcher-inner-padding)); background: var(--button); box-shadow: var(--button-box-shadow); - padding: var(--switcher-inner-padding); + padding: var(--sidebar-inner-padding); } .switcher.big :global(.button) { width: 100%; - height: calc(40px - var(--switcher-inner-padding)); + height: calc(40px - var(--sidebar-inner-padding)); + border-radius: calc(var(--border-radius) - var(--sidebar-inner-padding));; } .switcher.big :global(.button:not(:focus-visible)) { diff --git a/web/src/components/misc/Toggle.svelte b/web/src/components/misc/Toggle.svelte new file mode 100644 index 00000000..ed0dbb31 --- /dev/null +++ b/web/src/components/misc/Toggle.svelte @@ -0,0 +1,42 @@ + + +
+
+
+ + diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 719fb173..163600ec 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -2,11 +2,10 @@ import "@fontsource/ibm-plex-mono/400.css"; import "@fontsource/ibm-plex-mono/500.css"; + import device from "$lib/device"; import currentTheme, { statusBarColors } from "$lib/state/theme"; import Sidebar from "$components/sidebar/Sidebar.svelte"; - - import device from "$lib/device"; @@ -45,7 +44,10 @@ --sidebar-highlight: #ffffff; --sidebar-hover: rgba(255, 255, 255, 0.1); - --input-border: #8d8d95; + --input-border: var(--gray); + + --toggle-bg: var(--input-border); + --toggle-bg-enabled: var(--secondary); --padding: 12px; --border-radius: 11px; @@ -85,6 +87,9 @@ --input-border: #383838; + --toggle-bg: var(--input-border); + --toggle-bg-enabled: #777777; + --sidebar-mobile-gradient: linear-gradient( 90deg, rgba(16, 16, 16, 0.9) 0%, @@ -217,9 +222,10 @@ } :global(.subtext) { - font-size: 13px; + font-size: 12px; color: var(--gray); line-height: 1.4; + padding: 0 var(--padding); } #cobalt { diff --git a/web/src/routes/settings/general/appearance/+page.svelte b/web/src/routes/settings/general/appearance/+page.svelte index 68022510..dd4b679b 100644 --- a/web/src/routes/settings/general/appearance/+page.svelte +++ b/web/src/routes/settings/general/appearance/+page.svelte @@ -2,7 +2,7 @@ import SettingsCategory from "$components/settings/SettingsCategory.svelte"; import Switcher from "$components/buttons/Switcher.svelte"; import SettingsButton from "$components/buttons/SettingsButton.svelte"; - import SettingsCheckbox from "$components/buttons/SettingsCheckbox.svelte"; + import SettingsToggle from "$components/buttons/SettingsToggle.svelte"; import { themeOptions } from "$lib/types/settings"; @@ -18,13 +18,13 @@ - - - - @@ -22,7 +22,7 @@ - - - - Date: Sat, 29 Jun 2024 22:53:09 +0600 Subject: [PATCH 090/334] web/SettingsToggle: clean up --- web/src/components/buttons/SettingsToggle.svelte | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/web/src/components/buttons/SettingsToggle.svelte b/web/src/components/buttons/SettingsToggle.svelte index ef253ac2..ccbc1b2c 100644 --- a/web/src/components/buttons/SettingsToggle.svelte +++ b/web/src/components/buttons/SettingsToggle.svelte @@ -31,9 +31,7 @@ }) } > -
-

{title}

-
+

{title}

+

{$page.status}: {$page.error?.message}

\ No newline at end of file From 157b687ab5fbd7f9213d47fb33afa3a9ee6284ec Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Thu, 4 Jul 2024 22:25:22 +0000 Subject: [PATCH 112/334] web/settings: redirect to full page if base page is opened on desktop --- web/src/routes/settings/+layout.svelte | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index 819938a6..65c1fb4e 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -13,6 +13,8 @@ import IconFileSettings from "@tabler/icons-svelte/IconFileSettings.svelte"; import IconChevronLeft from "@tabler/icons-svelte/IconChevronLeft.svelte"; + import { goto } from "$app/navigation"; + import { defaultSettingsPage } from "$lib/settings/defaults"; let screenWidth: number; @@ -21,7 +23,13 @@ currentPageTitle !== "settings" ? ` / ${$t(`settings.page.${currentPageTitle}`)}` : ""; $: isMobile = screenWidth <= 750; - $: isHome = $page.url.pathname === `/settings`; + $: isHome = $page.url.pathname === '/settings'; + $: { + if (!isMobile && isHome) { + goto(defaultSettingsPage(), { replaceState: true }); + } + } + From 9ae0473f80732df4499cfd6bf6ebd02340c0e4f0 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Thu, 4 Jul 2024 22:25:47 +0000 Subject: [PATCH 113/334] web/sidebar: simplify settings link logic --- web/src/components/sidebar/Sidebar.svelte | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/web/src/components/sidebar/Sidebar.svelte b/web/src/components/sidebar/Sidebar.svelte index 9eef6cc8..e76be484 100644 --- a/web/src/components/sidebar/Sidebar.svelte +++ b/web/src/components/sidebar/Sidebar.svelte @@ -12,17 +12,12 @@ import IconComet from "@tabler/icons-svelte/IconComet.svelte"; import IconHeart from "@tabler/icons-svelte/IconHeart.svelte"; import IconInfoCircle from "@tabler/icons-svelte/IconInfoCircle.svelte"; + import { defaultSettingsPage } from "$lib/settings/defaults"; - let screenWidth: number, - settingsLink: string; + let screenWidth: number; + let settingsLink = defaultSettingsPage(); - $: isMobile = screenWidth <= 750; - - $: if (isMobile) { - settingsLink = "/settings"; - } else { - settingsLink = "/settings/general/appearance"; - } + $: screenWidth, settingsLink = defaultSettingsPage(); From a6a51b850a7ebb4b16f1aece2d7dbce4c08a61e0 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Thu, 4 Jul 2024 22:27:38 +0000 Subject: [PATCH 114/334] web/chore: tabs to spaces idk how this happened :-3 --- web/src/routes/+error.svelte | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/web/src/routes/+error.svelte b/web/src/routes/+error.svelte index ba0b6166..abcd6efe 100644 --- a/web/src/routes/+error.svelte +++ b/web/src/routes/+error.svelte @@ -1,16 +1,16 @@ From 9b3f289b0e3665c349790dc2562b3df5d1f99bbc Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 7 Jul 2024 18:52:06 +0600 Subject: [PATCH 115/334] web/lib/api: don't follow redirects away from api --- web/src/lib/api.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/lib/api.ts b/web/src/lib/api.ts index 7892dc8e..d1008377 100644 --- a/web/src/lib/api.ts +++ b/web/src/lib/api.ts @@ -28,6 +28,7 @@ const request = async (url: string) => { const response: CobaltAPIResponse | undefined = await fetch(`${apiURL}/api/json`, { method: "POST", + redirect: "manual", body: JSON.stringify(request), headers: { 'Accept': 'application/json', From 430bfaca43fafa9b9da05f80033a4eb22be3510a Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 7 Jul 2024 19:14:49 +0600 Subject: [PATCH 116/334] web/settings: add section ids --- .../components/settings/SettingsCategory.svelte | 5 +++-- .../components/settings/SettingsSection.svelte | 4 ++-- .../settings/general/appearance/+page.svelte | 8 ++++++-- web/src/routes/settings/save/audio/+page.svelte | 15 +++++++++++---- .../routes/settings/save/metadata/+page.svelte | 15 +++++++++++---- web/src/routes/settings/save/video/+page.svelte | 10 ++++++++-- 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/web/src/components/settings/SettingsCategory.svelte b/web/src/components/settings/SettingsCategory.svelte index 8ccd1cf5..3ec3c895 100644 --- a/web/src/components/settings/SettingsCategory.svelte +++ b/web/src/components/settings/SettingsCategory.svelte @@ -1,16 +1,17 @@ -
+

{title}

{#if description.length > 0}
{description}
{/if} -
+ diff --git a/web/src/components/settings/SettingsSection.svelte b/web/src/components/settings/SettingsNavSection.svelte similarity index 100% rename from web/src/components/settings/SettingsSection.svelte rename to web/src/components/settings/SettingsNavSection.svelte diff --git a/web/src/components/settings/SettingsTab.svelte b/web/src/components/settings/SettingsNavTab.svelte similarity index 100% rename from web/src/components/settings/SettingsTab.svelte rename to web/src/components/settings/SettingsNavTab.svelte diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index 65c1fb4e..5ad31ef9 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -3,8 +3,8 @@ import { t } from "$lib/i18n/translations"; - import SettingsTab from "$components/settings/SettingsTab.svelte"; - import SettingsSection from "$components/settings/SettingsSection.svelte"; + import SettingsNavTab from "$components/settings/SettingsNavTab.svelte"; + import SettingsNavSection from "$components/settings/SettingsNavSection.svelte"; import IconSunHigh from "@tabler/icons-svelte/IconSunHigh.svelte"; @@ -68,38 +68,38 @@ {/if}
@@ -120,15 +120,13 @@ grid-template-columns: var(--settings-nav-width) 1fr; overflow: hidden; padding-left: var(--settings-padding); - padding-top: var(--settings-padding); } #settings-page-content { display: flex; flex-direction: column; - gap: var(--settings-padding); max-width: 600px; - padding: 0 var(--settings-padding); + padding: calc(var(--settings-padding) / 2); overflow-y: scroll; } @@ -140,6 +138,7 @@ #settings-sidebar { width: var(--settings-nav-width); + padding-top: var(--settings-padding); } #settings-sidebar { @@ -189,14 +188,18 @@ padding: 0; } - #settings-page-content, #settings-navigation { padding: var(--padding); + padding-bottom: calc(var(--padding) * 2); + } + + #settings-page-content { + padding: var(--padding) 0; + padding-top: 0; } #settings-page-content { max-width: unset; - gap: calc(var(--padding) * 2); } #settings-header { @@ -210,6 +213,7 @@ #settings-sidebar { gap: 0px; + padding: 0; } #settings-page-title { From da1a11b5ce5822c68cec876030c5888765c32a54 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 7 Jul 2024 16:10:12 +0000 Subject: [PATCH 118/334] svelte: don't use relative paths for bundle links in html this prevents a blank page from showing up when a user visits a non-existing page on a static build --- web/svelte.config.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/svelte.config.js b/web/svelte.config.js index aac39830..b4751daa 100644 --- a/web/svelte.config.js +++ b/web/svelte.config.js @@ -17,6 +17,9 @@ const config = { precompress: false, strict: true }), + paths: { + relative: false + }, alias: { $components: 'src/components', $i18n: 'i18n', From 35a8628cc177dde458047f3ffe39093dc2f0c4b1 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 7 Jul 2024 22:45:35 +0600 Subject: [PATCH 119/334] web/SettingsToggle: change aria role to switch --- web/src/components/buttons/SettingsToggle.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/src/components/buttons/SettingsToggle.svelte b/web/src/components/buttons/SettingsToggle.svelte index 1bbb59fb..d310ca39 100644 --- a/web/src/components/buttons/SettingsToggle.svelte +++ b/web/src/components/buttons/SettingsToggle.svelte @@ -23,7 +23,8 @@
+ {/each} +
+ + + diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 96510462..718a9041 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -3,14 +3,30 @@ import API from "$lib/api"; import { device } from "$lib/device"; + import { t } from "$lib/i18n/translations"; + import { createDialog } from "$lib/dialogs"; + import type { DialogInfo } from "$lib/types/dialog"; + export let url: string; $: buttonText = ">>"; $: buttonAltText = $t('a11y.save.download'); $: isDisabled = false; + let defaultErrorPopup = { + id: "save-error", + type: "small", + title: "", + bodySubText: "", + buttons: [{ + text: $t("general.gotit"), + color: "gray", + action: () => {}, + }] + } + const changeDownloadButton = (state: string) => { isDisabled = true; switch (state) { @@ -59,14 +75,20 @@ changeDownloadButton("error"); restoreDownloadButton(); - return alert("couldn't access the api"); + return createDialog({ + ...defaultErrorPopup as DialogInfo, + bodyText: "couldn't access the api" + }) } if (response.status === "error" || response.status === "rate-limit") { changeDownloadButton("error"); restoreDownloadButton(); - return alert(`error from api: ${response.text}`); + return createDialog({ + ...defaultErrorPopup as DialogInfo, + bodyText: response.text + }) } if (response.status === "redirect") { @@ -90,7 +112,10 @@ changeDownloadButton("error"); restoreDownloadButton(); - return alert("couldn't probe the stream"); + return createDialog({ + ...defaultErrorPopup as DialogInfo, + bodyText: "couldn't probe the stream" + }) } } }; diff --git a/web/src/lib/dialogs.ts b/web/src/lib/dialogs.ts new file mode 100644 index 00000000..a186be04 --- /dev/null +++ b/web/src/lib/dialogs.ts @@ -0,0 +1,23 @@ +import { readable, type Updater } from "svelte/store"; +import type { DialogInfo } from "$lib/types/dialog"; + +let update: (_: Updater) => void; + +export default readable( + [], + (_, _update) => { update = _update } +); + +export function createDialog(newData: DialogInfo) { + update((popups) => { + popups.push(newData); + return popups; + }); +} + +export function killDialog() { + update((popups) => { + popups.pop() + return popups; + }); +} diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts new file mode 100644 index 00000000..b473acd1 --- /dev/null +++ b/web/src/lib/types/dialog.ts @@ -0,0 +1,14 @@ +export type DialogButton = { + text: string, + color: string, + action: () => unknown | Promise +} + +export type DialogInfo = { + id: string, + type: "small", + title: string, + bodyText: string, + bodySubText: string, + buttons: DialogButton[] +} diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 2ba680c5..35306b81 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -8,6 +8,7 @@ import Sidebar from "$components/sidebar/Sidebar.svelte"; import NotchSticker from "$components/misc/NotchSticker.svelte"; + import DialogHolder from "$components/dialog/DialogHolder.svelte"; $: reduceMotion = $settings.appearance.reduceMotion @@ -33,6 +34,7 @@ {#if device.is.iPhone && app.is.installed} {/if} +
@@ -302,6 +304,15 @@ font-size: 11px; } + :global(dialog) { + max-height: 100%; + max-width: 100%; + padding: var(--padding); + border-radius: var(--border-radius); + border: none; + pointer-events: all; + } + :global(.subtext) { font-size: 12.5px; font-weight: 500; From 1f0958a0d1922f10d55deb6bb033b618a46ca12b Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 13 Jul 2024 13:17:03 +0000 Subject: [PATCH 170/334] web/settings: move to state folder --- web/src/components/buttons/SettingsButton.svelte | 2 +- web/src/components/buttons/SettingsToggle.svelte | 2 +- web/src/components/save/Omnibox.svelte | 2 +- web/src/components/settings/LanguageAutoToggle.svelte | 4 ++-- web/src/components/settings/LanguageDropdown.svelte | 2 +- web/src/lib/api.ts | 2 +- web/src/lib/{ => state}/settings.ts | 6 +++--- web/src/lib/state/theme.ts | 2 +- web/src/routes/+layout.svelte | 2 +- web/src/routes/+layout.ts | 2 +- web/src/routes/settings/+layout.svelte | 2 +- web/src/routes/settings/advanced/debug/+page.svelte | 2 +- 12 files changed, 15 insertions(+), 15 deletions(-) rename web/src/lib/{ => state}/settings.ts (92%) diff --git a/web/src/components/buttons/SettingsButton.svelte b/web/src/components/buttons/SettingsButton.svelte index ca3be280..871c2fa0 100644 --- a/web/src/components/buttons/SettingsButton.svelte +++ b/web/src/components/buttons/SettingsButton.svelte @@ -6,7 +6,7 @@ Value extends CobaltSettings[Context][Id] " > - import settings, { updateSetting } from "$lib/settings"; + import settings, { updateSetting } from "$lib/state/settings"; import type { CobaltSettings } from "$lib/types/settings"; export let settingContext: Context; diff --git a/web/src/components/buttons/SettingsToggle.svelte b/web/src/components/buttons/SettingsToggle.svelte index 8995da90..1e37aa3e 100644 --- a/web/src/components/buttons/SettingsToggle.svelte +++ b/web/src/components/buttons/SettingsToggle.svelte @@ -5,7 +5,7 @@ Id extends keyof CobaltSettings[Context] " > - import settings, { updateSetting } from "$lib/settings"; + import settings, { updateSetting } from "$lib/state/settings"; import type { CobaltSettings } from "$lib/types/settings"; import Toggle from "$components/misc/Toggle.svelte"; diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index bbe98070..b8ba01b1 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -12,7 +12,7 @@ import ActionButton from "$components/buttons/ActionButton.svelte"; import SettingsButton from "$components/buttons/SettingsButton.svelte"; - import { updateSetting } from "$lib/settings"; + import { updateSetting } from "$lib/state/settings"; import type { DownloadModeOption } from "$lib/types/settings"; import IconSparkles from "$lib/icons/Sparkles.svelte"; diff --git a/web/src/components/settings/LanguageAutoToggle.svelte b/web/src/components/settings/LanguageAutoToggle.svelte index 0de00d62..aa896c9f 100644 --- a/web/src/components/settings/LanguageAutoToggle.svelte +++ b/web/src/components/settings/LanguageAutoToggle.svelte @@ -1,7 +1,7 @@ + + + + \ No newline at end of file From f582be5d440a0e345607a18bcdf6c10b4a8bd0f9 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 14 Jul 2024 21:27:34 +0600 Subject: [PATCH 177/334] web/i18n/save: remove "the" from terms note --- web/i18n/en/save.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/i18n/en/save.json b/web/i18n/en/save.json index ef676658..83d260d2 100644 --- a/web/i18n/en/save.json +++ b/web/i18n/en/save.json @@ -6,5 +6,5 @@ "mute": "mute", "input.placeholder": "paste the link here", "terms.note.agreement": "by continuing, you agree to", - "terms.note.link": "the terms and ethics of use" + "terms.note.link": "terms and ethics of use" } From 9f649ff1db62395588fa9fdc4aa9cd746a984526 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 14 Jul 2024 21:51:56 +0600 Subject: [PATCH 178/334] web/settings: update analytics text & add a link to more info --- web/i18n/en/settings.json | 7 ++++--- web/src/components/misc/OuterLink.svelte | 7 +++++++ .../settings/general/privacy/+page.svelte | 20 +++++++++++++++---- 3 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 web/src/components/misc/OuterLink.svelte diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 3b0195e5..6a299974 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -85,9 +85,10 @@ "language.preferred.title": "preferred language", "language.preferred.description": "language used for interface and content. if any text isn’t translated to this language, it will be displayed in english.", - "privacy": "anonymous traffic analytics", - "privacy.disableAnalytics.title": "opt out of private analytics", - "privacy.disableAnalytics.description": "enable if you don't want to be included in anonymous traffic stats. read more about this in about > privacy policy (tl;dr: nothing about you is ever stored or tracked, no cookies are used).", + "privacy.analytics": "anonymous traffic analytics", + "privacy.analytics.title": "don't contribute to analytics", + "privacy.analytics.description": "we use a self-hosted plausible instance for getting an approximate number of active cobalt users. no identifiable informaton about you is ever stored. all processed data is anonymized and aggregated.\n\nplausible does not use any cookies and is fully compliant with GDPR, CCPA, and PECR.", + "privacy.analytics.learnmore": "learn more about plausible's dedication to privacy.", "advanced.debug": "debug", "advanced.debug.title": "enable debug features", diff --git a/web/src/components/misc/OuterLink.svelte b/web/src/components/misc/OuterLink.svelte new file mode 100644 index 00000000..b8f97dc1 --- /dev/null +++ b/web/src/components/misc/OuterLink.svelte @@ -0,0 +1,7 @@ + + + + + diff --git a/web/src/routes/settings/general/privacy/+page.svelte b/web/src/routes/settings/general/privacy/+page.svelte index 1512ee04..c6f65a7f 100644 --- a/web/src/routes/settings/general/privacy/+page.svelte +++ b/web/src/routes/settings/general/privacy/+page.svelte @@ -3,13 +3,25 @@ import SettingsCategory from "$components/settings/SettingsCategory.svelte"; import SettingsToggle from "$components/buttons/SettingsToggle.svelte"; + import OuterLink from "$components/misc/OuterLink.svelte"; - + - \ No newline at end of file +
+ + {$t("settings.privacy.analytics.learnmore")} + +
+
+ + From 5a630c2320b8d146efed3e88b38aec6dd858fb21 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 13 Jul 2024 20:37:38 +0000 Subject: [PATCH 179/334] web/migrate: set up migration from old settings format --- web/src/lib/settings/migrate.ts | 115 ++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 web/src/lib/settings/migrate.ts diff --git a/web/src/lib/settings/migrate.ts b/web/src/lib/settings/migrate.ts new file mode 100644 index 00000000..64c9ae53 --- /dev/null +++ b/web/src/lib/settings/migrate.ts @@ -0,0 +1,115 @@ +import type { RecursivePartial } from "$lib/types/generic"; +import type { CobaltSettings } from "$lib/types/settings"; +import defaultSettings from "./defaults"; + +const oldSwitcherValues = { + theme: ['auto', 'light', 'dark'], + vCodec: ['h264', 'av1', 'vp9'], + vQuality: ['720', 'max', '2160', '1440', '1080', '480', '360', '240', '144'], + aFormat: ['mp3', 'best', 'ogg', 'wav', 'opus'], + filenamePattern: ['classic', 'pretty', 'basic', 'nerdy'] +} as const; + +const oldCheckboxes = [ + 'audioMode', + 'downloadPopup', + 'fullTikTokAudio', + 'muteAudio', + 'reduceTransparency', + 'disableAnimations', + 'disableMetadata', + 'twitterGif', + 'plausible_ignore', + 'ytDub', + 'tiktokH265' +] as const; + +type LegacySwitchers = keyof typeof oldSwitcherValues; +type LegacyCheckboxes = typeof oldCheckboxes[number]; + +const _get = (name: LegacyCheckboxes | LegacySwitchers) => { + const value = localStorage.getItem(name); + if (value !== null) { + return value; + } +} + +const getBool = (name: LegacyCheckboxes) => { + const value = _get(name); + + if (value !== undefined) { + return value === 'true'; + } +} + +const getLiteral = (name: T) => { + const value = _get(name); + if (value === undefined) { + return; + } + + const values = oldSwitcherValues[name] as readonly string[]; + if (values.includes(value)) { + type SwitcherOptions = typeof oldSwitcherValues[T][number]; + return value as SwitcherOptions; + } +} + +const getDownloadMode = () => { + if (getBool('muteAudio')) { + return 'mute'; + } + + if (getBool('audioMode')) { + return 'audio'; + } + + return 'auto'; +} + +const cleanup = () => { + for (const key of Object.keys(localStorage)) { + // plausible script needs this value, so we keep it if migrating + if (key !== 'plausible_ignore') { + localStorage.removeItem(key); + } + } +} + +export const migrateOldSettings = () => { + if (getLiteral('vCodec') === undefined) { + /* on the old frontend, preferences such as "vCodec" are set right + * when you open it. so, if this preference does not exist, we can + * assume that the user never used the old frontend, and abort the + * migration early. */ + return; + } + + const migrated: RecursivePartial = { + schemaVersion: defaultSettings.schemaVersion, + appearance: { + theme: getLiteral('theme'), + reduceTransparency: getBool('reduceTransparency'), + reduceMotion: getBool('disableAnimations'), + }, + privacy: { + disableAnalytics: getBool('plausible_ignore') + }, + save: { + youtubeVideoCodec: getLiteral('vCodec'), + videoQuality: getLiteral('vQuality'), + audioFormat: getLiteral('aFormat'), + downloadMode: getDownloadMode(), + filenameStyle: getLiteral('filenamePattern'), + tiktokFullAudio: getBool('fullTikTokAudio'), + tiktokH265: getBool('tiktokH265'), + downloadPopup: getBool('downloadPopup'), + disableMetadata: getBool('disableMetadata'), + twitterGif: getBool('twitterGif'), + youtubeDubBrowserLang: getBool('ytDub'), + } + }; + + cleanup(); + return migrated; +} From 436b735d2ab879257c779027a9acde5c97ed1724 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 13 Jul 2024 20:39:40 +0000 Subject: [PATCH 180/334] web/settings: try to migrate settings if new format is not used yet --- web/src/lib/state/settings.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web/src/lib/state/settings.ts b/web/src/lib/state/settings.ts index 1b62b750..555c45a9 100644 --- a/web/src/lib/state/settings.ts +++ b/web/src/lib/state/settings.ts @@ -4,6 +4,7 @@ import { merge } from 'ts-deepmerge'; import type { RecursivePartial } from '../types/generic'; import type { CobaltSettings } from '../types/settings'; +import { migrateOldSettings } from '../settings/migrate'; import defaultSettings from '../settings/defaults'; type PartialSettings = RecursivePartial; @@ -43,6 +44,11 @@ const migrate = (settings: PartialSettingsWithSchema) => { const loadFromStorage = () => { const settings = localStorage.getItem('settings'); if (!settings) { + const migrated = migrateOldSettings(); + if (migrated) { + return writeToStorage(migrated); + } + return {}; } From 128ab388f3128f2b94fcaccf3f5c489188df66b5 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 14 Jul 2024 22:50:18 +0600 Subject: [PATCH 181/334] web: add env variable & plausible functionality --- web/src/lib/env.ts | 9 ++++++ web/src/routes/+layout.svelte | 10 +++++++ .../settings/general/privacy/+page.svelte | 29 ++++++++++--------- 3 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 web/src/lib/env.ts diff --git a/web/src/lib/env.ts b/web/src/lib/env.ts new file mode 100644 index 00000000..a5f08382 --- /dev/null +++ b/web/src/lib/env.ts @@ -0,0 +1,9 @@ +import { env } from "$env/dynamic/public"; + +const variables = { + HOST: env.PUBLIC_HOST, + PLAUSIBLE_HOST: env.PUBLIC_PLAUSIBLE_HOST, + PLAUSIBLE_ENABLED: env.PUBLIC_HOST && env.PUBLIC_PLAUSIBLE_HOST, +} + +export default variables; diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index e203f1de..20eeabbc 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -2,6 +2,7 @@ import "@fontsource/ibm-plex-mono/400.css"; import "@fontsource/ibm-plex-mono/500.css"; + import env from "$lib/env"; import settings from "$lib/state/settings"; import { device, app } from "$lib/device"; import { locale } from "$lib/i18n/translations"; @@ -23,6 +24,15 @@ {#if device.is.mobile} {/if} + + {#if env.PLAUSIBLE_ENABLED} + + {/if}
diff --git a/web/src/routes/settings/general/privacy/+page.svelte b/web/src/routes/settings/general/privacy/+page.svelte index c6f65a7f..00eacbca 100644 --- a/web/src/routes/settings/general/privacy/+page.svelte +++ b/web/src/routes/settings/general/privacy/+page.svelte @@ -1,4 +1,5 @@ - - -
- - {$t("settings.privacy.analytics.learnmore")} - -
-
+{#if env.PLAUSIBLE_ENABLED} + + +
+ + {$t("settings.privacy.analytics.learnmore")} + +
+
+{/if} diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 8ee30862..3ca087a1 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -2,7 +2,10 @@ import { killDialog } from "$lib/dialogs"; import type { DialogButton } from "$lib/types/dialog"; + import MeowbaltError from "$components/meowbalt/MeowbaltError.svelte"; + export let id: string; + export let meowbalt: string = ""; export let title: string = ""; export let bodyText: string = ""; export let bodySubText: string = ""; @@ -10,46 +13,227 @@ let dialogParent: HTMLDialogElement; + let closing = false; + const close = () => { if (dialogParent) { - dialogParent.close(); - killDialog(); + closing = true; + setTimeout(() => { + dialogParent.close(); + killDialog(); + }, 150) } - } + }; $: if (dialogParent) { dialogParent.showModal(); } - - - + + diff --git a/web/src/components/meowbalt/MeowbaltError.svelte b/web/src/components/meowbalt/MeowbaltError.svelte new file mode 100644 index 00000000..34ec570e --- /dev/null +++ b/web/src/components/meowbalt/MeowbaltError.svelte @@ -0,0 +1,19 @@ + + +{$t("a11y.meowbalt.error")} + + diff --git a/web/src/components/meowbalt/MeowbaltLoaf.svelte b/web/src/components/meowbalt/MeowbaltLoaf.svelte index 908b1ec8..3e8533e3 100644 --- a/web/src/components/meowbalt/MeowbaltLoaf.svelte +++ b/web/src/components/meowbalt/MeowbaltLoaf.svelte @@ -6,7 +6,6 @@ id="meowbalt-loaf" src="/meowbalt/smile.png" height="152" - width="141" alt={$t("a11y.meowbalt.smile")} /> diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 718a9041..5201b3bc 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -18,11 +18,13 @@ let defaultErrorPopup = { id: "save-error", type: "small", + meowbalt: "error", title: "", bodySubText: "", buttons: [{ text: $t("general.gotit"), color: "gray", + main: true, action: () => {}, }] } diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index b473acd1..20bea678 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -1,14 +1,16 @@ export type DialogButton = { text: string, color: string, + main: boolean, action: () => unknown | Promise } export type DialogInfo = { id: string, type: "small", + meowbalt: "error", title: string, bodyText: string, bodySubText: string, - buttons: DialogButton[] + buttons: DialogButton[], } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 01f025fe..4af2d963 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -66,10 +66,14 @@ --button: #f4f4f4; --button-hover: #e8e8e8; --button-hover-transparent: rgba(0, 0, 0, 0.06); - --button-stroke: rgba(0, 0, 0, 0.05); + --button-stroke: rgba(0, 0, 0, 0.06); --button-text: #282828; --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; + --popup-bg: #f1f1f1; + --popup-backdrop: var(--primary); + --popup-stroke: rgba(0, 0, 0, 0.08); + --sidebar-bg: #000000; --sidebar-highlight: #ffffff; --sidebar-hover: rgba(255, 255, 255, 0.1); @@ -120,6 +124,10 @@ --button-text: #e1e1e1; --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; + --popup-bg: #191919; + --popup-backdrop: var(--primary); + --popup-stroke: rgba(255, 255, 255, 0.08); + --sidebar-bg: #101010; --sidebar-highlight: #f2f2f2; @@ -319,15 +327,6 @@ font-size: 11px; } - :global(dialog) { - max-height: 100%; - max-width: 100%; - padding: var(--padding); - border-radius: var(--border-radius); - border: none; - pointer-events: all; - } - :global(.subtext) { font-size: 12.5px; font-weight: 500; diff --git a/web/static/meowbalt/checking.png b/web/static/meowbalt/checking.png new file mode 100644 index 0000000000000000000000000000000000000000..0d6a51c2bb32c9a246b79ebc13bb2753129af4dd GIT binary patch literal 15440 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 iF6)rv@;dDQSdJey#*KvQyPM$v0000 Date: Tue, 16 Jul 2024 22:03:16 +0600 Subject: [PATCH 187/334] web/Omnibox: ignore keyboard shortcuts when dialog is visible --- web/src/components/save/Omnibox.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 63f6c1df..63d68fa9 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -5,6 +5,8 @@ import { t } from "$lib/i18n/translations"; + import dialogs from "$lib/dialogs"; + import { updateSetting } from "$lib/state/settings"; import type { DownloadModeOption } from "$lib/types/settings"; @@ -65,7 +67,7 @@ }; const handleKeydown = (e: KeyboardEvent) => { - if (!linkInput) { + if (!linkInput || $dialogs.length > 0) { return; } From 504dfdb995094478ab83f29915e1d24861caafaa Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 16 Jul 2024 22:11:57 +0600 Subject: [PATCH 188/334] web/Omnibox: ignore keyboard shortcuts when processing --- web/src/components/save/Omnibox.svelte | 6 ++++-- web/src/components/save/buttons/DownloadButton.svelte | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 63d68fa9..3cd09beb 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -28,6 +28,8 @@ let linkInput: HTMLInputElement | undefined; let isFocused = false; + let isDisabled: boolean = false; + let downloadButton: SvelteComponent; const validLink = (link: string) => { @@ -67,7 +69,7 @@ }; const handleKeydown = (e: KeyboardEvent) => { - if (!linkInput || $dialogs.length > 0) { + if (!linkInput || $dialogs.length > 0 || isDisabled) { return; } @@ -136,7 +138,7 @@ (link = "")} /> {/if} {#if validLink(link)} - + {/if}
diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 5201b3bc..c6a37969 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -10,6 +10,7 @@ import type { DialogInfo } from "$lib/types/dialog"; export let url: string; + export let isDisabled = false; $: buttonText = ">>"; $: buttonAltText = $t('a11y.save.download'); From 8ebde3919704c3e1a9793b82f6ed22f486d966cb Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 16 Jul 2024 22:17:51 +0600 Subject: [PATCH 189/334] web/Omnibox: prevent paste button spamming --- web/src/components/save/Omnibox.svelte | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 3cd09beb..327aeea3 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -53,6 +53,10 @@ } const pasteClipboard = () => { + if (isDisabled || $dialogs.length > 0) { + return; + } + navigator.clipboard.readText().then(async (text) => { let matchLink = text.match(/https:\/\/[^\s]+/g); if (matchLink) { From e1a898bd5877bed283f0682600824a36d3a32950 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Thu, 27 Jun 2024 23:18:52 +0000 Subject: [PATCH 190/334] frontend: move update banners to new frontend --- .../static/update-banners}/bettertogether.webp | Bin .../static/update-banners}/catmakeup.webp | Bin .../static/update-banners}/catphonestand.webp | Bin .../static/update-banners}/catroomba.webp | Bin .../static/update-banners}/catsleep.webp | Bin .../static/update-banners}/catspeed.webp | Bin .../static/update-banners}/catswitchboxes.webp | Bin .../static/update-banners}/cattired.webp | Bin .../static/update-banners}/developers.webp | Bin .../static/update-banners}/happymeowth.webp | Bin .../static/update-banners}/meowth7eleven.webp | Bin .../static/update-banners}/meowthball.webp | Bin .../static/update-banners}/meowthbusinessman.webp | Bin .../static/update-banners}/meowthcenter.webp | Bin .../static/update-banners}/meowthcooking.webp | Bin .../static/update-banners}/meowthhammer.webp | Bin .../static/update-banners}/meowthpolishegg.webp | Bin .../static/update-banners}/meowthproductions.webp | Bin .../static/update-banners}/meowthsnap.webp | Bin .../static/update-banners}/meowthstrong.webp | Bin .../static/update-banners}/millionusers.webp | Bin .../static/update-banners}/newdomain.webp | Bin .../static/update-banners}/onemillionr.webp | Bin .../static/update-banners}/shutup.webp | Bin .../static/update-banners}/twitchupdate.webp | Bin .../static/update-banners}/valentines.webp | Bin 26 files changed, 0 insertions(+), 0 deletions(-) rename {src/front/updateBanners => web/static/update-banners}/bettertogether.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catmakeup.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catphonestand.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catroomba.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catsleep.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catspeed.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/catswitchboxes.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/cattired.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/developers.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/happymeowth.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowth7eleven.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthball.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthbusinessman.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthcenter.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthcooking.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthhammer.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthpolishegg.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthproductions.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthsnap.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/meowthstrong.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/millionusers.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/newdomain.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/onemillionr.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/shutup.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/twitchupdate.webp (100%) rename {src/front/updateBanners => web/static/update-banners}/valentines.webp (100%) diff --git a/src/front/updateBanners/bettertogether.webp b/web/static/update-banners/bettertogether.webp similarity index 100% rename from src/front/updateBanners/bettertogether.webp rename to web/static/update-banners/bettertogether.webp diff --git a/src/front/updateBanners/catmakeup.webp b/web/static/update-banners/catmakeup.webp similarity index 100% rename from src/front/updateBanners/catmakeup.webp rename to web/static/update-banners/catmakeup.webp diff --git a/src/front/updateBanners/catphonestand.webp b/web/static/update-banners/catphonestand.webp similarity index 100% rename from src/front/updateBanners/catphonestand.webp rename to web/static/update-banners/catphonestand.webp diff --git a/src/front/updateBanners/catroomba.webp b/web/static/update-banners/catroomba.webp similarity index 100% rename from src/front/updateBanners/catroomba.webp rename to web/static/update-banners/catroomba.webp diff --git a/src/front/updateBanners/catsleep.webp b/web/static/update-banners/catsleep.webp similarity index 100% rename from src/front/updateBanners/catsleep.webp rename to web/static/update-banners/catsleep.webp diff --git a/src/front/updateBanners/catspeed.webp b/web/static/update-banners/catspeed.webp similarity index 100% rename from src/front/updateBanners/catspeed.webp rename to web/static/update-banners/catspeed.webp diff --git a/src/front/updateBanners/catswitchboxes.webp b/web/static/update-banners/catswitchboxes.webp similarity index 100% rename from src/front/updateBanners/catswitchboxes.webp rename to web/static/update-banners/catswitchboxes.webp diff --git a/src/front/updateBanners/cattired.webp b/web/static/update-banners/cattired.webp similarity index 100% rename from src/front/updateBanners/cattired.webp rename to web/static/update-banners/cattired.webp diff --git a/src/front/updateBanners/developers.webp b/web/static/update-banners/developers.webp similarity index 100% rename from src/front/updateBanners/developers.webp rename to web/static/update-banners/developers.webp diff --git a/src/front/updateBanners/happymeowth.webp b/web/static/update-banners/happymeowth.webp similarity index 100% rename from src/front/updateBanners/happymeowth.webp rename to web/static/update-banners/happymeowth.webp diff --git a/src/front/updateBanners/meowth7eleven.webp b/web/static/update-banners/meowth7eleven.webp similarity index 100% rename from src/front/updateBanners/meowth7eleven.webp rename to web/static/update-banners/meowth7eleven.webp diff --git a/src/front/updateBanners/meowthball.webp b/web/static/update-banners/meowthball.webp similarity index 100% rename from src/front/updateBanners/meowthball.webp rename to web/static/update-banners/meowthball.webp diff --git a/src/front/updateBanners/meowthbusinessman.webp b/web/static/update-banners/meowthbusinessman.webp similarity index 100% rename from src/front/updateBanners/meowthbusinessman.webp rename to web/static/update-banners/meowthbusinessman.webp diff --git a/src/front/updateBanners/meowthcenter.webp b/web/static/update-banners/meowthcenter.webp similarity index 100% rename from src/front/updateBanners/meowthcenter.webp rename to web/static/update-banners/meowthcenter.webp diff --git a/src/front/updateBanners/meowthcooking.webp b/web/static/update-banners/meowthcooking.webp similarity index 100% rename from src/front/updateBanners/meowthcooking.webp rename to web/static/update-banners/meowthcooking.webp diff --git a/src/front/updateBanners/meowthhammer.webp b/web/static/update-banners/meowthhammer.webp similarity index 100% rename from src/front/updateBanners/meowthhammer.webp rename to web/static/update-banners/meowthhammer.webp diff --git a/src/front/updateBanners/meowthpolishegg.webp b/web/static/update-banners/meowthpolishegg.webp similarity index 100% rename from src/front/updateBanners/meowthpolishegg.webp rename to web/static/update-banners/meowthpolishegg.webp diff --git a/src/front/updateBanners/meowthproductions.webp b/web/static/update-banners/meowthproductions.webp similarity index 100% rename from src/front/updateBanners/meowthproductions.webp rename to web/static/update-banners/meowthproductions.webp diff --git a/src/front/updateBanners/meowthsnap.webp b/web/static/update-banners/meowthsnap.webp similarity index 100% rename from src/front/updateBanners/meowthsnap.webp rename to web/static/update-banners/meowthsnap.webp diff --git a/src/front/updateBanners/meowthstrong.webp b/web/static/update-banners/meowthstrong.webp similarity index 100% rename from src/front/updateBanners/meowthstrong.webp rename to web/static/update-banners/meowthstrong.webp diff --git a/src/front/updateBanners/millionusers.webp b/web/static/update-banners/millionusers.webp similarity index 100% rename from src/front/updateBanners/millionusers.webp rename to web/static/update-banners/millionusers.webp diff --git a/src/front/updateBanners/newdomain.webp b/web/static/update-banners/newdomain.webp similarity index 100% rename from src/front/updateBanners/newdomain.webp rename to web/static/update-banners/newdomain.webp diff --git a/src/front/updateBanners/onemillionr.webp b/web/static/update-banners/onemillionr.webp similarity index 100% rename from src/front/updateBanners/onemillionr.webp rename to web/static/update-banners/onemillionr.webp diff --git a/src/front/updateBanners/shutup.webp b/web/static/update-banners/shutup.webp similarity index 100% rename from src/front/updateBanners/shutup.webp rename to web/static/update-banners/shutup.webp diff --git a/src/front/updateBanners/twitchupdate.webp b/web/static/update-banners/twitchupdate.webp similarity index 100% rename from src/front/updateBanners/twitchupdate.webp rename to web/static/update-banners/twitchupdate.webp diff --git a/src/front/updateBanners/valentines.webp b/web/static/update-banners/valentines.webp similarity index 100% rename from src/front/updateBanners/valentines.webp rename to web/static/update-banners/valentines.webp From a8569838100f3d7b1b47f1ad94074c418556e475 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 29 Jun 2024 17:36:26 +0000 Subject: [PATCH 191/334] web: convert changelogs from old format https://gist.github.com/dumbmoron/3fc6c0c747d791928aba939976fd9304 --- src/modules/changelog/changelog.json | 308 --------------------------- web/changelogs/3.5.2.md | 16 ++ web/changelogs/3.5.4.md | 5 + web/changelogs/3.5.md | 19 ++ web/changelogs/3.6.3.md | 14 ++ web/changelogs/3.6.md | 10 + web/changelogs/3.7.md | 18 ++ web/changelogs/4.0.md | 22 ++ web/changelogs/4.1.md | 10 + web/changelogs/4.2.md | 15 ++ web/changelogs/4.3.2.md | 13 ++ web/changelogs/4.3.md | 27 +++ web/changelogs/4.4.md | 12 ++ web/changelogs/4.5.md | 33 +++ web/changelogs/4.6.md | 25 +++ web/changelogs/4.7.md | 38 ++++ web/changelogs/4.8.md | 30 +++ web/changelogs/5.0.md | 41 ++++ web/changelogs/5.1.md | 45 ++++ web/changelogs/5.2.md | 52 +++++ web/changelogs/5.3.md | 20 ++ web/changelogs/5.4.md | 34 +++ web/changelogs/6.0.md | 68 ++++++ web/changelogs/6.2.md | 23 ++ web/changelogs/7.0.md | 83 ++++++++ web/changelogs/7.1.md | 28 +++ web/changelogs/7.11.md | 45 ++++ web/changelogs/7.13.md | 59 +++++ web/changelogs/7.14.md | 43 ++++ web/changelogs/7.3.md | 30 +++ web/changelogs/7.4.md | 45 ++++ web/changelogs/7.5.md | 28 +++ web/changelogs/7.6.md | 33 +++ web/changelogs/7.7.md | 30 +++ web/changelogs/7.8.md | 35 +++ web/changelogs/7.9.md | 33 +++ 36 files changed, 1082 insertions(+), 308 deletions(-) delete mode 100644 src/modules/changelog/changelog.json create mode 100644 web/changelogs/3.5.2.md create mode 100644 web/changelogs/3.5.4.md create mode 100644 web/changelogs/3.5.md create mode 100644 web/changelogs/3.6.3.md create mode 100644 web/changelogs/3.6.md create mode 100644 web/changelogs/3.7.md create mode 100644 web/changelogs/4.0.md create mode 100644 web/changelogs/4.1.md create mode 100644 web/changelogs/4.2.md create mode 100644 web/changelogs/4.3.2.md create mode 100644 web/changelogs/4.3.md create mode 100644 web/changelogs/4.4.md create mode 100644 web/changelogs/4.5.md create mode 100644 web/changelogs/4.6.md create mode 100644 web/changelogs/4.7.md create mode 100644 web/changelogs/4.8.md create mode 100644 web/changelogs/5.0.md create mode 100644 web/changelogs/5.1.md create mode 100644 web/changelogs/5.2.md create mode 100644 web/changelogs/5.3.md create mode 100644 web/changelogs/5.4.md create mode 100644 web/changelogs/6.0.md create mode 100644 web/changelogs/6.2.md create mode 100644 web/changelogs/7.0.md create mode 100644 web/changelogs/7.1.md create mode 100644 web/changelogs/7.11.md create mode 100644 web/changelogs/7.13.md create mode 100644 web/changelogs/7.14.md create mode 100644 web/changelogs/7.3.md create mode 100644 web/changelogs/7.4.md create mode 100644 web/changelogs/7.5.md create mode 100644 web/changelogs/7.6.md create mode 100644 web/changelogs/7.7.md create mode 100644 web/changelogs/7.8.md create mode 100644 web/changelogs/7.9.md diff --git a/src/modules/changelog/changelog.json b/src/modules/changelog/changelog.json deleted file mode 100644 index e90a1a33..00000000 --- a/src/modules/changelog/changelog.json +++ /dev/null @@ -1,308 +0,0 @@ -{ - "current": { - "version": "7.14", - "date": "May 17, 2024", - "title": "now helping over 1 million people monthly", - "banner": { - "file": "millionusers.webp", - "alt": "collage of two photos, side by side. left photo: brown cake with 7 lit candles forming 1000000 and one ferrero rocher candy in the middle with cobalt (double greater than symbol) logo on it. right photo: chocolate cake with 7 lit candles forming 1000000 and cobalt logo formed with whipped cream on the cake. two plushes of meowth and pompompurin in party hats are seen behind the cake.", - "width": 1736, - "height": 1440 - }, - "content": "yesterday, cobalt hit 1 million users around the world! it's an absolutely insane milestone for us and we're incredibly grateful to everyone saving and creating what they love with help of cobalt. thank you for being our friends.\n\nin anticipation of 7 figure user count, we've revamped the cobalt codebase and infrastructure to be faster and more reliable than ever. a combination of many changes has resulted into incredible download speeds (up to 30 MB/s, as tested by both developers in europe).\n\nnote: there's no backend instance in asia just yet, so if you're there, you might experience average speeds *for now*. you can help us afford a dedicated server in asia by donating to cobalt in the \"donate\" menu.\n\nchanges since the last major update\n\nservice improvements:\n*; youtube music support on the main instance is back!\n*; added support for pinterest images and gifs.\n*; cobalt will now use original soundcloud mp3 file when available.\n*; fixed a youtube bug that prevented some videos from downloading.\n\nui/ux improvements:\n*; cobalt web app is now fully optimized for ipad. you can add it to home screen from share menu to make it act like a native app!\n*; majorly reduced vertical padding when viewing cobalt in mobile web browser, allowing for more content at once. most noticeable on smaller screens.\n*; status bar color is now dynamic in the web browser on ios and web app on android.\n*; web app on android feels way more native than before.\n*; filename style icons are no longer blurry in safari.\n*; changelog notification no longer overlaps with dynamic island on newer iphones when cobalt is installed as a web app.\n*; fixed safe area padding.\n\nother changes:\n*; added support for freebind, made by one of the cobalt developers.\n*; rate limit and max video length limits are now customizable through environment variables.\n*; cobalt api now returns rate limit headers at all times.\n*; majorly cleaned up the codebase: removed unnecessary functions, rewrote those that were cryptic and confusing. it's way more comprehensible and contribution-friendly than ever before.\n*; moved the cobalt repo to our organization on github. everything stayed the same and all old links link back to it.\n\nnote for instance hosters:\nalong with cobalt repo, the docker image also moved! please update the url for it in your config along with watchtower args to include restarting containers (just in case) as seen in updated docker compose example. we're mirroring packages to old url for now, but it won't last forever.\n\nthat's it for now! hope you have an amazing day and share the 1 million celebration with us :)\n\njoin our discord server to discuss everything cobalt there" - }, - "history": [{ - "version": "7.13", - "date": "May 5, 2024", - "title": "better ux, improvements for youtube, twitter, tiktok, instagram, and more!", - "banner": { - "file": "meowthbusinessman.webp", - "alt": "photo of a businessman holding hands together (merkel-raute pose) with meowth plush head.", - "width": 1440, - "height": 960 - }, - "content": "long time no see! well, actually, you've been using the latest version for some time now. we've moved to a rolling release scheme, allowing for speedy update rollouts :)\n\nsince 7.11, there has been a ton of changes. here are the most notable of them:\n*; youtube downloads are now faster and more reliable than ever.\n*; all posts from twitter are now downloadable, including sensitive ones.\n*; you now can download tiktok videos in 1080p h265! just enable h265 support in settings > video.\n*; added support for sharing links directly to the cobalt web app on android.\n*; added 240p and 144p quality options to the quality picker in settings (for some reason, many of you wanted this).\n*; pasting a link with additional text around it will now work; cobalt will extract the link for you (works only via the paste button).\n*; added anonymous traffic analytics by plausible. we're using a selfhosted instance and don't collect any identifiable information about you. you can learn more in about > privacy policy. you can also opt out of anonymous analytics in settings > other.\n\nservice support improvements:\n*; implemented internal streams functionality, allowing for more fine-grained file streaming and therefore proper youtube support.\n*; added fallback to m4a if opus isn't available for youtube.\n*; added a total of 7 ways to get instagram post info, including mobile api, embed, and graphql api. absolute torture.\n*; added support for reddit user posts.\n*; updated the way tiktok downloads are handled for better reliability and 1080p support.\n*; added tiktok author's username to filename.\n*; added support for rutube shorts and yappy videos.\n*; added support for m.soundcloud.com links.\n*; added support for new post and reel links from instagram.\n*; added support for photo twitter links, only used for gifs.\n*; added support for m.bilibili.com links.\n*; added support for new type of vimeo links.\n*; added support for ddinstagram.com links.\n*; updated youtube codec info in settings to display the fact that av1 is a better choice now.\n*; updated best audio picking for tiktok and soundcloud.\n*; changed the youtube client to web, since android client no longer works.\n*; removed the vimeo download type switcher, as it should've always been automatic instead.\n*; removed an ability to enable the tiktok watermark, as it no longer includes the author's username.\n\nui & ux improvements:\n*; youtube audio dub switcher is now a toggle with a much easier to understand description.\n*; meowbalt now sticks out on the left side of download popup on desktop.\n*; updated \"made with love\" text to include the research & dev team behind cobalt, imput.\n*; fixed grammar of russian localization.\n*; rounded corners are now correctly rendered across all browsers.\n*; various minor improvements, including smaller button padding.\n*; removed the notification (red dot) functionality as the most recent changelog is already always on screen.\n*; removed settings migration from the old domain.\n\nother changes:\n*; various docs updates in github repo, making sure they're functional across branches and forks.\n*; major codebase cleanup.\n\nthank you for using cobalt, and thank you for being one of our 900k friends! i hope you like this update as much as we liked making it.\n\nwe're committed to keeping cobalt the best way to save what you love without ads or invasion of your privacy. there's a ton of cool stuff to come soon; stay tuned and have an amazing rest of your day <3\n\nif you want to help our goal of a better internet for everyone, just share cobalt with a friend!\n\n(original photo of a man in a suit by benzoix on freepik)" - }, { - "version": "7.11", - "date": "March 6, 2024", - "title": "cache encryption, meowbalt, dailymotion, bilibili, and much more!", - "banner": { - "file": "meowth7eleven.webp", - "alt": "meowth plush in front of 7-eleven store", - "width": 850, - "height": 640 - }, - "content": "cobalt may not have as many groceries as 7-eleven, but it sure does have lots of big changes in this update!\n\n*; all cached stream info is now encrypted and can only be decrypted with a link you get from cobalt.\n*; new popup style featuring meowbalt, cobalt's speedy mascot. you will see him more often from now on!\n*; added support for dailymotion (including short links).\n*; added support for bilibili.tv, fixed support for bilibili.com, and added support for all related short links.\n*; added support for unlisted vimeo links.\n*; added support for tumblr audio and revamped the entire module.\n*; added support for embed ok.ru links.\n\nwe also updated the privacy policy to reflect the addition of data encryption, go check it out.\n\nfor people with iphones:\n*; clearer ios saving tutorial.\n*; added \"save to files\" ios shortcut.\n*; updated save to photos shortcut.\n\nmake sure to save both shortcuts and read the updated tutorial!\n\nfor people who host a cobalt instance:\n*; updated all environment variables TO_BE_LIKE_THIS. time to update your configs! for now cobalt is backwards compatible with old variable names, but it won't last forever.\n*; added a list of all environment variables and their descriptions to run-an-instance doc.\n*; updated cookie file example with more services and improved examples.\n*; updated docker compose example with better explanations and up-to-date env variable samples.\n*; updated some packages to get rid of all unnecessary messages in console.\n\nwant to host an instance? learn how to do it here.\n\nfrontend changes:\n*; removed migration popup.\n*; corners across ui are even more round now.\n*; bottom glass bkg in popups is no longer rounded on top right.\n*; small popup no longer stretches like gum, it's fixed in size on desktop.\n*; small popup animation no longer lags on mobile.\n*; better ui scaling across resolutions.\n*; updated donation text.\n\nthank you for using cobalt, all 750k of you. hope you like this update as much as we enjoyed making it :D" - }, { - "version": "7.9", - "date": "January 17, 2024", - "title": "twitter gifs, pinterest, ok.ru, and more!", - "banner": { - "file": "meowthball.webp", - "alt": "meowth rolling on a big catnip ball", - "width": 478, - "height": 350 - }, - "content": "yes, you read that right. cobalt now lets you convert any twitter gif to an actual .gif file! (finally)\njust go to settings and enable this feature :)\n\nservice improvements:\n*; added an option to convert gifs from twitter into actual .gif format. files will be bigger and lower quality, but maybe you want that.\n*; pinterest support has been completely redone, now all videos (and even pin.it links) are supported.\n*; added support for ok.ru in case you're a russian grandma.\n*; now processing all reddit links (including old.reddit.com).\n*; instagram live vods are now supported.\n*; fixed a rare vimeo bug related to 1440p videos.\n\nother improvements:\n*; ui fade in animation is no longer present if you've disabled animations.\n*; all images now have alt descriptions.\n*; cobalt html is now biblically correct and follows the html spec.\n*; lots of cleaning up.\n\npatches since 7.8:\n*; shift+key shortcuts are now ignored if url bar is focused.\n*; longer soundcloud links are now supported, also catching more tiktok-related errors.\n*; removed mastodon from support links as that account is no longer active.\n*; added ability to download a specific video from multi media tweets and support for /mediaViewer links.\n*; fixed modal blurriness in chromium.\n*; minor html changes (road to biblically correct one).\n\nlots of long-awaited updates (especially twitter gifs), hope you enjoy them and have a great day :D" - }, { - "version": "7.8", - "date": "December 25, 2023", - "title": "new years clean up! bug fixes and fresh look for the home page", - "banner": { - "file": "catroomba.webp", - "alt": "a cat riding a roomba vacuum", - "width": 300, - "height": 168 - }, - "content": "merry christmas and happy new year! this update fixes several (very annoying) bugs to help you enjoy your holidays better.\n\nyou might have already noticed, but we've refreshed the home page on desktop and mobile! less space wasted, more pleasant to look at. let us know if you like it or not :D\n\nservice improvements:\n*; #264 anything that includes a period in the url should be possible to download (including instagram stories).\n*; #73 soundcloud: falling back to mp3 instead of refusing to download the song at all.\n*; #275 youtube: query parameters are parsed and handled correctly, all links should be supported, no matter where v query is located.\n*; tlds are parsed and validated correctly (e.g. \"pinterest.co.uk\" works now).\n*; fixvx.com links are now supported.\n\ninterface improvements:\n*; cleaner and more consistent home page layout.\n*; cleaned up support section in \"about\". also includes a link to the status page.\n\ninternal improvements:\n*; urls, subdomains, and tlds are properly validated.\n*; minor clean up.\n\nchanges since 7.7:\n*; made terms and ethics more descriptive.\n*; fix only affected twitter videos.\n*; fixed quick ⌘+V pasting on mac.\n*; now catching even more youtube-related errors.\n\nthis might not seem like a lot, but even smaller changes make a difference!\n\nenjoy this update and the rest of your day :D" - }, { - "version": "7.7", - "date": "December 2, 2023", - "title": "bugfixes and better downloads!", - "banner": { - "file": "meowthpolishegg.webp", - "alt": "meowth polishing a togepi egg", - "width": 640, - "height": 480 - }, - "content": "this update fixes various issues with supported services. no new features yet, but twitter fix is surely something good to have in the meantime!\n\nservice improvements:\n*; broken twitter videos are now automatically fixed by cobalt.\n*; all vimeo videos and audios should now be possible to download.\n*; vimeo: fixed short resolution displayed in \"basic\" and \"pretty\" filename styles.\n\ninterface improvements:\n*; streamables are now easier to save on ios.\n\ninternal improvements:\n*; port env variable is now not strictly necessary for cobalt to run.\n*; minor clean up.\n\nchanges since 7.6:\n*; fix for an issue related to youtube dubs.\n*; fixed a memory leak related to live renders.\n*; handling all errors related to twitter downloads.\n*; fixed support for reddit links in various languages.\n*; added rich filenames support for twitch clips.\n*; updated support and donation lists.\n\nstay tuned for future updates and have a great day :D" - }, { - "version": "7.6", - "date": "October 15, 2023", - "title": "customizable file names, instagram stories, and first cobalt sponsor!", - "banner": { - "file": "meowthcenter.webp", - "alt": "meowth plush in a datacenter wearing a hardhat, wielding a hammer", - "width": 851, - "height": 640 - }, - "content": "as many have (very) often requested, cobalt now lets you pick between several file name format styles!\ngo to settings > other and change it to whichever you like! there's a preview of each style, so you know how exactly files are gonna look like.\n\nif you liked file names the way they were before, don't worry: classic style is still the default :)\n\non a different but not any less important note: cobalt is now sponsored by royalehosting.net!\noverall service performance and stability is gonna be better, but also more content will be possible to download thanks to geniuine server locations. and yes, still no ads or trackers.\n\nthis update also includes a bunch of other changes, check them out:\n\nservice improvements:\n*; added support for instagram stories thanks to #194.\n*; fixed reddit support thanks to #221.\n*; added support for rich file names for youtube, vimeo, soundcloud, rutube, and vk.\n*; numbers and emoji no longer disappear from file name and metadata.\n*; mute and audio dub file name tags don't appear together anymore.\n*; youtube: dub file name tag doesn't appear anymore if audio track is default.\n\ninterface improvements:\n*; added a list of sponsors to about tab. if you host an instance, it's disabled by default, but can be enabled with showSponsors env variable.\n*; about button now opens about tab when no new changelog is available.\n*; fixed download button thickness on ios.\n\nyou now can reach out to cobalt via email for support! it's located in the about tab along with other socials, such as discord.\n\ni hope you enjoy this long-awaited update and have a blissful day :D" - }, { - "version": "7.5", - "date": "September 16, 2023", - "title": "support for twitch clips and rutube!", - "banner": { - "file": "twitchupdate.webp", - "alt": "meowth plush staring into the camera, laptop with generic purple service in the background", - "width": 851, - "height": 640 - }, - "content": "hey! this update (finally) adds support for twitch clips and rutube, among other smaller changes.\n\nservice improvements:\n*; added support for twitch clips. no vods, they're unnecessary. just clip whatever you want to download!\n*; added support for rutube in case you ever wanted to download something russian.\n\ninterface improvements:\n*; added a note about cobalt not being affiliated with any supported services.\n*; added a note about meta (the company) in russian.\n*; better russian localization. will keep improving it to make it sound not so robotic over time.\n\nother improvements:\n*; all official servers are now using the docker package. and so should you!\n*; moved the load balancer to poland. requests should be slightly faster now.\n*; minor codebase clean up.\n\nif you're confused about the new domain, read the older changelog! just scroll lower and press \"expand\".\n\ni hope you find this update useful and have a wonderful day :)\n\nbtw, cobalt has a pretty active community server on discord. go to about > support & source code to join!" - }, { - "version": "7.4", - "date": "September 9, 2023", - "title": "new domain, what's coming in future, bug fixes, and more!", - "banner": { - "file": "newdomain.webp", - "alt": "text: new domain, same cobalt", - "width": 960, - "height": 540 - }, - "content": "cobalt is finally moving to its own domain! many of you have been anticipating this, and many kept forgetting the link due to how cryptic it was.\n\nwell, worry no more - cobalt.tools is here.\n\nif you haven't yet, open co.wukko.me to transfer your settings here! no additional action from you is required. just open the old link and cobalt will do everything for you :)\n\nmake sure to update your bookmarks and reinstall the web app!\n\nhere's what domain change means:\n*; still no ads, same owner, same features, same reliability. just a way more rememberable link (it's literally two words).\n*; cobalt.tools makes it clear that cobalt is a tool and that it's \"cobalt\", not \"wukko\".\n*; i can host various versions of cobalt on subdomains without links looking awkward.\n*; i can host cobalt-related websites without polluting my personal domain's dns (such as crowdin).\n*; i stand by same privacy policies (and in fact am using the same exact server as before).\n\nthe domain change is required for the future of cobalt.\n\nhere's what's coming soon:\n*; support for many top-requested sites, such as (but not limited to) twitch and niconico.\n*; education version of cobalt, as often requested by students and educators.\n*; major localization system upgrade, allowing for simpler community contributions.\n*; region-specific versions with 100% translations and tweaks.\n*; native clients for desktop and mobile (not sure about this one, i'm no superman).\n*; ...and more!\n\nnow, here's what's new in 7.4:\n*; tabs in popups now scroll to top on tab bar tap.\n*; padding across web app was tuned.\n*; (obviously) a migration agent. soon will be used for importing and exporting settings.\n*; some minor clean ups in codebase.\n\nif you want to help cobalt achieve goals listed above, consider donating! donations are the only way i can keep cobalt ad-less, powerful, (basically) limitless, and also 100% free.\n\nin fact, donations have helped me grow cobalt more than i've ever anticipated. just imagine how much better it will be in a year.\n\ngo to donations down below to find ways to donate!\n\nthank you for reading through all of this. i hope you enjoy this update and have a great day :D" - }, { - "version": "7.2 & 7.3", - "date": "September 6, 2023", - "title": "extended video length limit, metadata toggle, ui improvements, and more!", - "banner": { - "file": "meowthsnap.webp", - "alt": "cartoon meowth pointing paw dramatically and saying something", - "width": 500, - "height": 280 - }, - "content": "this update gives cobalt a sharp look in chromium browsers and makes it even more useful than before. check out the full changelog below!\n\nservice improvements:\n*; increased video length limit from 3 hours to 5 hours. feel free to download lectures you need :)\n*; you can now disable file metadata in settings.\n*; fixed a bug which previously caused some downloads to end up being 0 bytes.\n\nui improvements:\n*; fixed clickable area for urgent notice (text on top).\n*; fixed blurry header in chrome.\n*; fixed blurry tab bar in chrome.\n*; fixed blurry switches in chrome.\n*; fixed weirdly rounded corners in popups.\n*; fixed 1px gap on edges of various elements in popup in chrome.\n*; fixed overscrolling in other settings tab on ios.\n*; fixed unexpected button highlight effect on phones.\n*; removed outdated fixes for tiny screens.\n\nother improvements:\n*; cobalt web & api start faster than before, additional preparation functions aren't unexpectedly run anymore.\n*; cobalt is now available as a docker package. check it out on github.\n\nthank you for being here. i hope you have a great day :D" - }, { - "version": "7.1", - "date": "August 20, 2023", - "title": "instagram, streamable, video metadata, and more!", - "banner": { - "file": "meowthproductions.webp", - "alt": "meowth roaring in a fancy circle, à la MGM studios intro", - "width": 640, - "height": 358 - }, - "content": "service improvements:\n*; extended instagram support: high quality photos, videos, reels. everything should work without any issues, enjoy! :)\n*; added support for streamable.com (thanks to #179)\n*; added video metadata to youtube videos.\n*; fixed vk video downloads.\n*; vxtwitter links are now supported.\n*; fixed support for youtube audio dubs.\n\nui improvements:\n*; fixed picker popup: it's now scrollable in all cases and clickable areas don't overlap each other.\n\nbackend improvements:\n*; cobalt will now let you know if something goes wrong during video download instead of nuking the stream.\n*; added support for cookies (thanks to #177)\n*; replaced got with undici (thanks to #182). downloads should be slightly faster and clean of garbage in headers.\n\ninternal improvements:\n*; moved host overrides into its own module.\n*; minor clean ups.\n\neven more cool stuff is coming in future updates! thank you for using cobalt :D" - }, { - "version": "7.0", - "date": "August 15, 2023", - "title": "biggest ui refresh yet!", - "banner": { - "file": "meowthcooking.webp", - "alt": "meowth handling orders in a restaurant", - "width": 640, - "height": 360 - }, - "content": "hey! this update is huge and mostly aimed to refresh the ui, but there are also some other nice fixes/additions. read below for more info :)\n\ntl;dr:\n*; entirety of web app has been refreshed. it's more prettier and optimized than ever, both on phone and desktop.\n*; if you're on ios, try adding cobalt to home screen! it'll look and act like a native app.\n*; all soundcloud links are now supported and audio quality is higher than before.\n*; all x (previously twitter) links are now supported and work properly.\n*; newer reddit videos are downloadable now.\n*; added some sort of eula, list of keyboard shortcuts, updated privacy policy for more clarity. check it all in refreshed about tab!\n*; cobalt now lets you know if your browser doesn't support clipboard pasting and helps you fix it.\n\naccessibility notice:\nthis update includes animations and transparency, if you'd like to disable any or all of them, head to settings > other > accessibility.\n\n[full changelog]\n\nservice improvements:\n*; fixed unexpected 502 errors when downloading newer reddit videos.\n*; newer reddit videos (with audio) are downloadable now.\n*; upgraded soundcloud downloads to use higher audio quality than before.\n*; all soundcloud links are now supported.\n*; added support for x.com urls.\n*; changed twitter api once again. now everything works, again.\n\nweb improvements:\n*; all-new matte glass aesthetic, applied to revamped popup headers, tab selectors, and also small popups.\n*; rounded corners everywhere! cobalt is now safe for everyone who can't handle sharp objects.\n*; paddings everywhere are smaller, more content fits on the screen at once.\n*; optimized installed web app to look and act like a native app, especially on ios.\n*; added update release dates to changelogs.\n*; cobalt now lets you know if your browser doesn't support clipboard api and helps you fix it.\n*; refreshed all popups: less padding, more content.\n*; completely remade error and download popups, they're consistent with the rest of refreshed design.\n*; refreshed the look of entire changelog tab: separated title and version/commit, made title bigger, evened out all paddings.\n*; replaced close button with back button, moved it to left.\n*; added interaction animations.\n*; added more keyboard shorcuts.\n*; added a list of keyboard shortcuts to about tab.\n*; added eula to about tab. check it out.\n*; added more accessibility options, put them all into one category. you can disable animations and transparency if you want to.\n*; added a link to self-troubleshooting guide to about tab.\n*; renamed 2160p and 4320p to 4k and 8k respectfully for better clarity.\n*; popups now work without any weird workarounds, especially on mobile. they're clean and nice.\n*; home screen now also works without any weird workarounds. it is also clean and nice.\n*; optimized css of almost all ui elements. should be even more consistent across platforms now.\n*; added ability to translate \"cobalt\" more in-depth localization. for example, in russian \"cobalt\" is now \"кобальт\", that's the style i'll be going with from now on.\n*; updated many localization strings for more clarity.\n*; removed ability to change the app name dynamically in all locations. cobalt is a sustained app name.\n*; updated donation and privacy policy texts for more clarity in both english and russian.\n*; home screen now smoothly fades in instead of popping in.\n*; proper banner loading. no more jumping text!\n*; proper banner error handling. if banner wasn't loaded, it'll simply go grey instead of disappearing.\n*; links are no longer italic and are instead underlined.\n*; collapsible lists now have corresponding emoji.\n*; donate button is now highlighted with magenta instead of white.\n*; proper dropdown arrow.\n*; removed 6.0 api fallback.\n*; fixed celebrations emoji. again.\n*; cleaned up all related frontend modules, especially page.js.\n*; urgent notice is now a js element, not a static piece of text. can be updated easily.\n\napi improvements:\n*; now catching all json api related errors.\n*; moved on demand blocks to web server, now changelog can be updated independently from preferred api server.\n*; now sending standard rate limiting headers.\n*; better readability in source.\n\nother improvements:\n*; renamed docker-compose.yml.example to docker-compose.example.yml for linting in code editors.\n*; added a wiki with wip troubleshooting guide on github. more guides are coming soon!\n\nthat's a ton of changes! i really hope you like this update as much as i do.\n\nif you experience any issues, feel free to contact me on any platform listed in about tab! i'd love to hear back from you.\n\nthank you for sticking with me and cobalt, i hope you have THE best day :D" - }, { - "version": "6.2", - "date": "June 27 2023", - "title": "all network issues have been fixed!", - "banner": { - "file": "meowthhammer.webp", - "alt": "meowth plush holding a hammer in real life", - "width": 1280, - "height": 827 - }, - "content": "hey! there have been some hiccups in cobalt's stability lately, i was going through finals while trying to scale up the infrastructure, and that didn't really work out, lol.\nBUT i'm happy to announce that i've optimized all nodes! there should no longer be any networking issues.\n\nenjoy stable experience while i work in background to make cobalt even better :)\n\nhere's what's new in this update:\n*; better button contrast in both themes. \n*; button highlight in light theme now actually looks like a highlight.\n*; removed ip gate for streamables and updated privacy policy to reflect this change.\n*; streamable links now last for 20 seconds instead of 2 minutes.\n*; cleaned up stream verification algorithm. now the same function doesn't run 4 times in a row.\n*; removed deprecated way of hosting a cobalt instance.\n\nthank you for sticking with cobalt, and i hope you have a great day :D\n\nbanner photo is by @halftroller on twitter, thank you so much!" - }, { - "version": "6.0", - "date": "June 7, 2023", - "title": "better reliability, new infrastructure, pinterest support, and way more!", - "banner": { - "file": "catswitchboxes.webp", - "alt": "a cat climbing into two empty boxes of asahi beer", - "width": 600, - "height": 314 - }, - "content": "hey! long time no see, hopefully over 40 changes will make up for it :)\n\ncobalt now has an official community discord server. you can go there for news, support, or just to chat. go check it out!\n\ntl;dr\n*; new infra, new hosting structure, new main instance api url. developers, get it here.\n*; added support for pinterest, vine archive, tumblr audio, youtube vr videos.\n*; better web app performance and look.\n*; better stability thanks to load balancing.\n*; (hopefully) no more random video/audio download drops.\n\nservice improvements:\n*; added support for pinterest videos and stories (pr by @Snazzah).\n*; added support for tumblr audio. sorry, tumblr.\n*; added support for youtube vr videos. please note that they're in youtube's proprietary ratio.\n*; added support for vine archive.\n*; added support for ancient vk videos in 240p.\n*; fixed an issue related to muted video downloads from tumblr.\n*; moved to twitter v2 api.\n*; soundcloud share links are now processed without errors.\n\nui improvements:\n*; lazy image loading. should significantly speed up the page load.\n*; fixed checkbox width on mobile devices.\n*; addition of a temporary urgent notice.\n*; added hover border to all buttons.\n*; less annoying donation button highlight.\n*; more consistent color scheme.\n*; added link to a discord server into about popup.\n*; remember celebratory emoji changes? they've been fixed, and are now dynamically loaded!\n*; changelog history now lets you try to load it again if first attempt failed for whatever reason.\n*; padding (everywhere) has been slightly reduced to fit in more content and be consistent across ui.\n*; added more info to the \"how to save\" popup for ios devices.\n*; crypto wallet press-to-copy buttons now look like buttons.\n*; improved ui layout for smallest screens (iphone 5, 5s, se, etc).\n*; removed partial translations for sake of clarity and consistency.\n\ninternal improvements:\n*; separated web and api servers. they're now completely independent and therefore more stress-resistant.\n*; added a dedicated script for building the web app if you don't want to reload the frontend server.\n*; web app building improvements.\n*; async localization preloading.\n*; consistent server start time reporting.\n*; dynamic stream and ip hashing salt generation.\n\ninfrastructure improvements:\n*; load balancing: your api requests are now sent to the least busy server. yes, there are now several of them with more to come in the future.\n*; when possible, server in closest region is used instead of a far-away one. this should help with download speeds.\n*; currently there are multiple servers in europe. i will let you know when (and if) i manage to get an american one.\n\nupdates for developers and instance hosters:\n*; server info api endpoint: you can now check up on the api server of choice. it reports all the basic info you may need. check the api docs for more info.\n*; api names: each and every api instance should have a distinctive name. this will be useful in the future :)\n*; added docker compose sample config.\n*; updated and more granular setup script.\n*; better api scalability and faster server start up thanks to web and api separation.\n*; added ability to specify ffmpeg threads. simply add ffmpegThreads to your environment variables!\n\ni'm still in awe from how popular cobalt has become. there are now over 200k of unique users monthly, and that number only keeps growing. i even had to come up with something to accommodate for larger traffic, it's absolutely insane.\n\nlove you all, have a great day :D" - }, { - "version": "5.4", - "title": "instagram support, docker, and more!", - "banner": { - "file": "catphonestand.webp", - "alt": "a cat holding a phone under its chin while a person plays clash of clans on it", - "width": 451, - "height": 272 - }, - "content": "something many of you've been waiting for is finally here! try it out and let me know what you think :)\n\ntl;dr:\n*; added experimental instagram support! download any reels or videos you like, and make sure to report any issues you encounter. yes, you can convert either to audio.\n*; fixed support for on.soundcloud links.\n*; added share button to \"how to save?\" popup.\n*; added docker support.\n\nservice improvements:\n*; added experimental support for videos from instagram. currently only reels and post videos are downloadable, but i'm looking into ways to save high resolution photos too. if you experience any issues, please report them on either of support platforms.\n*; fixed support for on.soundcloud share links. should work just as well as other versions!\n*; fixed an issue that made some youtube videos impossible to download.\n\ninterface improvements:\n*; new css-only checkmark! yes, i can't stop tinkering with it because slight flashing on svg load annoyed me. now it loads instantly (and also looks slightly better).\n*; fixed copy animation.\n*; minor localization improvements.\n*; fixed the embed logo that i broke somewhere in between 5.3 and 5.4.\n\ninternal improvements:\n*; now using nanoid for live render stream ids.\n*; added support for docker. it's kind of clumsy because of how i get .git folder inside the container, but if you know how to do it better, feel free to make a pr.\n*; cobalt now checks only for existence of environment variables, not exactly the .env file.\n*; changed the way user ip address is retrieved for instances using cloudflare.\n*; added ability to disable cors, both to setup script and environment variables.\n\ni can't believe how diverse and widespread cobalt has become. it's used in all fields: music production, education, content creation, and even game development. thank you. this is absolutely nuts.\nif you don't mind sharing, please tell me about your use case. i'd really love to hear how you use cobalt and how i could make it even more useful for you." - }, { - "version": "5.3", - "title": "better looks, better feel", - "banner": { - "file": "cattired.webp", - "alt": "a cat laying on a sofa face down, wiggling its tail", - "width": 640, - "height": 286 - }, - "content": "this update isn't as big as previous ones, but it still greatly enhances the cobalt experience.\n\nhere's what's up:\n*; new mode switcher! elegant and 100% clear. should no longer cause any confusion. let me know if you like it better this way :D\n*; wide paste button on mobile is back, but now it's even closer to your finger.\n*; removed the weird grey chin on changelog banners.\n*; removed left-handed layout toggle since it is no longer needed.\n*; fixed input area display in chromium 112+.\n*; centered the main action box.\n*; cleaned up css of main action box to get rid of tricks and ensure correct display on all devices.\n*; fixed a bug that'd cause notifications dots to disappear when an unrelated checkbox was checked.\n\nhopefully from now on i'll focus on adding support for more services.\nthank you for using cobalt. stay cool :)" - }, { - "version": "5.2", - "title": "fastest one in the game", - "banner": { - "file": "catspeed.webp", - "alt": "a cat running very fast in an exercise wheel", - "width": 640, - "height": 356 - }, - "content": "hey, notice anything different? well, at very least the page loaded way faster! this update includes many improvements and fixes, but also some new features.\n\ntl;dr:\n*; twitter retweet links are now supported.\n*; all vimeo videos should now be possible to download.\n*; you now can download audio from vimeo.\n*; it's now possible to pick between preferred vimeo download method in settings.\n*; fixed issues related to tiktok, twitter, twitter spaces, and vimeo downloads.\n*; overall cobalt performance should be MUCH better.\n\nservice improvements:\n*; added support for twitter retweet links. now all kinds of tweet links are supported.\n*; fixed the issue related to periods in tiktok usernames (#96).\n*; fixed twitter spaces downloads.\n*; added support for audio downloads from vimeo.\n*; added ability to choose between \"progressive\" and \"dash\" vimeo downloads. go to settings > video to pick your preference.\n*; fixed the issue related to vimeo quality picking.\n*; fixed the issue when vimeo module wouldn't show appropriate errors and instead would fallback to default ones.\n*; improved audio only downloads for some edge cases.\n*; (hopefully) better youtube reliability.\n*; temporarily disabled douyin support due to api endpoint cut off.\n\ninterface improvements:\n*; merged clipboard and mode switcher rows into one for mobile view.\n*; added left-handed layout toggle for those who prefer to have the clipboard button on left.\n*; new custom-made clipboard icon. now it clearly indicates what it does.\n*; improved english and russian localization. both are way more direct and less bloaty.\n*; frontend page is now rendered once and is cached on disk instead of being rendered every time someone requests a page. this greatly improves page loading speeds and further reduces strain put on the server.\n*; frontend page is now minimized just like js and css files. this should minimize traffic wasted on loading the page, along with minor loading speed improvement.\n*; added proper checkbox icon for better clarity.\n*; checkboxes are now stretched edge-to-edge on phone to be easier to manage for right-handed people.\n*; removed button hover highlights on phones.\n*; fixed button press animations for safari on ios.\n*; fixed text selection on ios. previously you could select text or images anywhere, but now they're selectable in limited places, just like on other platforms.\n*; frontend platform is now marked in settings: p is for pc; m is for mobile; i is for ios. this is done for possible future debugging and issue-solving.\n*; better error messaging.\n\ninternal improvements:\n*; better rate limiting, there should be way less cases of accidental limits.\n*; added support for m3u8 playlists. this will be useful for future additions, and is currently used by vimeo module.\n*; added support for \"chop\" stream format for vimeo downloads.\n*; fixed vk user id extraction. i assumed the - in url was a separator, but it's actually a part of id.\n*; completely reworked the vimeo module. it's much cleaner and better performant now.\n*; minor clean ups across the board.\n\nnot really related to this update, but thank you for 50k monthly users! i really appreciate that you're still here, because that means i'm doing some things right :D" - }, { - "version": "5.1", - "title": "the evil has been defeated", - "banner": { - "file": "happymeowth.webp", - "alt": "meowth jumping up into the sky very excitedly", - "width": 500, - "height": 330 - }, - "content": "hey, ever wanted to download a youtube video without a hassle? cobalt is here to help. this update fixes all issues related to youtube downloads.\nnot only that, but it also introduces features never before seen in a downloader, such as youtube dub downloads! read below to see what's up :)\n\ntl;dr:\n*; audio in youtube videos FINALLY no longer gets cut off.\n*; you now can pick any video resolution you want (from 360p to 8k) and any possible youtube video codec (h264/av1/vp9).\n*; you now can download youtube videos with dubs in your native language. just check settings > audio.\n*; youtube processing has been vastly sped up.\n\nok, now onto the nerdy part of changelog. this update is pretty huge and includes improvements across the board.\n\nservice improvements:\n*; all youtube functionality has been reworked. cobalt now relies on innertube apis, not web scraping.\n*; random audio cut off issue has been fixed, let me know if it ever occurs again. (closes #62, #66, #75, #88).\n*; added support for youtube dubs. currently it's using your browser's default language when enabled, but i have plans on making a picker. i'll ask people on twitter and mastodon if this feature is needed, and add a picker in next updates.\n*; instead of adding more quality presets, i added granular quality options. pick whatever you like, from 360p up to 4320p (for all services, not just youtube).\n*; replaced a format picker with codec picker for youtube. you can pick h264, av1, or vp9. all of them should work as expected (closes #88).\n*; youtube audio files are now properly matched to corresponding video files.\n*; it's now always possible to download pristine h264 720p/360p videos from youtube. these videos will work ANYWHERE, so they're default for mobile.\n*; youtube requests are no longer permanently cached, ram usage should drop even further.\n*; youtube video and audio file names now include codec and dub language when applicable.\n*; max video and audio duration limits have been bumped up to 3 hours.\n*; general performance of entire youtube download process has been greatly improved.\n*; vk module has been reworked to be more compact and not make use of outdated technique of quality picking. should also be way more reliable.\n\ninternal improvements:\n*; cleaned up services config, all constants have been moved directly to modules for quicker access.\n*; matching module has been slightly cleaned up.\n\ninterface improvements:\n*; many descriptions and error messages have been slightly tuned to be less wordy.\n*; unnecessary title duplications in settings have been merged into one.\n*; added more clarity to quality and codec descriptions.\n\nif you use cobalt api, please note that you have to update your creation to support new features.\n\nthis is the second batch of 5.x improvements, there's way more to come. thank you for being here, i really appreciate your support.\n\nif you want to thank me (the developer), there's a nice tab under this changelog that has \"donations\" text on it. anything helps me continue developing and hosting the friendliest media downloader :D" - }, { - "version": "5.0", - "title": "it's all about attention to detail!", - "banner": { - "file": "valentines.webp", - "alt": "relaxed meowth with sakura petals falling in front of them", - "width": 489, - "height": 374 - }, - "content": "happy valentine's day! i have an update for you, as a gift :D\n\ntl;dr: added support for reddit gifs, fixed douyin downloads, fixed vimeo quality picking, revamped entirety of codebase, and many other fixes.\n\nhere's more info:\n\nthis update is mostly about cleaning up and polishing the codebase, but it also has some new features. here's what's up:\n\nservice-related improvements:\n*; you now can download gifs from reddit!\n*; attempting to download a video from douyin no longer throws an error (bytedance changed the api endpoint, yet again).\n*; fixed quality picking for vimeo downloads.\n*; fixed length limit check in vimeo module.\n*; fixed support for \"user view\" vk clips links.\n*; various twitter errors are now displayed correctly instead of falling back to the default error.\n*; state of all services is now tested on each commit.\n\nui improvements:\n*; cobalt social links no longer disappear if you have an aggressive ad blocking extension installed.\n*; various localization improvements for both english and russian.\n*; changed some service aliases to display full list of supported downloads.\n*; added current branch information to version text (in settings).\n*; fixed typos in older changelogs.\n\ninternal improvements:\n*; everything has been sanitized, improved, and refactored. code is now much easier to read and maintain.\n*; rewrote and/or optimized all modules that were messy or inefficient.\n*; all git interaction functions now store info in cache instead of fetching it every time the function is called.\n*; added a test script that checks functionality of all supported services.\n*; updated deepsource config. checks are more accurate now.\n*; requests from internet explorer are now dropped entirely instead of redirecting people stuck in 90s to a proper browser download page. this was done to avoid (my) personal bias towards browsers.\n\ni put a ton of effort into this version, and i hope you like it as much as i do.\n\nthank you for using cobalt. there's so much more to come :)" - }, { - "version": "4.8", - "title": "prettier than ever", - "banner": { - "file": "catmakeup.webp", - "alt": "a cat being brushed with a powder makeup brush", - "width": 394, - "height": 266 - }, - "content": "this version brings many visual improvements and a completely revamped \"about\" tab.\n\nwhat's new in \"about\" tab:\n*; all information is now split into collapsible sections, making it easier to navigate.\n*; added privacy policy to further prove that none of your data is collected.\n*; added emoji to the page title to make it look consistent with other pages.\n*; added mastodon account handle and link.\n*; there are now short notes at the end of each section.\n*; other changes that are too small to describe. just go check it out!\n\nvisual improvements:\n*; less wasted space: paddings and margins have been reduced and optimized for usability, consistency, and overall beauty.\n*; all links are now in italic. it's much easier to tell them apart from regular highlights.\n*; error popup no longer looks broken and out of place.\n*; download popup now has a proper close button, not something from 2.x era.\n*; emoji are no longer selectable or draggable.\n*; better scalability: desktop layout for home screen is shown if device viewport is wide enough to fit in three action buttons.\n*; page shouldn't look broken on phones in landscape mode (i still highly recommend using cobalt in portrait mode).\n*; removed bulletpoint padding. it was unnecessary.\n*; updated some service names.\n\nas always, you can suggest features or report bugs on any platform listed in the \"support\" section of about tab.\n\nthank you for using cobalt. i hope you have a good day :)" - }, { - "version": "4.7", - "title": "we're better together! thank you for bug reports.", - "banner": { - "file": "bettertogether.webp", - "alt": "various different pokémon jumping in happiness", - "width": 640, - "height": 358 - }, - "content": "this update includes a bunch of improvements, many of which were made thanks to the community :D\n\nservice-related improvements:\n*; private soundcloud links are now supported (#68);\n*; tiktok usernames with dots in them no longer confuse cobalt (#71);\n*; .ogg files no longer wrongfully include a video channel (#67);\n*; fixed an issue that caused cobalt to freak out when user attempted to download an audio from audio-only service with \"mute video\" option enabled.\n\nui improvements:\n*; popup padding has been evened out. popups are now able to fit in more information on scroll, especially on mobile;\n*; all buttons are now of even size and are displayed without any padding issues across all modern browsers and devices;\n*; checkbox is no longer crippled on ios;\n*; many explanation texts have been simplified to get rid of unnecessary bloat (no bullshit, remember?);\n*; moved tiktok section in video settings higher due to higher priority;\n*; fixed unexpectedly displayed scrollbars on switch rows in firefox.\n\nstability improvements:\n*; ffmpeg process now should end upon finishing the render;\n*; ffmpeg should also quit when download is abruptly cut off;\n*; fixed a memory leak that was caused by misconfigured stream information caching (#63).\n\ninternal improvements:\n*; requested streams are now stored in cache for 2 minutes instead of 1000 hours (yes, 1000 hours, i fucked up);\n*; cached data is now reused if user requests same content within 2 minutes;\n*; page render module is now even cleaner than before;\n*; proper support for bullet-points in loc strings.\n\nyou can suggest features or report bugs on github or twitter. both work just fine, use whichever you're more comfortable with.\n\nthank you for using cobalt, and thank you for reading this changelog.\n\nyou're amazing, keep it up :)" - }, { - "version": "4.6", - "title": "mute videos and proper soundcloud support", - "banner": { - "file": "shutup.webp", - "alt": "a cat yawning, with a crossed out loudspeaker icon next to it", - "width": 1024, - "height": 665 - }, - "content": "i've been longing to implement both of these things, and here they finally are.\n\nservice-related improvements:\n*; you now can download videos with no audio! simply enable the \"mute audio\" option in settings > audio.\n*; soundcloud module has been updated, and downloads should no longer break after some time.\nvisual improvements:\n*; moved some things around in settings popup, and added separators where separation is needed.\n*; updated some texts in english and russian.\n*; version and commit hash have been joined together, now they're a single unit.\ninternal improvements:\n*; updated api documentation to include isAudioMuted.\n*; simplified the startup message.\n*; created render elements for separator and explanation due to high duplication of them in the page.\n*; fully deprecated GET method for API requests.\n*; fixed some code quirks.\nhere's how soundcloud downloads got fixed:\n\npreviously, client_id was (stupidly) hardcoded. that means cobalt wasn't able to fetch song data if soundcloud web app got updated.\nnow, cobalt tries to find the up-to-date client_id, caches it in memory, and checks if web app version has changed to update the id accordingly. you can see this change for yourself on github." - }, { - "version": "4.5", - "title": "better, faster, stronger, stable", - "banner": { - "file": "meowthstrong.webp", - "alt": "meowth stretching", - "width": 500, - "height": 280 - }, - "content": "your favorite social media downloader just got even better! this update includes a ton of improvements and fixes.\n\nin fact, there are so many changes, i had to split them in sections.\n\nservice-related improvements:\n*; vimeo module has been revamped, all sorts of videos should now be supported.\n*; vimeo audio downloads! you now can download audios from more recent videos.\n*; cobalt now supports all sorts of tumblr links. (even those scary ones from the mobile app)\n*; vk clips support has been fixed. they rolled back the separation of videos and clips, so i had to do the same.\n*; youtube videos with community warnings should now be possible to download.\nuser interface improvements:\n*; list of supported services is now MUCH easier to read.\n*; banners in changelog history should no longer overlap each other.\n*; bullet points! they have a bit of extra padding, so it makes them stand out of the rest of text.\ninternal improvements:\n*; cobalt will now match the link to regex when using ?u= query for autopasting it into input area.\n*; better rate limiting: limiting now is done per minute, not per 20 minutes. this ensures less waiting and less attack area for request spammers.\n*; moved to my own fork of ytdl-core, cause main project seems to have been abandoned. go check it out on github or npm!\n*; ALL user inputs are now properly sanitized on the server. that includes variables for POST api method, too.\n*; \"got\" package has been (mostly) replaced by native fetch api. this should greatly reduce ram usage.\n*; all unnecessary duplications of module imports have been gotten rid of. no more error passing strings from inside of service modules. you don't make mistakes only if you don't do anything, right?\n*; other code optimizations. there's less clutter overall.\nhuge update, right? seems like everything's fixed now?\n\nnope, one issue still persists: sometimes youtube server drops packets for an audio file while cobalt's rendering the video for you. this results in abrupt cuts of audio. if you want to help solving this issue, please feel free to do it on github!\n\nthank you for reading this, and thank you for sticking with cobalt and me." - }, { - "version": "4.4", - "title": "over 1 million monthly requests. thank you.", - "banner": { - "file": "onemillionr.webp", - "alt": "cobalt logo and a confetti emoji", - "width": 1441, - "height": 1441 - }, - "content": "this is a huge milestone for me, i cannot express enough how grateful i am for each and every one of you.\nthank you for using cobalt, and thank you for showing that people love the web that's friendly and bullshit-free. i'm hoping to never disappoint you in the future and keep up the good work.\n\nthank you <3\n\nif you want to thank ME, check out the renovated donations tab, which now is also linked alongside bottom action buttons." - }, { - "version": "4.3.2", - "title": "twitter improvements & changelog overhaul", - "content": "- you can download explicit content from twitter.\n- direct video links from twitter are properly supported (video/1, video/2, etc.).\n- changelog history got support for banners.\n- changelog categories are not messy anymore.\n- cobalt version in changelogs is now highlighted.\n- changelog history got separators to make text easier to read.\n- changelog history can be collapsed after loading.\n- download button takes less time to change back to pressable state.\n\nif you're a developer and would like to play around with cobalt's api, then read more about it in older changelogs below!" - }, { - "version": "4.3", - "title": "developers, developers, developers, developers", - "banner": { - "file": "developers.webp", - "alt": "steve ballmer going \"developers, developers, developers\"", - "width": 640, - "height": 360 - }, - "content": "this update features a TON of improvements.\n\ndevelopers, you now can rely on cobalt for getting content from social media. the api has been revamped and documentation is now available. you can read more about API changes down below. go crazy, and have fun :D\n\nif you're not a developer, here's a list of changes that you probably care about:\n- rate limit is now approximately 8 times bigger. no more waiting, even if you want to download entirety of your tiktok \"for you\" page.\n- some updates will now have expressive banners, just like this one.\n- fixed what was causing an error when a youtube video had no description.\n- mp4 format button text should now be displayed properly, no matter if you touched the switcher or not.\n\nnext, the star of this update — improved api!\n- main endpoint now uses POST method instead of GET.\n- internal variables for preferences have been updated to be consistent and easier to understand.\n- ip address is now hashed right upon request, not somewhere deep inside the code.\n- global stream salt variable is no longer unnecessarily passed over a billion functions.\n- url and picker keys are now separate in the json response.\n- cobalt web app now correctly processes responses with \"success\" status.\n\nif you currently have a siri shortcut or some other script that uses the GET method, make sure to update it soon. this method is deprecated, limited, and will be removed entirely in coming updates.\n\nif you ever make something using cobalt's api, make sure to mention @justusecobalt on twitter, i would absolutely love to see what you made." - }, { - "version": "4.2", - "title": "optimized quality picking and 8k video support", - "content": "- this update fixes quality picking that was accidentally broken in 4.0 update.\n- you now can download videos in 8k from youtube. why would you that? no idea. but i'm more than happy to give you this option.\n- default video quality for downloads from pc is now 1440p, and 720p for phones.\n- default video format is now mp4 for everyone.\n- default audio format is now mp3 for everyone.\n\nyou can always change new defaults back to whatever you prefer in settings.\n\nother changes:\n- added more clarity to quality picker description.\n- youtube video codecs are now right in the picker.\n- setup script is now easier to understand." - }, { - "version": "4.1", - "title": "better tiktok image downloads", - "content": "here's what's up:\n- tiktok images are saved as .jpeg instead of .webp (finally, i know).\n- added support for image downloads from douyin.\n- fixed tiktok audio downloads from the image picker.\n- emoji in about button now changes on special occasions. be it halloween or christmas, cobalt will change just a tiny bit to fit in :D\n\nif you're not caught up with new stuff in cobalt 4.x yet, check out the previous changelog down below. there's a ton of stuff to like." - }, { - "version": "4.0", - "title": "better and faster than ever", - "content": "this update has a ton of improvements and new features.\n\nchanges you probably care about:\n- cobalt now has support for recorded twitter spaces! download the previous conversation no matter how long it was.\n- download speeds from youtube are at least 10 times better now. you're welcome.\n- both video and audio length limits have been extended to 2 hours.\n- audio downloads from youtube, youtube music, twitter spaces, and soundcloud now have metadata! most often it's just title and artist, but when cobalt is able to get more info, it adds that metadata too.\n- tiktok downloads have been fixed, yet again, and if they ever break in the future, cobalt will fall back to downloading a less annoyingly watermarked video.\n- soundcloud downloads have been fixed, too.\n\nless notable changes:\n- currently experimenting with using mp3 as default audio format. if you set something other than mp3 before, it'll be set to mp3. you can always change it back in settings. let me know what you think about this.\n- \"download audio\" button from image picker no longer stays on the screen after popup was closed.\n- clipboard button now shows up depending on your browser's support for it.\n- you can no longer manually hide the clipboard button, 'cause it's unnecessary.\n- small internal improvements such as separation of changelog version and title.\n- fair bit of internal clean up.\n\nif you want to help me implement covers for downloaded audios, you can do it on github." - }, { - "version": "3.7", - "title": "support for multi media tweets is here!", - "content": "cobalt now lets you save any of the videos or gifs in a tweet. even if there are many of them.\n\nsimply paste a link like you'd usually do and cobalt will ask what exactly you want to save.\n\nFIREFOX USERS: if you have strict tracking protection on, you might wanna turn it off for cobalt, or else twitter video previews won't load. firefox filters out twitter image cdn as if it was a tracker, which it's not. it's a false-positive.\n\nhowever, you can leave it on if you're fine with blank squares and video numbers. i have thought of that in prior, you're welcome.\n\nother changes:\n- repurposed ex tiktok-only image picker to be dynamic and adapt depending on content to pick. that's exactly how twitter multi media downloads work.\n- cobalt is now properly viewable on phones with tiny screens, such as first gen iphone se.\n- scrollbars now should be visible only where they're needed.\n- brought back proper twitter api, because other one doesn't have multi media stuff (at least yet).\n- cleaned up some internal files, including main frontend js file.\n- reorganized some files in project directory, now you won't get lost when contributing or just looking through cobalt's code." - }, { - "version": "3.6.2 + 3.6.3", - "title": "less disturbance", - "content": "changelog popup no longer annoys you after a major update! this action has been replaced with a notification dot. if you see a red dot, then there's something new.\n\nyour old setting that disabled the changelog popup now applies to notifications.\n\nnew users will see a notification dot instead of an about popup, too. this was mostly done to prevent complications if your browser is set up to clean local storage when you close it.\n\nother changes:\n- popups are now a bit wider, just so more content fits at once.\n- better interface scaling.\n- code is a bit cleaner now.\n- changed twitter api endpoint. there should no longer be any rate limits." - }, { - "version": "3.6", - "title": "improvements all around!", - "content": "- download mode switcher is moving places, it's now right next to link input area.\n- smart mode has been renamed to auto mode, because this name is easier to understand.\n- all spacings in ui have been evened out. no more eye strain.\n- added support for twitter /video/1 links\n- clipboard button exception has been redone to prepare for adoption of readtext clipboard api in firefox.\n- cobalt is now using different tiktok api endpoint, because previous one got killed, just like the one before.\n- \"other\" settings tab has been cleaned up." - }, { - "version": "3.5.4", - "title": "tiktok support is back :D", - "content": "you can download videos, sounds, and images from tiktok again!\nhuge thank you to @minzique for finding another api endpoint that works." - }, { - "version": "3.5.2", - "title": "vk clips support, improved changelog system, and less bugs", - "content": "new features: \n- added support for vk clips. cobalt now lets you download even more cringy videos!\n- added update history right to the changelog menu. it's not loaded by default to minimize page load time, but can be loaded upon pressing a button. probably someone will enjoy this.\n- as you've just read, cobalt now has on-demand blocks. they're rendered on server upon request and exist to prevent any unnecessary clutter by default. the first feature to use on-demand rendering is history of updates in changelog tab.\n\nchanges:\n- moved twitter entry to about tab and made it localized.\n- added clarity to what services exactly are supported in about tab.\n\nbug fixes:\n- cobalt should no longer crash to firefox users if they love to play around with user-agent switching.\n- vk videos of any resolution and aspect ratio should now be downloadable.\n- vk quality picking has been fixed after vk broke it for parsers on their side." - }, { - "version": "3.5", - "title": "ui revamp and usability improvements", - "content": "new features:\n- cobalt now lets you paste the link in your clipboard and download the file in a single press of a button.if your clipboard's latest content isn't a valid url, cobalt won't process or paste it. you can also hide the clipboard button in settings if you want to.\nunfortunately, the clipboard feature is not available to firefox users because mozilla didn't add proper support for clipboard api.\n- there's now a button to quickly clean the input area, right next to download button. it's really useful in case when you want to quickly save a bunch of videos and don't want to bother selecting text.\n- keyboard shortcuts! you love them, i love them, and now we can use them to perform quick actions in cobalt. use ctrl+v combo to paste the link without focusing the input area; press escape key to close the active popup or clean the input area; and if you didn't know, you can also press enter to download content from the link.\n\nnew looks:\n- main box has been revamped. it has lost its border, thick padding, and now feels light and fresh.\n- download button is now prettier, and has been tuned to make >> look just like the logo.\n- buttons on the bottom now actually look like buttons and are way more descriptive. no more #@+?$ bullshit. it's way easier to see and understand what each of them does.\n- bottom buttons are prettier and easier to use on a phone. they're bigger and stretch out to sides, making them easier to press.\n\nfixes:\n- it's now impossible to overlap multiple popups at once. no more mess if you decide to explore popups while waiting for request to process.\n- popup tabs have been slightly moved down to prevent popup content overlapping.\n- ui scalability has been improved." - }] -} diff --git a/web/changelogs/3.5.2.md b/web/changelogs/3.5.2.md new file mode 100644 index 00000000..7add6687 --- /dev/null +++ b/web/changelogs/3.5.2.md @@ -0,0 +1,16 @@ +--- +title: "vk clips support, improved changelog system, and less bugs" +--- +new features: +- added support for vk clips. cobalt now lets you download even more cringy videos! +- added update history right to the changelog menu. it's not loaded by default to minimize page load time, but can be loaded upon pressing a button. probably someone will enjoy this. +- as you've just read, cobalt now has on-demand blocks. they're rendered on server upon request and exist to prevent any unnecessary clutter by default. the first feature to use on-demand rendering is history of updates in changelog tab. + +changes: +- moved twitter entry to about tab and made it localized. +- added clarity to what services exactly are supported in about tab. + +bug fixes: +- cobalt should no longer crash to firefox users if they love to play around with user-agent switching. +- vk videos of any resolution and aspect ratio should now be downloadable. +- vk quality picking has been fixed after vk broke it for parsers on their side. \ No newline at end of file diff --git a/web/changelogs/3.5.4.md b/web/changelogs/3.5.4.md new file mode 100644 index 00000000..f3a4cd64 --- /dev/null +++ b/web/changelogs/3.5.4.md @@ -0,0 +1,5 @@ +--- +title: "tiktok support is back :D" +--- +you can download videos, sounds, and images from tiktok again! +huge thank you to @minzique for finding another api endpoint that works. \ No newline at end of file diff --git a/web/changelogs/3.5.md b/web/changelogs/3.5.md new file mode 100644 index 00000000..0e706cdc --- /dev/null +++ b/web/changelogs/3.5.md @@ -0,0 +1,19 @@ +--- +title: "ui revamp and usability improvements" +--- +new features: +- cobalt now lets you paste the link in your clipboard and download the file in a single press of a button.if your clipboard's latest content isn't a valid url, cobalt won't process or paste it. you can also hide the clipboard button in settings if you want to. +unfortunately, the clipboard feature is not available to firefox users because mozilla didn't add proper support for clipboard api. +- there's now a button to quickly clean the input area, right next to download button. it's really useful in case when you want to quickly save a bunch of videos and don't want to bother selecting text. +- keyboard shortcuts! you love them, i love them, and now we can use them to perform quick actions in cobalt. use ctrl+v combo to paste the link without focusing the input area; press escape key to close the active popup or clean the input area; and if you didn't know, you can also press enter to download content from the link. + +new looks: +- main box has been revamped. it has lost its border, thick padding, and now feels light and fresh. +- download button is now prettier, and has been tuned to make >> look just like the logo. +- buttons on the bottom now actually look like buttons and are way more descriptive. no more #@+?$ bullshit. it's way easier to see and understand what each of them does. +- bottom buttons are prettier and easier to use on a phone. they're bigger and stretch out to sides, making them easier to press. + +fixes: +- it's now impossible to overlap multiple popups at once. no more mess if you decide to explore popups while waiting for request to process. +- popup tabs have been slightly moved down to prevent popup content overlapping. +- ui scalability has been improved. \ No newline at end of file diff --git a/web/changelogs/3.6.3.md b/web/changelogs/3.6.3.md new file mode 100644 index 00000000..49459ecc --- /dev/null +++ b/web/changelogs/3.6.3.md @@ -0,0 +1,14 @@ +--- +title: "less disturbance" +--- +changelog popup no longer annoys you after a major update! this action has been replaced with a notification dot. if you see a red dot, then there's something new. + +your old setting that disabled the changelog popup now applies to notifications. + +new users will see a notification dot instead of an about popup, too. this was mostly done to prevent complications if your browser is set up to clean local storage when you close it. + +other changes: +- popups are now a bit wider, just so more content fits at once. +- better interface scaling. +- code is a bit cleaner now. +- changed twitter api endpoint. there should no longer be any rate limits. \ No newline at end of file diff --git a/web/changelogs/3.6.md b/web/changelogs/3.6.md new file mode 100644 index 00000000..39d34308 --- /dev/null +++ b/web/changelogs/3.6.md @@ -0,0 +1,10 @@ +--- +title: "improvements all around!" +--- +- download mode switcher is moving places, it's now right next to link input area. +- smart mode has been renamed to auto mode, because this name is easier to understand. +- all spacings in ui have been evened out. no more eye strain. +- added support for twitter /video/1 links +- clipboard button exception has been redone to prepare for adoption of readtext clipboard api in firefox. +- cobalt is now using different tiktok api endpoint, because previous one got killed, just like the one before. +- "other" settings tab has been cleaned up. \ No newline at end of file diff --git a/web/changelogs/3.7.md b/web/changelogs/3.7.md new file mode 100644 index 00000000..3fdad1e6 --- /dev/null +++ b/web/changelogs/3.7.md @@ -0,0 +1,18 @@ +--- +title: "support for multi media tweets is here!" +--- +cobalt now lets you save any of the videos or gifs in a tweet. even if there are many of them. + +simply paste a link like you'd usually do and cobalt will ask what exactly you want to save. + +FIREFOX USERS: if you have strict tracking protection on, you might wanna turn it off for cobalt, or else twitter video previews won't load. firefox filters out twitter image cdn as if it was a tracker, which it's not. it's a false-positive. + +however, you can leave it on if you're fine with blank squares and video numbers. i have thought of that in prior, you're welcome. + +other changes: +- repurposed ex tiktok-only image picker to be dynamic and adapt depending on content to pick. that's exactly how twitter multi media downloads work. +- cobalt is now properly viewable on phones with tiny screens, such as first gen iphone se. +- scrollbars now should be visible only where they're needed. +- brought back proper twitter api, because other one doesn't have multi media stuff (at least yet). +- cleaned up some internal files, including main frontend js file. +- reorganized some files in project directory, now you won't get lost when contributing or just looking through cobalt's code. \ No newline at end of file diff --git a/web/changelogs/4.0.md b/web/changelogs/4.0.md new file mode 100644 index 00000000..287c5625 --- /dev/null +++ b/web/changelogs/4.0.md @@ -0,0 +1,22 @@ +--- +title: "better and faster than ever" +--- +this update has a ton of improvements and new features. + +changes you probably care about: +- cobalt now has support for recorded twitter spaces! download the previous conversation no matter how long it was. +- download speeds from youtube are at least 10 times better now. you're welcome. +- both video and audio length limits have been extended to 2 hours. +- audio downloads from youtube, youtube music, twitter spaces, and soundcloud now have metadata! most often it's just title and artist, but when cobalt is able to get more info, it adds that metadata too. +- tiktok downloads have been fixed, yet again, and if they ever break in the future, cobalt will fall back to downloading a less annoyingly watermarked video. +- soundcloud downloads have been fixed, too. + +less notable changes: +- currently experimenting with using mp3 as default audio format. if you set something other than mp3 before, it'll be set to mp3. you can always change it back in settings. let me know what you think about this. +- "download audio" button from image picker no longer stays on the screen after popup was closed. +- clipboard button now shows up depending on your browser's support for it. +- you can no longer manually hide the clipboard button, 'cause it's unnecessary. +- small internal improvements such as separation of changelog version and title. +- fair bit of internal clean up. + +if you want to help me implement covers for downloaded audios, you can do it on github. \ No newline at end of file diff --git a/web/changelogs/4.1.md b/web/changelogs/4.1.md new file mode 100644 index 00000000..c8dacab1 --- /dev/null +++ b/web/changelogs/4.1.md @@ -0,0 +1,10 @@ +--- +title: "better tiktok image downloads" +--- +here's what's up: +- tiktok images are saved as .jpeg instead of .webp (finally, i know). +- added support for image downloads from douyin. +- fixed tiktok audio downloads from the image picker. +- emoji in about button now changes on special occasions. be it halloween or christmas, cobalt will change just a tiny bit to fit in :D + +if you're not caught up with new stuff in cobalt 4.x yet, check out the previous changelog down below. there's a ton of stuff to like. \ No newline at end of file diff --git a/web/changelogs/4.2.md b/web/changelogs/4.2.md new file mode 100644 index 00000000..9424f061 --- /dev/null +++ b/web/changelogs/4.2.md @@ -0,0 +1,15 @@ +--- +title: "optimized quality picking and 8k video support" +--- +- this update fixes quality picking that was accidentally broken in 4.0 update. +- you now can download videos in 8k from youtube. why would you that? no idea. but i'm more than happy to give you this option. +- default video quality for downloads from pc is now 1440p, and 720p for phones. +- default video format is now mp4 for everyone. +- default audio format is now mp3 for everyone. + +you can always change new defaults back to whatever you prefer in settings. + +other changes: +- added more clarity to quality picker description. +- youtube video codecs are now right in the picker. +- setup script is now easier to understand. \ No newline at end of file diff --git a/web/changelogs/4.3.2.md b/web/changelogs/4.3.2.md new file mode 100644 index 00000000..adabaff3 --- /dev/null +++ b/web/changelogs/4.3.2.md @@ -0,0 +1,13 @@ +--- +title: "twitter improvements & changelog overhaul" +--- +- you can download explicit content from twitter. +- direct video links from twitter are properly supported (video/1, video/2, etc.). +- changelog history got support for banners. +- changelog categories are not messy anymore. +- cobalt version in changelogs is now highlighted. +- changelog history got separators to make text easier to read. +- changelog history can be collapsed after loading. +- download button takes less time to change back to pressable state. + +if you're a developer and would like to play around with cobalt's api, then read more about it in older changelogs below! \ No newline at end of file diff --git a/web/changelogs/4.3.md b/web/changelogs/4.3.md new file mode 100644 index 00000000..8d07cb9a --- /dev/null +++ b/web/changelogs/4.3.md @@ -0,0 +1,27 @@ +--- +title: "developers, developers, developers, developers" +banner: + file: "developers.webp" + alt: "steve ballmer going \"developers, developers, developers\"" +--- +this update features a TON of improvements. + +developers, you now can rely on cobalt for getting content from social media. the api has been revamped and documentation is now available. you can read more about API changes down below. go crazy, and have fun :D + +if you're not a developer, here's a list of changes that you probably care about: +- rate limit is now approximately 8 times bigger. no more waiting, even if you want to download entirety of your tiktok "for you" page. +- some updates will now have expressive banners, just like this one. +- fixed what was causing an error when a youtube video had no description. +- mp4 format button text should now be displayed properly, no matter if you touched the switcher or not. + +next, the star of this update — improved api! +- main endpoint now uses POST method instead of GET. +- internal variables for preferences have been updated to be consistent and easier to understand. +- ip address is now hashed right upon request, not somewhere deep inside the code. +- global stream salt variable is no longer unnecessarily passed over a billion functions. +- url and picker keys are now separate in the json response. +- cobalt web app now correctly processes responses with "success" status. + +if you currently have a siri shortcut or some other script that uses the GET method, make sure to update it soon. this method is deprecated, limited, and will be removed entirely in coming updates. + +if you ever make something using cobalt's api, make sure to mention @justusecobalt on twitter, i would absolutely love to see what you made. \ No newline at end of file diff --git a/web/changelogs/4.4.md b/web/changelogs/4.4.md new file mode 100644 index 00000000..5d63ea5d --- /dev/null +++ b/web/changelogs/4.4.md @@ -0,0 +1,12 @@ +--- +title: "over 1 million monthly requests. thank you." +banner: + file: "onemillionr.webp" + alt: "cobalt logo and a confetti emoji" +--- +this is a huge milestone for me, i cannot express enough how grateful i am for each and every one of you. +thank you for using cobalt, and thank you for showing that people love the web that's friendly and bullshit-free. i'm hoping to never disappoint you in the future and keep up the good work. + +thank you &lt;3 + +if you want to thank ME, check out the renovated donations tab, which now is also linked alongside bottom action buttons. \ No newline at end of file diff --git a/web/changelogs/4.5.md b/web/changelogs/4.5.md new file mode 100644 index 00000000..26e68881 --- /dev/null +++ b/web/changelogs/4.5.md @@ -0,0 +1,33 @@ +--- +title: "better, faster, stronger, stable" +banner: + file: "meowthstrong.webp" + alt: "meowth stretching" +--- +your favorite social media downloader just got even better! this update includes a ton of improvements and fixes. + +in fact, there are so many changes, i had to split them in sections. + +service-related improvements: +- vimeo module has been revamped, all sorts of videos should now be supported. +- vimeo audio downloads! you now can download audios from more recent videos. +- cobalt now supports all sorts of tumblr links. (even those scary ones from the mobile app) +- vk clips support has been fixed. they rolled back the separation of videos and clips, so i had to do the same. +- youtube videos with community warnings should now be possible to download. +user interface improvements: +- list of supported services is now MUCH easier to read. +- banners in changelog history should no longer overlap each other. +- bullet points! they have a bit of extra padding, so it makes them stand out of the rest of text. +internal improvements: +- cobalt will now match the link to regex when using ?u= query for autopasting it into input area. +- better rate limiting: limiting now is done per minute, not per 20 minutes. this ensures less waiting and less attack area for request spammers. +- moved to my own fork of ytdl-core, cause main project seems to have been abandoned. go check it out on github or npm! +- ALL user inputs are now properly sanitized on the server. that includes variables for POST api method, too. +- "got" package has been (mostly) replaced by native fetch api. this should greatly reduce ram usage. +- all unnecessary duplications of module imports have been gotten rid of. no more error passing strings from inside of service modules. you don't make mistakes only if you don't do anything, right? +- other code optimizations. there's less clutter overall. +huge update, right? seems like everything's fixed now? + +nope, one issue still persists: sometimes youtube server drops packets for an audio file while cobalt's rendering the video for you. this results in abrupt cuts of audio. if you want to help solving this issue, please feel free to do it on github! + +thank you for reading this, and thank you for sticking with cobalt and me. \ No newline at end of file diff --git a/web/changelogs/4.6.md b/web/changelogs/4.6.md new file mode 100644 index 00000000..bc13fc99 --- /dev/null +++ b/web/changelogs/4.6.md @@ -0,0 +1,25 @@ +--- +title: "mute videos and proper soundcloud support" +banner: + file: "shutup.webp" + alt: "a cat yawning, with a crossed out loudspeaker icon next to it" +--- +i've been longing to implement both of these things, and here they finally are. + +service-related improvements: +- you now can download videos with no audio! simply enable the "mute audio" option in settings > audio. +- soundcloud module has been updated, and downloads should no longer break after some time. +visual improvements: +- moved some things around in settings popup, and added separators where separation is needed. +- updated some texts in english and russian. +- version and commit hash have been joined together, now they're a single unit. +internal improvements: +- updated api documentation to include isAudioMuted. +- simplified the startup message. +- created render elements for separator and explanation due to high duplication of them in the page. +- fully deprecated GET method for API requests. +- fixed some code quirks. +here's how soundcloud downloads got fixed: + +previously, client_id was (stupidly) hardcoded. that means cobalt wasn't able to fetch song data if soundcloud web app got updated. +now, cobalt tries to find the up-to-date client_id, caches it in memory, and checks if web app version has changed to update the id accordingly. you can see this change for yourself on github. \ No newline at end of file diff --git a/web/changelogs/4.7.md b/web/changelogs/4.7.md new file mode 100644 index 00000000..b81c16e0 --- /dev/null +++ b/web/changelogs/4.7.md @@ -0,0 +1,38 @@ +--- +title: "we're better together! thank you for bug reports." +banner: + file: "bettertogether.webp" + alt: "various different pokémon jumping in happiness" +--- +this update includes a bunch of improvements, many of which were made thanks to the community :D + +service-related improvements: +- private soundcloud links are now supported (#68); +- tiktok usernames with dots in them no longer confuse cobalt (#71); +- .ogg files no longer wrongfully include a video channel (#67); +- fixed an issue that caused cobalt to freak out when user attempted to download an audio from audio-only service with "mute video" option enabled. + +ui improvements: +- popup padding has been evened out. popups are now able to fit in more information on scroll, especially on mobile; +- all buttons are now of even size and are displayed without any padding issues across all modern browsers and devices; +- checkbox is no longer crippled on ios; +- many explanation texts have been simplified to get rid of unnecessary bloat (no bullshit, remember?); +- moved tiktok section in video settings higher due to higher priority; +- fixed unexpectedly displayed scrollbars on switch rows in firefox. + +stability improvements: +- ffmpeg process now should end upon finishing the render; +- ffmpeg should also quit when download is abruptly cut off; +- fixed a memory leak that was caused by misconfigured stream information caching (#63). + +internal improvements: +- requested streams are now stored in cache for 2 minutes instead of 1000 hours (yes, 1000 hours, i fucked up); +- cached data is now reused if user requests same content within 2 minutes; +- page render module is now even cleaner than before; +- proper support for bullet-points in loc strings. + +you can suggest features or report bugs on github or twitter. both work just fine, use whichever you're more comfortable with. + +thank you for using cobalt, and thank you for reading this changelog. + +you're amazing, keep it up :) \ No newline at end of file diff --git a/web/changelogs/4.8.md b/web/changelogs/4.8.md new file mode 100644 index 00000000..60db3452 --- /dev/null +++ b/web/changelogs/4.8.md @@ -0,0 +1,30 @@ +--- +title: "prettier than ever" +banner: + file: "catmakeup.webp" + alt: "a cat being brushed with a powder makeup brush" +--- +this version brings many visual improvements and a completely revamped "about" tab. + +what's new in "about" tab: +- all information is now split into collapsible sections, making it easier to navigate. +- added privacy policy to further prove that none of your data is collected. +- added emoji to the page title to make it look consistent with other pages. +- added mastodon account handle and link. +- there are now short notes at the end of each section. +- other changes that are too small to describe. just go check it out! + +visual improvements: +- less wasted space: paddings and margins have been reduced and optimized for usability, consistency, and overall beauty. +- all links are now in italic. it's much easier to tell them apart from regular highlights. +- error popup no longer looks broken and out of place. +- download popup now has a proper close button, not something from 2.x era. +- emoji are no longer selectable or draggable. +- better scalability: desktop layout for home screen is shown if device viewport is wide enough to fit in three action buttons. +- page shouldn't look broken on phones in landscape mode (i still highly recommend using cobalt in portrait mode). +- removed bulletpoint padding. it was unnecessary. +- updated some service names. + +as always, you can suggest features or report bugs on any platform listed in the "support" section of about tab. + +thank you for using cobalt. i hope you have a good day :) \ No newline at end of file diff --git a/web/changelogs/5.0.md b/web/changelogs/5.0.md new file mode 100644 index 00000000..328fdbf0 --- /dev/null +++ b/web/changelogs/5.0.md @@ -0,0 +1,41 @@ +--- +title: "it's all about attention to detail!" +banner: + file: "valentines.webp" + alt: "relaxed meowth with sakura petals falling in front of them" +--- +happy valentine's day! i have an update for you, as a gift :D + +tl;dr: added support for reddit gifs, fixed douyin downloads, fixed vimeo quality picking, revamped entirety of codebase, and many other fixes. + +here's more info: + +this update is mostly about cleaning up and polishing the codebase, but it also has some new features. here's what's up: + +service-related improvements: +- you now can download gifs from reddit! +- attempting to download a video from douyin no longer throws an error (bytedance changed the api endpoint, yet again). +- fixed quality picking for vimeo downloads. +- fixed length limit check in vimeo module. +- fixed support for "user view" vk clips links. +- various twitter errors are now displayed correctly instead of falling back to the default error. +- state of all services is now tested on each commit. + +ui improvements: +- cobalt social links no longer disappear if you have an aggressive ad blocking extension installed. +- various localization improvements for both english and russian. +- changed some service aliases to display full list of supported downloads. +- added current branch information to version text (in settings). +- fixed typos in older changelogs. + +internal improvements: +- everything has been sanitized, improved, and refactored. code is now much easier to read and maintain. +- rewrote and/or optimized all modules that were messy or inefficient. +- all git interaction functions now store info in cache instead of fetching it every time the function is called. +- added a test script that checks functionality of all supported services. +- updated deepsource config. checks are more accurate now. +- requests from internet explorer are now dropped entirely instead of redirecting people stuck in 90s to a proper browser download page. this was done to avoid (my) personal bias towards browsers. + +i put a ton of effort into this version, and i hope you like it as much as i do. + +thank you for using cobalt. there's so much more to come :) \ No newline at end of file diff --git a/web/changelogs/5.1.md b/web/changelogs/5.1.md new file mode 100644 index 00000000..905c573d --- /dev/null +++ b/web/changelogs/5.1.md @@ -0,0 +1,45 @@ +--- +title: "the evil has been defeated" +banner: + file: "happymeowth.webp" + alt: "meowth jumping up into the sky very excitedly" +--- +hey, ever wanted to download a youtube video without a hassle? cobalt is here to help. this update fixes all issues related to youtube downloads. +not only that, but it also introduces features never before seen in a downloader, such as youtube dub downloads! read below to see what's up :) + +tl;dr: +- audio in youtube videos FINALLY no longer gets cut off. +- you now can pick any video resolution you want (from 360p to 8k) and any possible youtube video codec (h264/av1/vp9). +- you now can download youtube videos with dubs in your native language. just check settings > audio. +- youtube processing has been vastly sped up. + +ok, now onto the nerdy part of changelog. this update is pretty huge and includes improvements across the board. + +service improvements: +- all youtube functionality has been reworked. cobalt now relies on innertube apis, not web scraping. +- random audio cut off issue has been fixed, let me know if it ever occurs again. (closes #62, #66, #75, #88). +- added support for youtube dubs. currently it's using your browser's default language when enabled, but i have plans on making a picker. i'll ask people on twitter and mastodon if this feature is needed, and add a picker in next updates. +- instead of adding more quality presets, i added granular quality options. pick whatever you like, from 360p up to 4320p (for all services, not just youtube). +- replaced a format picker with codec picker for youtube. you can pick h264, av1, or vp9. all of them should work as expected (closes #88). +- youtube audio files are now properly matched to corresponding video files. +- it's now always possible to download pristine h264 720p/360p videos from youtube. these videos will work ANYWHERE, so they're default for mobile. +- youtube requests are no longer permanently cached, ram usage should drop even further. +- youtube video and audio file names now include codec and dub language when applicable. +- max video and audio duration limits have been bumped up to 3 hours. +- general performance of entire youtube download process has been greatly improved. +- vk module has been reworked to be more compact and not make use of outdated technique of quality picking. should also be way more reliable. + +internal improvements: +- cleaned up services config, all constants have been moved directly to modules for quicker access. +- matching module has been slightly cleaned up. + +interface improvements: +- many descriptions and error messages have been slightly tuned to be less wordy. +- unnecessary title duplications in settings have been merged into one. +- added more clarity to quality and codec descriptions. + +if you use cobalt api, please note that you have to update your creation to support new features. + +this is the second batch of 5.x improvements, there's way more to come. thank you for being here, i really appreciate your support. + +if you want to thank me (the developer), there's a nice tab under this changelog that has "donations" text on it. anything helps me continue developing and hosting the friendliest media downloader :D \ No newline at end of file diff --git a/web/changelogs/5.2.md b/web/changelogs/5.2.md new file mode 100644 index 00000000..e6e7c72b --- /dev/null +++ b/web/changelogs/5.2.md @@ -0,0 +1,52 @@ +--- +title: "fastest one in the game" +banner: + file: "catspeed.webp" + alt: "a cat running very fast in an exercise wheel" +--- +hey, notice anything different? well, at very least the page loaded way faster! this update includes many improvements and fixes, but also some new features. + +tl;dr: +- twitter retweet links are now supported. +- all vimeo videos should now be possible to download. +- you now can download audio from vimeo. +- it's now possible to pick between preferred vimeo download method in settings. +- fixed issues related to tiktok, twitter, twitter spaces, and vimeo downloads. +- overall cobalt performance should be MUCH better. + +service improvements: +- added support for twitter retweet links. now all kinds of tweet links are supported. +- fixed the issue related to periods in tiktok usernames (#96). +- fixed twitter spaces downloads. +- added support for audio downloads from vimeo. +- added ability to choose between "progressive" and "dash" vimeo downloads. go to settings > video to pick your preference. +- fixed the issue related to vimeo quality picking. +- fixed the issue when vimeo module wouldn't show appropriate errors and instead would fallback to default ones. +- improved audio only downloads for some edge cases. +- (hopefully) better youtube reliability. +- temporarily disabled douyin support due to api endpoint cut off. + +interface improvements: +- merged clipboard and mode switcher rows into one for mobile view. +- added left-handed layout toggle for those who prefer to have the clipboard button on left. +- new custom-made clipboard icon. now it clearly indicates what it does. +- improved english and russian localization. both are way more direct and less bloaty. +- frontend page is now rendered once and is cached on disk instead of being rendered every time someone requests a page. this greatly improves page loading speeds and further reduces strain put on the server. +- frontend page is now minimized just like js and css files. this should minimize traffic wasted on loading the page, along with minor loading speed improvement. +- added proper checkbox icon for better clarity. +- checkboxes are now stretched edge-to-edge on phone to be easier to manage for right-handed people. +- removed button hover highlights on phones. +- fixed button press animations for safari on ios. +- fixed text selection on ios. previously you could select text or images anywhere, but now they're selectable in limited places, just like on other platforms. +- frontend platform is now marked in settings: p is for pc; m is for mobile; i is for ios. this is done for possible future debugging and issue-solving. +- better error messaging. + +internal improvements: +- better rate limiting, there should be way less cases of accidental limits. +- added support for m3u8 playlists. this will be useful for future additions, and is currently used by vimeo module. +- added support for "chop" stream format for vimeo downloads. +- fixed vk user id extraction. i assumed the - in url was a separator, but it's actually a part of id. +- completely reworked the vimeo module. it's much cleaner and better performant now. +- minor clean ups across the board. + +not really related to this update, but thank you for 50k monthly users! i really appreciate that you're still here, because that means i'm doing some things right :D \ No newline at end of file diff --git a/web/changelogs/5.3.md b/web/changelogs/5.3.md new file mode 100644 index 00000000..3233f365 --- /dev/null +++ b/web/changelogs/5.3.md @@ -0,0 +1,20 @@ +--- +title: "better looks, better feel" +banner: + file: "cattired.webp" + alt: "a cat laying on a sofa face down, wiggling its tail" +--- +this update isn't as big as previous ones, but it still greatly enhances the cobalt experience. + +here's what's up: +- new mode switcher! elegant and 100% clear. should no longer cause any confusion. let me know if you like it better this way :D +- wide paste button on mobile is back, but now it's even closer to your finger. +- removed the weird grey chin on changelog banners. +- removed left-handed layout toggle since it is no longer needed. +- fixed input area display in chromium 112+. +- centered the main action box. +- cleaned up css of main action box to get rid of tricks and ensure correct display on all devices. +- fixed a bug that'd cause notifications dots to disappear when an unrelated checkbox was checked. + +hopefully from now on i'll focus on adding support for more services. +thank you for using cobalt. stay cool :) \ No newline at end of file diff --git a/web/changelogs/5.4.md b/web/changelogs/5.4.md new file mode 100644 index 00000000..ef405fc5 --- /dev/null +++ b/web/changelogs/5.4.md @@ -0,0 +1,34 @@ +--- +title: "instagram support, docker, and more!" +banner: + file: "catphonestand.webp" + alt: "a cat holding a phone under its chin while a person plays clash of clans on it" +--- +something many of you've been waiting for is finally here! try it out and let me know what you think :) + +tl;dr: +- added experimental instagram support! download any reels or videos you like, and make sure to report any issues you encounter. yes, you can convert either to audio. +- fixed support for on.soundcloud links. +- added share button to "how to save?" popup. +- added docker support. + +service improvements: +- added experimental support for videos from instagram. currently only reels and post videos are downloadable, but i'm looking into ways to save high resolution photos too. if you experience any issues, please report them on either of support platforms. +- fixed support for on.soundcloud share links. should work just as well as other versions! +- fixed an issue that made some youtube videos impossible to download. + +interface improvements: +- new css-only checkmark! yes, i can't stop tinkering with it because slight flashing on svg load annoyed me. now it loads instantly (and also looks slightly better). +- fixed copy animation. +- minor localization improvements. +- fixed the embed logo that i broke somewhere in between 5.3 and 5.4. + +internal improvements: +- now using nanoid for live render stream ids. +- added support for docker. it's kind of clumsy because of how i get .git folder inside the container, but if you know how to do it better, feel free to make a pr. +- cobalt now checks only for existence of environment variables, not exactly the .env file. +- changed the way user ip address is retrieved for instances using cloudflare. +- added ability to disable cors, both to setup script and environment variables. + +i can't believe how diverse and widespread cobalt has become. it's used in all fields: music production, education, content creation, and even game development. thank you. this is absolutely nuts. +if you don't mind sharing, please tell me about your use case. i'd really love to hear how you use cobalt and how i could make it even more useful for you. \ No newline at end of file diff --git a/web/changelogs/6.0.md b/web/changelogs/6.0.md new file mode 100644 index 00000000..109f4832 --- /dev/null +++ b/web/changelogs/6.0.md @@ -0,0 +1,68 @@ +--- +title: "better reliability, new infrastructure, pinterest support, and way more!" +date: "June 7, 2023" +banner: + file: "catswitchboxes.webp" + alt: "a cat climbing into two empty boxes of asahi beer" +--- +hey! long time no see, hopefully over 40 changes will make up for it :) + +cobalt now has an official community discord server. you can go there for news, support, or just to chat. go check it out! + +tl;dr +- new infra, new hosting structure, new main instance api url. developers, get it here. +- added support for pinterest, vine archive, tumblr audio, youtube vr videos. +- better web app performance and look. +- better stability thanks to load balancing. +- (hopefully) no more random video/audio download drops. + +service improvements: +- added support for pinterest videos and stories (pr by @Snazzah). +- added support for tumblr audio. sorry, tumblr. +- added support for youtube vr videos. please note that they're in youtube's proprietary ratio. +- added support for vine archive. +- added support for ancient vk videos in 240p. +- fixed an issue related to muted video downloads from tumblr. +- moved to twitter v2 api. +- soundcloud share links are now processed without errors. + +ui improvements: +- lazy image loading. should significantly speed up the page load. +- fixed checkbox width on mobile devices. +- addition of a temporary urgent notice. +- added hover border to all buttons. +- less annoying donation button highlight. +- more consistent color scheme. +- added link to a discord server into about popup. +- remember celebratory emoji changes? they've been fixed, and are now dynamically loaded! +- changelog history now lets you try to load it again if first attempt failed for whatever reason. +- padding (everywhere) has been slightly reduced to fit in more content and be consistent across ui. +- added more info to the "how to save" popup for ios devices. +- crypto wallet press-to-copy buttons now look like buttons. +- improved ui layout for smallest screens (iphone 5, 5s, se, etc). +- removed partial translations for sake of clarity and consistency. + +internal improvements: +- separated web and api servers. they're now completely independent and therefore more stress-resistant. +- added a dedicated script for building the web app if you don't want to reload the frontend server. +- web app building improvements. +- async localization preloading. +- consistent server start time reporting. +- dynamic stream and ip hashing salt generation. + +infrastructure improvements: +- load balancing: your api requests are now sent to the least busy server. yes, there are now several of them with more to come in the future. +- when possible, server in closest region is used instead of a far-away one. this should help with download speeds. +- currently there are multiple servers in europe. i will let you know when (and if) i manage to get an american one. + +updates for developers and instance hosters: +- server info api endpoint: you can now check up on the api server of choice. it reports all the basic info you may need. check the api docs for more info. +- api names: each and every api instance should have a distinctive name. this will be useful in the future :) +- added docker compose sample config. +- updated and more granular setup script. +- better api scalability and faster server start up thanks to web and api separation. +- added ability to specify ffmpeg threads. simply add ffmpegThreads to your environment variables! + +i'm still in awe from how popular cobalt has become. there are now over 200k of unique users monthly, and that number only keeps growing. i even had to come up with something to accommodate for larger traffic, it's absolutely insane. + +love you all, have a great day :D \ No newline at end of file diff --git a/web/changelogs/6.2.md b/web/changelogs/6.2.md new file mode 100644 index 00000000..012d06c6 --- /dev/null +++ b/web/changelogs/6.2.md @@ -0,0 +1,23 @@ +--- +title: "all network issues have been fixed!" +date: "June 27 2023" +banner: + file: "meowthhammer.webp" + alt: "meowth plush holding a hammer in real life" +--- +hey! there have been some hiccups in cobalt's stability lately, i was going through finals while trying to scale up the infrastructure, and that didn't really work out, lol. +BUT i'm happy to announce that i've optimized all nodes! there should no longer be any networking issues. + +enjoy stable experience while i work in background to make cobalt even better :) + +here's what's new in this update: +- better button contrast in both themes. +- button highlight in light theme now actually looks like a highlight. +- removed ip gate for streamables and updated privacy policy to reflect this change. +- streamable links now last for 20 seconds instead of 2 minutes. +- cleaned up stream verification algorithm. now the same function doesn't run 4 times in a row. +- removed deprecated way of hosting a cobalt instance. + +thank you for sticking with cobalt, and i hope you have a great day :D + +banner photo is by @halftroller on twitter, thank you so much! \ No newline at end of file diff --git a/web/changelogs/7.0.md b/web/changelogs/7.0.md new file mode 100644 index 00000000..594d4316 --- /dev/null +++ b/web/changelogs/7.0.md @@ -0,0 +1,83 @@ +--- +title: "biggest ui refresh yet!" +date: "August 15, 2023" +banner: + file: "meowthcooking.webp" + alt: "meowth handling orders in a restaurant" +--- +hey! this update is huge and mostly aimed to refresh the ui, but there are also some other nice fixes/additions. read below for more info :) + +tl;dr: +- entirety of web app has been refreshed. it's more prettier and optimized than ever, both on phone and desktop. +- if you're on ios, try adding cobalt to home screen! it'll look and act like a native app. +- all soundcloud links are now supported and audio quality is higher than before. +- all x (previously twitter) links are now supported and work properly. +- newer reddit videos are downloadable now. +- added some sort of eula, list of keyboard shortcuts, updated privacy policy for more clarity. check it all in refreshed about tab! +- cobalt now lets you know if your browser doesn't support clipboard pasting and helps you fix it. + +accessibility notice: +this update includes animations and transparency, if you'd like to disable any or all of them, head to settings > other > accessibility. + +[full changelog] + +service improvements: +- fixed unexpected 502 errors when downloading newer reddit videos. +- newer reddit videos (with audio) are downloadable now. +- upgraded soundcloud downloads to use higher audio quality than before. +- all soundcloud links are now supported. +- added support for x.com urls. +- changed twitter api once again. now everything works, again. + +web improvements: +- all-new matte glass aesthetic, applied to revamped popup headers, tab selectors, and also small popups. +- rounded corners everywhere! cobalt is now safe for everyone who can't handle sharp objects. +- paddings everywhere are smaller, more content fits on the screen at once. +- optimized installed web app to look and act like a native app, especially on ios. +- added update release dates to changelogs. +- cobalt now lets you know if your browser doesn't support clipboard api and helps you fix it. +- refreshed all popups: less padding, more content. +- completely remade error and download popups, they're consistent with the rest of refreshed design. +- refreshed the look of entire changelog tab: separated title and version/commit, made title bigger, evened out all paddings. +- replaced close button with back button, moved it to left. +- added interaction animations. +- added more keyboard shorcuts. +- added a list of keyboard shortcuts to about tab. +- added eula to about tab. check it out. +- added more accessibility options, put them all into one category. you can disable animations and transparency if you want to. +- added a link to self-troubleshooting guide to about tab. +- renamed 2160p and 4320p to 4k and 8k respectfully for better clarity. +- popups now work without any weird workarounds, especially on mobile. they're clean and nice. +- home screen now also works without any weird workarounds. it is also clean and nice. +- optimized css of almost all ui elements. should be even more consistent across platforms now. +- added ability to translate "cobalt" more in-depth localization. for example, in russian "cobalt" is now "кобальт", that's the style i'll be going with from now on. +- updated many localization strings for more clarity. +- removed ability to change the app name dynamically in all locations. cobalt is a sustained app name. +- updated donation and privacy policy texts for more clarity in both english and russian. +- home screen now smoothly fades in instead of popping in. +- proper banner loading. no more jumping text! +- proper banner error handling. if banner wasn't loaded, it'll simply go grey instead of disappearing. +- links are no longer italic and are instead underlined. +- collapsible lists now have corresponding emoji. +- donate button is now highlighted with magenta instead of white. +- proper dropdown arrow. +- removed 6.0 api fallback. +- fixed celebrations emoji. again. +- cleaned up all related frontend modules, especially page.js. +- urgent notice is now a js element, not a static piece of text. can be updated easily. + +api improvements: +- now catching all json api related errors. +- moved on demand blocks to web server, now changelog can be updated independently from preferred api server. +- now sending standard rate limiting headers. +- better readability in source. + +other improvements: +- renamed docker-compose.yml.example to docker-compose.example.yml for linting in code editors. +- added a wiki with wip troubleshooting guide on github. more guides are coming soon! + +that's a ton of changes! i really hope you like this update as much as i do. + +if you experience any issues, feel free to contact me on any platform listed in about tab! i'd love to hear back from you. + +thank you for sticking with me and cobalt, i hope you have THE best day :D \ No newline at end of file diff --git a/web/changelogs/7.1.md b/web/changelogs/7.1.md new file mode 100644 index 00000000..cf49d0b7 --- /dev/null +++ b/web/changelogs/7.1.md @@ -0,0 +1,28 @@ +--- +title: "instagram, streamable, video metadata, and more!" +date: "August 20, 2023" +banner: + file: "meowthproductions.webp" + alt: "meowth roaring in a fancy circle, à la MGM studios intro" +--- +service improvements: +- extended instagram support: high quality photos, videos, reels. everything should work without any issues, enjoy! :) +- added support for streamable.com (thanks to #179) +- added video metadata to youtube videos. +- fixed vk video downloads. +- vxtwitter links are now supported. +- fixed support for youtube audio dubs. + +ui improvements: +- fixed picker popup: it's now scrollable in all cases and clickable areas don't overlap each other. + +backend improvements: +- cobalt will now let you know if something goes wrong during video download instead of nuking the stream. +- added support for cookies (thanks to #177) +- replaced got with undici (thanks to #182). downloads should be slightly faster and clean of garbage in headers. + +internal improvements: +- moved host overrides into its own module. +- minor clean ups. + +even more cool stuff is coming in future updates! thank you for using cobalt :D \ No newline at end of file diff --git a/web/changelogs/7.11.md b/web/changelogs/7.11.md new file mode 100644 index 00000000..9de3b125 --- /dev/null +++ b/web/changelogs/7.11.md @@ -0,0 +1,45 @@ +--- +title: "cache encryption, meowbalt, dailymotion, bilibili, and much more!" +date: "March 6, 2024" +banner: + file: "meowth7eleven.webp" + alt: "meowth plush in front of 7-eleven store" +--- +cobalt may not have as many groceries as 7-eleven, but it sure does have lots of big changes in this update! + +- all cached stream info is now encrypted and can only be decrypted with a link you get from cobalt. +- new popup style featuring meowbalt, cobalt's speedy mascot. you will see him more often from now on! +- added support for dailymotion (including short links). +- added support for bilibili.tv, fixed support for bilibili.com, and added support for all related short links. +- added support for unlisted vimeo links. +- added support for tumblr audio and revamped the entire module. +- added support for embed ok.ru links. + +we also updated the privacy policy to reflect the addition of data encryption, go check it out. + +for people with iphones: +- clearer ios saving tutorial. +- added "save to files" ios shortcut. +- updated save to photos shortcut. + +make sure to save both shortcuts and read the updated tutorial! + +for people who host a cobalt instance: +- updated all environment variables TO_BE_LIKE_THIS. time to update your configs! for now cobalt is backwards compatible with old variable names, but it won't last forever. +- added a list of all environment variables and their descriptions to run-an-instance doc. +- updated cookie file example with more services and improved examples. +- updated docker compose example with better explanations and up-to-date env variable samples. +- updated some packages to get rid of all unnecessary messages in console. + +want to host an instance? learn how to do it here. + +frontend changes: +- removed migration popup. +- corners across ui are even more round now. +- bottom glass bkg in popups is no longer rounded on top right. +- small popup no longer stretches like gum, it's fixed in size on desktop. +- small popup animation no longer lags on mobile. +- better ui scaling across resolutions. +- updated donation text. + +thank you for using cobalt, all 750k of you. hope you like this update as much as we enjoyed making it :D \ No newline at end of file diff --git a/web/changelogs/7.13.md b/web/changelogs/7.13.md new file mode 100644 index 00000000..fa78c536 --- /dev/null +++ b/web/changelogs/7.13.md @@ -0,0 +1,59 @@ +--- +title: "better ux, improvements for youtube, twitter, tiktok, instagram, and more!" +date: "May 5, 2024" +banner: + file: "meowthbusinessman.webp" + alt: "photo of a businessman holding hands together (merkel-raute pose) with meowth plush head." +--- +long time no see! well, actually, you've been using the latest version for some time now. we've moved to a rolling release scheme, allowing for speedy update rollouts :) + +since 7.11, there has been a ton of changes. here are the most notable of them: +- youtube downloads are now faster and more reliable than ever. +- all posts from twitter are now downloadable, including sensitive ones. +- you now can download tiktok videos in 1080p h265! just enable h265 support in settings > video. +- added support for sharing links directly to the cobalt web app on android. +- added 240p and 144p quality options to the quality picker in settings (for some reason, many of you wanted this). +- pasting a link with additional text around it will now work; cobalt will extract the link for you (works only via the paste button). +- added anonymous traffic analytics by plausible. we're using a selfhosted instance and don't collect any identifiable information about you. you can learn more in about > privacy policy. you can also opt out of anonymous analytics in settings > other. + +service support improvements: +- implemented internal streams functionality, allowing for more fine-grained file streaming and therefore proper youtube support. +- added fallback to m4a if opus isn't available for youtube. +- added a total of 7 ways to get instagram post info, including mobile api, embed, and graphql api. absolute torture. +- added support for reddit user posts. +- updated the way tiktok downloads are handled for better reliability and 1080p support. +- added tiktok author's username to filename. +- added support for rutube shorts and yappy videos. +- added support for m.soundcloud.com links. +- added support for new post and reel links from instagram. +- added support for photo twitter links, only used for gifs. +- added support for m.bilibili.com links. +- added support for new type of vimeo links. +- added support for ddinstagram.com links. +- updated youtube codec info in settings to display the fact that av1 is a better choice now. +- updated best audio picking for tiktok and soundcloud. +- changed the youtube client to web, since android client no longer works. +- removed the vimeo download type switcher, as it should've always been automatic instead. +- removed an ability to enable the tiktok watermark, as it no longer includes the author's username. + +ui & ux improvements: +- youtube audio dub switcher is now a toggle with a much easier to understand description. +- meowbalt now sticks out on the left side of download popup on desktop. +- updated "made with love" text to include the research & dev team behind cobalt, imput. +- fixed grammar of russian localization. +- rounded corners are now correctly rendered across all browsers. +- various minor improvements, including smaller button padding. +- removed the notification (red dot) functionality as the most recent changelog is already always on screen. +- removed settings migration from the old domain. + +other changes: +- various docs updates in github repo, making sure they're functional across branches and forks. +- major codebase cleanup. + +thank you for using cobalt, and thank you for being one of our 900k friends! i hope you like this update as much as we liked making it. + +we're committed to keeping cobalt the best way to save what you love without ads or invasion of your privacy. there's a ton of cool stuff to come soon; stay tuned and have an amazing rest of your day &lt;3 + +if you want to help our goal of a better internet for everyone, just share cobalt with a friend! + +(original photo of a man in a suit by benzoix on freepik) \ No newline at end of file diff --git a/web/changelogs/7.14.md b/web/changelogs/7.14.md new file mode 100644 index 00000000..386f1d5c --- /dev/null +++ b/web/changelogs/7.14.md @@ -0,0 +1,43 @@ +--- +title: "now helping over 1 million people monthly" +date: "May 17, 2024" +banner: + file: "millionusers.webp" + alt: "collage of two photos, side by side. left photo: brown cake with 7 lit candles forming 1000000 and one ferrero rocher candy in the middle with cobalt (double greater than symbol) logo on it. right photo: chocolate cake with 7 lit candles forming 1000000 and cobalt logo formed with whipped cream on the cake. two plushes of meowth and pompompurin in party hats are seen behind the cake." +--- +yesterday, cobalt hit 1 million users around the world! it's an absolutely insane milestone for us and we're incredibly grateful to everyone saving and creating what they love with help of cobalt. thank you for being our friends. + +in anticipation of 7 figure user count, we've revamped the cobalt codebase and infrastructure to be faster and more reliable than ever. a combination of many changes has resulted into incredible download speeds (up to 30 MB/s, as tested by both developers in europe). + +note: there's no backend instance in asia just yet, so if you're there, you might experience average speeds *for now*. you can help us afford a dedicated server in asia by donating to cobalt in the "donate" menu. + +changes since the last major update + +service improvements: +- youtube music support on the main instance is back! +- added support for pinterest images and gifs. +- cobalt will now use original soundcloud mp3 file when available. +- fixed a youtube bug that prevented some videos from downloading. + +ui/ux improvements: +- cobalt web app is now fully optimized for ipad. you can add it to home screen from share menu to make it act like a native app! +- majorly reduced vertical padding when viewing cobalt in mobile web browser, allowing for more content at once. most noticeable on smaller screens. +- status bar color is now dynamic in the web browser on ios and web app on android. +- web app on android feels way more native than before. +- filename style icons are no longer blurry in safari. +- changelog notification no longer overlaps with dynamic island on newer iphones when cobalt is installed as a web app. +- fixed safe area padding. + +other changes: +- added support for freebind, made by one of the cobalt developers. +- rate limit and max video length limits are now customizable through environment variables. +- cobalt api now returns rate limit headers at all times. +- majorly cleaned up the codebase: removed unnecessary functions, rewrote those that were cryptic and confusing. it's way more comprehensible and contribution-friendly than ever before. +- moved the cobalt repo to our organization on github. everything stayed the same and all old links link back to it. + +note for instance hosters: +along with cobalt repo, the docker image also moved! please update the url for it in your config along with watchtower args to include restarting containers (just in case) as seen in updated docker compose example. we're mirroring packages to old url for now, but it won't last forever. + +that's it for now! hope you have an amazing day and share the 1 million celebration with us :) + +join our discord server to discuss everything cobalt there \ No newline at end of file diff --git a/web/changelogs/7.3.md b/web/changelogs/7.3.md new file mode 100644 index 00000000..d16e2898 --- /dev/null +++ b/web/changelogs/7.3.md @@ -0,0 +1,30 @@ +--- +title: "extended video length limit, metadata toggle, ui improvements, and more!" +date: "September 6, 2023" +banner: + file: "meowthsnap.webp" + alt: "cartoon meowth pointing paw dramatically and saying something" +--- +this update gives cobalt a sharp look in chromium browsers and makes it even more useful than before. check out the full changelog below! + +service improvements: +- increased video length limit from 3 hours to 5 hours. feel free to download lectures you need :) +- you can now disable file metadata in settings. +- fixed a bug which previously caused some downloads to end up being 0 bytes. + +ui improvements: +- fixed clickable area for urgent notice (text on top). +- fixed blurry header in chrome. +- fixed blurry tab bar in chrome. +- fixed blurry switches in chrome. +- fixed weirdly rounded corners in popups. +- fixed 1px gap on edges of various elements in popup in chrome. +- fixed overscrolling in other settings tab on ios. +- fixed unexpected button highlight effect on phones. +- removed outdated fixes for tiny screens. + +other improvements: +- cobalt web & api start faster than before, additional preparation functions aren't unexpectedly run anymore. +- cobalt is now available as a docker package. check it out on github. + +thank you for being here. i hope you have a great day :D \ No newline at end of file diff --git a/web/changelogs/7.4.md b/web/changelogs/7.4.md new file mode 100644 index 00000000..42d6a790 --- /dev/null +++ b/web/changelogs/7.4.md @@ -0,0 +1,45 @@ +--- +title: "new domain, what's coming in future, bug fixes, and more!" +date: "September 9, 2023" +banner: + file: "newdomain.webp" + alt: "text: new domain, same cobalt" +--- +cobalt is finally moving to its own domain! many of you have been anticipating this, and many kept forgetting the link due to how cryptic it was. + +well, worry no more - cobalt.tools is here. + +if you haven't yet, open co.wukko.me to transfer your settings here! no additional action from you is required. just open the old link and cobalt will do everything for you :) + +make sure to update your bookmarks and reinstall the web app! + +here's what domain change means: +- still no ads, same owner, same features, same reliability. just a way more rememberable link (it's literally two words). +- cobalt.tools makes it clear that cobalt is a tool and that it's "cobalt", not "wukko". +- i can host various versions of cobalt on subdomains without links looking awkward. +- i can host cobalt-related websites without polluting my personal domain's dns (such as crowdin). +- i stand by same privacy policies (and in fact am using the same exact server as before). + +the domain change is required for the future of cobalt. + +here's what's coming soon: +- support for many top-requested sites, such as (but not limited to) twitch and niconico. +- education version of cobalt, as often requested by students and educators. +- major localization system upgrade, allowing for simpler community contributions. +- region-specific versions with 100% translations and tweaks. +- native clients for desktop and mobile (not sure about this one, i'm no superman). +- ...and more! + +now, here's what's new in 7.4: +- tabs in popups now scroll to top on tab bar tap. +- padding across web app was tuned. +- (obviously) a migration agent. soon will be used for importing and exporting settings. +- some minor clean ups in codebase. + +if you want to help cobalt achieve goals listed above, consider donating! donations are the only way i can keep cobalt ad-less, powerful, (basically) limitless, and also 100% free. + +in fact, donations have helped me grow cobalt more than i've ever anticipated. just imagine how much better it will be in a year. + +go to donations down below to find ways to donate! + +thank you for reading through all of this. i hope you enjoy this update and have a great day :D \ No newline at end of file diff --git a/web/changelogs/7.5.md b/web/changelogs/7.5.md new file mode 100644 index 00000000..420beeb1 --- /dev/null +++ b/web/changelogs/7.5.md @@ -0,0 +1,28 @@ +--- +title: "support for twitch clips and rutube!" +date: "September 16, 2023" +banner: + file: "twitchupdate.webp" + alt: "meowth plush staring into the camera, laptop with generic purple service in the background" +--- +hey! this update (finally) adds support for twitch clips and rutube, among other smaller changes. + +service improvements: +- added support for twitch clips. no vods, they're unnecessary. just clip whatever you want to download! +- added support for rutube in case you ever wanted to download something russian. + +interface improvements: +- added a note about cobalt not being affiliated with any supported services. +- added a note about meta (the company) in russian. +- better russian localization. will keep improving it to make it sound not so robotic over time. + +other improvements: +- all official servers are now using the docker package. and so should you! +- moved the load balancer to poland. requests should be slightly faster now. +- minor codebase clean up. + +if you're confused about the new domain, read the older changelog! just scroll lower and press "expand". + +i hope you find this update useful and have a wonderful day :) + +btw, cobalt has a pretty active community server on discord. go to about > support & source code to join! \ No newline at end of file diff --git a/web/changelogs/7.6.md b/web/changelogs/7.6.md new file mode 100644 index 00000000..dd43d5b7 --- /dev/null +++ b/web/changelogs/7.6.md @@ -0,0 +1,33 @@ +--- +title: "customizable file names, instagram stories, and first cobalt sponsor!" +date: "October 15, 2023" +banner: + file: "meowthcenter.webp" + alt: "meowth plush in a datacenter wearing a hardhat, wielding a hammer" +--- +as many have (very) often requested, cobalt now lets you pick between several file name format styles! +go to settings > other and change it to whichever you like! there's a preview of each style, so you know how exactly files are gonna look like. + +if you liked file names the way they were before, don't worry: classic style is still the default :) + +on a different but not any less important note: cobalt is now sponsored by royalehosting.net! +overall service performance and stability is gonna be better, but also more content will be possible to download thanks to geniuine server locations. and yes, still no ads or trackers. + +this update also includes a bunch of other changes, check them out: + +service improvements: +- added support for instagram stories thanks to #194. +- fixed reddit support thanks to #221. +- added support for rich file names for youtube, vimeo, soundcloud, rutube, and vk. +- numbers and emoji no longer disappear from file name and metadata. +- mute and audio dub file name tags don't appear together anymore. +- youtube: dub file name tag doesn't appear anymore if audio track is default. + +interface improvements: +- added a list of sponsors to about tab. if you host an instance, it's disabled by default, but can be enabled with showSponsors env variable. +- about button now opens about tab when no new changelog is available. +- fixed download button thickness on ios. + +you now can reach out to cobalt via email for support! it's located in the about tab along with other socials, such as discord. + +i hope you enjoy this long-awaited update and have a blissful day :D \ No newline at end of file diff --git a/web/changelogs/7.7.md b/web/changelogs/7.7.md new file mode 100644 index 00000000..220d2a79 --- /dev/null +++ b/web/changelogs/7.7.md @@ -0,0 +1,30 @@ +--- +title: "bugfixes and better downloads!" +date: "December 2, 2023" +banner: + file: "meowthpolishegg.webp" + alt: "meowth polishing a togepi egg" +--- +this update fixes various issues with supported services. no new features yet, but twitter fix is surely something good to have in the meantime! + +service improvements: +- broken twitter videos are now automatically fixed by cobalt. +- all vimeo videos and audios should now be possible to download. +- vimeo: fixed short resolution displayed in "basic" and "pretty" filename styles. + +interface improvements: +- streamables are now easier to save on ios. + +internal improvements: +- port env variable is now not strictly necessary for cobalt to run. +- minor clean up. + +changes since 7.6: +- fix for an issue related to youtube dubs. +- fixed a memory leak related to live renders. +- handling all errors related to twitter downloads. +- fixed support for reddit links in various languages. +- added rich filenames support for twitch clips. +- updated support and donation lists. + +stay tuned for future updates and have a great day :D \ No newline at end of file diff --git a/web/changelogs/7.8.md b/web/changelogs/7.8.md new file mode 100644 index 00000000..e82a9786 --- /dev/null +++ b/web/changelogs/7.8.md @@ -0,0 +1,35 @@ +--- +title: "new years clean up! bug fixes and fresh look for the home page" +date: "December 25, 2023" +banner: + file: "catroomba.webp" + alt: "a cat riding a roomba vacuum" +--- +merry christmas and happy new year! this update fixes several (very annoying) bugs to help you enjoy your holidays better. + +you might have already noticed, but we've refreshed the home page on desktop and mobile! less space wasted, more pleasant to look at. let us know if you like it or not :D + +service improvements: +- #264 anything that includes a period in the url should be possible to download (including instagram stories). +- #73 soundcloud: falling back to mp3 instead of refusing to download the song at all. +- #275 youtube: query parameters are parsed and handled correctly, all links should be supported, no matter where v query is located. +- tlds are parsed and validated correctly (e.g. "pinterest.co.uk" works now). +- fixvx.com links are now supported. + +interface improvements: +- cleaner and more consistent home page layout. +- cleaned up support section in "about". also includes a link to the status page. + +internal improvements: +- urls, subdomains, and tlds are properly validated. +- minor clean up. + +changes since 7.7: +- made terms and ethics more descriptive. +- fix only affected twitter videos. +- fixed quick ⌘+V pasting on mac. +- now catching even more youtube-related errors. + +this might not seem like a lot, but even smaller changes make a difference! + +enjoy this update and the rest of your day :D \ No newline at end of file diff --git a/web/changelogs/7.9.md b/web/changelogs/7.9.md new file mode 100644 index 00000000..12af9592 --- /dev/null +++ b/web/changelogs/7.9.md @@ -0,0 +1,33 @@ +--- +title: "twitter gifs, pinterest, ok.ru, and more!" +date: "January 17, 2024" +banner: + file: "meowthball.webp" + alt: "meowth rolling on a big catnip ball" +--- +yes, you read that right. cobalt now lets you convert any twitter gif to an actual .gif file! (finally) +just go to settings and enable this feature :) + +service improvements: +- added an option to convert gifs from twitter into actual .gif format. files will be bigger and lower quality, but maybe you want that. +- pinterest support has been completely redone, now all videos (and even pin.it links) are supported. +- added support for ok.ru in case you're a russian grandma. +- now processing all reddit links (including old.reddit.com). +- instagram live vods are now supported. +- fixed a rare vimeo bug related to 1440p videos. + +other improvements: +- ui fade in animation is no longer present if you've disabled animations. +- all images now have alt descriptions. +- cobalt html is now biblically correct and follows the html spec. +- lots of cleaning up. + +patches since 7.8: +- shift+key shortcuts are now ignored if url bar is focused. +- longer soundcloud links are now supported, also catching more tiktok-related errors. +- removed mastodon from support links as that account is no longer active. +- added ability to download a specific video from multi media tweets and support for /mediaViewer links. +- fixed modal blurriness in chromium. +- minor html changes (road to biblically correct one). + +lots of long-awaited updates (especially twitter gifs), hope you enjoy them and have a great day :D \ No newline at end of file From 3aa17733d1bb3fc9b204dd6b7fbd922b75db5422 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 29 Jun 2024 17:58:00 +0000 Subject: [PATCH 192/334] frontend: install and configure mdsvex --- web/package-lock.json | 619 +++++------------------------------------- web/package.json | 2 + web/src/app.d.ts | 11 + web/svelte.config.js | 16 +- 4 files changed, 98 insertions(+), 550 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index e5760755..93f9664f 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -22,7 +22,9 @@ "@sveltejs/vite-plugin-svelte": "^3.0.0", "@types/eslint__js": "^8.42.3", "@types/node": "^20.14.10", + "compare-versions": "^6.1.0", "eslint": "^8.57.0", + "mdsvex": "^0.11.2", "svelte": "^4.2.7", "svelte-check": "^3.6.0", "tslib": "^2.4.1", @@ -47,262 +49,6 @@ "node": ">=6.0.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/linux-x64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", @@ -319,102 +65,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -607,149 +257,6 @@ "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", "dev": true }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", - "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", - "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", - "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", - "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", - "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", - "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", - "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", - "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", - "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", - "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", - "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.18.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", @@ -776,45 +283,6 @@ "linux" ] }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", - "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", - "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", - "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@sveltejs/adapter-static": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.2.tgz", @@ -989,6 +457,12 @@ "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", "dev": true }, + "node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.13.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", @@ -1456,6 +930,12 @@ "dev": true, "license": "MIT" }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1957,20 +1437,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -2314,6 +1780,21 @@ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" }, + "node_modules/mdsvex": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.11.2.tgz", + "integrity": "sha512-Y4ab+vLvTJS88196Scb/RFNaHMHVSWw6CwfsgWIQP8f42D57iDII0/qABSu530V4pkv8s6T2nx3ds0MC1VwFLA==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.3", + "prism-svelte": "^0.4.7", + "prismjs": "^1.17.1", + "vfile-message": "^2.0.4" + }, + "peerDependencies": { + "svelte": "^3.56.0 || ^4.0.0 || ^5.0.0-next.120" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2612,6 +2093,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prism-svelte": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz", + "integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==", + "dev": true + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3183,6 +2679,19 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3193,6 +2702,20 @@ "punycode": "^2.1.0" } }, + "node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { "version": "5.2.13", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz", diff --git a/web/package.json b/web/package.json index 4512cc02..a787d10c 100644 --- a/web/package.json +++ b/web/package.json @@ -30,7 +30,9 @@ "@sveltejs/vite-plugin-svelte": "^3.0.0", "@types/eslint__js": "^8.42.3", "@types/node": "^20.14.10", + "compare-versions": "^6.1.0", "eslint": "^8.57.0", + "mdsvex": "^0.11.2", "svelte": "^4.2.7", "svelte-check": "^3.6.0", "tslib": "^2.4.1", diff --git a/web/src/app.d.ts b/web/src/app.d.ts index c7c0ed1d..b30667de 100644 --- a/web/src/app.d.ts +++ b/web/src/app.d.ts @@ -1,3 +1,14 @@ +// needed so that changelog files are appropriately +// typed as svelte components +declare module '*.md' { + import type { SvelteComponentDev } from 'svelte/internal'; + + export default class Comp extends SvelteComponentDev { + $$prop_def: {}; + } + export const metadata: Record; +} + // See https://kit.svelte.dev/docs/types#app // for information about these interfaces declare global { diff --git a/web/svelte.config.js b/web/svelte.config.js index b4751daa..821da9bb 100644 --- a/web/svelte.config.js +++ b/web/svelte.config.js @@ -1,12 +1,24 @@ import adapter from '@sveltejs/adapter-static'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; +import { mdsvex } from 'mdsvex'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://kit.svelte.dev/docs/integrations#preprocessors // for more information about preprocessors - preprocess: vitePreprocess(), - + extensions: [".svelte", ".md"], + preprocess: [ + vitePreprocess(), + mdsvex({ + extensions: ['.md'], + layout: join( + dirname(fileURLToPath(import.meta.url)), + '/src/components/misc/ChangelogEntryWrapper.svelte' + ) + }) + ], kit: { adapter: adapter({ // default options are shown. On some platforms From 766482c21a42299557519068790990a6d0d47f33 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 29 Jun 2024 18:23:56 +0000 Subject: [PATCH 193/334] frontend: setup initial updates page --- web/src/components/misc/ChangelogEntry.svelte | 36 ++++++++++++ .../misc/ChangelogEntryWrapper.svelte | 11 ++++ web/src/lib/changelogs.ts | 22 +++++++ web/src/lib/types/changelogs.ts | 19 ++++++ web/src/routes/updates/+page.svelte | 58 +++++++++++++++++-- 5 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 web/src/components/misc/ChangelogEntry.svelte create mode 100644 web/src/components/misc/ChangelogEntryWrapper.svelte create mode 100644 web/src/lib/changelogs.ts create mode 100644 web/src/lib/types/changelogs.ts diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/misc/ChangelogEntry.svelte new file mode 100644 index 00000000..1b278498 --- /dev/null +++ b/web/src/components/misc/ChangelogEntry.svelte @@ -0,0 +1,36 @@ + + +
+

{ version }: { title }

+

{ date }

+ {#if banner} + {banner.alt} + {/if} +
+ +
+
\ No newline at end of file diff --git a/web/src/components/misc/ChangelogEntryWrapper.svelte b/web/src/components/misc/ChangelogEntryWrapper.svelte new file mode 100644 index 00000000..3821fa42 --- /dev/null +++ b/web/src/components/misc/ChangelogEntryWrapper.svelte @@ -0,0 +1,11 @@ + + + + + diff --git a/web/src/lib/changelogs.ts b/web/src/lib/changelogs.ts new file mode 100644 index 00000000..78e7df75 --- /dev/null +++ b/web/src/lib/changelogs.ts @@ -0,0 +1,22 @@ +import { compareVersions } from 'compare-versions'; + +export function getVersionFromPath(path: string) { + return path.split('/').pop()?.split('.md').shift()!; +} + +export function getAllChangelogs() { + const changelogImports = import.meta.glob("/changelogs/*.md"); + + const sortedVersions = Object.keys(changelogImports) + .map(path => [path, getVersionFromPath(path)]) + .sort(([, a], [, b]) => compareVersions(a, b)); + + const sortedChangelogs = sortedVersions.reduce( + (obj, [path, version]) => ({ + [version]: changelogImports[path], + ...obj + }), {} as typeof changelogImports + ); + + return sortedChangelogs; +} diff --git a/web/src/lib/types/changelogs.ts b/web/src/lib/types/changelogs.ts new file mode 100644 index 00000000..3dd41afc --- /dev/null +++ b/web/src/lib/types/changelogs.ts @@ -0,0 +1,19 @@ +import type { SvelteComponent } from "svelte" + +export interface ChangelogMetadata { + title: string, + date?: string + banner?: { + file: string, + alt: string + } +}; + +export interface MarkdownMetadata { + metadata: ChangelogMetadata +}; + +export type ChangelogImport = { + default: SvelteComponent, + metadata: ChangelogMetadata +} | undefined; diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index dc9670fa..4809d0fa 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -1,13 +1,61 @@ - + + - {$t("general.cobalt")}: {$t("tabs.donate")} + {$t("general.cobalt")}: {$t("tabs.updates")} - +
+ {#if changelog} + + {/if} + {#if versions[currentIndex + 1]} + + {/if} +
\ No newline at end of file From a22b0e51361fa430fdd8ac181947f582834a1875 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Tue, 16 Jul 2024 17:19:17 +0000 Subject: [PATCH 194/334] web/ChangelogEntry: initial css --- web/src/components/misc/ChangelogEntry.svelte | 71 ++++++++++++++++--- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/misc/ChangelogEntry.svelte index 1b278498..7991e304 100644 --- a/web/src/components/misc/ChangelogEntry.svelte +++ b/web/src/components/misc/ChangelogEntry.svelte @@ -5,11 +5,15 @@ export let banner: { file: string, alt: string } | undefined; -
-

{ version }: { title }

-

{ date }

- {#if banner} - {banner.alt} - {/if} -
- +
+

+
{ version }
+
{ title }
+

+ { date } +
+ {#if banner} + {banner.alt} + {/if} +
+ +
-
\ No newline at end of file + From 3305bba28a4c218594997d5879ddbf5e3c9ff56b Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Tue, 16 Jul 2024 17:21:53 +0000 Subject: [PATCH 195/334] web/updates: update hash on navigation, navigate if present on load --- web/src/routes/updates/+page.svelte | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 4809d0fa..79e70b5d 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -1,7 +1,8 @@ @@ -63,9 +114,40 @@
{#if changelog} - - {/if} - {#if versions[currentIndex + 1]} - +
+ +
+
+ +
+ + +
+
+
+ +
{/if}
\ No newline at end of file From 5c07afe4ff869875252a1481291ab705b838537a Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Tue, 16 Jul 2024 17:27:43 +0000 Subject: [PATCH 197/334] web/updates: keyboard navigation --- web/src/routes/updates/+page.svelte | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index d2dd5496..98125a9b 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -52,6 +52,11 @@ changelogs[next]().catch(() => {}); } + const handleKeydown = (e: KeyboardEvent) => { + if (e.key === 'ArrowLeft') loadPrev(); + else if (e.key === 'ArrowRight') loadNext(); + } + $: prev = versions[currentIndex - 1]; $: next = versions[currentIndex + 1]; $: currentIndex, loadChangelog(); @@ -112,6 +117,8 @@ + +
{#if changelog}
@@ -150,4 +157,4 @@
{/if} -
\ No newline at end of file +
From e6ec8c673400697e8c5f8041b5641daa20b4ce5d Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 17 Jul 2024 13:14:56 +0600 Subject: [PATCH 198/334] web/package: fix the svelte icons version & update lock --- web/package-lock.json | 1163 +++++++++++++++++++++++++++++++++-------- web/package.json | 2 +- 2 files changed, 941 insertions(+), 224 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 93f9664f..476e94e0 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", - "@tabler/icons-svelte": "^3.6.0", + "@tabler/icons-svelte": "3.6.0", "sveltekit-i18n": "^2.4.2", "ts-deepmerge": "^7.0.0" }, @@ -41,6 +41,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -49,14 +50,151 @@ "node": ">=6.0.0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -65,6 +203,244 @@ "node": ">=12" } }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -82,9 +458,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, "license": "MIT", "engines": { @@ -116,9 +492,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.5.0.tgz", - "integrity": "sha512-A7+AOT2ICkodvtsWnxZP4Xxk3NbZ3VMHd8oihydLRGrJgqqdEz1qSeEgXYyT/Cu8h1TWWsQRejIx48mtjZ5y1w==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz", + "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==", "dev": true, "license": "MIT", "engines": { @@ -128,12 +504,14 @@ "node_modules/@fontsource-variable/noto-sans-mono": { "version": "5.0.20", "resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-mono/-/noto-sans-mono-5.0.20.tgz", - "integrity": "sha512-Mik/wbKjiir7t+KBaDZnPZ5GjDnPOXpMF7obmFeyRa528ZsrKcFiSn4ZvArrn3sJMCp/k23wakOcXOWlGNc9cw==" + "integrity": "sha512-Mik/wbKjiir7t+KBaDZnPZ5GjDnPOXpMF7obmFeyRa528ZsrKcFiSn4ZvArrn3sJMCp/k23wakOcXOWlGNc9cw==", + "license": "OFL-1.1" }, "node_modules/@fontsource/ibm-plex-mono": { "version": "5.0.13", "resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz", - "integrity": "sha512-gtlMmvk//2AgDEZDFsoL5z9mgW3ZZg/9SC7pIfDwNKp5DtZpApgqd1Fua3HhPwYRIHrT76IQ1tMTzQKLEGtJGQ==" + "integrity": "sha512-gtlMmvk//2AgDEZDFsoL5z9mgW3ZZg/9SC7pIfDwNKp5DtZpApgqd1Fua3HhPwYRIHrT76IQ1tMTzQKLEGtJGQ==", + "license": "OFL-1.1" }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", @@ -177,6 +555,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -190,6 +569,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -198,19 +578,22 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -221,6 +604,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -234,6 +618,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -243,6 +628,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -255,34 +641,233 @@ "version": "1.0.0-next.25", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", - "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", + "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz", + "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz", + "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz", + "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz", + "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz", + "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz", + "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz", + "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz", + "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz", + "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz", + "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", + "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", - "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz", + "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz", + "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz", + "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz", + "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sveltejs/adapter-static": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.2.tgz", @@ -294,11 +879,12 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.5.10", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.10.tgz", - "integrity": "sha512-OqoyTmFG2cYmCFAdBfW+Qxbg8m23H4dv6KqwEt7ofr/ROcfcIl3Z/VT56L22H9f0uNZyr+9Bs1eh2gedOCK9kA==", + "version": "2.5.18", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.18.tgz", + "integrity": "sha512-+g06hvpVAnH7b4CDjhnTDgFWBKBiQJpuSmQeGYOuzbO3SC3tdYjRNlDCrafvDtKbGiT2uxY5Dn9qdEUGVZdWOQ==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^0.6.0", @@ -330,6 +916,7 @@ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.1.tgz", "integrity": "sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==", "dev": true, + "license": "MIT", "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", "debug": "^4.3.4", @@ -352,6 +939,7 @@ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -383,6 +971,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.6.0.tgz", "integrity": "sha512-Zv0Ofc64RCMpZ2F8CvsWAphrSjerx5hEErt/RMmE+W8r4E5l5Lizi+My9KbbZQ4NyAtrtrOX80OY1oROZrRzEA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/codecalm" @@ -392,6 +981,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/@tabler/icons-svelte/-/icons-svelte-3.6.0.tgz", "integrity": "sha512-phI61t81MlWhodATjvQQdqw8vTL0srSW6GsHzJmuhIMJGB4rwFzAXB2Ec4Pkz0vWFzVQgkeSE/AsiOLIUKWkxA==", + "license": "MIT", "dependencies": { "@tabler/icons": "3.6.0" }, @@ -407,7 +997,8 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/eslint": { "version": "8.56.10", @@ -433,7 +1024,8 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", @@ -443,10 +1035,11 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", "dev": true, + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } @@ -455,26 +1048,28 @@ "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/unist": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", - "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/type-utils": "7.13.1", - "@typescript-eslint/utils": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -498,16 +1093,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", - "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", + "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4" }, "engines": { @@ -527,14 +1122,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", - "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -545,14 +1140,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", - "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/utils": "7.13.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -573,9 +1168,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", - "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", "dev": true, "license": "MIT", "engines": { @@ -587,14 +1182,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", - "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -626,9 +1221,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -642,16 +1237,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", - "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1" + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -665,13 +1260,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", - "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/types": "7.16.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -690,9 +1285,10 @@ "license": "ISC" }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -758,6 +1354,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -777,6 +1374,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "license": "Apache-2.0", "dependencies": { "dequal": "^2.0.3" } @@ -792,24 +1390,27 @@ } }, "node_modules/axobject-query": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", - "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", - "dependencies": { - "dequal": "^2.0.3" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -822,6 +1423,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -832,6 +1434,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -844,6 +1447,7 @@ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -853,6 +1457,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -879,6 +1484,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -898,10 +1504,24 @@ "fsevents": "~2.3.2" } }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/code-red": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "@types/estree": "^1.0.1", @@ -934,19 +1554,22 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -970,6 +1593,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "license": "MIT", "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -983,6 +1607,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -1007,6 +1632,7 @@ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1015,6 +1641,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -1024,6 +1651,7 @@ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1032,7 +1660,8 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.0.0.tgz", "integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/dir-glob": { "version": "3.0.1", @@ -1064,14 +1693,16 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -1079,29 +1710,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/escape-string-regexp": { @@ -1213,24 +1844,12 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/esm-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/espree": { "version": "9.6.1", @@ -1251,9 +1870,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -1290,6 +1909,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } @@ -1316,6 +1936,7 @@ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -1327,6 +1948,19 @@ "node": ">=8.6.0" } }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -1346,6 +1980,7 @@ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -1368,6 +2003,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1407,23 +2043,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", @@ -1435,7 +2054,23 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } }, "node_modules/glob": { "version": "7.2.3", @@ -1443,6 +2078,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1459,15 +2095,16 @@ } }, "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" } }, "node_modules/globals": { @@ -1490,7 +2127,8 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/globby": { "version": "11.1.0", @@ -1517,13 +2155,15 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", @@ -1557,6 +2197,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -1573,6 +2214,7 @@ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -1594,6 +2236,7 @@ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1603,13 +2246,15 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -1622,6 +2267,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1631,6 +2277,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -1643,6 +2290,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -1661,6 +2309,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "license": "MIT", "dependencies": { "@types/estree": "*" } @@ -1721,6 +2370,7 @@ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1742,7 +2392,8 @@ "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "license": "MIT" }, "node_modules/locate-path": { "version": "6.0.0", @@ -1771,6 +2422,7 @@ "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } @@ -1778,13 +2430,15 @@ "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "license": "CC0-1.0" }, "node_modules/mdsvex": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.11.2.tgz", "integrity": "sha512-Y4ab+vLvTJS88196Scb/RFNaHMHVSWw6CwfsgWIQP8f42D57iDII0/qABSu530V4pkv8s6T2nx3ds0MC1VwFLA==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^2.0.3", "prism-svelte": "^0.4.7", @@ -1800,6 +2454,7 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -1809,6 +2464,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -1822,6 +2478,7 @@ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -1831,6 +2488,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1843,6 +2501,7 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1852,6 +2511,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -1864,6 +2524,7 @@ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -1873,6 +2534,7 @@ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -1881,7 +2543,8 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.7", @@ -1894,6 +2557,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1913,6 +2577,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1922,6 +2587,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -1981,6 +2647,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -2003,6 +2670,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2031,6 +2699,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^3.0.0", @@ -2041,13 +2710,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -2056,9 +2727,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "dev": true, "funding": [ { @@ -2074,9 +2745,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -2097,13 +2769,15 @@ "version": "0.4.7", "resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz", "integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/prismjs": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2136,13 +2810,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -2155,6 +2831,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -2164,29 +2841,35 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rollup": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", - "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", + "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "1.0.5" }, @@ -2198,22 +2881,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.0", - "@rollup/rollup-android-arm64": "4.18.0", - "@rollup/rollup-darwin-arm64": "4.18.0", - "@rollup/rollup-darwin-x64": "4.18.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", - "@rollup/rollup-linux-arm-musleabihf": "4.18.0", - "@rollup/rollup-linux-arm64-gnu": "4.18.0", - "@rollup/rollup-linux-arm64-musl": "4.18.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", - "@rollup/rollup-linux-riscv64-gnu": "4.18.0", - "@rollup/rollup-linux-s390x-gnu": "4.18.0", - "@rollup/rollup-linux-x64-gnu": "4.18.0", - "@rollup/rollup-linux-x64-musl": "4.18.0", - "@rollup/rollup-win32-arm64-msvc": "4.18.0", - "@rollup/rollup-win32-ia32-msvc": "4.18.0", - "@rollup/rollup-win32-x64-msvc": "4.18.0", + "@rollup/rollup-android-arm-eabi": "4.18.1", + "@rollup/rollup-android-arm64": "4.18.1", + "@rollup/rollup-darwin-arm64": "4.18.1", + "@rollup/rollup-darwin-x64": "4.18.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.1", + "@rollup/rollup-linux-arm-musleabihf": "4.18.1", + "@rollup/rollup-linux-arm64-gnu": "4.18.1", + "@rollup/rollup-linux-arm64-musl": "4.18.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1", + "@rollup/rollup-linux-riscv64-gnu": "4.18.1", + "@rollup/rollup-linux-s390x-gnu": "4.18.1", + "@rollup/rollup-linux-x64-gnu": "4.18.1", + "@rollup/rollup-linux-x64-musl": "4.18.1", + "@rollup/rollup-win32-arm64-msvc": "4.18.1", + "@rollup/rollup-win32-ia32-msvc": "4.18.1", + "@rollup/rollup-win32-x64-msvc": "4.18.1", "fsevents": "~2.3.2" } }, @@ -2236,6 +2919,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -2245,6 +2929,7 @@ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", "dev": true, + "license": "MIT", "dependencies": { "mri": "^1.1.0" }, @@ -2257,6 +2942,7 @@ "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", "dev": true, + "license": "MIT", "dependencies": { "es6-promise": "^3.1.2", "graceful-fs": "^4.1.3", @@ -2264,10 +2950,24 @@ "rimraf": "^2.5.2" } }, + "node_modules/sander/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -2281,7 +2981,8 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/shebang-command": { "version": "2.0.0", @@ -2311,6 +3012,7 @@ "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", "dev": true, + "license": "MIT", "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", @@ -2335,6 +3037,7 @@ "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.1.tgz", "integrity": "sha512-o7npfeJE6wi6J9l0/5LKshFzZ2rMatRiCDwYeDQaOzqdzRJwALhX7mk/A/ecg6wjMu7wdZbmXfD2S/vpOg0bdQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.14", "buffer-crc32": "^1.0.0", @@ -2349,6 +3052,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -2371,6 +3075,7 @@ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, + "license": "MIT", "dependencies": { "min-indent": "^1.0.0" }, @@ -2408,6 +3113,7 @@ "version": "4.2.18", "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", @@ -2429,15 +3135,14 @@ } }, "node_modules/svelte-check": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.0.tgz", - "integrity": "sha512-7Nxn+3X97oIvMzYJ7t27w00qUf1Y52irE2RU2dQAd5PyvfGp4E7NLhFKVhb6PV2fx7dCRMpNKDIuazmGthjpSQ==", + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.4.tgz", + "integrity": "sha512-61aHMkdinWyH8BkkTX9jPLYxYzaAAz/FK/VQqdr2FiCQQ/q04WCwDlpGbHff1GdrMYTmW8chlTFvRWL9k0A8vg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "chokidar": "^3.4.1", - "fast-glob": "^3.2.7", - "import-fresh": "^3.2.1", "picocolors": "^1.0.0", "sade": "^1.7.4", "svelte-preprocess": "^5.1.3", @@ -2455,6 +3160,7 @@ "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", "dev": true, + "license": "ISC", "engines": { "node": "^12.20 || ^14.13.1 || >= 16" }, @@ -2468,6 +3174,7 @@ "integrity": "sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "@types/pug": "^2.0.6", "detect-indent": "^6.1.0", @@ -2552,6 +3259,7 @@ "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", "dev": true, + "license": "MIT", "dependencies": { "globalyzer": "0.1.0", "globrex": "^0.1.2" @@ -2562,6 +3270,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -2574,6 +3283,7 @@ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2592,9 +3302,9 @@ } }, "node_modules/ts-deepmerge": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-7.0.0.tgz", - "integrity": "sha512-WZ/iAJrKDhdINv1WG6KZIGHrZDar6VfhftG1QJFpVbOYZMYJLJOvZOo1amictRXVdBXZIgBHKswMTXzElngprA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-7.0.1.tgz", + "integrity": "sha512-JBFCmNenZdUCc+TRNCtXVM6N8y/nDQHAcpj5BlwXG/gnogjam1NunulB9ia68mnqYI446giMfpqeBFFkOleh+g==", "license": "ISC", "engines": { "node": ">=14.13.1" @@ -2604,7 +3314,8 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", @@ -2633,9 +3344,9 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2647,15 +3358,15 @@ } }, "node_modules/typescript-eslint": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.1.tgz", - "integrity": "sha512-pvLEuRs8iS9s3Cnp/Wt//hpK8nKc8hVa3cLljHqzaJJQYP8oys8GUyIFqtlev+2lT/fqMPcyQko+HJ6iYK3nFA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.16.1.tgz", + "integrity": "sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "7.13.1", - "@typescript-eslint/parser": "7.13.1", - "@typescript-eslint/utils": "7.13.1" + "@typescript-eslint/eslint-plugin": "7.16.1", + "@typescript-eslint/parser": "7.16.1", + "@typescript-eslint/utils": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2677,13 +3388,15 @@ "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/unist-util-stringify-position": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^2.0.2" }, @@ -2707,6 +3420,7 @@ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" @@ -2717,13 +3431,14 @@ } }, "node_modules/vite": { - "version": "5.2.13", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz", - "integrity": "sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", + "esbuild": "^0.21.3", + "postcss": "^8.4.39", "rollup": "^4.13.0" }, "bin": { @@ -2776,6 +3491,7 @@ "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", "dev": true, + "license": "MIT", "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" }, @@ -2815,7 +3531,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yocto-queue": { "version": "0.1.0", diff --git a/web/package.json b/web/package.json index a787d10c..30e9f0e3 100644 --- a/web/package.json +++ b/web/package.json @@ -43,7 +43,7 @@ "dependencies": { "@fontsource-variable/noto-sans-mono": "^5.0.20", "@fontsource/ibm-plex-mono": "^5.0.13", - "@tabler/icons-svelte": "^3.6.0", + "@tabler/icons-svelte": "3.6.0", "sveltekit-i18n": "^2.4.2", "ts-deepmerge": "^7.0.0" } From 8eee02489914a549b02723d3af160c1ca872a745 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Wed, 17 Jul 2024 07:30:22 +0000 Subject: [PATCH 199/334] web/updates: don't prevent default action for keyboard inputs --- web/src/routes/updates/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 98125a9b..5cbaf12f 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -117,7 +117,7 @@ - +
{#if changelog} From 1ec9d92eb2123b33e153a86962521d336e182a0d Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 17 Jul 2024 13:32:07 +0600 Subject: [PATCH 200/334] web/updates: clean up components --- web/src/components/misc/ChangelogEntry.svelte | 41 ++++---- .../misc/ChangelogEntryWrapper.svelte | 1 + web/src/routes/updates/+page.svelte | 96 +++++++++---------- 3 files changed, 70 insertions(+), 68 deletions(-) diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/misc/ChangelogEntry.svelte index 7991e304..902aa7ef 100644 --- a/web/src/components/misc/ChangelogEntry.svelte +++ b/web/src/components/misc/ChangelogEntry.svelte @@ -4,6 +4,27 @@ export let date: string; export let banner: { file: string, alt: string } | undefined; + +
+

+
{ version }
+
{ title }
+

+ { date } +
+ {#if banner} + {banner.alt} + {/if} +
+ +
+
+
+ -
-

-
{ version }
-
{ title }
-

- { date } -
- {#if banner} - {banner.alt} - {/if} -
- -
-
-
diff --git a/web/src/components/misc/ChangelogEntryWrapper.svelte b/web/src/components/misc/ChangelogEntryWrapper.svelte index 3821fa42..6dc6e56a 100644 --- a/web/src/components/misc/ChangelogEntryWrapper.svelte +++ b/web/src/components/misc/ChangelogEntryWrapper.svelte @@ -6,6 +6,7 @@ export let date = ''; export let banner = undefined; + diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 5cbaf12f..3691e055 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -62,6 +62,54 @@ $: currentIndex, loadChangelog(); + + + {$t("general.cobalt")}: {$t("tabs.updates")} + + + + + +
+ {#if changelog} +
+ +
+
+ +
+ + +
+
+
+ +
+ {/if} +
+ - - - - {$t("general.cobalt")}: {$t("tabs.updates")} - - - - - -
- {#if changelog} -
- -
-
- -
- - -
-
-
- -
- {/if} -
From 6e374fde622988b5f7927f94cc00703786d24da1 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 17 Jul 2024 14:04:53 +0600 Subject: [PATCH 201/334] web/updates: make changelogs look nicer - fixes horizontal scrolling on mobile - removes text backdrop - improves readability --- web/src/components/misc/ChangelogEntry.svelte | 80 ++++++++++--------- .../misc/ChangelogEntryWrapper.svelte | 6 +- web/src/routes/updates/+page.svelte | 79 +++++++++--------- 3 files changed, 86 insertions(+), 79 deletions(-) diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/misc/ChangelogEntry.svelte index 902aa7ef..e4474aef 100644 --- a/web/src/components/misc/ChangelogEntry.svelte +++ b/web/src/components/misc/ChangelogEntry.svelte @@ -2,15 +2,17 @@ export let version: string; export let title: string; export let date: string; - export let banner: { file: string, alt: string } | undefined; + export let banner: { file: string; alt: string } | undefined;
-

-
{ version }
-
{ title }
-

- { date } +
+
+
{version}
+
{date}
+
+

{title}

+
{#if banner} main { - padding: 1em; + overflow-x: hidden; } - img { - max-width: 100%; - } - - h1 { - padding-top: 1em; - } - - .contents :global(.text-backdrop) { - border-radius: 4px; - background-color: var(--button); - color: var(--background); - padding: 0.3rem; - } - - .contents :global(.text-backdrop.link) { - text-decoration: underline; - } - - h1 { + #changelog-header { display: flex; flex-direction: column; align-items: start; + gap: calc(var(--padding) / 2); + padding: 1em 0; /* match default

padding */ } - h1 .changelog-version { - padding: .15rem .5rem; - border-radius: 4px; - background-color: var(--button-hover); + .changelog-info { + display: flex; + flex-direction: row; + align-items: center; + gap: 14px; } - h1 .changelog-title { - padding: .15rem 0; - text-align: left; + .changelog-version { + padding: 3px 8px; + border-radius: 6px; + background-color: var(--secondary); + color: var(--primary); + font-size: 21px; + font-weight: 500; + } + + .changelog-date { + font-size: 13px; + font-weight: 500; + color: var(--gray); + } + + .changelog-title { + padding: 0; + line-height: 1.2; } .changelog-banner { - padding: 2em; - width: 100%; - max-height: 300pt; - min-height: 210pt; display: block; object-fit: cover; + max-height: 320pt; + min-height: 210pt; + width: 100%; + max-width: 100; aspect-ratio: 16/9; + border-radius: var(--padding); } .changelog-content { @@ -84,5 +86,7 @@ .contents { max-width: 100%; + line-height: 1.5; + font-size: 15px; } diff --git a/web/src/components/misc/ChangelogEntryWrapper.svelte b/web/src/components/misc/ChangelogEntryWrapper.svelte index 6dc6e56a..d01b93f9 100644 --- a/web/src/components/misc/ChangelogEntryWrapper.svelte +++ b/web/src/components/misc/ChangelogEntryWrapper.svelte @@ -1,9 +1,9 @@ diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 3691e055..d8532ec2 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -1,17 +1,17 @@ + From 0e60ea95821eecbfdf38e56bc1b0fac634ded520 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Wed, 17 Jul 2024 09:07:25 +0000 Subject: [PATCH 211/334] web/ChangelogEntry: consistent date formatting --- web/src/components/misc/ChangelogEntry.svelte | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/misc/ChangelogEntry.svelte index a8f581d0..804705cf 100644 --- a/web/src/components/misc/ChangelogEntry.svelte +++ b/web/src/components/misc/ChangelogEntry.svelte @@ -1,15 +1,31 @@

{version}
-
{date}
+ {#if date} +
{formatDate(date)}
+ {/if}

{title}

From c3c7a6b7baedeba236af5933383b35efacdd24d6 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 20 Jul 2024 12:43:14 +0000 Subject: [PATCH 212/334] web/version: convert to readable --- web/src/lib/version.ts | 30 ++++++++++--------- .../settings/advanced/debug/+page.svelte | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/web/src/lib/version.ts b/web/src/lib/version.ts index ff9b4a0b..22539f55 100644 --- a/web/src/lib/version.ts +++ b/web/src/lib/version.ts @@ -1,3 +1,5 @@ +import { readable } from "svelte/store"; + type VersionResponse = { commit: string; branch: string; @@ -5,19 +7,19 @@ type VersionResponse = { version: string; } -const fetchVersion = async function () { - const response: VersionResponse | undefined = await fetch('/version.json') - .then(r => r.json()) - .catch(() => {}); +const unknownVersion = { + commit: "unknown", + branch: "unknown", + remote: "unknown", + version: "unknown" +}; - if (!response) return { - commit: "unknown", - branch: "unknown", - remote: "unknown", - version: "unknown" +export const version = readable( + unknownVersion, + (set) => { + fetch('/version.json') + .then(r => r.json()) + .then(set) + .catch(() => {}) } - - return response; -} - -export const version = await fetchVersion(); +) diff --git a/web/src/routes/settings/advanced/debug/+page.svelte b/web/src/routes/settings/advanced/debug/+page.svelte index 9dd63bd9..05feefeb 100644 --- a/web/src/routes/settings/advanced/debug/+page.svelte +++ b/web/src/routes/settings/advanced/debug/+page.svelte @@ -32,7 +32,7 @@

version:

- {JSON.stringify(version, null, 2)} + {JSON.stringify($version, null, 2)}
{/if} From 2c1bd50e70b33968ce74adf48f85da282b5d08c0 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 20 Jul 2024 12:43:22 +0000 Subject: [PATCH 213/334] Revert "web/vite: change build target to esnext" This reverts commit 842f91ec54cf1ed88258e2a224c8f76709d0ceae. --- web/vite.config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/web/vite.config.ts b/web/vite.config.ts index 2aed5de1..d6663e0d 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -6,7 +6,6 @@ export default defineConfig({ sveltekit() ], build: { - target: "esnext", rollupOptions: { output: { manualChunks: (id) => { From cd41fc9d493ec6c9795e17112b217b1871e51d7a Mon Sep 17 00:00:00 2001 From: wukko Date: Thu, 18 Jul 2024 17:22:29 +0600 Subject: [PATCH 214/334] web/SmallDialog: fix rendering & performance issues, new mobile animation --- web/src/components/dialog/SmallDialog.svelte | 63 +++++++++++++++----- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index bee98362..8763b122 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -1,4 +1,6 @@ - +
{#if meowbalt === "error"}
@@ -76,7 +83,7 @@ From 205494b367dc46831e66b200cf58adbb41ab456f Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 20 Jul 2024 18:49:51 +0600 Subject: [PATCH 215/334] web/SmallDialog: fix scaling on small screens --- web/src/components/dialog/SmallDialog.svelte | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 8763b122..c14cd102 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -25,7 +25,7 @@ setTimeout(() => { dialogParent.close(); killDialog(); - }, 150) + }, 150); } }; @@ -33,7 +33,7 @@ dialogParent.showModal(); tick().then(() => { open = true; - }) + }); } @@ -73,11 +73,7 @@
- +
diff --git a/web/src/components/meowbalt/MeowbaltLoaf.svelte b/web/src/components/meowbalt/MeowbaltLoaf.svelte deleted file mode 100644 index 3e8533e3..00000000 --- a/web/src/components/meowbalt/MeowbaltLoaf.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - -{$t("a11y.meowbalt.smile")} - - diff --git a/web/src/components/misc/Meowbalt.svelte b/web/src/components/misc/Meowbalt.svelte new file mode 100644 index 00000000..e367758e --- /dev/null +++ b/web/src/components/misc/Meowbalt.svelte @@ -0,0 +1,31 @@ + + +{$t(`a11y.meowbalt.${emotion}`)} + + diff --git a/web/src/components/misc/Placeholder.svelte b/web/src/components/misc/Placeholder.svelte index c38e9836..a8001ab0 100644 --- a/web/src/components/misc/Placeholder.svelte +++ b/web/src/components/misc/Placeholder.svelte @@ -1,10 +1,11 @@
- +
{pageName} page is not ready yet!
diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index c6a37969..b2c5ae8d 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -20,15 +20,12 @@ id: "save-error", type: "small", meowbalt: "error", - title: "", - bodySubText: "", buttons: [{ text: $t("general.gotit"), - color: "gray", main: true, action: () => {}, }] - } + } as DialogInfo const changeDownloadButton = (state: string) => { isDisabled = true; diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index 20bea678..888dc646 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -1,6 +1,8 @@ +import type { MeowbaltEmotions } from "$lib/types/meowbalt"; + export type DialogButton = { text: string, - color: string, + color: "blue" | "red" | "default", main: boolean, action: () => unknown | Promise } @@ -8,7 +10,7 @@ export type DialogButton = { export type DialogInfo = { id: string, type: "small", - meowbalt: "error", + meowbalt: MeowbaltEmotions | "", title: string, bodyText: string, bodySubText: string, diff --git a/web/src/lib/types/meowbalt.ts b/web/src/lib/types/meowbalt.ts new file mode 100644 index 00000000..6913f606 --- /dev/null +++ b/web/src/lib/types/meowbalt.ts @@ -0,0 +1 @@ +export type MeowbaltEmotions = "smile" | "error" | "question" | "think"; diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index ea612eb6..efe0a00b 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -71,6 +71,9 @@ --button-text: #282828; --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; + --button-elevated: #e3e3e3; + --button-elevated-hover: #dadada; + --popup-bg: #f1f1f1; --popup-backdrop: var(--primary); --popup-stroke: rgba(0, 0, 0, 0.08); @@ -126,6 +129,9 @@ --button-text: #e1e1e1; --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; + --button-elevated: #282828; + --button-elevated-hover: #2f2f2f; + --popup-bg: #191919; --popup-backdrop: var(--primary); --popup-stroke: rgba(255, 255, 255, 0.08); diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 680bef45..1c59864e 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -2,7 +2,7 @@ import { t } from "$lib/i18n/translations"; import Omnibox from "$components/save/Omnibox.svelte"; - import MeowbaltLoaf from "$components/meowbalt/MeowbaltLoaf.svelte"; + import Meowbalt from "$components/misc/Meowbalt.svelte"; @@ -11,7 +11,7 @@
- +
diff --git a/web/static/meowbalt/checking.png b/web/static/meowbalt/question.png similarity index 100% rename from web/static/meowbalt/checking.png rename to web/static/meowbalt/question.png From def6e26b9ffe37fa69364c3808c1db2a429d8c19 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sat, 20 Jul 2024 14:01:13 +0000 Subject: [PATCH 219/334] web/settings: add "erase all settings" button --- web/i18n/en/settings.json | 3 ++- .../buttons/ResetSettingsButton.svelte | 22 +++++++++++++++++++ web/src/lib/state/settings.ts | 7 ++++++ web/src/routes/+layout.svelte | 11 +++++++++- web/src/routes/settings/advanced/+page.svelte | 5 +++++ 5 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 web/src/components/buttons/ResetSettingsButton.svelte diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index f5380063..4df36dc5 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -92,5 +92,6 @@ "advanced.debug": "debug", "advanced.debug.title": "enable debug features", - "advanced.debug.description": "gives you access to a page with app & device info useful for debugging." + "advanced.debug.description": "gives you access to a page with app & device info useful for debugging.", + "advanced.reset": "erase all settings" } diff --git a/web/src/components/buttons/ResetSettingsButton.svelte b/web/src/components/buttons/ResetSettingsButton.svelte new file mode 100644 index 00000000..85a2139d --- /dev/null +++ b/web/src/components/buttons/ResetSettingsButton.svelte @@ -0,0 +1,22 @@ + + + + + diff --git a/web/src/lib/state/settings.ts b/web/src/lib/state/settings.ts index 555c45a9..79dfdc31 100644 --- a/web/src/lib/state/settings.ts +++ b/web/src/lib/state/settings.ts @@ -88,6 +88,13 @@ export function updateSetting(partial: PartialSettings) { }); } +export function resetSettings() { + update(() => { + localStorage.removeItem('settings'); + return {}; + }); +} + export default derived( storedSettings, $settings => mergeWithDefaults($settings) diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index efe0a00b..b6eac3e6 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -60,8 +60,10 @@ --white: #ffffff; --gray: #75757e; - --blue: #2f8af9; + --red: #f92f2f; + --dark-red: #df0707; --green: #51cf5e; + --blue: #2f8af9; --button: #f4f4f4; --button-hover: #e8e8e8; @@ -111,6 +113,13 @@ rgba(0, 0, 0, 0) 96%, rgba(0, 0, 0, 0.9) 100% ); + + --skeleton-gradient: linear-gradient( + 90deg, + var(--button), + var(--button-hover), + var(--button) + ); } :global([data-theme="dark"]) { diff --git a/web/src/routes/settings/advanced/+page.svelte b/web/src/routes/settings/advanced/+page.svelte index 55b454d1..1fe02104 100644 --- a/web/src/routes/settings/advanced/+page.svelte +++ b/web/src/routes/settings/advanced/+page.svelte @@ -3,6 +3,7 @@ import SettingsCategory from "$components/settings/SettingsCategory.svelte"; import SettingsToggle from "$components/buttons/SettingsToggle.svelte"; + import ResetSettingsButton from "$components/buttons/ResetSettingsButton.svelte"; @@ -13,3 +14,7 @@ description={$t("settings.advanced.debug.description")} /> + + + + \ No newline at end of file From d7bf98a80b7d4785cab05ff7534e7b362a122563 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 20 Jul 2024 21:48:17 +0600 Subject: [PATCH 220/334] web: settings reset confirmation, icons for small dialog - cleaned up dialog i18n - better red color - made :active state visible for dialog buttons on mobile - better body padding in small dialog - better small dialog typing with optional values --- web/i18n/en/dialog.json | 8 +++ web/i18n/en/general.json | 3 +- web/i18n/en/settings.json | 2 + .../buttons/ResetSettingsButton.svelte | 47 +++++++++++++--- web/src/components/dialog/DialogHolder.svelte | 1 + web/src/components/dialog/SmallDialog.svelte | 55 +++++++++++++++---- .../save/buttons/DownloadButton.svelte | 6 +- web/src/lib/types/dialog.ts | 13 +++-- web/src/routes/+layout.svelte | 10 +++- web/src/routes/settings/advanced/+page.svelte | 4 +- 10 files changed, 117 insertions(+), 32 deletions(-) create mode 100644 web/i18n/en/dialog.json diff --git a/web/i18n/en/dialog.json b/web/i18n/en/dialog.json new file mode 100644 index 00000000..96a552ec --- /dev/null +++ b/web/i18n/en/dialog.json @@ -0,0 +1,8 @@ +{ + "button.gotit": "got it", + "button.cancel": "cancel", + "button.erase": "erase", + + "erase.title": "erase all settings?", + "erase.body": "are you sure you want to reset all settings? this action is immediate and irreversible." +} diff --git a/web/i18n/en/general.json b/web/i18n/en/general.json index 5a371ff8..6ea5e8a0 100644 --- a/web/i18n/en/general.json +++ b/web/i18n/en/general.json @@ -1,4 +1,3 @@ { - "cobalt": "cobalt", - "gotit": "got it" + "cobalt": "cobalt" } diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 4df36dc5..0d20cc15 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -93,5 +93,7 @@ "advanced.debug": "debug", "advanced.debug.title": "enable debug features", "advanced.debug.description": "gives you access to a page with app & device info useful for debugging.", + + "advanced.data": "settings data", "advanced.reset": "erase all settings" } diff --git a/web/src/components/buttons/ResetSettingsButton.svelte b/web/src/components/buttons/ResetSettingsButton.svelte index 85a2139d..0434c84d 100644 --- a/web/src/components/buttons/ResetSettingsButton.svelte +++ b/web/src/components/buttons/ResetSettingsButton.svelte @@ -1,22 +1,55 @@ - diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index 7d6ef1dd..1f306c6b 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -12,6 +12,7 @@ id={dialog.id} title={dialog.title} meowbalt={dialog.meowbalt} + icon={dialog.icon} bodyText={dialog.bodyText} bodySubText={dialog.bodySubText} buttons={dialog.buttons} diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 3820c88e..4aa12b72 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -2,13 +2,16 @@ import { tick } from "svelte"; import { killDialog } from "$lib/dialogs"; - import type { DialogButton } from "$lib/types/dialog"; + import type { DialogButton, SmallDialogIcons } from "$lib/types/dialog"; import Meowbalt from "$components/misc/Meowbalt.svelte"; import type { MeowbaltEmotions } from "$lib/types/meowbalt"; + import IconAlertTriangle from "@tabler/icons-svelte/IconAlertTriangle.svelte"; + export let id: string; - export let meowbalt: MeowbaltEmotions; + export let meowbalt: MeowbaltEmotions | undefined; + export let icon: SmallDialogIcons | undefined; export let title: string = ""; export let bodyText: string = ""; export let bodySubText: string = ""; @@ -45,12 +48,19 @@
{/if} - {#if title} - - {/if}
From dbbd43e002d80a043496549ae1b52b76a63186db Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 14:42:17 +0600 Subject: [PATCH 228/334] web/changelog: move components to dedicated folder --- web/src/components/{misc => changelog}/ChangelogEntry.svelte | 0 .../{misc => changelog}/ChangelogEntryWrapper.svelte | 4 ++-- web/svelte.config.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename web/src/components/{misc => changelog}/ChangelogEntry.svelte (100%) rename web/src/components/{misc => changelog}/ChangelogEntryWrapper.svelte (73%) diff --git a/web/src/components/misc/ChangelogEntry.svelte b/web/src/components/changelog/ChangelogEntry.svelte similarity index 100% rename from web/src/components/misc/ChangelogEntry.svelte rename to web/src/components/changelog/ChangelogEntry.svelte diff --git a/web/src/components/misc/ChangelogEntryWrapper.svelte b/web/src/components/changelog/ChangelogEntryWrapper.svelte similarity index 73% rename from web/src/components/misc/ChangelogEntryWrapper.svelte rename to web/src/components/changelog/ChangelogEntryWrapper.svelte index 0907758d..0a2dcd58 100644 --- a/web/src/components/misc/ChangelogEntryWrapper.svelte +++ b/web/src/components/changelog/ChangelogEntryWrapper.svelte @@ -1,11 +1,11 @@
-
+
{version}
{#if date} @@ -56,6 +56,10 @@ padding-bottom: 1em; /* match default

padding */ } + #changelog-header.no-padding { + padding-bottom: 0; + } + .changelog-info { display: flex; flex-direction: row; From ec768ebfc21ef1eb01c2be418f42d31c74883a64 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 16:34:37 +0600 Subject: [PATCH 230/334] web/settings/metadata: basic filename preview component --- web/i18n/en/settings.json | 3 + .../settings/FilenamePreview.svelte | 83 +++++++++++++++++++ .../settings/save/metadata/+page.svelte | 2 + 3 files changed, 88 insertions(+) create mode 100644 web/src/components/settings/FilenamePreview.svelte diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 0d20cc15..c761ff85 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -65,6 +65,9 @@ "metadata.filename.nerdy": "nerdy", "metadata.filename.description": "filename style using which cobalt files will be downloaded. this description is temporary as there's no dynamic preview component yet.", + "metadata.filename.preview.video": "Video Title", + "metadata.filename.preview.audio": "Audio Title - Audio Author", + "metadata.file": "file metadata", "metadata.disable.title": "disable file metadata", "metadata.disable.description": "title, artist, and other info will not be added to the file.", diff --git a/web/src/components/settings/FilenamePreview.svelte b/web/src/components/settings/FilenamePreview.svelte new file mode 100644 index 00000000..64fce4f4 --- /dev/null +++ b/web/src/components/settings/FilenamePreview.svelte @@ -0,0 +1,83 @@ + + +

+
+ {videoFilePreview}.{youtubeVideoExt} +
+
+ {audioFilePreview}.{audioFormat} +
+
+ + diff --git a/web/src/routes/settings/save/metadata/+page.svelte b/web/src/routes/settings/save/metadata/+page.svelte index 91c3d621..1da7010f 100644 --- a/web/src/routes/settings/save/metadata/+page.svelte +++ b/web/src/routes/settings/save/metadata/+page.svelte @@ -7,6 +7,7 @@ import Switcher from "$components/buttons/Switcher.svelte"; import SettingsButton from "$components/buttons/SettingsButton.svelte"; import SettingsToggle from "$components/buttons/SettingsToggle.svelte"; + import FilenamePreview from "$components/settings/FilenamePreview.svelte"; @@ -24,6 +25,7 @@ {/each} + Date: Sun, 21 Jul 2024 16:40:39 +0600 Subject: [PATCH 231/334] web/ResetSettingsButton: update dialog text erase -> reset --- web/i18n/en/dialog.json | 6 +++--- web/i18n/en/settings.json | 2 +- web/src/components/buttons/ResetSettingsButton.svelte | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/web/i18n/en/dialog.json b/web/i18n/en/dialog.json index 96a552ec..b57fae5b 100644 --- a/web/i18n/en/dialog.json +++ b/web/i18n/en/dialog.json @@ -1,8 +1,8 @@ { "button.gotit": "got it", "button.cancel": "cancel", - "button.erase": "erase", + "button.reset": "reset", - "erase.title": "erase all settings?", - "erase.body": "are you sure you want to reset all settings? this action is immediate and irreversible." + "reset.title": "reset all settings?", + "reset.body": "are you sure you want to reset all settings? this action is immediate and irreversible." } diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index c761ff85..7273ea1e 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -98,5 +98,5 @@ "advanced.debug.description": "gives you access to a page with app & device info useful for debugging.", "advanced.data": "settings data", - "advanced.reset": "erase all settings" + "advanced.reset": "reset all settings" } diff --git a/web/src/components/buttons/ResetSettingsButton.svelte b/web/src/components/buttons/ResetSettingsButton.svelte index 0434c84d..e6b6a61a 100644 --- a/web/src/components/buttons/ResetSettingsButton.svelte +++ b/web/src/components/buttons/ResetSettingsButton.svelte @@ -11,8 +11,8 @@ id: "wipe-confirm", type: "small", icon: "warn-red", - title: $t("dialog.erase.title"), - bodyText: $t("dialog.erase.body"), + title: $t("dialog.reset.title"), + bodyText: $t("dialog.reset.body"), buttons: [ { text: $t("dialog.button.cancel"), @@ -20,7 +20,7 @@ action: () => {}, }, { - text: $t("dialog.button.erase"), + text: $t("dialog.button.reset"), color: "red", main: true, action: () => resetSettings(), From 0cea58922ddebb2ed1d9eabcb26dc1ffa128c1ae Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 09:42:48 +0000 Subject: [PATCH 232/334] web/changelogs: display skeleton when changelog is loading --- .../changelog/ChangelogEntry.svelte | 17 ++- .../changelog/ChangelogSkeleton.svelte | 128 ++++++++++++++++++ web/src/components/misc/Skeleton.svelte | 64 +++++++++ web/src/lib/types/changelogs.ts | 2 +- web/src/routes/updates/+page.svelte | 32 +++-- 5 files changed, 228 insertions(+), 15 deletions(-) create mode 100644 web/src/components/changelog/ChangelogSkeleton.svelte create mode 100644 web/src/components/misc/Skeleton.svelte diff --git a/web/src/components/changelog/ChangelogEntry.svelte b/web/src/components/changelog/ChangelogEntry.svelte index 01116d46..3026a9d4 100644 --- a/web/src/components/changelog/ChangelogEntry.svelte +++ b/web/src/components/changelog/ChangelogEntry.svelte @@ -1,9 +1,13 @@ + +
+
+
+
{ version }
+
+ +
+
+

+ +

+
+
+ +
+ {#each {length: 3 + Math.random() * 5} as _} +

+ +

+ {/each} +
+
+
+ + diff --git a/web/src/components/misc/Skeleton.svelte b/web/src/components/misc/Skeleton.svelte new file mode 100644 index 00000000..91e39e48 --- /dev/null +++ b/web/src/components/misc/Skeleton.svelte @@ -0,0 +1,64 @@ + + +
+ + \ No newline at end of file diff --git a/web/src/lib/types/changelogs.ts b/web/src/lib/types/changelogs.ts index 3dd41afc..e4d73c5d 100644 --- a/web/src/lib/types/changelogs.ts +++ b/web/src/lib/types/changelogs.ts @@ -16,4 +16,4 @@ export interface MarkdownMetadata { export type ChangelogImport = { default: SvelteComponent, metadata: ChangelogMetadata -} | undefined; +}; \ No newline at end of file diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 11d4d959..0ebce5cd 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -5,13 +5,15 @@ import { getAllChangelogs } from "$lib/changelogs"; import type { ChangelogImport } from "$lib/types/changelogs"; + import ChangelogSkeleton from "$components/changelog/ChangelogSkeleton.svelte"; + import IconChevronLeft from "@tabler/icons-svelte/IconChevronLeft.svelte"; import IconChevronRight from "@tabler/icons-svelte/IconChevronRight.svelte"; const changelogs = getAllChangelogs(); const versions = Object.keys(changelogs); - let changelog: (ChangelogImport & { version: string }) | undefined; + let changelog: { version: string; page: Promise } | undefined; let currentIndex = 0; { @@ -24,17 +26,13 @@ const loadChangelog = async () => { const version = versions[currentIndex]; - const log = (await changelogs[version]()) as ChangelogImport; - if (!log) { - return; // FIXME: now wot + changelog = { + version, + page: changelogs[version]() as Promise } - changelog = { - ...log, - version, - }; - window.location.hash = version; + await changelog.page; }; const loadNext = () => { @@ -77,10 +75,17 @@
- + {#await changelog.page} + {#key changelog.version} + + {/key} + {:then page} + + {/await}
- + \ No newline at end of file diff --git a/web/src/components/changelog/ChangelogSkeleton.svelte b/web/src/components/changelog/ChangelogSkeleton.svelte index 22237322..128146ac 100644 --- a/web/src/components/changelog/ChangelogSkeleton.svelte +++ b/web/src/components/changelog/ChangelogSkeleton.svelte @@ -39,90 +39,4 @@
- + \ No newline at end of file From d8acb5406a262616d945ac68735e7b3a9d561ab6 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 16:49:38 +0600 Subject: [PATCH 235/334] web/layout: fix skeleton gradient --- web/src/routes/+layout.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 7191c227..c342d62e 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -118,9 +118,9 @@ --skeleton-gradient: linear-gradient( 90deg, - var(--button), var(--button-hover), - var(--button) + var(--button), + var(--button-hover) ); } From 238cd22c8d11533c225bea4c58e92ff17b62b115 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 16:57:42 +0600 Subject: [PATCH 236/334] web/ChangelogSkeleton: fix title skeleton cutting off, reduce rounding --- web/src/components/changelog/ChangelogSkeleton.svelte | 10 ++++------ web/src/components/misc/Skeleton.svelte | 3 ++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/web/src/components/changelog/ChangelogSkeleton.svelte b/web/src/components/changelog/ChangelogSkeleton.svelte index 128146ac..11f1d999 100644 --- a/web/src/components/changelog/ChangelogSkeleton.svelte +++ b/web/src/components/changelog/ChangelogSkeleton.svelte @@ -14,12 +14,10 @@ />
-

- -

+
.skeleton { - border-radius: var(--border-radius); + border-radius: calc(var(--border-radius) / 2); background-color: var(--button); background-image: var(--skeleton-gradient); background-size: 200px 100%; @@ -40,6 +40,7 @@ } .skeleton.big { + border-radius: var(--border-radius); background-size: 700px 100%; animation: skeleton-big 1.2s ease-in-out infinite; } From 88fa780f6da417e57e0929f169b8b40bf40bf204 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 17:06:47 +0600 Subject: [PATCH 237/334] web/layout: add dark theme skeleton gradient --- web/src/routes/+layout.svelte | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index c342d62e..2cf815c9 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -107,6 +107,7 @@ --switcher-padding: var(--sidebar-inner-padding); + /* used for fading the tab bar on scroll */ --sidebar-mobile-gradient: linear-gradient( 90deg, rgba(0, 0, 0, 0.9) 0%, @@ -165,6 +166,13 @@ rgba(16, 16, 16, 0) 96%, rgba(16, 16, 16, 0.9) 100% ); + + --skeleton-gradient: linear-gradient( + 90deg, + var(--button), + var(--button-hover), + var(--button) + ); } :global([data-theme="light"] [data-reduce-transparency="true"]) { From 213f2d2c9251a2e5d6ebff60ecd9f60d8705e5ea Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 17:22:22 +0600 Subject: [PATCH 238/334] web/updates: hide navigation buttons when nowhere to navigate - removed box shadow on desktop - centered button vertically with flex --- web/src/routes/updates/+page.svelte | 43 +++++++++++++++++------------ 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 0ebce5cd..1cd59664 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -68,11 +68,13 @@
{#if changelog} -
- +
+ {#if prev} + + {/if}
{#await changelog.page} @@ -102,16 +104,17 @@
-
- +
+ {#if next} + + {/if}
{/if}
@@ -127,16 +130,21 @@ .button-wrapper-desktop { display: flex; justify-content: center; + align-items: center; + height: 100%; } .button-wrapper-desktop button { position: absolute; - top: 50%; background-color: transparent; display: flex; border: none; } + .button-wrapper-desktop button:not(:focus-visible) { + box-shadow: none; + } + .changelog-wrapper { flex: 1; max-width: 850px; @@ -146,8 +154,9 @@ } button[disabled] { - opacity: 0.5; + opacity: 0; cursor: default; + pointer-events: none; } .button-wrapper-mobile { From ebaa209c47523cdcb57a62010b21e35a415923c2 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 11:29:57 +0000 Subject: [PATCH 239/334] web/changelogs: add dates to all changelogs --- web/changelogs/3.5.2.md | 3 ++- web/changelogs/3.5.4.md | 1 + web/changelogs/3.5.md | 1 + web/changelogs/3.6.3.md | 1 + web/changelogs/3.6.md | 1 + web/changelogs/3.7.md | 1 + web/changelogs/4.0.md | 1 + web/changelogs/4.1.md | 1 + web/changelogs/4.2.md | 1 + web/changelogs/4.3.2.md | 1 + web/changelogs/4.3.md | 1 + web/changelogs/4.4.md | 1 + web/changelogs/4.5.md | 1 + web/changelogs/4.6.md | 1 + web/changelogs/4.7.md | 1 + web/changelogs/4.8.md | 1 + web/changelogs/5.0.md | 1 + web/changelogs/5.1.md | 1 + web/changelogs/5.2.md | 1 + web/changelogs/5.3.md | 1 + web/changelogs/5.4.md | 1 + 21 files changed, 22 insertions(+), 1 deletion(-) diff --git a/web/changelogs/3.5.2.md b/web/changelogs/3.5.2.md index 7add6687..22e8f916 100644 --- a/web/changelogs/3.5.2.md +++ b/web/changelogs/3.5.2.md @@ -1,7 +1,8 @@ --- title: "vk clips support, improved changelog system, and less bugs" +date: "Sep 11, 2022" --- -new features: +new features: - added support for vk clips. cobalt now lets you download even more cringy videos! - added update history right to the changelog menu. it's not loaded by default to minimize page load time, but can be loaded upon pressing a button. probably someone will enjoy this. - as you've just read, cobalt now has on-demand blocks. they're rendered on server upon request and exist to prevent any unnecessary clutter by default. the first feature to use on-demand rendering is history of updates in changelog tab. diff --git a/web/changelogs/3.5.4.md b/web/changelogs/3.5.4.md index 3ad71fa1..a0e863b0 100644 --- a/web/changelogs/3.5.4.md +++ b/web/changelogs/3.5.4.md @@ -1,5 +1,6 @@ --- title: "tiktok support is back :D" +date: "Sep 21, 2022" --- you can download videos, sounds, and images from tiktok again! huge thank you to [@minzique](https://github.com/minzique) for finding another api endpoint that works. \ No newline at end of file diff --git a/web/changelogs/3.5.md b/web/changelogs/3.5.md index 0e706cdc..834d7a04 100644 --- a/web/changelogs/3.5.md +++ b/web/changelogs/3.5.md @@ -1,5 +1,6 @@ --- title: "ui revamp and usability improvements" +date: "Sep 8, 2022" --- new features: - cobalt now lets you paste the link in your clipboard and download the file in a single press of a button.if your clipboard's latest content isn't a valid url, cobalt won't process or paste it. you can also hide the clipboard button in settings if you want to. diff --git a/web/changelogs/3.6.3.md b/web/changelogs/3.6.3.md index 49459ecc..80150494 100644 --- a/web/changelogs/3.6.3.md +++ b/web/changelogs/3.6.3.md @@ -1,5 +1,6 @@ --- title: "less disturbance" +date: "Oct 5, 2022" --- changelog popup no longer annoys you after a major update! this action has been replaced with a notification dot. if you see a red dot, then there's something new. diff --git a/web/changelogs/3.6.md b/web/changelogs/3.6.md index 39d34308..cc494e7f 100644 --- a/web/changelogs/3.6.md +++ b/web/changelogs/3.6.md @@ -1,5 +1,6 @@ --- title: "improvements all around!" +date: "Sep 28, 2022" --- - download mode switcher is moving places, it's now right next to link input area. - smart mode has been renamed to auto mode, because this name is easier to understand. diff --git a/web/changelogs/3.7.md b/web/changelogs/3.7.md index 3fdad1e6..ada689d7 100644 --- a/web/changelogs/3.7.md +++ b/web/changelogs/3.7.md @@ -1,5 +1,6 @@ --- title: "support for multi media tweets is here!" +date: "Oct 9, 2022" --- cobalt now lets you save any of the videos or gifs in a tweet. even if there are many of them. diff --git a/web/changelogs/4.0.md b/web/changelogs/4.0.md index abc40fa4..cad32081 100644 --- a/web/changelogs/4.0.md +++ b/web/changelogs/4.0.md @@ -1,5 +1,6 @@ --- title: "better and faster than ever" +date: "Oct 24, 2022" --- this update has a ton of improvements and new features. diff --git a/web/changelogs/4.1.md b/web/changelogs/4.1.md index c8dacab1..3d6e2af9 100644 --- a/web/changelogs/4.1.md +++ b/web/changelogs/4.1.md @@ -1,5 +1,6 @@ --- title: "better tiktok image downloads" +date: "Oct 27, 2022" --- here's what's up: - tiktok images are saved as .jpeg instead of .webp (finally, i know). diff --git a/web/changelogs/4.2.md b/web/changelogs/4.2.md index 9424f061..f9dd4609 100644 --- a/web/changelogs/4.2.md +++ b/web/changelogs/4.2.md @@ -1,5 +1,6 @@ --- title: "optimized quality picking and 8k video support" +date: "Nov 4, 2022" --- - this update fixes quality picking that was accidentally broken in 4.0 update. - you now can download videos in 8k from youtube. why would you that? no idea. but i'm more than happy to give you this option. diff --git a/web/changelogs/4.3.2.md b/web/changelogs/4.3.2.md index adabaff3..07e8a6a5 100644 --- a/web/changelogs/4.3.2.md +++ b/web/changelogs/4.3.2.md @@ -1,5 +1,6 @@ --- title: "twitter improvements & changelog overhaul" +date: "Nov 15, 2022" --- - you can download explicit content from twitter. - direct video links from twitter are properly supported (video/1, video/2, etc.). diff --git a/web/changelogs/4.3.md b/web/changelogs/4.3.md index bdf9c018..3ec39101 100644 --- a/web/changelogs/4.3.md +++ b/web/changelogs/4.3.md @@ -1,5 +1,6 @@ --- title: "developers, developers, developers, developers" +date: "Nov 12, 2022" banner: file: "developers.webp" alt: "steve ballmer going \"developers, developers, developers\"" diff --git a/web/changelogs/4.4.md b/web/changelogs/4.4.md index 5d63ea5d..06e00198 100644 --- a/web/changelogs/4.4.md +++ b/web/changelogs/4.4.md @@ -1,5 +1,6 @@ --- title: "over 1 million monthly requests. thank you." +date: "Nov 20, 2022" banner: file: "onemillionr.webp" alt: "cobalt logo and a confetti emoji" diff --git a/web/changelogs/4.5.md b/web/changelogs/4.5.md index a0996b70..a15c10da 100644 --- a/web/changelogs/4.5.md +++ b/web/changelogs/4.5.md @@ -1,5 +1,6 @@ --- title: "better, faster, stronger, stable" +date: "Dec 6, 2022" banner: file: "meowthstrong.webp" alt: "meowth stretching" diff --git a/web/changelogs/4.6.md b/web/changelogs/4.6.md index bc13fc99..89a16380 100644 --- a/web/changelogs/4.6.md +++ b/web/changelogs/4.6.md @@ -1,5 +1,6 @@ --- title: "mute videos and proper soundcloud support" +date: "Dec 17, 2022" banner: file: "shutup.webp" alt: "a cat yawning, with a crossed out loudspeaker icon next to it" diff --git a/web/changelogs/4.7.md b/web/changelogs/4.7.md index 9c482a19..089b1358 100644 --- a/web/changelogs/4.7.md +++ b/web/changelogs/4.7.md @@ -1,5 +1,6 @@ --- title: "we're better together! thank you for bug reports." +date: "Jan 13, 2023" banner: file: "bettertogether.webp" alt: "various different pokémon jumping in happiness" diff --git a/web/changelogs/4.8.md b/web/changelogs/4.8.md index f333cc0a..ae0118dc 100644 --- a/web/changelogs/4.8.md +++ b/web/changelogs/4.8.md @@ -1,5 +1,6 @@ --- title: "prettier than ever" +date: "Jan 29, 2023" banner: file: "catmakeup.webp" alt: "a cat being brushed with a powder makeup brush" diff --git a/web/changelogs/5.0.md b/web/changelogs/5.0.md index 328fdbf0..b2599211 100644 --- a/web/changelogs/5.0.md +++ b/web/changelogs/5.0.md @@ -1,5 +1,6 @@ --- title: "it's all about attention to detail!" +date: "Feb 13, 2023" banner: file: "valentines.webp" alt: "relaxed meowth with sakura petals falling in front of them" diff --git a/web/changelogs/5.1.md b/web/changelogs/5.1.md index 905c573d..1b37d145 100644 --- a/web/changelogs/5.1.md +++ b/web/changelogs/5.1.md @@ -1,5 +1,6 @@ --- title: "the evil has been defeated" +date: "Feb 26, 2023" banner: file: "happymeowth.webp" alt: "meowth jumping up into the sky very excitedly" diff --git a/web/changelogs/5.2.md b/web/changelogs/5.2.md index e6e7c72b..d1114825 100644 --- a/web/changelogs/5.2.md +++ b/web/changelogs/5.2.md @@ -1,5 +1,6 @@ --- title: "fastest one in the game" +date: "Mar 24, 2023" banner: file: "catspeed.webp" alt: "a cat running very fast in an exercise wheel" diff --git a/web/changelogs/5.3.md b/web/changelogs/5.3.md index 3233f365..1aa2adb9 100644 --- a/web/changelogs/5.3.md +++ b/web/changelogs/5.3.md @@ -1,5 +1,6 @@ --- title: "better looks, better feel" +date: "Apr 3, 2023" banner: file: "cattired.webp" alt: "a cat laying on a sofa face down, wiggling its tail" diff --git a/web/changelogs/5.4.md b/web/changelogs/5.4.md index ef405fc5..6dfa58b2 100644 --- a/web/changelogs/5.4.md +++ b/web/changelogs/5.4.md @@ -1,5 +1,6 @@ --- title: "instagram support, docker, and more!" +date: "Apr 24, 2023" banner: file: "catphonestand.webp" alt: "a cat holding a phone under its chin while a person plays clash of clans on it" From 534af330ce56d2ab536871d7c43a91fac823a6a9 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 11:30:06 +0000 Subject: [PATCH 240/334] web/changelogs: make `date` attribute required --- web/src/components/changelog/ChangelogEntry.svelte | 2 +- web/src/lib/types/changelogs.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/components/changelog/ChangelogEntry.svelte b/web/src/components/changelog/ChangelogEntry.svelte index 6100af31..d23500fc 100644 --- a/web/src/components/changelog/ChangelogEntry.svelte +++ b/web/src/components/changelog/ChangelogEntry.svelte @@ -3,7 +3,7 @@ export let version: string; export let title: string; - export let date: string | undefined; + export let date: string; export let banner: { file: string; alt: string } | undefined; let bannerLoaded = false; diff --git a/web/src/lib/types/changelogs.ts b/web/src/lib/types/changelogs.ts index e4d73c5d..ed3d85f9 100644 --- a/web/src/lib/types/changelogs.ts +++ b/web/src/lib/types/changelogs.ts @@ -2,7 +2,7 @@ import type { SvelteComponent } from "svelte" export interface ChangelogMetadata { title: string, - date?: string + date: string banner?: { file: string, alt: string From 4fab0d3fb8a657870949a54ef580e34ebbf88721 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 11:31:55 +0000 Subject: [PATCH 241/334] web/ChangelogEntry: expect date to always exist --- web/src/components/changelog/ChangelogEntry.svelte | 4 +--- web/src/lib/types/changelogs.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/web/src/components/changelog/ChangelogEntry.svelte b/web/src/components/changelog/ChangelogEntry.svelte index d23500fc..4fdc1129 100644 --- a/web/src/components/changelog/ChangelogEntry.svelte +++ b/web/src/components/changelog/ChangelogEntry.svelte @@ -27,9 +27,7 @@
{version}
- {#if date} -
{formatDate(date)}
- {/if} +
{formatDate(date)}

{title}

diff --git a/web/src/lib/types/changelogs.ts b/web/src/lib/types/changelogs.ts index ed3d85f9..d07740d6 100644 --- a/web/src/lib/types/changelogs.ts +++ b/web/src/lib/types/changelogs.ts @@ -2,7 +2,7 @@ import type { SvelteComponent } from "svelte" export interface ChangelogMetadata { title: string, - date: string + date: string, banner?: { file: string, alt: string From 4402484a0cd70fe0dd0c9f807512dd898e991f18 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 17:34:31 +0600 Subject: [PATCH 242/334] web/updates: reduce mobile navigation padding --- web/src/routes/updates/+page.svelte | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 1cd59664..63884bd0 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -166,9 +166,8 @@ @media only screen and (max-width: 1150px) { .button-wrapper-mobile { display: flex; - padding-bottom: 1rem; - margin-left: 1rem; - margin-right: 1rem; + padding: var(--border-radius); + padding-top: 0; justify-content: space-between; } From 9b4f593f87b2b30cc55b81f5ef6daf2153af9f31 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 15:53:33 +0000 Subject: [PATCH 243/334] web/changelogs: add more historical changelogs --- web/changelogs/2.0.md | 20 ++++++++++++++++++ web/changelogs/2.2.5.md | 17 +++++++++++++++ web/changelogs/2.2.6.md | 10 +++++++++ web/changelogs/2.2.8.md | 7 +++++++ web/changelogs/2.2.9.md | 10 +++++++++ web/changelogs/2.2.md | 16 ++++++++++++++ web/changelogs/3.0.md | 46 +++++++++++++++++++++++++++++++++++++++++ web/changelogs/3.1.md | 11 ++++++++++ web/changelogs/3.2.md | 12 +++++++++++ web/changelogs/3.3.md | 17 +++++++++++++++ web/changelogs/3.4.md | 15 ++++++++++++++ 11 files changed, 181 insertions(+) create mode 100644 web/changelogs/2.0.md create mode 100644 web/changelogs/2.2.5.md create mode 100644 web/changelogs/2.2.6.md create mode 100644 web/changelogs/2.2.8.md create mode 100644 web/changelogs/2.2.9.md create mode 100644 web/changelogs/2.2.md create mode 100644 web/changelogs/3.0.md create mode 100644 web/changelogs/3.1.md create mode 100644 web/changelogs/3.2.md create mode 100644 web/changelogs/3.3.md create mode 100644 web/changelogs/3.4.md diff --git a/web/changelogs/2.0.md b/web/changelogs/2.0.md new file mode 100644 index 00000000..0e778003 --- /dev/null +++ b/web/changelogs/2.0.md @@ -0,0 +1,20 @@ +--- +title: "everything is new!" +date: "Jun 28, 2022" +--- + +- added support for: bilibili.com, youtube, youtube music, reddit, vk; +- remade the way downloads are handled; +- added proper website branding; +- added settings, donations, and changelog menu; +- added manual theme picker; +- added format picker for youtube; +- added quality picker for youtube and vk downloads (bilibili and twitter later); +- improved usability; +- upgraded the download button to be adaptive depending on current status; +- popups are now adaptive, too; +- better scalability; +- took out trash; +- moved from commonjs to ems; +- overall revamp of backend and frontend; +- fixed various issues that were present in older version. \ No newline at end of file diff --git a/web/changelogs/2.2.5.md b/web/changelogs/2.2.5.md new file mode 100644 index 00000000..11fde1c0 --- /dev/null +++ b/web/changelogs/2.2.5.md @@ -0,0 +1,17 @@ +--- +title: "remade localization system once again" +date: "Jul 24, 2022" +--- + +- new localization system: fast, dynamic, way more organized +- localization strings are WAY more descriptive +- it's now easier to add support for other languages (just one loc file instead of five) +- localization now falls back to english if localized string isnt available +- got rid of all static language selectors (probably) +- slightly updated english and russian strings +- miscellaneous settings items have been bundled together and moved to the bottom, cause they're used the least +- bottom links should no longer touch the popup border on overflow +- rearranged popup order in the rendered page +- bumped version up to 2.2.5 + +if you see strings that are like this: !!EXAMPLE!! or withoutspace please file an issue on github diff --git a/web/changelogs/2.2.6.md b/web/changelogs/2.2.6.md new file mode 100644 index 00000000..02ce1a29 --- /dev/null +++ b/web/changelogs/2.2.6.md @@ -0,0 +1,10 @@ +--- +title: "tiktok is back!" +date: "Jul 28, 2022" +--- + +- added support for tiktok (images won't work, they're only accessible through the app) +- hopefully main input bar is now not rounded on ios, i fucking hate apple +- if service is not supported, a correlating error will appear, not generic one +- removed duplicates from config that are present in package json already +- tiny bit of clean up \ No newline at end of file diff --git a/web/changelogs/2.2.8.md b/web/changelogs/2.2.8.md new file mode 100644 index 00000000..ba054adc --- /dev/null +++ b/web/changelogs/2.2.8.md @@ -0,0 +1,7 @@ +--- +title: "faster and more accessible" +date: "Jul 30, 2022" +--- + +- spanish localization by @adrigoomy +- cobalt should load even faster cause all loaded files are now way smaller (esbuild implementation) \ No newline at end of file diff --git a/web/changelogs/2.2.9.md b/web/changelogs/2.2.9.md new file mode 100644 index 00000000..ef54654c --- /dev/null +++ b/web/changelogs/2.2.9.md @@ -0,0 +1,10 @@ +--- +title: "fixes" +date: "Aug 6, 2022" +--- + +- fixed neighbor quality picking for youtube videos +- webm is now default for youtube downloads for all platforms except for ios +- even more readme changes +- a tiny bit of clean up +- preparing stuff for next major update \ No newline at end of file diff --git a/web/changelogs/2.2.md b/web/changelogs/2.2.md new file mode 100644 index 00000000..768094e6 --- /dev/null +++ b/web/changelogs/2.2.md @@ -0,0 +1,16 @@ +--- +title: "beginning of 2.2" +date: "Jul 13, 2022" +--- + +- added download popup to solve the issue with downloads on ios +- merged big and small popups into one +- made buttons in donation menu act like buttons +- began to clean up localisation +- added ability to embed repo url into localisation strings +- moved ffmpeg args to config for more flexibility (and hopefully future changes) +- removed error response in stream that could result in a crash +- removed notice for ios users from about cause it's no longer relevant +- made error popup look and act like the rest +- a tiny bit of clean up +- changelog is now made out of latest commit (and doesn't break) \ No newline at end of file diff --git a/web/changelogs/3.0.md b/web/changelogs/3.0.md new file mode 100644 index 00000000..37c2d5e8 --- /dev/null +++ b/web/changelogs/3.0.md @@ -0,0 +1,46 @@ +--- +title: "everything what you've been waiting for. welcome to cobalt 3.0 :)" +date: "Aug 12, 2022" +--- + +follow cobalt's twitter account for polls, updates, and more: [@justusecobalt](https://twitter.com/justusecobalt) + +stuff that you can notice: + +- you can now download audio from any supported service, in any format that you set in settings (+). yes, that includes mp3, which you all have been waiting for :D +- it's now easier to switch between download modes (just a single toggle on the bottom). +- your youtube download format has been reset, sorry, but that was required to implement all audio downloads. +- default download format for youtube videos on all platforms is now webm. except for ios. + +- cobalt now has emoji, just to spice up the black and white ui. all of them have been tuned to look the best in both themes. isn't it cool? +- about, changelog, and donation popups have been merged into just one, for covnenience. +- changelog got a huge upgrade (as you can see), and now there are both major changes and latest commit info, just so commits can finally go back to being batshit insane. +- changelog popup appears on every major update, but you can disable it in settings, if you want to. +- changelog now opens by default when pressing "?" button. i don't think anyone reads "about" as often. +- settings (+) have been split into three tabs, also for convenience and ease of use. + +- added support for donation links. you can now donate through boosty, not only via crypto :D +- donate popup has been rearranged and tuned just a tiny bit. + +- you can now click away from any popup by pressing the void behind it. +- you can also press "escape" key on keyboard to close any popup. + +- switchers and buttons are now way easier on eye. white border is gone from where it's unneeded. +- buttons are now very satisfying to press. +- switchers are scrollable if there's not enough space to fit all contents on screen. +- scaling is now even better than before. + +internal stuff: + +- frontend won't send video related stuff if audio mode is on. +- matching has, yet again, gone through mitosis, and is now probably the cleanest it can get. +- page rendering is now modular, something like what frameworks have but way lighter. this makes adding new features WAY easier. +- removed some stuff that didn't make sense (like storing language of stream request). +- cleaned up insides of cobalt, of course. +- almost all links now open in new tab, just like they should have from the very beginning. + +known issues: +- impossible to download audio from vk. i'll try to fix it in the next update. +- headers are not sticky in tabbed popups. maybe this is a good thing, i'll think about it. + +if you ever notice any issues, make sure to report them on github. your report doesn't have to sound professional, just do your best to describe the issue. \ No newline at end of file diff --git a/web/changelogs/3.1.md b/web/changelogs/3.1.md new file mode 100644 index 00000000..8b4bff75 --- /dev/null +++ b/web/changelogs/3.1.md @@ -0,0 +1,11 @@ +--- +title: small quality of life improvements +date: "Aug 16, 2022" +--- + +- tiktok videos can now be downloaded without watermark, you just have to enable it in video settings (+)! +- you now can pass "u" query to main website to fill out the input area right away (co.wukko.me?u=your_link_here). +- added ability to select text in certain areas of website. +- some internal stuff has been cleaned up. + +follow cobalt's twitter account for polls, updates, and more: [@justusecobalt](https://twitter.com/justusecobalt) \ No newline at end of file diff --git a/web/changelogs/3.2.md b/web/changelogs/3.2.md new file mode 100644 index 00000000..5896eb05 --- /dev/null +++ b/web/changelogs/3.2.md @@ -0,0 +1,12 @@ +--- +title: ukrainian localization and new error popup +date: "Aug 19, 2022" +--- + +- added ukrainian localization (thanks to löffel). +- new error popup! it's now prettier, more compact, and has an easily accessible close button. +- russian localization has been patched up a bit +- cleaned up css a bit +- added github contributors to made with love message. +- emojis have been tuned to have the same shade of yellow. +- updated translation guidelines in readme a bit. \ No newline at end of file diff --git a/web/changelogs/3.3.md b/web/changelogs/3.3.md new file mode 100644 index 00000000..39f50d8c --- /dev/null +++ b/web/changelogs/3.3.md @@ -0,0 +1,17 @@ +--- +title: soundcloud and better usability +date: "Sep 3, 2022" +--- + +- added ability to save images from tiktok conveniently, and without watermarks. +- it's now way easier to contribute translations to cobalt. read more on how to do it [on github](https://github.com/imputnet/cobalt#how-to-contribute-translations). in short, you don't need to fork the repo anymore, everything is handled through crowdin :D +- updated readme in github repo to make it easier to read and understand. +- began to add more descriptive errors, more to come soon. + +internal stuff: +- remade entirety of tiktok module and merged it with douyin one. now both (basically identical) platforms have perfect parity of download features. +- cleaned up the twitter module, now it's way more compact and easy to read. +- moved changelog out of english localization. +- other small improvements and fixes. + +follow cobalt's twitter account for polls, updates, and more: [@justusecobalt](https://twitter.com/justusecobalt) \ No newline at end of file diff --git a/web/changelogs/3.4.md b/web/changelogs/3.4.md new file mode 100644 index 00000000..c781af17 --- /dev/null +++ b/web/changelogs/3.4.md @@ -0,0 +1,15 @@ +--- +title: tiktok images and better localization +date: "Sep 3, 2022" +--- + +- added ability to save images from tiktok conveniently, and without watermarks. +- it's now way easier to contribute translations to cobalt. read more on how to do it [on github](https://github.com/imputnet/cobalt#how-to-contribute-translations). in short, you don't need to fork the repo anymore, everything is handled through crowdin :D +- updated readme in github repo to make it easier to read and understand. +- began to add more descriptive errors, more to come soon. + +internal stuff: +- remade entirety of tiktok module and merged it with douyin one. now both (basically identical) platforms have perfect parity of download features. +- cleaned up the twitter module, now it's way more compact and easy to read. +- moved changelog out of english localization. +- other small improvements and fixes. \ No newline at end of file From f93f3cd55886537334fa35176ba22341a17316de Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 21 Jul 2024 22:49:26 +0600 Subject: [PATCH 244/334] web/DownloadButton: fallback if status isn't supported --- web/src/components/save/buttons/DownloadButton.svelte | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/web/src/components/save/buttons/DownloadButton.svelte b/web/src/components/save/buttons/DownloadButton.svelte index 40b78942..55657ddf 100644 --- a/web/src/components/save/buttons/DownloadButton.svelte +++ b/web/src/components/save/buttons/DownloadButton.svelte @@ -118,6 +118,14 @@ }) } } + + changeDownloadButton("error"); + restoreDownloadButton(); + + return createDialog({ + ...defaultErrorPopup as DialogInfo, + bodyText: "unknown/unsupported status" + }) }; From bb446ecf3ee477bec637b96f6167d66fd6eb2727 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 21 Jul 2024 17:26:21 +0000 Subject: [PATCH 245/334] web: add Optional type and use it --- web/src/components/changelog/ChangelogEntry.svelte | 3 ++- web/src/components/dialog/SmallDialog.svelte | 7 ++++--- web/src/components/misc/Skeleton.svelte | 8 +++++--- web/src/components/save/Omnibox.svelte | 3 ++- web/src/lib/api.ts | 5 +++-- web/src/lib/types/generic.ts | 1 + web/src/routes/updates/+page.svelte | 3 ++- 7 files changed, 19 insertions(+), 11 deletions(-) diff --git a/web/src/components/changelog/ChangelogEntry.svelte b/web/src/components/changelog/ChangelogEntry.svelte index 4fdc1129..75748940 100644 --- a/web/src/components/changelog/ChangelogEntry.svelte +++ b/web/src/components/changelog/ChangelogEntry.svelte @@ -1,10 +1,11 @@ + + + + diff --git a/web/src/components/dialog/DialogButtons.svelte b/web/src/components/dialog/DialogButtons.svelte new file mode 100644 index 00000000..5f086a78 --- /dev/null +++ b/web/src/components/dialog/DialogButtons.svelte @@ -0,0 +1,61 @@ + + + + + diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index 7a9550fe..61503fcd 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -1,7 +1,9 @@ @@ -18,11 +20,56 @@ buttons={dialog.buttons} /> {/if} + + {#if dialog.type === "picker"} + + {/if} {/each}
diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte new file mode 100644 index 00000000..5c5c0d61 --- /dev/null +++ b/web/src/components/dialog/PickerDialog.svelte @@ -0,0 +1,231 @@ + + + +
+ +
+ {#if items} + {#each items as item} + + {/each} + {/if} +
+ {#if buttons} + + {/if} +
+ + +
+ + diff --git a/web/src/components/dialog/PickerItem.svelte b/web/src/components/dialog/PickerItem.svelte new file mode 100644 index 00000000..b56abcc9 --- /dev/null +++ b/web/src/components/dialog/PickerItem.svelte @@ -0,0 +1,65 @@ + + + + + diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 3a4cdddf..b2951d62 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -1,12 +1,14 @@ diff --git a/web/src/lib/download.ts b/web/src/lib/download.ts new file mode 100644 index 00000000..e08320ef --- /dev/null +++ b/web/src/lib/download.ts @@ -0,0 +1,9 @@ +import { device } from "$lib/device"; + +export const downloadFile = (url: string) => { + if (device.is.iOS) { + return navigator?.share({ url }).catch(() => {}); + } else { + return window.open(url, "_blank"); + } +}; diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index 6630fd6f..f6d2439d 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -9,13 +9,20 @@ export type DialogButton = { export type SmallDialogIcons = "warn-red"; +export type DialogPickerItem = { + type?: 'photo' | 'video', + url: string, + thumb?: string, +} + export type DialogInfo = { id: string, - type: "small", + type: "small" | "picker", meowbalt?: MeowbaltEmotions, icon?: SmallDialogIcons, title?: string, bodyText?: string, bodySubText?: string, - buttons: DialogButton[], + buttons?: DialogButton[], + items?: DialogPickerItem[], } From 4e4f7af43710e53adb3b6398d129792699e4df89 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Mon, 22 Jul 2024 08:38:06 +0000 Subject: [PATCH 249/334] web/settings: types for preparation for future migrations --- web/src/lib/state/settings.ts | 18 +++++++++--------- web/src/lib/types/generic.ts | 2 +- web/src/lib/types/settings.ts | 13 +++++++++++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/web/src/lib/state/settings.ts b/web/src/lib/state/settings.ts index 79dfdc31..e19c50bb 100644 --- a/web/src/lib/state/settings.ts +++ b/web/src/lib/state/settings.ts @@ -1,15 +1,15 @@ import { derived, readable, type Updater } from 'svelte/store'; import { merge } from 'ts-deepmerge'; -import type { RecursivePartial } from '../types/generic'; -import type { CobaltSettings } from '../types/settings'; +import type { + CobaltSettings, + PartialSettings, + AllPartialSettingsWithSchema +} from '../types/settings'; import { migrateOldSettings } from '../settings/migrate'; import defaultSettings from '../settings/defaults'; -type PartialSettings = RecursivePartial; -type PartialSettingsWithSchema = RecursivePartial & { schemaVersion: number }; - const updatePlausiblePreference = (settings: PartialSettings) => { if (settings.privacy?.disableAnalytics) { localStorage.setItem('plausible_ignore', 'true'); @@ -27,18 +27,18 @@ const writeToStorage = (settings: PartialSettings) => { return settings; } -type Migrator = (s: PartialSettings) => PartialSettings; +type Migrator = (s: AllPartialSettingsWithSchema) => AllPartialSettingsWithSchema; const migrations: Record = { } -const migrate = (settings: PartialSettingsWithSchema) => { +const migrate = (settings: AllPartialSettingsWithSchema): PartialSettings => { return Object.keys(migrations) .map(Number) .filter(version => version > settings.schemaVersion) .reduce((settings, migrationVersion) => { return migrations[migrationVersion](settings); - }, settings as PartialSettings); + }, settings as AllPartialSettingsWithSchema); } const loadFromStorage = () => { @@ -52,7 +52,7 @@ const loadFromStorage = () => { return {}; } - const parsed = JSON.parse(settings) as PartialSettingsWithSchema; + const parsed = JSON.parse(settings) as AllPartialSettingsWithSchema; if (parsed.schemaVersion < defaultSettings.schemaVersion) { return migrate(parsed); } diff --git a/web/src/lib/types/generic.ts b/web/src/lib/types/generic.ts index a03d969f..9807cea5 100644 --- a/web/src/lib/types/generic.ts +++ b/web/src/lib/types/generic.ts @@ -8,4 +8,4 @@ export type RecursivePartial = { }; export type DefaultImport = () => Promise<{ default: T }>; -export type Optional = T | undefined; \ No newline at end of file +export type Optional = T | undefined; diff --git a/web/src/lib/types/settings.ts b/web/src/lib/types/settings.ts index bfeb2d10..5965bf49 100644 --- a/web/src/lib/types/settings.ts +++ b/web/src/lib/types/settings.ts @@ -1,4 +1,5 @@ import languages from '$i18n/languages.json'; +import type { RecursivePartial } from './generic'; export const themeOptions = ["auto", "light", "dark"] as const; export const audioFormatOptions = ["best", "mp3", "ogg", "wav", "opus"] as const; @@ -37,12 +38,20 @@ type CobaltSettingsSave = { youtubeDubBrowserLang: boolean, }; -export type CobaltSettings = { - schemaVersion: number, +export type CurrentCobaltSettings = { + schemaVersion: 2, advanced: CobaltSettingsAdvanced, appearance: CobaltSettingsAppearance, save: CobaltSettingsSave, privacy: CobaltSettingsPrivacy }; +export type CobaltSettings = CurrentCobaltSettings; + +export type PartialSettings = RecursivePartial; +export type PartialSettingsWithSchema = RecursivePartial & { schemaVersion: number }; + +export type AllSchemaVersions = CurrentCobaltSettings; +export type AllPartialSettingsWithSchema = RecursivePartial & { schemaVersion: number }; + export type DownloadModeOption = CobaltSettings['save']['downloadMode']; From 7c5b703e373b6c8a5480304f080f54678d109d00 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Mon, 22 Jul 2024 09:06:11 +0000 Subject: [PATCH 250/334] web/dialog: refactor types and logic --- web/src/components/dialog/DialogHolder.svelte | 4 +--- .../save/buttons/DownloadButton.svelte | 8 ++++---- web/src/lib/types/dialog.ts | 17 +++++++++++++---- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index 61503fcd..a77607c3 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -19,9 +19,7 @@ bodySubText={dialog.bodySubText} buttons={dialog.buttons} /> - {/if} - - {#if dialog.type === "picker"} + {:else if dialog.type === "picker"} Date: Mon, 22 Jul 2024 15:13:51 +0600 Subject: [PATCH 251/334] web/picker: add item type icons and improve accessibility --- web/i18n/en/a11y/dialog.json | 3 +- web/src/components/dialog/PickerDialog.svelte | 10 +++- web/src/components/dialog/PickerItem.svelte | 52 +++++++++++++++++-- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/web/i18n/en/a11y/dialog.json b/web/i18n/en/a11y/dialog.json index 451d74cf..cdade377 100644 --- a/web/i18n/en/a11y/dialog.json +++ b/web/i18n/en/a11y/dialog.json @@ -1,3 +1,4 @@ { - "picker.item.generic": "media thumbnail" + "picker.item.photo": "photo thumbnail", + "picker.item.video": "video thumbnail" } diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte index 5c5c0d61..c1bb82a5 100644 --- a/web/src/components/dialog/PickerDialog.svelte +++ b/web/src/components/dialog/PickerDialog.svelte @@ -50,6 +50,14 @@ open = true; }); } + + // item id for alt text + let counter = 0; + + const itemNumber = () => { + counter++ + return counter + } {#if items} {#each items as item} - + {/each} {/if}
diff --git a/web/src/components/dialog/PickerItem.svelte b/web/src/components/dialog/PickerItem.svelte index b56abcc9..e53dcfe2 100644 --- a/web/src/components/dialog/PickerItem.svelte +++ b/web/src/components/dialog/PickerItem.svelte @@ -6,9 +6,18 @@ import Skeleton from "$components/misc/Skeleton.svelte"; + import IconMovie from "@tabler/icons-svelte/IconMovie.svelte"; + import IconPhoto from "@tabler/icons-svelte/IconPhoto.svelte"; + export let item: DialogPickerItem; + export let number: number; let imageLoaded = false; + + let itemType = item.type; + if (!itemType) { + itemType = "photo" + } From 705fac16a69cd97b3713b032954d785c184f2cde Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Mon, 22 Jul 2024 09:24:17 +0000 Subject: [PATCH 252/334] web/dialog: internal refactor --- web/src/components/dialog/DialogHolder.svelte | 19 ++++--------------- web/src/components/dialog/PickerDialog.svelte | 16 ++++------------ web/src/components/dialog/SmallDialog.svelte | 12 ++++++------ 3 files changed, 14 insertions(+), 33 deletions(-) diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index a77607c3..72941b1a 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -9,22 +9,11 @@
{#each $dialogs as dialog} - {#if dialog.type === "small"} - + {@const { type, ...data } = dialog} + {#if type === "small"} + {:else if dialog.type === "picker"} - + {/if} {/each}
diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte index c1bb82a5..fe269cee 100644 --- a/web/src/components/dialog/PickerDialog.svelte +++ b/web/src/components/dialog/PickerDialog.svelte @@ -15,8 +15,8 @@ import IconBoxMultiple from "@tabler/icons-svelte/IconBoxMultiple.svelte"; export let id: string; - export let items: Optional; - export let buttons: Optional; + export let items: Optional = undefined; + export let buttons: Optional = undefined; let dialogDescription = "dialog.picker.description."; @@ -50,14 +50,6 @@ open = true; }); } - - // item id for alt text - let counter = 0; - - const itemNumber = () => { - counter++ - return counter - }
{#if items} - {#each items as item} - + {#each items as item, i} + {/each} {/if}
diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index b2951d62..d54f2b13 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -13,12 +13,12 @@ import IconAlertTriangle from "@tabler/icons-svelte/IconAlertTriangle.svelte"; export let id: string; - export let meowbalt: Optional; - export let icon: Optional; - export let title: string = ""; - export let bodyText: string = ""; - export let bodySubText: string = ""; - export let buttons: Optional; + export let meowbalt: Optional = undefined; + export let icon: Optional = undefined; + export let title = ""; + export let bodyText = ""; + export let bodySubText = ""; + export let buttons: Optional = undefined; let dialogParent: HTMLDialogElement; From c03337fed99e42c4461aece91642effce909252d Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Mon, 22 Jul 2024 10:11:23 +0000 Subject: [PATCH 253/334] web/skeleton: don't render if hidden --- web/src/components/misc/Skeleton.svelte | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/src/components/misc/Skeleton.svelte b/web/src/components/misc/Skeleton.svelte index bb0b295f..7f625e4b 100644 --- a/web/src/components/misc/Skeleton.svelte +++ b/web/src/components/misc/Skeleton.svelte @@ -10,16 +10,17 @@ $: style = [ width && `width: ${width}`, - height && `height: ${height}`, - hidden && `display: none` + height && `height: ${height}` ].filter(a => a).join(';'); +{#if hidden !== true}
+{/if} From d170f619d2d1f33627cd8539e9643cf8ba857ab1 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Mon, 22 Jul 2024 10:17:06 +0000 Subject: [PATCH 255/334] web: use conditionals instead of special classes where it makes sense --- web/src/components/misc/NotchSticker.svelte | 12 +++++------- web/src/routes/settings/+layout.svelte | 12 +++++------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/web/src/components/misc/NotchSticker.svelte b/web/src/components/misc/NotchSticker.svelte index 84c3cc76..7dd45af2 100644 --- a/web/src/components/misc/NotchSticker.svelte +++ b/web/src/components/misc/NotchSticker.svelte @@ -39,9 +39,11 @@ } - +{#if state !== "hidden"} + +{/if} \ No newline at end of file diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 2cf815c9..d5fe935d 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -76,6 +76,7 @@ --button-elevated: #e3e3e3; --button-elevated-hover: #dadada; + --button-elevated-shimmer: #ededed; --popup-bg: #f1f1f1; --popup-stroke: rgba(0, 0, 0, 0.08); @@ -123,6 +124,13 @@ var(--button), var(--button-hover) ); + + --skeleton-gradient-elevated: linear-gradient( + 90deg, + var(--button-elevated), + var(--button-elevated-shimmer), + var(--button-elevated) + ); } :global([data-theme="dark"]) { @@ -143,7 +151,7 @@ --button-box-shadow: 0 0 0 1.5px var(--button-stroke) inset; --button-elevated: #282828; - --button-elevated-hover: #2f2f2f; + --button-elevated-hover: #323232; --popup-bg: #191919; --popup-stroke: rgba(255, 255, 255, 0.08); @@ -173,6 +181,13 @@ var(--button-hover), var(--button) ); + + --skeleton-gradient-elevated: linear-gradient( + 90deg, + var(--button-elevated), + var(--button-elevated-hover), + var(--button-elevated) + ); } :global([data-theme="light"] [data-reduce-transparency="true"]) { From bdd572ea5185ba63b64d2b4850cbbe4eb5ce4684 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 09:59:08 +0600 Subject: [PATCH 261/334] web/dialogs: reduce margin on mobile --- web/src/components/dialog/PickerDialog.svelte | 2 +- web/src/components/dialog/SmallDialog.svelte | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte index db01c9cd..ef2089a4 100644 --- a/web/src/components/dialog/PickerDialog.svelte +++ b/web/src/components/dialog/PickerDialog.svelte @@ -169,7 +169,7 @@ @media screen and (max-width: 535px) { .picker-dialog { margin-bottom: calc( - var(--dialog-padding) + env(safe-area-inset-bottom) + var(--padding) / 2 + env(safe-area-inset-bottom) ); box-shadow: 0 0 0 2px var(--popup-stroke) inset; } diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index d54f2b13..9f729c48 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -98,14 +98,14 @@ text-align: center; max-width: 340px; width: calc( - 100% - var(--padding) * 2 - var(--dialog-padding) * 2 + 100% - var(--padding) - var(--dialog-padding) * 2 ); background: var(--popup-bg); box-shadow: 0 0 0 2px var(--popup-stroke) inset, 0 0 60px 10px var(--popup-bg); padding: var(--dialog-padding); - margin: var(--padding); + margin: calc(var(--padding) / 2); border-radius: 29px; position: relative; will-change: transform; @@ -148,7 +148,7 @@ @media screen and (max-width: 535px) { .small-dialog { - margin-bottom: calc(var(--padding) + env(safe-area-inset-bottom)); + margin-bottom: calc(var(--padding) / 2 + env(safe-area-inset-bottom)); box-shadow: 0 0 0 2px var(--popup-stroke) inset; } } From 8c96ccbc7bd4d2cbf1f944393b74011d964750ac Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 10:01:55 +0600 Subject: [PATCH 262/334] web/SmallDialog: make body scrollable on overflow & limit height --- web/src/components/dialog/SmallDialog.svelte | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 9f729c48..20482dd1 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -88,6 +88,7 @@ } .popup-body { + overflow-y: scroll; gap: 8px; } @@ -100,6 +101,7 @@ width: calc( 100% - var(--padding) - var(--dialog-padding) * 2 ); + max-height: 50%; background: var(--popup-bg); box-shadow: 0 0 0 2px var(--popup-stroke) inset, From 0225a7c46c4fad8c5e952079c1157c47ff6efb61 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 11:00:27 +0600 Subject: [PATCH 263/334] web/settings: simplify sidebar, add version info, flatten page navigation --- web/i18n/en/settings.json | 2 +- web/src/lib/settings/defaults.ts | 2 +- web/src/routes/settings/+layout.svelte | 46 ++++++++++++++----- .../{general => }/appearance/+page.svelte | 0 .../settings/{save => }/audio/+page.svelte | 0 .../{advanced => }/debug/+page.svelte | 0 .../{save/metadata => download}/+page.svelte | 0 .../{general => }/privacy/+page.svelte | 0 .../settings/{save => }/video/+page.svelte | 0 9 files changed, 36 insertions(+), 14 deletions(-) rename web/src/routes/settings/{general => }/appearance/+page.svelte (100%) rename web/src/routes/settings/{save => }/audio/+page.svelte (100%) rename web/src/routes/settings/{advanced => }/debug/+page.svelte (100%) rename web/src/routes/settings/{save/metadata => download}/+page.svelte (100%) rename web/src/routes/settings/{general => }/privacy/+page.svelte (100%) rename web/src/routes/settings/{save => }/video/+page.svelte (100%) diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 7273ea1e..82bfb282 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -3,7 +3,7 @@ "page.privacy": "privacy", "page.video": "video", "page.audio": "audio", - "page.metadata": "metadata", + "page.download": "downloading", "page.advanced": "advanced", "page.debug": "debug information", diff --git a/web/src/lib/settings/defaults.ts b/web/src/lib/settings/defaults.ts index c8bdb8a6..38725766 100644 --- a/web/src/lib/settings/defaults.ts +++ b/web/src/lib/settings/defaults.ts @@ -39,7 +39,7 @@ const defaultSettingsPage = () => { } } - return "/settings/general/appearance"; + return "/settings/appearance"; } export default defaultSettings; diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index b76b3f8d..747ff401 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -2,6 +2,7 @@ import { page } from "$app/stores"; import settings from "$lib/state/settings"; + import { version } from "$lib/version"; import { t } from "$lib/i18n/translations"; @@ -12,7 +13,7 @@ import IconMovie from "@tabler/icons-svelte/IconMovie.svelte"; import IconMusic from "@tabler/icons-svelte/IconMusic.svelte"; - import IconFileSettings from "@tabler/icons-svelte/IconFileSettings.svelte"; + import IconFileDownload from "@tabler/icons-svelte/IconFileDownload.svelte"; import IconSettingsBolt from "@tabler/icons-svelte/IconSettingsBolt.svelte"; import IconBug from "@tabler/icons-svelte/IconBug.svelte"; import IconLock from "@tabler/icons-svelte/IconLock.svelte"; @@ -24,6 +25,8 @@ let screenWidth: number; + $: versionText = `v.${$version.version}-${$version.commit.slice(0, 7)}`; + $: currentPageTitle = $page.url.pathname.split("/").at(-1); $: stringPageTitle = currentPageTitle !== "settings" ? ` / ${$t(`settings.page.${currentPageTitle}`)}` : ""; @@ -68,51 +71,56 @@ {/if} {:else} +
+ {versionText} +

{$t("tabs.settings")}

{/if}
@@ -180,7 +194,7 @@ } #settings-sidebar { - gap: 24px; + gap: var(--padding); } #settings-navigation { @@ -192,6 +206,14 @@ --back-padding: calc(var(--padding) / 2); } + .settings-version { + padding: 0; + } + + .settings-version.center { + text-align: center; + } + .back-button { display: flex; align-items: center; diff --git a/web/src/routes/settings/general/appearance/+page.svelte b/web/src/routes/settings/appearance/+page.svelte similarity index 100% rename from web/src/routes/settings/general/appearance/+page.svelte rename to web/src/routes/settings/appearance/+page.svelte diff --git a/web/src/routes/settings/save/audio/+page.svelte b/web/src/routes/settings/audio/+page.svelte similarity index 100% rename from web/src/routes/settings/save/audio/+page.svelte rename to web/src/routes/settings/audio/+page.svelte diff --git a/web/src/routes/settings/advanced/debug/+page.svelte b/web/src/routes/settings/debug/+page.svelte similarity index 100% rename from web/src/routes/settings/advanced/debug/+page.svelte rename to web/src/routes/settings/debug/+page.svelte diff --git a/web/src/routes/settings/save/metadata/+page.svelte b/web/src/routes/settings/download/+page.svelte similarity index 100% rename from web/src/routes/settings/save/metadata/+page.svelte rename to web/src/routes/settings/download/+page.svelte diff --git a/web/src/routes/settings/general/privacy/+page.svelte b/web/src/routes/settings/privacy/+page.svelte similarity index 100% rename from web/src/routes/settings/general/privacy/+page.svelte rename to web/src/routes/settings/privacy/+page.svelte diff --git a/web/src/routes/settings/save/video/+page.svelte b/web/src/routes/settings/video/+page.svelte similarity index 100% rename from web/src/routes/settings/save/video/+page.svelte rename to web/src/routes/settings/video/+page.svelte From ee162aa23635cf4ffef091f53ff7ee5f9923e0fa Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 12:13:40 +0600 Subject: [PATCH 264/334] web/ClearButton: fix rendering bug in safari & clean up --- .../components/save/buttons/ClearButton.svelte | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/web/src/components/save/buttons/ClearButton.svelte b/web/src/components/save/buttons/ClearButton.svelte index 9962aa1b..4847a95a 100644 --- a/web/src/components/save/buttons/ClearButton.svelte +++ b/web/src/components/save/buttons/ClearButton.svelte @@ -1,12 +1,16 @@ - From 48078e7e756f2050cf11f5faf029bde9d235405a Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 12:19:12 +0600 Subject: [PATCH 265/334] web/updates: replace chevron with arrow --- web/src/routes/updates/+page.svelte | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index 140eb046..2a8aa8f7 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -8,8 +8,8 @@ import ChangelogSkeleton from "$components/changelog/ChangelogSkeleton.svelte"; - import IconChevronLeft from "@tabler/icons-svelte/IconChevronLeft.svelte"; - import IconChevronRight from "@tabler/icons-svelte/IconChevronRight.svelte"; + import IconArrowLeft from "@tabler/icons-svelte/IconArrowLeft.svelte"; + import IconArrowRight from "@tabler/icons-svelte/IconArrowRight.svelte"; const changelogs = getAllChangelogs(); const versions = Object.keys(changelogs); @@ -72,7 +72,7 @@
{#if prev} {/if} @@ -91,7 +91,7 @@ {/await}
@@ -113,7 +113,7 @@ on:mousemove={preloadNext} > {next || ""} - + {/if}
@@ -142,6 +142,10 @@ border: none; } + button :global(svg) { + stroke-width: 1.6px; + } + .button-wrapper-desktop button:not(:focus-visible) { box-shadow: none; } From 5c6ef1913282dcae295e217df30e41b413641562 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 12:19:38 +0600 Subject: [PATCH 266/334] web/settings: update the back button icon --- web/src/routes/settings/+layout.svelte | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index 747ff401..a6e9d391 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -18,7 +18,7 @@ import IconBug from "@tabler/icons-svelte/IconBug.svelte"; import IconLock from "@tabler/icons-svelte/IconLock.svelte"; - import IconChevronLeft from "@tabler/icons-svelte/IconChevronLeft.svelte"; + import IconArrowLeft from "@tabler/icons-svelte/IconArrowLeft.svelte"; import { goto } from "$app/navigation"; import { defaultSettingsPage } from "$lib/settings/defaults"; @@ -60,7 +60,7 @@ role="button" aria-label={$t("a11y.general.back")} > - + {/if}

@@ -234,6 +234,7 @@ stroke-width: 2px; height: 22px; width: 22px; + will-change: transform; } @media screen and (max-width: 750px) { From 518f634385c1c68011c16fa5e72078916e06f11c Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 12:20:30 +0600 Subject: [PATCH 267/334] web/settings: reduce thickness of back button icon --- web/src/routes/settings/+layout.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/routes/settings/+layout.svelte b/web/src/routes/settings/+layout.svelte index a6e9d391..b09d24b1 100644 --- a/web/src/routes/settings/+layout.svelte +++ b/web/src/routes/settings/+layout.svelte @@ -231,7 +231,7 @@ } .back-button :global(svg) { - stroke-width: 2px; + stroke-width: 1.8px; height: 22px; width: 22px; will-change: transform; From 94853f0b7b5852375fa46711ec67e373d488a583 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 12:34:14 +0600 Subject: [PATCH 268/334] web/FilenamePreview: finish the component --- web/i18n/en/settings.json | 2 +- .../settings/FilenamePreview.svelte | 83 +++++++++++++++++-- web/src/routes/settings/download/+page.svelte | 10 ++- 3 files changed, 84 insertions(+), 11 deletions(-) diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 82bfb282..0127627b 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -63,7 +63,7 @@ "metadata.filename.basic": "basic", "metadata.filename.pretty": "pretty", "metadata.filename.nerdy": "nerdy", - "metadata.filename.description": "filename style using which cobalt files will be downloaded. this description is temporary as there's no dynamic preview component yet.", + "metadata.filename.description": "filename style will only be used for files processed or proxied by cobalt. some services don't support filename styles.", "metadata.filename.preview.video": "Video Title", "metadata.filename.preview.audio": "Audio Title - Audio Author", diff --git a/web/src/components/settings/FilenamePreview.svelte b/web/src/components/settings/FilenamePreview.svelte index 64fce4f4..829e1745 100644 --- a/web/src/components/settings/FilenamePreview.svelte +++ b/web/src/components/settings/FilenamePreview.svelte @@ -2,6 +2,9 @@ import settings from "$lib/state/settings"; import { t } from "$lib/i18n/translations"; + import IconMovie from "@tabler/icons-svelte/IconMovie.svelte"; + import IconMusic from "@tabler/icons-svelte/IconMusic.svelte"; + let videoFilePreview: string; let audioFilePreview: string; @@ -66,18 +69,86 @@
-
- {videoFilePreview}.{youtubeVideoExt} +
+
+ +
+
+
{`${videoFilePreview}.${youtubeVideoExt}`}
+
video file preview
+
-
- {audioFilePreview}.{audioFormat} +
+
+ +
+
+
{`${audioFilePreview}.${audioFormat}`}
+
audio file preview
+
diff --git a/web/src/routes/settings/download/+page.svelte b/web/src/routes/settings/download/+page.svelte index 1da7010f..6e6ea6f0 100644 --- a/web/src/routes/settings/download/+page.svelte +++ b/web/src/routes/settings/download/+page.svelte @@ -11,10 +11,7 @@ - + {#each filenameStyleOptions as value} {/each} + + +
+ {$t("settings.metadata.filename.description")} +
Date: Tue, 23 Jul 2024 12:44:13 +0600 Subject: [PATCH 269/334] web/changelogs: remove 3.3 changelog as it's a duplicate of 3.4 --- web/changelogs/3.3.md | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 web/changelogs/3.3.md diff --git a/web/changelogs/3.3.md b/web/changelogs/3.3.md deleted file mode 100644 index 39f50d8c..00000000 --- a/web/changelogs/3.3.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: soundcloud and better usability -date: "Sep 3, 2022" ---- - -- added ability to save images from tiktok conveniently, and without watermarks. -- it's now way easier to contribute translations to cobalt. read more on how to do it [on github](https://github.com/imputnet/cobalt#how-to-contribute-translations). in short, you don't need to fork the repo anymore, everything is handled through crowdin :D -- updated readme in github repo to make it easier to read and understand. -- began to add more descriptive errors, more to come soon. - -internal stuff: -- remade entirety of tiktok module and merged it with douyin one. now both (basically identical) platforms have perfect parity of download features. -- cleaned up the twitter module, now it's way more compact and easy to read. -- moved changelog out of english localization. -- other small improvements and fixes. - -follow cobalt's twitter account for polls, updates, and more: [@justusecobalt](https://twitter.com/justusecobalt) \ No newline at end of file From c12088e29717bec7ad7b5a1d715775eb889d7275 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 13:18:08 +0600 Subject: [PATCH 270/334] web/SmallDialog: flex container for header & icon fixes stranded padding --- web/src/components/dialog/SmallDialog.svelte | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/src/components/dialog/SmallDialog.svelte b/web/src/components/dialog/SmallDialog.svelte index 20482dd1..1e55259b 100644 --- a/web/src/components/dialog/SmallDialog.svelte +++ b/web/src/components/dialog/SmallDialog.svelte @@ -127,7 +127,15 @@ font-size: 19px; } - .popup-header .popup-icon.warn-red :global(svg) { + .popup-header, + .popup-icon { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + + .popup-icon.warn-red :global(svg) { stroke-width: 1.5px; height: 50px; width: 50px; From 314d3590ec231943924e63402223181e4fb951d3 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 23 Jul 2024 13:22:05 +0600 Subject: [PATCH 271/334] web/DialogButtons: don't apply hover effect if button is colored --- web/src/components/dialog/DialogButtons.svelte | 1 + web/src/routes/+layout.svelte | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/web/src/components/dialog/DialogButtons.svelte b/web/src/components/dialog/DialogButtons.svelte index 5f086a78..3b9943e1 100644 --- a/web/src/components/dialog/DialogButtons.svelte +++ b/web/src/components/dialog/DialogButtons.svelte @@ -9,6 +9,7 @@ {#each buttons as button} + + +
+ + +
+

make a recurring donation via liberapay

+
+ + + +
+
+ +
+

donate with cryptocurrencies

+
+ {#each Object.entries(donate.crypto) as [ name, address ]} +
+
{ name } (press to copy)
+ +
+ {/each} +
+
+ + + From e0bc0553ca4dd54b60938e84142176e7808279a1 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Fri, 26 Jul 2024 09:05:14 +0000 Subject: [PATCH 294/334] web/donate: fix price padding --- web/src/routes/donate/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/routes/donate/+page.svelte b/web/src/routes/donate/+page.svelte index f305ce3a..2469c4ea 100644 --- a/web/src/routes/donate/+page.svelte +++ b/web/src/routes/donate/+page.svelte @@ -216,7 +216,7 @@ vertical-align: middle; } - section h3 { + section > h3 { padding: var(--padding) 0; } From 7427788efd791da9ddbdd99e3ab2e7e73b2529d4 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 26 Jul 2024 21:34:18 +0600 Subject: [PATCH 295/334] web/PickerItem: add support for gifs in picker --- web/i18n/en/a11y/dialog.json | 3 ++- web/src/components/dialog/PickerItem.svelte | 5 ++++- web/src/lib/types/dialog.ts | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/web/i18n/en/a11y/dialog.json b/web/i18n/en/a11y/dialog.json index cdade377..84df736b 100644 --- a/web/i18n/en/a11y/dialog.json +++ b/web/i18n/en/a11y/dialog.json @@ -1,4 +1,5 @@ { "picker.item.photo": "photo thumbnail", - "picker.item.video": "video thumbnail" + "picker.item.video": "video thumbnail", + "picker.item.gif": "gif thumbnail" } diff --git a/web/src/components/dialog/PickerItem.svelte b/web/src/components/dialog/PickerItem.svelte index fa159981..f5071885 100644 --- a/web/src/components/dialog/PickerItem.svelte +++ b/web/src/components/dialog/PickerItem.svelte @@ -8,6 +8,7 @@ import IconMovie from "@tabler/icons-svelte/IconMovie.svelte"; import IconPhoto from "@tabler/icons-svelte/IconPhoto.svelte"; + import IconGif from "@tabler/icons-svelte/IconGif.svelte"; export let item: DialogPickerItem; export let number: number; @@ -21,6 +22,8 @@
{#if itemType === "video"} + {:else if itemType === "gif"} + {:else} {/if} @@ -31,7 +34,7 @@ src={item.thumb ?? item.url} class:loading={!imageLoaded} - class:video-thumbnail={itemType === "video"} + class:video-thumbnail={["video", "gif"].includes(itemType)} on:load={() => imageLoaded = true} alt="{$t(`a11y.dialog.picker.item.${itemType}`)} {number}" diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index 2e61946d..f01af5e4 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -10,7 +10,7 @@ export type DialogButton = { export type SmallDialogIcons = "warn-red"; export type DialogPickerItem = { - type?: 'photo' | 'video', + type?: 'photo' | 'video' | 'gif', url: string, thumb?: string, } From b3d8a9bf1c065ffdd265acd03d7cb06649eccae3 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Fri, 26 Jul 2024 17:00:01 +0000 Subject: [PATCH 296/334] web/donate: minor css fixes --- web/src/routes/donate/+page.svelte | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/web/src/routes/donate/+page.svelte b/web/src/routes/donate/+page.svelte index 2469c4ea..65b3c130 100644 --- a/web/src/routes/donate/+page.svelte +++ b/web/src/routes/donate/+page.svelte @@ -193,7 +193,9 @@ + > + { address } +
{/each}
@@ -204,6 +206,7 @@ #donate-page { max-width: 850px; margin: 0 auto; + overflow-x: hidden; padding: var(--padding); } @@ -271,7 +274,9 @@ width: 100%; display: block; text-align: left; - font-size: 12px; + font-size: .75em; + overflow: hidden; + text-overflow: ellipsis; } .crypto-wallets { From 82ecf16d79108610a96146edcf1e01512f946508 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Fri, 26 Jul 2024 17:06:03 +0000 Subject: [PATCH 297/334] web/donate: disable padding-left for wallets on mobile --- web/src/routes/donate/+page.svelte | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/web/src/routes/donate/+page.svelte b/web/src/routes/donate/+page.svelte index 65b3c130..efd65747 100644 --- a/web/src/routes/donate/+page.svelte +++ b/web/src/routes/donate/+page.svelte @@ -228,13 +228,6 @@ justify-content: space-evenly; } - @media screen and (max-width: 750px) { - .donation-options { - flex-direction: column; - gap: 1em; - align-items: center; - } - } .donation-option { display: flex; flex-direction: column; @@ -292,10 +285,22 @@ gap: .25em; } - input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } + + @media screen and (max-width: 750px) { + .donation-options { + flex-direction: column; + gap: 1em; + align-items: center; + } + + .crypto-wallets { + padding-left: 0; + } + } + From 0a7747c497b227a1b0b432012167c2fbe1803ce8 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 27 Jul 2024 12:53:57 +0600 Subject: [PATCH 298/334] web/dialogs: move duplicated dialog css to parent --- web/src/components/dialog/DialogHolder.svelte | 23 ++++++++++++++++++ web/src/components/dialog/PickerDialog.svelte | 22 ----------------- web/src/components/dialog/SmallDialog.svelte | 24 +++---------------- 3 files changed, 26 insertions(+), 43 deletions(-) diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index 72941b1a..141491d0 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -95,6 +95,25 @@ -webkit-backdrop-filter: none !important; } + :global(.dialog-body) { + --dialog-padding: 18px; + + display: flex; + flex-direction: column; + align-items: center; + + background: var(--popup-bg); + box-shadow: + 0 0 0 2px var(--popup-stroke) inset, + 0 0 60px 10px var(--popup-bg); + border-radius: 29px; + + padding: var(--dialog-padding); + + position: relative; + will-change: transform; + } + :global(.open .dialog-body) { animation: modal-in 0.35s; } @@ -107,6 +126,10 @@ @media screen and (max-width: 535px) { :global(.open .dialog-body) { animation: modal-in-mobile 0.4s; + margin-bottom: calc( + var(--padding) / 2 + env(safe-area-inset-bottom) + ); + box-shadow: 0 0 0 2px var(--popup-stroke) inset; } } diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte index ef2089a4..34d8d0b7 100644 --- a/web/src/components/dialog/PickerDialog.svelte +++ b/web/src/components/dialog/PickerDialog.svelte @@ -88,27 +88,12 @@ From 778190b2b3b541456122c21443612022a9fc6dc0 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 27 Jul 2024 14:24:24 +0600 Subject: [PATCH 299/334] web/dialogs: create a container for reused code --- .../components/dialog/DialogContainer.svelte | 33 +++++++++++++++ web/src/components/dialog/PickerDialog.svelte | 42 ++++--------------- web/src/components/dialog/SmallDialog.svelte | 36 +++------------- 3 files changed, 48 insertions(+), 63 deletions(-) create mode 100644 web/src/components/dialog/DialogContainer.svelte diff --git a/web/src/components/dialog/DialogContainer.svelte b/web/src/components/dialog/DialogContainer.svelte new file mode 100644 index 00000000..0827bc19 --- /dev/null +++ b/web/src/components/dialog/DialogContainer.svelte @@ -0,0 +1,33 @@ + + + + + diff --git a/web/src/components/dialog/PickerDialog.svelte b/web/src/components/dialog/PickerDialog.svelte index 34d8d0b7..ce7b55f5 100644 --- a/web/src/components/dialog/PickerDialog.svelte +++ b/web/src/components/dialog/PickerDialog.svelte @@ -1,13 +1,13 @@ - -
+ +
+ diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 4e21beac..adf439d4 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -333,6 +333,18 @@ background-color: var(--button-hover); } + :global(.button.elevated) { + background-color: var(--button-elevated); + } + + :global(.button.elevated:active) { + background-color: var(--button-elevated-hover); + } + + :global(.button.elevated:not(:focus-visible)) { + box-shadow: none; + } + :global(.button.active) { color: var(--primary); background-color: var(--secondary); @@ -353,6 +365,10 @@ :global(button:hover) { background-color: var(--button-hover); } + + :global(.button.elevated:hover) { + background-color: var(--button-elevated-hover); + } :global(.button.active:not(.color):hover) { background-color: var(--button-active-hover); From a9f9a3e34225ec82e9a03aec6a91ab97dc7052d4 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 27 Jul 2024 15:07:26 +0600 Subject: [PATCH 301/334] web/dialogs: add saving method dialog --- web/i18n/en/dialog.json | 7 +- .../buttons/VerticalActionButton.svelte | 31 ++++ web/src/components/dialog/DialogHolder.svelte | 6 +- web/src/components/dialog/SavingDialog.svelte | 139 ++++++++++++++++++ web/src/components/misc/Meowbalt.svelte | 5 +- web/src/lib/download.ts | 42 +++++- web/src/lib/types/dialog.ts | 10 +- 7 files changed, 230 insertions(+), 10 deletions(-) create mode 100644 web/src/components/buttons/VerticalActionButton.svelte create mode 100644 web/src/components/dialog/SavingDialog.svelte diff --git a/web/i18n/en/dialog.json b/web/i18n/en/dialog.json index bfe30bec..75f673f8 100644 --- a/web/i18n/en/dialog.json +++ b/web/i18n/en/dialog.json @@ -4,6 +4,9 @@ "button.reset": "reset", "button.done": "done", "button.downloadAudio": "download audio", + "button.download": "download", + "button.share": "share", + "button.copy": "copy", "reset.title": "reset all settings?", "reset.body": "are you sure you want to reset all settings? this action is immediate and irreversible.", @@ -11,5 +14,7 @@ "picker.title": "select what to save", "picker.description.desktop": "click an item to save it. images can also be saved via the right click menu.", "picker.description.phone": "press an item to save it. images can also be saved with a long press.", - "picker.description.ios": "press an item to save it with a shortcut. images can also be saved with a long press." + "picker.description.ios": "press an item to save it with a shortcut. images can also be saved with a long press.", + + "saving.title": "choose how to save" } diff --git a/web/src/components/buttons/VerticalActionButton.svelte b/web/src/components/buttons/VerticalActionButton.svelte new file mode 100644 index 00000000..a9d37689 --- /dev/null +++ b/web/src/components/buttons/VerticalActionButton.svelte @@ -0,0 +1,31 @@ + + + + + diff --git a/web/src/components/dialog/DialogHolder.svelte b/web/src/components/dialog/DialogHolder.svelte index 141491d0..7a481d42 100644 --- a/web/src/components/dialog/DialogHolder.svelte +++ b/web/src/components/dialog/DialogHolder.svelte @@ -3,6 +3,7 @@ import SmallDialog from "$components/dialog/SmallDialog.svelte"; import PickerDialog from "$components/dialog/PickerDialog.svelte"; + import SavingDialog from "$components/dialog/SavingDialog.svelte"; $: backdropVisible = $dialogs.length > 0; @@ -10,10 +11,13 @@
{#each $dialogs as dialog} {@const { type, ...data } = dialog} + {#if type === "small"} - {:else if dialog.type === "picker"} + {:else if type === "picker"} + {:else if type === "saving"} + {/if} {/each}
diff --git a/web/src/components/dialog/SavingDialog.svelte b/web/src/components/dialog/SavingDialog.svelte new file mode 100644 index 00000000..6e039df8 --- /dev/null +++ b/web/src/components/dialog/SavingDialog.svelte @@ -0,0 +1,139 @@ + + + + + + + + + diff --git a/web/src/components/misc/Meowbalt.svelte b/web/src/components/misc/Meowbalt.svelte index 13c52556..26ad14b3 100644 --- a/web/src/components/misc/Meowbalt.svelte +++ b/web/src/components/misc/Meowbalt.svelte @@ -21,11 +21,14 @@ object-fit: cover; } - .think, .error { height: 160px; } + .question { + height: 140px; + } + .error { margin-left: 25px; } diff --git a/web/src/lib/download.ts b/web/src/lib/download.ts index e08320ef..74f65606 100644 --- a/web/src/lib/download.ts +++ b/web/src/lib/download.ts @@ -1,9 +1,41 @@ -import { device } from "$lib/device"; +import { get } from "svelte/store"; + +import { app, device } from "$lib/device"; +import settings from "$lib/state/settings"; + +import { createDialog } from "$lib/dialogs"; + +export const openURL = (url: string) => { + return window.open(url, "_blank"); +} + +export const shareURL = async (url: string) => { + try { + return await navigator?.share({ url }); + } catch { + return false; + } +} + +export const copyURL = async (url: string) => { + try { + return await navigator?.clipboard.writeText(url); + } catch { + return false; + } +} export const downloadFile = (url: string) => { - if (device.is.iOS) { - return navigator?.share({ url }).catch(() => {}); + const savingPreference = get(settings).save.downloadPopup; + if (savingPreference) { + createDialog({ + type: "saving", + id: "saving", + url + }) + } else if (device.is.iOS && app.is.installed) { + return shareURL(url); } else { - return window.open(url, "_blank"); + return openURL(url); } -}; +} diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index f01af5e4..f7951309 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -17,7 +17,6 @@ export type DialogPickerItem = { type Dialog = { id: string, - buttons?: DialogButton[], }; type SmallDialog = Dialog & { @@ -27,11 +26,18 @@ type SmallDialog = Dialog & { title?: string, bodyText?: string, bodySubText?: string, + buttons?: DialogButton[], }; type PickerDialog = Dialog & { type: "picker", items?: DialogPickerItem[], + buttons?: DialogButton[], }; -export type DialogInfo = SmallDialog | PickerDialog; \ No newline at end of file +type SavingDialog = Dialog & { + type: "saving", + url: string, +}; + +export type DialogInfo = SmallDialog | PickerDialog | SavingDialog; From 26eaac5742ce00971a232b230edf4684cbfc97e9 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 27 Jul 2024 15:07:38 +0600 Subject: [PATCH 302/334] web/ActionButton: clean up --- web/src/components/buttons/ActionButton.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/src/components/buttons/ActionButton.svelte b/web/src/components/buttons/ActionButton.svelte index 3c2a4433..8eaa5b47 100644 --- a/web/src/components/buttons/ActionButton.svelte +++ b/web/src/components/buttons/ActionButton.svelte @@ -1,6 +1,8 @@ + + diff --git a/web/src/components/dialog/DialogButtons.svelte b/web/src/components/dialog/DialogButtons.svelte index 082d20e0..f239865f 100644 --- a/web/src/components/dialog/DialogButtons.svelte +++ b/web/src/components/dialog/DialogButtons.svelte @@ -1,23 +1,14 @@ @@ -31,14 +22,4 @@ border-radius: var(--border-radius); min-height: 40px; } - - .popup-button { - width: 100%; - height: 40px; - } - - .popup-button.red { - background-color: var(--red); - color: var(--white); - } diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index f7951309..0a5004db 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -4,6 +4,7 @@ export type DialogButton = { text: string, color?: "red", main: boolean, + timeout?: number, // milliseconds action: () => unknown | Promise } From f34340a06d2c42dc74c3dad954ed5228992c4b52 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 14:50:59 +0600 Subject: [PATCH 318/334] web/TransferSettings: add a timeout to import button in dialog --- web/src/components/settings/TransferSettings.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/settings/TransferSettings.svelte b/web/src/components/settings/TransferSettings.svelte index a24ad568..a238aac9 100644 --- a/web/src/components/settings/TransferSettings.svelte +++ b/web/src/components/settings/TransferSettings.svelte @@ -54,6 +54,7 @@ text: $t("dialog.button.import"), color: "red", main: true, + timeout: 5000, action: () => updateSettings(reader), }, ], From 87adffaf0276b30a4370ab5cb0155fae03e676ac Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 14:51:02 +0600 Subject: [PATCH 319/334] web/ResetSettingsButton: add a timeout to reset button in dialog --- web/src/components/buttons/ResetSettingsButton.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/buttons/ResetSettingsButton.svelte b/web/src/components/buttons/ResetSettingsButton.svelte index e6b6a61a..ee60938e 100644 --- a/web/src/components/buttons/ResetSettingsButton.svelte +++ b/web/src/components/buttons/ResetSettingsButton.svelte @@ -23,6 +23,7 @@ text: $t("dialog.button.reset"), color: "red", main: true, + timeout: 5000, action: () => resetSettings(), }, ], From 5c780a2d2e37757e2e74329399c4df85578234a0 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 18:59:58 +0600 Subject: [PATCH 320/334] web: added saving method preference, made downloading resilient --- web/i18n/en/settings.json | 9 +++-- web/src/components/dialog/SavingDialog.svelte | 4 +- web/src/lib/device.ts | 15 ++++--- web/src/lib/download.ts | 39 ++++++++++--------- web/src/lib/settings/defaults.ts | 2 +- web/src/lib/settings/migrate.ts | 2 - web/src/lib/types/settings.ts | 3 +- web/src/routes/settings/download/+page.svelte | 25 +++++++----- 8 files changed, 56 insertions(+), 43 deletions(-) diff --git a/web/i18n/en/settings.json b/web/i18n/en/settings.json index 0127627b..69555ab3 100644 --- a/web/i18n/en/settings.json +++ b/web/i18n/en/settings.json @@ -72,9 +72,12 @@ "metadata.disable.title": "disable file metadata", "metadata.disable.description": "title, artist, and other info will not be added to the file.", - "saving.method": "saving method", - "saving.ask.title": "ask how to save", - "saving.ask.description": "offer several ways to save the file instead of opening it in a new tab.", + "saving.title": "saving method", + "saving.ask": "ask", + "saving.download": "download", + "saving.share": "share", + "saving.copy": "copy", + "saving.description": "preferred way of saving the file or link from cobalt. if preferred method is unavailable or something goes wrong, cobalt will ask you what to do next.", "accessibility": "accessibility", "accessibility.transparency.title": "reduce visual transparency", diff --git a/web/src/components/dialog/SavingDialog.svelte b/web/src/components/dialog/SavingDialog.svelte index 34c84b84..5e1832ab 100644 --- a/web/src/components/dialog/SavingDialog.svelte +++ b/web/src/components/dialog/SavingDialog.svelte @@ -34,7 +34,7 @@

- {#if !(app.is.installed && device.is.iOS)} + {#if device.supports.directDownload} {/if} - {#if navigator.share !== undefined} + {#if device.supports.share} { /* if new tab got blocked by user agent, show a saving dialog */ if (!open) { - openSavingDialog(url); + return openSavingDialog(url); } } export const shareURL = async (url: string) => { - try { - return await navigator?.share({ url }); - } catch { - return false; - } + return await navigator?.share({ url }); } export const copyURL = async (url: string) => { - try { - return await navigator?.clipboard.writeText(url); - } catch { - return false; - } + return await navigator?.clipboard?.writeText(url); } export const downloadFile = (url: string) => { - const savingPreference = get(settings).save.downloadPopup; + const pref = get(settings).save.savingMethod; /* user actions (such as invoke share, open new tab) have expiration. @@ -49,11 +41,20 @@ export const downloadFile = (url: string) => { invoke an action without the user agent interrupting it. if not, we show a saving dialog for user to re-invoke that action. */ - if (savingPreference || !navigator.userActivation.isActive) { - openSavingDialog(url); - } else if (device.is.iOS && app.is.installed) { - return shareURL(url); - } else { - return openURL(url); + + if (pref === "ask" || !navigator.userActivation.isActive) { + return openSavingDialog(url); } + + try { + if (pref === "share" && device.supports.share) { + return shareURL(url); + } else if (pref === "download" && device.supports.directDownload) { + return openURL(url); + } else if (pref === "copy") { + return copyURL(url); + } + } catch {} + + return openSavingDialog(url); } diff --git a/web/src/lib/settings/defaults.ts b/web/src/lib/settings/defaults.ts index 528d2cad..58f46fec 100644 --- a/web/src/lib/settings/defaults.ts +++ b/web/src/lib/settings/defaults.ts @@ -18,8 +18,8 @@ const defaultSettings: CobaltSettings = { audioFormat: "mp3", disableMetadata: false, downloadMode: "auto", - downloadPopup: false, filenameStyle: "classic", + savingMethod: "download", tiktokH265: false, tiktokFullAudio: false, twitterGif: false, diff --git a/web/src/lib/settings/migrate.ts b/web/src/lib/settings/migrate.ts index 81feb99f..769ab360 100644 --- a/web/src/lib/settings/migrate.ts +++ b/web/src/lib/settings/migrate.ts @@ -10,7 +10,6 @@ const oldSwitcherValues = { const oldCheckboxes = [ 'audioMode', - 'downloadPopup', 'fullTikTokAudio', 'muteAudio', 'reduceTransparency', @@ -101,7 +100,6 @@ export const migrateOldSettings = () => { filenameStyle: getLiteral('filenamePattern'), tiktokFullAudio: getBool('fullTikTokAudio'), tiktokH265: getBool('tiktokH265'), - downloadPopup: getBool('downloadPopup'), disableMetadata: getBool('disableMetadata'), twitterGif: getBool('twitterGif'), youtubeDubBrowserLang: getBool('ytDub'), diff --git a/web/src/lib/types/settings.ts b/web/src/lib/types/settings.ts index 5965bf49..ff4c66b7 100644 --- a/web/src/lib/types/settings.ts +++ b/web/src/lib/types/settings.ts @@ -7,6 +7,7 @@ export const downloadModeOptions = ["auto", "audio", "mute"] as const; export const filenameStyleOptions = ["classic", "basic", "pretty", "nerdy"] as const; export const videoQualityOptions = ["max", "2160", "1440", "1080", "720", "480", "360", "240", "144"] as const; export const youtubeVideoCodecOptions = ["h264", "av1", "vp9"] as const; +export const savingMethodOptions = ["ask", "download", "share", "copy"] as const; type CobaltSettingsAppearance = { theme: typeof themeOptions[number], @@ -28,8 +29,8 @@ type CobaltSettingsSave = { audioFormat: typeof audioFormatOptions[number], disableMetadata: boolean, downloadMode: typeof downloadModeOptions[number], - downloadPopup: boolean, filenameStyle: typeof filenameStyleOptions[number], + savingMethod: typeof savingMethodOptions[number], tiktokH265: boolean, tiktokFullAudio: boolean, twitterGif: boolean, diff --git a/web/src/routes/settings/download/+page.svelte b/web/src/routes/settings/download/+page.svelte index 6e6ea6f0..5c5985b2 100644 --- a/web/src/routes/settings/download/+page.svelte +++ b/web/src/routes/settings/download/+page.svelte @@ -1,7 +1,7 @@ @@ -69,6 +70,9 @@
+
+ {bodyText} +
diff --git a/web/src/lib/download.ts b/web/src/lib/download.ts index fbd3a124..60227f21 100644 --- a/web/src/lib/download.ts +++ b/web/src/lib/download.ts @@ -1,23 +1,30 @@ import { get } from "svelte/store"; -import { device } from "$lib/device"; import settings from "$lib/state/settings"; -import { createDialog } from "$lib/dialogs"; +import { device } from "$lib/device"; +import { t } from "$lib/i18n/translations"; -export const openSavingDialog = (url: string) => - createDialog({ +import { createDialog } from "$lib/dialogs"; +import type { DialogInfo } from "$lib/types/dialog"; + +export const openSavingDialog = (url: string, body: string | void) => { + let dialogData: DialogInfo = { type: "saving", id: "saving", url - }) + } + if (body) dialogData.bodyText = body; + + createDialog(dialogData) +} export const openURL = (url: string) => { const open = window.open(url, "_blank"); /* if new tab got blocked by user agent, show a saving dialog */ if (!open) { - return openSavingDialog(url); + return openSavingDialog(url, get(t)("dialog.saving.blocked")); } } diff --git a/web/src/lib/types/dialog.ts b/web/src/lib/types/dialog.ts index 0a5004db..d3d086e1 100644 --- a/web/src/lib/types/dialog.ts +++ b/web/src/lib/types/dialog.ts @@ -39,6 +39,7 @@ type PickerDialog = Dialog & { type SavingDialog = Dialog & { type: "saving", url: string, + bodyText?: string, }; export type DialogInfo = SmallDialog | PickerDialog | SavingDialog; From 3aeebcc911ca00834a60f9e43297bdeddcef4846 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 19:20:32 +0600 Subject: [PATCH 322/334] web/SavingDialog: don't render body text parent if there's no text --- web/src/components/dialog/SavingDialog.svelte | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/web/src/components/dialog/SavingDialog.svelte b/web/src/components/dialog/SavingDialog.svelte index 4940af3c..bba591f1 100644 --- a/web/src/components/dialog/SavingDialog.svelte +++ b/web/src/components/dialog/SavingDialog.svelte @@ -70,9 +70,11 @@
-
- {bodyText} -
+ {#if bodyText} +
+ {bodyText} +
+ {/if} Date: Sun, 28 Jul 2024 23:29:32 +0600 Subject: [PATCH 323/334] web/SavingDialog: show that link was copied, better accessibility --- web/i18n/en/a11y/dialog.json | 4 +- .../buttons/VerticalActionButton.svelte | 15 +++++- web/src/components/dialog/SavingDialog.svelte | 21 ++++++-- web/src/components/misc/CopyIcon.svelte | 54 +++++++++++++++++++ 4 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 web/src/components/misc/CopyIcon.svelte diff --git a/web/i18n/en/a11y/dialog.json b/web/i18n/en/a11y/dialog.json index 84df736b..478a1587 100644 --- a/web/i18n/en/a11y/dialog.json +++ b/web/i18n/en/a11y/dialog.json @@ -1,5 +1,7 @@ { "picker.item.photo": "photo thumbnail", "picker.item.video": "video thumbnail", - "picker.item.gif": "gif thumbnail" + "picker.item.gif": "gif thumbnail", + + "saving.copied": "link copied" } diff --git a/web/src/components/buttons/VerticalActionButton.svelte b/web/src/components/buttons/VerticalActionButton.svelte index a9d37689..14602500 100644 --- a/web/src/components/buttons/VerticalActionButton.svelte +++ b/web/src/components/buttons/VerticalActionButton.svelte @@ -5,9 +5,17 @@ }; export let fill = false; export let elevated = false; + export let ariaLabel = ""; - @@ -19,6 +27,11 @@ gap: calc(var(--padding) / 2); } + .button.vertical :global(svg) { + width: 24px; + height: 24px; + } + .button.vertical.fill { width: 100%; padding: var(--padding) 0; diff --git a/web/src/components/dialog/SavingDialog.svelte b/web/src/components/dialog/SavingDialog.svelte index bba591f1..ee0a5ee4 100644 --- a/web/src/components/dialog/SavingDialog.svelte +++ b/web/src/components/dialog/SavingDialog.svelte @@ -10,16 +10,25 @@ import DialogButtons from "$components/dialog/DialogButtons.svelte"; import VerticalActionButton from "$components/buttons/VerticalActionButton.svelte"; - import IconCopy from "@tabler/icons-svelte/IconCopy.svelte"; import IconShare2 from "@tabler/icons-svelte/IconShare2.svelte"; import IconDownload from "@tabler/icons-svelte/IconDownload.svelte"; import IconFileDownload from "@tabler/icons-svelte/IconFileDownload.svelte"; + import CopyIcon from "$components/misc/CopyIcon.svelte"; + export let id: string; export let url: string; export let bodyText: string = ""; let close: () => void; + + let copied = false; + + $: if (copied) { + setTimeout(() => { + copied = false; + }, 1500); + } @@ -63,18 +72,24 @@ id="save-copy" fill elevated - click={async () => copyURL(url)} + click={async () => { + copyURL(url); + copied = true; + }} + ariaLabel={copied ? $t("a11y.dialog.saving.copied") : ""} > - + {$t("dialog.button.copy")} + {#if bodyText}
{bodyText}
{/if} + + import IconCopy from "@tabler/icons-svelte/IconCopy.svelte"; + import IconCheck from "@tabler/icons-svelte/IconCheck.svelte"; + + export let check = false; + + +
+
+ +
+
+ +
+
+ + From a4e0e21a976e85347e688d7c14068239a7f0fc05 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 28 Jul 2024 23:36:38 +0600 Subject: [PATCH 324/334] web/Omnibox: accept keyboard shortcuts only when focused --- web/src/components/save/Omnibox.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/components/save/Omnibox.svelte b/web/src/components/save/Omnibox.svelte index 01772358..80d89aba 100644 --- a/web/src/components/save/Omnibox.svelte +++ b/web/src/components/save/Omnibox.svelte @@ -83,11 +83,11 @@ linkInput.focus(); } - if (e.key === "Enter" && validLink($link)) { + if (e.key === "Enter" && validLink($link) && isFocused) { downloadButton.download($link); } - if (["Escape", "Clear"].includes(e.key)) { + if (["Escape", "Clear"].includes(e.key) && isFocused) { $link = ""; } From 8b866ddf6feb092c66b7fc89e09b67d48e9c3e3a Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 29 Jul 2024 13:11:29 +0600 Subject: [PATCH 325/334] web/SettingsNavTab: reduce padding on desktop --- web/src/components/settings/SettingsNavTab.svelte | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/src/components/settings/SettingsNavTab.svelte b/web/src/components/settings/SettingsNavTab.svelte index 70838c8b..63274b99 100644 --- a/web/src/components/settings/SettingsNavTab.svelte +++ b/web/src/components/settings/SettingsNavTab.svelte @@ -32,7 +32,7 @@ \ No newline at end of file + diff --git a/web/src/components/changelog/ChangelogSkeleton.svelte b/web/src/components/changelog/ChangelogSkeleton.svelte index 11f1d999..07cc02f8 100644 --- a/web/src/components/changelog/ChangelogSkeleton.svelte +++ b/web/src/components/changelog/ChangelogSkeleton.svelte @@ -3,7 +3,7 @@ export let version: string; -
+
{ version }
@@ -24,7 +24,7 @@ class="big changelog-banner" width="100%" /> -
+
{#each {length: 3 + Math.random() * 5} as _}

- - \ No newline at end of file From a6a0e916749446e403060e57b4a6a5b2f9d5eb99 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Tue, 30 Jul 2024 14:08:49 +0000 Subject: [PATCH 328/334] web/TransferSettings: don't offer export if there is nothing to export --- web/src/components/settings/TransferSettings.svelte | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/src/components/settings/TransferSettings.svelte b/web/src/components/settings/TransferSettings.svelte index a238aac9..3db4ee8b 100644 --- a/web/src/components/settings/TransferSettings.svelte +++ b/web/src/components/settings/TransferSettings.svelte @@ -85,9 +85,11 @@ import + {#if $storedSettings.schemaVersion} export + {/if} diff --git a/web/src/components/changelog/ChangelogSkeleton.svelte b/web/src/components/changelog/ChangelogSkeleton.svelte deleted file mode 100644 index 07cc02f8..00000000 --- a/web/src/components/changelog/ChangelogSkeleton.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - -
-
-
-
{ version }
-
- -
-
- -
-
- -
- {#each {length: 3 + Math.random() * 5} as _} -

- -

- {/each} -
-
-
diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte index d8e13601..99aba833 100644 --- a/web/src/routes/updates/+page.svelte +++ b/web/src/routes/updates/+page.svelte @@ -6,7 +6,7 @@ import type { ChangelogImport } from "$lib/types/changelogs"; import type { Optional } from "$lib/types/generic"; - import ChangelogSkeleton from "$components/changelog/ChangelogSkeleton.svelte"; + import ChangelogEntry from "$components/changelog/ChangelogEntry.svelte"; import IconArrowLeft from "@tabler/icons-svelte/IconArrowLeft.svelte"; import IconArrowRight from "@tabler/icons-svelte/IconArrowRight.svelte"; @@ -98,7 +98,10 @@
{#await changelog.page} {#key changelog.version} - + {/key} {:then page}