소스 검색

remove frontend assets

Daniel Bohry 1 주 전
부모
커밋
40b2adb7f1

+ 1 - 243
.github/workflows/buildAndRelease.yml

@@ -65,246 +65,4 @@ jobs:
       - name: Build and Push Image
         run: |
           docker buildx create --use
-          docker buildx build --platform linux/amd64,linux/arm64 -t lhamacorp/knotes:latest --push .
-
-  # Disabled desktop release jobs
-  # create-desktop-release:
-  #   name: Create Desktop Release
-  #   needs: dockerize
-  #   runs-on: ubuntu-latest
-  #   outputs:
-  #     release-tag: ${{ steps.get-version.outputs.tag }}
-  #     release-version: ${{ steps.get-version.outputs.version }}
-  #   steps:
-  #     - uses: actions/checkout@v4
-
-  #     - name: Get version from package.json
-  #       id: get-version
-  #       run: |
-  #         VERSION=$(node -p "require('./desktop-app/package.json').version")
-  #         TIMESTAMP=$(date +%Y%m%d-%H%M%S)
-  #         TAG="v${VERSION}-${TIMESTAMP}"
-  #         echo "version=${VERSION}" >> $GITHUB_OUTPUT
-  #         echo "tag=${TAG}" >> $GITHUB_OUTPUT
-
-  #     - name: Create Desktop App Release
-  #       id: create-release
-  #       env:
-  #         GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-  #       run: |
-  #         TAG="${{ steps.get-version.outputs.tag }}"
-  #         VERSION="${{ steps.get-version.outputs.version }}"
-
-  #         # Create release notes
-  #         cat > release-notes.md << 'EOF'
-  #         ## 🚀 kNotes Release - Docker + Desktop Apps
-
-  #         This release includes both the deployed web application and desktop apps for all platforms.
-
-  #         ### 🐳 Docker Deployment:
-  #         - **Image**: `lhamacorp/knotes:latest`
-  #         - **Platforms**: linux/amd64, linux/arm64
-  #         - **Deployed to**: https://notes.lhamacorp.com
-
-  #         ### 📱 Desktop Apps:
-  #         - **Windows**: Download the `.exe` installer
-  #         - **macOS**: Download the `.dmg` installer
-  #         - **Linux**: Download the `.AppImage` file
-
-  #         ### ✨ What's New:
-  #         - Latest frontend updates from the web application
-  #         - Automatic synchronization with deployed API
-  #         - Bug fixes and improvements
-  #         - Auto-update functionality for desktop apps
-
-  #         ### 📦 Installation:
-  #         1. Download the appropriate desktop app for your operating system
-  #         2. Install/run the application
-  #         3. The app connects to the deployed API and will check for future updates automatically
-
-  #         **Built from commit**: ${{ github.sha }}
-  #         **Docker image**: `docker pull lhamacorp/knotes:latest`
-  #         EOF
-
-  #         # Create release using GitHub CLI
-  #         gh release create "$TAG" \
-  #           --title "kNotes Desktop v${VERSION}" \
-  #           --notes-file release-notes.md \
-  #           --latest || {
-  #           echo "Release already exists, updating it..."
-  #           gh release edit "$TAG" \
-  #             --title "kNotes Desktop v${VERSION}" \
-  #             --notes-file release-notes.md \
-  #             --latest
-  #         }
-
-  # build-linux-desktop:
-  #   name: Build Linux Desktop
-  #   needs: create-desktop-release
-  #   runs-on: ubuntu-latest
-  #   steps:
-  #     - uses: actions/checkout@v4
-
-  #     - name: Setup Node.js
-  #       uses: actions/setup-node@v4
-  #       with:
-  #         node-version: '18'
-  #         cache: 'npm'
-  #         cache-dependency-path: desktop-app/package-lock.json
-
-  #     - name: Copy frontend files
-  #       run: |
-  #         cp -r src/main/resources/static/* desktop-app/
-
-  #     - name: Install dependencies
-  #       run: |
-  #         cd desktop-app
-  #         npm ci
-
-  #     - name: Build Linux Desktop App
-  #       run: |
-  #         cd desktop-app
-  #         npm run build-linux
-
-  #     - name: Debug Build Output
-  #       run: |
-  #         cd desktop-app
-  #         echo "=== Build Output ==="
-  #         ls -la dist/ || echo "No dist directory"
-  #         echo "=== End Build Output ==="
-
-  #     - name: Upload Linux Build to Release
-  #       env:
-  #         GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-  #       run: |
-  #         cd desktop-app
-  #         TAG="${{ needs.create-desktop-release.outputs.release-tag }}"
-  #         echo "Uploading to release: $TAG"
-
-  #         # Check if AppImage exists
-  #         if ls dist/kNotes-*.AppImage 1> /dev/null 2>&1; then
-  #           echo "Found AppImage files:"
-  #           ls -la dist/kNotes-*.AppImage
-  #           gh release upload "$TAG" dist/kNotes-*.AppImage --clobber
-  #         else
-  #           echo "No AppImage files found"
-  #         fi
-
-  #         # Upload additional files if they exist
-  #         if [ -f "dist/latest-linux.yml" ]; then
-  #           gh release upload "$TAG" dist/latest-linux.yml --clobber
-  #         fi
-
-  # build-windows-desktop:
-  #   name: Build Windows Desktop
-  #   needs: create-desktop-release
-  #   runs-on: windows-latest
-  #   steps:
-  #     - uses: actions/checkout@v4
-
-  #     - name: Setup Node.js
-  #       uses: actions/setup-node@v4
-  #       with:
-  #         node-version: '18'
-  #         cache: 'npm'
-  #         cache-dependency-path: desktop-app/package-lock.json
-
-  #     - name: Copy frontend files
-  #       run: |
-  #         xcopy "src\main\resources\static\*" "desktop-app\" /E /I /Y
-
-  #     - name: Install dependencies
-  #       run: |
-  #         cd desktop-app
-  #         npm ci
-
-  #     - name: Build Windows Desktop App
-  #       run: |
-  #         cd desktop-app
-  #         npm run build-win
-
-  #     - name: Debug Windows Build Output
-  #       run: |
-  #         cd desktop-app
-  #         echo "=== Windows Build Output ==="
-  #         ls -la dist/ || echo "No dist directory"
-  #         echo "=== End Windows Build Output ==="
-
-  #     - name: Upload Windows Build to Release
-  #       env:
-  #         GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-  #       run: |
-  #         cd desktop-app
-  #         TAG="${{ needs.create-desktop-release.outputs.release-tag }}"
-  #         echo "Uploading to release: $TAG"
-
-  #         # Check if EXE exists
-  #         if ls dist/*.exe 1> /dev/null 2>&1; then
-  #           echo "Found Windows installer files:"
-  #           ls -la dist/*.exe
-  #           gh release upload "$TAG" dist/*.exe --clobber
-  #         else
-  #           echo "No Windows installer files found"
-  #         fi
-
-  #         # Upload additional files if they exist
-  #         if [ -f "dist/latest.yml" ]; then
-  #           gh release upload "$TAG" dist/latest.yml --clobber
-  #         fi
-
-  # build-macos-desktop:
-  #   name: Build macOS Desktop
-  #   needs: create-desktop-release
-  #   runs-on: macos-latest
-  #   steps:
-  #     - uses: actions/checkout@v4
-
-  #     - name: Setup Node.js
-  #       uses: actions/setup-node@v4
-  #       with:
-  #         node-version: '18'
-  #         cache: 'npm'
-  #         cache-dependency-path: desktop-app/package-lock.json
-
-  #     - name: Copy frontend files
-  #       run: |
-  #         cp -r src/main/resources/static/* desktop-app/
-
-  #     - name: Install dependencies
-  #       run: |
-  #         cd desktop-app
-  #         npm ci
-
-  #     - name: Build macOS Desktop App
-  #       run: |
-  #         cd desktop-app
-  #         npm run build-mac
-
-  #     - name: Debug macOS Build Output
-  #       run: |
-  #         cd desktop-app
-  #         echo "=== macOS Build Output ==="
-  #         ls -la dist/ || echo "No dist directory"
-  #         echo "=== End macOS Build Output ==="
-
-  #     - name: Upload macOS Build to Release
-  #       env:
-  #         GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-  #       run: |
-  #         cd desktop-app
-  #         TAG="${{ needs.create-desktop-release.outputs.release-tag }}"
-  #         echo "Uploading to release: $TAG"
-
-  #         # Check if DMG exists
-  #         if ls dist/*.dmg 1> /dev/null 2>&1; then
-  #           echo "Found macOS installer files:"
-  #           ls -la dist/*.dmg
-  #           gh release upload "$TAG" dist/*.dmg --clobber
-  #         else
-  #           echo "No macOS installer files found"
-  #         fi
-
-  #         # Upload additional files if they exist
-  #         if [ -f "dist/latest-mac.yml" ]; then
-  #           gh release upload "$TAG" dist/latest-mac.yml --clobber
-  #         fi
+          docker buildx build --platform linux/amd64,linux/arm64 -t lhamacorp/knotes-be:latest --push .

+ 0 - 198
.github/workflows/test-workflow.yml

@@ -1,198 +0,0 @@
-name: Test Workflow (Dry Run)
-
-on:
-  workflow_dispatch:  # Manual trigger only
-    inputs:
-      test_level:
-        description: 'Test level (basic/full)'
-        required: false
-        default: 'basic'
-        type: choice
-        options:
-          - basic
-          - full
-
-jobs:
-  test-build:
-    name: Test Java Build
-    runs-on: ubuntu-latest
-
-    services:
-      mongodb:
-        image: mongo:7.0
-        options: >-
-          --health-cmd "mongosh --quiet --eval 'db.runCommand({ping: 1})'"
-          --health-interval 10s
-          --health-timeout 5s
-          --health-retries 5
-        ports:
-          - 27017:27017
-
-    env:
-      mongo: mongodb://localhost:27017
-      database: knotes-test
-
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Set up JDK
-        uses: actions/setup-java@v4
-        with:
-          java-version: '25'
-          distribution: 'temurin'
-
-      - name: Test Build (Dry Run)
-        run: |
-          echo "✅ Would run: chmod +x ./gradlew && ./gradlew clean build test"
-          echo "✅ Java build test passed"
-
-  test-docker:
-    name: Test Docker Build
-    needs: test-build
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Set up JDK
-        uses: actions/setup-java@v4
-        with:
-          java-version: '25'
-          distribution: 'temurin'
-
-      - name: Test Docker Build (Dry Run)
-        run: |
-          echo "✅ Would build application JAR"
-          echo "✅ Would run: docker buildx build --platform linux/amd64,linux/arm64 -t lhamacorp/knotes:latest"
-          echo "✅ Would push to Docker Hub (SKIPPED IN TEST)"
-          echo "🐳 Docker build test passed"
-
-  test-release:
-    name: Test Release Creation
-    needs: test-docker
-    runs-on: ubuntu-latest
-    outputs:
-      test-tag: ${{ steps.version.outputs.tag }}
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Test Version Generation
-        id: version
-        run: |
-          VERSION=$(node -p "require('./desktop-app/package.json').version")
-          TIMESTAMP=$(date +%Y%m%d-%H%M%S)
-          TAG="test-v${VERSION}-${TIMESTAMP}"
-          echo "version=${VERSION}" >> $GITHUB_OUTPUT
-          echo "tag=${TAG}" >> $GITHUB_OUTPUT
-          echo "✅ Would create release with tag: ${TAG}"
-          echo "✅ Would create release with version: ${VERSION}"
-
-      - name: Test Release Creation (Dry Run)
-        run: |
-          echo "✅ Would create GitHub release using GitHub CLI with:"
-          echo "   📋 Tag: ${{ steps.version.outputs.tag }}"
-          echo "   📋 Title: kNotes Desktop v${{ steps.version.outputs.version }}"
-          echo "   📋 Command: gh release create ${{ steps.version.outputs.tag }}"
-          echo "   📋 Docker deployment info included"
-          echo "   📋 Desktop app download links ready"
-          echo "🚀 Release creation test passed (GitHub CLI method)"
-
-  test-desktop-linux:
-    name: Test Linux Desktop Build
-    needs: test-release
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Setup Node.js
-        uses: actions/setup-node@v4
-        with:
-          node-version: '18'
-          cache: 'npm'
-          cache-dependency-path: desktop-app/package-lock.json
-
-      - name: Test Frontend Copy
-        run: |
-          echo "✅ Would copy: src/main/resources/static/* to desktop-app/"
-          ls -la src/main/resources/static/ || echo "Frontend files found"
-          echo "📁 Frontend copy test passed"
-
-      - name: Test Dependencies Installation
-        run: |
-          cd desktop-app
-          echo "✅ Would run: npm ci"
-          echo "✅ Current package.json version: $(node -p "require('./package.json').version")"
-          echo "📦 Dependencies test passed"
-
-      - name: Test Linux Build (Dry Run)
-        if: ${{ github.event.inputs.test_level == 'full' }}
-        run: |
-          cd desktop-app
-          echo "✅ Would run: npm run build-linux"
-          echo "✅ Would create: kNotes-X.X.X.AppImage"
-          echo "✅ Would run: gh release upload TAG dist/kNotes-*.AppImage"
-          echo "🐧 Linux build test passed (separate build + upload)"
-
-  test-desktop-windows:
-    name: Test Windows Desktop Build
-    needs: test-release
-    runs-on: windows-latest
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Setup Node.js
-        uses: actions/setup-node@v4
-        with:
-          node-version: '18'
-          cache: 'npm'
-          cache-dependency-path: desktop-app/package-lock.json
-
-      - name: Test Windows Build (Dry Run)
-        run: |
-          echo "✅ Would copy: src\main\resources\static\* to desktop-app\"
-          echo "✅ Would run: npm ci"
-          echo "✅ Would run: npm run build-win"
-          echo "✅ Would create: kNotes Setup X.X.X.exe"
-          echo "✅ Would run: gh release upload TAG dist/*.exe"
-          echo "🪟 Windows build test passed (separate build + upload)"
-
-  test-desktop-macos:
-    name: Test macOS Desktop Build
-    needs: test-release
-    runs-on: macos-latest
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Setup Node.js
-        uses: actions/setup-node@v4
-        with:
-          node-version: '18'
-          cache: 'npm'
-          cache-dependency-path: desktop-app/package-lock.json
-
-      - name: Test macOS Build (Dry Run)
-        run: |
-          echo "✅ Would copy: src/main/resources/static/* to desktop-app/"
-          echo "✅ Would run: npm ci"
-          echo "✅ Would run: npm run build-mac"
-          echo "✅ Would create: kNotes-X.X.X.dmg"
-          echo "✅ Would run: gh release upload TAG dist/*.dmg"
-          echo "🍎 macOS build test passed (separate build + upload)"
-
-  test-summary:
-    name: Test Summary
-    needs: [test-desktop-linux, test-desktop-windows, test-desktop-macos]
-    runs-on: ubuntu-latest
-    steps:
-      - name: Test Results
-        run: |
-          echo "🎉 WORKFLOW TEST COMPLETE!"
-          echo ""
-          echo "✅ Java Build Test: PASSED"
-          echo "✅ Docker Build Test: PASSED"
-          echo "✅ Release Creation Test: PASSED"
-          echo "✅ Linux Desktop Test: PASSED"
-          echo "✅ Windows Desktop Test: PASSED"
-          echo "✅ macOS Desktop Test: PASSED"
-          echo ""
-          echo "🚀 Your unified workflow is ready!"
-          echo "🔥 Next step: Push to main branch to trigger real deployment"

+ 0 - 40
desktop-app/.gitignore

@@ -1,40 +0,0 @@
-# Dependencies
-node_modules/
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-
-# Build output
-dist/
-build/
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Environment files
-.env
-.env.local
-.env.development.local
-.env.test.local
-.env.production.local
-
-# IDE files
-.vscode/
-.idea/
-*.swp
-*.swo
-
-# OS generated files
-.DS_Store
-.DS_Store?
-._*
-.Spotlight-V100
-.Trashes
-ehthumbs.db
-Thumbs.db
-
-# Electron specific
-/dist_electron/

+ 0 - 48
desktop-app/404.html

@@ -1,48 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-    <meta name="theme-color" content="#2d2d2d">
-    <meta name="apple-mobile-web-app-capable" content="yes">
-    <meta name="apple-mobile-web-app-status-bar-style" content="default">
-    <meta name="apple-mobile-web-app-title" content="kNotes">
-    <meta name="mobile-web-app-capable" content="yes">
-    <meta name="application-name" content="kNotes">
-    <title>Page Not Found - kNotes</title>
-    <link rel="stylesheet" href="css/style.css">
-    <link rel="icon" type="image/x-icon" href="img/favicon.ico">
-</head>
-<body>
-<div id="headerContainer"></div>
-
-<div class="content">
-    <div class="error-content">
-        <div class="error-icon">📄</div>
-        <h1 class="error-title">Page Not Found</h1>
-        <p class="error-message">
-            The page you're looking for doesn't exist. It might have been moved, deleted,
-            or you entered the wrong URL.
-        </p>
-        <div class="error-actions">
-            <button class="dialog-btn primary" onclick="navigateToPage('home.html')">
-                Go Home
-            </button>
-            <button class="dialog-btn secondary" onclick="showIdInput()">
-                Open Note
-            </button>
-        </div>
-    </div>
-</div>
-
-<div id="modalContainer"></div>
-
-<script src="js/components.js"></script>
-<script src="js/script.js"></script>
-<script>
-document.addEventListener('DOMContentLoaded', async () => {
-    await initPage('error');
-});
-</script>
-</body>
-</html>

+ 0 - 87
desktop-app/AUTO_UPDATE_SETUP.md

