diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 32feda3..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,27 +0,0 @@ -module.exports = { - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 2020, - sourceType: 'module', - project: './tsconfig.json', - }, - plugins: ['@typescript-eslint'], - extends: [ - 'eslint:recommended', - '@typescript-eslint/recommended', - ], - //rules: { - // '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], - // '@typescript-eslint/explicit-function-return-type': 'off', - // '@typescript-eslint/explicit-module-boundary-types': 'off', - // '@typescript-eslint/no-explicit-any': 'warn', - // '@typescript-eslint/prefer-const': 'error', - // 'no-console': 'warn', - // 'prefer-const': 'error', - // }, - env: { - node: true, - es6: true, - }, - ignorePatterns: ['dist/', 'node_modules/', '*.js'], -}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2519ee8..1618ebc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,58 +4,29 @@ on: push: branches: [main] paths: - - 'src/**' - - 'tests/**' - - 'package.json' - - 'pnpm-lock.yaml' + - "src/**" + - "tests/**" + - "package.json" + - "bun.lock" pull_request: branches: [main] paths: - - 'src/**' - - 'tests/**' - - 'package.json' - - 'pnpm-lock.yaml' + - "src/**" + - "tests/**" + - "package.json" + - "bun.lock" jobs: test: runs-on: ubuntu-latest timeout-minutes: 5 - steps: - - uses: actions/checkout@v4 - - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: latest - - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: ${{ env.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run tests - run: pnpm run test:run - - - name: Upload coverage reports - uses: codecov/codecov-action@v4 - with: - file: ./coverage/lcov.info - flags: unittests - name: codecov-umbrella + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - run: bun install --frozen-lockfile + - run: bun run format:check + - run: bun run typecheck + - run: bun run test + - run: bun run build diff --git a/.github/workflows/pages-deploy.yml b/.github/workflows/pages-deploy.yml deleted file mode 100644 index 9bba314..0000000 --- a/.github/workflows/pages-deploy.yml +++ /dev/null @@ -1,92 +0,0 @@ -name: Deploy to GitHub Pages - -on: - # Runs on pushes targeting the default branch - push: - branches: ["main"] - paths: - - 'examples/**' - - 'src/**' - - 'package.json' - - 'pnpm-lock.yaml' - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Build job - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: latest - - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: ${{ env.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build production - run: pnpm run build:prod - - - name: Install examples dependencies - run: cd examples && pnpm install --no-frozen-lockfile - - - name: Build examples - run: pnpm run examples:build - - - name: Copy classigo UMD build - run: cp dist/index.umd.js examples/dist/classigo.umd.js - - - name: Setup Pages - uses: actions/configure-pages@v5 - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: './examples/dist' - - # Deployment job - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 41ef4fc..81ee7b5 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -9,137 +9,27 @@ jobs: runs-on: ubuntu-latest permissions: contents: write - packages: write - id-token: write - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - registry-url: 'https://registry.npmjs.org' - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: latest - - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: ${{ env.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Extract version from release - id: version - run: | - # Extract version from release tag - RELEASE_TAG="${{ github.event.release.tag_name }}" - VERSION=${RELEASE_TAG#v} # Remove 'v' prefix - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Release version: $VERSION" - - - name: Update package.json version - run: | - VERSION="${{ steps.version.outputs.version }}" - - # Update version in package.json - node -e " - const pkg = require('./package.json'); - pkg.version = '$VERSION'; - require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); - " - echo "Updated package.json to version $VERSION" - - # Verify the update worked - UPDATED_VERSION=$(node -p "require('./package.json').version") - if [ "$UPDATED_VERSION" != "$VERSION" ]; then - echo "❌ Error: Version was not updated correctly" - echo "Expected: $VERSION, Got: $UPDATED_VERSION" - exit 1 - fi - echo "✅ Version updated successfully: $UPDATED_VERSION" - - - name: Build project - run: pnpm run build:prod - - - name: Run tests - run: pnpm run test:run - - - name: Publish to npm - run: npm publish --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: Update main branch with new version - run: | - VERSION="${{ steps.version.outputs.version }}" - - # Git configuration - git config --local user.email "github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - - # Checkout main branch - git checkout main || { - echo "❌ Error: Could not checkout main branch" - exit 1 - } - - # Fetch latest changes without pulling tags - git fetch origin main || { - echo "❌ Error: Could not fetch latest changes" - exit 1 - } - - # Reset to origin/main to get latest changes - git reset --hard origin/main || { - echo "❌ Error: Could not reset to origin/main" - exit 1 - } - - # Update package.json version - node -e " - const pkg = require('./package.json'); - pkg.version = '$VERSION'; - require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); - " - - # Add and commit changes - git add package.json - git commit -m "Bump version to $VERSION [skip ci]" || { - echo "❌ Error: Could not commit changes" - exit 1 - } - - # Push to main - git push origin main || { - echo "❌ Error: Could not push to main" - exit 1 - } - - echo "✅ package.json updated on main branch" - - - name: Success message - run: | - VERSION="${{ steps.version.outputs.version }}" - echo "🎉 Publication v$VERSION successful!" - echo "📦 Package published on npm" - echo "📝 package.json updated in main" - echo "🔗 Release: ${{ github.event.release.html_url }}" - echo "📦 npm: https://www.npmjs.com/package/classigo" + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - uses: actions/setup-node@v4 + with: + node-version: "20" + registry-url: "https://registry.npmjs.org" + - run: bun install --frozen-lockfile + - run: bun run test + - run: bun run build + - name: Sync version from release tag + run: | + VERSION="${{ github.event.release.tag_name }}" + VERSION="${VERSION#v}" + node -e " + const pkg = require('./package.json'); + pkg.version = '$VERSION'; + require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); + " + - run: npm publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index c2f2c8d..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,286 +0,0 @@ -name: Create Release Draft - -on: - workflow_dispatch: - inputs: - release_type: - description: 'Release type' - required: true - default: 'patch' - type: choice - options: - - patch - - minor - - major - -jobs: - create-draft: - runs-on: ubuntu-latest - permissions: - contents: write - actions: write - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: latest - - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: ${{ env.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Read current version - id: current_version - run: | - CURRENT_VERSION=$(node -p "require('./package.json').version") - echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT - echo "Current version: $CURRENT_VERSION" - - - name: Calculate new version - id: new_version - run: | - CURRENT_VERSION="${{ steps.current_version.outputs.current_version }}" - RELEASE_TYPE="${{ github.event.inputs.release_type }}" - - IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION" - MAJOR="${VERSION_PARTS[0]}" - MINOR="${VERSION_PARTS[1]}" - PATCH="${VERSION_PARTS[2]}" - - case $RELEASE_TYPE in - "major") - NEW_MAJOR=$((MAJOR + 1)) - NEW_VERSION="${NEW_MAJOR}.0.0" - ;; - "minor") - NEW_MINOR=$((MINOR + 1)) - NEW_VERSION="${MAJOR}.${NEW_MINOR}.0" - ;; - "patch") - NEW_PATCH=$((PATCH + 1)) - NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}" - ;; - esac - - # Check if version already exists - if git tag -l | grep -q "v$NEW_VERSION"; then - echo "❌ Error: Version v$NEW_VERSION already exists" - echo "Existing tags:" - git tag -l | grep "v$NEW_VERSION" || echo "No tags found" - exit 1 - fi - - echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT - echo "New version: $NEW_VERSION" - - - name: Build project - run: | - pnpm run build:prod - - # Check if build files exist - if [ ! -f "./dist/index.mjs" ] || [ ! -f "./dist/index.cjs" ] || [ ! -f "./dist/index.d.ts" ]; then - echo "❌ Error: Build files were not created" - echo "Dist folder content:" - ls -la ./dist/ || echo "Dist folder does not exist" - exit 1 - fi - echo "✅ Build successful, files created:" - ls -la ./dist/ - - - name: Run tests - run: | - pnpm run test:run - - if [ $? -ne 0 ]; then - echo "❌ Error: Tests failed" - exit 1 - fi - echo "✅ Tests passed" - - - name: Create tag - run: | - NEW_VERSION="${{ steps.new_version.outputs.new_version }}" - - # Git configuration - git config --local user.email "github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - - # Check if tag already exists - if git tag -l | grep -q "v$NEW_VERSION"; then - echo "⚠️ Tag v$NEW_VERSION already exists, removing..." - git tag -d "v$NEW_VERSION" || true - git push origin ":refs/tags/v$NEW_VERSION" || true - fi - - # Create a temporary branch for the tag - git checkout -b temp-release-branch - - # Update package.json version only on this branch - node -e " - const pkg = require('./package.json'); - pkg.version = '$NEW_VERSION'; - require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); - " - - # Commit the version change - git add package.json - git commit -m "Bump version to $NEW_VERSION [skip ci]" - - # Create tag from this branch - git tag -a "v$NEW_VERSION" -m "Release v$NEW_VERSION" - - # Push tag - echo "Pushing tag..." - git push origin "v$NEW_VERSION" || { - echo "❌ Error pushing tag" - git tag -l - exit 1 - } - - # Clean up temporary branch - git checkout main - git branch -D temp-release-branch - - echo "✅ Tag created and pushed successfully" - - - name: Generate changelog - id: changelog - run: | - NEW_VERSION="${{ steps.new_version.outputs.new_version }}" - PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "") - - if [ -n "$PREVIOUS_TAG" ]; then - CHANGELOG=$(git log --pretty=format:"- %s" $PREVIOUS_TAG..HEAD) - else - CHANGELOG=$(git log --pretty=format:"- %s" --reverse) - fi - - echo "changelog<> $GITHUB_OUTPUT - echo "$CHANGELOG" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - - name: Create Draft Release - id: create_release - run: | - NEW_VERSION="${{ steps.new_version.outputs.new_version }}" - - # Create release draft via GitHub API - echo "## 🚀 Release v$NEW_VERSION" > release_body.txt - echo "" >> release_body.txt - echo "### 📋 Changelog" >> release_body.txt - echo "${{ steps.changelog.outputs.changelog }}" >> release_body.txt - echo "" >> release_body.txt - echo "### 📦 Installation" >> release_body.txt - echo '```bash' >> release_body.txt - echo 'npm install classigo' >> release_body.txt - echo '```' >> release_body.txt - echo "" >> release_body.txt - echo '```bash' >> release_body.txt - echo 'pnpm add classigo' >> release_body.txt - echo '```' >> release_body.txt - echo "" >> release_body.txt - echo '```bash' >> release_body.txt - echo 'yarn add classigo' >> release_body.txt - echo '```' >> release_body.txt - echo "" >> release_body.txt - echo "### 🔧 Usage" >> release_body.txt - echo '```javascript' >> release_body.txt - echo 'import classigo from "classigo";' >> release_body.txt - echo '' >> release_body.txt - echo '// Basic usage' >> release_body.txt - echo 'const className = classigo("base", "active", "large");' >> release_body.txt - echo '// Result: "base active large"' >> release_body.txt - echo '```' >> release_body.txt - echo "" >> release_body.txt - echo "### 📝 Notes" >> release_body.txt - echo "- Version: $NEW_VERSION" >> release_body.txt - echo "- Build tested and validated" >> release_body.txt - echo "- Tests executed successfully" >> release_body.txt - echo "- **Draft release - Review before publishing**" >> release_body.txt - - RELEASE_BODY=$(cat release_body.txt) - - # Create release JSON with variables replaced - echo "{\"tag_name\":\"v$NEW_VERSION\",\"name\":\"Release v$NEW_VERSION\",\"body\":$(echo "$RELEASE_BODY" | jq -R -s .),\"draft\":true,\"prerelease\":false}" > release_data.json - - echo "Release data:" - cat release_data.json - - RELEASE_RESPONSE=$(curl -s -X POST \ - -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Content-Type: application/json" \ - "https://api.github.com/repos/${{ github.repository }}/releases" \ - -d @release_data.json) - - echo "Release creation response: $RELEASE_RESPONSE" - - # Check if creation was successful - RELEASE_ID=$(echo "$RELEASE_RESPONSE" | jq -r '.id') - if [ "$RELEASE_ID" = "null" ] || [ -z "$RELEASE_ID" ]; then - echo "❌ Error creating release" - echo "Response: $RELEASE_RESPONSE" - exit 1 - fi - - echo "✅ Release draft created successfully, ID: $RELEASE_ID" - echo "release_id=$RELEASE_ID" >> $GITHUB_OUTPUT - - - name: Upload Release Assets - run: | - RELEASE_ID="${{ steps.create_release.outputs.release_id }}" - UPLOAD_URL="https://uploads.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID/assets" - - echo "📤 Uploading build files..." - - # Upload main files - for file in index.mjs index.cjs index.d.ts index.umd.js; do - if [ -f "./dist/$file" ]; then - echo "📤 Uploading $file..." - curl -s -X POST \ - -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Content-Type: application/octet-stream" \ - --data-binary @./dist/$file \ - "$UPLOAD_URL?name=$file" - fi - done - - echo "✅ Assets uploaded successfully" - - - name: Success message - run: | - NEW_VERSION="${{ steps.new_version.outputs.new_version }}" - RELEASE_ID="${{ steps.create_release.outputs.release_id }}" - echo "🎉 Release draft v$NEW_VERSION created successfully!" - echo "📦 Assets uploaded" - echo "🔗 Release: https://github.com/${{ github.repository }}/releases/tag/v$NEW_VERSION" - echo "" - echo "📋 Next steps:" - echo "1. Review the release draft on GitHub" - echo "2. If everything looks good, publish the release" - echo "3. The 'Publish to npm' workflow will trigger automatically" diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 7846d92..0000000 --- a/.npmignore +++ /dev/null @@ -1,51 +0,0 @@ -# Source files -src/ -scripts/ -bench/ -examples/ -docs/ - -# Development files -vite.config.js -vite.config.prod.js -tsconfig.json -eslint.config.js -.gitignore - -# Documentation -docs/ -README.fr.md - -# Development dependencies -node_modules/ -pnpm-lock.yaml -package-lock.json -yarn.lock - -# IDE files -.vscode/ -.idea/ -*.swp -*.swo -.github/ - -# OS files -.DS_Store -Thumbs.db - -# Logs -*.log -npm-debug.log* - -# Temporary files -*.tmp -*.temp - -# Test files -test/ -tests/ -*.test.* -*.spec.* - -# Build artifacts (keep only dist/) -*.tsbuildinfo diff --git a/CONTRIBUTING.fr.md b/CONTRIBUTING.fr.md new file mode 100644 index 0000000..36cf0d4 --- /dev/null +++ b/CONTRIBUTING.fr.md @@ -0,0 +1,106 @@ +# Contribuer à classigo + +Merci d'envisager une contribution. Quelques règles gardent le projet sain — merci de les lire avant d'ouvrir une PR. + +> 🇬🇧 English version : [CONTRIBUTING.md](./CONTRIBUTING.md) (la version faisant foi). + +## Langue + +**Les titres de PR, descriptions, messages de commit, commentaires de code et discussions doivent être en anglais.** Je suis francophone moi-même, mais l'anglais garde le projet accessible à tout le monde. Les issues aussi — le français est ok en DM, pas sur le tracker. + +Cette page est traduite pour faciliter la lecture, mais **la version anglaise fait foi** en cas de divergence, et **ta PR doit être rédigée en anglais**. + +## Avant d'ouvrir une PR + +1. **Fork** le repo et crée une branche à partir de `main`. +2. **Utilise Bun** comme gestionnaire de paquets — `bun install`, pas `npm`/`pnpm`/`yarn`. Le lockfile est `bun.lock` ; mélanger les gestionnaires provoque des conflits inutiles que je ne déboguerai pas pour toi. +3. **Format, typecheck, tests et build en local** : + + ```sh + bun install + bun run format:check + bun run typecheck + bun run test + bun run build + ``` + + La CI tourne les mêmes checks sur chaque PR — si un seul plante, la PR ne merge pas. + +4. **Si le changement touche le cœur** (`src/index.ts`, `src/lite.ts`, `src/types.ts`), lance le bench et inclus le delta : + + ```sh + bun run bench + ``` + + Le pitch de classigo c'est la performance. Un changement qui régresse le hot path a besoin d'une bonne raison. + +## Pipeline de build + +Le build se fait en deux étapes — ne casse aucune des deux : + +```sh +tsc -p tsconfig.build.json # émet uniquement les déclarations .d.ts +bun build src/index.ts src/lite.ts --outdir dist --format esm --minify # émet le JS minifié +``` + +`bun run build` lance les deux. Si tu ajoutes un nouveau point d'entrée, mets à jour à la fois le script `build` dans `package.json` et la map `exports`. + +## Scope d'une PR + +- **Une feature / un fix par PR.** +- **Petit et ciblé > gros et étalé.** +- **Décris ce qui change et pourquoi** dans le corps de la PR. Un delta de bench ou un test qui reproduit le bug rend la review nettement plus rapide. +- **Pas de reformatage opportuniste.** Prettier tourne en CI — ne mélange pas "j'ai tout reformaté" avec un vrai changement de logique. + +## Tests + +- Tout changement runtime doit avoir un test dans [`tests/runtime.test.ts`](./tests/runtime.test.ts). +- N'affaiblis pas un test existant pour faire passer un changement. Si un test est faux, explique pourquoi dans la PR et corrige-le explicitement. + +## Style de commit + +Suis [Conventional Commits](https://www.conventionalcommits.org/fr/v1.0.0/) : + +``` +(): +``` + +- **Types autorisés** : `feat`, `fix`, `refactor`, `perf`, `docs`, `test`, `chore`, `build`, `ci`, `style`. +- **Scope** correspond à la zone touchée : `core`, `lite`, `types`, `bench`, `docs`, `ci`. +- **Résumé** : présent, impératif, en minuscules, pas de point final. +- **Pas de gitmoji** dans les messages de commit. +- **Breaking changes** : ajoute `!` après le scope (ex. `feat(core)!: ...`) et un footer `BREAKING CHANGE:` qui explique la migration. + +> Rappel : le commit lui-même reste en anglais, même si la PR est discutée en français ailleurs. + +Exemples : + +``` +feat(lite): add classigo/lite strings-only export +perf(core): invert typeof check to favour string fast path +fix(types): widen ClassObject values to accept null +docs(readme): document migration from v1 +build(ci): add minification step via bun build +``` + +## Ce sur quoi je vais pousser back + +- Ajouter des dépendances. classigo est zéro-dep et je veux que ça le reste. +- Des features qui régressent le hot path sans gain clair. +- Le support des tableaux ou des appels imbriqués — c'est un non-objectif délibéré. Utilise clsx si tu en as besoin. +- Des breaking changes sans note de migration. + +## Signaler un bug + +Ouvre une issue avec : +- Version de classigo, runtime (Bun/Node/Deno) + version, version TS. +- Une reproduction **minimale** — idéalement un test qui plante à coller dans `tests/runtime.test.ts`. +- Ce que tu attendais vs. ce qui s'est passé. + +## Sécurité + +Si tu trouves quelque chose lié à la sécurité, n'ouvre pas d'issue publique. Utilise [le système de signalement privé de GitHub](https://github.com/SUP2Ak/classigo/security/advisories/new) à la place. + +--- + +Merci d'être arrivé jusqu'ici. Les PR qui suivent ce qui est au-dessus mergent vite. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..42efefa --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,102 @@ +# Contributing to classigo + +Thanks for considering a contribution. A few guidelines keep the project healthy — please read them before opening a PR. + +> 🇫🇷 Version française : [CONTRIBUTING.fr.md](./CONTRIBUTING.fr.md). PRs must still be written in English (see below). + +## Language + +**PR titles, descriptions, commit messages, code comments, and discussion must be in English.** I'm francophone myself, but English keeps the project accessible to everyone. Open issues in English too — French is fine in DMs, not on the tracker. + +## Before you open a PR + +1. **Fork** the repo and create a branch off `main`. +2. **Use Bun** as your package manager — `bun install`, not `npm`/`pnpm`/`yarn`. The lockfile is `bun.lock`; mixing managers causes spurious conflicts I won't debug for you. +3. **Format, typecheck, test, and build locally**: + + ```sh + bun install + bun run format:check + bun run typecheck + bun run test + bun run build + ``` + + CI runs the same gates on every PR — if one fails, the PR won't merge. + +4. **If the change touches the core** (`src/index.ts`, `src/lite.ts`, `src/types.ts`), run the bench and include the delta: + + ```sh + bun run bench + ``` + + classigo's pitch is performance. A change that regresses the hot path needs a good reason. + +## Build pipeline + +The build is a two-step process — don't break either: + +```sh +tsc -p tsconfig.build.json # emits .d.ts declarations only +bun build src/index.ts src/lite.ts --outdir dist --format esm --minify # emits minified JS +``` + +`bun run build` runs both. If you add a new entry point, update both the `build` script in `package.json` and the `exports` map. + +## PR scope + +- **One feature / one fix per PR.** +- **Small and focused beats big and sprawling.** +- **Describe what changed and why** in the PR body. A bench delta or a failing test that reproduces the bug makes review significantly faster. +- **No drive-by reformatting.** Prettier runs in CI — don't mix "I reformatted everything" with actual logic changes. + +## Tests + +- Every runtime-facing change needs a test in [`tests/runtime.test.ts`](./tests/runtime.test.ts). +- Don't weaken existing tests to make a change pass. If a test is wrong, explain why in the PR and fix it explicitly. + +## Commit style + +Follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/): + +``` +(): +``` + +- **Allowed types**: `feat`, `fix`, `refactor`, `perf`, `docs`, `test`, `chore`, `build`, `ci`, `style`. +- **Scope** should match the area touched: `core`, `lite`, `types`, `bench`, `docs`, `ci`. +- **Summary**: present-tense imperative, lowercase, no trailing period. +- **No gitmoji** in commit messages. +- **Breaking changes**: add `!` after the scope (e.g. `feat(core)!: ...`) and a `BREAKING CHANGE:` footer explaining the migration. + +Examples: + +``` +feat(lite): add classigo/lite strings-only export +perf(core): invert typeof check to favour string fast path +fix(types): widen ClassObject values to accept null +docs(readme): document migration from v1 +build(ci): add minification step via bun build +``` + +## What I'll push back on + +- Adding dependencies. classigo is zero-dep and I'd like to keep it that way. +- Features that regress the hot path without a clear payoff. +- Array or nested-call support — that's a deliberate non-goal. Use clsx if you need it. +- Breaking changes without a migration note. + +## Reporting bugs + +Open an issue with: +- classigo version, runtime (Bun/Node/Deno) + version, TS version. +- A **minimal** reproduction — ideally a failing test I can paste into `tests/runtime.test.ts`. +- What you expected vs. what happened. + +## Security + +If you find something security-relevant, don't open a public issue. Use [GitHub's private vulnerability reporting](https://github.com/SUP2Ak/classigo/security/advisories/new) instead. + +--- + +Thanks for reading this far. PRs that follow the above tend to merge quickly. diff --git a/README.fr.md b/README.fr.md index 9a8a5df..c3ffff3 100644 --- a/README.fr.md +++ b/README.fr.md @@ -1,135 +1,224 @@ -# 🎯 Classigo +# classigo -**Utilitaire ultra-optimisé pour la gestion des noms de classes avec CSS Modules** +> Utilitaire de class names rapide pour TypeScript — strings, objets, zéro dépendance. -[![npm version](https://img.shields.io/npm/v/classigo.svg)](https://www.npmjs.com/package/classigo) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![Bundle Size](https://img.shields.io/badge/bundle%20size-159B-brightgreen)](https://bundlephobia.com/package/classigo) +[![npm](https://img.shields.io/npm/v/classigo.svg)](https://www.npmjs.com/package/classigo) +[![downloads](https://img.shields.io/npm/dw/classigo.svg)](https://www.npmjs.com/package/classigo) +[![bundle size](https://img.shields.io/badge/minified-217B-brightgreen)](https://bundlephobia.com/package/classigo) +[![MIT](https://img.shields.io/npm/l/classigo.svg)](./LICENSE) +[![TypeScript](https://img.shields.io/badge/TypeScript-%3E%3D5.0-blue.svg)](https://www.typescriptlang.org/) -## 🚀 Fonctionnalités +> _English version: [README.md](./README.md) (reference)_ -- **⚡ Ultra-rapide** : Optimisé pour des performances maximales (52M ops/sec) -- **🎯 API simple** : Signature de fonction propre et intuitive -- **🔧 TypeScript** : Support complet TypeScript avec sécurité des types -- **📦 Léger** : 159B (59% plus petit que clsx) -- **🔄 Autonome** : Utilitaire JavaScript pur, fonctionne partout -- **🎨 CSS Modules** : Intégration parfaite avec CSS/SCSS Modules -- **📦 Multi-format** : Support ES Modules, CommonJS et UMD +```ts +import classigo from "classigo"; -## 📦 Installation +// Strings + valeurs falsy +classigo("btn", isActive && "btn--active", isDisabled && "btn--disabled"); +// → "btn btn--active" -```bash -npm install classigo +// Syntaxe objet +classigo("btn", { + "btn--active": isActive, + "btn--disabled": isDisabled, + "btn--loading": isLoading, +}); +// → "btn btn--active" + +// Mixte +classigo("btn", `btn--${variant}`, { "btn--active": isActive }); +// → "btn btn--primary btn--active" ``` -```bash -yarn add classigo +## Pourquoi classigo ? + +Honnêtement — pas parce que la différence de performance va compter dans ton app. Un cycle de rendu coûte des milliers de nanosecondes ; ton utilitaire de className en coûte des dizaines. Personne n'a jamais livré un produit lent à cause de clsx. + +La vraie raison d'utiliser classigo c'est le **contrat**. Il ne supporte pas les tableaux, les nombres, ni les appels imbriqués — délibérément. Ça signifie : + +- Passer un tableau est une **erreur de compilation TypeScript**, pas une surprise silencieuse au runtime. +- Les types décrivent précisément ce que la fonction fait réellement. +- Le bundle est petit parce qu'il n'y a pas de code pour des cas que la fonction ne gère pas. + +| | classigo | classigo/lite | clsx | classnames | +| :--- | :---: | :---: | :---: | :---: | +| Strings + valeurs falsy | ✅ | ✅ | ✅ | ✅ | +| Syntaxe objet (`{ [cls]: boolean }`) | ✅ | ❌ | ✅ | ✅ | +| Tableaux / appels imbriqués | ❌ | ❌ | ✅ | ✅ | +| Nombres | ❌ | ❌ | ✅ | ✅ | +| ESM uniquement | ✅ | ✅ | ✅ | ❌ | +| Zéro dépendance | ✅ | ✅ | ✅ | ✅ | +| Taille minifiée | **217B** | **137B** | ~560B | ~1.1kB | + +**Quand utiliser classigo :** tu contrôles tous les inputs — les class names viennent de strings, template literals, conditionnels ou objets. Ça couvre la grande majorité du code composant React / Vue / Svelte. + +**Quand utiliser clsx à la place :** tu reçois des listes de classes depuis une source externe (CMS, config, API) qui peuvent être des tableaux ou des structures imbriquées, ou une fonction dans ta codebase retourne du `string[]` que tu veux passer directement sans spread. + +```ts +// classigo couvre ça — tu contrôles les inputs +classigo("btn", `btn--${variant}`, { "btn--active": isActive }) + +// clsx couvre ça — tableau externe de forme inconnue +const rules = fetchClassRulesFromCMS(); // (string | string[])[] +clsx(...rules) + +// le workaround spread fonctionne quand tu sais que le tableau est plat +classigo(...myKnownFlatArray) // ✅ ok +classigo(...myUnknownArray) // ❌ casse si un élément est lui-même un tableau ``` -```bash -pnpm add classigo +**Tu utilises déjà clsx ?** Ne migre pas. La différence n'est pas perceptible dans une vraie app. classigo a du sens si tu pars de zéro et veux un utilitaire minimal avec un contrat strict — ou si tu préfères simplement qu'un tableau accidentel à un point d'appel soit attrapé à la compilation plutôt que silencieusement joint de travers. + +## Tu as vraiment besoin d'un utilitaire de class ? + +Pour quelques conditionnels, peut-être pas : + +```ts +// Parfaitement lisible sans librairie +const cls = ["btn", isActive && "btn--active", isDisabled && "btn--disabled"] + .filter(Boolean) + .join(" "); ``` -```bash +L'approche tableau est lisible mais alloue un nouveau tableau à chaque appel. Quand ton composant re-render des centaines de fois par seconde, ou quand ton design system appelle un utilitaire de class dans chaque composant, ces allocations s'accumulent. Un utilitaire resserré qui fait une seule passe de concaténation de string rentabilise son usage sur les chemins de rendu haute fréquence. + +## Installation + +```sh bun add classigo +# ou +npm i classigo +# ou +pnpm add classigo ``` +Requiert TypeScript **≥ 5.0**. Zéro dépendance runtime. +## API -## 🎯 Démarrage Rapide +### `classigo(...classes)` -```typescript -import classigo from 'classigo'; -import styles from './Button.module.css'; +Combine les class names en filtrant les valeurs falsy. Accepte des strings, des valeurs falsy (`false`, `null`, `undefined`), et des objets (`{ [className]: boolean }`). -// Utilisation basique -const className = classigo( - styles.button, - styles['button--primary'], - styles['button--large'] -); +```ts +import classigo from "classigo"; +// ou +import { classigo } from "classigo"; +``` -// Avec conditions -const className = classigo( - styles.button, - styles['button--primary'], - isLarge && styles['button--large'], - isDisabled && styles['button--disabled'] -); +```ts +// Strings +classigo("btn", "btn--primary") +// → "btn btn--primary" -// Avec template literals -const className = classigo( - styles.button, - styles[`button--${variant}`], - isLarge && styles['button--large'] -); +// Les valeurs falsy sont ignorées +classigo("btn", false, null, undefined, "btn--active") +// → "btn btn--active" + +// Conditionnel avec && +classigo("btn", isActive && "btn--active") +// → "btn btn--active" (quand isActive est true) +// → "btn" (quand isActive est false) + +// Objet — chaque clé est incluse quand sa valeur est truthy +classigo("btn", { "btn--active": isActive, "btn--disabled": isDisabled }) +// → "btn btn--active" + +// Template literals +classigo(`card--${variant}`, `card--${size}`) +// → "card--primary card--lg" + +// Pattern CSS Modules +classigo(styles.root, { [styles.active]: isActive }) +// → "root active" (quand isActive est true) ``` +**Signature de type :** +```ts +type ClassObject = Record; +type ClassValue = string | false | null | undefined | ClassObject; -## ⚡ Performance +function classigo(...classes: ClassValue[]): string; +``` -**classigo** est significativement plus rapide et plus petit que les alternatives : +### `classigo/lite` -- **52.3M ops/sec** vs clsx (45.1M ops/sec) - **16% plus rapide** -- **159B** vs clsx (388B) - **59% plus petit** -- **Surpasse constamment** Array.filter().join() et autres utilitaires +Une variante strings uniquement — pas de support objet, bundle minimal (137B). Utile quand tu contrôles tous les inputs et n'as jamais besoin de la syntaxe objet. -### Résultats des Benchmarks +```ts +import classigo from "classigo/lite"; +// ou +import { classigo } from "classigo/lite"; +``` + +```ts +classigo("btn", isActive && "btn--active", isDisabled && "btn--disabled"); +// → "btn btn--active" +``` -| Test | classigo | clsx | classnames | -|------|----------|------|------------| -| Classes de base | 🥇 43.2M ops/sec | 🥈 38.5M ops/sec | 🥉 37.3M ops/sec | -| Classes conditionnelles | 🥇 64.4M ops/sec | 🥈 54.3M ops/sec | 🥉 50.3M ops/sec | -| Template literals | 🥇 62.2M ops/sec | 🥈 52.5M ops/sec | 🥉 50.4M ops/sec | -| Valeurs falsy | 🥇 55.6M ops/sec | 🥈 48.8M ops/sec | 🥉 45.3M ops/sec | -| SCSS complexe | 🥇 36.0M ops/sec | 🥈 31.4M ops/sec | 🥉 25.1M ops/sec | +**Signature de type :** -### Comparaison des Tailles de Bundle +```ts +type ClassLiteValue = string | false | null | undefined; -| Bibliothèque | CJS | ESM | UMD | -|--------------|-----|-----|-----| -| **classigo** | **159B** | **195B** | **359B** | -| clsx | 397B | 388B | 543B | -| classnames | 1.5KB | ❌ | ❌ | +function classigo(...classes: ClassLiteValue[]): string; +``` -*Benchmarks exécutés avec 1M itérations × 20 rounds* +Passer un objet à `classigo/lite` est une **erreur de compilation TypeScript** — c'est précisément l'intérêt. Si tu veux que le système de types garantisse qu'aucun objet n'atteindra ce point d'appel, utilise `/lite`. -Pour plus d'informations, voir [docs/README.md](./docs/README.md). +## Migration depuis v1 -## 🎮 Exemples en Direct +v2 introduit deux changements cassants : -- **[Tous les Exemples](https://sup2ak.github.io/classigo/)** - Vitrine des démos interactives -- **[Démo React](https://sup2ak.github.io/classigo/react-demo/)** - Composant bouton interactif avec CSS Modules -- **[Démo Vue](https://sup2ak.github.io/classigo/vue-demo/)** - Composant Vue 3 avec Composition API -- **[Démo Svelte](https://sup2ak.github.io/classigo/svelte-demo/)** - Composant Svelte avec réactivité -- **[Démo Vanilla JS](https://sup2ak.github.io/classigo/vanilla-demo/)** - Implémentation JavaScript pure +**1. ESM uniquement.** CommonJS (`require("classigo")`) n'est plus supporté. Si ton projet a besoin de CJS, reste sur v1 ou utilise un bundler qui convertit l'ESM. -*Les exemples montrent la génération de className en temps réel et les comparaisons de performance* +**2. Syntaxe objet ajoutée.** C'est rétrocompatible pour un usage purement string, mais les types publiés acceptent maintenant `ClassObject` aux côtés des strings. Si tu as des assertions de type strictes qui supposaient que `ClassValue` était string-only, mets-les à jour ou passe à `classigo/lite`. -## 🤝 Contribution +```ts +// v1 +classigo("btn", isActive && "btn--active"); // ✅ fonctionne toujours -**Démarrage rapide:** -```bash -git clone https://github.com/SUP2Ak/classigo.git -cd classigo -pnpm install -pnpm run build +// v2 — nouveau +classigo("btn", { "btn--active": isActive }); // ✅ syntaxe objet +import classigoLite from "classigo/lite"; // ✅ export strings-only ``` -## 🙏 Remerciements +Aucun autre changement d'API. La signature de la fonction est identique par ailleurs. -Cet utilitaire s'inspire et s'appuie sur l'excellent travail de : +## Benchmarks -- **[clsx](https://github.com/lukeed/clsx)** par Luke Edwards -- **[classnames](https://github.com/JedWatson/classnames)** par Jed Watson +Je bench parce que j'aime savoir si ce que j'ai construit est rapide ou lent — pas parce que ces chiffres devraient guider ton choix d'adoption. Un appel de className coûte des dizaines de nanosecondes ; un rendu React en coûte des milliers. Le bench existe par curiosité et pour attraper les régressions si quelqu'un soumet une PR qui change le hot path. -Cet utilitaire a été principalement construit pour mon usage personnel, mais s'il aide quelqu'un d'autre, tant mieux ! +Cela dit, voilà les chiffres. Mesuré avec [mitata](https://github.com/nicolo-ribaudo/mitata) sur un i7-14700KF, Bun 1.2.13. Plus bas = meilleur. -## 📄 Licence +| Scénario | classigo v2 | classigo/lite | clsx | classnames | +| :--- | ---: | ---: | ---: | ---: | +| 3 strings | **8.67 ns** | 11.54 ns | 24.46 ns | 18.03 ns | +| conditionnel (4 args, 2× `&&`) | **17.24 ns** | 13.42 ns | 31.97 ns | 18.00 ns | +| complexe (8 args, template literals) | **26.38 ns** | 27.94 ns | 58.27 ns | 34.39 ns | +| re-render — toggle boolean | 9.21 ns | **8.66 ns** | 17.08 ns | 11.98 ns | +| syntaxe objet (3 clés) | **20.34 ns** | — | 29.96 ns | 24.96 ns | +| design-system (20 args dynamiques) | **96.45 ns** | 106.28 ns | 148.82 ns | 121.79 ns | +| css-modules (objet 15 clés) | **71.73 ns** | — | 80.45 ns | 83.61 ns | -MIT © [SUP2Ak](https://github.com/SUP2Ak) +Ce que les chiffres disent vraiment : + +- classigo est plus rapide parce qu'il fait moins — pas de gestion de tableaux, pas de récursion, pas de coercition de nombres. La différence de vitesse est une conséquence directe de l'API plus étroite, pas d'une percée algorithmique. +- L'écart se réduit quand la charge augmente (objet 15 clés : 1.12× vs clsx). Quand l'itération `for...in` domine, chaque librairie converge vers le même coût. +- `/lite` gagne sur les patterns boolean-toggle purs — aucun check `typeof`, boucle la plus courte possible. Utilise-le quand tu n'as jamais besoin de la syntaxe objet. +- Ces chiffres ne déplaceront pas l'aiguille dans ton app. Profile tes rendus avant de conclure que les class names sont ton goulot d'étranglement. + +Lance la suite toi-même : + +```sh +bun run bench +``` + +## Contribuer ---- +Voir [CONTRIBUTING.md](./CONTRIBUTING.md) pour les règles complètes. La version courte : utilise Bun, suis les Conventional Commits, lance `bun run test && bun run build` avant d'ouvrir une PR, et inclus un delta de bench si tu touches `src/index.ts` ou `src/lite.ts`. -**Fait avec ❤️ pour la communauté CSS Modules** +## Licence + +MIT © [SUP2Ak](https://github.com/SUP2Ak) diff --git a/README.md b/README.md index 6e98c96..33d7a5e 100644 --- a/README.md +++ b/README.md @@ -1,135 +1,224 @@ -# 🎯 Classigo +# classigo -**Ultra-optimized class name utility for CSS Modules** +> Fast class name utility for TypeScript — strings, objects, zero dependencies. -[![npm version](https://img.shields.io/npm/v/classigo.svg)](https://www.npmjs.com/package/classigo) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![Bundle Size](https://img.shields.io/badge/bundle%20size-159B-brightgreen)](https://bundlephobia.com/package/classigo) +[![npm](https://img.shields.io/npm/v/classigo.svg)](https://www.npmjs.com/package/classigo) +[![downloads](https://img.shields.io/npm/dw/classigo.svg)](https://www.npmjs.com/package/classigo) +[![bundle size](https://img.shields.io/badge/minified-217B-brightgreen)](https://bundlephobia.com/package/classigo) +[![MIT](https://img.shields.io/npm/l/classigo.svg)](./LICENSE) +[![TypeScript](https://img.shields.io/badge/TypeScript-%3E%3D5.0-blue.svg)](https://www.typescriptlang.org/) -## 🚀 Features +> _Version française : [README.fr.md](./README.fr.md)_ -- **⚡ Ultra-fast**: Optimized for maximum performance (52M ops/sec) -- **🎯 Simple API**: Clean and intuitive function signature -- **🔧 TypeScript**: Full TypeScript support with type safety -- **📦 Lightweight**: 159B (59% smaller than clsx) -- **🔄 Standalone**: Pure JavaScript utility, works everywhere -- **🎨 CSS Modules**: Perfect integration with CSS/SCSS Modules -- **📦 Multi-format**: ES Modules, CommonJS, and UMD support +```ts +import classigo from "classigo"; -## 📦 Installation +// Strings + falsy values +classigo("btn", isActive && "btn--active", isDisabled && "btn--disabled"); +// → "btn btn--active" -```bash -npm install classigo +// Object syntax +classigo("btn", { + "btn--active": isActive, + "btn--disabled": isDisabled, + "btn--loading": isLoading, +}); +// → "btn btn--active" + +// Mixed +classigo("btn", `btn--${variant}`, { "btn--active": isActive }); +// → "btn btn--primary btn--active" ``` -```bash -yarn add classigo +## Why classigo? + +Honestly — not because the performance difference will matter in your app. A render cycle costs thousands of nanoseconds; your className utility costs tens. Nobody has ever shipped a slow product because they used clsx. + +The real reason to use classigo is the **contract**. It does not support arrays, numbers, or nested calls — deliberately. That means: + +- Passing an array is a **TypeScript compile error**, not a silent runtime surprise. +- The types accurately describe what the function actually does. +- The bundle is small because there is no code for cases the function doesn't handle. + +| | classigo | classigo/lite | clsx | classnames | +| :--- | :---: | :---: | :---: | :---: | +| Strings + falsy values | ✅ | ✅ | ✅ | ✅ | +| Object syntax (`{ [cls]: boolean }`) | ✅ | ❌ | ✅ | ✅ | +| Arrays / nested calls | ❌ | ❌ | ✅ | ✅ | +| Numbers | ❌ | ❌ | ✅ | ✅ | +| ESM only | ✅ | ✅ | ✅ | ❌ | +| Zero dependencies | ✅ | ✅ | ✅ | ✅ | +| Minified size | **217B** | **137B** | ~560B | ~1.1kB | + +**When to use classigo:** you control all inputs — class names come from strings, template literals, conditionals, or objects. That covers the vast majority of component code in React / Vue / Svelte. + +**When to use clsx instead:** you receive class lists from an external source (CMS, config, API) that may be arrays or nested structures, or a utility in your codebase returns `string[]` that you want to pass directly without spreading. + +```ts +// classigo covers this — you control the inputs +classigo("btn", `btn--${variant}`, { "btn--active": isActive }) + +// clsx covers this — external array of unknown shape +const rules = fetchClassRulesFromCMS(); // (string | string[])[] +clsx(...rules) + +// the spread workaround works when you know the array is flat +classigo(...myKnownFlatArray) // ✅ fine +classigo(...myUnknownArray) // ❌ breaks if any element is itself an array ``` -```bash -pnpm add classigo +**Already using clsx?** Don't migrate. The difference isn't perceptible in a real app. classigo makes sense if you're starting fresh and want a minimal, strict-contract utility — or if you just prefer knowing that an accidental array at a call site is caught at compile time rather than silently joined wrong. + +## Do you even need a class utility? + +For a handful of conditionals, you might not: + +```ts +// Perfectly fine without a library +const cls = ["btn", isActive && "btn--active", isDisabled && "btn--disabled"] + .filter(Boolean) + .join(" "); ``` -```bash +The array approach is readable but allocates a new array every call. Once your component re-renders hundreds of times per second, or your design system calls a class util in every component, that allocation adds up. A tight utility that does one string concatenation pass pays for itself in high-frequency render paths. + +## Install + +```sh bun add classigo +# or +npm i classigo +# or +pnpm add classigo ``` +Requires TypeScript **≥ 5.0**. Zero runtime dependencies. +## API -## 🎯 Quick Start +### `classigo(...classes)` -```typescript -import classigo from 'classigo'; -import styles from './Button.module.css'; +Combines class names, filtering out falsy values. Accepts strings, falsy values (`false`, `null`, `undefined`), and objects (`{ [className]: boolean }`). -// Basic usage -const className = classigo( - styles.button, - styles['button--primary'], - styles['button--large'] -); +```ts +import classigo from "classigo"; +// or +import { classigo } from "classigo"; +``` -// With conditions -const className = classigo( - styles.button, - styles['button--primary'], - isLarge && styles['button--large'], - isDisabled && styles['button--disabled'] -); +```ts +// Strings +classigo("btn", "btn--primary") +// → "btn btn--primary" -// With template literals -const className = classigo( - styles.button, - styles[`button--${variant}`], - isLarge && styles['button--large'] -); +// Falsy values are skipped +classigo("btn", false, null, undefined, "btn--active") +// → "btn btn--active" + +// Conditional with && +classigo("btn", isActive && "btn--active") +// → "btn btn--active" (when isActive is true) +// → "btn" (when isActive is false) + +// Object — each key is included when its value is truthy +classigo("btn", { "btn--active": isActive, "btn--disabled": isDisabled }) +// → "btn btn--active" + +// Template literals +classigo(`card--${variant}`, `card--${size}`) +// → "card--primary card--lg" + +// CSS Modules pattern +classigo(styles.root, { [styles.active]: isActive }) +// → "root active" (when isActive is true) ``` +**Type signature:** +```ts +type ClassObject = Record; +type ClassValue = string | false | null | undefined | ClassObject; -## ⚡ Performance +function classigo(...classes: ClassValue[]): string; +``` -**classigo** is significantly faster and smaller than alternatives: +### `classigo/lite` -- **52.3M ops/sec** vs clsx (45.1M ops/sec) - **16% faster** -- **159B** vs clsx (388B) - **59% smaller** -- **Consistently outperforms** Array.filter().join() and other utilities +A strings-only variant — no object support, smallest possible bundle (137B). Useful when you control all inputs and never need object syntax. -### Benchmark Results +```ts +import classigo from "classigo/lite"; +// or +import { classigo } from "classigo/lite"; +``` + +```ts +classigo("btn", isActive && "btn--active", isDisabled && "btn--disabled"); +// → "btn btn--active" +``` -| Test | classigo | clsx | classnames | -|------|----------|------|------------| -| Basic classes | 🥇 43.2M ops/sec | 🥈 38.5M ops/sec | 🥉 37.3M ops/sec | -| Conditional classes | 🥇 64.4M ops/sec | 🥈 54.3M ops/sec | 🥉 50.3M ops/sec | -| Template literals | 🥇 62.2M ops/sec | 🥈 52.5M ops/sec | 🥉 50.4M ops/sec | -| Falsy values | 🥇 55.6M ops/sec | 🥈 48.8M ops/sec | 🥉 45.3M ops/sec | -| Complex SCSS | 🥇 36.0M ops/sec | 🥈 31.4M ops/sec | 🥉 25.1M ops/sec | +**Type signature:** -### Bundle Size Comparison +```ts +type ClassLiteValue = string | false | null | undefined; -| Library | CJS | ESM | UMD | -|---------|-----|-----|-----| -| **classigo** | **159B** | **195B** | **359B** | -| clsx | 397B | 388B | 543B | -| classnames | 1.5KB | ❌ | ❌ | +function classigo(...classes: ClassLiteValue[]): string; +``` -*Benchmarks run with 1M iterations × 20 rounds* +Passing an object to `classigo/lite` is a **TypeScript compile error** — which is the point. If you want the type system to enforce that no object ever reaches this call site, use `/lite`. -For more information, see [docs/README.md](./docs/README.md). +## Migrating from v1 -## 🎮 Live Examples +v2 has two breaking changes: -- **[All Examples](https://sup2ak.github.io/classigo/)** - Interactive demos showcase -- **[React Demo](https://sup2ak.github.io/classigo/react-demo/)** - Interactive button component with CSS Modules -- **[Vue Demo](https://sup2ak.github.io/classigo/vue-demo/)** - Vue 3 component with Composition API -- **[Svelte Demo](https://sup2ak.github.io/classigo/svelte-demo/)** - Svelte component with reactivity -- **[Vanilla JS Demo](https://sup2ak.github.io/classigo/vanilla-demo/)** - Pure JavaScript implementation +**1. ESM only.** CommonJS (`require("classigo")`) is no longer supported. If your project needs CJS, stay on v1 or use a bundler that converts ESM. -*Examples show real-time className generation and performance comparisons* +**2. Object syntax added.** This is backwards-compatible for pure string usage, but the published types now accept `ClassObject` alongside strings. If you have strict type assertions that assumed `ClassValue` was string-only, update them or switch to `classigo/lite`. -## 🤝 Contributing +```ts +// v1 +classigo("btn", isActive && "btn--active"); // ✅ still works -**Quick start:** -```bash -git clone https://github.com/SUP2Ak/classigo.git -cd classigo -pnpm install -pnpm run build +// v2 — new +classigo("btn", { "btn--active": isActive }); // ✅ object syntax +import classigoLite from "classigo/lite"; // ✅ strings-only export ``` -## 🙏 Acknowledgments +There are no API changes beyond these two. The function signature is otherwise identical. -This utility was inspired by and builds upon the excellent work of: +## Benchmarks -- **[clsx](https://github.com/lukeed/clsx)** by Luke Edwards -- **[classnames](https://github.com/JedWatson/classnames)** by Jed Watson +I bench because I like to know whether what I built is fast or slow — not because these numbers should drive your adoption decision. A className call costs tens of nanoseconds; a React render costs thousands. The bench exists for curiosity and for catching regressions if someone submits a PR that changes the hot path. -This utility was primarily built for my personal use, but if it helps anyone else, that's great! +That said, here are the numbers. Measured with [mitata](https://github.com/nicolo-ribaudo/mitata) on an i7-14700KF, Bun 1.2.13. Lower is better. -## 📄 License +| Scenario | classigo v2 | classigo/lite | clsx | classnames | +| :--- | ---: | ---: | ---: | ---: | +| 3 strings | **8.67 ns** | 11.54 ns | 24.46 ns | 18.03 ns | +| conditional (4 args, 2× `&&`) | **17.24 ns** | 13.42 ns | 31.97 ns | 18.00 ns | +| complex (8 args, template literals) | **26.38 ns** | 27.94 ns | 58.27 ns | 34.39 ns | +| re-render — boolean toggle | 9.21 ns | **8.66 ns** | 17.08 ns | 11.98 ns | +| object syntax (3-key object) | **20.34 ns** | — | 29.96 ns | 24.96 ns | +| design-system (20 dynamic args) | **96.45 ns** | 106.28 ns | 148.82 ns | 121.79 ns | +| css-modules (15-key object) | **71.73 ns** | — | 80.45 ns | 83.61 ns | -MIT © [SUP2Ak](https://github.com/SUP2Ak) +What the numbers actually tell you: + +- classigo is faster because it does less — no array handling, no recursion, no number coercion. The speed difference is a direct consequence of the narrower API, not an algorithmic breakthrough. +- The gap compresses as workload grows (15-key object: 1.12× vs clsx). When `for...in` iteration dominates, every library converges to the same cost. +- `/lite` wins on pure boolean-toggle patterns — no `typeof` check at all, shortest possible loop. Use it when you never need object syntax. +- These numbers will not move the needle in your app. Profile your renders before concluding classnames is your bottleneck. + +Run the suite yourself: + +```sh +bun run bench +``` + +## Contributing ---- +See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full guidelines. The short version: use Bun, follow Conventional Commits, run `bun run test && bun run build` before opening a PR, and include a bench delta if you touch `src/index.ts` or `src/lite.ts`. -**Made with ❤️ for the CSS Modules community** +## License + +MIT © [SUP2Ak](https://github.com/SUP2Ak) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..deb167c --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,29 @@ +# Security Policy + +## Supported versions + +Only the latest published version of classigo receives security fixes. + +| Version | Supported | +| ------- | --------- | +| latest | ✅ | +| older | ❌ | + +## Reporting a vulnerability + +**Do not open a public issue for security reports.** + +Use GitHub's private vulnerability reporting instead: +**[Report a vulnerability](https://github.com/SUP2Ak/classigo/security/advisories/new)** + +Include: + +- A description of the vulnerability and its potential impact. +- Steps to reproduce or a minimal proof of concept. +- The classigo version and runtime (Node/Bun/Deno). + +I will acknowledge your report within **72 hours** and aim to release a fix within **14 days** depending on severity. + +## Scope + +classigo is a zero-dependency string utility with no network access, no file system access, and no external calls. The attack surface is limited to string concatenation and object key iteration. diff --git a/bench/bench.ts b/bench/bench.ts new file mode 100644 index 0000000..df56b21 --- /dev/null +++ b/bench/bench.ts @@ -0,0 +1,795 @@ +import { bench, run, summary, group } from "mitata"; +import { clsx } from "clsx"; +import classnames from "classnames"; +import classigoV2 from "../src/index.ts"; +import classigoLite from "../src/lite.ts"; +// @ts-ignore — v1 CJS default export +import classigoV1npm from "classigo-v1"; + +// --------------------------------------------------------------------------- +// v1 before-optimization inline (for comparison purity) +// --------------------------------------------------------------------------- + +function appendClass(value: string, newClass: string): string { + return !newClass ? value : value ? value + " " + newClass : newClass; +} +function classigoV1inline( + ...classes: (string | undefined | null | false)[] +): string { + let result = ""; + for (let i = 0; i < classes.length; i++) { + const cls = classes[i]; + result = cls ? appendClass(result, cls) : result; + } + return result; +} + +// --------------------------------------------------------------------------- +// v2 before-optimization inline (typeof === "string" check) +// --------------------------------------------------------------------------- + +function classigoV2before( + ...classes: ( + | string + | false + | null + | undefined + | Record + )[] +): string { + let result = ""; + for (let i = 0; i < classes.length; i++) { + const cls = classes[i]; + if (!cls) continue; + if (typeof cls === "string") { + result = result ? result + " " + cls : cls; + continue; + } + const obj = cls as Record; + for (const key in obj) { + if (obj[key]) result = result ? result + " " + key : key; + } + } + return result; +} + +// --------------------------------------------------------------------------- +// Stable test data +// --------------------------------------------------------------------------- + +const variant = "primary"; +const size = "lg"; +const isActive = true; +const isDisabled = false; +const isLoading = false; +const isHovered = true; +let tick = 0; +const states = ["idle", "loading", "success", "error"] as const; +let stateIdx = 0; + +// --------------------------------------------------------------------------- +// Group 1 — Simple: 3 plain strings +// --------------------------------------------------------------------------- + +summary(() => { + group("simple — 3 strings", () => { + bench("classigo v2 (optimized) ", () => + classigoV2("btn", "btn--primary", "btn--lg"), + ); + bench("classigo v2 (before) ", () => + classigoV2before("btn", "btn--primary", "btn--lg"), + ); + bench("classigo v1 (npm 1.0.1) ", () => + classigoV1npm("btn", "btn--primary", "btn--lg"), + ); + bench("classigo v1 (inline) ", () => + classigoV1inline("btn", "btn--primary", "btn--lg"), + ); + bench("classigo lite ", () => + classigoLite("btn", "btn--primary", "btn--lg"), + ); + bench("clsx ", () => + clsx("btn", "btn--primary", "btn--lg"), + ); + bench("classnames ", () => + classnames("btn", "btn--primary", "btn--lg"), + ); + }); +}); + +// --------------------------------------------------------------------------- +// Group 2 — Conditional strings with && +// --------------------------------------------------------------------------- + +summary(() => { + group("conditional — 4 args, 2 with &&", () => { + bench("classigo v2 (optimized) ", () => + classigoV2( + "btn", + `btn--${variant}`, + isActive && "btn--active", + isDisabled && "btn--disabled", + ), + ); + bench("classigo v2 (before) ", () => + classigoV2before( + "btn", + `btn--${variant}`, + isActive && "btn--active", + isDisabled && "btn--disabled", + ), + ); + bench("classigo v1 (npm 1.0.1) ", () => + classigoV1npm( + "btn", + `btn--${variant}`, + isActive && "btn--active", + isDisabled && "btn--disabled", + ), + ); + bench("classigo v1 (inline) ", () => + classigoV1inline( + "btn", + `btn--${variant}`, + isActive && "btn--active", + isDisabled && "btn--disabled", + ), + ); + bench("classigo lite ", () => + classigoLite( + "btn", + `btn--${variant}`, + isActive && "btn--active", + isDisabled && "btn--disabled", + ), + ); + bench("clsx ", () => + clsx( + "btn", + `btn--${variant}`, + isActive && "btn--active", + isDisabled && "btn--disabled", + ), + ); + bench("classnames ", () => + classnames( + "btn", + `btn--${variant}`, + isActive && "btn--active", + isDisabled && "btn--disabled", + ), + ); + }); +}); + +// --------------------------------------------------------------------------- +// Group 3 — Complex: 8 args +// --------------------------------------------------------------------------- + +summary(() => { + group("complex — 8 args, template literals + conditionals", () => { + bench("classigo v2 (optimized) ", () => + classigoV2( + "card", + `card--${variant}`, + `card--${size}`, + isActive && "card--active", + isDisabled && "card--disabled", + isLoading && "card--loading", + isHovered && "card--hovered", + "card--rounded", + ), + ); + bench("classigo v2 (before) ", () => + classigoV2before( + "card", + `card--${variant}`, + `card--${size}`, + isActive && "card--active", + isDisabled && "card--disabled", + isLoading && "card--loading", + isHovered && "card--hovered", + "card--rounded", + ), + ); + bench("classigo v1 (npm 1.0.1) ", () => + classigoV1npm( + "card", + `card--${variant}`, + `card--${size}`, + isActive && "card--active", + isDisabled && "card--disabled", + isLoading && "card--loading", + isHovered && "card--hovered", + "card--rounded", + ), + ); + bench("classigo v1 (inline) ", () => + classigoV1inline( + "card", + `card--${variant}`, + `card--${size}`, + isActive && "card--active", + isDisabled && "card--disabled", + isLoading && "card--loading", + isHovered && "card--hovered", + "card--rounded", + ), + ); + bench("classigo lite ", () => + classigoLite( + "card", + `card--${variant}`, + `card--${size}`, + isActive && "card--active", + isDisabled && "card--disabled", + isLoading && "card--loading", + isHovered && "card--hovered", + "card--rounded", + ), + ); + bench("clsx ", () => + clsx( + "card", + `card--${variant}`, + `card--${size}`, + isActive && "card--active", + isDisabled && "card--disabled", + isLoading && "card--loading", + isHovered && "card--hovered", + "card--rounded", + ), + ); + bench("classnames ", () => + classnames( + "card", + `card--${variant}`, + `card--${size}`, + isActive && "card--active", + isDisabled && "card--disabled", + isLoading && "card--loading", + isHovered && "card--hovered", + "card--rounded", + ), + ); + }); +}); + +// --------------------------------------------------------------------------- +// Group 4 — Object syntax (v1 N/A) +// --------------------------------------------------------------------------- + +summary(() => { + group("object syntax — v1 N/A", () => { + bench("classigo v2 (optimized) ", () => + classigoV2("btn", { + "btn--active": isActive, + "btn--disabled": isDisabled, + "btn--loading": isLoading, + }), + ); + bench("classigo v2 (before) ", () => + classigoV2before("btn", { + "btn--active": isActive, + "btn--disabled": isDisabled, + "btn--loading": isLoading, + }), + ); + bench("clsx ", () => + clsx("btn", { + "btn--active": isActive, + "btn--disabled": isDisabled, + "btn--loading": isLoading, + }), + ); + bench("classnames ", () => + classnames("btn", { + "btn--active": isActive, + "btn--disabled": isDisabled, + "btn--loading": isLoading, + }), + ); + }); +}); + +// --------------------------------------------------------------------------- +// Group 5 — Re-render: boolean toggles each call +// --------------------------------------------------------------------------- + +summary(() => { + group("re-render — boolean toggles each call", () => { + bench("classigo v2 (optimized) ", () => { + tick ^= 1; + return classigoV2( + "btn", + tick ? "btn--active" : null, + isDisabled && "btn--disabled", + ); + }); + bench("classigo v2 (before) ", () => { + tick ^= 1; + return classigoV2before( + "btn", + tick ? "btn--active" : null, + isDisabled && "btn--disabled", + ); + }); + bench("classigo v1 (npm 1.0.1) ", () => { + tick ^= 1; + return classigoV1npm( + "btn", + tick ? "btn--active" : undefined, + isDisabled && "btn--disabled", + ); + }); + bench("classigo v1 (inline) ", () => { + tick ^= 1; + return classigoV1inline( + "btn", + tick ? "btn--active" : undefined, + isDisabled && "btn--disabled", + ); + }); + bench("classigo lite ", () => { + tick ^= 1; + return classigoLite( + "btn", + tick ? "btn--active" : undefined, + isDisabled && "btn--disabled", + ); + }); + bench("clsx ", () => { + tick ^= 1; + return clsx( + "btn", + tick ? "btn--active" : null, + isDisabled && "btn--disabled", + ); + }); + bench("classnames ", () => { + tick ^= 1; + return classnames( + "btn", + tick ? "btn--active" : null, + isDisabled && "btn--disabled", + ); + }); + }); +}); + +// --------------------------------------------------------------------------- +// Group 6 — Re-render inline object (anti-pattern) +// --------------------------------------------------------------------------- + +summary(() => { + group("re-render — inline object recreated each call", () => { + bench("classigo v2 (optimized) ", () => { + tick ^= 1; + return classigoV2("btn", { + "btn--active": tick === 1, + "btn--primary": true, + }); + }); + bench("classigo v2 (before) ", () => { + tick ^= 1; + return classigoV2before("btn", { + "btn--active": tick === 1, + "btn--primary": true, + }); + }); + bench("clsx ", () => { + tick ^= 1; + return clsx("btn", { "btn--active": tick === 1, "btn--primary": true }); + }); + bench("classnames ", () => { + tick ^= 1; + return classnames("btn", { + "btn--active": tick === 1, + "btn--primary": true, + }); + }); + }); +}); + +// --------------------------------------------------------------------------- +// Group 7 — Ultra-dynamic: all args vary per call +// --------------------------------------------------------------------------- + +summary(() => { + group("ultra-dynamic — all args vary per call", () => { + bench("classigo v2 (optimized) ", () => { + stateIdx = (stateIdx + 1) % states.length; + const s = states[stateIdx]!; + return classigoV2( + "badge", + `badge--${s}`, + s === "loading" && "badge--pulse", + s === "error" && "badge--shake", + { + "badge--visible": s !== "idle", + "badge--highlighted": s === "success", + }, + ); + }); + bench("classigo v2 (before) ", () => { + stateIdx = (stateIdx + 1) % states.length; + const s = states[stateIdx]!; + return classigoV2before( + "badge", + `badge--${s}`, + s === "loading" && "badge--pulse", + s === "error" && "badge--shake", + { + "badge--visible": s !== "idle", + "badge--highlighted": s === "success", + }, + ); + }); + bench("clsx ", () => { + stateIdx = (stateIdx + 1) % states.length; + const s = states[stateIdx]!; + return clsx( + "badge", + `badge--${s}`, + s === "loading" && "badge--pulse", + s === "error" && "badge--shake", + { + "badge--visible": s !== "idle", + "badge--highlighted": s === "success", + }, + ); + }); + bench("classnames ", () => { + stateIdx = (stateIdx + 1) % states.length; + const s = states[stateIdx]!; + return classnames( + "badge", + `badge--${s}`, + s === "loading" && "badge--pulse", + s === "error" && "badge--shake", + { + "badge--visible": s !== "idle", + "badge--highlighted": s === "success", + }, + ); + }); + }); +}); + +// --------------------------------------------------------------------------- +// Group 8 — Design-system: 20 args, fully dynamic (defeats JIT constant folding) +// Simulates a real complex component — large class pool rotating across calls +// --------------------------------------------------------------------------- + +const dsComponents = [ + "btn", + "card", + "badge", + "input", + "modal", + "chip", + "avatar", + "tag", +] as const; +const dsVariants = [ + "primary", + "secondary", + "danger", + "warning", + "success", + "info", + "ghost", + "outline", +] as const; +const dsSizes = ["xs", "sm", "md", "lg", "xl", "2xl"] as const; +const dsRounded = ["none", "sm", "md", "lg", "full"] as const; +let dsN = 0; + +summary(() => { + group("design-system — 20 dynamic args (large class pool)", () => { + bench("classigo v2 (optimized) ", () => { + const n = ++dsN; + const c = dsComponents[n % dsComponents.length]!; + const v = dsVariants[n % dsVariants.length]!; + const sz = dsSizes[n % dsSizes.length]!; + const r = dsRounded[n % dsRounded.length]!; + return classigoV2( + c, + `${c}--${v}`, + `${c}--${sz}`, + `${c}--rounded-${r}`, + n % 3 === 0 && `${c}--active`, + n % 7 === 0 && `${c}--disabled`, + n % 5 === 0 && `${c}--loading`, + n % 4 === 0 && `${c}--focused`, + n % 2 === 0 && `${c}--hovered`, + n % 6 === 0 && `${c}--selected`, + n % 9 === 0 && `${c}--dragging`, + n % 11 === 0 && `${c}--expanded`, + n % 13 === 0 && `${c}--highlighted`, + n % 15 === 0 && `${c}--truncated`, + n % 17 === 0 && `${c}--elevated`, + n % 19 === 0 && `${c}--bordered`, + n % 23 === 0 && `${c}--animated`, + n % 29 === 0 && `${c}--rtl`, + "transition", + "will-change-transform", + ); + }); + bench("classigo v2 (before) ", () => { + const n = ++dsN; + const c = dsComponents[n % dsComponents.length]!; + const v = dsVariants[n % dsVariants.length]!; + const sz = dsSizes[n % dsSizes.length]!; + const r = dsRounded[n % dsRounded.length]!; + return classigoV2before( + c, + `${c}--${v}`, + `${c}--${sz}`, + `${c}--rounded-${r}`, + n % 3 === 0 && `${c}--active`, + n % 7 === 0 && `${c}--disabled`, + n % 5 === 0 && `${c}--loading`, + n % 4 === 0 && `${c}--focused`, + n % 2 === 0 && `${c}--hovered`, + n % 6 === 0 && `${c}--selected`, + n % 9 === 0 && `${c}--dragging`, + n % 11 === 0 && `${c}--expanded`, + n % 13 === 0 && `${c}--highlighted`, + n % 15 === 0 && `${c}--truncated`, + n % 17 === 0 && `${c}--elevated`, + n % 19 === 0 && `${c}--bordered`, + n % 23 === 0 && `${c}--animated`, + n % 29 === 0 && `${c}--rtl`, + "transition", + "will-change-transform", + ); + }); + bench("classigo v1 (npm 1.0.1) ", () => { + const n = ++dsN; + const c = dsComponents[n % dsComponents.length]!; + const v = dsVariants[n % dsVariants.length]!; + const sz = dsSizes[n % dsSizes.length]!; + const r = dsRounded[n % dsRounded.length]!; + return classigoV1npm( + c, + `${c}--${v}`, + `${c}--${sz}`, + `${c}--rounded-${r}`, + n % 3 === 0 && `${c}--active`, + n % 7 === 0 && `${c}--disabled`, + n % 5 === 0 && `${c}--loading`, + n % 4 === 0 && `${c}--focused`, + n % 2 === 0 && `${c}--hovered`, + n % 6 === 0 && `${c}--selected`, + n % 9 === 0 && `${c}--dragging`, + n % 11 === 0 && `${c}--expanded`, + n % 13 === 0 && `${c}--highlighted`, + n % 15 === 0 && `${c}--truncated`, + n % 17 === 0 && `${c}--elevated`, + n % 19 === 0 && `${c}--bordered`, + n % 23 === 0 && `${c}--animated`, + n % 29 === 0 && `${c}--rtl`, + "transition", + "will-change-transform", + ); + }); + bench("classigo lite ", () => { + const n = ++dsN; + const c = dsComponents[n % dsComponents.length]!; + const v = dsVariants[n % dsVariants.length]!; + const sz = dsSizes[n % dsSizes.length]!; + const r = dsRounded[n % dsRounded.length]!; + return classigoLite( + c, + `${c}--${v}`, + `${c}--${sz}`, + `${c}--rounded-${r}`, + n % 3 === 0 && `${c}--active`, + n % 7 === 0 && `${c}--disabled`, + n % 5 === 0 && `${c}--loading`, + n % 4 === 0 && `${c}--focused`, + n % 2 === 0 && `${c}--hovered`, + n % 6 === 0 && `${c}--selected`, + n % 9 === 0 && `${c}--dragging`, + n % 11 === 0 && `${c}--expanded`, + n % 13 === 0 && `${c}--highlighted`, + n % 15 === 0 && `${c}--truncated`, + n % 17 === 0 && `${c}--elevated`, + n % 19 === 0 && `${c}--bordered`, + n % 23 === 0 && `${c}--animated`, + n % 29 === 0 && `${c}--rtl`, + "transition", + "will-change-transform", + ); + }); + bench("clsx ", () => { + const n = ++dsN; + const c = dsComponents[n % dsComponents.length]!; + const v = dsVariants[n % dsVariants.length]!; + const sz = dsSizes[n % dsSizes.length]!; + const r = dsRounded[n % dsRounded.length]!; + return clsx( + c, + `${c}--${v}`, + `${c}--${sz}`, + `${c}--rounded-${r}`, + n % 3 === 0 && `${c}--active`, + n % 7 === 0 && `${c}--disabled`, + n % 5 === 0 && `${c}--loading`, + n % 4 === 0 && `${c}--focused`, + n % 2 === 0 && `${c}--hovered`, + n % 6 === 0 && `${c}--selected`, + n % 9 === 0 && `${c}--dragging`, + n % 11 === 0 && `${c}--expanded`, + n % 13 === 0 && `${c}--highlighted`, + n % 15 === 0 && `${c}--truncated`, + n % 17 === 0 && `${c}--elevated`, + n % 19 === 0 && `${c}--bordered`, + n % 23 === 0 && `${c}--animated`, + n % 29 === 0 && `${c}--rtl`, + "transition", + "will-change-transform", + ); + }); + bench("classnames ", () => { + const n = ++dsN; + const c = dsComponents[n % dsComponents.length]!; + const v = dsVariants[n % dsVariants.length]!; + const sz = dsSizes[n % dsSizes.length]!; + const r = dsRounded[n % dsRounded.length]!; + return classnames( + c, + `${c}--${v}`, + `${c}--${sz}`, + `${c}--rounded-${r}`, + n % 3 === 0 && `${c}--active`, + n % 7 === 0 && `${c}--disabled`, + n % 5 === 0 && `${c}--loading`, + n % 4 === 0 && `${c}--focused`, + n % 2 === 0 && `${c}--hovered`, + n % 6 === 0 && `${c}--selected`, + n % 9 === 0 && `${c}--dragging`, + n % 11 === 0 && `${c}--expanded`, + n % 13 === 0 && `${c}--highlighted`, + n % 15 === 0 && `${c}--truncated`, + n % 17 === 0 && `${c}--elevated`, + n % 19 === 0 && `${c}--bordered`, + n % 23 === 0 && `${c}--animated`, + n % 29 === 0 && `${c}--rtl`, + "transition", + "will-change-transform", + ); + }); + }); +}); + +// --------------------------------------------------------------------------- +// Group 9 — CSS-modules pattern: large object, 15 keys, all dynamic +// Closest to real usage: { [styles.active]: isActive, ... } +// --------------------------------------------------------------------------- + +let cssN = 0; + +summary(() => { + group("css-modules — large object, 15 dynamic keys", () => { + bench("classigo v2 (optimized) ", () => { + const n = ++cssN; + return classigoV2("root", { + active: n % 3 === 0, + disabled: n % 7 === 0, + loading: n % 5 === 0, + focused: n % 4 === 0, + hovered: n % 2 === 0, + selected: n % 6 === 0, + dragging: n % 9 === 0, + expanded: n % 11 === 0, + highlighted: n % 13 === 0, + truncated: n % 15 === 0, + elevated: n % 17 === 0, + bordered: n % 19 === 0, + animated: n % 23 === 0, + rtl: n % 29 === 0, + fullWidth: n % 31 === 0, + }); + }); + bench("classigo v2 (before) ", () => { + const n = ++cssN; + return classigoV2before("root", { + active: n % 3 === 0, + disabled: n % 7 === 0, + loading: n % 5 === 0, + focused: n % 4 === 0, + hovered: n % 2 === 0, + selected: n % 6 === 0, + dragging: n % 9 === 0, + expanded: n % 11 === 0, + highlighted: n % 13 === 0, + truncated: n % 15 === 0, + elevated: n % 17 === 0, + bordered: n % 19 === 0, + animated: n % 23 === 0, + rtl: n % 29 === 0, + fullWidth: n % 31 === 0, + }); + }); + bench("clsx ", () => { + const n = ++cssN; + return clsx("root", { + active: n % 3 === 0, + disabled: n % 7 === 0, + loading: n % 5 === 0, + focused: n % 4 === 0, + hovered: n % 2 === 0, + selected: n % 6 === 0, + dragging: n % 9 === 0, + expanded: n % 11 === 0, + highlighted: n % 13 === 0, + truncated: n % 15 === 0, + elevated: n % 17 === 0, + bordered: n % 19 === 0, + animated: n % 23 === 0, + rtl: n % 29 === 0, + fullWidth: n % 31 === 0, + }); + }); + bench("classnames ", () => { + const n = ++cssN; + return classnames("root", { + active: n % 3 === 0, + disabled: n % 7 === 0, + loading: n % 5 === 0, + focused: n % 4 === 0, + hovered: n % 2 === 0, + selected: n % 6 === 0, + dragging: n % 9 === 0, + expanded: n % 11 === 0, + highlighted: n % 13 === 0, + truncated: n % 15 === 0, + elevated: n % 17 === 0, + bordered: n % 19 === 0, + animated: n % 23 === 0, + rtl: n % 29 === 0, + fullWidth: n % 31 === 0, + }); + }); + }); +}); + +// --------------------------------------------------------------------------- +// Package sizes +// --------------------------------------------------------------------------- + +import { statSync } from "fs"; +import { resolve, dirname } from "path"; +import { fileURLToPath } from "url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const kb = (b: number) => (b / 1024).toFixed(2) + " kB"; +const sz = (p: string) => { + try { + return statSync(p).size; + } catch { + return null; + } +}; + +const v2Size = sz(resolve(__dirname, "../dist/index.js")); +const liteSize = sz(resolve(__dirname, "../dist/lite.js")); +const v1Size = sz( + resolve(__dirname, "../node_modules/classigo-v1/dist/index.mjs"), +); +const clsxSize = sz(resolve(__dirname, "../node_modules/clsx/dist/clsx.mjs")); +const cnSize = sz(resolve(__dirname, "../node_modules/classnames/index.js")); + +console.log("\n── Package sizes (minified) ────────────────────"); +console.log(`classigo v2 ${v2Size ? kb(v2Size).padStart(9) : "build first"}`); +console.log( + `classigo lite ${liteSize ? kb(liteSize).padStart(9) : "build first"}`, +); +console.log(`classigo v1 ${v1Size ? kb(v1Size).padStart(9) : "N/A"}`); +console.log(`clsx ${clsxSize ? kb(clsxSize).padStart(9) : "N/A"}`); +console.log(`classnames ${cnSize ? kb(cnSize).padStart(9) : "N/A"}`); +console.log("────────────────────────────────────────────────\n"); + +await run(); diff --git a/bench/index.js b/bench/index.js deleted file mode 100644 index aaf4de3..0000000 --- a/bench/index.js +++ /dev/null @@ -1,627 +0,0 @@ -/* global require, console, __dirname */ - -const { performance } = require("perf_hooks"); -const fs = require("fs"); -const path = require("path"); - -// Import our competitors -const classnames = require("classnames"); -const clsx = require("clsx"); -const classigo = require("../dist/index.cjs"); - -// ============================================================================ -// MASSIVE CLASS GENERATION -// ============================================================================ - -function generateMassiveClasses(count = 10000) { - const classes = []; - const conditions = []; - - // Generate base classes - for (let i = 0; i < count; i++) { - classes.push(`class-${i}`); - - // Generate conditional classes (50% true, 50% false) - const isActive = Math.random() > 0.5; - conditions.push(isActive ? `active-${i}` : false); - } - - return { classes, conditions }; -} - -function generateComplexClasses(count = 5000) { - const baseClasses = []; - const conditionalClasses = []; - const templateClasses = []; - - const variants = ['primary', 'secondary', 'success', 'warning', 'danger']; - const sizes = ['small', 'medium', 'large', 'xl']; - const states = ['hover', 'focus', 'active', 'disabled']; - - for (let i = 0; i < count; i++) { - // Base classes - baseClasses.push(`component-${i}`); - - // Conditional classes with complex logic - const shouldShow = Math.random() > 0.3; - const isEnabled = Math.random() > 0.2; - const hasError = Math.random() > 0.1; - - conditionalClasses.push({ - [`enabled-${i}`]: isEnabled, - [`error-${i}`]: hasError, - [`visible-${i}`]: shouldShow - }); - - // Template literal classes - const variant = variants[Math.floor(Math.random() * variants.length)]; - const size = sizes[Math.floor(Math.random() * sizes.length)]; - const state = states[Math.floor(Math.random() * states.length)]; - - templateClasses.push({ - base: `btn-${i}`, - variant: `btn--${variant}`, - size: `btn--${size}`, - state: `btn--${state}` - }); - } - - return { baseClasses, conditionalClasses, templateClasses }; -} - -// ============================================================================ -// SIZE ANALYSIS -// ============================================================================ - -function getFileSize(filePath) { - try { - const stats = fs.statSync(filePath); - return stats.size; - } catch (error) { - console.error("Error getting file size:", error); - return null; - } -} - -function formatBytes(bytes) { - if (bytes === 0) return "0 B"; - const k = 1024; - const sizes = ["B", "KB", "MB"]; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + " " + sizes[i]; -} - -function analyzeSizes() { - console.log("📦 Bundle Size Analysis\n"); - - // Get all format files - const packages = [ - { - name: "classnames", - formats: [ - { type: "CJS", path: require.resolve("classnames") }, - ], - }, - { - name: "clsx", - formats: [ - { type: "CJS", path: path.resolve("./node_modules/clsx/dist/clsx.js") }, - { - type: "ESM", - path: path.resolve("./node_modules/clsx/dist/clsx.mjs"), - }, - { - type: "UMD", - path: path.resolve("./node_modules/clsx/dist/clsx.min.js"), - }, - ], - }, - { - name: "classigo", - formats: [ - { type: "CJS", path: path.resolve(__dirname, "../dist/index.cjs") }, - { type: "ESM", path: path.resolve(__dirname, "../dist/index.mjs") }, - { type: "UMD", path: path.resolve(__dirname, "../dist/index.umd.js") }, - ], - }, - ]; - - // Analyze each package - packages.forEach((pkg) => { - console.log(`📦 ${pkg.name.toUpperCase()}:`); - console.log("─".repeat(30)); - - pkg.formats.forEach((format) => { - const size = getFileSize(format.path); - console.log( - ` ${format.type.padEnd(4)}: ${ - size !== null ? formatBytes(size).padStart(8) : "NOT FOUND" - }`, - ); - }); - - // Find smallest format - const sizes = pkg.formats.map((f) => ({ ...f, size: getFileSize(f.path) })) - .filter((f) => f.size !== null); - if (sizes.length > 0) { - const smallest = sizes.reduce((min, f) => f.size < min.size ? f : min); - console.log( - ` 🏆 Smallest: ${smallest.type} (${formatBytes(smallest.size)})`, - ); - } - - console.log(""); - }); - - // Compare smallest versions - console.log("🏆 SMALLEST VERSIONS COMPARISON:"); - console.log("─".repeat(40)); - - const smallestVersions = packages.map((pkg) => { - const sizes = pkg.formats.map((f) => ({ ...f, size: getFileSize(f.path) })) - .filter((f) => f.size !== null); - - if (sizes.length === 0) { - return { name: pkg.name, size: null, type: "N/A" }; - } - - const smallest = sizes.reduce((min, f) => f.size < min.size ? f : min); - return { name: pkg.name, ...smallest }; - }).sort((a, b) => { - if (a.size === null && b.size === null) return 0; - if (a.size === null) return 1; - if (b.size === null) return -1; - return a.size - b.size; - }); - - smallestVersions.forEach((pkg, index) => { - const medal = index === 0 ? "🥇" : index === 1 ? "🥈" : "🥉"; - const sizeDisplay = pkg.size !== null - ? formatBytes(pkg.size).padStart(8) - : "NOT FOUND".padStart(8); - console.log( - `${medal} ${pkg.name.padEnd(12)} ${sizeDisplay} (${pkg.type})`, - ); - }); - - return smallestVersions; -} - -// ============================================================================ -// RUNTIME BENCHMARK -// ============================================================================ - -// Test data -const isActive = true; -const isLarge = false; -const variant = "primary"; - -// Benchmark configuration -const ITERATIONS = 1000000; -const WARMUP_ITERATIONS = 100000; -const ROUNDS = 20; - -// Utility to run benchmark with multiple rounds -function runBenchmark(name, fn) { - const results = []; - - for (let round = 0; round < ROUNDS; round++) { - // Warmup - for (let i = 0; i < WARMUP_ITERATIONS; i++) { - fn(); - } - - // Actual benchmark - const start = performance.now(); - for (let i = 0; i < ITERATIONS; i++) { - fn(); - } - const end = performance.now(); - - const duration = end - start; - const opsPerSec = Math.round((ITERATIONS / duration) * 1000); - results.push(opsPerSec); - } - - // Calculate statistics - const avg = Math.round(results.reduce((a, b) => a + b, 0) / results.length); - const min = Math.min(...results); - const max = Math.max(...results); - const median = results.sort((a, b) => a - b)[Math.floor(results.length / 2)]; - - return { name, results, avg, min, max, median }; -} - -function runBenchmarks() { - console.log("🏃‍♂️ Runtime Performance Benchmark\n"); - console.log(`Iterations: ${ITERATIONS.toLocaleString()}`); - console.log(`Warmup iterations: ${WARMUP_ITERATIONS.toLocaleString()}`); - console.log(`Rounds: ${ROUNDS}\n`); - - // Test cases - const testCases = [ - { - name: "Basic classes", - classnames: () => - classnames("button", "button--primary", "button--large"), - clsx: () => clsx("button", "button--primary", "button--large"), - classigo: () => classigo("button", "button--primary", "button--large"), - }, - { - name: "Conditional classes", - classnames: () => - classnames( - "button", - isActive && "button--active", - isLarge && "button--large", - ), - clsx: () => - clsx( - "button", - isActive && "button--active", - isLarge && "button--large", - ), - classigo: () => - classigo( - "button", - isActive && "button--active", - isLarge && "button--large", - ), - }, - { - name: "Template literals", - classnames: () => - classnames("button", `button--${variant}`, isLarge && "button--large"), - clsx: () => - clsx("button", `button--${variant}`, isLarge && "button--large"), - classigo: () => - classigo("button", `button--${variant}`, isLarge && "button--large"), - }, - { - name: "Falsy values", - classnames: () => - classnames("button", null, undefined, false, "button--primary"), - clsx: () => clsx("button", null, undefined, false, "button--primary"), - classigo: () => - classigo("button", null, undefined, false, "button--primary"), - }, - { - name: "Complex SCSS", - classnames: () => - classnames( - "card", - "card--elevated", - isActive && "card--interactive", - `card--${variant}`, - ), - clsx: () => - clsx( - "card", - "card--elevated", - isActive && "card--interactive", - `card--${variant}`, - ), - classigo: () => - classigo( - "card", - "card--elevated", - isActive && "card--interactive", - `card--${variant}`, - ), - }, - ]; - - const results = []; - - testCases.forEach((testCase, index) => { - console.log(`📊 Test ${index + 1}: ${testCase.name}`); - console.log("─".repeat(50)); - - const classnamesResult = runBenchmark("classnames", testCase.classnames); - const clsxResult = runBenchmark("clsx", testCase.clsx); - const classigoResult = runBenchmark("classigo", testCase.classigo); - - // Sort by performance - const sortedResults = [classnamesResult, clsxResult, classigoResult] - .sort((a, b) => b.avg - a.avg); - - sortedResults.forEach((result, rank) => { - const medal = rank === 0 ? "🥇" : rank === 1 ? "🥈" : "🥉"; - console.log( - `${medal} ${result.name.padEnd(12)} ${ - result.avg.toLocaleString().padStart(8) - } avg ops/sec`, - ); - console.log( - ` └─ Min: ${result.min.toLocaleString().padStart(6)} | Max: ${ - result.max.toLocaleString().padStart(6) - } | Median: ${result.median.toLocaleString().padStart(6)}`, - ); - }); - - console.log(""); - results.push({ testCase: testCase.name, results: sortedResults }); - }); - - // Summary - console.log("📈 RUNTIME SUMMARY"); - console.log("─".repeat(50)); - - const summary = { - classnames: { total: 0, wins: 0 }, - clsx: { total: 0, wins: 0 }, - classigo: { total: 0, wins: 0 }, - }; - - results.forEach(({ results: testResults }) => { - testResults.forEach((result, rank) => { - summary[result.name].total += result.avg; - if (rank === 0) summary[result.name].wins++; - }); - }); - - const sortedSummary = Object.entries(summary) - .map(([name, data]) => ({ - name, - ...data, - avg: Math.round(data.total / results.length), - })) - .sort((a, b) => b.avg - a.avg); - - sortedSummary.forEach((lib, rank) => { - const medal = rank === 0 ? "🥇" : rank === 1 ? "🥈" : "🥉"; - console.log( - `${medal} ${lib.name.padEnd(12)} ${ - lib.avg.toLocaleString().padStart(8) - } avg ops/sec (${lib.wins} wins)`, - ); - }); - - return sortedSummary; -} - -// ============================================================================ -// MASSIVE BENCHMARK -// ============================================================================ - -function runMassiveBenchmark() { - console.log("🔥 MASSIVE CLASS BENCHMARK (10,000+ classes)\n"); - - // Generate massive test data - const { classes, conditions } = generateMassiveClasses(10000); - const { templateClasses } = generateComplexClasses(5000); - - console.log(`📊 Generated ${classes.length.toLocaleString()} base classes`); - console.log(`📊 Generated ${templateClasses.length.toLocaleString()} template classes\n`); - - // Benchmark configuration for massive tests - const MASSIVE_ITERATIONS = 10000; - const MASSIVE_WARMUP = 1000; - const MASSIVE_ROUNDS = 10; - - function runMassiveBenchmark(name, fn) { - const results = []; - - for (let round = 0; round < MASSIVE_ROUNDS; round++) { - // Warmup - for (let i = 0; i < MASSIVE_WARMUP; i++) { - fn(); - } - - // Actual benchmark - const start = performance.now(); - for (let i = 0; i < MASSIVE_ITERATIONS; i++) { - fn(); - } - const end = performance.now(); - - const duration = end - start; - const opsPerSec = Math.round((MASSIVE_ITERATIONS / duration) * 1000); - results.push(opsPerSec); - } - - const avg = Math.round(results.reduce((a, b) => a + b, 0) / results.length); - const min = Math.min(...results); - const max = Math.max(...results); - - return { name, avg, min, max }; - } - - // Test 1: Massive array of classes - console.log("📊 Test 1: Massive Array (10,000 classes)"); - console.log("─".repeat(50)); - - const massiveArrayResults = [ - runMassiveBenchmark("classnames", () => classnames(...classes)), - runMassiveBenchmark("clsx", () => clsx(...classes)), - runMassiveBenchmark("classigo", () => classigo(...classes)) - ].sort((a, b) => b.avg - a.avg); - - massiveArrayResults.forEach((result, rank) => { - const medal = rank === 0 ? "🥇" : rank === 1 ? "🥈" : "🥉"; - console.log( - `${medal} ${result.name.padEnd(12)} ${ - result.avg.toLocaleString().padStart(8) - } ops/sec` - ); - }); - - console.log(""); - - // Test 2: Massive conditional classes - console.log("📊 Test 2: Massive Conditionals (10,000 conditions)"); - console.log("─".repeat(50)); - - const massiveConditionalResults = [ - runMassiveBenchmark("classnames", () => { - const args = []; - for (let i = 0; i < classes.length; i++) { - args.push(classes[i]); - args.push(conditions[i]); - } - return classnames(...args); - }), - runMassiveBenchmark("clsx", () => { - const args = []; - for (let i = 0; i < classes.length; i++) { - args.push(classes[i]); - args.push(conditions[i]); - } - return clsx(...args); - }), - runMassiveBenchmark("classigo", () => { - const args = []; - for (let i = 0; i < classes.length; i++) { - args.push(classes[i]); - args.push(conditions[i]); - } - return classigo(...args); - }) - ].sort((a, b) => b.avg - a.avg); - - massiveConditionalResults.forEach((result, rank) => { - const medal = rank === 0 ? "🥇" : rank === 1 ? "🥈" : "🥉"; - console.log( - `${medal} ${result.name.padEnd(12)} ${ - result.avg.toLocaleString().padStart(8) - } ops/sec` - ); - }); - - console.log(""); - - // Test 3: Complex template literals - console.log("📊 Test 3: Complex Templates (5,000 templates)"); - console.log("─".repeat(50)); - - const complexTemplateResults = [ - runMassiveBenchmark("classnames", () => { - const args = []; - for (let i = 0; i < templateClasses.length; i++) { - const tpl = templateClasses[i]; - args.push(tpl.base, tpl.variant, tpl.size, tpl.state); - } - return classnames(...args); - }), - runMassiveBenchmark("clsx", () => { - const args = []; - for (let i = 0; i < templateClasses.length; i++) { - const tpl = templateClasses[i]; - args.push(tpl.base, tpl.variant, tpl.size, tpl.state); - } - return clsx(...args); - }), - runMassiveBenchmark("classigo", () => { - const args = []; - for (let i = 0; i < templateClasses.length; i++) { - const tpl = templateClasses[i]; - args.push(tpl.base, tpl.variant, tpl.size, tpl.state); - } - return classigo(...args); - }) - ].sort((a, b) => b.avg - a.avg); - - complexTemplateResults.forEach((result, rank) => { - const medal = rank === 0 ? "🥇" : rank === 1 ? "🥈" : "🥉"; - console.log( - `${medal} ${result.name.padEnd(12)} ${ - result.avg.toLocaleString().padStart(8) - } ops/sec` - ); - }); - - console.log(""); - - // Massive summary - console.log("🔥 MASSIVE BENCHMARK SUMMARY"); - console.log("─".repeat(50)); - - const massiveSummary = { - classnames: { total: 0, wins: 0 }, - clsx: { total: 0, wins: 0 }, - classigo: { total: 0, wins: 0 } - }; - - [massiveArrayResults, massiveConditionalResults, complexTemplateResults].forEach(results => { - results.forEach((result, rank) => { - massiveSummary[result.name].total += result.avg; - if (rank === 0) massiveSummary[result.name].wins++; - }); - }); - - const sortedMassiveSummary = Object.entries(massiveSummary) - .map(([name, data]) => ({ - name, - ...data, - avg: Math.round(data.total / 3) - })) - .sort((a, b) => b.avg - a.avg); - - sortedMassiveSummary.forEach((lib, rank) => { - const medal = rank === 0 ? "🥇" : rank === 1 ? "🥈" : "🥉"; - console.log( - `${medal} ${lib.name.padEnd(12)} ${ - lib.avg.toLocaleString().padStart(8) - } avg ops/sec (${lib.wins} wins)` - ); - }); - - return sortedMassiveSummary; -} - -// ============================================================================ -// MAIN EXECUTION -// ============================================================================ - -console.log("🎯 CLASSIGO vs CLSX vs CLASSNAMES - COMPLETE ANALYSIS\n"); -console.log("=".repeat(60)); - -// Run size analysis -const sizeResults = analyzeSizes(); - -console.log("\n" + "=".repeat(60) + "\n"); - -// Run runtime benchmarks -const runtimeResults = runBenchmarks(); - -console.log("\n" + "=".repeat(60) + "\n"); - -// Run massive benchmark -const massiveResults = runMassiveBenchmark(); - -console.log("\n" + "=".repeat(60) + "\n"); - -// ============================================================================ -// FINAL SUMMARY -// ============================================================================ - -console.log("🏆 FINAL SUMMARY"); -console.log("─".repeat(60)); - -// Size winner -const sizeWinner = sizeResults[0]; -console.log( - `📦 Size Winner: ${sizeWinner.name} (${ - formatBytes(sizeWinner.size) - } ${sizeWinner.type})`, -); - -// Runtime winner -const runtimeWinner = runtimeResults[0]; -console.log( - `⚡ Runtime Winner: ${runtimeWinner.name} (${runtimeWinner.avg.toLocaleString()} ops/sec, ${runtimeWinner.wins} wins)`, -); - -// Massive winner -const massiveWinner = massiveResults[0]; -console.log( - `🔥 Massive Winner: ${massiveWinner.name} (${massiveWinner.avg.toLocaleString()} ops/sec, ${massiveWinner.wins} wins)`, -); - -// Overall winner -const overallWinner = sizeWinner.name === runtimeWinner.name && runtimeWinner.name === massiveWinner.name - ? sizeWinner.name - : "Tie"; -console.log(`🎯 Overall Winner: ${overallWinner}`); - -console.log("\n✨ Analysis completed!"); diff --git a/bench/package-lock.json b/bench/package-lock.json deleted file mode 100644 index 3b39477..0000000 --- a/bench/package-lock.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "classigo-benchmark", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "classigo-benchmark", - "version": "1.0.0", - "dependencies": { - "classnames": "^2.5.1", - "clsx": "^2.1.1" - }, - "devDependencies": { - "benchmark": "^2.1.4" - } - }, - "node_modules/benchmark": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", - "integrity": "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.4", - "platform": "^1.3.3" - } - }, - "node_modules/classnames": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", - "license": "MIT" - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, - "node_modules/platform": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", - "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", - "dev": true, - "license": "MIT" - } - } -} diff --git a/bench/package.json b/bench/package.json deleted file mode 100644 index d1c7cf9..0000000 --- a/bench/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "classigo-benchmark", - "version": "1.0.0", - "description": "Benchmark suite for classigo vs classnames vs clsx", - "main": "index.js", - "scripts": { - "bench": "node index.js" - }, - "dependencies": { - "classnames": "^2.5.1", - "clsx": "^2.1.1" - }, - "devDependencies": { - "benchmark": "^2.1.4" - } -} diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..ea063aa --- /dev/null +++ b/bun.lock @@ -0,0 +1,38 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "classigo", + "devDependencies": { + "@types/bun": "latest", + "classigo-v1": "npm:classigo@1.0.1", + "classnames": "latest", + "clsx": "latest", + "mitata": "latest", + "prettier": "^3.3.0", + "typescript": "6.0.3", + }, + }, + }, + "packages": { + "@types/bun": ["@types/bun@1.3.13", "", { "dependencies": { "bun-types": "1.3.13" } }, "sha512-9fqXWk5YIHGGnUau9TEi+qdlTYDAnOj+xLCmSTwXfAIqXr2x4tytJb43E9uCvt09zJURKXwAtkoH4nLQfzeTXw=="], + + "@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + + "bun-types": ["bun-types@1.3.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-QXKeHLlOLqQX9LgYaHJfzdBaV21T63HhFJnvuRCcjZiaUDpbs5ED1MgxbMra71CsryN/1dAoXuJJJwIv/2drVA=="], + + "classigo-v1": ["classigo@1.0.1", "", {}, "sha512-goGjdAhTleUcYW5E8PP1Wckdcb/Sxau6sh9GiOA9ObI3cx1BtX2lvfi1etRe1vSgEEc1UyERssjMnZZ3NNIg5Q=="], + + "classnames": ["classnames@2.5.1", "", {}, "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="], + + "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + + "mitata": ["mitata@1.0.34", "", {}, "sha512-Mc3zrtNBKIMeHSCQ0XqRLo1vbdIx1wvFV9c8NJAiyho6AjNfMY8bVhbS12bwciUdd1t4rj8099CH3N3NFahaUA=="], + + "prettier": ["prettier@3.8.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw=="], + + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + + "undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], + } +} diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index e85dffa..0000000 --- a/docs/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# 📚 Documentation - -## 📋 Structure - -- **[README.md](../README.md)** - Documentation principale (EN) -- **[README.fr.md](../README.fr.md)** - Documentation principale (FR) - -## 📁 Guides - -### 🇫🇷 Français (`/fr`) -- **[API.md](./fr/API.md)** - Référence API complète -- **[MIGRATION.md](./fr/MIGRATION.md)** - Migration depuis classnames/clsx -- **[TIPS.md](./fr/TIPS.md)** - Conseils et bonnes pratiques -- **[DEPLOYMENT.md](./fr/DEPLOYMENT.md)** - Guide de déploiement - -### 🇬🇧 English (`/en`) -- **[API.md](./en/API.md)** - Complete API reference -- **[MIGRATION.md](./en/MIGRATION.md)** - Migration from classnames/clsx -- **[TIPS.md](./en/TIPS.md)** - Tips and best practices -- **[DEPLOYMENT.md](./en/DEPLOYMENT.md)** - Deployment guide - ---- - -**Pour un petit projet, on garde ça simple ! 🎯** diff --git a/docs/en/API.md b/docs/en/API.md deleted file mode 100644 index 02f93fc..0000000 --- a/docs/en/API.md +++ /dev/null @@ -1,129 +0,0 @@ -# 🔧 API Reference - -## Function Signature - -```typescript -function classigo(...classes: (string | undefined | null | false)[]): string -``` - -## Parameters - -- `...classes`: Variable number of class names or falsy values - -## Returns - -- `string`: Combined class names separated by spaces - -## Examples - -### Basic Usage - -```typescript -import classigo from 'classigo'; - -// Basic classes -classigo('button', 'button--primary', 'button--large') -// → "button button--primary button--large" - -// With falsy values -classigo('button', null, undefined, false, 'button--primary') -// → "button button--primary" - -// Empty result -classigo(null, undefined, false) -// → "" -``` - -### Conditional Classes - -```typescript -import classigo from 'classigo'; - -// With conditions -classigo('button', 'button--primary', isLarge && 'button--large') -// → "button button--primary" (if isLarge is false) -// → "button button--primary button--large" (if isLarge is true) - -// Multiple conditions -classigo( - 'button', - 'button--primary', - isLarge && 'button--large', - isDisabled && 'button--disabled' -) -``` - -### Template Literals - -```typescript -import classigo from 'classigo'; - -// Dynamic classes -classigo('button', `button--${variant}`, `button--${size}`) -// → "button button--primary button--large" (if variant = 'primary', size = 'large') - -// Mixed with conditions -classigo( - 'button', - `button--${variant}`, - isLarge && 'button--large' -) -``` - -### CSS Modules - -```typescript -import classigo from 'classigo'; -import styles from './Button.module.css'; - -// Static classes -classigo(styles.button, styles['button--primary'], styles['button--large']) - -// Dynamic classes -classigo( - styles.button, - styles[`button--${variant}`], - isLarge && styles['button--large'] -) -``` - -## TypeScript Support - -```typescript -import classigo from 'classigo'; - -// Type-safe usage -const className: string = classigo( - 'button', - 'button--primary', - isLarge && 'button--large' -); - -// With CSS Modules -import styles from './Button.module.css'; - -const className: string = classigo( - styles.button, - styles['button--primary'], - isLarge && styles['button--large'] -); -``` - -## Supported Values - -| Type | Example | Result | -|------|---------|--------| -| `string` | `'button'` | ✅ Included | -| `undefined` | `undefined` | ❌ Filtered out | -| `null` | `null` | ❌ Filtered out | -| `false` | `false` | ❌ Filtered out | -| `0` | `0` | ❌ Filtered out | -| `''` | `''` | ❌ Filtered out | - -## Not Supported - -- **Objects**: `{ 'button': true }` ❌ -- **Arrays**: `['button', 'primary']` ❌ -- **Functions**: `() => 'button'` ❌ -- **Numbers**: `123` ❌ -- **Booleans**: `true` ❌ diff --git a/docs/en/DEPLOYMENT.md b/docs/en/DEPLOYMENT.md deleted file mode 100644 index f5dd169..0000000 --- a/docs/en/DEPLOYMENT.md +++ /dev/null @@ -1,170 +0,0 @@ -# Deployment Guide - -This guide explains how to deploy Classigo to npm and GitHub Pages using GitHub Actions. - -## 🚀 Manual Workflows - -### Publishing to npm - -Use the **"Publish Package"** workflow to publish a new version to npm: - -1. Go to **Actions** → **Publish Package** -2. Click **"Run workflow"** -3. Configure the inputs: - - **Version**: `patch`, `minor`, `major`, or specific version (e.g., `1.2.3`) - - **Create git tag**: Check to create a git tag and GitHub release -4. Click **"Run workflow"** - -The workflow will: -- ✅ Run linting and tests -- ✅ Build production bundle -- ✅ Update package version -- ✅ Publish to npm -- ✅ Create git tag and GitHub release (if enabled) - -### Deploying to GitHub Pages - -Use the **"Deploy to gh-pages Branch"** workflow to update the live examples: - -1. Go to **Actions** → **Deploy to gh-pages Branch** -2. Click **"Run workflow"** -3. Select the source branch (default: `main`) -4. Click **"Run workflow"** - -The workflow will: -- ✅ Run linting and tests -- ✅ Build production bundle -- ✅ Copy examples to gh-pages branch -- ✅ Deploy to GitHub Pages - -## 🔄 Automatic Deployment - -### GitHub Pages Auto-deploy - -The **"Deploy to gh-pages Branch"** workflow also runs automatically when: -- Changes are pushed to `main` branch -- Files in `examples/` directory are modified - -This ensures your live examples are always up-to-date. - -## 📋 Prerequisites - -### npm Publishing - -1. **NPM_TOKEN**: Add your npm access token to GitHub secrets - - Go to npm → Access Tokens → Generate new token - - Add to GitHub: Settings → Secrets → `NPM_TOKEN` - -2. **Repository permissions**: Ensure the workflow has write permissions - - Settings → Actions → General → Workflow permissions - - Enable "Read and write permissions" - -### GitHub Pages - -1. **Enable GitHub Pages**: - - Settings → Pages - - Source: "Deploy from a branch" - - Branch: `gh-pages` - - Folder: `/ (root)` - -2. **Repository permissions**: Ensure the workflow has write permissions - - Settings → Actions → General → Workflow permissions - - Enable "Read and write permissions" - -## 🛠️ Local Development - -### Testing GitHub Pages Locally - -You can test your GitHub Pages examples locally before deploying: - -```bash -# Quick test (build + serve once) -pnpm run dev-pages - -# Development with auto-reload -pnpm run dev-pages:watch -``` - -**Features:** -- ✅ **Auto-rebuild**: Changes in `examples/` trigger automatic rebuild -- ✅ **Auto-reload**: Server restarts automatically after rebuild -- ✅ **Browser auto-open**: Opens your default browser automatically -- ✅ **Hot reload**: Edit files and see changes instantly - -**Available URLs:** -- `http://localhost:3000/` - Home page -- `http://localhost:3000/react-demo/` - React example -- `http://localhost:3000/vanilla-demo/` - Vanilla JS example - -### Setup GitHub Pages locally - -```bash -# Setup gh-pages directory -pnpm run setup-gh-pages - -# Serve locally (one-time) -pnpm run serve-gh-pages - -# Development mode with auto-rebuild -pnpm run dev-pages - -# Watch mode (auto-rebuild on changes) -pnpm run dev-pages:watch - -# Deploy manually (requires gh-pages branch) -pnpm run deploy-pages -``` - -### Manual npm publishing - -```bash -# Build production -pnpm run build:prod - -# Update version -pnpm version patch # or minor, major - -# Publish -pnpm publish -``` - -## 📊 Workflow Status - -Check workflow status in the **Actions** tab: - -- ✅ **Green**: All checks passed -- ❌ **Red**: Tests or build failed -- 🟡 **Yellow**: Workflow in progress - -## 🔧 Troubleshooting - -### npm Publishing Issues - -- **Authentication error**: Check `NPM_TOKEN` secret -- **Version conflict**: Ensure version doesn't already exist -- **Build failure**: Check linting and test errors - -### GitHub Pages Issues - -- **404 errors**: Check gh-pages branch exists and is configured -- **Build failure**: Check for syntax errors in examples -- **Permission denied**: Check repository permissions - -### Common Commands - -```bash -# Check workflow status -gh run list - -# View workflow logs -gh run view - -# Rerun failed workflow -gh run rerun -``` - -## 📚 Related Documentation - -- [API Reference](./API.md) -- [Migration Guide](./MIGRATION.md) -- [Tips & Best Practices](./TIPS.md) diff --git a/docs/en/MIGRATION.md b/docs/en/MIGRATION.md deleted file mode 100644 index 5561a8f..0000000 --- a/docs/en/MIGRATION.md +++ /dev/null @@ -1,46 +0,0 @@ -# 🔄 Migration - -## From classnames - -**Before:** -```typescript -import classNames from 'classnames'; - -const className = classNames('button', { - 'button--primary': true, - 'button--large': isLarge -}); -``` - -**After:** -```typescript -import classigo from 'classigo'; - -const className = classigo('button', 'button--primary', isLarge && 'button--large'); -``` - -## From clsx - -**Before:** -```typescript -import clsx from 'clsx'; - -const className = clsx('button', { - 'button--primary': true, - 'button--large': isLarge -}); -``` - -**After:** -```typescript -import classigo from 'classigo'; - -const className = classigo('button', 'button--primary', isLarge && 'button--large'); -``` - -## ✅ Checklist - -- [ ] Replace `import classNames from 'classnames'` with `import classigo from 'classigo'` -- [ ] Replace `import clsx from 'clsx'` with `import classigo from 'classigo'` -- [ ] Convert object syntax to `&&` conditions -- [ ] Test your components diff --git a/docs/en/TIPS.md b/docs/en/TIPS.md deleted file mode 100644 index 58c1087..0000000 --- a/docs/en/TIPS.md +++ /dev/null @@ -1,56 +0,0 @@ -# 💡 Tips - -## ✅ Do - -**Use `&&` for conditions:** -```typescript -const className = classigo( - 'button', - isLarge && 'button--large', - isDisabled && 'button--disabled' -); -``` - -**Use template literals:** -```typescript -const className = classigo( - 'button', - `button--${variant}`, - `button--${size}` -); -``` - -## ❌ Don't - -**Don't use object syntax:** -```typescript -// This won't work -const className = classigo({ - 'button': true, - 'button--primary': isPrimary -}); -``` - -**Don't use array syntax:** -```typescript -// This won't work -const className = classigo([ - 'button', - 'button--primary' -]); -``` - -**Don't use ternaries:** -```typescript -// Slower -const className = classigo( - 'button', - isLarge ? 'button--large' : '' -); -``` - -## 🎯 Performance - -- Use `&&` instead of ternaries -- Use template literals for dynamic strings -- Avoid `Array.filter().join()` pattern diff --git a/docs/fr/API.md b/docs/fr/API.md deleted file mode 100644 index e3e9278..0000000 --- a/docs/fr/API.md +++ /dev/null @@ -1,129 +0,0 @@ -# 🔧 Référence API - -## Signature de Fonction - -```typescript -function classigo(...classes: (string | undefined | null | false)[]): string -``` - -## Paramètres - -- `...classes`: Nombre variable de noms de classes ou valeurs falsy - -## Retourne - -- `string`: Noms de classes combinés séparés par des espaces - -## Exemples - -### Utilisation Basique - -```typescript -import classigo from 'classigo'; - -// Classes de base -classigo('button', 'button--primary', 'button--large') -// → "button button--primary button--large" - -// Avec valeurs falsy -classigo('button', null, undefined, false, 'button--primary') -// → "button button--primary" - -// Résultat vide -classigo(null, undefined, false) -// → "" -``` - -### Classes Conditionnelles - -```typescript -import classigo from 'classigo'; - -// Avec conditions -classigo('button', 'button--primary', isLarge && 'button--large') -// → "button button--primary" (si isLarge est false) -// → "button button--primary button--large" (si isLarge est true) - -// Conditions multiples -classigo( - 'button', - 'button--primary', - isLarge && 'button--large', - isDisabled && 'button--disabled' -) -``` - -### Template Literals - -```typescript -import classigo from 'classigo'; - -// Classes dynamiques -classigo('button', `button--${variant}`, `button--${size}`) -// → "button button--primary button--large" (si variant = 'primary', size = 'large') - -// Mixte avec conditions -classigo( - 'button', - `button--${variant}`, - isLarge && 'button--large' -) -``` - -### CSS Modules - -```typescript -import classigo from 'classigo'; -import styles from './Button.module.css'; - -// Classes statiques -classigo(styles.button, styles['button--primary'], styles['button--large']) - -// Classes dynamiques -classigo( - styles.button, - styles[`button--${variant}`], - isLarge && styles['button--large'] -) -``` - -## Support TypeScript - -```typescript -import classigo from 'classigo'; - -// Utilisation type-safe -const className: string = classigo( - 'button', - 'button--primary', - isLarge && 'button--large' -); - -// Avec CSS Modules -import styles from './Button.module.css'; - -const className: string = classigo( - styles.button, - styles['button--primary'], - isLarge && styles['button--large'] -); -``` - -## Valeurs Supportées - -| Type | Exemple | Résultat | -|------|---------|----------| -| `string` | `'button'` | ✅ Inclus | -| `undefined` | `undefined` | ❌ Filtré | -| `null` | `null` | ❌ Filtré | -| `false` | `false` | ❌ Filtré | -| `0` | `0` | ❌ Filtré | -| `''` | `''` | ❌ Filtré | - -## Non Supporté - -- **Objets**: `{ 'button': true }` ❌ -- **Arrays**: `['button', 'primary']` ❌ -- **Fonctions**: `() => 'button'` ❌ -- **Nombres**: `123` ❌ -- **Booléens**: `true` ❌ diff --git a/docs/fr/MIGRATION.md b/docs/fr/MIGRATION.md deleted file mode 100644 index 96be116..0000000 --- a/docs/fr/MIGRATION.md +++ /dev/null @@ -1,46 +0,0 @@ -# 🔄 Migration - -## Depuis classnames - -**Avant:** -```typescript -import classNames from 'classnames'; - -const className = classNames('button', { - 'button--primary': true, - 'button--large': isLarge -}); -``` - -**Après:** -```typescript -import classigo from 'classigo'; - -const className = classigo('button', 'button--primary', isLarge && 'button--large'); -``` - -## Depuis clsx - -**Avant:** -```typescript -import clsx from 'clsx'; - -const className = clsx('button', { - 'button--primary': true, - 'button--large': isLarge -}); -``` - -**Après:** -```typescript -import classigo from 'classigo'; - -const className = classigo('button', 'button--primary', isLarge && 'button--large'); -``` - -## ✅ Checklist - -- [ ] Remplacer `import classNames from 'classnames'` par `import classigo from 'classigo'` -- [ ] Remplacer `import clsx from 'clsx'` par `import classigo from 'classigo'` -- [ ] Convertir la syntaxe objet en conditions `&&` -- [ ] Tester vos composants diff --git a/docs/fr/TIPS.md b/docs/fr/TIPS.md deleted file mode 100644 index 6715caf..0000000 --- a/docs/fr/TIPS.md +++ /dev/null @@ -1,56 +0,0 @@ -# 💡 Conseils - -## ✅ À faire - -**Utilisez `&&` pour les conditions:** -```typescript -const className = classigo( - 'button', - isLarge && 'button--large', - isDisabled && 'button--disabled' -); -``` - -**Utilisez les template literals:** -```typescript -const className = classigo( - 'button', - `button--${variant}`, - `button--${size}` -); -``` - -## ❌ À éviter - -**N'utilisez pas la syntaxe objet:** -```typescript -// Ça ne marchera pas -const className = classigo({ - 'button': true, - 'button--primary': isPrimary -}); -``` - -**N'utilisez pas la syntaxe array:** -```typescript -// Ça ne marchera pas -const className = classigo([ - 'button', - 'button--primary' -]); -``` - -**N'utilisez pas les ternaires:** -```typescript -// Plus lent -const className = classigo( - 'button', - isLarge ? 'button--large' : '' -); -``` - -## 🎯 Performance - -- Utilisez `&&` au lieu des ternaires -- Utilisez les template literals pour les chaînes dynamiques -- Évitez le pattern `Array.filter().join()` diff --git a/eslint.config.js b/eslint.config.js deleted file mode 100644 index 95dcc6d..0000000 --- a/eslint.config.js +++ /dev/null @@ -1,33 +0,0 @@ -import js from '@eslint/js'; -import tseslint from '@typescript-eslint/eslint-plugin'; -import tsparser from '@typescript-eslint/parser'; - -export default [ - js.configs.recommended, - { - files: ['src/**/*.ts'], - languageOptions: { - parser: tsparser, - parserOptions: { - ecmaVersion: 2020, - sourceType: 'module', - project: './tsconfig.json', - }, - }, - plugins: { - '@typescript-eslint': tseslint, - }, - rules: { - ...tseslint.configs.recommended.rules, - '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-explicit-any': 'warn', - 'no-console': 'warn', - 'prefer-const': 'error', - }, - }, - { - ignores: ['dist/', 'node_modules/', '*.js'], - }, -]; diff --git a/examples/favicon.ico b/examples/favicon.ico deleted file mode 100644 index 8e94738..0000000 --- a/examples/favicon.ico +++ /dev/null @@ -1,2 +0,0 @@ -# Simple favicon placeholder -# This prevents 404 errors for favicon.ico requests diff --git a/examples/favicon.svg b/examples/favicon.svg deleted file mode 100644 index 0d00cec..0000000 --- a/examples/favicon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - C - diff --git a/examples/index.html b/examples/index.html deleted file mode 100644 index aadb377..0000000 --- a/examples/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - Classigo Examples - - - - - -
-
-
Loading Classigo Examples...
-
- -
-
Chargement des exemples...
-
- - - - - \ No newline at end of file diff --git a/examples/package.json b/examples/package.json deleted file mode 100644 index 3166648..0000000 --- a/examples/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "classigo-examples", - "version": "1.0.0", - "description": "Live examples for Classigo - Ultra-optimized class name utility", - "type": "module", - "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview" - }, - "dependencies": { - "react": "^19.1.1", - "react-dom": "^19.1.1", - "vue": "^3.5.20", - "svelte": "^5.38.6", - "classigo": "file:../dist" - }, - "devDependencies": { - "@vitejs/plugin-react": "^5.0.2", - "@vitejs/plugin-vue": "^6.0.1", - "vite": "^7.1.3", - "@sveltejs/vite-plugin-svelte": "^6.1.3", - "@types/react": "^19.1.12", - "@types/react-dom": "^19.1.9", - "vue-tsc": "^3.0.6" - } -} diff --git a/examples/pnpm-lock.yaml b/examples/pnpm-lock.yaml deleted file mode 100644 index 4a0d1f0..0000000 --- a/examples/pnpm-lock.yaml +++ /dev/null @@ -1,1828 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - classigo: - specifier: file:../dist - version: dist@file:../dist - react: - specifier: ^19.1.1 - version: 19.1.1 - react-dom: - specifier: ^19.1.1 - version: 19.1.1(react@19.1.1) - svelte: - specifier: ^5.38.6 - version: 5.38.6 - vue: - specifier: ^3.5.20 - version: 3.5.20(typescript@5.9.2) - devDependencies: - '@sveltejs/vite-plugin-svelte': - specifier: ^6.1.3 - version: 6.1.3(svelte@5.38.6)(vite@7.1.3) - '@types/react': - specifier: ^19.1.12 - version: 19.1.12 - '@types/react-dom': - specifier: ^19.1.9 - version: 19.1.9(@types/react@19.1.12) - '@vitejs/plugin-react': - specifier: ^5.0.2 - version: 5.0.2(vite@7.1.3) - '@vitejs/plugin-vue': - specifier: ^6.0.1 - version: 6.0.1(vite@7.1.3)(vue@3.5.20(typescript@5.9.2)) - gh-pages: - specifier: ^6.3.0 - version: 6.3.0 - vite: - specifier: ^7.1.3 - version: 7.1.3 - vue-tsc: - specifier: ^3.0.6 - version: 3.0.6(typescript@5.9.2) - -packages: - - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.28.0': - resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.28.3': - resolution: {integrity: sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.28.3': - resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.27.2': - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.27.1': - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.28.3': - resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-plugin-utils@7.27.1': - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.28.3': - resolution: {integrity: sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.28.3': - resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/plugin-transform-react-jsx-self@7.27.1': - resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-jsx-source@7.27.1': - resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.28.3': - resolution: {integrity: sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} - engines: {node: '>=6.9.0'} - - '@esbuild/aix-ppc64@0.25.9': - resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.25.9': - resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.25.9': - resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.25.9': - resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.25.9': - resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.25.9': - resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.25.9': - resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.25.9': - resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.25.9': - resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.25.9': - resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.25.9': - resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.25.9': - resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.25.9': - resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.25.9': - resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.9': - resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.25.9': - resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.25.9': - resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.25.9': - resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.25.9': - resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.25.9': - resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.9': - resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.25.9': - resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.25.9': - resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.25.9': - resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.25.9': - resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.25.9': - resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.30': - resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@rolldown/pluginutils@1.0.0-beta.29': - resolution: {integrity: sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==} - - '@rolldown/pluginutils@1.0.0-beta.34': - resolution: {integrity: sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA==} - - '@rollup/rollup-android-arm-eabi@4.49.0': - resolution: {integrity: sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.49.0': - resolution: {integrity: sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.49.0': - resolution: {integrity: sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.49.0': - resolution: {integrity: sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.49.0': - resolution: {integrity: sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.49.0': - resolution: {integrity: sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.49.0': - resolution: {integrity: sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.49.0': - resolution: {integrity: sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.49.0': - resolution: {integrity: sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.49.0': - resolution: {integrity: sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loongarch64-gnu@4.49.0': - resolution: {integrity: sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-ppc64-gnu@4.49.0': - resolution: {integrity: sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.49.0': - resolution: {integrity: sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.49.0': - resolution: {integrity: sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.49.0': - resolution: {integrity: sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.49.0': - resolution: {integrity: sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.49.0': - resolution: {integrity: sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.49.0': - resolution: {integrity: sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.49.0': - resolution: {integrity: sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.49.0': - resolution: {integrity: sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg==} - cpu: [x64] - os: [win32] - - '@sveltejs/acorn-typescript@1.0.5': - resolution: {integrity: sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==} - peerDependencies: - acorn: ^8.9.0 - - '@sveltejs/vite-plugin-svelte-inspector@5.0.1': - resolution: {integrity: sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==} - engines: {node: ^20.19 || ^22.12 || >=24} - peerDependencies: - '@sveltejs/vite-plugin-svelte': ^6.0.0-next.0 - svelte: ^5.0.0 - vite: ^6.3.0 || ^7.0.0 - - '@sveltejs/vite-plugin-svelte@6.1.3': - resolution: {integrity: sha512-3pppgIeIZs6nrQLazzKcdnTJ2IWiui/UucEPXKyFG35TKaHQrfkWBnv6hyJcLxFuR90t+LaoecrqTs8rJKWfSQ==} - engines: {node: ^20.19 || ^22.12 || >=24} - peerDependencies: - svelte: ^5.0.0 - vite: ^6.3.0 || ^7.0.0 - - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - - '@types/babel__traverse@7.28.0': - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/react-dom@19.1.9': - resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} - peerDependencies: - '@types/react': ^19.0.0 - - '@types/react@19.1.12': - resolution: {integrity: sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==} - - '@vitejs/plugin-react@5.0.2': - resolution: {integrity: sha512-tmyFgixPZCx2+e6VO9TNITWcCQl8+Nl/E8YbAyPVv85QCc7/A3JrdfG2A8gIzvVhWuzMOVrFW1aReaNxrI6tbw==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - - '@vitejs/plugin-vue@6.0.1': - resolution: {integrity: sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - vue: ^3.2.25 - - '@volar/language-core@2.4.23': - resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==} - - '@volar/source-map@2.4.23': - resolution: {integrity: sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==} - - '@volar/typescript@2.4.23': - resolution: {integrity: sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag==} - - '@vue/compiler-core@3.5.20': - resolution: {integrity: sha512-8TWXUyiqFd3GmP4JTX9hbiTFRwYHgVL/vr3cqhr4YQ258+9FADwvj7golk2sWNGHR67QgmCZ8gz80nQcMokhwg==} - - '@vue/compiler-dom@3.5.20': - resolution: {integrity: sha512-whB44M59XKjqUEYOMPYU0ijUV0G+4fdrHVKDe32abNdX/kJe1NUEMqsi4cwzXa9kyM9w5S8WqFsrfo1ogtBZGQ==} - - '@vue/compiler-sfc@3.5.20': - resolution: {integrity: sha512-SFcxapQc0/feWiSBfkGsa1v4DOrnMAQSYuvDMpEaxbpH5dKbnEM5KobSNSgU+1MbHCl+9ftm7oQWxvwDB6iBfw==} - - '@vue/compiler-ssr@3.5.20': - resolution: {integrity: sha512-RSl5XAMc5YFUXpDQi+UQDdVjH9FnEpLDHIALg5J0ITHxkEzJ8uQLlo7CIbjPYqmZtt6w0TsIPbo1izYXwDG7JA==} - - '@vue/compiler-vue2@2.7.16': - resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} - - '@vue/language-core@3.0.6': - resolution: {integrity: sha512-e2RRzYWm+qGm8apUHW1wA5RQxzNhkqbbKdbKhiDUcmMrNAZGyM8aTiL3UrTqkaFI5s7wJRGGrp4u3jgusuBp2A==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@vue/reactivity@3.5.20': - resolution: {integrity: sha512-hS8l8x4cl1fmZpSQX/NXlqWKARqEsNmfkwOIYqtR2F616NGfsLUm0G6FQBK6uDKUCVyi1YOL8Xmt/RkZcd/jYQ==} - - '@vue/runtime-core@3.5.20': - resolution: {integrity: sha512-vyQRiH5uSZlOa+4I/t4Qw/SsD/gbth0SW2J7oMeVlMFMAmsG1rwDD6ok0VMmjXY3eI0iHNSSOBilEDW98PLRKw==} - - '@vue/runtime-dom@3.5.20': - resolution: {integrity: sha512-KBHzPld/Djw3im0CQ7tGCpgRedryIn4CcAl047EhFTCCPT2xFf4e8j6WeKLgEEoqPSl9TYqShc3Q6tpWpz/Xgw==} - - '@vue/server-renderer@3.5.20': - resolution: {integrity: sha512-HthAS0lZJDH21HFJBVNTtx+ULcIbJQRpjSVomVjfyPkFSpCwvsPTA+jIzOaUm3Hrqx36ozBHePztQFg6pj5aKg==} - peerDependencies: - vue: 3.5.20 - - '@vue/shared@3.5.20': - resolution: {integrity: sha512-SoRGP596KU/ig6TfgkCMbXkr4YJ91n/QSdMuqeP5r3hVIYA3CPHUBCc7Skak0EAKV+5lL4KyIh61VA/pK1CIAA==} - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - alien-signals@2.0.7: - resolution: {integrity: sha512-wE7y3jmYeb0+h6mr5BOovuqhFv22O/MV9j5p0ndJsa7z1zJNPGQ4ph5pQk/kTTCWRC3xsA4SmtwmkzQO+7NCNg==} - - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - - axobject-query@4.1.0: - resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} - engines: {node: '>= 0.4'} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - browserslist@4.25.4: - resolution: {integrity: sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - caniuse-lite@1.0.30001739: - resolution: {integrity: sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==} - - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - - commander@13.1.0: - resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} - engines: {node: '>=18'} - - commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - - de-indent@1.0.2: - resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} - - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - dist@file:../dist: - resolution: {directory: ../dist, type: directory} - - electron-to-chromium@1.5.211: - resolution: {integrity: sha512-IGBvimJkotaLzFnwIVgW9/UD/AOJ2tByUmeOrtqBfACSbAw5b1G0XpvdaieKyc7ULmbwXVx+4e4Be8pOPBrYkw==} - - email-addresses@5.0.0: - resolution: {integrity: sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - esbuild@0.25.9: - resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - esm-env@1.2.2: - resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} - - esrap@2.1.0: - resolution: {integrity: sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==} - - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - filename-reserved-regex@2.0.0: - resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==} - engines: {node: '>=4'} - - filenamify@4.3.0: - resolution: {integrity: sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==} - engines: {node: '>=8'} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-cache-dir@3.3.2: - resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} - engines: {node: '>=8'} - - find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - - fs-extra@11.3.1: - resolution: {integrity: sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==} - engines: {node: '>=14.14'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - gh-pages@6.3.0: - resolution: {integrity: sha512-Ot5lU6jK0Eb+sszG8pciXdjMXdBJ5wODvgjR+imihTqsUWF2K6dJ9HST55lgqcs8wWcw6o6wAsUzfcYRhJPXbA==} - engines: {node: '>=10'} - hasBin: true - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-reference@3.0.3: - resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsonfile@6.2.0: - resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} - - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - - locate-character@3.0.0: - resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} - - locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - - magic-string@0.30.18: - resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==} - - make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - muggle-string@0.4.1: - resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - - p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - - path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - - pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - react-dom@19.1.1: - resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==} - peerDependencies: - react: ^19.1.1 - - react-refresh@0.17.0: - resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} - engines: {node: '>=0.10.0'} - - react@19.1.1: - resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} - engines: {node: '>=0.10.0'} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rollup@4.49.0: - resolution: {integrity: sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - scheduler@0.26.0: - resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - strip-outer@1.0.1: - resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} - engines: {node: '>=0.10.0'} - - svelte@5.38.6: - resolution: {integrity: sha512-ltBPlkvqk3bgCK7/N323atUpP3O3Y+DrGV4dcULrsSn4fZaaNnOmdplNznwfdWclAgvSr5rxjtzn/zJhRm6TKg==} - engines: {node: '>=18'} - - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} - engines: {node: '>=12.0.0'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - trim-repeated@1.0.0: - resolution: {integrity: sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==} - engines: {node: '>=0.10.0'} - - typescript@5.9.2: - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} - engines: {node: '>=14.17'} - hasBin: true - - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - vite@7.1.3: - resolution: {integrity: sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' - less: ^4.0.0 - lightningcss: ^1.21.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitefu@1.1.1: - resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} - peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 - peerDependenciesMeta: - vite: - optional: true - - vscode-uri@3.1.0: - resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} - - vue-tsc@3.0.6: - resolution: {integrity: sha512-Tbs8Whd43R2e2nxez4WXPvvdjGbW24rOSgRhLOHXzWiT4pcP4G7KeWh0YCn18rF4bVwv7tggLLZ6MJnO6jXPBg==} - hasBin: true - peerDependencies: - typescript: '>=5.0.0' - - vue@3.5.20: - resolution: {integrity: sha512-2sBz0x/wis5TkF1XZ2vH25zWq3G1bFEPOfkBcx2ikowmphoQsPH6X0V3mmPCXA2K1N/XGTnifVyDQP4GfDDeQw==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - - zimmerframe@1.1.2: - resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} - -snapshots: - - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 - - '@babel/code-frame@7.27.1': - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/compat-data@7.28.0': {} - - '@babel/core@7.28.3': - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) - '@babel/helpers': 7.28.3 - '@babel/parser': 7.28.3 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 - convert-source-map: 2.0.0 - debug: 4.4.1 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.28.3': - dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 - jsesc: 3.1.0 - - '@babel/helper-compilation-targets@7.27.2': - dependencies: - '@babel/compat-data': 7.28.0 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.25.4 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-globals@7.28.0': {} - - '@babel/helper-module-imports@7.27.1': - dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.3)': - dependencies: - '@babel/core': 7.28.3 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.3 - transitivePeerDependencies: - - supports-color - - '@babel/helper-plugin-utils@7.27.1': {} - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.27.1': {} - - '@babel/helper-validator-option@7.27.1': {} - - '@babel/helpers@7.28.3': - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - - '@babel/parser@7.28.3': - dependencies: - '@babel/types': 7.28.2 - - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.3)': - dependencies: - '@babel/core': 7.28.3 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.3)': - dependencies: - '@babel/core': 7.28.3 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/template@7.27.2': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 - - '@babel/traverse@7.28.3': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.3 - '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - debug: 4.4.1 - transitivePeerDependencies: - - supports-color - - '@babel/types@7.28.2': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - - '@esbuild/aix-ppc64@0.25.9': - optional: true - - '@esbuild/android-arm64@0.25.9': - optional: true - - '@esbuild/android-arm@0.25.9': - optional: true - - '@esbuild/android-x64@0.25.9': - optional: true - - '@esbuild/darwin-arm64@0.25.9': - optional: true - - '@esbuild/darwin-x64@0.25.9': - optional: true - - '@esbuild/freebsd-arm64@0.25.9': - optional: true - - '@esbuild/freebsd-x64@0.25.9': - optional: true - - '@esbuild/linux-arm64@0.25.9': - optional: true - - '@esbuild/linux-arm@0.25.9': - optional: true - - '@esbuild/linux-ia32@0.25.9': - optional: true - - '@esbuild/linux-loong64@0.25.9': - optional: true - - '@esbuild/linux-mips64el@0.25.9': - optional: true - - '@esbuild/linux-ppc64@0.25.9': - optional: true - - '@esbuild/linux-riscv64@0.25.9': - optional: true - - '@esbuild/linux-s390x@0.25.9': - optional: true - - '@esbuild/linux-x64@0.25.9': - optional: true - - '@esbuild/netbsd-arm64@0.25.9': - optional: true - - '@esbuild/netbsd-x64@0.25.9': - optional: true - - '@esbuild/openbsd-arm64@0.25.9': - optional: true - - '@esbuild/openbsd-x64@0.25.9': - optional: true - - '@esbuild/openharmony-arm64@0.25.9': - optional: true - - '@esbuild/sunos-x64@0.25.9': - optional: true - - '@esbuild/win32-arm64@0.25.9': - optional: true - - '@esbuild/win32-ia32@0.25.9': - optional: true - - '@esbuild/win32-x64@0.25.9': - optional: true - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.30 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.30': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 - - '@rolldown/pluginutils@1.0.0-beta.29': {} - - '@rolldown/pluginutils@1.0.0-beta.34': {} - - '@rollup/rollup-android-arm-eabi@4.49.0': - optional: true - - '@rollup/rollup-android-arm64@4.49.0': - optional: true - - '@rollup/rollup-darwin-arm64@4.49.0': - optional: true - - '@rollup/rollup-darwin-x64@4.49.0': - optional: true - - '@rollup/rollup-freebsd-arm64@4.49.0': - optional: true - - '@rollup/rollup-freebsd-x64@4.49.0': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.49.0': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.49.0': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.49.0': - optional: true - - '@rollup/rollup-linux-loongarch64-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.49.0': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-x64-musl@4.49.0': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.49.0': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.49.0': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.49.0': - optional: true - - '@sveltejs/acorn-typescript@1.0.5(acorn@8.15.0)': - dependencies: - acorn: 8.15.0 - - '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.6)(vite@7.1.3))(svelte@5.38.6)(vite@7.1.3)': - dependencies: - '@sveltejs/vite-plugin-svelte': 6.1.3(svelte@5.38.6)(vite@7.1.3) - debug: 4.4.1 - svelte: 5.38.6 - vite: 7.1.3 - transitivePeerDependencies: - - supports-color - - '@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.6)(vite@7.1.3)': - dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.6)(vite@7.1.3))(svelte@5.38.6)(vite@7.1.3) - debug: 4.4.1 - deepmerge: 4.3.1 - kleur: 4.1.5 - magic-string: 0.30.18 - svelte: 5.38.6 - vite: 7.1.3 - vitefu: 1.1.1(vite@7.1.3) - transitivePeerDependencies: - - supports-color - - '@types/babel__core@7.20.5': - dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 - '@types/babel__generator': 7.27.0 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.28.0 - - '@types/babel__generator@7.27.0': - dependencies: - '@babel/types': 7.28.2 - - '@types/babel__template@7.4.4': - dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 - - '@types/babel__traverse@7.28.0': - dependencies: - '@babel/types': 7.28.2 - - '@types/estree@1.0.8': {} - - '@types/react-dom@19.1.9(@types/react@19.1.12)': - dependencies: - '@types/react': 19.1.12 - - '@types/react@19.1.12': - dependencies: - csstype: 3.1.3 - - '@vitejs/plugin-react@5.0.2(vite@7.1.3)': - dependencies: - '@babel/core': 7.28.3 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.3) - '@rolldown/pluginutils': 1.0.0-beta.34 - '@types/babel__core': 7.20.5 - react-refresh: 0.17.0 - vite: 7.1.3 - transitivePeerDependencies: - - supports-color - - '@vitejs/plugin-vue@6.0.1(vite@7.1.3)(vue@3.5.20(typescript@5.9.2))': - dependencies: - '@rolldown/pluginutils': 1.0.0-beta.29 - vite: 7.1.3 - vue: 3.5.20(typescript@5.9.2) - - '@volar/language-core@2.4.23': - dependencies: - '@volar/source-map': 2.4.23 - - '@volar/source-map@2.4.23': {} - - '@volar/typescript@2.4.23': - dependencies: - '@volar/language-core': 2.4.23 - path-browserify: 1.0.1 - vscode-uri: 3.1.0 - - '@vue/compiler-core@3.5.20': - dependencies: - '@babel/parser': 7.28.3 - '@vue/shared': 3.5.20 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - - '@vue/compiler-dom@3.5.20': - dependencies: - '@vue/compiler-core': 3.5.20 - '@vue/shared': 3.5.20 - - '@vue/compiler-sfc@3.5.20': - dependencies: - '@babel/parser': 7.28.3 - '@vue/compiler-core': 3.5.20 - '@vue/compiler-dom': 3.5.20 - '@vue/compiler-ssr': 3.5.20 - '@vue/shared': 3.5.20 - estree-walker: 2.0.2 - magic-string: 0.30.18 - postcss: 8.5.6 - source-map-js: 1.2.1 - - '@vue/compiler-ssr@3.5.20': - dependencies: - '@vue/compiler-dom': 3.5.20 - '@vue/shared': 3.5.20 - - '@vue/compiler-vue2@2.7.16': - dependencies: - de-indent: 1.0.2 - he: 1.2.0 - - '@vue/language-core@3.0.6(typescript@5.9.2)': - dependencies: - '@volar/language-core': 2.4.23 - '@vue/compiler-dom': 3.5.20 - '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.20 - alien-signals: 2.0.7 - muggle-string: 0.4.1 - path-browserify: 1.0.1 - picomatch: 4.0.3 - optionalDependencies: - typescript: 5.9.2 - - '@vue/reactivity@3.5.20': - dependencies: - '@vue/shared': 3.5.20 - - '@vue/runtime-core@3.5.20': - dependencies: - '@vue/reactivity': 3.5.20 - '@vue/shared': 3.5.20 - - '@vue/runtime-dom@3.5.20': - dependencies: - '@vue/reactivity': 3.5.20 - '@vue/runtime-core': 3.5.20 - '@vue/shared': 3.5.20 - csstype: 3.1.3 - - '@vue/server-renderer@3.5.20(vue@3.5.20(typescript@5.9.2))': - dependencies: - '@vue/compiler-ssr': 3.5.20 - '@vue/shared': 3.5.20 - vue: 3.5.20(typescript@5.9.2) - - '@vue/shared@3.5.20': {} - - acorn@8.15.0: {} - - alien-signals@2.0.7: {} - - aria-query@5.3.2: {} - - array-union@2.1.0: {} - - async@3.2.6: {} - - axobject-query@4.1.0: {} - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browserslist@4.25.4: - dependencies: - caniuse-lite: 1.0.30001739 - electron-to-chromium: 1.5.211 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.4) - - caniuse-lite@1.0.30001739: {} - - clsx@2.1.1: {} - - commander@13.1.0: {} - - commondir@1.0.1: {} - - convert-source-map@2.0.0: {} - - csstype@3.1.3: {} - - de-indent@1.0.2: {} - - debug@4.4.1: - dependencies: - ms: 2.1.3 - - deepmerge@4.3.1: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - dist@file:../dist: {} - - electron-to-chromium@1.5.211: {} - - email-addresses@5.0.0: {} - - entities@4.5.0: {} - - esbuild@0.25.9: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.9 - '@esbuild/android-arm': 0.25.9 - '@esbuild/android-arm64': 0.25.9 - '@esbuild/android-x64': 0.25.9 - '@esbuild/darwin-arm64': 0.25.9 - '@esbuild/darwin-x64': 0.25.9 - '@esbuild/freebsd-arm64': 0.25.9 - '@esbuild/freebsd-x64': 0.25.9 - '@esbuild/linux-arm': 0.25.9 - '@esbuild/linux-arm64': 0.25.9 - '@esbuild/linux-ia32': 0.25.9 - '@esbuild/linux-loong64': 0.25.9 - '@esbuild/linux-mips64el': 0.25.9 - '@esbuild/linux-ppc64': 0.25.9 - '@esbuild/linux-riscv64': 0.25.9 - '@esbuild/linux-s390x': 0.25.9 - '@esbuild/linux-x64': 0.25.9 - '@esbuild/netbsd-arm64': 0.25.9 - '@esbuild/netbsd-x64': 0.25.9 - '@esbuild/openbsd-arm64': 0.25.9 - '@esbuild/openbsd-x64': 0.25.9 - '@esbuild/openharmony-arm64': 0.25.9 - '@esbuild/sunos-x64': 0.25.9 - '@esbuild/win32-arm64': 0.25.9 - '@esbuild/win32-ia32': 0.25.9 - '@esbuild/win32-x64': 0.25.9 - - escalade@3.2.0: {} - - escape-string-regexp@1.0.5: {} - - esm-env@1.2.2: {} - - esrap@2.1.0: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - estree-walker@2.0.2: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fastq@1.19.1: - dependencies: - reusify: 1.1.0 - - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - filename-reserved-regex@2.0.0: {} - - filenamify@4.3.0: - dependencies: - filename-reserved-regex: 2.0.0 - strip-outer: 1.0.1 - trim-repeated: 1.0.0 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-cache-dir@3.3.2: - dependencies: - commondir: 1.0.1 - make-dir: 3.1.0 - pkg-dir: 4.2.0 - - find-up@4.1.0: - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - - fs-extra@11.3.1: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.2.0 - universalify: 2.0.1 - - fsevents@2.3.3: - optional: true - - gensync@1.0.0-beta.2: {} - - gh-pages@6.3.0: - dependencies: - async: 3.2.6 - commander: 13.1.0 - email-addresses: 5.0.0 - filenamify: 4.3.0 - find-cache-dir: 3.3.2 - fs-extra: 11.3.1 - globby: 11.1.0 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - - graceful-fs@4.2.11: {} - - he@1.2.0: {} - - ignore@5.3.2: {} - - is-extglob@2.1.1: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - is-reference@3.0.3: - dependencies: - '@types/estree': 1.0.8 - - js-tokens@4.0.0: {} - - jsesc@3.1.0: {} - - json5@2.2.3: {} - - jsonfile@6.2.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - kleur@4.1.5: {} - - locate-character@3.0.0: {} - - locate-path@5.0.0: - dependencies: - p-locate: 4.1.0 - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - - magic-string@0.30.18: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - make-dir@3.1.0: - dependencies: - semver: 6.3.1 - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - ms@2.1.3: {} - - muggle-string@0.4.1: {} - - nanoid@3.3.11: {} - - node-releases@2.0.19: {} - - p-limit@2.3.0: - dependencies: - p-try: 2.2.0 - - p-locate@4.1.0: - dependencies: - p-limit: 2.3.0 - - p-try@2.2.0: {} - - path-browserify@1.0.1: {} - - path-exists@4.0.0: {} - - path-type@4.0.0: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.3: {} - - pkg-dir@4.2.0: - dependencies: - find-up: 4.1.0 - - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - queue-microtask@1.2.3: {} - - react-dom@19.1.1(react@19.1.1): - dependencies: - react: 19.1.1 - scheduler: 0.26.0 - - react-refresh@0.17.0: {} - - react@19.1.1: {} - - reusify@1.1.0: {} - - rollup@4.49.0: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.49.0 - '@rollup/rollup-android-arm64': 4.49.0 - '@rollup/rollup-darwin-arm64': 4.49.0 - '@rollup/rollup-darwin-x64': 4.49.0 - '@rollup/rollup-freebsd-arm64': 4.49.0 - '@rollup/rollup-freebsd-x64': 4.49.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.49.0 - '@rollup/rollup-linux-arm-musleabihf': 4.49.0 - '@rollup/rollup-linux-arm64-gnu': 4.49.0 - '@rollup/rollup-linux-arm64-musl': 4.49.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.49.0 - '@rollup/rollup-linux-ppc64-gnu': 4.49.0 - '@rollup/rollup-linux-riscv64-gnu': 4.49.0 - '@rollup/rollup-linux-riscv64-musl': 4.49.0 - '@rollup/rollup-linux-s390x-gnu': 4.49.0 - '@rollup/rollup-linux-x64-gnu': 4.49.0 - '@rollup/rollup-linux-x64-musl': 4.49.0 - '@rollup/rollup-win32-arm64-msvc': 4.49.0 - '@rollup/rollup-win32-ia32-msvc': 4.49.0 - '@rollup/rollup-win32-x64-msvc': 4.49.0 - fsevents: 2.3.3 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - scheduler@0.26.0: {} - - semver@6.3.1: {} - - slash@3.0.0: {} - - source-map-js@1.2.1: {} - - strip-outer@1.0.1: - dependencies: - escape-string-regexp: 1.0.5 - - svelte@5.38.6: - dependencies: - '@jridgewell/remapping': 2.3.5 - '@jridgewell/sourcemap-codec': 1.5.5 - '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) - '@types/estree': 1.0.8 - acorn: 8.15.0 - aria-query: 5.3.2 - axobject-query: 4.1.0 - clsx: 2.1.1 - esm-env: 1.2.2 - esrap: 2.1.0 - is-reference: 3.0.3 - locate-character: 3.0.0 - magic-string: 0.30.18 - zimmerframe: 1.1.2 - - tinyglobby@0.2.14: - dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - trim-repeated@1.0.0: - dependencies: - escape-string-regexp: 1.0.5 - - typescript@5.9.2: {} - - universalify@2.0.1: {} - - update-browserslist-db@1.1.3(browserslist@4.25.4): - dependencies: - browserslist: 4.25.4 - escalade: 3.2.0 - picocolors: 1.1.1 - - vite@7.1.3: - dependencies: - esbuild: 0.25.9 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.49.0 - tinyglobby: 0.2.14 - optionalDependencies: - fsevents: 2.3.3 - - vitefu@1.1.1(vite@7.1.3): - optionalDependencies: - vite: 7.1.3 - - vscode-uri@3.1.0: {} - - vue-tsc@3.0.6(typescript@5.9.2): - dependencies: - '@volar/typescript': 2.4.23 - '@vue/language-core': 3.0.6(typescript@5.9.2) - typescript: 5.9.2 - - vue@3.5.20(typescript@5.9.2): - dependencies: - '@vue/compiler-dom': 3.5.20 - '@vue/compiler-sfc': 3.5.20 - '@vue/runtime-dom': 3.5.20 - '@vue/server-renderer': 3.5.20(vue@3.5.20(typescript@5.9.2)) - '@vue/shared': 3.5.20 - optionalDependencies: - typescript: 5.9.2 - - yallist@3.1.1: {} - - zimmerframe@1.1.2: {} diff --git a/examples/react-demo/index.html b/examples/react-demo/index.html deleted file mode 100644 index b4d7fb1..0000000 --- a/examples/react-demo/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - React + Classigo Demo - - -
- - - \ No newline at end of file diff --git a/examples/react-demo/main.tsx b/examples/react-demo/main.tsx deleted file mode 100644 index c73d2a2..0000000 --- a/examples/react-demo/main.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom/client'; -import ReactDemo from '../src/components/ReactDemo'; - -ReactDOM.createRoot(document.getElementById('app')!).render( - - - -); diff --git a/examples/src/components/ReactDemo.tsx b/examples/src/components/ReactDemo.tsx deleted file mode 100644 index a40865e..0000000 --- a/examples/src/components/ReactDemo.tsx +++ /dev/null @@ -1,280 +0,0 @@ -/** @jsxImportSource react */ -import React, { useEffect, useRef, useState } from "react"; -import { createPortal } from "react-dom"; -import classigo from "classigo"; -import "../styles.css"; - -const ReactDemo: React.FC = () => { - const [variant, setVariant] = useState<"primary" | "secondary">("primary"); - const [size, setSize] = useState<"small" | "medium" | "large">("medium"); - const [disabled, setDisabled] = useState(false); - const [rounded, setRounded] = useState(false); - const [outlined, setOutlined] = useState(false); - const [openMenu, setOpenMenu] = useState<"variant" | "size" | null>(null); - const [isTouchDevice, setIsTouchDevice] = useState(false); - - const variantRef = useRef(null); - const sizeRef = useRef(null); - - useEffect(() => { - const checkTouchDevice = () => { - setIsTouchDevice( - "ontouchstart" in window || navigator.maxTouchPoints > 0, - ); - }; - checkTouchDevice(); - window.addEventListener("resize", checkTouchDevice); - return () => window.removeEventListener("resize", checkTouchDevice); - }, []); - - const buttonClasses = classigo( - "button", - `button--${variant}`, - `button--${size}`, - disabled && "button--disabled", - rounded && "button--rounded", - outlined && "button--outlined", - ); - - const handleButtonClick = () => { - console.log("Button clicked!", { - variant, - size, - disabled, - rounded, - outlined, - }); - }; - - const handleSelectChange = (type: "variant" | "size", value: string) => { - if (type === "variant") { - setVariant(value as "primary" | "secondary"); - } else if (type === "size") { - setSize(value as "small" | "medium" | "large"); - } - setOpenMenu(null); - }; - - const toggleMenu = (menuType: "variant" | "size") => { - setOpenMenu(openMenu === menuType ? null : menuType); - }; - - const closeAllMenus = () => { - setOpenMenu(null); - }; - - useEffect(() => { - const handleClickOutside = () => { - closeAllMenus(); - }; - - if (openMenu) { - document.addEventListener("click", handleClickOutside); - return () => document.removeEventListener("click", handleClickOutside); - } - }, [openMenu]); - - const MenuPortal = () => { - if (!openMenu) return null; - - const ref = openMenu === "variant" ? variantRef : sizeRef; - const rect = ref.current?.getBoundingClientRect(); - - if (!rect) return null; - - return createPortal( -
e.stopPropagation()} - > - {openMenu === "variant" && ( - <> -
handleSelectChange("variant", "primary")} - > - Primary -
-
handleSelectChange("variant", "secondary")} - > - Secondary -
- - )} - - {openMenu === "size" && ( - <> -
handleSelectChange("size", "small")} - > - Small -
-
handleSelectChange("size", "medium")} - > - Medium -
-
handleSelectChange("size", "large")} - > - Large -
- - )} -
, - document.body - ); - }; - - return ( -
-
-

- React - React + Classigo Demo -

-

- Interactive button component demonstrating classigo with React hooks - and CSS Modules integration. -

-
- -
-
- -
- -
-
-

Button Properties

-
-
{ - e.stopPropagation(); - toggleMenu("variant"); - }} - > -
🎨
-
-
Variant
-
{variant}
-
-
- › -
-
- -
{ - e.stopPropagation(); - toggleMenu("size"); - }} - > -
📏
-
-
Size
-
{size}
-
-
- › -
-
-
-
- -
-

