From 452843a65e72c446faaca3a35951491912c3304b Mon Sep 17 00:00:00 2001 From: Simon Emms Date: Mon, 9 Mar 2026 19:44:19 +0000 Subject: [PATCH 01/10] feat: import ui from zigflow/zigflow repo --- .commitlintrc.yaml | 2 +- .devcontainer/devcontainer.json | 16 +- .eslintignore | 13 - .github/workflows/build.yml | 387 +++ .github/workflows/deploy.yml | 98 - .gitignore | 38 +- .licenserc.yaml | 14 +- .pre-commit-config.yaml | 31 +- .prettierignore | 27 +- .prettierrc | 29 +- .vscode/settings.json | 1 + CLAUDE.md | 456 ++++ CODE_OF_CONDUCT.md | 24 +- Dockerfile | 57 + Makefile | 21 - README.md | 36 +- Taskfile.yml | 59 + charts/ui/.helmignore | 23 + charts/ui/Chart.yaml | 23 + charts/ui/README.md | 56 + charts/ui/README.tpl | 44 + charts/ui/templates/NOTES.txt | 5 + charts/ui/templates/_helpers.tpl | 80 + charts/ui/templates/deployment.yaml | 88 + charts/ui/templates/hpa.yaml | 32 + charts/ui/templates/service.yaml | 13 + charts/ui/templates/serviceaccount.yaml | 13 + .../ui/templates/tests/test-connection.yaml | 15 + charts/ui/values.yaml | 110 + eslint.config.js | 65 +- package-lock.json | 2088 +++++++++-------- package.json | 60 +- playwright.config.ts | 46 + skaffold.yaml | 48 + src/app.d.ts | 16 +- src/app.html | 20 +- src/lib/assets/favicon.ico | Bin 0 -> 15406 bytes src/lib/export/.gitkeep | 0 src/lib/export/yaml.ts | 391 +++ src/lib/index.ts | 10 +- src/lib/tasks/actions.ts | 646 +++++ src/lib/tasks/model.ts | 288 +++ src/lib/tasks/parse.ts | 741 ++++++ src/lib/tasks/registry.ts | 249 ++ src/lib/tasks/validation.ts | 262 +++ src/lib/ui/.gitkeep | 0 src/lib/ui/Breadcrumb.svelte | 94 + src/lib/ui/Canvas.svelte | 325 +++ src/lib/ui/ContextIndicator.svelte | 53 + src/lib/ui/FlowNode.svelte | 270 +++ src/lib/ui/Inspector.svelte | 537 +++++ src/lib/ui/Sidebar.svelte | 271 +++ src/lib/ui/canvas-context.ts | 27 + src/routes/+layout.svelte | 37 + src/routes/+page.svelte | 2 - src/{index.test.ts => routes/+page.ts} | 13 +- src/routes/workflows/+page.server.ts | 84 + src/routes/workflows/+page.svelte | 131 ++ .../workflows/[...workflowId]/+page.server.ts | 56 + .../workflows/[...workflowId]/+page.svelte | 999 ++++++++ .../[...workflowId]/+page.ts} | 16 +- src/styles/.gitkeep | 0 static/favicon.png | Bin 1571 -> 0 bytes static/robots.txt | 3 + svelte.config.js | 25 +- tests/workflow-navigation.spec.ts | 99 + tests/yaml-export-shape.spec.ts | 63 + tsconfig.json | 1 + vite.config.ts | 18 +- workflows/demo-workflow.yaml | 60 + 70 files changed, 8539 insertions(+), 1386 deletions(-) delete mode 100644 .eslintignore create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/deploy.yml create mode 100644 CLAUDE.md create mode 100644 Dockerfile delete mode 100644 Makefile create mode 100644 Taskfile.yml create mode 100644 charts/ui/.helmignore create mode 100644 charts/ui/Chart.yaml create mode 100644 charts/ui/README.md create mode 100644 charts/ui/README.tpl create mode 100644 charts/ui/templates/NOTES.txt create mode 100644 charts/ui/templates/_helpers.tpl create mode 100644 charts/ui/templates/deployment.yaml create mode 100644 charts/ui/templates/hpa.yaml create mode 100644 charts/ui/templates/service.yaml create mode 100644 charts/ui/templates/serviceaccount.yaml create mode 100644 charts/ui/templates/tests/test-connection.yaml create mode 100644 charts/ui/values.yaml create mode 100644 playwright.config.ts create mode 100644 skaffold.yaml create mode 100644 src/lib/assets/favicon.ico create mode 100644 src/lib/export/.gitkeep create mode 100644 src/lib/export/yaml.ts create mode 100644 src/lib/tasks/actions.ts create mode 100644 src/lib/tasks/model.ts create mode 100644 src/lib/tasks/parse.ts create mode 100644 src/lib/tasks/registry.ts create mode 100644 src/lib/tasks/validation.ts create mode 100644 src/lib/ui/.gitkeep create mode 100644 src/lib/ui/Breadcrumb.svelte create mode 100644 src/lib/ui/Canvas.svelte create mode 100644 src/lib/ui/ContextIndicator.svelte create mode 100644 src/lib/ui/FlowNode.svelte create mode 100644 src/lib/ui/Inspector.svelte create mode 100644 src/lib/ui/Sidebar.svelte create mode 100644 src/lib/ui/canvas-context.ts create mode 100644 src/routes/+layout.svelte delete mode 100644 src/routes/+page.svelte rename src/{index.test.ts => routes/+page.ts} (69%) create mode 100644 src/routes/workflows/+page.server.ts create mode 100644 src/routes/workflows/+page.svelte create mode 100644 src/routes/workflows/[...workflowId]/+page.server.ts create mode 100644 src/routes/workflows/[...workflowId]/+page.svelte rename src/routes/{+layout.ts => workflows/[...workflowId]/+page.ts} (57%) create mode 100644 src/styles/.gitkeep delete mode 100644 static/favicon.png create mode 100644 static/robots.txt create mode 100644 tests/workflow-navigation.spec.ts create mode 100644 tests/yaml-export-shape.spec.ts create mode 100644 workflows/demo-workflow.yaml diff --git a/.commitlintrc.yaml b/.commitlintrc.yaml index 9cb74a7..0974185 100644 --- a/.commitlintrc.yaml +++ b/.commitlintrc.yaml @@ -1,2 +1,2 @@ extends: - - "@commitlint/config-conventional" + - '@commitlint/config-conventional' diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2912e00..5924cf8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,7 +1,11 @@ { "image": "ghcr.io/mrsimonemms/devcontainers/full", "name": "devcontainer", - "features": {}, + "features": { + "ghcr.io/dhoeric/features/trivy:1": {}, + "ghcr.io/devcontainers-extra/features/go-task:1": {}, + "ghcr.io/rio/features/skaffold:2": {} + }, "customizations": { "vscode": { "extensions": [ @@ -11,7 +15,15 @@ "settings": {} } }, + "postCreateCommand": { + "playwright": "npx --yes playwright install --with-deps" + }, "containerEnv": { + "PLAYWRIGHT_HTML_HOST": "0.0.0.0", + "PUBLIC_WORKFLOWS_DIR": "/workspaces/studio/workflows", "VITE_HOST": "0.0.0.0" - } + }, + "forwardPorts": [ + 5173 + ] } diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 3897265..0000000 --- a/.eslintignore +++ /dev/null @@ -1,13 +0,0 @@ -.DS_Store -node_modules -/build -/.svelte-kit -/package -.env -.env.* -!.env.example - -# Ignore files for PNPM, NPM and YARN -pnpm-lock.yaml -package-lock.json -yarn.lock diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..7f6922a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,387 @@ +name: Build +on: + push: + branches: + - main + tags: + - "v*.*.*" + pull_request: + branches: + - main + workflow_dispatch: +permissions: + actions: read + contents: write + packages: write + id-token: write + pull-requests: read + security-events: write +jobs: + commitlint: + runs-on: ubuntu-latest + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 # fetch-depth is required + + - uses: wagoid/commitlint-github-action@v6 + + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 # Required for pre-commit to be able scan history + + - uses: actions/setup-node@v6 + with: + node-version: lts/* + + - run: npm ci + + - uses: actions/setup-python@v6 + with: + python-version: 3.x + + - uses: pre-commit/action@v3.0.1 + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-node@v6 + with: + node-version: lts/* + + - name: Install dependencies + run: npm ci + + - name: Linting + run: npm run lint + + - name: Checking + run: npm run check + + helm: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Install Temporal CLI + uses: temporalio/setup-temporal@v0 + + - name: Install Helm + uses: azure/setup-helm@v4 + + - name: helm lint + run: helm lint charts/ui + + - name: Run Trivy scan + uses: aquasecurity/trivy-action@0.35.0 + with: + scan-type: config + scan-ref: ./charts/ui + format: sarif + output: trivy-helm.sarif + exit-code: "1" + severity: HIGH,CRITICAL + limit-severities-for-sarif: true + + - name: Upload Trivy scan results to GitHub Security tab + if: always() + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: trivy-helm.sarif + + - name: Install Skaffold + run: | + curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 + chmod +x skaffold + sudo mv skaffold /usr/local/bin/ + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Create Kind cluster + uses: helm/kind-action@v1 + with: + cluster_name: kind + + - name: Build ui image + uses: docker/build-push-action@v6 + with: + context: . + tags: ui:latest + load: true + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Load image into Kind + run: kind load docker-image ui:latest + + - name: Deploy UI + run: | + echo '{"builds":[{"imageName":"ui","tag":"ui:latest"}]}' > /tmp/artifacts.json + skaffold deploy --build-artifacts /tmp/artifacts.json + + - name: Wait for UI deployment + run: kubectl rollout status -n zigflow deployment/ui --timeout=30s + + - name: Port forward UI + run: kubectl port-forward svc/ui -n zigflow 3000:3000 & + + - name: Call webapp + run: | + timeout 30s curl -fsSL localhost:3000 || { + echo "Calling UI timed out or failed" + exit 1 + } + + - name: Dump logs on failure + if: failure() + run: | + kubectl get pods -A + kubectl logs -n zigflow deploy/ui --all-containers=true || true + + # Generate metadata shared across all build jobs + metadata: + runs-on: ubuntu-latest + needs: + - commitlint + - helm + - pre-commit + - test + outputs: + is_tag: ${{ steps.branch-name.outputs.is_tag }} + tag: ${{ steps.branch-name.outputs.tag }} + current_branch: ${{ steps.branch-name.outputs.current_branch }} + version: ${{ steps.metadata.outputs.version }} + commit_id: ${{ steps.metadata.outputs.commit_id }} + git_repo: ${{ steps.metadata.outputs.git_repo }} + push: ${{ steps.metadata.outputs.push }} + platforms: ${{ steps.metadata.outputs.platforms }} + is_prerelease: ${{ steps.metadata.outputs.is_prerelease }} + steps: + - name: Get branch names + id: branch-name + uses: tj-actions/branch-names@v9 + with: + strip_tag_prefix: v + + - name: Generate metadata + id: metadata + run: | + if [ "${{ steps.branch-name.outputs.is_tag }}" = "true" ]; + then + echo "version=${{ steps.branch-name.outputs.tag }}" >> "$GITHUB_OUTPUT" + echo "platforms=[\"linux/amd64\",\"linux/arm64\"]" >> "$GITHUB_OUTPUT" + echo "push=true" >> "$GITHUB_OUTPUT" + + # Detect if tag is a pre-release (contains -rc, -beta, -alpha, etc.) + TAG="${{ steps.branch-name.outputs.tag }}" + if echo "$TAG" | grep -qE -- '-(rc|beta|alpha|pre)'; then + echo "is_prerelease=true" >> "$GITHUB_OUTPUT" + else + echo "is_prerelease=false" >> "$GITHUB_OUTPUT" + fi + else + echo "version=development" >> "$GITHUB_OUTPUT" + echo "platforms=[\"linux/amd64\"]" >> "$GITHUB_OUTPUT" + echo "push=${{ github.ref == 'refs/heads/main' }}" >> "$GITHUB_OUTPUT" + echo "is_prerelease=false" >> "$GITHUB_OUTPUT" + fi + + echo "commit_id=${GITHUB_SHA}" >> "$GITHUB_OUTPUT" + echo "git_repo=github.com/${GITHUB_REPOSITORY}" >> "$GITHUB_OUTPUT" + + # Build ui Docker images in parallel by architecture + docker_ui: + runs-on: ${{ matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} + needs: metadata + strategy: + matrix: + platform: ${{ fromJson(needs.metadata.outputs.platforms) }} + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + if: needs.metadata.outputs.push == 'true' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate platform-specific tag + id: tag + run: | + PLATFORM_TAG=$(echo "${{ matrix.platform }}" | sed 's/\//-/g') + echo "platform_tag=${PLATFORM_TAG}" >> "$GITHUB_OUTPUT" + + # Image name with SHA-based tag for this platform + echo "image_ref=ghcr.io/${GITHUB_REPOSITORY,,}:${GITHUB_SHA}-${PLATFORM_TAG}" >> "$GITHUB_OUTPUT" + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + build-args: | + GIT_COMMIT=${{ needs.metadata.outputs.commit_id }} + GIT_REPO=${{ needs.metadata.outputs.git_repo }} + VERSION=${{ needs.metadata.outputs.version }} + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: ${{ matrix.platform }} + load: ${{ needs.metadata.outputs.push == 'false' }} + push: ${{ needs.metadata.outputs.push == 'true' }} + tags: ${{ steps.tag.outputs.image_ref }} + # Save as artifact for non-main branches + + - name: Pull images + if: ${{ needs.metadata.outputs.push == 'true' }} + run: docker pull ${{ steps.tag.outputs.image_ref }} + + - name: Run Trivy scan + uses: aquasecurity/trivy-action@0.35.0 + with: + image-ref: ${{ steps.tag.outputs.image_ref }} + format: sarif + output: trivy-zigflow-${{ steps.tag.outputs.platform_tag }}.sarif + exit-code: "1" + ignore-unfixed: true + vuln-type: os,library + severity: HIGH,CRITICAL + limit-severities-for-sarif: true + + - name: Upload Trivy scan results to GitHub Security tab + if: always() + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: trivy-zigflow-${{ steps.tag.outputs.platform_tag }}.sarif + + # Combine architecture-specific images into a multi-arch manifest + docker_ui_manifest: + runs-on: ubuntu-latest + if: needs.metadata.outputs.push == 'true' + needs: + - metadata + - docker_ui + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Install Cosign + uses: sigstore/cosign-installer@v4.0.0 + + - name: Install Syft + uses: jaxxstorm/action-install-gh-release@v1.10.0 + with: + repo: anchore/syft + + - name: Generate manifest tags and create manifest + run: | + REPO_LOWER="ghcr.io/${GITHUB_REPOSITORY,,}" + + # Build list of source images based on platforms + SOURCE_IMAGES="${REPO_LOWER}:${GITHUB_SHA}-linux-amd64" + + # Add arm64 only if it was built (tags only) + if [ "${{ needs.metadata.outputs.is_tag }}" = "true" ]; + then + SOURCE_IMAGES="${SOURCE_IMAGES} ${REPO_LOWER}:${GITHUB_SHA}-linux-arm64" + fi + + # Determine target tags based on ref type + if [ "${{ needs.metadata.outputs.is_tag }}" = "true" ]; + then + # For tags: choose latest/prerelease + version tag + SHA based on pre-release status + if [ "${{ needs.metadata.outputs.is_prerelease }}" = "true" ]; then + TARGET_TAGS="${REPO_LOWER}:prerelease ${REPO_LOWER}:${{ needs.metadata.outputs.tag }} ${REPO_LOWER}:${GITHUB_SHA}" + else + TARGET_TAGS="${REPO_LOWER}:latest ${REPO_LOWER}:${{ needs.metadata.outputs.tag }} ${REPO_LOWER}:${GITHUB_SHA}" + fi + elif [ "${{ github.ref }}" = "refs/heads/main" ]; + then + # For main branch: branch-main + SHA + TARGET_TAGS="${REPO_LOWER}:branch-main ${REPO_LOWER}:${GITHUB_SHA}" + else + # For other branches: branch- + SHA + BRANCH="${{ needs.metadata.outputs.current_branch }}" + BRANCH_TAG="branch-${BRANCH//\//-}" + BRANCH_TAG="${BRANCH_TAG,,}" + TARGET_TAGS="${REPO_LOWER}:${BRANCH_TAG} ${REPO_LOWER}:${GITHUB_SHA}" + fi + + # Create manifest for each target tag + for TAG in ${TARGET_TAGS}; do + echo "Creating manifest for ${TAG} from: ${SOURCE_IMAGES}" + docker buildx imagetools create -t "${TAG}" ${SOURCE_IMAGES} + + cosign sign --yes "${TAG}" + syft "${TAG}" -o cyclonedx-json > sbom.json + cosign attach sbom --sbom sbom.json "${TAG}" + cosign sign --yes --attachment sbom "${TAG}" + done + + # Build and publish Helm chart in parallel + helm_chart: + runs-on: ubuntu-latest + needs: metadata + if: needs.metadata.outputs.is_tag == 'true' + steps: + - uses: actions/checkout@v6 + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: ">=1.25.0" + + - name: Prepare chart README + run: | + go install github.com/norwoodj/helm-docs/cmd/helm-docs@latest + helm-docs + yq -i '.version = "${{ needs.metadata.outputs.tag }}"' charts/ui/Chart.yaml + yq -i '.annotations."org.opencontainers.image.documentation" = "https://github.com/zigflow/ui/blob/${{ needs.metadata.outputs.tag }}/charts/ui/README.md"' charts/ui/Chart.yaml + + - name: Import GPG key + uses: crazy-max/ghaction-import-gpg@v6 + id: gpg + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + + # Helm requires the legacy GPG format + # @link https://helm.sh/docs/topics/provenance/#the-workflow + - name: Convert GPG v2 key + run: | + gpg --export > ~/.gnupg/pubring.gpg + gpg --batch --pinentry-mode loopback --yes --passphrase '${{ secrets.GPG_PASSPHRASE }}' --export-secret-key > ~/.gnupg/secring.gpg + + - name: Publish Helm chart + uses: appany/helm-oci-chart-releaser@v0.5.0 + with: + name: ui + registry: ghcr.io + repository: ${{ github.repository_owner }}/charts + tag: ${{ needs.metadata.outputs.tag }} + registry_username: ${{ github.actor }} + registry_password: ${{ secrets.GITHUB_TOKEN }} + sign: true + signing_key: ${{ steps.gpg.outputs.name }} + signing_passphrase: ${{ secrets.GPG_PASSPHRASE }} + update_dependencies: true diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index c556dcd..0000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,98 +0,0 @@ -name: Deploy to GitHub Pages -on: - push: - branches: - - main - pull_request: - branches: - - main - workflow_dispatch: -permissions: - pull-requests: read -jobs: - commitlint: - runs-on: ubuntu-latest - env: - GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetch-depth is required - - # This needs a generated dependency - doesn't add anything to this test - - run: rm tsconfig.json - - - uses: wagoid/commitlint-github-action@v5 - - pre-commit: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v4 - with: - python-version: 3.x - - - name: Set up Go - uses: actions/setup-go@v4 - with: - go-version: '>=1.20.0' - - - name: Set up JS - uses: actions/setup-node@v4 - with: - node-version: lts/* - cache: "npm" - - - name: Install dependencies - run: npm ci - - - uses: pre-commit/action@v3.0.0 - - build: - runs-on: ubuntu-latest - needs: - - commitlint - - pre-commit - steps: - - name: Checkout - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: lts/* - - - name: Install dependencies - run: npm ci - - - name: Lint - run: npm run lint - - - name: Build - run: | - npm run build - touch build/.nojekyll - - - name: Upload Artifacts - uses: actions/upload-pages-artifact@v3 - with: - path: 'build/' - - deploy: - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/main' - needs: - - build - - permissions: - pages: write - id-token: write - - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - - steps: - - name: Deploy - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 96de2d4..4f988c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,35 @@ -dist -tmp - node_modules -.idea +# Output +.output +.vercel +.netlify +.wrangler +/.svelte-kit +/build + +# OS .DS_Store Thumbs.db -.commit -.devbox -.envrc -coverage -.nyc_output -/build -.vercel -/.svelte-kit -/package +# Env .env .env.* !.env.example +!.env.test + +# Vite vite.config.js.timestamp-* vite.config.ts.timestamp-* -.claude +static/fonts + +# Playwright +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ +/playwright/.auth/ + +/workflows +!/workflows/demo-workflow.yaml diff --git a/.licenserc.yaml b/.licenserc.yaml index 43bdf1c..4084ce8 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -4,14 +4,14 @@ header: copyright-owner: Zigflow authors copyright-year: 2025 - 2026 paths-ignore: - - "**/dist" - - "**/tmp" + - '**/dist' + - '**/tmp' - LICENSE - - "**/.*" - - "**/go.*" - - "**/*.{json,md,yml,yaml,txt}" - - "**/.gitkeep" - - "**/*.svelte" + - '**/.*' + - '**/go.*' + - '**/*.{json,md,yml,yaml,txt}' + - '**/.gitkeep' + - '**/*.svelte' comment: on-failure dependency: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cf534f5..63b538c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,12 +12,13 @@ repos: - --no-sort-keys - id: check-json - id: check-yaml + exclude: charts args: - --allow-multiple-documents - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/compilerla/conventional-pre-commit - rev: v4.3.0 + rev: v4.4.0 hooks: - id: conventional-pre-commit stages: @@ -27,22 +28,11 @@ repos: hooks: - id: markdown-toc - repo: https://github.com/DavidAnson/markdownlint-cli2 - rev: v0.20.0 + rev: v0.21.0 hooks: - id: markdownlint-cli2 - - repo: https://github.com/pre-commit/mirrors-prettier - rev: v4.0.0-alpha.8 - hooks: - - id: prettier - args: - - --plugin - - prettier-plugin-svelte - - --plugin - - prettier-plugin-organize-imports - stages: - - pre-commit - repo: https://github.com/pre-commit/mirrors-eslint - rev: v10.0.0-beta.0 + rev: v10.0.3 hooks: - id: eslint files: \.([jt]sx?|svelte)$ # *.js, *.jsx *.ts, *.tsx and *.svelte @@ -51,3 +41,16 @@ repos: rev: v0.2.4 hooks: - id: scan + - repo: local + hooks: + - id: format + name: Format code + language: unsupported + entry: npm run format + - repo: https://github.com/norwoodj/helm-docs + rev: v1.14.2 + hooks: + - id: helm-docs-built + args: + - --template-files=./charts/zigflow/README.tpl +exclude: charts/.*/README.md diff --git a/.prettierignore b/.prettierignore index 9cbe644..ab65cd7 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,17 +1,14 @@ -*.md -*.yml -*.yaml -*.json -.DS_Store -node_modules -/build -/.svelte-kit -/package -.env -.env.* -!.env.example - -# Ignore files for PNPM, NPM and YARN -pnpm-lock.yaml +# Package Managers package-lock.json +pnpm-lock.yaml yarn.lock +bun.lock +bun.lockb + +# Miscellaneous +/static/ +README.md + +*.yaml +*.json +*.yml diff --git a/.prettierrc b/.prettierrc index a90fb79..7a8403d 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,8 +1,25 @@ { - "useTabs": true, - "singleQuote": true, - "trailingComma": "all", - "printWidth": 80, - "plugins": ["prettier-plugin-svelte", "prettier-plugin-organize-imports"], - "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] + "singleQuote": true, + "trailingComma": "all", + "printWidth": 80, + "plugins": [ + "prettier-plugin-svelte", + "@trivago/prettier-plugin-sort-imports" + ], + "importOrder": ["^[./]"], + "importOrderSeparation": true, + "importOrderSortSpecifiers": true, + "importOrderParserPlugins": ["typescript", "decorators-legacy"], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte", + "importOrder": ["^[./]"], + "importOrderSeparation": true, + "importOrderSortSpecifiers": true, + "importOrderParserPlugins": ["typescript", "decorators-legacy"] + } + } + ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 9543518..c884e76 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,7 @@ ".github/workflows/*.{yml,yaml}" ] }, + "prettier.prettierPath": "node_modules/prettier/index.cjs", "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..9dca5c5 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,456 @@ +# Claude Instructions (zigflow.dev visual editor) + +This repository contains a **visual flow editor for Zigflow**, built using: + +- **SvelteKit** +- **TypeScript** +- **Svelte Flow** +- **App-defined SCSS (no general-purpose CSS framework)** +- **SvelteKit Node adapter** +- **Docker (production runtime)** + +The UI is an implementation detail. +The **Flow Graph model (IR) is the source of truth**. + +Claude should prioritize correctness, clarity, and alignment with existing +tooling over novelty or abstraction. + +--- + +## Core principles + +- Treat the flow graph / IR as authoritative +- UI state must be serializable and reproducible +- Prefer explicit, boring data structures over clever abstractions +- Optimize for correctness and debuggability over minimal code +- Developer experience matters — keep things understandable +- Assume this will run long-lived in Docker + +--- + +## Technology stack (authoritative) + +- **Framework:** SvelteKit +- **Adapter:** `@sveltejs/adapter-node` +- **Language:** TypeScript (required; no new JS-only files) +- **Graph / canvas:** Svelte Flow +- **Styling:** App-defined SCSS (no general-purpose CSS framework) +- **Runtime:** Node.js (Docker) +- **Linting:** ESLint (flat config) +- **Formatting:** Prettier (project-defined config) + +Do not: + +- Introduce React or React-specific patterns +- Introduce general-purpose CSS frameworks (Bulma, Tailwind, Bootstrap, etc.) +- Introduce utility-first CSS systems +- Bypass TypeScript with `any` unless unavoidable and documented +- Add alternative formatters or linters + +--- + +## Runtime & deployment assumptions + +- The app runs as a **Node server**, not a static site +- Docker is the primary production environment +- File system access must be treated as ephemeral +- All state must be serializable (DB, object storage, or exportable files) + +Do not: + +- Rely on in-memory state for persistence +- Assume serverless constraints +- Introduce adapter-specific hacks + +--- + +## Project structure guidance + +This project uses a small number of **conceptual root directories**. +Their purpose matters more than their exact contents. + +### `src/lib/graph/` + +Authoritative flow graph model and schema. + +- Node and edge types +- Graph structure and invariants +- Validation logic +- No UI code +- Must be usable from non-UI contexts (CLI, tests, exporters) + +### `src/lib/export/` + +Exporters and code generation. + +- Pure functions only +- Accept validated graph models +- No UI dependencies +- Deterministic output + +### `src/lib/ui/` + +Reusable UI primitives and editor-specific components. + +- Svelte components only +- Styling via app-owned SCSS +- May depend on Svelte Flow +- No graph semantics or validation logic + +### `src/routes/` + +SvelteKit routes and server endpoints. + +- Page composition +- Load/save/export endpoints +- No business logic +- No graph validation or mutation logic + +### `src/routes/workflows//` + +Workflow-specific editor routes. + +- Each workflow is addressed by a stable `workflowId` +- Routes under this path are responsible for: + - Loading workflow state + - Rendering the editor UI + - Invoking validation and export logic +- Workflow identity must come from the route, not inferred from UI state + +Do not: + +- Introduce generic `shared`, `common`, or `utils` directories +- Place domain logic under `routes` +- Couple graph logic to Svelte components +- Encode workflow identity implicitly in component state + +### `src/styles/` + +Application-owned SCSS. + +- Design tokens (spacing, colours, typography) +- Layout helpers actually used by the app +- UI component styles +- Svelte Flow-specific styling + +--- + +## Architecture rules + +- Separate concerns strictly: + - **Flow schema & validation** (no UI code) + - **Exporters / code generation** + - **UI (Svelte components, Svelte Flow, inspector panels)** + - **Server routes (load/save/export)** +- Validation must operate on the flow graph, not UI components +- Exported output must never depend on UI-specific state +- UI should adapt to the model, not vice versa + +--- + +## Flow graph model + +- Nodes and edges must have **stable, explicit IDs** +- All node types must be explicitly typed +- No implicit behavior inferred from visual layout or position +- Graph must be fully serializable to JSON +- The graph schema must be usable outside the UI (CLI, tests, exporters) + +Do not: + +- Encode logic in Svelte component state +- Infer control flow from x/y positioning +- Allow invalid graphs to export + +--- + +## Node behavior + +Each node type must define: + +- Allowed incoming edge count +- Allowed outgoing edge count +- Required configuration fields +- Validation rules specific to that node + +Specific rules: + +- Condition nodes must label outgoing edges +- Join nodes must validate fan-in count +- Entry node must be explicit and unique + +--- + +## Validation expectations + +Before export, the following must be enforced: + +- Exactly one entry node +- All nodes reachable from the entry node +- No orphaned edges +- No cycles unless explicitly supported +- Node-specific structural constraints enforced + +Validation errors must be: + +- Deterministic +- Human-readable +- Mapped to node IDs where possible +- Suitable for UI display + +--- + +## UI & styling guidelines + +### Svelte + Svelte Flow + +- Svelte Flow is the canonical canvas abstraction +- Use **Svelte Flow’s native CSS** for graph rendering +- Do not reimplement or override core Svelte Flow layout behavior +- Inspector panels edit **node config**, not graph topology +- UI must reflect validation state clearly +- Avoid auto-magic graph rewrites + +--- + +### UI primitives & styling approach + +This project does **not** use a general-purpose CSS framework. + +Instead: + +- UI styling is defined explicitly in app-owned SCSS +- Common UI elements are implemented as small, reusable Svelte components +- Styling exists to support correctness and clarity, not visual experimentation + +Core expectations: + +- Define a small set of UI primitives (buttons, inputs, panels, modals) +- Prefer composition over large, configurable components +- Keep styles predictable and easy to audit +- Avoid hidden behaviour encoded in CSS +- Layout should be explicit in Svelte components + +Do not: + +- Recreate a full component framework +- Introduce large sets of generic utility classes +- Encode application logic in CSS +- Add theming or design-token abstractions prematurely + +--- + +### SCSS rules + +- All custom styles must be written in **SCSS** +- Prefer variables, mixins, and nesting over repetition +- SCSS should express structure and intent, not act as a component framework +- Keep Svelte Flow styling separate from app UI styles +- Avoid global CSS leakage where possible + +Encouraged: + +- A small number of well-named SCSS entry points +- Clear separation between: + - Design tokens (spacing, colours, typography) + - Layout helpers actually used by the app + - App-specific component styles + - Svelte Flow-related styles + +--- + +## Performance guidelines (important) + +This editor must remain responsive for **medium-to-large graphs**. +Performance regressions are considered correctness issues. + +### Graph & state management + +- Treat the Flow Graph as immutable at the conceptual level +- Prefer targeted updates over full graph replacement +- Avoid deep cloning unless necessary +- Do not recompute validation on every minor UI interaction +- Debounce or batch expensive operations (validation, export) + +--- + +### Svelte-specific guidance + +- Avoid unnecessary reactive statements on large collections +- Be explicit about reactivity boundaries +- Prefer derived values over duplicated state +- Do not bind large objects directly to form inputs + +--- + +### Deprecated APIs and patterns + +**CRITICAL: Never use deprecated APIs or patterns.** + +This applies to all dependencies and frameworks in the project. + +Core principles: + +- Use current, non-deprecated APIs for all new code +- If a deprecation warning appears, fix it immediately +- Do not ignore, suppress, or work around deprecation warnings +- Follow the official migration path for deprecated features +- Prefer the recommended pattern over backwards-compatible approaches + +When in doubt: + +- Check TypeScript hints and IDE warnings +- Consult official documentation for the relevant library or framework +- Use the pattern that produces no warnings +- Ask + +--- + +### Svelte Flow usage + +- Do not recreate node or edge arrays unnecessarily +- Avoid excessive custom node re-rendering +- Keep custom node components lightweight +- Avoid DOM-heavy node templates +- Be cautious with large numbers of edge labels + +--- + +### CSS & layout performance + +- Avoid expensive global selectors +- Minimize deeply nested SCSS rules +- Do not animate layout-affecting properties unnecessarily +- Prefer transform-based animations when needed + +--- + +### Server & Docker considerations + +- Server routes should be stateless +- Avoid long-running synchronous operations +- Export and validation should be fast and deterministic +- Assume multiple concurrent users in production + +--- + +## Formatting & linting (do not fight the tools) + +### Prettier + +This project uses a **strict, predefined Prettier configuration**. + +Key expectations: + +- Single quotes +- Trailing commas +- 80-character line width +- Sorted imports +- Proper Svelte formatting via `prettier-plugin-svelte` + +Claude should not introduce formatting changes that contradict Prettier output. + +**IMPORTANT: Before completing any work, always run `npm run format` and +`npm run lint` to ensure all files are properly formatted. This is mandatory.** + +The `npm run lint` command includes: + +- Prettier code formatting check +- ESLint for JavaScript/TypeScript code +- Markdown linting (markdownlint-cli2) for all .md files + +**IMPORTANT: After fixing format and lint issues, run `npm run dev` to verify +the application starts without errors. Fix any runtime errors before considering +the work complete. This is mandatory.** + +--- + +### ESLint + +- ESLint flat config is authoritative +- TypeScript + Svelte rules are enabled +- `no-undef` is intentionally disabled +- Svelte files are type-checked via `typescript-eslint` + +**IMPORTANT: Before completing any work, always run `npm run lint` to ensure +all code passes linting. This is mandatory.** + +Do not: + +- Suppress lint rules casually +- Introduce alternative lint configs +- Disable rules without justification + +Fix code, not rules. + +--- + +## TypeScript rules + +- TypeScript is mandatory for all new code +- Prefer explicit types at module boundaries +- Avoid `any`; if used, explain why in a comment +- Shared graph types must live outside UI components + +--- + +## Export / output + +- Export formats must be stable and versioned +- No UI-only metadata in exported output +- Exporters should be pure functions +- Prefer deterministic ordering for diff-friendliness + +--- + +## Testing expectations + +- Flow validation logic must be unit tested +- Exporters must have golden-file tests +- UI tests should focus on interaction and behavior, not layout + +--- + +## Dependency management + +- Prefer latest stable versions of dependencies +- Avoid unnecessary dependencies +- Document any major dependency decisions + +--- + +## When unsure + +If requirements are ambiguous: + +- Ask before introducing new node semantics +- Prefer extending the schema over special cases +- Leave TODOs with context rather than guessing + +Clarity beats speed. +Correctness beats cleverness. + +--- + +## Creative scope & default assumptions + +Unless explicitly instructed otherwise, assume: + +- This project is a **developer-facing tool**, not a consumer product +- The goal is **clarity and correctness** over visual polish +- Default outputs should be: + - Minimal but complete + - Explicit rather than abstract + - Easy to extend later + +Claude should not: + +- Invent product features or workflows without being asked +- Add UX affordances “just in case” +- Introduce configuration surfaces prematurely +- Assume multi-user or collaborative features by default + +When asked to “build” something: + +- Start with the smallest viable, end-to-end slice +- Prefer scaffolding that can grow over finished-looking systems diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 8c67a01..655438e 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -17,23 +17,23 @@ diverse, inclusive, and healthy community. Examples of behavior that contributes to a positive environment for our community include: -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -* Focusing on what is best not just for us as individuals, but for the +- Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: -* The use of sexualized language or imagery, and sexual attention or +- The use of sexualized language or imagery, and sexual attention or advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities @@ -60,7 +60,7 @@ representative at an online or offline event. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -[simon@simonemms.com]. +. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the @@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an +standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7fbf51b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,57 @@ +# Copyright 2025 - 2026 Zigflow authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM node:lts AS dev +ARG APP +ARG GIT_COMMIT +ARG VERSION +USER node +WORKDIR /home/node/app +ENV GIT_COMMIT="${GIT_COMMIT}" +ENV VERSION="${VERSION}" +COPY --chown=node:node . . +ENV HOST=0.0.0.0 +ENV PORT=5173 +EXPOSE 5173 +CMD [ "npm", "run", "dev" ] + +FROM node:lts-alpine AS builder +ARG VERSION +ENV VERSION="${VERSION}" +USER node +WORKDIR /home/node/app +COPY --chown=node:node . . +RUN npm ci \ + && npm run build \ + && npm prune --production + +FROM gcr.io/distroless/nodejs20 +ARG GIT_COMMIT +ARG GIT_REPO +ARG VERSION +WORKDIR /opt/app +ENV GIT_REPO="${GIT_REPO}" +ENV GIT_COMMIT="${GIT_COMMIT}" +ENV VERSION="${VERSION}" +ENV HOST=0.0.0.0 +ENV PORT=3000 +ENV PUBLIC_WORKFLOWS_DIR=/data +ENV NODE_ENV=production +COPY --from=builder /home/node/app/build build +COPY --from=builder /home/node/app/node_modules node_modules +COPY --from=builder /home/node/app/package.json package.json +USER 65532 +EXPOSE 3000 +VOLUME [ "/data" ] +CMD [ "build" ] diff --git a/Makefile b/Makefile deleted file mode 100644 index cf99770..0000000 --- a/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2026 Zigflow authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -cruft-update: -ifeq (,$(wildcard .cruft.json)) - @echo "Cruft not configured" -else - @cruft check || cruft update --skip-apply-ask --refresh-private-variables -endif -.PHONY: cruft-update diff --git a/README.md b/README.md index 699bc9c..2a0d5fa 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,3 @@ -# ui +# UI A drag and drop UI for building Temporal workflows - - - -* [Contributing](#contributing) - * [Open in Gitpod](#open-in-gitpod) - * [Open in a container](#open-in-a-container) - * [Commit style](#commit-style) - - - - - -## Contributing - -### Open in Gitpod - -* [Open in Gitpod](https://gitpod.io/from-referrer/) - -### Open in a container - -* [Open in a container](https://code.visualstudio.com/docs/devcontainers/containers) - -### Commit style - -All commits must be done in the [Conventional Commit](https://www.conventionalcommits.org) -format. - -```git -[optional scope]: - -[optional body] - -[optional footer(s)] -``` diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..58adc35 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,59 @@ +version: '3' + +vars: + TMP_IMG: ttl.sh/zigflow-ui + TMP_IMG_TAG: 24h + +tasks: + commitlint: + desc: Run commitlint + cmds: + - npx commitlint --version + - npx commitlint --to HEAD + + cruft-update: + desc: Check/update cruft template + cmds: + - | + if [ ! -f .cruft.json ]; then + echo "Cruft not configured" + else + cruft check || cruft update --skip-apply-ask --refresh-private-variables + fi + + helm-img: + desc: Build and push temporary Helm image + cmds: + - docker build -t {{.TMP_IMG}}:{{.TMP_IMG_TAG}} . + - docker push {{.TMP_IMG}}:{{.TMP_IMG_TAG}} + + helm: + desc: Deploy Helm chart locally + cmds: + - touch values.example.yaml + - | + helm upgrade \ + --cleanup-on-fail \ + --create-namespace \ + --install \ + --namespace zigflow \ + --reset-values \ + --rollback-on-failure \ + --set image.pullPolicy=Always \ + --set image.repository={{.TMP_IMG}} \ + --set image.tag={{.TMP_IMG_TAG}} \ + --values ./values.example.yaml \ + --wait \ + zigflow ./charts/ui + + minikube: + desc: Start minikube and apply dev manifests + cmds: + - | + minikube profile list | grep minikube | grep OK || minikube start + + scan: + desc: Scan for vulnerabilities + cmds: + - trivy config --severity HIGH,CRITICAL --format table --exit-code 1 charts/ui + - trivy image --severity HIGH,CRITICAL --format table --exit-code 1 --pkg-types os,library --ignore-unfixed ghcr.io/zigflow/ui diff --git a/charts/ui/.helmignore b/charts/ui/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/ui/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/ui/Chart.yaml b/charts/ui/Chart.yaml new file mode 100644 index 0000000..915fc20 --- /dev/null +++ b/charts/ui/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +name: ui +description: Web UI for visualising and editing Zigflow workflows +type: application +version: 0.0.0 +icon: https://raw.githubusercontent.com/zigflow/zigflow/refs/heads/main/designs/z-logo.png +home: https://zigflow.dev +maintainers: + - name: Simon Emms + email: simon@simonemms.com + url: https://simonemms.com +sources: + - https://github.com/zigflow/ui +keywords: + - DSL + - Durable Execution + - Serverless Workflow + - Temporal + - Workflow Management System + - Workflows + - YAML +annotations: + org.opencontainers.image.documentation: https://github.com/zigflow/ui/tree/main/charts/ui diff --git a/charts/ui/README.md b/charts/ui/README.md new file mode 100644 index 0000000..38a5b9f --- /dev/null +++ b/charts/ui/README.md @@ -0,0 +1,56 @@ +# ui + +![Version: 0.0.0](https://img.shields.io/badge/Version-0.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) + +Web UI for visualising and editing Zigflow workflows + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| Simon Emms | | | + +## Source Code + +* + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | Node affinity | +| autoscaling.enabled | bool | `false` | Autoscaling enabled | +| autoscaling.maxReplicas | int | `100` | Maximum replicas | +| autoscaling.minReplicas | int | `1` | Minimum replicas | +| autoscaling.targetCPUUtilizationPercentage | int | `80` | When to trigger a new replica | +| dataDir | string | `"/data"` | Path on the container where workflow YAML files are read from | +| envvars | list | `[]` | Additional environment variables | +| fullnameOverride | string | `""` | String to fully override names | +| image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | +| image.repository | string | `"ghcr.io/zigflow/ui"` | Image repository | +| image.tag | string | `""` | Image tag - defaults to the chart's Version if not set | +| imagePullSecrets | list | `[]` | Docker registry secret names | +| livenessProbe.httpGet.path | string | `"/"` | Path to demonstrate app liveness | +| livenessProbe.httpGet.port | string | `"http"` | Port to demonstrate app liveness | +| nameOverride | string | `""` | String to partially override name | +| nodeSelector | object | `{}` | Node selector | +| podAnnotations | object | `{}` | Pod annotations | +| podLabels | object | `{}` | Pod labels | +| podSecurityContext | object | `{"fsGroup":1000,"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` | Pod's security context | +| readinessProbe.httpGet.path | string | `"/"` | Path to demonstrate app readiness | +| readinessProbe.httpGet.port | string | `"http"` | Port to demonstrate app readiness | +| replicaCount | int | `1` | Number of replicas | +| resources | object | `{}` | Configure resources available | +| securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` | Container's security context | +| service.port | int | `3000` | Service port | +| service.type | string | `"ClusterIP"` | Service type | +| serviceAccount.annotations | object | `{}` | Annotations to add to the service account | +| serviceAccount.automount | bool | `true` | Automatically mount a ServiceAccount's API credentials? | +| serviceAccount.create | bool | `true` | Specifies whether a service account should be created | +| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | +| tolerations | list | `[]` | Node toleration | +| volumeMounts | list | `[]` | Additional volumeMounts on the output Deployment definition. | +| volumes | list | `[]` | Additional volumes on the output Deployment definition. | + diff --git a/charts/ui/README.tpl b/charts/ui/README.tpl new file mode 100644 index 0000000..cecb8ab --- /dev/null +++ b/charts/ui/README.tpl @@ -0,0 +1,44 @@ +{* + Copyright 2025 - 2026 Zigflow authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*} + +# Zigflow UI + +{{ template "chart.deprecationWarning" . }} + +[![Version](https://img.shields.io/github/v/release/zigflow/ui?label=Version&color=007ec6)](https://github.com/zigflow/ui/tree/main/charts/ui) +![Type: Application](https://img.shields.io/badge/Type-Application-informational) + +{{ template "chart.description" . }} + +{{ template "chart.homepageLine" . }} + +## TL;DR + +Be sure to set `${ZIGFLOW_VERSION}` with [your desired version](https://github.com/zigflow/ui/pkgs/container/charts%2Fui) + +```sh +helm install myrelease oci://ghcr.io/mrsimonemms/charts/ui@${ZIGFLOW_VERSION} +``` + +{{ template "chart.maintainersSection" . }} + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSectionHtml" . }} + +{{ template "helm-docs.versionFooter" . }} diff --git a/charts/ui/templates/NOTES.txt b/charts/ui/templates/NOTES.txt new file mode 100644 index 0000000..16a95f5 --- /dev/null +++ b/charts/ui/templates/NOTES.txt @@ -0,0 +1,5 @@ +Deployed +======== + +App: {{ include "ui.fullname" . }} +Namespace: {{ .Release.Namespace }} diff --git a/charts/ui/templates/_helpers.tpl b/charts/ui/templates/_helpers.tpl new file mode 100644 index 0000000..4570828 --- /dev/null +++ b/charts/ui/templates/_helpers.tpl @@ -0,0 +1,80 @@ +{* + Copyright 2025 - 2026 Zigflow authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*} + + + +{{/* +Expand the name of the chart. +*/}} +{{- define "ui.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "ui.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ui.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "ui.labels" -}} +helm.sh/chart: {{ include "ui.chart" . }} +{{ include "ui.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "ui.selectorLabels" -}} +app.kubernetes.io/name: {{ include "ui.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "ui.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "ui.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/ui/templates/deployment.yaml b/charts/ui/templates/deployment.yaml new file mode 100644 index 0000000..255e821 --- /dev/null +++ b/charts/ui/templates/deployment.yaml @@ -0,0 +1,88 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "ui.fullname" . }} + labels: + {{- include "ui.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "ui.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "ui.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "ui.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.Version }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: HOST + value: "0.0.0.0" + - name: PORT + value: {{ .Values.service.port | quote }} + - name: PUBLIC_WORKFLOWS_DATA_DIR + value: {{ .Values.dataDir | quote }} + {{- with .Values.envvars }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/ui/templates/hpa.yaml b/charts/ui/templates/hpa.yaml new file mode 100644 index 0000000..aa932aa --- /dev/null +++ b/charts/ui/templates/hpa.yaml @@ -0,0 +1,32 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "ui.fullname" . }} + labels: + {{- include "ui.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "ui.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/charts/ui/templates/service.yaml b/charts/ui/templates/service.yaml new file mode 100644 index 0000000..68b5f34 --- /dev/null +++ b/charts/ui/templates/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "ui.fullname" . }} + labels: {{- include "ui.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: {{- include "ui.selectorLabels" . | nindent 4 }} diff --git a/charts/ui/templates/serviceaccount.yaml b/charts/ui/templates/serviceaccount.yaml new file mode 100644 index 0000000..82e4c86 --- /dev/null +++ b/charts/ui/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "ui.serviceAccountName" . }} + labels: + {{- include "ui.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +{{- end }} diff --git a/charts/ui/templates/tests/test-connection.yaml b/charts/ui/templates/tests/test-connection.yaml new file mode 100644 index 0000000..125cf32 --- /dev/null +++ b/charts/ui/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "ui.fullname" . }}-test-connection" + labels: + {{- include "ui.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "ui.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/charts/ui/values.yaml b/charts/ui/values.yaml new file mode 100644 index 0000000..afa155a --- /dev/null +++ b/charts/ui/values.yaml @@ -0,0 +1,110 @@ +# Default values for ui. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# -- Number of replicas +replicaCount: 1 + +# -- Path on the container where workflow YAML files are read from +dataDir: /data + +# -- Additional environment variables +envvars: [] +# - name: SOME_VAR +# value: some-value + +image: + # -- Image repository + repository: ghcr.io/zigflow/ui + # -- Image pull policy + pullPolicy: IfNotPresent + # -- Image tag - defaults to the chart's Version if not set + tag: "" + +# -- Docker registry secret names +imagePullSecrets: [] +# -- String to partially override name +nameOverride: "" +# -- String to fully override names +fullnameOverride: "" + +serviceAccount: + # -- Specifies whether a service account should be created + create: true + # -- Automatically mount a ServiceAccount's API credentials? + automount: true + # -- Annotations to add to the service account + annotations: {} + # -- The name of the service account to use. If not set and create is true, a name is generated using the fullname template + name: "" + +# -- Pod annotations +podAnnotations: {} +# -- Pod labels +podLabels: {} + +# -- Pod's security context +podSecurityContext: + runAsNonRoot: true + fsGroup: 1000 + seccompProfile: + type: RuntimeDefault + +# -- Container's security context +securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + +service: + # -- Service type + type: ClusterIP + # -- Service port + port: 3000 + +# -- Configure resources available +resources: {} + +livenessProbe: + httpGet: + # -- Path to demonstrate app liveness + path: / + # -- Port to demonstrate app liveness + port: http +readinessProbe: + httpGet: + # -- Path to demonstrate app readiness + path: / + # -- Port to demonstrate app readiness + port: http + +autoscaling: + # -- Autoscaling enabled + enabled: false + # -- Minimum replicas + minReplicas: 1 + # -- Maximum replicas + maxReplicas: 100 + # -- When to trigger a new replica + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +# -- Additional volumes on the output Deployment definition. +volumes: [] + +# -- Additional volumeMounts on the output Deployment definition. +volumeMounts: [] + +# -- Node selector +nodeSelector: {} + +# -- Node toleration +tolerations: [] + +# -- Node affinity +affinity: {} diff --git a/eslint.config.js b/eslint.config.js index 5ce6254..0adad1f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,5 @@ /* - * Copyright 2026 Zigflow authors + * Copyright 2025 - 2026 Zigflow authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,37 +13,48 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { includeIgnoreFile } from '@eslint/compat'; import js from '@eslint/js'; import prettier from 'eslint-config-prettier'; import svelte from 'eslint-plugin-svelte'; import globals from 'globals'; +import { fileURLToPath } from 'node:url'; import ts from 'typescript-eslint'; -export default ts.config( - js.configs.recommended, - ...ts.configs.recommended, - ...svelte.configs['flat/recommended'], - prettier, - ...svelte.configs['flat/prettier'], - { - languageOptions: { - globals: { - ...globals.browser, - ...globals.node, - }, - }, - }, - { - files: ['**/*.svelte'], +import svelteConfig from './svelte.config.js'; - languageOptions: { - parserOptions: { - parser: ts.parser, - }, - }, - }, - { - ignores: ['build/', '.svelte-kit/', 'dist/'], - }, +const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url)); + +export default ts.config( + includeIgnoreFile(gitignorePath), + js.configs.recommended, + ...ts.configs.recommended, + ...svelte.configs['flat/recommended'], + prettier, + ...svelte.configs['flat/prettier'], + { + languageOptions: { + globals: { ...globals.browser, ...globals.node }, + }, + rules: { + // typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects. + // see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors + 'no-undef': 'off', + // eslint-plugin-svelte@3.15.x crashes with TypeError when visiting boolean + // shorthand attributes (e.g. `fitView` with no value). Disable until fixed upstream. + // see: https://github.com/sveltejs/eslint-plugin-svelte/issues + 'svelte/no-navigation-without-resolve': 'off', + }, + }, + { + files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'], + languageOptions: { + parserOptions: { + projectService: true, + extraFileExtensions: ['.svelte'], + parser: ts.parser, + svelteConfig, + }, + }, + }, ); diff --git a/package-lock.json b/package-lock.json index 151771b..23995de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,37 +1,150 @@ { - "name": "ui", + "name": "@zigflow/ui", "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "ui", + "name": "@zigflow/ui", "version": "0.0.0", "license": "Apache-2.0", "devDependencies": { - "@sveltejs/adapter-static": "^3.0.1", - "@sveltejs/kit": "^2.5.10", - "@sveltejs/vite-plugin-svelte": "^4.0.0", - "@types/eslint": "^9.6.0", - "eslint": "^9.7.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-svelte": "^2.39.0", - "globals": "^15.0.0", - "prettier": "^3.2.5", - "prettier-plugin-organize-imports": "^3.2.4", - "prettier-plugin-svelte": "^3.2.3", - "svelte": "^5.0.0", - "svelte-check": "^4.0.0", - "typescript": "^5.4.5", - "typescript-eslint": "^8.0.0", - "vite": "^5.2.11", - "vitest": "^2.0.0" + "@eslint/compat": "^2.0.3", + "@eslint/js": "^9.39.4", + "@playwright/test": "^1.58.2", + "@sveltejs/adapter-node": "^5.5.4", + "@sveltejs/kit": "^2.53.4", + "@sveltejs/vite-plugin-svelte": "^6.2.4", + "@trivago/prettier-plugin-sort-imports": "^6.0.2", + "@types/js-yaml": "^4.0.9", + "@types/node": "^25.3.5", + "@xyflow/svelte": "^1.5.1", + "eslint": "^9.39.4", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-svelte": "^3.15.1", + "globals": "^17.4.0", + "js-yaml": "^4.1.1", + "prettier": "^3.8.1", + "prettier-plugin-svelte": "^3.5.1", + "svelte": "^5.53.8", + "svelte-check": "^4.4.5", + "typescript": "^5.9.3", + "typescript-eslint": "^8.57.0", + "vite": "^7.3.1" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", "cpu": [ "ppc64" ], @@ -42,13 +155,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", "cpu": [ "arm" ], @@ -59,13 +172,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", "cpu": [ "arm64" ], @@ -76,13 +189,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", "cpu": [ "x64" ], @@ -93,13 +206,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", "cpu": [ "arm64" ], @@ -110,13 +223,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", "cpu": [ "x64" ], @@ -127,13 +240,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", "cpu": [ "arm64" ], @@ -144,13 +257,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", "cpu": [ "x64" ], @@ -161,13 +274,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", "cpu": [ "arm" ], @@ -178,13 +291,11 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.27.3", "cpu": [ "arm64" ], @@ -195,13 +306,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", "cpu": [ "ia32" ], @@ -212,13 +323,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", "cpu": [ "loong64" ], @@ -229,13 +340,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", "cpu": [ "mips64el" ], @@ -246,13 +357,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", "cpu": [ "ppc64" ], @@ -263,13 +374,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", "cpu": [ "riscv64" ], @@ -280,13 +391,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", "cpu": [ "s390x" ], @@ -297,13 +408,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", "cpu": [ "x64" ], @@ -314,13 +425,30 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", "cpu": [ "x64" ], @@ -331,13 +459,30 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", "cpu": [ "x64" ], @@ -348,13 +493,30 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", "cpu": [ "x64" ], @@ -365,13 +527,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", "cpu": [ "arm64" ], @@ -382,13 +544,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", "cpu": [ "ia32" ], @@ -399,13 +561,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", "cpu": [ "x64" ], @@ -416,13 +578,11 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -440,8 +600,6 @@ }, "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "license": "Apache-2.0", "engines": { @@ -453,18 +611,33 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/compat": { + "version": "2.0.3", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.1.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "peerDependencies": { + "eslint": "^8.40 || 9 || 10" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, "node_modules/@eslint/config-array": { "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", - "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -476,10 +649,28 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/config-helpers": { "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -489,10 +680,8 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/core": { + "node_modules/@eslint/config-helpers/node_modules/@eslint/core": { "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -502,10 +691,19 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/core": { + "version": "1.1.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, "node_modules/@eslint/eslintrc": { "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", - "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", "dev": true, "license": "MIT", "dependencies": { @@ -526,10 +724,17 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", "engines": { @@ -539,10 +744,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/js": { "version": "9.39.4", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", - "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", "dev": true, "license": "MIT", "engines": { @@ -554,8 +768,6 @@ }, "node_modules/@eslint/object-schema": { "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -564,8 +776,6 @@ }, "node_modules/@eslint/plugin-kit": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -576,10 +786,19 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.17.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -588,8 +807,6 @@ }, "node_modules/@humanfs/node": { "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -602,8 +819,6 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -616,8 +831,6 @@ }, "node_modules/@humanwhocodes/retry": { "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -630,8 +843,6 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { @@ -641,8 +852,6 @@ }, "node_modules/@jridgewell/remapping": { "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "license": "MIT", "dependencies": { @@ -652,8 +861,6 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", "engines": { @@ -662,15 +869,11 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -678,13 +881,113 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@playwright/test": { + "version": "1.58.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@polka/url": { "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", - "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", "dev": true, "license": "MIT" }, + "node_modules/@rollup/plugin-commonjs": { + "version": "29.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.2.0", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-json": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "16.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.59.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", @@ -799,8 +1102,6 @@ }, "node_modules/@rollup/rollup-linux-arm64-gnu": { "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", "cpu": [ "arm64" ], @@ -1037,35 +1338,41 @@ }, "node_modules/@standard-schema/spec": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, + "node_modules/@svelte-put/shortcut": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "svelte": "^5.1.0" + } + }, "node_modules/@sveltejs/acorn-typescript": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.9.tgz", - "integrity": "sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==", "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^8.9.0" } }, - "node_modules/@sveltejs/adapter-static": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.10.tgz", - "integrity": "sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew==", + "node_modules/@sveltejs/adapter-node": { + "version": "5.5.4", "dev": true, "license": "MIT", + "dependencies": { + "@rollup/plugin-commonjs": "^29.0.0", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.0", + "rollup": "^4.59.0" + }, "peerDependencies": { - "@sveltejs/kit": "^2.0.0" + "@sveltejs/kit": "^2.4.0" } }, "node_modules/@sveltejs/kit": { "version": "2.53.4", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.53.4.tgz", - "integrity": "sha512-iAIPEahFgDJJyvz8g0jP08KvqnM6JvdW8YfsygZ+pMeMvyM2zssWMltcsotETvjSZ82G3VlitgDtBIvpQSZrTA==", "dev": true, "license": "MIT", "dependencies": { @@ -1105,88 +1412,162 @@ } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-4.0.4.tgz", - "integrity": "sha512-0ba1RQ/PHen5FGpdSrW7Y3fAMQjrXantECALeOiOdBdzR5+5vPP6HVZRLmZaQL+W8m++o+haIAKq5qT+MiZ7VA==", + "version": "6.2.4", "dev": true, "license": "MIT", "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^3.0.0-next.0||^3.0.0", - "debug": "^4.3.7", + "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", "deepmerge": "^4.3.1", - "kleur": "^4.1.5", - "magic-string": "^0.30.12", - "vitefu": "^1.0.3" + "magic-string": "^0.30.21", + "obug": "^2.1.0", + "vitefu": "^1.1.1" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22" + "node": "^20.19 || ^22.12 || >=24" }, "peerDependencies": { - "svelte": "^5.0.0-next.96 || ^5.0.0", - "vite": "^5.0.0" + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" } }, "node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-3.0.1.tgz", - "integrity": "sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ==", + "version": "5.0.2", "dev": true, "license": "MIT", "dependencies": { - "debug": "^4.3.7" + "obug": "^2.1.0" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22" + "node": "^20.19 || ^22.12 || >=24" }, "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^4.0.0-next.0||^4.0.0", - "svelte": "^5.0.0-next.96 || ^5.0.0", - "vite": "^5.0.0" + "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports": { + "version": "6.0.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/generator": "^7.28.0", + "@babel/parser": "^7.28.0", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.0", + "javascript-natural-sort": "^0.7.1", + "lodash-es": "^4.17.21", + "minimatch": "^9.0.0", + "parse-imports-exports": "^0.2.4" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@vue/compiler-sfc": "3.x", + "prettier": "2.x - 3.x", + "prettier-plugin-ember-template-tag": ">= 2.0.0", + "prettier-plugin-svelte": "3.x", + "svelte": "4.x || 5.x" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + }, + "prettier-plugin-ember-template-tag": { + "optional": true + }, + "prettier-plugin-svelte": { + "optional": true + }, + "svelte": { + "optional": true + } } }, "node_modules/@types/cookie": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", "dev": true, "license": "MIT" }, - "node_modules/@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "node_modules/@types/d3-color": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" } }, "node_modules/@types/estree": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", "dev": true, "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.2", "dev": true, "license": "MIT" }, "node_modules/@types/trusted-types": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "dev": true, "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.0.tgz", - "integrity": "sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1214,8 +1595,6 @@ }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, "license": "MIT", "engines": { @@ -1224,8 +1603,6 @@ }, "node_modules/@typescript-eslint/parser": { "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.0.tgz", - "integrity": "sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==", "dev": true, "license": "MIT", "dependencies": { @@ -1249,8 +1626,6 @@ }, "node_modules/@typescript-eslint/project-service": { "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.0.tgz", - "integrity": "sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==", "dev": true, "license": "MIT", "dependencies": { @@ -1271,8 +1646,6 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.0.tgz", - "integrity": "sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==", "dev": true, "license": "MIT", "dependencies": { @@ -1289,8 +1662,6 @@ }, "node_modules/@typescript-eslint/tsconfig-utils": { "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.0.tgz", - "integrity": "sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==", "dev": true, "license": "MIT", "engines": { @@ -1306,8 +1677,6 @@ }, "node_modules/@typescript-eslint/type-utils": { "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.0.tgz", - "integrity": "sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1331,8 +1700,6 @@ }, "node_modules/@typescript-eslint/types": { "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.0.tgz", - "integrity": "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==", "dev": true, "license": "MIT", "engines": { @@ -1345,8 +1712,6 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.0.tgz", - "integrity": "sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==", "dev": true, "license": "MIT", "dependencies": { @@ -1373,8 +1738,6 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, "license": "MIT", "engines": { @@ -1383,8 +1746,6 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { @@ -1396,8 +1757,6 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -1412,176 +1771,83 @@ }, "node_modules/@typescript-eslint/utils": { "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.0.tgz", - "integrity": "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.57.0", "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.0.tgz", - "integrity": "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.57.0", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@vitest/expect": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", - "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "2.1.9", - "@vitest/utils": "2.1.9", - "chai": "^5.1.2", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/mocker": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", - "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "2.1.9", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.12" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^5.0.0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } - } - }, - "node_modules/@vitest/pretty-format": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", - "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^1.2.0" + "@typescript-eslint/typescript-estree": "8.57.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@vitest/runner": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", - "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.57.0", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "2.1.9", - "pathe": "^1.1.2" + "@typescript-eslint/types": "8.57.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@vitest/snapshot": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", - "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "2.1.9", - "magic-string": "^0.30.12", - "pathe": "^1.1.2" + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://opencollective.com/eslint" } }, - "node_modules/@vitest/spy": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", - "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "node_modules/@xyflow/svelte": { + "version": "1.5.1", "dev": true, "license": "MIT", "dependencies": { - "tinyspy": "^3.0.2" + "@svelte-put/shortcut": "^4.1.0", + "@xyflow/system": "0.0.75" }, - "funding": { - "url": "https://opencollective.com/vitest" + "peerDependencies": { + "svelte": "^5.25.0" } }, - "node_modules/@vitest/utils": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", - "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "node_modules/@xyflow/system": { + "version": "0.0.75", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.9", - "loupe": "^3.1.2", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/d3-drag": "^3.0.7", + "@types/d3-interpolate": "^3.0.4", + "@types/d3-selection": "^3.0.10", + "@types/d3-transition": "^3.0.8", + "@types/d3-zoom": "^3.0.8", + "d3-drag": "^3.0.0", + "d3-interpolate": "^3.0.1", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0" } }, "node_modules/acorn": { "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -1593,8 +1859,6 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1603,8 +1867,6 @@ }, "node_modules/ajv": { "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -1620,8 +1882,6 @@ }, "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": { @@ -1636,35 +1896,19 @@ }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, "license": "Python-2.0" }, "node_modules/aria-query": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", - "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">= 0.4" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, "node_modules/axobject-query": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1673,63 +1917,27 @@ }, "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/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==", + "version": "2.0.2", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "balanced-match": "^1.0.0" } }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, "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": { @@ -1743,20 +1951,8 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, "node_modules/chokidar": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", "dependencies": { @@ -1771,8 +1967,6 @@ }, "node_modules/clsx": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "dev": true, "license": "MIT", "engines": { @@ -1781,8 +1975,6 @@ }, "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": { @@ -1794,22 +1986,21 @@ }, "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/commondir": { + "version": "1.0.1", "dev": true, "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, "license": "MIT" }, "node_modules/cookie": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, "license": "MIT", "engines": { @@ -1818,8 +2009,6 @@ }, "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": { @@ -1833,8 +2022,6 @@ }, "node_modules/cssesc": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, "license": "MIT", "bin": { @@ -1844,10 +2031,104 @@ "node": ">=4" } }, + "node_modules/d3-color": { + "version": "3.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/debug": { "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { @@ -1862,27 +2143,13 @@ } } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "license": "MIT", "engines": { @@ -1891,22 +2158,11 @@ }, "node_modules/devalue": { "version": "5.6.3", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.3.tgz", - "integrity": "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==", - "dev": true, - "license": "MIT" - }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", "dev": true, "license": "MIT" }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.27.3", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1914,38 +2170,39 @@ "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" } }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { @@ -1957,8 +2214,6 @@ }, "node_modules/eslint": { "version": "9.39.4", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", - "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2015,62 +2270,44 @@ } } }, - "node_modules/eslint-compat-utils": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", - "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, "node_modules/eslint-config-prettier": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", - "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", + "version": "10.1.8", "dev": true, "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, "peerDependencies": { "eslint": ">=7.0.0" } }, "node_modules/eslint-plugin-svelte": { - "version": "2.46.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.46.1.tgz", - "integrity": "sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw==", + "version": "3.15.1", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@jridgewell/sourcemap-codec": "^1.4.15", - "eslint-compat-utils": "^0.5.1", + "@eslint-community/eslint-utils": "^4.6.1", + "@jridgewell/sourcemap-codec": "^1.5.0", "esutils": "^2.0.3", - "known-css-properties": "^0.35.0", - "postcss": "^8.4.38", + "globals": "^16.0.0", + "known-css-properties": "^0.37.0", + "postcss": "^8.4.49", "postcss-load-config": "^3.1.4", - "postcss-safe-parser": "^6.0.0", - "postcss-selector-parser": "^6.1.0", - "semver": "^7.6.2", - "svelte-eslint-parser": "^0.43.0" + "postcss-safe-parser": "^7.0.0", + "semver": "^7.6.3", + "svelte-eslint-parser": "^1.4.0" }, "engines": { - "node": "^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://github.com/sponsors/ota-meshi" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0", + "eslint": "^8.57.1 || ^9.0.0 || ^10.0.0", "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "peerDependenciesMeta": { @@ -2079,10 +2316,19 @@ } } }, + "node_modules/eslint-plugin-svelte/node_modules/globals": { + "version": "16.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-scope": { "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -2098,8 +2344,6 @@ }, "node_modules/eslint-visitor-keys": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2109,17 +2353,44 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/core": { + "version": "0.17.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/esm-env": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", - "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", "dev": true, "license": "MIT" }, "node_modules/espree": { "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -2136,8 +2407,6 @@ }, "node_modules/esquery": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -2149,8 +2418,6 @@ }, "node_modules/esrap": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.3.tgz", - "integrity": "sha512-8fOS+GIGCQZl/ZIlhl59htOlms6U8NvX6ZYgYHpRU/b6tVSh3uHkOHZikl3D4cMbYM0JlpBe+p/BkZEi8J9XIQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2159,8 +2426,6 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -2172,8 +2437,6 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -2181,60 +2444,35 @@ } }, "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "version": "2.0.2", "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } + "license": "MIT" }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, "license": "MIT" }, "node_modules/fdir": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", "engines": { @@ -2251,8 +2489,6 @@ }, "node_modules/file-entry-cache": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2264,8 +2500,6 @@ }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { @@ -2281,8 +2515,6 @@ }, "node_modules/flat-cache": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { @@ -2295,15 +2527,13 @@ }, "node_modules/flatted": { "version": "3.4.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", - "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", "dev": true, "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -2315,10 +2545,16 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", "dependencies": { @@ -2329,9 +2565,7 @@ } }, "node_modules/globals": { - "version": "15.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", - "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "version": "17.4.0", "dev": true, "license": "MIT", "engines": { @@ -2343,18 +2577,25 @@ }, "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/hasown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -2363,8 +2604,6 @@ }, "node_modules/import-fresh": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2380,18 +2619,28 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" } }, + "node_modules/is-core-module": { + "version": "2.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", "engines": { @@ -2400,8 +2649,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { @@ -2411,27 +2658,36 @@ "node": ">=0.10.0" } }, + "node_modules/is-module": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, "node_modules/is-reference": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", - "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "version": "1.2.1", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "^1.0.6" + "@types/estree": "*" } }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "dev": true, + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, "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==", "dev": true, "license": "MIT", "dependencies": { @@ -2441,31 +2697,34 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, "license": "MIT" }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", "dependencies": { @@ -2474,8 +2733,6 @@ }, "node_modules/kleur": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", "dev": true, "license": "MIT", "engines": { @@ -2483,16 +2740,12 @@ } }, "node_modules/known-css-properties": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz", - "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==", + "version": "0.37.0", "dev": true, "license": "MIT" }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2505,8 +2758,6 @@ }, "node_modules/lilconfig": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "dev": true, "license": "MIT", "engines": { @@ -2515,15 +2766,11 @@ }, "node_modules/locate-character": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", "dev": true, "license": "MIT" }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { @@ -2536,24 +2783,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "node_modules/lodash-es": { + "version": "4.17.23", "dev": true, "license": "MIT" }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "node_modules/lodash.merge": { + "version": "4.6.2", "dev": true, "license": "MIT" }, "node_modules/magic-string": { "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2561,22 +2802,21 @@ } }, "node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "version": "9.0.9", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.2" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mri": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", "dev": true, "license": "MIT", "engines": { @@ -2585,8 +2825,6 @@ }, "node_modules/mrmime": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "dev": true, "license": "MIT", "engines": { @@ -2595,15 +2833,11 @@ }, "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==", "dev": true, "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -2621,15 +2855,20 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, "license": "MIT" }, + "node_modules/obug": { + "version": "2.1.1", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, "node_modules/optionator": { "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", "dependencies": { @@ -2646,8 +2885,6 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2662,8 +2899,6 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -2678,8 +2913,6 @@ }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", "dependencies": { @@ -2689,10 +2922,21 @@ "node": ">=6" } }, + "node_modules/parse-imports-exports": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-statements": "1.0.11" + } + }, + "node_modules/parse-statements": { + "version": "1.0.11", + "dev": true, + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { @@ -2701,42 +2945,24 @@ }, "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/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "node_modules/path-parse": { + "version": "1.0.7", "dev": true, "license": "MIT" }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, "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/picomatch": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -2746,10 +2972,36 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/playwright": { + "version": "1.58.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.58.2", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/postcss": { "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, "funding": [ { @@ -2777,8 +3029,6 @@ }, "node_modules/postcss-load-config": { "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", - "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", "dev": true, "license": "MIT", "dependencies": { @@ -2805,27 +3055,41 @@ } } }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "1.10.2", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, "node_modules/postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "version": "7.0.1", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "node": ">=18.0" }, "peerDependencies": { - "postcss": "^8.3.3" + "postcss": "^8.4.31" } }, "node_modules/postcss-scss": { "version": "4.0.9", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", - "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", "dev": true, "funding": [ { @@ -2850,9 +3114,7 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "version": "7.1.1", "dev": true, "license": "MIT", "dependencies": { @@ -2865,8 +3127,6 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", "engines": { @@ -2875,8 +3135,6 @@ }, "node_modules/prettier": { "version": "3.8.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", - "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", "bin": { @@ -2889,31 +3147,8 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/prettier-plugin-organize-imports": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.4.tgz", - "integrity": "sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@volar/vue-language-plugin-pug": "^1.0.4", - "@volar/vue-typescript": "^1.0.4", - "prettier": ">=2.0", - "typescript": ">=2.9" - }, - "peerDependenciesMeta": { - "@volar/vue-language-plugin-pug": { - "optional": true - }, - "@volar/vue-typescript": { - "optional": true - } - } - }, "node_modules/prettier-plugin-svelte": { "version": "3.5.1", - "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.5.1.tgz", - "integrity": "sha512-65+fr5+cgIKWKiqM1Doum4uX6bY8iFCdztvvp2RcF+AJoieaw9kJOFMNcJo/bkmKYsxFaM9OsVZK/gWauG/5mg==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2923,8 +3158,6 @@ }, "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": { @@ -2933,8 +3166,6 @@ }, "node_modules/readdirp": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, "license": "MIT", "engines": { @@ -2945,10 +3176,27 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/resolve": { + "version": "1.22.11", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", "engines": { @@ -2957,8 +3205,6 @@ }, "node_modules/rollup": { "version": "4.59.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "dev": true, "license": "MIT", "dependencies": { @@ -3002,8 +3248,6 @@ }, "node_modules/sade": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", "dev": true, "license": "MIT", "dependencies": { @@ -3015,8 +3259,6 @@ }, "node_modules/semver": { "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -3028,15 +3270,11 @@ }, "node_modules/set-cookie-parser": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.0.1.tgz", - "integrity": "sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==", "dev": true, "license": "MIT" }, "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": { @@ -3048,25 +3286,14 @@ }, "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/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, "node_modules/sirv": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", - "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", "dev": true, "license": "MIT", "dependencies": { @@ -3080,32 +3307,14 @@ }, "node_modules/source-map-js": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", - "dev": true, - "license": "MIT" - }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", "engines": { @@ -3117,8 +3326,6 @@ }, "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": { @@ -3128,10 +3335,19 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/svelte": { "version": "5.53.8", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.53.8.tgz", - "integrity": "sha512-UD++BnEc3PUFgjin381LiMHzDjT187Fy+KsPZxvaKrYPZqR0GQ/Ha8h7GDoegIF8tFl1uogoNUejKgcRk77T2Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3158,8 +3374,6 @@ }, "node_modules/svelte-check": { "version": "4.4.5", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.4.5.tgz", - "integrity": "sha512-1bSwIRCvvmSHrlK52fOlZmVtUZgil43jNL/2H18pRpa+eQjzGt6e3zayxhp1S7GajPFKNM/2PMCG+DZFHlG9fw==", "dev": true, "license": "MIT", "dependencies": { @@ -3181,20 +3395,21 @@ } }, "node_modules/svelte-eslint-parser": { - "version": "0.43.0", - "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.43.0.tgz", - "integrity": "sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==", + "version": "1.6.0", "dev": true, "license": "MIT", "dependencies": { - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "postcss": "^8.4.39", - "postcss-scss": "^4.0.9" + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.0.0", + "postcss": "^8.4.49", + "postcss-scss": "^4.0.9", + "postcss-selector-parser": "^7.0.0", + "semver": "^7.7.2" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0", + "pnpm": "10.30.3" }, "funding": { "url": "https://github.com/sponsors/ota-meshi" @@ -3208,72 +3423,16 @@ } } }, - "node_modules/svelte-eslint-parser/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/svelte-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/svelte-eslint-parser/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "node_modules/svelte/node_modules/is-reference": { + "version": "3.0.3", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "@types/estree": "^1.0.6" } }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, - "license": "MIT" - }, "node_modules/tinyglobby": { "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3287,40 +3446,8 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", - "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", - "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/totalist": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, "license": "MIT", "engines": { @@ -3329,8 +3456,6 @@ }, "node_modules/ts-api-utils": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", - "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", "dev": true, "license": "MIT", "engines": { @@ -3342,8 +3467,6 @@ }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", "dependencies": { @@ -3355,8 +3478,6 @@ }, "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": { @@ -3369,8 +3490,6 @@ }, "node_modules/typescript-eslint": { "version": "8.57.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.0.tgz", - "integrity": "sha512-W8GcigEMEeB07xEZol8oJ26rigm3+bfPHxHvwbYUlu1fUDsGuQ7Hiskx5xGW/xM4USc9Ephe3jtv7ZYPQntHeA==", "dev": true, "license": "MIT", "dependencies": { @@ -3391,10 +3510,13 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/undici-types": { + "version": "7.18.2", + "dev": true, + "license": "MIT" + }, "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": { @@ -3403,27 +3525,26 @@ }, "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" }, "node_modules/vite": { - "version": "5.4.21", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", - "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "version": "7.3.1", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -3432,19 +3553,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -3465,36 +3592,32 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, - "node_modules/vite-node": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", - "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.7", - "es-module-lexer": "^1.5.4", - "pathe": "^1.1.2", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/vitefu": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.2.tgz", - "integrity": "sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==", "dev": true, "license": "MIT", "workspaces": [ @@ -3511,76 +3634,8 @@ } } }, - "node_modules/vitest": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", - "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "2.1.9", - "@vitest/mocker": "2.1.9", - "@vitest/pretty-format": "^2.1.9", - "@vitest/runner": "2.1.9", - "@vitest/snapshot": "2.1.9", - "@vitest/spy": "2.1.9", - "@vitest/utils": "2.1.9", - "chai": "^5.1.2", - "debug": "^4.3.7", - "expect-type": "^1.1.0", - "magic-string": "^0.30.12", - "pathe": "^1.1.2", - "std-env": "^3.8.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.1", - "tinypool": "^1.0.1", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0", - "vite-node": "2.1.9", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.1.9", - "@vitest/ui": "2.1.9", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, "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": { @@ -3593,47 +3648,16 @@ "node": ">= 8" } }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", "engines": { @@ -3645,8 +3669,6 @@ }, "node_modules/zimmerframe": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", - "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", "dev": true, "license": "MIT" } diff --git a/package.json b/package.json index 63399f2..c5e0681 100644 --- a/package.json +++ b/package.json @@ -1,39 +1,47 @@ { - "name": "ui", - "version": "0.0.0", + "name": "@zigflow/ui", "description": "A drag and drop UI for building Temporal workflows", - "author": "Zigflow authors ", "private": true, "license": "Apache-2.0", + "version": "0.0.0", + "type": "module", "scripts": { "build": "vite build", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "dev": "vite dev", - "format": "prettier --plugin prettier-plugin-svelte --plugin prettier-plugin-organize-imports --write .", - "lint": "prettier --plugin prettier-plugin-svelte --plugin prettier-plugin-organize-imports --check . && eslint .", + "format": "prettier --write .", + "lint": "prettier --check . && eslint .", "preview": "vite preview", - "test": "npm run test:unit", - "test:unit": "vitest" + "prepare": "svelte-kit sync || echo ''", + "start": "node build", + "test:e2e": "playwright test", + "test:e2e:ui": "playwright test --ui", + "test:e2e:headed": "playwright test --headed", + "test:e2e:debug": "playwright test --debug" }, "devDependencies": { - "@sveltejs/adapter-static": "^3.0.1", - "@sveltejs/kit": "^2.5.10", - "@sveltejs/vite-plugin-svelte": "^4.0.0", - "@types/eslint": "^9.6.0", - "eslint": "^9.7.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-svelte": "^2.39.0", - "globals": "^15.0.0", - "prettier": "^3.2.5", - "prettier-plugin-organize-imports": "^3.2.4", - "prettier-plugin-svelte": "^3.2.3", - "svelte": "^5.0.0", - "svelte-check": "^4.0.0", - "typescript": "^5.4.5", - "typescript-eslint": "^8.0.0", - "vite": "^5.2.11", - "vitest": "^2.0.0" - }, - "type": "module" + "@eslint/compat": "^2.0.3", + "@eslint/js": "^9.39.4", + "@playwright/test": "^1.58.2", + "@sveltejs/adapter-node": "^5.5.4", + "@sveltejs/kit": "^2.53.4", + "@sveltejs/vite-plugin-svelte": "^6.2.4", + "@trivago/prettier-plugin-sort-imports": "^6.0.2", + "@types/js-yaml": "^4.0.9", + "@types/node": "^25.3.5", + "@xyflow/svelte": "^1.5.1", + "eslint": "^9.39.4", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-svelte": "^3.15.1", + "globals": "^17.4.0", + "js-yaml": "^4.1.1", + "prettier": "^3.8.1", + "prettier-plugin-svelte": "^3.5.1", + "svelte": "^5.53.8", + "svelte-check": "^4.4.5", + "typescript": "^5.9.3", + "typescript-eslint": "^8.57.0", + "vite": "^7.3.1" + } } diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..cf35c5a --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2025 - 2026 Zigflow authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testDir: './tests', + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, + reporter: 'html', + + use: { + baseURL: 'http://localhost:5173', + trace: 'on-first-retry', + }, + + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + // Start with Chromium only to reduce noise while stabilising + // Re-enable others later if needed + ], + + webServer: { + command: 'npm run dev', + url: 'http://localhost:5173', + reuseExistingServer: true, + timeout: 120_000, + }, +}); diff --git a/skaffold.yaml b/skaffold.yaml new file mode 100644 index 0000000..8ea60b0 --- /dev/null +++ b/skaffold.yaml @@ -0,0 +1,48 @@ +apiVersion: skaffold/v4beta13 +kind: Config +metadata: + name: ui + +build: + artifacts: + - image: ui + docker: + dockerfile: Dockerfile + target: dev + sync: + manual: + - src: "src/**/*" + dest: /home/node/app + - src: "static/**/*" + dest: /home/node/app + local: + push: false + useBuildkit: true + +deploy: + helm: + releases: + - name: ui + chartPath: charts/ui + namespace: zigflow + createNamespace: true + setValueTemplates: + image.repository: "{{.IMAGE_REPO_ui}}" + image.tag: "{{.IMAGE_TAG_ui}}" + setValues: + image: + pullPolicy: Never + securityContext: + readOnlyRootFilesystem: false + +portForward: + - resourceType: Service + resourceName: ui + namespace: zigflow + port: 3000 + localPort: 3000 + +profiles: + - name: minikube + activation: + - kubeContext: minikube diff --git a/src/app.d.ts b/src/app.d.ts index 69ea6a6..96b188e 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -1,5 +1,5 @@ /* - * Copyright 2026 Zigflow authors + * Copyright 2025 - 2026 Zigflow authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,13 @@ // See https://svelte.dev/docs/kit/types#app.d.ts // for information about these interfaces declare global { - namespace App { - // interface Error {} - // interface Locals {} - // interface PageData {} - // interface PageState {} - // interface Platform {} - } + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } } export {}; diff --git a/src/app.html b/src/app.html index 3f1bc28..bdf0c9f 100644 --- a/src/app.html +++ b/src/app.html @@ -1,5 +1,5 @@ + + + + + + diff --git a/src/lib/ui/Canvas.svelte b/src/lib/ui/Canvas.svelte new file mode 100644 index 0000000..554093b --- /dev/null +++ b/src/lib/ui/Canvas.svelte @@ -0,0 +1,325 @@ + + + + +
+ + + + +
+ + diff --git a/src/lib/ui/ContextIndicator.svelte b/src/lib/ui/ContextIndicator.svelte new file mode 100644 index 0000000..80f96fc --- /dev/null +++ b/src/lib/ui/ContextIndicator.svelte @@ -0,0 +1,53 @@ + + + + + + +{#if label} +
+ {label} +
+{/if} + + diff --git a/src/lib/ui/FlowNode.svelte b/src/lib/ui/FlowNode.svelte new file mode 100644 index 0000000..89710e9 --- /dev/null +++ b/src/lib/ui/FlowNode.svelte @@ -0,0 +1,270 @@ + + + + + + +
cb?.onselect(id)} + onkeydown={(e) => { + if (e.key === 'Enter' || e.key === ' ') cb?.onselect(id); + }} + role="button" + tabindex="0" +> + + + {#if isStructural} + +
+ {data.typeLabel} + {data.label} +
+ + {#if data.navRows && data.navRows.length > 0} +
    + {#each data.navRows as row (row.id)} +
  • + +
  • + {/each} +
+ {/if} + {:else} + +
+ {data.typeLabel} + {data.label} +
+ {/if} + + +
+ + diff --git a/src/lib/ui/Inspector.svelte b/src/lib/ui/Inspector.svelte new file mode 100644 index 0000000..a65d134 --- /dev/null +++ b/src/lib/ui/Inspector.svelte @@ -0,0 +1,537 @@ + + + + + + + diff --git a/src/lib/ui/Sidebar.svelte b/src/lib/ui/Sidebar.svelte new file mode 100644 index 0000000..16cab0e --- /dev/null +++ b/src/lib/ui/Sidebar.svelte @@ -0,0 +1,271 @@ + + + + + + + diff --git a/src/lib/ui/canvas-context.ts b/src/lib/ui/canvas-context.ts new file mode 100644 index 0000000..f52e7cd --- /dev/null +++ b/src/lib/ui/canvas-context.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2025 - 2026 Zigflow authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Shared context key and type for Canvas → FlowNode callback communication. +// Keeping callbacks out of node data ensures structuredClone can succeed on +// node objects, which silences SvelteFlow's "Use $state.raw for nodes" warning. + +export const CANVAS_CALLBACKS_KEY = 'canvas-callbacks'; + +export type CanvasCallbacks = { + onselect: (nodeId: string) => void; + onenternode: (nodeId: string) => void; + onenterbranch: (nodeId: string, branchId: string) => void; +}; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..c40a65d --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,37 @@ + + + + + + + + +{@render children()} + + diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte deleted file mode 100644 index cc88df0..0000000 --- a/src/routes/+page.svelte +++ /dev/null @@ -1,2 +0,0 @@ -

Welcome to SvelteKit

-

Visit svelte.dev/docs/kit to read the documentation

diff --git a/src/index.test.ts b/src/routes/+page.ts similarity index 69% rename from src/index.test.ts rename to src/routes/+page.ts index 5f11acc..b548b02 100644 --- a/src/index.test.ts +++ b/src/routes/+page.ts @@ -1,5 +1,5 @@ /* - * Copyright 2026 Zigflow authors + * Copyright 2025 - 2026 Zigflow authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { redirect } from '@sveltejs/kit'; -import { describe, expect, it } from 'vitest'; +import type { PageLoad } from './$types'; -describe('sum test', () => { - it('adds 1 + 2 to equal 3', () => { - expect(1 + 2).toBe(3); - }); -}); +export const load: PageLoad = () => { + redirect(307, '/workflows'); +}; diff --git a/src/routes/workflows/+page.server.ts b/src/routes/workflows/+page.server.ts new file mode 100644 index 0000000..d8df88e --- /dev/null +++ b/src/routes/workflows/+page.server.ts @@ -0,0 +1,84 @@ +/* + * Copyright 2025 - 2026 Zigflow authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { env } from '$env/dynamic/public'; +import { redirect } from '@sveltejs/kit'; +import { promises as fs } from 'fs'; +import yaml from 'js-yaml'; +import { resolve } from 'path'; + +import type { Actions, PageServerLoad } from './$types'; + +const WORKFLOWS_DIR = + env.PUBLIC_WORKFLOWS_DIR ?? resolve(process.cwd(), 'workflows'); + +export const load: PageServerLoad = async () => { + let workflowFiles: string[] = []; + try { + const entries = await fs.readdir(WORKFLOWS_DIR); + workflowFiles = entries + .filter((f) => f.endsWith('.yaml') || f.endsWith('.yml')) + .sort(); + } catch { + // Directory does not exist yet — return empty list. + } + return { workflowFiles }; +}; + +export const actions: Actions = { + default: async ({ request }) => { + const formData = await request.formData(); + const rawName = String(formData.get('name') ?? '').trim(); + if (!rawName) { + return { error: 'Workflow name is required' }; + } + + // Sanitise: lowercase, alphanumeric and hyphens only. + const name = rawName + .toLowerCase() + .replace(/[^a-z0-9-]/g, '-') + .replace(/-+/g, '-') + .replace(/^-|-$/g, ''); + + if (!name) { + return { + error: 'Workflow name must contain at least one valid character', + }; + } + + const fileName = `${name}.yaml`; + const filePath = resolve(WORKFLOWS_DIR, fileName); + + // New format: wrap the primary workflow under its name. + const skeleton = yaml.dump( + { + document: { + dsl: '1.0.0', + namespace: 'default', + name, + version: '0.0.1', + title: name, + }, + do: [{ [name]: { do: [] } }], + }, + { indent: 2, lineWidth: -1, noRefs: true, sortKeys: false }, + ); + + await fs.mkdir(WORKFLOWS_DIR, { recursive: true }); + await fs.writeFile(filePath, skeleton, 'utf-8'); + + redirect(302, `/workflows/${fileName}`); + }, +}; diff --git a/src/routes/workflows/+page.svelte b/src/routes/workflows/+page.svelte new file mode 100644 index 0000000..52fbf57 --- /dev/null +++ b/src/routes/workflows/+page.svelte @@ -0,0 +1,131 @@ + + + + +
+

Workflows

+ + {#if data.workflowFiles.length > 0} + + {:else} +

No workflow files found.

+ {/if} + +
+ + +
+
+ + diff --git a/src/routes/workflows/[...workflowId]/+page.server.ts b/src/routes/workflows/[...workflowId]/+page.server.ts new file mode 100644 index 0000000..ae3edb0 --- /dev/null +++ b/src/routes/workflows/[...workflowId]/+page.server.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2025 - 2026 Zigflow authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { env } from '$env/dynamic/public'; +import { exportToYaml } from '$lib/export/yaml'; +import { parseWorkflowFile } from '$lib/tasks/parse'; +import { error } from '@sveltejs/kit'; +import { promises as fs } from 'fs'; +import { resolve } from 'path'; + +import type { PageServerLoad } from './$types'; + +const WORKFLOWS_DIR = + env.PUBLIC_WORKFLOWS_DIR ?? resolve(process.cwd(), 'workflows'); + +export const load: PageServerLoad = async ({ params }) => { + const fileName = params.workflowId; + const filePath = resolve(WORKFLOWS_DIR, fileName); + + let content: string; + try { + content = await fs.readFile(filePath, 'utf-8'); + } catch { + throw error(404, `Workflow file not found: ${fileName}`); + } + + let workflowFile, modified; + try { + ({ workflowFile, modified } = parseWorkflowFile(content, fileName)); + } catch (err) { + throw error(400, `Failed to parse workflow "${fileName}": ${err}`); + } + + // Write back immediately if any IDs were generated, so deep links remain + // stable within the same file across server restarts. + if (modified) { + const result = exportToYaml(workflowFile); + if (result.ok) { + await fs.writeFile(filePath, result.yaml, 'utf-8'); + } + } + + return { workflowFile }; +}; diff --git a/src/routes/workflows/[...workflowId]/+page.svelte b/src/routes/workflows/[...workflowId]/+page.svelte new file mode 100644 index 0000000..21a9eb3 --- /dev/null +++ b/src/routes/workflows/[...workflowId]/+page.svelte @@ -0,0 +1,999 @@ + + + + +
+ + + + +
+
+ + +
+ + + +
+ {#if currentGraph !== null} + + {:else} +
No graph to display.
+ {/if} + + +
+
+
+ + +{#if showExport} + +{/if} + + diff --git a/src/routes/+layout.ts b/src/routes/workflows/[...workflowId]/+page.ts similarity index 57% rename from src/routes/+layout.ts rename to src/routes/workflows/[...workflowId]/+page.ts index f8eeda3..593f53c 100644 --- a/src/routes/+layout.ts +++ b/src/routes/workflows/[...workflowId]/+page.ts @@ -1,5 +1,5 @@ /* - * Copyright 2026 Zigflow authors + * Copyright 2025 - 2026 Zigflow authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import type { PageLoad } from './$types'; -// Settings useful for statically generated sites -export const prerender = true; -export const ssr = true; -export const trailingSlash = 'always'; +export const load: PageLoad = ({ data, params, url }) => { + const selected = url.searchParams.get('selected'); + const selectedSegments = selected ? selected.split('/').filter(Boolean) : []; + return { + ...data, + workflowId: params.workflowId, + selectedSegments, + }; +}; diff --git a/src/styles/.gitkeep b/src/styles/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/static/favicon.png b/static/favicon.png deleted file mode 100644 index 825b9e65af7c104cfb07089bb28659393b4f2097..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1571 zcmV+;2Hg3HP)Px)-AP12RCwC$UE6KzI1p6{F2N z1VK2vi|pOpn{~#djwYcWXTI_im_u^TJgMZ4JMOsSj!0ma>B?-(Hr@X&W@|R-$}W@Z zgj#$x=!~7LGqHW?IO8+*oE1MyDp!G=L0#^lUx?;!fXv@l^6SvTnf^ac{5OurzC#ZMYc20lI%HhX816AYVs1T3heS1*WaWH z%;x>)-J}YB5#CLzU@GBR6sXYrD>Vw(Fmt#|JP;+}<#6b63Ike{Fuo!?M{yEffez;| zp!PfsuaC)>h>-AdbnwN13g*1LowNjT5?+lFVd#9$!8Z9HA|$*6dQ8EHLu}U|obW6f z2%uGv?vr=KNq7YYa2Roj;|zooo<)lf=&2yxM@e`kM$CmCR#x>gI>I|*Ubr({5Y^rb zghxQU22N}F51}^yfDSt786oMTc!W&V;d?76)9KXX1 z+6Okem(d}YXmmOiZq$!IPk5t8nnS{%?+vDFz3BevmFNgpIod~R{>@#@5x9zJKEHLHv!gHeK~n)Ld!M8DB|Kfe%~123&Hz1Z(86nU7*G5chmyDe ziV7$pB7pJ=96hpxHv9rCR29%bLOXlKU<_13_M8x)6;P8E1Kz6G<&P?$P^%c!M5`2` zfY2zg;VK5~^>TJGQzc+33-n~gKt{{of8GzUkWmU110IgI0DLxRIM>0US|TsM=L|@F z0Bun8U!cRB7-2apz=y-7*UxOxz@Z0)@QM)9wSGki1AZ38ceG7Q72z5`i;i=J`ILzL z@iUO?SBBG-0cQuo+an4TsLy-g-x;8P4UVwk|D8{W@U1Zi z!M)+jqy@nQ$p?5tsHp-6J304Q={v-B>66$P0IDx&YT(`IcZ~bZfmn11#rXd7<5s}y zBi9eim&zQc0Dk|2>$bs0PnLmDfMP5lcXRY&cvJ=zKxI^f0%-d$tD!`LBf9^jMSYUA zI8U?CWdY@}cRq6{5~y+)#h1!*-HcGW@+gZ4B};0OnC~`xQOyH19z*TA!!BJ%9s0V3F?CAJ{hTd#*tf+ur-W9MOURF-@B77_-OshsY}6 zOXRY=5%C^*26z?l)1=$bz30!so5tfABdSYzO+H=CpV~aaUefmjvfZ3Ttu9W&W3Iu6 zROlh0MFA5h;my}8lB0tAV-Rvc2Zs_CCSJnx@d`**$idgy-iMob4dJWWw|21b4NB=LfsYp0Aeh{Ov)yztQi;eL4y5 zMi>8^SzKqk8~k?UiQK^^-5d8c%bV?$F8%X~czyiaKCI2=UH + * Copyright 2025 - 2026 Zigflow authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,24 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import adapter from '@sveltejs/adapter-node'; -import adapter from '@sveltejs/adapter-static'; -import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; - -/** @type {import('@sveltejs/vite-plugin-svelte').Config} */ +/** @type {import('@sveltejs/kit').Config} */ const config = { - // Consult https://kit.svelte.dev/docs/integrations#preprocessors - // for more information about preprocessors - preprocess: vitePreprocess(), + compilerOptions: { + runes: true, + }, - kit: { - // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. - // If your environment is not supported or you settled on a specific environment, switch out the adapter. - // See https://kit.svelte.dev/docs/adapters for more information about adapters. - adapter: adapter({ - fallback: '404.html', - }), - }, + kit: { + adapter: adapter(), + }, }; export default config; diff --git a/tests/workflow-navigation.spec.ts b/tests/workflow-navigation.spec.ts new file mode 100644 index 0000000..6678425 --- /dev/null +++ b/tests/workflow-navigation.spec.ts @@ -0,0 +1,99 @@ +/* + * Copyright 2025 - 2026 Zigflow authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { expect, test } from '@playwright/test'; + +const WORKFLOW = '/workflows/demo-workflow.yaml'; + +test.describe('Workflow navigation invariants', () => { + test('selecting a root node updates query param', async ({ page }) => { + await page.goto(WORKFLOW); + + await page.getByText('greet').click(); + + const url = new URL(page.url()); + const selected = url.searchParams.get('selected'); + + expect(selected).toBeTruthy(); + expect(selected?.split('/').length).toBe(1); + }); + + test('refresh preserves root selection', async ({ page }) => { + await page.goto(WORKFLOW); + + await page.getByText('greet').click(); + const firstUrl = page.url(); + + await page.reload(); + await expect(page).toHaveURL(firstUrl); + + await expect( + page.locator('.flow-node-name', { hasText: 'greet' }), + ).toHaveAttribute('data-selected', 'true'); + + // Inspector should also be open after refresh with a selected node. + await expect(page.locator('.inspector-name')).toContainText('greet'); + }); + + test('selecting switch branch updates query param', async ({ page }) => { + await page.goto(WORKFLOW); + + await page.getByText('route').click(); + await page.getByText('fast-path').click(); + + const url = new URL(page.url()); + const selected = url.searchParams.get('selected'); + + expect(selected).toBeTruthy(); + expect(selected?.split('/').length).toBe(2); + }); + + test('deep link restores branch context', async ({ page }) => { + await page.goto(WORKFLOW); + + await page.getByText('route').click(); + await page.getByText('fast-path').click(); + + const deepLink = page.url(); + + const newPage = await page.context().newPage(); + await newPage.goto(deepLink); + + await expect(newPage).toHaveURL(deepLink); + await expect(newPage.getByText(/Editing/i)).toContainText('fast-path'); + }); + + test('browser back restores previous selection', async ({ page }) => { + await page.goto(WORKFLOW); + + await page.getByText('greet').click(); + const firstUrl = page.url(); + + await page.getByText('pause').click(); + const secondUrl = page.url(); + + expect(firstUrl).not.toBe(secondUrl); + + await page.goBack(); + + await expect(page).toHaveURL(firstUrl); + await expect( + page.locator('.flow-node-name', { hasText: 'greet' }), + ).toHaveAttribute('data-selected', 'true'); + + // Inspector should reopen after popstate restores a selected node. + await expect(page.locator('.inspector-name')).toContainText('greet'); + }); +}); diff --git a/tests/yaml-export-shape.spec.ts b/tests/yaml-export-shape.spec.ts new file mode 100644 index 0000000..bbd2d06 --- /dev/null +++ b/tests/yaml-export-shape.spec.ts @@ -0,0 +1,63 @@ +/* + * Copyright 2025 - 2026 Zigflow authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { expect, test } from '@playwright/test'; + +const WORKFLOW = '/workflows/demo-workflow.yaml'; + +test.describe('YAML export shape', () => { + test('exported YAML uses workflows-list format', async ({ page }) => { + await page.goto(WORKFLOW); + + await page.getByRole('button', { name: 'Export YAML' }).click(); + + const exportCode = page.locator('.export-code'); + await expect(exportCode).toBeVisible(); + + const text = await exportCode.textContent(); + expect(text).toBeTruthy(); + + // Top-level do: must contain named workflow declarations, not bare steps. + expect(text).toMatch(/- demo-workflow:\s+do:/); + + // Hoisted sub-workflows must appear as top-level workflow entries. + expect(text).toMatch(/- route-fast-path:\s+do:/); + expect(text).toMatch(/- route-default:\s+do:/); + + // Switch branches must use then: references, not inline steps. + expect(text).toContain('then: route-fast-path'); + expect(text).toContain('then: route-default'); + + // Primary workflow steps must be nested under demo-workflow.do. + expect(text).toContain('greet:'); + expect(text).toContain('pause:'); + expect(text).toContain('route:'); + }); + + test('sidebar lists all top-level workflows', async ({ page }) => { + await page.goto(WORKFLOW); + + // All three workflows from the new format should be in the sidebar. + await expect( + page.getByRole('button', { name: 'demo-workflow' }), + ).toBeVisible(); + await expect( + page.getByRole('button', { name: 'route-fast-path' }), + ).toBeVisible(); + await expect( + page.getByRole('button', { name: 'route-default' }), + ).toBeVisible(); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 4344710..bbeba3a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "./.svelte-kit/tsconfig.json", "compilerOptions": { + "rewriteRelativeImportExtensions": true, "allowJs": true, "checkJs": true, "esModuleInterop": true, diff --git a/vite.config.ts b/vite.config.ts index 216663b..ef5a8f6 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,5 @@ /* - * Copyright 2026 Zigflow authors + * Copyright 2025 - 2026 Zigflow authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,17 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - import { sveltekit } from '@sveltejs/kit/vite'; -import { defineConfig } from 'vitest/config'; +import { defineConfig } from 'vite'; export default defineConfig({ - plugins: [sveltekit()], - server: { - host: process.env.VITE_HOST, - port: Number(process.env.VITE_PORT ?? 5173), - }, - test: { - include: ['src/**/*.{test,spec}.{js,ts}'], - }, + plugins: [sveltekit()], + server: { + host: process.env.HOST ?? '0.0.0.0', + port: Number(process.env.PORT ?? 5173), + }, }); diff --git a/workflows/demo-workflow.yaml b/workflows/demo-workflow.yaml new file mode 100644 index 0000000..4ee00dc --- /dev/null +++ b/workflows/demo-workflow.yaml @@ -0,0 +1,60 @@ +document: + dsl: 1.0.0 + namespace: demo + name: demo-workflow + version: 0.0.1 + title: Demo Workflow +do: + - demo-workflow: + do: + - greet: + set: + message: Hello, World! + metadata: + __zigflow_id: 15b9ba59-d039-46cd-9d88-0b4adeae4d3d + - pause: + wait: + seconds: 5 + metadata: + __zigflow_id: 76e94b56-cdef-4d2c-8e34-9ef4272c2022 + - route: + switch: + - fast-path: + then: route-fast-path + when: ${ $input.fast == true } + metadata: + __zigflow_id: f24ed99f-e0f0-4779-8ab6-b013f2589889 + - default: + then: route-default + metadata: + __zigflow_id: 895e4b0a-ff1e-4ccd-9295-e6c7b763958c + metadata: + __zigflow_id: c4dd198a-b394-4a7e-81c1-764c87ae509b + - parallel-work: + fork: + compete: false + branches: + - branch-a: + do: [] + metadata: + __zigflow_id: 8fd21a81-26c0-4023-87c3-a284ee857f4c + - branch-b: + do: [] + metadata: + __zigflow_id: 742eca7b-6f91-4200-901f-31b76a74395b + metadata: + __zigflow_id: a28d11d1-6e35-453f-b2af-64811c0ff650 + - safe-call: + try: [] + metadata: + __zigflow_id: 7e649e6b-50f6-4e93-a501-7f8ffaf4d6aa + - process-items: + for: + in: ${ $input.items } + do: [] + metadata: + __zigflow_id: e4879bd8-ed9e-4955-bff1-33490e86e5f7 + - route-fast-path: + do: [] + - route-default: + do: [] From f927c76b49045d1fe4ca30d25e415faf841c40c1 Mon Sep 17 00:00:00 2001 From: Simon Emms Date: Tue, 10 Mar 2026 18:13:11 +0000 Subject: [PATCH 02/10] chore: add security policy Signed-off-by: Simon Emms --- SECURITY.md | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..019b351 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,114 @@ +# Security Policy + +Zigflow is an open-source project licensed under the Apache License 2.0 and is +provided on an "AS IS" basis, without warranties or conditions of any kind. + +Security issues are taken seriously and will be addressed on a best-effort basis. + +--- + +## Supported Versions + +Security updates are provided for: + +- The `main` branch +- The most recent stable release + +Older releases may not receive security updates. Users are strongly encouraged +to upgrade to the latest version. + +There are no guaranteed response times or service level agreements. + +--- + +## Reporting a Vulnerability + +If you discover a security vulnerability, please report it privately. + +**Do not open a public GitHub issue for security vulnerabilities.** + +Instead, use one of the following: + +- GitHub Security Advisories via the repository’s Security tab +- Email: + +Please include: + +- A clear description of the vulnerability +- The affected version(s) or commit(s) +- Steps to reproduce +- A proof of concept, exploit details or logs where possible +- Any suggested mitigation + +You will receive an acknowledgement within 5 working days. +As Zigflow is maintained in spare time, response times may occasionally be longer. + +If you do not receive a response within that time, please follow up. + +--- + +## What to Expect + +After a report is received: + +1. The issue will be reviewed and severity assessed. +2. Additional information may be requested. +3. If confirmed, a fix will be developed and released. +4. The vulnerability may be disclosed publicly once a fix is available. + +Fix timelines depend on severity, complexity and maintainer availability. +There are no guaranteed remediation timelines. + +--- + +## CVEs + +Where appropriate, a CVE identifier may be requested and published for +confirmed vulnerabilities. + +If a CVE is assigned: + +- The CVE ID will be referenced in the security advisory +- Release notes will document affected versions +- Remediation guidance will be provided + +--- + +## Scope + +This policy applies to: + +- The Zigflow source code +- Official releases and distributed artefacts +- Build and packaging configuration + +Out of scope: + +- Vulnerabilities in third-party dependencies unless directly introduced by Zigflow +- Theoretical issues without a reproducible attack path +- Denial of service under unrealistic load conditions +- Social engineering or phishing attempts + +--- + +## Responsible Disclosure + +Please: + +- Avoid accessing data that does not belong to you +- Avoid modifying or deleting data +- Avoid actions that could degrade availability for other users + +If you act in good faith and follow responsible disclosure practices, no legal +action will be taken against you for reporting vulnerabilities. + +--- + +## Security Best Practices for Users + +Users of Zigflow should: + +- Run the latest supported version +- Restrict network exposure where applicable +- Follow the principle of least privilege +- Monitor logs and system behaviour for anomalies From 2bc04a0183af8bc5bf3379bba025696251e993fd Mon Sep 17 00:00:00 2001 From: Simon Emms Date: Tue, 10 Mar 2026 19:07:20 +0000 Subject: [PATCH 03/10] chore: rename project to studio Signed-off-by: Simon Emms --- .cruft.json | 4 +- .github/workflows/build.yml | 38 +++++++++---------- .licenserc.yaml | 2 +- Dockerfile | 2 +- README.md | 5 ++- Taskfile.yml | 8 ++-- charts/{ui => studio}/.helmignore | 0 charts/{ui => studio}/Chart.yaml | 6 +-- charts/{ui => studio}/README.md | 6 +-- charts/{ui => studio}/README.tpl | 10 ++--- charts/{ui => studio}/templates/NOTES.txt | 2 +- charts/{ui => studio}/templates/_helpers.tpl | 22 +++++------ .../{ui => studio}/templates/deployment.yaml | 10 ++--- charts/{ui => studio}/templates/hpa.yaml | 6 +-- charts/{ui => studio}/templates/service.yaml | 6 +-- .../templates/serviceaccount.yaml | 4 +- .../templates/tests/test-connection.yaml | 6 +-- charts/{ui => studio}/values.yaml | 4 +- eslint.config.js | 2 +- package-lock.json | 4 +- package.json | 2 +- playwright.config.ts | 2 +- skaffold.yaml | 14 +++---- src/app.d.ts | 2 +- src/app.html | 2 +- src/lib/export/yaml.ts | 2 +- src/lib/index.ts | 2 +- src/lib/tasks/actions.ts | 2 +- src/lib/tasks/model.ts | 2 +- src/lib/tasks/parse.ts | 2 +- src/lib/tasks/registry.ts | 2 +- src/lib/tasks/validation.ts | 2 +- src/lib/ui/Breadcrumb.svelte | 2 +- src/lib/ui/Canvas.svelte | 2 +- src/lib/ui/ContextIndicator.svelte | 2 +- src/lib/ui/FlowNode.svelte | 2 +- src/lib/ui/Inspector.svelte | 2 +- src/lib/ui/Sidebar.svelte | 2 +- src/routes/+layout.svelte | 2 +- src/routes/+page.ts | 2 +- src/routes/workflows/+page.server.ts | 2 +- src/routes/workflows/+page.svelte | 2 +- .../workflows/[...workflowId]/+page.server.ts | 2 +- .../workflows/[...workflowId]/+page.svelte | 2 +- src/routes/workflows/[...workflowId]/+page.ts | 2 +- svelte.config.js | 2 +- tests/workflow-navigation.spec.ts | 2 +- vite.config.ts | 2 +- 48 files changed, 109 insertions(+), 106 deletions(-) rename charts/{ui => studio}/.helmignore (100%) rename charts/{ui => studio}/Chart.yaml (86%) rename charts/{ui => studio}/README.md (96%) rename charts/{ui => studio}/README.tpl (76%) rename charts/{ui => studio}/templates/NOTES.txt (58%) rename charts/{ui => studio}/templates/_helpers.tpl (81%) rename charts/{ui => studio}/templates/deployment.yaml (89%) rename charts/{ui => studio}/templates/hpa.yaml (86%) rename charts/{ui => studio}/templates/service.yaml (53%) rename charts/{ui => studio}/templates/serviceaccount.yaml (73%) rename charts/{ui => studio}/templates/tests/test-connection.yaml (50%) rename charts/{ui => studio}/values.yaml (97%) diff --git a/.cruft.json b/.cruft.json index 48ed88c..3cb6709 100644 --- a/.cruft.json +++ b/.cruft.json @@ -4,9 +4,9 @@ "checkout": "main", "context": { "cookiecutter": { - "project_name": "ui", + "project_name": "studio", "description": "A drag and drop UI for building Temporal workflows", - "author": "Zigflow authors ", + "author": "Zigflow authors ", "type": "svelte", "_template": "https://github.com/mrsimonemms/new", "_commit": "575419a2c0d81d09e68c8a42d027c32b138f1b71" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7f6922a..4d23546 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,13 +77,13 @@ jobs: uses: azure/setup-helm@v4 - name: helm lint - run: helm lint charts/ui + run: helm lint charts/studio - name: Run Trivy scan uses: aquasecurity/trivy-action@0.35.0 with: scan-type: config - scan-ref: ./charts/ui + scan-ref: ./charts/studio format: sarif output: trivy-helm.sarif exit-code: "1" @@ -110,28 +110,28 @@ jobs: with: cluster_name: kind - - name: Build ui image + - name: Build studio image uses: docker/build-push-action@v6 with: context: . - tags: ui:latest + tags: studio:latest load: true cache-from: type=gha cache-to: type=gha,mode=max - name: Load image into Kind - run: kind load docker-image ui:latest + run: kind load docker-image studio:latest - - name: Deploy UI + - name: Deploy Studio run: | - echo '{"builds":[{"imageName":"ui","tag":"ui:latest"}]}' > /tmp/artifacts.json + echo '{"builds":[{"imageName":"studio","tag":"studio:latest"}]}' > /tmp/artifacts.json skaffold deploy --build-artifacts /tmp/artifacts.json - - name: Wait for UI deployment - run: kubectl rollout status -n zigflow deployment/ui --timeout=30s + - name: Wait for Studio deployment + run: kubectl rollout status -n zigflow deployment/studio --timeout=30s - - name: Port forward UI - run: kubectl port-forward svc/ui -n zigflow 3000:3000 & + - name: Port forward Studio + run: kubectl port-forward svc/studio -n zigflow 3000:3000 & - name: Call webapp run: | @@ -144,7 +144,7 @@ jobs: if: failure() run: | kubectl get pods -A - kubectl logs -n zigflow deploy/ui --all-containers=true || true + kubectl logs -n zigflow deploy/studio --all-containers=true || true # Generate metadata shared across all build jobs metadata: @@ -197,8 +197,8 @@ jobs: echo "commit_id=${GITHUB_SHA}" >> "$GITHUB_OUTPUT" echo "git_repo=github.com/${GITHUB_REPOSITORY}" >> "$GITHUB_OUTPUT" - # Build ui Docker images in parallel by architecture - docker_ui: + # Build studio Docker images in parallel by architecture + docker_studio: runs-on: ${{ matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} needs: metadata strategy: @@ -268,12 +268,12 @@ jobs: sarif_file: trivy-zigflow-${{ steps.tag.outputs.platform_tag }}.sarif # Combine architecture-specific images into a multi-arch manifest - docker_ui_manifest: + docker_studio_manifest: runs-on: ubuntu-latest if: needs.metadata.outputs.push == 'true' needs: - metadata - - docker_ui + - docker_studio steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -355,8 +355,8 @@ jobs: run: | go install github.com/norwoodj/helm-docs/cmd/helm-docs@latest helm-docs - yq -i '.version = "${{ needs.metadata.outputs.tag }}"' charts/ui/Chart.yaml - yq -i '.annotations."org.opencontainers.image.documentation" = "https://github.com/zigflow/ui/blob/${{ needs.metadata.outputs.tag }}/charts/ui/README.md"' charts/ui/Chart.yaml + yq -i '.version = "${{ needs.metadata.outputs.tag }}"' charts/studio/Chart.yaml + yq -i '.annotations."org.opencontainers.image.documentation" = "https://github.com/zigflow/studio/blob/${{ needs.metadata.outputs.tag }}/charts/studio/README.md"' charts/studio/Chart.yaml - name: Import GPG key uses: crazy-max/ghaction-import-gpg@v6 @@ -375,7 +375,7 @@ jobs: - name: Publish Helm chart uses: appany/helm-oci-chart-releaser@v0.5.0 with: - name: ui + name: studio registry: ghcr.io repository: ${{ github.repository_owner }}/charts tag: ${{ needs.metadata.outputs.tag }} diff --git a/.licenserc.yaml b/.licenserc.yaml index 4084ce8..ed3bb74 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -1,7 +1,7 @@ header: license: spdx-id: Apache-2.0 - copyright-owner: Zigflow authors + copyright-owner: Zigflow authors copyright-year: 2025 - 2026 paths-ignore: - '**/dist' diff --git a/Dockerfile b/Dockerfile index 7fbf51b..6bf3836 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2025 - 2026 Zigflow authors +# Copyright 2025 - 2026 Zigflow authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 2a0d5fa..31f644a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ -# UI +# Studio + +> **Work in progress.** This project is under active development and is not yet +> ready for production use. A drag and drop UI for building Temporal workflows diff --git a/Taskfile.yml b/Taskfile.yml index 58adc35..cff05ce 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,7 +1,7 @@ version: '3' vars: - TMP_IMG: ttl.sh/zigflow-ui + TMP_IMG: ttl.sh/zigflow-studio TMP_IMG_TAG: 24h tasks: @@ -44,7 +44,7 @@ tasks: --set image.tag={{.TMP_IMG_TAG}} \ --values ./values.example.yaml \ --wait \ - zigflow ./charts/ui + zigflow ./charts/studio minikube: desc: Start minikube and apply dev manifests @@ -55,5 +55,5 @@ tasks: scan: desc: Scan for vulnerabilities cmds: - - trivy config --severity HIGH,CRITICAL --format table --exit-code 1 charts/ui - - trivy image --severity HIGH,CRITICAL --format table --exit-code 1 --pkg-types os,library --ignore-unfixed ghcr.io/zigflow/ui + - trivy config --severity HIGH,CRITICAL --format table --exit-code 1 charts/studio + - trivy image --severity HIGH,CRITICAL --format table --exit-code 1 --pkg-types os,library --ignore-unfixed ghcr.io/zigflow/studio diff --git a/charts/ui/.helmignore b/charts/studio/.helmignore similarity index 100% rename from charts/ui/.helmignore rename to charts/studio/.helmignore diff --git a/charts/ui/Chart.yaml b/charts/studio/Chart.yaml similarity index 86% rename from charts/ui/Chart.yaml rename to charts/studio/Chart.yaml index 915fc20..c32242e 100644 --- a/charts/ui/Chart.yaml +++ b/charts/studio/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -name: ui +name: studio description: Web UI for visualising and editing Zigflow workflows type: application version: 0.0.0 @@ -10,7 +10,7 @@ maintainers: email: simon@simonemms.com url: https://simonemms.com sources: - - https://github.com/zigflow/ui + - https://github.com/zigflow/studio keywords: - DSL - Durable Execution @@ -20,4 +20,4 @@ keywords: - Workflows - YAML annotations: - org.opencontainers.image.documentation: https://github.com/zigflow/ui/tree/main/charts/ui + org.opencontainers.image.documentation: https://github.com/zigflow/studio/tree/main/charts/studio diff --git a/charts/ui/README.md b/charts/studio/README.md similarity index 96% rename from charts/ui/README.md rename to charts/studio/README.md index 38a5b9f..e36e536 100644 --- a/charts/ui/README.md +++ b/charts/studio/README.md @@ -1,4 +1,4 @@ -# ui +# studio ![Version: 0.0.0](https://img.shields.io/badge/Version-0.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) @@ -14,7 +14,7 @@ Web UI for visualising and editing Zigflow workflows ## Source Code -* +* ## Values @@ -29,7 +29,7 @@ Web UI for visualising and editing Zigflow workflows | envvars | list | `[]` | Additional environment variables | | fullnameOverride | string | `""` | String to fully override names | | image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | -| image.repository | string | `"ghcr.io/zigflow/ui"` | Image repository | +| image.repository | string | `"ghcr.io/zigflow/studio"` | Image repository | | image.tag | string | `""` | Image tag - defaults to the chart's Version if not set | | imagePullSecrets | list | `[]` | Docker registry secret names | | livenessProbe.httpGet.path | string | `"/"` | Path to demonstrate app liveness | diff --git a/charts/ui/README.tpl b/charts/studio/README.tpl similarity index 76% rename from charts/ui/README.tpl rename to charts/studio/README.tpl index cecb8ab..f26dcf4 100644 --- a/charts/ui/README.tpl +++ b/charts/studio/README.tpl @@ -1,5 +1,5 @@ {* - Copyright 2025 - 2026 Zigflow authors + Copyright 2025 - 2026 Zigflow authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,11 +14,11 @@ limitations under the License. *} -# Zigflow UI +# Zigflow Studio {{ template "chart.deprecationWarning" . }} -[![Version](https://img.shields.io/github/v/release/zigflow/ui?label=Version&color=007ec6)](https://github.com/zigflow/ui/tree/main/charts/ui) +[![Version](https://img.shields.io/github/v/release/zigflow/studio?label=Version&color=007ec6)](https://github.com/zigflow/studio/tree/main/charts/studio) ![Type: Application](https://img.shields.io/badge/Type-Application-informational) {{ template "chart.description" . }} @@ -27,10 +27,10 @@ ## TL;DR -Be sure to set `${ZIGFLOW_VERSION}` with [your desired version](https://github.com/zigflow/ui/pkgs/container/charts%2Fui) +Be sure to set `${ZIGFLOW_VERSION}` with [your desired version](https://github.com/zigflow/studio/pkgs/container/charts%2Fstudio) ```sh -helm install myrelease oci://ghcr.io/mrsimonemms/charts/ui@${ZIGFLOW_VERSION} +helm install myrelease oci://ghcr.io/mrsimonemms/charts/studio@${ZIGFLOW_VERSION} ``` {{ template "chart.maintainersSection" . }} diff --git a/charts/ui/templates/NOTES.txt b/charts/studio/templates/NOTES.txt similarity index 58% rename from charts/ui/templates/NOTES.txt rename to charts/studio/templates/NOTES.txt index 16a95f5..6168617 100644 --- a/charts/ui/templates/NOTES.txt +++ b/charts/studio/templates/NOTES.txt @@ -1,5 +1,5 @@ Deployed ======== -App: {{ include "ui.fullname" . }} +App: {{ include "studio.fullname" . }} Namespace: {{ .Release.Namespace }} diff --git a/charts/ui/templates/_helpers.tpl b/charts/studio/templates/_helpers.tpl similarity index 81% rename from charts/ui/templates/_helpers.tpl rename to charts/studio/templates/_helpers.tpl index 4570828..8510d26 100644 --- a/charts/ui/templates/_helpers.tpl +++ b/charts/studio/templates/_helpers.tpl @@ -1,5 +1,5 @@ {* - Copyright 2025 - 2026 Zigflow authors + Copyright 2025 - 2026 Zigflow authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ {{/* Expand the name of the chart. */}} -{{- define "ui.name" -}} +{{- define "studio.name" -}} {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- end }} @@ -28,7 +28,7 @@ Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). If release name contains chart name it will be used as a full name. */}} -{{- define "ui.fullname" -}} +{{- define "studio.fullname" -}} {{- if .Values.fullnameOverride }} {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} {{- else }} @@ -44,16 +44,16 @@ If release name contains chart name it will be used as a full name. {{/* Create chart name and version as used by the chart label. */}} -{{- define "ui.chart" -}} +{{- define "studio.chart" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end }} {{/* Common labels */}} -{{- define "ui.labels" -}} -helm.sh/chart: {{ include "ui.chart" . }} -{{ include "ui.selectorLabels" . }} +{{- define "studio.labels" -}} +helm.sh/chart: {{ include "studio.chart" . }} +{{ include "studio.selectorLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} @@ -63,17 +63,17 @@ app.kubernetes.io/managed-by: {{ .Release.Service }} {{/* Selector labels */}} -{{- define "ui.selectorLabels" -}} -app.kubernetes.io/name: {{ include "ui.name" . }} +{{- define "studio.selectorLabels" -}} +app.kubernetes.io/name: {{ include "studio.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} {{/* Create the name of the service account to use */}} -{{- define "ui.serviceAccountName" -}} +{{- define "studio.serviceAccountName" -}} {{- if .Values.serviceAccount.create }} -{{- default (include "ui.fullname" .) .Values.serviceAccount.name }} +{{- default (include "studio.fullname" .) .Values.serviceAccount.name }} {{- else }} {{- default "default" .Values.serviceAccount.name }} {{- end }} diff --git a/charts/ui/templates/deployment.yaml b/charts/studio/templates/deployment.yaml similarity index 89% rename from charts/ui/templates/deployment.yaml rename to charts/studio/templates/deployment.yaml index 255e821..2f223d1 100644 --- a/charts/ui/templates/deployment.yaml +++ b/charts/studio/templates/deployment.yaml @@ -1,16 +1,16 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{ include "ui.fullname" . }} + name: {{ include "studio.fullname" . }} labels: - {{- include "ui.labels" . | nindent 4 }} + {{- include "studio.labels" . | nindent 4 }} spec: {{- if not .Values.autoscaling.enabled }} replicas: {{ .Values.replicaCount }} {{- end }} selector: matchLabels: - {{- include "ui.selectorLabels" . | nindent 6 }} + {{- include "studio.selectorLabels" . | nindent 6 }} template: metadata: {{- with .Values.podAnnotations }} @@ -18,7 +18,7 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} labels: - {{- include "ui.labels" . | nindent 8 }} + {{- include "studio.labels" . | nindent 8 }} {{- with .Values.podLabels }} {{- toYaml . | nindent 8 }} {{- end }} @@ -27,7 +27,7 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} - serviceAccountName: {{ include "ui.serviceAccountName" . }} + serviceAccountName: {{ include "studio.serviceAccountName" . }} {{- with .Values.podSecurityContext }} securityContext: {{- toYaml . | nindent 8 }} diff --git a/charts/ui/templates/hpa.yaml b/charts/studio/templates/hpa.yaml similarity index 86% rename from charts/ui/templates/hpa.yaml rename to charts/studio/templates/hpa.yaml index aa932aa..bb9f3e1 100644 --- a/charts/ui/templates/hpa.yaml +++ b/charts/studio/templates/hpa.yaml @@ -2,14 +2,14 @@ apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: - name: {{ include "ui.fullname" . }} + name: {{ include "studio.fullname" . }} labels: - {{- include "ui.labels" . | nindent 4 }} + {{- include "studio.labels" . | nindent 4 }} spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment - name: {{ include "ui.fullname" . }} + name: {{ include "studio.fullname" . }} minReplicas: {{ .Values.autoscaling.minReplicas }} maxReplicas: {{ .Values.autoscaling.maxReplicas }} metrics: diff --git a/charts/ui/templates/service.yaml b/charts/studio/templates/service.yaml similarity index 53% rename from charts/ui/templates/service.yaml rename to charts/studio/templates/service.yaml index 68b5f34..87161e8 100644 --- a/charts/ui/templates/service.yaml +++ b/charts/studio/templates/service.yaml @@ -1,8 +1,8 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "ui.fullname" . }} - labels: {{- include "ui.labels" . | nindent 4 }} + name: {{ include "studio.fullname" . }} + labels: {{- include "studio.labels" . | nindent 4 }} spec: type: {{ .Values.service.type }} ports: @@ -10,4 +10,4 @@ spec: targetPort: http protocol: TCP name: http - selector: {{- include "ui.selectorLabels" . | nindent 4 }} + selector: {{- include "studio.selectorLabels" . | nindent 4 }} diff --git a/charts/ui/templates/serviceaccount.yaml b/charts/studio/templates/serviceaccount.yaml similarity index 73% rename from charts/ui/templates/serviceaccount.yaml rename to charts/studio/templates/serviceaccount.yaml index 82e4c86..fb4b028 100644 --- a/charts/ui/templates/serviceaccount.yaml +++ b/charts/studio/templates/serviceaccount.yaml @@ -2,9 +2,9 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: {{ include "ui.serviceAccountName" . }} + name: {{ include "studio.serviceAccountName" . }} labels: - {{- include "ui.labels" . | nindent 4 }} + {{- include "studio.labels" . | nindent 4 }} {{- with .Values.serviceAccount.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/charts/ui/templates/tests/test-connection.yaml b/charts/studio/templates/tests/test-connection.yaml similarity index 50% rename from charts/ui/templates/tests/test-connection.yaml rename to charts/studio/templates/tests/test-connection.yaml index 125cf32..58146b5 100644 --- a/charts/ui/templates/tests/test-connection.yaml +++ b/charts/studio/templates/tests/test-connection.yaml @@ -1,9 +1,9 @@ apiVersion: v1 kind: Pod metadata: - name: "{{ include "ui.fullname" . }}-test-connection" + name: "{{ include "studio.fullname" . }}-test-connection" labels: - {{- include "ui.labels" . | nindent 4 }} + {{- include "studio.labels" . | nindent 4 }} annotations: "helm.sh/hook": test spec: @@ -11,5 +11,5 @@ spec: - name: wget image: busybox command: ['wget'] - args: ['{{ include "ui.fullname" . }}:{{ .Values.service.port }}'] + args: ['{{ include "studio.fullname" . }}:{{ .Values.service.port }}'] restartPolicy: Never diff --git a/charts/ui/values.yaml b/charts/studio/values.yaml similarity index 97% rename from charts/ui/values.yaml rename to charts/studio/values.yaml index afa155a..92ea980 100644 --- a/charts/ui/values.yaml +++ b/charts/studio/values.yaml @@ -1,4 +1,4 @@ -# Default values for ui. +# Default values for studio. # This is a YAML-formatted file. # Declare variables to be passed into your templates. @@ -15,7 +15,7 @@ envvars: [] image: # -- Image repository - repository: ghcr.io/zigflow/ui + repository: ghcr.io/zigflow/studio # -- Image pull policy pullPolicy: IfNotPresent # -- Image tag - defaults to the chart's Version if not set diff --git a/eslint.config.js b/eslint.config.js index 0adad1f..8c3af12 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,5 @@ /* - * Copyright 2025 - 2026 Zigflow authors + * Copyright 2025 - 2026 Zigflow authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/package-lock.json b/package-lock.json index 23995de..4e8e7d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "@zigflow/ui", + "name": "@zigflow/studio", "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@zigflow/ui", + "name": "@zigflow/studio", "version": "0.0.0", "license": "Apache-2.0", "devDependencies": { diff --git a/package.json b/package.json index c5e0681..35a1aa7 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@zigflow/ui", + "name": "@zigflow/studio", "description": "A drag and drop UI for building Temporal workflows", "private": true, "license": "Apache-2.0", diff --git a/playwright.config.ts b/playwright.config.ts index cf35c5a..9873c89 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,5 +1,5 @@ /* - * Copyright 2025 - 2026 Zigflow authors + * Copyright 2025 - 2026 Zigflow authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/skaffold.yaml b/skaffold.yaml index 8ea60b0..2d2df9e 100644 --- a/skaffold.yaml +++ b/skaffold.yaml @@ -1,11 +1,11 @@ apiVersion: skaffold/v4beta13 kind: Config metadata: - name: ui + name: studio build: artifacts: - - image: ui + - image: studio docker: dockerfile: Dockerfile target: dev @@ -22,13 +22,13 @@ build: deploy: helm: releases: - - name: ui - chartPath: charts/ui + - name: studio + chartPath: charts/studio namespace: zigflow createNamespace: true setValueTemplates: - image.repository: "{{.IMAGE_REPO_ui}}" - image.tag: "{{.IMAGE_TAG_ui}}" + image.repository: "{{.IMAGE_REPO_studio}}" + image.tag: "{{.IMAGE_TAG_studio}}" setValues: image: pullPolicy: Never @@ -37,7 +37,7 @@ deploy: portForward: - resourceType: Service - resourceName: ui + resourceName: studio namespace: zigflow port: 3000 localPort: 3000 diff --git a/src/app.d.ts b/src/app.d.ts index 96b188e..e8ed002 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -1,5 +1,5 @@ /* - * Copyright 2025 - 2026 Zigflow authors + * Copyright 2025 - 2026 Zigflow authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app.html b/src/app.html index bdf0c9f..f95c4be 100644 --- a/src/app.html +++ b/src/app.html @@ -1,5 +1,5 @@ -{@render children()} +
+
+ {@render children()} +
+
+ +
+
diff --git a/src/routes/workflows/+page.svelte b/src/routes/workflows/+page.svelte index ea41a4c..2cbd08e 100644 --- a/src/routes/workflows/+page.svelte +++ b/src/routes/workflows/+page.svelte @@ -16,6 +16,7 @@
-

Workflows

+

{t('workflows.title')}

{#if data.workflowFiles.length > 0}
    @@ -36,7 +37,7 @@ {/each}
{:else} -

No workflow files found.

+

{t('workflows.empty')}

{/if}
@@ -44,10 +45,10 @@ class="name-input" name="name" type="text" - placeholder="workflow-name" + placeholder={t('workflows.newPlaceholder')} required /> - +
diff --git a/src/routes/workflows/[...workflowId]/+page.svelte b/src/routes/workflows/[...workflowId]/+page.svelte index d44088a..c71ae2e 100644 --- a/src/routes/workflows/[...workflowId]/+page.svelte +++ b/src/routes/workflows/[...workflowId]/+page.svelte @@ -17,6 +17,7 @@