@@ -1,87 +0,0 @@
-# 🔄 Auto-Update System Setup - Complete!
-
-Your kNotes desktop app now has **full automatic update capabilities**! Here's what has been implemented:
-
-## ✅ What's Been Set Up
-
-### 1. **electron-updater Integration**
-- ✅ Added `electron-updater` dependency
-- ✅ Configured auto-update checking in `main.js`
-- ✅ Added "Check for Updates" menu item
-- ✅ User-friendly update notifications and dialogs
-
-### 2. **Unified GitHub Actions Workflow**
-- ✅ Updated `.github/workflows/buildAndRelease.yml` to include desktop builds
-- ✅ Automatically triggers on ANY push to main branch
-- ✅ **First**: Deploys Docker image to production
-- ✅ **Then**: Builds desktop apps for Windows, macOS, and Linux
-- ✅ **Finally**: Creates single GitHub Release with everything
-
-### 3. **Configuration Files**
-- ✅ Updated `package.json` with publish settings
-- ✅ Added GitHub as update provider
-- ✅ Version bumped to `1.1.0` for first auto-update release
-
-### 4. **Helper Scripts**
-- ✅ Created `update-frontend.sh` for local testing
-- ✅ Updated README with auto-update documentation
-
-## 🚀 How It Works
-
-### Automatic Workflow:
-1. **You make changes** to frontend files in `src/main/resources/static/`
-2. **Push to main branch** → GitHub Actions detects changes
-3. **Builds desktop apps** for Windows, macOS, and Linux
-4. **Creates GitHub Release** with all platform binaries
-5. **Users get notified** when they open the app
-6. **Updates download** in background automatically
-7. **One-click install** when users are ready
-
-### Manual Testing:
-```bash
-# Update frontend files
-./update-frontend.sh
-
-# Build new version
-npm run build-linux
-
-# Test the app
-./dist/kNotes-1.1.0.AppImage
-```
-
-## 📦 Current Build Status
-
-- **Version**: 1.1.0
-- **AppImage**: `kNotes-1.1.0.AppImage` (104.4 MB)
-- **Auto-updater**: ✅ Enabled and configured
-- **GitHub Integration**: ✅ Ready for releases
-
-## 🔧 Update Process for Users
-
-1. **App starts** → Checks for updates automatically (3 seconds after startup)
-2. **Update found** → Shows notification: "Update available, downloading in background"
-3. **Download complete** → Shows dialog: "Update ready, restart now or later?"
-4. **User restarts** → App updates and relaunches with new version
-
-## 📋 Next Steps
-
-### To Enable Auto-Updates:
-1. **Push this desktop app code** to your GitHub repository
-2. **Make any frontend change** in `src/main/resources/static/`
-3. **Push to main** → First auto-release will be created!
-4. **Share the release** with users
-
-### Repository Settings Needed:
-- Make sure GitHub Actions are enabled
-- Ensure `GITHUB_TOKEN` has release permissions (should be automatic)
-- Repository must be public or have appropriate permissions for releases
-
-## 🎯 Benefits
-
-- ✅ **Zero maintenance** - Updates happen automatically
-- ✅ **Always current** - Desktop app stays in sync with web app
-- ✅ **Cross-platform** - Works on Windows, macOS, and Linux
-- ✅ **User-friendly** - Non-disruptive background updates
-- ✅ **Secure** - Uses GitHub's infrastructure and signing
-
-Your desktop app is now fully equipped with professional-grade automatic updating! 🎉

+ 0 - 68
desktop-app/EXPECTED_RELEASE.md

@@ -1,68 +0,0 @@
-# 📋 Expected GitHub Release
-
-## Release Page Preview
-
-**URL**: `https://github.com/lhamacorp/knotes/releases/tag/v1.1.0-20260116-201500`
-
-### 📥 Downloads Section:
-```
-📦 Assets (9)
-
-🐧 Linux:
-  └── kNotes-1.1.0.AppImage              (104.4 MB)
-  └── kNotes-1.1.0.AppImage.blockmap     (106 KB)
-  └── latest-linux.yml                   (358 B)
-
-🪟 Windows:
-  └── kNotes Setup 1.1.0.exe             (120.1 MB)
-  └── kNotes Setup 1.1.0.exe.blockmap    (121 KB)
-  └── latest.yml                          (364 B)
-
-🍎 macOS:
-  └── kNotes-1.1.0.dmg                   (115.2 MB)
-  └── kNotes-1.1.0.dmg.blockmap          (117 KB)
-  └── latest-mac.yml                      (372 B)
-
-Total download count: 0 (new release)
-```
-
-### 📝 Release Description:
-```markdown
-## kNotes Desktop App - Automatic Release
-
-This release was automatically generated when frontend changes were detected.
-
-### What's New:
-- Latest frontend updates from the web application
-- Automatic synchronization with deployed API
-- Bug fixes and improvements
-
-### Downloads:
-- **Windows**: Download the `.exe` installer
-- **macOS**: Download the `.dmg` installer
-- **Linux**: Download the `.AppImage` file
-
-### Installation:
-1. Download the appropriate file for your operating system
-2. Install/run the application
-3. The app will automatically check for future updates
-
-Built from commit: a1b2c3d4...
-```
-
-## 🎯 User Download Experience
-
-### For Linux Users:
-1. Click `kNotes-1.1.0.AppImage`
-2. `chmod +x kNotes-1.1.0.AppImage`
-3. `./kNotes-1.1.0.AppImage`
-
-### For Windows Users:
-1. Click `kNotes Setup 1.1.0.exe`
-2. Run installer → App installed in Program Files
-3. Desktop shortcut created
-
-### For macOS Users:
-1. Click `kNotes-1.1.0.dmg`
-2. Open DMG → Drag app to Applications folder
-3. Launch from Launchpad/Applications

+ 0 - 123
desktop-app/README.md

@@ -1,123 +0,0 @@
-# kNotes Desktop App
-
-A cross-platform desktop version of kNotes that connects to your hosted API at https://notes.lhamacorp.com.
-
-## Prerequisites
-
-- [Node.js](https://nodejs.org/) (version 16 or higher)
-- npm (comes with Node.js)
-
-## Installation
-
-1. Navigate to the desktop-app directory:
-   ```bash
-   cd desktop-app
-   ```
-
-2. Install dependencies:
-   ```bash
-   npm install
-   ```
-
-## Running in Development
-
-To run the app in development mode:
-```bash
-npm start
-```
-
-## Building for Distribution
-
-### Build for All Platforms (requires appropriate OS)
-```bash
-npm run build-all
-```
-
-### Build for Specific Platforms
-
-**Windows:**
-```bash
-npm run build-win
-```
-
-**macOS:**
-```bash
-npm run build-mac
-```
-
-**Linux:**
-```bash
-npm run build-linux
-```
-
-### Build Output
-
-Built applications will be available in the `dist/` directory:
-- **Windows**: `.exe` installer and portable app
-- **macOS**: `.dmg` installer and `.app` file
-- **Linux**: `.AppImage` portable executable
-
-## Features
-
-- 🖥️ Native desktop app experience
-- 🌐 Connects to your hosted kNotes API
-- 🌙 Dark/Light theme support
-- ⌨️ Keyboard shortcuts:
-  - `Ctrl/Cmd + N` - New Note
-  - `Ctrl/Cmd + H` - Home
-  - `Ctrl/Cmd + Q` - Quit
-- 📱 Responsive interface
-- 💾 Auto-save functionality
-- 🔄 Real-time conflict detection
-- 🔄 **Automatic Updates** - App updates automatically when frontend changes
-
-## Architecture
-
-The desktop app is built with:
-- **Electron** - Cross-platform desktop framework
-- **Vanilla JavaScript** - No additional framework dependencies
-- **Native HTML/CSS** - Clean, fast interface
-
-The app acts as a desktop wrapper around your existing frontend, making HTTP requests to your deployed API at `https://notes.lhamacorp.com/api/notes`.
-
-## Automatic Updates
-
-The desktop app includes automatic update functionality:
-
-### How It Works
-1. **Any Changes Pushed** - When you push ANY changes to the main branch, GitHub Actions triggers a unified release workflow
-2. **Docker Deployment First** - Web application is built, tested, and deployed to https://notes.lhamacorp.com
-3. **Desktop Apps Follow** - After successful Docker deployment, desktop apps are built for all platforms using the latest frontend
-4. **Single GitHub Release** - One release contains both Docker deployment info AND all desktop app binaries
-5. **Auto-Update Notifications** - Desktop users get notified of new versions automatically
-6. **One-Click Installation** - Users can restart to apply updates with a single click
-
-### Manual Update Check
-Users can also manually check for updates via: **File Menu → Check for Updates**
-
-### Update Process
-- ✅ Non-disruptive background downloads
-- ✅ User chooses when to restart and apply updates
-- ✅ Automatic rollback protection
-- ✅ Secure signature verification
-
-## Development Notes
-
-- The app loads `home.html` by default
-- All API calls are routed to the hosted backend
-- Theme preferences are stored locally using localStorage
-- The app includes security best practices (disabled node integration, context isolation)
-
-## Troubleshooting
-
-1. **App won't start**: Make sure Node.js and npm are installed correctly
-2. **Build fails**: Check that you have the necessary build tools for your platform
-3. **API connection issues**: Verify that https://notes.lhamacorp.com is accessible from your network
-
-## Security
-
-The desktop app follows Electron security best practices:
-- Node integration is disabled
-- Context isolation is enabled
-- External links open in the default browser
-- Web security is enforced

+ 0 - 53
desktop-app/RELEASE_FILES.md

@@ -1,53 +0,0 @@
-# 📦 GitHub Release Files
-
-When the **unified workflow** runs (after Docker deployment), it creates a GitHub Release with these files:
-
-## 🐧 Linux Files
-```
-kNotes-1.1.0.AppImage                    # ~104MB - Portable executable
-kNotes-1.1.0.AppImage.blockmap          # Delta update file
-latest-linux.yml                        # Auto-updater metadata
-```
-
-## 🪟 Windows Files
-```
-kNotes Setup 1.1.0.exe                  # ~120MB - NSIS installer
-kNotes Setup 1.1.0.exe.blockmap        # Delta update file
-latest.yml                              # Auto-updater metadata
-```
-
-## 🍎 macOS Files
-```
-kNotes-1.1.0.dmg                        # ~115MB - Disk image installer
-kNotes-1.1.0.dmg.blockmap              # Delta update file
-kNotes-1.1.0-mac.zip                   # Raw .app bundle
-latest-mac.yml                          # Auto-updater metadata
-```
-
-## 📝 Release Notes (Auto-generated)
-```markdown
-## kNotes Desktop v1.1.0
-
-### What's New:
-- Latest frontend updates from the web application
-- Automatic synchronization with deployed API
-- Bug fixes and improvements
-
-### Downloads:
-- **Windows**: Download the .exe installer
-- **macOS**: Download the .dmg installer
-- **Linux**: Download the .AppImage file
-
-Built from commit: abc123...
-```
-
-## 🔗 Release URL
-The release will be available at:
-`https://github.com/lhamacorp/knotes/releases/latest`
-
-## 👥 User Experience
-1. Users go to GitHub releases page
-2. Download appropriate file for their OS
-3. Install/run the application
-4. App automatically checks for future updates
-5. Users get notified when new versions are available

+ 0 - 23
desktop-app/components/base.html

@@ -1,23 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-    <meta name="theme-color" content="#2d2d2d">
-    <meta name="apple-mobile-web-app-capable" content="yes">
-    <meta name="apple-mobile-web-app-status-bar-style" content="default">
-    <meta name="apple-mobile-web-app-title" content="kNotes">
-    <meta name="mobile-web-app-capable" content="yes">
-    <meta name="application-name" content="kNotes">
-    <title>{{PAGE_TITLE}}</title>
-    <link rel="stylesheet" href="css/style.css">
-    <link rel="icon" type="image/x-icon" href="img/favicon.ico">
-</head>
-<body>
-{{PAGE_CONTENT}}
-
-<script src="js/components.js"></script>
-<script src="js/script.js"></script>
-{{PAGE_SCRIPT}}
-</body>
-</html>

+ 0 - 8
desktop-app/components/header.html

@@ -1,8 +0,0 @@
-<div class="header">
-    <div class="title" onclick="navigateToPage('home.html')" style="cursor: pointer;">
-        <img src="img/logo.png" alt="kNotes logo"/> kNotes
-    </div>
-    <div class="header-right">
-        {{HEADER_CONTENT}}
-    </div>
-</div>

+ 0 - 10
desktop-app/components/modal.html

@@ -1,10 +0,0 @@
-<div id="idInputOverlay" class="id-input-overlay hidden">
-    <div class="id-input-dialog">
-        <h3>Open Note</h3>
-        <input type="text" id="noteIdInput" class="id-input" placeholder="Enter note ID"/>
-        <div class="dialog-buttons">
-            <button class="dialog-btn secondary" onclick="hideIdInput()">Cancel</button>
-            <button class="dialog-btn primary" onclick="loadNoteFromInput()">Open</button>
-        </div>
-    </div>
-</div>

+ 0 - 763
desktop-app/css/style.css

@@ -1,763 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap');
-
-/* CSS Variables for Theme Support - Dark Theme Default */
-:root {
-    --bg-primary: #1a1a1a;
-    --bg-secondary: #2d2d2d;
-    --bg-tertiary: #404040;
-    --text-primary: #e0e0e0;
-    --text-secondary: #b0b0b0;
-    --text-tertiary: #808080;
-    --border-primary: #404040;
-    --border-secondary: #555;
-    --accent-primary: #4dabf7;
-    --accent-primary-hover: #339af0;
-    --accent-secondary: #868e96;
-    --overlay-bg: rgba(0,0,0,0.7);
-    --shadow: rgba(0,0,0,0.5);
-}
-
-/* Light Theme Variables */
-[data-theme="light"] {
-    --bg-primary: #fafafa;
-    --bg-secondary: white;
-    --bg-tertiary: #f5f5f5;
-    --text-primary: #333;
-    --text-secondary: #666;
-    --text-tertiary: #999;
-    --border-primary: #e0e0e0;
-    --border-secondary: #ddd;
-    --accent-primary: #007bff;
-    --accent-primary-hover: #0056b3;
-    --accent-secondary: #6c757d;
-    --overlay-bg: rgba(0,0,0,0.5);
-    --shadow: rgba(0,0,0,0.3);
-}
-
-* {
-    margin: 0;
-    padding: 0;
-    box-sizing: border-box;
-}
-
-body {
-    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
-    background-color: var(--bg-primary);
-    color: var(--text-primary);
-    height: 100vh;
-    height: calc(var(--vh, 1vh) * 100); /* Fallback for mobile browsers */
-    display: flex;
-    flex-direction: column;
-    transition: background-color 0.3s ease, color 0.3s ease;
-    overflow-x: hidden;
-}
-
-.header {
-    background: var(--bg-secondary);
-    border-bottom: 1px solid var(--border-primary);
-    padding: 15px 20px;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    min-height: 60px;
-    transition: background-color 0.3s ease, border-color 0.3s ease;
-}
-
-.title {
-    font-size: 18px;
-    color: var(--text-primary);
-    font-weight: 500;
-    display: flex;
-    align-items: center;
-    gap: 8px;
-}
-
-.title img {
-    height: 28px;
-    width: 28px;
-    border-radius: 6px;
-    vertical-align: middle;
-    flex-shrink: 0;
-    object-fit: contain;
-    background: var(--bg-tertiary);
-    transition: all 0.3s ease;
-}
-
-/* Fallback when logo fails to load */
-.title img[alt]:empty::before,
-.title img[alt]:not([src])::before {
-    content: "📝";
-    display: block;
-    font-size: 16px;
-    text-align: center;
-    line-height: 28px;
-}
-
-.note-id {
-    font-family: monospace;
-    font-size: 12px;
-    color: var(--text-secondary);
-    background: var(--bg-tertiary);
-    padding: 4px 8px;
-    border-radius: 3px;
-    transition: background-color 0.2s, color 0.2s;
-}
-
-.note-id:hover {
-    background: var(--accent-primary);
-    color: white;
-}
-
-.note-id:active {
-    background: var(--accent-primary-hover);
-    color: white;
-}
-
-.header-right {
-    display: flex;
-    align-items: center;
-    gap: 10px;
-}
-
-/* Update toast message */
-.update-toast {
-    position: fixed;
-    bottom: 20px;
-    right: 20px;
-    background: var(--accent-primary);
-    color: white;
-    padding: 12px 18px;
-    border-radius: 8px;
-    font-size: 14px;
-    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
-    z-index: 1000;
-    animation: slideInUp 0.3s ease-out;
-}
-
-.update-toast.hidden {
-    display: none;
-}
-
-@keyframes slideInUp {
-    from {
-        transform: translateY(100%);
-        opacity: 0;
-    }
-    to {
-        transform: translateY(0);
-        opacity: 1;
-    }
-}
-
-.new-btn {
-    background: var(--accent-primary);
-    color: white;
-    border: none;
-    padding: 8px 16px;
-    border-radius: 4px;
-    cursor: pointer;
-    font-size: 14px;
-    transition: background-color 0.2s ease;
-}
-
-.new-btn:hover {
-    background: var(--accent-primary-hover);
-}
-
-.content {
-    flex: 1;
-    display: flex;
-}
-
-.note-area {
-    flex: 1;
-    border: none;
-    outline: none;
-    padding: 30px;
-    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
-    font-size: 16px;
-    line-height: 1.6;
-    resize: none;
-    background: var(--bg-secondary);
-    color: var(--text-primary);
-    transition: background-color 0.3s ease, color 0.3s ease;
-}
-
-.note-area::placeholder {
-    color: var(--text-tertiary);
-}
-
-.id-input-overlay {
-    position: fixed;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    background: var(--overlay-bg);
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    z-index: 1000;
-}
-
-.id-input-dialog {
-    background: var(--bg-secondary);
-    padding: 30px;
-    border-radius: 8px;
-    box-shadow: 0 4px 20px var(--shadow);
-    max-width: 400px;
-    width: 90%;
-    transition: background-color 0.3s ease;
-}
-
-.id-input-dialog h3 {
-    margin-bottom: 15px;
-    color: var(--text-primary);
-}
-
-.id-input {
-    width: 100%;
-    padding: 12px;
-    border: 1px solid var(--border-secondary);
-    border-radius: 4px;
-    font-size: 14px;
-    margin-bottom: 15px;
-    background: var(--bg-secondary);
-    color: var(--text-primary);
-    transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
-}
-
-.dialog-buttons {
-    display: flex;
-    gap: 10px;
-    justify-content: flex-end;
-}
-
-.dialog-btn {
-    padding: 8px 16px;
-    border: none;
-    border-radius: 4px;
-    cursor: pointer;
-    font-size: 14px;
-    transition: background-color 0.2s ease;
-}
-
-.dialog-btn.primary {
-    background: var(--accent-primary);
-    color: white;
-}
-
-.dialog-btn.primary:hover {
-    background: var(--accent-primary-hover);
-}
-
-.dialog-btn.secondary {
-    background: var(--accent-secondary);
-    color: white;
-}
-
-.dialog-btn.secondary:hover {
-    opacity: 0.9;
-}
-
-/* Theme Switch Styles */
-.theme-switch {
-    background: var(--bg-tertiary);
-    border: 1px solid var(--border-primary);
-    border-radius: 20px;
-    padding: 6px;
-    cursor: pointer;
-    width: 36px;
-    height: 36px;
-    position: relative;
-    transition: all 0.3s ease;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    font-size: 16px;
-}
-
-.theme-switch:hover {
-    background: var(--border-primary);
-    transform: scale(1.05);
-}
-
-.theme-switch::before {
-    content: '☀️';
-    transition: all 0.3s ease;
-    filter: drop-shadow(0 1px 2px rgba(0,0,0,0.2));
-}
-
-.theme-switch.dark::before {
-    content: '🌙';
-}
-
-.hidden {
-    display: none;
-}
-
-/* Mobile-First Responsive Design */
-
-/* Base styles are already mobile-friendly, now add tablet and desktop improvements */
-
-/* Small smartphones (portrait) */
-@media screen and (max-width: 480px) {
-    .header {
-        padding: 12px 15px;
-        min-height: 56px;
-        flex-wrap: nowrap;
-    }
-
-    .title {
-        font-size: 16px;
-        font-weight: 600;
-        gap: 6px;
-    }
-
-    .title img {
-        height: 24px;
-        width: 24px;
-        border-radius: 4px;
-    }
-
-    .header-right {
-        gap: 8px;
-        flex-shrink: 0;
-    }
-
-    .note-id {
-        font-size: 10px;
-        padding: 3px 6px;
-        max-width: 80px;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        white-space: nowrap;
-    }
-
-    /* Make theme switch more touch-friendly */
-    .theme-switch {
-        width: 44px;
-        height: 44px;
-        padding: 8px;
-        min-width: 44px;
-        min-height: 44px;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        font-size: 18px;
-    }
-
-    /* Touch-friendly buttons */
-    .new-btn {
-        padding: 10px 14px;
-        font-size: 13px;
-        min-height: 44px;
-        touch-action: manipulation;
-        -webkit-tap-highlight-color: transparent;
-    }
-
-    /* Optimize text area for mobile */
-    .note-area {
-        padding: 20px 15px;
-        font-size: 16px; /* Prevents zoom on iOS */
-        line-height: 1.5;
-        -webkit-appearance: none;
-        border-radius: 0;
-    }
-
-    /* Mobile-optimized modal */
-    .id-input-overlay {
-        padding: 20px 15px;
-        align-items: flex-start;
-        padding-top: 25vh;
-    }
-
-    .id-input-dialog {
-        padding: 24px 20px;
-        margin: 0;
-        border-radius: 12px;
-        width: 100%;
-        max-width: 320px;
-    }
-
-    .id-input-dialog h3 {
-        font-size: 18px;
-        margin-bottom: 16px;
-    }
-
-    .id-input {
-        padding: 14px 12px;
-        font-size: 16px; /* Prevents zoom on iOS */
-        border-radius: 8px;
-        margin-bottom: 20px;
-        -webkit-appearance: none;
-    }
-
-    .dialog-buttons {
-        gap: 12px;
-        flex-direction: row;
-    }
-
-    .dialog-btn {
-        flex: 1;
-        padding: 12px 16px;
-        font-size: 14px;
-        font-weight: 500;
-        min-height: 44px;
-        border-radius: 8px;
-        touch-action: manipulation;
-        -webkit-tap-highlight-color: transparent;
-    }
-}
-
-/* Larger smartphones and small tablets (landscape phones) */
-@media screen and (min-width: 481px) and (max-width: 768px) {
-    .header {
-        padding: 15px 20px;
-    }
-
-    .title {
-        font-size: 18px;
-        gap: 7px;
-    }
-
-    .title img {
-        height: 26px;
-        width: 26px;
-        border-radius: 5px;
-    }
-
-    .note-area {
-        padding: 25px 20px;
-        font-size: 16px;
-    }
-
-    .id-input-dialog {
-        max-width: 400px;
-        padding: 28px 24px;
-    }
-
-    .theme-switch {
-        width: 38px;
-        height: 38px;
-        font-size: 17px;
-    }
-}
-
-/* Tablets and small desktops */
-@media screen and (min-width: 769px) and (max-width: 1024px) {
-    .header {
-        padding: 16px 24px;
-        min-height: 64px;
-    }
-
-    .title {
-        font-size: 20px;
-        gap: 8px;
-    }
-
-    .title img {
-        height: 28px;
-        width: 28px;
-        border-radius: 6px;
-    }
-
-    .note-area {
-        padding: 32px 28px;
-        font-size: 17px;
-    }
-
-    .new-btn {
-        padding: 10px 18px;
-        font-size: 15px;
-    }
-}
-
-/* Large screens and desktops */
-@media screen and (min-width: 1025px) {
-    .header {
-        padding: 18px 32px;
-        min-height: 68px;
-    }
-
-    .title {
-        font-size: 22px;
-        gap: 10px;
-    }
-
-    .title img {
-        height: 32px;
-        width: 32px;
-        border-radius: 7px;
-    }
-
-    .note-area {
-        padding: 40px 36px;
-        font-size: 18px;
-    }
-
-    .id-input-dialog {
-        max-width: 480px;
-        padding: 36px 32px;
-    }
-}
-
-/* Touch-specific improvements */
-@media (hover: none) and (pointer: coarse) {
-    /* This targets touch devices specifically */
-
-    .new-btn:hover,
-    .dialog-btn:hover,
-    .theme-switch:hover {
-        /* Remove hover effects on touch devices */
-        background: var(--accent-primary);
-        opacity: 1;
-    }
-
-    .dialog-btn.secondary:hover {
-        background: var(--accent-secondary);
-        opacity: 1;
-    }
-
-    .theme-switch:hover {
-        background: var(--bg-tertiary);
-    }
-
-    /* Add active states for touch feedback */
-    .new-btn:active {
-        background: var(--accent-primary-hover);
-        transform: scale(0.98);
-    }
-
-    /* Toast mobile styles */
-    .update-toast {
-        bottom: 15px;
-        right: 15px;
-        padding: 10px 15px;
-        font-size: 13px;
-        border-radius: 6px;
-    }
-
-    .dialog-btn:active {
-        transform: scale(0.98);
-    }
-
-    .theme-switch:active {
-        transform: scale(0.95);
-    }
-}
-
-/* High-DPI displays */
-@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
-    .theme-switch::before {
-        box-shadow: 0 1px 3px rgba(0,0,0,0.3);
-    }
-
-    .id-input-dialog {
-        box-shadow: 0 8px 32px var(--shadow);
-    }
-}
-
-/* Landscape orientation optimizations */
-@media screen and (max-height: 500px) and (orientation: landscape) {
-    .header {
-        min-height: 48px;
-        padding: 10px 15px;
-    }
-
-    .title {
-        font-size: 14px;
-        gap: 4px;
-    }
-
-    .title img {
-        height: 20px;
-        width: 20px;
-        border-radius: 3px;
-    }
-
-    .new-btn {
-        padding: 8px 12px;
-        font-size: 12px;
-        min-height: 36px;
-    }
-
-    .theme-switch {
-        width: 36px;
-        height: 36px;
-        min-height: 36px;
-        font-size: 14px;
-    }
-
-    .note-area {
-        padding: 15px;
-        font-size: 15px;
-    }
-
-    .id-input-overlay {
-        padding-top: 10vh;
-    }
-
-    .id-input-dialog {
-        padding: 20px;
-        max-width: 400px;
-    }
-}
-
-/* Accessibility improvements */
-@media (prefers-reduced-motion: reduce) {
-    * {
-        animation-duration: 0.01ms !important;
-        animation-iteration-count: 1 !important;
-        transition-duration: 0.01ms !important;
-    }
-
-    .theme-switch::before {
-        transition: none;
-    }
-
-    body {
-        transition: none;
-    }
-}
-
-/* Dark theme specific mobile adjustments */
-[data-theme="dark"] {
-    /* Better contrast for mobile screens */
-    --text-primary: #f0f0f0;
-    --text-secondary: #c0c0c0;
-    --border-primary: #4a4a4a;
-}
-
-@media screen and (max-width: 480px) {
-    [data-theme="dark"] {
-        --bg-primary: #0d1117;
-        --bg-secondary: #1c2128;
-        --bg-tertiary: #2d333b;
-    }
-}
-
-/* 404 Error Page Styles */
-.error-content {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    justify-content: center;
-    text-align: center;
-    padding: 40px 20px;
-    height: 100%;
-    max-width: 500px;
-    margin: 0 auto;
-}
-
-.error-icon {
-    font-size: 64px;
-    margin-bottom: 24px;
-    opacity: 0.8;
-}
-
-.error-title {
-    font-size: 32px;
-    font-weight: 600;
-    color: var(--text-primary);
-    margin-bottom: 16px;
-    line-height: 1.2;
-}
-
-.error-message {
-    font-size: 16px;
-    color: var(--text-secondary);
-    line-height: 1.6;
-    margin-bottom: 32px;
-    max-width: 400px;
-}
-
-.error-actions {
-    display: flex;
-    gap: 16px;
-    flex-wrap: wrap;
-    justify-content: center;
-}
-
-.error-actions .dialog-btn {
-    min-width: 140px;
-    padding: 12px 24px;
-    font-size: 14px;
-    font-weight: 500;
-    border-radius: 8px;
-    cursor: pointer;
-    border: none;
-    transition: all 0.2s ease;
-    text-decoration: none;
-    display: inline-block;
-}
-
-/* Mobile optimizations for 404 page */
-@media screen and (max-width: 480px) {
-    .error-content {
-        padding: 30px 15px;
-    }
-
-    .error-icon {
-        font-size: 48px;
-        margin-bottom: 20px;
-    }
-
-    .error-title {
-        font-size: 24px;
-        margin-bottom: 12px;
-    }
-
-    .error-message {
-        font-size: 14px;
-        margin-bottom: 24px;
-    }
-
-    .error-actions {
-        flex-direction: column;
-        width: 100%;
-        gap: 12px;
-    }
-
-    .error-actions .dialog-btn {
-        width: 100%;
-        min-width: unset;
-    }
-}
-
-/* Tablet optimizations for 404 page */
-@media screen and (min-width: 481px) and (max-width: 768px) {
-    .error-content {
-        padding: 36px 24px;
-    }
-
-    .error-icon {
-        font-size: 56px;
-    }
-
-    .error-title {
-        font-size: 28px;
-    }
-}
-
-/* Desktop optimizations for 404 page */
-@media screen and (min-width: 1025px) {
-    .error-content {
-        padding: 60px 40px;
-    }
-
-    .error-icon {
-        font-size: 72px;
-        margin-bottom: 28px;
-    }
-
-    .error-title {
-        font-size: 36px;
-        margin-bottom: 20px;
-    }
-
-    .error-message {
-        font-size: 18px;
-        margin-bottom: 40px;
-    }
-}