Button States

-
-
- Disabled -
- -
- Rounded -
- -
- Outlined -
-
-
-
- -
- Generated className: - {buttonClasses} -
-
- - - -
-

⚡ Performance

-

- classigo: 52M ops/sec • 159B bundle size • Ultra-optimized for CSS - Modules -

-
- - ← Back to Examples -
- ); -}; - -export default ReactDemo; diff --git a/examples/src/components/SvelteDemo.svelte b/examples/src/components/SvelteDemo.svelte deleted file mode 100644 index d88fa6f..0000000 --- a/examples/src/components/SvelteDemo.svelte +++ /dev/null @@ -1,347 +0,0 @@ - - - - -
-
-

- - Svelte + Classigo Demo -

-

- Interactive button component demonstrating classigo with Svelte reactivity and CSS Modules integration. -

-
- -
-
- -
- -
-
-

Button Properties

-
-
{ - e.stopPropagation(); - toggleMenu('variant'); - }} - on:keydown={(e) => { - if (e.key === 'Enter' || e.key === ' ') { - e.preventDefault(); - toggleMenu('variant'); - } - }} - > -
🎨
-
-
Variant
-
{variant}
-
-
- › -
-
- -
{ - e.stopPropagation(); - toggleMenu('size'); - }} - on:keydown={(e) => { - if (e.key === 'Enter' || e.key === ' ') { - e.preventDefault(); - toggleMenu('size'); - } - }} - > -
📏
-
-
Size
-
{size}
-
-
- › -
-
-
-
- -
-