+ 0 - 44
desktop-app/home.html

@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-    <meta name="theme-color" content="#007bff">
-    <meta name="apple-mobile-web-app-capable" content="yes">
-    <meta name="apple-mobile-web-app-status-bar-style" content="default">
-    <meta name="apple-mobile-web-app-title" content="kNotes">
-    <meta name="mobile-web-app-capable" content="yes">
-    <meta name="application-name" content="kNotes">
-    <title>kNotes - Simple Note Taking</title>
-    <link rel="stylesheet" href="css/style.css">
-    <link rel="icon" type="image/x-icon" href="img/favicon.ico">
-</head>
-<body>
-<div id="headerContainer"></div>
-
-<div class="content">
-    <div class="error-content">
-        <div class="error-icon">📝</div>
-        <h1 class="error-title">Welcome to kNotes</h1>
-        <div class="error-actions">
-            <button class="dialog-btn primary" onclick="navigateToPage('index.html')">
-                Create New Note
-            </button>
-            <button class="dialog-btn secondary" onclick="showIdInput()">
-                Open Existing Note
-            </button>
-        </div>
-    </div>
-</div>
-
-<div id="modalContainer"></div>
-
-<script src="js/components.js"></script>
-<script src="js/script.js"></script>
-<script>
-document.addEventListener('DOMContentLoaded', async () => {
-    await initPage('home');
-});
-</script>
-</body>
-</html>

BIN
desktop-app/img/favicon.ico


BIN
desktop-app/img/logo.png


+ 0 - 37
desktop-app/index.html

@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-    <meta name="theme-color" content="#007bff">
-    <meta name="apple-mobile-web-app-capable" content="yes">
-    <meta name="apple-mobile-web-app-status-bar-style" content="default">
-    <meta name="apple-mobile-web-app-title" content="kNotes">
-    <meta name="mobile-web-app-capable" content="yes">
-    <meta name="application-name" content="kNotes">
-    <title>kNotes</title>
-    <link rel="stylesheet" href="css/style.css">
-    <link rel="icon" type="image/x-icon" href="img/favicon.ico">
-</head>
-<body>
-<div id="headerContainer"></div>
-
-<div id="updateToast" class="update-toast hidden">
-    📄 Note was updated
-</div>
-
-<div class="content">
-    <textarea class="note-area" id="noteContent" placeholder="Start typing your note..."></textarea>
-</div>
-
-<div id="modalContainer"></div>
-
-<script src="js/components.js"></script>
-<script src="js/script.js"></script>
-<script>
-document.addEventListener('DOMContentLoaded', async () => {
-    await initPage('editor');
-});
-</script>
-</body>
-</html>

+ 0 - 79
desktop-app/js/components.js

@@ -1,79 +0,0 @@
-// Navigation function for Electron desktop app
-function navigateToPage(page) {
-    try {
-        window.location.replace(page);
-    } catch (error) {
-        console.error('Navigation error:', error);
-        window.location.href = page;
-    }
-}
-
-async function loadComponent(componentPath, targetId, customizations = {}) {
-    try {
-        const response = await fetch(componentPath);
-        if (!response.ok) throw new Error(`Failed to load ${componentPath}`);
-
-        let html = await response.text();
-
-        Object.entries(customizations).forEach(([placeholder, value]) => {
-            html = html.replace(new RegExp(`{{${placeholder}}}`, 'g'), value);
-        });
-
-        const targetElement = document.getElementById(targetId);
-        if (targetElement) {
-            targetElement.innerHTML = html;
-        }
-    } catch (error) {
-        console.error('Component loading failed:', error);
-    }
-}
-
-const PAGE_CONFIGS = {
-    editor: {
-        header: `
-            <span class="note-id" id="noteIdDisplay" style="display: none; cursor: pointer;" onclick="copyNoteLink()" title="Click to copy note ID"></span>
-            <div class="theme-switch" id="themeSwitch" onclick="toggleTheme()" title="Toggle dark/light theme"></div>
-            <button class="new-btn" onclick="showIdInput()">Open</button>
-            <button class="new-btn" onclick="newNote()">New</button>
-        `,
-        needsModal: true,
-        needsToast: true
-    },
-    home: {
-        header: `
-            <div class="theme-switch" id="themeSwitch" onclick="toggleTheme()" title="Toggle dark/light theme"></div>
-        `,
-        needsModal: true,
-        needsToast: false
-    },
-    error: {
-        header: `
-            <div class="theme-switch" id="themeSwitch" onclick="toggleTheme()" title="Toggle dark/light theme"></div>
-            <button class="new-btn" onclick="navigateToPage('home.html')">Home</button>
-        `,
-        needsModal: true,
-        needsToast: false
-    }
-};
-
-async function initPage(pageType) {
-    const config = PAGE_CONFIGS[pageType];
-    if (!config) {
-        console.error('Unknown page type:', pageType);
-        return;
-    }
-
-    await loadComponent('components/header.html', 'headerContainer', {
-        HEADER_CONTENT: config.header
-    });
-
-    if (config.needsModal) {
-        await loadComponent('components/modal.html', 'modalContainer');
-    }
-
-    if (typeof initializeTheme === 'function') {
-        initializeTheme();
-    }
-
-    updateThemeSwitchState();
-}

+ 0 - 442
desktop-app/js/script.js

@@ -1,442 +0,0 @@
-const API_BASE = 'https://notes.lhamacorp.com/api/notes';
-let currentNoteId = null;
-let autoSaveTimeout = null;
-let lastSavedContent = '';
-let currentNoteModifiedAt = null;
-let versionCheckInterval = null;
-const VERSION_CHECK_INTERVAL_MS = 5000;
-
-function initializeTheme() {
-    const savedTheme = localStorage.getItem('theme') || 'dark';
-    const body = document.body;
-
-    if (savedTheme === 'light') {
-        body.setAttribute('data-theme', 'light');
-    } else {
-        body.removeAttribute('data-theme');
-    }
-
-    const themeSwitch = document.getElementById('themeSwitch');
-    if (themeSwitch) {
-        if (savedTheme === 'light') {
-            themeSwitch.classList.remove('dark');
-        } else {
-            themeSwitch.classList.add('dark');
-        }
-    }
-
-    updateThemeColor();
-}
-
-function updateThemeSwitchState() {
-    const savedTheme = localStorage.getItem('theme') || 'dark';
-    const themeSwitch = document.getElementById('themeSwitch');
-
-    if (themeSwitch) {
-        if (savedTheme === 'light') {
-            themeSwitch.classList.remove('dark');
-        } else {
-            themeSwitch.classList.add('dark');
-        }
-    }
-}
-
-function toggleTheme() {
-    const body = document.body;
-    const themeSwitch = document.getElementById('themeSwitch');
-
-    if (!themeSwitch) return;
-
-    const currentTheme = body.getAttribute('data-theme');
-
-    if (currentTheme === 'light') {
-        body.removeAttribute('data-theme');
-        themeSwitch.classList.add('dark');
-        localStorage.setItem('theme', 'dark');
-    } else {
-        body.setAttribute('data-theme', 'light');
-        themeSwitch.classList.remove('dark');
-        localStorage.setItem('theme', 'light');
-    }
-
-    updateThemeColor();
-}
-
-function init() {
-    initializeTheme();
-    setupMobileOptimizations();
-
-    const pathname = window.location.pathname;
-    const pathParts = pathname.split('/');
-    let idFromUrl = null;
-
-    for (const part of pathParts) {
-        if (part && /^[A-Za-z0-9]{26}$/.test(part)) {
-            idFromUrl = part;
-            break;
-        }
-    }
-
-    const noteContent = document.getElementById('noteContent');
-    if (noteContent) {
-        // Check for stored note ID from navigation (for desktop app)
-        const storedNoteId = sessionStorage.getItem('noteToLoad');
-        if (storedNoteId) {
-            sessionStorage.removeItem('noteToLoad');
-            loadNoteById(storedNoteId);
-        } else if (idFromUrl) {
-            loadNoteById(idFromUrl);
-        } else {
-            newNote();
-        }
-        noteContent.addEventListener('input', handleContentChange);
-    }
-
-    const noteIdInput = document.getElementById('noteIdInput');
-    if (noteIdInput) {
-        noteIdInput.addEventListener('keypress', function(e) {
-            if (e.key === 'Enter') {
-                loadNoteFromInput();
-            }
-        });
-    }
-}
-
-function setupMobileOptimizations() {
-    const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
-
-    if (isMobile) {
-        const noteContent = document.getElementById('noteContent');
-        if (noteContent) {
-            noteContent.addEventListener('focus', function() {
-                setTimeout(() => {
-                    this.scrollIntoView({ behavior: 'smooth', block: 'center' });
-                }, 300);
-            });
-
-            noteContent.addEventListener('touchmove', function(e) {
-                e.stopPropagation();
-            }, { passive: true });
-        }
-
-        updateThemeColor();
-    }
-
-    window.addEventListener('orientationchange', function() {
-        setTimeout(() => {
-            const vh = window.innerHeight * 0.01;
-            document.documentElement.style.setProperty('--vh', `${vh}px`);
-        }, 100);
-    });
-
-    const vh = window.innerHeight * 0.01;
-    document.documentElement.style.setProperty('--vh', `${vh}px`);
-}
-
-function updateThemeColor() {
-    const themeColorMeta = document.querySelector('meta[name="theme-color"]');
-    const currentTheme = document.body.getAttribute('data-theme');
-
-    if (themeColorMeta) {
-        if (currentTheme === 'light') {
-            themeColorMeta.setAttribute('content', '#007bff');
-        } else {
-            themeColorMeta.setAttribute('content', '#2d2d2d');
-        }
-    }
-}
-
-function handleContentChange() {
-    const noteContent = document.getElementById('noteContent');
-    if (!noteContent) {
-        console.error('Element with ID "noteContent" not found');
-        return;
-    }
-    const content = noteContent.value;
-
-    if (autoSaveTimeout) {
-        clearTimeout(autoSaveTimeout);
-    }
-
-    autoSaveTimeout = setTimeout(() => {
-        autoSave(content);
-    }, 1000);
-}
-
-async function autoSave(content) {
-    if (content === lastSavedContent) {
-        return;
-    }
-
-    try {
-        if (currentNoteId) {
-            const response = await fetch(`${API_BASE}/${currentNoteId}`, {
-                method: 'PUT',
-                headers: {
-                    'Content-Type': 'application/json',
-                },
-                body: JSON.stringify({
-                    content: content
-                })
-            });
-
-            if (response.ok) {
-                const updatedNote = await response.json();
-                setCurrentNoteVersion(updatedNote.modifiedAt);
-            }
-        } else {
-            const response = await fetch(API_BASE, {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                },
-                body: JSON.stringify({
-                    note: content
-                })
-            });
-
-            if (response.ok) {
-                const note = await response.json();
-                currentNoteId = note.id;
-
-                const newUrl = `/${note.id}`;
-                window.history.replaceState({}, '', newUrl);
-
-                showNoteId(note.id);
-                setCurrentNoteVersion(note.modifiedAt);
-            }
-        }
-
-        lastSavedContent = content;
-    } catch (error) {
-        console.error('Auto-save failed:', error);
-    }
-}
-
-async function loadNoteById(id) {
-    stopVersionPolling();
-
-    try {
-        const response = await fetch(`${API_BASE}/${id}`);
-
-        if (response.ok) {
-            const note = await response.json();
-            currentNoteId = note.id;
-
-            const noteContent = document.getElementById('noteContent');
-            if (noteContent) {
-                noteContent.value = note.content;
-                lastSavedContent = note.content;
-            } else {
-                console.error('Element with ID "noteContent" not found');
-            }
-
-            // Note: Skipping URL history manipulation for desktop app
-
-            showNoteId(note.id);
-            setCurrentNoteVersion(note.modifiedAt);
-        } else {
-            console.warn(`Note with ID ${id} not found (${response.status}), creating new note`);
-            await newNote();
-        }
-    } catch (error) {
-        console.error('Failed to load note:', error, 'creating new note instead');
-        await newNote();
-    }
-}
-
-function showNoteId(id) {
-    const noteIdDisplay = document.getElementById('noteIdDisplay');
-    if (noteIdDisplay) {
-        noteIdDisplay.textContent = id;
-        noteIdDisplay.style.display = 'inline-block';
-    } else {
-        console.error('Element with ID "noteIdDisplay" not found');
-    }
-}
-
-async function copyNoteLink() {
-    try {
-        const noteIdDisplay = document.getElementById('noteIdDisplay');
-        if (!noteIdDisplay) {
-            console.error('Element with ID "noteIdDisplay" not found');
-            return;
-        }
-
-        // Copy just the note ID, not the full URL
-        const noteId = currentNoteId;
-        if (!noteId) {
-            console.error('No note ID available to copy');
-            return;
-        }
-
-        await navigator.clipboard.writeText(noteId);
-
-        const originalText = noteIdDisplay.textContent;
-        noteIdDisplay.textContent = 'Copied!';
-        noteIdDisplay.style.color = 'var(--accent-primary)';
-
-        setTimeout(() => {
-            noteIdDisplay.textContent = originalText;
-            noteIdDisplay.style.color = '';
-        }, 2000);
-
-    } catch (error) {
-        console.error('Failed to copy note link:', error);
-
-        const noteIdDisplay = document.getElementById('noteIdDisplay');
-        if (noteIdDisplay) {
-            const originalText = noteIdDisplay.textContent;
-            noteIdDisplay.textContent = 'Copy failed';
-            setTimeout(() => {
-                noteIdDisplay.textContent = originalText;
-            }, 2000);
-        }
-    }
-}
-
-async function newNote() {
-    stopVersionPolling();
-
-    try {
-        const response = await fetch(API_BASE, {
-            method: 'POST',
-            headers: {
-                'Content-Type': 'application/json',
-            },
-            body: JSON.stringify({
-                note: ''
-            })
-        });
-
-        if (response.ok) {
-            const note = await response.json();
-            currentNoteId = note.id;
-            lastSavedContent = '';
-
-            const noteContent = document.getElementById('noteContent');
-            if (noteContent) {
-                noteContent.value = '';
-                noteContent.focus();
-            } else {
-                console.error('Element with ID "noteContent" not found');
-            }
-
-            // Note: Skipping URL history manipulation for desktop app
-
-            showNoteId(note.id);
-            setCurrentNoteVersion(note.modifiedAt);
-        }
-    } catch (error) {
-        console.error('Failed to create new note:', error);
-    }
-}
-
-function showIdInput() {
-    const idInputOverlay = document.getElementById('idInputOverlay');
-    const noteIdInput = document.getElementById('noteIdInput');
-
-    if (idInputOverlay) {
-        idInputOverlay.classList.remove('hidden');
-    }
-
-    if (noteIdInput) {
-        noteIdInput.focus();
-    }
-}
-
-function hideIdInput() {
-    const idInputOverlay = document.getElementById('idInputOverlay');
-    const noteIdInput = document.getElementById('noteIdInput');
-
-    if (idInputOverlay) {
-        idInputOverlay.classList.add('hidden');
-    }
-
-    if (noteIdInput) {
-        noteIdInput.value = '';
-    }
-}
-
-function loadNoteFromInput() {
-    const noteIdInput = document.getElementById('noteIdInput');
-    if (!noteIdInput) return;
-
-    const id = noteIdInput.value.trim();
-    if (id) {
-        hideIdInput();
-
-        // Check if we're on the home page, navigate to editor first
-        if (window.location.pathname.includes('home.html')) {
-            // Store the note ID to load after navigation
-            sessionStorage.setItem('noteToLoad', id);
-            window.location.replace('index.html');
-        } else {
-            // We're already on the editor page, just load the note
-            loadNoteById(id);
-        }
-    }
-}
-
-async function checkForNoteUpdates() {
-    if (!currentNoteId || !currentNoteModifiedAt) {
-        return;
-    }
-
-    try {
-        const response = await fetch(`${API_BASE}/${currentNoteId}/metadata`);
-
-        if (response.ok) {
-            const metadata = await response.json();
-            const serverModifiedAt = new Date(metadata.modifiedAt).getTime();
-            const localModifiedAt = new Date(currentNoteModifiedAt).getTime();
-
-            if (serverModifiedAt > localModifiedAt) {
-                await autoReloadNote();
-            }
-        }
-    } catch (error) {
-        console.error('Failed to check for note updates:', error);
-    }
-}
-
-function startVersionPolling() {
-    stopVersionPolling();
-
-    if (currentNoteId) {
-        versionCheckInterval = setInterval(checkForNoteUpdates, VERSION_CHECK_INTERVAL_MS);
-    }
-}
-
-function stopVersionPolling() {
-    if (versionCheckInterval) {
-        clearInterval(versionCheckInterval);
-        versionCheckInterval = null;
-    }
-}
-
-function setCurrentNoteVersion(modifiedAt) {
-    currentNoteModifiedAt = modifiedAt;
-    startVersionPolling();
-}
-
-function showUpdateToast() {
-    const toast = document.getElementById('updateToast');
-    if (toast) {
-        toast.classList.remove('hidden');
-
-        setTimeout(() => {
-            toast.classList.add('hidden');
-        }, 2000);
-    }
-}
-
-async function autoReloadNote() {
-    if (currentNoteId) {
-        stopVersionPolling();
-        await loadNoteById(currentNoteId);
-        showUpdateToast();
-    }
-}
-
-window.addEventListener('load', init);

+ 0 - 259
desktop-app/main.js

@@ -1,259 +0,0 @@
-const { app, BrowserWindow, Menu, shell, dialog } = require('electron');
-const path = require('path');
-
-// Graceful auto-updater loading
-let autoUpdater = null;
-try {
-  autoUpdater = require('electron-updater').autoUpdater;
-  console.log('Auto-updater loaded successfully');
-} catch (error) {
-  console.log('Auto-updater not available:', error.message);
-}
-
-// Keep a global reference of the window object
-let mainWindow;
-
-function createWindow() {
-  // Create the browser window
-  mainWindow = new BrowserWindow({
-    width: 1200,
-    height: 800,
-    minWidth: 800,
-    minHeight: 600,
-    icon: path.join(__dirname, 'img/logo.png'),
-    webPreferences: {
-      nodeIntegration: false,
-      contextIsolation: true,
-      enableRemoteModule: false,
-      webSecurity: true
-    },
-    show: false // Don't show until ready
-  });
-
-  // Load the home page
-  mainWindow.loadFile(path.join(__dirname, 'home.html'));
-
-  // Show window when ready to prevent visual flash
-  mainWindow.once('ready-to-show', () => {
-    mainWindow.show();
-  });
-
-  // Handle external links
-  mainWindow.webContents.setWindowOpenHandler(({ url }) => {
-    shell.openExternal(url);
-    return { action: 'deny' };
-  });
-
-  // Emitted when the window is closed
-  mainWindow.on('closed', () => {
-    mainWindow = null;
-  });
-
-  // Create application menu
-  createMenu();
-}
-
-function createMenu() {
-  const template = [
-    {
-      label: 'File',
-      submenu: [
-        {
-          label: 'New Note',
-          accelerator: 'CmdOrCtrl+N',
-          click: () => {
-            mainWindow.loadFile(path.join(__dirname, 'index.html'));
-          }
-        },
-        {
-          label: 'Home',
-          accelerator: 'CmdOrCtrl+H',
-          click: () => {
-            mainWindow.loadFile(path.join(__dirname, 'home.html'));
-          }
-        },
-        { type: 'separator' },
-        {
-          label: 'Check for Updates',
-          click: () => {
-            if (autoUpdater) {
-              autoUpdater.checkForUpdatesAndNotify();
-            } else {
-              dialog.showMessageBox(mainWindow, {
-                type: 'info',
-                title: 'Auto-updater Not Available',
-                message: 'Automatic updates are not available in this build.',
-                detail: 'Please check for updates manually at: https://github.com/lhamacorp/knotes/releases',
-                buttons: ['OK']
-              });
-            }
-          }
-        },
-        { type: 'separator' },
-        {
-          label: 'Quit',
-          accelerator: process.platform === 'darwin' ? 'Cmd+Q' : 'Ctrl+Q',
-          click: () => {
-            app.quit();
-          }
-        }
-      ]
-    },
-    {
-      label: 'Edit',
-      submenu: [
-        { role: 'undo' },
-        { role: 'redo' },
-        { type: 'separator' },
-        { role: 'cut' },
-        { role: 'copy' },
-        { role: 'paste' },
-        { role: 'selectall' }
-      ]
-    },
-    {
-      label: 'View',
-      submenu: [
-        { role: 'reload' },
-        { role: 'forceReload' },
-        { role: 'toggleDevTools' },
-        { type: 'separator' },
-        { role: 'resetZoom' },
-        { role: 'zoomIn' },
-        { role: 'zoomOut' },
-        { type: 'separator' },
-        { role: 'togglefullscreen' }
-      ]
-    },
-    {
-      label: 'Window',
-      submenu: [
-        { role: 'minimize' },
-        { role: 'close' }
-      ]
-    }
-  ];
-
-  // macOS specific menu adjustments
-  if (process.platform === 'darwin') {
-    template.unshift({
-      label: app.getName(),
-      submenu: [
-        { role: 'about' },
-        { type: 'separator' },
-        { role: 'services' },
-        { type: 'separator' },
-        { role: 'hide' },
-        { role: 'hideothers' },
-        { role: 'unhide' },
-        { type: 'separator' },
-        { role: 'quit' }
-      ]
-    });
-
-    // Window menu
-    template[4].submenu = [
-      { role: 'close' },
-      { role: 'minimize' },
-      { role: 'zoom' },
-      { type: 'separator' },
-      { role: 'front' }
-    ];
-  }
-
-  const menu = Menu.buildFromTemplate(template);
-  Menu.setApplicationMenu(menu);
-}
-
-// Auto-updater configuration
-function setupAutoUpdater() {
-  // Skip if auto-updater is not available
-  if (!autoUpdater) {
-    console.log('Auto-updater not available, skipping setup');
-    return;
-  }
-
-  // Configure auto-updater
-  autoUpdater.checkForUpdatesAndNotify();
-
-  // Auto-updater events
-  autoUpdater.on('checking-for-update', () => {
-    console.log('Checking for update...');
-  });
-
-  autoUpdater.on('update-available', (info) => {
-    console.log('Update available:', info);
-
-    dialog.showMessageBox(mainWindow, {
-      type: 'info',
-      title: 'Update Available',
-      message: 'A new version is available. It will be downloaded in the background.',
-      detail: `Version ${info.version} is now available. The update will be downloaded and installed automatically.`,
-      buttons: ['OK']
-    });
-  });
-
-  autoUpdater.on('update-not-available', (info) => {
-    console.log('Update not available:', info);
-  });
-
-  autoUpdater.on('error', (err) => {
-    console.error('Error in auto-updater:', err);
-  });
-
-  autoUpdater.on('download-progress', (progressObj) => {
-    let log_message = "Download speed: " + progressObj.bytesPerSecond;
-    log_message = log_message + ' - Downloaded ' + progressObj.percent + '%';
-    log_message = log_message + ' (' + progressObj.transferred + "/" + progressObj.total + ')';
-    console.log(log_message);
-  });
-
-  autoUpdater.on('update-downloaded', (info) => {
-    console.log('Update downloaded:', info);
-
-    dialog.showMessageBox(mainWindow, {
-      type: 'info',
-      title: 'Update Ready',
-      message: 'Update downloaded and ready to install',
-      detail: 'The application will restart to apply the update.',
-      buttons: ['Restart Now', 'Later']
-    }).then((result) => {
-      if (result.response === 0) {
-        autoUpdater.quitAndInstall();
-      }
-    });
-  });
-}
-
-// This method will be called when Electron has finished initialization
-app.whenReady().then(() => {
-  createWindow();
-
-  // Set up auto-updater after window is created
-  setTimeout(() => {
-    setupAutoUpdater();
-  }, 3000); // Wait 3 seconds after app start
-
-  app.on('activate', () => {
-    // On macOS, re-create a window when the dock icon is clicked
-    if (BrowserWindow.getAllWindows().length === 0) {
-      createWindow();
-    }
-  });
-});
-
-// Quit when all windows are closed
-app.on('window-all-closed', () => {
-  // On macOS, keep the app running even when all windows are closed
-  if (process.platform !== 'darwin') {
-    app.quit();
-  }
-});
-
-// Security: Prevent new window creation
-app.on('web-contents-created', (event, contents) => {
-  contents.on('new-window', (event, url) => {
-    event.preventDefault();
-    shell.openExternal(url);
-  });
-});

+ 0 - 4192
desktop-app/package-lock.json