Button States

-
-
- Disabled - -
- -
- Rounded - -
- -
- Outlined - -
-
-
-
- -
- Generated className: - {buttonClasses} -
-
- -
-

⚡ Performance

-

- classigo: 52M ops/sec • 159B bundle size • Ultra-optimized for CSS - Modules -

-
- - ← Back to Examples -
diff --git a/examples/src/components/VanillaDemo.js b/examples/src/components/VanillaDemo.js deleted file mode 100644 index 5409aac..0000000 --- a/examples/src/components/VanillaDemo.js +++ /dev/null @@ -1,318 +0,0 @@ -/* global document, window, navigator, console */ - -import classigo from 'classigo'; -import '../styles.css'; - -class VanillaDemo { - constructor() { - this.variant = 'primary'; - this.size = 'medium'; - this.disabled = false; - this.rounded = false; - this.outlined = false; - this.openMenu = null; - this.isTouchDevice = false; - - this.variantRef = null; - this.sizeRef = null; - - this.init(); - } - - checkTouchDevice() { - this.isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0; - } - - getButtonClasses() { - return classigo( - 'button', - `button--${this.variant}`, - `button--${this.size}`, - this.disabled && 'button--disabled', - this.rounded && 'button--rounded', - this.outlined && 'button--outlined' - ); - } - - updateButton() { - const button = document.querySelector('.button'); - if (button) { - button.className = this.getButtonClasses(); - button.disabled = this.disabled; - } - - const outputCode = document.querySelector('.outputCode'); - if (outputCode) { - outputCode.textContent = this.getButtonClasses(); - } - - this.updateSwitches(); - this.updateSelects(); - } - - updateSwitches() { - const switches = document.querySelectorAll('.switch'); - switches[0].className = classigo('switch', this.disabled && 'active'); - switches[1].className = classigo('switch', this.rounded && 'active'); - switches[2].className = classigo('switch', this.outlined && 'active'); - } - - updateSelects() { - const variantSelect = this.variantRef; - const sizeSelect = this.sizeRef; - - if (variantSelect) { - variantSelect.className = classigo( - 'select-item', - this.openMenu === 'variant' && 'select-item--active' - ); - const variantChevron = variantSelect.querySelector('.select-item-chevron'); - if (variantChevron) { - variantChevron.className = classigo( - 'select-item-chevron', - this.openMenu === 'variant' && 'select-item-chevron--active' - ); - } - } - - if (sizeSelect) { - sizeSelect.className = classigo( - 'select-item', - this.openMenu === 'size' && 'select-item--active' - ); - const sizeChevron = sizeSelect.querySelector('.select-item-chevron'); - if (sizeChevron) { - sizeChevron.className = classigo( - 'select-item-chevron', - this.openMenu === 'size' && 'select-item-chevron--active' - ); - } - } - } - - handleSelectChange(type, value) { - if (type === 'variant') { - this.variant = value; - } else if (type === 'size') { - this.size = value; - } - this.openMenu = null; - this.removeMenu(); - this.updateButton(); - } - - toggleMenu(menuType) { - if (this.openMenu === menuType) { - this.openMenu = null; - this.removeMenu(); - } else { - this.openMenu = menuType; - this.removeMenu(); - this.showMenu(); - } - this.updateSelects(); - } - - showMenu() { - if (!this.openMenu) return; - - const ref = this.openMenu === 'variant' ? this.variantRef : this.sizeRef; - if (!ref) return; - - const rect = ref.getBoundingClientRect(); - - const menu = document.createElement('div'); - menu.className = classigo('select-menu-portal', 'select-menu-portal--visible'); - menu.style.cssText = ` - position: absolute; - top: ${rect.bottom + window.scrollY + 4}px; - left: ${rect.left + window.scrollX}px; - width: ${rect.width}px; - z-index: 1000; - `; - - if (this.openMenu === 'variant') { - menu.innerHTML = ` -
Primary
-
Secondary
- `; - } else if (this.openMenu === 'size') { - menu.innerHTML = ` -
Small
-
Medium
-
Large
- `; - } - - menu.querySelectorAll('.select-option').forEach(option => { - option.addEventListener('click', () => { - this.handleSelectChange(this.openMenu, option.dataset.value); - }); - }); - - document.body.appendChild(menu); - } - - removeMenu() { - const existingMenu = document.querySelector('.select-menu-portal'); - if (existingMenu) { - existingMenu.remove(); - } - } - - bindEvents() { - const button = document.querySelector('.button'); - if (button) { - button.addEventListener('click', () => { - console.log('Button clicked!', { - variant: this.variant, - size: this.size, - disabled: this.disabled, - rounded: this.rounded, - outlined: this.outlined, - }); - }); - } - - const switches = document.querySelectorAll('.switch'); - switches[0].addEventListener('click', () => { - this.disabled = !this.disabled; - this.updateButton(); - }); - - switches[1].addEventListener('click', () => { - this.rounded = !this.rounded; - this.updateButton(); - }); - - switches[2].addEventListener('click', () => { - this.outlined = !this.outlined; - this.updateButton(); - }); - - if (this.variantRef) { - this.variantRef.addEventListener('click', (e) => { - e.stopPropagation(); - this.toggleMenu('variant'); - }); - } - - if (this.sizeRef) { - this.sizeRef.addEventListener('click', (e) => { - e.stopPropagation(); - this.toggleMenu('size'); - }); - } - - document.addEventListener('click', () => { - this.openMenu = null; - this.removeMenu(); - this.updateSelects(); - }); - } - - render() { - const app = document.getElementById('app'); - if (!app) return; - - app.innerHTML = ` -
-
-

- - Vanilla JS + Classigo Demo -

-

- Dynamic button component demonstrating classigo with vanilla JavaScript and CSS Modules integration. -

-
- -
-
- -
- -
-
-

Button Properties

-
-
-
🎨
-
-
Variant
-
${this.variant}
-
-
-
- -
-
📏
-
-
Size
-
${this.size}
-
-
-
-
-
- -
-

Button States

-
-
- Disabled - -
- -
- Rounded - -
- -
- Outlined - -
-
-
-
- -
- Generated className: - ${this.getButtonClasses()} -
-
- -
-

⚡ Performance

-

- classigo: 52M ops/sec • 159B bundle size • Ultra-optimized for CSS - Modules -

-
- - ← Back to Examples -
- `; - - this.variantRef = document.querySelector('[data-ref="variantRef"]'); - this.sizeRef = document.querySelector('[data-ref="sizeRef"]'); - - this.bindEvents(); - } - - init() { - if (typeof window !== 'undefined') { - this.checkTouchDevice(); - this.render(); - } - } -} - -export default VanillaDemo; diff --git a/examples/src/components/VueDemo.vue b/examples/src/components/VueDemo.vue deleted file mode 100644 index 2b832dd..0000000 --- a/examples/src/components/VueDemo.vue +++ /dev/null @@ -1,257 +0,0 @@ - - - - - diff --git a/examples/src/css-modules.d.ts b/examples/src/css-modules.d.ts deleted file mode 100644 index 133960b..0000000 --- a/examples/src/css-modules.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -declare module '*.css' { - const content: string - export default content -} - -declare module '*.scss' { - const content: string - export default content -} - -declare module '*.sass' { - const content: string - export default content -} diff --git a/examples/src/main.js b/examples/src/main.js deleted file mode 100644 index 49f6278..0000000 --- a/examples/src/main.js +++ /dev/null @@ -1,95 +0,0 @@ -/* global document, setTimeout */ - -import classigo from 'classigo'; -import './styles.css'; - -const app = document.getElementById('app'); - -const performanceStats = { - opsPerSec: '52M', - bundleSize: '159B', - framework: 'Standalone' -}; - -const examples = [ - { - title: 'React + Classigo', - description: 'Interactive button with React hooks and CSS Modules', - url: './react-demo/', - framework: 'React', - color: '#61dafb', - icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/react/react-original.svg' - }, - { - title: 'Vue 3 + Classigo', - description: 'Reactive button with Composition API and CSS Modules', - url: './vue-demo/', - framework: 'Vue', - color: '#42b883', - icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/vuejs/vuejs-original.svg' - }, - { - title: 'Svelte + Classigo', - description: 'Reactive button with Svelte and CSS Modules', - url: './svelte-demo/', - framework: 'Svelte', - color: '#ff3e00', - icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/svelte/svelte-original.svg' - }, - { - title: 'Vanilla JS + Classigo', - description: 'Dynamic button with vanilla JavaScript and CSS Modules', - url: './vanilla-demo/', - framework: 'Vanilla', - color: '#f7df1e', - icon: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg' - } -]; - -app.innerHTML = ` -
-
-

- Classigo - Classigo Examples -

-

Ultra-optimized class name utility for CSS Modules

-
- -
-

⚡ Performance

-

${performanceStats.opsPerSec} ops/sec • ${performanceStats.bundleSize} bundle size • ${performanceStats.framework}

-
- -
-
- ${examples.map(example => ` -
-
- ${example.framework} -

${example.title}

-
-

${example.description}

- - Try Demo - -
- `).join('')} -
-
- - -
-`; - -setTimeout(() => { - app.classList.add('loaded'); -}, 100); diff --git a/examples/src/page-transitions.js b/examples/src/page-transitions.js deleted file mode 100644 index d5ce95b..0000000 --- a/examples/src/page-transitions.js +++ /dev/null @@ -1,50 +0,0 @@ -/* global document, window, setTimeout, URL */ - - -// Gestion des transitions de page -const loadingOverlay = document.getElementById('loading-overlay'); -const app = document.getElementById('app'); - -// Masquer le loading une fois que l'app est chargée -window.addEventListener('load', () => { - if (app) { - app.classList.add('loaded'); - } - - // Masquer le loader après un délai - setTimeout(() => { - loadingOverlay.classList.add('fade-out'); - setTimeout(() => { - loadingOverlay.style.display = 'none'; - }, 300); - }, 500); -}); - -// Afficher le loader lors des changements de page -document.addEventListener('click', (e) => { - const link = e.target.closest('a'); - if (link && link.href && !link.href.includes('#')) { - // Vérifier si c'est un lien interne ou un lien de retour - const currentHost = window.location.host; - const linkHost = new URL(link.href).host; - const isInternalLink = linkHost === currentHost || linkHost === ''; - const isBackLink = link.href.includes('../') || link.textContent.includes('Back'); - - if (isInternalLink || isBackLink) { - e.preventDefault(); - loadingOverlay.style.display = 'flex'; - loadingOverlay.classList.remove('fade-out'); - - // Naviguer après un court délai - setTimeout(() => { - window.location.href = link.href; - }, 200); - } - } -}); - -// Masquer le loader si on revient en arrière -window.addEventListener('pageshow', () => { - loadingOverlay.style.display = 'none'; - loadingOverlay.classList.add('fade-out'); -}); diff --git a/examples/src/styles.css b/examples/src/styles.css deleted file mode 100644 index 69df8d7..0000000 --- a/examples/src/styles.css +++ /dev/null @@ -1,844 +0,0 @@ -/* CSS Variables for colors */ -:root { - /* Background colors */ - --bg-primary: #0a0a0a; - --bg-secondary: rgba(28, 28, 30, 0.8); - --bg-tertiary: rgba(44, 44, 46, 0.6); - --bg-card: rgba(28, 28, 30, 0.7); - --bg-input: rgba(44, 44, 46, 0.5); - --bg-switch-off: rgba(44, 44, 46, 0.8); - --bg-switch-on: #30d158; - - /* Text colors */ - --text-primary: #ffffff; - --text-secondary: rgba(255, 255, 255, 0.9); - --text-tertiary: rgba(255, 255, 255, 0.7); - --text-accent: #0a84ff; - - /* Accent colors */ - --accent-blue: #0a84ff; - --accent-green: #30d158; - --accent-orange: #ff9f0a; - --accent-red: #ff453a; - --accent-purple: #bf5af2; - --accent-pink: #ff375f; - --accent-yellow: #ffd60a; - - /* Subtle borders */ - --border-subtle: rgba(255, 255, 255, 0.08); - --border-visible: rgba(255, 255, 255, 0.12); - - /* Shadows */ - --shadow-subtle: 0 1px 3px rgba(0, 0, 0, 0.3); - --shadow-medium: 0 4px 12px rgba(0, 0, 0, 0.4); - - /* Spacing */ - --spacing-xs: 4px; - --spacing-sm: 8px; - --spacing-md: 16px; - --spacing-lg: 20px; - --spacing-xl: 24px; - --spacing-2xl: 32px; - --spacing-3xl: 40px; - - /* Border radius */ - --radius-sm: 6px; - --radius-md: 10px; - --radius-lg: 14px; - --radius-xl: 18px; - --radius-2xl: 22px; - --radius-full: 50px; -} - -/* Global styles */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', sans-serif; - background: linear-gradient(135deg, #1e3a8a 0%, #374151 50%, #1f2937 100%); - color: var(--text-primary); - min-height: 100vh; - line-height: 1.5; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - font-weight: 400; -} - -/* Container */ -.container { - max-width: 1000px; - margin: 0 auto; - padding: var(--spacing-2xl); - min-height: 100vh; - display: flex; - flex-direction: column; - gap: var(--spacing-3xl); -} - -/* Header */ -.header { - text-align: center; - margin-bottom: var(--spacing-3xl); -} - -.title { - font-size: 2.5rem; - font-weight: 700; - color: var(--text-primary); - margin-bottom: var(--spacing-md); - letter-spacing: -0.02em; - line-height: 1.2; - display: flex; - align-items: center; - justify-content: center; - gap: var(--spacing-md); -} - -.title-logo { - width: 48px; - height: 48px; -} - -.subtitle { - font-size: 1.125rem; - color: var(--text-secondary); - font-weight: 400; - max-width: 500px; - margin: 0 auto; - line-height: 1.4; -} - -/* Demo section */ -.demo { - background: var(--bg-card); - border-radius: var(--radius-xl); - padding: var(--spacing-2xl); - border: 1px solid var(--border-subtle); - box-shadow: var(--shadow-medium); - display: flex; - flex-direction: column; - gap: var(--spacing-2xl); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); -} - -/* Button container */ -.buttonContainer { - display: flex; - justify-content: center; - align-items: center; - min-height: 100px; - background: var(--bg-secondary); - border-radius: var(--radius-lg); - border: 1px solid var(--border-subtle); - padding: var(--spacing-xl); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); -} - -/* Button styles */ -.button { - font-family: inherit; - font-size: 1rem; - font-weight: 600; - padding: var(--spacing-md) var(--spacing-xl); - border: none; - border-radius: var(--radius-lg); - cursor: pointer; - transition: all 0.2s ease; - position: relative; - background: var(--accent-blue); - color: var(--text-primary); - box-shadow: var(--shadow-subtle); - letter-spacing: -0.01em; -} - -.button:hover:not(:disabled) { - transform: translateY(-1px); - box-shadow: var(--shadow-medium); -} - -.button:active:not(:disabled) { - transform: translateY(0); - transition: all 0.1s ease; -} - -.button:disabled { - opacity: 0.5; - cursor: not-allowed; - transform: none; -} - -/* Button variants */ -.button--primary { - background: var(--accent-blue); - color: var(--text-primary); -} - -.button--secondary { - background: var(--bg-tertiary); - color: var(--text-primary); - border: 1px solid var(--border-visible); -} - -.button--large { - font-size: 1.125rem; - padding: var(--spacing-lg) var(--spacing-2xl); - border-radius: var(--radius-xl); -} - -.button--small { - font-size: 0.875rem; - padding: var(--spacing-sm) var(--spacing-lg); - border-radius: var(--radius-md); -} - -.button--disabled { - background: var(--bg-tertiary); - color: var(--text-tertiary); - border: 1px solid var(--border-subtle); -} - -.button--rounded { - border-radius: var(--radius-full); -} - -.button--outlined { - background: transparent; - border: 1px solid var(--accent-blue); - color: var(--accent-blue); -} - -.button--outlined:hover:not(:disabled) { - background: var(--accent-blue); - color: var(--text-primary); -} - -/* Controls */ -.controls { - display: flex; - flex-direction: column; - gap: var(--spacing-xl); -} - -/* Selects section */ -.selects-section { - background: var(--bg-secondary); - border-radius: var(--radius-lg); - padding: var(--spacing-md); - border: 1px solid var(--border-subtle); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); -} - -.selects-section h3 { - font-size: 0.875rem; - font-weight: 600; - color: var(--text-secondary); - text-transform: uppercase; - letter-spacing: 0.05em; - margin-bottom: var(--spacing-md); - padding-left: var(--spacing-md); -} - -.selects-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: var(--spacing-sm); -} - -/* Select Item */ -.select-item { - display: flex; - align-items: center; - padding: var(--spacing-md); - background: var(--bg-input); - border-radius: var(--radius-md); - border: 1px solid var(--border-subtle); - cursor: pointer; - transition: all 0.2s ease; - position: relative; - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); -} - -.select-item:hover { - background: var(--bg-tertiary); - transform: translateY(-1px); - box-shadow: var(--shadow-subtle); -} - -.select-item:active { - transform: translateY(0); -} - -/* Zone de sécurité invisible pour éviter la fermeture accidentelle */ -.select-item::after { - content: ''; - position: absolute; - bottom: -8px; - left: 0; - right: 0; - height: 8px; - background: transparent; - pointer-events: none; -} - -.select-item-icon { - width: 20px; - height: 20px; - margin-right: var(--spacing-md); - display: flex; - align-items: center; - justify-content: center; - font-size: 1rem; - color: var(--accent-blue); -} - -.select-item-content { - flex: 1; - display: flex; - flex-direction: column; -} - -.select-item-label { - font-size: 0.875rem; - font-weight: 500; - color: var(--text-secondary); - text-transform: uppercase; - letter-spacing: 0.05em; - margin-bottom: var(--spacing-xs); -} - -.select-item-value { - font-size: 1rem; - font-weight: 600; - color: var(--text-primary); - transition: all 0.2s ease; -} - -.select-item-chevron { - color: var(--text-tertiary); - font-size: 0.875rem; - margin-left: var(--spacing-sm); - transition: all 0.2s ease; -} - -.select-item:hover .select-item-chevron { - color: var(--text-secondary); - transform: translateX(2px); -} - -.select-item-chevron--active { - transform: rotate(90deg) !important; - color: var(--accent-blue) !important; -} - -/* Select Menu Portal */ -.select-menu-portal { - background: var(--bg-secondary); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-md); - box-shadow: var(--shadow-medium); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - overflow: hidden; - animation: slideDown 0.2s ease-out; -} - -/* Select Menu (ancien - à supprimer) */ -.select-menu { - position: absolute; - top: calc(100% + 4px); - left: 0; - right: 0; - background: var(--bg-secondary); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-md); - box-shadow: var(--shadow-medium); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - z-index: 999999; - overflow: hidden; - animation: slideDown 0.2s ease-out; - min-width: 200px; -} - -/* Zone de sécurité au-dessus du menu */ -.select-menu::before { - content: ''; - position: absolute; - top: -8px; - left: 0; - right: 0; - height: 8px; - background: transparent; - pointer-events: none; -} - -@keyframes slideDown { - from { - opacity: 0; - transform: translateY(-10px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.select-option { - padding: var(--spacing-md); - color: var(--text-primary); - font-size: 0.875rem; - font-weight: 500; - cursor: pointer; - transition: all 0.2s ease; - border-bottom: 1px solid var(--border-subtle); -} - -.select-option:last-child { - border-bottom: none; -} - -.select-option:hover { - background: var(--bg-tertiary); - color: var(--accent-blue); -} - -.select-option:active { - background: var(--bg-input); -} - -/* Switches section */ -.switches-section { - background: var(--bg-secondary); - border-radius: var(--radius-lg); - padding: var(--spacing-md); - border: 1px solid var(--border-subtle); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); -} - -.switches-section h3 { - font-size: 0.875rem; - font-weight: 600; - color: var(--text-secondary); - text-transform: uppercase; - letter-spacing: 0.05em; - margin-bottom: var(--spacing-md); - padding-left: var(--spacing-md); -} - -.switches-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); - gap: var(--spacing-md); -} - -/* Switch Style */ -.switch-container { - display: flex; - align-items: center; - justify-content: space-between; - padding: var(--spacing-md); - background: var(--bg-input); - border-radius: var(--radius-md); - border: 1px solid var(--border-subtle); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); -} - -.switch-label { - font-size: 0.875rem; - font-weight: 500; - color: var(--text-secondary); - text-transform: uppercase; - letter-spacing: 0.05em; -} - -.switch { - position: relative; - width: 51px; - height: 31px; - background: var(--bg-switch-off); - border-radius: var(--radius-full); - cursor: pointer; - transition: all 0.3s ease; - border: none; - outline: none; -} - -.switch.active { - background: var(--bg-switch-on); -} - -.switch::before { - content: ''; - position: absolute; - top: 2px; - left: 2px; - width: 27px; - height: 27px; - background: #ffffff; - border-radius: 50%; - transition: all 0.3s ease; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); -} - -.switch.active::before { - transform: translateX(20px); -} - -/* Output */ -.output { - margin-top: var(--spacing-lg); - padding: var(--spacing-md); - background: var(--bg-secondary); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-md); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); -} - -.outputTitle { - display: block; - font-size: 0.875rem; - font-weight: 600; - color: var(--text-secondary); - text-transform: uppercase; - letter-spacing: 0.05em; - margin-bottom: var(--spacing-sm); -} - -.outputCode { - display: block; - font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', monospace; - font-size: 0.875rem; - font-weight: 500; - color: var(--accent-green); - background: var(--bg-input); - padding: var(--spacing-sm) var(--spacing-md); - border-radius: var(--radius-sm); - border: 1px solid var(--border-subtle); - word-break: break-all; - white-space: normal; - line-height: 1.4; - overflow-wrap: break-word; -} - -/* Performance section */ -.performance { - background: var(--bg-card); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-xl); - padding: var(--spacing-xl); - text-align: center; - box-shadow: var(--shadow-medium); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); -} - -.performance h3 { - font-size: 1.25rem; - font-weight: 700; - color: var(--text-primary); - margin-bottom: var(--spacing-md); -} - -.performance p { - font-size: 0.875rem; - color: var(--text-secondary); - line-height: 1.5; -} - -/* Back link */ -.backLink { - display: inline-flex; - align-items: center; - gap: var(--spacing-sm); - color: var(--accent-blue); - text-decoration: none; - font-weight: 600; - font-size: 0.875rem; - padding: var(--spacing-md) var(--spacing-lg); - background: var(--bg-card); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-lg); - transition: all 0.2s ease; - align-self: flex-start; - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); -} - -.backLink:hover { - background: var(--bg-secondary); - transform: translateX(-2px); -} - -/* Loading Animation */ -.loading-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: var(--bg-primary); - display: flex; - align-items: center; - justify-content: center; - z-index: 9999; - backdrop-filter: var(--glass-blur); - transition: opacity 0.3s ease; -} - -.loading-overlay.fade-out { - opacity: 0; - pointer-events: none; -} - -.loading-spinner { - width: 60px; - height: 60px; - border: 3px solid var(--glass-border); - border-top: 3px solid var(--accent-blue); - border-radius: 50%; - animation: spin 1s linear infinite; - background: var(--glass-bg); - backdrop-filter: var(--glass-blur); - box-shadow: var(--glass-shadow); -} - -.loading-text { - position: absolute; - bottom: -40px; - color: var(--text-secondary); - font-size: var(--font-size-sm); - font-weight: 500; - letter-spacing: 0.5px; -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} - -/* Page Transitions */ -.page-transition { - opacity: 0; - transform: translateY(20px); - transition: all 0.4s ease; -} - -.page-transition.loaded { - opacity: 1; - transform: translateY(0); -} - -/* Examples Grid */ -.examples-grid { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: var(--spacing-xl); - margin-top: var(--spacing-xl); -} - -.example-card { - background: var(--glass-bg); - border: var(--glass-border); - border-radius: var(--border-radius-lg); - padding: var(--spacing-xl); - backdrop-filter: var(--glass-blur); - transition: all 0.3s ease; - position: relative; - overflow: hidden; - display: flex; - flex-direction: column; -} - -.example-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 2px; - background: linear-gradient(90deg, var(--accent-blue), var(--accent-purple)); - opacity: 0; - transition: opacity 0.3s ease; -} - -/* Barre à gauche pour les cartes de gauche */ -.example-card:nth-child(odd)::before { - left: 0; - right: auto; - width: 2px; - height: 100%; -} - -/* Barre à droite pour les cartes de droite */ -.example-card:nth-child(even)::before { - left: auto; - right: 0; - width: 2px; - height: 100%; -} - -.example-card:hover { - transform: translateY(-2px); - box-shadow: var(--glass-shadow-hover); -} - -.example-card:hover::before { - opacity: 1; -} - -.example-header { - display: flex; - align-items: center; - margin-bottom: var(--spacing-md); - gap: var(--spacing-sm); -} - -.example-icon { - width: 32px; - height: 32px; - border-radius: var(--border-radius-sm); -} - -.example-title { - margin: 0; - color: var(--text-primary); - font-size: var(--font-size-lg); - font-weight: 600; -} - -.example-description { - color: var(--text-secondary); - margin-bottom: var(--spacing-lg); - line-height: 1.5; - flex-grow: 1; -} - -.example-link { - display: inline-block; - background: var(--accent-blue); - color: white; - padding: var(--spacing-sm) var(--spacing-lg); - border-radius: var(--border-radius-md); - text-decoration: none; - font-weight: 500; - transition: all 0.3s ease; - border: none; - cursor: pointer; - margin-top: auto; - align-self: flex-start; -} - -.example-link:hover { - background: var(--accent-blue-hover); - transform: translateY(-1px); -} - -.footer { - text-align: center; - margin-top: var(--spacing-xxl); -} - -/* Responsive design */ -@media (max-width: 768px) { - .container { - padding: var(--spacing-lg); - gap: var(--spacing-2xl); - } - - .title { - font-size: 2rem; - } - - .subtitle { - font-size: 1rem; - } - - .demo { - padding: var(--spacing-lg); - } - - .selects-grid, - .switches-grid { - grid-template-columns: 1fr; - gap: var(--spacing-sm); - } - - .buttonContainer { - min-height: 80px; - } -} - -/* Responsive adjustments */ -@media (max-width: 768px) { - .examples-grid { - grid-template-columns: 1fr; - gap: var(--spacing-lg); - } - - .example-card { - padding: var(--spacing-lg); - } - - .output { - display: block; - } - - .outputTitle { - display: block; - margin-bottom: var(--spacing-sm); - } - - .outputCode { - display: block; - word-break: break-all; - white-space: normal; - line-height: 1.4; - overflow-wrap: break-word; - } -} - -/* Animations */ -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(10px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.container { - animation: fadeIn 0.4s ease-out; -} - -/* Scrollbar styling */ -::-webkit-scrollbar { - width: 6px; -} - -::-webkit-scrollbar-track { - background: transparent; -} - -::-webkit-scrollbar-thumb { - background: var(--bg-tertiary); - border-radius: var(--radius-sm); - border: 1px solid var(--border-subtle); -} - -::-webkit-scrollbar-thumb:hover { - background: var(--bg-secondary); -} diff --git a/examples/src/vue-shims.d.ts b/examples/src/vue-shims.d.ts deleted file mode 100644 index 2b97bd9..0000000 --- a/examples/src/vue-shims.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module '*.vue' { - import type { DefineComponent } from 'vue' - const component: DefineComponent<{}, {}, any> - export default component -} diff --git a/examples/svelte-demo/index.html b/examples/svelte-demo/index.html deleted file mode 100644 index ba1edc7..0000000 --- a/examples/svelte-demo/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Svelte + Classigo Demo - - -
- - - \ No newline at end of file diff --git a/examples/svelte-demo/main.ts b/examples/svelte-demo/main.ts deleted file mode 100644 index 677f090..0000000 --- a/examples/svelte-demo/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import SvelteDemo from '../src/components/SvelteDemo.svelte'; - -const app = new SvelteDemo({ - target: document.getElementById('app')! -}); - -export default app; diff --git a/examples/tsconfig.json b/examples/tsconfig.json deleted file mode 100644 index 6bfa73a..0000000 --- a/examples/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - "strict": true, - "noUnusedLocals": false, - "noUnusedParameters": false, - "noFallthroughCasesInSwitch": true - }, - "include": ["src"] -} diff --git a/examples/vanilla-demo/index.html b/examples/vanilla-demo/index.html deleted file mode 100644 index ca710a6..0000000 --- a/examples/vanilla-demo/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Vanilla JS + Classigo Demo - - -
- - - \ No newline at end of file diff --git a/examples/vanilla-demo/main.js b/examples/vanilla-demo/main.js deleted file mode 100644 index 5924ca7..0000000 --- a/examples/vanilla-demo/main.js +++ /dev/null @@ -1,6 +0,0 @@ -import VanillaDemo from '../src/components/VanillaDemo.js'; - -// Initialize when DOM is ready -document.addEventListener('DOMContentLoaded', () => { - new VanillaDemo(); -}); diff --git a/examples/vite.config.js b/examples/vite.config.js deleted file mode 100644 index 13174a2..0000000 --- a/examples/vite.config.js +++ /dev/null @@ -1,45 +0,0 @@ -import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; -import vue from '@vitejs/plugin-vue'; -import { svelte } from '@sveltejs/vite-plugin-svelte'; -import { resolve } from 'path'; -import { fileURLToPath } from 'url'; - -// eslint-disable-next-line no-undef -const __dirname = fileURLToPath(new URL('.', import.meta.url)); - -export default defineConfig({ - base: '/classigo/', - plugins: [ - react(), - vue(), - svelte({ - compilerOptions: { - compatibility: { - componentApi: 4 - } - } - }) - ], - resolve: { - alias: { - '@': resolve(__dirname, 'src') - } - }, - build: { - outDir: 'dist', - rollupOptions: { - input: { - main: resolve(__dirname, 'index.html'), - react: resolve(__dirname, 'react-demo/index.html'), - vue: resolve(__dirname, 'vue-demo/index.html'), - svelte: resolve(__dirname, 'svelte-demo/index.html'), - vanilla: resolve(__dirname, 'vanilla-demo/index.html') - } - } - }, - server: { - port: 3000, - open: true - } -}); diff --git a/examples/vue-demo/index.html b/examples/vue-demo/index.html deleted file mode 100644 index 1f173c3..0000000 --- a/examples/vue-demo/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Vue 3 + Classigo Demo - - -
- - - \ No newline at end of file diff --git a/examples/vue-demo/main.ts b/examples/vue-demo/main.ts deleted file mode 100644 index f47d1c8..0000000 --- a/examples/vue-demo/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -// @ts-ignore -import { createApp } from 'vue'; -import VueDemo from '../src/components/VueDemo.vue'; - -createApp(VueDemo).mount('#app'); diff --git a/package.json b/package.json index 22af544..5c8b7cc 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,40 @@ { "name": "classigo", - "version": "1.0.1", + "version": "2.0.0", + "description": "Fast class name utility for TypeScript — strings and objects, zero dependencies.", + "keywords": [ + "classnames", + "clsx", + "css-modules", + "css-classes", + "utility", + "typescript", + "type-safe", + "zero-dependency", + "fast", + "performance", + "lightweight", + "esm", + "bun", + "node", + "react", + "vue", + "svelte" + ], + "license": "MIT", + "author": "SUP2Ak", "type": "module", - "description": "Ultra-optimized class name utility for CSS Modules. 52M ops/sec performance, TypeScript support, standalone.", - "main": "dist/index.cjs", - "module": "dist/index.mjs", + "main": "./dist/index.js", + "module": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", - "import": "./dist/index.mjs", - "require": "./dist/index.cjs" + "import": "./dist/index.js" + }, + "./lite": { + "types": "./dist/lite.d.ts", + "import": "./dist/lite.js" } }, "files": [ @@ -18,54 +42,26 @@ "README.md", "LICENSE" ], + "sideEffects": false, "scripts": { - "build": "vite build && tsc --emitDeclarationOnly --outDir dist && node scripts/generate-cjs-types.js", - "build:prod": "node scripts/clean-dist.js && vite build --config vite.config.prod.js && tsc --emitDeclarationOnly --outDir dist", - "build:dev": "vite build && tsc --emitDeclarationOnly --outDir dist && node scripts/generate-cjs-types.js", - "prepublishOnly": "pnpm run build:prod", - "lint": "eslint src/**/*.ts", - "lint:fix": "eslint src/**/*.ts --fix", - "test": "vitest", - "test:run": "vitest run", - "test:coverage": "vitest run --coverage", - "bench": "node bench/index.js", - "examples:dev": "cd examples && pnpm run dev", - "examples:build": "cd examples && pnpm run build", - "examples:preview": "cd examples && pnpm run preview" + "build": "tsc -p tsconfig.build.json && bun build src/index.ts src/lite.ts --outdir dist --format esm --minify", + "test": "bun test tests/", + "bench": "bun run bench/bench.ts", + "typecheck": "tsc --noEmit", + "format": "prettier --write \"src/**/*.ts\" \"bench/**/*.ts\" \"tests/**/*.ts\"", + "format:check": "prettier --check \"src/**/*.ts\" \"bench/**/*.ts\" \"tests/**/*.ts\"" }, - "keywords": [ - "classigo", - "classnames", - "clsx", - "css-classes", - "css-modules", - "scss-modules", - "utility", - "performance", - "typescript", - "react", - "vue", - "svelte", - "standalone", - "ultra-fast", - "optimized", - "bundle-size", - "lightweight" - ], - "author": "SUP2Ak", - "license": "MIT", "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.6", - "@rollup/plugin-node-resolve": "^16.0.1", - "@eslint/js": "^9.34.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", - "@typescript-eslint/parser": "^8.41.0", - "bun-types": "latest", - "eslint": "^9.34.0", - "typescript": "^5.0.0", - "vite": "^7.1.3", - "vitest": "^2.1.0", - "@vitest/coverage-v8": "^2.1.0" + "@types/bun": "latest", + "classigo-v1": "npm:classigo@1.0.1", + "classnames": "latest", + "clsx": "latest", + "mitata": "latest", + "prettier": "^3.3.0", + "typescript": "6.0.3" + }, + "engines": { + "node": ">=20" }, "repository": { "type": "git", @@ -74,5 +70,6 @@ "bugs": { "url": "https://github.com/SUP2Ak/classigo/issues" }, - "homepage": "https://github.com/SUP2Ak/classigo#readme" + "homepage": "https://github.com/SUP2Ak/classigo#readme", + "packageManager": "bun@1.2.13" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index d01ff3f..0000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,2732 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - devDependencies: - '@eslint/js': - specifier: ^9.34.0 - version: 9.34.0 - '@rollup/plugin-commonjs': - specifier: ^28.0.6 - version: 28.0.6(rollup@4.49.0) - '@rollup/plugin-node-resolve': - specifier: ^16.0.1 - version: 16.0.1(rollup@4.49.0) - '@typescript-eslint/eslint-plugin': - specifier: ^8.41.0 - version: 8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0)(typescript@5.9.2) - '@typescript-eslint/parser': - specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0)(typescript@5.9.2) - '@vitest/coverage-v8': - specifier: ^2.1.0 - version: 2.1.9(vitest@2.1.9(@types/node@24.3.0)(terser@5.43.1)) - bun-types: - specifier: latest - version: 1.2.21(@types/react@19.1.12) - eslint: - specifier: ^9.34.0 - version: 9.34.0 - typescript: - specifier: ^5.0.0 - version: 5.9.2 - vite: - specifier: ^7.1.3 - version: 7.1.3(@types/node@24.3.0)(terser@5.43.1) - vitest: - specifier: ^2.1.0 - version: 2.1.9(@types/node@24.3.0)(terser@5.43.1) - -packages: - - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.28.3': - resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} - engines: {node: '>=6.9.0'} - - '@bcoe/v8-coverage@0.2.3': - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.25.9': - resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.25.9': - resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.25.9': - resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.25.9': - resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.25.9': - resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.25.9': - resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.25.9': - resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.25.9': - resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.25.9': - resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.25.9': - resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.25.9': - resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.25.9': - resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.25.9': - resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.25.9': - resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.9': - resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.25.9': - resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.25.9': - resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.25.9': - resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.25.9': - resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.25.9': - resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.9': - resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.25.9': - resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.25.9': - resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.25.9': - resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.25.9': - resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.25.9': - resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.3.1': - resolution: {integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.15.2': - resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.34.0': - resolution: {integrity: sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.3.5': - resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@istanbuljs/schema@0.1.3': - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/source-map@0.3.11': - resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.30': - resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@rollup/plugin-commonjs@28.0.6': - resolution: {integrity: sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw==} - engines: {node: '>=16.0.0 || 14 >= 14.17'} - peerDependencies: - rollup: ^2.68.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-node-resolve@16.0.1': - resolution: {integrity: sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/pluginutils@5.2.0': - resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/rollup-android-arm-eabi@4.49.0': - resolution: {integrity: sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.49.0': - resolution: {integrity: sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.49.0': - resolution: {integrity: sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.49.0': - resolution: {integrity: sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.49.0': - resolution: {integrity: sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.49.0': - resolution: {integrity: sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.49.0': - resolution: {integrity: sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.49.0': - resolution: {integrity: sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.49.0': - resolution: {integrity: sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.49.0': - resolution: {integrity: sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loongarch64-gnu@4.49.0': - resolution: {integrity: sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-ppc64-gnu@4.49.0': - resolution: {integrity: sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.49.0': - resolution: {integrity: sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.49.0': - resolution: {integrity: sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.49.0': - resolution: {integrity: sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.49.0': - resolution: {integrity: sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.49.0': - resolution: {integrity: sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.49.0': - resolution: {integrity: sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.49.0': - resolution: {integrity: sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.49.0': - resolution: {integrity: sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg==} - cpu: [x64] - os: [win32] - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/node@24.3.0': - resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==} - - '@types/react@19.1.12': - resolution: {integrity: sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==} - - '@types/resolve@1.20.2': - resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - - '@typescript-eslint/eslint-plugin@8.41.0': - resolution: {integrity: sha512-8fz6oa6wEKZrhXWro/S3n2eRJqlRcIa6SlDh59FXJ5Wp5XRZ8B9ixpJDcjadHq47hMx0u+HW6SNa6LjJQ6NLtw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.41.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/parser@8.41.0': - resolution: {integrity: sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/project-service@8.41.0': - resolution: {integrity: sha512-b8V9SdGBQzQdjJ/IO3eDifGpDBJfvrNTp2QD9P2BeqWTGrRibgfgIlBSw6z3b6R7dPzg752tOs4u/7yCLxksSQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/scope-manager@8.41.0': - resolution: {integrity: sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.41.0': - resolution: {integrity: sha512-TDhxYFPUYRFxFhuU5hTIJk+auzM/wKvWgoNYOPcOf6i4ReYlOoYN8q1dV5kOTjNQNJgzWN3TUUQMtlLOcUgdUw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/type-utils@8.41.0': - resolution: {integrity: sha512-63qt1h91vg3KsjVVonFJWjgSK7pZHSQFKH6uwqxAH9bBrsyRhO6ONoKyXxyVBzG1lJnFAJcKAcxLS54N1ee1OQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/types@8.41.0': - resolution: {integrity: sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.41.0': - resolution: {integrity: sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/utils@8.41.0': - resolution: {integrity: sha512-udbCVstxZ5jiPIXrdH+BZWnPatjlYwJuJkDA4Tbo3WyYLh8NvB+h/bKeSZHDOFKfphsZYJQqaFtLeXEqurQn1A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/visitor-keys@8.41.0': - resolution: {integrity: sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@vitest/coverage-v8@2.1.9': - resolution: {integrity: sha512-Z2cOr0ksM00MpEfyVE8KXIYPEcBFxdbLSs56L8PO0QQMxt/6bDj45uQfxoc96v05KW3clk7vvgP0qfDit9DmfQ==} - peerDependencies: - '@vitest/browser': 2.1.9 - vitest: 2.1.9 - peerDependenciesMeta: - '@vitest/browser': - optional: true - - '@vitest/expect@2.1.9': - resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} - - '@vitest/mocker@2.1.9': - resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - - '@vitest/pretty-format@2.1.9': - resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} - - '@vitest/runner@2.1.9': - resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} - - '@vitest/snapshot@2.1.9': - resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} - - '@vitest/spy@2.1.9': - resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} - - '@vitest/utils@2.1.9': - resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.2.0: - resolution: {integrity: sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - bun-types@1.2.21: - resolution: {integrity: sha512-sa2Tj77Ijc/NTLS0/Odjq/qngmEPZfbfnOERi0KRUYhT9R8M4VBioWVmMWE5GrYbKMc+5lVybXygLdibHaqVqw==} - peerDependencies: - '@types/react': ^19 - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} - engines: {node: '>=18'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} - engines: {node: '>= 16'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - - commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.25.9: - resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} - engines: {node: '>=18'} - hasBin: true - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint@9.34.0: - resolution: {integrity: sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - expect-type@1.2.2: - resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} - engines: {node: '>=12.0.0'} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-reference@1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - - istanbul-lib-source-maps@5.0.6: - resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} - engines: {node: '>=10'} - - istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} - engines: {node: '>=8'} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - magic-string@0.30.18: - resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==} - - magicast@0.3.5: - resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} - - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} - hasBin: true - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rollup@4.49.0: - resolution: {integrity: sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - terser@5.43.1: - resolution: {integrity: sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==} - engines: {node: '>=10'} - hasBin: true - - test-exclude@7.0.1: - resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} - engines: {node: '>=18'} - - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} - engines: {node: '>=12.0.0'} - - tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} - - tinyrainbow@1.2.0: - resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} - engines: {node: '>=14.0.0'} - - tinyspy@3.0.2: - resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} - engines: {node: '>=14.0.0'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - typescript@5.9.2: - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@7.10.0: - resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - vite-node@2.1.9: - resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - - vite@5.4.19: - resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - - vite@7.1.3: - resolution: {integrity: sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' - less: ^4.0.0 - lightningcss: ^1.21.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitest@2.1.9: - resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.1.9 - '@vitest/ui': 2.1.9 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - -snapshots: - - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.27.1': {} - - '@babel/parser@7.28.3': - dependencies: - '@babel/types': 7.28.2 - - '@babel/types@7.28.2': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - - '@bcoe/v8-coverage@0.2.3': {} - - '@esbuild/aix-ppc64@0.21.5': - optional: true - - '@esbuild/aix-ppc64@0.25.9': - optional: true - - '@esbuild/android-arm64@0.21.5': - optional: true - - '@esbuild/android-arm64@0.25.9': - optional: true - - '@esbuild/android-arm@0.21.5': - optional: true - - '@esbuild/android-arm@0.25.9': - optional: true - - '@esbuild/android-x64@0.21.5': - optional: true - - '@esbuild/android-x64@0.25.9': - optional: true - - '@esbuild/darwin-arm64@0.21.5': - optional: true - - '@esbuild/darwin-arm64@0.25.9': - optional: true - - '@esbuild/darwin-x64@0.21.5': - optional: true - - '@esbuild/darwin-x64@0.25.9': - optional: true - - '@esbuild/freebsd-arm64@0.21.5': - optional: true - - '@esbuild/freebsd-arm64@0.25.9': - optional: true - - '@esbuild/freebsd-x64@0.21.5': - optional: true - - '@esbuild/freebsd-x64@0.25.9': - optional: true - - '@esbuild/linux-arm64@0.21.5': - optional: true - - '@esbuild/linux-arm64@0.25.9': - optional: true - - '@esbuild/linux-arm@0.21.5': - optional: true - - '@esbuild/linux-arm@0.25.9': - optional: true - - '@esbuild/linux-ia32@0.21.5': - optional: true - - '@esbuild/linux-ia32@0.25.9': - optional: true - - '@esbuild/linux-loong64@0.21.5': - optional: true - - '@esbuild/linux-loong64@0.25.9': - optional: true - - '@esbuild/linux-mips64el@0.21.5': - optional: true - - '@esbuild/linux-mips64el@0.25.9': - optional: true - - '@esbuild/linux-ppc64@0.21.5': - optional: true - - '@esbuild/linux-ppc64@0.25.9': - optional: true - - '@esbuild/linux-riscv64@0.21.5': - optional: true - - '@esbuild/linux-riscv64@0.25.9': - optional: true - - '@esbuild/linux-s390x@0.21.5': - optional: true - - '@esbuild/linux-s390x@0.25.9': - optional: true - - '@esbuild/linux-x64@0.21.5': - optional: true - - '@esbuild/linux-x64@0.25.9': - optional: true - - '@esbuild/netbsd-arm64@0.25.9': - optional: true - - '@esbuild/netbsd-x64@0.21.5': - optional: true - - '@esbuild/netbsd-x64@0.25.9': - optional: true - - '@esbuild/openbsd-arm64@0.25.9': - optional: true - - '@esbuild/openbsd-x64@0.21.5': - optional: true - - '@esbuild/openbsd-x64@0.25.9': - optional: true - - '@esbuild/openharmony-arm64@0.25.9': - optional: true - - '@esbuild/sunos-x64@0.21.5': - optional: true - - '@esbuild/sunos-x64@0.25.9': - optional: true - - '@esbuild/win32-arm64@0.21.5': - optional: true - - '@esbuild/win32-arm64@0.25.9': - optional: true - - '@esbuild/win32-ia32@0.21.5': - optional: true - - '@esbuild/win32-ia32@0.25.9': - optional: true - - '@esbuild/win32-x64@0.21.5': - optional: true - - '@esbuild/win32-x64@0.25.9': - optional: true - - '@eslint-community/eslint-utils@4.7.0(eslint@9.34.0)': - dependencies: - eslint: 9.34.0 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.1': {} - - '@eslint/config-array@0.21.0': - dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.1 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.3.1': {} - - '@eslint/core@0.15.2': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.1': - dependencies: - ajv: 6.12.6 - debug: 4.4.1 - espree: 10.4.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@9.34.0': {} - - '@eslint/object-schema@2.1.6': {} - - '@eslint/plugin-kit@0.3.5': - dependencies: - '@eslint/core': 0.15.2 - levn: 0.4.1 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.6': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.3.1': {} - - '@humanwhocodes/retry@0.4.3': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@istanbuljs/schema@0.1.3': {} - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.30 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/source-map@0.3.11': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 - optional: true - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.30': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@rollup/plugin-commonjs@28.0.6(rollup@4.49.0)': - dependencies: - '@rollup/pluginutils': 5.2.0(rollup@4.49.0) - commondir: 1.0.1 - estree-walker: 2.0.2 - fdir: 6.5.0(picomatch@4.0.3) - is-reference: 1.2.1 - magic-string: 0.30.18 - picomatch: 4.0.3 - optionalDependencies: - rollup: 4.49.0 - - '@rollup/plugin-node-resolve@16.0.1(rollup@4.49.0)': - dependencies: - '@rollup/pluginutils': 5.2.0(rollup@4.49.0) - '@types/resolve': 1.20.2 - deepmerge: 4.3.1 - is-module: 1.0.0 - resolve: 1.22.10 - optionalDependencies: - rollup: 4.49.0 - - '@rollup/pluginutils@5.2.0(rollup@4.49.0)': - dependencies: - '@types/estree': 1.0.8 - estree-walker: 2.0.2 - picomatch: 4.0.3 - optionalDependencies: - rollup: 4.49.0 - - '@rollup/rollup-android-arm-eabi@4.49.0': - optional: true - - '@rollup/rollup-android-arm64@4.49.0': - optional: true - - '@rollup/rollup-darwin-arm64@4.49.0': - optional: true - - '@rollup/rollup-darwin-x64@4.49.0': - optional: true - - '@rollup/rollup-freebsd-arm64@4.49.0': - optional: true - - '@rollup/rollup-freebsd-x64@4.49.0': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.49.0': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.49.0': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.49.0': - optional: true - - '@rollup/rollup-linux-loongarch64-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.49.0': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.49.0': - optional: true - - '@rollup/rollup-linux-x64-musl@4.49.0': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.49.0': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.49.0': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.49.0': - optional: true - - '@types/estree@1.0.8': {} - - '@types/json-schema@7.0.15': {} - - '@types/node@24.3.0': - dependencies: - undici-types: 7.10.0 - - '@types/react@19.1.12': - dependencies: - csstype: 3.1.3 - - '@types/resolve@1.20.2': {} - - '@typescript-eslint/eslint-plugin@8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0)(typescript@5.9.2)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.41.0(eslint@9.34.0)(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.41.0 - '@typescript-eslint/type-utils': 8.41.0(eslint@9.34.0)(typescript@5.9.2) - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0)(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.41.0 - eslint: 9.34.0 - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.41.0(eslint@9.34.0)(typescript@5.9.2)': - dependencies: - '@typescript-eslint/scope-manager': 8.41.0 - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.41.0 - debug: 4.4.1 - eslint: 9.34.0 - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.41.0(typescript@5.9.2)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.41.0(typescript@5.9.2) - '@typescript-eslint/types': 8.41.0 - debug: 4.4.1 - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.41.0': - dependencies: - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/visitor-keys': 8.41.0 - - '@typescript-eslint/tsconfig-utils@8.41.0(typescript@5.9.2)': - dependencies: - typescript: 5.9.2 - - '@typescript-eslint/type-utils@8.41.0(eslint@9.34.0)(typescript@5.9.2)': - dependencies: - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0)(typescript@5.9.2) - debug: 4.4.1 - eslint: 9.34.0 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.41.0': {} - - '@typescript-eslint/typescript-estree@8.41.0(typescript@5.9.2)': - dependencies: - '@typescript-eslint/project-service': 8.41.0(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.41.0(typescript@5.9.2) - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/visitor-keys': 8.41.0 - debug: 4.4.1 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.41.0(eslint@9.34.0)(typescript@5.9.2)': - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0) - '@typescript-eslint/scope-manager': 8.41.0 - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) - eslint: 9.34.0 - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.41.0': - dependencies: - '@typescript-eslint/types': 8.41.0 - eslint-visitor-keys: 4.2.1 - - '@vitest/coverage-v8@2.1.9(vitest@2.1.9(@types/node@24.3.0)(terser@5.43.1))': - dependencies: - '@ampproject/remapping': 2.3.0 - '@bcoe/v8-coverage': 0.2.3 - debug: 4.4.1 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 5.0.6 - istanbul-reports: 3.2.0 - magic-string: 0.30.18 - magicast: 0.3.5 - std-env: 3.9.0 - test-exclude: 7.0.1 - tinyrainbow: 1.2.0 - vitest: 2.1.9(@types/node@24.3.0)(terser@5.43.1) - transitivePeerDependencies: - - supports-color - - '@vitest/expect@2.1.9': - dependencies: - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 - chai: 5.3.3 - tinyrainbow: 1.2.0 - - '@vitest/mocker@2.1.9(vite@5.4.19(@types/node@24.3.0)(terser@5.43.1))': - dependencies: - '@vitest/spy': 2.1.9 - estree-walker: 3.0.3 - magic-string: 0.30.18 - optionalDependencies: - vite: 5.4.19(@types/node@24.3.0)(terser@5.43.1) - - '@vitest/pretty-format@2.1.9': - dependencies: - tinyrainbow: 1.2.0 - - '@vitest/runner@2.1.9': - dependencies: - '@vitest/utils': 2.1.9 - pathe: 1.1.2 - - '@vitest/snapshot@2.1.9': - dependencies: - '@vitest/pretty-format': 2.1.9 - magic-string: 0.30.18 - pathe: 1.1.2 - - '@vitest/spy@2.1.9': - dependencies: - tinyspy: 3.0.2 - - '@vitest/utils@2.1.9': - dependencies: - '@vitest/pretty-format': 2.1.9 - loupe: 3.2.1 - tinyrainbow: 1.2.0 - - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn@8.15.0: {} - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-regex@5.0.1: {} - - ansi-regex@6.2.0: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - argparse@2.0.1: {} - - assertion-error@2.0.1: {} - - balanced-match@1.0.2: {} - - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - buffer-from@1.1.2: - optional: true - - bun-types@1.2.21(@types/react@19.1.12): - dependencies: - '@types/node': 24.3.0 - '@types/react': 19.1.12 - - cac@6.7.14: {} - - callsites@3.1.0: {} - - chai@5.3.3: - dependencies: - assertion-error: 2.0.1 - check-error: 2.1.1 - deep-eql: 5.0.2 - loupe: 3.2.1 - pathval: 2.0.1 - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - check-error@2.1.1: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - commander@2.20.3: - optional: true - - commondir@1.0.1: {} - - concat-map@0.0.1: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - csstype@3.1.3: {} - - debug@4.4.1: - dependencies: - ms: 2.1.3 - - deep-eql@5.0.2: {} - - deep-is@0.1.4: {} - - deepmerge@4.3.1: {} - - eastasianwidth@0.2.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - es-module-lexer@1.7.0: {} - - esbuild@0.21.5: - optionalDependencies: - '@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 - - esbuild@0.25.9: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.9 - '@esbuild/android-arm': 0.25.9 - '@esbuild/android-arm64': 0.25.9 - '@esbuild/android-x64': 0.25.9 - '@esbuild/darwin-arm64': 0.25.9 - '@esbuild/darwin-x64': 0.25.9 - '@esbuild/freebsd-arm64': 0.25.9 - '@esbuild/freebsd-x64': 0.25.9 - '@esbuild/linux-arm': 0.25.9 - '@esbuild/linux-arm64': 0.25.9 - '@esbuild/linux-ia32': 0.25.9 - '@esbuild/linux-loong64': 0.25.9 - '@esbuild/linux-mips64el': 0.25.9 - '@esbuild/linux-ppc64': 0.25.9 - '@esbuild/linux-riscv64': 0.25.9 - '@esbuild/linux-s390x': 0.25.9 - '@esbuild/linux-x64': 0.25.9 - '@esbuild/netbsd-arm64': 0.25.9 - '@esbuild/netbsd-x64': 0.25.9 - '@esbuild/openbsd-arm64': 0.25.9 - '@esbuild/openbsd-x64': 0.25.9 - '@esbuild/openharmony-arm64': 0.25.9 - '@esbuild/sunos-x64': 0.25.9 - '@esbuild/win32-arm64': 0.25.9 - '@esbuild/win32-ia32': 0.25.9 - '@esbuild/win32-x64': 0.25.9 - - escape-string-regexp@4.0.0: {} - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint@9.34.0: - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.3.1 - '@eslint/core': 0.15.2 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.34.0 - '@eslint/plugin-kit': 0.3.5 - '@humanfs/node': 0.16.6 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.1 - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - transitivePeerDependencies: - - supports-color - - espree@10.4.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 4.2.1 - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - estree-walker@2.0.2: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.8 - - esutils@2.0.3: {} - - expect-type@1.2.2: {} - - fast-deep-equal@3.1.3: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fastq@1.19.1: - dependencies: - reusify: 1.1.0 - - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - - flatted@3.3.3: {} - - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob@10.4.5: - dependencies: - foreground-child: 3.3.1 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - - globals@14.0.0: {} - - graphemer@1.4.0: {} - - has-flag@4.0.0: {} - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - html-escaper@2.0.2: {} - - ignore@5.3.2: {} - - ignore@7.0.5: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-module@1.0.0: {} - - is-number@7.0.0: {} - - is-reference@1.2.1: - dependencies: - '@types/estree': 1.0.8 - - isexe@2.0.0: {} - - istanbul-lib-coverage@3.2.2: {} - - istanbul-lib-report@3.0.1: - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - - istanbul-lib-source-maps@5.0.6: - dependencies: - '@jridgewell/trace-mapping': 0.3.30 - debug: 4.4.1 - istanbul-lib-coverage: 3.2.2 - transitivePeerDependencies: - - supports-color - - istanbul-reports@3.2.0: - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - json-buffer@3.0.1: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.merge@4.6.2: {} - - loupe@3.2.1: {} - - lru-cache@10.4.3: {} - - magic-string@0.30.18: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - magicast@0.3.5: - dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 - source-map-js: 1.2.1 - - make-dir@4.0.0: - dependencies: - semver: 7.7.2 - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.12 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - - minipass@7.1.2: {} - - ms@2.1.3: {} - - nanoid@3.3.11: {} - - natural-compare@1.4.0: {} - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - package-json-from-dist@1.0.1: {} - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - path-exists@4.0.0: {} - - path-key@3.1.1: {} - - path-parse@1.0.7: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - - pathe@1.1.2: {} - - pathval@2.0.1: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.3: {} - - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - prelude-ls@1.2.1: {} - - punycode@2.3.1: {} - - queue-microtask@1.2.3: {} - - resolve-from@4.0.0: {} - - resolve@1.22.10: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - reusify@1.1.0: {} - - rollup@4.49.0: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.49.0 - '@rollup/rollup-android-arm64': 4.49.0 - '@rollup/rollup-darwin-arm64': 4.49.0 - '@rollup/rollup-darwin-x64': 4.49.0 - '@rollup/rollup-freebsd-arm64': 4.49.0 - '@rollup/rollup-freebsd-x64': 4.49.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.49.0 - '@rollup/rollup-linux-arm-musleabihf': 4.49.0 - '@rollup/rollup-linux-arm64-gnu': 4.49.0 - '@rollup/rollup-linux-arm64-musl': 4.49.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.49.0 - '@rollup/rollup-linux-ppc64-gnu': 4.49.0 - '@rollup/rollup-linux-riscv64-gnu': 4.49.0 - '@rollup/rollup-linux-riscv64-musl': 4.49.0 - '@rollup/rollup-linux-s390x-gnu': 4.49.0 - '@rollup/rollup-linux-x64-gnu': 4.49.0 - '@rollup/rollup-linux-x64-musl': 4.49.0 - '@rollup/rollup-win32-arm64-msvc': 4.49.0 - '@rollup/rollup-win32-ia32-msvc': 4.49.0 - '@rollup/rollup-win32-x64-msvc': 4.49.0 - fsevents: 2.3.3 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - semver@7.7.2: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - siginfo@2.0.0: {} - - signal-exit@4.1.0: {} - - source-map-js@1.2.1: {} - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - optional: true - - source-map@0.6.1: - optional: true - - stackback@0.0.2: {} - - std-env@3.9.0: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.2.0 - - strip-json-comments@3.1.1: {} - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - terser@5.43.1: - dependencies: - '@jridgewell/source-map': 0.3.11 - acorn: 8.15.0 - commander: 2.20.3 - source-map-support: 0.5.21 - optional: true - - test-exclude@7.0.1: - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 10.4.5 - minimatch: 9.0.5 - - tinybench@2.9.0: {} - - tinyexec@0.3.2: {} - - tinyglobby@0.2.14: - dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - tinypool@1.1.1: {} - - tinyrainbow@1.2.0: {} - - tinyspy@3.0.2: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - ts-api-utils@2.1.0(typescript@5.9.2): - dependencies: - typescript: 5.9.2 - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - typescript@5.9.2: {} - - undici-types@7.10.0: {} - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - vite-node@2.1.9(@types/node@24.3.0)(terser@5.43.1): - dependencies: - cac: 6.7.14 - debug: 4.4.1 - es-module-lexer: 1.7.0 - pathe: 1.1.2 - vite: 5.4.19(@types/node@24.3.0)(terser@5.43.1) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - vite@5.4.19(@types/node@24.3.0)(terser@5.43.1): - dependencies: - esbuild: 0.21.5 - postcss: 8.5.6 - rollup: 4.49.0 - optionalDependencies: - '@types/node': 24.3.0 - fsevents: 2.3.3 - terser: 5.43.1 - - vite@7.1.3(@types/node@24.3.0)(terser@5.43.1): - dependencies: - esbuild: 0.25.9 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.49.0 - tinyglobby: 0.2.14 - optionalDependencies: - '@types/node': 24.3.0 - fsevents: 2.3.3 - terser: 5.43.1 - - vitest@2.1.9(@types/node@24.3.0)(terser@5.43.1): - dependencies: - '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.19(@types/node@24.3.0)(terser@5.43.1)) - '@vitest/pretty-format': 2.1.9 - '@vitest/runner': 2.1.9 - '@vitest/snapshot': 2.1.9 - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 - chai: 5.3.3 - debug: 4.4.1 - expect-type: 1.2.2 - magic-string: 0.30.18 - pathe: 1.1.2 - std-env: 3.9.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinypool: 1.1.1 - tinyrainbow: 1.2.0 - vite: 5.4.19(@types/node@24.3.0)(terser@5.43.1) - vite-node: 2.1.9(@types/node@24.3.0)(terser@5.43.1) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 24.3.0 - transitivePeerDependencies: - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - - word-wrap@1.2.5: {} - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - yocto-queue@0.1.0: {} diff --git a/scripts/clean-dist.js b/scripts/clean-dist.js deleted file mode 100644 index 1a44aef..0000000 --- a/scripts/clean-dist.js +++ /dev/null @@ -1,28 +0,0 @@ -/* global console */ - -import fs from 'fs'; -import path from 'path'; -import { fileURLToPath } from 'url'; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); - -const distPath = path.resolve(__dirname, '../dist'); - -// Clean dist directory -if (fs.existsSync(distPath)) { - const files = fs.readdirSync(distPath); - files.forEach(file => { - const filePath = path.join(distPath, file); - const stat = fs.statSync(filePath); - if (stat.isDirectory()) { - fs.rmSync(filePath, { recursive: true, force: true }); - } else { - fs.unlinkSync(filePath); - } - }); - console.log('✅ Cleaned dist directory'); -} else { - fs.mkdirSync(distPath, { recursive: true }); - console.log('✅ Created dist directory'); -} diff --git a/scripts/generate-cjs-types.js b/scripts/generate-cjs-types.js deleted file mode 100644 index 5320e5d..0000000 --- a/scripts/generate-cjs-types.js +++ /dev/null @@ -1,25 +0,0 @@ -/* global console, process, __dirname, require */ - -const fs = require('fs'); -const path = require('path'); - -// Read the main types file -const mainTypesPath = path.resolve(__dirname, '../dist/index.d.ts'); -const cjsTypesPath = path.resolve(__dirname, '../dist/index.cjs.d.ts'); - -if (fs.existsSync(mainTypesPath)) { - const mainTypes = fs.readFileSync(mainTypesPath, 'utf8'); - - // Convert ESM export to CommonJS export - const cjsTypes = mainTypes.replace( - 'export default classigo;', - 'export = classigo;' - ); - - // Write the CJS types file - fs.writeFileSync(cjsTypesPath, cjsTypes); - console.log('✅ Generated CJS types file'); -} else { - console.error('❌ Main types file not found'); - process.exit(1); -} diff --git a/src/index.ts b/src/index.ts index a67aa47..f284bb5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,54 +1,40 @@ - - -/** - * Appends a class to an existing class string - * @param value - The existing class string - * @param newClass - The new class to append - * @returns The combined class string - */ -function appendClass(value: string, newClass: string): string { - return !newClass ? value : value ? (value + ' ' + newClass) : newClass; -} +import type { ClassObject, ClassValue } from "./types.ts"; /** - * Ultra-optimized class name utility for CSS Modules - * * Combines class names efficiently, filtering out falsy values. - * Perfect for conditional classes and CSS Modules integration. - * - * @param classes - Variable number of class names or falsy values - * @returns Combined class names separated by spaces + * Accepts strings, falsy values, and objects (`{ [className]: boolean }`). * * @example - * ```typescript - * // Basic usage - * classigo('button', 'button--primary', 'button--large') - * // → "button button--primary button--large" + * ```ts + * // Strings + * classigo("btn", "btn--primary", isLarge && "btn--lg") + * // → "btn btn--primary btn--lg" * - * // With conditions (prefer && over ternary) - * classigo('button', 'button--primary', isLarge && 'button--large') - * // → "button button--primary" (if isLarge is false) - * // → "button button--primary button--large" (if isLarge is true) + * // Objects + * classigo("btn", { "btn--active": isActive, "btn--disabled": !isEnabled }) + * // → "btn btn--active" * - * // With template literals - * classigo('button', `button--${variant}`, isLarge && 'button--large') - * // → "button button--primary button--large" (if variant = 'primary') - * - * // With CSS Modules - * classigo(styles.button, styles['button--primary'], isLarge && styles['button--large']) + * // Mixed + * classigo("btn", isLarge && "btn--lg", { "btn--active": isActive }) + * // → "btn btn--lg btn--active" * ``` - * - * @tip Use `&&` instead of ternary operators for better performance - * @tip Template literals work perfectly with classigo */ -function classigo(...classes: (string | undefined | null | false)[]): string { - let result = ''; - +export function classigo(...classes: ClassValue[]): string { + let result = ""; for (let i = 0; i < classes.length; i++) { const cls = classes[i]; - result = cls ? appendClass(result, cls) : result; + if (!cls) continue; + if (typeof cls !== "string") { + for (const key in cls as ClassObject) { + if ((cls as ClassObject)[key]) + result = result ? result + " " + key : key; + } + continue; + } + result = result ? result + " " + cls : cls; } return result; } export default classigo; +export type { ClassValue, ClassObject } from "./types.ts"; diff --git a/src/lite.ts b/src/lite.ts new file mode 100644 index 0000000..a3d10e2 --- /dev/null +++ b/src/lite.ts @@ -0,0 +1,12 @@ +export type ClassLiteValue = string | false | null | undefined; + +export function classigo(...classes: ClassLiteValue[]): string { + let result = ""; + for (let i = 0; i < classes.length; i++) { + const cls = classes[i]; + if (cls) result = result ? result + " " + cls : cls; + } + return result; +} + +export default classigo; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..a5915ef --- /dev/null +++ b/src/types.ts @@ -0,0 +1,2 @@ +export type ClassObject = Record; +export type ClassValue = string | false | null | undefined | ClassObject; diff --git a/tests/classigo.test.ts b/tests/classigo.test.ts deleted file mode 100644 index 5a502f0..0000000 --- a/tests/classigo.test.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { describe, it, expect } from 'vitest'; -import classigo from '../src/index'; - -// Need more implementations and tests -// To be sure that classigo is working correctly -// But for now, this is a good start - -describe('classigo', () => { - it('should combine basic classes', () => { - expect(classigo('button', 'primary', 'large')).toBe('button primary large'); - }); - - it('should handle empty strings', () => { - expect(classigo('button', '', 'large')).toBe('button large'); - }); - - it('should handle falsy values', () => { - expect(classigo('button', false, 'large')).toBe('button large'); - expect(classigo('button', null, 'large')).toBe('button large'); - expect(classigo('button', undefined, 'large')).toBe('button large'); - }); - - it('should handle conditional classes', () => { - const isActive = true; - const isDisabled = false; - - expect(classigo('button', isActive && 'active', isDisabled && 'disabled')) - .toBe('button active'); - }); - - it('should handle template literals', () => { - const variant = 'primary'; - expect(classigo('button', `button--${variant}`)).toBe('button button--primary'); - }); - - it('should handle CSS Modules', () => { - const styles = { - button: 'button_abc123', - primary: 'primary_def456', - large: 'large_ghi789' - }; - - expect(classigo(styles.button, styles.primary, styles.large)) - .toBe('button_abc123 primary_def456 large_ghi789'); - }); - - it('should handle mixed types', () => { - expect(classigo('button', 'primary', false, 'large', null, 'rounded')) - .toBe('button primary large rounded'); - }); - - it('should return empty string for all falsy values', () => { - expect(classigo(false, null, undefined, '')).toBe(''); - }); - - it('should handle single class', () => { - expect(classigo('button')).toBe('button'); - }); - - it('should handle no arguments', () => { - expect(classigo()).toBe(''); - }); -}); diff --git a/tests/runtime.test.ts b/tests/runtime.test.ts new file mode 100644 index 0000000..386df2f --- /dev/null +++ b/tests/runtime.test.ts @@ -0,0 +1,99 @@ +import { describe, it, expect } from "bun:test"; +import classigo from "../src/index.ts"; + +describe("strings", () => { + it("combines basic classes", () => { + expect(classigo("btn", "btn--primary", "btn--lg")).toBe( + "btn btn--primary btn--lg", + ); + }); + + it("handles a single class", () => { + expect(classigo("btn")).toBe("btn"); + }); + + it("handles no arguments", () => { + expect(classigo()).toBe(""); + }); + + it("filters empty strings", () => { + expect(classigo("btn", "", "btn--lg")).toBe("btn btn--lg"); + }); + + it("filters falsy values", () => { + expect(classigo("btn", false, null, undefined, "btn--primary")).toBe( + "btn btn--primary", + ); + }); + + it("returns empty string for all falsy", () => { + expect(classigo(false, null, undefined, "")).toBe(""); + }); + + it("handles conditional with &&", () => { + expect( + classigo("btn", true && "btn--active", false && "btn--disabled"), + ).toBe("btn btn--active"); + }); + + it("handles template literals", () => { + const variant = "primary"; + expect(classigo("btn", `btn--${variant}`)).toBe("btn btn--primary"); + }); +}); + +describe("objects", () => { + it("includes keys with truthy values", () => { + expect(classigo({ "btn--active": true, "btn--disabled": false })).toBe( + "btn--active", + ); + }); + + it("excludes keys with falsy values", () => { + expect(classigo({ a: false, b: null, c: undefined, d: true })).toBe("d"); + }); + + it("returns empty string for all falsy object values", () => { + expect(classigo({ a: false, b: null })).toBe(""); + }); + + it("handles empty object", () => { + expect(classigo({})).toBe(""); + }); +}); + +describe("mixed", () => { + it("combines strings and objects", () => { + expect( + classigo("btn", { "btn--active": true, "btn--disabled": false }), + ).toBe("btn btn--active"); + }); + + it("handles falsy between strings and objects", () => { + expect( + classigo("btn", null, { "btn--active": true }, false, "btn--lg"), + ).toBe("btn btn--active btn--lg"); + }); + + it("CSS Modules pattern — resolved hashes as strings", () => { + const styles = { button: "button_abc123", primary: "primary_def456" }; + expect(classigo(styles.button, styles.primary)).toBe( + "button_abc123 primary_def456", + ); + }); + + it("CSS Modules pattern — object shorthand", () => { + const styles = { + button: "btn_x1", + active: "active_y2", + disabled: "disabled_z3", + }; + const isActive = true; + expect( + classigo(styles.button, { + [styles.active]: isActive, + [styles.disabled]: !isActive, + }), + ).toBe("btn_x1 active_y2"); + }); +}); diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 0000000..07d3ffb --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": false, + "emitDeclarationOnly": true, + "outDir": "./dist", + "rootDir": "./src", + "declaration": true, + "declarationMap": true, + "allowImportingTsExtensions": false, + "rewriteRelativeImportExtensions": true + }, + "include": ["src/**/*"], + "exclude": ["tests", "bench", "dist", "node_modules"] +} diff --git a/tsconfig.json b/tsconfig.json index 4178421..ade8efc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,32 +1,15 @@ { "compilerOptions": { - "target": "ES2020", - "module": "ESNext", - "moduleResolution": "node", - "declaration": true, - "declarationMap": true, - "outDir": "./dist", - "rootDir": "./src", + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", "strict": true, - "esModuleInterop": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "noEmit": true, "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": false, - "removeComments": false, - "sourceMap": true, - "exactOptionalPropertyTypes": true + "allowImportingTsExtensions": true, + "types": ["bun"] }, - "include": [ - "src/**/*" - ], - "exclude": [ - "examples", - "node_modules", - "dist", - "demo", - "**/*.test.ts", - "**/*.spec.ts" - ] + "include": ["src/**/*", "tests/**/*", "bench/**/*"] } diff --git a/vite.config.js b/vite.config.js deleted file mode 100644 index 2704823..0000000 --- a/vite.config.js +++ /dev/null @@ -1,76 +0,0 @@ -import { defineConfig } from "vite"; -import { resolve } from "path"; - -export default defineConfig({ - build: { - lib: { - entry: resolve(__dirname, "src/index.ts"), - name: "classigo", - formats: ["es", "cjs", "umd"], - fileName: (format) => - `index.${ - format === "es" ? "mjs" : format === "cjs" ? "cjs" : "umd.js" - }`, - }, - minify: "esbuild", - rollupOptions: { - external: [], - output: { - globals: {}, - compact: true - }, - }, - }, - plugins: [ - { - name: 'generate-unminified-cjs', - writeBundle(_, bundle) { - if (bundle['index.cjs']) { - const fs = require('fs'); - const path = require('path'); - const { execSync } = require('child_process'); - - try { - // Compile TypeScript to JavaScript (non-minified) - execSync('npx tsc src/index.ts --outDir dist --target es2020 --module commonjs --declaration false --sourceMap false --skipLibCheck true', { stdio: 'inherit' }); - - // Read the compiled JS file - const compiledPath = path.resolve(__dirname, 'dist/index.js'); - if (fs.existsSync(compiledPath)) { - const compiledCode = fs.readFileSync(compiledPath, 'utf8'); - - // Convert exports.default to module.exports - const cjsCode = compiledCode - .replace(/exports\.default = classigo;/, 'module.exports = classigo;') - .replace(/Object\.defineProperty\(exports, "__esModule", \{ value: true \}\);/, ''); - - // Write as dev version - const devPath = path.resolve(__dirname, 'dist/index.cjs.dev.js'); - fs.writeFileSync(devPath, cjsCode); - - // Clean up the temporary file - fs.unlinkSync(compiledPath); - } - } catch (error) { - console.error('Failed to generate unminified CJS:', error.message); - } - } - } - }, - { - name: 'force-single-line', - writeBundle(_, bundle) { - const fs = require('fs'); - const path = require('path'); - - // Force single line for ESM - if (bundle['index.mjs']) { - const mjsPath = path.resolve(__dirname, 'dist/index.mjs'); - const content = fs.readFileSync(mjsPath, 'utf8'); - const singleLine = content.replace(/\n/g, '').replace(/\s+/g, ' ').trim(); - fs.writeFileSync(mjsPath, singleLine); - } - } - } - ] -}); diff --git a/vite.config.prod.js b/vite.config.prod.js deleted file mode 100644 index e1867da..0000000 --- a/vite.config.prod.js +++ /dev/null @@ -1,41 +0,0 @@ -import { defineConfig } from "vite"; -import { resolve } from "path"; - -export default defineConfig({ - build: { - lib: { - entry: resolve(__dirname, "src/index.ts"), - name: "classigo", - formats: ["es", "cjs", "umd"], - fileName: (format) => - `index.${ - format === "es" ? "mjs" : format === "cjs" ? "cjs" : "umd.js" - }`, - }, - minify: "esbuild", - rollupOptions: { - external: [], - output: { - globals: {}, - compact: true - }, - }, - }, - plugins: [ - { - name: 'force-single-line', - async writeBundle(_, bundle) { - const fs = await import('fs'); - const path = await import('path'); - - // Force single line for ESM - if (bundle['index.mjs']) { - const mjsPath = path.resolve(__dirname, 'dist/index.mjs'); - const content = fs.readFileSync(mjsPath, 'utf8'); - const singleLine = content.replace(/\n/g, '').replace(/\s+/g, ' ').trim(); - fs.writeFileSync(mjsPath, singleLine); - } - } - } - ] -}); diff --git a/vitest.config.ts b/vitest.config.ts deleted file mode 100644 index 74e533f..0000000 --- a/vitest.config.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - globals: true, - environment: 'node', - coverage: { - provider: 'v8', - reporter: ['text', 'json', 'html'], - exclude: [ - 'node_modules/', - 'dist/', - 'bench/', - 'scripts/', - '**/*.d.ts', - ], - }, - }, -});