@@ -1,4192 +0,0 @@
-{
-  "name": "knotes-desktop",
-  "version": "1.1.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "knotes-desktop",
-      "version": "1.1.0",
-      "license": "MIT",
-      "dependencies": {
-        "electron-updater": "^6.1.7"
-      },
-      "devDependencies": {
-        "electron": "^28.2.0",
-        "electron-builder": "^24.9.1"
-      }
-    },
-    "node_modules/@develar/schema-utils": {
-      "version": "2.6.5",
-      "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz",
-      "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ajv": "^6.12.0",
-        "ajv-keywords": "^3.4.1"
-      },
-      "engines": {
-        "node": ">= 8.9.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
-    "node_modules/@electron/asar": {
-      "version": "3.4.1",
-      "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.4.1.tgz",
-      "integrity": "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "commander": "^5.0.0",
-        "glob": "^7.1.6",
-        "minimatch": "^3.0.4"
-      },
-      "bin": {
-        "asar": "bin/asar.js"
-      },
-      "engines": {
-        "node": ">=10.12.0"
-      }
-    },
-    "node_modules/@electron/asar/node_modules/brace-expansion": {
-      "version": "1.1.12",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
-      "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/@electron/asar/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/@electron/get": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz",
-      "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "debug": "^4.1.1",
-        "env-paths": "^2.2.0",
-        "fs-extra": "^8.1.0",
-        "got": "^11.8.5",
-        "progress": "^2.0.3",
-        "semver": "^6.2.0",
-        "sumchecker": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "global-agent": "^3.0.0"
-      }
-    },
-    "node_modules/@electron/notarize": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.2.1.tgz",
-      "integrity": "sha512-aL+bFMIkpR0cmmj5Zgy0LMKEpgy43/hw5zadEArgmAMWWlKc5buwFvFT9G/o/YJkvXAJm5q3iuTuLaiaXW39sg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "debug": "^4.1.1",
-        "fs-extra": "^9.0.1",
-        "promise-retry": "^2.0.1"
-      },
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/@electron/notarize/node_modules/fs-extra": {
-      "version": "9.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
-      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "at-least-node": "^1.0.0",
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@electron/notarize/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/@electron/notarize/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/@electron/osx-sign": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.5.tgz",
-      "integrity": "sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "compare-version": "^0.1.2",
-        "debug": "^4.3.4",
-        "fs-extra": "^10.0.0",
-        "isbinaryfile": "^4.0.8",
-        "minimist": "^1.2.6",
-        "plist": "^3.0.5"
-      },
-      "bin": {
-        "electron-osx-flat": "bin/electron-osx-flat.js",
-        "electron-osx-sign": "bin/electron-osx-sign.js"
-      },
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
-    "node_modules/@electron/osx-sign/node_modules/fs-extra": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@electron/osx-sign/node_modules/isbinaryfile": {
-      "version": "4.0.10",
-      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz",
-      "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 8.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/gjtorikian/"
-      }
-    },
-    "node_modules/@electron/osx-sign/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/@electron/osx-sign/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/@electron/universal": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.5.1.tgz",
-      "integrity": "sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@electron/asar": "^3.2.1",
-        "@malept/cross-spawn-promise": "^1.1.0",
-        "debug": "^4.3.1",
-        "dir-compare": "^3.0.0",
-        "fs-extra": "^9.0.1",
-        "minimatch": "^3.0.4",
-        "plist": "^3.0.4"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/@electron/universal/node_modules/brace-expansion": {
-      "version": "1.1.12",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
-      "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/@electron/universal/node_modules/fs-extra": {
-      "version": "9.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
-      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "at-least-node": "^1.0.0",
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@electron/universal/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/@electron/universal/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/@electron/universal/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/@isaacs/cliui": {
-      "version": "8.0.2",
-      "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
-      "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "string-width": "^5.1.2",
-        "string-width-cjs": "npm:string-width@^4.2.0",
-        "strip-ansi": "^7.0.1",
-        "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
-        "wrap-ansi": "^8.1.0",
-        "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
-      "version": "6.2.2",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
-      "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
-      }
-    },
-    "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
-      "version": "6.2.3",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
-      "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
-      "version": "9.2.2",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
-      "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@isaacs/cliui/node_modules/string-width": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
-      "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "eastasianwidth": "^0.2.0",
-        "emoji-regex": "^9.2.2",
-        "strip-ansi": "^7.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
-      "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
-      }
-    },
-    "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
-      "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^6.1.0",
-        "string-width": "^5.0.1",
-        "strip-ansi": "^7.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-      }
-    },
-    "node_modules/@malept/cross-spawn-promise": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz",
-      "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/malept"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund"
-        }
-      ],
-      "license": "Apache-2.0",
-      "dependencies": {
-        "cross-spawn": "^7.0.1"
-      },
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@malept/flatpak-bundler": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz",
-      "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "debug": "^4.1.1",
-        "fs-extra": "^9.0.0",
-        "lodash": "^4.17.15",
-        "tmp-promise": "^3.0.2"
-      },
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/@malept/flatpak-bundler/node_modules/fs-extra": {
-      "version": "9.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
-      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "at-least-node": "^1.0.0",
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@malept/flatpak-bundler/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/@malept/flatpak-bundler/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/@pkgjs/parseargs": {
-      "version": "0.11.0",
-      "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
-      "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/@sindresorhus/is": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
-      "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/is?sponsor=1"
-      }
-    },
-    "node_modules/@szmarczak/http-timer": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
-      "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "defer-to-connect": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@tootallnate/once": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
-      "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@types/cacheable-request": {
-      "version": "6.0.3",
-      "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
-      "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/http-cache-semantics": "*",
-        "@types/keyv": "^3.1.4",
-        "@types/node": "*",
-        "@types/responselike": "^1.0.0"
-      }
-    },
-    "node_modules/@types/debug": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
-      "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/ms": "*"
-      }
-    },
-    "node_modules/@types/fs-extra": {
-      "version": "9.0.13",
-      "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
-      "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@types/http-cache-semantics": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
-      "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@types/keyv": {
-      "version": "3.1.4",
-      "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
-      "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@types/ms": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
-      "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@types/node": {
-      "version": "18.19.130",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz",
-      "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "undici-types": "~5.26.4"
-      }
-    },
-    "node_modules/@types/plist": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz",
-      "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "@types/node": "*",
-        "xmlbuilder": ">=11.0.1"
-      }
-    },
-    "node_modules/@types/responselike": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz",
-      "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@types/verror": {
-      "version": "1.10.11",
-      "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz",
-      "integrity": "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true
-    },
-    "node_modules/@types/yauzl": {
-      "version": "2.10.3",
-      "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
-      "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
-    "node_modules/@xmldom/xmldom": {
-      "version": "0.8.11",
-      "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz",
-      "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/7zip-bin": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz",
-      "integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/agent-base": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
-      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 6.0.0"
-      }
-    },
-    "node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/ajv-keywords": {
-      "version": "3.5.2",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
-      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-      "dev": true,
-      "license": "MIT",
-      "peerDependencies": {
-        "ajv": "^6.9.1"
-      }
-    },
-    "node_modules/ansi-regex": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/app-builder-bin": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz",
-      "integrity": "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/app-builder-lib": {
-      "version": "24.13.3",
-      "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.13.3.tgz",
-      "integrity": "sha512-FAzX6IBit2POXYGnTCT8YHFO/lr5AapAII6zzhQO3Rw4cEDOgK+t1xhLc5tNcKlicTHlo9zxIwnYCX9X2DLkig==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@develar/schema-utils": "~2.6.5",
-        "@electron/notarize": "2.2.1",
-        "@electron/osx-sign": "1.0.5",
-        "@electron/universal": "1.5.1",
-        "@malept/flatpak-bundler": "^0.4.0",
-        "@types/fs-extra": "9.0.13",
-        "async-exit-hook": "^2.0.1",
-        "bluebird-lst": "^1.0.9",
-        "builder-util": "24.13.1",
-        "builder-util-runtime": "9.2.4",
-        "chromium-pickle-js": "^0.2.0",
-        "debug": "^4.3.4",
-        "ejs": "^3.1.8",
-        "electron-publish": "24.13.1",
-        "form-data": "^4.0.0",
-        "fs-extra": "^10.1.0",
-        "hosted-git-info": "^4.1.0",
-        "is-ci": "^3.0.0",
-        "isbinaryfile": "^5.0.0",
-        "js-yaml": "^4.1.0",
-        "lazy-val": "^1.0.5",
-        "minimatch": "^5.1.1",
-        "read-config-file": "6.3.2",
-        "sanitize-filename": "^1.6.3",
-        "semver": "^7.3.8",
-        "tar": "^6.1.12",
-        "temp-file": "^3.4.0"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      },
-      "peerDependencies": {
-        "dmg-builder": "24.13.3",
-        "electron-builder-squirrel-windows": "24.13.3"
-      }
-    },
-    "node_modules/app-builder-lib/node_modules/fs-extra": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/app-builder-lib/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/app-builder-lib/node_modules/semver": {
-      "version": "7.7.3",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
-      "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
-      "dev": true,
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/app-builder-lib/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/archiver": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz",
-      "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "archiver-utils": "^2.1.0",
-        "async": "^3.2.4",
-        "buffer-crc32": "^0.2.1",
-        "readable-stream": "^3.6.0",
-        "readdir-glob": "^1.1.2",
-        "tar-stream": "^2.2.0",
-        "zip-stream": "^4.1.0"
-      },
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/archiver-utils": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
-      "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "glob": "^7.1.4",
-        "graceful-fs": "^4.2.0",
-        "lazystream": "^1.0.0",
-        "lodash.defaults": "^4.2.0",
-        "lodash.difference": "^4.5.0",
-        "lodash.flatten": "^4.4.0",
-        "lodash.isplainobject": "^4.0.6",
-        "lodash.union": "^4.6.0",
-        "normalize-path": "^3.0.0",
-        "readable-stream": "^2.0.0"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/archiver-utils/node_modules/readable-stream": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
-      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.3",
-        "isarray": "~1.0.0",
-        "process-nextick-args": "~2.0.0",
-        "safe-buffer": "~5.1.1",
-        "string_decoder": "~1.1.1",
-        "util-deprecate": "~1.0.1"
-      }
-    },
-    "node_modules/archiver-utils/node_modules/safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/archiver-utils/node_modules/string_decoder": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/argparse": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
-      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
-      "license": "Python-2.0"
-    },
-    "node_modules/assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/astral-regex": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
-      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/async": {
-      "version": "3.2.6",
-      "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
-      "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/async-exit-hook": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz",
-      "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/at-least-node": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
-      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">= 4.0.0"
-      }
-    },
-    "node_modules/balanced-match": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/base64-js": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
-      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "MIT"
-    },
-    "node_modules/bl": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
-      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "buffer": "^5.5.0",
-        "inherits": "^2.0.4",
-        "readable-stream": "^3.4.0"
-      }
-    },
-    "node_modules/bluebird": {
-      "version": "3.7.2",
-      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
-      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/bluebird-lst": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz",
-      "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "bluebird": "^3.5.5"
-      }
-    },
-    "node_modules/boolean": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
-      "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
-      "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
-      "dev": true,
-      "license": "MIT",
-      "optional": true
-    },
-    "node_modules/brace-expansion": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
-      "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0"
-      }
-    },
-    "node_modules/buffer": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
-      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "base64-js": "^1.3.1",
-        "ieee754": "^1.1.13"
-      }
-    },
-    "node_modules/buffer-crc32": {
-      "version": "0.2.13",
-      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/buffer-equal": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz",
-      "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/buffer-from": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
-      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/builder-util": {
-      "version": "24.13.1",
-      "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.13.1.tgz",
-      "integrity": "sha512-NhbCSIntruNDTOVI9fdXz0dihaqX2YuE1D6zZMrwiErzH4ELZHE6mdiB40wEgZNprDia+FghRFgKoAqMZRRjSA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/debug": "^4.1.6",
-        "7zip-bin": "~5.2.0",
-        "app-builder-bin": "4.0.0",
-        "bluebird-lst": "^1.0.9",
-        "builder-util-runtime": "9.2.4",
-        "chalk": "^4.1.2",
-        "cross-spawn": "^7.0.3",
-        "debug": "^4.3.4",
-        "fs-extra": "^10.1.0",
-        "http-proxy-agent": "^5.0.0",
-        "https-proxy-agent": "^5.0.1",
-        "is-ci": "^3.0.0",
-        "js-yaml": "^4.1.0",
-        "source-map-support": "^0.5.19",
-        "stat-mode": "^1.0.0",
-        "temp-file": "^3.4.0"
-      }
-    },
-    "node_modules/builder-util-runtime": {
-      "version": "9.2.4",
-      "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz",
-      "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "debug": "^4.3.4",
-        "sax": "^1.2.4"
-      },
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
-    "node_modules/builder-util/node_modules/fs-extra": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/builder-util/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/builder-util/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/cacheable-lookup": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
-      "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10.6.0"
-      }
-    },
-    "node_modules/cacheable-request": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
-      "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "clone-response": "^1.0.2",
-        "get-stream": "^5.1.0",
-        "http-cache-semantics": "^4.0.0",
-        "keyv": "^4.0.0",
-        "lowercase-keys": "^2.0.0",
-        "normalize-url": "^6.0.1",
-        "responselike": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/call-bind-apply-helpers": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
-      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0",
-        "function-bind": "^1.1.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
-    "node_modules/chownr": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
-      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/chromium-pickle-js": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
-      "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/ci-info": {
-      "version": "3.9.0",
-      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
-      "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/sibiraj-s"
-        }
-      ],
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/cli-truncate": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
-      "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "slice-ansi": "^3.0.0",
-        "string-width": "^4.2.0"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/cliui": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
-      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.1",
-        "wrap-ansi": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/clone-response": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
-      "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "mimic-response": "^1.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/combined-stream": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
-      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "delayed-stream": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/commander": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
-      "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/compare-version": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz",
-      "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/compress-commons": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz",
-      "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "buffer-crc32": "^0.2.13",
-        "crc32-stream": "^4.0.2",
-        "normalize-path": "^3.0.0",
-        "readable-stream": "^3.6.0"
-      },
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/config-file-ts": {
-      "version": "0.2.6",
-      "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.6.tgz",
-      "integrity": "sha512-6boGVaglwblBgJqGyxm4+xCmEGcWgnWHSWHY5jad58awQhB6gftq0G8HbzU39YqCIYHMLAiL1yjwiZ36m/CL8w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "glob": "^10.3.10",
-        "typescript": "^5.3.3"
-      }
-    },
-    "node_modules/config-file-ts/node_modules/glob": {
-      "version": "10.5.0",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
-      "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "foreground-child": "^3.1.0",
-        "jackspeak": "^3.1.2",
-        "minimatch": "^9.0.4",
-        "minipass": "^7.1.2",
-        "package-json-from-dist": "^1.0.0",
-        "path-scurry": "^1.11.1"
-      },
-      "bin": {
-        "glob": "dist/esm/bin.mjs"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/config-file-ts/node_modules/minimatch": {
-      "version": "9.0.5",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
-      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/config-file-ts/node_modules/minipass": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
-      "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      }
-    },
-    "node_modules/core-util-is": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/crc": {
-      "version": "3.8.0",
-      "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
-      "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "buffer": "^5.1.0"
-      }
-    },
-    "node_modules/crc-32": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
-      "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "peer": true,
-      "bin": {
-        "crc32": "bin/crc32.njs"
-      },
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/crc32-stream": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz",
-      "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "crc-32": "^1.2.0",
-        "readable-stream": "^3.4.0"
-      },
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/cross-spawn": {
-      "version": "7.0.6",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
-      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/debug": {
-      "version": "4.4.3",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
-      "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/decompress-response": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
-      "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "mimic-response": "^3.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/decompress-response/node_modules/mimic-response": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
-      "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/defer-to-connect": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
-      "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/define-data-property": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
-      "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "es-define-property": "^1.0.0",
-        "es-errors": "^1.3.0",
-        "gopd": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/define-properties": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
-      "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "define-data-property": "^1.0.1",
-        "has-property-descriptors": "^1.0.0",
-        "object-keys": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/detect-node": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
-      "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true
-    },
-    "node_modules/dir-compare": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz",
-      "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "buffer-equal": "^1.0.0",
-        "minimatch": "^3.0.4"
-      }
-    },
-    "node_modules/dir-compare/node_modules/brace-expansion": {
-      "version": "1.1.12",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
-      "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/dir-compare/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/dmg-builder": {
-      "version": "24.13.3",
-      "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.13.3.tgz",
-      "integrity": "sha512-rcJUkMfnJpfCboZoOOPf4L29TRtEieHNOeAbYPWPxlaBw/Z1RKrRA86dOI9rwaI4tQSc/RD82zTNHprfUHXsoQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "app-builder-lib": "24.13.3",
-        "builder-util": "24.13.1",
-        "builder-util-runtime": "9.2.4",
-        "fs-extra": "^10.1.0",
-        "iconv-lite": "^0.6.2",
-        "js-yaml": "^4.1.0"
-      },
-      "optionalDependencies": {
-        "dmg-license": "^1.0.11"
-      }
-    },
-    "node_modules/dmg-builder/node_modules/fs-extra": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/dmg-builder/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/dmg-builder/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/dmg-license": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz",
-      "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "dependencies": {
-        "@types/plist": "^3.0.1",
-        "@types/verror": "^1.10.3",
-        "ajv": "^6.10.0",
-        "crc": "^3.8.0",
-        "iconv-corefoundation": "^1.1.7",
-        "plist": "^3.0.4",
-        "smart-buffer": "^4.0.2",
-        "verror": "^1.10.0"
-      },
-      "bin": {
-        "dmg-license": "bin/dmg-license.js"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/dotenv": {
-      "version": "9.0.2",
-      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz",
-      "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/dotenv-expand": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
-      "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
-      "dev": true,
-      "license": "BSD-2-Clause"
-    },
-    "node_modules/dunder-proto": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
-      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "call-bind-apply-helpers": "^1.0.1",
-        "es-errors": "^1.3.0",
-        "gopd": "^1.2.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/eastasianwidth": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
-      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/ejs": {
-      "version": "3.1.10",
-      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
-      "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "jake": "^10.8.5"
-      },
-      "bin": {
-        "ejs": "bin/cli.js"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/electron": {
-      "version": "28.3.3",
-      "resolved": "https://registry.npmjs.org/electron/-/electron-28.3.3.tgz",
-      "integrity": "sha512-ObKMLSPNhomtCOBAxFS8P2DW/4umkh72ouZUlUKzXGtYuPzgr1SYhskhFWgzAsPtUzhL2CzyV2sfbHcEW4CXqw==",
-      "dev": true,
-      "hasInstallScript": true,
-      "license": "MIT",
-      "dependencies": {
-        "@electron/get": "^2.0.0",
-        "@types/node": "^18.11.18",
-        "extract-zip": "^2.0.1"
-      },
-      "bin": {
-        "electron": "cli.js"
-      },
-      "engines": {
-        "node": ">= 12.20.55"
-      }
-    },
-    "node_modules/electron-builder": {
-      "version": "24.13.3",
-      "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.13.3.tgz",
-      "integrity": "sha512-yZSgVHft5dNVlo31qmJAe4BVKQfFdwpRw7sFp1iQglDRCDD6r22zfRJuZlhtB5gp9FHUxCMEoWGq10SkCnMAIg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "app-builder-lib": "24.13.3",
-        "builder-util": "24.13.1",
-        "builder-util-runtime": "9.2.4",
-        "chalk": "^4.1.2",
-        "dmg-builder": "24.13.3",
-        "fs-extra": "^10.1.0",
-        "is-ci": "^3.0.0",
-        "lazy-val": "^1.0.5",
-        "read-config-file": "6.3.2",
-        "simple-update-notifier": "2.0.0",
-        "yargs": "^17.6.2"
-      },
-      "bin": {
-        "electron-builder": "cli.js",
-        "install-app-deps": "install-app-deps.js"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/electron-builder-squirrel-windows": {
-      "version": "24.13.3",
-      "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-24.13.3.tgz",
-      "integrity": "sha512-oHkV0iogWfyK+ah9ZIvMDpei1m9ZRpdXcvde1wTpra2U8AFDNNpqJdnin5z+PM1GbQ5BoaKCWas2HSjtR0HwMg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "app-builder-lib": "24.13.3",
-        "archiver": "^5.3.1",
-        "builder-util": "24.13.1",
-        "fs-extra": "^10.1.0"
-      }
-    },
-    "node_modules/electron-builder-squirrel-windows/node_modules/fs-extra": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/electron-builder-squirrel-windows/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/electron-builder-squirrel-windows/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/electron-builder/node_modules/fs-extra": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/electron-builder/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/electron-builder/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/electron-publish": {
-      "version": "24.13.1",
-      "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.13.1.tgz",
-      "integrity": "sha512-2ZgdEqJ8e9D17Hwp5LEq5mLQPjqU3lv/IALvgp+4W8VeNhryfGhYEQC/PgDPMrnWUp+l60Ou5SJLsu+k4mhQ8A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/fs-extra": "^9.0.11",
-        "builder-util": "24.13.1",
-        "builder-util-runtime": "9.2.4",
-        "chalk": "^4.1.2",
-        "fs-extra": "^10.1.0",
-        "lazy-val": "^1.0.5",
-        "mime": "^2.5.2"
-      }
-    },
-    "node_modules/electron-publish/node_modules/fs-extra": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/electron-publish/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/electron-publish/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/electron-updater": {
-      "version": "6.7.3",
-      "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.7.3.tgz",
-      "integrity": "sha512-EgkT8Z9noqXKbwc3u5FkJA+r48jwZ5DTUiOkJMOTEEH//n5Am6wfQGz7nvSFEA2oIAMv9jRzn5JKTyWeSKOPgg==",
-      "license": "MIT",
-      "dependencies": {
-        "builder-util-runtime": "9.5.1",
-        "fs-extra": "^10.1.0",
-        "js-yaml": "^4.1.0",
-        "lazy-val": "^1.0.5",
-        "lodash.escaperegexp": "^4.1.2",
-        "lodash.isequal": "^4.5.0",
-        "semver": "~7.7.3",
-        "tiny-typed-emitter": "^2.1.0"
-      }
-    },
-    "node_modules/electron-updater/node_modules/builder-util-runtime": {
-      "version": "9.5.1",
-      "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.5.1.tgz",
-      "integrity": "sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ==",
-      "license": "MIT",
-      "dependencies": {
-        "debug": "^4.3.4",
-        "sax": "^1.2.4"
-      },
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
-    "node_modules/electron-updater/node_modules/fs-extra": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/electron-updater/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/electron-updater/node_modules/semver": {
-      "version": "7.7.3",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
-      "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/electron-updater/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/end-of-stream": {
-      "version": "1.4.5",
-      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
-      "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "once": "^1.4.0"
-      }
-    },
-    "node_modules/env-paths": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
-      "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/err-code": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
-      "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/es-define-property": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
-      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-errors": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
-      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-object-atoms": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
-      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-set-tostringtag": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
-      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0",
-        "get-intrinsic": "^1.2.6",
-        "has-tostringtag": "^1.0.2",
-        "hasown": "^2.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es6-error": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
-      "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true
-    },
-    "node_modules/escalade": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
-      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/escape-string-regexp": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/extract-zip": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
-      "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "debug": "^4.1.1",
-        "get-stream": "^5.1.0",
-        "yauzl": "^2.10.0"
-      },
-      "bin": {
-        "extract-zip": "cli.js"
-      },
-      "engines": {
-        "node": ">= 10.17.0"
-      },
-      "optionalDependencies": {
-        "@types/yauzl": "^2.9.1"
-      }
-    },
-    "node_modules/extsprintf": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz",
-      "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "license": "MIT",
-      "optional": true
-    },
-    "node_modules/fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/fd-slicer": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
-      "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "pend": "~1.2.0"
-      }
-    },
-    "node_modules/filelist": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
-      "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "minimatch": "^5.0.1"
-      }
-    },
-    "node_modules/foreground-child": {
-      "version": "3.3.1",
-      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
-      "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "cross-spawn": "^7.0.6",
-        "signal-exit": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/form-data": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
-      "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.8",
-        "es-set-tostringtag": "^2.1.0",
-        "hasown": "^2.0.2",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/fs-constants": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
-      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/fs-extra": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
-      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=6 <7 || >=8"
-      }
-    },
-    "node_modules/fs-minipass": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
-      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "minipass": "^3.0.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/fs-minipass/node_modules/minipass": {
-      "version": "3.3.6",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
-      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/function-bind": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
-      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
-      "dev": true,
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/get-caller-file": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
-      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": "6.* || 8.* || >= 10.*"
-      }
-    },
-    "node_modules/get-intrinsic": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
-      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "call-bind-apply-helpers": "^1.0.2",
-        "es-define-property": "^1.0.1",
-        "es-errors": "^1.3.0",
-        "es-object-atoms": "^1.1.1",
-        "function-bind": "^1.1.2",
-        "get-proto": "^1.0.1",
-        "gopd": "^1.2.0",
-        "has-symbols": "^1.1.0",
-        "hasown": "^2.0.2",
-        "math-intrinsics": "^1.1.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/get-proto": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
-      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "dunder-proto": "^1.0.1",
-        "es-object-atoms": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/get-stream": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
-      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
-      "deprecated": "Glob versions prior to v9 are no longer supported",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/glob/node_modules/brace-expansion": {
-      "version": "1.1.12",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
-      "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/glob/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/global-agent": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
-      "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
-      "dev": true,
-      "license": "BSD-3-Clause",
-      "optional": true,
-      "dependencies": {
-        "boolean": "^3.0.1",
-        "es6-error": "^4.1.1",
-        "matcher": "^3.0.0",
-        "roarr": "^2.15.3",
-        "semver": "^7.3.2",
-        "serialize-error": "^7.0.1"
-      },
-      "engines": {
-        "node": ">=10.0"
-      }
-    },
-    "node_modules/global-agent/node_modules/semver": {
-      "version": "7.7.3",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
-      "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
-      "dev": true,
-      "license": "ISC",
-      "optional": true,
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/globalthis": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
-      "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "define-properties": "^1.2.1",
-        "gopd": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/gopd": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
-      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/got": {
-      "version": "11.8.6",
-      "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
-      "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@sindresorhus/is": "^4.0.0",
-        "@szmarczak/http-timer": "^4.0.5",
-        "@types/cacheable-request": "^6.0.1",
-        "@types/responselike": "^1.0.0",
-        "cacheable-lookup": "^5.0.3",
-        "cacheable-request": "^7.0.2",
-        "decompress-response": "^6.0.0",
-        "http2-wrapper": "^1.0.0-beta.5.2",
-        "lowercase-keys": "^2.0.0",
-        "p-cancelable": "^2.0.0",
-        "responselike": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10.19.0"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/got?sponsor=1"
-      }
-    },
-    "node_modules/graceful-fs": {
-      "version": "4.2.11",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
-      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
-      "license": "ISC"
-    },
-    "node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/has-property-descriptors": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
-      "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "es-define-property": "^1.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/has-symbols": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
-      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/has-tostringtag": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
-      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "has-symbols": "^1.0.3"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/hasown": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
-      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "function-bind": "^1.1.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/hosted-git-info": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
-      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/http-cache-semantics": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
-      "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==",
-      "dev": true,
-      "license": "BSD-2-Clause"
-    },
-    "node_modules/http-proxy-agent": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
-      "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@tootallnate/once": "2",
-        "agent-base": "6",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/http2-wrapper": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
-      "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "quick-lru": "^5.1.1",
-        "resolve-alpn": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=10.19.0"
-      }
-    },
-    "node_modules/https-proxy-agent": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
-      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "6",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/iconv-corefoundation": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz",
-      "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "dependencies": {
-        "cli-truncate": "^2.1.0",
-        "node-addon-api": "^1.6.3"
-      },
-      "engines": {
-        "node": "^8.11.2 || >=10"
-      }
-    },
-    "node_modules/iconv-lite": {
-      "version": "0.6.3",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
-      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ieee754": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
-      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
-      "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "once": "^1.3.0",
-        "wrappy": "1"
-      }
-    },
-    "node_modules/inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/is-ci": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
-      "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ci-info": "^3.2.0"
-      },
-      "bin": {
-        "is-ci": "bin.js"
-      }
-    },
-    "node_modules/is-fullwidth-code-point": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/isbinaryfile": {
-      "version": "5.0.7",
-      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.7.tgz",
-      "integrity": "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 18.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/gjtorikian/"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/jackspeak": {
-      "version": "3.4.3",
-      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
-      "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
-      "dev": true,
-      "license": "BlueOak-1.0.0",
-      "dependencies": {
-        "@isaacs/cliui": "^8.0.2"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      },
-      "optionalDependencies": {
-        "@pkgjs/parseargs": "^0.11.0"
-      }
-    },
-    "node_modules/jake": {
-      "version": "10.9.4",
-      "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz",
-      "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "async": "^3.2.6",
-        "filelist": "^1.0.4",
-        "picocolors": "^1.1.1"
-      },
-      "bin": {
-        "jake": "bin/cli.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/js-yaml": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
-      "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
-      "license": "MIT",
-      "dependencies": {
-        "argparse": "^2.0.1"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
-    "node_modules/json-buffer": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
-      "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/json-stringify-safe": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
-      "dev": true,
-      "license": "ISC",
-      "optional": true
-    },
-    "node_modules/json5": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
-      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "json5": "lib/cli.js"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/jsonfile": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
-      "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
-      "dev": true,
-      "license": "MIT",
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/keyv": {
-      "version": "4.5.4",
-      "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
-      "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "json-buffer": "3.0.1"
-      }
-    },
-    "node_modules/lazy-val": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
-      "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
-      "license": "MIT"
-    },
-    "node_modules/lazystream": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
-      "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "readable-stream": "^2.0.5"
-      },
-      "engines": {
-        "node": ">= 0.6.3"
-      }
-    },
-    "node_modules/lazystream/node_modules/readable-stream": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
-      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.3",
-        "isarray": "~1.0.0",
-        "process-nextick-args": "~2.0.0",
-        "safe-buffer": "~5.1.1",
-        "string_decoder": "~1.1.1",
-        "util-deprecate": "~1.0.1"
-      }
-    },
-    "node_modules/lazystream/node_modules/safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/lazystream/node_modules/string_decoder": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "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/lodash.defaults": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
-      "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/lodash.difference": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
-      "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/lodash.escaperegexp": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
-      "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==",
-      "license": "MIT"
-    },
-    "node_modules/lodash.flatten": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
-      "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/lodash.isequal": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
-      "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
-      "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.",
-      "license": "MIT"
-    },
-    "node_modules/lodash.isplainobject": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
-      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/lodash.union": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
-      "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/lowercase-keys": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
-      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/matcher": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
-      "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "escape-string-regexp": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/math-intrinsics": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
-      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/mime": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
-      "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "mime": "cli.js"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mimic-response": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
-      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/minimatch": {
-      "version": "5.1.6",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
-      "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/minimist": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
-      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
-      "dev": true,
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/minipass": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
-      "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/minizlib": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
-      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "minipass": "^3.0.0",
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/minizlib/node_modules/minipass": {
-      "version": "3.3.6",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
-      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/mkdirp": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
-      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "mkdirp": "bin/cmd.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/node-addon-api": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
-      "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true
-    },
-    "node_modules/normalize-path": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
-      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/normalize-url": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
-      "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/object-keys": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
-      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "wrappy": "1"
-      }
-    },
-    "node_modules/p-cancelable": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
-      "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/package-json-from-dist": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
-      "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
-      "dev": true,
-      "license": "BlueOak-1.0.0"
-    },
-    "node_modules/path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/path-scurry": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
-      "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
-      "dev": true,
-      "license": "BlueOak-1.0.0",
-      "dependencies": {
-        "lru-cache": "^10.2.0",
-        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/path-scurry/node_modules/lru-cache": {
-      "version": "10.4.3",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
-      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/pend": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/picocolors": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
-      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/plist": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
-      "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@xmldom/xmldom": "^0.8.8",
-        "base64-js": "^1.5.1",
-        "xmlbuilder": "^15.1.1"
-      },
-      "engines": {
-        "node": ">=10.4.0"
-      }
-    },
-    "node_modules/process-nextick-args": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
-      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/progress": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
-      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/promise-retry": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
-      "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "err-code": "^2.0.2",
-        "retry": "^0.12.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/pump": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
-      "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.1"
-      }
-    },
-    "node_modules/punycode": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
-      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/quick-lru": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
-      "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/read-config-file": {
-      "version": "6.3.2",
-      "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz",
-      "integrity": "sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "config-file-ts": "^0.2.4",
-        "dotenv": "^9.0.2",
-        "dotenv-expand": "^5.1.0",
-        "js-yaml": "^4.1.0",
-        "json5": "^2.2.0",
-        "lazy-val": "^1.0.4"
-      },
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
-    "node_modules/readable-stream": {
-      "version": "3.6.2",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
-      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/readdir-glob": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz",
-      "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "peer": true,
-      "dependencies": {
-        "minimatch": "^5.1.0"
-      }
-    },
-    "node_modules/require-directory": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/resolve-alpn": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
-      "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/responselike": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
-      "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "lowercase-keys": "^2.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/retry": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
-      "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/roarr": {
-      "version": "2.15.4",
-      "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
-      "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
-      "dev": true,
-      "license": "BSD-3-Clause",
-      "optional": true,
-      "dependencies": {
-        "boolean": "^3.0.1",
-        "detect-node": "^2.0.4",
-        "globalthis": "^1.0.1",
-        "json-stringify-safe": "^5.0.1",
-        "semver-compare": "^1.0.0",
-        "sprintf-js": "^1.1.2"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/safe-buffer": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
-      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/sanitize-filename": {
-      "version": "1.6.3",
-      "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
-      "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
-      "dev": true,
-      "license": "WTFPL OR ISC",
-      "dependencies": {
-        "truncate-utf8-bytes": "^1.0.0"
-      }
-    },
-    "node_modules/sax": {
-      "version": "1.4.4",
-      "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz",
-      "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==",
-      "license": "BlueOak-1.0.0",
-      "engines": {
-        "node": ">=11.0.0"
-      }
-    },
-    "node_modules/semver": {
-      "version": "6.3.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
-      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
-      "dev": true,
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      }
-    },
-    "node_modules/semver-compare": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
-      "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true
-    },
-    "node_modules/serialize-error": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
-      "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "type-fest": "^0.13.1"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "shebang-regex": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/signal-exit": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
-      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/simple-update-notifier": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
-      "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "semver": "^7.5.3"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/simple-update-notifier/node_modules/semver": {
-      "version": "7.7.3",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
-      "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
-      "dev": true,
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/slice-ansi": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
-      "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "astral-regex": "^2.0.0",
-        "is-fullwidth-code-point": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/smart-buffer": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
-      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "engines": {
-        "node": ">= 6.0.0",
-        "npm": ">= 3.0.0"
-      }
-    },
-    "node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/source-map-support": {
-      "version": "0.5.21",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
-      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "buffer-from": "^1.0.0",
-        "source-map": "^0.6.0"
-      }
-    },
-    "node_modules/sprintf-js": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
-      "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
-      "dev": true,
-      "license": "BSD-3-Clause",
-      "optional": true
-    },
-    "node_modules/stat-mode": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz",
-      "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/string_decoder": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
-      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "safe-buffer": "~5.2.0"
-      }
-    },
-    "node_modules/string-width": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/string-width-cjs": {
-      "name": "string-width",
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/strip-ansi": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/strip-ansi-cjs": {
-      "name": "strip-ansi",
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/sumchecker": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
-      "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "debug": "^4.1.0"
-      },
-      "engines": {
-        "node": ">= 8.0"
-      }
-    },
-    "node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/tar": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
-      "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "chownr": "^2.0.0",
-        "fs-minipass": "^2.0.0",
-        "minipass": "^5.0.0",
-        "minizlib": "^2.1.1",
-        "mkdirp": "^1.0.3",
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/tar-stream": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
-      "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "bl": "^4.0.3",
-        "end-of-stream": "^1.4.1",
-        "fs-constants": "^1.0.0",
-        "inherits": "^2.0.3",
-        "readable-stream": "^3.1.1"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/temp-file": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz",
-      "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "async-exit-hook": "^2.0.1",
-        "fs-extra": "^10.0.0"
-      }
-    },
-    "node_modules/temp-file/node_modules/fs-extra": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/temp-file/node_modules/jsonfile": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
-      "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/temp-file/node_modules/universalify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/tiny-typed-emitter": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz",
-      "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==",
-      "license": "MIT"
-    },
-    "node_modules/tmp": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
-      "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=14.14"
-      }
-    },
-    "node_modules/tmp-promise": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz",
-      "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "tmp": "^0.2.0"
-      }
-    },
-    "node_modules/truncate-utf8-bytes": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
-      "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==",
-      "dev": true,
-      "license": "WTFPL",
-      "dependencies": {
-        "utf8-byte-length": "^1.0.1"
-      }
-    },
-    "node_modules/type-fest": {
-      "version": "0.13.1",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
-      "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
-      "dev": true,
-      "license": "(MIT OR CC0-1.0)",
-      "optional": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "5.9.3",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
-      "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
-    "node_modules/undici-types": {
-      "version": "5.26.5",
-      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
-      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/universalify": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
-      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 4.0.0"
-      }
-    },
-    "node_modules/uri-js": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
-      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
-      "dev": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "punycode": "^2.1.0"
-      }
-    },
-    "node_modules/utf8-byte-length": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
-      "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==",
-      "dev": true,
-      "license": "(WTFPL OR MIT)"
-    },
-    "node_modules/util-deprecate": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true
-    },
-    "node_modules/verror": {
-      "version": "1.10.1",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz",
-      "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "^1.2.0"
-      },
-      "engines": {
-        "node": ">=0.6.0"
-      }
-    },
-    "node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/wrap-ansi": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-      }
-    },
-    "node_modules/wrap-ansi-cjs": {
-      "name": "wrap-ansi",
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-      }
-    },
-    "node_modules/wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/xmlbuilder": {
-      "version": "15.1.1",
-      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
-      "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/y18n": {
-      "version": "5.0.8",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
-      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/yallist": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/yargs": {
-      "version": "17.7.2",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
-      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "cliui": "^8.0.1",
-        "escalade": "^3.1.1",
-        "get-caller-file": "^2.0.5",
-        "require-directory": "^2.1.1",
-        "string-width": "^4.2.3",
-        "y18n": "^5.0.5",
-        "yargs-parser": "^21.1.1"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/yargs-parser": {
-      "version": "21.1.1",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
-      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/yauzl": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
-      "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "buffer-crc32": "~0.2.3",
-        "fd-slicer": "~1.1.0"
-      }
-    },
-    "node_modules/zip-stream": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz",
-      "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "archiver-utils": "^3.0.4",
-        "compress-commons": "^4.1.2",
-        "readable-stream": "^3.6.0"
-      },
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/zip-stream/node_modules/archiver-utils": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz",
-      "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==",
-      "dev": true,
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "glob": "^7.2.3",
-        "graceful-fs": "^4.2.0",
-        "lazystream": "^1.0.0",
-        "lodash.defaults": "^4.2.0",
-        "lodash.difference": "^4.5.0",
-        "lodash.flatten": "^4.4.0",
-        "lodash.isplainobject": "^4.0.6",
-        "lodash.union": "^4.6.0",
-        "normalize-path": "^3.0.0",
-        "readable-stream": "^3.6.0"
-      },
-      "engines": {
-        "node": ">= 10"
-      }
-    }
-  }
-}

+ 0 - 64
desktop-app/package.json

@@ -1,64 +0,0 @@
-{
-  "name": "knotes-desktop",
-  "version": "1.2.1",
-  "description": "kNotes Desktop App - A simple notes application",
-  "main": "main.js",
-  "scripts": {
-    "start": "electron .",
-    "build": "electron-builder",
-    "build-all": "electron-builder -mwl",
-    "build-win": "electron-builder --win --publish=never",
-    "build-mac": "electron-builder --mac --publish=never",
-    "build-linux": "electron-builder --linux --publish=never",
-    "dist": "electron-builder --publish=never",
-    "publish": "electron-builder --publish=always",
-    "publish-linux": "electron-builder --linux --publish=always",
-    "publish-win": "electron-builder --win --publish=always",
-    "publish-mac": "electron-builder --mac --publish=always"
-  },
-  "author": "lhamacorp",
-  "license": "MIT",
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/lhamacorp/knotes.git"
-  },
-  "dependencies": {
-    "electron-updater": "^6.1.7"
-  },
-  "devDependencies": {
-    "electron": "^28.2.0",
-    "electron-builder": "^24.9.1"
-  },
-  "build": {
-    "appId": "com.lhamacorp.knotes",
-    "productName": "kNotes",
-    "directories": {
-      "output": "dist"
-    },
-    "files": [
-      "**/*",
-      "!node_modules/**/*",
-      "node_modules/electron-updater/**/*",
-      "!dist"
-    ],
-    "generateUpdatesFilesForAllChannels": false,
-    "publish": null,
-    "mac": {
-      "category": "public.app-category.productivity",
-      "icon": "img/logo.png"
-    },
-    "win": {
-      "target": "nsis",
-      "icon": "img/logo.png"
-    },
-    "linux": {
-      "target": "AppImage",
-      "icon": "img/logo.png",
-      "category": "Office"
-    },
-    "nsis": {
-      "oneClick": false,
-      "allowToChangeInstallationDirectory": true
-    }
-  }
-}

+ 0 - 31
desktop-app/update-frontend.sh

@@ -1,31 +0,0 @@
-#!/bin/bash
-
-# Script to update desktop app with latest frontend changes
-# Usage: ./update-frontend.sh
-
-echo "🔄 Updating desktop app with latest frontend changes..."
-
-# Check if we're in the right directory
-if [ ! -f "package.json" ] || [ ! -f "../src/main/resources/static/index.html" ]; then
-    echo "❌ Error: Please run this script from the desktop-app directory"
-    exit 1
-fi
-
-# Copy frontend files
-echo "📁 Copying frontend files..."
-cp -r ../src/main/resources/static/* . 2>/dev/null || {
-    echo "❌ Error: Could not copy frontend files"
-    exit 1
-}
-
-# Check if files were copied successfully
-if [ -f "index.html" ] && [ -f "home.html" ] && [ -d "js" ] && [ -d "css" ]; then
-    echo "✅ Frontend files updated successfully"
-    echo "🏗️  You can now run 'npm run build-linux' to create a new build"
-    echo "🚀 Or run 'npm start' to test the changes"
-else
-    echo "❌ Error: Some frontend files may not have been copied correctly"
-    exit 1
-fi
-
-echo "✨ Update complete!"

+ 0 - 74
desktop-app/validate.js

@@ -1,74 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-
-console.log('🔍 Validating Desktop App Structure...\n');
-
-// Check required files
-const requiredFiles = [
-  'main.js',
-  'package.json',
-  'index.html',
-  'home.html',
-  'js/script.js',
-  'js/components.js',
-  'css/style.css'
-];
-
-let allFilesPresent = true;
-
-requiredFiles.forEach(file => {
-  const filePath = path.join(__dirname, file);
-  if (fs.existsSync(filePath)) {
-    console.log(`✅ ${file} - Present`);
-  } else {
-    console.log(`❌ ${file} - Missing`);
-    allFilesPresent = false;
-  }
-});
-
-// Check API configuration
-try {
-  const scriptContent = fs.readFileSync(path.join(__dirname, 'js/script.js'), 'utf8');
-  if (scriptContent.includes('https://notes.lhamacorp.com/api/notes')) {
-    console.log('✅ API_BASE - Correctly configured for production');
-  } else {
-    console.log('❌ API_BASE - Not configured for production');
-    allFilesPresent = false;
-  }
-} catch (error) {
-  console.log('❌ Could not validate API configuration');
-  allFilesPresent = false;
-}
-
-// Check package.json scripts
-try {
-  const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
-  const requiredScripts = ['start', 'build', 'build-all', 'build-win', 'build-mac', 'build-linux'];
-
-  console.log('\n📦 Build Scripts:');
-  requiredScripts.forEach(script => {
-    if (packageJson.scripts && packageJson.scripts[script]) {
-      console.log(`✅ npm run ${script} - Available`);
-    } else {
-      console.log(`❌ npm run ${script} - Missing`);
-    }
-  });
-} catch (error) {
-  console.log('❌ Could not validate package.json');
-}
-
-// Check if build output exists
-if (fs.existsSync(path.join(__dirname, 'dist/linux-unpacked/knotes-desktop'))) {
-  console.log('\n🏗️  Build Status:');
-  console.log('✅ Linux build - Completed successfully');
-  console.log('📂 Executable: ./dist/linux-unpacked/knotes-desktop');
-}
-
-console.log('\n🎉 Desktop App Validation Complete!');
-console.log(allFilesPresent ? '✅ All components are properly configured' : '❌ Some issues found');
-
-console.log('\n📋 Next Steps:');
-console.log('1. Run "npm start" on a machine with GUI to test');
-console.log('2. Run "npm run build-linux" to create AppImage');
-console.log('3. Run "npm run build-win" on Windows to create installer');
-console.log('4. Run "npm run build-mac" on macOS to create DMG');

+ 0 - 48
src/main/resources/static/404.html

@@ -1,48 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-    <meta name="theme-color" content="#2d2d2d">
-    <meta name="apple-mobile-web-app-capable" content="yes">
-    <meta name="apple-mobile-web-app-status-bar-style" content="default">
-    <meta name="apple-mobile-web-app-title" content="kNotes">
-    <meta name="mobile-web-app-capable" content="yes">
-    <meta name="application-name" content="kNotes">
-    <title>Page Not Found - kNotes</title>
-    <link rel="stylesheet" href="css/style.css">
-    <link rel="icon" type="image/x-icon" href="img/favicon.ico">
-</head>
-<body>
-<div id="headerContainer"></div>
-
-<div class="content">
-    <div class="error-content">
-        <div class="error-icon">📄</div>
-        <h1 class="error-title">Page Not Found</h1>
-        <p class="error-message">
-            The page you're looking for doesn't exist. It might have been moved, deleted,
-            or you entered the wrong URL.
-        </p>
-        <div class="error-actions">
-            <button class="dialog-btn primary" onclick="window.location.href='/'">
-                Go Home
-            </button>
-            <button class="dialog-btn secondary" onclick="showIdInput()">
-                Open Note
-            </button>
-        </div>
-    </div>
-</div>
-
-<div id="modalContainer"></div>
-
-<script src="js/components.js"></script>
-<script src="js/script.js"></script>
-<script>
-document.addEventListener('DOMContentLoaded', async () => {
-    await initPage('error');
-});
-</script>
-</body>
-</html>

+ 0 - 23
src/main/resources/static/components/base.html

@@ -1,23 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-    <meta name="theme-color" content="#2d2d2d">
-    <meta name="apple-mobile-web-app-capable" content="yes">
-    <meta name="apple-mobile-web-app-status-bar-style" content="default">
-    <meta name="apple-mobile-web-app-title" content="kNotes">
-    <meta name="mobile-web-app-capable" content="yes">
-    <meta name="application-name" content="kNotes">
-    <title>{{PAGE_TITLE}}</title>
-    <link rel="stylesheet" href="css/style.css">
-    <link rel="icon" type="image/x-icon" href="img/favicon.ico">
-</head>
-<body>
-{{PAGE_CONTENT}}
-
-<script src="js/components.js"></script>
-<script src="js/script.js"></script>
-{{PAGE_SCRIPT}}
-</body>
-</html>

+ 0 - 8
src/main/resources/static/components/header.html

@@ -1,8 +0,0 @@
-<div class="header">
-    <div class="title" onclick="window.location.href='/'" style="cursor: pointer;">
-        <img src="img/logo.png" alt="kNotes logo"/> kNotes
-    </div>
-    <div class="header-right">
-        {{HEADER_CONTENT}}
-    </div>
-</div>

+ 0 - 10
src/main/resources/static/components/modal.html

@@ -1,10 +0,0 @@
-<div id="idInputOverlay" class="id-input-overlay hidden">
-    <div class="id-input-dialog">
-        <h3>Open Note</h3>
-        <input type="text" id="noteIdInput" class="id-input" placeholder="Enter note ID"/>
-        <div class="dialog-buttons">
-            <button class="dialog-btn secondary" onclick="hideIdInput()">Cancel</button>
-            <button class="dialog-btn primary" onclick="loadNoteFromInput()">Open</button>
-        </div>
-    </div>
-</div>

+ 0 - 763
src/main/resources/static/css/style.css

@@ -1,763 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap');
-
-/* CSS Variables for Theme Support - Dark Theme Default */
-:root {
-    --bg-primary: #1a1a1a;
-    --bg-secondary: #2d2d2d;
-    --bg-tertiary: #404040;
-    --text-primary: #e0e0e0;
-    --text-secondary: #b0b0b0;
-    --text-tertiary: #808080;
-    --border-primary: #404040;
-    --border-secondary: #555;
-    --accent-primary: #4dabf7;
-    --accent-primary-hover: #339af0;
-    --accent-secondary: #868e96;
-    --overlay-bg: rgba(0,0,0,0.7);
-    --shadow: rgba(0,0,0,0.5);
-}
-
-/* Light Theme Variables */
-[data-theme="light"] {
-    --bg-primary: #fafafa;
-    --bg-secondary: white;
-    --bg-tertiary: #f5f5f5;
-    --text-primary: #333;
-    --text-secondary: #666;
-    --text-tertiary: #999;
-    --border-primary: #e0e0e0;
-    --border-secondary: #ddd;
-    --accent-primary: #007bff;
-    --accent-primary-hover: #0056b3;
-    --accent-secondary: #6c757d;
-    --overlay-bg: rgba(0,0,0,0.5);
-    --shadow: rgba(0,0,0,0.3);
-}
-
-* {
-    margin: 0;
-    padding: 0;
-    box-sizing: border-box;
-}
-
-body {
-    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
-    background-color: var(--bg-primary);
-    color: var(--text-primary);
-    height: 100vh;
-    height: calc(var(--vh, 1vh) * 100); /* Fallback for mobile browsers */
-    display: flex;
-    flex-direction: column;
-    transition: background-color 0.3s ease, color 0.3s ease;
-    overflow-x: hidden;
-}
-
-.header {
-    background: var(--bg-secondary);
-    border-bottom: 1px solid var(--border-primary);
-    padding: 15px 20px;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    min-height: 60px;
-    transition: background-color 0.3s ease, border-color 0.3s ease;
-}
-
-.title {
-    font-size: 18px;
-    color: var(--text-primary);
-    font-weight: 500;
-    display: flex;
-    align-items: center;
-    gap: 8px;
-}
-
-.title img {
-    height: 28px;
-    width: 28px;
-    border-radius: 6px;
-    vertical-align: middle;
-    flex-shrink: 0;
-    object-fit: contain;
-    background: var(--bg-tertiary);
-    transition: all 0.3s ease;
-}
-
-/* Fallback when logo fails to load */
-.title img[alt]:empty::before,
-.title img[alt]:not([src])::before {
-    content: "📝";
-    display: block;
-    font-size: 16px;
-    text-align: center;
-    line-height: 28px;
-}
-
-.note-id {
-    font-family: monospace;
-    font-size: 12px;
-    color: var(--text-secondary);
-    background: var(--bg-tertiary);
-    padding: 4px 8px;
-    border-radius: 3px;
-    transition: background-color 0.2s, color 0.2s;
-}
-
-.note-id:hover {
-    background: var(--accent-primary);
-    color: white;
-}
-
-.note-id:active {
-    background: var(--accent-primary-hover);
-    color: white;
-}
-
-.header-right {
-    display: flex;
-    align-items: center;
-    gap: 10px;
-}
-
-/* Update toast message */
-.update-toast {
-    position: fixed;
-    bottom: 20px;
-    right: 20px;
-    background: var(--accent-primary);
-    color: white;
-    padding: 12px 18px;
-    border-radius: 8px;
-    font-size: 14px;
-    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
-    z-index: 1000;
-    animation: slideInUp 0.3s ease-out;
-}
-
-.update-toast.hidden {
-    display: none;
-}
-
-@keyframes slideInUp {
-    from {
-        transform: translateY(100%);
-        opacity: 0;
-    }
-    to {
-        transform: translateY(0);
-        opacity: 1;
-    }
-}
-
-.new-btn {
-    background: var(--accent-primary);
-    color: white;
-    border: none;
-    padding: 8px 16px;
-    border-radius: 4px;
-    cursor: pointer;
-    font-size: 14px;
-    transition: background-color 0.2s ease;
-}
-
-.new-btn:hover {
-    background: var(--accent-primary-hover);
-}
-
-.content {
-    flex: 1;
-    display: flex;
-}
-
-.note-area {
-    flex: 1;
-    border: none;
-    outline: none;
-    padding: 30px;
-    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
-    font-size: 16px;
-    line-height: 1.6;
-    resize: none;
-    background: var(--bg-secondary);
-    color: var(--text-primary);
-    transition: background-color 0.3s ease, color 0.3s ease;
-}
-
-.note-area::placeholder {
-    color: var(--text-tertiary);
-}
-
-.id-input-overlay {
-    position: fixed;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    background: var(--overlay-bg);
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    z-index: 1000;
-}
-
-.id-input-dialog {
-    background: var(--bg-secondary);
-    padding: 30px;
-    border-radius: 8px;
-    box-shadow: 0 4px 20px var(--shadow);
-    max-width: 400px;
-    width: 90%;
-    transition: background-color 0.3s ease;
-}
-
-.id-input-dialog h3 {
-    margin-bottom: 15px;
-    color: var(--text-primary);
-}
-
-.id-input {
-    width: 100%;
-    padding: 12px;
-    border: 1px solid var(--border-secondary);
-    border-radius: 4px;
-    font-size: 14px;
-    margin-bottom: 15px;
-    background: var(--bg-secondary);
-    color: var(--text-primary);
-    transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
-}
-
-.dialog-buttons {
-    display: flex;
-    gap: 10px;
-    justify-content: flex-end;
-}
-
-.dialog-btn {
-    padding: 8px 16px;
-    border: none;
-    border-radius: 4px;
-    cursor: pointer;
-    font-size: 14px;
-    transition: background-color 0.2s ease;
-}
-
-.dialog-btn.primary {
-    background: var(--accent-primary);
-    color: white;
-}
-
-.dialog-btn.primary:hover {
-    background: var(--accent-primary-hover);
-}
-
-.dialog-btn.secondary {
-    background: var(--accent-secondary);
-    color: white;
-}
-
-.dialog-btn.secondary:hover {
-    opacity: 0.9;
-}
-
-/* Theme Switch Styles */
-.theme-switch {
-    background: var(--bg-tertiary);
-    border: 1px solid var(--border-primary);
-    border-radius: 20px;
-    padding: 6px;
-    cursor: pointer;
-    width: 36px;
-    height: 36px;
-    position: relative;
-    transition: all 0.3s ease;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    font-size: 16px;
-}
-
-.theme-switch:hover {
-    background: var(--border-primary);
-    transform: scale(1.05);
-}
-
-.theme-switch::before {
-    content: '☀️';
-    transition: all 0.3s ease;
-    filter: drop-shadow(0 1px 2px rgba(0,0,0,0.2));
-}
-
-.theme-switch.dark::before {
-    content: '🌙';
-}
-
-.hidden {
-    display: none;
-}
-
-/* Mobile-First Responsive Design */
-
-/* Base styles are already mobile-friendly, now add tablet and desktop improvements */
-
-/* Small smartphones (portrait) */
-@media screen and (max-width: 480px) {
-    .header {
-        padding: 12px 15px;
-        min-height: 56px;
-        flex-wrap: nowrap;
-    }
-
-    .title {
-        font-size: 16px;
-        font-weight: 600;
-        gap: 6px;
-    }
-
-    .title img {
-        height: 24px;
-        width: 24px;
-        border-radius: 4px;
-    }
-
-    .header-right {
-        gap: 8px;
-        flex-shrink: 0;
-    }
-
-    .note-id {
-        font-size: 10px;
-        padding: 3px 6px;
-        max-width: 80px;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        white-space: nowrap;
-    }
-
-    /* Make theme switch more touch-friendly */
-    .theme-switch {
-        width: 44px;
-        height: 44px;
-        padding: 8px;
-        min-width: 44px;
-        min-height: 44px;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        font-size: 18px;
-    }
-
-    /* Touch-friendly buttons */
-    .new-btn {
-        padding: 10px 14px;
-        font-size: 13px;
-        min-height: 44px;
-        touch-action: manipulation;
-        -webkit-tap-highlight-color: transparent;
-    }
-
-    /* Optimize text area for mobile */
-    .note-area {
-        padding: 20px 15px;
-        font-size: 16px; /* Prevents zoom on iOS */
-        line-height: 1.5;
-        -webkit-appearance: none;
-        border-radius: 0;
-    }
-
-    /* Mobile-optimized modal */
-    .id-input-overlay {
-        padding: 20px 15px;
-        align-items: flex-start;
-        padding-top: 25vh;
-    }
-
-    .id-input-dialog {
-        padding: 24px 20px;
-        margin: 0;
-        border-radius: 12px;
-        width: 100%;
-        max-width: 320px;
-    }
-
-    .id-input-dialog h3 {
-        font-size: 18px;
-        margin-bottom: 16px;
-    }
-
-    .id-input {
-        padding: 14px 12px;
-        font-size: 16px; /* Prevents zoom on iOS */
-        border-radius: 8px;
-        margin-bottom: 20px;
-        -webkit-appearance: none;
-    }
-
-    .dialog-buttons {
-        gap: 12px;
-        flex-direction: row;
-    }
-
-    .dialog-btn {
-        flex: 1;
-        padding: 12px 16px;
-        font-size: 14px;
-        font-weight: 500;
-        min-height: 44px;
-        border-radius: 8px;
-        touch-action: manipulation;
-        -webkit-tap-highlight-color: transparent;
-    }
-}
-
-/* Larger smartphones and small tablets (landscape phones) */
-@media screen and (min-width: 481px) and (max-width: 768px) {
-    .header {
-        padding: 15px 20px;
-    }
-
-    .title {
-        font-size: 18px;
-        gap: 7px;
-    }
-
-    .title img {
-        height: 26px;
-        width: 26px;
-        border-radius: 5px;
-    }
-
-    .note-area {
-        padding: 25px 20px;
-        font-size: 16px;
-    }
-
-    .id-input-dialog {
-        max-width: 400px;
-        padding: 28px 24px;
-    }
-
-    .theme-switch {
-        width: 38px;
-        height: 38px;
-        font-size: 17px;
-    }
-}
-
-/* Tablets and small desktops */
-@media screen and (min-width: 769px) and (max-width: 1024px) {
-    .header {
-        padding: 16px 24px;
-        min-height: 64px;
-    }
-
-    .title {
-        font-size: 20px;
-        gap: 8px;
-    }
-
-    .title img {
-        height: 28px;
-        width: 28px;
-        border-radius: 6px;
-    }
-
-    .note-area {
-        padding: 32px 28px;
-        font-size: 17px;
-    }
-
-    .new-btn {
-        padding: 10px 18px;
-        font-size: 15px;
-    }
-}
-
-/* Large screens and desktops */
-@media screen and (min-width: 1025px) {
-    .header {
-        padding: 18px 32px;
-        min-height: 68px;
-    }
-
-    .title {
-        font-size: 22px;
-        gap: 10px;
-    }
-
-    .title img {
-        height: 32px;
-        width: 32px;
-        border-radius: 7px;
-    }
-
-    .note-area {
-        padding: 40px 36px;
-        font-size: 18px;
-    }
-
-    .id-input-dialog {
-        max-width: 480px;
-        padding: 36px 32px;
-    }
-}
-
-/* Touch-specific improvements */
-@media (hover: none) and (pointer: coarse) {
-    /* This targets touch devices specifically */
-
-    .new-btn:hover,
-    .dialog-btn:hover,
-    .theme-switch:hover {
-        /* Remove hover effects on touch devices */
-        background: var(--accent-primary);
-        opacity: 1;
-    }
-
-    .dialog-btn.secondary:hover {
-        background: var(--accent-secondary);
-        opacity: 1;
-    }
-
-    .theme-switch:hover {
-        background: var(--bg-tertiary);
-    }
-
-    /* Add active states for touch feedback */
-    .new-btn:active {
-        background: var(--accent-primary-hover);
-        transform: scale(0.98);
-    }
-
-    /* Toast mobile styles */
-    .update-toast {
-        bottom: 15px;
-        right: 15px;
-        padding: 10px 15px;
-        font-size: 13px;
-        border-radius: 6px;
-    }
-
-    .dialog-btn:active {
-        transform: scale(0.98);
-    }
-
-    .theme-switch:active {
-        transform: scale(0.95);
-    }
-}
-
-/* High-DPI displays */
-@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
-    .theme-switch::before {
-        box-shadow: 0 1px 3px rgba(0,0,0,0.3);
-    }
-
-    .id-input-dialog {
-        box-shadow: 0 8px 32px var(--shadow);
-    }
-}
-
-/* Landscape orientation optimizations */
-@media screen and (max-height: 500px) and (orientation: landscape) {
-    .header {
-        min-height: 48px;
-        padding: 10px 15px;
-    }
-
-    .title {
-        font-size: 14px;
-        gap: 4px;
-    }
-
-    .title img {
-        height: 20px;
-        width: 20px;
-        border-radius: 3px;
-    }
-
-    .new-btn {
-        padding: 8px 12px;
-        font-size: 12px;
-        min-height: 36px;
-    }
-
-    .theme-switch {
-        width: 36px;
-        height: 36px;
-        min-height: 36px;
-        font-size: 14px;
-    }
-
-    .note-area {
-        padding: 15px;
-        font-size: 15px;
-    }
-
-    .id-input-overlay {
-        padding-top: 10vh;
-    }
-
-    .id-input-dialog {
-        padding: 20px;
-        max-width: 400px;
-    }
-}
-
-/* Accessibility improvements */
-@media (prefers-reduced-motion: reduce) {
-    * {
-        animation-duration: 0.01ms !important;
-        animation-iteration-count: 1 !important;
-        transition-duration: 0.01ms !important;
-    }
-
-    .theme-switch::before {
-        transition: none;
-    }
-
-    body {
-        transition: none;
-    }
-}
-
-/* Dark theme specific mobile adjustments */
-[data-theme="dark"] {
-    /* Better contrast for mobile screens */
-    --text-primary: #f0f0f0;
-    --text-secondary: #c0c0c0;
-    --border-primary: #4a4a4a;
-}
-
-@media screen and (max-width: 480px) {
-    [data-theme="dark"] {
-        --bg-primary: #0d1117;
-        --bg-secondary: #1c2128;
-        --bg-tertiary: #2d333b;
-    }
-}
-
-/* 404 Error Page Styles */
-.error-content {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    justify-content: center;
-    text-align: center;
-    padding: 40px 20px;
-    height: 100%;
-    max-width: 500px;
-    margin: 0 auto;
-}
-
-.error-icon {
-    font-size: 64px;
-    margin-bottom: 24px;
-    opacity: 0.8;
-}
-
-.error-title {
-    font-size: 32px;
-    font-weight: 600;
-    color: var(--text-primary);
-    margin-bottom: 16px;
-    line-height: 1.2;
-}
-
-.error-message {
-    font-size: 16px;
-    color: var(--text-secondary);
-    line-height: 1.6;
-    margin-bottom: 32px;
-    max-width: 400px;
-}
-
-.error-actions {
-    display: flex;
-    gap: 16px;
-    flex-wrap: wrap;
-    justify-content: center;
-}
-
-.error-actions .dialog-btn {
-    min-width: 140px;
-    padding: 12px 24px;
-    font-size: 14px;
-    font-weight: 500;
-    border-radius: 8px;
-    cursor: pointer;
-    border: none;
-    transition: all 0.2s ease;
-    text-decoration: none;
-    display: inline-block;
-}
-
-/* Mobile optimizations for 404 page */
-@media screen and (max-width: 480px) {
-    .error-content {
-        padding: 30px 15px;
-    }
-
-    .error-icon {
-        font-size: 48px;
-        margin-bottom: 20px;
-    }
-
-    .error-title {
-        font-size: 24px;
-        margin-bottom: 12px;
-    }
-
-    .error-message {
-        font-size: 14px;
-        margin-bottom: 24px;
-    }
-
-    .error-actions {
-        flex-direction: column;
-        width: 100%;
-        gap: 12px;
-    }
-
-    .error-actions .dialog-btn {
-        width: 100%;
-        min-width: unset;
-    }
-}
-
-/* Tablet optimizations for 404 page */
-@media screen and (min-width: 481px) and (max-width: 768px) {
-    .error-content {
-        padding: 36px 24px;
-    }
-
-    .error-icon {
-        font-size: 56px;
-    }
-
-    .error-title {
-        font-size: 28px;
-    }
-}
-
-/* Desktop optimizations for 404 page */
-@media screen and (min-width: 1025px) {
-    .error-content {
-        padding: 60px 40px;
-    }
-
-    .error-icon {
-        font-size: 72px;
-        margin-bottom: 28px;
-    }
-
-    .error-title {
-        font-size: 36px;
-        margin-bottom: 20px;
-    }
-
-    .error-message {
-        font-size: 18px;
-        margin-bottom: 40px;
-    }
-}

+ 0 - 44
src/main/resources/static/home.html

@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-    <meta name="theme-color" content="#007bff">
-    <meta name="apple-mobile-web-app-capable" content="yes">
-    <meta name="apple-mobile-web-app-status-bar-style" content="default">
-    <meta name="apple-mobile-web-app-title" content="kNotes">
-    <meta name="mobile-web-app-capable" content="yes">
-    <meta name="application-name" content="kNotes">
-    <title>kNotes - Simple Note Taking</title>
-    <link rel="stylesheet" href="css/style.css">
-    <link rel="icon" type="image/x-icon" href="img/favicon.ico">
-</head>
-<body>
-<div id="headerContainer"></div>
-
-<div class="content">
-    <div class="error-content">
-        <div class="error-icon">📝</div>
-        <h1 class="error-title">Welcome to kNotes</h1>
-        <div class="error-actions">
-            <button class="dialog-btn primary" onclick="window.location.href='/index.html'">
-                Create New Note
-            </button>
-            <button class="dialog-btn secondary" onclick="showIdInput()">
-                Open Existing Note
-            </button>
-        </div>
-    </div>
-</div>
-
-<div id="modalContainer"></div>
-
-<script src="js/components.js"></script>
-<script src="js/script.js"></script>
-<script>
-document.addEventListener('DOMContentLoaded', async () => {
-    await initPage('home');
-});
-</script>
-</body>
-</html>

BIN
src/main/resources/static/img/favicon.ico


BIN
src/main/resources/static/img/logo.png


+ 0 - 37
src/main/resources/static/index.html

@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-    <meta name="theme-color" content="#007bff">
-    <meta name="apple-mobile-web-app-capable" content="yes">
-    <meta name="apple-mobile-web-app-status-bar-style" content="default">
-    <meta name="apple-mobile-web-app-title" content="kNotes">
-    <meta name="mobile-web-app-capable" content="yes">
-    <meta name="application-name" content="kNotes">
-    <title>kNotes</title>
-    <link rel="stylesheet" href="css/style.css">
-    <link rel="icon" type="image/x-icon" href="img/favicon.ico">
-</head>
-<body>
-<div id="headerContainer"></div>
-
-<div id="updateToast" class="update-toast hidden">
-    📄 Note was updated
-</div>
-
-<div class="content">
-    <textarea class="note-area" id="noteContent" placeholder="Start typing your note..."></textarea>
-</div>
-
-<div id="modalContainer"></div>
-
-<script src="js/components.js"></script>
-<script src="js/script.js"></script>
-<script>
-document.addEventListener('DOMContentLoaded', async () => {
-    await initPage('editor');
-});
-</script>
-</body>
-</html>

+ 0 - 69
src/main/resources/static/js/components.js

@@ -1,69 +0,0 @@
-async function loadComponent(componentPath, targetId, customizations = {}) {
-    try {
-        const response = await fetch(componentPath);
-        if (!response.ok) throw new Error(`Failed to load ${componentPath}`);
-
-        let html = await response.text();
-
-        Object.entries(customizations).forEach(([placeholder, value]) => {
-            html = html.replace(new RegExp(`{{${placeholder}}}`, 'g'), value);
-        });
-
-        const targetElement = document.getElementById(targetId);
-        if (targetElement) {
-            targetElement.innerHTML = html;
-        }
-    } catch (error) {
-        console.error('Component loading failed:', error);
-    }
-}
-
-const PAGE_CONFIGS = {
-    editor: {
-        header: `
-            <span class="note-id" id="noteIdDisplay" style="display: none; cursor: pointer;" onclick="copyNoteLink()" title="Click to copy note link"></span>
-            <div class="theme-switch" id="themeSwitch" onclick="toggleTheme()" title="Toggle dark/light theme"></div>
-            <button class="new-btn" onclick="showIdInput()">Open</button>
-            <button class="new-btn" onclick="newNote()">New</button>
-        `,
-        needsModal: true,
-        needsToast: true
-    },
-    home: {
-        header: `
-            <div class="theme-switch" id="themeSwitch" onclick="toggleTheme()" title="Toggle dark/light theme"></div>
-        `,
-        needsModal: true,
-        needsToast: false
-    },
-    error: {
-        header: `
-            <div class="theme-switch" id="themeSwitch" onclick="toggleTheme()" title="Toggle dark/light theme"></div>
-            <button class="new-btn" onclick="window.location.href='/'">Home</button>
-        `,
-        needsModal: true,
-        needsToast: false
-    }
-};
-
-async function initPage(pageType) {
-    const config = PAGE_CONFIGS[pageType];
-    if (!config) {
-        console.error('Unknown page type:', pageType);
-        return;
-    }
-
-    await loadComponent('/components/header.html', 'headerContainer', {
-        HEADER_CONTENT: config.header
-    });
-
-    if (config.needsModal) {
-        await loadComponent('/components/modal.html', 'modalContainer');
-    }
-
-    if (typeof initializeTheme === 'function') {
-        initializeTheme();
-    }
-
-    updateThemeSwitchState();
-}

+ 0 - 424
src/main/resources/static/js/script.js

@@ -1,424 +0,0 @@
-const API_BASE = '/api/notes';
-let currentNoteId = null;
-let autoSaveTimeout = null;
-let lastSavedContent = '';
-let currentNoteModifiedAt = null;
-let versionCheckInterval = null;
-const VERSION_CHECK_INTERVAL_MS = 5000;
-
-function initializeTheme() {
-    const savedTheme = localStorage.getItem('theme') || 'dark';
-    const body = document.body;
-
-    if (savedTheme === 'light') {
-        body.setAttribute('data-theme', 'light');
-    } else {
-        body.removeAttribute('data-theme');
-    }
-
-    const themeSwitch = document.getElementById('themeSwitch');
-    if (themeSwitch) {
-        if (savedTheme === 'light') {
-            themeSwitch.classList.remove('dark');
-        } else {
-            themeSwitch.classList.add('dark');
-        }
-    }
-
-    updateThemeColor();
-}
-
-function updateThemeSwitchState() {
-    const savedTheme = localStorage.getItem('theme') || 'dark';
-    const themeSwitch = document.getElementById('themeSwitch');
-
-    if (themeSwitch) {
-        if (savedTheme === 'light') {
-            themeSwitch.classList.remove('dark');
-        } else {
-            themeSwitch.classList.add('dark');
-        }
-    }
-}
-
-function toggleTheme() {
-    const body = document.body;
-    const themeSwitch = document.getElementById('themeSwitch');
-
-    if (!themeSwitch) return;
-
-    const currentTheme = body.getAttribute('data-theme');
-
-    if (currentTheme === 'light') {
-        body.removeAttribute('data-theme');
-        themeSwitch.classList.add('dark');
-        localStorage.setItem('theme', 'dark');
-    } else {
-        body.setAttribute('data-theme', 'light');
-        themeSwitch.classList.remove('dark');
-        localStorage.setItem('theme', 'light');
-    }
-
-    updateThemeColor();
-}
-
-function init() {
-    initializeTheme();
-    setupMobileOptimizations();
-
-    const pathname = window.location.pathname;
-    const pathParts = pathname.split('/');
-    let idFromUrl = null;
-
-    for (const part of pathParts) {
-        if (part && /^[A-Za-z0-9]{26}$/.test(part)) {
-            idFromUrl = part;
-            break;
-        }
-    }
-
-    const noteContent = document.getElementById('noteContent');
-    if (noteContent) {
-        if (idFromUrl) {
-            loadNoteById(idFromUrl);
-        } else {
-            newNote();
-        }
-        noteContent.addEventListener('input', handleContentChange);
-    }
-
-    const noteIdInput = document.getElementById('noteIdInput');
-    if (noteIdInput) {
-        noteIdInput.addEventListener('keypress', function(e) {
-            if (e.key === 'Enter') {
-                loadNoteFromInput();
-            }
-        });
-    }
-}
-
-function setupMobileOptimizations() {
-    const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
-
-    if (isMobile) {
-        const noteContent = document.getElementById('noteContent');
-        if (noteContent) {
-            noteContent.addEventListener('focus', function() {
-                setTimeout(() => {
-                    this.scrollIntoView({ behavior: 'smooth', block: 'center' });
-                }, 300);
-            });
-
-            noteContent.addEventListener('touchmove', function(e) {
-                e.stopPropagation();
-            }, { passive: true });
-        }
-
-        updateThemeColor();
-    }
-
-    window.addEventListener('orientationchange', function() {
-        setTimeout(() => {
-            const vh = window.innerHeight * 0.01;
-            document.documentElement.style.setProperty('--vh', `${vh}px`);
-        }, 100);
-    });
-
-    const vh = window.innerHeight * 0.01;
-    document.documentElement.style.setProperty('--vh', `${vh}px`);
-}
-
-function updateThemeColor() {
-    const themeColorMeta = document.querySelector('meta[name="theme-color"]');
-    const currentTheme = document.body.getAttribute('data-theme');
-
-    if (themeColorMeta) {
-        if (currentTheme === 'light') {
-            themeColorMeta.setAttribute('content', '#007bff');
-        } else {
-            themeColorMeta.setAttribute('content', '#2d2d2d');
-        }
-    }
-}
-
-function handleContentChange() {
-    const noteContent = document.getElementById('noteContent');
-    if (!noteContent) {
-        console.error('Element with ID "noteContent" not found');
-        return;
-    }
-    const content = noteContent.value;
-
-    if (autoSaveTimeout) {
-        clearTimeout(autoSaveTimeout);
-    }
-
-    autoSaveTimeout = setTimeout(() => {
-        autoSave(content);
-    }, 1000);
-}
-
-async function autoSave(content) {
-    if (content === lastSavedContent) {
-        return;
-    }
-
-    try {
-        if (currentNoteId) {
-            const response = await fetch(`${API_BASE}/${currentNoteId}`, {
-                method: 'PUT',
-                headers: {
-                    'Content-Type': 'application/json',
-                },
-                body: JSON.stringify({
-                    content: content
-                })
-            });
-
-            if (response.ok) {
-                const updatedNote = await response.json();
-                setCurrentNoteVersion(updatedNote.modifiedAt);
-            }
-        } else {
-            const response = await fetch(API_BASE, {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                },
-                body: JSON.stringify({
-                    note: content
-                })
-            });
-
-            if (response.ok) {
-                const note = await response.json();
-                currentNoteId = note.id;
-
-                const newUrl = `/${note.id}`;
-                window.history.replaceState({}, '', newUrl);
-
-                showNoteId(note.id);
-                setCurrentNoteVersion(note.modifiedAt);
-            }
-        }
-
-        lastSavedContent = content;
-    } catch (error) {
-        console.error('Auto-save failed:', error);
-    }
-}
-
-async function loadNoteById(id) {
-    stopVersionPolling();
-
-    try {
-        const response = await fetch(`${API_BASE}/${id}`);
-
-        if (response.ok) {
-            const note = await response.json();
-            currentNoteId = note.id;
-
-            const noteContent = document.getElementById('noteContent');
-            if (noteContent) {
-                noteContent.value = note.content;
-                lastSavedContent = note.content;
-            } else {
-                console.error('Element with ID "noteContent" not found');
-            }
-
-            const newUrl = `/${note.id}`;
-            window.history.replaceState({}, '', newUrl);
-
-            showNoteId(note.id);
-            setCurrentNoteVersion(note.modifiedAt);
-        } else {
-            console.warn(`Note with ID ${id} not found (${response.status}), creating new note`);
-            await newNote();
-        }
-    } catch (error) {
-        console.error('Failed to load note:', error, 'creating new note instead');
-        await newNote();
-    }
-}
-
-function showNoteId(id) {
-    const noteIdDisplay = document.getElementById('noteIdDisplay');
-    if (noteIdDisplay) {
-        noteIdDisplay.textContent = id;
-        noteIdDisplay.style.display = 'inline-block';
-    } else {
-        console.error('Element with ID "noteIdDisplay" not found');
-    }
-}
-
-async function copyNoteLink() {
-    try {
-        const noteIdDisplay = document.getElementById('noteIdDisplay');
-        if (!noteIdDisplay) {
-            console.error('Element with ID "noteIdDisplay" not found');
-            return;
-        }
-
-        const currentUrl = window.location.href;
-        await navigator.clipboard.writeText(currentUrl);
-
-        const originalText = noteIdDisplay.textContent;
-        noteIdDisplay.textContent = 'Copied!';
-        noteIdDisplay.style.color = 'var(--accent-primary)';
-
-        setTimeout(() => {
-            noteIdDisplay.textContent = originalText;
-            noteIdDisplay.style.color = '';
-        }, 2000);
-
-    } catch (error) {
-        console.error('Failed to copy note link:', error);
-
-        const noteIdDisplay = document.getElementById('noteIdDisplay');
-        if (noteIdDisplay) {
-            const originalText = noteIdDisplay.textContent;
-            noteIdDisplay.textContent = 'Copy failed';
-            setTimeout(() => {
-                noteIdDisplay.textContent = originalText;
-            }, 2000);
-        }
-    }
-}
-
-async function newNote() {
-    stopVersionPolling();
-
-    try {
-        const response = await fetch(API_BASE, {
-            method: 'POST',
-            headers: {
-                'Content-Type': 'application/json',
-            },
-            body: JSON.stringify({
-                note: ''
-            })
-        });
-
-        if (response.ok) {
-            const note = await response.json();
-            currentNoteId = note.id;
-            lastSavedContent = '';
-
-            const noteContent = document.getElementById('noteContent');
-            if (noteContent) {
-                noteContent.value = '';
-                noteContent.focus();
-            } else {
-                console.error('Element with ID "noteContent" not found');
-            }
-
-            const newUrl = `/${note.id}`;
-            window.history.replaceState({}, '', newUrl);
-
-            showNoteId(note.id);
-            setCurrentNoteVersion(note.modifiedAt);
-        }
-    } catch (error) {
-        console.error('Failed to create new note:', error);
-    }
-}
-
-function showIdInput() {
-    const idInputOverlay = document.getElementById('idInputOverlay');
-    const noteIdInput = document.getElementById('noteIdInput');
-
-    if (idInputOverlay) {
-        idInputOverlay.classList.remove('hidden');
-    }
-
-    if (noteIdInput) {
-        noteIdInput.focus();
-    }
-}
-
-function hideIdInput() {
-    const idInputOverlay = document.getElementById('idInputOverlay');
-    const noteIdInput = document.getElementById('noteIdInput');
-
-    if (idInputOverlay) {
-        idInputOverlay.classList.add('hidden');
-    }
-
-    if (noteIdInput) {
-        noteIdInput.value = '';
-    }
-}
-
-function loadNoteFromInput() {
-    const noteIdInput = document.getElementById('noteIdInput');
-    if (!noteIdInput) return;
-
-    const id = noteIdInput.value.trim();
-    if (id) {
-        hideIdInput();
-        window.location.href = `/${id}`;
-    }
-}
-
-async function checkForNoteUpdates() {
-    if (!currentNoteId || !currentNoteModifiedAt) {
-        return;
-    }
-
-    try {
-        const response = await fetch(`${API_BASE}/${currentNoteId}/metadata`);
-
-        if (response.ok) {
-            const metadata = await response.json();
-            const serverModifiedAt = new Date(metadata.modifiedAt).getTime();
-            const localModifiedAt = new Date(currentNoteModifiedAt).getTime();
-
-            if (serverModifiedAt > localModifiedAt) {
-                await autoReloadNote();
-            }
-        }
-    } catch (error) {
-        console.error('Failed to check for note updates:', error);
-    }
-}
-
-function startVersionPolling() {
-    stopVersionPolling();
-
-    if (currentNoteId) {
-        versionCheckInterval = setInterval(checkForNoteUpdates, VERSION_CHECK_INTERVAL_MS);
-    }
-}
-
-function stopVersionPolling() {
-    if (versionCheckInterval) {
-        clearInterval(versionCheckInterval);
-        versionCheckInterval = null;
-    }
-}
-
-function setCurrentNoteVersion(modifiedAt) {
-    currentNoteModifiedAt = modifiedAt;
-    startVersionPolling();
-}
-
-function showUpdateToast() {
-    const toast = document.getElementById('updateToast');
-    if (toast) {
-        toast.classList.remove('hidden');
-
-        setTimeout(() => {
-            toast.classList.add('hidden');
-        }, 2000);
-    }
-}
-
-async function autoReloadNote() {
-    if (currentNoteId) {
-        stopVersionPolling();
-        await loadNoteById(currentNoteId);
-        showUpdateToast();
-    }
-}
-
-window.addEventListener('load', init);