diff --git a/.build/common.ts b/.build/common.ts index e2190974f..86ccd15d1 100644 --- a/.build/common.ts +++ b/.build/common.ts @@ -1,3 +1,9 @@ +export interface PackageOptions { + name: string; + packageName: string; + file: string; +} + /** * Shared common options for both ESBuild and Vite */ @@ -27,4 +33,4 @@ export const packageOptions = { packageName: 'mermaid-layout-elk', file: 'layouts.ts', }, -} as const; +} as const satisfies Record; diff --git a/.build/jsonSchema.ts b/.build/jsonSchema.ts index 50b9ff097..7a700c1e2 100644 --- a/.build/jsonSchema.ts +++ b/.build/jsonSchema.ts @@ -19,6 +19,7 @@ const MERMAID_CONFIG_DIAGRAM_KEYS = [ 'xyChart', 'requirement', 'mindmap', + 'kanban', 'timeline', 'gitGraph', 'c4', diff --git a/.cspell/code-terms.txt b/.cspell/code-terms.txt index 8e4c02261..f4862006f 100644 --- a/.cspell/code-terms.txt +++ b/.cspell/code-terms.txt @@ -26,6 +26,7 @@ concat controlx controly CSSCLASS +curv CYLINDEREND CYLINDERSTART DAGA diff --git a/.cspell/cspell.config.yaml b/.cspell/cspell.config.yaml index 33d690193..b16040c8c 100644 --- a/.cspell/cspell.config.yaml +++ b/.cspell/cspell.config.yaml @@ -28,6 +28,9 @@ dictionaryDefinitions: - name: suggestions words: - none + - disp + - subproc + - tria suggestWords: - seperator:separator - vertice:vertex diff --git a/.cspell/mermaid-terms.txt b/.cspell/mermaid-terms.txt index 59a3d108f..cb6db41de 100644 --- a/.cspell/mermaid-terms.txt +++ b/.cspell/mermaid-terms.txt @@ -5,12 +5,14 @@ bmatrix braintree catmull compositTitleSize +curv doublecircle elems gantt gitgraph gzipped handDrawn +kanban knsv Knut marginx @@ -24,6 +26,7 @@ multigraph nodesep NOTEGROUP Pinterest +procs rankdir ranksep rect diff --git a/.esbuild/build.ts b/.esbuild/build.ts index 2bb42a557..423e8f047 100644 --- a/.esbuild/build.ts +++ b/.esbuild/build.ts @@ -8,7 +8,10 @@ import { defaultOptions, getBuildConfig } from './util.js'; const shouldVisualize = process.argv.includes('--visualize'); const buildPackage = async (entryName: keyof typeof packageOptions) => { - const commonOptions: MermaidBuildOptions = { ...defaultOptions, entryName } as const; + const commonOptions: MermaidBuildOptions = { + ...defaultOptions, + options: packageOptions[entryName], + } as const; const buildConfigs: MermaidBuildOptions[] = [ // package.mjs { ...commonOptions }, @@ -40,7 +43,7 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => { continue; } const fileName = Object.keys(metafile.outputs) - .find((file) => !file.includes('chunks') && file.endsWith('js')) + .find((file) => !file.includes('chunks') && file.endsWith('js'))! .replace('dist/', ''); // Upload metafile into https://esbuild.github.io/analyze/ await writeFile(`stats/${fileName}.meta.json`, JSON.stringify(metafile)); diff --git a/.esbuild/server.ts b/.esbuild/server.ts index ef61ebec2..6e1bcb460 100644 --- a/.esbuild/server.ts +++ b/.esbuild/server.ts @@ -9,13 +9,18 @@ import { generateLangium } from '../.build/generateLangium.js'; import { defaultOptions, getBuildConfig } from './util.js'; const configs = Object.values(packageOptions).map(({ packageName }) => - getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: packageName }) + getBuildConfig({ + ...defaultOptions, + minify: false, + core: false, + options: packageOptions[packageName], + }) ); const mermaidIIFEConfig = getBuildConfig({ ...defaultOptions, minify: false, core: false, - entryName: 'mermaid', + options: packageOptions.mermaid, format: 'iife', }); configs.push(mermaidIIFEConfig); diff --git a/.esbuild/util.ts b/.esbuild/util.ts index 522176113..6d6d1d59b 100644 --- a/.esbuild/util.ts +++ b/.esbuild/util.ts @@ -3,7 +3,7 @@ import { fileURLToPath } from 'url'; import type { BuildOptions } from 'esbuild'; import { readFileSync } from 'fs'; import jsonSchemaPlugin from './jsonSchemaPlugin.js'; -import { packageOptions } from '../.build/common.js'; +import type { PackageOptions } from '../.build/common.js'; import { jisonPlugin } from './jisonPlugin.js'; const __dirname = fileURLToPath(new URL('.', import.meta.url)); @@ -13,10 +13,10 @@ export interface MermaidBuildOptions extends BuildOptions { core: boolean; metafile: boolean; format: 'esm' | 'iife'; - entryName: keyof typeof packageOptions; + options: PackageOptions; } -export const defaultOptions: Omit = { +export const defaultOptions: Omit = { minify: false, metafile: false, core: false, @@ -52,9 +52,14 @@ const getFileName = (fileName: string, { core, format, minify }: MermaidBuildOpt }; export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => { - const { core, entryName, metafile, format, minify } = options; + const { + core, + metafile, + format, + minify, + options: { name, file, packageName }, + } = options; const external: string[] = ['require', 'fs', 'path']; - const { name, file, packageName } = packageOptions[entryName]; const outFileName = getFileName(name, options); const output: BuildOptions = buildOptions({ absWorkingDir: resolve(__dirname, `../packages/${packageName}`), diff --git a/.github/lychee.toml b/.github/lychee.toml index 2e3b08c41..288ab054a 100644 --- a/.github/lychee.toml +++ b/.github/lychee.toml @@ -44,7 +44,10 @@ exclude = [ "https://chromewebstore.google.com", # Drupal 403 -"https://(www.)?drupal.org" +"https://(www.)?drupal.org", + +# Swimm returns 404, eventhough the link is valid +"https://docs.swimm.io" ] # Exclude all private IPs from checking. diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 6a43791ed..13b913c11 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -19,7 +19,7 @@ jobs: # uses version from "packageManager" field in package.json - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: cache: pnpm node-version-file: '.node-version' diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index eb0c4594a..79e9deea1 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -23,7 +23,7 @@ jobs: - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: cache: pnpm node-version-file: '.node-version' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 65962ce64..94ede60ab 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -36,7 +36,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 with: config-file: ./.github/codeql/codeql-config.yml languages: ${{ matrix.language }} @@ -48,7 +48,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/autobuild@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -62,4 +62,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 diff --git a/.github/workflows/e2e-applitools.yml b/.github/workflows/e2e-applitools.yml index 6da65afe5..b1eb70674 100644 --- a/.github/workflows/e2e-applitools.yml +++ b/.github/workflows/e2e-applitools.yml @@ -38,7 +38,7 @@ jobs: # uses version from "packageManager" field in package.json - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version-file: '.node-version' diff --git a/.github/workflows/e2e-timings.yml b/.github/workflows/e2e-timings.yml new file mode 100644 index 000000000..e3f724d81 --- /dev/null +++ b/.github/workflows/e2e-timings.yml @@ -0,0 +1,53 @@ +name: E2E - Generate Timings + +on: + # run this workflow every night at 3am + schedule: + - cron: '28 3 * * *' + # or when the user triggers it from GitHub Actions page + workflow_dispatch: + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +permissions: + contents: write + +jobs: + timings: + runs-on: ubuntu-latest + container: + image: cypress/browsers:node-20.11.0-chrome-121.0.6167.85-1-ff-120.0-edge-121.0.2277.83-1 + options: --user 1001 + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 + - name: Setup Node.js + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + with: + node-version-file: '.node-version' + - name: Install dependencies + uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6 + with: + runTests: false + - name: Cypress run + uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6 + id: cypress + with: + install: false + start: pnpm run dev:coverage + wait-on: 'http://localhost:9000' + browser: chrome + publish-summary: false + env: + VITEST_COVERAGE: true + CYPRESS_COMMIT: ${{ github.sha }} + SPLIT: 1 + SPLIT_INDEX: 0 + SPLIT_FILE: 'cypress/timings.json' + - name: Commit changes + uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4 + with: + add: 'cypress/timings.json' + author_name: 'github-actions[bot]' + author_email: '41898282+github-actions[bot]@users.noreply.github.com' + message: 'chore: update E2E timings' diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 2b91d078e..c5bbc6e62 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -28,7 +28,6 @@ env: ) || github.event.before }} - shouldRunParallel: ${{ secrets.CYPRESS_RECORD_KEY != '' && !(github.event_name == 'push' && github.ref == 'refs/heads/develop') }} jobs: cache: runs-on: ubuntu-latest @@ -39,7 +38,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version-file: '.node-version' - name: Cache snapshots @@ -59,7 +58,7 @@ jobs: - name: Install dependencies if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }} - uses: cypress-io/github-action@df7484c5ba85def7eef30db301afa688187bc378 # v6.7.2 + uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6 with: # just perform install runTests: false @@ -80,7 +79,7 @@ jobs: strategy: fail-fast: false matrix: - containers: [1, 2, 3, 4] + containers: [1, 2, 3, 4, 5] steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 @@ -88,7 +87,7 @@ jobs: # uses version from "packageManager" field in package.json - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version-file: '.node-version' @@ -101,7 +100,7 @@ jobs: key: ${{ runner.os }}-snapshots-${{ env.targetHash }} - name: Install dependencies - uses: cypress-io/github-action@df7484c5ba85def7eef30db301afa688187bc378 # v6.7.2 + uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6 with: runTests: false @@ -117,11 +116,8 @@ jobs: # Install NPM dependencies, cache them correctly # and run all Cypress tests - name: Cypress run - uses: cypress-io/github-action@df7484c5ba85def7eef30db301afa688187bc378 # v6.7.2 + uses: cypress-io/github-action@0da3c06ed8217b912deea9d8ee69630baed1737e # v6.7.6 id: cypress - # If CYPRESS_RECORD_KEY is set, run in parallel on all containers - # Otherwise (e.g. if running from fork), we run on a single container only - if: ${{ env.shouldRunParallel == 'true' || ( matrix.containers == 1 ) }} with: install: false start: pnpm run dev:coverage @@ -129,16 +125,18 @@ jobs: browser: chrome # Disable recording if we don't have an API key # e.g. if this action was run from a fork - record: ${{ env.shouldRunParallel == 'true' }} - parallel: ${{ env.shouldRunParallel == 'true' }} + record: ${{ secrets.CYPRESS_RECORD_KEY != '' }} env: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} VITEST_COVERAGE: true CYPRESS_COMMIT: ${{ github.sha }} ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }} - ARGOS_PARALLEL: ${{ env.shouldRunParallel == 'true' }} - ARGOS_PARALLEL_TOTAL: 4 + ARGOS_PARALLEL: true + ARGOS_PARALLEL_TOTAL: ${{ strategy.job-total }} ARGOS_PARALLEL_INDEX: ${{ matrix.containers }} + SPLIT: ${{ strategy.job-total }} + SPLIT_INDEX: ${{ strategy.job-index }} + SPLIT_FILE: 'cypress/timings.json' - name: Upload Coverage to Codecov uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index febd2f92d..24e7ee35d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -29,7 +29,7 @@ jobs: # uses version from "packageManager" field in package.json - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: cache: pnpm node-version-file: '.node-version' diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index ecb411b5c..587ddae08 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -28,7 +28,7 @@ jobs: - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: cache: pnpm node-version-file: '.node-version' diff --git a/.github/workflows/release-preview-publish.yml b/.github/workflows/release-preview-publish.yml index 96556aa26..fa48d3659 100644 --- a/.github/workflows/release-preview-publish.yml +++ b/.github/workflows/release-preview-publish.yml @@ -16,7 +16,7 @@ jobs: - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: cache: pnpm node-version-file: '.node-version' diff --git a/.github/workflows/release-preview.yml b/.github/workflows/release-preview.yml index 283c316fb..7b7dba987 100644 --- a/.github/workflows/release-preview.yml +++ b/.github/workflows/release-preview.yml @@ -3,6 +3,7 @@ name: Preview release on: pull_request: branches: [develop] + types: [opened, synchronize, labeled, ready_for_review] concurrency: group: ${{ github.workflow }}-${{ github.event.number }} @@ -30,7 +31,7 @@ jobs: - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: cache: pnpm node-version-file: '.node-version' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3db5f6f37..4e8e9cd83 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: cache: pnpm node-version-file: '.node-version' @@ -36,7 +36,7 @@ jobs: - name: Create Release Pull Request or Publish to npm id: changesets - uses: changesets/action@aba318e9165b45b7948c60273e0b72fce0a64eb9 # v1.4.7 + uses: changesets/action@3de3850952bec538fde60aac71731376e57b9b57 # v1.4.8 with: version: pnpm changeset:version publish: pnpm changeset:publish diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 0dee2e666..528e94045 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -16,11 +16,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: persist-credentials: false - name: Run analysis - uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3 with: results_file: results.sarif results_format: sarif @@ -32,6 +32,6 @@ jobs: path: results.sarif retention-days: 5 - name: Upload to code-scanning - uses: github/codeql-action/upload-sarif@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 # v3.26.4 + uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12 with: sarif_file: results.sarif diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 375d5fada..7323ec027 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: # uses version from "packageManager" field in package.json - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: cache: pnpm node-version-file: '.node-version' @@ -38,6 +38,10 @@ jobs: run: | pnpm exec vitest run ./packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts --coverage + - name: Verify out-of-tree build with TypeScript + run: | + pnpm test:check:tsc + - name: Upload Coverage to Codecov uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0 # Run step only pushes to develop and pull_requests diff --git a/Dockerfile b/Dockerfile index fa933f999..7be53d24e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,9 @@ USER 0:0 RUN corepack enable \ && corepack enable pnpm +RUN apk add --no-cache git~=2.43.4 \ + && git config --add --system safe.directory /mermaid + ENV NODE_OPTIONS="--max_old_space_size=8192" EXPOSE 9000 3333 diff --git a/cypress.config.ts b/cypress.config.ts index 3346b5549..b0257b9b2 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -1,8 +1,9 @@ -import { defineConfig } from 'cypress'; -import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin'; -import coverage from '@cypress/code-coverage/task'; import eyesPlugin from '@applitools/eyes-cypress'; import { registerArgosTask } from '@argos-ci/cypress/task'; +import coverage from '@cypress/code-coverage/task'; +import { defineConfig } from 'cypress'; +import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin'; +import cypressSplit from 'cypress-split'; export default eyesPlugin( defineConfig({ @@ -13,6 +14,7 @@ export default eyesPlugin( specPattern: 'cypress/integration/**/*.{js,ts}', setupNodeEvents(on, config) { coverage(on, config); + cypressSplit(on, config); on('before:browser:launch', (browser, launchOptions) => { if (browser.name === 'chrome' && browser.isHeadless) { launchOptions.args.push('--window-size=1440,1024', '--force-device-scale-factor=1'); diff --git a/cypress/helpers/util.ts b/cypress/helpers/util.ts index 74b17cf05..52da4a72e 100644 --- a/cypress/helpers/util.ts +++ b/cypress/helpers/util.ts @@ -29,6 +29,7 @@ export const mermaidUrl = ( options: CypressMermaidConfig, api: boolean ): string => { + options.handDrawnSeed = 1; const codeObject: CodeObject = { code: graphStr, mermaid: options, diff --git a/cypress/integration/rendering/architecture.spec.ts b/cypress/integration/rendering/architecture.spec.ts index 1deb1f7da..bc2276352 100644 --- a/cypress/integration/rendering/architecture.spec.ts +++ b/cypress/integration/rendering/architecture.spec.ts @@ -173,7 +173,8 @@ describe.skip('architecture diagram', () => { }); }); -describe('architecture - external', () => { +// Skipped as the layout is not deterministic, and causes issues in E2E tests. +describe.skip('architecture - external', () => { it('should allow adding external icons', () => { urlSnapshotTest('http://localhost:9000/architecture-external.html'); }); diff --git a/cypress/integration/rendering/classDiagram-elk-v3.spec.js b/cypress/integration/rendering/classDiagram-elk-v3.spec.js new file mode 100644 index 000000000..ee6ca0b2b --- /dev/null +++ b/cypress/integration/rendering/classDiagram-elk-v3.spec.js @@ -0,0 +1,1037 @@ +import { imgSnapshotTest } from '../../helpers/util.ts'; +describe('Class diagram V3 ELK', () => { + it('ELK-0: should render a simple class diagram', () => { + imgSnapshotTest( + ` + classDiagram + + classA -- classB : Inheritance + classA -- classC : link + classC -- classD : link + classB -- classD + + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-1: should render a simple class diagram', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-1.1: should render a simple class diagram without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: false, layout: 'elk' } + ); + }); + + it('ELK-2: should render a simple class diagrams with cardinality', () => { + imgSnapshotTest( + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-2.1: should render a simple class diagrams with cardinality without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: false, layout: 'elk' } + ); + }); + + it('ELK-2.2 should render a simple class diagram with different visibilities', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class01 : -privateMethod() + Class01 : +publicMethod() + Class01 : #protectedMethod() + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK-2.3 should render a simple class diagram with different visibilities without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class01 : -privateMethod() + Class01 : +publicMethod() + Class01 : #protectedMethod() + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + `, + { logLevel: 1, htmlLabels: false, layout: 'elk' } + ); + }); + + it('ELK-3: should render multiple class diagrams', () => { + imgSnapshotTest( + [ + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + ], + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-4: should render a simple class diagram with comments', () => { + imgSnapshotTest( + ` + classDiagram + %% this is a comment + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-5: should render a simple class diagram with abstract method', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()* + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-5.1: should render a simple class diagram with abstract method without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()* + `, + { logLevel: 1, htmlLabels: false, layout: 'elk' } + ); + }); + + it('ELK-6: should render a simple class diagram with static method', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()$ + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-6.1: should render a simple class diagram with static method without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()$ + `, + { logLevel: 1, htmlLabels: false, layout: 'elk' } + ); + }); + + it('ELK-7: should render a simple class diagram with Generic class', () => { + imgSnapshotTest( + ` + classDiagram + class Class01~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-7.1: should render a simple class diagram with Generic class without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class01~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: false, layout: 'elk' } + ); + }); + + it('ELK-8: should render a simple class diagram with Generic class and relations', () => { + imgSnapshotTest( + ` + classDiagram + Class01~T~ <|-- AveryLongClass : Cool + Class03~T~ *-- Class04~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-9: should render a simple class diagram with clickable link', () => { + imgSnapshotTest( + ` + classDiagram + Class01~T~ <|-- AveryLongClass : Cool + Class03~T~ *-- Class04~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + link Class01 "google.com" "A Tooltip" + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-10: should render a simple class diagram with clickable callback', () => { + imgSnapshotTest( + ` + classDiagram + Class01~T~ <|-- AveryLongClass : Cool + Class03~T~ *-- Class04~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + callback Class01 "functionCall" "A Tooltip" + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-11: should render a simple class diagram with return type on method', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + test(int[] ids) bool + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-11.1: should render a simple class diagram with return type on method without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + test(int[] ids) bool + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: false, layout: 'elk' } + ); + }); + + it('ELK-12: should render a simple class diagram with generic types', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-12.1: should render a simple class diagram with generic types without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: false, layout: 'elk' } + ); + }); + + it('ELK-13: should render a simple class diagram with css classes applied', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + + cssClass "Class10" exClass2 + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-14: should render a simple class diagram with css classes applied directly', () => { + imgSnapshotTest( + ` + classDiagram + class Class10:::exClass2 { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-15: should render a simple class diagram with css classes applied two multiple classes', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + class Class20 + + cssClass "Class10, class20" exClass2 + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-16a: should render a simple class diagram with static field', () => { + imgSnapshotTest( + ` + classDiagram + class Foo { + +String bar$ + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-16b: should handle the direction statement with TB', () => { + imgSnapshotTest( + ` + classDiagram + direction TB + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK-17a: should handle the direction statement with BT', () => { + imgSnapshotTest( + ` + classDiagram + direction BT + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK-17b: should handle the direction statement with RL', () => { + imgSnapshotTest( + ` + classDiagram + direction RL + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-18a: should handle the direction statement with LR', () => { + imgSnapshotTest( + ` + classDiagram + direction LR + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-18b: should render a simple class diagram with notes', () => { + imgSnapshotTest( + ` + classDiagram + note "I love this diagram!\nDo you love it?" + class Class10 { + int id + size() + } + note for Class10 "Cool class\nI said it's very cool class!" + + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK-1433: should render a simple class with a title', () => { + imgSnapshotTest( + `--- +title: simple class diagram +--- +classDiagram +class Class10 +`, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK: should render a class with text label', () => { + imgSnapshotTest( + `classDiagram + class C1["Class 1 with text label"] + C1 --> C2`, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK: should render two classes with text labels', () => { + imgSnapshotTest( + `classDiagram + class C1["Class 1 with text label"] + class C2["Class 2 with chars @?"] + C1 --> C2`, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render a class with a text label, members and annotation', () => { + imgSnapshotTest( + `classDiagram + class C1["Class 1 with text label"] { + <<interface>> + +member1 + } + C1 --> C2`, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render multiple classes with same text labels', () => { + imgSnapshotTest( + `classDiagram + class C1["Class with text label"] + class C2["Class with text label"] + class C3["Class with text label"] + C1 --> C2 + C3 ..> C2 + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render classes with different text labels', () => { + imgSnapshotTest( + `classDiagram + class C1["OneWord"] + class C2["With, Comma"] + class C3["With (Brackets)"] + class C4["With [Brackets]"] + class C5["With {Brackets}"] + class C7["With 1 number"] + class C8["With . period..."] + class C9["With - dash"] + class C10["With _ underscore"] + class C11["With ' single quote"] + class C12["With ~!@#$%^&*()_+=-/?"] + class C13["With Città foreign language"] + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + + it('ELK: should render classLabel if class has already been defined earlier', () => { + imgSnapshotTest( + `classDiagram + Animal <|-- Duck + class Duck["Duck with text label"] + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should add classes namespaces', function () { + imgSnapshotTest( + ` + classDiagram + namespace Namespace1 { + class C1 + class C2 + } + C1 --> C2 + class C3 + class C4 + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with no members', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with no members if hideEmptyMembersBox is enabled', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + `, + { logLevel: 1, class: { htmlLabels: true, hideEmptyMembersBox: true }, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with no attributes, only methods', () => { + imgSnapshotTest( + ` + classDiagram + class Duck { + +swim() + +quack() + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with no methods, only attributes', () => { + imgSnapshotTest( + ` + classDiagram + class Duck { + +String beakColor + +int age + +float weight + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with style definition', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with style definition without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px + `, + { logLevel: 1, htmlLabels: false, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with classDef definitions', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + classDef pink fill:#f9f + classDef bold stroke:#333,stroke-width:6px,color:#fff + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with classDefs being applied', () => { + imgSnapshotTest( + ` + classDiagram + class Class10:::pink + cssClass "Class10" bold + classDef pink fill:#f9f + classDef bold stroke:#333,stroke-width:6px,color:#fff + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with classDefs being applied without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10:::pink + cssClass "Class10" bold + classDef pink fill:#f9f + classDef bold stroke:#333,stroke-width:6px,color:#fff + `, + { logLevel: 1, htmlLabels: false, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with markdown styling', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 { + +attribute *italic** + ~attribute **bold*** + _italicmethod_() + __boldmethod__() + _+_swim_()a_ + __+quack() test__ + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with markdown styling without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 { + +attribute *italic** + ~attribute **bold*** + _italicmethod_() + __boldmethod__() + _+_swim_()a_ + __+quack() test__ + } + `, + { logLevel: 1, htmlLabels: false, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with the handDrawn look', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn', layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with styles and the handDrawn look', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px,color:white + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn', layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with styles and the handDrawn look without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px,color:white + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn', layout: 'elk' } + ); + }); + it('ELK: should render a full class diagram with the handDrawn look', () => { + imgSnapshotTest( + ` + classDiagram + note "I love this diagram!\nDo you love it?" + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + note for Class10 "Cool class\nI said it's very cool class!" + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn', layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with a custom theme', () => { + imgSnapshotTest( + ` + %%{ + init: { + 'theme': 'base', + 'themeVariables': { + 'primaryColor': '#BB2528', + 'primaryTextColor': '#fff', + 'primaryBorderColor': '#7C0000', + 'lineColor': '#F83d29', + 'secondaryColor': '#006100', + 'tertiaryColor': '#fff' + } + } + }%% + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); + it('ELK: should render a simple class diagram with a custom theme and the handDrawn look', () => { + imgSnapshotTest( + ` + %%{ + init: { + 'theme': 'base', + 'themeVariables': { + 'primaryColor': '#BB2528', + 'primaryTextColor': '#fff', + 'primaryBorderColor': '#7C0000', + 'lineColor': '#F83d29', + 'secondaryColor': '#006100', + 'tertiaryColor': '#fff' + } + } + }%% + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn', layout: 'elk' } + ); + }); + it('ELK: should render a full class diagram using elk', () => { + imgSnapshotTest( + ` + classDiagram + note "I love this diagram!\nDo you love it?" + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + note for Class10 "Cool class\nI said it's very cool class!" + `, + { logLevel: 1, htmlLabels: true, layout: 'elk' } + ); + }); +}); diff --git a/cypress/integration/rendering/classDiagram-handDrawn-v3.spec.js b/cypress/integration/rendering/classDiagram-handDrawn-v3.spec.js new file mode 100644 index 000000000..32a82c089 --- /dev/null +++ b/cypress/integration/rendering/classDiagram-handDrawn-v3.spec.js @@ -0,0 +1,1041 @@ +import { imgSnapshotTest } from '../../helpers/util.ts'; +describe('Class diagram V3 HD', () => { + it('HD-0: should render a simple class diagram', () => { + imgSnapshotTest( + ` + classDiagram + + classA -- classB : Inheritance + classA -- classC : link + classC -- classD : link + classB -- classD + + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-1: should render a simple class diagram', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-1.1: should render a simple class diagram without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + + it('HD-2: should render a simple class diagrams with cardinality', () => { + imgSnapshotTest( + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-2.1: should render a simple class diagrams with cardinality without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + + it('HD-2.2 should render a simple class diagram with different visibilities', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class01 : -privateMethod() + Class01 : +publicMethod() + Class01 : #protectedMethod() + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD-2.3 should render a simple class diagram with different visibilities without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class01 : -privateMethod() + Class01 : +publicMethod() + Class01 : #protectedMethod() + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + + it('HD-3: should render multiple class diagrams', () => { + imgSnapshotTest( + [ + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + ], + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-4: should render a simple class diagram with comments', () => { + imgSnapshotTest( + ` + classDiagram + %% this is a comment + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-5: should render a simple class diagram with abstract method', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()* + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-5.1: should render a simple class diagram with abstract method without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()* + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + + it('HD-6: should render a simple class diagram with static method', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()$ + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-6.1: should render a simple class diagram with static method without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()$ + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + + it('HD-7: should render a simple class diagram with Generic class', () => { + imgSnapshotTest( + ` + classDiagram + class Class01~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-7.1: should render a simple class diagram with Generic class without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class01~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + + it('HD-8: should render a simple class diagram with Generic class and relations', () => { + imgSnapshotTest( + ` + classDiagram + Class01~T~ <|-- AveryLongClass : Cool + Class03~T~ *-- Class04~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-9: should render a simple class diagram with clickable link', () => { + imgSnapshotTest( + ` + classDiagram + Class01~T~ <|-- AveryLongClass : Cool + Class03~T~ *-- Class04~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + link Class01 "google.com" "A Tooltip" + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-10: should render a simple class diagram with clickable callback', () => { + imgSnapshotTest( + ` + classDiagram + Class01~T~ <|-- AveryLongClass : Cool + Class03~T~ *-- Class04~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + callback Class01 "functionCall" "A Tooltip" + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-11: should render a simple class diagram with return type on method', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + test(int[] ids) bool + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-11.1: should render a simple class diagram with return type on method without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + test(int[] ids) bool + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + + it('HD-12: should render a simple class diagram with generic types', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-12.1: should render a simple class diagram with generic types without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + + it('HD-13: should render a simple class diagram with css classes applied', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + + cssClass "Class10" exClass2 + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-14: should render a simple class diagram with css classes applied directly', () => { + imgSnapshotTest( + ` + classDiagram + class Class10:::exClass2 { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-15: should render a simple class diagram with css classes applied two multiple classes', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + class Class20 + + cssClass "Class10, class20" exClass2 + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-16a: should render a simple class diagram with static field', () => { + imgSnapshotTest( + ` + classDiagram + class Foo { + +String bar$ + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-16b: should handle the direction statement with TB', () => { + imgSnapshotTest( + ` + classDiagram + direction TB + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD-17a: should handle the direction statement with BT', () => { + imgSnapshotTest( + ` + classDiagram + direction BT + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD-17b: should handle the direction statement with RL', () => { + imgSnapshotTest( + ` + classDiagram + direction RL + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-18a: should handle the direction statement with LR', () => { + imgSnapshotTest( + ` + classDiagram + direction LR + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-18b: should render a simple class diagram with notes', () => { + imgSnapshotTest( + ` + classDiagram + note "I love this diagram!\nDo you love it?" + class Class10 { + int id + size() + } + note for Class10 "Cool class\nI said it's very cool class!" + + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD-1433: should render a simple class with a title', () => { + imgSnapshotTest( + `--- +title: simple class diagram +--- +classDiagram +class Class10 +`, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD: should render a class with text label', () => { + imgSnapshotTest( + `classDiagram + class C1["Class 1 with text label"] + C1 --> C2`, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD: should render two classes with text labels', () => { + imgSnapshotTest( + `classDiagram + class C1["Class 1 with text label"] + class C2["Class 2 with chars @?"] + C1 --> C2`, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a class with a text label, members and annotation', () => { + imgSnapshotTest( + `classDiagram + class C1["Class 1 with text label"] { + <<interface>> + +member1 + } + C1 --> C2`, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render multiple classes with same text labels', () => { + imgSnapshotTest( + `classDiagram +class C1["Class with text label"] +class C2["Class with text label"] +class C3["Class with text label"] +C1 --> C2 +C3 ..> C2 + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render classes with different text labels', () => { + imgSnapshotTest( + `classDiagram +class C1["OneWord"] +class C2["With, Comma"] +class C3["With (Brackets)"] +class C4["With [Brackets]"] +class C5["With {Brackets}"] +class C7["With 1 number"] +class C8["With . period..."] +class C9["With - dash"] +class C10["With _ underscore"] +class C11["With ' single quote"] +class C12["With ~!@#$%^&*()_+=-/?"] +class C13["With Città foreign language"] + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + + it('HD: should render classLabel if class has already been defined earlier', () => { + imgSnapshotTest( + `classDiagram + Animal <|-- Duck + class Duck["Duck with text label"] +`, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should add classes namespaces', function () { + imgSnapshotTest( + ` + classDiagram + namespace Namespace1 { + class C1 + class C2 + } + C1 --> C2 + class C3 + class C4 + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with no members', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with no members if hideEmptyMembersBox is enabled', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + `, + { logLevel: 1, class: { htmlLabels: true, hideEmptyMembersBox: true }, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with no attributes, only methods', () => { + imgSnapshotTest( + ` + classDiagram + class Duck { + +swim() + +quack() + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with no methods, only attributes', () => { + imgSnapshotTest( + ` + classDiagram + class Duck { + +String beakColor + +int age + +float weight + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with style definition', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with style definition without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with classDef definitions', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + classDef pink fill:#f9f + classDef bold stroke:#333,stroke-width:6px,color:#fff + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with classDefs being applied', () => { + imgSnapshotTest( + ` + classDiagram + class Class10:::pink + cssClass "Class10" bold + classDef pink fill:#f9f + classDef bold stroke:#333,stroke-width:6px,color:#fff + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with classDefs being applied without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10:::pink + cssClass "Class10" bold + classDef pink fill:#f9f + classDef bold stroke:#333,stroke-width:6px,color:#fff + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with markdown styling', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 { + +attribute *italic** + ~attribute **bold*** + _italicmethod_() + __boldmethod__() + _+_swim_()a_ + __+quack() test__ + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with markdown styling without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 { + +attribute *italic** + ~attribute **bold*** + _italicmethod_() + __boldmethod__() + _+_swim_()a_ + __+quack() test__ + } + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with the handDrawn look', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with styles and the handDrawn look', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px,color:white + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with styles and the handDrawn look without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px,color:white + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + it('HD: should render a full class diagram with the handDrawn look', () => { + imgSnapshotTest( + ` + classDiagram + note "I love this diagram!\nDo you love it?" + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + note for Class10 "Cool class\nI said it's very cool class!" + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with a custom theme', () => { + imgSnapshotTest( + ` + %%{ + init: { + 'theme': 'base', + 'themeVariables': { + 'primaryColor': '#BB2528', + 'primaryTextColor': '#fff', + 'primaryBorderColor': '#7C0000', + 'lineColor': '#F83d29', + 'secondaryColor': '#006100', + 'tertiaryColor': '#fff' + } + } + }%% + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a simple class diagram with a custom theme and the handDrawn look', () => { + imgSnapshotTest( + ` + %%{ + init: { + 'theme': 'base', + 'themeVariables': { + 'primaryColor': '#BB2528', + 'primaryTextColor': '#fff', + 'primaryBorderColor': '#7C0000', + 'lineColor': '#F83d29', + 'secondaryColor': '#006100', + 'tertiaryColor': '#fff' + } + } + }%% + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('HD: should render a full class diagram using elk', () => { + imgSnapshotTest( + ` +--- + config: + layout: elk +--- + classDiagram + note "I love this diagram!\nDo you love it?" + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + note for Class10 "Cool class\nI said it's very cool class!" + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); +}); diff --git a/cypress/integration/rendering/classDiagram-v2.spec.js b/cypress/integration/rendering/classDiagram-v2.spec.js index 0918a2ff9..f54768d9a 100644 --- a/cypress/integration/rendering/classDiagram-v2.spec.js +++ b/cypress/integration/rendering/classDiagram-v2.spec.js @@ -595,4 +595,63 @@ class C13["With Città foreign language"] { logLevel: 1, flowchart: { htmlLabels: false } } ); }); + + it('renders a class diagram with a generic class in a namespace', () => { + const diagramDefinition = ` + classDiagram-v2 + namespace Company.Project.Module { + class GenericClass~T~ { + +addItem(item: T) + +getItem() T + } + } + `; + + imgSnapshotTest(diagramDefinition); + }); + + it('renders a class diagram with nested namespaces and relationships', () => { + const diagramDefinition = ` + classDiagram-v2 + namespace Company.Project.Module.SubModule { + class Report { + +generatePDF(data: List) + +generateCSV(data: List) + } + } + namespace Company.Project.Module { + class Admin { + +generateReport() + } + } + Admin --> Report : generates + `; + + imgSnapshotTest(diagramDefinition); + }); + + it('renders a class diagram with multiple classes and relationships in a namespace', () => { + const diagramDefinition = ` + classDiagram-v2 + namespace Company.Project.Module { + class User { + +login(username: String, password: String) + +logout() + } + class Admin { + +addUser(user: User) + +removeUser(user: User) + +generateReport() + } + class Report { + +generatePDF(reportData: List) + +generateCSV(reportData: List) + } + } + Admin --> User : manages + Admin --> Report : generates + `; + + imgSnapshotTest(diagramDefinition); + }); }); diff --git a/cypress/integration/rendering/classDiagram-v3.spec.js b/cypress/integration/rendering/classDiagram-v3.spec.js new file mode 100644 index 000000000..626d6fcea --- /dev/null +++ b/cypress/integration/rendering/classDiagram-v3.spec.js @@ -0,0 +1,1031 @@ +import { imgSnapshotTest } from '../../helpers/util.ts'; +describe('Class diagram V3', () => { + it('0: should render a simple class diagram', () => { + imgSnapshotTest( + ` + classDiagram + + classA -- classB : Inheritance + classA -- classC : link + classC -- classD : link + classB -- classD + + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('1: should render a simple class diagram', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('1.1: should render a simple class diagram without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: false } + ); + }); + + it('2: should render a simple class diagrams with cardinality', () => { + imgSnapshotTest( + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('2.1: should render a simple class diagrams with cardinality without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: false } + ); + }); + + it('2.2 should render a simple class diagram with different visibilities', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class01 : -privateMethod() + Class01 : +publicMethod() + Class01 : #protectedMethod() + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + `, + { logLevel: 1, htmlLabels: true } + ); + }); + it('2.3 should render a simple class diagram with different visibilities without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class01 : -privateMethod() + Class01 : +publicMethod() + Class01 : #protectedMethod() + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + `, + { logLevel: 1, htmlLabels: false } + ); + }); + + it('3: should render multiple class diagrams', () => { + imgSnapshotTest( + [ + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + ` + classDiagram + Class01 "1" <|--|> "*" AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 "1" <--> "*" C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + ], + { logLevel: 1, htmlLabels: true } + ); + }); + + it('4: should render a simple class diagram with comments', () => { + imgSnapshotTest( + ` + classDiagram + %% this is a comment + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('5: should render a simple class diagram with abstract method', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()* + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('5.1: should render a simple class diagram with abstract method without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()* + `, + { logLevel: 1, htmlLabels: false } + ); + }); + + it('6: should render a simple class diagram with static method', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()$ + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('6.1: should render a simple class diagram with static method without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + Class01 <|-- AveryLongClass : Cool + Class01 : someMethod()$ + `, + { logLevel: 1, htmlLabels: false } + ); + }); + + it('7: should render a simple class diagram with Generic class', () => { + imgSnapshotTest( + ` + classDiagram + class Class01~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('7.1: should render a simple class diagram with Generic class without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class01~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: false } + ); + }); + + it('8: should render a simple class diagram with Generic class and relations', () => { + imgSnapshotTest( + ` + classDiagram + Class01~T~ <|-- AveryLongClass : Cool + Class03~T~ *-- Class04~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('9: should render a simple class diagram with clickable link', () => { + imgSnapshotTest( + ` + classDiagram + Class01~T~ <|-- AveryLongClass : Cool + Class03~T~ *-- Class04~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + link Class01 "google.com" "A Tooltip" + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('10: should render a simple class diagram with clickable callback', () => { + imgSnapshotTest( + ` + classDiagram + Class01~T~ <|-- AveryLongClass : Cool + Class03~T~ *-- Class04~T~ + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class08 <--> C2: Cool label + class Class10~T~ { + <<service>> + int id + test() + } + callback Class01 "functionCall" "A Tooltip" + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('11: should render a simple class diagram with return type on method', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + test(int[] ids) bool + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('11.1: should render a simple class diagram with return type on method without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + test(int[] ids) bool + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: false } + ); + }); + + it('12: should render a simple class diagram with generic types', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('12.1: should render a simple class diagram with generic types without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10~T~ { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: false } + ); + }); + + it('13: should render a simple class diagram with css classes applied', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + + cssClass "Class10" exClass2 + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('14: should render a simple class diagram with css classes applied directly', () => { + imgSnapshotTest( + ` + classDiagram + class Class10:::exClass2 { + int[] id + List~int~ ids + test(List~int~ ids) List~bool~ + testArray() bool[] + } + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('15: should render a simple class diagram with css classes applied two multiple classes', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + class Class20 + + cssClass "Class10, class20" exClass2 + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('16a: should render a simple class diagram with static field', () => { + imgSnapshotTest( + ` + classDiagram + class Foo { + +String bar$ + } + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('16b: should handle the direction statement with TB', () => { + imgSnapshotTest( + ` + classDiagram + direction TB + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true } + ); + }); + it('17a: should handle the direction statement with BT', () => { + imgSnapshotTest( + ` + classDiagram + direction BT + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true } + ); + }); + it('17b: should handle the direction statement with RL', () => { + imgSnapshotTest( + ` + classDiagram + direction RL + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('18a: should handle the direction statement with LR', () => { + imgSnapshotTest( + ` + classDiagram + direction LR + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('18b: should render a simple class diagram with notes', () => { + imgSnapshotTest( + ` + classDiagram + note "I love this diagram!\nDo you love it?" + class Class10 { + int id + size() + } + note for Class10 "Cool class\nI said it's very cool class!" + + `, + { logLevel: 1, htmlLabels: true } + ); + }); + + it('1433: should render a simple class with a title', () => { + imgSnapshotTest( + `--- +title: simple class diagram +--- +classDiagram +class Class10 +` + ); + }); + + it('should render a class with text label', () => { + imgSnapshotTest( + `classDiagram + class C1["Class 1 with text label"] + C1 --> C2` + ); + }); + + it('should render two classes with text labels', () => { + imgSnapshotTest( + `classDiagram + class C1["Class 1 with text label"] + class C2["Class 2 with chars @?"] + C1 --> C2` + ); + }); + it('should render a class with a text label, members and annotation', () => { + imgSnapshotTest( + `classDiagram + class C1["Class 1 with text label"] { + <<interface>> + +member1 + } + C1 --> C2` + ); + }); + it('should render multiple classes with same text labels', () => { + imgSnapshotTest( + `classDiagram +class C1["Class with text label"] +class C2["Class with text label"] +class C3["Class with text label"] +C1 --> C2 +C3 ..> C2 + ` + ); + }); + it('should render classes with different text labels', () => { + imgSnapshotTest( + `classDiagram +class C1["OneWord"] +class C2["With, Comma"] +class C3["With (Brackets)"] +class C4["With [Brackets]"] +class C5["With {Brackets}"] +class C7["With 1 number"] +class C8["With . period..."] +class C9["With - dash"] +class C10["With _ underscore"] +class C11["With ' single quote"] +class C12["With ~!@#$%^&*()_+=-/?"] +class C13["With Città foreign language"] + ` + ); + }); + + it('should render classLabel if class has already been defined earlier', () => { + imgSnapshotTest( + `classDiagram + Animal <|-- Duck + class Duck["Duck with text label"] +` + ); + }); + it('should add classes namespaces', function () { + imgSnapshotTest( + ` + classDiagram + namespace Namespace1 { + class C1 + class C2 + } + C1 --> C2 + class C3 + class C4 + ` + ); + }); + it('should render a simple class diagram with no members', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + `, + { logLevel: 1, htmlLabels: true } + ); + }); + it('should render a simple class diagram with no members if hideEmptyMembersBox is enabled', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + `, + { logLevel: 1, class: { htmlLabels: true, hideEmptyMembersBox: true } } + ); + }); + it('should render a simple class diagram with no attributes, only methods', () => { + imgSnapshotTest( + ` + classDiagram + class Duck { + +swim() + +quack() + } + ` + ); + }); + it('should render a simple class diagram with no methods, only attributes', () => { + imgSnapshotTest( + ` + classDiagram + class Duck { + +String beakColor + +int age + +float weight + } + ` + ); + }); + it('should render a simple class diagram with style definition', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px + `, + { logLevel: 1, htmlLabels: true } + ); + }); + it('should render a simple class diagram with style definition without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px + `, + { logLevel: 1, htmlLabels: false } + ); + }); + it('should render a simple class diagram with classDef definitions', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + classDef pink fill:#f9f + classDef bold stroke:#333,stroke-width:6px,color:#fff + `, + { logLevel: 1, htmlLabels: true } + ); + }); + it('should render a simple class diagram with classDefs being applied', () => { + imgSnapshotTest( + ` + classDiagram + class Class10:::pink + cssClass "Class10" bold + classDef pink fill:#f9f + classDef bold stroke:#333,stroke-width:6px,color:#fff + `, + { logLevel: 1, htmlLabels: true } + ); + }); + it('should render a simple class diagram with classDefs being applied without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10:::pink + cssClass "Class10" bold + classDef pink fill:#f9f + classDef bold stroke:#333,stroke-width:6px,color:#fff + `, + { logLevel: 1, htmlLabels: false } + ); + }); + it('should render a simple class diagram with markdown styling', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 { + +attribute *italic** + ~attribute **bold*** + _italicmethod_() + __boldmethod__() + _+_swim_()a_ + __+quack() test__ + } + `, + { logLevel: 1, htmlLabels: true } + ); + }); + it('should render a simple class diagram with markdown styling without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 { + +attribute *italic** + ~attribute **bold*** + _italicmethod_() + __boldmethod__() + _+_swim_()a_ + __+quack() test__ + } + `, + { logLevel: 1, htmlLabels: false } + ); + }); + it('should render a simple class diagram with the handDrawn look', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('should render a simple class diagram with styles and the handDrawn look', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px,color:white + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('should render a simple class diagram with styles and the handDrawn look without htmlLabels', () => { + imgSnapshotTest( + ` + classDiagram + class Class10 + style Class10 fill:#f9f,stroke:#333,stroke-width:4px,color:white + `, + { logLevel: 1, htmlLabels: false, look: 'handDrawn' } + ); + }); + it('should render a full class diagram with the handDrawn look', () => { + imgSnapshotTest( + ` + classDiagram + note "I love this diagram!\nDo you love it?" + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + note for Class10 "Cool class\nI said it's very cool class!" + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('should render a simple class diagram with a custom theme', () => { + imgSnapshotTest( + ` + %%{ + init: { + 'theme': 'base', + 'themeVariables': { + 'primaryColor': '#BB2528', + 'primaryTextColor': '#fff', + 'primaryBorderColor': '#7C0000', + 'lineColor': '#F83d29', + 'secondaryColor': '#006100', + 'tertiaryColor': '#fff' + } + } + }%% + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true } + ); + }); + it('should render a simple class diagram with a custom theme and the handDrawn look', () => { + imgSnapshotTest( + ` + %%{ + init: { + 'theme': 'base', + 'themeVariables': { + 'primaryColor': '#BB2528', + 'primaryTextColor': '#fff', + 'primaryBorderColor': '#7C0000', + 'lineColor': '#F83d29', + 'secondaryColor': '#006100', + 'tertiaryColor': '#fff' + } + } + }%% + classDiagram + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 *-- Class04 + Class05 o-- Class06 + Class07 .. Class08 + Class09 --> C2 : Where am i? + Class09 --* C3 + Class09 --|> Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + `, + { logLevel: 1, htmlLabels: true, look: 'handDrawn' } + ); + }); + it('should render a full class diagram using elk', () => { + imgSnapshotTest( + ` +--- + config: + layout: elk +--- + classDiagram + note "I love this diagram!\nDo you love it?" + Class01 <|-- AveryLongClass : Cool + <<interface>> Class01 + Class03 "1" *-- "*" Class04 + Class05 "1" o-- "many" Class06 + Class07 "1" .. "*" Class08 + Class09 "1" --> "*" C2 : Where am i? + Class09 "*" --* "*" C3 + Class09 "1" --|> "1" Class07 + Class12 <|.. Class08 + Class11 ..>Class12 + Class07 : equals() + Class07 : Object[] elementData + Class01 : size() + Class01 : int chimp + Class01 : int gorilla + Class01 : -int privateChimp + Class01 : +int publicGorilla + Class01 : #int protectedMarmoset + Class08 <--> C2: Cool label + class Class10 { + <<service>> + int id + test() + } + note for Class10 "Cool class\nI said it's very cool class!" + `, + { logLevel: 1, htmlLabels: true } + ); + }); +}); diff --git a/cypress/integration/rendering/flowchart-handDrawn.spec.js b/cypress/integration/rendering/flowchart-handDrawn.spec.js index 10d6dde87..49c55c628 100644 --- a/cypress/integration/rendering/flowchart-handDrawn.spec.js +++ b/cypress/integration/rendering/flowchart-handDrawn.spec.js @@ -12,7 +12,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -30,7 +29,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: true }, fontFamily: 'courier', } @@ -47,7 +45,7 @@ describe('Flowchart HandDrawn', () => { C -->|Two| E[iPhone] C -->|Three| F[Car] `, - { look: 'handDrawn', handDrawnSeed: 1, fontFamily: 'courier' } + { look: 'handDrawn', fontFamily: 'courier' } ); }); @@ -62,7 +60,7 @@ describe('Flowchart HandDrawn', () => { C -->|Two| E[\\iPhone\\] C -->|Three| F[Car] `, - { look: 'handDrawn', handDrawnSeed: 1, fontFamily: 'courier' } + { look: 'handDrawn', fontFamily: 'courier' } ); }); @@ -78,7 +76,7 @@ describe('Flowchart HandDrawn', () => { classDef processHead fill:#888888,color:white,font-weight:bold,stroke-width:3px,stroke:#001f3f class 1A,1B,D,E processHead `, - { look: 'handDrawn', handDrawnSeed: 1, fontFamily: 'courier' } + { look: 'handDrawn', fontFamily: 'courier' } ); }); @@ -107,7 +105,7 @@ describe('Flowchart HandDrawn', () => { 35(SAM.CommonFA.PopulationFME)-->39(SAM.CommonFA.ChargeDetails) 36(SAM.CommonFA.PremetricCost)-->39(SAM.CommonFA.ChargeDetails) `, - { look: 'handDrawn', handDrawnSeed: 1, fontFamily: 'courier' } + { look: 'handDrawn', fontFamily: 'courier' } ); }); @@ -178,7 +176,7 @@ describe('Flowchart HandDrawn', () => { 9a072290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002 9a072290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002 `, - { look: 'handDrawn', handDrawnSeed: 1, fontFamily: 'courier' } + { look: 'handDrawn', fontFamily: 'courier' } ); }); @@ -187,7 +185,7 @@ describe('Flowchart HandDrawn', () => { ` graph TB;subgraph "number as labels";1;end; `, - { look: 'handDrawn', handDrawnSeed: 1, fontFamily: 'courier' } + { look: 'handDrawn', fontFamily: 'courier' } ); }); @@ -199,7 +197,7 @@ describe('Flowchart HandDrawn', () => { a1-->a2 end `, - { look: 'handDrawn', handDrawnSeed: 1, fontFamily: 'courier' } + { look: 'handDrawn', fontFamily: 'courier' } ); }); @@ -211,7 +209,7 @@ describe('Flowchart HandDrawn', () => { a1-->a2 end `, - { look: 'handDrawn', handDrawnSeed: 1, fontFamily: 'courier' } + { look: 'handDrawn', fontFamily: 'courier' } ); }); @@ -246,7 +244,7 @@ describe('Flowchart HandDrawn', () => { style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue `, - { look: 'handDrawn', handDrawnSeed: 1, fontFamily: 'courier' } + { look: 'handDrawn', fontFamily: 'courier' } ); }); @@ -348,7 +346,7 @@ describe('Flowchart HandDrawn', () => { sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A; sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22; `, - { look: 'handDrawn', handDrawnSeed: 1, fontFamily: 'courier' } + { look: 'handDrawn', fontFamily: 'courier' } ); }); @@ -364,7 +362,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, listUrl: false, listId: 'color styling', fontFamily: 'courier', @@ -390,7 +387,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, listUrl: false, listId: 'color styling', fontFamily: 'courier', @@ -411,7 +407,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -435,7 +430,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -457,7 +451,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -471,7 +464,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -485,7 +477,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -500,7 +491,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -527,7 +517,6 @@ describe('Flowchart HandDrawn', () => { class A someclass;`, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -544,7 +533,7 @@ describe('Flowchart HandDrawn', () => { C -->|Two| E[iPhone] C -->|Three| F[fa:fa-car Car] `, - { look: 'handDrawn', handDrawnSeed: 1, flowchart: { nodeSpacing: 50 }, fontFamily: 'courier' } + { look: 'handDrawn', flowchart: { nodeSpacing: 50 }, fontFamily: 'courier' } ); }); @@ -560,7 +549,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { rankSpacing: '100' }, fontFamily: 'courier', } @@ -578,7 +566,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -603,7 +590,7 @@ describe('Flowchart HandDrawn', () => { click E "notes://do-your-thing/id" "other protocol test" click F "javascript:alert('test')" "script test" `, - { look: 'handDrawn', handDrawnSeed: 1, securityLevel: 'loose', fontFamily: 'courier' } + { look: 'handDrawn', securityLevel: 'loose', fontFamily: 'courier' } ); }); @@ -623,7 +610,7 @@ describe('Flowchart HandDrawn', () => { click B "index.html#link-clicked" "link test" click D testClick "click test" `, - { look: 'handDrawn', handDrawnSeed: 1, flowchart: { htmlLabels: true } } + { look: 'handDrawn', flowchart: { htmlLabels: true } } ); }); @@ -645,7 +632,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -664,7 +650,7 @@ describe('Flowchart HandDrawn', () => { class A myClass1 class D myClass2 `, - { look: 'handDrawn', handDrawnSeed: 1, flowchart: { htmlLabels: true } } + { look: 'handDrawn', flowchart: { htmlLabels: true } } ); }); @@ -682,7 +668,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -711,7 +696,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -728,7 +712,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -752,7 +735,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: false }, fontFamily: 'courier', } @@ -769,7 +751,7 @@ describe('Flowchart HandDrawn', () => { C -->|Two| E[iPhone] C -->|Three| F[fa:fa-car Car] `, - { look: 'handDrawn', handDrawnSeed: 1, flowchart: { diagramPadding: 0 } } + { look: 'handDrawn', flowchart: { diagramPadding: 0 } } ); }); @@ -804,7 +786,7 @@ describe('Flowchart HandDrawn', () => { `graph TD a["Haiya"]-->b `, - { look: 'handDrawn', handDrawnSeed: 1, htmlLabels: false, flowchart: { htmlLabels: false } } + { look: 'handDrawn', htmlLabels: false, flowchart: { htmlLabels: false } } ); }); it('FDH37: should render non-escaped with html labels', () => { @@ -814,7 +796,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', @@ -830,7 +811,7 @@ describe('Flowchart HandDrawn', () => { C -->|Two| E[iPhone] C -->|Three| F[fa:fa-car Car] `, - { look: 'handDrawn', handDrawnSeed: 1, flowchart: { useMaxWidth: true } } + { look: 'handDrawn', flowchart: { useMaxWidth: true } } ); cy.get('svg').should((svg) => { expect(svg).to.have.attr('width', '100%'); @@ -853,7 +834,7 @@ describe('Flowchart HandDrawn', () => { C -->|Two| E[iPhone] C -->|Three| F[fa:fa-car Car] `, - { look: 'handDrawn', handDrawnSeed: 1, flowchart: { useMaxWidth: false } } + { look: 'handDrawn', flowchart: { useMaxWidth: false } } ); cy.get('svg').should((svg) => { // const height = parseFloat(svg.attr('height')); @@ -874,7 +855,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', @@ -904,7 +884,6 @@ describe('Flowchart HandDrawn', () => { `, { look: 'handDrawn', - handDrawnSeed: 1, htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', @@ -919,7 +898,6 @@ graph TD `, { look: 'handDrawn', - handDrawnSeed: 1, htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', @@ -937,7 +915,6 @@ graph TD `, { look: 'handDrawn', - handDrawnSeed: 1, htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', @@ -977,7 +954,6 @@ graph TD `, { look: 'handDrawn', - handDrawnSeed: 1, htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', @@ -999,7 +975,6 @@ graph TD `, { look: 'handDrawn', - handDrawnSeed: 1, htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', @@ -1016,7 +991,6 @@ graph TD `, { look: 'handDrawn', - handDrawnSeed: 1, htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', @@ -1032,7 +1006,6 @@ graph TD `, { look: 'handDrawn', - handDrawnSeed: 1, htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', @@ -1051,7 +1024,6 @@ graph TD `, { look: 'handDrawn', - handDrawnSeed: 1, flowchart: { htmlLabels: true }, securityLevel: 'loose', } diff --git a/cypress/integration/rendering/flowchart-shape-alias.spec.ts b/cypress/integration/rendering/flowchart-shape-alias.spec.ts new file mode 100644 index 000000000..86aef718c --- /dev/null +++ b/cypress/integration/rendering/flowchart-shape-alias.spec.ts @@ -0,0 +1,142 @@ +import { imgSnapshotTest } from '../../helpers/util.ts'; + +const aliasSet1 = ['process', 'rect', 'proc', 'rectangle'] as const; + +const aliasSet2 = ['event', 'rounded'] as const; + +const aliasSet3 = ['stadium', 'pill', 'terminal'] as const; + +const aliasSet4 = ['fr-rect', 'subproc', 'subprocess', 'framed-rectangle', 'subroutine'] as const; + +const aliasSet5 = ['db', 'database', 'cylinder', 'cyl'] as const; + +const aliasSet6 = ['diam', 'decision', 'diamond'] as const; + +const aliasSet7 = ['hex', 'hexagon', 'prepare'] as const; + +const aliasSet8 = ['lean-r', 'lean-right', 'in-out'] as const; + +const aliasSet9 = ['lean-l', 'lean-left', 'out-in'] as const; + +const aliasSet10 = ['trap-b', 'trapezoid-bottom', 'priority'] as const; + +const aliasSet11 = ['trap-t', 'trapezoid-top', 'manual'] as const; + +const aliasSet12 = ['dbl-circ', 'double-circle'] as const; + +const aliasSet13 = ['notched-rectangle', 'card', 'notch-rect'] as const; + +const aliasSet14 = [ + 'lin-rect', + 'lined-rectangle', + 'lin-proc', + 'lined-process', + 'shaded-process', +] as const; + +const aliasSet15 = ['sm-circ', 'small-circle', 'start'] as const; + +const aliasSet16 = ['fr-circ', 'framed-circle', 'stop'] as const; + +const aliasSet17 = ['fork', 'join'] as const; +// brace-r', 'braces' +const aliasSet18 = ['comment', 'brace-l'] as const; + +const aliasSet19 = ['bolt', 'com-link', 'lightning-bolt'] as const; + +const aliasSet20 = ['doc', 'document'] as const; + +const aliasSet21 = ['delay', 'half-rounded-rectangle'] as const; + +const aliasSet22 = ['h-cyl', 'das', 'horizontal-cylinder'] as const; + +const aliasSet23 = ['lin-cyl', 'disk', 'lined-cylinder'] as const; + +const aliasSet24 = ['curv-trap', 'display', 'curved-trapezoid'] as const; + +const aliasSet25 = ['div-rect', 'div-proc', 'divided-rectangle', 'divided-process'] as const; + +const aliasSet26 = ['extract', 'tri', 'triangle'] as const; + +const aliasSet27 = ['win-pane', 'internal-storage', 'window-pane'] as const; + +const aliasSet28 = ['f-circ', 'junction', 'filled-circle'] as const; + +const aliasSet29 = ['lin-doc', 'lined-document'] as const; + +const aliasSet30 = ['notch-pent', 'loop-limit', 'notched-pentagon'] as const; + +const aliasSet31 = ['flip-tri', 'manual-file', 'flipped-triangle'] as const; + +const aliasSet32 = ['sl-rect', 'manual-input', 'sloped-rectangle'] as const; + +const aliasSet33 = ['docs', 'documents', 'st-doc', 'stacked-document'] as const; + +const aliasSet34 = ['procs', 'processes', 'st-rect', 'stacked-rectangle'] as const; + +const aliasSet35 = ['flag', 'paper-tape'] as const; + +const aliasSet36 = ['bow-rect', 'stored-data', 'bow-tie-rectangle'] as const; + +const aliasSet37 = ['cross-circ', 'summary', 'crossed-circle'] as const; + +const aliasSet38 = ['tag-doc', 'tagged-document'] as const; + +const aliasSet39 = ['tag-rect', 'tag-proc', 'tagged-rectangle', 'tagged-process'] as const; + +const aliasSet40 = ['collate', 'hourglass'] as const; + +// Aggregate all alias sets into a single array +const aliasSets = [ + aliasSet1, + aliasSet2, + aliasSet3, + aliasSet4, + aliasSet5, + aliasSet6, + aliasSet7, + aliasSet8, + aliasSet9, + aliasSet10, + aliasSet11, + aliasSet12, + aliasSet13, + aliasSet14, + aliasSet15, + aliasSet16, + aliasSet17, + aliasSet18, + aliasSet19, + aliasSet20, + aliasSet21, + aliasSet22, + aliasSet23, + aliasSet24, + aliasSet25, + aliasSet26, + aliasSet27, + aliasSet28, + aliasSet29, + aliasSet30, + aliasSet31, + aliasSet32, + aliasSet33, + aliasSet34, + aliasSet35, + aliasSet36, + aliasSet37, + aliasSet38, + aliasSet39, +] as const; + +aliasSets.forEach((aliasSet) => { + describe(`Test ${aliasSet.join(',')} `, () => { + it(`All ${aliasSet.join(',')} should render same shape`, () => { + let flowchartCode = `flowchart \n`; + aliasSet.forEach((alias, index) => { + flowchartCode += ` n${index}@{ shape: ${alias}, label: "${alias}" }\n`; + }); + imgSnapshotTest(flowchartCode); + }); + }); +}); diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js index 452cdb5a0..66452f4b2 100644 --- a/cypress/integration/rendering/flowchart-v2.spec.js +++ b/cypress/integration/rendering/flowchart-v2.spec.js @@ -786,7 +786,7 @@ A ~~~ B `--- title: Subgraph nodeSpacing and rankSpacing example config: - flowchart: + flowchart: nodeSpacing: 250 rankSpacing: 250 --- @@ -1052,5 +1052,28 @@ end } ); }); + it('Should render self-loops', () => { + imgSnapshotTest( + `flowchart + A --> A + subgraph B + B1 --> B1 + end + subgraph C + subgraph C1 + C2 --> C2 + subgraph D + D1 --> D1 + end + D --> D + end + C1 --> C1 + end + `, + { + flowchart: { subGraphTitleMargin: { top: 10, bottom: 5 } }, + } + ); + }); }); }); diff --git a/cypress/integration/rendering/iconShape.spec.ts b/cypress/integration/rendering/iconShape.spec.ts new file mode 100644 index 000000000..4c12c3fa3 --- /dev/null +++ b/cypress/integration/rendering/iconShape.spec.ts @@ -0,0 +1,143 @@ +import { imgSnapshotTest } from '../../helpers/util'; + +const looks = ['classic', 'handDrawn'] as const; +const directions = [ + 'TB', + //'BT', + 'LR', + // 'RL' +] as const; +const forms = [undefined, 'square', 'circle', 'rounded'] as const; +const labelPos = [undefined, 't', 'b'] as const; + +looks.forEach((look) => { + directions.forEach((direction) => { + forms.forEach((form) => { + labelPos.forEach((pos) => { + describe(`Test iconShape in ${form ? `${form} form,` : ''} ${look} look and dir ${direction} with label position ${pos ? pos : 'not defined'}`, () => { + it(`without label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> nAA@{ icon: 'fa:bell'`; + if (form) { + flowchartCode += `, form: '${form}'`; + } + flowchartCode += ` }\n`; + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> nAA@{ icon: 'fa:bell', label: 'This is a label for icon shape'`; + if (form) { + flowchartCode += `, form: '${form}'`; + } + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with very long label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> nAA@{ icon: 'fa:bell', label: 'This is a very very very very very long long long label for icon shape'`; + if (form) { + flowchartCode += `, form: '${form}'`; + } + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with markdown htmlLabels:true`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> nAA@{ icon: 'fa:bell', label: 'This is **bold**
and strong for icon shape'`; + if (form) { + flowchartCode += `, form: '${form}'`; + } + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with markdown htmlLabels:false`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> nAA@{ icon: 'fa:bell', label: 'This is **bold**
and strong for icon shape'`; + if (form) { + flowchartCode += `, form: '${form}'`; + } + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + imgSnapshotTest(flowchartCode, { + look, + htmlLabels: false, + flowchart: { htmlLabels: false }, + }); + }); + + it(`with styles`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> nAA@{ icon: 'fa:bell', label: 'new icon shape'`; + if (form) { + flowchartCode += `, form: '${form}'`; + } + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + flowchartCode += ` style nAA fill:#f9f,stroke:#333,stroke-width:4px \n`; + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with classDef`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`; + flowchartCode += ` nA --> nAA@{ icon: 'fa:bell', label: 'new icon shape'`; + if (form) { + flowchartCode += `, form: '${form}'`; + } + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + flowchartCode += ` nAA:::customClazz\n`; + imgSnapshotTest(flowchartCode, { look }); + }); + }); + }); + }); + }); +}); + +describe('Test iconShape with different h', () => { + it('with different h', () => { + let flowchartCode = `flowchart TB\n`; + const icon = 'fa:bell'; + const iconHeight = 64; + flowchartCode += ` nA --> nAA@{ icon: '${icon}', label: 'icon with different h', h: ${iconHeight} }\n`; + imgSnapshotTest(flowchartCode); + }); +}); + +describe('Test colored iconShape', () => { + it('with no styles', () => { + let flowchartCode = `flowchart TB\n`; + const icon = 'fluent-emoji:tropical-fish'; + flowchartCode += ` nA --> nAA@{ icon: '${icon}', form: 'square', label: 'icon with color' }\n`; + imgSnapshotTest(flowchartCode); + }); + + it('with styles', () => { + let flowchartCode = `flowchart TB\n`; + const icon = 'fluent-emoji:tropical-fish'; + flowchartCode += ` nA --> nAA@{ icon: '${icon}', form: 'square', label: 'icon with color' }\n`; + flowchartCode += ` style nAA fill:#f9f,stroke:#333,stroke-width:4px \n`; + imgSnapshotTest(flowchartCode); + }); +}); diff --git a/cypress/integration/rendering/imageShape.spec.ts b/cypress/integration/rendering/imageShape.spec.ts new file mode 100644 index 000000000..d2e267149 --- /dev/null +++ b/cypress/integration/rendering/imageShape.spec.ts @@ -0,0 +1,103 @@ +import { imgSnapshotTest } from '../../helpers/util'; + +const looks = ['classic', 'handDrawn'] as const; +const directions = [ + 'TB', + //'BT', + 'LR', + // 'RL' +] as const; +const labelPos = [undefined, 't', 'b'] as const; + +looks.forEach((look) => { + directions.forEach((direction) => { + labelPos.forEach((pos) => { + describe(`Test imageShape in ${look} look and dir ${direction} with label position ${pos ? pos : 'not defined'}`, () => { + it(`without label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', w: '100', h: '100' }\n`; + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'This is a label for image shape'`; + + flowchartCode += `, w: '100', h: '200'`; + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with very long label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'This is a very very very very very long long long label for image shape'`; + + flowchartCode += `, w: '100', h: '250'`; + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with markdown htmlLabels:true`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'This is **bold**
and strong for image shape'`; + + flowchartCode += `, w: '550', h: '200'`; + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + imgSnapshotTest(flowchartCode, { look, htmlLabels: true }); + }); + + it(`with markdown htmlLabels:false`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'This is **bold**
and strong for image shape'`; + flowchartCode += `, w: '250', h: '200'`; + + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + imgSnapshotTest(flowchartCode, { + look, + htmlLabels: false, + flowchart: { htmlLabels: false }, + }); + }); + + it(`with styles`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'new image shape'`; + flowchartCode += `, w: '550', h: '200'`; + + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + flowchartCode += ` style A fill:#f9f,stroke:#333,stroke-width:4px \n`; + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with classDef`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#000000,stroke-dasharray: 5 5\n`; + flowchartCode += ` nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', label: 'new image shape'`; + + flowchartCode += `, w: '500', h: '550'`; + if (pos) { + flowchartCode += `, pos: '${pos}'`; + } + flowchartCode += ` }\n`; + flowchartCode += ` A:::customClazz\n`; + imgSnapshotTest(flowchartCode, { look }); + }); + }); + }); + }); +}); diff --git a/cypress/integration/rendering/kanban.spec.ts b/cypress/integration/rendering/kanban.spec.ts new file mode 100644 index 000000000..6293776d6 --- /dev/null +++ b/cypress/integration/rendering/kanban.spec.ts @@ -0,0 +1,136 @@ +import { imgSnapshotTest } from '../../helpers/util.ts'; + +describe('Kanban diagram', () => { + it('1: should render a kanban with a single section', () => { + imgSnapshotTest( + `kanban + id1[Todo] + docs[Create Documentation] + docs[Create Blog about the new diagram] + `, + {} + ); + }); + it('2: should render a kanban with multiple sections', () => { + imgSnapshotTest( + `kanban + id1[Todo] + docs[Create Documentation] + id2 + docs[Create Blog about the new diagram] + `, + {} + ); + }); + it('3: should render a kanban with a single wrapping node', () => { + imgSnapshotTest( + `kanban + id1[Todo] + id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] + `, + {} + ); + }); + it('4: should handle the height of a section with a wrapping node at the end', () => { + imgSnapshotTest( + `kanban + id1[Todo] + id2[One line] + id3[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] + `, + {} + ); + }); + it('5: should handle the height of a section with a wrapping node at the top', () => { + imgSnapshotTest( + `kanban + id1[Todo] + id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] + id3[One line] + `, + {} + ); + }); + it('6: should handle the height of a section with a wrapping node in the middle', () => { + imgSnapshotTest( + `kanban + id1[Todo] + id2[One line] + id3[Title of diagram is more than 100 chars when user duplicates diagram with 100 char, wrapping] + id4[One line] + `, + {} + ); + }); + it('6: should handle assigments', () => { + imgSnapshotTest( + `kanban + id1[Todo] + docs[Create Documentation] + id2[In progress] + docs[Create Blog about the new diagram]@{ assigned: 'knsv' } + `, + {} + ); + }); + it('7: should handle prioritization', () => { + imgSnapshotTest( + `kanban + id2[In progress] + vh[Very High]@{ priority: 'Very High' } + h[High]@{ priority: 'High' } + m[Default priority] + l[Low]@{ priority: 'Low' } + vl[Very Low]@{ priority: 'Very Low' } + `, + {} + ); + }); + it('7: should handle external tickets', () => { + imgSnapshotTest( + `kanban + id1[Todo] + docs[Create Documentation] + id2[In progress] + docs[Create Blog about the new diagram]@{ ticket: MC-2037 } + `, + {} + ); + }); + it('8: should handle assignments, prioritization and tickets ids in the same item', () => { + imgSnapshotTest( + `kanban + id2[In progress] + docs[Create Blog about the new diagram]@{ priority: 'Very Low', ticket: MC-2037, assigned: 'knsv' } + `, + {} + ); + }); + it('10: Full example', () => { + imgSnapshotTest( + `--- +config: + kanban: + ticketBaseUrl: 'https://abc123.atlassian.net/browse/#TICKET#' +--- +kanban + id1[Todo] + docs[Create Documentation] + docs[Create Blog about the new diagram] + id7[In progress] + id6[Create renderer so that it works in all cases. We also add som extra text here for testing purposes. And some more just for the extra flare.] + id8[Design grammar]@{ assigned: 'knsv' } + id9[Ready for deploy] + id10[Ready for test] + id11[Done] + id5[define getData] + id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char]@{ ticket: MC-2036, priority: 'Very High'} + id3[Update DB function]@{ ticket: MC-2037, assigned: knsv, priority: 'High' } + id4[Create parsing tests]@{ ticket: MC-2038, assigned: 'K.Sveidqvist', priority: 'High' } + id66[last item]@{ priority: 'Very Low', assigned: 'knsv' } + id12[Can't reproduce] + `, + {} + ); + }); +}); diff --git a/cypress/integration/rendering/newShapes.spec.ts b/cypress/integration/rendering/newShapes.spec.ts new file mode 100644 index 000000000..6c71a3846 --- /dev/null +++ b/cypress/integration/rendering/newShapes.spec.ts @@ -0,0 +1,146 @@ +import { imgSnapshotTest } from '../../helpers/util.ts'; + +const looks = ['classic', 'handDrawn'] as const; +const directions = [ + 'TB', + //'BT', + 'LR', + //'RL' +] as const; +const newShapesSet1 = [ + 'triangle', + 'sloped-rectangle', + 'horizontal-cylinder', + 'flipped-triangle', + 'hourglass', +] as const; +const newShapesSet2 = [ + 'tagged-rectangle', + 'documents', + 'lightning-bolt', + 'filled-circle', + 'window-pane', +] as const; + +const newShapesSet3 = [ + 'curved-trapezoid', + 'bow-rect', + 'tagged-document', + 'divided-rectangle', + 'crossed-circle', +] as const; + +const newShapesSet4 = [ + 'document', + 'notched-pentagon', + 'lined-cylinder', + 'stacked-document', + 'half-rounded-rectangle', +] as const; + +const newShapesSet5 = [ + 'lined-document', + 'tagged-document', + 'brace-l', + 'comment', + 'braces', + 'brace-r', +] as const; + +const newShapesSet6 = ['brace-r', 'braces'] as const; +// Aggregate all shape sets into a single array +const newShapesSets = [ + newShapesSet1, + newShapesSet2, + newShapesSet3, + newShapesSet4, + newShapesSet5, + newShapesSet6, +]; + +looks.forEach((look) => { + directions.forEach((direction) => { + newShapesSets.forEach((newShapesSet) => { + describe(`Test ${newShapesSet.join(', ')} in ${look} look and dir ${direction}`, () => { + it(`without label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + newShapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape} }\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + newShapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`connect all shapes with each other`, () => { + let flowchartCode = `flowchart ${direction}\n`; + newShapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`; + }); + for (let i = 0; i < newShapesSet.length; i++) { + for (let j = i + 1; j < newShapesSet.length; j++) { + flowchartCode += ` n${i}${i} --> n${j}${j}\n`; + } + } + if (!(direction === 'TB' && look === 'handDrawn' && newShapesSet === newShapesSet1)) { + //skip this test, works in real. Need to look + imgSnapshotTest(flowchartCode, { look }); + } + }); + + it(`with very long label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + newShapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a very very very very very long long long label for ${newShape} shape' }\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with markdown htmlLabels:true`, () => { + let flowchartCode = `flowchart ${direction}\n`; + newShapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold**
and strong for ${newShape} shape' }\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with markdown htmlLabels:false`, () => { + let flowchartCode = `flowchart ${direction}\n`; + newShapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold**
and strong for ${newShape} shape' }\n`; + }); + imgSnapshotTest(flowchartCode, { + look, + htmlLabels: false, + flowchart: { htmlLabels: false }, + }); + }); + + it(`with styles`, () => { + let flowchartCode = `flowchart ${direction}\n`; + newShapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`; + flowchartCode += ` style n${index}${index} fill:#f9f,stroke:#333,stroke-width:4px \n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with classDef`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`; + newShapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`; + flowchartCode += ` n${index}${index}:::customClazz\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + }); + }); + }); +}); diff --git a/cypress/integration/rendering/oldShapes.spec.ts b/cypress/integration/rendering/oldShapes.spec.ts new file mode 100644 index 000000000..628e70ea8 --- /dev/null +++ b/cypress/integration/rendering/oldShapes.spec.ts @@ -0,0 +1,107 @@ +import { imgSnapshotTest } from '../../helpers/util'; + +const looks = ['classic', 'handDrawn'] as const; +const directions = [ + 'TB', + //'BT', + 'LR', + //'RL' +] as const; + +const shapesSet1 = ['text', 'card', 'lin-rect', 'diamond', 'hexagon'] as const; + +// removing labelRect, need have alias for it +const shapesSet2 = ['rounded', 'rect', 'start', 'stop'] as const; + +const shapesSet3 = ['fork', 'choice', 'note', 'stadium', 'odd'] as const; + +const shapesSet4 = ['subroutine', 'cylinder', 'circle', 'doublecircle', 'odd'] as const; + +const shapesSet5 = ['anchor', 'lean-r', 'lean-l', 'trap-t', 'trap-b'] as const; + +// Aggregate all shape sets into a single array +const shapesSets = [shapesSet1, shapesSet2, shapesSet3, shapesSet4, shapesSet5] as const; + +looks.forEach((look) => { + directions.forEach((direction) => { + shapesSets.forEach((shapesSet) => { + describe(`Test ${shapesSet.join(', ')} in ${look} look and dir ${direction}`, () => { + it(`without label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape} }\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`connect all shapes with each other`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`; + }); + for (let i = 0; i < shapesSet.length; i++) { + for (let j = i + 1; j < shapesSet.length; j++) { + flowchartCode += ` n${i}${i} --> n${j}${j}\n`; + } + } + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with very long label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a very very very very very long long long label for ${newShape} shape' }\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with markdown htmlLabels:true`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold**
and strong for ${newShape} shape' }\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with markdown htmlLabels:false`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold**
and strong for ${newShape} shape' }\n`; + }); + imgSnapshotTest(flowchartCode, { + look, + htmlLabels: false, + flowchart: { htmlLabels: false }, + }); + }); + + it(`with styles`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`; + flowchartCode += ` style n${index}${index} fill:#f9f,stroke:#333,stroke-width:4px \n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with classDef`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`; + flowchartCode += ` n${index}${index}:::customClazz\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + }); + }); + }); +}); diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index a3cbf60bf..66fc0f2d3 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -10,6 +10,10 @@ href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css" rel="stylesheet" /> + -
-
----
-  title: hello2
-  config:
-    look: handDrawn
-    layout: elk
-    elk:
-        
-        
----
-stateDiagram-v2
-    direction LR
-    accTitle: An idealized Open Source supply-chain graph
-
-    %%
-    state "🟦 Importer" as author_importer
-    state "🟥 Supplier, Owner" as author_owner
-    state "🟨🟥 Maintainer, Author\n🟨 Custodian" as author
-    state "🟩 Distributor" as repository_distributor
-    state "🟦 Importer" as language_importer
-    state "🟦🟨 Packager" as language_packager
-    state "🟦🟨 OSS Steward" as language_steward
-    state "🟨 Curator" as language_curator
-    state "🟩 Distributor" as language_distributor
-    state "🟦 Contributor" as contributor
-    state "🟦 Importer" as package_importer
-    state "🟨 Patcher" as package_patcher
-    state "🟨🟦 Builder\n🟨🟦 Packager\n🟨🟦 Containerizer" as package_packager
-    state "🟨 Curator" as package_curator
-    state "🟩 Distributor" as package_distributor
-    state "🟦 Importer" as integrator_importer
-    state "🟥 Supplier, Manufacturer, Owner" as integrator_owner
-    state "🟦🟨🟥 Integrator, Developer" as integrator_developer
-    state "🟩🟨 SBOM Redactor\n🟩 Publisher" as integrator_publisher
-    state "🟦🟨 Builder" as integrator_builder
-    state "🟨 Deployer" as deployer
-    state "🟦 Vuln. Checker" as integrator_checker
-    state "🟩🟨 SBOM Redactor" as redactor
-    state "🟦 Consumer\n🟦  User" as consumer
-    state "🟦 Auditor" as auditor_internal
-    state "🟦 Auditor" as auditor_external
-
-    %%
-    classDef createsSBOM stroke:red,stroke-width:3px;
-    classDef updatesSBOM stroke:yellow,stroke-width:3px;
-    classDef assemblesSBOM stroke:yellow,stroke-width:3px;
-    classDef distributesSBOM stroke:green,stroke-width:3px;
-    classDef verifiesSBOM stroke:#07f,stroke-width:3px;
-
-    %%
-    class author_importer verifiesSBOM
-    class author_owner createsSBOM
-    class manufacturer_owner createsSBOM
-    class author assemblesSBOM
-    class package_importer verifiesSBOM
-    class package_patcher updatesSBOM
-    class package_packager assemblesSBOM
-    class package_curator distributesSBOM
-    class package_distributor distributesSBOM
-    class language_importer verifiesSBOM
-    class language_packager assemblesSBOM
-    class language_steward updatesSBOM
-    class language_curator distributesSBOM
-    class language_distributor distributesSBOM
-    class repository_distributor distributesSBOM
-    class integrator_importer verifiesSBOM
-    class integrator_owner createsSBOM
-    class integrator_developer assemblesSBOM
-    class integrator_publisher distributesSBOM
-    class integrator_builder assemblesSBOM
-    class integrator_checker verifiesSBOM
-    class deployer assemblesSBOM
-    class redactor distributesSBOM
-    class auditor_internal verifiesSBOM
-    class auditor_external verifiesSBOM
-
-    state "Maintainer Environment" as environment_maintainer {
-        [*] --> author_importer
-        [*] --> author
-        author_importer --> author
-        author_owner --> author
-        author       --> language_packager
-    }
-
-    [*] --> environment_maintainer
-
-    state "Language Ecosystem" as ecosystem_lang {
-        [*] --> language_importer
-        [*] --> language_steward
-        [*] --> language_curator
-        [*] --> language_distributor
-        language_importer --> language_distributor
-        language_importer --> language_curator
-        language_steward --> language_curator
-        language_curator --> language_distributor
-    }
-
-    language_packager --> ecosystem_lang
-    ecosystem_lang    --> ecosystem_lang
-
-    state "Public Collaboration Ecosystem" as ecosystem_repo {
-        [*] --> repository_distributor
-    }
-
-    author         --> ecosystem_repo
-    ecosystem_repo --> author
-
-    repository_distributor --> contributor
-    contributor            --> repository_distributor
-
-    state "Package Ecosystem" as ecosystem_package {
-        [*] --> package_importer
-        [*] --> package_packager
-        [*] --> package_patcher
-        package_importer --> package_patcher
-        package_importer --> package_packager
-        package_patcher  --> package_packager
-        package_packager --> package_curator
-        package_packager --> package_distributor
-        package_curator  --> package_distributor
-    }
-
-    repository_distributor --> ecosystem_package
-    language_distributor   --> ecosystem_package
-    ecosystem_package      --> ecosystem_package
-
-    state "Integrator Environment" as environment_integrator {
-        [*] --> integrator_developer
-        [*] --> integrator_importer
-        integrator_importer  --> integrator_developer
-        integrator_owner     --> integrator_developer
-        integrator_builder   --> integrator_publisher
-        integrator_developer --> integrator_checker
-        integrator_checker   --> integrator_developer
-        auditor_internal     --> integrator_developer
-        integrator_developer --> integrator_builder
-        integrator_developer --> auditor_internal
-    }
-
-    repository_distributor --> environment_integrator
-    language_distributor   --> environment_integrator
-    package_distributor    --> environment_integrator
-
-    state "Production Environment" as environment_prod {
-        [*] --> deployer
-        deployer --> redactor
-    }
-
-    integrator_publisher --> [*]
-    integrator_developer --> environment_prod
-    integrator_builder   --> environment_prod
-    integrator_publisher --> environment_prod
-
-    deployer --> auditor_external
-    deployer --> consumer
-    redactor --> consumer
-
-
-
-
-
----
-  title: hello2
-  config:
-    look: handDrawn
-    layout: dagre
-    elk:
-        nodePlacementStrategy: BRANDES_KOEPF
----
-stateDiagram-v2
-  A --> A
-  state A {
-    B --> D
-    state B {
-      C
-    }
-    state D {
-      E
-    }
-  }
-
-
-
-
----
-  title: hello2
-  config:
-    look: handDrawn
-    layout: dagre
-    elk:
-        nodePlacementStrategy: BRANDES_KOEPF
----
-flowchart
-  A --> A
-  subgraph A
-    B --> B
-    subgraph B
-      C
-    end
-  end
-
-
-
-
----
-config:
-  look: handdrawn
-  flowchart:
-    htmlLabels: true
----
-flowchart
-      A[I am a long text, where do I go??? handdrawn - true]
-
-
-
-
----
-config:
-  flowchart:
-    htmlLabels: false
----
-flowchart
-      A[I am a long text, where do I go??? classic - false]
-
-
----
-config:
-  flowchart:
-    htmlLabels: true
----
-flowchart
-      A[I am a long text, where do I go??? classic - true]
-
-
-
+    
 flowchart LR
-    id1(Start)-->id2(Stop)
-    style id1 fill:#f9f,stroke:#333,stroke-width:4px
-    style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
-
+nA[Default] --> A@{ icon: 'fa:bell', form: 'rounded' }
 
     
- -
-      flowchart LR
-    A:::foo & B:::bar --> C:::foobar
-    classDef foo stroke:#f00
-    classDef bar stroke:#0f0
-    classDef ash color:red
-    class C ash
-    style C stroke:#00f, fill:black
+    
+flowchart LR
+nA[Style] --> A@{ icon: 'fa:bell', form: 'rounded' }
+style A fill:#f9f,stroke:#333,stroke-width:4px
+    
+
+flowchart LR
+nA[Class] --> A@{ icon: 'fa:bell', form: 'rounded' }
+A:::AClass
+classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
+    
+
+flowchart LR
+  nA[Class] --> A@{ icon: 'logos:aws', form: 'rounded' }
 
     
+
+flowchart LR
+nA[Default] --> A@{ icon: 'fa:bell', form: 'square' }
 
+    
+
+flowchart LR
+nA[Style] --> A@{ icon: 'fa:bell', form: 'square' }
+style A fill:#f9f,stroke:#333,stroke-width:4px
+    
+
+flowchart LR
+nA[Class] --> A@{ icon: 'fa:bell', form: 'square' }
+A:::AClass
+classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
+    
+
+flowchart LR
+  nA[Class] --> A@{ icon: 'logos:aws', form: 'square' }
+
+    
+
+flowchart LR
+nA[Default] --> A@{ icon: 'fa:bell', form: 'circle' }
+
+    
+
+flowchart LR
+nA[Style] --> A@{ icon: 'fa:bell', form: 'circle' }
+style A fill:#f9f,stroke:#333,stroke-width:4px
+    
+
+flowchart LR
+nA[Class] --> A@{ icon: 'fa:bell', form: 'circle' }
+A:::AClass
+classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
+    
+
+flowchart LR
+  nA[Class] --> A@{ icon: 'logos:aws', form: 'circle' }
+  A:::AClass
+  classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
+    
+
+flowchart LR
+  nA[Style] --> A@{ icon: 'logos:aws', form: 'circle' }
+  style A fill:#f9f,stroke:#333,stroke-width:4px
+    
-      stateDiagram
-    A:::foo
-    B:::bar --> C:::foobar
-    classDef foo stroke:#f00
-    classDef bar stroke:#0f0
-    style C stroke:#00f, fill:black, color:white
-
+kanban
+  id2[In progress]
+    docs[Create Blog about the new diagram]@{ priority: 'Very Low', ticket: MC-2037, assigned: 'knsv' }
     
+
+---
+config:
+  kanban:
+    ticketBaseUrl: 'https://mermaidchart.atlassian.net/browse/#TICKET#'
+    # sectionWidth: 300
+---
+kanban
+  Todo
+    [Create Documentation]
+    docs[Create Blog about the new diagram]
+  id7[In progress]
+    id6[Create renderer so that it works in all cases. We also add som extra text here for testing purposes. And some more just for the extra flare.]
+  id9[Ready for deploy]
+    id8[Design grammar]@{ assigned: 'knsv' }
+  id10[Ready for test]
+    id4[Create parsing tests]@{ ticket: MC-2038, assigned: 'K.Sveidqvist', priority: 'High' }
+    id66[last item]@{ priority: 'Very Low', assigned: 'knsv' }
+  id11[Done]
+    id5[define getData]
+    id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char]@{ ticket: MC-2036, priority: 'Very High'}
+    id3[Update DB function]@{ ticket: MC-2037, assigned: knsv, priority: 'High' }
 
+  id12[Can't reproduce]
+    id3[Weird flickering in Firefox]
+    
+ + diff --git a/cypress/platform/viewer.js b/cypress/platform/viewer.js index 77da253c2..a9d4d2d81 100644 --- a/cypress/platform/viewer.js +++ b/cypress/platform/viewer.js @@ -50,6 +50,60 @@ const contentLoaded = async function () { mermaid.registerLayoutLoaders(layouts); mermaid.initialize(graphObj.mermaid); + const staticBellIconPack = { + prefix: 'fa6-regular', + icons: { + bell: { + body: '', + width: 448, + }, + }, + width: 512, + height: 512, + }; + /* MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE */ + const staticAwsLogoIconPack = { + prefix: 'fluent-emoji', + icons: { + 'tropical-fish': { + width: 32, + height: 32, + body: '', + }, + }, + width: 256, + height: 256, + }; + mermaid.registerIconPacks([ + { + name: 'fa', + loader: () => staticBellIconPack, + }, + { + name: 'fluent-emoji', + loader: () => staticAwsLogoIconPack, + }, + ]); await mermaid.run(); } }; diff --git a/cypress/platform/yari.html b/cypress/platform/yari.html new file mode 100644 index 000000000..501541c3b --- /dev/null +++ b/cypress/platform/yari.html @@ -0,0 +1,663 @@ + + +

Class Nodes

+
+
+

Basic Class

+
+          ---
+            config:
+              htmlLabels: false
+          ---
+          classDiagram
+          class _Duck_ {
+            +String beakColor
+            _+_swim_()a_
+            __+quack() test__
+          }
+        
+
+
+

Basic Class

+
+          ---
+          config:
+            htmlLabels: false
+          ---
+          classDiagram
+          class Class10:::exClass2 {
+            int[] id
+            List~int~ ids
+            test(List~int~ ids) List~bool~
+            testArray() bool[]
+          }
+        
+
+
+

Basic Class

+
+          flowchart TD
+            Start --> Stop
+        
+
+
+

Complex Class

+
+                classDiagram
+                class Square~Shape~{
+                  int id
+                  List~int~ position
+                  setPoints(List~int~ points)
+                  getPoints() List~int~
+                }
+          
+          Square : -List~string~ messages
+          Square : +setMessages(List~string~ messages)
+          Square : +getMessages() List~string~
+          Square : +getDistanceMatrix() List~List~int~~
+              
+
+
+

No Attributes

+
+          classDiagram
+          class Duck {
+            +swim()
+            +quack()
+          }
+        
+
+
+

No Methods

+
+          classDiagram
+          class Duck {
+            +String beakColor
+          }
+        
+
+
+

Only Class Name

+

Empty line as attribute

+
+          ---
+            config:
+              class:
+                hideEmptyMembersBox: false
+          ---
+          classDiagram
+          class Duck {
+            
+          }
+        
+
+
+

Visibility and Types

+

(Further tilde testing)

+
+ classDiagram class Duck { ~interface~~~ +String beakColor #swim() ~quack()~~~ + -test()~~~~~~~ +deposit(amount) bool } +
+
+
+

Additional Classifiers

+

(* Abstract | $ Static)

+
+ classDiagram class Square~Shape~ { int id* List~int~ position* setPoints(List~int~points)* + getPoints()* List~int~ } Square : -List~string~ messages$ Square : + +setMessages(List~string~ messages)* Square : +getMessages()$ List~string~ Square : + +getDistanceMatrix() List~List~int~~$ +
+
+
+

Label

+
+          classDiagram
+          class Animal~test~["Animal with a label"]
+        
+
+
+

Spacing

+

(Fix ensures consistent spacing rules)

+

(No space or single space?)

+
+          classDiagram
+          class ClassName {
+          -attribute:type
+          -            attribute : type
+               test
+          
+          + GetAttribute() type                 
+          +     GetAttribute() type
+          }
+        
+
+
+

Annotation

+
+          classDiagram
+          class Shape
+          <<interface>> Shape
+          Shape : noOfVertices
+          Shape : draw()
+        
+
+
+

Long Class Name Text

+
+          classDiagram
+          class ThisIsATestForALongClassName {
+            <<interface>>
+            noOfLetters
+            delete()
+          }
+        
+
+
+

Long Annotation Text

+
+          classDiagram
+          class Shape
+          <<superlongannotationtext>> Shape
+          Shape : noOfVertices
+          Shape : draw()
+        
+
+
+

Long Member Text

+
+          classDiagram
+          class Shape
+          <<interface>> Shape
+          Shape : noOfVertices
+          Shape : longtexttestkeepgoingandgoing
+          Shape : draw()
+        
+
+
+

Link

+
+          classDiagram
+          class Shape
+          link Shape "https://www.github.com" "This is a tooltip for a link"
+        
+
+
+

Click

+
+          classDiagram
+          class Shape
+          click Shape href "https://www.github.com" "This is a tooltip for a link"
+        
+
+
+

Hand Drawn

+
+          ---
+          config:
+            look: handDrawn
+            htmlLabels: true
+          ---
+          classDiagram
+          class Hand {
+            +String beakColor
+            +swim()
+            +quack()
+          }
+          style Hand fill:#f9f,stroke:#29f,stroke-width:2px
+        
+
+
+

Neutral Theme

+
+          ---
+          config:
+            theme: neutral
+          ---
+          classDiagram
+          class Duck {
+            +String beakColor
+            +swim()
+            +quack()
+          }
+        
+
+
+

Dark Theme

+
+          ---
+          config:
+            theme: dark
+          ---
+          classDiagram
+          class Duck {
+            +String beakColor
+            +swim()
+            +quack()
+          }
+        
+
+
+

Forest Theme

+
+          ---
+          config:
+            theme: forest
+          ---
+          classDiagram
+          class Duck {
+            +String beakColor
+            +swim()
+            +quack()
+          }
+        
+
+
+

Base Theme

+
+          ---
+          config:
+            theme: base
+          ---
+          classDiagram
+          class Duck {
+            +String beakColor
+            +swim()
+            +quack()
+          }
+        
+
+
+

Custom Theme

+
+          %%{
+            init: {
+              'theme': 'base',
+              'themeVariables': {
+                'primaryColor': '#BB2528',
+                'primaryTextColor': '#fff',
+                'primaryBorderColor': '#7C0000',
+                'lineColor': '#F83d29',
+                'secondaryColor': '#006100',
+                'tertiaryColor': '#fff'
+              }
+            }
+          }%%
+          classDiagram
+          class Duck {
+            +String beakColor
+            +swim()
+            +quack()
+          }
+          Duck--Dog
+        
+
+
+

Styling within Diagram

+
+          classDiagram
+          class Duck {
+            +String beakColor
+            +swim()
+            +quack()
+          }
+          style Duck fill:#f9f,stroke:#333,stroke-width:8px
+        
+
+
+

Styling with classDef Statement

+
+          classDiagram
+          class Duck:::bold {
+            +String beakColor
+            +swim()
+            +quack()
+          }
+
+          class Dog {
+            +int numTeeth
+            +bark()
+          }
+
+          cssClass "Duck,Dog" pink
+
+          classDef pink fill:#f9f
+          classDef default color:#f1e
+          classDef bold stroke:#333,stroke-width:6px,color:#fff
+        
+
+
+

Styling with Class in Stylesheet

+
+          classDiagram
+          class Duck {
+            +String beakColor
+            +swim()
+            +quack()
+          }
+          class Duck:::styleClass
+        
+
+
+

Diagram Testing

+
+
+

Class Nodes Only

+
+          ---
+          title: Animal example
+          ---
+          classDiagram
+              Animal : +int age
+              Animal : +String gender
+              Animal: +isMammal()
+              Animal: +mate()
+              class Duck{
+                  +String beakColor
+                  +swim()
+                  +quack()
+              }
+              class Fish{
+                  -int sizeInFeet
+                  -canEat()
+              }
+              class Zebra{
+                  +bool is_wild
+                  +run()
+              }
+        
+
+
+

Class Nodes LR

+
+          ---
+          title: Animal example
+          ---
+          classDiagram
+              direction LR
+              Animal : +int age
+              Animal : +String gender
+              Animal: +isMammal()
+              Animal: +mate()
+              class Duck{
+                  +String beakColor
+                  +swim()
+                  +quack()
+              }
+              class Fish{
+                  -int sizeInFeet
+                  -canEat()
+              }
+              class Zebra{
+                  +bool is_wild
+                  +run()
+              }
+        
+
+
+

Relations

+
+          classDiagram
+            classA <|-- classB
+            classC *-- classD
+            classE o-- classF
+            classG <-- classH
+            classI -- classJ
+            classK <.. classL
+            classM <|.. classN
+            classO .. classP
+        
+
+
+

Two Way Relation

+
+          classDiagram
+          class Animal {
+            int size
+            walk()
+          }
+          class Zebra {
+            int size
+            walk()
+          }
+            Animal o--|> Zebra
+
+        
+
+
+

Relations with Labels

+
+          classDiagram
+            classA <|-- classB : implements
+            classC *-- classD : composition
+            classE o-- classF : aggregation
+        
+
+
+

Cardinality / Multiplicity

+
+          classDiagram
+            Customer "1" --> "*" Ticket
+            Student "1" --> "1..*" Course
+            Galaxy --> "many" Star : Contains
+        
+
+
+

Complex Relations with Theme

+
+          ---
+          config:
+            theme: forest
+            look: handDrawns
+            layout: elk
+          ---
+          classDiagram
+            direction RL
+            class Student {
+              -idCard : IdCard
+            }
+            class IdCard{
+              -id : int
+              -name : string
+            }
+            class Bike{
+              -id : int
+              -name : string
+            }
+            Student "1" o--o "1" IdCard : carries
+            Student "1" o--o "1" Bike : rides
+        
+
+
+

Notes

+
+          classDiagram
+            note "This is a general note"
+            note for MyClass "This is a note for a class"
+            class MyClass
+        
+
+
+

Namespaces

+
+          classDiagram
+            namespace BaseShapes {
+                class Triangle
+                class Rectangle {
+                  double width
+                  double height
+                }
+            }
+        
+
+
+

Namespaces

+
+          ---
+            config:
+              layout: elk
+          ---
+          classDiagram
+          namespace Namespace1 {
+            class C1
+            class C2
+          }
+          C1 --> C2
+          class C3
+          class C4
+        
+
+
+

Full Example

+
+          ---
+          title: Animal example
+          config:
+            layout: dagre
+          ---
+          classDiagram
+              note "From Duck till Zebra"
+              Animal <|--|> Duck
+              note for Duck "can fly
can swim
can dive
can help in debugging" + Animal <|-- Fish + Animal <|--|> Zebra + Animal : +int age + Animal : +String gender + Animal: +isMammal() + Animal: +mate() + class Duck{ + +String beakColor + +swim() + +quack() + } + class Fish{ + -int sizeInFeet + -canEat() + } + class Zebra{ + +bool is_wild + +run() + } + cssClass "Duck" test + classDef test fill:#f71 + %%classDef default fill:#f93 +
+
+
+

Full Example

+
+          ---
+            config:
+              theme: forest
+              look: handDrawn
+          ---
+          classDiagram
+          note for Outside "Note testing"
+          namespace Test {
+              class Outside
+          }
+          namespace BaseShapes {
+              class Triangle
+              class Rectangle {
+                double width
+                double height
+              }
+          }
+          Outside <|--|> Rectangle
+          style Triangle fill:#f9f,stroke:#333,stroke-width:4px
+        
+
+
+
+          ---
+            config:
+              look: handDrawn
+              layout: elk
+          ---
+          classDiagram
+            Class01 "1" <|--|> "*" AveryLongClass : Cool
+            <<interface>> Class01
+            Class03 "1" *-- "*" Class04
+            Class05 "1" o-- "many" Class06
+            Class07 "1" .. "*" Class08
+            Class09 "1" --> "*" C2 : Where am i?
+            Class09 "*" --* "*" C3
+            Class09 "1" --|> "1" Class07
+            NewClass ()--() Class04
+            Class09 <|--|> AveryLongClass
+            Class07  : equals()
+            Class07  : Object[] elementData
+            Class01  : size()
+            Class01  : int chimp
+            Class01  : int gorilla
+            Class08 "1" <--> "*" C2: Cool label
+            class Class10 {
+              <<service>>
+              int id
+              test()
+            }
+            Class10 o--o AveryLongClass
+            Class10 <--> Class07
+        
+
+
+
+          classDiagram
+            test ()--() test2
+        
+
+
+ + + + + diff --git a/cypress/timings.json b/cypress/timings.json new file mode 100644 index 000000000..3455d82fc --- /dev/null +++ b/cypress/timings.json @@ -0,0 +1,152 @@ +{ + "durations": [ + { + "spec": "cypress/integration/other/configuration.spec.js", + "duration": 4989 + }, + { + "spec": "cypress/integration/other/external-diagrams.spec.js", + "duration": 1382 + }, + { + "spec": "cypress/integration/other/ghsa.spec.js", + "duration": 3178 + }, + { + "spec": "cypress/integration/other/iife.spec.js", + "duration": 1372 + }, + { + "spec": "cypress/integration/other/interaction.spec.js", + "duration": 8998 + }, + { + "spec": "cypress/integration/other/rerender.spec.js", + "duration": 1249 + }, + { + "spec": "cypress/integration/other/xss.spec.js", + "duration": 25664 + }, + { + "spec": "cypress/integration/rendering/appli.spec.js", + "duration": 1928 + }, + { + "spec": "cypress/integration/rendering/architecture.spec.ts", + "duration": 2330 + }, + { + "spec": "cypress/integration/rendering/block.spec.js", + "duration": 11156 + }, + { + "spec": "cypress/integration/rendering/c4.spec.js", + "duration": 3418 + }, + { + "spec": "cypress/integration/rendering/classDiagram-v2.spec.js", + "duration": 14866 + }, + { + "spec": "cypress/integration/rendering/classDiagram.spec.js", + "duration": 9894 + }, + { + "spec": "cypress/integration/rendering/conf-and-directives.spec.js", + "duration": 5778 + }, + { + "spec": "cypress/integration/rendering/current.spec.js", + "duration": 1690 + }, + { + "spec": "cypress/integration/rendering/erDiagram.spec.js", + "duration": 9144 + }, + { + "spec": "cypress/integration/rendering/errorDiagram.spec.js", + "duration": 1951 + }, + { + "spec": "cypress/integration/rendering/flowchart-elk.spec.js", + "duration": 2196 + }, + { + "spec": "cypress/integration/rendering/flowchart-handDrawn.spec.js", + "duration": 21029 + }, + { + "spec": "cypress/integration/rendering/flowchart-shape-alias.spec.ts", + "duration": 16087 + }, + { + "spec": "cypress/integration/rendering/flowchart-v2.spec.js", + "duration": 27465 + }, + { + "spec": "cypress/integration/rendering/flowchart.spec.js", + "duration": 20035 + }, + { + "spec": "cypress/integration/rendering/gantt.spec.js", + "duration": 11366 + }, + { + "spec": "cypress/integration/rendering/gitGraph.spec.js", + "duration": 34025 + }, + { + "spec": "cypress/integration/rendering/iconShape.spec.ts", + "duration": 185902 + }, + { + "spec": "cypress/integration/rendering/imageShape.spec.ts", + "duration": 41631 + }, + { + "spec": "cypress/integration/rendering/info.spec.ts", + "duration": 1736 + }, + { + "spec": "cypress/integration/rendering/journey.spec.js", + "duration": 2247 + }, + { + "spec": "cypress/integration/rendering/katex.spec.js", + "duration": 2144 + }, + { + "spec": "cypress/integration/rendering/marker_unique_id.spec.js", + "duration": 1646 + }, + { + "spec": "cypress/integration/rendering/mindmap.spec.ts", + "duration": 6406 + }, + { + "spec": "cypress/integration/rendering/newShapes.spec.ts", + "duration": 107219 + }, + { + "spec": "cypress/integration/rendering/stateDiagram.spec.js", + "duration": 15834 + }, + { + "spec": "cypress/integration/rendering/theme.spec.js", + "duration": 33240 + }, + { + "spec": "cypress/integration/rendering/timeline.spec.ts", + "duration": 7122 + }, + { + "spec": "cypress/integration/rendering/xyChart.spec.js", + "duration": 11127 + }, + { + "spec": "cypress/integration/rendering/zenuml.spec.js", + "duration": 2391 + } + ] +} diff --git a/demos/classchart.html b/demos/classchart.html index 0b3026710..fe69afbf2 100644 --- a/demos/classchart.html +++ b/demos/classchart.html @@ -159,30 +159,87 @@ class People List~List~Person~~

-
     classDiagram
-      A1 --> B1
-      namespace A {
-        class A1 {
-          +foo : string
-        }
-        class A2 {
-          +bar : int
+      namespace Company.Project.Module {
+        class GenericClass~T~ {
+          +addItem(item: T)
+          +getItem() T
         }
       }
-      namespace B {
-        class B1 {
-          +foo : bool
-        }
-        class B2 {
-          +bar : float
-        }
-      }
-      A2 --> B2
     

- +
+    classDiagram
+      namespace Company.Project.Module.SubModule {
+        class Report {
+          +generatePDF(data: List)
+          +generateCSV(data: List)
+        }
+      }
+      namespace Company.Project.Module {
+        class Admin {
+          +generateReport()
+        }
+      }
+      Admin --> Report : generates
+    
+
+    classDiagram
+      namespace Company.Project.Module {
+        class User {
+          +login(username: String, password: String)
+          +logout()
+        }
+        class Admin {
+          +addUser(user: User)
+          +removeUser(user: User)
+          +generateReport()
+        }
+        class Report {
+          +generatePDF(reportData: List)
+          +generateCSV(reportData: List)
+        }
+      }
+      Admin --> User : manages
+      Admin --> Report : generates
+    
+
+
+    classDiagram
+      namespace Shapes {
+        class Shape {
+          +calculateArea() double
+        }
+        class Circle {
+          +double radius
+        }
+        class Square {
+          +double side
+        }
+      }
+      
+      Shape <|-- Circle
+      Shape <|-- Square
+      
+      namespace Vehicles {
+        class Vehicle {
+          +String brand
+        }
+        class Car {
+          +int horsepower
+        }
+        class Bike {
+          +boolean hasGears
+        }
+      }
+      
+      Vehicle <|-- Car
+      Vehicle <|-- Bike
+      Car --> Circle : "Logo Shape"
+      Bike --> Square : "Logo Shape"
+                  
+    
       classDiagram
         note "This is a outer note"
diff --git a/docs/adding-new-shape.md b/docs/adding-new-shape.md
new file mode 100644
index 000000000..64a177237
--- /dev/null
+++ b/docs/adding-new-shape.md
@@ -0,0 +1,233 @@
+> **Warning**
+>
+> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
+>
+> ## Please edit the corresponding file in [/packages/mermaid/src/docs/adding-new-shape.md](../packages/mermaid/src/docs/adding-new-shape.md).
+
+# Custom SVG Shapes Library
+
+This library provides a collection of custom SVG shapes, utilities, and helpers for generating diagram components. The shapes are designed to be used within an SVG container and include a variety of common and complex shapes.
+
+## Overview
+
+## Shape Helpers and Utilities
+
+Before starting with shape creation, it's essential to familiarize yourself with the utilities provided in the `utils.ts` file from `packages/mermaid/src/rendering-util/rendering-elements/shapes/util.js`. These utilities are designed to assist with various aspects of SVG shape manipulation and ensure consistent and accurate rendering.
+
+## Available Utilities
+
+### 1. `labelHelper`
+
+- **Purpose**: This function creates and inserts labels inside SVG shapes.
+- **Features**:
+  - Handles both HTML labels and plain text.
+  - Calculates the bounding box dimensions of the label.
+  - Ensures proper positioning of labels within shapes.
+
+### 2. `updateNodeBounds`
+
+- **Purpose**: Updates the bounding box dimensions (width and height) of a node.
+- **Usage**:
+  - Adjusts the size of the node to fit the content or shape.
+  - Useful for ensuring that shapes resize appropriately based on their content.
+
+### 3. `insertPolygonShape`
+
+- **Purpose**: Inserts a polygon shape into an SVG container.
+- **Features**:
+  - Handles the creation and insertion of complex polygonal shapes.
+  - Configures the shape's appearance and positioning within the SVG container.
+
+### 4. `getNodeClasses`
+
+- **Purpose**: Returns the appropriate CSS classes for a node based on its configuration.
+- **Usage**:
+  - Dynamically applies CSS classes to nodes for styling purposes.
+  - Ensures that nodes adhere to the desired design and theme.
+
+### 5. `createPathFromPoints`
+
+- **Purpose**: Generates an SVG path string from an array of points.
+- **Usage**:
+  - Converts a list of points into a smooth path.
+  - Useful for creating custom shapes or paths within the SVG.
+
+### 6. `generateFullSineWavePoints`
+
+- **Purpose**: Generates points for a sine wave, useful for creating wavy-edged shapes.
+- **Usage**:
+  - Facilitates the creation of shapes with wavy or sine-wave edges.
+  - Can be used to add decorative or dynamic edges to shapes.
+
+## Getting Started
+
+To utilize these utilities, simply import them from the `utils.ts` file into your shape creation script. These helpers will streamline the process of building and customizing SVG shapes, ensuring consistent results across your projects.
+
+```typescript
+import {
+  labelHelper,
+  updateNodeBounds,
+  insertPolygonShape,
+  getNodeClasses,
+  createPathFromPoints,
+  generateFullSineWavePoints,
+} from './utils.ts';
+```
+
+## Example Usage
+
+Here’s a basic example of how you might use some of these utilities:
+
+```typescript
+import { labelHelper, insertPolygonShape } from './utils.ts';
+
+const svgContainer = document.getElementById('svgContainer');
+
+// Insert a polygon shape
+insertPolygonShape(svgContainer /* shape-specific parameters */);
+
+// Create and insert a label inside the shape
+labelHelper(svgContainer /* label-specific parameters */);
+```
+
+## Adding New Shapes
+
+### 1. Create the Shape Function
+
+To add a new shape:
+
+- **Create the shape function**: Create a new file of name of the shape and export a function in the `shapes` directory that generates your shape. The file and function should follow the pattern used in existing shapes and return an SVG element.
+
+- **Example**:
+
+  ```typescript
+  import { Node, RenderOptions } from '../../types.ts';
+
+  export const myNewShape = async (
+    parent: SVGAElement,
+    node: Node,
+    renderOptions: RenderOptions
+  ) => {
+    // Create your shape here
+    const shape = parent.insert('g').attr('class', 'my-new-shape');
+    // Add other elements or styles as needed
+    return shape;
+  };
+  ```
+
+### 2. Register the Shape
+
+- **Register the shape**: Add your shape to the `shapes` object in the [main shapes module](../rendering-util/rendering-elements/shapes.ts). This allows your shape to be recognized and used within the system.
+
+- **Example**:
+
+  ```typescript
+  import { myNewShape } from './shapes/myNewShape';
+
+  const shapes = {
+    ...,
+    {
+      semanticName: 'My Shape',
+      name: 'Shape Name',
+      shortName: '',
+      description: '',
+      aliases: ['', '', '', ''],
+      handler: myNewShape,
+    },
+  };
+  ```
+
+# Shape Intersection Algorithms
+
+This contains algorithms and utilities for calculating intersection points for various shapes in SVG. Arrow intersection points are crucial for accurately determining where arrows connect with shapes. Ensuring precise intersection points enhances the clarity and accuracy of flowcharts and diagrams.
+
+## Shape Intersection Functions
+
+### 1. `Ellipse`
+
+Calculates the intersection points for an ellipse.
+
+**Usage**:
+
+```javascript
+import intersectEllipse from './intersect-ellipse.js';
+
+const intersection = intersectEllipse(node, rx, ry, point);
+```
+
+- **Parameters**:
+  - `node`: The SVG node element.
+  - `rx`: The x-radius of the ellipse.
+  - `ry`: The y-radius of the ellipse.
+  - `point`: The point from which the intersection is calculated.
+
+### 2. `intersectRect`
+
+Calculates the intersection points for a rectangle.
+
+**Usage**:
+
+```javascript
+import intersectRect from './intersect-rect.js';
+
+const intersection = intersectRect(node, point);
+```
+
+- **Parameters**:
+  - `node`: The SVG node element.
+  - `point`: The point from which the intersection is calculated.
+
+### 3. `intersectPolygon`
+
+Calculates the intersection points for a polygon.
+
+**Usage**:
+
+```javascript
+import intersectPolygon from './intersect-polygon.js';
+
+const intersection = intersectPolygon(node, polyPoints, point);
+```
+
+- **Parameters**:
+  - `node`: The SVG node element.
+  - `polyPoints`: Array of points defining the polygon.
+  - `point`: The point from which the intersection is calculated.
+
+## Cypress Tests
+
+To ensure the robustness of the flowchart shapes, there are implementation of comprehensive Cypress test cases in `newShapes.spec.ts` file. These tests cover various aspects such as:
+
+- **Shapes**: Testing new shapes like `bowTieRect`, `waveRectangle`, `trapezoidalPentagon`, etc.
+- **Looks**: Verifying shapes under different visual styles (`classic` and `handDrawn`).
+- **Directions**: Ensuring correct rendering in all flow directions of arrows :
+  - `TB` `(Top -> Bottom)`
+  - `BT` `(Bottom -> Top)`
+  - `LR` `(Left -> Right)`
+  - `RL` `(Right -> Left)`
+- **Labels**: Testing shapes with different labels, including:
+  - No labels
+  - Short labels
+  - Very long labels
+  - Markdown with `htmlLabels:true` and `htmlLabels:false`
+- **Styles**: Applying custom styles to shapes and verifying correct rendering.
+- **Class Definitions**: Using `classDef` to apply custom classes and testing their impact.
+
+### Running the Tests
+
+To run the Cypress tests, follow these steps:
+
+1. Ensure you have all dependencies installed by running:
+
+   ```bash
+   pnpm install
+   ```
+
+2. Start the Cypress test runner:
+
+   ```bash
+   cypress open --env updateSnapshots=true
+
+   ```
+
+3. Select the test suite from the Cypress interface to run all the flowchart shape tests.
diff --git a/docs/config/icons.md b/docs/config/icons.md
new file mode 100644
index 000000000..729afa1d5
--- /dev/null
+++ b/docs/config/icons.md
@@ -0,0 +1,55 @@
+> **Warning**
+>
+> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
+>
+> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/icons.md](../../packages/mermaid/src/docs/config/icons.md).
+
+# Registering icon pack in mermaid
+
+The icon packs available can be found at [icones.js.org](https://icones.js.org/).
+We use the name defined when registering the icon pack, to override the prefix field of the iconify pack. This allows the user to use shorter names for the icons. It also allows us to load a particular pack only when it is used in a diagram.
+
+Using JSON file directly from CDN:
+
+```js
+import mermaid from 'CDN/mermaid.esm.mjs';
+mermaid.registerIconPacks([
+  {
+    name: 'logos',
+    loader: () =>
+      fetch('https://unpkg.com/@iconify-json/logos@1/icons.json').then((res) => res.json()),
+  },
+]);
+```
+
+Using packages and a bundler:
+
+```bash
+npm install @iconify-json/logos@1
+```
+
+With lazy loading
+
+```js
+import mermaid from 'mermaid';
+
+mermaid.registerIconPacks([
+  {
+    name: 'logos',
+    loader: () => import('@iconify-json/logos').then((module) => module.icons),
+  },
+]);
+```
+
+Without lazy loading
+
+```js
+import mermaid from 'mermaid';
+import { icons } from '@iconify-json/logos';
+mermaid.registerIconPacks([
+  {
+    name: icons.prefix, // To use the prefix defined in the icon pack
+    icons,
+  },
+]);
+```
diff --git a/docs/config/setup/classes/mermaid.UnknownDiagramError.md b/docs/config/setup/classes/mermaid.UnknownDiagramError.md
index 3e1edf597..a3359c9d0 100644
--- a/docs/config/setup/classes/mermaid.UnknownDiagramError.md
+++ b/docs/config/setup/classes/mermaid.UnknownDiagramError.md
@@ -127,7 +127,7 @@ Error.prepareStackTrace
 
 #### Defined in
 
-node_modules/@types/node/globals.d.ts:28
+node_modules/.pnpm/@types+node\@20.16.11/node_modules/@types/node/globals.d.ts:98
 
 ---
 
@@ -141,7 +141,7 @@ Error.stackTraceLimit
 
 #### Defined in
 
-node_modules/@types/node/globals.d.ts:30
+node_modules/.pnpm/@types+node\@20.16.11/node_modules/@types/node/globals.d.ts:100
 
 ## Methods
 
@@ -168,4 +168,4 @@ Error.captureStackTrace
 
 #### Defined in
 
-node_modules/@types/node/globals.d.ts:21
+node_modules/.pnpm/@types+node\@20.16.11/node_modules/@types/node/globals.d.ts:91
diff --git a/docs/config/setup/interfaces/mermaid.LayoutData.md b/docs/config/setup/interfaces/mermaid.LayoutData.md
index 6f128f4a7..5616e1c9a 100644
--- a/docs/config/setup/interfaces/mermaid.LayoutData.md
+++ b/docs/config/setup/interfaces/mermaid.LayoutData.md
@@ -16,11 +16,11 @@
 
 ### config
 
-• **config**: `MermaidConfig`
+• **config**: [`MermaidConfig`](mermaid.MermaidConfig.md)
 
 #### Defined in
 
-[packages/mermaid/src/rendering-util/types.d.ts:118](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.d.ts#L118)
+[packages/mermaid/src/rendering-util/types.ts:144](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L144)
 
 ---
 
@@ -30,7 +30,7 @@
 
 #### Defined in
 
-[packages/mermaid/src/rendering-util/types.d.ts:117](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.d.ts#L117)
+[packages/mermaid/src/rendering-util/types.ts:143](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L143)
 
 ---
 
@@ -40,4 +40,4 @@
 
 #### Defined in
 
-[packages/mermaid/src/rendering-util/types.d.ts:116](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.d.ts#L116)
+[packages/mermaid/src/rendering-util/types.ts:142](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/rendering-util/types.ts#L142)
diff --git a/docs/config/setup/interfaces/mermaid.MermaidConfig.md b/docs/config/setup/interfaces/mermaid.MermaidConfig.md
index ad078653a..14c348145 100644
--- a/docs/config/setup/interfaces/mermaid.MermaidConfig.md
+++ b/docs/config/setup/interfaces/mermaid.MermaidConfig.md
@@ -49,7 +49,7 @@ This matters if you are using base tag settings.
 
 #### Defined in
 
-[packages/mermaid/src/config.type.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L200)
+[packages/mermaid/src/config.type.ts:201](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L201)
 
 ---
 
@@ -59,7 +59,7 @@ This matters if you are using base tag settings.
 
 #### Defined in
 
-[packages/mermaid/src/config.type.ts:197](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L197)
+[packages/mermaid/src/config.type.ts:198](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L198)
 
 ---
 
@@ -121,7 +121,7 @@ should not change unless content is changed.
 
 #### Defined in
 
-[packages/mermaid/src/config.type.ts:201](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L201)
+[packages/mermaid/src/config.type.ts:202](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L202)
 
 ---
 
@@ -183,7 +183,7 @@ See 
 
 #### Defined in
 
-[packages/mermaid/src/config.type.ts:203](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L203)
+[packages/mermaid/src/config.type.ts:204](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L204)
 
 ---
 
@@ -217,7 +217,7 @@ If set to true, ignores legacyMathML.
 
 #### Defined in
 
-[packages/mermaid/src/config.type.ts:196](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L196)
+[packages/mermaid/src/config.type.ts:197](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L197)
 
 ---
 
@@ -253,6 +253,16 @@ Defines the seed to be used when using handDrawn look. This is important for the
 
 ---
 
+### kanban
+
+• `Optional` **kanban**: `KanbanDiagramConfig`
+
+#### Defined in
+
+[packages/mermaid/src/config.type.ts:196](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L196)
+
+---
+
 ### layout
 
 • `Optional` **layout**: `string`
@@ -310,7 +320,7 @@ Defines which main look to use for the diagram.
 
 #### Defined in
 
-[packages/mermaid/src/config.type.ts:204](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L204)
+[packages/mermaid/src/config.type.ts:205](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L205)
 
 ---
 
@@ -354,7 +364,7 @@ The maximum allowed size of the users text diagram
 
 #### Defined in
 
-[packages/mermaid/src/config.type.ts:199](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L199)
+[packages/mermaid/src/config.type.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L200)
 
 ---
 
@@ -394,7 +404,7 @@ The maximum allowed size of the users text diagram
 
 #### Defined in
 
-[packages/mermaid/src/config.type.ts:198](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L198)
+[packages/mermaid/src/config.type.ts:199](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L199)
 
 ---
 
@@ -465,7 +475,7 @@ This is useful when you want to control how to handle syntax errors in your appl
 
 #### Defined in
 
-[packages/mermaid/src/config.type.ts:210](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L210)
+[packages/mermaid/src/config.type.ts:211](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L211)
 
 ---
 
@@ -518,7 +528,7 @@ You may also use `themeCSS` to override this value.
 
 #### Defined in
 
-[packages/mermaid/src/config.type.ts:202](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L202)
+[packages/mermaid/src/config.type.ts:203](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L203)
 
 ---
 
diff --git a/docs/config/setup/interfaces/mermaid.ParseOptions.md b/docs/config/setup/interfaces/mermaid.ParseOptions.md
index 2b8084209..717e35565 100644
--- a/docs/config/setup/interfaces/mermaid.ParseOptions.md
+++ b/docs/config/setup/interfaces/mermaid.ParseOptions.md
@@ -19,4 +19,4 @@ The `parseError` function will not be called.
 
 #### Defined in
 
-[packages/mermaid/src/types.ts:43](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L43)
+[packages/mermaid/src/types.ts:59](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L59)
diff --git a/docs/config/setup/interfaces/mermaid.ParseResult.md b/docs/config/setup/interfaces/mermaid.ParseResult.md
index 42f8ea8ba..9f90b6dd4 100644
--- a/docs/config/setup/interfaces/mermaid.ParseResult.md
+++ b/docs/config/setup/interfaces/mermaid.ParseResult.md
@@ -10,6 +10,18 @@
 
 ## Properties
 
+### config
+
+• **config**: [`MermaidConfig`](mermaid.MermaidConfig.md)
+
+The config passed as YAML frontmatter or directives
+
+#### Defined in
+
+[packages/mermaid/src/types.ts:70](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L70)
+
+---
+
 ### diagramType
 
 • **diagramType**: `string`
@@ -18,4 +30,4 @@ The diagram type, e.g. 'flowchart', 'sequence', etc.
 
 #### Defined in
 
-[packages/mermaid/src/types.ts:50](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L50)
+[packages/mermaid/src/types.ts:66](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L66)
diff --git a/docs/config/setup/interfaces/mermaid.RenderResult.md b/docs/config/setup/interfaces/mermaid.RenderResult.md
index f2b5c7872..f882b7af4 100644
--- a/docs/config/setup/interfaces/mermaid.RenderResult.md
+++ b/docs/config/setup/interfaces/mermaid.RenderResult.md
@@ -39,7 +39,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
 
 #### Defined in
 
-[packages/mermaid/src/types.ts:73](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L73)
+[packages/mermaid/src/types.ts:98](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L98)
 
 ---
 
@@ -51,7 +51,7 @@ The diagram type, e.g. 'flowchart', 'sequence', etc.
 
 #### Defined in
 
-[packages/mermaid/src/types.ts:63](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L63)
+[packages/mermaid/src/types.ts:88](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L88)
 
 ---
 
@@ -63,4 +63,4 @@ The svg code for the rendered graph.
 
 #### Defined in
 
-[packages/mermaid/src/types.ts:59](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L59)
+[packages/mermaid/src/types.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L84)
diff --git a/docs/config/setup/modules/defaultConfig.md b/docs/config/setup/modules/defaultConfig.md
index 0a3e15855..b4cf55dd1 100644
--- a/docs/config/setup/modules/defaultConfig.md
+++ b/docs/config/setup/modules/defaultConfig.md
@@ -14,7 +14,7 @@
 
 #### Defined in
 
-[packages/mermaid/src/defaultConfig.ts:266](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L266)
+[packages/mermaid/src/defaultConfig.ts:270](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L270)
 
 ---
 
diff --git a/docs/ecosystem/integrations-community.md b/docs/ecosystem/integrations-community.md
index ef51b423c..71b02cd93 100644
--- a/docs/ecosystem/integrations-community.md
+++ b/docs/ecosystem/integrations-community.md
@@ -64,7 +64,7 @@ To add an integration to this list, see the [Integrations - create page](./integ
 - [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅
 - [Mermerd](https://github.com/KarnerTh/mermerd)
 - [Slab](https://slab.com) ✅
-- [Swimm](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-) ✅
+- [Swimm](https://docs.swimm.io/features/diagrams-and-charts) ✅
 - [NotesHub](https://noteshub.app) ✅
 - [Notion](https://notion.so) ✅
 - [Observable](https://observablehq.com/@observablehq/mermaid) ✅
@@ -200,15 +200,22 @@ Communication tools and platforms
 - [Vim](https://www.vim.org)
   - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram)
   - [Official Vim Syntax and ft plugin](https://github.com/craigmac/vim-mermaid)
+- [Zed](https://zed.dev)
+  - [zed-mermaid](https://github.com/gabeidx/zed-mermaid)
 
 ### Document Generation
 
+- [Astro](https://astro.build/)
+  - [Adding diagrams to your Astro site with MermaidJS and Playwright](https://agramont.net/blog/diagraming-with-mermaidjs-astro/)
 - [Codedoc](https://codedoc.cc/)
   - [codedoc-mermaid-plugin](https://www.npmjs.com/package/codedoc-mermaid-plugin)
 - [Docsy Hugo Theme](https://www.docsy.dev/docs/adding-content/lookandfeel/#diagrams-with-mermaid) ✅
 - [Docusaurus](https://docusaurus.io/docs/markdown-features/diagrams) ✅
 - [Gatsby](https://www.gatsbyjs.com/)
   - [gatsby-remark-mermaid](https://github.com/remcohaszing/gatsby-remark-mermaid)
+- [Jekyll](https://jekyllrb.com/)
+  - [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid)
+  - [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams)
 - [JSDoc](https://jsdoc.app/)
   - [jsdoc-mermaid](https://github.com/Jellyvision/jsdoc-mermaid)
 - [Madness](https://madness.dannyb.co/)
@@ -217,7 +224,7 @@ Communication tools and platforms
 - [MkDocs](https://www.mkdocs.org)
   - [mkdocs-mermaid2-plugin](https://github.com/fralau/mkdocs-mermaid2-plugin)
   - [mkdocs-material](https://github.com/squidfunk/mkdocs-material), check the [docs](https://squidfunk.github.io/mkdocs-material/reference/diagrams/)
-  - [Quarto](https://quarto.org/)
+- [Quarto](https://quarto.org/) ✅
 - [rehype](https://github.com/rehypejs/rehype)
   - [rehype-mermaid](https://github.com/remcohaszing/rehype-mermaid)
 - [remark](https://remark.js.org/)
@@ -246,17 +253,12 @@ Communication tools and platforms
 
 ### Other
 
-- [Astro](https://astro.build/)
-  - [Adding diagrams to your Astro site with MermaidJS and Playwright](https://agramont.net/blog/diagraming-with-mermaidjs-astro/)
 - [Bisheng](https://www.npmjs.com/package/bisheng)
   - [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
 - [Blazorade Mermaid: Render Mermaid diagrams in Blazor applications](https://github.com/Blazorade/Blazorade-Mermaid/wiki)
 - [Codemia: A tool to practice system design problems](https://codemia.io) ✅
 - [ExDoc](https://github.com/elixir-lang/ex_doc)
   - [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs)
-- [Jekyll](https://jekyllrb.com/)
-  - [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid)
-  - [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams)
 - [MarkChart: Preview Mermaid diagrams on macOS](https://markchart.app/)
 - [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
 - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
diff --git a/docs/ecosystem/mermaid-chart.md b/docs/ecosystem/mermaid-chart.md
index 9b3440a0a..1348219c1 100644
--- a/docs/ecosystem/mermaid-chart.md
+++ b/docs/ecosystem/mermaid-chart.md
@@ -22,17 +22,20 @@ Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an accoun
 
 - **Editor** - A web based editor for creating and editing Mermaid diagrams.
 
-- **Visual Editor** - The Visual Editor enables users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options.
+- **Mermaid AI** - Use our embedded AI Chat to generate diagrams from natural language descriptions.
 
-- **AI Chat** - Use our embedded AI Chat to generate diagrams from natural language descriptions.
+- **Whiteboard** - A virtual whiteboard for creating and editing Mermaid diagrams.
 
 - **Plugins** - A plugin system for extending the functionality of Mermaid.
 
   Official Mermaid Chart plugins:
 
   - [Mermaid Chart GPT](https://chat.openai.com/g/g-1IRFKwq4G-mermaid-chart)
+  - [Confluence](https://marketplace.atlassian.com/apps/1234056/mermaid-chart-for-confluence?hosting=cloud&tab=overview)
+  - [Jira](https://marketplace.atlassian.com/apps/1234810/mermaid-chart-for-jira?tab=overview&hosting=cloud)
   - [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MermaidChart.vscode-mermaid-chart)
   - [JetBrains IDE](https://plugins.jetbrains.com/plugin/23043-mermaid-chart)
+  - [Google Docs](https://gsuite.google.com/marketplace/app/mermaidchart/947683068472)
   - [Microsoft PowerPoint and Word](https://appsource.microsoft.com/en-us/product/office/WA200006214?tab=Overview)
 
   Visit our [Plugins](https://www.mermaidchart.com/plugins) page for more information.
diff --git a/docs/intro/syntax-reference.md b/docs/intro/syntax-reference.md
index f736840e6..b671aa390 100644
--- a/docs/intro/syntax-reference.md
+++ b/docs/intro/syntax-reference.md
@@ -94,10 +94,8 @@ Mermaid offers a variety of styles or “looks” for your diagrams, allowing yo
 
 **Available Looks:**
 
-```
-•	Hand-Drawn Look: For a more personal, creative touch, the hand-drawn look brings a sketch-like quality to your diagrams. This style is perfect for informal settings or when you want to add a bit of personality to your diagrams.
-•	Classic Look: If you prefer the traditional Mermaid style, the classic look maintains the original appearance that many users are familiar with. It’s great for consistency across projects or when you want to keep the familiar aesthetic.
-```
+- Hand-Drawn Look: For a more personal, creative touch, the hand-drawn look brings a sketch-like quality to your diagrams. This style is perfect for informal settings or when you want to add a bit of personality to your diagrams.
+- Classic Look: If you prefer the traditional Mermaid style, the classic look maintains the original appearance that many users are familiar with. It’s great for consistency across projects or when you want to keep the familiar aesthetic.
 
 **How to Select a Look:**
 
@@ -133,10 +131,8 @@ In addition to customizing the look of your diagrams, Mermaid Chart now allows y
 
 #### Supported Layout Algorithms:
 
-```
-•	Dagre (default): This is the classic layout algorithm that has been used in Mermaid for a long time. It provides a good balance of simplicity and visual clarity, making it ideal for most diagrams.
-•	ELK: For those who need more sophisticated layout capabilities, especially when working with large or intricate diagrams, the ELK (Eclipse Layout Kernel) layout offers advanced options. It provides a more optimized arrangement, potentially reducing overlapping and improving readability. This is not included out the box but needs to be added when integrating mermaid for sites/applications that want to have elk support.
-```
+- Dagre (default): This is the classic layout algorithm that has been used in Mermaid for a long time. It provides a good balance of simplicity and visual clarity, making it ideal for most diagrams.
+- ELK: For those who need more sophisticated layout capabilities, especially when working with large or intricate diagrams, the ELK (Eclipse Layout Kernel) layout offers advanced options. It provides a more optimized arrangement, potentially reducing overlapping and improving readability. This is not included out the box but needs to be added when integrating mermaid for sites/applications that want to have elk support.
 
 #### How to Select a Layout Algorithm:
 
diff --git a/docs/news/blog.md b/docs/news/blog.md
index 4d33f67f5..70a31e5c0 100644
--- a/docs/news/blog.md
+++ b/docs/news/blog.md
@@ -6,6 +6,24 @@
 
 # Blog
 
+## [Mermaid 11.4 is out: New Features and Kanban Diagramming](https://www.mermaidchart.com/blog/posts/mermaid-11-4-is-out-new-features-and-kanban-diagramming)
+
+Mermaid 11.4 brings enhanced functionality with the introduction of Kanban diagrams, allowing users to create visual workflows with status columns and task details.
+
+October 31, 2024 · 2 mins
+
+## [How To Build an ER Diagram with Mermaid Chart](https://www.mermaidchart.com/blog/posts/how-to-build-an-er-diagram-with-mermaid-chart)
+
+An entity relationship (ER) diagram acts like a blueprint for your database. This makes ER diagrams effective tools for anyone dealing with complex databases, data modeling, and AI model training.
+
+October 24, 2024 · 4 mins
+
+## [Expanding the Horizons of Mermaid Flowcharts: Introducing 30 New Shapes!](https://www.mermaidchart.com/blog/posts/new-mermaid-flowchart-shapes/)
+
+24 September 2024 · 5 mins
+
+Discover 30 new shapes in Mermaid flowcharts, offering enhanced clarity, customization, and versatility for more dynamic and expressive visualizations.
+
 ## [Introducing Architecture Diagrams in Mermaid](https://www.mermaidchart.com/blog/posts/mermaid-supports-architecture-diagrams/)
 
 2 September 2024 · 2 mins
diff --git a/docs/syntax/architecture.md b/docs/syntax/architecture.md
index 12a7cf409..f0f0e9ac7 100644
--- a/docs/syntax/architecture.md
+++ b/docs/syntax/architecture.md
@@ -79,15 +79,15 @@ service {service id}({icon name})[{title}] (in {parent id})?
 Put together:
 
 ```
-service database(db)[Database]
+service database1(database)[My Database]
 ```
 
-creates the service identified as `database`, using the icon `db`, with the label `Database`.
+creates the service identified as `database1`, using the icon `database`, with the label `My Database`.
 
 If the service belongs to a group, it can be placed inside it through the optional `in` keyword
 
 ```
-service database(db)[Database] in private_api
+service database1(database)[My Database] in private_api
 ```
 
 ### Edges
@@ -194,55 +194,7 @@ architecture-beta
 ## Icons
 
 By default, architecture diagram supports the following icons: `cloud`, `database`, `disk`, `internet`, `server`.
-Users can use any of the 200,000+ icons available in iconify.design, or add their own custom icons, by following the steps below.
-
-The icon packs available can be found at [icones.js.org](https://icones.js.org/).
-We use the name defined when registering the icon pack, to override the prefix field of the iconify pack. This allows the user to use shorter names for the icons. It also allows us to load a particular pack only when it is used in a diagram.
-
-Using JSON file directly from CDN:
-
-```js
-import mermaid from 'CDN/mermaid.esm.mjs';
-mermaid.registerIconPacks([
-  {
-    name: 'logos',
-    loader: () =>
-      fetch('https://unpkg.com/@iconify-json/logos/icons.json').then((res) => res.json()),
-  },
-]);
-```
-
-Using packages and a bundler:
-
-```bash
-npm install @iconify-json/logos
-```
-
-With lazy loading
-
-```js
-import mermaid from 'mermaid';
-
-mermaid.registerIconPacks([
-  {
-    name: 'logos',
-    loader: () => import('@iconify-json/logos').then((module) => module.icons),
-  },
-]);
-```
-
-Without lazy loading
-
-```js
-import mermaid from 'mermaid';
-import { icons } from '@iconify-json/logos';
-mermaid.registerIconPacks([
-  {
-    name: icons.prefix, // To use the prefix defined in the icon pack
-    icons,
-  },
-]);
-```
+Users can use any of the 200,000+ icons available in iconify.design, or add their own custom icons, by following the steps [here](../config/icons.md).
 
 After the icons are installed, they can be used in the architecture diagram by using the format "name:icon-name", where name is the value used when registering the icon pack.
 
diff --git a/docs/syntax/block.md b/docs/syntax/block.md
index df367fab1..7048ef352 100644
--- a/docs/syntax/block.md
+++ b/docs/syntax/block.md
@@ -141,7 +141,7 @@ block-beta
   a["A label"] b:2 c:2 d
 ```
 
-In this example, the block labeled "A wide one" spans two columns, while blocks 'b', 'c', and 'd' are allocated their own columns. This flexibility in block sizing is crucial for accurately representing systems with components of varying significance or size.
+In this example, the block labeled "A labels" spans one column, while blocks 'b', 'c' span 2 columns, and 'd' is again allocated its own column. This flexibility in block sizing is crucial for accurately representing systems with components of varying significance or size.
 
 ### Creating Composite Blocks
 
@@ -211,6 +211,27 @@ block-beta
 
 This example demonstrates how Mermaid dynamically adjusts the width of the columns to accommodate the widest block, in this case, 'a' and the composite block 'e'. This dynamic adjustment is essential for creating visually balanced and easy-to-understand diagrams.
 
+**Merging Blocks Horizontally:**
+In scenarios where you need to stack blocks horizontally, you can use column width to accomplish the task. Blocks can be arranged vertically by putting them in a single column. Here is how you can create a block diagram in which 4 blocks are stacked on top of each other:
+
+```mermaid-example
+block-beta
+  block
+    columns 1
+    a["A label"] b c d
+  end
+```
+
+```mermaid
+block-beta
+  block
+    columns 1
+    a["A label"] b c d
+  end
+```
+
+In this example, the width of the merged block dynamically adjusts to the width of the largest child block.
+
 With these advanced configuration options, Mermaid's block diagrams can be tailored to represent a wide array of complex systems and structures. The flexibility offered by these features enables users to create diagrams that are both informative and visually appealing. In the following sections, we will explore further capabilities, including different block shapes and linking options.
 
 ## 4. Block Varieties and Shapes
diff --git a/docs/syntax/classDiagram.md b/docs/syntax/classDiagram.md
index ed15922f1..746d0eba6 100644
--- a/docs/syntax/classDiagram.md
+++ b/docs/syntax/classDiagram.md
@@ -427,6 +427,51 @@ And `Link` can be one of:
 | --   | Solid       |
 | ..   | Dashed      |
 
+### Lollipop Interfaces
+
+Classes can also be given a special relation type that defines a lollipop interface on the class. A lollipop interface is defined using the following syntax:
+
+- `bar ()-- foo`
+- `foo --() bar`
+
+The interface (bar) with the lollipop connects to the class (foo).
+
+Note: Each interface that is defined is unique and is meant to not be shared between classes / have multiple edges connecting to it.
+
+```mermaid-example
+classDiagram
+  bar ()-- foo
+```
+
+```mermaid
+classDiagram
+  bar ()-- foo
+```
+
+```mermaid-example
+classDiagram
+  class Class01 {
+    int amount
+    draw()
+  }
+  Class01 --() bar
+  Class02 --() bar
+
+  foo ()-- Class01
+```
+
+```mermaid
+classDiagram
+  class Class01 {
+    int amount
+    draw()
+  }
+  Class01 --() bar
+  Class02 --() bar
+
+  foo ()-- Class01
+```
+
 ## Define Namespace
 
 A namespace groups classes.
@@ -776,10 +821,12 @@ Beginner's tip—a full example using interactive links in an HTML page:
 
 ## Styling
 
-### Styling a node (v10.7.0+)
+### Styling a node
 
 It is possible to apply specific styles such as a thicker border or a different background color to an individual node using the `style` keyword.
 
+Note that notes and namespaces cannot be styled individually but do support themes.
+
 ```mermaid-example
 classDiagram
   class Animal
@@ -799,11 +846,102 @@ classDiagram
 #### Classes
 
 More convenient than defining the style every time is to define a class of styles and attach this class to the nodes that
-should have a different look. This is done by predefining classes in css styles that can be applied from the graph definition using the `cssClass` statement or the `:::` short hand.
+should have a different look.
+
+A class definition looks like the example below:
+
+```
+classDef className fill:#f9f,stroke:#333,stroke-width:4px;
+```
+
+Also, it is possible to define style to multiple classes in one statement:
+
+```
+classDef firstClassName,secondClassName font-size:12pt;
+```
+
+Attachment of a class to a node is done as per below:
+
+```
+cssClass "nodeId1" className;
+```
+
+It is also possible to attach a class to a list of nodes in one statement:
+
+```
+cssClass "nodeId1,nodeId2" className;
+```
+
+A shorter form of adding a class is to attach the classname to the node using the `:::` operator:
+
+```mermaid-example
+classDiagram
+    class Animal:::someclass
+    classDef someclass fill:#f96
+```
+
+```mermaid
+classDiagram
+    class Animal:::someclass
+    classDef someclass fill:#f96
+```
+
+Or:
+
+```mermaid-example
+classDiagram
+    class Animal:::someclass {
+        -int sizeInFeet
+        -canEat()
+    }
+    classDef someclass fill:#f96
+```
+
+```mermaid
+classDiagram
+    class Animal:::someclass {
+        -int sizeInFeet
+        -canEat()
+    }
+    classDef someclass fill:#f96
+```
+
+### Default class
+
+If a class is named default it will be applied to all nodes. Specific styles and classes should be defined afterwards to override the applied default styling.
+
+```
+classDef default fill:#f9f,stroke:#333,stroke-width:4px;
+```
+
+```mermaid-example
+classDiagram
+  class Animal:::pink
+  class Mineral
+
+  classDef default fill:#f96,color:red
+  classDef pink color:#f9f
+```
+
+```mermaid
+classDiagram
+  class Animal:::pink
+  class Mineral
+
+  classDef default fill:#f96,color:red
+  classDef pink color:#f9f
+```
+
+### CSS Classes
+
+It is also possible to predefine classes in CSS styles that can be applied from the graph definition as in the example
+below:
+
+**Example style**
 
 ```html
 
 ```
 
-Then attaching that class to a specific node:
-
-```
-    cssClass "nodeId1" styleClass;
-```
-
-It is also possible to attach a class to a list of nodes in one statement:
-
-```
-    cssClass "nodeId1,nodeId2" styleClass;
-```
-
-A shorter form of adding a class is to attach the classname to the node using the `:::` operator:
+**Example definition**
 
 ```mermaid-example
 classDiagram
@@ -835,136 +961,32 @@ classDiagram
     class Animal:::styleClass
 ```
 
-Or:
-
-```mermaid-example
-classDiagram
-    class Animal:::styleClass {
-        -int sizeInFeet
-        -canEat()
-    }
-```
-
-```mermaid
-classDiagram
-    class Animal:::styleClass {
-        -int sizeInFeet
-        -canEat()
-    }
-```
-
-?> cssClasses cannot be added using this shorthand method at the same time as a relation statement.
-
-?> Due to limitations with existing markup for class diagrams, it is not currently possible to define css classes within the diagram itself. **_Coming soon!_**
-
-### Default Styles
-
-The main styling of the class diagram is done with a preset number of css classes. During rendering these classes are extracted from the file located at src/themes/class.scss. The classes used here are described below:
-
-| Class              | Description                                                       |
-| ------------------ | ----------------------------------------------------------------- |
-| g.classGroup text  | Styles for general class text                                     |
-| classGroup .title  | Styles for general class title                                    |
-| g.classGroup rect  | Styles for class diagram rectangle                                |
-| g.classGroup line  | Styles for class diagram line                                     |
-| .classLabel .box   | Styles for class label box                                        |
-| .classLabel .label | Styles for class label text                                       |
-| composition        | Styles for composition arrow head and arrow line                  |
-| aggregation        | Styles for aggregation arrow head and arrow line(dashed or solid) |
-| dependency         | Styles for dependency arrow head and arrow line                   |
-
-#### Sample stylesheet
-
-```scss
-body {
-  background: white;
-}
-
-g.classGroup text {
-  fill: $nodeBorder;
-  stroke: none;
-  font-family: 'trebuchet ms', verdana, arial;
-  font-family: var(--mermaid-font-family);
-  font-size: 10px;
-
-  .title {
-    font-weight: bolder;
-  }
-}
-
-g.classGroup rect {
-  fill: $nodeBkg;
-  stroke: $nodeBorder;
-}
-
-g.classGroup line {
-  stroke: $nodeBorder;
-  stroke-width: 1;
-}
-
-.classLabel .box {
-  stroke: none;
-  stroke-width: 0;
-  fill: $nodeBkg;
-  opacity: 0.5;
-}
-
-.classLabel .label {
-  fill: $nodeBorder;
-  font-size: 10px;
-}
-
-.relation {
-  stroke: $nodeBorder;
-  stroke-width: 1;
-  fill: none;
-}
-
-@mixin composition {
-  fill: $nodeBorder;
-  stroke: $nodeBorder;
-  stroke-width: 1;
-}
-
-#compositionStart {
-  @include composition;
-}
-
-#compositionEnd {
-  @include composition;
-}
-
-@mixin aggregation {
-  fill: $nodeBkg;
-  stroke: $nodeBorder;
-  stroke-width: 1;
-}
-
-#aggregationStart {
-  @include aggregation;
-}
-
-#aggregationEnd {
-  @include aggregation;
-}
-
-#dependencyStart {
-  @include composition;
-}
-
-#dependencyEnd {
-  @include composition;
-}
-
-#extensionStart {
-  @include composition;
-}
-
-#extensionEnd {
-  @include composition;
-}
-```
+> cssClasses cannot be added using this shorthand method at the same time as a relation statement.
 
 ## Configuration
 
-`Coming soon!`
+### Members Box
+
+It is possible to hide the empty members box of a class node.
+
+This is done by changing the **hideEmptyMembersBox** value of the class diagram configuration. For more information on how to edit the Mermaid configuration see the [configuration page.](https://mermaid.js.org/config/configuration.html)
+
+```mermaid-example
+---
+  config:
+    class:
+      hideEmptyMembersBox: true
+---
+classDiagram
+  class Duck
+```
+
+```mermaid
+---
+  config:
+    class:
+      hideEmptyMembersBox: true
+---
+classDiagram
+  class Duck
+```
diff --git a/docs/syntax/flowchart.md b/docs/syntax/flowchart.md
index 7efc5497b..3837e77de 100644
--- a/docs/syntax/flowchart.md
+++ b/docs/syntax/flowchart.md
@@ -298,6 +298,694 @@ flowchart TD
     id1(((This is the text in the circle)))
 ```
 
+## Expanded Node Shapes in Mermaid Flowcharts (v11.3.0+)
+
+Mermaid introduces 30 new shapes to enhance the flexibility and precision of flowchart creation. These new shapes provide more options to represent processes, decisions, events, data storage visually, and other elements within your flowcharts, improving clarity and semantic meaning.
+
+New Syntax for Shape Definition
+
+Mermaid now supports a general syntax for defining shape types to accommodate the growing number of shapes. This syntax allows you to assign specific shapes to nodes using a clear and flexible format:
+
+```
+A@{ shape: rect }
+```
+
+This syntax creates a node A as a rectangle. It renders in the same way as `A["A"]`, or `A`.
+
+### Complete List of New Shapes
+
+Below is a comprehensive list of the newly introduced shapes and their corresponding semantic meanings, short names, and aliases:
+
+| **Semantic Name**                 | **Shape Name**         | **Short Name** | **Description**                | **Alias Supported**                                              |
+| --------------------------------- | ---------------------- | -------------- | ------------------------------ | ---------------------------------------------------------------- |
+| Card                              | Notched Rectangle      | `notch-rect`   | Represents a card              | `card`, `notched-rectangle`                                      |
+| Collate                           | Hourglass              | `hourglass`    | Represents a collate operation | `collate`, `hourglass`                                           |
+| Com Link                          | Lightning Bolt         | `bolt`         | Communication link             | `com-link`, `lightning-bolt`                                     |
+| Comment                           | Curly Brace            | `brace`        | Adds a comment                 | `brace-l`, `comment`                                             |
+| Comment Right                     | Curly Brace            | `brace-r`      | Adds a comment                 |                                                                  |
+| Comment with braces on both sides | Curly Braces           | `braces`       | Adds a comment                 |                                                                  |
+| Data Input/Output                 | Lean Right             | `lean-r`       | Represents input or output     | `in-out`, `lean-right`                                           |
+| Data Input/Output                 | Lean Left              | `lean-l`       | Represents output or input     | `lean-left`, `out-in`                                            |
+| Database                          | Cylinder               | `cyl`          | Database storage               | `cylinder`, `database`, `db`                                     |
+| Decision                          | Diamond                | `diam`         | Decision-making step           | `decision`, `diamond`, `question`                                |
+| Delay                             | Half-Rounded Rectangle | `delay`        | Represents a delay             | `half-rounded-rectangle`                                         |
+| Direct Access Storage             | Horizontal Cylinder    | `h-cyl`        | Direct access storage          | `das`, `horizontal-cylinder`                                     |
+| Disk Storage                      | Lined Cylinder         | `lin-cyl`      | Disk storage                   | `disk`, `lined-cylinder`                                         |
+| Display                           | Curved Trapezoid       | `curv-trap`    | Represents a display           | `curved-trapezoid`, `display`                                    |
+| Divided Process                   | Divided Rectangle      | `div-rect`     | Divided process shape          | `div-proc`, `divided-process`, `divided-rectangle`               |
+| Document                          | Document               | `doc`          | Represents a document          | `doc`, `document`                                                |
+| Event                             | Rounded Rectangle      | `rounded`      | Represents an event            | `event`                                                          |
+| Extract                           | Triangle               | `tri`          | Extraction process             | `extract`, `triangle`                                            |
+| Fork/Join                         | Filled Rectangle       | `fork`         | Fork or join in process flow   | `join`                                                           |
+| Internal Storage                  | Window Pane            | `win-pane`     | Internal storage               | `internal-storage`, `window-pane`                                |
+| Junction                          | Filled Circle          | `f-circ`       | Junction point                 | `filled-circle`, `junction`                                      |
+| Lined Document                    | Lined Document         | `lin-doc`      | Lined document                 | `lined-document`                                                 |
+| Lined/Shaded Process              | Lined Rectangle        | `lin-rect`     | Lined process shape            | `lin-proc`, `lined-process`, `lined-rectangle`, `shaded-process` |
+| Loop Limit                        | Trapezoidal Pentagon   | `notch-pent`   | Loop limit step                | `loop-limit`, `notched-pentagon`                                 |
+| Manual File                       | Flipped Triangle       | `flip-tri`     | Manual file operation          | `flipped-triangle`, `manual-file`                                |
+| Manual Input                      | Sloped Rectangle       | `sl-rect`      | Manual input step              | `manual-input`, `sloped-rectangle`                               |
+| Manual Operation                  | Trapezoid Base Top     | `trap-t`       | Represents a manual task       | `inv-trapezoid`, `manual`, `trapezoid-top`                       |
+| Multi-Document                    | Stacked Document       | `docs`         | Multiple documents             | `documents`, `st-doc`, `stacked-document`                        |
+| Multi-Process                     | Stacked Rectangle      | `st-rect`      | Multiple processes             | `processes`, `procs`, `stacked-rectangle`                        |
+| Odd                               | Odd                    | `odd`          | Odd shape                      |                                                                  |
+| Paper Tape                        | Flag                   | `flag`         | Paper tape                     | `paper-tape`                                                     |
+| Prepare Conditional               | Hexagon                | `hex`          | Preparation or condition step  | `hexagon`, `prepare`                                             |
+| Priority Action                   | Trapezoid Base Bottom  | `trap-b`       | Priority action                | `priority`, `trapezoid`, `trapezoid-bottom`                      |
+| Process                           | Rectangle              | `rect`         | Standard process shape         | `proc`, `process`, `rectangle`                                   |
+| Start                             | Circle                 | `circle`       | Starting point                 | `circ`                                                           |
+| Start                             | Small Circle           | `sm-circ`      | Small starting point           | `small-circle`, `start`                                          |
+| Stop                              | Double Circle          | `dbl-circ`     | Represents a stop point        | `double-circle`                                                  |
+| Stop                              | Framed Circle          | `fr-circ`      | Stop point                     | `framed-circle`, `stop`                                          |
+| Stored Data                       | Bow Tie Rectangle      | `bow-rect`     | Stored data                    | `bow-tie-rectangle`, `stored-data`                               |
+| Subprocess                        | Framed Rectangle       | `fr-rect`      | Subprocess                     | `framed-rectangle`, `subproc`, `subprocess`, `subroutine`        |
+| Summary                           | Crossed Circle         | `cross-circ`   | Summary                        | `crossed-circle`, `summary`                                      |
+| Tagged Document                   | Tagged Document        | `tag-doc`      | Tagged document                | `tag-doc`, `tagged-document`                                     |
+| Tagged Process                    | Tagged Rectangle       | `tag-rect`     | Tagged process                 | `tag-proc`, `tagged-process`, `tagged-rectangle`                 |
+| Terminal Point                    | Stadium                | `stadium`      | Terminal point                 | `pill`, `terminal`                                               |
+| Text Block                        | Text Block             | `text`         | Text block                     |                                                                  |
+
+### Example Flowchart with New Shapes
+
+Here’s an example flowchart that utilizes some of the newly introduced shapes:
+
+```mermaid-example
+flowchart RL
+    A@{ shape: manual-file, label: "File Handling"}
+    B@{ shape: manual-input, label: "User Input"}
+    C@{ shape: docs, label: "Multiple Documents"}
+    D@{ shape: procs, label: "Process Automation"}
+    E@{ shape: paper-tape, label: "Paper Records"}
+```
+
+```mermaid
+flowchart RL
+    A@{ shape: manual-file, label: "File Handling"}
+    B@{ shape: manual-input, label: "User Input"}
+    C@{ shape: docs, label: "Multiple Documents"}
+    D@{ shape: procs, label: "Process Automation"}
+    E@{ shape: paper-tape, label: "Paper Records"}
+```
+
+### Process
+
+```mermaid-example
+flowchart TD
+    A@{ shape: rect, label: "This is a process" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: rect, label: "This is a process" }
+```
+
+### Event
+
+```mermaid-example
+flowchart TD
+    A@{ shape: rounded, label: "This is an event" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: rounded, label: "This is an event" }
+```
+
+### Terminal Point (Stadium)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: stadium, label: "Terminal point" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: stadium, label: "Terminal point" }
+```
+
+### Subprocess
+
+```mermaid-example
+flowchart TD
+    A@{ shape: subproc, label: "This is a subprocess" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: subproc, label: "This is a subprocess" }
+```
+
+### Database (Cylinder)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: cyl, label: "Database" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: cyl, label: "Database" }
+```
+
+### Start (Circle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: circle, label: "Start" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: circle, label: "Start" }
+```
+
+### Odd
+
+```mermaid-example
+flowchart TD
+    A@{ shape: odd, label: "Odd shape" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: odd, label: "Odd shape" }
+```
+
+### Decision (Diamond)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: diamond, label: "Decision" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: diamond, label: "Decision" }
+```
+
+### Prepare Conditional (Hexagon)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: hex, label: "Prepare conditional" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: hex, label: "Prepare conditional" }
+```
+
+### Data Input/Output (Lean Right)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: lean-r, label: "Input/Output" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: lean-r, label: "Input/Output" }
+```
+
+### Data Input/Output (Lean Left)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: lean-l, label: "Output/Input" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: lean-l, label: "Output/Input" }
+```
+
+### Priority Action (Trapezoid Base Bottom)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: trap-b, label: "Priority action" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: trap-b, label: "Priority action" }
+```
+
+### Manual Operation (Trapezoid Base Top)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: trap-t, label: "Manual operation" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: trap-t, label: "Manual operation" }
+```
+
+### Stop (Double Circle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: dbl-circ, label: "Stop" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: dbl-circ, label: "Stop" }
+```
+
+### Text Block
+
+```mermaid-example
+flowchart TD
+    A@{ shape: text, label: "This is a text block" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: text, label: "This is a text block" }
+```
+
+### Card (Notched Rectangle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: notch-rect, label: "Card" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: notch-rect, label: "Card" }
+```
+
+### Lined/Shaded Process
+
+```mermaid-example
+flowchart TD
+    A@{ shape: lin-rect, label: "Lined process" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: lin-rect, label: "Lined process" }
+```
+
+### Start (Small Circle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: sm-circ, label: "Small start" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: sm-circ, label: "Small start" }
+```
+
+### Stop (Framed Circle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: framed-circle, label: "Stop" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: framed-circle, label: "Stop" }
+```
+
+### Fork/Join (Long Rectangle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: fork, label: "Fork or Join" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: fork, label: "Fork or Join" }
+```
+
+### Collate (Hourglass)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: hourglass, label: "Collate" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: hourglass, label: "Collate" }
+```
+
+### Comment (Curly Brace)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: comment, label: "Comment" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: comment, label: "Comment" }
+```
+
+### Comment Right (Curly Brace Right)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: brace-r, label: "Comment" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: brace-r, label: "Comment" }
+```
+
+### Comment with braces on both sides
+
+```mermaid-example
+flowchart TD
+    A@{ shape: braces, label: "Comment" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: braces, label: "Comment" }
+```
+
+### Com Link (Lightning Bolt)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: bolt, label: "Communication link" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: bolt, label: "Communication link" }
+```
+
+### Document
+
+```mermaid-example
+flowchart TD
+    A@{ shape: doc, label: "Document" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: doc, label: "Document" }
+```
+
+### Delay (Half-Rounded Rectangle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: delay, label: "Delay" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: delay, label: "Delay" }
+```
+
+### Direct Access Storage (Horizontal Cylinder)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: das, label: "Direct access storage" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: das, label: "Direct access storage" }
+```
+
+### Disk Storage (Lined Cylinder)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: lin-cyl, label: "Disk storage" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: lin-cyl, label: "Disk storage" }
+```
+
+### Display (Curved Trapezoid)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: curv-trap, label: "Display" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: curv-trap, label: "Display" }
+```
+
+### Divided Process (Divided Rectangle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: div-rect, label: "Divided process" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: div-rect, label: "Divided process" }
+```
+
+### Extract (Small Triangle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: tri, label: "Extract" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: tri, label: "Extract" }
+```
+
+### Internal Storage (Window Pane)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: win-pane, label: "Internal storage" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: win-pane, label: "Internal storage" }
+```
+
+### Junction (Filled Circle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: f-circ, label: "Junction" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: f-circ, label: "Junction" }
+```
+
+### Lined Document
+
+```mermaid-example
+flowchart TD
+    A@{ shape: lin-doc, label: "Lined document" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: lin-doc, label: "Lined document" }
+```
+
+### Loop Limit (Notched Pentagon)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: notch-pent, label: "Loop limit" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: notch-pent, label: "Loop limit" }
+```
+
+### Manual File (Flipped Triangle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: flip-tri, label: "Manual file" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: flip-tri, label: "Manual file" }
+```
+
+### Manual Input (Sloped Rectangle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: sl-rect, label: "Manual input" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: sl-rect, label: "Manual input" }
+```
+
+### Multi-Document (Stacked Document)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: docs, label: "Multiple documents" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: docs, label: "Multiple documents" }
+```
+
+### Multi-Process (Stacked Rectangle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: processes, label: "Multiple processes" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: processes, label: "Multiple processes" }
+```
+
+### Paper Tape (Flag)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: flag, label: "Paper tape" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: flag, label: "Paper tape" }
+```
+
+### Stored Data (Bow Tie Rectangle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: bow-rect, label: "Stored data" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: bow-rect, label: "Stored data" }
+```
+
+### Summary (Crossed Circle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: cross-circ, label: "Summary" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: cross-circ, label: "Summary" }
+```
+
+### Tagged Document
+
+```mermaid-example
+flowchart TD
+    A@{ shape: tag-doc, label: "Tagged document" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: tag-doc, label: "Tagged document" }
+```
+
+### Tagged Process (Tagged Rectangle)
+
+```mermaid-example
+flowchart TD
+    A@{ shape: tag-rect, label: "Tagged process" }
+```
+
+```mermaid
+flowchart TD
+    A@{ shape: tag-rect, label: "Tagged process" }
+```
+
+## Special shapes in Mermaid Flowcharts (v11.3.0+)
+
+Mermaid also introduces 2 special shapes to enhance your flowcharts: **icon** and **image**. These shapes allow you to include icons and images directly within your flowcharts, providing more visual context and clarity.
+
+### Icon Shape
+
+You can use the `icon` shape to include an icon in your flowchart. To use icons, you need to register the icon pack first. Follow the instructions provided [here](../config/icons.md). The syntax for defining an icon shape is as follows:
+
+```mermaid-example
+flowchart TD
+    A@{ icon: "fa:user", form: "square", label: "User Icon", pos: "t", h: 60 }
+```
+
+```mermaid
+flowchart TD
+    A@{ icon: "fa:user", form: "square", label: "User Icon", pos: "t", h: 60 }
+```
+
+### Parameters
+
+- **icon**: The name of the icon from the registered icon pack.
+- **form**: Specifies the background shape of the icon. If not defined there will be no background to icon. Options include:
+  - `square`
+  - `circle`
+  - `rounded`
+- **label**: The text label associated with the icon. This can be any string. If not defined, no label will be displayed.
+- **pos**: The position of the label. If not defined label will default to bottom of icon. Possible values are:
+  - `t`
+  - `b`
+- **h**: The height of the icon. If not defined this will default to 48 which is minimum.
+
+### Image Shape
+
+You can use the `image` shape to include an image in your flowchart. The syntax for defining an image shape is as follows:
+
+```mermaid-example
+flowchart TD
+    A@{ img: "https://example.com/image.png", label: "Image Label", pos: "t", w: 60, h: 60, constraint: "off" }
+```
+
+```mermaid
+flowchart TD
+    A@{ img: "https://example.com/image.png", label: "Image Label", pos: "t", w: 60, h: 60, constraint: "off" }
+```
+
+### Parameters
+
+- **img**: The URL of the image to be displayed.
+- **label**: The text label associated with the image. This can be any string. If not defined, no label will be displayed.
+- **pos**: The position of the label. If not defined, the label will default to the bottom of the image. Possible values are:
+  - `t`
+  - `b`
+- **w**: The width of the image. If not defined, this will default to the natural width of the image.
+- **h**: The height of the image. If not defined, this will default to the natural height of the image.
+- **constraint**: Determines if the image should constrain the node size. This setting also ensures the image maintains its original aspect ratio, adjusting the height (`h`) accordingly to the width (`w`). If not defined, this will default to `off` Possible values are:
+  - `on`
+  - `off`
+
+These new shapes provide additional flexibility and visual appeal to your flowcharts, making them more informative and engaging.
+
 ## Links between nodes
 
 Nodes can be connected with links/edges. It is possible to have different types of links or attach a text string to a link.
diff --git a/docs/syntax/kanban.md b/docs/syntax/kanban.md
new file mode 100644
index 000000000..e29057266
--- /dev/null
+++ b/docs/syntax/kanban.md
@@ -0,0 +1,161 @@
+> **Warning**
+>
+> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
+>
+> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/kanban.md](../../packages/mermaid/src/docs/syntax/kanban.md).
+
+# Mermaid Kanban Diagram Documentation
+
+Mermaid’s Kanban diagram allows you to create visual representations of tasks moving through different stages of a workflow. This guide explains how to use the Kanban diagram syntax, based on the provided example.
+
+## Overview
+
+A Kanban diagram in Mermaid starts with the kanban keyword, followed by the definition of columns (stages) and tasks within those columns.
+
+```mermaid-example
+kanban
+  column1[Column Title]
+    task1[Task Description]
+```
+
+```mermaid
+kanban
+  column1[Column Title]
+    task1[Task Description]
+```
+
+## Defining Columns
+
+Columns represent the different stages in your workflow, such as “Todo,” “In Progress,” “Done,” etc. Each column is defined using a unique identifier and a title enclosed in square brackets.
+
+**Syntax:**
+
+```
+columnId[Column Title]
+```
+
+- columnId: A unique identifier for the column.
+- \[Column Title]: The title displayed on the column header.
+
+Like this `id1[Todo]`
+
+## Adding Tasks to Columns
+
+Tasks are listed under their respective columns with an indentation. Each task also has a unique identifier and a description enclosed in square brackets.
+
+**Syntax:**
+
+```
+taskId[Task Description]
+```
+
+```
+•	taskId: A unique identifier for the task.
+•	[Task Description]: The description of the task.
+```
+
+**Example:**
+
+```
+docs[Create Documentation]
+```
+
+## Adding Metadata to Tasks
+
+You can include additional metadata for each task using the @{ ... } syntax. Metadata can contain key-value pairs like assigned, ticket, priority, etc. This will be rendered added to the rendering of the node.
+
+## Supported Metadata Keys
+
+```
+•	assigned: Specifies who is responsible for the task.
+•	ticket: Links the task to a ticket or issue number.
+•	priority: Indicates the urgency of the task. Allowed values: 'Very High', 'High', 'Low' and 'Very Low'
+```
+
+```mermaid-example
+kanban
+todo[Todo]
+  id3[Update Database Function]@{ ticket: MC-2037, assigned: 'knsv', priority: 'High' }
+```
+
+```mermaid
+kanban
+todo[Todo]
+  id3[Update Database Function]@{ ticket: MC-2037, assigned: 'knsv', priority: 'High' }
+```
+
+## Configuration Options
+
+You can customize the Kanban diagram using a configuration block at the beginning of your markdown file. This is useful for setting global settings like a base URL for tickets. Currently there is one configuration option for kanban diagrams tacketBaseUrl. This can be set as in the the following example:
+
+```yaml
+---
+config:
+  kanban:
+    ticketBaseUrl: 'https://yourproject.atlassian.net/browse/#TICKET#'
+---
+```
+
+When the kanban item has an assigned ticket number the ticket number in the diagram will have a link to an external system where the ticket is defined. The `ticketBaseUrl` sets the base URL to the external system and #TICKET# is replaced with the ticket value from task metadata to create a valid link.
+
+## Full Example
+
+Below is the full Kanban diagram based on the provided example:
+
+```mermaid-example
+---
+config:
+  kanban:
+    ticketBaseUrl: 'https://mermaidchart.atlassian.net/browse/#TICKET#'
+---
+kanban
+  Todo
+    [Create Documentation]
+    docs[Create Blog about the new diagram]
+  [In progress]
+    id6[Create renderer so that it works in all cases. We also add som extra text here for testing purposes. And some more just for the extra flare.]
+  id9[Ready for deploy]
+    id8[Design grammar]@{ assigned: 'knsv' }
+  id10[Ready for test]
+    id4[Create parsing tests]@{ ticket: MC-2038, assigned: 'K.Sveidqvist', priority: 'High' }
+    id66[last item]@{ priority: 'Very Low', assigned: 'knsv' }
+  id11[Done]
+    id5[define getData]
+    id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char]@{ ticket: MC-2036, priority: 'Very High'}
+    id3[Update DB function]@{ ticket: MC-2037, assigned: knsv, priority: 'High' }
+
+  id12[Can't reproduce]
+    id3[Weird flickering in Firefox]
+```
+
+```mermaid
+---
+config:
+  kanban:
+    ticketBaseUrl: 'https://mermaidchart.atlassian.net/browse/#TICKET#'
+---
+kanban
+  Todo
+    [Create Documentation]
+    docs[Create Blog about the new diagram]
+  [In progress]
+    id6[Create renderer so that it works in all cases. We also add som extra text here for testing purposes. And some more just for the extra flare.]
+  id9[Ready for deploy]
+    id8[Design grammar]@{ assigned: 'knsv' }
+  id10[Ready for test]
+    id4[Create parsing tests]@{ ticket: MC-2038, assigned: 'K.Sveidqvist', priority: 'High' }
+    id66[last item]@{ priority: 'Very Low', assigned: 'knsv' }
+  id11[Done]
+    id5[define getData]
+    id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char]@{ ticket: MC-2036, priority: 'Very High'}
+    id3[Update DB function]@{ ticket: MC-2037, assigned: knsv, priority: 'High' }
+
+  id12[Can't reproduce]
+    id3[Weird flickering in Firefox]
+```
+
+In conclusion, creating a Kanban diagram in Mermaid is a straightforward process that effectively visualizes your workflow. Start by using the kanban keyword to initiate the diagram. Define your columns with unique identifiers and titles to represent different stages of your project. Under each column, list your tasks—also with unique identifiers—and provide detailed descriptions as needed. Remember that proper indentation is crucial; tasks must be indented under their parent columns to maintain the correct structure.
+
+You can enhance your diagram by adding optional metadata to tasks using the @{ ... } syntax, which allows you to include additional context such as assignee, ticket numbers, and priority levels. For further customization, utilize the configuration block at the top of your file to set global options like ticketBaseUrl for linking tickets directly from your diagram.
+
+By adhering to these guidelines—ensuring unique identifiers, proper indentation, and utilizing metadata and configuration options—you can create a comprehensive and customized Kanban board that effectively maps out your project’s workflow using Mermaid.
diff --git a/docs/syntax/sequenceDiagram.md b/docs/syntax/sequenceDiagram.md
index 435ac7583..84240a0cd 100644
--- a/docs/syntax/sequenceDiagram.md
+++ b/docs/syntax/sequenceDiagram.md
@@ -155,6 +155,9 @@ end
 box rgb(33,66,99)
 ... actors ...
 end
+box rgba(33,66,99,0.5)
+... actors ...
+end
 ```
 
 > **Note**
@@ -217,7 +220,7 @@ There are ten types of arrows currently supported:
 | `<<->>`  | Solid line with bidirectional arrowheads (v11.0.0+)  |
 | `<<-->>` | Dotted line with bidirectional arrowheads (v11.0.0+) |
 | `-x`     | Solid line with a cross at the end                   |
-| `--x`    | Dotted line with a cross at the end.                 |
+| `--x`    | Dotted line with a cross at the end                  |
 | `-)`     | Solid line with an open arrow at the end (async)     |
 | `--)`    | Dotted line with a open arrow at the end (async)     |
 
@@ -580,6 +583,12 @@ sequenceDiagram
 
 It is possible to highlight flows by providing colored background rects. This is done by the notation
 
+```
+rect COLOR
+... content ...
+end
+```
+
 The colors are defined using rgb and rgba syntax.
 
 ```
diff --git a/eslint.config.js b/eslint.config.js
index 8b4807bc5..3278c7eb4 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -23,6 +23,7 @@ export default tseslint.config(
       '**/generated/',
       '**/coverage/',
       'packages/mermaid/src/config.type.ts',
+      'packages/mermaid/src/docs/.vitepress/components.d.ts',
     ],
   },
   {
diff --git a/package.json b/package.json
index 5683b6ed9..c4c692d85 100644
--- a/package.json
+++ b/package.json
@@ -42,6 +42,7 @@
     "test": "pnpm lint && vitest run",
     "test:watch": "vitest --watch",
     "test:coverage": "vitest --coverage",
+    "test:check:tsc": "tsx scripts/tsc-check.ts",
     "prepare": "husky && pnpm build",
     "pre-commit": "lint-staged"
   },
@@ -63,7 +64,7 @@
   },
   "devDependencies": {
     "@applitools/eyes-cypress": "^3.44.4",
-    "@argos-ci/cypress": "^2.1.0",
+    "@argos-ci/cypress": "^2.2.2",
     "@changesets/changelog-github": "^0.5.0",
     "@changesets/cli": "^2.27.7",
     "@cspell/eslint-plugin": "^8.8.4",
@@ -90,19 +91,20 @@
     "cspell": "^8.6.0",
     "cypress": "^13.14.1",
     "cypress-image-snapshot": "^4.0.1",
+    "cypress-split": "^1.24.0",
     "esbuild": "^0.21.5",
     "eslint": "^9.4.0",
     "eslint-config-prettier": "^9.1.0",
     "eslint-plugin-cypress": "^3.3.0",
     "eslint-plugin-html": "^8.1.1",
     "eslint-plugin-jest": "^28.6.0",
-    "eslint-plugin-jsdoc": "^48.2.9",
+    "eslint-plugin-jsdoc": "^50.0.0",
     "eslint-plugin-json": "^4.0.0",
     "eslint-plugin-lodash": "^8.0.0",
     "eslint-plugin-markdown": "^5.0.0",
     "eslint-plugin-no-only-tests": "^3.1.0",
     "eslint-plugin-tsdoc": "^0.3.0",
-    "eslint-plugin-unicorn": "^55.0.0",
+    "eslint-plugin-unicorn": "^56.0.0",
     "express": "^4.19.1",
     "globals": "^15.4.0",
     "globby": "^14.0.1",
@@ -130,5 +132,10 @@
   },
   "nyc": {
     "report-dir": "coverage/cypress"
+  },
+  "pnpm": {
+    "patchedDependencies": {
+      "roughjs": "patches/roughjs.patch"
+    }
   }
 }
diff --git a/packages/mermaid-layout-elk/CHANGELOG.md b/packages/mermaid-layout-elk/CHANGELOG.md
index 9588e7885..ce023eb65 100644
--- a/packages/mermaid-layout-elk/CHANGELOG.md
+++ b/packages/mermaid-layout-elk/CHANGELOG.md
@@ -1,5 +1,20 @@
 # @mermaid-js/layout-elk
 
+## 0.1.5
+
+### Patch Changes
+
+- [#5825](https://github.com/mermaid-js/mermaid/pull/5825) [`233e36c`](https://github.com/mermaid-js/mermaid/commit/233e36c9884fcce141a72ce7c845179781e18632) Thanks [@ashishjain0512](https://github.com/ashishjain0512)! - chore: Update render options
+
+- Updated dependencies [[`6c5b7ce`](https://github.com/mermaid-js/mermaid/commit/6c5b7ce9f41c0fbd59fe03dbefc8418d97697f0a), [`9e3aa70`](https://github.com/mermaid-js/mermaid/commit/9e3aa705ae21fd4898504ab22d775a9e437b898e), [`de2c05c`](https://github.com/mermaid-js/mermaid/commit/de2c05cd5463af68d19dd7b6b3f1303d69ddb2dd)]:
+  - mermaid@11.3.0
+
+## 0.1.4
+
+### Patch Changes
+
+- [#5847](https://github.com/mermaid-js/mermaid/pull/5847) [`dd03043`](https://github.com/mermaid-js/mermaid/commit/dd0304387e85fc57a9ebb666f89ef788c012c2c5) Thanks [@sidharthv96](https://github.com/sidharthv96)! - chore: fix render types
+
 ## 0.1.3
 
 ### Patch Changes
diff --git a/packages/mermaid-layout-elk/package.json b/packages/mermaid-layout-elk/package.json
index 673702be7..26e06b2b1 100644
--- a/packages/mermaid-layout-elk/package.json
+++ b/packages/mermaid-layout-elk/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@mermaid-js/layout-elk",
-  "version": "0.1.3",
+  "version": "0.1.5",
   "description": "ELK layout engine for mermaid",
   "module": "dist/mermaid-layout-elk.core.mjs",
   "types": "dist/layouts.d.ts",
diff --git a/packages/mermaid-layout-elk/src/render.ts b/packages/mermaid-layout-elk/src/render.ts
index 7ac43bb7f..60cdff8d6 100644
--- a/packages/mermaid-layout-elk/src/render.ts
+++ b/packages/mermaid-layout-elk/src/render.ts
@@ -3,6 +3,21 @@ import ELK from 'elkjs/lib/elk.bundled.js';
 import type { InternalHelpers, LayoutData, RenderOptions, SVG, SVGGroup } from 'mermaid';
 import { type TreeData, findCommonAncestor } from './find-common-ancestor.js';
 
+type Node = LayoutData['nodes'][number];
+
+interface LabelData {
+  width: number;
+  height: number;
+  wrappingWidth?: number;
+  labelNode?: SVGGElement | null;
+}
+
+interface NodeWithVertex extends Omit {
+  children?: unknown[];
+  labelData?: LabelData;
+  domId?: Node['domId'] | SVGGroup | d3.Selection;
+}
+
 export const render = async (
   data4Layout: LayoutData,
   svg: SVG,
@@ -24,33 +39,44 @@ export const render = async (
   const nodeDb: Record = {};
   const clusterDb: Record = {};
 
-  const addVertex = async (nodeEl: any, graph: { children: any[] }, nodeArr: any, node: any) => {
-    const labelData: any = { width: 0, height: 0 };
+  const addVertex = async (
+    nodeEl: SVGGroup,
+    graph: { children: NodeWithVertex[] },
+    nodeArr: Node[],
+    node: Node
+  ) => {
+    const labelData: LabelData = { width: 0, height: 0 };
 
-    let boundingBox;
-    const child = {
-      ...node,
-    };
-    graph.children.push(child);
-    nodeDb[node.id] = child;
+    const config = getConfig();
 
     // Add the element to the DOM
     if (!node.isGroup) {
-      const childNodeEl = await insertNode(nodeEl, node, node.dir);
-      boundingBox = childNodeEl.node().getBBox();
+      const child: NodeWithVertex = {
+        ...node,
+      };
+      graph.children.push(child);
+      nodeDb[node.id] = child;
+
+      const childNodeEl = await insertNode(nodeEl, node, { config, dir: node.dir });
+      const boundingBox = childNodeEl.node()!.getBBox();
       child.domId = childNodeEl;
       child.width = boundingBox.width;
       child.height = boundingBox.height;
     } else {
       // A subgraph
-      child.children = [];
+      const child: NodeWithVertex & { children: NodeWithVertex[] } = {
+        ...node,
+        children: [],
+      };
+      graph.children.push(child);
+      nodeDb[node.id] = child;
       await addVertices(nodeEl, nodeArr, child, node.id);
 
       if (node.label) {
         // @ts-ignore TODO: fix this
         const { shapeSvg, bbox } = await labelHelper(nodeEl, node, undefined, true);
         labelData.width = bbox.width;
-        labelData.wrappingWidth = getConfig().flowchart!.wrappingWidth;
+        labelData.wrappingWidth = config.flowchart!.wrappingWidth;
         // Give some padding for elk
         labelData.height = bbox.height - 2;
         labelData.labelNode = shapeSvg.node();
@@ -67,28 +93,16 @@ export const render = async (
   };
 
   const addVertices = async function (
-    nodeEl: any,
-    nodeArr: any[],
-    graph: {
-      id: string;
-      layoutOptions: {
-        'elk.hierarchyHandling': string;
-        'elk.algorithm': any;
-        'nodePlacement.strategy': any;
-        'elk.layered.mergeEdges': any;
-        'elk.direction': string;
-        'spacing.baseValue': number;
-      };
-      children: never[];
-      edges: never[];
-    },
-    parentId?: undefined
+    nodeEl: SVGGroup,
+    nodeArr: Node[],
+    graph: { children: NodeWithVertex[] },
+    parentId?: string
   ) {
-    const siblings = nodeArr.filter((node: { parentId: any }) => node.parentId === parentId);
+    const siblings = nodeArr.filter((node) => node?.parentId === parentId);
     log.info('addVertices APA12', siblings, parentId);
     // Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
     await Promise.all(
-      siblings.map(async (node: any) => {
+      siblings.map(async (node) => {
         await addVertex(nodeEl, graph, nodeArr, node);
       })
     );
@@ -135,6 +149,7 @@ export const render = async (
             const clusterNode = JSON.parse(JSON.stringify(node));
             clusterNode.x = node.offset.posX + node.width / 2;
             clusterNode.y = node.offset.posY + node.height / 2;
+            clusterNode.width = Math.max(clusterNode.width, node.labelData.width);
             await insertCluster(subgraphEl, clusterNode);
 
             log.debug('Id (UIO)= ', node.id, node.width, node.shape, node.labels);
@@ -224,7 +239,7 @@ export const render = async (
    * Add edges to graph based on parsed graph definition
    */
   const addEdges = async function (
-    dataForLayout: { edges: any; direction: string },
+    dataForLayout: { edges: any; direction?: string },
     graph: {
       id?: string;
       layoutOptions?: {
@@ -261,6 +276,8 @@ export const render = async (
         interpolate: undefined;
         style: undefined;
         labelType: any;
+        startLabelRight?: string;
+        endLabelLeft?: string;
       }) {
         // Identify Link
         const linkIdBase = edge.id; // 'L-' + edge.start + '-' + edge.end;
@@ -314,6 +331,9 @@ export const render = async (
         let style = '';
         let labelStyle = '';
 
+        edgeData.startLabelRight = edge.startLabelRight;
+        edgeData.endLabelLeft = edge.endLabelLeft;
+
         switch (edge.stroke) {
           case 'normal':
             style = 'fill:none;';
@@ -749,12 +769,12 @@ export const render = async (
     layoutOptions: {
       'elk.hierarchyHandling': 'INCLUDE_CHILDREN',
       'elk.algorithm': algorithm,
-      'nodePlacement.strategy': data4Layout.config.elk.nodePlacementStrategy,
-      'elk.layered.mergeEdges': data4Layout.config.elk.mergeEdges,
+      'nodePlacement.strategy': data4Layout.config.elk?.nodePlacementStrategy,
+      'elk.layered.mergeEdges': data4Layout.config.elk?.mergeEdges,
       'elk.direction': 'DOWN',
       'spacing.baseValue': 35,
       'elk.layered.unnecessaryBendpoints': true,
-      'elk.layered.cycleBreaking.strategy': data4Layout.config.elk.cycleBreakingStrategy,
+      'elk.layered.cycleBreaking.strategy': data4Layout.config.elk?.cycleBreakingStrategy,
       // 'spacing.nodeNode': 20,
       // 'spacing.nodeNodeBetweenLayers': 25,
       // 'spacing.edgeNode': 20,
@@ -837,8 +857,8 @@ export const render = async (
           ...node.layoutOptions,
           'elk.algorithm': algorithm,
           'elk.direction': dir2ElkDirection(node.dir),
-          'nodePlacement.strategy': data4Layout.config['elk.nodePlacement.strategy'],
-          'elk.layered.mergeEdges': data4Layout.config['elk.mergeEdges'],
+          'nodePlacement.strategy': data4Layout.config.elk?.nodePlacementStrategy,
+          'elk.layered.mergeEdges': data4Layout.config.elk?.mergeEdges,
           'elk.hierarchyHandling': 'SEPARATE_CHILDREN',
         };
       }
diff --git a/packages/mermaid/CHANGELOG.md b/packages/mermaid/CHANGELOG.md
index d7221d232..6332963ed 100644
--- a/packages/mermaid/CHANGELOG.md
+++ b/packages/mermaid/CHANGELOG.md
@@ -1,5 +1,79 @@
 # mermaid
 
+## 11.4.0
+
+### Minor Changes
+
+- [#5999](https://github.com/mermaid-js/mermaid/pull/5999) [`742ad7c`](https://github.com/mermaid-js/mermaid/commit/742ad7c130964df1fb5544e909d9556081285f68) Thanks [@knsv](https://github.com/knsv)! - Adding Kanban board, a new diagram type
+
+- [#5880](https://github.com/mermaid-js/mermaid/pull/5880) [`bdf145f`](https://github.com/mermaid-js/mermaid/commit/bdf145ffe362462176d9c1e68d5f3ff5c9d962b0) Thanks [@yari-dewalt](https://github.com/yari-dewalt)! - Class diagram changes:
+
+  - Updates the class diagram to the new unified way of rendering.
+  - Includes a new "classBox" shape to be used in diagrams
+  - Other updates such as:
+    - the option to hide the empty members box in class diagrams,
+    - support for handDrawn look,
+    - the introduction of the classDef statement into class diagrams,
+    - support for styling the default class,
+    - support lollipop interfaces.
+  - Includes fixes / additions for #5562 #3139 and #4037
+
+### Patch Changes
+
+- [#5937](https://github.com/mermaid-js/mermaid/pull/5937) [`17b7831`](https://github.com/mermaid-js/mermaid/commit/17b783135f9b2b7748b620dbf81d0f56ab4755f1) Thanks [@saurabhg772244](https://github.com/saurabhg772244)! - fix: Jagged edge fix for icon shape
+
+- [#5933](https://github.com/mermaid-js/mermaid/pull/5933) [`72d60d2`](https://github.com/mermaid-js/mermaid/commit/72d60d2633584eb59bccdb6cf30b9522db645db2) Thanks [@remcohaszing](https://github.com/remcohaszing)! - Add missing TypeScript dependencies
+
+- [#5937](https://github.com/mermaid-js/mermaid/pull/5937) [`17b7831`](https://github.com/mermaid-js/mermaid/commit/17b783135f9b2b7748b620dbf81d0f56ab4755f1) Thanks [@saurabhg772244](https://github.com/saurabhg772244)! - fix: Icon color fix for colored icons.
+
+- [#6002](https://github.com/mermaid-js/mermaid/pull/6002) [`5fabd41`](https://github.com/mermaid-js/mermaid/commit/5fabd414fbee01e43bf6c900907ffc1511ca7440) Thanks [@aloisklink](https://github.com/aloisklink)! - fix: error `mermaid.parse` on an invalid shape, so that it matches the errors thrown by `mermaid.render`
+
+## 11.3.0
+
+### Minor Changes
+
+- [#5825](https://github.com/mermaid-js/mermaid/pull/5825) [`9e3aa70`](https://github.com/mermaid-js/mermaid/commit/9e3aa705ae21fd4898504ab22d775a9e437b898e) Thanks [@ashishjain0512](https://github.com/ashishjain0512)! - New Flowchart Shapes (with new syntax)
+
+### Patch Changes
+
+- [#5849](https://github.com/mermaid-js/mermaid/pull/5849) [`6c5b7ce`](https://github.com/mermaid-js/mermaid/commit/6c5b7ce9f41c0fbd59fe03dbefc8418d97697f0a) Thanks [@ReneLombard](https://github.com/ReneLombard)! - Fixed an issue when the mermaid classdiagram crashes when adding a . to the namespace.
+  Forexample
+
+  ```mermaid
+
+  classDiagram
+    namespace Company.Project.Module {
+      class GenericClass~T~ {
+        +addItem(item: T)
+        +getItem() T
+      }
+    }
+  ```
+
+- [#5914](https://github.com/mermaid-js/mermaid/pull/5914) [`de2c05c`](https://github.com/mermaid-js/mermaid/commit/de2c05cd5463af68d19dd7b6b3f1303d69ddb2dd) Thanks [@aloisklink](https://github.com/aloisklink)! - Ban DOMPurify v3.1.7 as a dependency
+
+## 11.2.1
+
+### Patch Changes
+
+- [#5856](https://github.com/mermaid-js/mermaid/pull/5856) [`bfd8c63`](https://github.com/mermaid-js/mermaid/commit/bfd8c63daaa8420e57da9953922b9f0c94123064) Thanks [@knsv](https://github.com/knsv)! - Fix for issue with calculation of label width when using in firefox
+
+## 11.2.0
+
+### Minor Changes
+
+- [#5831](https://github.com/mermaid-js/mermaid/pull/5831) [`64abf29`](https://github.com/mermaid-js/mermaid/commit/64abf29ea870eaa47148197f95ce714f85bd7eea) Thanks [@sidharthv96](https://github.com/sidharthv96)! - feat: Return parsed config from mermaid.parse
+
+### Patch Changes
+
+- [#5838](https://github.com/mermaid-js/mermaid/pull/5838) [`5e75320`](https://github.com/mermaid-js/mermaid/commit/5e75320d49eab65aca630dcc3c04c8d620a8bbf7) Thanks [@bollwyvl](https://github.com/bollwyvl)! - fix: Replace $root with relative paths
+
+## 11.1.1
+
+### Patch Changes
+
+- [#5828](https://github.com/mermaid-js/mermaid/pull/5828) [`4c43d21`](https://github.com/mermaid-js/mermaid/commit/4c43d21196f784b6f483ae635fc462329f3d176f) Thanks [@knsv](https://github.com/knsv)! - fix: Fix for issue where self-loops in the root of diagrams break the rendering
+
 ## 11.1.0
 
 ### Minor Changes
diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json
index 317150788..78bf58388 100644
--- a/packages/mermaid/package.json
+++ b/packages/mermaid/package.json
@@ -1,6 +1,6 @@
 {
   "name": "mermaid",
-  "version": "11.1.0",
+  "version": "11.4.0",
   "description": "Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",
   "type": "module",
   "module": "./dist/mermaid.core.mjs",
@@ -35,8 +35,8 @@
     "clean": "rimraf dist",
     "dev": "pnpm -w dev",
     "docs:code": "typedoc src/defaultConfig.ts src/config.ts src/mermaid.ts && prettier --write ./src/docs/config/setup",
-    "docs:build": "rimraf ../../docs && pnpm docs:spellcheck && pnpm docs:code && tsx scripts/docs.cli.mts",
-    "docs:verify": "pnpm docs:spellcheck && pnpm docs:code && tsx scripts/docs.cli.mts --verify",
+    "docs:build": "rimraf ../../docs && pnpm docs:code && pnpm docs:spellcheck && tsx scripts/docs.cli.mts",
+    "docs:verify": "pnpm docs:code && pnpm docs:spellcheck && tsx scripts/docs.cli.mts --verify",
     "docs:pre:vitepress": "pnpm --filter ./src/docs prefetch && rimraf src/vitepress && pnpm docs:code && tsx scripts/docs.cli.mts --vitepress && pnpm --filter ./src/vitepress install --no-frozen-lockfile --ignore-scripts",
     "docs:build:vitepress": "pnpm docs:pre:vitepress && (cd src/vitepress && pnpm run build) && cpy --flat src/docs/landing/ ./src/vitepress/.vitepress/dist/landing",
     "docs:dev": "pnpm docs:pre:vitepress && concurrently \"pnpm --filter ./src/vitepress dev\" \"tsx scripts/docs.cli.mts --watch --vitepress\"",
@@ -70,14 +70,16 @@
     "@braintree/sanitize-url": "^7.0.1",
     "@iconify/utils": "^2.1.32",
     "@mermaid-js/parser": "workspace:^",
+    "@types/d3": "^7.4.3",
+    "@types/dompurify": "^3.0.5",
     "cytoscape": "^3.29.2",
     "cytoscape-cose-bilkent": "^4.1.0",
     "cytoscape-fcose": "^2.2.0",
     "d3": "^7.9.0",
     "d3-sankey": "^0.12.3",
-    "dagre-d3-es": "7.0.10",
+    "dagre-d3-es": "7.0.11",
     "dayjs": "^1.11.10",
-    "dompurify": "^3.0.11",
+    "dompurify": "^3.0.11 <3.1.7",
     "katex": "^0.16.9",
     "khroma": "^2.1.0",
     "lodash-es": "^4.17.21",
@@ -92,13 +94,11 @@
     "@iconify/types": "^2.0.0",
     "@types/cytoscape": "^3.21.4",
     "@types/cytoscape-fcose": "^2.2.4",
-    "@types/d3": "^7.4.3",
     "@types/d3-sankey": "^0.12.4",
     "@types/d3-scale": "^4.0.8",
     "@types/d3-scale-chromatic": "^3.0.3",
     "@types/d3-selection": "^3.0.10",
     "@types/d3-shape": "^3.1.6",
-    "@types/dompurify": "^3.0.5",
     "@types/jsdom": "^21.1.6",
     "@types/katex": "^0.16.7",
     "@types/lodash-es": "^4.17.12",
diff --git a/packages/mermaid/scripts/docs.mts b/packages/mermaid/scripts/docs.mts
index 374e78870..073a3c1a9 100644
--- a/packages/mermaid/scripts/docs.mts
+++ b/packages/mermaid/scripts/docs.mts
@@ -41,7 +41,8 @@ import { exec } from 'child_process';
 import { globby } from 'globby';
 import { JSDOM } from 'jsdom';
 import { dump, load, JSON_SCHEMA } from 'js-yaml';
-import type { Code, ListItem, Root, Text, YAML } from 'mdast';
+import type { Code, ListItem, PhrasingContent, Root, Text, YAML } from 'mdast';
+import { register } from 'node:module';
 import { posix, dirname, relative, join } from 'path';
 import prettier from 'prettier';
 import { remark } from 'remark';
@@ -53,6 +54,10 @@ import mm from 'micromatch';
 import flatmap from 'unist-util-flatmap';
 import { visit } from 'unist-util-visit';
 
+// short-circuit `.schema.yaml` imports, so that we can safely import `shapes.js`
+register('./loadHook.mjs', import.meta.url);
+const { shapesDefs } = await import('../src/rendering-util/rendering-elements/shapes.js');
+
 export const MERMAID_RELEASE_VERSION = JSON.parse(readFileSync('../mermaid/package.json', 'utf8'))
   .version as string;
 const MERMAID_MAJOR_VERSION = MERMAID_RELEASE_VERSION.split('.')[0];
@@ -103,6 +108,60 @@ const generateHeader = (file: string): string => {
 > ## Please edit the corresponding file in [${filePathFromRoot}](${sourcePathRelativeToGenerated}).`;
 };
 
+/**
+ * Builds a markdown list of shapes supported in flowcharts.
+ */
+export function buildShapeDoc() {
+  const data = shapesDefs
+    .sort((a, b) => a.semanticName.localeCompare(b.semanticName))
+    .map((shape): PhrasingContent[][] => {
+      const { name, semanticName, description, shortName, aliases = [] } = shape;
+      return [
+        [{ type: 'text', value: semanticName }],
+        [{ type: 'text', value: name }],
+        [{ type: 'inlineCode', value: shortName }],
+        [{ type: 'text', value: description }],
+        aliases.sort().flatMap((alias, index) => [
+          ...(index !== 0 ? ([{ type: 'text', value: ', ' }] as const) : []),
+          {
+            type: 'inlineCode',
+            value: alias,
+          },
+        ]),
+      ];
+    });
+
+  // don't prettify this table, since we'd do it later
+  return remark()
+    .use(remarkGfm)
+    .stringify({
+      type: 'root',
+      children: [
+        {
+          type: 'table',
+          children: [
+            ['Semantic Name', 'Shape Name', 'Short Name', 'Description', 'Alias Supported'].map(
+              (s): PhrasingContent[] => [
+                {
+                  type: 'strong',
+                  children: [{ type: 'text', value: s }],
+                },
+              ]
+            ),
+            ...data,
+          ].map((row) => ({
+            type: 'tableRow',
+            children: row.map((cell) => ({
+              type: 'tableCell',
+              children: cell,
+            })),
+          })),
+        },
+      ],
+    })
+    .toString();
+}
+
 /**
  * Given a source file name and path, return the documentation destination full path and file name
  * Create the destination path if it does not already exist.
@@ -192,10 +251,22 @@ export const transformToBlockQuote = (
 const injectPlaceholders = (text: string): string =>
   text.replace(//g, MERMAID_MAJOR_VERSION).replace(//g, CDN_URL);
 
+const virtualGenerators: Record string> = {
+  shapesTable: buildShapeDoc,
+};
+
 const transformIncludeStatements = (file: string, text: string): string => {
   // resolve includes - src https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L65-L76
-  return text.replace(includesRE, (m, m1) => {
+  return text.replace(includesRE, (m, m1: string) => {
     try {
+      if (m1.startsWith('virtual:')) {
+        const key = m1.replace('virtual:', '');
+        const generator = virtualGenerators[key];
+        if (!generator) {
+          throw new Error(`Unknown virtual generator: ${key} in "${file}"`);
+        }
+        return generator();
+      }
       const includePath = join(dirname(file), m1).replaceAll('\\', '/');
       const content = readSyncedUTF8file(includePath);
       includedFiles.add(changeToFinalDocDir(includePath));
diff --git a/packages/mermaid/scripts/docs.spec.ts b/packages/mermaid/scripts/docs.spec.ts
index c84bc1bac..68677d4c9 100644
--- a/packages/mermaid/scripts/docs.spec.ts
+++ b/packages/mermaid/scripts/docs.spec.ts
@@ -1,4 +1,4 @@
-import { transformMarkdownAst, transformToBlockQuote } from './docs.mjs';
+import { buildShapeDoc, transformMarkdownAst, transformToBlockQuote } from './docs.mjs';
 
 import { remark } from 'remark'; // import it this way so we can mock it
 import remarkFrontmatter from 'remark-frontmatter';
@@ -165,4 +165,59 @@ This Markdown should be kept.
       });
     });
   });
+
+  describe('buildShapeDoc', () => {
+    it('should build shapesTable based on the shapeDefs', () => {
+      expect(buildShapeDoc()).toMatchInlineSnapshot(`
+        "| **Semantic Name**                 | **Shape Name**         | **Short Name** | **Description**                | **Alias Supported**                                              |
+        | --------------------------------- | ---------------------- | -------------- | ------------------------------ | ---------------------------------------------------------------- |
+        | Card                              | Notched Rectangle      | \`notch-rect\`   | Represents a card              | \`card\`, \`notched-rectangle\`                                      |
+        | Collate                           | Hourglass              | \`hourglass\`    | Represents a collate operation | \`collate\`, \`hourglass\`                                           |
+        | Com Link                          | Lightning Bolt         | \`bolt\`         | Communication link             | \`com-link\`, \`lightning-bolt\`                                     |
+        | Comment                           | Curly Brace            | \`brace\`        | Adds a comment                 | \`brace-l\`, \`comment\`                                             |
+        | Comment Right                     | Curly Brace            | \`brace-r\`      | Adds a comment                 |                                                                  |
+        | Comment with braces on both sides | Curly Braces           | \`braces\`       | Adds a comment                 |                                                                  |
+        | Data Input/Output                 | Lean Right             | \`lean-r\`       | Represents input or output     | \`in-out\`, \`lean-right\`                                           |
+        | Data Input/Output                 | Lean Left              | \`lean-l\`       | Represents output or input     | \`lean-left\`, \`out-in\`                                            |
+        | Database                          | Cylinder               | \`cyl\`          | Database storage               | \`cylinder\`, \`database\`, \`db\`                                     |
+        | Decision                          | Diamond                | \`diam\`         | Decision-making step           | \`decision\`, \`diamond\`, \`question\`                                |
+        | Delay                             | Half-Rounded Rectangle | \`delay\`        | Represents a delay             | \`half-rounded-rectangle\`                                         |
+        | Direct Access Storage             | Horizontal Cylinder    | \`h-cyl\`        | Direct access storage          | \`das\`, \`horizontal-cylinder\`                                     |
+        | Disk Storage                      | Lined Cylinder         | \`lin-cyl\`      | Disk storage                   | \`disk\`, \`lined-cylinder\`                                         |
+        | Display                           | Curved Trapezoid       | \`curv-trap\`    | Represents a display           | \`curved-trapezoid\`, \`display\`                                    |
+        | Divided Process                   | Divided Rectangle      | \`div-rect\`     | Divided process shape          | \`div-proc\`, \`divided-process\`, \`divided-rectangle\`               |
+        | Document                          | Document               | \`doc\`          | Represents a document          | \`doc\`, \`document\`                                                |
+        | Event                             | Rounded Rectangle      | \`rounded\`      | Represents an event            | \`event\`                                                          |
+        | Extract                           | Triangle               | \`tri\`          | Extraction process             | \`extract\`, \`triangle\`                                            |
+        | Fork/Join                         | Filled Rectangle       | \`fork\`         | Fork or join in process flow   | \`join\`                                                           |
+        | Internal Storage                  | Window Pane            | \`win-pane\`     | Internal storage               | \`internal-storage\`, \`window-pane\`                                |
+        | Junction                          | Filled Circle          | \`f-circ\`       | Junction point                 | \`filled-circle\`, \`junction\`                                      |
+        | Lined Document                    | Lined Document         | \`lin-doc\`      | Lined document                 | \`lined-document\`                                                 |
+        | Lined/Shaded Process              | Lined Rectangle        | \`lin-rect\`     | Lined process shape            | \`lin-proc\`, \`lined-process\`, \`lined-rectangle\`, \`shaded-process\` |
+        | Loop Limit                        | Trapezoidal Pentagon   | \`notch-pent\`   | Loop limit step                | \`loop-limit\`, \`notched-pentagon\`                                 |
+        | Manual File                       | Flipped Triangle       | \`flip-tri\`     | Manual file operation          | \`flipped-triangle\`, \`manual-file\`                                |
+        | Manual Input                      | Sloped Rectangle       | \`sl-rect\`      | Manual input step              | \`manual-input\`, \`sloped-rectangle\`                               |
+        | Manual Operation                  | Trapezoid Base Top     | \`trap-t\`       | Represents a manual task       | \`inv-trapezoid\`, \`manual\`, \`trapezoid-top\`                       |
+        | Multi-Document                    | Stacked Document       | \`docs\`         | Multiple documents             | \`documents\`, \`st-doc\`, \`stacked-document\`                        |
+        | Multi-Process                     | Stacked Rectangle      | \`st-rect\`      | Multiple processes             | \`processes\`, \`procs\`, \`stacked-rectangle\`                        |
+        | Odd                               | Odd                    | \`odd\`          | Odd shape                      |                                                                  |
+        | Paper Tape                        | Flag                   | \`flag\`         | Paper tape                     | \`paper-tape\`                                                     |
+        | Prepare Conditional               | Hexagon                | \`hex\`          | Preparation or condition step  | \`hexagon\`, \`prepare\`                                             |
+        | Priority Action                   | Trapezoid Base Bottom  | \`trap-b\`       | Priority action                | \`priority\`, \`trapezoid\`, \`trapezoid-bottom\`                      |
+        | Process                           | Rectangle              | \`rect\`         | Standard process shape         | \`proc\`, \`process\`, \`rectangle\`                                   |
+        | Start                             | Circle                 | \`circle\`       | Starting point                 | \`circ\`                                                           |
+        | Start                             | Small Circle           | \`sm-circ\`      | Small starting point           | \`small-circle\`, \`start\`                                          |
+        | Stop                              | Double Circle          | \`dbl-circ\`     | Represents a stop point        | \`double-circle\`                                                  |
+        | Stop                              | Framed Circle          | \`fr-circ\`      | Stop point                     | \`framed-circle\`, \`stop\`                                          |
+        | Stored Data                       | Bow Tie Rectangle      | \`bow-rect\`     | Stored data                    | \`bow-tie-rectangle\`, \`stored-data\`                               |
+        | Subprocess                        | Framed Rectangle       | \`fr-rect\`      | Subprocess                     | \`framed-rectangle\`, \`subproc\`, \`subprocess\`, \`subroutine\`        |
+        | Summary                           | Crossed Circle         | \`cross-circ\`   | Summary                        | \`crossed-circle\`, \`summary\`                                      |
+        | Tagged Document                   | Tagged Document        | \`tag-doc\`      | Tagged document                | \`tag-doc\`, \`tagged-document\`                                     |
+        | Tagged Process                    | Tagged Rectangle       | \`tag-rect\`     | Tagged process                 | \`tag-proc\`, \`tagged-process\`, \`tagged-rectangle\`                 |
+        | Terminal Point                    | Stadium                | \`stadium\`      | Terminal point                 | \`pill\`, \`terminal\`                                               |
+        | Text Block                        | Text Block             | \`text\`         | Text block                     |                                                                  |
+        "
+      `);
+    });
+  });
 });
diff --git a/packages/mermaid/scripts/loadHook.mjs b/packages/mermaid/scripts/loadHook.mjs
new file mode 100644
index 000000000..50129861b
--- /dev/null
+++ b/packages/mermaid/scripts/loadHook.mjs
@@ -0,0 +1,22 @@
+import { fileURLToPath } from 'node:url';
+/** @import import { LoadHook } from "node:module"; */
+/**
+ * @type {LoadHook}
+ *
+ * Load hook that short circuits the loading of `.schema.yaml` files with `export default {}`.
+ * These would normally be loaded using ESBuild, but that doesn't work for these local scripts.
+ *
+ * @see https://nodejs.org/api/module.html#loadurl-context-nextload
+ */
+export const load = async (url, context, nextLoad) => {
+  const filePath = url.startsWith('file://') ? fileURLToPath(url) : url;
+  if (filePath.endsWith('.schema.yaml')) {
+    return {
+      format: 'module',
+      shortCircuit: true,
+      source: `export default {}`,
+    };
+  } else {
+    return await nextLoad(url, context);
+  }
+};
diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts
index 035a158e0..86281cd52 100644
--- a/packages/mermaid/src/config.type.ts
+++ b/packages/mermaid/src/config.type.ts
@@ -193,6 +193,7 @@ export interface MermaidConfig {
   requirement?: RequirementDiagramConfig;
   architecture?: ArchitectureDiagramConfig;
   mindmap?: MindmapDiagramConfig;
+  kanban?: KanbanDiagramConfig;
   gitGraph?: GitGraphDiagramConfig;
   c4?: C4DiagramConfig;
   sankey?: SankeyDiagramConfig;
@@ -716,6 +717,7 @@ export interface ClassDiagramConfig extends BaseDiagramConfig {
    */
   diagramPadding?: number;
   htmlLabels?: boolean;
+  hideEmptyMembersBox?: boolean;
 }
 /**
  * The object containing configurations specific for entity relationship diagrams
@@ -1023,6 +1025,17 @@ export interface MindmapDiagramConfig extends BaseDiagramConfig {
   padding?: number;
   maxNodeWidth?: number;
 }
+/**
+ * The object containing configurations specific for kanban diagrams
+ *
+ * This interface was referenced by `MermaidConfig`'s JSON-Schema
+ * via the `definition` "KanbanDiagramConfig".
+ */
+export interface KanbanDiagramConfig extends BaseDiagramConfig {
+  padding?: number;
+  sectionWidth?: number;
+  ticketBaseUrl?: string;
+}
 /**
  * This interface was referenced by `MermaidConfig`'s JSON-Schema
  * via the `definition` "GitGraphDiagramConfig".
diff --git a/packages/mermaid/src/dagre-wrapper/index.js b/packages/mermaid/src/dagre-wrapper/index.js
index fa2b70ca2..86ae7e284 100644
--- a/packages/mermaid/src/dagre-wrapper/index.js
+++ b/packages/mermaid/src/dagre-wrapper/index.js
@@ -87,7 +87,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
           // insertCluster(clusters, graph.node(v));
         } else {
           log.info('Node - the non recursive path', v, node.id, node);
-          await insertNode(nodes, graph.node(v), dir);
+          await insertNode(nodes, graph.node(v), { config: siteConfig, dir });
         }
       }
     })
diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js
index b841064b6..2677fd785 100644
--- a/packages/mermaid/src/dagre-wrapper/nodes.js
+++ b/packages/mermaid/src/dagre-wrapper/nodes.js
@@ -1131,7 +1131,7 @@ const shapes = {
 
 let nodeElems = {};
 
-export const insertNode = async (elem, node, dir) => {
+export const insertNode = async (elem, node, renderOptions) => {
   let newEl;
   let el;
 
@@ -1144,9 +1144,9 @@ export const insertNode = async (elem, node, dir) => {
       target = node.linkTarget || '_blank';
     }
     newEl = elem.insert('svg:a').attr('xlink:href', node.link).attr('target', target);
-    el = await shapes[node.shape](newEl, node, dir);
+    el = await shapes[node.shape](newEl, node, renderOptions);
   } else {
-    el = await shapes[node.shape](elem, node, dir);
+    el = await shapes[node.shape](elem, node, renderOptions);
     newEl = el;
   }
   if (node.tooltip) {
diff --git a/packages/mermaid/src/defaultConfig.ts b/packages/mermaid/src/defaultConfig.ts
index 97f3e0bb1..a3dab2ddb 100644
--- a/packages/mermaid/src/defaultConfig.ts
+++ b/packages/mermaid/src/defaultConfig.ts
@@ -21,8 +21,9 @@ const config: RequiredDeep = {
   // TODO: Should we replace these with `null` so that they can go in the JSON Schema?
   deterministicIDSeed: undefined,
   elk: {
+    // mergeEdges is needed here to be considered
     mergeEdges: false,
-    nodePlacementStrategy: 'SIMPLE',
+    nodePlacementStrategy: 'BRANDES_KOEPF',
   },
   themeCSS: undefined,
 
@@ -52,6 +53,9 @@ const config: RequiredDeep = {
       };
     },
   },
+  class: {
+    hideEmptyMembersBox: false,
+  },
   gantt: {
     ...defaultConfigJson.gantt,
     tickInterval: undefined,
diff --git a/packages/mermaid/src/diagram-api/diagram-orchestration.ts b/packages/mermaid/src/diagram-api/diagram-orchestration.ts
index d68a1c498..5b8cfc3fe 100644
--- a/packages/mermaid/src/diagram-api/diagram-orchestration.ts
+++ b/packages/mermaid/src/diagram-api/diagram-orchestration.ts
@@ -19,6 +19,7 @@ import errorDiagram from '../diagrams/error/errorDiagram.js';
 import flowchartElk from '../diagrams/flowchart/elk/detector.js';
 import timeline from '../diagrams/timeline/detector.js';
 import mindmap from '../diagrams/mindmap/detector.js';
+import kanban from '../diagrams/kanban/detector.js';
 import sankey from '../diagrams/sankey/sankeyDetector.js';
 import { packet } from '../diagrams/packet/detector.js';
 import block from '../diagrams/block/blockDetector.js';
@@ -70,6 +71,7 @@ export const addDiagrams = () => {
   // Ordering of detectors is important. The first one to return true will be used.
   registerLazyLoadedDiagrams(
     c4,
+    kanban,
     classDiagramV2,
     classDiagram,
     er,
diff --git a/packages/mermaid/src/diagrams/architecture/architectureIcons.ts b/packages/mermaid/src/diagrams/architecture/architectureIcons.ts
index dd6c99f9c..fac4a7b12 100644
--- a/packages/mermaid/src/diagrams/architecture/architectureIcons.ts
+++ b/packages/mermaid/src/diagrams/architecture/architectureIcons.ts
@@ -1,4 +1,4 @@
-import { unknownIcon } from '$root/rendering-util/icons.js';
+import { unknownIcon } from '../../rendering-util/icons.js';
 import type { IconifyJSON } from '@iconify/types';
 
 const wrapIcon = (icon: string) => {
diff --git a/packages/mermaid/src/diagrams/architecture/architectureRenderer.ts b/packages/mermaid/src/diagrams/architecture/architectureRenderer.ts
index 3abb69b9f..af9429539 100644
--- a/packages/mermaid/src/diagrams/architecture/architectureRenderer.ts
+++ b/packages/mermaid/src/diagrams/architecture/architectureRenderer.ts
@@ -1,4 +1,4 @@
-import { registerIconPacks } from '$root/rendering-util/icons.js';
+import { registerIconPacks } from '../../rendering-util/icons.js';
 import type { Position } from 'cytoscape';
 import cytoscape from 'cytoscape';
 import type { FcoseLayoutOptions } from 'cytoscape-fcose';
diff --git a/packages/mermaid/src/diagrams/architecture/svgDraw.ts b/packages/mermaid/src/diagrams/architecture/svgDraw.ts
index 357839394..b10a451fe 100644
--- a/packages/mermaid/src/diagrams/architecture/svgDraw.ts
+++ b/packages/mermaid/src/diagrams/architecture/svgDraw.ts
@@ -1,4 +1,4 @@
-import { getIconSVG } from '$root/rendering-util/icons.js';
+import { getIconSVG } from '../../rendering-util/icons.js';
 import type cytoscape from 'cytoscape';
 import { getConfig } from '../../diagram-api/diagramAPI.js';
 import { createText } from '../../rendering-util/createText.js';
@@ -170,8 +170,8 @@ export const drawEdges = async function (edgesEl: D3Element, cy: cytoscape.Core)
               textElem.attr(
                 'transform',
                 `
-                translate(${midX}, ${midY - bboxOrig.height / 2}) 
-                translate(${(x * bboxNew.width) / 2}, ${(y * bboxNew.height) / 2}) 
+                translate(${midX}, ${midY - bboxOrig.height / 2})
+                translate(${(x * bboxNew.width) / 2}, ${(y * bboxNew.height) / 2})
                 rotate(${-1 * x * y * 45}, 0, ${bboxOrig.height / 2})
               `
               );
diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
index 97eca4074..8957b4d8f 100644
--- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
+++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
@@ -124,7 +124,8 @@ async function calculateBlockSize(
   }
 
   // Add the element to the DOM to size it
-  const nodeEl = await insertNode(elem, node);
+  const config = getConfig();
+  const nodeEl = await insertNode(elem, node, { config });
   const boundingBox = nodeEl.node().getBBox();
   const obj = db.getBlock(node.id);
   obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl };
@@ -138,7 +139,8 @@ export async function insertBlockPositioned(elem: any, block: Block, db: any) {
   // Add the element to the DOM to size it
   const obj = db.getBlock(node.id);
   if (obj.type !== 'space') {
-    await insertNode(elem, node);
+    const config = getConfig();
+    await insertNode(elem, node, { config });
     block.intersect = node?.intersect;
     positionNode(node);
   }
diff --git a/packages/mermaid/src/diagrams/class/classDb.ts b/packages/mermaid/src/diagrams/class/classDb.ts
index 2548d2a72..e15103469 100644
--- a/packages/mermaid/src/diagrams/class/classDb.ts
+++ b/packages/mermaid/src/diagrams/class/classDb.ts
@@ -1,9 +1,8 @@
-import type { Selection } from 'd3';
-import { select } from 'd3';
+import { select, type Selection } from 'd3';
 import { log } from '../../logger.js';
 import { getConfig } from '../../diagram-api/diagramAPI.js';
 import common from '../common/common.js';
-import utils from '../../utils.js';
+import utils, { getEdgeId } from '../../utils.js';
 import {
   setAccTitle,
   getAccTitle,
@@ -21,13 +20,18 @@ import type {
   ClassMap,
   NamespaceMap,
   NamespaceNode,
+  StyleClass,
+  Interface,
 } from './classTypes.js';
+import type { Node, Edge } from '../../rendering-util/types.js';
 
 const MERMAID_DOM_ID_PREFIX = 'classId-';
 
 let relations: ClassRelation[] = [];
 let classes = new Map();
+const styleClasses = new Map();
 let notes = new Map();
+let interfaces: Interface[] = [];
 let classCounter = 0;
 let namespaces = new Map();
 let namespaceCounter = 0;
@@ -58,6 +62,8 @@ export const setClassLabel = function (_id: string, label: string) {
 
   const { className } = splitClassNameAndType(id);
   classes.get(className)!.label = label;
+  classes.get(className)!.text =
+    `${label}${classes.get(className)!.type ? `<${classes.get(className)!.type}>` : ''}`;
 };
 
 /**
@@ -80,7 +86,9 @@ export const addClass = function (_id: string) {
     id: name,
     type: type,
     label: name,
-    cssClasses: [],
+    text: `${name}${type ? `<${type}>` : ''}`,
+    shape: 'classBox',
+    cssClasses: 'default',
     methods: [],
     members: [],
     annotations: [],
@@ -91,6 +99,16 @@ export const addClass = function (_id: string) {
   classCounter++;
 };
 
+const addInterface = function (label: string, classId: string) {
+  const classInterface: Interface = {
+    id: `interface${interfaces.length}`,
+    label,
+    classId,
+  };
+
+  interfaces.push(classInterface);
+};
+
 /**
  * Function to lookup domId from id in the graph definition.
  *
@@ -108,7 +126,8 @@ export const lookUpDomId = function (_id: string): string {
 export const clear = function () {
   relations = [];
   classes = new Map();
-  notes = new Map();
+  notes = [];
+  interfaces = [];
   functions = [];
   functions.push(setupToolTips);
   namespaces = new Map();
@@ -138,19 +157,50 @@ export const getNotes = function () {
   return notes;
 };
 
-export const addRelation = function (relation: ClassRelation) {
-  log.debug('Adding relation: ' + JSON.stringify(relation));
-  addClass(relation.id1);
-  addClass(relation.id2);
+export const addRelation = function (classRelation: ClassRelation) {
+  log.debug('Adding relation: ' + JSON.stringify(classRelation));
+  // Due to relationType cannot just check if it is equal to 'none' or it complains, can fix this later
+  const invalidTypes = [
+    relationType.LOLLIPOP,
+    relationType.AGGREGATION,
+    relationType.COMPOSITION,
+    relationType.DEPENDENCY,
+    relationType.EXTENSION,
+  ];
 
-  relation.id1 = splitClassNameAndType(relation.id1).className;
-  relation.id2 = splitClassNameAndType(relation.id2).className;
+  if (
+    classRelation.relation.type1 === relationType.LOLLIPOP &&
+    !invalidTypes.includes(classRelation.relation.type2)
+  ) {
+    addClass(classRelation.id2);
+    addInterface(classRelation.id1, classRelation.id2);
+    classRelation.id1 = `interface${interfaces.length - 1}`;
+  } else if (
+    classRelation.relation.type2 === relationType.LOLLIPOP &&
+    !invalidTypes.includes(classRelation.relation.type1)
+  ) {
+    addClass(classRelation.id1);
+    addInterface(classRelation.id2, classRelation.id1);
+    classRelation.id2 = `interface${interfaces.length - 1}`;
+  } else {
+    addClass(classRelation.id1);
+    addClass(classRelation.id2);
+  }
 
-  relation.relationTitle1 = common.sanitizeText(relation.relationTitle1.trim(), getConfig());
+  classRelation.id1 = splitClassNameAndType(classRelation.id1).className;
+  classRelation.id2 = splitClassNameAndType(classRelation.id2).className;
 
-  relation.relationTitle2 = common.sanitizeText(relation.relationTitle2.trim(), getConfig());
+  classRelation.relationTitle1 = common.sanitizeText(
+    classRelation.relationTitle1.trim(),
+    getConfig()
+  );
 
-  relations.push(relation);
+  classRelation.relationTitle2 = common.sanitizeText(
+    classRelation.relationTitle2.trim(),
+    getConfig()
+  );
+
+  relations.push(classRelation);
 };
 
 /**
@@ -237,11 +287,37 @@ export const setCssClass = function (ids: string, className: string) {
     }
     const classNode = classes.get(id);
     if (classNode) {
-      classNode.cssClasses.push(className);
+      classNode.cssClasses += ' ' + className;
     }
   });
 };
 
+export const defineClass = function (ids: string[], style: string[]) {
+  for (const id of ids) {
+    let styleClass = styleClasses.get(id);
+    if (styleClass === undefined) {
+      styleClass = { id, styles: [], textStyles: [] };
+      styleClasses.set(id, styleClass);
+    }
+
+    if (style) {
+      style.forEach(function (s) {
+        if (/color/.exec(s)) {
+          const newStyle = s.replace('fill', 'bgFill'); // .replace('color', 'fill');
+          styleClass.textStyles.push(newStyle);
+        }
+        styleClass.styles.push(s);
+      });
+    }
+
+    classes.forEach((value) => {
+      if (value.cssClasses.includes(id)) {
+        value.styles.push(...style.flatMap((s) => s.split(',')));
+      }
+    });
+  }
+};
+
 /**
  * Called by parser when a tooltip is found, e.g. a clickable element.
  *
@@ -397,7 +473,6 @@ const setupToolTips = function (element: Element) {
       // @ts-ignore - getBoundingClientRect is not part of the d3 type definition
       const rect = this.getBoundingClientRect();
 
-      // @ts-expect-error - Incorrect types
       tooltipElem.transition().duration(200).style('opacity', '.9');
       tooltipElem
         .text(el.attr('title'))
@@ -407,7 +482,6 @@ const setupToolTips = function (element: Element) {
       el.classed('hover', true);
     })
     .on('mouseout', function () {
-      // @ts-expect-error - Incorrect types
       tooltipElem.transition().duration(500).style('opacity', 0);
       const el = select(this);
       el.classed('hover', false);
@@ -493,6 +567,152 @@ export const setCssStyle = function (id: string, styles: string[]) {
   }
 };
 
+/**
+ * Gets the arrow marker for a type index
+ *
+ * @param type - The type to look for
+ * @returns The arrow marker
+ */
+function getArrowMarker(type: number) {
+  let marker;
+  switch (type) {
+    case 0:
+      marker = 'aggregation';
+      break;
+    case 1:
+      marker = 'extension';
+      break;
+    case 2:
+      marker = 'composition';
+      break;
+    case 3:
+      marker = 'dependency';
+      break;
+    case 4:
+      marker = 'lollipop';
+      break;
+    default:
+      marker = 'none';
+  }
+  return marker;
+}
+
+export const getData = () => {
+  const nodes: Node[] = [];
+  const edges: Edge[] = [];
+  const config = getConfig();
+
+  for (const namespaceKey of namespaces.keys()) {
+    const namespace = namespaces.get(namespaceKey);
+    if (namespace) {
+      const node: Node = {
+        id: namespace.id,
+        label: namespace.id,
+        isGroup: true,
+        padding: config.class!.padding ?? 16,
+        // parent node must be one of [rect, roundedWithTitle, noteGroup, divider]
+        shape: 'rect',
+        cssStyles: ['fill: none', 'stroke: black'],
+        look: config.look,
+      };
+      nodes.push(node);
+    }
+  }
+
+  for (const classKey of classes.keys()) {
+    const classNode = classes.get(classKey);
+    if (classNode) {
+      const node = classNode as unknown as Node;
+      node.parentId = classNode.parent;
+      node.look = config.look;
+      nodes.push(node);
+    }
+  }
+
+  let cnt = 0;
+  for (const note of notes) {
+    cnt++;
+    const noteNode: Node = {
+      id: note.id,
+      label: note.text,
+      isGroup: false,
+      shape: 'note',
+      padding: config.class!.padding ?? 6,
+      cssStyles: [
+        'text-align: left',
+        'white-space: nowrap',
+        `fill: ${config.themeVariables.noteBkgColor}`,
+        `stroke: ${config.themeVariables.noteBorderColor}`,
+      ],
+      look: config.look,
+    };
+    nodes.push(noteNode);
+
+    const noteClassId = classes.get(note.class)?.id ?? '';
+
+    if (noteClassId) {
+      const edge: Edge = {
+        id: `edgeNote${cnt}`,
+        start: note.id,
+        end: noteClassId,
+        type: 'normal',
+        thickness: 'normal',
+        classes: 'relation',
+        arrowTypeStart: 'none',
+        arrowTypeEnd: 'none',
+        arrowheadStyle: '',
+        labelStyle: [''],
+        style: ['fill: none'],
+        pattern: 'dotted',
+        look: config.look,
+      };
+      edges.push(edge);
+    }
+  }
+
+  for (const _interface of interfaces) {
+    const interfaceNode: Node = {
+      id: _interface.id,
+      label: _interface.label,
+      isGroup: false,
+      shape: 'rect',
+      cssStyles: ['opacity: 0;'],
+      look: config.look,
+    };
+    nodes.push(interfaceNode);
+  }
+
+  cnt = 0;
+  for (const classRelation of relations) {
+    cnt++;
+    const edge: Edge = {
+      id: getEdgeId(classRelation.id1, classRelation.id2, {
+        prefix: 'id',
+        counter: cnt,
+      }),
+      start: classRelation.id1,
+      end: classRelation.id2,
+      type: 'normal',
+      label: classRelation.title,
+      labelpos: 'c',
+      thickness: 'normal',
+      classes: 'relation',
+      arrowTypeStart: getArrowMarker(classRelation.relation.type1),
+      arrowTypeEnd: getArrowMarker(classRelation.relation.type2),
+      startLabelRight: classRelation.relationTitle1 === 'none' ? '' : classRelation.relationTitle1,
+      endLabelLeft: classRelation.relationTitle2 === 'none' ? '' : classRelation.relationTitle2,
+      arrowheadStyle: '',
+      labelStyle: ['display: inline-block'],
+      style: classRelation.style || '',
+      pattern: classRelation.relation.lineType == 1 ? 'dashed' : 'solid',
+      look: config.look,
+    };
+    edges.push(edge);
+  }
+
+  return { nodes, edges, other: {}, config, direction: getDirection() };
+};
+
 export default {
   setAccTitle,
   getAccTitle,
@@ -519,6 +739,7 @@ export default {
   relationType,
   setClickEvent,
   setCssClass,
+  defineClass,
   setLink,
   getTooltip,
   setTooltip,
@@ -531,4 +752,5 @@ export default {
   getNamespace,
   getNamespaces,
   setCssStyle,
+  getData,
 };
diff --git a/packages/mermaid/src/diagrams/class/classDiagram-styles.spec.js b/packages/mermaid/src/diagrams/class/classDiagram-styles.spec.js
index 957188401..18bdaade5 100644
--- a/packages/mermaid/src/diagrams/class/classDiagram-styles.spec.js
+++ b/packages/mermaid/src/diagrams/class/classDiagram-styles.spec.js
@@ -13,7 +13,7 @@ describe('class diagram, ', function () {
 
       parser.parse(str);
 
-      expect(parser.yy.getClass('Class01').cssClasses[0]).toBe('exClass');
+      expect(parser.yy.getClass('Class01').cssClasses).toBe('default exClass');
     });
 
     it('should be possible to apply a css class to a class directly with struct', function () {
@@ -28,7 +28,7 @@ describe('class diagram, ', function () {
       parser.parse(str);
 
       const testClass = parser.yy.getClass('Class1');
-      expect(testClass.cssClasses[0]).toBe('exClass');
+      expect(testClass.cssClasses).toBe('default exClass');
     });
 
     it('should be possible to apply a css class to a class with relations', function () {
@@ -36,7 +36,7 @@ describe('class diagram, ', function () {
 
       parser.parse(str);
 
-      expect(parser.yy.getClass('Class01').cssClasses[0]).toBe('exClass');
+      expect(parser.yy.getClass('Class01').cssClasses).toBe('default exClass');
     });
 
     it('should be possible to apply a cssClass to a class', function () {
@@ -44,7 +44,7 @@ describe('class diagram, ', function () {
 
       parser.parse(str);
 
-      expect(parser.yy.getClass('Class01').cssClasses[0]).toBe('exClass');
+      expect(parser.yy.getClass('Class01').cssClasses).toBe('default exClass');
     });
 
     it('should be possible to apply a cssClass to a comma separated list of classes', function () {
@@ -53,8 +53,8 @@ describe('class diagram, ', function () {
 
       parser.parse(str);
 
-      expect(parser.yy.getClass('Class01').cssClasses[0]).toBe('exClass');
-      expect(parser.yy.getClass('Class02').cssClasses[0]).toBe('exClass');
+      expect(parser.yy.getClass('Class01').cssClasses).toBe('default exClass');
+      expect(parser.yy.getClass('Class02').cssClasses).toBe('default exClass');
     });
     it('should be possible to apply a style to an individual node', function () {
       const str =
@@ -69,5 +69,47 @@ describe('class diagram, ', function () {
       expect(styleElements[1]).toBe('stroke:#333');
       expect(styleElements[2]).toBe('stroke-width:4px');
     });
+    it('should be possible to define and assign a class inside the diagram', function () {
+      const str =
+        'classDiagram\n' + 'class Class01\n cssClass "Class01" pink\n classDef pink fill:#f9f';
+
+      parser.parse(str);
+
+      expect(parser.yy.getClass('Class01').cssClasses).toBe('default pink');
+    });
+    it('should be possible to define and assign a class using shorthand inside the diagram', function () {
+      const str = 'classDiagram\n' + 'class Class01:::pink\n classDef pink fill:#f9f';
+
+      parser.parse(str);
+
+      expect(parser.yy.getClass('Class01').cssClasses).toBe('default pink');
+    });
+    it('should properly assign styles from a class defined inside the diagram', function () {
+      const str =
+        'classDiagram\n' +
+        'class Class01:::pink\n classDef pink fill:#f9f,stroke:#333,stroke-width:6px';
+
+      parser.parse(str);
+
+      expect(parser.yy.getClass('Class01').styles).toStrictEqual([
+        'fill:#f9f',
+        'stroke:#333',
+        'stroke-width:6px',
+      ]);
+    });
+    it('should properly assign multiple classes and styles from classes defined inside the diagram', function () {
+      const str =
+        'classDiagram\n' +
+        'class Class01:::pink\n cssClass "Class01" bold\n classDef pink fill:#f9f\n classDef bold stroke:#333,stroke-width:6px';
+
+      parser.parse(str);
+
+      expect(parser.yy.getClass('Class01').styles).toStrictEqual([
+        'fill:#f9f',
+        'stroke:#333',
+        'stroke-width:6px',
+      ]);
+      expect(parser.yy.getClass('Class01').cssClasses).toBe('default pink bold');
+    });
   });
 });
diff --git a/packages/mermaid/src/diagrams/class/classDiagram-v2.ts b/packages/mermaid/src/diagrams/class/classDiagram-v2.ts
index ec5398d29..6a3747e41 100644
--- a/packages/mermaid/src/diagrams/class/classDiagram-v2.ts
+++ b/packages/mermaid/src/diagrams/class/classDiagram-v2.ts
@@ -3,7 +3,7 @@ import type { DiagramDefinition } from '../../diagram-api/types.js';
 import parser from './parser/classDiagram.jison';
 import db from './classDb.js';
 import styles from './styles.js';
-import renderer from './classRenderer-v2.js';
+import renderer from './classRenderer-v3-unified.js';
 
 export const diagram: DiagramDefinition = {
   parser,
diff --git a/packages/mermaid/src/diagrams/class/classDiagram.spec.ts b/packages/mermaid/src/diagrams/class/classDiagram.spec.ts
index 7153ff8ca..938c49f56 100644
--- a/packages/mermaid/src/diagrams/class/classDiagram.spec.ts
+++ b/packages/mermaid/src/diagrams/class/classDiagram.spec.ts
@@ -14,6 +14,78 @@ describe('given a basic class diagram, ', function () {
       classDb.clear();
       parser.yy = classDb;
     });
+    it('should handle classes within namespaces', () => {
+      const str = `classDiagram
+        namespace Company.Project {
+          class User {
+            +login(username: String, password: String)
+            +logout()
+          }
+        }
+        namespace Company.Project.Module {
+          class Admin {
+            +addUser(user: User)
+            +removeUser(user: User)
+          }
+        }`;
+
+      parser.parse(str);
+
+      const user = classDb.getClass('User');
+      const admin = classDb.getClass('Admin');
+
+      // Check if the classes are correctly registered under their respective namespaces
+      expect(user.parent).toBe('Company.Project');
+      expect(admin.parent).toBe('Company.Project.Module');
+      expect(user.methods.length).toBe(2);
+      expect(admin.methods.length).toBe(2);
+    });
+
+    it('should handle generic classes within namespaces', () => {
+      const str = `classDiagram
+    namespace Company.Project.Module {
+        class GenericClass~T~ {
+            +addItem(item: T)
+            +getItem() T
+        }
+    }`;
+
+      parser.parse(str);
+
+      const genericClass = classDb.getClass('GenericClass');
+      expect(genericClass.type).toBe('T');
+      expect(genericClass.methods[0].getDisplayDetails().displayText).toBe('+addItem(item: T)');
+      expect(genericClass.methods[1].getDisplayDetails().displayText).toBe('+getItem() : T');
+    });
+
+    it('should handle nested namespaces and relationships', () => {
+      const str = `      classDiagram
+        namespace Company.Project.Module.SubModule {
+          class Report {
+            +generatePDF(data: List)
+            +generateCSV(data: List)
+          }
+        }
+        namespace Company.Project.Module {
+          class Admin {
+            +generateReport()
+          }
+        }
+        Admin --> Report : generates`;
+
+      parser.parse(str);
+
+      const report = classDb.getClass('Report');
+      const admin = classDb.getClass('Admin');
+      const relations = classDb.getRelations();
+
+      expect(report.parent).toBe('Company.Project.Module.SubModule');
+      expect(admin.parent).toBe('Company.Project.Module');
+      expect(relations[0].id1).toBe('Admin');
+      expect(relations[0].id2).toBe('Report');
+      expect(relations[0].title).toBe('generates');
+    });
+
     it('should handle accTitle and accDescr', function () {
       const str = `classDiagram
             accTitle: My Title
@@ -48,6 +120,22 @@ describe('given a basic class diagram, ', function () {
       }
     });
 
+    it('should handle fully qualified class names in relationships', () => {
+      const str = `classDiagram
+        namespace Company.Project.Module {
+          class User
+          class Admin
+        }
+          Admin --> User : manages`;
+
+      parser.parse(str);
+
+      const relations = classDb.getRelations();
+      expect(relations[0].id1).toBe('Admin');
+      expect(relations[0].id2).toBe('User');
+      expect(relations[0].title).toBe('manages');
+    });
+
     it('should handle backquoted class names', function () {
       const str = 'classDiagram\n' + 'class `Car`';
 
@@ -158,7 +246,7 @@ describe('given a basic class diagram, ', function () {
 
       const c1 = classDb.getClass('C1');
       expect(c1.label).toBe('Class 1 with text label');
-      expect(c1.cssClasses[0]).toBe('styleClass');
+      expect(c1.cssClasses).toBe('default styleClass');
     });
 
     it('should parse a class with text label and css class', () => {
@@ -173,7 +261,7 @@ describe('given a basic class diagram, ', function () {
       const c1 = classDb.getClass('C1');
       expect(c1.label).toBe('Class 1 with text label');
       expect(c1.members[0].getDisplayDetails().displayText).toBe('int member1');
-      expect(c1.cssClasses[0]).toBe('styleClass');
+      expect(c1.cssClasses).toBe('default styleClass');
     });
 
     it('should parse two classes with text labels and css classes', () => {
@@ -188,11 +276,11 @@ describe('given a basic class diagram, ', function () {
 
       const c1 = classDb.getClass('C1');
       expect(c1.label).toBe('Class 1 with text label');
-      expect(c1.cssClasses[0]).toBe('styleClass');
+      expect(c1.cssClasses).toBe('default styleClass');
 
       const c2 = classDb.getClass('C2');
       expect(c2.label).toBe('Long long long long long long long long long long label');
-      expect(c2.cssClasses[0]).toBe('styleClass');
+      expect(c2.cssClasses).toBe('default styleClass');
     });
 
     it('should parse two classes with text labels and css class shorthands', () => {
@@ -205,11 +293,11 @@ describe('given a basic class diagram, ', function () {
 
       const c1 = classDb.getClass('C1');
       expect(c1.label).toBe('Class 1 with text label');
-      expect(c1.cssClasses[0]).toBe('styleClass1');
+      expect(c1.cssClasses).toBe('default styleClass1');
 
       const c2 = classDb.getClass('C2');
       expect(c2.label).toBe('Class 2 !@#$%^&*() label');
-      expect(c2.cssClasses[0]).toBe('styleClass2');
+      expect(c2.cssClasses).toBe('default styleClass2');
     });
 
     it('should parse multiple classes with same text labels', () => {
@@ -393,12 +481,27 @@ class C13["With Città foreign language"]
           Student "1" --o "1" IdCard : carries
           Student "1" --o "1" Bike : rides`);
 
-      expect(classDb.getClasses().size).toBe(3);
+      const studentClass = classDb.getClasses().get('Student');
+      // Check that the important properties match, but ignore the domId
+      expect(studentClass).toMatchObject({
+        id: 'Student',
+        label: 'Student',
+        members: [
+          expect.objectContaining({
+            id: 'idCard : IdCard',
+            visibility: '-',
+          }),
+        ],
+        methods: [],
+        annotations: [],
+        cssClasses: 'default',
+      });
+
       expect(classDb.getClasses().get('Student')).toMatchInlineSnapshot(`
         {
           "annotations": [],
-          "cssClasses": [],
-          "domId": "classId-Student-134",
+          "cssClasses": "default",
+          "domId": "classId-Student-141",
           "id": "Student",
           "label": "Student",
           "members": [
@@ -406,11 +509,14 @@ class C13["With Città foreign language"]
               "classifier": "",
               "id": "idCard : IdCard",
               "memberType": "attribute",
+              "text": "\\-idCard : IdCard",
               "visibility": "-",
             },
           ],
           "methods": [],
+          "shape": "classBox",
           "styles": [],
+          "text": "Student",
           "type": "",
         }
       `);
@@ -654,7 +760,7 @@ foo()
 
       const actual = parser.yy.getClass('Class1');
       expect(actual.link).toBe('google.com');
-      expect(actual.cssClasses[0]).toBe('clickable');
+      expect(actual.cssClasses).toBe('default clickable');
     });
 
     it('should handle href link with tooltip', function () {
@@ -670,7 +776,7 @@ foo()
       const actual = parser.yy.getClass('Class1');
       expect(actual.link).toBe('google.com');
       expect(actual.tooltip).toBe('A Tooltip');
-      expect(actual.cssClasses[0]).toBe('clickable');
+      expect(actual.cssClasses).toBe('default clickable');
     });
 
     it('should handle href link with tooltip and target', function () {
@@ -689,7 +795,7 @@ foo()
       const actual = parser.yy.getClass('Class1');
       expect(actual.link).toBe('google.com');
       expect(actual.tooltip).toBe('A tooltip');
-      expect(actual.cssClasses[0]).toBe('clickable');
+      expect(actual.cssClasses).toBe('default clickable');
     });
 
     it('should handle function call', function () {
@@ -1384,8 +1490,7 @@ describe('given a class diagram with relationships, ', function () {
 
       const testClass = parser.yy.getClass('Class1');
       expect(testClass.link).toBe('google.com');
-      expect(testClass.cssClasses.length).toBe(1);
-      expect(testClass.cssClasses[0]).toBe('clickable');
+      expect(testClass.cssClasses).toBe('default clickable');
     });
 
     it('should associate click and href link and css appropriately', function () {
@@ -1398,8 +1503,7 @@ describe('given a class diagram with relationships, ', function () {
 
       const testClass = parser.yy.getClass('Class1');
       expect(testClass.link).toBe('google.com');
-      expect(testClass.cssClasses.length).toBe(1);
-      expect(testClass.cssClasses[0]).toBe('clickable');
+      expect(testClass.cssClasses).toBe('default clickable');
     });
 
     it('should associate link with tooltip', function () {
@@ -1413,8 +1517,7 @@ describe('given a class diagram with relationships, ', function () {
       const testClass = parser.yy.getClass('Class1');
       expect(testClass.link).toBe('google.com');
       expect(testClass.tooltip).toBe('A tooltip');
-      expect(testClass.cssClasses.length).toBe(1);
-      expect(testClass.cssClasses[0]).toBe('clickable');
+      expect(testClass.cssClasses).toBe('default clickable');
     });
 
     it('should associate click and href link with tooltip', function () {
@@ -1428,8 +1531,7 @@ describe('given a class diagram with relationships, ', function () {
       const testClass = parser.yy.getClass('Class1');
       expect(testClass.link).toBe('google.com');
       expect(testClass.tooltip).toBe('A tooltip');
-      expect(testClass.cssClasses.length).toBe(1);
-      expect(testClass.cssClasses[0]).toBe('clickable');
+      expect(testClass.cssClasses).toBe('default clickable');
     });
 
     it('should associate click and href link with tooltip and target appropriately', function () {
@@ -1686,8 +1788,7 @@ C1 -->  C2
 
       const c1 = classDb.getClass('C1');
       expect(c1.label).toBe('Class 1 with text label');
-      expect(c1.cssClasses.length).toBe(1);
-      expect(c1.cssClasses[0]).toBe('styleClass');
+      expect(c1.cssClasses).toBe('default styleClass');
       const member = c1.members[0];
       expect(member.getDisplayDetails().displayText).toBe('+member1');
     });
@@ -1703,8 +1804,7 @@ cssClass "C1" styleClass
 
       const c1 = classDb.getClass('C1');
       expect(c1.label).toBe('Class 1 with text label');
-      expect(c1.cssClasses.length).toBe(1);
-      expect(c1.cssClasses[0]).toBe('styleClass');
+      expect(c1.cssClasses).toBe('default styleClass');
       const member = c1.members[0];
       expect(member.getDisplayDetails().displayText).toBe('+member1');
     });
@@ -1721,13 +1821,11 @@ cssClass "C1,C2" styleClass
 
       const c1 = classDb.getClass('C1');
       expect(c1.label).toBe('Class 1 with text label');
-      expect(c1.cssClasses.length).toBe(1);
-      expect(c1.cssClasses[0]).toBe('styleClass');
+      expect(c1.cssClasses).toBe('default styleClass');
 
       const c2 = classDb.getClass('C2');
       expect(c2.label).toBe('Long long long long long long long long long long label');
-      expect(c2.cssClasses.length).toBe(1);
-      expect(c2.cssClasses[0]).toBe('styleClass');
+      expect(c2.cssClasses).toBe('default styleClass');
     });
 
     it('should parse two classes with text labels and css class shorthands', () => {
@@ -1741,13 +1839,11 @@ C1 --> C2
 
       const c1 = classDb.getClass('C1');
       expect(c1.label).toBe('Class 1 with text label');
-      expect(c1.cssClasses.length).toBe(1);
-      expect(c1.cssClasses[0]).toBe('styleClass1');
+      expect(c1.cssClasses).toBe('default styleClass1');
 
       const c2 = classDb.getClass('C2');
       expect(c2.label).toBe('Class 2 !@#$%^&*() label');
-      expect(c2.cssClasses.length).toBe(1);
-      expect(c2.cssClasses[0]).toBe('styleClass2');
+      expect(c2.cssClasses).toBe('default styleClass2');
     });
 
     it('should parse multiple classes with same text labels', () => {
diff --git a/packages/mermaid/src/diagrams/class/classDiagram.ts b/packages/mermaid/src/diagrams/class/classDiagram.ts
index 7f027c186..6a3747e41 100644
--- a/packages/mermaid/src/diagrams/class/classDiagram.ts
+++ b/packages/mermaid/src/diagrams/class/classDiagram.ts
@@ -3,7 +3,7 @@ import type { DiagramDefinition } from '../../diagram-api/types.js';
 import parser from './parser/classDiagram.jison';
 import db from './classDb.js';
 import styles from './styles.js';
-import renderer from './classRenderer.js';
+import renderer from './classRenderer-v3-unified.js';
 
 export const diagram: DiagramDefinition = {
   parser,
diff --git a/packages/mermaid/src/diagrams/class/classRenderer-v3-unified.ts b/packages/mermaid/src/diagrams/class/classRenderer-v3-unified.ts
new file mode 100644
index 000000000..670f93f16
--- /dev/null
+++ b/packages/mermaid/src/diagrams/class/classRenderer-v3-unified.ts
@@ -0,0 +1,79 @@
+import { getConfig } from '../../diagram-api/diagramAPI.js';
+import type { DiagramStyleClassDef } from '../../diagram-api/types.js';
+import { log } from '../../logger.js';
+import { getDiagramElement } from '../../rendering-util/insertElementsForSize.js';
+import { getRegisteredLayoutAlgorithm, render } from '../../rendering-util/render.js';
+import { setupViewPortForSVG } from '../../rendering-util/setupViewPortForSVG.js';
+import type { LayoutData } from '../../rendering-util/types.js';
+import utils from '../../utils.js';
+
+/**
+ * Get the direction from the statement items.
+ * Look through all of the documents (docs) in the parsedItems
+ * Because is a _document_ direction, the default direction is not necessarily the same as the overall default _diagram_ direction.
+ * @param parsedItem - the parsed statement item to look through
+ * @param defaultDir - the direction to use if none is found
+ * @returns The direction to use
+ */
+export const getDir = (parsedItem: any, defaultDir = 'TB') => {
+  if (!parsedItem.doc) {
+    return defaultDir;
+  }
+
+  let dir = defaultDir;
+
+  for (const parsedItemDoc of parsedItem.doc) {
+    if (parsedItemDoc.stmt === 'dir') {
+      dir = parsedItemDoc.value;
+    }
+  }
+
+  return dir;
+};
+
+export const getClasses = function (
+  text: string,
+  diagramObj: any
+): Map {
+  return diagramObj.db.getClasses();
+};
+
+export const draw = async function (text: string, id: string, _version: string, diag: any) {
+  log.info('REF0:');
+  log.info('Drawing class diagram (v3)', id);
+  const { securityLevel, state: conf, layout } = getConfig();
+  // Extracting the data from the parsed structure into a more usable form
+  // Not related to the refactoring, but this is the first step in the rendering process
+  // diag.db.extract(diag.db.getRootDocV2());
+
+  // The getData method provided in all supported diagrams is used to extract the data from the parsed structure
+  // into the Layout data format
+  const data4Layout = diag.db.getData() as LayoutData;
+
+  // Create the root SVG - the element is the div containing the SVG element
+  const svg = getDiagramElement(id, securityLevel);
+
+  data4Layout.type = diag.type;
+  data4Layout.layoutAlgorithm = getRegisteredLayoutAlgorithm(layout);
+
+  data4Layout.nodeSpacing = conf?.nodeSpacing || 50;
+  data4Layout.rankSpacing = conf?.rankSpacing || 50;
+  data4Layout.markers = ['aggregation', 'extension', 'composition', 'dependency', 'lollipop'];
+  data4Layout.diagramId = id;
+  await render(data4Layout, svg);
+  const padding = 8;
+  utils.insertTitle(
+    svg,
+    'classDiagramTitleText',
+    conf?.titleTopMargin ?? 25,
+    diag.db.getDiagramTitle()
+  );
+
+  setupViewPortForSVG(svg, padding, 'classDiagram', conf?.useMaxWidth ?? true);
+};
+
+export default {
+  getClasses,
+  draw,
+  getDir,
+};
diff --git a/packages/mermaid/src/diagrams/class/classTypes.ts b/packages/mermaid/src/diagrams/class/classTypes.ts
index fe352d863..1f406e80f 100644
--- a/packages/mermaid/src/diagrams/class/classTypes.ts
+++ b/packages/mermaid/src/diagrams/class/classTypes.ts
@@ -5,7 +5,9 @@ export interface ClassNode {
   id: string;
   type: string;
   label: string;
-  cssClasses: string[];
+  shape: string;
+  text: string;
+  cssClasses: string;
   methods: ClassMember[];
   members: ClassMember[];
   annotations: string[];
@@ -16,6 +18,7 @@ export interface ClassNode {
   linkTarget?: string;
   haveCallback?: boolean;
   tooltip?: string;
+  look?: string;
 }
 
 export type Visibility = '#' | '+' | '~' | '-' | '';
@@ -30,6 +33,7 @@ export class ClassMember {
   cssStyle!: string;
   memberType!: 'method' | 'attribute';
   visibility!: Visibility;
+  text: string;
   /**
    * denote if static or to determine which css class to apply to the node
    * @defaultValue ''
@@ -50,6 +54,7 @@ export class ClassMember {
     this.memberType = memberType;
     this.visibility = '';
     this.classifier = '';
+    this.text = '';
     const sanitizedInput = sanitizeText(input, getConfig());
     this.parseMember(sanitizedInput);
   }
@@ -85,7 +90,7 @@ export class ClassMember {
           this.visibility = detectedVisibility as Visibility;
         }
 
-        this.id = match[2].trim();
+        this.id = match[2];
         this.parameters = match[3] ? match[3].trim() : '';
         potentialClassifier = match[4] ? match[4].trim() : '';
         this.returnType = match[5] ? match[5].trim() : '';
@@ -118,6 +123,14 @@ export class ClassMember {
     }
 
     this.classifier = potentialClassifier;
+    // Preserve one space only
+    this.id = this.id.startsWith(' ') ? ' ' + this.id.trim() : this.id.trim();
+
+    const combinedText = `${this.visibility ? '\\' + this.visibility : ''}${parseGenericTypes(this.id)}${this.memberType === 'method' ? `(${parseGenericTypes(this.parameters)})${this.returnType ? ' : ' + parseGenericTypes(this.returnType) : ''}` : ''}`;
+    this.text = combinedText.replaceAll('<', '<').replaceAll('>', '>');
+    if (this.text.startsWith('\\<')) {
+      this.text = this.text.replace('\\<', '~');
+    }
   }
 
   parseClassifier() {
@@ -156,6 +169,12 @@ export interface ClassRelation {
   };
 }
 
+export interface Interface {
+  id: string;
+  label: string;
+  classId: string;
+}
+
 export interface NamespaceNode {
   id: string;
   domId: string;
@@ -164,6 +183,12 @@ export interface NamespaceNode {
   children: NamespaceMap;
 }
 
+export interface StyleClass {
+  id: string;
+  styles: string[];
+  textStyles: string[];
+}
+
 export type ClassMap = Map;
 export type ClassNoteMap = Map;
 export type NamespaceMap = Map;
diff --git a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison
index 230bbfcb7..b1d62a3ff 100644
--- a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison
+++ b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison
@@ -61,6 +61,7 @@ Function arguments are optional: 'call ()' simply executes 'callb
 [^"]*                   return "STR";
 <*>["]                          this.begin("string");
 "style"                         return 'STYLE';
+"classDef"                      return 'CLASSDEF';
 
 "namespace"  { this.begin('namespace'); return 'NAMESPACE'; }
 \s*(\r?\n)+          { this.popState(); return 'NEWLINE'; }
@@ -241,11 +242,13 @@ classLabel
 
 namespaceName
     : alphaNumToken { $$=$1; }
+    | alphaNumToken DOT namespaceName { $$=$1+'.'+$3; }
     | alphaNumToken namespaceName { $$=$1+$2; }
     ;
 
 className
     : alphaNumToken { $$=$1; }
+    | alphaNumToken DOT className { $$=$1+'.'+$3; }
     | classLiteralName { $$=$1; }
     | alphaNumToken className { $$=$1+$2; }
     | alphaNumToken GENERICTYPE { $$=$1+'~'+$2+'~'; }
@@ -263,6 +266,7 @@ statement
     | styleStatement
     | cssClassStatement
     | noteStatement
+    | classDefStatement
     | direction
     | acc_title acc_title_value  { $$=$2.trim();yy.setAccTitle($$); }
     | acc_descr acc_descr_value  { $$=$2.trim();yy.setAccDescription($$); }
@@ -270,12 +274,12 @@ statement
     ;
 
 namespaceStatement
-    : namespaceIdentifier STRUCT_START classStatements STRUCT_STOP          {yy.addClassesToNamespace($1, $3[0], $3[1]);}
-    | namespaceIdentifier STRUCT_START NEWLINE classStatements STRUCT_STOP  {yy.addClassesToNamespace($1, $4[0], $4[1]);}
+    : namespaceIdentifier STRUCT_START classStatements STRUCT_STOP          { yy.addClassesToNamespace($1, $3[0], $3[1]); }
+    | namespaceIdentifier STRUCT_START NEWLINE classStatements STRUCT_STOP  { yy.addClassesToNamespace($1, $4[0], $4[1]); }
     ;
 
 namespaceIdentifier
-    : NAMESPACE namespaceName   {$$=$2; yy.addNamespace($2);}
+    : NAMESPACE namespaceName { $$=$2; yy.addNamespace($2); }
     ;
 
 classStatements
@@ -323,8 +327,17 @@ relationStatement
     ;
 
 noteStatement
-    : NOTE_FOR className noteText  { $$=yy.addNote($3, $2); }
-    | NOTE noteText                { $$=yy.addNote($2); }
+    : NOTE_FOR className noteText  { $$ = yy.addNote($3, $2); }
+    | NOTE noteText                { $$ = yy.addNote($2); }
+    ;
+
+classDefStatement
+    : CLASSDEF classList stylesOpt {$$ = $CLASSDEF;yy.defineClass($classList,$stylesOpt);}
+    ;
+
+classList
+    : ALPHA { $$ = [$ALPHA]; }
+    | classList COMMA ALPHA = { $$ = $classList.concat([$ALPHA]); }
     ;
 
 direction
diff --git a/packages/mermaid/src/diagrams/class/shapeUtil.ts b/packages/mermaid/src/diagrams/class/shapeUtil.ts
new file mode 100644
index 000000000..94c8f817a
--- /dev/null
+++ b/packages/mermaid/src/diagrams/class/shapeUtil.ts
@@ -0,0 +1,223 @@
+import { select } from 'd3';
+import { getConfig } from '../../config.js';
+import { getNodeClasses } from '../../rendering-util/rendering-elements/shapes/util.js';
+import { calculateTextWidth, decodeEntities } from '../../utils.js';
+import type { ClassMember, ClassNode } from './classTypes.js';
+import { sanitizeText } from '../../diagram-api/diagramAPI.js';
+import { createText } from '../../rendering-util/createText.js';
+import { evaluate, hasKatex } from '../common/common.js';
+import type { Node } from '../../rendering-util/types.js';
+import type { MermaidConfig } from '../../config.type.js';
+import type { D3Selection } from '../../types.js';
+
+// Creates the shapeSvg and inserts text
+export async function textHelper(
+  parent: D3Selection,
+  node: any,
+  config: MermaidConfig,
+  useHtmlLabels: boolean,
+  GAP = config.class!.padding ?? 12
+) {
+  const TEXT_PADDING = !useHtmlLabels ? 3 : 0;
+  const shapeSvg = parent
+    // @ts-ignore: Ignore error for using .insert on SVGAElement
+    .insert('g')
+    .attr('class', getNodeClasses(node))
+    .attr('id', node.domId || node.id);
+
+  let annotationGroup = null;
+  let labelGroup = null;
+  let membersGroup = null;
+  let methodsGroup = null;
+
+  let annotationGroupHeight = 0;
+  let labelGroupHeight = 0;
+  let membersGroupHeight = 0;
+
+  annotationGroup = shapeSvg.insert('g').attr('class', 'annotation-group text');
+  if (node.annotations.length > 0) {
+    const annotation = node.annotations[0];
+    await addText(annotationGroup, { text: `«${annotation}»` } as unknown as ClassMember, 0);
+
+    const annotationGroupBBox = annotationGroup.node()!.getBBox();
+    annotationGroupHeight = annotationGroupBBox.height;
+  }
+
+  labelGroup = shapeSvg.insert('g').attr('class', 'label-group text');
+  await addText(labelGroup, node, 0, ['font-weight: bolder']);
+  const labelGroupBBox = labelGroup.node()!.getBBox();
+  labelGroupHeight = labelGroupBBox.height;
+
+  membersGroup = shapeSvg.insert('g').attr('class', 'members-group text');
+  let yOffset = 0;
+  for (const member of node.members) {
+    const height = await addText(membersGroup, member, yOffset, [member.parseClassifier()]);
+    yOffset += height + TEXT_PADDING;
+  }
+  membersGroupHeight = membersGroup.node()!.getBBox().height;
+  if (membersGroupHeight <= 0) {
+    membersGroupHeight = GAP / 2;
+  }
+
+  methodsGroup = shapeSvg.insert('g').attr('class', 'methods-group text');
+  let methodsYOffset = 0;
+  for (const method of node.methods) {
+    const height = await addText(methodsGroup, method, methodsYOffset, [method.parseClassifier()]);
+    methodsYOffset += height + TEXT_PADDING;
+  }
+
+  let bbox = shapeSvg.node()!.getBBox();
+
+  // Center annotation
+  if (annotationGroup !== null) {
+    const annotationGroupBBox = annotationGroup.node()!.getBBox();
+    annotationGroup.attr('transform', `translate(${-annotationGroupBBox.width / 2})`);
+  }
+
+  // Adjust label
+  labelGroup.attr('transform', `translate(${-labelGroupBBox.width / 2}, ${annotationGroupHeight})`);
+
+  bbox = shapeSvg.node()!.getBBox();
+
+  membersGroup.attr(
+    'transform',
+    `translate(${0}, ${annotationGroupHeight + labelGroupHeight + GAP * 2})`
+  );
+  bbox = shapeSvg.node()!.getBBox();
+  methodsGroup.attr(
+    'transform',
+    `translate(${0}, ${annotationGroupHeight + labelGroupHeight + (membersGroupHeight ? membersGroupHeight + GAP * 4 : GAP * 2)})`
+  );
+
+  bbox = shapeSvg.node()!.getBBox();
+
+  return { shapeSvg, bbox };
+}
+
+// Modified version of labelHelper() to help create and place text for classes
+async function addText(
+  parentGroup: D3Selection,
+  node: Node | ClassNode | ClassMember,
+  yOffset: number,
+  styles: string[] = []
+) {
+  const textEl = parentGroup.insert('g').attr('class', 'label').attr('style', styles.join('; '));
+  const config = getConfig();
+  let useHtmlLabels =
+    'useHtmlLabels' in node ? node.useHtmlLabels : (evaluate(config.htmlLabels) ?? true);
+
+  let textContent = '';
+  // Support regular node type (.label) and classNodes (.text)
+  if ('text' in node) {
+    textContent = node.text;
+  } else {
+    textContent = node.label!;
+  }
+
+  // createText() will cause unwanted behavior because of classDiagram syntax so workarounds are needed
+
+  if (!useHtmlLabels && textContent.startsWith('\\')) {
+    textContent = textContent.substring(1);
+  }
+
+  if (hasKatex(textContent)) {
+    useHtmlLabels = true;
+  }
+
+  const text = await createText(
+    textEl,
+    sanitizeText(decodeEntities(textContent)),
+    {
+      width: calculateTextWidth(textContent, config) + 50, // Add room for error when splitting text into multiple lines
+      classes: 'markdown-node-label',
+      useHtmlLabels,
+    },
+    config
+  );
+  let bbox;
+  let numberOfLines = 1;
+
+  if (!useHtmlLabels) {
+    // Undo font-weight normal
+    if (styles.includes('font-weight: bolder')) {
+      select(text).selectAll('tspan').attr('font-weight', '');
+    }
+
+    numberOfLines = text.children.length;
+
+    const textChild = text.children[0];
+    if (text.textContent === '' || text.textContent.includes('>')) {
+      textChild.textContent =
+        textContent[0] +
+        textContent.substring(1).replaceAll('>', '>').replaceAll('<', '<').trim();
+
+      // Text was improperly removed due to spaces (preserve one space if present)
+      const preserveSpace = textContent[1] === ' ';
+      if (preserveSpace) {
+        textChild.textContent = textChild.textContent[0] + ' ' + textChild.textContent.substring(1);
+      }
+    }
+
+    // To support empty boxes
+    if (textChild.textContent === 'undefined') {
+      textChild.textContent = '';
+    }
+
+    // Get the bounding box after the text update
+    bbox = text.getBBox();
+  } else {
+    const div = text.children[0];
+    const dv = select(text);
+
+    numberOfLines = div.innerHTML.split('
').length; + // Katex math support + if (div.innerHTML.includes('')) { + numberOfLines += div.innerHTML.split('').length - 1; + } + + // Support images + const images = div.getElementsByTagName('img'); + if (images) { + const noImgText = textContent.replace(/]*>/g, '').trim() === ''; + await Promise.all( + [...images].map( + (img) => + new Promise((res) => { + function setupImage() { + img.style.display = 'flex'; + img.style.flexDirection = 'column'; + + if (noImgText) { + // default size if no text + const bodyFontSize = + config.fontSize?.toString() ?? window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + const width = parseInt(bodyFontSize, 10) * enlargingFactor + 'px'; + img.style.minWidth = width; + img.style.maxWidth = width; + } else { + img.style.width = '100%'; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener('error', setupImage); + img.addEventListener('load', setupImage); + }) + ) + ); + } + + bbox = div.getBoundingClientRect(); + dv.attr('width', bbox.width); + dv.attr('height', bbox.height); + } + + // Center text and offset by yOffset + textEl.attr('transform', 'translate(0,' + (-bbox.height / (2 * numberOfLines) + yOffset) + ')'); + return bbox.height; +} diff --git a/packages/mermaid/src/diagrams/class/styles.js b/packages/mermaid/src/diagrams/class/styles.js index 9bad27f38..4a888a265 100644 --- a/packages/mermaid/src/diagrams/class/styles.js +++ b/packages/mermaid/src/diagrams/class/styles.js @@ -20,6 +20,10 @@ const getStyles = (options) => .label text { fill: ${options.classText}; } + +.labelBkg { + background: ${options.mainBkg}; +} .edgeLabel .label span { background: ${options.mainBkg}; } diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts index 488ecc83d..1dbc789c9 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts +++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts @@ -2,8 +2,10 @@ import { select } from 'd3'; import utils, { getEdgeId } from '../../utils.js'; import { getConfig, defaultConfig } from '../../diagram-api/diagramAPI.js'; import common from '../common/common.js'; +import { isValidShape, type ShapeID } from '../../rendering-util/rendering-elements/shapes.js'; import type { Node, Edge } from '../../rendering-util/types.js'; import { log } from '../../logger.js'; +import * as yaml from 'js-yaml'; import { setAccTitle, getAccTitle, @@ -13,7 +15,16 @@ import { setDiagramTitle, getDiagramTitle, } from '../common/commonDb.js'; -import type { FlowVertex, FlowClass, FlowSubGraph, FlowText, FlowEdge, FlowLink } from './types.js'; +import type { + FlowVertex, + FlowClass, + FlowSubGraph, + FlowText, + FlowEdge, + FlowLink, + FlowVertexTypeParam, +} from './types.js'; +import type { NodeMetaData } from '../../types.js'; const MERMAID_DOM_ID_PREFIX = 'flowchart-'; let vertexCounter = 0; @@ -51,17 +62,18 @@ export const lookUpDomId = function (id: string) { /** * Function called by parser when a node definition has been found - * */ export const addVertex = function ( id: string, textObj: FlowText, - type: 'group', + type: FlowVertexTypeParam, style: string[], classes: string[], dir: string, - props = {} + props = {}, + shapeData: any ) { + // console.log('addVertex', id, shapeData); if (!id || id.trim().length === 0) { return; } @@ -115,6 +127,60 @@ export const addVertex = function ( } else if (props !== undefined) { Object.assign(vertex.props, props); } + + if (shapeData !== undefined) { + let yamlData; + // detect if shapeData contains a newline character + // console.log('shapeData', shapeData); + if (!shapeData.includes('\n')) { + // console.log('yamlData shapeData has no new lines', shapeData); + yamlData = '{\n' + shapeData + '\n}'; + } else { + // console.log('yamlData shapeData has new lines', shapeData); + yamlData = shapeData + '\n'; + } + // console.log('yamlData', yamlData); + const doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA }) as NodeMetaData; + if (doc.shape) { + if (doc.shape !== doc.shape.toLowerCase() || doc.shape.includes('_')) { + throw new Error(`No such shape: ${doc.shape}. Shape names should be lowercase.`); + } else if (!isValidShape(doc.shape)) { + throw new Error(`No such shape: ${doc.shape}.`); + } + vertex.type = doc?.shape; + } + + if (doc?.label) { + vertex.text = doc?.label; + } + if (doc?.icon) { + vertex.icon = doc?.icon; + if (!doc.label?.trim() && vertex.text === id) { + vertex.text = ''; + } + } + if (doc?.form) { + vertex.form = doc?.form; + } + if (doc?.pos) { + vertex.pos = doc?.pos; + } + if (doc?.img) { + vertex.img = doc?.img; + if (!doc.label?.trim() && vertex.text === id) { + vertex.text = ''; + } + } + if (doc?.constraint) { + vertex.constraint = doc.constraint; + } + if (doc.w) { + vertex.assetWidth = Number(doc.w); + } + if (doc.h) { + vertex.assetHeight = Number(doc.h); + } + } }; /** @@ -425,7 +491,6 @@ const setupToolTips = function (element: Element) { } const rect = (this as Element)?.getBoundingClientRect(); - // @ts-ignore TODO: fix this tooltipElem.transition().duration(200).style('opacity', '.9'); tooltipElem .text(el.attr('title')) @@ -435,7 +500,6 @@ const setupToolTips = function (element: Element) { el.classed('hover', true); }) .on('mouseout', function () { - // @ts-ignore TODO: fix this tooltipElem.transition().duration(500).style('opacity', 0); const el = select(this); el.classed('hover', false); @@ -761,15 +825,34 @@ export const lex = { firstGraph, }; -const getTypeFromVertex = (vertex: FlowVertex) => { - if (vertex.type === 'square') { - return 'squareRect'; +const getTypeFromVertex = (vertex: FlowVertex): ShapeID => { + if (vertex.img) { + return 'imageSquare'; } - if (vertex.type === 'round') { - return 'roundedRect'; + if (vertex.icon) { + if (vertex.form === 'circle') { + return 'iconCircle'; + } + if (vertex.form === 'square') { + return 'iconSquare'; + } + if (vertex.form === 'rounded') { + return 'iconRounded'; + } + return 'icon'; + } + switch (vertex.type) { + case 'square': + case undefined: + return 'squareRect'; + case 'round': + return 'roundedRect'; + case 'ellipse': + // @ts-expect-error -- Ellipses are broken, see https://github.com/mermaid-js/mermaid/issues/5976 + return 'ellipse'; + default: + return vertex.type; } - - return vertex.type ?? 'squareRect'; }; const findNode = (nodes: Node[], id: string) => nodes.find((node) => node.id === id); @@ -810,7 +893,7 @@ const addNodeFromVertex = ( node.cssCompiledStyles = getCompiledStyles(vertex.classes); node.cssClasses = vertex.classes.join(' '); } else { - nodes.push({ + const baseNode = { id: vertex.id, label: vertex.text, labelStyle: '', @@ -819,15 +902,32 @@ const addNodeFromVertex = ( cssStyles: vertex.styles, cssCompiledStyles: getCompiledStyles(['default', 'node', ...vertex.classes]), cssClasses: 'default ' + vertex.classes.join(' '), - shape: getTypeFromVertex(vertex), dir: vertex.dir, domId: vertex.domId, - isGroup, look, link: vertex.link, linkTarget: vertex.linkTarget, tooltip: getTooltip(vertex.id), - }); + icon: vertex.icon, + pos: vertex.pos, + img: vertex.img, + assetWidth: vertex.assetWidth, + assetHeight: vertex.assetHeight, + constraint: vertex.constraint, + }; + if (isGroup) { + nodes.push({ + ...baseNode, + isGroup: true, + shape: 'rect', + }); + } else { + nodes.push({ + ...baseNode, + isGroup: false, + shape: getTypeFromVertex(vertex), + }); + } } }; diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js new file mode 100644 index 000000000..1669cfada --- /dev/null +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js @@ -0,0 +1,293 @@ +import flowDb from '../flowDb.js'; +import flow from './flow.jison'; +import { setConfig } from '../../../config.js'; + +setConfig({ + securityLevel: 'strict', +}); + +describe('when parsing directions', function () { + beforeEach(function () { + flow.parser.yy = flowDb; + flow.parser.yy.clear(); + flow.parser.yy.setGen('gen-2'); + }); + + it('should handle basic shape data statements', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded}`); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + }); + it('should handle basic shape data statements', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded }`); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + }); + + it('should handle basic shape data statements with &', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded } & E`); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(2); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + expect(data4Layout.nodes[1].label).toEqual('E'); + }); + it('should handle shape data statements with edges', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded } --> E`); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(2); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + expect(data4Layout.nodes[1].label).toEqual('E'); + }); + it('should handle basic shape data statements with amp and edges 1', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded } & E --> F`); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(3); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + expect(data4Layout.nodes[1].label).toEqual('E'); + }); + it('should handle basic shape data statements with amp and edges 2', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded } & E@{ shape: rounded } --> F`); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(3); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + expect(data4Layout.nodes[1].label).toEqual('E'); + }); + it('should handle basic shape data statements with amp and edges 3', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded } & E@{ shape: rounded } --> F & G@{ shape: rounded }`); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(4); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + expect(data4Layout.nodes[1].label).toEqual('E'); + }); + it('should handle basic shape data statements with amp and edges 4', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded } & E@{ shape: rounded } --> F@{ shape: rounded } & G@{ shape: rounded }`); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(4); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + expect(data4Layout.nodes[1].label).toEqual('E'); + }); + it('should handle basic shape data statements with amp and edges 5, trailing space', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded } & E@{ shape: rounded } --> F{ shape: rounded } & G{ shape: rounded } `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(4); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + expect(data4Layout.nodes[1].label).toEqual('E'); + }); + it('should no matter of there are no leading spaces', function () { + const res = flow.parser.parse(`flowchart TB + D@{shape: rounded}`); + + const data4Layout = flow.parser.yy.getData(); + + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + }); + + it('should no matter of there are many leading spaces', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded}`); + + const data4Layout = flow.parser.yy.getData(); + + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + }); + + it('should be forgiving with many spaces before teh end', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded }`); + + const data4Layout = flow.parser.yy.getData(); + + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('D'); + }); + it('should be possible to add multiple properties on the same line', function () { + const res = flow.parser.parse(`flowchart TB + D@{ shape: rounded , label: "DD"}`); + + const data4Layout = flow.parser.yy.getData(); + + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('rounded'); + expect(data4Layout.nodes[0].label).toEqual('DD'); + }); + it('should be possible to link to a node with more data', function () { + const res = flow.parser.parse(`flowchart TB + A --> D@{ + shape: circle + other: "clock" + } + + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(2); + expect(data4Layout.nodes[0].shape).toEqual('squareRect'); + expect(data4Layout.nodes[0].label).toEqual('A'); + expect(data4Layout.nodes[1].label).toEqual('D'); + expect(data4Layout.nodes[1].shape).toEqual('circle'); + + expect(data4Layout.edges.length).toBe(1); + }); + it('should not disturb adding multiple nodes after each other', function () { + const res = flow.parser.parse(`flowchart TB + A[hello] + B@{ + shape: circle + other: "clock" + } + C[Hello]@{ + shape: circle + other: "clock" + } + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(3); + expect(data4Layout.nodes[0].shape).toEqual('squareRect'); + expect(data4Layout.nodes[0].label).toEqual('hello'); + expect(data4Layout.nodes[1].shape).toEqual('circle'); + expect(data4Layout.nodes[1].label).toEqual('B'); + expect(data4Layout.nodes[2].shape).toEqual('circle'); + expect(data4Layout.nodes[2].label).toEqual('Hello'); + }); + it('should use handle bracket end (}) character inside the shape data', function () { + const res = flow.parser.parse(`flowchart TB + A@{ + label: "This is }" + other: "clock" + } + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('squareRect'); + expect(data4Layout.nodes[0].label).toEqual('This is }'); + }); + it('should error on non-existent shape', function () { + expect(() => { + flow.parser.parse(`flowchart TB + A@{ shape: this-shape-does-not-exist } + `); + }).toThrow('No such shape: this-shape-does-not-exist.'); + }); + it('should error on internal-only shape', function () { + expect(() => { + // this shape does exist, but it's only supposed to be for internal/backwards compatibility use + flow.parser.parse(`flowchart TB + A@{ shape: rect_left_inv_arrow } + `); + }).toThrow('No such shape: rect_left_inv_arrow. Shape names should be lowercase.'); + }); + it('Diamond shapes should work as usual', function () { + const res = flow.parser.parse(`flowchart TB + A{This is a label} +`); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('diamond'); + expect(data4Layout.nodes[0].label).toEqual('This is a label'); + }); + it('Multi line strings should be supported', function () { + const res = flow.parser.parse(`flowchart TB + A@{ + label: | + This is a + multiline string + other: "clock" + } + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('squareRect'); + expect(data4Layout.nodes[0].label).toEqual('This is a\nmultiline string\n'); + }); + it('Multi line strings should be supported', function () { + const res = flow.parser.parse(`flowchart TB + A@{ + label: "This is a + multiline string" + other: "clock" + } + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('squareRect'); + expect(data4Layout.nodes[0].label).toEqual('This is a
multiline string'); + }); + it(' should be possible to use } in strings', function () { + const res = flow.parser.parse(`flowchart TB + A@{ + label: "This is a string with }" + other: "clock" + } + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('squareRect'); + expect(data4Layout.nodes[0].label).toEqual('This is a string with }'); + }); + it(' should be possible to use @ in strings', function () { + const res = flow.parser.parse(`flowchart TB + A@{ + label: "This is a string with @" + other: "clock" + } + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('squareRect'); + expect(data4Layout.nodes[0].label).toEqual('This is a string with @'); + }); + it(' should be possible to use @ in strings', function () { + const res = flow.parser.parse(`flowchart TB + A@{ + label: "This is a string with}" + other: "clock" + } + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(1); + expect(data4Layout.nodes[0].shape).toEqual('squareRect'); + expect(data4Layout.nodes[0].label).toEqual('This is a string with}'); + }); +}); diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison index 54949bfae..b3df82fa5 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison @@ -23,6 +23,9 @@ %x href %x callbackname %x callbackargs +%x shapeData +%x shapeDataStr +%x shapeDataEndBracket %% accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; } @@ -34,6 +37,32 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multilin [^\}]* return "acc_descr_multiline_value"; // .*[^\n]* { return "acc_descr_line"} + +\@\{ { + // console.log('=> shapeData', yytext); + this.pushState("shapeData"); yytext=""; return 'SHAPE_DATA' } +["] { + // console.log('=> shapeDataStr', yytext); + this.pushState("shapeDataStr"); + return 'SHAPE_DATA'; + } +["] { + // console.log('shapeData <==', yytext); + this.popState(); return 'SHAPE_DATA'} +[^\"]+ { + // console.log('shapeData', yytext); + const re = /\n\s*/g; + yytext = yytext.replace(re,"
"); + return 'SHAPE_DATA'} +[^}^"]+ { + // console.log('shapeData', yytext); + return 'SHAPE_DATA'; + } +"}" { + // console.log('<== root', yytext) + this.popState(); + } + /* ---interactivity command--- 'call' adds a callback to the specified node. 'call' can only be specified when @@ -49,10 +78,11 @@ Function arguments are optional: 'call ()' simply executes 'callba \) this.popState(); [^)]* return 'CALLBACKARGS'; + [^`"]+ { return "MD_STR";} [`]["] { this.popState();} <*>["][`] { this.begin("md_string");} -[^"]+ return "STR"; +[^"]+ { return "STR"; } ["] this.popState(); <*>["] this.pushState("string"); "style" return 'STYLE'; @@ -62,6 +92,8 @@ Function arguments are optional: 'call ()' simply executes 'callba "classDef" return 'CLASSDEF'; "class" return 'CLASS'; + + /* ---interactivity command--- 'href' adds a link to the specified node. 'href' can only be specified when the @@ -356,23 +388,38 @@ statement separator: NEWLINE | SEMI | EOF ; +shapeData: + shapeData SHAPE_DATA + { $$ = $1 + $2; } + | SHAPE_DATA + { $$ = $1; } + ; -vertexStatement: vertexStatement link node - { /* console.warn('vs',$vertexStatement.stmt,$node); */ yy.addLink($vertexStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($vertexStatement.nodes) } } +vertexStatement: vertexStatement link node shapeData + { /* console.warn('vs shapeData',$vertexStatement.stmt,$node, $shapeData);*/ yy.addVertex($node[0],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); yy.addLink($vertexStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($vertexStatement.nodes) } } + | vertexStatement link node + { /*console.warn('vs',$vertexStatement.stmt,$node);*/ yy.addLink($vertexStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($vertexStatement.nodes) } } | vertexStatement link node spaceList { /* console.warn('vs',$vertexStatement.stmt,$node); */ yy.addLink($vertexStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($vertexStatement.nodes) } } - |node spaceList {/*console.warn('noda', $node);*/ $$ = {stmt: $node, nodes:$node }} - |node { /*console.warn('noda', $node);*/ $$ = {stmt: $node, nodes:$node }} + |node spaceList { /*console.warn('vertexStatement: node spaceList', $node);*/ $$ = {stmt: $node, nodes:$node }} + |node shapeData { + /*console.warn('vertexStatement: node shapeData', $node[0], $shapeData);*/ + yy.addVertex($node[0],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); + $$ = {stmt: $node, nodes:$node, shapeData: $shapeData} + } + |node { /* console.warn('vertexStatement: single node', $node); */ $$ = {stmt: $node, nodes:$node }} ; node: styledVertex - { /* console.warn('nod', $styledVertex); */ $$ = [$styledVertex];} + { /*console.warn('nod', $styledVertex);*/ $$ = [$styledVertex];} + | node shapeData spaceList AMP spaceList styledVertex + { yy.addVertex($node[0],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); $$ = $node.concat($styledVertex); /*console.warn('pip2', $node[0], $styledVertex, $$);*/ } | node spaceList AMP spaceList styledVertex - { $$ = $node.concat($styledVertex); /* console.warn('pip', $node[0], $styledVertex, $$); */ } + { $$ = $node.concat($styledVertex); /*console.warn('pip', $node[0], $styledVertex, $$);*/ } ; styledVertex: vertex - { /* console.warn('nod', $vertex); */ $$ = $vertex;} + { /* console.warn('nodc', $vertex);*/ $$ = $vertex;} | vertex STYLE_SEPARATOR idString {$$ = $vertex;yy.setClass($vertex,$idString)} ; diff --git a/packages/mermaid/src/diagrams/flowchart/styles.ts b/packages/mermaid/src/diagrams/flowchart/styles.ts index 0ca2c1321..ade9613fb 100644 --- a/packages/mermaid/src/diagrams/flowchart/styles.ts +++ b/packages/mermaid/src/diagrams/flowchart/styles.ts @@ -59,7 +59,7 @@ const getStyles = (options: FlowChartStyleOptions) => stroke: ${options.nodeBorder}; stroke-width: 1px; } - .rough-node .label text , .node .label text { + .rough-node .label text , .node .label text, .image-shape .label, .icon-shape .label { text-anchor: middle; } // .flowchart-label .text-outer-tspan { @@ -75,13 +75,20 @@ const getStyles = (options: FlowChartStyleOptions) => stroke-width: 1px; } - .node .label { + .rough-node .label,.node .label, .image-shape .label, .icon-shape .label { text-align: center; } .node.clickable { cursor: pointer; } + + .root .anchor path { + fill: ${options.lineColor} !important; + stroke-width: 0; + stroke: ${options.lineColor}; + } + .arrowheadPath { fill: ${options.arrowheadColor}; } @@ -151,6 +158,25 @@ const getStyles = (options: FlowChartStyleOptions) => font-size: 18px; fill: ${options.textColor}; } + + rect.text { + fill: none; + stroke-width: 0; + } + + .icon-shape, .image-shape { + background-color: ${options.edgeLabelBackground}; + p { + background-color: ${options.edgeLabelBackground}; + padding: 2px; + } + rect { + opacity: 0.5; + background-color: ${options.edgeLabelBackground}; + fill: ${options.edgeLabelBackground}; + } + text-align: center; + } `; export default getStyles; diff --git a/packages/mermaid/src/diagrams/flowchart/types.ts b/packages/mermaid/src/diagrams/flowchart/types.ts index ee64ae56b..b2c5cf620 100644 --- a/packages/mermaid/src/diagrams/flowchart/types.ts +++ b/packages/mermaid/src/diagrams/flowchart/types.ts @@ -1,3 +1,28 @@ +import type { ShapeID } from '../../rendering-util/rendering-elements/shapes.js'; + +/** + * Valid `type` args to `yy.addVertex` taken from + * `packages/mermaid/src/diagrams/flowchart/parser/flow.jison` + */ +export type FlowVertexTypeParam = + | undefined + | 'square' + | 'doublecircle' + | 'circle' + | 'ellipse' + | 'stadium' + | 'subroutine' + | 'rect' + | 'cylinder' + | 'round' + | 'diamond' + | 'hexagon' + | 'odd' + | 'trapezoid' + | 'inv_trapezoid' + | 'lean_right' + | 'lean_left'; + export interface FlowVertex { classes: string[]; dir?: string; @@ -10,7 +35,16 @@ export interface FlowVertex { props?: any; styles: string[]; text?: string; - type?: string; + type?: ShapeID | FlowVertexTypeParam; + icon?: string; + form?: string; + pos?: 't' | 'b'; + img?: string; + assetWidth?: number; + assetHeight?: number; + defaultWidth?: number; + imageAspectRatio?: number; + constraint?: 'on' | 'off'; } export interface FlowText { diff --git a/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js b/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js index 281e9b6bd..33f91a882 100644 --- a/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js +++ b/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js @@ -1,7 +1,6 @@ import { parser } from './gantt.jison'; import ganttDb from '../ganttDb.js'; -import { convert } from '../../../tests/util.js'; -import { vi } from 'vitest'; +import { vi, it } from 'vitest'; const spyOn = vi.spyOn; const parserFnConstructor = (str) => { return () => { @@ -150,14 +149,14 @@ describe('when parsing a gantt diagram it', function () { expect(tasks[3].id).toEqual('d'); expect(tasks[3].task).toEqual('task D'); }); - it.each(convert` + it.each` tags | milestone | done | crit | active ${'milestone'} | ${true} | ${false} | ${false} | ${false} ${'done'} | ${false} | ${true} | ${false} | ${false} ${'crit'} | ${false} | ${false} | ${true} | ${false} ${'active'} | ${false} | ${false} | ${false} | ${true} ${'crit,milestone,done'} | ${true} | ${true} | ${true} | ${false} - `)('should handle a task with tags $tags', ({ tags, milestone, done, crit, active }) => { + `('should handle a task with tags $tags', ({ tags, milestone, done, crit, active }) => { const str = 'gantt\n' + 'dateFormat YYYY-MM-DD\n' + diff --git a/packages/mermaid/src/diagrams/kanban/detector.ts b/packages/mermaid/src/diagrams/kanban/detector.ts new file mode 100644 index 000000000..3c07ca4df --- /dev/null +++ b/packages/mermaid/src/diagrams/kanban/detector.ts @@ -0,0 +1,23 @@ +import type { + DiagramDetector, + DiagramLoader, + ExternalDiagramDefinition, +} from '../../diagram-api/types.js'; +const id = 'kanban'; + +const detector: DiagramDetector = (txt) => { + return /^\s*kanban/.test(txt); +}; + +const loader: DiagramLoader = async () => { + const { diagram } = await import('./kanban-definition.js'); + return { id, diagram }; +}; + +const plugin: ExternalDiagramDefinition = { + id, + detector, + loader, +}; + +export default plugin; diff --git a/packages/mermaid/src/diagrams/kanban/kanban-definition.ts b/packages/mermaid/src/diagrams/kanban/kanban-definition.ts new file mode 100644 index 000000000..fbaed30c0 --- /dev/null +++ b/packages/mermaid/src/diagrams/kanban/kanban-definition.ts @@ -0,0 +1,13 @@ +// @ts-ignore: JISON doesn't support types +import parser from './parser/kanban.jison'; +import db from './kanbanDb.js'; +import renderer from './kanbanRenderer.js'; +import styles from './styles.js'; +import type { DiagramDefinition } from '../../diagram-api/types.js'; + +export const diagram: DiagramDefinition = { + db, + renderer, + parser, + styles, +}; diff --git a/packages/mermaid/src/diagrams/kanban/kanban.spec.ts b/packages/mermaid/src/diagrams/kanban/kanban.spec.ts new file mode 100644 index 000000000..58fdab0e6 --- /dev/null +++ b/packages/mermaid/src/diagrams/kanban/kanban.spec.ts @@ -0,0 +1,494 @@ +// @ts-expect-error No types available for JISON +import { parser as kanban } from './parser/kanban.jison'; +import kanbanDB from './kanbanDb.js'; +import type { KanbanNode } from '../../rendering-util/types.js'; +// Todo fix utils functions for tests +import { setLogLevel } from '../../diagram-api/diagramAPI.js'; + +describe('when parsing a kanban ', function () { + beforeEach(function () { + kanban.yy = kanbanDB; + kanban.yy.clear(); + setLogLevel('trace'); + }); + describe('hiearchy', function () { + it('KNBN-1 should handle a simple root definition abc122', function () { + const str = `kanban + root`; + + kanban.parse(str); + const sections = kanban.yy.getSections(); + expect(sections.length).toEqual(1); + expect(sections[0].label).toEqual('root'); + }); + it('KNBN-2 should handle a hierachial kanban definition', function () { + const str = `kanban + root + child1 + child2 + `; + + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections.length).toEqual(1); + expect(sections[0].label).toEqual('root'); + expect(children.length).toEqual(2); + expect(children[0].label).toEqual('child1'); + expect(children[1].label).toEqual('child2'); + }); + + /** CATCH case when a lower level comes later, should throw + * a + * b + * c + */ + + it('3 should handle a simple root definition with a shape and without an id abc123', function () { + const str = `kanban + (root)`; + + kanban.parse(str); + const sections = kanban.yy.getSections(); + expect(sections[0].label).toEqual('root'); + }); + + it('KNBN-4 should not dsitinguis between deeper hierachial levels in thr kanban definition', function () { + const str = `kanban + root + child1 + leaf1 + child2`; + + // less picky is better + // expect(() => kanban.parse(str)).toThrow( + // 'There can be only one root. No parent could be found for ("fakeRoot")' + // ); + + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections.length).toBe(1); + expect(children.length).toBe(3); + }); + it('5 Multiple sections are ok', function () { + const str = `kanban + section1 + section2`; + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections.length).toBe(2); + expect(sections[0].label).toBe('section1'); + expect(sections[1].label).toBe('section2'); + + // expect(() => kanban.parse(str)).toThrow( + // 'There can be only one root. No parent could be found for ("fakeRoot")' + // ); + }); + it('KNBN-6 real root in wrong place', function () { + const str = `kanban + root + fakeRoot + realRootWrongPlace`; + expect(() => kanban.parse(str)).toThrow( + 'Items without section detected, found section ("fakeRoot")' + ); + }); + }); + describe('nodes', function () { + it('KNBN-7 should handle an id and type for a node definition', function () { + const str = `kanban + root[The root] + `; + + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(sections[0].label).toEqual('The root'); + }); + it('KNBN-8 should handle an id and type for a node definition', function () { + const str = `kanban + root + theId(child1)`; + + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].label).toEqual('root'); + expect(children.length).toEqual(1); + const child = children[0]; + expect(child.label).toEqual('child1'); + expect(child.id).toEqual('theId'); + }); + it('KNBN-9 should handle an id and type for a node definition', function () { + const str = `kanban +root + theId(child1)`; + + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].label).toEqual('root'); + expect(children.length).toEqual(1); + const child = children[0]; + expect(child.label).toEqual('child1'); + expect(child.id).toEqual('theId'); + }); + }); + describe('decorations', function () { + it('KNBN-13 should be possible to set an icon for the node', function () { + const str = `kanban + root[The root] + ::icon(bomb) + `; + // ::class1 class2 + + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(sections[0].label).toEqual('The root'); + + expect(sections[0].icon).toEqual('bomb'); + }); + it('KNBN-14 should be possible to set classes for the node', function () { + const str = `kanban + root[The root] + :::m-4 p-8 + `; + // ::class1 class2 + + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(sections[0].label).toEqual('The root'); + expect(sections[0].cssClasses).toEqual('m-4 p-8'); + }); + it('KNBN-15 should be possible to set both classes and icon for the node', function () { + const str = `kanban + root[The root] + :::m-4 p-8 + ::icon(bomb) + `; + // ::class1 class2 + + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(sections[0].label).toEqual('The root'); + expect(sections[0].cssClasses).toEqual('m-4 p-8'); + expect(sections[0].icon).toEqual('bomb'); + }); + it('KNBN-16 should be possible to set both classes and icon for the node', function () { + const str = `kanban + root[The root] + ::icon(bomb) + :::m-4 p-8 + `; + // ::class1 class2 + + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(sections[0].label).toEqual('The root'); + // expect(sections[0].type).toEqual('rect'); + expect(sections[0].cssClasses).toEqual('m-4 p-8'); + expect(sections[0].icon).toEqual('bomb'); + }); + }); + describe('descriptions', function () { + it('KNBN-17 should be possible to use node syntax in the descriptions', function () { + const str = `kanban + root["String containing []"] +`; + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(sections[0].label).toEqual('String containing []'); + }); + it('KNBN-18 should be possible to use node syntax in the descriptions in children', function () { + const str = `kanban + root["String containing []"] + child1["String containing ()"] +`; + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(sections[0].label).toEqual('String containing []'); + expect(children.length).toEqual(1); + expect(children[0].label).toEqual('String containing ()'); + }); + it('KNBN-19 should be possible to have a child after a class assignment', function () { + const str = `kanban + root(Root) + Child(Child) + :::hot + a(a) + b[New Stuff]`; + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(sections[0].label).toEqual('Root'); + expect(children.length).toEqual(3); + + const item1 = children[0]; + const item2 = children[1]; + const item3 = children[2]; + expect(item1.id).toEqual('Child'); + expect(item2.id).toEqual('a'); + expect(item3.id).toEqual('b'); + }); + }); + it('KNBN-20 should be possible to have meaningless empty rows in a kanban abc124', function () { + const str = `kanban + root(Root) + Child(Child) + a(a) + + b[New Stuff]`; + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(sections[0].label).toEqual('Root'); + expect(children.length).toEqual(3); + + const item1 = children[0]; + const item2 = children[1]; + const item3 = children[2]; + expect(item1.id).toEqual('Child'); + expect(item2.id).toEqual('a'); + expect(item3.id).toEqual('b'); + }); + it('KNBN-21 should be possible to have comments in a kanban', function () { + const str = `kanban + root(Root) + Child(Child) + a(a) + + %% This is a comment + b[New Stuff]`; + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(sections[0].label).toEqual('Root'); + + const child = children[0]; + expect(child.id).toEqual('Child'); + expect(children[1].id).toEqual('a'); + expect(children[2].id).toEqual('b'); + expect(children.length).toEqual(3); + }); + + it('KNBN-22 should be possible to have comments at the end of a line', function () { + const str = `kanban + root(Root) + Child(Child) + a(a) %% This is a comment + b[New Stuff]`; + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(sections[0].label).toEqual('Root'); + expect(children.length).toEqual(3); + + const child1 = children[0]; + expect(child1.id).toEqual('Child'); + const child2 = children[1]; + expect(child2.id).toEqual('a'); + const child3 = children[2]; + expect(child3.id).toEqual('b'); + }); + it('KNBN-23 Rows with only spaces should not interfere', function () { + const str = 'kanban\nroot\n A\n \n\n B'; + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(children.length).toEqual(2); + + const child = children[0]; + expect(child.id).toEqual('A'); + const child2 = children[1]; + expect(child2.id).toEqual('B'); + }); + it('KNBN-24 Handle rows above the kanban declarations', function () { + const str = '\n \nkanban\nroot\n A\n \n\n B'; + kanban.parse(str); + + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(children.length).toEqual(2); + + const child = children[0]; + expect(child.id).toEqual('A'); + const child2 = children[1]; + expect(child2.id).toEqual('B'); + }); + it('KNBN-25 Handle rows above the kanban declarations, no space', function () { + const str = '\n\n\nkanban\nroot\n A\n \n\n B'; + kanban.parse(str); + const data = kanban.yy.getData(); + const sections = kanban.yy.getSections(); + const children = data.nodes.filter((n: KanbanNode) => n.parentId === sections[0].id); + + expect(sections[0].id).toEqual('root'); + expect(children.length).toEqual(2); + + const child = children[0]; + expect(child.id).toEqual('A'); + const child2 = children[1]; + expect(child2.id).toEqual('B'); + }); +}); +describe('item data data', function () { + beforeEach(function () { + kanban.yy = kanbanDB; + kanban.yy.clear(); + setLogLevel('trace'); + }); + it('KNBN-30 should be possible to set the priority', function () { + let str = `kanban + root + `; + str = `kanban + root@{ priority: high } + `; + kanban.parse(str); + const sections = kanban.yy.getSections(); + expect(sections[0].id).toEqual('root'); + expect(sections[0].priority).toEqual('high'); + }); + it('KNBN-31 should be possible to set the assignment', function () { + const str = `kanban + root@{ assigned: knsv } + `; + kanban.parse(str); + const sections = kanban.yy.getSections(); + expect(sections[0].id).toEqual('root'); + expect(sections[0].assigned).toEqual('knsv'); + }); + it('KNBN-32 should be possible to set the icon', function () { + const str = `kanban + root@{ icon: star } + `; + kanban.parse(str); + const sections = kanban.yy.getSections(); + expect(sections[0].id).toEqual('root'); + expect(sections[0].icon).toEqual('star'); + }); + it('KNBN-33 should be possible to set the icon', function () { + const str = `kanban + root@{ icon: star } + `; + kanban.parse(str); + const sections = kanban.yy.getSections(); + expect(sections[0].id).toEqual('root'); + expect(sections[0].icon).toEqual('star'); + }); + it('KNBN-34 should be possible to set the metadata using multiple lines', function () { + const str = `kanban + root@{ + icon: star + assigned: knsv + } + `; + kanban.parse(str); + const sections = kanban.yy.getSections(); + expect(sections[0].id).toEqual('root'); + expect(sections[0].icon).toEqual('star'); + expect(sections[0].assigned).toEqual('knsv'); + }); + it('KNBN-35 should be possible to set the metadata using one line', function () { + const str = `kanban + root@{ icon: star, assigned: knsv } + `; + kanban.parse(str); + const sections = kanban.yy.getSections(); + expect(sections[0].id).toEqual('root'); + expect(sections[0].icon).toEqual('star'); + expect(sections[0].assigned).toEqual('knsv'); + }); + it('KNBN-36 should be possible to set the label using the new syntax', function () { + const str = `kanban + root@{ icon: star, label: 'fix things' } + `; + kanban.parse(str); + const sections = kanban.yy.getSections(); + expect(sections[0].label).toEqual('fix things'); + }); + it('KNBN-37 should be possible to set the external id', function () { + const str = `kanban + root@{ ticket: MC-1234 } + `; + kanban.parse(str); + const sections = kanban.yy.getSections(); + const data = kanban.yy.getData(); + expect(sections[0].id).toEqual('root'); + expect(sections[0].ticket).toEqual('MC-1234'); + }); +}); diff --git a/packages/mermaid/src/diagrams/kanban/kanbanDb.ts b/packages/mermaid/src/diagrams/kanban/kanbanDb.ts new file mode 100644 index 000000000..478c37803 --- /dev/null +++ b/packages/mermaid/src/diagrams/kanban/kanbanDb.ts @@ -0,0 +1,253 @@ +import { getConfig } from '../../diagram-api/diagramAPI.js'; +import type { D3Element } from '../../types.js'; +import { sanitizeText } from '../../diagrams/common/common.js'; +import { log } from '../../logger.js'; +import type { Edge, KanbanNode } from '../../rendering-util/types.js'; +import defaultConfig from '../../defaultConfig.js'; +import type { NodeMetaData } from '../../types.js'; +import * as yaml from 'js-yaml'; + +let nodes: KanbanNode[] = []; +let sections: KanbanNode[] = []; +let cnt = 0; +let elements: Record = {}; + +const clear = () => { + nodes = []; + sections = []; + cnt = 0; + elements = {}; +}; +/* + * if your level is the section level return null - then you do not belong to a level + * otherwise return the current section + */ +const getSection = (level: number) => { + if (nodes.length === 0) { + // console.log('No nodes'); + return null; + } + const sectionLevel = nodes[0].level; + let lastSection = null; + for (let i = nodes.length - 1; i >= 0; i--) { + if (nodes[i].level === sectionLevel && !lastSection) { + lastSection = nodes[i]; + // console.log('lastSection found', lastSection); + } + // console.log('HERE', nodes[i].id, level, nodes[i].level, sectionLevel); + if (nodes[i].level < sectionLevel) { + throw new Error('Items without section detected, found section ("' + nodes[i].label + '")'); + } + } + if (level === lastSection?.level) { + return null; + } + + // No found + return lastSection; +}; + +const getSections = function () { + return sections; +}; + +const getData = function () { + const edges = [] as Edge[]; + const _nodes: KanbanNode[] = []; + + const sections = getSections(); + const conf = getConfig(); + + for (const section of sections) { + const node = { + id: section.id, + label: sanitizeText(section.label ?? '', conf), + isGroup: true, + ticket: section.ticket, + shape: 'kanbanSection', + level: section.level, + look: conf.look, + } satisfies KanbanNode; + _nodes.push(node); + const children = nodes.filter((n) => n.parentId === section.id); + + for (const item of children) { + const childNode = { + id: item.id, + parentId: section.id, + label: sanitizeText(item.label ?? '', conf), + isGroup: false, + ticket: item?.ticket, + priority: item?.priority, + assigned: item?.assigned, + icon: item?.icon, + shape: 'kanbanItem', + level: item.level, + rx: 5, + ry: 5, + cssStyles: ['text-align: left'], + } satisfies KanbanNode; + _nodes.push(childNode); + } + } + + return { nodes: _nodes, edges, other: {}, config: getConfig() }; +}; + +const addNode = (level: number, id: string, descr: string, type: number, shapeData: string) => { + const conf = getConfig(); + let padding: number = conf.mindmap?.padding ?? defaultConfig.mindmap.padding; + switch (type) { + case nodeType.ROUNDED_RECT: + case nodeType.RECT: + case nodeType.HEXAGON: + padding *= 2; + } + + const node: KanbanNode = { + id: sanitizeText(id, conf) || 'kbn' + cnt++, + level, + label: sanitizeText(descr, conf), + width: conf.mindmap?.maxNodeWidth ?? defaultConfig.mindmap.maxNodeWidth, + padding, + isGroup: false, + } satisfies KanbanNode; + + if (shapeData !== undefined) { + let yamlData; + // detect if shapeData contains a newline character + // console.log('shapeData', shapeData); + if (!shapeData.includes('\n')) { + // console.log('yamlData shapeData has no new lines', shapeData); + yamlData = '{\n' + shapeData + '\n}'; + } else { + // console.log('yamlData shapeData has new lines', shapeData); + yamlData = shapeData + '\n'; + } + const doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA }) as NodeMetaData; + // console.log('yamlData', doc); + if (doc.shape && (doc.shape !== doc.shape.toLowerCase() || doc.shape.includes('_'))) { + throw new Error(`No such shape: ${doc.shape}. Shape names should be lowercase.`); + } + + // if shape is defined in the yaml data, use it if it is a valid shape kanbanItem + if (doc?.shape && doc.shape === 'kanbanItem') { + node.shape = doc?.shape; + } + if (doc?.label) { + node.label = doc?.label; + } + if (doc?.icon) { + node.icon = doc?.icon; + } + if (doc?.assigned) { + node.assigned = doc?.assigned; + } + if (doc?.ticket) { + node.ticket = doc?.ticket; + } + + if (doc?.priority) { + node.priority = doc?.priority; + } + } + + const section = getSection(level); + if (section) { + // @ts-ignore false positive for section.id + node.parentId = section.id || 'kbn' + cnt++; + } else { + sections.push(node); + } + nodes.push(node); +}; + +const nodeType = { + DEFAULT: 0, + NO_BORDER: 0, + ROUNDED_RECT: 1, + RECT: 2, + CIRCLE: 3, + CLOUD: 4, + BANG: 5, + HEXAGON: 6, +}; + +const getType = (startStr: string, endStr: string): number => { + log.debug('In get type', startStr, endStr); + switch (startStr) { + case '[': + return nodeType.RECT; + case '(': + return endStr === ')' ? nodeType.ROUNDED_RECT : nodeType.CLOUD; + case '((': + return nodeType.CIRCLE; + case ')': + return nodeType.CLOUD; + case '))': + return nodeType.BANG; + case '{{': + return nodeType.HEXAGON; + default: + return nodeType.DEFAULT; + } +}; + +const setElementForId = (id: number, element: D3Element) => { + elements[id] = element; +}; + +const decorateNode = (decoration?: { class?: string; icon?: string }) => { + if (!decoration) { + return; + } + const config = getConfig(); + const node = nodes[nodes.length - 1]; + if (decoration.icon) { + node.icon = sanitizeText(decoration.icon, config); + } + if (decoration.class) { + node.cssClasses = sanitizeText(decoration.class, config); + } +}; + +const type2Str = (type: number) => { + switch (type) { + case nodeType.DEFAULT: + return 'no-border'; + case nodeType.RECT: + return 'rect'; + case nodeType.ROUNDED_RECT: + return 'rounded-rect'; + case nodeType.CIRCLE: + return 'circle'; + case nodeType.CLOUD: + return 'cloud'; + case nodeType.BANG: + return 'bang'; + case nodeType.HEXAGON: + return 'hexgon'; // cspell: disable-line + default: + return 'no-border'; + } +}; + +// Expose logger to grammar +const getLogger = () => log; +const getElementById = (id: number) => elements[id]; + +const db = { + clear, + addNode, + getSections, + getData, + nodeType, + getType, + setElementForId, + decorateNode, + type2Str, + getLogger, + getElementById, +} as const; + +export default db; diff --git a/packages/mermaid/src/diagrams/kanban/kanbanRenderer.ts b/packages/mermaid/src/diagrams/kanban/kanbanRenderer.ts new file mode 100644 index 000000000..dc57808a9 --- /dev/null +++ b/packages/mermaid/src/diagrams/kanban/kanbanRenderer.ts @@ -0,0 +1,96 @@ +import { getConfig } from '../../diagram-api/diagramAPI.js'; +import type { DrawDefinition } from '../../diagram-api/types.js'; +import { log } from '../../logger.js'; +import { selectSvgElement } from '../../rendering-util/selectSvgElement.js'; +import { setupGraphViewbox } from '../../setupGraphViewbox.js'; +import type { KanbanDB } from './kanbanTypes.js'; +import defaultConfig from '../../defaultConfig.js'; +import { insertCluster } from '../../rendering-util/rendering-elements/clusters.js'; +import { insertNode, positionNode } from '../../rendering-util/rendering-elements/nodes.js'; +import type { ClusterNode } from '../../rendering-util/types.js'; + +export const draw: DrawDefinition = async (text, id, _version, diagObj) => { + log.debug('Rendering kanban diagram\n' + text); + + const db = diagObj.db as KanbanDB; + const data4Layout = db.getData(); + + const conf = getConfig(); + conf.htmlLabels = false; + + const svg = selectSvgElement(id); + + // Draw the graph and start with drawing the nodes without proper position + // this gives us the size of the nodes and we can set the positions later + + const sectionsElem = svg.append('g'); + sectionsElem.attr('class', 'sections'); + const nodesElem = svg.append('g'); + nodesElem.attr('class', 'items'); + const sections = data4Layout.nodes.filter( + // TODO: TypeScript 5.5 will infer this predicate automatically + (node): node is typeof node & ClusterNode => node.isGroup + ); + let cnt = 0; + // TODO set padding + const padding = 10; + + const sectionObjects = []; + let maxLabelHeight = 25; + for (const section of sections) { + const WIDTH = conf?.kanban?.sectionWidth || 200; + // const top = (-WIDTH * 3) / 2 + 25; + // let y = top; + cnt = cnt + 1; + section.x = WIDTH * cnt + ((cnt - 1) * padding) / 2; + section.width = WIDTH; + section.y = 0; + section.height = WIDTH * 3; + section.rx = 5; + section.ry = 5; + + // Todo, use theme variable THEME_COLOR_LIMIT instead of 10 + section.cssClasses = section.cssClasses + ' section-' + cnt; + const sectionObj = await insertCluster(sectionsElem, section); + maxLabelHeight = Math.max(maxLabelHeight, sectionObj?.labelBBox?.height); + sectionObjects.push(sectionObj); + } + let i = 0; + for (const section of sections) { + const sectionObj = sectionObjects[i]; + i = i + 1; + const WIDTH = conf?.kanban?.sectionWidth || 200; + const top = (-WIDTH * 3) / 2 + maxLabelHeight; + let y = top; + const sectionItems = data4Layout.nodes.filter((node) => node.parentId === section.id); + for (const item of sectionItems) { + if (item.isGroup) { + // Kanban diagrams should not have groups within groups + // this should never happen + throw new Error('Groups within groups are not allowed in Kanban diagrams'); + } + item.x = section.x; + item.width = WIDTH - 1.5 * padding; + const nodeEl = await insertNode(nodesElem, item, { config: conf }); + const bbox = nodeEl.node()!.getBBox(); + item.y = y + bbox.height / 2; + await positionNode(item); + y = item.y + bbox.height / 2 + padding / 2; + } + const rect = sectionObj.cluster.select('rect'); + const height = Math.max(y - top + 3 * padding, 50) + (maxLabelHeight - 25); + rect.attr('height', height); + } + + // Setup the view box and size of the svg element + setupGraphViewbox( + undefined, + svg, + conf.mindmap?.padding ?? defaultConfig.kanban.padding, + conf.mindmap?.useMaxWidth ?? defaultConfig.kanban.useMaxWidth + ); +}; + +export default { + draw, +}; diff --git a/packages/mermaid/src/diagrams/kanban/kanbanTypes.ts b/packages/mermaid/src/diagrams/kanban/kanbanTypes.ts new file mode 100644 index 000000000..efcb61f98 --- /dev/null +++ b/packages/mermaid/src/diagrams/kanban/kanbanTypes.ts @@ -0,0 +1,3 @@ +import type kanbanDb from './kanbanDb.js'; + +export type KanbanDB = typeof kanbanDb; diff --git a/packages/mermaid/src/diagrams/kanban/parser/kanban.jison b/packages/mermaid/src/diagrams/kanban/parser/kanban.jison new file mode 100644 index 000000000..6fb31bf0b --- /dev/null +++ b/packages/mermaid/src/diagrams/kanban/parser/kanban.jison @@ -0,0 +1,166 @@ +/** mermaid + * https://knsv.github.io/mermaid + * (c) 2015 Knut Sveidqvist + * MIT license. + */ +%lex + +%options case-insensitive + +%{ + // Pre-lexer code can go here +%} +%x NODE +%x NSTR +%x NSTR2 +%x ICON +%x CLASS +%x shapeData +%x shapeDataStr +%x shapeDataEndBracket + +%% + +\@\{ { + // console.log('=> shapeData', yytext); + this.pushState("shapeData"); yytext=""; return 'SHAPE_DATA' } +["] { + // console.log('=> shapeDataStr', yytext); + this.pushState("shapeDataStr"); + return 'SHAPE_DATA'; + } +["] { + // console.log('shapeData <==', yytext); + this.popState(); return 'SHAPE_DATA'} +[^\"]+ { + // console.log('shapeData', yytext); + const re = /\n\s*/g; + yytext = yytext.replace(re,"
"); + return 'SHAPE_DATA'} +[^}^"]+ { + // console.log('shapeData', yytext); + return 'SHAPE_DATA'; + } +"}" { + // console.log('<== root', yytext) + this.popState(); + } +\s*\%\%.* {yy.getLogger().trace('Found comment',yytext); return 'SPACELINE';} +// \%\%[^\n]*\n /* skip comments */ +"kanban" {return 'KANBAN';} +":::" { this.begin('CLASS'); } +.+ { this.popState();return 'CLASS'; } +\n { this.popState();} +// [\s]*"::icon(" { this.begin('ICON'); } +"::icon(" { yy.getLogger().trace('Begin icon');this.begin('ICON'); } +[\s]+[\n] {yy.getLogger().trace('SPACELINE');return 'SPACELINE' /* skip all whitespace */ ;} +[\n]+ return 'NL'; +[^\)]+ { return 'ICON'; } +\) {yy.getLogger().trace('end icon');this.popState();} +"-)" { yy.getLogger().trace('Exploding node'); this.begin('NODE');return 'NODE_DSTART'; } +"(-" { yy.getLogger().trace('Cloud'); this.begin('NODE');return 'NODE_DSTART'; } +"))" { yy.getLogger().trace('Explosion Bang'); this.begin('NODE');return 'NODE_DSTART'; } +")" { yy.getLogger().trace('Cloud Bang'); this.begin('NODE');return 'NODE_DSTART'; } +"((" { this.begin('NODE');return 'NODE_DSTART'; } +"{{" { this.begin('NODE');return 'NODE_DSTART'; } +"(" { this.begin('NODE');return 'NODE_DSTART'; } +"[" { this.begin('NODE');return 'NODE_DSTART'; } +[\s]+ return 'SPACELIST' /* skip all whitespace */ ; +// !(-\() return 'NODE_ID'; +[^\(\[\n\)\{\}@]+ {return 'NODE_ID';} +<> return 'EOF'; +["][`] { this.begin("NSTR2");} +[^`"]+ { return "NODE_DESCR";} +[`]["] { this.popState();} +["] { yy.getLogger().trace('Starting NSTR');this.begin("NSTR");} +[^"]+ { yy.getLogger().trace('description:', yytext); return "NODE_DESCR";} +["] {this.popState();} +[\)]\) {this.popState();yy.getLogger().trace('node end ))');return "NODE_DEND";} +[\)] {this.popState();yy.getLogger().trace('node end )');return "NODE_DEND";} +[\]] {this.popState();yy.getLogger().trace('node end ...',yytext);return "NODE_DEND";} +"}}" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";} +"(-" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";} +"-)" {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";} +"((" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";} +"(" {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";} +[^\)\]\(\}]+ { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';} +.+(?!\(\() { yy.getLogger().trace('Long description:', yytext); return 'NODE_DESCR';} +// [\[] return 'NODE_START'; +// .+ return 'TXT' ; + +/lex + +%start start + +%% /* language grammar */ + +start +// %{ : info document 'EOF' { return yy; } } + : mindMap + | spaceLines mindMap + ; + +spaceLines + : SPACELINE + | spaceLines SPACELINE + | spaceLines NL + ; + +mindMap + : KANBAN document { return yy; } + | KANBAN NL document { return yy; } + ; + +stop + : NL {yy.getLogger().trace('Stop NL ');} + | EOF {yy.getLogger().trace('Stop EOF ');} + | SPACELINE + | stop NL {yy.getLogger().trace('Stop NL2 ');} + | stop EOF {yy.getLogger().trace('Stop EOF2 ');} + ; +document + : document statement stop + | statement stop + ; + +statement + : SPACELIST node shapeData { yy.getLogger().info('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type, $3); } + | SPACELIST node { yy.getLogger().info('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type); } + | SPACELIST ICON { yy.getLogger().trace('Icon: ',$2);yy.decorateNode({icon: $2}); } + | SPACELIST CLASS { yy.decorateNode({class: $2}); } + | SPACELINE { yy.getLogger().trace('SPACELIST');} + | node shapeData { yy.getLogger().trace('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type, $2); } + | node { yy.getLogger().trace('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type); } + | ICON { yy.decorateNode({icon: $1}); } + | CLASS { yy.decorateNode({class: $1}); } + | SPACELIST + ; + + + +node + :nodeWithId + |nodeWithoutId + ; + +nodeWithoutId + : NODE_DSTART NODE_DESCR NODE_DEND + { yy.getLogger().trace("node found ..", $1); $$ = { id: $2, descr: $2, type: yy.getType($1, $3) }; } + ; + +nodeWithId + : NODE_ID { $$ = { id: $1, descr: $1, type: 0 }; } + | NODE_ID NODE_DSTART NODE_DESCR NODE_DEND + { yy.getLogger().trace("node found ..", $1); $$ = { id: $1, descr: $3, type: yy.getType($2, $4) }; } + ; + +shapeData: + shapeData SHAPE_DATA + { $$ = $1 + $2; } + | SHAPE_DATA + { $$ = $1; } + ; + + + +%% diff --git a/packages/mermaid/src/diagrams/kanban/samples.md b/packages/mermaid/src/diagrams/kanban/samples.md new file mode 100644 index 000000000..a75cfeeef --- /dev/null +++ b/packages/mermaid/src/diagrams/kanban/samples.md @@ -0,0 +1,105 @@ +```mermaid +kanban + New + Sometimes wrong Shape type is highlighted + In progress + + +``` + +```mermaid +kanban + Todo + Create JISON + Update DB function + Create parsing tests + define getData + Create renderer + In progress + Design grammar + +``` + +Adding ID + +```mermaid +kanban + id1[Todo] + id2[Create JISON] + id3[Update DB function] + id4[Create parsing tests] + id5[define getData] + id6[Create renderer] + id7[In progress] + id8[Design grammar] + +``` + +Background color for section + +```mermaid +kanban + id1[Todo] + id2[Create JISON] + id3[Update DB function] + id4[Create parsing tests] + id5[define getData] + id6[Create renderer] + id7[In progress] + id8[Design grammar] + + style n2 stroke:#AA00FF,fill:#E1BEE7 +``` + +Background color for section + +```mermaid +kanban + id1[Todo] + id2[Create JISON] + id3[Update DB function] + id4[Create parsing tests] + id5[define getData] + id6[Create renderer] + id7[In progress] + id8[Design grammar] + + id2@{ + assigned: knsv + icon: heart + priority: high + descr: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + } + style n1 stroke:#AA00FF,fill:#E1BEE7 +``` + +Background color for section + +```mermaid +--- +config: + kanban: + showIds: true + fields: [[title],[description][id, assigned]] +--- +kanban + id1[Todo] + id2[Create JISON] + id3[Update DB function] + id4[Create parsing tests] + id5[define getData] + id6[Create renderer] + id7[In progress] + id8[Design grammar] + + id2@{ + assigned: knsv + icon: heart + priority: high + descr: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + } + style n1 stroke:#AA00FF,fill:#E1BEE7 +``` + +priority - dedicated +link - dedicated diff --git a/packages/mermaid/src/diagrams/kanban/styles.ts b/packages/mermaid/src/diagrams/kanban/styles.ts new file mode 100644 index 000000000..8b40224b2 --- /dev/null +++ b/packages/mermaid/src/diagrams/kanban/styles.ts @@ -0,0 +1,109 @@ +// @ts-expect-error Incorrect khroma types +import { darken, lighten, isDark } from 'khroma'; +import type { DiagramStylesProvider } from '../../diagram-api/types.js'; + +const genSections: DiagramStylesProvider = (options) => { + let sections = ''; + + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + options['lineColor' + i] = options['lineColor' + i] || options['cScaleInv' + i]; + if (isDark(options['lineColor' + i])) { + options['lineColor' + i] = lighten(options['lineColor' + i], 20); + } else { + options['lineColor' + i] = darken(options['lineColor' + i], 20); + } + } + + const adjuster = (color: string, level: number) => + options.darkMode ? darken(color, level) : lighten(color, level); + + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + const sw = '' + (17 - 3 * i); + sections += ` + .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${ + i - 1 + } polygon, .section-${i - 1} path { + fill: ${adjuster(options['cScale' + i], 10)}; + stroke: ${adjuster(options['cScale' + i], 10)}; + + } + .section-${i - 1} text { + fill: ${options['cScaleLabel' + i]}; + } + .node-icon-${i - 1} { + font-size: 40px; + color: ${options['cScaleLabel' + i]}; + } + .section-edge-${i - 1}{ + stroke: ${options['cScale' + i]}; + } + .edge-depth-${i - 1}{ + stroke-width: ${sw}; + } + .section-${i - 1} line { + stroke: ${options['cScaleInv' + i]} ; + stroke-width: 3; + } + + .disabled, .disabled circle, .disabled text { + fill: lightgray; + } + .disabled text { + fill: #efefef; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.background}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + + .kanban-ticket-link { + fill: ${options.background}; + stroke: ${options.nodeBorder}; + text-decoration: underline; + } + `; + } + return sections; +}; + +// TODO: These options seem incorrect. +const getStyles: DiagramStylesProvider = (options) => + ` + .edge { + stroke-width: 3; + } + ${genSections(options)} + .section-root rect, .section-root path, .section-root circle, .section-root polygon { + fill: ${options.git0}; + } + .section-root text { + fill: ${options.gitBranchLabel0}; + } + .icon-container { + height:100%; + display: flex; + justify-content: center; + align-items: center; + } + .edge { + fill: none; + } + .cluster-label, .label { + color: ${options.textColor}; + fill: ${options.textColor}; + } + .kanban-label { + dy: 1em; + alignment-baseline: middle; + text-anchor: middle; + dominant-baseline: middle; + text-align: center; + } +`; +export default getStyles; diff --git a/packages/mermaid/src/diagrams/pie/pie.spec.ts b/packages/mermaid/src/diagrams/pie/pie.spec.ts index b7bbf65bf..f00906cc5 100644 --- a/packages/mermaid/src/diagrams/pie/pie.spec.ts +++ b/packages/mermaid/src/diagrams/pie/pie.spec.ts @@ -130,8 +130,8 @@ describe('pie', () => { expect(sections.get('bat')).toBe(40); }); - it('should handle simple pie with negative decimal', () => { - expect(async () => { + it('should handle simple pie with negative decimal', async () => { + await expect(async () => { await parser.parse(`pie "ash" : -60.67 "bat" : 40.12 diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js index 7f6b80ca5..fde813cef 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js +++ b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js @@ -2063,8 +2063,8 @@ participant Alice`; }); }); - it.each(['__proto__', 'constructor'])('should allow %s as an actor name', function (prop) { - expect( + it.each(['__proto__', 'constructor'])('should allow %s as an actor name', async function (prop) { + await expect( mermaidAPI.parse(` sequenceDiagram ${prop}-->>A: Hello, how are you?`) diff --git a/packages/mermaid/src/diagrams/sequence/svgDraw.js b/packages/mermaid/src/diagrams/sequence/svgDraw.js index 51968ef9f..c681c9491 100644 --- a/packages/mermaid/src/diagrams/sequence/svgDraw.js +++ b/packages/mermaid/src/diagrams/sequence/svgDraw.js @@ -329,7 +329,7 @@ export const fixLifeLineHeights = (diagram, actors, actorKeys, conf) => { const drawActorTypeParticipant = function (elem, actor, conf, isFooter) { const actorY = isFooter ? actor.stopy : actor.starty; const center = actor.x + actor.width / 2; - const centerY = actorY + 5; + const centerY = actorY + actor.height; const boxplusLineGroup = elem.append('g').lower(); var g = boxplusLineGroup; diff --git a/packages/mermaid/src/docs/.vitepress/components/ProductHuntBadge.vue b/packages/mermaid/src/docs/.vitepress/components/ProductHuntBadge.vue deleted file mode 100644 index 17f0767d7..000000000 --- a/packages/mermaid/src/docs/.vitepress/components/ProductHuntBadge.vue +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/packages/mermaid/src/docs/.vitepress/components/TopBar.vue b/packages/mermaid/src/docs/.vitepress/components/TopBar.vue index 5aa515575..4b1b250bb 100644 --- a/packages/mermaid/src/docs/.vitepress/components/TopBar.vue +++ b/packages/mermaid/src/docs/.vitepress/components/TopBar.vue @@ -7,17 +7,21 @@ interface Taglines { } const taglines: Taglines[] = [ + { + label: 'Explore the Mermaid Whiteboard from the creators of Mermaid', + url: 'https://www.mermaidchart.com/whiteboard?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=whiteboard', + }, { label: 'Use the Visual Editor in Mermaid Chart to design and build diagrams', - url: 'https://www.mermaidchart.com/play?utm_source=mermaid_live_editor&utm_medium=banner_ad&utm_campaign=visual_editor', + url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=visual_editor', }, { label: 'Diagram live with teammates in Mermaid Chart', - url: 'https://www.mermaidchart.com/play?utm_source=mermaid_live_editor&utm_medium=banner_ad&utm_campaign=teams', + url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=teams', }, { - label: 'Skip the rough draft with Mermaid AI in Mermaid Chart', - url: 'https://www.mermaidchart.com/play?utm_source=mermaid_live_editor&utm_medium=banner_ad&utm_campaign=mermaid_ai', + label: 'Replace ChatGPT Pro, Mermaid.live, and LucidChart with Mermaid Pro', + url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=AIbundle', }, ]; @@ -25,7 +29,7 @@ let index = ref(Math.floor(Math.random() * taglines.length)); onMounted(() => { setInterval(() => { index.value = (index.value + 1) % taglines.length; - }, 60_000); + }, 40_000); }); @@ -41,7 +45,7 @@ onMounted(() => { > {{ taglines[index].label }} diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts index 619de961d..8a0225c56 100644 --- a/packages/mermaid/src/docs/.vitepress/config.ts +++ b/packages/mermaid/src/docs/.vitepress/config.ts @@ -157,6 +157,7 @@ function sidebarSyntax() { { text: 'XY Chart 🔥', link: '/syntax/xyChart' }, { text: 'Block Diagram 🔥', link: '/syntax/block' }, { text: 'Packet 🔥', link: '/syntax/packet' }, + { text: 'Kanban 🔥', link: '/syntax/kanban' }, { text: 'Architecture 🔥', link: '/syntax/architecture' }, { text: 'Other Examples', link: '/syntax/examples' }, ], @@ -174,6 +175,7 @@ function sidebarConfig() { { text: 'API-Usage', link: '/config/usage' }, { text: 'Mermaid API Configuration', link: '/config/setup/README' }, { text: 'Mermaid Configuration Options', link: '/config/schema-docs/config' }, + { text: 'Registering icons', link: '/config/icons' }, { text: 'Directives', link: '/config/directives' }, { text: 'Theming', link: '/config/theming' }, { text: 'Math', link: '/config/math' }, diff --git a/packages/mermaid/src/docs/adding-new-shape.md b/packages/mermaid/src/docs/adding-new-shape.md new file mode 100644 index 000000000..8ba5d083c --- /dev/null +++ b/packages/mermaid/src/docs/adding-new-shape.md @@ -0,0 +1,225 @@ +# Custom SVG Shapes Library + +This library provides a collection of custom SVG shapes, utilities, and helpers for generating diagram components. The shapes are designed to be used within an SVG container and include a variety of common and complex shapes. + +## Overview + +## Shape Helpers and Utilities + +Before starting with shape creation, it's essential to familiarize yourself with the utilities provided in the `utils.ts` file from `packages/mermaid/src/rendering-util/rendering-elements/shapes/util.js`. These utilities are designed to assist with various aspects of SVG shape manipulation and ensure consistent and accurate rendering. + +## Available Utilities + +### 1. `labelHelper` + +- **Purpose**: This function creates and inserts labels inside SVG shapes. +- **Features**: + - Handles both HTML labels and plain text. + - Calculates the bounding box dimensions of the label. + - Ensures proper positioning of labels within shapes. + +### 2. `updateNodeBounds` + +- **Purpose**: Updates the bounding box dimensions (width and height) of a node. +- **Usage**: + - Adjusts the size of the node to fit the content or shape. + - Useful for ensuring that shapes resize appropriately based on their content. + +### 3. `insertPolygonShape` + +- **Purpose**: Inserts a polygon shape into an SVG container. +- **Features**: + - Handles the creation and insertion of complex polygonal shapes. + - Configures the shape's appearance and positioning within the SVG container. + +### 4. `getNodeClasses` + +- **Purpose**: Returns the appropriate CSS classes for a node based on its configuration. +- **Usage**: + - Dynamically applies CSS classes to nodes for styling purposes. + - Ensures that nodes adhere to the desired design and theme. + +### 5. `createPathFromPoints` + +- **Purpose**: Generates an SVG path string from an array of points. +- **Usage**: + - Converts a list of points into a smooth path. + - Useful for creating custom shapes or paths within the SVG. + +### 6. `generateFullSineWavePoints` + +- **Purpose**: Generates points for a sine wave, useful for creating wavy-edged shapes. +- **Usage**: + - Facilitates the creation of shapes with wavy or sine-wave edges. + - Can be used to add decorative or dynamic edges to shapes. + +## Getting Started + +To utilize these utilities, simply import them from the `utils.ts` file into your shape creation script. These helpers will streamline the process of building and customizing SVG shapes, ensuring consistent results across your projects. + +```typescript +import { + labelHelper, + updateNodeBounds, + insertPolygonShape, + getNodeClasses, + createPathFromPoints, + generateFullSineWavePoints, +} from './utils.ts'; +``` + +## Example Usage + +Here’s a basic example of how you might use some of these utilities: + +```typescript +import { labelHelper, insertPolygonShape } from './utils.ts'; + +const svgContainer = document.getElementById('svgContainer'); + +// Insert a polygon shape +insertPolygonShape(svgContainer /* shape-specific parameters */); + +// Create and insert a label inside the shape +labelHelper(svgContainer /* label-specific parameters */); +``` + +## Adding New Shapes + +### 1. Create the Shape Function + +To add a new shape: + +- **Create the shape function**: Create a new file of name of the shape and export a function in the `shapes` directory that generates your shape. The file and function should follow the pattern used in existing shapes and return an SVG element. + +- **Example**: + + ```typescript + import { Node, RenderOptions } from '../../types.ts'; + + export const myNewShape = async ( + parent: SVGAElement, + node: Node, + renderOptions: RenderOptions + ) => { + // Create your shape here + const shape = parent.insert('g').attr('class', 'my-new-shape'); + // Add other elements or styles as needed + return shape; + }; + ``` + +### 2. Register the Shape + +- **Register the shape**: Add your shape to the `shapes` object in the [main shapes module](../rendering-util/rendering-elements/shapes.ts). This allows your shape to be recognized and used within the system. + +- **Example**: + + ```typescript + import { myNewShape } from './shapes/myNewShape'; + + const shapes = { + ..., + { + semanticName: 'My Shape', + name: 'Shape Name', + shortName: '', + description: '', + aliases: ['', '', '', ''], + handler: myNewShape, + }, + }; + ``` + +# Shape Intersection Algorithms + +This contains algorithms and utilities for calculating intersection points for various shapes in SVG. Arrow intersection points are crucial for accurately determining where arrows connect with shapes. Ensuring precise intersection points enhances the clarity and accuracy of flowcharts and diagrams. + +## Shape Intersection Functions + +### 1. `Ellipse` + +Calculates the intersection points for an ellipse. + +**Usage**: + +```javascript +import intersectEllipse from './intersect-ellipse.js'; + +const intersection = intersectEllipse(node, rx, ry, point); +``` + +- **Parameters**: + - `node`: The SVG node element. + - `rx`: The x-radius of the ellipse. + - `ry`: The y-radius of the ellipse. + - `point`: The point from which the intersection is calculated. + +### 2. `intersectRect` + +Calculates the intersection points for a rectangle. + +**Usage**: + +```javascript +import intersectRect from './intersect-rect.js'; + +const intersection = intersectRect(node, point); +``` + +- **Parameters**: + - `node`: The SVG node element. + - `point`: The point from which the intersection is calculated. + +### 3. `intersectPolygon` + +Calculates the intersection points for a polygon. + +**Usage**: + +```javascript +import intersectPolygon from './intersect-polygon.js'; + +const intersection = intersectPolygon(node, polyPoints, point); +``` + +- **Parameters**: + - `node`: The SVG node element. + - `polyPoints`: Array of points defining the polygon. + - `point`: The point from which the intersection is calculated. + +## Cypress Tests + +To ensure the robustness of the flowchart shapes, there are implementation of comprehensive Cypress test cases in `newShapes.spec.ts` file. These tests cover various aspects such as: + +- **Shapes**: Testing new shapes like `bowTieRect`, `waveRectangle`, `trapezoidalPentagon`, etc. +- **Looks**: Verifying shapes under different visual styles (`classic` and `handDrawn`). +- **Directions**: Ensuring correct rendering in all flow directions of arrows : + - `TB` `(Top -> Bottom)` + - `BT` `(Bottom -> Top)` + - `LR` `(Left -> Right)` + - `RL` `(Right -> Left)` +- **Labels**: Testing shapes with different labels, including: + - No labels + - Short labels + - Very long labels + - Markdown with `htmlLabels:true` and `htmlLabels:false` +- **Styles**: Applying custom styles to shapes and verifying correct rendering. +- **Class Definitions**: Using `classDef` to apply custom classes and testing their impact. + +### Running the Tests + +To run the Cypress tests, follow these steps: + +1. Ensure you have all dependencies installed by running: + ```bash + pnpm install + ``` +2. Start the Cypress test runner: + + ```bash + cypress open --env updateSnapshots=true + + ``` + +3. Select the test suite from the Cypress interface to run all the flowchart shape tests. diff --git a/packages/mermaid/src/docs/config/icons.md b/packages/mermaid/src/docs/config/icons.md new file mode 100644 index 000000000..db079f841 --- /dev/null +++ b/packages/mermaid/src/docs/config/icons.md @@ -0,0 +1,49 @@ +# Registering icon pack in mermaid + +The icon packs available can be found at [icones.js.org](https://icones.js.org/). +We use the name defined when registering the icon pack, to override the prefix field of the iconify pack. This allows the user to use shorter names for the icons. It also allows us to load a particular pack only when it is used in a diagram. + +Using JSON file directly from CDN: + +```js +import mermaid from 'CDN/mermaid.esm.mjs'; +mermaid.registerIconPacks([ + { + name: 'logos', + loader: () => + fetch('https://unpkg.com/@iconify-json/logos@1/icons.json').then((res) => res.json()), + }, +]); +``` + +Using packages and a bundler: + +```bash +npm install @iconify-json/logos@1 +``` + +With lazy loading + +```js +import mermaid from 'mermaid'; + +mermaid.registerIconPacks([ + { + name: 'logos', + loader: () => import('@iconify-json/logos').then((module) => module.icons), + }, +]); +``` + +Without lazy loading + +```js +import mermaid from 'mermaid'; +import { icons } from '@iconify-json/logos'; +mermaid.registerIconPacks([ + { + name: icons.prefix, // To use the prefix defined in the icon pack + icons, + }, +]); +``` diff --git a/packages/mermaid/src/docs/ecosystem/integrations-community.md b/packages/mermaid/src/docs/ecosystem/integrations-community.md index 9970d1e9c..974cccc12 100644 --- a/packages/mermaid/src/docs/ecosystem/integrations-community.md +++ b/packages/mermaid/src/docs/ecosystem/integrations-community.md @@ -59,7 +59,7 @@ To add an integration to this list, see the [Integrations - create page](./integ - [Mermaid Flow Visual Editor](https://www.mermaidflow.app) ✅ - [Mermerd](https://github.com/KarnerTh/mermerd) - [Slab](https://slab.com) ✅ -- [Swimm](https://docs.swimm.io/features/diagrams-and-charts/#mermaid--swimm--up-to-date-diagrams-) ✅ +- [Swimm](https://docs.swimm.io/features/diagrams-and-charts) ✅ - [NotesHub](https://noteshub.app) ✅ - [Notion](https://notion.so) ✅ - [Observable](https://observablehq.com/@observablehq/mermaid) ✅ @@ -195,15 +195,22 @@ Communication tools and platforms - [Vim](https://www.vim.org) - [Vim Diagram Syntax](https://github.com/zhaozg/vim-diagram) - [Official Vim Syntax and ft plugin](https://github.com/craigmac/vim-mermaid) +- [Zed](https://zed.dev) + - [zed-mermaid](https://github.com/gabeidx/zed-mermaid) ### Document Generation +- [Astro](https://astro.build/) + - [Adding diagrams to your Astro site with MermaidJS and Playwright](https://agramont.net/blog/diagraming-with-mermaidjs-astro/) - [Codedoc](https://codedoc.cc/) - [codedoc-mermaid-plugin](https://www.npmjs.com/package/codedoc-mermaid-plugin) - [Docsy Hugo Theme](https://www.docsy.dev/docs/adding-content/lookandfeel/#diagrams-with-mermaid) ✅ - [Docusaurus](https://docusaurus.io/docs/markdown-features/diagrams) ✅ - [Gatsby](https://www.gatsbyjs.com/) - [gatsby-remark-mermaid](https://github.com/remcohaszing/gatsby-remark-mermaid) +- [Jekyll](https://jekyllrb.com/) + - [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid) + - [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams) - [JSDoc](https://jsdoc.app/) - [jsdoc-mermaid](https://github.com/Jellyvision/jsdoc-mermaid) - [Madness](https://madness.dannyb.co/) @@ -212,7 +219,7 @@ Communication tools and platforms - [MkDocs](https://www.mkdocs.org) - [mkdocs-mermaid2-plugin](https://github.com/fralau/mkdocs-mermaid2-plugin) - [mkdocs-material](https://github.com/squidfunk/mkdocs-material), check the [docs](https://squidfunk.github.io/mkdocs-material/reference/diagrams/) - - [Quarto](https://quarto.org/) +- [Quarto](https://quarto.org/) ✅ - [rehype](https://github.com/rehypejs/rehype) - [rehype-mermaid](https://github.com/remcohaszing/rehype-mermaid) - [remark](https://remark.js.org/) @@ -241,17 +248,12 @@ Communication tools and platforms ### Other -- [Astro](https://astro.build/) - - [Adding diagrams to your Astro site with MermaidJS and Playwright](https://agramont.net/blog/diagraming-with-mermaidjs-astro/) - [Bisheng](https://www.npmjs.com/package/bisheng) - [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid) - [Blazorade Mermaid: Render Mermaid diagrams in Blazor applications](https://github.com/Blazorade/Blazorade-Mermaid/wiki) - [Codemia: A tool to practice system design problems](https://codemia.io) ✅ - [ExDoc](https://github.com/elixir-lang/ex_doc) - [Rendering Mermaid graphs](https://github.com/elixir-lang/ex_doc#rendering-mermaid-graphs) -- [Jekyll](https://jekyllrb.com/) - - [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid) - - [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams) - [MarkChart: Preview Mermaid diagrams on macOS](https://markchart.app/) - [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic) - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server) diff --git a/packages/mermaid/src/docs/ecosystem/mermaid-chart.md b/packages/mermaid/src/docs/ecosystem/mermaid-chart.md index 049df836e..77a7020b7 100644 --- a/packages/mermaid/src/docs/ecosystem/mermaid-chart.md +++ b/packages/mermaid/src/docs/ecosystem/mermaid-chart.md @@ -16,17 +16,20 @@ Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an accoun - **Editor** - A web based editor for creating and editing Mermaid diagrams. -- **Visual Editor** - The Visual Editor enables users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options. +- **Mermaid AI** - Use our embedded AI Chat to generate diagrams from natural language descriptions. -- **AI Chat** - Use our embedded AI Chat to generate diagrams from natural language descriptions. +- **Whiteboard** - A virtual whiteboard for creating and editing Mermaid diagrams. - **Plugins** - A plugin system for extending the functionality of Mermaid. Official Mermaid Chart plugins: - [Mermaid Chart GPT](https://chat.openai.com/g/g-1IRFKwq4G-mermaid-chart) + - [Confluence](https://marketplace.atlassian.com/apps/1234056/mermaid-chart-for-confluence?hosting=cloud&tab=overview) + - [Jira](https://marketplace.atlassian.com/apps/1234810/mermaid-chart-for-jira?tab=overview&hosting=cloud) - [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MermaidChart.vscode-mermaid-chart) - [JetBrains IDE](https://plugins.jetbrains.com/plugin/23043-mermaid-chart) + - [Google Docs](https://gsuite.google.com/marketplace/app/mermaidchart/947683068472) - [Microsoft PowerPoint and Word](https://appsource.microsoft.com/en-us/product/office/WA200006214?tab=Overview) Visit our [Plugins](https://www.mermaidchart.com/plugins) page for more information. diff --git a/packages/mermaid/src/docs/intro/syntax-reference.md b/packages/mermaid/src/docs/intro/syntax-reference.md index 7d7fd5994..14c56370a 100644 --- a/packages/mermaid/src/docs/intro/syntax-reference.md +++ b/packages/mermaid/src/docs/intro/syntax-reference.md @@ -76,8 +76,8 @@ Mermaid offers a variety of styles or “looks” for your diagrams, allowing yo **Available Looks:** - • Hand-Drawn Look: For a more personal, creative touch, the hand-drawn look brings a sketch-like quality to your diagrams. This style is perfect for informal settings or when you want to add a bit of personality to your diagrams. - • Classic Look: If you prefer the traditional Mermaid style, the classic look maintains the original appearance that many users are familiar with. It’s great for consistency across projects or when you want to keep the familiar aesthetic. +- Hand-Drawn Look: For a more personal, creative touch, the hand-drawn look brings a sketch-like quality to your diagrams. This style is perfect for informal settings or when you want to add a bit of personality to your diagrams. +- Classic Look: If you prefer the traditional Mermaid style, the classic look maintains the original appearance that many users are familiar with. It’s great for consistency across projects or when you want to keep the familiar aesthetic. **How to Select a Look:** @@ -101,8 +101,8 @@ In addition to customizing the look of your diagrams, Mermaid Chart now allows y #### Supported Layout Algorithms: - • Dagre (default): This is the classic layout algorithm that has been used in Mermaid for a long time. It provides a good balance of simplicity and visual clarity, making it ideal for most diagrams. - • ELK: For those who need more sophisticated layout capabilities, especially when working with large or intricate diagrams, the ELK (Eclipse Layout Kernel) layout offers advanced options. It provides a more optimized arrangement, potentially reducing overlapping and improving readability. This is not included out the box but needs to be added when integrating mermaid for sites/applications that want to have elk support. +- Dagre (default): This is the classic layout algorithm that has been used in Mermaid for a long time. It provides a good balance of simplicity and visual clarity, making it ideal for most diagrams. +- ELK: For those who need more sophisticated layout capabilities, especially when working with large or intricate diagrams, the ELK (Eclipse Layout Kernel) layout offers advanced options. It provides a more optimized arrangement, potentially reducing overlapping and improving readability. This is not included out the box but needs to be added when integrating mermaid for sites/applications that want to have elk support. #### How to Select a Layout Algorithm: diff --git a/packages/mermaid/src/docs/news/blog.md b/packages/mermaid/src/docs/news/blog.md index 36a84396d..d15f79cdc 100644 --- a/packages/mermaid/src/docs/news/blog.md +++ b/packages/mermaid/src/docs/news/blog.md @@ -1,5 +1,23 @@ # Blog +## [Mermaid 11.4 is out: New Features and Kanban Diagramming](https://www.mermaidchart.com/blog/posts/mermaid-11-4-is-out-new-features-and-kanban-diagramming) + +Mermaid 11.4 brings enhanced functionality with the introduction of Kanban diagrams, allowing users to create visual workflows with status columns and task details. + +October 31, 2024 · 2 mins + +## [How To Build an ER Diagram with Mermaid Chart](https://www.mermaidchart.com/blog/posts/how-to-build-an-er-diagram-with-mermaid-chart) + +An entity relationship (ER) diagram acts like a blueprint for your database. This makes ER diagrams effective tools for anyone dealing with complex databases, data modeling, and AI model training. + +October 24, 2024 · 4 mins + +## [Expanding the Horizons of Mermaid Flowcharts: Introducing 30 New Shapes!](https://www.mermaidchart.com/blog/posts/new-mermaid-flowchart-shapes/) + +24 September 2024 · 5 mins + +Discover 30 new shapes in Mermaid flowcharts, offering enhanced clarity, customization, and versatility for more dynamic and expressive visualizations. + ## [Introducing Architecture Diagrams in Mermaid](https://www.mermaidchart.com/blog/posts/mermaid-supports-architecture-diagrams/) 2 September 2024 · 2 mins diff --git a/packages/mermaid/src/docs/syntax/architecture.md b/packages/mermaid/src/docs/syntax/architecture.md index 476c60532..3fc5629f4 100644 --- a/packages/mermaid/src/docs/syntax/architecture.md +++ b/packages/mermaid/src/docs/syntax/architecture.md @@ -59,15 +59,15 @@ service {service id}({icon name})[{title}] (in {parent id})? Put together: ``` -service database(db)[Database] +service database1(database)[My Database] ``` -creates the service identified as `database`, using the icon `db`, with the label `Database`. +creates the service identified as `database1`, using the icon `database`, with the label `My Database`. If the service belongs to a group, it can be placed inside it through the optional `in` keyword ``` -service database(db)[Database] in private_api +service database1(database)[My Database] in private_api ``` ### Edges @@ -156,55 +156,7 @@ architecture-beta ## Icons By default, architecture diagram supports the following icons: `cloud`, `database`, `disk`, `internet`, `server`. -Users can use any of the 200,000+ icons available in iconify.design, or add their own custom icons, by following the steps below. - -The icon packs available can be found at [icones.js.org](https://icones.js.org/). -We use the name defined when registering the icon pack, to override the prefix field of the iconify pack. This allows the user to use shorter names for the icons. It also allows us to load a particular pack only when it is used in a diagram. - -Using JSON file directly from CDN: - -```js -import mermaid from 'CDN/mermaid.esm.mjs'; -mermaid.registerIconPacks([ - { - name: 'logos', - loader: () => - fetch('https://unpkg.com/@iconify-json/logos/icons.json').then((res) => res.json()), - }, -]); -``` - -Using packages and a bundler: - -```bash -npm install @iconify-json/logos -``` - -With lazy loading - -```js -import mermaid from 'mermaid'; - -mermaid.registerIconPacks([ - { - name: 'logos', - loader: () => import('@iconify-json/logos').then((module) => module.icons), - }, -]); -``` - -Without lazy loading - -```js -import mermaid from 'mermaid'; -import { icons } from '@iconify-json/logos'; -mermaid.registerIconPacks([ - { - name: icons.prefix, // To use the prefix defined in the icon pack - icons, - }, -]); -``` +Users can use any of the 200,000+ icons available in iconify.design, or add their own custom icons, by following the steps [here](../config/icons.md). After the icons are installed, they can be used in the architecture diagram by using the format "name:icon-name", where name is the value used when registering the icon pack. diff --git a/packages/mermaid/src/docs/syntax/block.md b/packages/mermaid/src/docs/syntax/block.md index 7c5907dc7..5b8aa1c99 100644 --- a/packages/mermaid/src/docs/syntax/block.md +++ b/packages/mermaid/src/docs/syntax/block.md @@ -106,7 +106,7 @@ block-beta a["A label"] b:2 c:2 d ``` -In this example, the block labeled "A wide one" spans two columns, while blocks 'b', 'c', and 'd' are allocated their own columns. This flexibility in block sizing is crucial for accurately representing systems with components of varying significance or size. +In this example, the block labeled "A labels" spans one column, while blocks 'b', 'c' span 2 columns, and 'd' is again allocated its own column. This flexibility in block sizing is crucial for accurately representing systems with components of varying significance or size. ### Creating Composite Blocks @@ -153,6 +153,19 @@ block-beta This example demonstrates how Mermaid dynamically adjusts the width of the columns to accommodate the widest block, in this case, 'a' and the composite block 'e'. This dynamic adjustment is essential for creating visually balanced and easy-to-understand diagrams. +**Merging Blocks Horizontally:** +In scenarios where you need to stack blocks horizontally, you can use column width to accomplish the task. Blocks can be arranged vertically by putting them in a single column. Here is how you can create a block diagram in which 4 blocks are stacked on top of each other: + +```mermaid-example +block-beta + block + columns 1 + a["A label"] b c d + end +``` + +In this example, the width of the merged block dynamically adjusts to the width of the largest child block. + With these advanced configuration options, Mermaid's block diagrams can be tailored to represent a wide array of complex systems and structures. The flexibility offered by these features enables users to create diagrams that are both informative and visually appealing. In the following sections, we will explore further capabilities, including different block shapes and linking options. ## 4. Block Varieties and Shapes diff --git a/packages/mermaid/src/docs/syntax/classDiagram.md b/packages/mermaid/src/docs/syntax/classDiagram.md index 029d11b54..552670d3f 100644 --- a/packages/mermaid/src/docs/syntax/classDiagram.md +++ b/packages/mermaid/src/docs/syntax/classDiagram.md @@ -277,6 +277,34 @@ And `Link` can be one of: | -- | Solid | | .. | Dashed | +### Lollipop Interfaces + +Classes can also be given a special relation type that defines a lollipop interface on the class. A lollipop interface is defined using the following syntax: + +- `bar ()-- foo` +- `foo --() bar` + +The interface (bar) with the lollipop connects to the class (foo). + +Note: Each interface that is defined is unique and is meant to not be shared between classes / have multiple edges connecting to it. + +```mermaid-example +classDiagram + bar ()-- foo +``` + +```mermaid-example +classDiagram + class Class01 { + int amount + draw() + } + Class01 --() bar + Class02 --() bar + + foo ()-- Class01 +``` + ## Define Namespace A namespace groups classes. @@ -518,10 +546,12 @@ Beginner's tip—a full example using interactive links in an HTML page: ## Styling -### Styling a node (v10.7.0+) +### Styling a node It is possible to apply specific styles such as a thicker border or a different background color to an individual node using the `style` keyword. +Note that notes and namespaces cannot be styled individually but do support themes. + ```mermaid-example classDiagram class Animal @@ -533,11 +563,78 @@ classDiagram #### Classes More convenient than defining the style every time is to define a class of styles and attach this class to the nodes that -should have a different look. This is done by predefining classes in css styles that can be applied from the graph definition using the `cssClass` statement or the `:::` short hand. +should have a different look. + +A class definition looks like the example below: + +``` +classDef className fill:#f9f,stroke:#333,stroke-width:4px; +``` + +Also, it is possible to define style to multiple classes in one statement: + +``` +classDef firstClassName,secondClassName font-size:12pt; +``` + +Attachment of a class to a node is done as per below: + +``` +cssClass "nodeId1" className; +``` + +It is also possible to attach a class to a list of nodes in one statement: + +``` +cssClass "nodeId1,nodeId2" className; +``` + +A shorter form of adding a class is to attach the classname to the node using the `:::` operator: + +```mermaid-example +classDiagram + class Animal:::someclass + classDef someclass fill:#f96 +``` + +Or: + +```mermaid-example +classDiagram + class Animal:::someclass { + -int sizeInFeet + -canEat() + } + classDef someclass fill:#f96 +``` + +### Default class + +If a class is named default it will be applied to all nodes. Specific styles and classes should be defined afterwards to override the applied default styling. + +``` +classDef default fill:#f9f,stroke:#333,stroke-width:4px; +``` + +```mermaid-example +classDiagram + class Animal:::pink + class Mineral + + classDef default fill:#f96,color:red + classDef pink color:#f9f +``` + +### CSS Classes + +It is also possible to predefine classes in CSS styles that can be applied from the graph definition as in the example +below: + +**Example style** ```html ``` -Then attaching that class to a specific node: - -``` - cssClass "nodeId1" styleClass; -``` - -It is also possible to attach a class to a list of nodes in one statement: - -``` - cssClass "nodeId1,nodeId2" styleClass; -``` - -A shorter form of adding a class is to attach the classname to the node using the `:::` operator: +**Example definition** ```mermaid-example classDiagram class Animal:::styleClass ``` -Or: - -```mermaid-example -classDiagram - class Animal:::styleClass { - -int sizeInFeet - -canEat() - } -``` - -?> cssClasses cannot be added using this shorthand method at the same time as a relation statement. - -?> Due to limitations with existing markup for class diagrams, it is not currently possible to define css classes within the diagram itself. **_Coming soon!_** - -### Default Styles - -The main styling of the class diagram is done with a preset number of css classes. During rendering these classes are extracted from the file located at src/themes/class.scss. The classes used here are described below: - -| Class | Description | -| ------------------ | ----------------------------------------------------------------- | -| g.classGroup text | Styles for general class text | -| classGroup .title | Styles for general class title | -| g.classGroup rect | Styles for class diagram rectangle | -| g.classGroup line | Styles for class diagram line | -| .classLabel .box | Styles for class label box | -| .classLabel .label | Styles for class label text | -| composition | Styles for composition arrow head and arrow line | -| aggregation | Styles for aggregation arrow head and arrow line(dashed or solid) | -| dependency | Styles for dependency arrow head and arrow line | - -#### Sample stylesheet - -```scss -body { - background: white; -} - -g.classGroup text { - fill: $nodeBorder; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-family: var(--mermaid-font-family); - font-size: 10px; - - .title { - font-weight: bolder; - } -} - -g.classGroup rect { - fill: $nodeBkg; - stroke: $nodeBorder; -} - -g.classGroup line { - stroke: $nodeBorder; - stroke-width: 1; -} - -.classLabel .box { - stroke: none; - stroke-width: 0; - fill: $nodeBkg; - opacity: 0.5; -} - -.classLabel .label { - fill: $nodeBorder; - font-size: 10px; -} - -.relation { - stroke: $nodeBorder; - stroke-width: 1; - fill: none; -} - -@mixin composition { - fill: $nodeBorder; - stroke: $nodeBorder; - stroke-width: 1; -} - -#compositionStart { - @include composition; -} - -#compositionEnd { - @include composition; -} - -@mixin aggregation { - fill: $nodeBkg; - stroke: $nodeBorder; - stroke-width: 1; -} - -#aggregationStart { - @include aggregation; -} - -#aggregationEnd { - @include aggregation; -} - -#dependencyStart { - @include composition; -} - -#dependencyEnd { - @include composition; -} - -#extensionStart { - @include composition; -} - -#extensionEnd { - @include composition; -} -``` +> cssClasses cannot be added using this shorthand method at the same time as a relation statement. ## Configuration -`Coming soon!` +### Members Box + +It is possible to hide the empty members box of a class node. + +This is done by changing the **hideEmptyMembersBox** value of the class diagram configuration. For more information on how to edit the Mermaid configuration see the [configuration page.](https://mermaid.js.org/config/configuration.html) + +```mermaid-example +--- + config: + class: + hideEmptyMembersBox: true +--- +classDiagram + class Duck +``` diff --git a/packages/mermaid/src/docs/syntax/flowchart.md b/packages/mermaid/src/docs/syntax/flowchart.md index acffbc693..829b71c2d 100644 --- a/packages/mermaid/src/docs/syntax/flowchart.md +++ b/packages/mermaid/src/docs/syntax/flowchart.md @@ -194,6 +194,404 @@ flowchart TD id1(((This is the text in the circle))) ``` +## Expanded Node Shapes in Mermaid Flowcharts (v11.3.0+) + +Mermaid introduces 30 new shapes to enhance the flexibility and precision of flowchart creation. These new shapes provide more options to represent processes, decisions, events, data storage visually, and other elements within your flowcharts, improving clarity and semantic meaning. + +New Syntax for Shape Definition + +Mermaid now supports a general syntax for defining shape types to accommodate the growing number of shapes. This syntax allows you to assign specific shapes to nodes using a clear and flexible format: + +``` +A@{ shape: rect } +``` + +This syntax creates a node A as a rectangle. It renders in the same way as `A["A"]`, or `A`. + +### Complete List of New Shapes + +Below is a comprehensive list of the newly introduced shapes and their corresponding semantic meanings, short names, and aliases: + + + +### Example Flowchart with New Shapes + +Here’s an example flowchart that utilizes some of the newly introduced shapes: + +```mermaid-example +flowchart RL + A@{ shape: manual-file, label: "File Handling"} + B@{ shape: manual-input, label: "User Input"} + C@{ shape: docs, label: "Multiple Documents"} + D@{ shape: procs, label: "Process Automation"} + E@{ shape: paper-tape, label: "Paper Records"} +``` + +### Process + +```mermaid-example +flowchart TD + A@{ shape: rect, label: "This is a process" } +``` + +### Event + +```mermaid-example +flowchart TD + A@{ shape: rounded, label: "This is an event" } +``` + +### Terminal Point (Stadium) + +```mermaid-example +flowchart TD + A@{ shape: stadium, label: "Terminal point" } +``` + +### Subprocess + +```mermaid-example +flowchart TD + A@{ shape: subproc, label: "This is a subprocess" } +``` + +### Database (Cylinder) + +```mermaid-example +flowchart TD + A@{ shape: cyl, label: "Database" } +``` + +### Start (Circle) + +```mermaid-example +flowchart TD + A@{ shape: circle, label: "Start" } +``` + +### Odd + +```mermaid-example +flowchart TD + A@{ shape: odd, label: "Odd shape" } +``` + +### Decision (Diamond) + +```mermaid-example +flowchart TD + A@{ shape: diamond, label: "Decision" } +``` + +### Prepare Conditional (Hexagon) + +```mermaid-example +flowchart TD + A@{ shape: hex, label: "Prepare conditional" } +``` + +### Data Input/Output (Lean Right) + +```mermaid-example +flowchart TD + A@{ shape: lean-r, label: "Input/Output" } +``` + +### Data Input/Output (Lean Left) + +```mermaid-example +flowchart TD + A@{ shape: lean-l, label: "Output/Input" } +``` + +### Priority Action (Trapezoid Base Bottom) + +```mermaid-example +flowchart TD + A@{ shape: trap-b, label: "Priority action" } +``` + +### Manual Operation (Trapezoid Base Top) + +```mermaid-example +flowchart TD + A@{ shape: trap-t, label: "Manual operation" } +``` + +### Stop (Double Circle) + +```mermaid-example +flowchart TD + A@{ shape: dbl-circ, label: "Stop" } +``` + +### Text Block + +```mermaid-example +flowchart TD + A@{ shape: text, label: "This is a text block" } +``` + +### Card (Notched Rectangle) + +```mermaid-example +flowchart TD + A@{ shape: notch-rect, label: "Card" } +``` + +### Lined/Shaded Process + +```mermaid-example +flowchart TD + A@{ shape: lin-rect, label: "Lined process" } +``` + +### Start (Small Circle) + +```mermaid-example +flowchart TD + A@{ shape: sm-circ, label: "Small start" } +``` + +### Stop (Framed Circle) + +```mermaid-example +flowchart TD + A@{ shape: framed-circle, label: "Stop" } +``` + +### Fork/Join (Long Rectangle) + +```mermaid-example +flowchart TD + A@{ shape: fork, label: "Fork or Join" } +``` + +### Collate (Hourglass) + +```mermaid-example +flowchart TD + A@{ shape: hourglass, label: "Collate" } +``` + +### Comment (Curly Brace) + +```mermaid-example +flowchart TD + A@{ shape: comment, label: "Comment" } +``` + +### Comment Right (Curly Brace Right) + +```mermaid-example +flowchart TD + A@{ shape: brace-r, label: "Comment" } +``` + +### Comment with braces on both sides + +```mermaid-example +flowchart TD + A@{ shape: braces, label: "Comment" } +``` + +### Com Link (Lightning Bolt) + +```mermaid-example +flowchart TD + A@{ shape: bolt, label: "Communication link" } +``` + +### Document + +```mermaid-example +flowchart TD + A@{ shape: doc, label: "Document" } +``` + +### Delay (Half-Rounded Rectangle) + +```mermaid-example +flowchart TD + A@{ shape: delay, label: "Delay" } +``` + +### Direct Access Storage (Horizontal Cylinder) + +```mermaid-example +flowchart TD + A@{ shape: das, label: "Direct access storage" } +``` + +### Disk Storage (Lined Cylinder) + +```mermaid-example +flowchart TD + A@{ shape: lin-cyl, label: "Disk storage" } +``` + +### Display (Curved Trapezoid) + +```mermaid-example +flowchart TD + A@{ shape: curv-trap, label: "Display" } +``` + +### Divided Process (Divided Rectangle) + +```mermaid-example +flowchart TD + A@{ shape: div-rect, label: "Divided process" } +``` + +### Extract (Small Triangle) + +```mermaid-example +flowchart TD + A@{ shape: tri, label: "Extract" } +``` + +### Internal Storage (Window Pane) + +```mermaid-example +flowchart TD + A@{ shape: win-pane, label: "Internal storage" } +``` + +### Junction (Filled Circle) + +```mermaid-example +flowchart TD + A@{ shape: f-circ, label: "Junction" } +``` + +### Lined Document + +```mermaid-example +flowchart TD + A@{ shape: lin-doc, label: "Lined document" } +``` + +### Loop Limit (Notched Pentagon) + +```mermaid-example +flowchart TD + A@{ shape: notch-pent, label: "Loop limit" } +``` + +### Manual File (Flipped Triangle) + +```mermaid-example +flowchart TD + A@{ shape: flip-tri, label: "Manual file" } +``` + +### Manual Input (Sloped Rectangle) + +```mermaid-example +flowchart TD + A@{ shape: sl-rect, label: "Manual input" } +``` + +### Multi-Document (Stacked Document) + +```mermaid-example +flowchart TD + A@{ shape: docs, label: "Multiple documents" } +``` + +### Multi-Process (Stacked Rectangle) + +```mermaid-example +flowchart TD + A@{ shape: processes, label: "Multiple processes" } +``` + +### Paper Tape (Flag) + +```mermaid-example +flowchart TD + A@{ shape: flag, label: "Paper tape" } +``` + +### Stored Data (Bow Tie Rectangle) + +```mermaid-example +flowchart TD + A@{ shape: bow-rect, label: "Stored data" } +``` + +### Summary (Crossed Circle) + +```mermaid-example +flowchart TD + A@{ shape: cross-circ, label: "Summary" } +``` + +### Tagged Document + +```mermaid-example +flowchart TD + A@{ shape: tag-doc, label: "Tagged document" } +``` + +### Tagged Process (Tagged Rectangle) + +```mermaid-example +flowchart TD + A@{ shape: tag-rect, label: "Tagged process" } +``` + +## Special shapes in Mermaid Flowcharts (v11.3.0+) + +Mermaid also introduces 2 special shapes to enhance your flowcharts: **icon** and **image**. These shapes allow you to include icons and images directly within your flowcharts, providing more visual context and clarity. + +### Icon Shape + +You can use the `icon` shape to include an icon in your flowchart. To use icons, you need to register the icon pack first. Follow the instructions provided [here](../config/icons.md). The syntax for defining an icon shape is as follows: + +```mermaid-example +flowchart TD + A@{ icon: "fa:user", form: "square", label: "User Icon", pos: "t", h: 60 } +``` + +### Parameters + +- **icon**: The name of the icon from the registered icon pack. +- **form**: Specifies the background shape of the icon. If not defined there will be no background to icon. Options include: + - `square` + - `circle` + - `rounded` +- **label**: The text label associated with the icon. This can be any string. If not defined, no label will be displayed. +- **pos**: The position of the label. If not defined label will default to bottom of icon. Possible values are: + - `t` + - `b` +- **h**: The height of the icon. If not defined this will default to 48 which is minimum. + +### Image Shape + +You can use the `image` shape to include an image in your flowchart. The syntax for defining an image shape is as follows: + +```mermaid-example +flowchart TD + A@{ img: "https://example.com/image.png", label: "Image Label", pos: "t", w: 60, h: 60, constraint: "off" } +``` + +### Parameters + +- **img**: The URL of the image to be displayed. +- **label**: The text label associated with the image. This can be any string. If not defined, no label will be displayed. +- **pos**: The position of the label. If not defined, the label will default to the bottom of the image. Possible values are: + - `t` + - `b` +- **w**: The width of the image. If not defined, this will default to the natural width of the image. +- **h**: The height of the image. If not defined, this will default to the natural height of the image. +- **constraint**: Determines if the image should constrain the node size. This setting also ensures the image maintains its original aspect ratio, adjusting the height (`h`) accordingly to the width (`w`). If not defined, this will default to `off` Possible values are: + - `on` + - `off` + +These new shapes provide additional flexibility and visual appeal to your flowcharts, making them more informative and engaging. + ## Links between nodes Nodes can be connected with links/edges. It is possible to have different types of links or attach a text string to a link. diff --git a/packages/mermaid/src/docs/syntax/kanban.md b/packages/mermaid/src/docs/syntax/kanban.md new file mode 100644 index 000000000..4ef98fbac --- /dev/null +++ b/packages/mermaid/src/docs/syntax/kanban.md @@ -0,0 +1,113 @@ +# Mermaid Kanban Diagram Documentation + +Mermaid’s Kanban diagram allows you to create visual representations of tasks moving through different stages of a workflow. This guide explains how to use the Kanban diagram syntax, based on the provided example. + +## Overview + +A Kanban diagram in Mermaid starts with the kanban keyword, followed by the definition of columns (stages) and tasks within those columns. + +```mermaid-example +kanban + column1[Column Title] + task1[Task Description] +``` + +## Defining Columns + +Columns represent the different stages in your workflow, such as “Todo,” “In Progress,” “Done,” etc. Each column is defined using a unique identifier and a title enclosed in square brackets. + +**Syntax:** + +``` +columnId[Column Title] +``` + +- columnId: A unique identifier for the column. +- [Column Title]: The title displayed on the column header. + +Like this `id1[Todo]` + +## Adding Tasks to Columns + +Tasks are listed under their respective columns with an indentation. Each task also has a unique identifier and a description enclosed in square brackets. + +**Syntax:** + +``` +taskId[Task Description] +``` + + • taskId: A unique identifier for the task. + • [Task Description]: The description of the task. + +**Example:** + +``` +docs[Create Documentation] +``` + +## Adding Metadata to Tasks + +You can include additional metadata for each task using the @{ ... } syntax. Metadata can contain key-value pairs like assigned, ticket, priority, etc. This will be rendered added to the rendering of the node. + +## Supported Metadata Keys + + • assigned: Specifies who is responsible for the task. + • ticket: Links the task to a ticket or issue number. + • priority: Indicates the urgency of the task. Allowed values: 'Very High', 'High', 'Low' and 'Very Low' + +```mermaid-example +kanban +todo[Todo] + id3[Update Database Function]@{ ticket: MC-2037, assigned: 'knsv', priority: 'High' } +``` + +## Configuration Options + +You can customize the Kanban diagram using a configuration block at the beginning of your markdown file. This is useful for setting global settings like a base URL for tickets. Currently there is one configuration option for kanban diagrams tacketBaseUrl. This can be set as in the the following example: + +```yaml +--- +config: + kanban: + ticketBaseUrl: 'https://yourproject.atlassian.net/browse/#TICKET#' +--- +``` + +When the kanban item has an assigned ticket number the ticket number in the diagram will have a link to an external system where the ticket is defined. The `ticketBaseUrl` sets the base URL to the external system and #TICKET# is replaced with the ticket value from task metadata to create a valid link. + +## Full Example + +Below is the full Kanban diagram based on the provided example: + +```mermaid-example +--- +config: + kanban: + ticketBaseUrl: 'https://mermaidchart.atlassian.net/browse/#TICKET#' +--- +kanban + Todo + [Create Documentation] + docs[Create Blog about the new diagram] + [In progress] + id6[Create renderer so that it works in all cases. We also add som extra text here for testing purposes. And some more just for the extra flare.] + id9[Ready for deploy] + id8[Design grammar]@{ assigned: 'knsv' } + id10[Ready for test] + id4[Create parsing tests]@{ ticket: MC-2038, assigned: 'K.Sveidqvist', priority: 'High' } + id66[last item]@{ priority: 'Very Low', assigned: 'knsv' } + id11[Done] + id5[define getData] + id2[Title of diagram is more than 100 chars when user duplicates diagram with 100 char]@{ ticket: MC-2036, priority: 'Very High'} + id3[Update DB function]@{ ticket: MC-2037, assigned: knsv, priority: 'High' } + + id12[Can't reproduce] + id3[Weird flickering in Firefox] +``` + +In conclusion, creating a Kanban diagram in Mermaid is a straightforward process that effectively visualizes your workflow. Start by using the kanban keyword to initiate the diagram. Define your columns with unique identifiers and titles to represent different stages of your project. Under each column, list your tasks—also with unique identifiers—and provide detailed descriptions as needed. Remember that proper indentation is crucial; tasks must be indented under their parent columns to maintain the correct structure. + +You can enhance your diagram by adding optional metadata to tasks using the @{ ... } syntax, which allows you to include additional context such as assignee, ticket numbers, and priority levels. For further customization, utilize the configuration block at the top of your file to set global options like ticketBaseUrl for linking tickets directly from your diagram. + +By adhering to these guidelines—ensuring unique identifiers, proper indentation, and utilizing metadata and configuration options—you can create a comprehensive and customized Kanban board that effectively maps out your project’s workflow using Mermaid. diff --git a/packages/mermaid/src/docs/syntax/sequenceDiagram.md b/packages/mermaid/src/docs/syntax/sequenceDiagram.md index 8826f6275..2357b9bf4 100644 --- a/packages/mermaid/src/docs/syntax/sequenceDiagram.md +++ b/packages/mermaid/src/docs/syntax/sequenceDiagram.md @@ -105,6 +105,9 @@ end box rgb(33,66,99) ... actors ... end +box rgba(33,66,99,0.5) +... actors ... +end ``` ```note @@ -152,7 +155,7 @@ There are ten types of arrows currently supported: | `<<->>` | Solid line with bidirectional arrowheads (v11.0.0+) | | `<<-->>` | Dotted line with bidirectional arrowheads (v11.0.0+) | | `-x` | Solid line with a cross at the end | -| `--x` | Dotted line with a cross at the end. | +| `--x` | Dotted line with a cross at the end | | `-)` | Solid line with an open arrow at the end (async) | | `--)` | Dotted line with a open arrow at the end (async) | @@ -394,6 +397,12 @@ sequenceDiagram It is possible to highlight flows by providing colored background rects. This is done by the notation +``` +rect COLOR +... content ... +end +``` + The colors are defined using rgb and rgba syntax. ``` diff --git a/packages/mermaid/src/mermaid.ts b/packages/mermaid/src/mermaid.ts index 52cca1cfe..e9fc9196a 100644 --- a/packages/mermaid/src/mermaid.ts +++ b/packages/mermaid/src/mermaid.ts @@ -2,7 +2,7 @@ * Web page integration module for the mermaid framework. It uses the mermaidAPI for mermaid * functionality and to render the diagrams to svg code! */ -import { registerIconPacks } from '$root/rendering-util/icons.js'; +import { registerIconPacks } from './rendering-util/icons.js'; import { dedent } from 'ts-dedent'; import type { MermaidConfig } from './config.type.js'; import { detectType, registerLazyLoadedDiagrams } from './diagram-api/detectType.js'; diff --git a/packages/mermaid/src/mermaidAPI.spec.ts b/packages/mermaid/src/mermaidAPI.spec.ts index dd8b3bbc8..5bd1b1dfc 100644 --- a/packages/mermaid/src/mermaidAPI.spec.ts +++ b/packages/mermaid/src/mermaidAPI.spec.ts @@ -1,4 +1,4 @@ -import { vi, it, expect, describe, beforeEach } from 'vitest'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; // ------------------------------------- // Mocks and mocking @@ -66,8 +66,8 @@ vi.mock('stylis', () => { }); import { compile, serialize } from 'stylis'; -import { decodeEntities, encodeEntities } from './utils.js'; import { Diagram } from './Diagram.js'; +import { decodeEntities, encodeEntities } from './utils.js'; import { toBase64 } from './utils/base64.js'; /** @@ -693,18 +693,79 @@ describe('mermaidAPI', () => { await expect(mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).resolves .toMatchInlineSnapshot(` { + "config": {}, "diagramType": "flowchart-v2", } `); }); + it('returns config when defined in frontmatter', async () => { + await expect( + mermaidAPI.parse(`--- +config: + theme: base + flowchart: + htmlLabels: true +--- +graph TD;A--x|text including URL space|B;`) + ).resolves.toMatchInlineSnapshot(` + { + "config": { + "flowchart": { + "htmlLabels": true, + }, + "theme": "base", + }, + "diagramType": "flowchart-v2", + } +`); + }); + + it('returns config when defined in directive', async () => { + await expect( + mermaidAPI.parse(`%%{init: { 'theme': 'base' } }%% +graph TD;A--x|text including URL space|B;`) + ).resolves.toMatchInlineSnapshot(` + { + "config": { + "theme": "base", + }, + "diagramType": "flowchart-v2", + } +`); + }); + + it('returns merged config when defined in frontmatter and directive', async () => { + await expect( + mermaidAPI.parse(`--- +config: + theme: forest + flowchart: + htmlLabels: true +--- +%%{init: { 'theme': 'base' } }%% +graph TD;A--x|text including URL space|B;`) + ).resolves.toMatchInlineSnapshot(` + { + "config": { + "flowchart": { + "htmlLabels": true, + }, + "theme": "base", + }, + "diagramType": "flowchart-v2", + } +`); + }); + it('returns true for valid definition with silent option', async () => { await expect( mermaidAPI.parse('graph TD;A--x|text including URL space|B;', { suppressErrors: true }) ).resolves.toMatchInlineSnapshot(` - { - "diagramType": "flowchart-v2", - } - `); + { + "config": {}, + "diagramType": "flowchart-v2", + } + `); }); }); @@ -718,7 +779,7 @@ describe('mermaidAPI', () => { // We have to have both the specific textDiagramType and the expected type name because the expected type may be slightly different than was is put in the diagram text (ex: in -v2 diagrams) const diagramTypesAndExpectations = [ { textDiagramType: 'C4Context', expectedType: 'c4' }, - { textDiagramType: 'classDiagram', expectedType: 'classDiagram' }, + { textDiagramType: 'classDiagram', expectedType: 'class' }, { textDiagramType: 'classDiagram-v2', expectedType: 'classDiagram' }, { textDiagramType: 'erDiagram', expectedType: 'er' }, { textDiagramType: 'graph', expectedType: 'flowchart-v2' }, diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts index 3fdd967f1..c44161a52 100644 --- a/packages/mermaid/src/mermaidAPI.ts +++ b/packages/mermaid/src/mermaidAPI.ts @@ -73,9 +73,9 @@ async function parse(text: string, parseOptions?: ParseOptions): Promise { addDiagrams(); try { - const { code } = processAndSetConfigs(text); + const { code, config } = processAndSetConfigs(text); const diagram = await getDiagramFromText(code); - return { diagramType: diagram.type }; + return { diagramType: diagram.type, config }; } catch (error) { if (parseOptions?.suppressErrors) { return false; diff --git a/packages/mermaid/src/preprocess.ts b/packages/mermaid/src/preprocess.ts index 10bc0adea..a62326070 100644 --- a/packages/mermaid/src/preprocess.ts +++ b/packages/mermaid/src/preprocess.ts @@ -49,7 +49,7 @@ const processDirectives = (code: string) => { * @param code - The code to preprocess. * @returns The object containing the preprocessed code, title, and configuration. */ -export function preprocessDiagram(code: string): DiagramMetadata & { code: string } { +export function preprocessDiagram(code: string) { const cleanedCode = cleanupText(code); const frontMatterResult = processFrontmatter(cleanedCode); const directiveResult = processDirectives(frontMatterResult.text); @@ -59,5 +59,5 @@ export function preprocessDiagram(code: string): DiagramMetadata & { code: strin code, title: frontMatterResult.title, config, - }; + } satisfies DiagramMetadata & { code: string }; } diff --git a/packages/mermaid/src/rendering-util/createText.ts b/packages/mermaid/src/rendering-util/createText.ts index a6ad7fa1c..cc189e46e 100644 --- a/packages/mermaid/src/rendering-util/createText.ts +++ b/packages/mermaid/src/rendering-util/createText.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ // @ts-nocheck TODO: Fix types -import { getConfig } from '$root/diagram-api/diagramAPI.js'; -import common, { hasKatex, renderKatex } from '$root/diagrams/common/common.js'; +import { getConfig } from '../diagram-api/diagramAPI.js'; +import common, { hasKatex, renderKatex } from '../diagrams/common/common.js'; import { select } from 'd3'; import type { MermaidConfig } from '../config.type.js'; import type { SVGGroup } from '../diagram-api/types.js'; @@ -20,6 +20,11 @@ function applyStyle(dom, styleFn) { async function addHtmlSpan(element, node, width, classes, addBackground = false) { const fo = element.append('foreignObject'); + // This is not the final width but used in order to make sure the foreign + // object in firefox gets a width at all. The final width is fetched from the div + fo.attr('width', `${10 * width}px`); + fo.attr('height', `${10 * width}px`); + const div = fo.append('xhtml:div'); let label = node.label; if (node.label && hasKatex(node.label)) { @@ -136,8 +141,8 @@ function createFormattedText( const bbox = textElement.node().getBBox(); const padding = 2; bkg - .attr('x', -padding) - .attr('y', -padding) + .attr('x', bbox.x - padding) + .attr('y', bbox.y - padding) .attr('width', bbox.width + 2 * padding) .attr('height', bbox.height + 2 * padding); @@ -199,9 +204,9 @@ export const createText = async ( width = 200, addSvgBackground = false, } = {}, - config: MermaidConfig + config?: MermaidConfig ) => { - log.info( + log.debug( 'XYZ createText', text, style, diff --git a/packages/mermaid/src/rendering-util/handle-markdown-text.ts b/packages/mermaid/src/rendering-util/handle-markdown-text.ts index 4b6a04428..f898875cf 100644 --- a/packages/mermaid/src/rendering-util/handle-markdown-text.ts +++ b/packages/mermaid/src/rendering-util/handle-markdown-text.ts @@ -39,6 +39,7 @@ export function markdownToLines(markdown: string, config: MermaidConfig = {}): M lines.push([]); } textLine.split(' ').forEach((word) => { + word = word.replace(/'/g, `'`); if (word) { lines[currentLine].push({ content: word, type: parentType }); } @@ -85,6 +86,8 @@ export function markdownToHTML(markdown: string, { markdownAutoWrap }: MermaidCo return ''; } else if (node.type === 'html') { return `${node.text}`; + } else if (node.type === 'escape') { + return node.text; } return `Unsupported markdown: ${node.type}`; } diff --git a/packages/mermaid/src/rendering-util/icons.ts b/packages/mermaid/src/rendering-util/icons.ts index 27709b822..5eef3f7eb 100644 --- a/packages/mermaid/src/rendering-util/icons.ts +++ b/packages/mermaid/src/rendering-util/icons.ts @@ -1,4 +1,4 @@ -import { log } from '$root/logger.js'; +import { log } from '../logger.js'; import type { ExtendedIconifyIcon, IconifyIcon, IconifyJSON } from '@iconify/types'; import type { IconifyIconCustomisations } from '@iconify/utils'; import { getIconData, iconToHTML, iconToSVG, replaceIDs, stringToIcon } from '@iconify/utils'; diff --git a/packages/mermaid/src/rendering-util/insertElementsForSize.js b/packages/mermaid/src/rendering-util/insertElementsForSize.js index 162551058..b71286351 100644 --- a/packages/mermaid/src/rendering-util/insertElementsForSize.js +++ b/packages/mermaid/src/rendering-util/insertElementsForSize.js @@ -1,5 +1,4 @@ import { select } from 'd3'; -import { insertNode } from '../dagre-wrapper/nodes.js'; export const getDiagramElement = (id, securityLevel) => { let sandboxElement; @@ -17,36 +16,3 @@ export const getDiagramElement = (id, securityLevel) => { return svg; }; - -export function insertElementsForSize(el, data) { - const nodesElem = el.insert('g').attr('class', 'nodes'); - el.insert('g').attr('class', 'edges'); - data.nodes.forEach(async (item) => { - item.shape = 'rect'; - await insertNode(nodesElem, { - ...item, - class: 'default flowchart-label', - labelStyle: '', - x: 0, - y: 0, - width: 100, - rx: 0, - ry: 0, - height: 100, - shape: 'rect', - padding: 8, - }); - // Create a new DOM element - // const element = document.createElement('div'); - - // // Set the content of the element to the name of the item - // element.textContent = item.name; - - // // Set the size of the element to the size of the item - // element.style.width = `${item.size}px`; - // element.style.height = `${item.size}px`; - - // Append the element to the body of the document - // document.body.appendChild(element); - }); -} diff --git a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js index 307242675..6f1fa7d3b 100644 --- a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js +++ b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js @@ -23,7 +23,7 @@ import { insertEdge, clear as clearEdges, } from '../../rendering-elements/edges.js'; -import { log } from '$root/logger.js'; +import { log } from '../../../logger.js'; import { getSubGraphTitleMargins } from '../../../utils/subGraphTitleMargins.js'; import { getConfig } from '../../../diagram-api/diagramAPI.js'; @@ -125,7 +125,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit // insertCluster(clusters, graph.node(v)); } else { log.trace('Node - the non recursive path XAX', v, nodes, graph.node(v), dir); - await insertNode(nodes, graph.node(v), dir); + await insertNode(nodes, graph.node(v), { config: siteConfig, dir }); } } }) @@ -349,8 +349,10 @@ export const render = async (data4Layout, svg) => { edgeMid.arrowTypeEnd = 'none'; edgeMid.id = nodeId + '-cyclic-special-mid'; edge2.label = ''; - edge1.fromCluster = nodeId; - edge2.toCluster = nodeId; + if (node.isGroup) { + edge1.fromCluster = nodeId; + edge2.toCluster = nodeId; + } edge2.id = nodeId + '-cyclic-special-2'; graph.setEdge(nodeId, specialId1, edge1, nodeId + '-cyclic-special-0'); graph.setEdge(specialId1, specialId2, edgeMid, nodeId + '-cyclic-special-1'); diff --git a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.js b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.js index 54ad5d27f..f0e5cd5ed 100644 --- a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.js +++ b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.js @@ -1,5 +1,5 @@ /** Decorates with functions required by mermaids dagre-wrapper. */ -import { log } from '$root/logger.js'; +import { log } from '../../../logger.js'; import * as graphlib from 'dagre-d3-es/src/graphlib/index.js'; import * as graphlibJson from 'dagre-d3-es/src/graphlib/json.js'; diff --git a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.spec.js b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.spec.js index dd71a2f7e..11acd44eb 100644 --- a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.spec.js +++ b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.spec.js @@ -6,7 +6,7 @@ import { extractDescendants, sortNodesByHierarchy, } from './mermaid-graphlib.js'; -import { setLogLevel, log } from '$root/logger.js'; +import { setLogLevel, log } from '../../../logger.js'; describe('Graphlib decorations', () => { let g; diff --git a/packages/mermaid/src/rendering-util/render.ts b/packages/mermaid/src/rendering-util/render.ts index 013be7ba4..b975e7bf9 100644 --- a/packages/mermaid/src/rendering-util/render.ts +++ b/packages/mermaid/src/rendering-util/render.ts @@ -1,7 +1,7 @@ -import type { SVG } from '$root/diagram-api/types.js'; -import type { InternalHelpers } from '$root/internals.js'; -import { internalHelpers } from '$root/internals.js'; -import { log } from '$root/logger.js'; +import type { SVG } from '../diagram-api/types.js'; +import type { InternalHelpers } from '../internals.js'; +import { internalHelpers } from '../internals.js'; +import { log } from '../logger.js'; import type { LayoutData } from './types.js'; export interface RenderOptions { diff --git a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js index ba87f78f5..1dd87d438 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js @@ -1,17 +1,14 @@ -import { getConfig } from '$root/diagram-api/diagramAPI.js'; -import { evaluate } from '$root/diagrams/common/common.js'; -import { log } from '$root/logger.js'; -import { getSubGraphTitleMargins } from '$root/utils/subGraphTitleMargins.js'; +import { getConfig } from '../../diagram-api/diagramAPI.js'; +import { evaluate } from '../../diagrams/common/common.js'; +import { log } from '../../logger.js'; +import { getSubGraphTitleMargins } from '../../utils/subGraphTitleMargins.js'; import { select } from 'd3'; import rough from 'roughjs'; import { createText } from '../createText.ts'; import intersectRect from '../rendering-elements/intersect/intersect-rect.js'; import createLabel from './createLabel.js'; import { createRoundedRectPathD } from './shapes/roundedRectPath.ts'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import { styles2String, userNodeOverrides } from './shapes/handDrawnShapeStyles.js'; const rect = async (parent, node) => { log.info('Creating subgraph rect for ', node.id, node); @@ -283,6 +280,117 @@ const roundedWithTitle = async (parent, node) => { return { cluster: shapeSvg, labelBBox: bbox }; }; +const kanbanSection = async (parent, node) => { + log.info('Creating subgraph rect for ', node.id, node); + const siteConfig = getConfig(); + const { themeVariables, handDrawnSeed } = siteConfig; + const { clusterBkg, clusterBorder } = themeVariables; + + const { labelStyles, nodeStyles, borderStyles, backgroundStyles } = styles2String(node); + + // Add outer g element + const shapeSvg = parent + .insert('g') + .attr('class', 'cluster ' + node.cssClasses) + .attr('id', node.id) + .attr('data-look', node.look); + + const useHtmlLabels = evaluate(siteConfig.flowchart.htmlLabels); + + // Create the label and insert it after the rect + const labelEl = shapeSvg.insert('g').attr('class', 'cluster-label '); + + const text = await createText(labelEl, node.label, { + style: node.labelStyle, + useHtmlLabels, + isNode: true, + width: node.width, + }); + + // Get the size of the label + let bbox = text.getBBox(); + + if (evaluate(siteConfig.flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = select(text); + bbox = div.getBoundingClientRect(); + dv.attr('width', bbox.width); + dv.attr('height', bbox.height); + } + + const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width; + if (node.width <= bbox.width + node.padding) { + node.diff = (width - node.width) / 2 - node.padding; + } else { + node.diff = -node.padding; + } + + const height = node.height; + const x = node.x - width / 2; + const y = node.y - height / 2; + + log.trace('Data ', node, JSON.stringify(node)); + let rect; + if (node.look === 'handDrawn') { + // @ts-ignore TODO: Fix rough typings + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, { + roughness: 0.7, + fill: clusterBkg, + // fill: 'red', + stroke: clusterBorder, + fillWeight: 4, + seed: handDrawnSeed, + }); + const roughNode = rc.path(createRoundedRectPathD(x, y, width, height, node.rx), options); + rect = shapeSvg.insert(() => { + log.debug('Rough node insert CXC', roughNode); + return roughNode; + }, ':first-child'); + // Should we affect the options instead of doing this? + rect.select('path:nth-child(2)').attr('style', borderStyles.join(';')); + rect.select('path').attr('style', backgroundStyles.join(';').replace('fill', 'stroke')); + } else { + // add the rect + rect = shapeSvg.insert('rect', ':first-child'); + // center the rect around its coordinate + rect + .attr('style', nodeStyles) + .attr('rx', node.rx) + .attr('ry', node.ry) + .attr('x', x) + .attr('y', y) + .attr('width', width) + .attr('height', height); + } + const { subGraphTitleTopMargin } = getSubGraphTitleMargins(siteConfig); + labelEl.attr( + 'transform', + // This puts the label on top of the box instead of inside it + `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 + subGraphTitleTopMargin})` + ); + + if (labelStyles) { + const span = labelEl.select('span'); + if (span) { + span.attr('style', labelStyles); + } + } + // Center the label + + const rectBox = rect.node().getBBox(); + node.offsetX = 0; + node.width = rectBox.width; + node.height = rectBox.height; + // Used by layout engine to position subgraph in parent + node.offsetY = bbox.height - node.padding / 2; + + node.intersect = function (point) { + return intersectRect(node, point); + }; + + return { cluster: shapeSvg, labelBBox: bbox }; +}; const divider = (parent, node) => { const siteConfig = getConfig(); @@ -358,10 +466,18 @@ const shapes = { roundedWithTitle, noteGroup, divider, + kanbanSection, }; let clusterElems = new Map(); +/** + * @typedef {keyof typeof shapes} ClusterShapeID + */ + +/** + * @param {import('../types.js').ClusterNode} node - Shape defaults to 'rect' + */ export const insertCluster = async (elem, node) => { const shape = node.shape || 'rect'; const cluster = await shapes[shape](elem, node); diff --git a/packages/mermaid/src/rendering-util/rendering-elements/createLabel.js b/packages/mermaid/src/rendering-util/rendering-elements/createLabel.js index 0afdbb714..482dbb9f1 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/createLabel.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/createLabel.js @@ -1,8 +1,8 @@ import { select } from 'd3'; -import { log } from '$root/logger.js'; -import { getConfig } from '$root/diagram-api/diagramAPI.js'; -import common, { evaluate, renderKatex, hasKatex } from '$root/diagrams/common/common.js'; -import { decodeEntities } from '$root/utils.js'; +import { log } from '../../logger.js'; +import { getConfig } from '../../diagram-api/diagramAPI.js'; +import common, { evaluate, renderKatex, hasKatex } from '../../diagrams/common/common.js'; +import { decodeEntities } from '../../utils.js'; /** * @param dom diff --git a/packages/mermaid/src/rendering-util/rendering-elements/edgeMarker.spec.ts b/packages/mermaid/src/rendering-util/rendering-elements/edgeMarker.spec.ts index 05c7472c9..7702782c2 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/edgeMarker.spec.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/edgeMarker.spec.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/unbound-method */ -import type { SVG } from '$root/diagram-api/types.js'; +import type { SVG } from '../../diagram-api/types.js'; import type { Mocked } from 'vitest'; import { addEdgeMarkers } from './edgeMarker.js'; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/edgeMarker.ts b/packages/mermaid/src/rendering-util/rendering-elements/edgeMarker.ts index ea748d8aa..5371ac32d 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/edgeMarker.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/edgeMarker.ts @@ -1,6 +1,6 @@ -import type { SVG } from '$root/diagram-api/types.js'; -import { log } from '$root/logger.js'; -import type { EdgeData } from '$root/types.js'; +import type { SVG } from '../../diagram-api/types.js'; +import { log } from '../../logger.js'; +import type { EdgeData } from '../../types.js'; /** * Adds SVG markers to a path element based on the arrow types specified in the edge. * diff --git a/packages/mermaid/src/rendering-util/rendering-elements/edges.js b/packages/mermaid/src/rendering-util/rendering-elements/edges.js index 087fcf0be..a6a7a55f7 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/edges.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/edges.js @@ -1,10 +1,10 @@ -import { getConfig } from '$root/diagram-api/diagramAPI.js'; -import { evaluate } from '$root/diagrams/common/common.js'; -import { log } from '$root/logger.js'; -import { createText } from '$root/rendering-util/createText.ts'; -import utils from '$root/utils.js'; -import { getLineFunctionsWithOffset } from '$root/utils/lineWithOffset.js'; -import { getSubGraphTitleMargins } from '$root/utils/subGraphTitleMargins.js'; +import { getConfig } from '../../diagram-api/diagramAPI.js'; +import { evaluate } from '../../diagrams/common/common.js'; +import { log } from '../../logger.js'; +import { createText } from '../createText.js'; +import utils from '../../utils.js'; +import { getLineFunctionsWithOffset } from '../../utils/lineWithOffset.js'; +import { getSubGraphTitleMargins } from '../../utils/subGraphTitleMargins.js'; import { curveBasis, line, select } from 'd3'; import rough from 'roughjs'; import createLabel from './createLabel.js'; @@ -463,15 +463,6 @@ export const insertEdge = function (elem, edge, clusterDb, diagramType, startNod let lineData = points.filter((p) => !Number.isNaN(p.y)); lineData = fixCorners(lineData); - let lastPoint = lineData[lineData.length - 1]; - if (lineData.length > 1) { - lastPoint = lineData[lineData.length - 1]; - const secondLastPoint = lineData[lineData.length - 2]; - const diffX = (lastPoint.x - secondLastPoint.x) / 2; - const diffY = (lastPoint.y - secondLastPoint.y) / 2; - const midPoint = { x: secondLastPoint.x + diffX, y: secondLastPoint.y + diffY }; - lineData.splice(-1, 0, midPoint); - } let curve = curveBasis; if (edge.curve) { curve = edge.curve; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/markers.js b/packages/mermaid/src/rendering-util/rendering-elements/markers.js index 0b0972a8a..b2592e20e 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/markers.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/markers.js @@ -1,5 +1,5 @@ /** Setup arrow head and define the marker. The result is appended to the svg. */ -import { log } from '$root/logger.js'; +import { log } from '../../logger.js'; // Only add the number of markers that the diagram needs const insertMarkers = (elem, markerArray, type, id) => { diff --git a/packages/mermaid/src/rendering-util/rendering-elements/nodes.js b/packages/mermaid/src/rendering-util/rendering-elements/nodes.js deleted file mode 100644 index 54d4ddf3e..000000000 --- a/packages/mermaid/src/rendering-util/rendering-elements/nodes.js +++ /dev/null @@ -1,122 +0,0 @@ -import { log } from '$root/logger.js'; -import { state } from './shapes/state.ts'; -import { roundedRect } from './shapes/roundedRect.ts'; -import { squareRect } from './shapes/squareRect.ts'; -import { stateStart } from './shapes/stateStart.ts'; -import { stateEnd } from './shapes/stateEnd.ts'; -import { forkJoin } from './shapes/forkJoin.ts'; -import { choice } from './shapes/choice.ts'; -import { note } from './shapes/note.ts'; -import { stadium } from './shapes/stadium.js'; -import { rectWithTitle } from './shapes/rectWithTitle.js'; -import { getConfig } from '$root/diagram-api/diagramAPI.js'; -import { subroutine } from './shapes/subroutine.js'; -import { cylinder } from './shapes/cylinder.js'; -import { circle } from './shapes/circle.js'; -import { doublecircle } from './shapes/doubleCircle.js'; -import { rect_left_inv_arrow } from './shapes/rectLeftInvArrow.js'; -import { question } from './shapes/question.js'; -import { hexagon } from './shapes/hexagon.js'; -import { lean_right } from './shapes/leanRight.js'; -import { lean_left } from './shapes/leanLeft.js'; -import { trapezoid } from './shapes/trapezoid.js'; -import { inv_trapezoid } from './shapes/invertedTrapezoid.js'; -import { labelRect } from './shapes/labelRect.js'; - -const shapes = { - state, - stateStart, - stateEnd, - fork: forkJoin, - join: forkJoin, - choice, - note, - roundedRect, - rectWithTitle, - squareRect, - stadium, - subroutine, - cylinder, - circle, - doublecircle, - odd: rect_left_inv_arrow, - diamond: question, - hexagon, - lean_right, - lean_left, - trapezoid, - inv_trapezoid, - labelRect, -}; - -const nodeElems = new Map(); - -export const insertNode = async (elem, node, dir) => { - let newEl; - let el; - - //special check for rect shape (with or without rounded corners) - if (node.shape === 'rect') { - if (node.rx && node.ry) { - node.shape = 'roundedRect'; - } else { - node.shape = 'squareRect'; - } - } - - // Add link when appropriate - if (node.link) { - let target; - if (getConfig().securityLevel === 'sandbox') { - target = '_top'; - } else if (node.linkTarget) { - target = node.linkTarget || '_blank'; - } - newEl = elem.insert('svg:a').attr('xlink:href', node.link).attr('target', target); - el = await shapes[node.shape](newEl, node, dir); - } else { - el = await shapes[node.shape](elem, node, dir); - newEl = el; - } - if (node.tooltip) { - el.attr('title', node.tooltip); - } - - nodeElems.set(node.id, newEl); - - if (node.haveCallback) { - nodeElems.get(node.id).attr('class', nodeElems.get(node.id).attr('class') + ' clickable'); - } - return newEl; -}; -export const setNodeElem = (elem, node) => { - nodeElems.set(node.id, elem); -}; -export const clear = () => { - nodeElems.clear(); -}; - -export const positionNode = (node) => { - const el = nodeElems.get(node.id); - log.trace( - 'Transforming node', - node.diff, - node, - 'translate(' + (node.x - node.width / 2 - 5) + ', ' + node.width / 2 + ')' - ); - const padding = 8; - const diff = node.diff || 0; - if (node.clusterNode) { - el.attr( - 'transform', - 'translate(' + - (node.x + diff - node.width / 2) + - ', ' + - (node.y - node.height / 2 - padding) + - ')' - ); - } else { - el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')'); - } - return diff; -}; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/nodes.spec.ts b/packages/mermaid/src/rendering-util/rendering-elements/nodes.spec.ts new file mode 100644 index 000000000..c1f0e1437 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/nodes.spec.ts @@ -0,0 +1,236 @@ +import { shapes } from './shapes.js'; +import { describe, it, expect } from 'vitest'; + +describe('Test Alias for shapes', function () { + // for each shape in docs/syntax/flowchart.md, along with its semantic name, short name, and alias name, add a test case + // Process | rect | proc | rectangle + it('should support alias for rectangle shape ', function () { + expect(shapes.process).toBe(shapes.rect); + expect(shapes.proc).toBe(shapes.rect); + expect(shapes.rectangle).toBe(shapes.rect); + }); + + // event | rounded + it('should support alias for rounded shape ', function () { + expect(shapes.event).toBe(shapes.rounded); + }); + + // stadium | pill | term + it('should support alias for stadium shape ', function () { + expect(shapes.pill).toBe(shapes.stadium); + expect(shapes.terminal).toBe(shapes.stadium); + }); + + // fr-rect | subproc | framed-rectangle | subroutine + it('should support alias for subroutine shape ', function () { + expect(shapes['framed-rectangle']).toBe(shapes['fr-rect']); + expect(shapes.subproc).toBe(shapes['fr-rect']); + expect(shapes.subroutine).toBe(shapes['fr-rect']); + }); + + // cyl | db | cylinder + it('should support alias for cylinder shape ', function () { + expect(shapes.db).toBe(shapes.cylinder); + expect(shapes.cyl).toBe(shapes.cylinder); + }); + + // diam | decision | diamond + it('should support alias for diamond shape ', function () { + expect(shapes.diam).toBe(shapes.decision); + expect(shapes.diamond).toBe(shapes.decision); + }); + + // hex | hexagon | prepare + it('should support alias for hexagon shape ', function () { + expect(shapes.hex).toBe(shapes.hexagon); + expect(shapes.prepare).toBe(shapes.hexagon); + }); + + // l-r | lean-right | in-out + it('should support alias for lean-right shape ', function () { + expect(shapes['lean-r']).toBe(shapes['lean-right']); + expect(shapes['in-out']).toBe(shapes['lean-right']); + }); + + // l-l | lean-left | out-in + it('should support alias for lean-left shape ', function () { + expect(shapes['lean-l']).toBe(shapes['lean-left']); + expect(shapes['out-in']).toBe(shapes['lean-left']); + }); + + // trap-b | trapezoid-bottom | priority | trapezoid + it('should support alias for trapezoid shape ', function () { + expect(shapes['trapezoid-bottom']).toBe(shapes['trap-b']); + expect(shapes.priority).toBe(shapes['trap-b']); + expect(shapes.trapezoid).toBe(shapes['trap-b']); + }); + + // trap-t | trapezoid-top | manual | inv-trapezoid + it('should support alias for inv_trapezoid shape ', function () { + expect(shapes['trapezoid-top']).toBe(shapes['trap-t']); + expect(shapes.manual).toBe(shapes['trap-t']); + expect(shapes['inv-trapezoid']).toBe(shapes['trap-t']); + }); + + // dbl-circ| double-circle + it('should support alias for doublecircle shape ', function () { + expect(shapes['double-circle']).toBe(shapes['dbl-circ']); + }); + + // notched-rectangle | card | notch-rect + it('should support alias for notched-rectangle shape ', function () { + expect(shapes.card).toBe(shapes['notched-rectangle']); + expect(shapes['notch-rect']).toBe(shapes['notched-rectangle']); + }); + + it('should support alias for shadedProcess shape ', function () { + const aliases = ['lined-process', 'lined-rectangle', 'lin-proc', 'lin-rect'] as const; + for (const alias of aliases) { + expect(shapes[alias]).toBe(shapes['shaded-process']); + } + }); + + // sm-circ | small-circle | start + it('should support alias for smallCircle shape ', function () { + expect(shapes['small-circle']).toBe(shapes['sm-circ']); + expect(shapes.start).toBe(shapes['sm-circ']); + }); + + // framed-circle | stop + it('should support alias for framed circle shape ', function () { + expect(shapes.stop).toBe(shapes['framed-circle']); + }); + + // fork | join + it('should support alias for fork shape ', function () { + expect(shapes.join).toBe(shapes.fork); + }); + + // brace | comment | brace-l + it('should support alias for brace shape ', function () { + expect(shapes.comment).toBe(shapes.brace); + expect(shapes['brace-l']).toBe(shapes.brace); + }); + + // bolt | com-link | lightning-bolt + it('should support alias for bolt shape ', function () { + expect(shapes['com-link']).toBe(shapes.bolt); + expect(shapes['lightning-bolt']).toBe(shapes.bolt); + }); + + // document | doc + it('should support alias for waveEdgedRectangle shape ', function () { + expect(shapes.doc).toBe(shapes.document); + }); + + // delay | half-rounded-rectangle + it('should support alias for halfRoundedRectangle shape ', function () { + expect(shapes.delay).toBe(shapes['half-rounded-rectangle']); + }); + + // h-cyl | das | horizontal-cylinder + it('should support alias for horizontal-cylinder shape ', function () { + expect(shapes.das).toBe(shapes['h-cyl']); + expect(shapes['horizontal-cylinder']).toBe(shapes['h-cyl']); + }); + + // lin-cyl | disk | lined-cylinder + it('should support alias for linedCylinder shape ', function () { + expect(shapes.disk).toBe(shapes['lin-cyl']); + expect(shapes['lined-cylinder']).toBe(shapes['lin-cyl']); + }); + + // curv-trap | display | curved-trapezoid + it('should support alias for curvedTrapezoid shape ', function () { + expect(shapes.display).toBe(shapes['curv-trap']); + expect(shapes['curved-trapezoid']).toBe(shapes['curv-trap']); + }); + + // div-rect | div-proc | divided-rectangle + it('should support alias for dividedRectangle shape ', function () { + expect(shapes['div-proc']).toBe(shapes['div-rect']); + expect(shapes['divided-rectangle']).toBe(shapes['div-rect']); + }); + + // sm-tri | extract | small-triangle | triangle + it('should support alias for smallTriangle shape ', function () { + expect(shapes.extract).toBe(shapes.tri); + expect(shapes.triangle).toBe(shapes.tri); + }); + + // win-pane | internal-storage | window-pane + it('should support alias for windowPane shape ', function () { + expect(shapes['internal-storage']).toBe(shapes['win-pane']); + expect(shapes['window-pane']).toBe(shapes['win-pane']); + }); + + // fc | junction | filled-circle + it('should support alias for filledCircle shape ', function () { + expect(shapes.junction).toBe(shapes['f-circ']); + expect(shapes['filled-circle']).toBe(shapes['f-circ']); + }); + + // | lin-doc | lined-document + it('should support alias for linedWaveEdgedRectangle shape ', function () { + expect(shapes['lin-doc']).toBe(shapes['lined-document']); + }); + + // notch-pent | loop-limit | notched-pentagon + it('should support alias for notchedPentagon shape ', function () { + expect(shapes['loop-limit']).toBe(shapes['notch-pent']); + expect(shapes['notched-pentagon']).toBe(shapes['notch-pent']); + }); + + // flip-tri | manual-file | flipped-triangle + it('should support alias for flippedTriangle shape ', function () { + expect(shapes['manual-file']).toBe(shapes['flip-tri']); + expect(shapes['flipped-triangle']).toBe(shapes['flip-tri']); + }); + + //sl-rect | manual-input | sloped-rectangle + it('should support alias for slopedRectangle shape ', function () { + expect(shapes['manual-input']).toBe(shapes['sl-rect']); + expect(shapes['sloped-rectangle']).toBe(shapes['sl-rect']); + }); + + // docs | documents | st-doc | stacked-document + it('should support alias for multiWaveEdgedRectangle shape ', function () { + expect(shapes.docs).toBe(shapes.documents); + expect(shapes['st-doc']).toBe(shapes['stacked-document']); + }); + + // procs | processes | st-rect | stacked-rectangle + it('should support alias for multiRect shape ', function () { + expect(shapes.procs).toBe(shapes.processes); + expect(shapes['st-rect']).toBe(shapes['stacked-rectangle']); + }); + + // flag | paper-tape + it('should support alias for paperTape shape ', function () { + expect(shapes['paper-tape']).toBe(shapes.flag); + }); + + // bow-rect| stored-data | bow-tie-rectangle + it('should support alias for bowTieRect shape ', function () { + expect(shapes['stored-data']).toBe(shapes['bow-rect']); + expect(shapes['bow-tie-rectangle']).toBe(shapes['bow-rect']); + }); + + // cross-circ | summary | crossed-circle + it('should support alias for crossedCircle shape ', function () { + expect(shapes.summary).toBe(shapes['cross-circ']); + expect(shapes['crossed-circle']).toBe(shapes['cross-circ']); + }); + + // tag-doc| tag-document + it('should support alias for taggedDocument shape ', function () { + expect(shapes['tag-doc']).toBe(shapes['tagged-document']); + }); + + // tag-rect | tag-proc | tagged-rectangle | tagged-process + it('should support alias for taggedRect shape ', function () { + expect(shapes['tag-proc']).toBe(shapes['tag-rect']); + expect(shapes['tagged-rectangle']).toBe(shapes['tag-rect']); + expect(shapes['tagged-process']).toBe(shapes['tag-rect']); + }); +}); diff --git a/packages/mermaid/src/rendering-util/rendering-elements/nodes.ts b/packages/mermaid/src/rendering-util/rendering-elements/nodes.ts new file mode 100644 index 000000000..5af6cd17a --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/nodes.ts @@ -0,0 +1,96 @@ +import { log } from '../../logger.js'; +import { shapes } from './shapes.js'; +import type { Node, NonClusterNode, ShapeRenderOptions } from '../types.js'; +import type { SVGGroup } from '../../mermaid.js'; +import type { D3Selection } from '../../types.js'; +import type { graphlib } from 'dagre-d3-es'; + +type ShapeHandler = (typeof shapes)[keyof typeof shapes]; +type NodeElement = D3Selection | Awaited>; + +const nodeElems = new Map(); + +export async function insertNode( + elem: SVGGroup, + node: NonClusterNode, + renderOptions: ShapeRenderOptions +) { + let newEl: NodeElement | undefined; + let el; + + //special check for rect shape (with or without rounded corners) + if (node.shape === 'rect') { + if (node.rx && node.ry) { + node.shape = 'roundedRect'; + } else { + node.shape = 'squareRect'; + } + } + + const shapeHandler = node.shape ? shapes[node.shape] : undefined; + + if (!shapeHandler) { + throw new Error(`No such shape: ${node.shape}. Please check your syntax.`); + } + + if (node.link) { + // Add link when appropriate + let target; + if (renderOptions.config.securityLevel === 'sandbox') { + target = '_top'; + } else if (node.linkTarget) { + target = node.linkTarget || '_blank'; + } + newEl = elem + .insert('svg:a') + .attr('xlink:href', node.link) + .attr('target', target ?? null); + el = await shapeHandler(newEl, node, renderOptions); + } else { + el = await shapeHandler(elem, node, renderOptions); + newEl = el; + } + if (node.tooltip) { + el.attr('title', node.tooltip); + } + + nodeElems.set(node.id, newEl); + + if (node.haveCallback) { + newEl.attr('class', newEl.attr('class') + ' clickable'); + } + return newEl; +} + +export const setNodeElem = (elem: NodeElement, node: Pick) => { + nodeElems.set(node.id, elem); +}; + +export const clear = () => { + nodeElems.clear(); +}; + +export const positionNode = (node: ReturnType) => { + const el = nodeElems.get(node.id)!; + log.trace( + 'Transforming node', + node.diff, + node, + 'translate(' + (node.x - node.width / 2 - 5) + ', ' + node.width / 2 + ')' + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + 'transform', + 'translate(' + + (node.x + diff - node.width / 2) + + ', ' + + (node.y - node.height / 2 - padding) + + ')' + ); + } else { + el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')'); + } + return diff; +}; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes.ts new file mode 100644 index 000000000..dbfc93677 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes.ts @@ -0,0 +1,504 @@ +import type { Entries } from 'type-fest'; +import type { D3Selection, MaybePromise } from '../../types.js'; +import type { Node, ShapeRenderOptions } from '../types.js'; +import { anchor } from './shapes/anchor.js'; +import { bowTieRect } from './shapes/bowTieRect.js'; +import { card } from './shapes/card.js'; +import { choice } from './shapes/choice.js'; +import { circle } from './shapes/circle.js'; +import { crossedCircle } from './shapes/crossedCircle.js'; +import { curlyBraceLeft } from './shapes/curlyBraceLeft.js'; +import { curlyBraceRight } from './shapes/curlyBraceRight.js'; +import { curlyBraces } from './shapes/curlyBraces.js'; +import { curvedTrapezoid } from './shapes/curvedTrapezoid.js'; +import { cylinder } from './shapes/cylinder.js'; +import { dividedRectangle } from './shapes/dividedRect.js'; +import { doublecircle } from './shapes/doubleCircle.js'; +import { filledCircle } from './shapes/filledCircle.js'; +import { flippedTriangle } from './shapes/flippedTriangle.js'; +import { forkJoin } from './shapes/forkJoin.js'; +import { halfRoundedRectangle } from './shapes/halfRoundedRectangle.js'; +import { hexagon } from './shapes/hexagon.js'; +import { hourglass } from './shapes/hourglass.js'; +import { icon } from './shapes/icon.js'; +import { iconCircle } from './shapes/iconCircle.js'; +import { iconRounded } from './shapes/iconRounded.js'; +import { iconSquare } from './shapes/iconSquare.js'; +import { imageSquare } from './shapes/imageSquare.js'; +import { inv_trapezoid } from './shapes/invertedTrapezoid.js'; +import { labelRect } from './shapes/labelRect.js'; +import { lean_left } from './shapes/leanLeft.js'; +import { lean_right } from './shapes/leanRight.js'; +import { lightningBolt } from './shapes/lightningBolt.js'; +import { linedCylinder } from './shapes/linedCylinder.js'; +import { linedWaveEdgedRect } from './shapes/linedWaveEdgedRect.js'; +import { multiRect } from './shapes/multiRect.js'; +import { multiWaveEdgedRectangle } from './shapes/multiWaveEdgedRectangle.js'; +import { note } from './shapes/note.js'; +import { question } from './shapes/question.js'; +import { rect_left_inv_arrow } from './shapes/rectLeftInvArrow.js'; +import { rectWithTitle } from './shapes/rectWithTitle.js'; +import { roundedRect } from './shapes/roundedRect.js'; +import { shadedProcess } from './shapes/shadedProcess.js'; +import { slopedRect } from './shapes/slopedRect.js'; +import { squareRect } from './shapes/squareRect.js'; +import { stadium } from './shapes/stadium.js'; +import { state } from './shapes/state.js'; +import { stateEnd } from './shapes/stateEnd.js'; +import { stateStart } from './shapes/stateStart.js'; +import { subroutine } from './shapes/subroutine.js'; +import { taggedRect } from './shapes/taggedRect.js'; +import { taggedWaveEdgedRectangle } from './shapes/taggedWaveEdgedRectangle.js'; +import { text } from './shapes/text.js'; +import { tiltedCylinder } from './shapes/tiltedCylinder.js'; +import { trapezoid } from './shapes/trapezoid.js'; +import { trapezoidalPentagon } from './shapes/trapezoidalPentagon.js'; +import { triangle } from './shapes/triangle.js'; +import { waveEdgedRectangle } from './shapes/waveEdgedRectangle.js'; +import { waveRectangle } from './shapes/waveRectangle.js'; +import { windowPane } from './shapes/windowPane.js'; +import { classBox } from './shapes/classBox.js'; +import { kanbanItem } from './shapes/kanbanItem.js'; + +type ShapeHandler = ( + parent: D3Selection, + node: Node, + options: ShapeRenderOptions +) => MaybePromise>; + +export interface ShapeDefinition { + semanticName: string; + name: string; + shortName: string; + description: string; + /** + * Aliases can include descriptive names, other short names, etc. + */ + aliases?: string[]; + /** + * These are names used by mermaid before the introduction of new shapes. These will not be in standard formats, and shouldn't be used by the users + */ + internalAliases?: string[]; + handler: ShapeHandler; +} + +export const shapesDefs = [ + { + semanticName: 'Process', + name: 'Rectangle', + shortName: 'rect', + description: 'Standard process shape', + aliases: ['proc', 'process', 'rectangle'], + internalAliases: ['squareRect'], + handler: squareRect, + }, + { + semanticName: 'Event', + name: 'Rounded Rectangle', + shortName: 'rounded', + description: 'Represents an event', + aliases: ['event'], + internalAliases: ['roundedRect'], + handler: roundedRect, + }, + { + semanticName: 'Terminal Point', + name: 'Stadium', + shortName: 'stadium', + description: 'Terminal point', + aliases: ['terminal', 'pill'], + handler: stadium, + }, + { + semanticName: 'Subprocess', + name: 'Framed Rectangle', + shortName: 'fr-rect', + description: 'Subprocess', + aliases: ['subprocess', 'subproc', 'framed-rectangle', 'subroutine'], + handler: subroutine, + }, + { + semanticName: 'Database', + name: 'Cylinder', + shortName: 'cyl', + description: 'Database storage', + aliases: ['db', 'database', 'cylinder'], + handler: cylinder, + }, + { + semanticName: 'Start', + name: 'Circle', + shortName: 'circle', + description: 'Starting point', + aliases: ['circ'], + handler: circle, + }, + { + semanticName: 'Decision', + name: 'Diamond', + shortName: 'diam', + description: 'Decision-making step', + aliases: ['decision', 'diamond', 'question'], + handler: question, + }, + { + semanticName: 'Prepare Conditional', + name: 'Hexagon', + shortName: 'hex', + description: 'Preparation or condition step', + aliases: ['hexagon', 'prepare'], + handler: hexagon, + }, + { + semanticName: 'Data Input/Output', + name: 'Lean Right', + shortName: 'lean-r', + description: 'Represents input or output', + aliases: ['lean-right', 'in-out'], + internalAliases: ['lean_right'], + handler: lean_right, + }, + { + semanticName: 'Data Input/Output', + name: 'Lean Left', + shortName: 'lean-l', + description: 'Represents output or input', + aliases: ['lean-left', 'out-in'], + internalAliases: ['lean_left'], + handler: lean_left, + }, + { + semanticName: 'Priority Action', + name: 'Trapezoid Base Bottom', + shortName: 'trap-b', + description: 'Priority action', + aliases: ['priority', 'trapezoid-bottom', 'trapezoid'], + handler: trapezoid, + }, + { + semanticName: 'Manual Operation', + name: 'Trapezoid Base Top', + shortName: 'trap-t', + description: 'Represents a manual task', + aliases: ['manual', 'trapezoid-top', 'inv-trapezoid'], + internalAliases: ['inv_trapezoid'], + handler: inv_trapezoid, + }, + { + semanticName: 'Stop', + name: 'Double Circle', + shortName: 'dbl-circ', + description: 'Represents a stop point', + aliases: ['double-circle'], + internalAliases: ['doublecircle'], + handler: doublecircle, + }, + { + semanticName: 'Text Block', + name: 'Text Block', + shortName: 'text', + description: 'Text block', + handler: text, + }, + { + semanticName: 'Card', + name: 'Notched Rectangle', + shortName: 'notch-rect', + description: 'Represents a card', + aliases: ['card', 'notched-rectangle'], + handler: card, + }, + { + semanticName: 'Lined/Shaded Process', + name: 'Lined Rectangle', + shortName: 'lin-rect', + description: 'Lined process shape', + aliases: ['lined-rectangle', 'lined-process', 'lin-proc', 'shaded-process'], + handler: shadedProcess, + }, + { + semanticName: 'Start', + name: 'Small Circle', + shortName: 'sm-circ', + description: 'Small starting point', + aliases: ['start', 'small-circle'], + internalAliases: ['stateStart'], + handler: stateStart, + }, + { + semanticName: 'Stop', + name: 'Framed Circle', + shortName: 'fr-circ', + description: 'Stop point', + aliases: ['stop', 'framed-circle'], + internalAliases: ['stateEnd'], + handler: stateEnd, + }, + { + semanticName: 'Fork/Join', + name: 'Filled Rectangle', + shortName: 'fork', + description: 'Fork or join in process flow', + aliases: ['join'], + internalAliases: ['forkJoin'], + handler: forkJoin, + }, + { + semanticName: 'Collate', + name: 'Hourglass', + shortName: 'hourglass', + description: 'Represents a collate operation', + aliases: ['hourglass', 'collate'], + handler: hourglass, + }, + { + semanticName: 'Comment', + name: 'Curly Brace', + shortName: 'brace', + description: 'Adds a comment', + aliases: ['comment', 'brace-l'], + handler: curlyBraceLeft, + }, + { + semanticName: 'Comment Right', + name: 'Curly Brace', + shortName: 'brace-r', + description: 'Adds a comment', + handler: curlyBraceRight, + }, + { + semanticName: 'Comment with braces on both sides', + name: 'Curly Braces', + shortName: 'braces', + description: 'Adds a comment', + handler: curlyBraces, + }, + { + semanticName: 'Com Link', + name: 'Lightning Bolt', + shortName: 'bolt', + description: 'Communication link', + aliases: ['com-link', 'lightning-bolt'], + handler: lightningBolt, + }, + { + semanticName: 'Document', + name: 'Document', + shortName: 'doc', + description: 'Represents a document', + aliases: ['doc', 'document'], + handler: waveEdgedRectangle, + }, + { + semanticName: 'Delay', + name: 'Half-Rounded Rectangle', + shortName: 'delay', + description: 'Represents a delay', + aliases: ['half-rounded-rectangle'], + handler: halfRoundedRectangle, + }, + { + semanticName: 'Direct Access Storage', + name: 'Horizontal Cylinder', + shortName: 'h-cyl', + description: 'Direct access storage', + aliases: ['das', 'horizontal-cylinder'], + handler: tiltedCylinder, + }, + { + semanticName: 'Disk Storage', + name: 'Lined Cylinder', + shortName: 'lin-cyl', + description: 'Disk storage', + aliases: ['disk', 'lined-cylinder'], + handler: linedCylinder, + }, + { + semanticName: 'Display', + name: 'Curved Trapezoid', + shortName: 'curv-trap', + description: 'Represents a display', + aliases: ['curved-trapezoid', 'display'], + handler: curvedTrapezoid, + }, + { + semanticName: 'Divided Process', + name: 'Divided Rectangle', + shortName: 'div-rect', + description: 'Divided process shape', + aliases: ['div-proc', 'divided-rectangle', 'divided-process'], + handler: dividedRectangle, + }, + { + semanticName: 'Extract', + name: 'Triangle', + shortName: 'tri', + description: 'Extraction process', + aliases: ['extract', 'triangle'], + handler: triangle, + }, + { + semanticName: 'Internal Storage', + name: 'Window Pane', + shortName: 'win-pane', + description: 'Internal storage', + aliases: ['internal-storage', 'window-pane'], + handler: windowPane, + }, + { + semanticName: 'Junction', + name: 'Filled Circle', + shortName: 'f-circ', + description: 'Junction point', + aliases: ['junction', 'filled-circle'], + handler: filledCircle, + }, + { + semanticName: 'Loop Limit', + name: 'Trapezoidal Pentagon', + shortName: 'notch-pent', + description: 'Loop limit step', + aliases: ['loop-limit', 'notched-pentagon'], + handler: trapezoidalPentagon, + }, + { + semanticName: 'Manual File', + name: 'Flipped Triangle', + shortName: 'flip-tri', + description: 'Manual file operation', + aliases: ['manual-file', 'flipped-triangle'], + handler: flippedTriangle, + }, + { + semanticName: 'Manual Input', + name: 'Sloped Rectangle', + shortName: 'sl-rect', + description: 'Manual input step', + aliases: ['manual-input', 'sloped-rectangle'], + handler: slopedRect, + }, + { + semanticName: 'Multi-Document', + name: 'Stacked Document', + shortName: 'docs', + description: 'Multiple documents', + aliases: ['documents', 'st-doc', 'stacked-document'], + handler: multiWaveEdgedRectangle, + }, + { + semanticName: 'Multi-Process', + name: 'Stacked Rectangle', + shortName: 'st-rect', + description: 'Multiple processes', + aliases: ['procs', 'processes', 'stacked-rectangle'], + handler: multiRect, + }, + { + semanticName: 'Stored Data', + name: 'Bow Tie Rectangle', + shortName: 'bow-rect', + description: 'Stored data', + aliases: ['stored-data', 'bow-tie-rectangle'], + handler: bowTieRect, + }, + { + semanticName: 'Summary', + name: 'Crossed Circle', + shortName: 'cross-circ', + description: 'Summary', + aliases: ['summary', 'crossed-circle'], + handler: crossedCircle, + }, + { + semanticName: 'Tagged Document', + name: 'Tagged Document', + shortName: 'tag-doc', + description: 'Tagged document', + aliases: ['tag-doc', 'tagged-document'], + handler: taggedWaveEdgedRectangle, + }, + { + semanticName: 'Tagged Process', + name: 'Tagged Rectangle', + shortName: 'tag-rect', + description: 'Tagged process', + aliases: ['tagged-rectangle', 'tag-proc', 'tagged-process'], + handler: taggedRect, + }, + { + semanticName: 'Paper Tape', + name: 'Flag', + shortName: 'flag', + description: 'Paper tape', + aliases: ['paper-tape'], + handler: waveRectangle, + }, + { + semanticName: 'Odd', + name: 'Odd', + shortName: 'odd', + description: 'Odd shape', + internalAliases: ['rect_left_inv_arrow'], + handler: rect_left_inv_arrow, + }, + { + semanticName: 'Lined Document', + name: 'Lined Document', + shortName: 'lin-doc', + description: 'Lined document', + aliases: ['lined-document'], + handler: linedWaveEdgedRect, + }, +] as const satisfies ShapeDefinition[]; + +const generateShapeMap = () => { + // These are the shapes that didn't have documentation present + const undocumentedShapes = { + // States + state, + choice, + note, + + // Rectangles + rectWithTitle, + labelRect, + + // Icons + iconSquare, + iconCircle, + icon, + iconRounded, + imageSquare, + anchor, + + // Kanban diagram + kanbanItem, + + // class diagram + classBox, + } as const; + + const entries = [ + ...(Object.entries(undocumentedShapes) as Entries), + ...shapesDefs.flatMap((shape) => { + const aliases = [ + shape.shortName, + ...('aliases' in shape ? shape.aliases : []), + ...('internalAliases' in shape ? shape.internalAliases : []), + ]; + return aliases.map((alias) => [alias, shape.handler] as const); + }), + ]; + return Object.fromEntries(entries) as Record< + (typeof entries)[number][0], + (typeof entries)[number][1] + > satisfies Record; +}; + +export const shapes = generateShapeMap(); + +export function isValidShape(shape: string): shape is ShapeID { + return shape in shapes; +} + +export type ShapeID = keyof typeof shapes; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/anchor.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/anchor.ts new file mode 100644 index 000000000..11821a11b --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/anchor.ts @@ -0,0 +1,46 @@ +import { log } from '../../../logger.js'; +import { updateNodeBounds, getNodeClasses } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import { handleUndefinedAttr } from '../../../utils.js'; +import type { D3Selection } from '../../../types.js'; + +export function anchor(parent: D3Selection, node: Node) { + const { labelStyles } = styles2String(node); + node.labelStyle = labelStyles; + const classes = getNodeClasses(node); + let cssClasses = classes; + if (!classes) { + cssClasses = 'anchor'; + } + const shapeSvg = parent + .insert('g') + .attr('class', cssClasses) + .attr('id', node.domId || node.id); + + const radius = 1; + + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, { fill: 'black', stroke: 'none', fillStyle: 'solid' }); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + } + const roughNode = rc.circle(0, 0, radius * 2, options); + const circleElem = shapeSvg.insert(() => roughNode, ':first-child'); + circleElem.attr('class', 'anchor').attr('style', handleUndefinedAttr(cssStyles)); + + updateNodeBounds(node, circleElem); + + node.intersect = function (point) { + log.info('Circle intersect', node, radius, point); + return intersect.circle(node, radius, point); + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/bowTieRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/bowTieRect.ts new file mode 100644 index 000000000..d4b41103f --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/bowTieRect.ts @@ -0,0 +1,127 @@ +import { labelHelper, updateNodeBounds, getNodeClasses, createPathFromPoints } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; + +function generateArcPoints( + x1: number, + y1: number, + x2: number, + y2: number, + rx: number, + ry: number, + clockwise: boolean +) { + const numPoints = 20; + // Calculate midpoint + const midX = (x1 + x2) / 2; + const midY = (y1 + y2) / 2; + + // Calculate the angle of the line connecting the points + const angle = Math.atan2(y2 - y1, x2 - x1); + + // Calculate transformed coordinates for the ellipse + const dx = (x2 - x1) / 2; + const dy = (y2 - y1) / 2; + + // Scale to unit circle + const transformedX = dx / rx; + const transformedY = dy / ry; + + // Calculate the distance between points on the unit circle + const distance = Math.sqrt(transformedX ** 2 + transformedY ** 2); + + // Check if the ellipse can be drawn with the given radii + if (distance > 1) { + throw new Error('The given radii are too small to create an arc between the points.'); + } + + // Calculate the distance from the midpoint to the center of the ellipse + const scaledCenterDistance = Math.sqrt(1 - distance ** 2); + + // Calculate the center of the ellipse + const centerX = midX + scaledCenterDistance * ry * Math.sin(angle) * (clockwise ? -1 : 1); + const centerY = midY - scaledCenterDistance * rx * Math.cos(angle) * (clockwise ? -1 : 1); + + // Calculate the start and end angles on the ellipse + const startAngle = Math.atan2((y1 - centerY) / ry, (x1 - centerX) / rx); + const endAngle = Math.atan2((y2 - centerY) / ry, (x2 - centerX) / rx); + + // Adjust angles for clockwise/counterclockwise + let angleRange = endAngle - startAngle; + if (clockwise && angleRange < 0) { + angleRange += 2 * Math.PI; + } + if (!clockwise && angleRange > 0) { + angleRange -= 2 * Math.PI; + } + + // Generate points + const points = []; + for (let i = 0; i < numPoints; i++) { + const t = i / (numPoints - 1); + const angle = startAngle + t * angleRange; + const x = centerX + rx * Math.cos(angle); + const y = centerY + ry * Math.sin(angle); + points.push({ x, y }); + } + + return points; +} + +export async function bowTieRect(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); + const w = bbox.width + node.padding + 20; + const h = bbox.height + node.padding; + + const ry = h / 2; + const rx = ry / (2.5 + h / 50); + + // let shape: d3.Selection; + const { cssStyles } = node; + + const points = [ + { x: w / 2, y: -h / 2 }, + { x: -w / 2, y: -h / 2 }, + ...generateArcPoints(-w / 2, -h / 2, -w / 2, h / 2, rx, ry, false), + { x: w / 2, y: h / 2 }, + ...generateArcPoints(w / 2, h / 2, w / 2, -h / 2, rx, ry, true), + ]; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + const bowTieRectPath = createPathFromPoints(points); + const bowTieRectShapePath = rc.path(bowTieRectPath, options); + const bowTieRectShape = shapeSvg.insert(() => bowTieRectShapePath, ':first-child'); + + bowTieRectShape.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + bowTieRectShape.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + bowTieRectShape.selectAll('path').attr('style', nodeStyles); + } + + bowTieRectShape.attr('transform', `translate(${rx / 2}, 0)`); + + updateNodeBounds(node, bowTieRectShape); + + node.intersect = function (point) { + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/card.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/card.ts new file mode 100644 index 000000000..4aaf9222a --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/card.ts @@ -0,0 +1,70 @@ +import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; + +import { insertPolygonShape } from './insertPolygonShape.js'; +import { createPathFromPoints } from './util.js'; +import type { D3Selection } from '../../../types.js'; + +// const createPathFromPoints = (points: { x: number; y: number }[]): string => { +// const pointStrings = points.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x},${p.y}`); +// pointStrings.push('Z'); +// return pointStrings.join(' '); +// }; + +export async function card(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); + + const h = bbox.height + node.padding; + const padding = 12; + const w = bbox.width + node.padding + padding; + const left = 0; + const right = w; + const top = -h; + const bottom = 0; + const points = [ + { x: left + padding, y: top }, + { x: right, y: top }, + { x: right, y: bottom }, + { x: left, y: bottom }, + { x: left, y: top + padding }, + { x: left + padding, y: top }, + ]; + + let polygon: D3Selection | Awaited>; + const { cssStyles } = node; + + if (node.look === 'handDrawn') { + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + const pathData = createPathFromPoints(points); + const roughNode = rc.path(pathData, options); + + polygon = shapeSvg + .insert(() => roughNode, ':first-child') + .attr('transform', `translate(${-w / 2}, ${h / 2})`); + + if (cssStyles) { + polygon.attr('style', cssStyles); + } + } else { + polygon = insertPolygonShape(shapeSvg, w, h, points); + } + + if (nodeStyles) { + polygon.attr('style', nodeStyles); + } + + updateNodeBounds(node, polygon); + + node.intersect = function (point) { + return intersect.polygon(node, points, point); + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/choice.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/choice.ts index 3d6f085a4..4edd68587 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/choice.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/choice.ts @@ -1,22 +1,21 @@ import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import type { SVG } from '$root/diagram-api/types.js'; -// @ts-ignore TODO: Fix rough typings +import type { Node } from '../../types.js'; import rough from 'roughjs'; -import { solidStateFill, styles2String } from './handDrawnShapeStyles.js'; -import { getConfig } from '$root/diagram-api/diagramAPI.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import { createPathFromPoints, getNodeClasses } from './util.js'; +import type { D3Selection } from '../../../types.js'; -export const choice = (parent: SVG, node: Node) => { - const { labelStyles, nodeStyles } = styles2String(node); - node.labelStyle = labelStyles; - const { themeVariables } = getConfig(); - const { lineColor } = themeVariables; +export function choice(parent: D3Selection, node: Node) { + const { nodeStyles } = styles2String(node); + node.label = ''; const shapeSvg = parent .insert('g') - .attr('class', 'node default') - .attr('id', node.domId || node.id); + .attr('class', getNodeClasses(node)) + .attr('id', node.domId ?? node.id); + const { cssStyles } = node; + + const s = Math.max(28, node.width ?? 0); - const s = 28; const points = [ { x: 0, y: s / 2 }, { x: s / 2, y: 0 }, @@ -24,41 +23,33 @@ export const choice = (parent: SVG, node: Node) => { { x: -s / 2, y: 0 }, ]; - let choice; - if (node.look === 'handDrawn') { - // @ts-ignore TODO: Fix rough typings - const rc = rough.svg(shapeSvg); - const pointArr = points.map(function (d) { - return [d.x, d.y]; - }); - const roughNode = rc.polygon(pointArr, solidStateFill(lineColor)); - choice = shapeSvg.insert(() => roughNode); - } else { - choice = shapeSvg.insert('polygon', ':first-child').attr( - 'points', - points - .map(function (d) { - return d.x + ',' + d.y; - }) - .join(' ') - ); + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; } - // center the circle around its coordinate - choice - .attr('class', 'state-start') - // @ts-ignore TODO: Fix rough typings - .attr('r', 7) - .attr('width', 28) - .attr('height', 28) - .attr('style', nodeStyles); + const choicePath = createPathFromPoints(points); + const roughNode = rc.path(choicePath, options); + const choiceShape = shapeSvg.insert(() => roughNode, ':first-child'); + + if (cssStyles && node.look !== 'handDrawn') { + choiceShape.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + choiceShape.selectAll('path').attr('style', nodeStyles); + } node.width = 28; node.height = 28; node.intersect = function (point) { - return intersect.circle(node, 14, point); + return intersect.polygon(node, points, point); }; return shapeSvg; -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/circle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/circle.ts index 1474b778f..6b3be6765 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/circle.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/circle.ts @@ -1,14 +1,13 @@ -import { log } from '$root/logger.js'; +import { log } from '../../../logger.js'; import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; +import { handleUndefinedAttr } from '../../../utils.js'; -export const circle = async (parent: SVGAElement, node: Node): Promise => { +export async function circle(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, getNodeClasses(node)); @@ -18,13 +17,13 @@ export const circle = async (parent: SVGAElement, node: Node): Promise roughNode, ':first-child'); - circleElem.attr('class', 'basic label-container').attr('style', cssStyles); + circleElem.attr('class', 'basic label-container').attr('style', handleUndefinedAttr(cssStyles)); } else { circleElem = shapeSvg .insert('circle', ':first-child') @@ -43,4 +42,4 @@ export const circle = async (parent: SVGAElement, node: Node): Promise(parent: D3Selection, node: Node) { + const config = getConfig(); + const PADDING = config.class!.padding ?? 12; + const GAP = PADDING; + const useHtmlLabels = node.useHtmlLabels ?? evaluate(config.htmlLabels) ?? true; + // Treat node as classNode + const classNode = node as unknown as ClassNode; + classNode.annotations = classNode.annotations ?? []; + classNode.members = classNode.members ?? []; + classNode.methods = classNode.methods ?? []; + + const { shapeSvg, bbox } = await textHelper(parent, node, config, useHtmlLabels, GAP); + + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + + node.cssStyles = classNode.styles || ''; + + const styles = classNode.styles?.join(';') || nodeStyles || ''; + + if (!node.cssStyles) { + node.cssStyles = styles.replaceAll('!important', '').split(';'); + } + + const renderExtraBox = + classNode.members.length === 0 && + classNode.methods.length === 0 && + !config.class?.hideEmptyMembersBox; + + // Setup roughjs + // @ts-ignore TODO: Fix rough typings + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const w = bbox.width; + let h = bbox.height; + if (classNode.members.length === 0 && classNode.methods.length === 0) { + h += GAP; + } else if (classNode.members.length > 0 && classNode.methods.length === 0) { + h += GAP * 2; + } + const x = -w / 2; + const y = -h / 2; + + // Create and center rectangle + const roughRect = rc.rectangle( + x - PADDING, + y - + PADDING - + (renderExtraBox + ? PADDING + : classNode.members.length === 0 && classNode.methods.length === 0 + ? -PADDING / 2 + : 0), + w + 2 * PADDING, + h + + 2 * PADDING + + (renderExtraBox + ? PADDING * 2 + : classNode.members.length === 0 && classNode.methods.length === 0 + ? -PADDING + : 0), + options + ); + + const rect = shapeSvg.insert(() => roughRect, ':first-child'); + rect.attr('class', 'basic label-container'); + const rectBBox = rect.node()!.getBBox(); + + // Rect is centered so now adjust labels. + // TODO: Fix types + shapeSvg.selectAll('.text').each((_: any, i: number, nodes: any) => { + const text = select(nodes[i]); + // Get the current transform attribute + const transform = text.attr('transform'); + // Initialize variables for the translation values + let translateY = 0; + // Check if the transform attribute exists + if (transform) { + const regex = RegExp(/translate\(([^,]+),([^)]+)\)/); + const translate = regex.exec(transform); + if (translate) { + translateY = parseFloat(translate[2]); + } + } + // Add to the y value + let newTranslateY = + translateY + + y + + PADDING - + (renderExtraBox + ? PADDING + : classNode.members.length === 0 && classNode.methods.length === 0 + ? -PADDING / 2 + : 0); + if (!useHtmlLabels) { + // Fix so non html labels are better centered. + // BBox of text seems to be slightly different when calculated so we offset + newTranslateY -= 4; + } + let newTranslateX = x; + if ( + text.attr('class').includes('label-group') || + text.attr('class').includes('annotation-group') + ) { + newTranslateX = -text.node()?.getBBox().width / 2 || 0; + shapeSvg.selectAll('text').each(function (_: any, i: number, nodes: any) { + if (window.getComputedStyle(nodes[i]).textAnchor === 'middle') { + newTranslateX = 0; + } + }); + } + // Set the updated transform attribute + text.attr('transform', `translate(${newTranslateX}, ${newTranslateY})`); + }); + + // Render divider lines. + const annotationGroupHeight = + (shapeSvg.select('.annotation-group').node() as SVGGraphicsElement).getBBox().height - + (renderExtraBox ? PADDING / 2 : 0) || 0; + const labelGroupHeight = + (shapeSvg.select('.label-group').node() as SVGGraphicsElement).getBBox().height - + (renderExtraBox ? PADDING / 2 : 0) || 0; + const membersGroupHeight = + (shapeSvg.select('.members-group').node() as SVGGraphicsElement).getBBox().height - + (renderExtraBox ? PADDING / 2 : 0) || 0; + // First line (under label) + if (classNode.members.length > 0 || classNode.methods.length > 0 || renderExtraBox) { + const roughLine = rc.line( + rectBBox.x, + annotationGroupHeight + labelGroupHeight + y + PADDING, + rectBBox.x + rectBBox.width, + annotationGroupHeight + labelGroupHeight + y + PADDING, + options + ); + const line = shapeSvg.insert(() => roughLine); + line.attr('class', 'divider').attr('style', styles); + } + + // Second line (under members) + if (renderExtraBox || classNode.members.length > 0 || classNode.methods.length > 0) { + const roughLine = rc.line( + rectBBox.x, + annotationGroupHeight + labelGroupHeight + membersGroupHeight + y + GAP * 2 + PADDING, + rectBBox.x + rectBBox.width, + annotationGroupHeight + labelGroupHeight + membersGroupHeight + y + PADDING + GAP * 2, + options + ); + const line = shapeSvg.insert(() => roughLine); + line.attr('class', 'divider').attr('style', styles); + } + + /// Apply styles /// + if (classNode.look !== 'handDrawn') { + shapeSvg.selectAll('path').attr('style', styles); + } + // Apply other styles like stroke-width and stroke-dasharray to border (not background of shape) + rect.select(':nth-child(2)').attr('style', styles); + // Divider lines + shapeSvg.selectAll('.divider').select('path').attr('style', styles); + // Text elements + if (node.labelStyle) { + shapeSvg.selectAll('span').attr('style', node.labelStyle); + } else { + shapeSvg.selectAll('span').attr('style', styles); + } + // SVG text uses fill not color + if (!useHtmlLabels) { + // We just want to apply color to the text + const colorRegex = RegExp(/color\s*:\s*([^;]*)/); + const match = colorRegex.exec(styles); + if (match) { + const colorStyle = match[0].replace('color', 'fill'); + shapeSvg.selectAll('tspan').attr('style', colorStyle); + } else if (labelStyles) { + const match = colorRegex.exec(labelStyles); + if (match) { + const colorStyle = match[0].replace('color', 'fill'); + shapeSvg.selectAll('tspan').attr('style', colorStyle); + } + } + } + + updateNodeBounds(node, rect); + node.intersect = function (point) { + return intersect.rect(node, point); + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/crossedCircle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/crossedCircle.ts new file mode 100644 index 000000000..eaacb9f34 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/crossedCircle.ts @@ -0,0 +1,67 @@ +import { log } from '../../../logger.js'; +import { getNodeClasses, updateNodeBounds } from './util.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import intersect from '../intersect/index.js'; +import type { D3Selection } from '../../../types.js'; + +function createLine(r: number) { + const xAxis45 = Math.cos(Math.PI / 4); // cosine of 45 degrees + const yAxis45 = Math.sin(Math.PI / 4); // sine of 45 degrees + const lineLength = r * 2; + + const pointQ1 = { x: (lineLength / 2) * xAxis45, y: (lineLength / 2) * yAxis45 }; // Quadrant I + const pointQ2 = { x: -(lineLength / 2) * xAxis45, y: (lineLength / 2) * yAxis45 }; // Quadrant II + const pointQ3 = { x: -(lineLength / 2) * xAxis45, y: -(lineLength / 2) * yAxis45 }; // Quadrant III + const pointQ4 = { x: (lineLength / 2) * xAxis45, y: -(lineLength / 2) * yAxis45 }; // Quadrant IV + + return `M ${pointQ2.x},${pointQ2.y} L ${pointQ4.x},${pointQ4.y} + M ${pointQ1.x},${pointQ1.y} L ${pointQ3.x},${pointQ3.y}`; +} + +export function crossedCircle(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + node.label = ''; + const shapeSvg = parent + .insert('g') + .attr('class', getNodeClasses(node)) + .attr('id', node.domId ?? node.id); + const radius = Math.max(30, node?.width ?? 0); + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const circleNode = rc.circle(0, 0, radius * 2, options); + const linePath = createLine(radius); + const lineNode = rc.path(linePath, options); + + const crossedCircle = shapeSvg.insert(() => circleNode, ':first-child'); + crossedCircle.insert(() => lineNode); + + if (cssStyles && node.look !== 'handDrawn') { + crossedCircle.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + crossedCircle.selectAll('path').attr('style', nodeStyles); + } + + updateNodeBounds(node, crossedCircle); + + node.intersect = function (point) { + log.info('crossedCircle intersect', node, { radius, point }); + const pos = intersect.circle(node, radius, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceLeft.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceLeft.ts new file mode 100644 index 000000000..00113ae4f --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceLeft.ts @@ -0,0 +1,115 @@ +import { labelHelper, updateNodeBounds, getNodeClasses, createPathFromPoints } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; + +function generateCirclePoints( + centerX: number, + centerY: number, + radius: number, + numPoints = 100, + startAngle = 0, + endAngle = 180 +) { + const points = []; + + // Convert angles to radians + const startAngleRad = (startAngle * Math.PI) / 180; + const endAngleRad = (endAngle * Math.PI) / 180; + + // Calculate the angle range in radians + const angleRange = endAngleRad - startAngleRad; + + // Calculate the angle step + const angleStep = angleRange / (numPoints - 1); + + for (let i = 0; i < numPoints; i++) { + const angle = startAngleRad + i * angleStep; + const x = centerX + radius * Math.cos(angle); + const y = centerY + radius * Math.sin(angle); + points.push({ x: -x, y: -y }); + } + + return points; +} + +export async function curlyBraceLeft( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = bbox.width + (node.padding ?? 0); + const h = bbox.height + (node.padding ?? 0); + const radius = Math.max(5, h * 0.1); + + const { cssStyles } = node; + + const points = [ + ...generateCirclePoints(w / 2, -h / 2, radius, 30, -90, 0), + { x: -w / 2 - radius, y: radius }, + ...generateCirclePoints(w / 2 + radius * 2, -radius, radius, 20, -180, -270), + ...generateCirclePoints(w / 2 + radius * 2, radius, radius, 20, -90, -180), + { x: -w / 2 - radius, y: -h / 2 }, + ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), + ]; + + const rectPoints = [ + { x: w / 2, y: -h / 2 - radius }, + { x: -w / 2, y: -h / 2 - radius }, + ...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0), + { x: -w / 2 - radius, y: -radius }, + ...generateCirclePoints(w / 2 + w * 0.1, -radius, radius, 20, -180, -270), + ...generateCirclePoints(w / 2 + w * 0.1, radius, radius, 20, -90, -180), + { x: -w / 2 - radius, y: h / 2 }, + ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), + { x: -w / 2, y: h / 2 + radius }, + { x: w / 2, y: h / 2 + radius }, + ]; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, { fill: 'none' }); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + const curlyBraceLeftPath = createPathFromPoints(points); + const newCurlyBracePath = curlyBraceLeftPath.replace('Z', ''); + const curlyBraceLeftNode = rc.path(newCurlyBracePath, options); + const rectPath = createPathFromPoints(rectPoints); + const rectShape = rc.path(rectPath, { ...options }); + const curlyBraceLeftShape = shapeSvg.insert('g', ':first-child'); + curlyBraceLeftShape.insert(() => rectShape, ':first-child').attr('stroke-opacity', 0); + curlyBraceLeftShape.insert(() => curlyBraceLeftNode, ':first-child'); + curlyBraceLeftShape.attr('class', 'text'); + + if (cssStyles && node.look !== 'handDrawn') { + curlyBraceLeftShape.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + curlyBraceLeftShape.selectAll('path').attr('style', nodeStyles); + } + + curlyBraceLeftShape.attr('transform', `translate(${radius}, 0)`); + + label.attr( + 'transform', + `translate(${-w / 2 + radius - (bbox.x - (bbox.left ?? 0))},${-h / 2 + (node.padding ?? 0) / 2 - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, curlyBraceLeftShape); + + node.intersect = function (point) { + const pos = intersect.polygon(node, rectPoints, point); + + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceRight.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceRight.ts new file mode 100644 index 000000000..d208efc97 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceRight.ts @@ -0,0 +1,115 @@ +import { labelHelper, updateNodeBounds, getNodeClasses, createPathFromPoints } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; + +function generateCirclePoints( + centerX: number, + centerY: number, + radius: number, + numPoints = 100, + startAngle = 0, + endAngle = 180 +) { + const points = []; + + // Convert angles to radians + const startAngleRad = (startAngle * Math.PI) / 180; + const endAngleRad = (endAngle * Math.PI) / 180; + + // Calculate the angle range in radians + const angleRange = endAngleRad - startAngleRad; + + // Calculate the angle step + const angleStep = angleRange / (numPoints - 1); + + for (let i = 0; i < numPoints; i++) { + const angle = startAngleRad + i * angleStep; + const x = centerX + radius * Math.cos(angle); + const y = centerY + radius * Math.sin(angle); + points.push({ x, y }); + } + + return points; +} + +export async function curlyBraceRight( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = bbox.width + (node.padding ?? 0); + const h = bbox.height + (node.padding ?? 0); + const radius = Math.max(5, h * 0.1); + + const { cssStyles } = node; + + const points = [ + ...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0), + { x: w / 2 + radius, y: -radius }, + ...generateCirclePoints(w / 2 + radius * 2, -radius, radius, 20, -180, -270), + ...generateCirclePoints(w / 2 + radius * 2, radius, radius, 20, -90, -180), + { x: w / 2 + radius, y: h / 2 }, + ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), + ]; + + const rectPoints = [ + { x: -w / 2, y: -h / 2 - radius }, + { x: w / 2, y: -h / 2 - radius }, + ...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0), + { x: w / 2 + radius, y: -radius }, + ...generateCirclePoints(w / 2 + radius * 2, -radius, radius, 20, -180, -270), + ...generateCirclePoints(w / 2 + radius * 2, radius, radius, 20, -90, -180), + { x: w / 2 + radius, y: h / 2 }, + ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), + { x: w / 2, y: h / 2 + radius }, + { x: -w / 2, y: h / 2 + radius }, + ]; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, { fill: 'none' }); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + const curlyBraceRightPath = createPathFromPoints(points); + const newCurlyBracePath = curlyBraceRightPath.replace('Z', ''); + const curlyBraceRightNode = rc.path(newCurlyBracePath, options); + const rectPath = createPathFromPoints(rectPoints); + const rectShape = rc.path(rectPath, { ...options }); + const curlyBraceRightShape = shapeSvg.insert('g', ':first-child'); + curlyBraceRightShape.insert(() => rectShape, ':first-child').attr('stroke-opacity', 0); + curlyBraceRightShape.insert(() => curlyBraceRightNode, ':first-child'); + curlyBraceRightShape.attr('class', 'text'); + + if (cssStyles && node.look !== 'handDrawn') { + curlyBraceRightShape.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + curlyBraceRightShape.selectAll('path').attr('style', nodeStyles); + } + + curlyBraceRightShape.attr('transform', `translate(${-radius}, 0)`); + + label.attr( + 'transform', + `translate(${-w / 2 + (node.padding ?? 0) / 2 - (bbox.x - (bbox.left ?? 0))},${-h / 2 + (node.padding ?? 0) / 2 - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, curlyBraceRightShape); + + node.intersect = function (point) { + const pos = intersect.polygon(node, rectPoints, point); + + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraces.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraces.ts new file mode 100644 index 000000000..1fd9b6f05 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraces.ts @@ -0,0 +1,134 @@ +import { labelHelper, updateNodeBounds, getNodeClasses, createPathFromPoints } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; + +function generateCirclePoints( + centerX: number, + centerY: number, + radius: number, + numPoints = 100, + startAngle = 0, + endAngle = 180 +) { + const points = []; + + // Convert angles to radians + const startAngleRad = (startAngle * Math.PI) / 180; + const endAngleRad = (endAngle * Math.PI) / 180; + + // Calculate the angle range in radians + const angleRange = endAngleRad - startAngleRad; + + // Calculate the angle step + const angleStep = angleRange / (numPoints - 1); + + for (let i = 0; i < numPoints; i++) { + const angle = startAngleRad + i * angleStep; + const x = centerX + radius * Math.cos(angle); + const y = centerY + radius * Math.sin(angle); + points.push({ x: -x, y: -y }); + } + + return points; +} + +export async function curlyBraces( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = bbox.width + (node.padding ?? 0); + const h = bbox.height + (node.padding ?? 0); + const radius = Math.max(5, h * 0.1); + + const { cssStyles } = node; + + const leftCurlyBracePoints = [ + ...generateCirclePoints(w / 2, -h / 2, radius, 30, -90, 0), + { x: -w / 2 - radius, y: radius }, + ...generateCirclePoints(w / 2 + radius * 2, -radius, radius, 20, -180, -270), + ...generateCirclePoints(w / 2 + radius * 2, radius, radius, 20, -90, -180), + { x: -w / 2 - radius, y: -h / 2 }, + ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), + ]; + + const rightCurlyBracePoints = [ + ...generateCirclePoints(-w / 2 + radius + radius / 2, -h / 2, radius, 20, -90, -180), + { x: w / 2 - radius / 2, y: radius }, + ...generateCirclePoints(-w / 2 - radius / 2, -radius, radius, 20, 0, 90), + ...generateCirclePoints(-w / 2 - radius / 2, radius, radius, 20, -90, 0), + { x: w / 2 - radius / 2, y: -radius }, + ...generateCirclePoints(-w / 2 + radius + radius / 2, h / 2, radius, 30, -180, -270), + ]; + + const rectPoints = [ + { x: w / 2, y: -h / 2 - radius }, + { x: -w / 2, y: -h / 2 - radius }, + ...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0), + { x: -w / 2 - radius, y: -radius }, + ...generateCirclePoints(w / 2 + radius * 2, -radius, radius, 20, -180, -270), + ...generateCirclePoints(w / 2 + radius * 2, radius, radius, 20, -90, -180), + { x: -w / 2 - radius, y: h / 2 }, + ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), + { x: -w / 2, y: h / 2 + radius }, + { x: w / 2 - radius - radius / 2, y: h / 2 + radius }, + ...generateCirclePoints(-w / 2 + radius + radius / 2, -h / 2, radius, 20, -90, -180), + { x: w / 2 - radius / 2, y: radius }, + ...generateCirclePoints(-w / 2 - radius / 2, -radius, radius, 20, 0, 90), + ...generateCirclePoints(-w / 2 - radius / 2, radius, radius, 20, -90, 0), + { x: w / 2 - radius / 2, y: -radius }, + ...generateCirclePoints(-w / 2 + radius + radius / 2, h / 2, radius, 30, -180, -270), + ]; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, { fill: 'none' }); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + const leftCurlyBracePath = createPathFromPoints(leftCurlyBracePoints); + const newLeftCurlyBracePath = leftCurlyBracePath.replace('Z', ''); + const leftCurlyBraceNode = rc.path(newLeftCurlyBracePath, options); + const rightCurlyBracePath = createPathFromPoints(rightCurlyBracePoints); + const newRightCurlyBracePath = rightCurlyBracePath.replace('Z', ''); + const rightCurlyBraceNode = rc.path(newRightCurlyBracePath, options); + const rectPath = createPathFromPoints(rectPoints); + const rectShape = rc.path(rectPath, { ...options }); + const curlyBracesShape = shapeSvg.insert('g', ':first-child'); + curlyBracesShape.insert(() => rectShape, ':first-child').attr('stroke-opacity', 0); + curlyBracesShape.insert(() => leftCurlyBraceNode, ':first-child'); + curlyBracesShape.insert(() => rightCurlyBraceNode, ':first-child'); + curlyBracesShape.attr('class', 'text'); + + if (cssStyles && node.look !== 'handDrawn') { + curlyBracesShape.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + curlyBracesShape.selectAll('path').attr('style', nodeStyles); + } + + curlyBracesShape.attr('transform', `translate(${radius - radius / 4}, 0)`); + + label.attr( + 'transform', + `translate(${-w / 2 + (node.padding ?? 0) / 2 - (bbox.x - (bbox.left ?? 0))},${-h / 2 + (node.padding ?? 0) / 2 - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, curlyBracesShape); + + node.intersect = function (point) { + const pos = intersect.polygon(node, rectPoints, point); + + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/curvedTrapezoid.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curvedTrapezoid.ts new file mode 100644 index 000000000..26339b65c --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curvedTrapezoid.ts @@ -0,0 +1,75 @@ +import { + labelHelper, + updateNodeBounds, + getNodeClasses, + createPathFromPoints, + generateCirclePoints, +} from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; + +export async function curvedTrapezoid( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); + const minWidth = 80, + minHeight = 20; + const w = Math.max(minWidth, (bbox.width + (node.padding ?? 0) * 2) * 1.25, node?.width ?? 0); + const h = Math.max(minHeight, bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const radius = h / 2; + + const { cssStyles } = node; + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const totalWidth = w, + totalHeight = h; + const rw = totalWidth - radius; + const tw = totalHeight / 4; + + const points = [ + { x: rw, y: 0 }, + { x: tw, y: 0 }, + { x: 0, y: totalHeight / 2 }, + { x: tw, y: totalHeight }, + { x: rw, y: totalHeight }, + ...generateCirclePoints(-rw, -totalHeight / 2, radius, 50, 270, 90), + ]; + + const pathData = createPathFromPoints(points); + const shapeNode = rc.path(pathData, options); + + const polygon = shapeSvg.insert(() => shapeNode, ':first-child'); + polygon.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', nodeStyles); + } + + polygon.attr('transform', `translate(${-w / 2}, ${-h / 2})`); + + updateNodeBounds(node, polygon); + + node.intersect = function (point) { + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts index f85db0f05..9d2cd63f6 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts @@ -1,11 +1,10 @@ import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; +import { handleUndefinedAttr } from '../../../utils.js'; export const createCylinderPathD = ( x: number, @@ -51,20 +50,20 @@ export const createInnerCylinderPathD = ( ): string => { return [`M${x - width / 2},${-height / 2}`, `a${rx},${ry} 0,0,0 ${width},0`].join(' '); }; -export const cylinder = async (parent: SVGAElement, node: Node) => { +export async function cylinder(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; - const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); - const w = bbox.width + node.padding; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = Math.max(bbox.width + node.padding, node.width ?? 0); const rx = w / 2; const ry = rx / (2.5 + w / 50); - const h = bbox.height + ry + node.padding; + const h = Math.max(bbox.height + ry + node.padding, node.height ?? 0); - let cylinder: d3.Selection; + let cylinder: D3Selection | D3Selection; const { cssStyles } = node; if (node.look === 'handDrawn') { - // @ts-ignore - rough is not typed + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); const outerPathData = createOuterCylinderPathD(0, 0, w, h, rx, ry); const innerPathData = createInnerCylinderPathD(0, ry, w, h, rx, ry); @@ -83,7 +82,7 @@ export const cylinder = async (parent: SVGAElement, node: Node) => { .insert('path', ':first-child') .attr('d', pathData) .attr('class', 'basic label-container') - .attr('style', cssStyles) + .attr('style', handleUndefinedAttr(cssStyles)) .attr('style', nodeStyles); } @@ -92,6 +91,11 @@ export const cylinder = async (parent: SVGAElement, node: Node) => { updateNodeBounds(node, cylinder); + label.attr( + 'transform', + `translate(${-(bbox.width / 2) - (bbox.x - (bbox.left ?? 0))}, ${-(bbox.height / 2) + (node.padding ?? 0) / 1.5 - (bbox.y - (bbox.top ?? 0))})` + ); + node.intersect = function (point) { const pos = intersect.rect(node, point); const x = pos.x - (node.x ?? 0); @@ -118,4 +122,4 @@ export const cylinder = async (parent: SVGAElement, node: Node) => { }; return shapeSvg; -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/dividedRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/dividedRect.ts new file mode 100644 index 000000000..77df58155 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/dividedRect.ts @@ -0,0 +1,71 @@ +import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; + +export async function dividedRectangle( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const rectOffset = h * 0.2; + + const x = -w / 2; + const y = -h / 2 - rectOffset / 2; + + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const pts = [ + { x, y: y + rectOffset }, + { x: -x, y: y + rectOffset }, + { x: -x, y: -y }, + { x, y: -y }, + { x, y }, + { x: -x, y }, + { x: -x, y: y + rectOffset }, + ]; + + const poly = rc.polygon( + pts.map((p) => [p.x, p.y]), + options + ); + + const polygon = shapeSvg.insert(() => poly, ':first-child'); + polygon.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + polygon.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + polygon.selectAll('path').attr('style', nodeStyles); + } + + label.attr( + 'transform', + `translate(${x + (node.padding ?? 0) / 2 - (bbox.x - (bbox.left ?? 0))}, ${y + rectOffset + (node.padding ?? 0) / 2 - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, polygon); + + node.intersect = function (point) { + const pos = intersect.rect(node, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/document.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/document.ts new file mode 100644 index 000000000..d5ea3aa76 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/document.ts @@ -0,0 +1,120 @@ +import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; +import { handleUndefinedAttr } from '../../../utils.js'; + +export const createCylinderPathD = ( + x: number, + y: number, + width: number, + height: number, + rx: number, + ry: number +): string => { + return [ + `M${x},${y + ry}`, + `a${rx},${ry} 0,0,0 ${width},0`, + `a${rx},${ry} 0,0,0 ${-width},0`, + `l0,${height}`, + `a${rx},${ry} 0,0,0 ${width},0`, + `l0,${-height}`, + ].join(' '); +}; +export const createOuterCylinderPathD = ( + x: number, + y: number, + width: number, + height: number, + rx: number, + ry: number +): string => { + return [ + `M${x},${y + ry}`, + `M${x + width},${y + ry}`, + `a${rx},${ry} 0,0,0 ${-width},0`, + `l0,${height}`, + `a${rx},${ry} 0,0,0 ${width},0`, + `l0,${-height}`, + ].join(' '); +}; +export const createInnerCylinderPathD = ( + x: number, + y: number, + width: number, + height: number, + rx: number, + ry: number +): string => { + return [`M${x - width / 2},${-height / 2}`, `a${rx},${ry} 0,0,0 ${width},0`].join(' '); +}; +export async function cylinder(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + + let cylinder: D3Selection | D3Selection; + const { cssStyles } = node; + + if (node.look === 'handDrawn') { + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const outerPathData = createOuterCylinderPathD(0, 0, w, h, rx, ry); + const innerPathData = createInnerCylinderPathD(0, ry, w, h, rx, ry); + const outerNode = rc.path(outerPathData, userNodeOverrides(node, {})); + const innerLine = rc.path(innerPathData, userNodeOverrides(node, { fill: 'none' })); + + cylinder = shapeSvg.insert(() => innerLine, ':first-child'); + cylinder = shapeSvg.insert(() => outerNode, ':first-child'); + cylinder.attr('class', 'basic label-container'); + if (cssStyles) { + cylinder.attr('style', cssStyles); + } + } else { + const pathData = createCylinderPathD(0, 0, w, h, rx, ry); + cylinder = shapeSvg + .insert('path', ':first-child') + .attr('d', pathData) + .attr('class', 'basic label-container') + .attr('style', handleUndefinedAttr(cssStyles)) + .attr('style', nodeStyles); + } + + cylinder.attr('label-offset-y', ry); + cylinder.attr('transform', `translate(${-w / 2}, ${-(h / 2 + ry)})`); + + updateNodeBounds(node, cylinder); + + node.intersect = function (point) { + const pos = intersect.rect(node, point); + const x = pos.x - (node.x ?? 0); + + if ( + rx != 0 && + (Math.abs(x) < (node.width ?? 0) / 2 || + (Math.abs(x) == (node.width ?? 0) / 2 && + Math.abs(pos.y - (node.y ?? 0)) > (node.height ?? 0) / 2 - ry)) + ) { + let y = ry * ry * (1 - (x * x) / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point.y - (node.y ?? 0) > 0) { + y = -y; + } + + pos.y += y; + } + + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/doubleCircle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/doubleCircle.ts index 5ce616c0b..bc0d844da 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/doubleCircle.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/doubleCircle.ts @@ -1,14 +1,16 @@ -import { log } from '$root/logger.js'; +import { log } from '../../../logger.js'; import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; +import { handleUndefinedAttr } from '../../../utils.js'; -export const doublecircle = async (parent: SVGAElement, node: Node): Promise => { +export async function doublecircle( + parent: D3Selection, + node: Node +) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, getNodeClasses(node)); @@ -20,7 +22,7 @@ export const doublecircle = async (parent: SVGAElement, node: Node): Promise outerRoughNode, ':first-child'); - circleGroup.attr('class', node.cssClasses).attr('style', cssStyles); + circleGroup + .attr('class', handleUndefinedAttr(node.cssClasses)) + .attr('style', handleUndefinedAttr(cssStyles)); circleGroup.node()?.appendChild(outerRoughNode); circleGroup.node()?.appendChild(innerRoughNode); @@ -64,4 +68,4 @@ export const doublecircle = async (parent: SVGAElement, node: Node): Promise { +export async function drawRect( + parent: D3Selection, + node: Node, + options: RectOptions +) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; // console.log('IPI labelStyles:', labelStyles); @@ -42,17 +45,15 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt : rc.rectangle(x, y, totalWidth, totalHeight, options); rect = shapeSvg.insert(() => roughNode, ':first-child'); - rect.attr('class', 'basic label-container').attr('style', cssStyles); + rect.attr('class', 'basic label-container').attr('style', handleUndefinedAttr(cssStyles)); } else { rect = shapeSvg.insert('rect', ':first-child'); rect .attr('class', 'basic label-container') .attr('style', nodeStyles) - .attr('rx', rx) - .attr('data-id', 'abc') - .attr('data-et', 'node') - .attr('ry', ry) + .attr('rx', handleUndefinedAttr(rx)) + .attr('ry', handleUndefinedAttr(ry)) .attr('x', x) .attr('y', y) .attr('width', totalWidth) @@ -66,4 +67,4 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt }; return shapeSvg; -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/filledCircle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/filledCircle.ts new file mode 100644 index 000000000..3469697c7 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/filledCircle.ts @@ -0,0 +1,56 @@ +import rough from 'roughjs'; +import { log } from '../../../logger.js'; +import type { Node, ShapeRenderOptions } from '../../types.js'; +import intersect from '../intersect/index.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import { getNodeClasses, updateNodeBounds } from './util.js'; +import type { D3Selection } from '../../../types.js'; + +export function filledCircle( + parent: D3Selection, + node: Node, + { config: { themeVariables } }: ShapeRenderOptions +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.label = ''; + node.labelStyle = labelStyles; + const shapeSvg = parent + .insert('g') + .attr('class', getNodeClasses(node)) + .attr('id', node.domId ?? node.id); + const radius = 7; + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const { nodeBorder } = themeVariables; + const options = userNodeOverrides(node, { fillStyle: 'solid' }); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + } + + const circleNode = rc.circle(0, 0, radius * 2, options); + + const filledCircle = shapeSvg.insert(() => circleNode, ':first-child'); + + filledCircle.selectAll('path').attr('style', `fill: ${nodeBorder} !important;`); + + if (cssStyles && cssStyles.length > 0 && node.look !== 'handDrawn') { + filledCircle.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + filledCircle.selectAll('path').attr('style', nodeStyles); + } + + updateNodeBounds(node, filledCircle); + + node.intersect = function (point) { + log.info('filledCircle intersect', node, { radius, point }); + const pos = intersect.circle(node, radius, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/flippedTriangle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/flippedTriangle.ts new file mode 100644 index 000000000..33f65b326 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/flippedTriangle.ts @@ -0,0 +1,68 @@ +import { log } from '../../../logger.js'; +import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import { createPathFromPoints } from './util.js'; +import type { D3Selection } from '../../../types.js'; + +export async function flippedTriangle( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + + const w = bbox.width + (node.padding ?? 0); + const h = w + bbox.height; + + const tw = w + bbox.height; + const points = [ + { x: 0, y: -h }, + { x: tw, y: -h }, + { x: tw / 2, y: 0 }, + ]; + + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + const pathData = createPathFromPoints(points); + const roughNode = rc.path(pathData, options); + + const flippedTriangle = shapeSvg + .insert(() => roughNode, ':first-child') + .attr('transform', `translate(${-h / 2}, ${h / 2})`); + + if (cssStyles && node.look !== 'handDrawn') { + flippedTriangle.selectChildren('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + flippedTriangle.selectChildren('path').attr('style', nodeStyles); + } + + node.width = w; + node.height = h; + + updateNodeBounds(node, flippedTriangle); + + label.attr( + 'transform', + `translate(${-bbox.width / 2 - (bbox.x - (bbox.left ?? 0))}, ${-h / 2 + (node.padding ?? 0) / 2 + (bbox.y - (bbox.top ?? 0))})` + ); + + node.intersect = function (point) { + log.info('Triangle intersect', node, points, point); + return intersect.polygon(node, points, point); + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/forkJoin.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/forkJoin.ts index 07978be10..9ae587618 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/forkJoin.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/forkJoin.ts @@ -1,65 +1,66 @@ -import { updateNodeBounds } from './util.js'; -import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import type { SVG } from '$root/diagram-api/types.js'; import rough from 'roughjs'; -import { solidStateFill } from './handDrawnShapeStyles.js'; -import { getConfig } from '$root/diagram-api/diagramAPI.js'; +import type { Node, ShapeRenderOptions } from '../../types.js'; +import intersect from '../intersect/index.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import { getNodeClasses, updateNodeBounds } from './util.js'; +import type { D3Selection } from '../../../types.js'; -export const forkJoin = (parent: SVG, node: Node, dir: string) => { - const { themeVariables } = getConfig(); - const { lineColor } = themeVariables; +export function forkJoin( + parent: D3Selection, + node: Node, + { dir, config: { state, themeVariables } }: ShapeRenderOptions +) { + const { nodeStyles } = styles2String(node); + node.label = ''; const shapeSvg = parent .insert('g') - .attr('class', 'node default') - .attr('id', node.domId || node.id); + .attr('class', getNodeClasses(node)) + .attr('id', node.domId ?? node.id); - let width = 70; - let height = 10; + const { cssStyles } = node; + let width = Math.max(70, node?.width ?? 0); + let height = Math.max(10, node?.height ?? 0); if (dir === 'LR') { - width = 10; - height = 70; + width = Math.max(10, node?.width ?? 0); + height = Math.max(70, node?.height ?? 0); } + const x = (-1 * width) / 2; const y = (-1 * height) / 2; - let shape; - if (node.look === 'handDrawn') { - // @ts-ignore TODO: Fix rough typings - const rc = rough.svg(shapeSvg); - const roughNode = rc.rectangle(x, y, width, height, solidStateFill(lineColor)); - shape = shapeSvg.insert(() => roughNode); - } else { - shape = shapeSvg - .append('rect') - .attr('x', x) - .attr('y', y) - .attr('width', width) - .attr('height', height) - .attr('class', 'fork-join'); + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, { + stroke: themeVariables.lineColor, + fill: themeVariables.lineColor, + }); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const roughNode = rc.rectangle(x, y, width, height, options); + + const shape = shapeSvg.insert(() => roughNode, ':first-child'); + + if (cssStyles && node.look !== 'handDrawn') { + shape.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + shape.selectAll('path').attr('style', nodeStyles); } updateNodeBounds(node, shape); - let nodeHeight = 0; - let nodeWidth = 0; - let nodePadding = 10; - if (node.height) { - nodeHeight = node.height; + const padding = state?.padding ?? 0; + if (node.width && node.height) { + node.width += padding / 2 || 0; + node.height += padding / 2 || 0; } - if (node.width) { - nodeWidth = node.width; - } - - if (node.padding) { - nodePadding = node.padding; - } - - node.height = nodeHeight + nodePadding / 2; - node.width = nodeWidth + nodePadding / 2; node.intersect = function (point) { return intersect.rect(node, point); }; - return shapeSvg; -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/halfRoundedRectangle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/halfRoundedRectangle.ts new file mode 100644 index 000000000..330420cf0 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/halfRoundedRectangle.ts @@ -0,0 +1,72 @@ +import { log } from '../../../logger.js'; +import { + labelHelper, + updateNodeBounds, + getNodeClasses, + createPathFromPoints, + generateCirclePoints, +} from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; + +export async function halfRoundedRectangle( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const minWidth = 80, + minHeight = 50; + const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); + const w = Math.max(minWidth, bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(minHeight, bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const radius = h / 2; + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const points = [ + { x: -w / 2, y: -h / 2 }, + { x: w / 2 - radius, y: -h / 2 }, + ...generateCirclePoints(-w / 2 + radius, 0, radius, 50, 90, 270), + { x: w / 2 - radius, y: h / 2 }, + { x: -w / 2, y: h / 2 }, + ]; + + const pathData = createPathFromPoints(points); + const shapeNode = rc.path(pathData, options); + const polygon = shapeSvg.insert(() => shapeNode, ':first-child'); + polygon.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', nodeStyles); + } + + // label.attr( + // 'transform', + // `translate(${-w / 2 + (node.padding ?? 0) - (bbox.x - (bbox.left ?? 0))}, ${-h / 2 + (node.padding ?? 0) - (bbox.y - (bbox.top ?? 0))})` + // ); + + updateNodeBounds(node, polygon); + + node.intersect = function (point) { + log.info('Pill intersect', node, { radius, point }); + const pos = intersect.polygon(node, points, point); + return pos; + }; + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.ts index a5c963e7c..80e2a4423 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.ts @@ -1,5 +1,5 @@ -import { getConfig } from '$root/diagram-api/diagramAPI.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; +import { getConfig } from '../../../diagram-api/diagramAPI.js'; +import type { Node } from '../../types.js'; // Striped fill like start or fork nodes in state diagrams export const solidStateFill = (color: string) => { @@ -97,9 +97,11 @@ export const userNodeOverrides = (node: Node, options: any) => { fill: stylesMap.get('fill') || mainBkg, fillStyle: 'hachure', // solid fill fillWeight: 4, + hachureGap: 5.2, stroke: stylesMap.get('stroke') || nodeBorder, seed: handDrawnSeed, - strokeWidth: 1.3, + strokeWidth: stylesMap.get('stroke-width')?.replace('px', '') || 1.3, + fillLineDash: [0, 0], }, options ); diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/hexagon.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/hexagon.ts index 3b0ce3081..52a4397a2 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/hexagon.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/hexagon.ts @@ -1,13 +1,10 @@ import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import rough from 'roughjs'; - import { insertPolygonShape } from './insertPolygonShape.js'; +import type { D3Selection } from '../../../types.js'; export const createHexagonPathD = ( x: number, @@ -27,7 +24,7 @@ export const createHexagonPathD = ( ].join(' '); }; -export const hexagon = async (parent: SVGAElement, node: Node): Promise => { +export async function hexagon(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); @@ -45,11 +42,11 @@ export const hexagon = async (parent: SVGAElement, node: Node): Promise; + let polygon: D3Selection | Awaited>; const { cssStyles } = node; if (node.look === 'handDrawn') { - // @ts-ignore - rough is not typed + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); const options = userNodeOverrides(node, {}); const pathData = createHexagonPathD(0, 0, w, h, m); @@ -80,4 +77,4 @@ export const hexagon = async (parent: SVGAElement, node: Node): Promise(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.label = ''; + node.labelStyle = labelStyles; + const { shapeSvg } = await labelHelper(parent, node, getNodeClasses(node)); + + const w = Math.max(30, node?.width ?? 0); + const h = Math.max(30, node?.height ?? 0); + + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: 0, y: h }, + { x: w, y: h }, + ]; + + const pathData = createPathFromPoints(points); + const shapeNode = rc.path(pathData, options); + const polygon = shapeSvg.insert(() => shapeNode, ':first-child'); + polygon.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', nodeStyles); + } + + polygon.attr('transform', `translate(${-w / 2}, ${-h / 2})`); + + updateNodeBounds(node, polygon); + + // label.attr('transform', `translate(${-bbox.width / 2}, ${(h/2)})`); // To transform text below hourglass shape + + node.intersect = function (point) { + log.info('Pill intersect', node, { points }); + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts new file mode 100644 index 000000000..e0735f3d3 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts @@ -0,0 +1,138 @@ +import rough from 'roughjs'; +import { log } from '../../../logger.js'; +import { getIconSVG } from '../../icons.js'; +import type { Node, ShapeRenderOptions } from '../../types.js'; +import intersect from '../intersect/index.js'; +import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import { labelHelper, updateNodeBounds } from './util.js'; +import type { D3Selection } from '../../../types.js'; + +export async function icon( + parent: D3Selection, + node: Node, + { config: { themeVariables, flowchart } }: ShapeRenderOptions +) { + const { labelStyles } = styles2String(node); + node.labelStyle = labelStyles; + const assetHeight = node.assetHeight ?? 48; + const assetWidth = node.assetWidth ?? 48; + const iconSize = Math.max(assetHeight, assetWidth); + const defaultWidth = flowchart?.wrappingWidth; + node.width = Math.max(iconSize, defaultWidth ?? 0); + const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'icon-shape default'); + + const topLabel = node.pos === 't'; + + const height = iconSize; + const width = iconSize; + const { nodeBorder } = themeVariables; + const { stylesMap } = compileStyles(node); + + const x = -width / 2; + const y = -height / 2; + + const labelPadding = node.label ? 8 : 0; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, { stroke: 'none', fill: 'none' }); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const iconNode = rc.rectangle(x, y, width, height, options); + + const outerWidth = Math.max(width, bbox.width); + const outerHeight = height + bbox.height + labelPadding; + + const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, { + ...options, + fill: 'transparent', + stroke: 'none', + }); + + const iconShape = shapeSvg.insert(() => iconNode, ':first-child'); + const outerShape = shapeSvg.insert(() => outerNode); + + if (node.icon) { + const iconElem = shapeSvg.append('g'); + iconElem.html( + `${await getIconSVG(node.icon, { + height: iconSize, + width: iconSize, + fallbackPrefix: '', + })}` + ); + const iconBBox = iconElem.node()!.getBBox(); + const iconWidth = iconBBox.width; + const iconHeight = iconBBox.height; + const iconX = iconBBox.x; + const iconY = iconBBox.y; + iconElem.attr( + 'transform', + `translate(${-iconWidth / 2 - iconX},${ + topLabel + ? bbox.height / 2 + labelPadding / 2 - iconHeight / 2 - iconY + : -bbox.height / 2 - labelPadding / 2 - iconHeight / 2 - iconY + })` + ); + iconElem.attr('style', `color: ${stylesMap.get('stroke') ?? nodeBorder};`); + } + + label.attr( + 'transform', + `translate(${-bbox.width / 2 - (bbox.x - (bbox.left ?? 0))},${ + topLabel ? -outerHeight / 2 : outerHeight / 2 - bbox.height + })` + ); + + iconShape.attr( + 'transform', + `translate(${0},${ + topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2 + })` + ); + + updateNodeBounds(node, outerShape); + + node.intersect = function (point) { + log.info('iconSquare intersect', node, point); + if (!node.label) { + return intersect.rect(node, point); + } + const dx = node.x ?? 0; + const dy = node.y ?? 0; + const nodeHeight = node.height ?? 0; + let points = []; + if (topLabel) { + points = [ + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx + width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx + width / 2, y: dy + nodeHeight / 2 }, + { x: dx - width / 2, y: dy + nodeHeight / 2 }, + { x: dx - width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + ]; + } else { + points = [ + { x: dx - width / 2, y: dy - nodeHeight / 2 }, + { x: dx + width / 2, y: dy - nodeHeight / 2 }, + { x: dx + width / 2, y: dy - nodeHeight / 2 + height }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + height }, + { x: dx + bbox.width / 2 / 2, y: dy + nodeHeight / 2 }, + { x: dx - bbox.width / 2, y: dy + nodeHeight / 2 }, + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + height }, + { x: dx - width / 2, y: dy - nodeHeight / 2 + height }, + ]; + } + + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconCircle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconCircle.ts new file mode 100644 index 000000000..e8e16853a --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconCircle.ts @@ -0,0 +1,104 @@ +import rough from 'roughjs'; +import { log } from '../../../logger.js'; +import { getIconSVG } from '../../icons.js'; +import type { Node, ShapeRenderOptions } from '../../types.js'; +import intersect from '../intersect/index.js'; +import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import { labelHelper, updateNodeBounds } from './util.js'; +import type { D3Selection } from '../../../types.js'; + +export async function iconCircle( + parent: D3Selection, + node: Node, + { config: { themeVariables, flowchart } }: ShapeRenderOptions +) { + const { labelStyles } = styles2String(node); + node.labelStyle = labelStyles; + const assetHeight = node.assetHeight ?? 48; + const assetWidth = node.assetWidth ?? 48; + const iconSize = Math.max(assetHeight, assetWidth); + const defaultWidth = flowchart?.wrappingWidth; + node.width = Math.max(iconSize, defaultWidth ?? 0); + const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'icon-shape default'); + + const padding = 20; + const labelPadding = node.label ? 8 : 0; + + const topLabel = node.pos === 't'; + + const { nodeBorder, mainBkg } = themeVariables; + const { stylesMap } = compileStyles(node); + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + const fill = stylesMap.get('fill'); + options.stroke = fill ?? mainBkg; + + const iconElem = shapeSvg.append('g'); + if (node.icon) { + iconElem.html( + `${await getIconSVG(node.icon, { + height: iconSize, + width: iconSize, + fallbackPrefix: '', + })}` + ); + } + const iconBBox = iconElem.node()!.getBBox(); + const iconWidth = iconBBox.width; + const iconHeight = iconBBox.height; + const iconX = iconBBox.x; + const iconY = iconBBox.y; + + const diameter = Math.max(iconWidth, iconHeight) * Math.SQRT2 + padding * 2; + const iconNode = rc.circle(0, 0, diameter, options); + + const outerWidth = Math.max(diameter, bbox.width); + const outerHeight = diameter + bbox.height + labelPadding; + + const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, { + ...options, + fill: 'transparent', + stroke: 'none', + }); + + const iconShape = shapeSvg.insert(() => iconNode, ':first-child'); + const outerShape = shapeSvg.insert(() => outerNode); + iconElem.attr( + 'transform', + `translate(${-iconWidth / 2 - iconX},${ + topLabel + ? bbox.height / 2 + labelPadding / 2 - iconHeight / 2 - iconY + : -bbox.height / 2 - labelPadding / 2 - iconHeight / 2 - iconY + })` + ); + iconElem.attr('style', `color: ${stylesMap.get('stroke') ?? nodeBorder};`); + label.attr( + 'transform', + `translate(${-bbox.width / 2 - (bbox.x - (bbox.left ?? 0))},${ + topLabel ? -outerHeight / 2 : outerHeight / 2 - bbox.height + })` + ); + + iconShape.attr( + 'transform', + `translate(${0},${ + topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2 + })` + ); + + updateNodeBounds(node, outerShape); + + node.intersect = function (point) { + log.info('iconSquare intersect', node, point); + const pos = intersect.rect(node, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts new file mode 100644 index 000000000..40c427ef5 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts @@ -0,0 +1,145 @@ +import rough from 'roughjs'; +import { log } from '../../../logger.js'; +import { getIconSVG } from '../../icons.js'; +import type { Node, ShapeRenderOptions } from '../../types.js'; +import intersect from '../intersect/index.js'; +import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import { createRoundedRectPathD } from './roundedRectPath.js'; +import { labelHelper, updateNodeBounds } from './util.js'; +import type { D3Selection } from '../../../types.js'; + +export async function iconRounded( + parent: D3Selection, + node: Node, + { config: { themeVariables, flowchart } }: ShapeRenderOptions +) { + const { labelStyles } = styles2String(node); + node.labelStyle = labelStyles; + const assetHeight = node.assetHeight ?? 48; + const assetWidth = node.assetWidth ?? 48; + const iconSize = Math.max(assetHeight, assetWidth); + const defaultWidth = flowchart?.wrappingWidth; + node.width = Math.max(iconSize, defaultWidth ?? 0); + const { shapeSvg, bbox, halfPadding, label } = await labelHelper( + parent, + node, + 'icon-shape default' + ); + + const topLabel = node.pos === 't'; + + const height = iconSize + halfPadding * 2; + const width = iconSize + halfPadding * 2; + const { nodeBorder, mainBkg } = themeVariables; + const { stylesMap } = compileStyles(node); + + const x = -width / 2; + const y = -height / 2; + + const labelPadding = node.label ? 8 : 0; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + const fill = stylesMap.get('fill'); + options.stroke = fill ?? mainBkg; + + const iconNode = rc.path(createRoundedRectPathD(x, y, width, height, 5), options); + + const outerWidth = Math.max(width, bbox.width); + const outerHeight = height + bbox.height + labelPadding; + + const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, { + ...options, + fill: 'transparent', + stroke: 'none', + }); + + const iconShape = shapeSvg.insert(() => iconNode, ':first-child').attr('class', 'icon-shape2'); + const outerShape = shapeSvg.insert(() => outerNode); + + if (node.icon) { + const iconElem = shapeSvg.append('g'); + iconElem.html( + `${await getIconSVG(node.icon, { + height: iconSize, + width: iconSize, + fallbackPrefix: '', + })}` + ); + const iconBBox = iconElem.node()!.getBBox(); + const iconWidth = iconBBox.width; + const iconHeight = iconBBox.height; + const iconX = iconBBox.x; + const iconY = iconBBox.y; + iconElem.attr( + 'transform', + `translate(${-iconWidth / 2 - iconX},${ + topLabel + ? bbox.height / 2 + labelPadding / 2 - iconHeight / 2 - iconY + : -bbox.height / 2 - labelPadding / 2 - iconHeight / 2 - iconY + })` + ); + iconElem.attr('style', `color: ${stylesMap.get('stroke') ?? nodeBorder};`); + } + + label.attr( + 'transform', + `translate(${-bbox.width / 2 - (bbox.x - (bbox.left ?? 0))},${ + topLabel ? -outerHeight / 2 : outerHeight / 2 - bbox.height + })` + ); + + iconShape.attr( + 'transform', + `translate(${0},${ + topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2 + })` + ); + + updateNodeBounds(node, outerShape); + + node.intersect = function (point) { + log.info('iconSquare intersect', node, point); + if (!node.label) { + return intersect.rect(node, point); + } + const dx = node.x ?? 0; + const dy = node.y ?? 0; + const nodeHeight = node.height ?? 0; + let points = []; + if (topLabel) { + points = [ + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx + width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx + width / 2, y: dy + nodeHeight / 2 }, + { x: dx - width / 2, y: dy + nodeHeight / 2 }, + { x: dx - width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + ]; + } else { + points = [ + { x: dx - width / 2, y: dy - nodeHeight / 2 }, + { x: dx + width / 2, y: dy - nodeHeight / 2 }, + { x: dx + width / 2, y: dy - nodeHeight / 2 + height }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + height }, + { x: dx + bbox.width / 2 / 2, y: dy + nodeHeight / 2 }, + { x: dx - bbox.width / 2, y: dy + nodeHeight / 2 }, + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + height }, + { x: dx - width / 2, y: dy - nodeHeight / 2 + height }, + ]; + } + + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts new file mode 100644 index 000000000..e3536b89e --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts @@ -0,0 +1,145 @@ +import rough from 'roughjs'; +import { log } from '../../../logger.js'; +import { getIconSVG } from '../../icons.js'; +import type { Node, ShapeRenderOptions } from '../../types.js'; +import intersect from '../intersect/index.js'; +import { createRoundedRectPathD } from './roundedRectPath.js'; +import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import { labelHelper, updateNodeBounds } from './util.js'; +import type { D3Selection } from '../../../types.js'; + +export async function iconSquare( + parent: D3Selection, + node: Node, + { config: { themeVariables, flowchart } }: ShapeRenderOptions +) { + const { labelStyles } = styles2String(node); + node.labelStyle = labelStyles; + const assetHeight = node.assetHeight ?? 48; + const assetWidth = node.assetWidth ?? 48; + const iconSize = Math.max(assetHeight, assetWidth); + const defaultWidth = flowchart?.wrappingWidth; + node.width = Math.max(iconSize, defaultWidth ?? 0); + const { shapeSvg, bbox, halfPadding, label } = await labelHelper( + parent, + node, + 'icon-shape default' + ); + + const topLabel = node.pos === 't'; + + const height = iconSize + halfPadding * 2; + const width = iconSize + halfPadding * 2; + const { nodeBorder, mainBkg } = themeVariables; + const { stylesMap } = compileStyles(node); + + const x = -width / 2; + const y = -height / 2; + + const labelPadding = node.label ? 8 : 0; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + const fill = stylesMap.get('fill'); + options.stroke = fill ?? mainBkg; + + const iconNode = rc.path(createRoundedRectPathD(x, y, width, height, 0.1), options); + + const outerWidth = Math.max(width, bbox.width); + const outerHeight = height + bbox.height + labelPadding; + + const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, { + ...options, + fill: 'transparent', + stroke: 'none', + }); + + const iconShape = shapeSvg.insert(() => iconNode, ':first-child'); + const outerShape = shapeSvg.insert(() => outerNode); + + if (node.icon) { + const iconElem = shapeSvg.append('g'); + iconElem.html( + `${await getIconSVG(node.icon, { + height: iconSize, + width: iconSize, + fallbackPrefix: '', + })}` + ); + const iconBBox = iconElem.node()!.getBBox(); + const iconWidth = iconBBox.width; + const iconHeight = iconBBox.height; + const iconX = iconBBox.x; + const iconY = iconBBox.y; + iconElem.attr( + 'transform', + `translate(${-iconWidth / 2 - iconX},${ + topLabel + ? bbox.height / 2 + labelPadding / 2 - iconHeight / 2 - iconY + : -bbox.height / 2 - labelPadding / 2 - iconHeight / 2 - iconY + })` + ); + iconElem.attr('style', `color: ${stylesMap.get('stroke') ?? nodeBorder};`); + } + + label.attr( + 'transform', + `translate(${-bbox.width / 2 - (bbox.x - (bbox.left ?? 0))},${ + topLabel ? -outerHeight / 2 : outerHeight / 2 - bbox.height + })` + ); + + iconShape.attr( + 'transform', + `translate(${0},${ + topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2 + })` + ); + + updateNodeBounds(node, outerShape); + + node.intersect = function (point) { + log.info('iconSquare intersect', node, point); + if (!node.label) { + return intersect.rect(node, point); + } + const dx = node.x ?? 0; + const dy = node.y ?? 0; + const nodeHeight = node.height ?? 0; + let points = []; + if (topLabel) { + points = [ + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx + width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx + width / 2, y: dy + nodeHeight / 2 }, + { x: dx - width / 2, y: dy + nodeHeight / 2 }, + { x: dx - width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + ]; + } else { + points = [ + { x: dx - width / 2, y: dy - nodeHeight / 2 }, + { x: dx + width / 2, y: dy - nodeHeight / 2 }, + { x: dx + width / 2, y: dy - nodeHeight / 2 + height }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + height }, + { x: dx + bbox.width / 2 / 2, y: dy + nodeHeight / 2 }, + { x: dx - bbox.width / 2, y: dy + nodeHeight / 2 }, + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + height }, + { x: dx - width / 2, y: dy - nodeHeight / 2 + height }, + ]; + } + + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/imageSquare.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/imageSquare.ts new file mode 100644 index 000000000..5780ca1a6 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/imageSquare.ts @@ -0,0 +1,149 @@ +import rough from 'roughjs'; +import { log } from '../../../logger.js'; +import type { Node, ShapeRenderOptions } from '../../types.js'; +import intersect from '../intersect/index.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import { labelHelper, updateNodeBounds } from './util.js'; +import type { D3Selection } from '../../../types.js'; + +export async function imageSquare( + parent: D3Selection, + node: Node, + { config: { flowchart } }: ShapeRenderOptions +) { + const img = new Image(); + img.src = node?.img ?? ''; + await img.decode(); + + const imageNaturalWidth = Number(img.naturalWidth.toString().replace('px', '')); + const imageNaturalHeight = Number(img.naturalHeight.toString().replace('px', '')); + node.imageAspectRatio = imageNaturalWidth / imageNaturalHeight; + + const { labelStyles } = styles2String(node); + + node.labelStyle = labelStyles; + + const defaultWidth = flowchart?.wrappingWidth; + node.defaultWidth = flowchart?.wrappingWidth; + + const imageRawWidth = Math.max( + node.label ? (defaultWidth ?? 0) : 0, + node?.assetWidth ?? imageNaturalWidth + ); + + const imageWidth = + node.constraint === 'on' + ? node?.assetHeight + ? node.assetHeight * node.imageAspectRatio + : imageRawWidth + : imageRawWidth; + + const imageHeight = + node.constraint === 'on' + ? imageWidth / node.imageAspectRatio + : (node?.assetHeight ?? imageNaturalHeight); + node.width = Math.max(imageWidth, defaultWidth ?? 0); + const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'image-shape default'); + + const topLabel = node.pos === 't'; + + const x = -imageWidth / 2; + const y = -imageHeight / 2; + + const labelPadding = node.label ? 8 : 0; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const imageNode = rc.rectangle(x, y, imageWidth, imageHeight, options); + + const outerWidth = Math.max(imageWidth, bbox.width); + const outerHeight = imageHeight + bbox.height + labelPadding; + + const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, { + ...options, + fill: 'none', + stroke: 'none', + }); + + const iconShape = shapeSvg.insert(() => imageNode, ':first-child'); + const outerShape = shapeSvg.insert(() => outerNode); + + if (node.img) { + const image = shapeSvg.append('image'); + + // Set the image attributes + image.attr('href', node.img); + image.attr('width', imageWidth); + image.attr('height', imageHeight); + image.attr('preserveAspectRatio', 'none'); + + image.attr( + 'transform', + `translate(${-imageWidth / 2},${topLabel ? outerHeight / 2 - imageHeight : -outerHeight / 2})` + ); + } + + label.attr( + 'transform', + `translate(${-bbox.width / 2 - (bbox.x - (bbox.left ?? 0))},${ + topLabel + ? -imageHeight / 2 - bbox.height / 2 - labelPadding / 2 + : imageHeight / 2 - bbox.height / 2 + labelPadding / 2 + })` + ); + + iconShape.attr( + 'transform', + `translate(${0},${ + topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2 + })` + ); + + updateNodeBounds(node, outerShape); + + node.intersect = function (point) { + log.info('iconSquare intersect', node, point); + if (!node.label) { + return intersect.rect(node, point); + } + const dx = node.x ?? 0; + const dy = node.y ?? 0; + const nodeHeight = node.height ?? 0; + let points = []; + if (topLabel) { + points = [ + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx + imageWidth / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx + imageWidth / 2, y: dy + nodeHeight / 2 }, + { x: dx - imageWidth / 2, y: dy + nodeHeight / 2 }, + { x: dx - imageWidth / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding }, + ]; + } else { + points = [ + { x: dx - imageWidth / 2, y: dy - nodeHeight / 2 }, + { x: dx + imageWidth / 2, y: dy - nodeHeight / 2 }, + { x: dx + imageWidth / 2, y: dy - nodeHeight / 2 + imageHeight }, + { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + imageHeight }, + { x: dx + bbox.width / 2 / 2, y: dy + nodeHeight / 2 }, + { x: dx - bbox.width / 2, y: dy + nodeHeight / 2 }, + { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + imageHeight }, + { x: dx - imageWidth / 2, y: dy - nodeHeight / 2 + imageHeight }, + ]; + } + + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/insertPolygonShape.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/insertPolygonShape.ts index 6c00b9523..874996444 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/insertPolygonShape.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/insertPolygonShape.ts @@ -1,5 +1,7 @@ -export function insertPolygonShape( - parent: any, +import type { D3Selection } from '../../../types.js'; + +export function insertPolygonShape( + parent: D3Selection, w: number, h: number, points: { x: number; y: number }[] diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/invertedTrapezoid.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/invertedTrapezoid.ts index 37f415247..49e0f908e 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/invertedTrapezoid.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/invertedTrapezoid.ts @@ -1,50 +1,53 @@ -import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; +import { labelHelper, updateNodeBounds, getNodeClasses, createPathFromPoints } from './util.js'; import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import rough from 'roughjs'; import { insertPolygonShape } from './insertPolygonShape.js'; +import type { D3Selection } from '../../../types.js'; -export const createInvertedTrapezoidPathD = ( - x: number, - y: number, - width: number, - height: number -): string => { - return [ - `M${x + height / 6},${y}`, - `L${x + width - height / 6},${y}`, - `L${x + width + (2 * height) / 6},${y - height}`, - `L${x - (2 * height) / 6},${y - height}`, - 'Z', - ].join(' '); -}; +// export const createInvertedTrapezoidPathD = ( +// x: number, +// y: number, +// width: number, +// height: number +// ): string => { +// return [ +// `M${x + height / 6},${y}`, +// `L${x + width - height / 6},${y}`, +// `L${x + width + (2 * height) / 6},${y - height}`, +// `L${x - (2 * height) / 6},${y - height}`, +// 'Z', +// ].join(' '); +// }; -export const inv_trapezoid = async (parent: SVGAElement, node: Node): Promise => { +export async function inv_trapezoid( + parent: D3Selection, + node: Node +) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); - const w = bbox.width + node.padding; - const h = bbox.height + node.padding; + const w = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const points = [ - { x: h / 6, y: 0 }, - { x: w - h / 6, y: 0 }, - { x: w + (2 * h) / 6, y: -h }, - { x: (-2 * h) / 6, y: -h }, + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w + (3 * h) / 6, y: -h }, + { x: (-3 * h) / 6, y: -h }, ]; - let polygon: d3.Selection; + let polygon: typeof shapeSvg | ReturnType; const { cssStyles } = node; if (node.look === 'handDrawn') { - // @ts-ignore - rough is not typed + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); const options = userNodeOverrides(node, {}); - const pathData = createInvertedTrapezoidPathD(0, 0, w, h); + const pathData = createPathFromPoints(points); + // const pathData = createInvertedTrapezoidPathD(0, 0, w, h); const roughNode = rc.path(pathData, options); polygon = shapeSvg @@ -72,4 +75,4 @@ export const inv_trapezoid = async (parent: SVGAElement, node: Node): Promise) => { + switch (priority) { + case 'Very High': + return 'red'; + case 'High': + return 'orange'; + case 'Medium': + return null; // no stroke + case 'Low': + return 'blue'; + case 'Very Low': + return 'lightblue'; + } +}; +export async function kanbanItem( + parent: D3Selection, + // Omit the 'shape' prop since otherwise, it causes a TypeScript circular dependency error + kanbanNode: Omit | Omit, + { config }: ShapeRenderOptions +) { + const { labelStyles, nodeStyles } = styles2String(kanbanNode); + kanbanNode.labelStyle = labelStyles || ''; + + const labelPaddingX = 10; + const orgWidth = kanbanNode.width; + kanbanNode.width = (kanbanNode.width ?? 200) - 10; + + const { + shapeSvg, + bbox, + label: labelElTitle, + } = await labelHelper(parent, kanbanNode, getNodeClasses(kanbanNode)); + const padding = kanbanNode.padding || 10; + + let ticketUrl = ''; + let link; + + if ('ticket' in kanbanNode && kanbanNode.ticket && config?.kanban?.ticketBaseUrl) { + ticketUrl = config?.kanban?.ticketBaseUrl.replace('#TICKET#', kanbanNode.ticket); + link = shapeSvg + .insert('svg:a', ':first-child') + .attr('class', 'kanban-ticket-link') + .attr('xlink:href', ticketUrl) + .attr('target', '_blank'); + } + + const options = { + useHtmlLabels: kanbanNode.useHtmlLabels, + labelStyle: kanbanNode.labelStyle || '', + width: kanbanNode.width, + img: kanbanNode.img, + padding: kanbanNode.padding || 8, + centerLabel: false, + }; + let labelEl, bbox2; + if (link) { + ({ label: labelEl, bbox: bbox2 } = await insertLabel( + link, + ('ticket' in kanbanNode && kanbanNode.ticket) || '', + options + )); + } else { + ({ label: labelEl, bbox: bbox2 } = await insertLabel( + shapeSvg, + ('ticket' in kanbanNode && kanbanNode.ticket) || '', + options + )); + } + const { label: labelElAssigned, bbox: bboxAssigned } = await insertLabel( + shapeSvg, + ('assigned' in kanbanNode && kanbanNode.assigned) || '', + options + ); + kanbanNode.width = orgWidth; + const labelPaddingY = 10; + const totalWidth = kanbanNode?.width || 0; + const heightAdj = Math.max(bbox2.height, bboxAssigned.height) / 2; + const totalHeight = + Math.max(bbox.height + labelPaddingY * 2, kanbanNode?.height || 0) + heightAdj; + const x = -totalWidth / 2; + const y = -totalHeight / 2; + labelElTitle.attr( + 'transform', + 'translate(' + (padding - totalWidth / 2) + ', ' + (-heightAdj - bbox.height / 2) + ')' + ); + labelEl.attr( + 'transform', + 'translate(' + (padding - totalWidth / 2) + ', ' + (-heightAdj + bbox.height / 2) + ')' + ); + labelElAssigned.attr( + 'transform', + 'translate(' + + (padding + totalWidth / 2 - bboxAssigned.width - 2 * labelPaddingX) + + ', ' + + (-heightAdj + bbox.height / 2) + + ')' + ); + + let rect; + + const { rx, ry } = kanbanNode; + const { cssStyles } = kanbanNode; + + if (kanbanNode.look === 'handDrawn') { + // @ts-ignore TODO: Fix rough typings + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(kanbanNode, {}); + + const roughNode = + rx || ry + ? rc.path(createRoundedRectPathD(x, y, totalWidth, totalHeight, rx || 0), options) + : rc.rectangle(x, y, totalWidth, totalHeight, options); + + rect = shapeSvg.insert(() => roughNode, ':first-child'); + rect.attr('class', 'basic label-container').attr('style', cssStyles ? cssStyles : null); + } else { + rect = shapeSvg.insert('rect', ':first-child'); + + rect + .attr('class', 'basic label-container __APA__') + .attr('style', nodeStyles) + .attr('rx', rx ?? 5) + .attr('ry', ry ?? 5) + .attr('x', x) + .attr('y', y) + .attr('width', totalWidth) + .attr('height', totalHeight); + + const priority = 'priority' in kanbanNode && kanbanNode.priority; + if (priority) { + const line = shapeSvg.append('line'); + const lineX = x + 2; + + const y1 = y + Math.floor((rx ?? 0) / 2); + const y2 = y + totalHeight - Math.floor((rx ?? 0) / 2); + line + .attr('x1', lineX) + .attr('y1', y1) + .attr('x2', lineX) + .attr('y2', y2) + + .attr('stroke-width', '4') + .attr('stroke', colorFromPriority(priority)); + } + } + + updateNodeBounds(kanbanNode, rect); + kanbanNode.height = totalHeight; + + kanbanNode.intersect = function (point) { + return intersect.rect(kanbanNode, point); + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/labelRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/labelRect.ts index 2d5c6d6ea..de53da4f1 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/labelRect.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/labelRect.ts @@ -1,9 +1,13 @@ -import type { Node, RectOptions } from '$root/rendering-util/types.d.ts'; +import type { Node, RectOptions } from '../../types.js'; import { drawRect } from './drawRect.js'; import { labelHelper, updateNodeBounds } from './util.js'; import intersect from '../intersect/index.js'; +import type { D3Selection } from '../../../types.js'; -export const roundedRect = async (parent: SVGAElement, node: Node) => { +export async function roundedRect( + parent: D3Selection, + node: Node +) { const options = { rx: 5, ry: 5, @@ -13,10 +17,10 @@ export const roundedRect = async (parent: SVGAElement, node: Node) => { } as RectOptions; return drawRect(parent, node, options); -}; +} -export const labelRect = async (parent: SVGElement, node: Node) => { - const { shapeSvg } = await labelHelper(parent, node, 'label'); +export async function labelRect(parent: D3Selection, node: Node) { + const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'label'); // log.trace('Classes = ', node.class); // add the rect @@ -27,6 +31,10 @@ export const labelRect = async (parent: SVGElement, node: Node) => { const totalHeight = 0.1; rect.attr('width', totalWidth).attr('height', totalHeight); shapeSvg.attr('class', 'label edgeLabel'); + label.attr( + 'transform', + `translate(${-(bbox.width / 2) - (bbox.x - (bbox.left ?? 0))}, ${-(bbox.height / 2) - (bbox.y - (bbox.top ?? 0))})` + ); // if (node.props) { // const propKeys = new Set(Object.keys(node.props)); @@ -48,4 +56,4 @@ export const labelRect = async (parent: SVGElement, node: Node) => { }; return shapeSvg; -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/leanLeft.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/leanLeft.ts index bb57925e2..de84b2a7f 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/leanLeft.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/leanLeft.ts @@ -1,50 +1,33 @@ -import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; +import { labelHelper, updateNodeBounds, getNodeClasses, createPathFromPoints } from './util.js'; import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import rough from 'roughjs'; import { insertPolygonShape } from './insertPolygonShape.js'; +import type { D3Selection } from '../../../types.js'; -export const createLeanLeftPathD = ( - x: number, - y: number, - width: number, - height: number -): string => { - return [ - `M${x + (2 * height) / 6},${y}`, - `L${x + width + height / 6},${y}`, - `L${x + width - (2 * height) / 6},${y - height}`, - `L${x - height / 6},${y - height}`, - 'Z', - ].join(' '); -}; - -export const lean_left = async (parent: SVGAElement, node: Node): Promise => { +export async function lean_left(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); - - const w = bbox.width + node.padding; - const h = bbox.height + node.padding; + const w = Math.max(bbox.width + (node.padding ?? 0), node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0), node?.height ?? 0); const points = [ - { x: (2 * h) / 6, y: 0 }, - { x: w + h / 6, y: 0 }, - { x: w - (2 * h) / 6, y: -h }, - { x: -h / 6, y: -h }, + { x: 0, y: 0 }, + { x: w + (3 * h) / 6, y: 0 }, + { x: w, y: -h }, + { x: -(3 * h) / 6, y: -h }, ]; - let polygon: d3.Selection; + let polygon: typeof shapeSvg | ReturnType; const { cssStyles } = node; if (node.look === 'handDrawn') { - // @ts-ignore - rough is not typed + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); const options = userNodeOverrides(node, {}); - const pathData = createLeanLeftPathD(0, 0, w, h); + const pathData = createPathFromPoints(points); + // const pathData = createLeanLeftPathD(0, 0, w, h); const roughNode = rc.path(pathData, options); polygon = shapeSvg @@ -72,4 +55,4 @@ export const lean_left = async (parent: SVGAElement, node: Node): Promise { - return [ - `M${x - (2 * height) / 6},${y}`, - `L${x + width - height / 6},${y}`, - `L${x + width + (2 * height) / 6},${y - height}`, - `L${x + height / 6},${y - height}`, - 'Z', - ].join(' '); -}; - -export const lean_right = async (parent: SVGAElement, node: Node): Promise => { +export async function lean_right(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); - - const w = bbox.width + node.padding; - const h = bbox.height + node.padding; + const w = Math.max(bbox.width + (node.padding ?? 0), node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0), node?.height ?? 0); const points = [ - { x: (-2 * h) / 6, y: 0 }, - { x: w - h / 6, y: 0 }, - { x: w + (2 * h) / 6, y: -h }, - { x: h / 6, y: -h }, + { x: (-3 * h) / 6, y: 0 }, + { x: w, y: 0 }, + { x: w + (3 * h) / 6, y: -h }, + { x: 0, y: -h }, ]; - let polygon: d3.Selection; + let polygon: typeof shapeSvg | ReturnType; const { cssStyles } = node; if (node.look === 'handDrawn') { - // @ts-ignore - rough is not typed + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); const options = userNodeOverrides(node, {}); - const pathData = createLeanRightPathD(0, 0, w, h); + const pathData = createPathFromPoints(points); const roughNode = rc.path(pathData, options); polygon = shapeSvg @@ -72,4 +54,4 @@ export const lean_right = async (parent: SVGAElement, node: Node): Promise(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.label = ''; + node.labelStyle = labelStyles; + const shapeSvg = parent + .insert('g') + .attr('class', getNodeClasses(node)) + .attr('id', node.domId ?? node.id); + const { cssStyles } = node; + const width = Math.max(35, node?.width ?? 0); + const height = Math.max(35, node?.height ?? 0); + const gap = 7; + + const points = [ + { x: width, y: 0 }, + { x: 0, y: height + gap / 2 }, + { x: width - 2 * gap, y: height + gap / 2 }, + { x: 0, y: 2 * height }, + { x: width, y: height - gap / 2 }, + { x: 2 * gap, y: height - gap / 2 }, + ]; + + // @ts-expect-error shapeSvg d3 class is incorrect? + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const linePath = createPathFromPoints(points); + const lineNode = rc.path(linePath, options); + + const lightningBolt = shapeSvg.insert(() => lineNode, ':first-child'); + + if (cssStyles && node.look !== 'handDrawn') { + lightningBolt.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + lightningBolt.selectAll('path').attr('style', nodeStyles); + } + + lightningBolt.attr('transform', `translate(-${width / 2},${-height})`); + + updateNodeBounds(node, lightningBolt); + + node.intersect = function (point) { + log.info('lightningBolt intersect', node, point); + const pos = intersect.polygon(node, points, point); + + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/linedCylinder.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/linedCylinder.ts new file mode 100644 index 000000000..6cd348649 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/linedCylinder.ts @@ -0,0 +1,139 @@ +import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; +import { handleUndefinedAttr } from '../../../utils.js'; + +export const createCylinderPathD = ( + x: number, + y: number, + width: number, + height: number, + rx: number, + ry: number, + outerOffset: number +): string => { + return [ + `M${x},${y + ry}`, + `a${rx},${ry} 0,0,0 ${width},0`, + `a${rx},${ry} 0,0,0 ${-width},0`, + `l0,${height}`, + `a${rx},${ry} 0,0,0 ${width},0`, + `l0,${-height}`, + `M${x},${y + ry + outerOffset}`, + `a${rx},${ry} 0,0,0 ${width},0`, + ].join(' '); +}; +export const createOuterCylinderPathD = ( + x: number, + y: number, + width: number, + height: number, + rx: number, + ry: number, + outerOffset: number +): string => { + return [ + `M${x},${y + ry}`, + `M${x + width},${y + ry}`, + `a${rx},${ry} 0,0,0 ${-width},0`, + `l0,${height}`, + `a${rx},${ry} 0,0,0 ${width},0`, + `l0,${-height}`, + `M${x},${y + ry + outerOffset}`, + `a${rx},${ry} 0,0,0 ${width},0`, + ].join(' '); +}; +export const createInnerCylinderPathD = ( + x: number, + y: number, + width: number, + height: number, + rx: number, + ry: number +): string => { + return [`M${x - width / 2},${-height / 2}`, `a${rx},${ry} 0,0,0 ${width},0`].join(' '); +}; +export async function linedCylinder( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = Math.max(bbox.width + (node.padding ?? 0), node.width ?? 0); + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = Math.max(bbox.height + ry + (node.padding ?? 0), node.height ?? 0); + const outerOffset = h * 0.1; // 10% of height + + let cylinder: typeof shapeSvg | D3Selection; + const { cssStyles } = node; + + if (node.look === 'handDrawn') { + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const outerPathData = createOuterCylinderPathD(0, 0, w, h, rx, ry, outerOffset); + const innerPathData = createInnerCylinderPathD(0, ry, w, h, rx, ry); + const options = userNodeOverrides(node, {}); + + const outerNode = rc.path(outerPathData, options); + const innerLine = rc.path(innerPathData, options); + + const innerLineEl = shapeSvg.insert(() => innerLine, ':first-child'); + innerLineEl.attr('class', 'line'); + cylinder = shapeSvg.insert(() => outerNode, ':first-child'); + cylinder.attr('class', 'basic label-container'); + if (cssStyles) { + cylinder.attr('style', cssStyles); + } + } else { + const pathData = createCylinderPathD(0, 0, w, h, rx, ry, outerOffset); + cylinder = shapeSvg + .insert('path', ':first-child') + .attr('d', pathData) + .attr('class', 'basic label-container') + .attr('style', handleUndefinedAttr(cssStyles)) + .attr('style', nodeStyles); + } + + // find label and move it down + cylinder.attr('label-offset-y', ry); + cylinder.attr('transform', `translate(${-w / 2}, ${-(h / 2 + ry)})`); + + updateNodeBounds(node, cylinder); + + label.attr( + 'transform', + `translate(${-(bbox.width / 2) - (bbox.x - (bbox.left ?? 0))}, ${-(bbox.height / 2) + ry - (bbox.y - (bbox.top ?? 0))})` + ); + + node.intersect = function (point) { + const pos = intersect.rect(node, point); + const x = pos.x - (node.x ?? 0); + + if ( + rx != 0 && + (Math.abs(x) < (node.width ?? 0) / 2 || + (Math.abs(x) == (node.width ?? 0) / 2 && + Math.abs(pos.y - (node.y ?? 0)) > (node.height ?? 0) / 2 - ry)) + ) { + let y = ry * ry * (1 - (x * x) / (rx * rx)); + if (y > 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point.y - (node.y ?? 0) > 0) { + y = -y; + } + + pos.y += y; + } + + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/linedWaveEdgedRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/linedWaveEdgedRect.ts new file mode 100644 index 000000000..6f8123742 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/linedWaveEdgedRect.ts @@ -0,0 +1,83 @@ +import { + labelHelper, + updateNodeBounds, + getNodeClasses, + generateFullSineWavePoints, +} from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import rough from 'roughjs'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import type { D3Selection } from '../../../types.js'; + +export async function linedWaveEdgedRect( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const waveAmplitude = h / 4; + const finalH = h + waveAmplitude; + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const points = [ + { x: -w / 2 - (w / 2) * 0.1, y: -finalH / 2 }, + { x: -w / 2 - (w / 2) * 0.1, y: finalH / 2 }, + ...generateFullSineWavePoints( + -w / 2 - (w / 2) * 0.1, + finalH / 2, + w / 2 + (w / 2) * 0.1, + finalH / 2, + waveAmplitude, + 0.8 + ), + { x: w / 2 + (w / 2) * 0.1, y: -finalH / 2 }, + { x: -w / 2 - (w / 2) * 0.1, y: -finalH / 2 }, + { x: -w / 2, y: -finalH / 2 }, + { x: -w / 2, y: (finalH / 2) * 1.1 }, + { x: -w / 2, y: -finalH / 2 }, + ]; + + const poly = rc.polygon( + points.map((p) => [p.x, p.y]), + options + ); + + const waveEdgeRect = shapeSvg.insert(() => poly, ':first-child'); + + waveEdgeRect.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + waveEdgeRect.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + waveEdgeRect.selectAll('path').attr('style', nodeStyles); + } + + waveEdgeRect.attr('transform', `translate(0,${-waveAmplitude / 2})`); + label.attr( + 'transform', + `translate(${-w / 2 + (node.padding ?? 0) + ((w / 2) * 0.1) / 2 - (bbox.x - (bbox.left ?? 0))},${-h / 2 + (node.padding ?? 0) - waveAmplitude / 2 - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, waveEdgeRect); + node.intersect = function (point) { + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/multiRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/multiRect.ts new file mode 100644 index 000000000..a82929ec4 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/multiRect.ts @@ -0,0 +1,83 @@ +import { labelHelper, getNodeClasses, updateNodeBounds, createPathFromPoints } from './util.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import intersect from '../intersect/index.js'; +import type { D3Selection } from '../../../types.js'; + +export async function multiRect(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const rectOffset = 5; + const x = -w / 2; + const y = -h / 2; + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + const outerPathPoints = [ + { x: x - rectOffset, y: y + rectOffset }, + { x: x - rectOffset, y: y + h + rectOffset }, + { x: x + w - rectOffset, y: y + h + rectOffset }, + { x: x + w - rectOffset, y: y + h }, + { x: x + w, y: y + h }, + { x: x + w, y: y + h - rectOffset }, + { x: x + w + rectOffset, y: y + h - rectOffset }, + { x: x + w + rectOffset, y: y - rectOffset }, + { x: x + rectOffset, y: y - rectOffset }, + { x: x + rectOffset, y: y }, + { x, y }, + { x, y: y + rectOffset }, + ]; + + const innerPathPoints = [ + { x, y: y + rectOffset }, + { x: x + w - rectOffset, y: y + rectOffset }, + { x: x + w - rectOffset, y: y + h }, + { x: x + w, y: y + h }, + { x: x + w, y }, + { x, y }, + ]; + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const outerPath = createPathFromPoints(outerPathPoints); + const outerNode = rc.path(outerPath, options); + const innerPath = createPathFromPoints(innerPathPoints); + const innerNode = rc.path(innerPath, { ...options, fill: 'none' }); + + const multiRect = shapeSvg.insert(() => innerNode, ':first-child'); + multiRect.insert(() => outerNode, ':first-child'); + + multiRect.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + multiRect.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + multiRect.selectAll('path').attr('style', nodeStyles); + } + + label.attr( + 'transform', + `translate(${-(bbox.width / 2) - rectOffset - (bbox.x - (bbox.left ?? 0))}, ${-(bbox.height / 2) + rectOffset - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, multiRect); + + node.intersect = function (point) { + const pos = intersect.polygon(node, outerPathPoints, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/multiWaveEdgedRectangle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/multiWaveEdgedRectangle.ts new file mode 100644 index 000000000..db436879d --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/multiWaveEdgedRectangle.ts @@ -0,0 +1,108 @@ +import { + labelHelper, + updateNodeBounds, + getNodeClasses, + createPathFromPoints, + generateFullSineWavePoints, +} from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import rough from 'roughjs'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import type { D3Selection } from '../../../types.js'; + +export async function multiWaveEdgedRectangle( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const waveAmplitude = h / 4; + const finalH = h + waveAmplitude; + const x = -w / 2; + const y = -finalH / 2; + const rectOffset = 5; + + const { cssStyles } = node; + + const wavePoints = generateFullSineWavePoints( + x - rectOffset, + y + finalH + rectOffset, + x + w - rectOffset, + y + finalH + rectOffset, + waveAmplitude, + 0.8 + ); + + const lastWavePoint = wavePoints?.[wavePoints.length - 1]; + + const outerPathPoints = [ + { x: x - rectOffset, y: y + rectOffset }, + { x: x - rectOffset, y: y + finalH + rectOffset }, + ...wavePoints, + { x: x + w - rectOffset, y: lastWavePoint.y - rectOffset }, + { x: x + w, y: lastWavePoint.y - rectOffset }, + { x: x + w, y: lastWavePoint.y - 2 * rectOffset }, + { x: x + w + rectOffset, y: lastWavePoint.y - 2 * rectOffset }, + { x: x + w + rectOffset, y: y - rectOffset }, + { x: x + rectOffset, y: y - rectOffset }, + { x: x + rectOffset, y: y }, + { x, y }, + { x, y: y + rectOffset }, + ]; + + const innerPathPoints = [ + { x, y: y + rectOffset }, + { x: x + w - rectOffset, y: y + rectOffset }, + { x: x + w - rectOffset, y: lastWavePoint.y - rectOffset }, + { x: x + w, y: lastWavePoint.y - rectOffset }, + { x: x + w, y }, + { x, y }, + ]; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const outerPath = createPathFromPoints(outerPathPoints); + const outerNode = rc.path(outerPath, options); + const innerPath = createPathFromPoints(innerPathPoints); + const innerNode = rc.path(innerPath, options); + + const shape = shapeSvg.insert(() => outerNode, ':first-child'); + shape.insert(() => innerNode); + + shape.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + shape.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + shape.selectAll('path').attr('style', nodeStyles); + } + + shape.attr('transform', `translate(0,${-waveAmplitude / 2})`); + + label.attr( + 'transform', + `translate(${-(bbox.width / 2) - rectOffset - (bbox.x - (bbox.left ?? 0))}, ${-(bbox.height / 2) + rectOffset - waveAmplitude / 2 - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, shape); + + node.intersect = function (point) { + const pos = intersect.polygon(node, outerPathPoints, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/note.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/note.ts index 77fabf271..4a7f66a87 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/note.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/note.ts @@ -1,52 +1,53 @@ -import { log } from '$root/logger.js'; -import { labelHelper, updateNodeBounds } from './util.js'; -import intersect from '../intersect/index.js'; -import { getConfig } from '$root/diagram-api/diagramAPI.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; import rough from 'roughjs'; +import type { Node, ShapeRenderOptions } from '../../types.js'; +import intersect from '../intersect/index.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import { getNodeClasses, labelHelper, updateNodeBounds } from './util.js'; +import type { D3Selection } from '../../../types.js'; +import { getConfig } from '../../../config.js'; -export const note = async (parent: SVGAElement, node: Node) => { - const { themeVariables, handDrawnSeed } = getConfig(); - const { noteBorderColor, noteBkgColor } = themeVariables; - - const useHtmlLabels = node.useHtmlLabels; +export async function note( + parent: D3Selection, + node: Node, + { config: { themeVariables } }: ShapeRenderOptions +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const useHtmlLabels = node.useHtmlLabels || getConfig().flowchart?.htmlLabels !== false; if (!useHtmlLabels) { node.centerLabel = true; } - const { shapeSvg, bbox } = await labelHelper(parent, node, 'node ' + node.cssClasses); - - log.info('Classes = ', node.cssClasses); - const { cssStyles } = node; - let rect; - const totalWidth = bbox.width + node.padding; - const totalHeight = bbox.height + node.padding; + const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); + const totalWidth = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const totalHeight = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); const x = -totalWidth / 2; const y = -totalHeight / 2; + const { cssStyles } = node; - if (node.look === 'handDrawn') { - // add the rect - // @ts-ignore TODO: Fix rough typings - const rc = rough.svg(shapeSvg); - const roughNode = rc.rectangle(x, y, totalWidth, totalHeight, { - roughness: 0.7, - fill: noteBkgColor, - fillWeight: 3, - seed: handDrawnSeed, - // fillStyle: 'solid', // solid fill' - stroke: noteBorderColor, - }); + // add the rect + // @ts-ignore TODO: Fix rough typings + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, { + fill: themeVariables.noteBkgColor, + stroke: themeVariables.noteBorderColor, + }); - rect = shapeSvg.insert(() => roughNode, ':first-child'); - rect.attr('class', 'basic label-container').attr('style', cssStyles); - } else { - rect = shapeSvg.insert('rect', ':first-child'); - rect - .attr('rx', node.rx) - .attr('ry', node.ry) - .attr('x', x) - .attr('y', y) - .attr('width', totalWidth) - .attr('height', totalHeight); + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const noteShapeNode = rc.rectangle(x, y, totalWidth, totalHeight, options); + + const rect = shapeSvg.insert(() => noteShapeNode, ':first-child'); + rect.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + rect.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + rect.selectAll('path').attr('style', nodeStyles); } updateNodeBounds(node, rect); @@ -56,4 +57,4 @@ export const note = async (parent: SVGAElement, node: Node) => { }; return shapeSvg; -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/question.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/question.ts index ba770ab4e..eef958169 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/question.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/question.ts @@ -1,13 +1,11 @@ -import { log } from '$root/logger.js'; +import { log } from '../../../logger.js'; import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import rough from 'roughjs'; import { insertPolygonShape } from './insertPolygonShape.js'; +import type { D3Selection } from '../../../types.js'; export const createDecisionBoxPathD = (x: number, y: number, size: number): string => { return [ @@ -19,7 +17,7 @@ export const createDecisionBoxPathD = (x: number, y: number, size: number): stri ].join(' '); }; -export const question = async (parent: SVGAElement, node: Node): Promise => { +export async function question(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); @@ -35,11 +33,11 @@ export const question = async (parent: SVGAElement, node: Node): Promise; + let polygon: typeof shapeSvg | ReturnType; const { cssStyles } = node; if (node.look === 'handDrawn') { - // @ts-ignore - rough is not typed + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); const options = userNodeOverrides(node, {}); const pathData = createDecisionBoxPathD(0, 0, s); @@ -75,4 +73,4 @@ export const question = async (parent: SVGAElement, node: Node): Promise { - return [ - `M${x - height / 2},${y}`, - `L${x + width},${y}`, - `L${x + width},${y - height}`, - `L${x - height / 2},${y - height}`, - `L${x},${y - height / 2}`, - 'Z', - ].join(' '); -}; - -export const rect_left_inv_arrow = async ( - parent: SVGAElement, +export async function rect_left_inv_arrow( + parent: D3Selection, node: Node -): Promise => { +) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; - const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + + const w = Math.max(bbox.width + (node.padding ?? 0), node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0), node?.height ?? 0); + + const x = -w / 2; + const y = -h / 2; + const notch = y / 2; - const w = bbox.width + node.padding; - const h = bbox.height + node.padding; const points = [ - { x: -h / 2, y: 0 }, - { x: w, y: 0 }, - { x: w, y: -h }, - { x: -h / 2, y: -h }, - { x: 0, y: -h / 2 }, + { x: x + notch, y }, + { x: x, y: 0 }, + { x: x + notch, y: -y }, + { x: -x, y: -y }, + { x: -x, y }, ]; - let polygon; const { cssStyles } = node; + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); - if (node.look === 'handDrawn') { - // @ts-ignore - rough is not typed - const rc = rough.svg(shapeSvg); - const options = userNodeOverrides(node, {}); - const pathData = createPolygonPathD(0, 0, w, h); - const roughNode = rc.path(pathData, options); - - polygon = shapeSvg - .insert(() => roughNode, ':first-child') - .attr('transform', `translate(${-w / 2}, ${h / 2})`); - if (cssStyles) { - polygon.attr('style', cssStyles); - } - } else { - polygon = insertPolygonShape(shapeSvg, w, h, points); + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; } - if (nodeStyles) { - polygon.attr('style', nodeStyles); - } - node.width = w + h; - node.height = h; + const pathData = createPathFromPoints(points); + const roughNode = rc.path(pathData, options); + const polygon = shapeSvg.insert(() => roughNode, ':first-child'); + + polygon.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + polygon.selectAll('path').attr('style', cssStyles); + } + if (nodeStyles && node.look !== 'handDrawn') { + polygon.selectAll('path').attr('style', nodeStyles); + } + + polygon.attr('transform', `translate(${-notch / 2},0)`); + + label.attr( + 'transform', + `translate(${-notch / 2 - bbox.width / 2 - (bbox.x - (bbox.left ?? 0))}, ${-(bbox.height / 2) - (bbox.y - (bbox.top ?? 0))})` + ); updateNodeBounds(node, polygon); node.intersect = function (point) { @@ -70,4 +65,4 @@ export const rect_left_inv_arrow = async ( }; return shapeSvg; -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/rectWithTitle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/rectWithTitle.ts index 857e60b8b..bcaf2787a 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/rectWithTitle.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/rectWithTitle.ts @@ -1,19 +1,20 @@ -import type { Node } from '$root/rendering-util/types.d.ts'; +import type { Node } from '../../types.js'; import { select } from 'd3'; -import { evaluate } from '$root/diagrams/common/common.js'; +import { evaluate } from '../../../diagrams/common/common.js'; import { updateNodeBounds } from './util.js'; import createLabel from '../createLabel.js'; import intersect from '../intersect/index.js'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import rough from 'roughjs'; -import { getConfig } from '$root/diagram-api/diagramAPI.js'; +import { getConfig } from '../../../diagram-api/diagramAPI.js'; import { createRoundedRectPathD } from './roundedRectPath.js'; -import { log } from '$root/logger.js'; +import { log } from '../../../logger.js'; +import type { D3Selection } from '../../../types.js'; -export const rectWithTitle = async (parent: SVGElement, node: Node) => { +export async function rectWithTitle( + parent: D3Selection, + node: Node +) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; let classes; @@ -39,7 +40,7 @@ export const rectWithTitle = async (parent: SVGElement, node: Node) => { const title = node.label; - const text = label.node().appendChild(await createLabel(title, node.labelStyle, true, true)); + const text = label.node()!.appendChild(await createLabel(title, node.labelStyle, true, true)); let bbox = { width: 0, height: 0 }; if (evaluate(getConfig()?.flowchart?.htmlLabels)) { const div = text.children[0]; @@ -52,7 +53,7 @@ export const rectWithTitle = async (parent: SVGElement, node: Node) => { const textRows = description || []; const titleBox = text.getBBox(); const descr = label - .node() + .node()! .appendChild( await createLabel( textRows.join ? textRows.join('
') : textRows, @@ -90,7 +91,7 @@ export const rectWithTitle = async (parent: SVGElement, node: Node) => { // Get the size of the label // Bounding box for title and text - bbox = label.node().getBBox(); + bbox = label.node()!.getBBox(); // Center the label label.attr( @@ -154,4 +155,4 @@ export const rectWithTitle = async (parent: SVGElement, node: Node) => { }; return shapeSvg; -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/roundedRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/roundedRect.ts index 8a28b63ad..134bcdb6c 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/roundedRect.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/roundedRect.ts @@ -1,7 +1,11 @@ -import type { Node, RectOptions } from '$root/rendering-util/types.d.ts'; +import type { Node, RectOptions } from '../../types.js'; +import type { D3Selection } from '../../../types.js'; import { drawRect } from './drawRect.js'; -export const roundedRect = async (parent: SVGAElement, node: Node) => { +export async function roundedRect( + parent: D3Selection, + node: Node +) { const options = { rx: 5, ry: 5, @@ -11,4 +15,4 @@ export const roundedRect = async (parent: SVGAElement, node: Node) => { } as RectOptions; return drawRect(parent, node, options); -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/shadedProcess.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/shadedProcess.ts new file mode 100644 index 000000000..835f55ee4 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/shadedProcess.ts @@ -0,0 +1,71 @@ +import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; +import { handleUndefinedAttr } from '../../../utils.js'; + +export async function shadedProcess( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const halfPadding = node?.padding ?? 0; + const w = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const x = -bbox.width / 2 - halfPadding; + const y = -bbox.height / 2 - halfPadding; + + const { cssStyles } = node; + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const points = [ + { x, y }, + { x: x + w + 8, y }, + { x: x + w + 8, y: y + h }, + { x: x - 8, y: y + h }, + { x: x - 8, y: y }, + { x, y }, + { x, y: y + h }, + ]; + + const roughNode = rc.polygon( + points.map((p) => [p.x, p.y]), + options + ); + + const rect = shapeSvg.insert(() => roughNode, ':first-child'); + + rect.attr('class', 'basic label-container').attr('style', handleUndefinedAttr(cssStyles)); + + if (nodeStyles && node.look !== 'handDrawn') { + rect.selectAll('path').attr('style', nodeStyles); + } + + if (cssStyles && node.look !== 'handDrawn') { + rect.selectAll('path').attr('style', nodeStyles); + } + + label.attr( + 'transform', + `translate(${-w / 2 + 4 + (node.padding ?? 0) - (bbox.x - (bbox.left ?? 0))},${-h / 2 + (node.padding ?? 0) - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, rect); + + node.intersect = function (point) { + return intersect.rect(node, point); + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/slopedRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/slopedRect.ts new file mode 100644 index 000000000..d97e9fb6a --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/slopedRect.ts @@ -0,0 +1,63 @@ +import { labelHelper, updateNodeBounds, getNodeClasses, createPathFromPoints } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; + +export async function slopedRect(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const x = -w / 2; + const y = -h / 2; + + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const points = [ + { x, y }, + { x, y: y + h }, + { x: x + w, y: y + h }, + { x: x + w, y: y - h / 2 }, + ]; + + const pathData = createPathFromPoints(points); + const shapeNode = rc.path(pathData, options); + + const polygon = shapeSvg.insert(() => shapeNode, ':first-child'); + polygon.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', nodeStyles); + } + + polygon.attr('transform', `translate(0, ${h / 4})`); + label.attr( + 'transform', + `translate(${-w / 2 + (node.padding ?? 0) - (bbox.x - (bbox.left ?? 0))}, ${-h / 4 + (node.padding ?? 0) - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, polygon); + + node.intersect = function (point) { + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/squareRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/squareRect.ts index 8daeaec7a..af72a798f 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/squareRect.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/squareRect.ts @@ -1,7 +1,8 @@ -import type { Node, RectOptions } from '$root/rendering-util/types.d.ts'; +import type { Node, RectOptions } from '../../types.js'; +import type { D3Selection } from '../../../types.js'; import { drawRect } from './drawRect.js'; -export const squareRect = async (parent: SVGAElement, node: Node) => { +export async function squareRect(parent: D3Selection, node: Node) { const options = { rx: 0, ry: 0, @@ -10,4 +11,4 @@ export const squareRect = async (parent: SVGAElement, node: Node) => { labelPaddingY: (node?.padding || 0) * 1, } as RectOptions; return drawRect(parent, node, options); -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/stadium.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/stadium.ts index 14504b3a0..1b93aa1b3 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/stadium.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/stadium.ts @@ -1,12 +1,11 @@ import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import rough from 'roughjs'; import { createRoundedRectPathD } from './roundedRectPath.js'; +import type { D3Selection } from '../../../types.js'; +import { handleUndefinedAttr } from '../../../utils.js'; export const createStadiumPathD = ( x: number, @@ -53,7 +52,7 @@ export const createStadiumPathD = ( ].join(' '); }; -export const stadium = async (parent: SVGAElement, node: Node) => { +export async function stadium(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); @@ -64,7 +63,7 @@ export const stadium = async (parent: SVGAElement, node: Node) => { let rect; const { cssStyles } = node; if (node.look === 'handDrawn') { - // @ts-ignore - rough is not typed + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); const options = userNodeOverrides(node, {}); @@ -72,7 +71,7 @@ export const stadium = async (parent: SVGAElement, node: Node) => { const roughNode = rc.path(pathData, options); rect = shapeSvg.insert(() => roughNode, ':first-child'); - rect.attr('class', 'basic label-container').attr('style', cssStyles); + rect.attr('class', 'basic label-container').attr('style', handleUndefinedAttr(cssStyles)); } else { rect = shapeSvg.insert('rect', ':first-child'); @@ -94,4 +93,4 @@ export const stadium = async (parent: SVGAElement, node: Node) => { }; return shapeSvg; -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/state.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/state.ts index fac255735..821195e64 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/state.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/state.ts @@ -1,11 +1,12 @@ -import type { Node, RectOptions } from '$root/rendering-util/types.d.ts'; +import type { Node, RectOptions } from '../../types.js'; +import type { D3Selection } from '../../../types.js'; import { drawRect } from './drawRect.js'; -export const state = async (parent: SVGAElement, node: Node) => { +export async function state(parent: D3Selection, node: Node) { const options = { rx: 5, ry: 5, classes: 'flowchart-node', } as RectOptions; return drawRect(parent, node, options); -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/stateEnd.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/stateEnd.ts index a277ff0b9..4cc2838ae 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/stateEnd.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/stateEnd.ts @@ -1,35 +1,55 @@ -import { updateNodeBounds } from './util.js'; -import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import type { SVG } from '$root/diagram-api/types.js'; import rough from 'roughjs'; -import { solidStateFill } from './handDrawnShapeStyles.js'; -import { getConfig } from '$root/diagram-api/diagramAPI.js'; +import type { Node, ShapeRenderOptions } from '../../types.js'; +import intersect from '../intersect/index.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import { updateNodeBounds } from './util.js'; +import type { D3Selection } from '../../../types.js'; -export const stateEnd = (parent: SVG, node: Node) => { - const { themeVariables } = getConfig(); - const { lineColor } = themeVariables; +export function stateEnd( + parent: D3Selection, + node: Node, + { config: { themeVariables } }: ShapeRenderOptions +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { cssStyles } = node; + const { lineColor, stateBorder, nodeBorder } = themeVariables; const shapeSvg = parent .insert('g') .attr('class', 'node default') .attr('id', node.domId || node.id); - let circle; - let innerCircle; - if (node.look === 'handDrawn') { - // @ts-ignore TODO: Fix rough typings - const rc = rough.svg(shapeSvg); - const roughNode = rc.circle(0, 0, 14, { ...solidStateFill(lineColor), roughness: 0.5 }); - const roughInnerNode = rc.circle(0, 0, 5, { ...solidStateFill(lineColor), fillStyle: 'solid' }); - circle = shapeSvg.insert(() => roughNode); - innerCircle = shapeSvg.insert(() => roughInnerNode); - } else { - innerCircle = shapeSvg.insert('circle', ':first-child'); - circle = shapeSvg.insert('circle', ':first-child'); + // @ts-ignore TODO: Fix rough typings + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); - circle.attr('class', 'state-start').attr('r', 7).attr('width', 14).attr('height', 14); + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } - innerCircle.attr('class', 'state-end').attr('r', 5).attr('width', 10).attr('height', 10); + const roughNode = rc.circle(0, 0, 14, { + ...options, + stroke: lineColor, + strokeWidth: 2, + }); + const innerFill = stateBorder ?? nodeBorder; + const roughInnerNode = rc.circle(0, 0, 5, { + ...options, + fill: innerFill, + stroke: innerFill, + strokeWidth: 2, + fillStyle: 'solid', + }); + const circle = shapeSvg.insert(() => roughNode, ':first-child'); + circle.insert(() => roughInnerNode); + + if (cssStyles) { + circle.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles) { + circle.selectAll('path').attr('style', nodeStyles); } updateNodeBounds(node, circle); @@ -39,4 +59,4 @@ export const stateEnd = (parent: SVG, node: Node) => { }; return shapeSvg; -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/stateStart.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/stateStart.ts index 341b82e1c..07a0f8f92 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/stateStart.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/stateStart.ts @@ -1,13 +1,15 @@ -import { updateNodeBounds } from './util.js'; -import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import type { SVG } from '$root/diagram-api/types.js'; import rough from 'roughjs'; +import type { Node, ShapeRenderOptions } from '../../types.js'; +import intersect from '../intersect/index.js'; import { solidStateFill } from './handDrawnShapeStyles.js'; -import { getConfig } from '$root/diagram-api/diagramAPI.js'; +import { updateNodeBounds } from './util.js'; +import type { D3Selection } from '../../../types.js'; -export const stateStart = (parent: SVG, node: Node) => { - const { themeVariables } = getConfig(); +export function stateStart( + parent: D3Selection, + node: Node, + { config: { themeVariables } }: ShapeRenderOptions +) { const { lineColor } = themeVariables; const shapeSvg = parent @@ -15,20 +17,20 @@ export const stateStart = (parent: SVG, node: Node) => { .attr('class', 'node default') .attr('id', node.domId || node.id); - let circle; + let circle: D3Selection | D3Selection; if (node.look === 'handDrawn') { // @ts-ignore TODO: Fix rough typings const rc = rough.svg(shapeSvg); const roughNode = rc.circle(0, 0, 14, solidStateFill(lineColor)); circle = shapeSvg.insert(() => roughNode); + // center the circle around its coordinate + circle.attr('class', 'state-start').attr('r', 7).attr('width', 14).attr('height', 14); } else { circle = shapeSvg.insert('circle', ':first-child'); + // center the circle around its coordinate + circle.attr('class', 'state-start').attr('r', 7).attr('width', 14).attr('height', 14); } - // center the circle around its coordinate - // @ts-ignore TODO: Fix typings - circle.attr('class', 'state-start').attr('r', 7).attr('width', 14).attr('height', 14); - updateNodeBounds(node, circle); node.intersect = function (point) { @@ -36,4 +38,4 @@ export const stateStart = (parent: SVG, node: Node) => { }; return shapeSvg; -}; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/subroutine.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/subroutine.ts index c4393c25f..ab24af29c 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/subroutine.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/subroutine.ts @@ -1,12 +1,11 @@ import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import rough from 'roughjs'; import { insertPolygonShape } from './insertPolygonShape.js'; +import type { D3Selection } from '../../../types.js'; +import { handleUndefinedAttr } from '../../../utils.js'; export const createSubroutinePathD = ( x: number, @@ -34,7 +33,7 @@ export const createSubroutinePathD = ( ].join(' '); }; -export const subroutine = async (parent: SVGAElement, node: Node) => { +export async function subroutine(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); @@ -58,7 +57,7 @@ export const subroutine = async (parent: SVGAElement, node: Node) => { ]; if (node.look === 'handDrawn') { - // @ts-ignore - rough is not typed + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); const options = userNodeOverrides(node, {}); @@ -70,7 +69,7 @@ export const subroutine = async (parent: SVGAElement, node: Node) => { shapeSvg.insert(() => l2, ':first-child'); const rect = shapeSvg.insert(() => roughNode, ':first-child'); const { cssStyles } = node; - rect.attr('class', 'basic label-container').attr('style', cssStyles); + rect.attr('class', 'basic label-container').attr('style', handleUndefinedAttr(cssStyles)); updateNodeBounds(node, rect); } else { const el = insertPolygonShape(shapeSvg, w, h, points); @@ -85,6 +84,4 @@ export const subroutine = async (parent: SVGAElement, node: Node) => { }; return shapeSvg; -}; - -export default subroutine; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/taggedRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/taggedRect.ts new file mode 100644 index 000000000..3ae068a00 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/taggedRect.ts @@ -0,0 +1,70 @@ +import { labelHelper, getNodeClasses, updateNodeBounds, createPathFromPoints } from './util.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import intersect from '../intersect/index.js'; +import type { D3Selection } from '../../../types.js'; + +export async function taggedRect(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); + const w = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const x = -w / 2; + const y = -h / 2; + const tagWidth = 0.2 * h; + const tagHeight = 0.2 * h; + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + const rectPoints = [ + { x: x - tagWidth / 2, y }, + { x: x + w + tagWidth / 2, y }, + { x: x + w + tagWidth / 2, y: y + h }, + { x: x - tagWidth / 2, y: y + h }, + ]; + + const tagPoints = [ + { x: x + w - tagWidth / 2, y: y + h }, + { x: x + w + tagWidth / 2, y: y + h }, + { x: x + w + tagWidth / 2, y: y + h - tagHeight }, + ]; + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const rectPath = createPathFromPoints(rectPoints); + const rectNode = rc.path(rectPath, options); + + const tagPath = createPathFromPoints(tagPoints); + const tagNode = rc.path(tagPath, { ...options, fillStyle: 'solid' }); + + const taggedRect = shapeSvg.insert(() => tagNode, ':first-child'); + taggedRect.insert(() => rectNode, ':first-child'); + + taggedRect.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + taggedRect.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + taggedRect.selectAll('path').attr('style', nodeStyles); + } + + updateNodeBounds(node, taggedRect); + + node.intersect = function (point) { + const pos = intersect.polygon(node, rectPoints, point); + + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/taggedWaveEdgedRectangle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/taggedWaveEdgedRectangle.ts new file mode 100644 index 000000000..1451bdacc --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/taggedWaveEdgedRectangle.ts @@ -0,0 +1,105 @@ +import { + labelHelper, + updateNodeBounds, + getNodeClasses, + generateFullSineWavePoints, + createPathFromPoints, +} from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import rough from 'roughjs'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import type { D3Selection } from '../../../types.js'; + +export async function taggedWaveEdgedRectangle( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const waveAmplitude = h / 4; + const tagWidth = 0.2 * w; + const tagHeight = 0.2 * h; + const finalH = h + waveAmplitude; + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const points = [ + { x: -w / 2 - (w / 2) * 0.1, y: finalH / 2 }, + ...generateFullSineWavePoints( + -w / 2 - (w / 2) * 0.1, + finalH / 2, + w / 2 + (w / 2) * 0.1, + finalH / 2, + waveAmplitude, + 0.8 + ), + + { x: w / 2 + (w / 2) * 0.1, y: -finalH / 2 }, + { x: -w / 2 - (w / 2) * 0.1, y: -finalH / 2 }, + ]; + + const x = -w / 2 + (w / 2) * 0.1; + const y = -finalH / 2 - tagHeight * 0.4; + + const tagPoints = [ + { x: x + w - tagWidth, y: (y + h) * 1.4 }, + { x: x + w, y: y + h - tagHeight }, + { x: x + w, y: (y + h) * 0.9 }, + ...generateFullSineWavePoints( + x + w, + (y + h) * 1.3, + x + w - tagWidth, + (y + h) * 1.5, + -h * 0.03, + 0.5 + ), + ]; + + const waveEdgeRectPath = createPathFromPoints(points); + const waveEdgeRectNode = rc.path(waveEdgeRectPath, options); + + const taggedWaveEdgeRectPath = createPathFromPoints(tagPoints); + const taggedWaveEdgeRectNode = rc.path(taggedWaveEdgeRectPath, { + ...options, + fillStyle: 'solid', + }); + + const waveEdgeRect = shapeSvg.insert(() => taggedWaveEdgeRectNode, ':first-child'); + waveEdgeRect.insert(() => waveEdgeRectNode, ':first-child'); + + waveEdgeRect.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + waveEdgeRect.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + waveEdgeRect.selectAll('path').attr('style', nodeStyles); + } + + waveEdgeRect.attr('transform', `translate(0,${-waveAmplitude / 2})`); + label.attr( + 'transform', + `translate(${-w / 2 + (node.padding ?? 0) - (bbox.x - (bbox.left ?? 0))},${-h / 2 + (node.padding ?? 0) - waveAmplitude / 2 - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, waveEdgeRect); + node.intersect = function (point) { + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/text.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/text.ts new file mode 100644 index 000000000..cf253fd17 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/text.ts @@ -0,0 +1,37 @@ +import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String } from './handDrawnShapeStyles.js'; +import type { D3Selection } from '../../../types.js'; + +export async function text(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + + const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); + + const totalWidth = Math.max(bbox.width + node.padding, node?.width || 0); + const totalHeight = Math.max(bbox.height + node.padding, node?.height || 0); + const x = -totalWidth / 2; + const y = -totalHeight / 2; + + const rect = shapeSvg.insert('rect', ':first-child'); + + rect + .attr('class', 'text') + .attr('style', nodeStyles) + .attr('rx', 0) + .attr('ry', 0) + .attr('x', x) + .attr('y', y) + .attr('width', totalWidth) + .attr('height', totalHeight); + + updateNodeBounds(node, rect); + + node.intersect = function (point) { + return intersect.rect(node, point); + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/tiltedCylinder.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/tiltedCylinder.ts new file mode 100644 index 000000000..f8a2fb52b --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/tiltedCylinder.ts @@ -0,0 +1,142 @@ +import { labelHelper, getNodeClasses, updateNodeBounds } from './util.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import intersect from '../intersect/index.js'; +import type { D3Selection } from '../../../types.js'; +import { handleUndefinedAttr } from '../../../utils.js'; + +export const createCylinderPathD = ( + x: number, + y: number, + width: number, + height: number, + rx: number, + ry: number +): string => { + return `M${x},${y} + a${rx},${ry} 0,0,1 ${0},${-height} + l${width},${0} + a${rx},${ry} 0,0,1 ${0},${height} + M${width},${-height} + a${rx},${ry} 0,0,0 ${0},${height} + l${-width},${0}`; +}; + +export const createOuterCylinderPathD = ( + x: number, + y: number, + width: number, + height: number, + rx: number, + ry: number +): string => { + return [ + `M${x},${y}`, + `M${x + width},${y}`, + `a${rx},${ry} 0,0,0 ${0},${-height}`, + `l${-width},0`, + `a${rx},${ry} 0,0,0 ${0},${height}`, + `l${width},0`, + ].join(' '); +}; +export const createInnerCylinderPathD = ( + x: number, + y: number, + width: number, + height: number, + rx: number, + ry: number +): string => { + return [`M${x + width / 2},${-height / 2}`, `a${rx},${ry} 0,0,0 0,${height}`].join(' '); +}; + +export async function tiltedCylinder( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label, halfPadding } = await labelHelper( + parent, + node, + getNodeClasses(node) + ); + const labelPadding = node.look === 'neo' ? halfPadding * 2 : halfPadding; + const h = bbox.height + labelPadding; + const ry = h / 2; + const rx = ry / (2.5 + h / 50); + const w = bbox.width + rx + labelPadding; + const { cssStyles } = node; + + let cylinder: D3Selection | D3Selection; + + if (node.look === 'handDrawn') { + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const outerPathData = createOuterCylinderPathD(0, 0, w, h, rx, ry); + const innerPathData = createInnerCylinderPathD(0, 0, w, h, rx, ry); + const outerNode = rc.path(outerPathData, userNodeOverrides(node, {})); + const innerLine = rc.path(innerPathData, userNodeOverrides(node, { fill: 'none' })); + cylinder = shapeSvg.insert(() => innerLine, ':first-child'); + cylinder = shapeSvg.insert(() => outerNode, ':first-child'); + cylinder.attr('class', 'basic label-container'); + if (cssStyles) { + cylinder.attr('style', cssStyles); + } + } else { + const pathData = createCylinderPathD(0, 0, w, h, rx, ry); + cylinder = shapeSvg + .insert('path', ':first-child') + .attr('d', pathData) + .attr('class', 'basic label-container') + .attr('style', handleUndefinedAttr(cssStyles)) + .attr('style', nodeStyles); + cylinder.attr('class', 'basic label-container'); + + if (cssStyles) { + cylinder.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles) { + cylinder.selectAll('path').attr('style', nodeStyles); + } + } + + cylinder.attr('label-offset-x', rx); + cylinder.attr('transform', `translate(${-w / 2}, ${h / 2} )`); + + label.attr( + 'transform', + `translate(${-(bbox.width / 2) - rx - (bbox.x - (bbox.left ?? 0))}, ${-(bbox.height / 2) - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, cylinder); + + node.intersect = function (point) { + const pos = intersect.rect(node, point); + const y = pos.y - (node.y ?? 0); + + if ( + ry != 0 && + (Math.abs(y) < (node.height ?? 0) / 2 || + (Math.abs(y) == (node.height ?? 0) / 2 && + Math.abs(pos.x - (node.x ?? 0)) > (node.width ?? 0) / 2 - rx)) + ) { + let x = rx * rx * (1 - (y * y) / (ry * ry)); + if (x != 0) { + x = Math.sqrt(x); + } + x = rx - x; + if (point.x - (node.x ?? 0) > 0) { + x = -x; + } + + pos.x += x; + } + + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/trapezoid.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/trapezoid.ts index b2013097a..d0228d55b 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/trapezoid.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/trapezoid.ts @@ -1,29 +1,27 @@ -import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; +import { labelHelper, updateNodeBounds, getNodeClasses, createPathFromPoints } from './util.js'; import intersect from '../intersect/index.js'; -import type { Node } from '$root/rendering-util/types.d.ts'; -import { - styles2String, - userNodeOverrides, -} from '$root/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import rough from 'roughjs'; import { insertPolygonShape } from './insertPolygonShape.js'; +import type { D3Selection } from '../../../types.js'; -export const createTrapezoidPathD = ( - x: number, - y: number, - width: number, - height: number -): string => { - return [ - `M${x - (2 * height) / 6},${y}`, - `L${x + width + (2 * height) / 6},${y}`, - `L${x + width - height / 6},${y - height}`, - `L${x + height / 6},${y - height}`, - 'Z', - ].join(' '); -}; +// export const createTrapezoidPathD = ( +// x: number, +// y: number, +// width: number, +// height: number +// ): string => { +// return [ +// `M${x - (2 * height) / 6},${y}`, +// `L${x + width + (2 * height) / 6},${y}`, +// `L${x + width - height / 6},${y - height}`, +// `L${x + height / 6},${y - height}`, +// 'Z', +// ].join(' '); +// }; -export const trapezoid = async (parent: SVGAElement, node: Node): Promise => { +export async function trapezoid(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); @@ -31,20 +29,20 @@ export const trapezoid = async (parent: SVGAElement, node: Node): Promise; + let polygon: typeof shapeSvg | ReturnType; const { cssStyles } = node; if (node.look === 'handDrawn') { - // @ts-ignore - rough is not typed + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); const options = userNodeOverrides(node, {}); - const pathData = createTrapezoidPathD(0, 0, w, h); + const pathData = createPathFromPoints(points); const roughNode = rc.path(pathData, options); polygon = shapeSvg @@ -72,4 +70,4 @@ export const trapezoid = async (parent: SVGAElement, node: Node): Promise( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); + const minWidth = 60, + minHeight = 20; + const w = Math.max(minWidth, bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(minHeight, bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + + const { cssStyles } = node; + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const points = [ + { x: (-w / 2) * 0.8, y: -h / 2 }, + { x: (w / 2) * 0.8, y: -h / 2 }, + { x: w / 2, y: (-h / 2) * 0.6 }, + { x: w / 2, y: h / 2 }, + { x: -w / 2, y: h / 2 }, + { x: -w / 2, y: (-h / 2) * 0.6 }, + ]; + + const pathData = createPathFromPoints(points); + const shapeNode = rc.path(pathData, options); + + const polygon = shapeSvg.insert(() => shapeNode, ':first-child'); + polygon.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', nodeStyles); + } + + updateNodeBounds(node, polygon); + + node.intersect = function (point) { + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/triangle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/triangle.ts new file mode 100644 index 000000000..d4bd3c347 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/triangle.ts @@ -0,0 +1,68 @@ +import { log } from '../../../logger.js'; +import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import { createPathFromPoints } from './util.js'; +import { evaluate } from '../../../diagrams/common/common.js'; +import { getConfig } from '../../../diagram-api/diagramAPI.js'; +import type { D3Selection } from '../../../types.js'; + +export async function triangle(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const useHtmlLabels = evaluate(getConfig().flowchart?.htmlLabels); + + const w = bbox.width + (node.padding ?? 0); + const h = w + bbox.height; + + const tw = w + bbox.height; + const points = [ + { x: 0, y: 0 }, + { x: tw, y: 0 }, + { x: tw / 2, y: -h }, + ]; + + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + const pathData = createPathFromPoints(points); + const roughNode = rc.path(pathData, options); + + const polygon = shapeSvg + .insert(() => roughNode, ':first-child') + .attr('transform', `translate(${-h / 2}, ${h / 2})`); + + if (cssStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + polygon.selectChildren('path').attr('style', nodeStyles); + } + + node.width = w; + node.height = h; + + updateNodeBounds(node, polygon); + + label.attr( + 'transform', + `translate(${-bbox.width / 2 - (bbox.x - (bbox.left ?? 0))}, ${h / 2 - (bbox.height + (node.padding ?? 0) / (useHtmlLabels ? 2 : 1) - (bbox.y - (bbox.top ?? 0)))})` + ); + + node.intersect = function (point) { + log.info('Triangle intersect', node, points, point); + return intersect.polygon(node, points, point); + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/util.js b/packages/mermaid/src/rendering-util/rendering-elements/shapes/util.js deleted file mode 100644 index ca1290668..000000000 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/util.js +++ /dev/null @@ -1,136 +0,0 @@ -import { createText } from '$root/rendering-util/createText.ts'; -import { getConfig } from '$root/diagram-api/diagramAPI.js'; -import { select } from 'd3'; -import { evaluate, sanitizeText } from '$root/diagrams/common/common.js'; -import { decodeEntities } from '$root/utils.js'; - -export const labelHelper = async (parent, node, _classes) => { - let cssClasses; - const useHtmlLabels = node.useHtmlLabels || evaluate(getConfig().flowchart.htmlLabels); - if (!_classes) { - cssClasses = 'node default'; - } else { - cssClasses = _classes; - } - - // Add outer g element - const shapeSvg = parent - .insert('g') - .attr('class', cssClasses) - .attr('id', node.domId || node.id); - - // Create the label and insert it after the rect - const labelEl = shapeSvg.insert('g').attr('class', 'label').attr('style', node.labelStyle); - - // Replace label with default value if undefined - let label; - if (node.label === undefined) { - label = ''; - } else { - label = typeof node.label === 'string' ? node.label : node.label[0]; - } - - let text; - text = await createText(labelEl, sanitizeText(decodeEntities(label), getConfig()), { - useHtmlLabels, - width: node.width || getConfig().flowchart.wrappingWidth, - cssClasses: 'markdown-node-label', - style: node.labelStyle, - }); - // Get the size of the label - let bbox = text.getBBox(); - const halfPadding = node.padding / 2; - - if (evaluate(getConfig().flowchart.htmlLabels)) { - const div = text.children[0]; - const dv = select(text); - - // if there are images, need to wait for them to load before getting the bounding box - const images = div.getElementsByTagName('img'); - if (images) { - const noImgText = label.replace(/]*>/g, '').trim() === ''; - - await Promise.all( - [...images].map( - (img) => - new Promise((res) => { - /** - * - */ - function setupImage() { - img.style.display = 'flex'; - img.style.flexDirection = 'column'; - - if (noImgText) { - // default size if no text - const bodyFontSize = getConfig().fontSize - ? getConfig().fontSize - : window.getComputedStyle(document.body).fontSize; - const enlargingFactor = 5; - const width = parseInt(bodyFontSize, 10) * enlargingFactor + 'px'; - img.style.minWidth = width; - img.style.maxWidth = width; - } else { - img.style.width = '100%'; - } - res(img); - } - setTimeout(() => { - if (img.complete) { - setupImage(); - } - }); - img.addEventListener('error', setupImage); - img.addEventListener('load', setupImage); - }) - ) - ); - } - - bbox = div.getBoundingClientRect(); - dv.attr('width', bbox.width); - dv.attr('height', bbox.height); - } - - // Center the label - if (useHtmlLabels) { - labelEl.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')'); - } else { - labelEl.attr('transform', 'translate(' + 0 + ', ' + -bbox.height / 2 + ')'); - } - if (node.centerLabel) { - labelEl.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')'); - } - labelEl.insert('rect', ':first-child'); - return { shapeSvg, bbox, halfPadding, label: labelEl }; -}; - -export const updateNodeBounds = (node, element) => { - const bbox = element.node().getBBox(); - node.width = bbox.width; - node.height = bbox.height; -}; - -/** - * @param parent - * @param w - * @param h - * @param points - */ -export function insertPolygonShape(parent, w, h, points) { - return parent - .insert('polygon', ':first-child') - .attr( - 'points', - points - .map(function (d) { - return d.x + ',' + d.y; - }) - .join(' ') - ) - .attr('class', 'label-container') - .attr('transform', 'translate(' + -w / 2 + ',' + h / 2 + ')'); -} - -export const getNodeClasses = (node, extra) => - (node.look === 'handDrawn' ? 'rough-node' : 'node') + ' ' + node.cssClasses + ' ' + (extra || ''); diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/util.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/util.ts new file mode 100644 index 000000000..52471ecc0 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/util.ts @@ -0,0 +1,282 @@ +import { createText } from '../../createText.js'; +import type { Node } from '../../types.js'; +import { getConfig } from '../../../diagram-api/diagramAPI.js'; +import { select } from 'd3'; +import defaultConfig from '../../../defaultConfig.js'; +import { evaluate, sanitizeText } from '../../../diagrams/common/common.js'; +import { decodeEntities, handleUndefinedAttr, parseFontSize } from '../../../utils.js'; +import type { D3Selection, Point } from '../../../types.js'; + +export const labelHelper = async ( + parent: D3Selection, + node: Node, + _classes?: string +) => { + let cssClasses; + const useHtmlLabels = node.useHtmlLabels || evaluate(getConfig()?.htmlLabels); + if (!_classes) { + cssClasses = 'node default'; + } else { + cssClasses = _classes; + } + + // Add outer g element + const shapeSvg = parent + .insert('g') + .attr('class', cssClasses) + .attr('id', node.domId || node.id); + + // Create the label and insert it after the rect + const labelEl = shapeSvg + .insert('g') + .attr('class', 'label') + .attr('style', handleUndefinedAttr(node.labelStyle)); + + // Replace label with default value if undefined + let label; + if (node.label === undefined) { + label = ''; + } else { + label = typeof node.label === 'string' ? node.label : node.label[0]; + } + + const text = await createText(labelEl, sanitizeText(decodeEntities(label), getConfig()), { + useHtmlLabels, + width: node.width || getConfig().flowchart?.wrappingWidth, + // @ts-expect-error -- This is currently not used. Should this be `classes` instead? + cssClasses: 'markdown-node-label', + style: node.labelStyle, + addSvgBackground: !!node.icon || !!node.img, + }); + // Get the size of the label + let bbox = text.getBBox(); + const halfPadding = (node?.padding ?? 0) / 2; + + if (useHtmlLabels) { + const div = text.children[0]; + const dv = select(text); + + // if there are images, need to wait for them to load before getting the bounding box + const images = div.getElementsByTagName('img'); + if (images) { + const noImgText = label.replace(/]*>/g, '').trim() === ''; + + await Promise.all( + [...images].map( + (img) => + new Promise((res) => { + /** + * + */ + function setupImage() { + img.style.display = 'flex'; + img.style.flexDirection = 'column'; + + if (noImgText) { + // default size if no text + const bodyFontSize = getConfig().fontSize + ? getConfig().fontSize + : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + const [parsedBodyFontSize = defaultConfig.fontSize] = parseFontSize(bodyFontSize); + const width = parsedBodyFontSize * enlargingFactor + 'px'; + img.style.minWidth = width; + img.style.maxWidth = width; + } else { + img.style.width = '100%'; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener('error', setupImage); + img.addEventListener('load', setupImage); + }) + ) + ); + } + + bbox = div.getBoundingClientRect(); + dv.attr('width', bbox.width); + dv.attr('height', bbox.height); + } + + // Center the label + if (useHtmlLabels) { + labelEl.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')'); + } else { + labelEl.attr('transform', 'translate(' + 0 + ', ' + -bbox.height / 2 + ')'); + } + if (node.centerLabel) { + labelEl.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')'); + } + labelEl.insert('rect', ':first-child'); + return { shapeSvg, bbox, halfPadding, label: labelEl }; +}; +export const insertLabel = async ( + parent: D3Selection, + label: string, + options: { + labelStyle?: string | undefined; + icon?: boolean | undefined; + img?: string | undefined; + useHtmlLabels?: boolean | undefined; + padding: number; + width?: number | undefined; + centerLabel?: boolean | undefined; + addSvgBackground?: boolean | undefined; + } +) => { + const useHtmlLabels = options.useHtmlLabels || evaluate(getConfig()?.flowchart?.htmlLabels); + + // Create the label and insert it after the rect + const labelEl = parent + .insert('g') + .attr('class', 'label') + .attr('style', options.labelStyle || ''); + + const text = await createText(labelEl, sanitizeText(decodeEntities(label), getConfig()), { + useHtmlLabels, + width: options.width || getConfig()?.flowchart?.wrappingWidth, + style: options.labelStyle, + addSvgBackground: !!options.icon || !!options.img, + }); + // Get the size of the label + let bbox = text.getBBox(); + const halfPadding = options.padding / 2; + + if (evaluate(getConfig()?.flowchart?.htmlLabels)) { + const div = text.children[0]; + const dv = select(text); + + bbox = div.getBoundingClientRect(); + dv.attr('width', bbox.width); + dv.attr('height', bbox.height); + } + + // Center the label + if (useHtmlLabels) { + labelEl.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')'); + } else { + labelEl.attr('transform', 'translate(' + 0 + ', ' + -bbox.height / 2 + ')'); + } + if (options.centerLabel) { + labelEl.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')'); + } + labelEl.insert('rect', ':first-child'); + return { shapeSvg: parent, bbox, halfPadding, label: labelEl }; +}; +export const updateNodeBounds = ( + node: Node, + // D3Selection is for the roughjs case, D3Selection is for the non-roughjs case + element: D3Selection | D3Selection +) => { + const bbox = element.node()!.getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; + +/** + * @param parent - Parent element to append the polygon to + * @param w - Width of the polygon + * @param h - Height of the polygon + * @param points - Array of points to create the polygon + */ +export function insertPolygonShape( + parent: D3Selection, + w: number, + h: number, + points: Point[] +) { + return parent + .insert('polygon', ':first-child') + .attr( + 'points', + points + .map(function (d) { + return d.x + ',' + d.y; + }) + .join(' ') + ) + .attr('class', 'label-container') + .attr('transform', 'translate(' + -w / 2 + ',' + h / 2 + ')'); +} + +export const getNodeClasses = (node: Node, extra?: string) => + (node.look === 'handDrawn' ? 'rough-node' : 'node') + ' ' + node.cssClasses + ' ' + (extra || ''); + +export function createPathFromPoints(points: Point[]) { + const pointStrings = points.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x},${p.y}`); + pointStrings.push('Z'); + return pointStrings.join(' '); +} + +export function generateFullSineWavePoints( + x1: number, + y1: number, + x2: number, + y2: number, + amplitude: number, + numCycles: number +) { + const points = []; + const steps = 50; // Number of segments to create a smooth curve + const deltaX = x2 - x1; + const deltaY = y2 - y1; + const cycleLength = deltaX / numCycles; + + // Calculate frequency and phase shift + const frequency = (2 * Math.PI) / cycleLength; + const midY = y1 + deltaY / 2; + + for (let i = 0; i <= steps; i++) { + const t = i / steps; + const x = x1 + t * deltaX; + const y = midY + amplitude * Math.sin(frequency * (x - x1)); + + points.push({ x, y }); + } + + return points; +} + +/** + * @param centerX - x-coordinate of center of circle + * @param centerY - y-coordinate of center of circle + * @param radius - radius of circle + * @param numPoints - total points required + * @param startAngle - angle where arc will start + * @param endAngle - angle where arc will end + */ +export function generateCirclePoints( + centerX: number, + centerY: number, + radius: number, + numPoints: number, + startAngle: number, + endAngle: number +) { + const points = []; + + // Convert angles to radians + const startAngleRad = (startAngle * Math.PI) / 180; + const endAngleRad = (endAngle * Math.PI) / 180; + + // Calculate the angle range in radians + const angleRange = endAngleRad - startAngleRad; + + // Calculate the angle step + const angleStep = angleRange / (numPoints - 1); + + for (let i = 0; i < numPoints; i++) { + const angle = startAngleRad + i * angleStep; + const x = centerX + radius * Math.cos(angle); + const y = centerY + radius * Math.sin(angle); + points.push({ x: -x, y: -y }); + } + + return points; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/waveEdgedRectangle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/waveEdgedRectangle.ts new file mode 100644 index 000000000..d2c1a525d --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/waveEdgedRectangle.ts @@ -0,0 +1,83 @@ +import { + labelHelper, + updateNodeBounds, + getNodeClasses, + generateFullSineWavePoints, + createPathFromPoints, +} from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import rough from 'roughjs'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import type { D3Selection } from '../../../types.js'; + +export async function waveEdgedRectangle( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const waveAmplitude = h / 8; + const finalH = h + waveAmplitude; + const { cssStyles } = node; + + // To maintain minimum width + const minWidth = 70; + const widthDif = minWidth - w; + const extraW = widthDif > 0 ? widthDif / 2 : 0; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const points = [ + { x: -w / 2 - extraW, y: finalH / 2 }, + ...generateFullSineWavePoints( + -w / 2 - extraW, + finalH / 2, + w / 2 + extraW, + finalH / 2, + waveAmplitude, + 0.8 + ), + { x: w / 2 + extraW, y: -finalH / 2 }, + { x: -w / 2 - extraW, y: -finalH / 2 }, + ]; + + const waveEdgeRectPath = createPathFromPoints(points); + const waveEdgeRectNode = rc.path(waveEdgeRectPath, options); + + const waveEdgeRect = shapeSvg.insert(() => waveEdgeRectNode, ':first-child'); + + waveEdgeRect.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + waveEdgeRect.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + waveEdgeRect.selectAll('path').attr('style', nodeStyles); + } + + waveEdgeRect.attr('transform', `translate(0,${-waveAmplitude / 2})`); + label.attr( + 'transform', + `translate(${-w / 2 + (node.padding ?? 0) - (bbox.x - (bbox.left ?? 0))},${-h / 2 + (node.padding ?? 0) - waveAmplitude - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, waveEdgeRect); + node.intersect = function (point) { + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/waveRectangle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/waveRectangle.ts new file mode 100644 index 000000000..4ee6dba47 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/waveRectangle.ts @@ -0,0 +1,84 @@ +import { + labelHelper, + updateNodeBounds, + getNodeClasses, + createPathFromPoints, + generateFullSineWavePoints, +} from './util.js'; +import intersect from '../intersect/index.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import type { D3Selection } from '../../../types.js'; + +export async function waveRectangle( + parent: D3Selection, + node: Node +) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node)); + + const minWidth = 100; // Minimum width + const minHeight = 50; // Minimum height + + const baseWidth = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const baseHeight = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + + const aspectRatio = baseWidth / baseHeight; + + let w = baseWidth; + let h = baseHeight; + + if (w > h * aspectRatio) { + h = w / aspectRatio; + } else { + w = h * aspectRatio; + } + + w = Math.max(w, minWidth); + h = Math.max(h, minHeight); + + const waveAmplitude = Math.min(h * 0.2, h / 4); + const finalH = h + waveAmplitude * 2; + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const points = [ + { x: -w / 2, y: finalH / 2 }, + ...generateFullSineWavePoints(-w / 2, finalH / 2, w / 2, finalH / 2, waveAmplitude, 1), + { x: w / 2, y: -finalH / 2 }, + ...generateFullSineWavePoints(w / 2, -finalH / 2, -w / 2, -finalH / 2, waveAmplitude, -1), + ]; + + const waveRectPath = createPathFromPoints(points); + const waveRectNode = rc.path(waveRectPath, options); + + const waveRect = shapeSvg.insert(() => waveRectNode, ':first-child'); + + waveRect.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + waveRect.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + waveRect.selectAll('path').attr('style', nodeStyles); + } + + updateNodeBounds(node, waveRect); + node.intersect = function (point) { + const pos = intersect.polygon(node, points, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/windowPane.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/windowPane.ts new file mode 100644 index 000000000..e67c92a06 --- /dev/null +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/windowPane.ts @@ -0,0 +1,67 @@ +import { labelHelper, getNodeClasses, updateNodeBounds } from './util.js'; +import type { Node } from '../../types.js'; +import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; +import rough from 'roughjs'; +import intersect from '../intersect/index.js'; +import type { D3Selection } from '../../../types.js'; + +export async function windowPane(parent: D3Selection, node: Node) { + const { labelStyles, nodeStyles } = styles2String(node); + node.labelStyle = labelStyles; + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + const w = Math.max(bbox.width + (node.padding ?? 0) * 2, node?.width ?? 0); + const h = Math.max(bbox.height + (node.padding ?? 0) * 2, node?.height ?? 0); + const rectOffset = 5; + const x = -w / 2; + const y = -h / 2; + const { cssStyles } = node; + + // @ts-expect-error -- Passing a D3.Selection seems to work for some reason + const rc = rough.svg(shapeSvg); + const options = userNodeOverrides(node, {}); + + const outerPathPoints = [ + { x: x - rectOffset, y: y - rectOffset }, + { x: x - rectOffset, y: y + h }, + { x: x + w, y: y + h }, + { x: x + w, y: y - rectOffset }, + ]; + + const path = `M${x - rectOffset},${y - rectOffset} L${x + w},${y - rectOffset} L${x + w},${y + h} L${x - rectOffset},${y + h} L${x - rectOffset},${y - rectOffset} + M${x - rectOffset},${y} L${x + w},${y} + M${x},${y - rectOffset} L${x},${y + h}`; + + if (node.look !== 'handDrawn') { + options.roughness = 0; + options.fillStyle = 'solid'; + } + + const no = rc.path(path, options); + + const windowPane = shapeSvg.insert(() => no, ':first-child'); + windowPane.attr('transform', `translate(${rectOffset / 2}, ${rectOffset / 2})`); + + windowPane.attr('class', 'basic label-container'); + + if (cssStyles && node.look !== 'handDrawn') { + windowPane.selectAll('path').attr('style', cssStyles); + } + + if (nodeStyles && node.look !== 'handDrawn') { + windowPane.selectAll('path').attr('style', nodeStyles); + } + + label.attr( + 'transform', + `translate(${-(bbox.width / 2) + rectOffset / 2 - (bbox.x - (bbox.left ?? 0))}, ${-(bbox.height / 2) + rectOffset / 2 - (bbox.y - (bbox.top ?? 0))})` + ); + + updateNodeBounds(node, windowPane); + + node.intersect = function (point) { + const pos = intersect.polygon(node, outerPathPoints, point); + return pos; + }; + + return shapeSvg; +} diff --git a/packages/mermaid/src/rendering-util/setupViewPortForSVG.ts b/packages/mermaid/src/rendering-util/setupViewPortForSVG.ts index e21f3304b..d3df5ddb7 100644 --- a/packages/mermaid/src/rendering-util/setupViewPortForSVG.ts +++ b/packages/mermaid/src/rendering-util/setupViewPortForSVG.ts @@ -1,6 +1,6 @@ -import { configureSvgSize } from '$root/setupGraphViewbox.js'; -import type { SVG } from '$root/diagram-api/types.js'; -import { log } from '$root/logger.js'; +import { configureSvgSize } from '../setupGraphViewbox.js'; +import type { SVG } from '../diagram-api/types.js'; +import { log } from '../logger.js'; export const setupViewPortForSVG = ( svg: SVG, diff --git a/packages/mermaid/src/rendering-util/types.d.ts b/packages/mermaid/src/rendering-util/types.ts similarity index 76% rename from packages/mermaid/src/rendering-util/types.d.ts rename to packages/mermaid/src/rendering-util/types.ts index 67f8de40e..86cfd50b3 100644 --- a/packages/mermaid/src/rendering-util/types.d.ts +++ b/packages/mermaid/src/rendering-util/types.ts @@ -1,5 +1,7 @@ export type MarkdownWordType = 'normal' | 'strong' | 'em'; -import type { MermaidConfig } from '../../dist/config.type'; +import type { MermaidConfig } from '../config.type.js'; +import type { ClusterShapeID } from './rendering-elements/clusters.js'; +import type { ShapeID } from './rendering-elements/shapes.js'; export interface MarkdownWord { content: string; type: MarkdownWordType; @@ -8,8 +10,7 @@ export type MarkdownLine = MarkdownWord[]; /** Returns `true` if the line fits a constraint (e.g. it's under 𝑛 chars) */ export type CheckFitFunction = (text: MarkdownLine) => boolean; -// Common properties for any node in the system -interface Node { +interface BaseNode { id: string; label?: string; description?: string[]; @@ -37,8 +38,6 @@ interface Node { linkTarget?: string; tooltip?: string; padding?: number; //REMOVE?, use from LayoutData.config - Keep, this could be shape specific - shape?: string; - tooltip?: string; isGroup: boolean; width?: number; height?: number; @@ -65,10 +64,34 @@ interface Node { y?: number; look?: string; + icon?: string; + pos?: 't' | 'b'; + img?: string; + assetWidth?: number; + assetHeight?: number; + defaultWidth?: number; + imageAspectRatio?: number; + constraint?: 'on' | 'off'; } +/** + * Group/cluster nodes, e.g. nodes that contain other nodes. + */ +export interface ClusterNode extends BaseNode { + shape?: ClusterShapeID; + isGroup: true; +} + +export interface NonClusterNode extends BaseNode { + shape?: ShapeID; + isGroup: false; +} + +// Common properties for any node in the system +export type Node = ClusterNode | NonClusterNode; + // Common properties for any edge in the system -interface Edge { +export interface Edge { id: string; label?: string; classes?: string; @@ -88,6 +111,9 @@ interface Edge { stroke?: string; text?: string; type: string; + // Class Diagram specific properties + startLabelRight?: string; + endLabelLeft?: string; // Rendering specific properties curve?: string; labelpos?: string; @@ -98,7 +124,7 @@ interface Edge { look?: string; } -interface RectOptions { +export interface RectOptions { rx: number; ry: number; labelPaddingX: number; @@ -107,9 +133,9 @@ interface RectOptions { } // Extending the Node interface for specific types if needed -interface ClassDiagramNode extends Node { +export type ClassDiagramNode = Node & { memberData: any; // Specific property for class diagram nodes -} +}; // Specific interfaces for layout and render data export interface LayoutData { @@ -136,3 +162,18 @@ export type LayoutMethod = | 'fdp' | 'osage' | 'grid'; + +export interface ShapeRenderOptions { + config: MermaidConfig; + /** Some shapes render differently if a diagram has a direction `LR` */ + dir?: Node['dir']; +} + +export type KanbanNode = Node & { + // Kanban specif data + priority?: 'Very High' | 'High' | 'Medium' | 'Low' | 'Very Low'; + ticket?: string; + assigned?: string; + icon?: string; + level: number; +}; diff --git a/packages/mermaid/src/schemas/config.schema.yaml b/packages/mermaid/src/schemas/config.schema.yaml index a7b3549eb..e1014e889 100644 --- a/packages/mermaid/src/schemas/config.schema.yaml +++ b/packages/mermaid/src/schemas/config.schema.yaml @@ -48,6 +48,7 @@ required: - requirement - architecture - mindmap + - kanban - gitGraph - c4 - sankey @@ -279,6 +280,8 @@ properties: $ref: '#/$defs/ArchitectureDiagramConfig' mindmap: $ref: '#/$defs/MindmapDiagramConfig' + kanban: + $ref: '#/$defs/KanbanDiagramConfig' gitGraph: $ref: '#/$defs/GitGraphDiagramConfig' c4: @@ -964,6 +967,23 @@ $defs: # JSON Schema definition (maybe we should move these to a separate file) type: number default: 200 + KanbanDiagramConfig: + title: Kanban Diagram Config + allOf: [{ $ref: '#/$defs/BaseDiagramConfig' }] + description: The object containing configurations specific for kanban diagrams + type: object + unevaluatedProperties: false + properties: + padding: + type: number + default: 8 + sectionWidth: + type: number + default: 200 + ticketBaseUrl: + type: string + default: '' + PieDiagramConfig: title: Pie Diagram Config allOf: [{ $ref: '#/$defs/BaseDiagramConfig' }] @@ -1428,6 +1448,9 @@ $defs: # JSON Schema definition (maybe we should move these to a separate file) htmlLabels: type: boolean default: false + hideEmptyMembersBox: + type: boolean + default: false JourneyDiagramConfig: title: Journey Diagram Config diff --git a/packages/mermaid/src/types.ts b/packages/mermaid/src/types.ts index 9f4d77225..5587ca3f4 100644 --- a/packages/mermaid/src/types.ts +++ b/packages/mermaid/src/types.ts @@ -1,3 +1,19 @@ +export interface NodeMetaData { + shape?: string; + label?: string; + icon?: string; + form?: string; + pos?: 't' | 'b'; + img?: string; + w?: string; + h?: string; + constraint?: 'on' | 'off'; + priority: 'Very High' | 'High' | 'Medium' | 'Low' | 'Very Low'; + assigned?: string; + ticket?: string; +} +import type { MermaidConfig } from './config.type.js'; + export interface Point { x: number; y: number; @@ -48,10 +64,19 @@ export interface ParseResult { * The diagram type, e.g. 'flowchart', 'sequence', etc. */ diagramType: string; + /** + * The config passed as YAML frontmatter or directives + */ + config: MermaidConfig; } // This makes it clear that we're working with a d3 selected element of some kind, even though it's hard to specify the exact type. export type D3Element = any; +/** + * Helper type for d3 selections. + */ +export type D3Selection = d3.Selection; + export interface RenderResult { /** * The svg code for the rendered graph. @@ -72,3 +97,10 @@ export interface RenderResult { */ bindFunctions?: (element: Element) => void; } + +/** + * Can be converted back to `T` by awaiting/`Awaited`. + * + * This is useful for function types that may be either synchronous or asynchronous. + */ +export type MaybePromise = T | Promise; diff --git a/packages/mermaid/src/utils.ts b/packages/mermaid/src/utils.ts index 631b6dd85..c1d674834 100644 --- a/packages/mermaid/src/utils.ts +++ b/packages/mermaid/src/utils.ts @@ -1,5 +1,5 @@ import { sanitizeUrl } from '@braintree/sanitize-url'; -import type { CurveFactory } from 'd3'; +import type { BaseType, CurveFactory } from 'd3'; import { curveBasis, curveBasisClosed, @@ -824,6 +824,7 @@ export const insertTitle = ( parent .append('text') .text(title) + .attr('text-anchor', 'middle') .attr('x', bounds.x + bounds.width / 2) .attr('y', -titleTopMargin) .attr('class', cssClass); @@ -940,3 +941,15 @@ export const getEdgeId = ( ) => { return `${prefix ? `${prefix}_` : ''}${from}_${to}_${counter}${suffix ? `_${suffix}` : ''}`; }; + +/** + * D3's `selection.attr` method doesn't officially support `undefined`. + * + * However, it seems if you do pass `undefined`, it seems to be treated as `null` + * (e.g. it removes the attribute). + */ +export function handleUndefinedAttr( + attrValue: Parameters['attr']>[1] | undefined +) { + return attrValue ?? null; +} diff --git a/packages/mermaid/src/utils/lineWithOffset.ts b/packages/mermaid/src/utils/lineWithOffset.ts index 8e7c54424..800a5ffaf 100644 --- a/packages/mermaid/src/utils/lineWithOffset.ts +++ b/packages/mermaid/src/utils/lineWithOffset.ts @@ -52,18 +52,15 @@ export const getLineFunctionsWithOffset = ( data: (Point | [number, number])[] ) { let offset = 0; + const DIRECTION = + pointTransformer(data[0]).x < pointTransformer(data[data.length - 1]).x ? 'left' : 'right'; if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { - // Handle first point - // Calculate the angle and delta between the first two points const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); - // Calculate the offset based on the angle and the marker's dimensions offset = markerOffsets[edge.arrowTypeStart as keyof typeof markerOffsets] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { - // Handle last point - // Calculate the angle and delta between the last two points const { angle, deltaX } = calculateDeltaAndAngle( data[data.length - 1], data[data.length - 2] @@ -73,6 +70,41 @@ export const getLineFunctionsWithOffset = ( Math.cos(angle) * (deltaX >= 0 ? 1 : -1); } + + const differenceToEnd = Math.abs( + pointTransformer(d).x - pointTransformer(data[data.length - 1]).x + ); + const differenceInYEnd = Math.abs( + pointTransformer(d).y - pointTransformer(data[data.length - 1]).y + ); + const differenceToStart = Math.abs(pointTransformer(d).x - pointTransformer(data[0]).x); + const differenceInYStart = Math.abs(pointTransformer(d).y - pointTransformer(data[0]).y); + const startMarkerHeight = markerOffsets[edge.arrowTypeStart as keyof typeof markerOffsets]; + const endMarkerHeight = markerOffsets[edge.arrowTypeEnd as keyof typeof markerOffsets]; + const extraRoom = 1; + + // Adjust the offset if the difference is smaller than the marker height + if ( + differenceToEnd < endMarkerHeight && + differenceToEnd > 0 && + differenceInYEnd < endMarkerHeight + ) { + let adjustment = endMarkerHeight + extraRoom - differenceToEnd; + adjustment *= DIRECTION === 'right' ? -1 : 1; + // Adjust the offset by the amount needed to fit the marker + offset -= adjustment; + } + + if ( + differenceToStart < startMarkerHeight && + differenceToStart > 0 && + differenceInYStart < startMarkerHeight + ) { + let adjustment = startMarkerHeight + extraRoom - differenceToStart; + adjustment *= DIRECTION === 'right' ? -1 : 1; + offset += adjustment; + } + return pointTransformer(d).x + offset; }, y: function ( @@ -81,8 +113,9 @@ export const getLineFunctionsWithOffset = ( i: number, data: (Point | [number, number])[] ) { - // Same handling as X above let offset = 0; + const DIRECTION = + pointTransformer(data[0]).y < pointTransformer(data[data.length - 1]).y ? 'down' : 'up'; if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); offset = @@ -99,6 +132,40 @@ export const getLineFunctionsWithOffset = ( Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); } + + const differenceToEnd = Math.abs( + pointTransformer(d).y - pointTransformer(data[data.length - 1]).y + ); + const differenceInXEnd = Math.abs( + pointTransformer(d).x - pointTransformer(data[data.length - 1]).x + ); + const differenceToStart = Math.abs(pointTransformer(d).y - pointTransformer(data[0]).y); + const differenceInXStart = Math.abs(pointTransformer(d).x - pointTransformer(data[0]).x); + const startMarkerHeight = markerOffsets[edge.arrowTypeStart as keyof typeof markerOffsets]; + const endMarkerHeight = markerOffsets[edge.arrowTypeEnd as keyof typeof markerOffsets]; + const extraRoom = 1; + + // Adjust the offset if the difference is smaller than the marker height + if ( + differenceToEnd < endMarkerHeight && + differenceToEnd > 0 && + differenceInXEnd < endMarkerHeight + ) { + let adjustment = endMarkerHeight + extraRoom - differenceToEnd; + adjustment *= DIRECTION === 'up' ? -1 : 1; + // Adjust the offset by the amount needed to fit the marker + offset -= adjustment; + } + + if ( + differenceToStart < startMarkerHeight && + differenceToStart > 0 && + differenceInXStart < startMarkerHeight + ) { + let adjustment = startMarkerHeight + extraRoom - differenceToStart; + adjustment *= DIRECTION === 'up' ? -1 : 1; + offset += adjustment; + } return pointTransformer(d).y + offset; }, }; diff --git a/packages/mermaid/tsconfig.json b/packages/mermaid/tsconfig.json index 0f06a1731..447a5bb0d 100644 --- a/packages/mermaid/tsconfig.json +++ b/packages/mermaid/tsconfig.json @@ -3,16 +3,13 @@ "compilerOptions": { "rootDir": "./src", "outDir": "./dist", - "types": ["vitest/importMeta", "vitest/globals"], - "baseUrl": ".", // This must be set if "paths" is set - "paths": { - "$root/*": ["src/*"] - } + "types": ["vitest/importMeta", "vitest/globals"] }, "include": [ "./src/**/*.ts", "./package.json", "src/diagrams/gantt/ganttDb.js", - "src/diagrams/git/gitGraphRenderer.js" + "src/diagrams/git/gitGraphRenderer.js", + "src/diagrams/class/classRenderer.js" ] } diff --git a/packages/parser/tsconfig.json b/packages/parser/tsconfig.json index 7e830e229..4822488c9 100644 --- a/packages/parser/tsconfig.json +++ b/packages/parser/tsconfig.json @@ -4,7 +4,6 @@ "rootDir": ".", "outDir": "./dist", "allowJs": false, - "preserveSymlinks": false, "strictPropertyInitialization": false }, "include": ["./src/**/*.ts", "./tests/**/*.ts"], diff --git a/patches/roughjs.patch b/patches/roughjs.patch new file mode 100644 index 000000000..7a17084fe --- /dev/null +++ b/patches/roughjs.patch @@ -0,0 +1,10 @@ +diff --git a/bin/rough.d.ts b/bin/rough.d.ts +index 810db1fb34496a5b9f7c0734a7ad8be8605f5534..3624d5b6288a3d2b7d397dfcfffce60558f18cf9 100644 +--- a/bin/rough.d.ts ++++ b/bin/rough.d.ts +@@ -8,4 +8,4 @@ declare const _default: { + generator(config?: Config): RoughGenerator; + newSeed(): number; + }; +-export default _default; ++export = _default; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7fcdbb5f3..0a9bc7d75 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,34 +4,39 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +patchedDependencies: + roughjs: + hash: vxb6t6fqvzyhwhtjiliqr25jyq + path: patches/roughjs.patch + importers: .: devDependencies: '@applitools/eyes-cypress': specifier: ^3.44.4 - version: 3.44.7(encoding@0.1.13)(typescript@5.4.5) + version: 3.44.9(encoding@0.1.13)(typescript@5.4.5) '@argos-ci/cypress': - specifier: ^2.1.0 - version: 2.1.2(cypress@13.14.1) + specifier: ^2.2.2 + version: 2.2.2(cypress@13.15.0) '@changesets/changelog-github': specifier: ^0.5.0 version: 0.5.0(encoding@0.1.13) '@changesets/cli': specifier: ^2.27.7 - version: 2.27.7 + version: 2.27.9 '@cspell/eslint-plugin': specifier: ^8.8.4 - version: 8.13.3(eslint@9.8.0) + version: 8.14.4(eslint@9.12.0(jiti@1.21.6)) '@cypress/code-coverage': specifier: ^3.12.30 - version: 3.12.45(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(babel-loader@9.1.3(@babel/core@7.25.2)(webpack@5.93.0(esbuild@0.21.5)))(cypress@13.14.1)(webpack@5.93.0(esbuild@0.21.5)) + version: 3.13.4(@babel/core@7.25.7)(@babel/preset-env@7.25.7(@babel/core@7.25.7))(babel-loader@9.2.1(@babel/core@7.25.7)(webpack@5.95.0(esbuild@0.21.5)))(cypress@13.15.0)(webpack@5.95.0(esbuild@0.21.5)) '@eslint/js': specifier: ^9.4.0 - version: 9.8.0 + version: 9.12.0 '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.21.1)(tslib@2.7.0)(typescript@5.4.5) + version: 11.1.6(rollup@4.24.0)(tslib@2.7.0)(typescript@5.4.5) '@types/cors': specifier: ^2.8.17 version: 2.8.17 @@ -46,19 +51,19 @@ importers: version: 21.1.7 '@types/lodash': specifier: ^4.17.0 - version: 4.17.7 + version: 4.17.10 '@types/mdast': specifier: ^4.0.3 version: 4.0.4 '@types/node': specifier: ^20.11.30 - version: 20.16.2 + version: 20.16.11 '@types/rollup-plugin-visualizer': specifier: ^4.2.4 version: 4.2.4 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.6.0(vitest@1.6.0(@types/node@20.16.2)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.31.6)) + version: 1.6.0(vitest@1.6.0(@types/node@20.16.11)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.34.1)) '@vitest/spy': specifier: ^1.4.0 version: 1.6.0 @@ -85,67 +90,70 @@ importers: version: 7.0.3 cspell: specifier: ^8.6.0 - version: 8.14.2 + version: 8.14.4 cypress: specifier: ^13.14.1 - version: 13.14.1 + version: 13.15.0 cypress-image-snapshot: specifier: ^4.0.1 - version: 4.0.1(cypress@13.14.1)(jest@29.7.0(@types/node@20.16.2)) + version: 4.0.1(cypress@13.15.0)(jest@29.7.0(@types/node@20.16.11)) + cypress-split: + specifier: ^1.24.0 + version: 1.24.0(@babel/core@7.25.7) esbuild: specifier: ^0.21.5 version: 0.21.5 eslint: specifier: ^9.4.0 - version: 9.8.0 + version: 9.12.0(jiti@1.21.6) eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.0(eslint@9.8.0) + version: 9.1.0(eslint@9.12.0(jiti@1.21.6)) eslint-plugin-cypress: specifier: ^3.3.0 - version: 3.4.0(eslint@9.8.0) + version: 3.5.0(eslint@9.12.0(jiti@1.21.6)) eslint-plugin-html: specifier: ^8.1.1 - version: 8.1.1 + version: 8.1.2 eslint-plugin-jest: specifier: ^28.6.0 - version: 28.7.0(@typescript-eslint/eslint-plugin@8.0.1(@typescript-eslint/parser@8.0.1(eslint@9.8.0)(typescript@5.4.5))(eslint@9.8.0)(typescript@5.4.5))(eslint@9.8.0)(jest@29.7.0(@types/node@20.16.2))(typescript@5.4.5) + version: 28.8.3(@typescript-eslint/eslint-plugin@8.8.1(@typescript-eslint/parser@8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5))(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5))(eslint@9.12.0(jiti@1.21.6))(jest@29.7.0(@types/node@20.16.11))(typescript@5.4.5) eslint-plugin-jsdoc: - specifier: ^48.2.9 - version: 48.11.0(eslint@9.8.0) + specifier: ^50.0.0 + version: 50.3.1(eslint@9.12.0(jiti@1.21.6)) eslint-plugin-json: specifier: ^4.0.0 version: 4.0.1 eslint-plugin-lodash: specifier: ^8.0.0 - version: 8.0.0(eslint@9.8.0) + version: 8.0.0(eslint@9.12.0(jiti@1.21.6)) eslint-plugin-markdown: specifier: ^5.0.0 - version: 5.1.0(eslint@9.8.0) + version: 5.1.0(eslint@9.12.0(jiti@1.21.6)) eslint-plugin-no-only-tests: specifier: ^3.1.0 - version: 3.1.0 + version: 3.3.0 eslint-plugin-tsdoc: specifier: ^0.3.0 version: 0.3.0 eslint-plugin-unicorn: - specifier: ^55.0.0 - version: 55.0.0(eslint@9.8.0) + specifier: ^56.0.0 + version: 56.0.0(eslint@9.12.0(jiti@1.21.6)) express: specifier: ^4.19.1 - version: 4.19.2 + version: 4.21.0 globals: specifier: ^15.4.0 - version: 15.9.0 + version: 15.10.0 globby: specifier: ^14.0.1 version: 14.0.2 husky: specifier: ^9.0.11 - version: 9.1.5 + version: 9.1.6 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.16.2) + version: 29.7.0(@types/node@20.16.11) jison: specifier: ^0.4.18 version: 0.4.18 @@ -160,7 +168,7 @@ importers: version: 3.0.3 lint-staged: specifier: ^15.2.2 - version: 15.2.9 + version: 15.2.10 markdown-table: specifier: ^3.0.3 version: 3.0.3 @@ -181,28 +189,28 @@ importers: version: 5.0.10 rollup-plugin-visualizer: specifier: ^5.12.0 - version: 5.12.0(rollup@4.21.1) + version: 5.12.0(rollup@4.24.0) start-server-and-test: specifier: ^2.0.3 - version: 2.0.5 + version: 2.0.8 tsx: specifier: ^4.7.1 - version: 4.19.0 + version: 4.19.1 typescript: specifier: ~5.4.5 version: 5.4.5 typescript-eslint: specifier: ^8.0.0-alpha.34 - version: 8.0.1(eslint@9.8.0)(typescript@5.4.5) + version: 8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5) vite: specifier: ^5.2.3 - version: 5.4.2(@types/node@20.16.2)(terser@5.31.6) + version: 5.4.8(@types/node@20.16.11)(terser@5.34.1) vite-plugin-istanbul: specifier: ^6.0.0 - version: 6.0.2(vite@5.4.2(@types/node@20.16.2)(terser@5.31.6)) + version: 6.0.2(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1)) vitest: specifier: ^1.4.0 - version: 1.6.0(@types/node@20.16.2)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.31.6) + version: 1.6.0(@types/node@20.16.11)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.34.1) packages/mermaid: dependencies: @@ -211,19 +219,25 @@ importers: version: 7.1.0 '@iconify/utils': specifier: ^2.1.32 - version: 2.1.32 + version: 2.1.33 '@mermaid-js/parser': specifier: workspace:^ version: link:../parser + '@types/d3': + specifier: ^7.4.3 + version: 7.4.3 + '@types/dompurify': + specifier: ^3.0.5 + version: 3.0.5 cytoscape: specifier: ^3.29.2 - version: 3.30.1 + version: 3.30.2 cytoscape-cose-bilkent: specifier: ^4.1.0 - version: 4.1.0(cytoscape@3.30.1) + version: 4.1.0(cytoscape@3.30.2) cytoscape-fcose: specifier: ^2.2.0 - version: 2.2.0(cytoscape@3.30.1) + version: 2.2.0(cytoscape@3.30.2) d3: specifier: ^7.9.0 version: 7.9.0 @@ -231,13 +245,13 @@ importers: specifier: ^0.12.3 version: 0.12.3 dagre-d3-es: - specifier: 7.0.10 - version: 7.0.10 + specifier: 7.0.11 + version: 7.0.11 dayjs: specifier: ^1.11.10 version: 1.11.13 dompurify: - specifier: ^3.0.11 + specifier: ^3.0.11 <3.1.7 version: 3.1.6 katex: specifier: ^0.16.9 @@ -253,7 +267,7 @@ importers: version: 13.0.3 roughjs: specifier: ^4.6.6 - version: 4.6.6 + version: 4.6.6(patch_hash=vxb6t6fqvzyhwhtjiliqr25jyq) stylis: specifier: ^4.3.1 version: 4.3.4 @@ -272,13 +286,10 @@ importers: version: 2.0.0 '@types/cytoscape': specifier: ^3.21.4 - version: 3.21.5 + version: 3.21.8 '@types/cytoscape-fcose': specifier: ^2.2.4 version: 2.2.4 - '@types/d3': - specifier: ^7.4.3 - version: 7.4.3 '@types/d3-sankey': specifier: ^0.12.4 version: 0.12.4 @@ -290,13 +301,10 @@ importers: version: 3.0.3 '@types/d3-selection': specifier: ^3.0.10 - version: 3.0.10 + version: 3.0.11 '@types/d3-shape': specifier: ^3.1.6 version: 3.1.6 - '@types/dompurify': - specifier: ^3.0.5 - version: 3.0.5 '@types/jsdom': specifier: ^21.1.6 version: 21.1.7 @@ -368,10 +376,10 @@ importers: version: 5.0.10 start-server-and-test: specifier: ^2.0.3 - version: 2.0.5 + version: 2.0.8 type-fest: specifier: ^4.13.1 - version: 4.25.0 + version: 4.26.1 typedoc: specifier: ^0.25.12 version: 0.25.13(typescript@5.4.5) @@ -389,10 +397,10 @@ importers: version: 5.0.0 vitepress: specifier: ^1.0.1 - version: 1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.1)(axios@1.7.5)(postcss@8.4.41)(search-insights@2.15.0)(terser@5.31.6)(typescript@5.4.5) + version: 1.1.4(@algolia/client-search@4.24.0)(@types/node@20.16.11)(axios@1.7.7)(postcss@8.4.47)(search-insights@2.17.2)(terser@5.34.1)(typescript@5.4.5) vitepress-plugin-search: specifier: 1.0.4-alpha.22 - version: 1.0.4-alpha.22(flexsearch@0.7.43)(vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.1)(axios@1.7.5)(postcss@8.4.41)(search-insights@2.15.0)(terser@5.31.6)(typescript@5.4.5))(vue@3.4.38(typescript@5.4.5)) + version: 1.0.4-alpha.22(flexsearch@0.7.43)(vitepress@1.1.4(@algolia/client-search@4.24.0)(@types/node@20.16.11)(axios@1.7.7)(postcss@8.4.47)(search-insights@2.17.2)(terser@5.34.1)(typescript@5.4.5))(vue@3.5.11(typescript@5.4.5)) packages/mermaid-example-diagram: dependencies: @@ -436,7 +444,7 @@ importers: dependencies: '@zenuml/core': specifier: ^3.23.27 - version: 3.24.3(typescript@5.4.5) + version: 3.24.12(typescript@5.6.2) devDependencies: mermaid: specifier: workspace:^ @@ -449,7 +457,7 @@ importers: version: 7.4.47 '@vueuse/core': specifier: ^10.9.0 - version: 10.11.1(vue@3.4.38(typescript@5.4.5)) + version: 10.11.1(vue@3.5.11(typescript@5.6.2)) font-awesome: specifier: ^4.7.0 version: 4.7.0 @@ -461,20 +469,20 @@ importers: version: link:../.. vue: specifier: ^3.4.21 - version: 3.4.38(typescript@5.4.5) + version: 3.5.11(typescript@5.6.2) devDependencies: '@iconify-json/carbon': specifier: ^1.1.31 - version: 1.1.37 + version: 1.2.1 '@unocss/reset': specifier: ^0.59.0 version: 0.59.4 '@vite-pwa/vitepress': specifier: ^0.4.0 - version: 0.4.0(vite-plugin-pwa@0.19.8(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0)) + version: 0.4.0(vite-plugin-pwa@0.19.8(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0)) '@vitejs/plugin-vue': specifier: ^5.0.0 - version: 5.1.2(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(vue@3.4.38(typescript@5.4.5)) + version: 5.1.4(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))(vue@3.5.11(typescript@5.6.2)) fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -486,80 +494,19 @@ importers: version: 1.1.2 unocss: specifier: ^0.59.0 - version: 0.59.4(postcss@8.4.41)(rollup@2.79.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6)) + version: 0.59.4(postcss@8.4.47)(rollup@2.79.2)(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1)) unplugin-vue-components: specifier: ^0.26.0 - version: 0.26.0(@babel/parser@7.25.4)(rollup@2.79.1)(vue@3.4.38(typescript@5.4.5)) + version: 0.26.0(@babel/parser@7.25.7)(rollup@2.79.2)(vue@3.5.11(typescript@5.6.2))(webpack-sources@3.2.3) vite: specifier: ^5.0.0 - version: 5.4.2(@types/node@22.5.1)(terser@5.31.6) + version: 5.4.8(@types/node@20.16.11)(terser@5.34.1) vite-plugin-pwa: specifier: ^0.19.7 - version: 0.19.8(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0) + version: 0.19.8(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0) vitepress: specifier: 1.1.4 - version: 1.1.4(@algolia/client-search@4.24.0)(@types/node@22.5.1)(axios@1.7.5)(postcss@8.4.41)(search-insights@2.15.0)(terser@5.31.6)(typescript@5.4.5) - workbox-window: - specifier: ^7.0.0 - version: 7.1.0 - - packages/mermaid/src/vitepress: - dependencies: - '@mdi/font': - specifier: ^7.0.0 - version: 7.4.47 - '@vueuse/core': - specifier: ^10.9.0 - version: 10.11.1(vue@3.4.38(typescript@5.4.5)) - font-awesome: - specifier: ^4.7.0 - version: 4.7.0 - jiti: - specifier: ^1.21.0 - version: 1.21.6 - mermaid: - specifier: workspace:^ - version: link:../.. - vue: - specifier: ^3.4.21 - version: 3.4.38(typescript@5.4.5) - devDependencies: - '@iconify-json/carbon': - specifier: ^1.1.31 - version: 1.1.37 - '@unocss/reset': - specifier: ^0.59.0 - version: 0.59.4 - '@vite-pwa/vitepress': - specifier: ^0.4.0 - version: 0.4.0(vite-plugin-pwa@0.19.8(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0)) - '@vitejs/plugin-vue': - specifier: ^5.0.0 - version: 5.1.2(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(vue@3.4.38(typescript@5.4.5)) - fast-glob: - specifier: ^3.3.2 - version: 3.3.2 - https-localhost: - specifier: ^4.7.1 - version: 4.7.1 - pathe: - specifier: ^1.1.2 - version: 1.1.2 - unocss: - specifier: ^0.59.0 - version: 0.59.4(postcss@8.4.41)(rollup@4.21.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6)) - unplugin-vue-components: - specifier: ^0.26.0 - version: 0.26.0(@babel/parser@7.25.4)(rollup@4.21.1)(vue@3.4.38(typescript@5.4.5)) - vite: - specifier: ^5.0.0 - version: 5.4.2(@types/node@22.5.1)(terser@5.31.6) - vite-plugin-pwa: - specifier: ^0.19.7 - version: 0.19.8(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0) - vitepress: - specifier: 1.1.4 - version: 1.1.4(@algolia/client-search@4.24.0)(@types/node@22.5.1)(axios@1.7.5)(postcss@8.4.41)(search-insights@2.15.0)(terser@5.31.6)(typescript@5.4.5) + version: 1.1.4(@algolia/client-search@4.24.0)(@types/node@20.16.11)(axios@1.7.7)(postcss@8.4.47)(search-insights@2.17.2)(terser@5.34.1)(typescript@5.6.2) workbox-window: specifier: ^7.0.0 version: 7.1.0 @@ -585,16 +532,28 @@ importers: devDependencies: webpack: specifier: ^5.91.0 - version: 5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0) + version: 5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0) webpack-cli: specifier: ^4.10.0 - version: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0) + version: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0) webpack-dev-server: specifier: ^4.15.2 - version: 4.15.2(webpack-cli@4.10.0)(webpack@5.93.0) + version: 4.15.2(webpack-cli@4.10.0)(webpack@5.95.0) packages: + '@actions/core@1.11.1': + resolution: {integrity: sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==} + + '@actions/exec@1.1.1': + resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==} + + '@actions/http-client@2.2.3': + resolution: {integrity: sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==} + + '@actions/io@1.1.3': + resolution: {integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==} + '@adobe/jsonschema2md@8.0.2': resolution: {integrity: sha512-g90Rtz1Xghp9HTfbtBH2Pf5IpuUY1Ry9Wps5NNuNmxucbtmnCY4/1KXmtwe0yKxnknPF7nt5/Y8TOekMh450tQ==} engines: {node: ^18.0.0 || >= 20.0.0} @@ -673,9 +632,6 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@antfu/install-pkg@0.1.1': - resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} - '@antfu/install-pkg@0.4.1': resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==} @@ -688,12 +644,17 @@ packages: peerDependencies: ajv: '>=8' - '@applitools/core-base@1.16.0': - resolution: {integrity: sha512-6v5box6DqmvyfVNe0tjRSCIZpfkn6fc0DZMZI4+jKLczh4zm+Tlfey1ECavP3fRZayh79SGCpeIDqBNI9Ll7dA==} + '@applitools/core-base@1.16.1': + resolution: {integrity: sha512-T4/BCba4b77lJRh85Ir9Gwc2cKKwzLAdrPOWbzwx2euhl7ZPUdd4U4ncQpv9uKTYFwz5zu3v5TCeUxrRpRtXqg==} engines: {node: '>=12.13.0'} - '@applitools/core@4.18.1': - resolution: {integrity: sha512-Z0tW1PVOHcYL3NCn83B6lErKElHE9YkIJx+rQt8WqQw9PMpkUtiAwRA1sx6F10U0xSKbAJHRq7A9Yr4FMwnVog==} + '@applitools/core@4.18.2': + resolution: {integrity: sha512-loxNLlWyEdKBLTNUj4JUvDXImFxFVXZZ/NC/k5Z+LaXix3Xk5aIpCM+8Ii5Y96WBv8G7x/ZvQop7h823z3ai0Q==} + engines: {node: '>=12.13.0'} + hasBin: true + + '@applitools/core@4.19.0': + resolution: {integrity: sha512-OzGSZpRTouDFidzZx7IpqStoVThBz5ympBI6iowh1xkfbVRsRjKXaHIjCuB3TAkfTNy4V7lm2Pmzex7Dn4Fq1w==} engines: {node: '>=12.13.0'} hasBin: true @@ -701,8 +662,12 @@ packages: resolution: {integrity: sha512-rH3aq/dkTweEUgS/MKuthD79CZDqpQVJlqmxqVxLZVAzbeFxYdTG/gnfG0zj6YJ025jzcPH2ktdW16Rl3QLutg==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - '@applitools/dom-capture@11.3.1': - resolution: {integrity: sha512-TylDa9uir7LnZ8e/E76rMRR5+1t927RQeATqIub0WnWMHMCs3reNlinbolQ4PWS1zIwkGkVXQzClSF/dRz6OWA==} + '@applitools/dom-capture@11.4.0': + resolution: {integrity: sha512-8E5rjsuivGWx1TtZsjhwo32gF02dzwqvHf8NaN2fK+DTyomUvrh4QRD0ufUlKNeXIJhlVVgzjOkdfKjDj5pT/A==} + engines: {node: '>=12.13.0'} + + '@applitools/dom-capture@11.5.0': + resolution: {integrity: sha512-frsa+nztrxN0YyfnFNQ3fxs6Q8A93YmtqWw7v2rywv2vGk0bo1VzobFbfIFvwHEwk+oghobV+w94NdYk9jPVZA==} engines: {node: '>=12.13.0'} '@applitools/dom-shared@1.0.15': @@ -713,12 +678,21 @@ packages: resolution: {integrity: sha512-jdEWSbEOmD9LbzashTQ/YzYDdIKrhSBwNqNTIk8qjV8YtbQfZ+NtgCtW7nOsbknAMk95CfYEUV3R1rxCXs1XfA==} engines: {node: '>=12.13.0'} - '@applitools/driver@1.18.0': - resolution: {integrity: sha512-wJYPZ2oEzRtyxne518GgdQbE+JF7S6yZEZX6SJWpVwrv/MPBKD9byxRi89XZcSpyxweFt7Ud7yJskBbubXu7QQ==} + '@applitools/driver@1.19.0': + resolution: {integrity: sha512-fXNvT08/uR87Wi2nNURT9YXJYV/2ZG6DnKutk3jxsp29uNJXaHfruMXoA0p6guAWzo9gw592K0GKLTn1BB/3YA==} engines: {node: '>=12.13.0'} - '@applitools/ec-client@1.9.3': - resolution: {integrity: sha512-fnsnQpyDi3rltFEeDeUnNIRULpoWBsSf4L5F7g08LBpuAR5MTpY2WArn1nzD12rfQRoTsO7/5H0DYv/+Mr5w3A==} + '@applitools/driver@1.19.1': + resolution: {integrity: sha512-SWTOtdALeqrmaYo+gzeWupB3C4yDCNwEq/RFykW7k41yFg4145B/BgmubZjteDAr6W+4vmE8vXtbVWHNGPuFfA==} + engines: {node: '>=12.13.0'} + + '@applitools/ec-client@1.9.4': + resolution: {integrity: sha512-PFuvt/XrJxzoy/fXeLTq+bE5+0mitV0whi4MUWZAnESIvHj3k3+oUUTZxPmRQEiR1zzxGvN7ar3sMQfiW+houA==} + engines: {node: '>=12.13.0'} + hasBin: true + + '@applitools/ec-client@1.9.5': + resolution: {integrity: sha512-B2HvmSq5wKjszbV8y1b5jdMdQzR1izQ3DK3Egc/Y4ye/TXvuzsx6/t7/iV5TwLvGoS2jPWOr/iTgl3cCJjXUIg==} engines: {node: '>=12.13.0'} hasBin: true @@ -730,18 +704,18 @@ packages: resolution: {integrity: sha512-SjjDBFeiKspX3nHKOoSQ+l4JUiJK3xJiWAEaR8b+GuMvnGFLnrvAECHhuXXG00+LwBJM8WKmfxEe17nvZe+nhg==} engines: {node: '>=12'} - '@applitools/execution-grid-tunnel@3.0.5': - resolution: {integrity: sha512-Kp8Sgb5sS/+0CEo0ytvQONzJdmru3vu8BcNwvLyJoqPNf7zSDTr3AR60p9l4hh11nsBzJyi3+Uh8oR968J+mng==} + '@applitools/execution-grid-tunnel@3.0.8': + resolution: {integrity: sha512-4S6NcpxELH4NXketD3g6VUhWDUCuwAm4F1sCZdZLpPWOSMu5QwQDYUoe6/4t5KuktTQ4K7N90NmTzQrxiFtDKA==} engines: {node: '>=14.0.0'} hasBin: true - '@applitools/eyes-cypress@3.44.7': - resolution: {integrity: sha512-YgzUnc4YAoEQSNSLlwZvyP50Xua2U6h3WV7KAU+E9MbR2RwBBddUhI0y3PhnzJOZgvUJvSfdwqbw0Cxn0CfVjg==} + '@applitools/eyes-cypress@3.44.9': + resolution: {integrity: sha512-hWwo02uMeFkwU7bG2396DqKrOsjMxAMowaIH8okP09ZPgK+nSJbnIHM111nj+4+eLKx4WAyDa9JljILuXZ4x9A==} engines: {node: '>=12.13.0'} hasBin: true - '@applitools/eyes@1.22.1': - resolution: {integrity: sha512-+WOYGsRF3CuyLZQHJ2P4l3AjFFlHtW+s7kmjcyVswlvEcVJDxsiQzFnklo37IbbyX6oMi2Df8jOYPjXNCTQd7A==} + '@applitools/eyes@1.22.2': + resolution: {integrity: sha512-72mMjSYjfBHAdVqyubtLWAKgK3f/lcFZcyTh8UacCZv+PJ+8+/JAC+ovloUOV1HHOtgcR+ocPdw3VJsxDZZuig==} engines: {node: '>=12.13.0'} '@applitools/functional-commons@1.6.0': @@ -760,34 +734,52 @@ packages: resolution: {integrity: sha512-d54OTreCXE+G9qUxiPDHHBzwof3EnXPrADdZ7ToB9AoI+kOgs/v6wjMx0ghAoXyyOiLvlvJnmdHSyJssRdv5GA==} engines: {node: '>=12.13.0'} - '@applitools/nml-client@1.8.9': - resolution: {integrity: sha512-Jwz42oRVnu46V2lgj0eTfKaOu3eYo8T2Z2QhsN/5xleKISJQ8B86954JuZy9Rwx75+9T+ddmYqWfjSBWfhmVhg==} + '@applitools/nml-client@1.8.10': + resolution: {integrity: sha512-avoZnD39XrWJg5x7PiFv+58YEDLbWPRIb+dHrH9LVD1HcQC8tmht2KfVLnTJLJtJgRQojqZh5H8rmplfT46t8w==} + engines: {node: '>=12.13.0'} + + '@applitools/nml-client@1.8.11': + resolution: {integrity: sha512-Zoyjo9slRbvCGb/ldScNxTvRig5nuUdogXeiyV8jcKUocqb0LLfZZyNRRHnA0bmSk31mjqfB8HLG1wgBIKZ/eQ==} engines: {node: '>=12.13.0'} '@applitools/req@1.7.2': resolution: {integrity: sha512-L0tjPFGEJFAEGaifqtmtCghjkG7M0wnEwfzbHi6O+ThtTCbg4JSDRTaNvA+PLXQoS0mFvajG40/t5a4EgAG7QQ==} engines: {node: '>=16.13.0'} - '@applitools/screenshoter@3.8.35': - resolution: {integrity: sha512-1jos00VVJOU5uxgh9cVhj7nq9akMFvBIdfQRR9KkUFeylDxt8vRpkmO6zyfbxeK2jyiboPOZXPa0PvL7M0WNLQ==} + '@applitools/screenshoter@3.8.36': + resolution: {integrity: sha512-bzl+fs3c4L6J2t/PELxmoMGc40ZvjaExD0PMM6GvbNp3uPbDtGS348DC1ZYsSl481OxTae/uiO/iVOQP4bNZCQ==} + engines: {node: '>=12.13.0'} + + '@applitools/screenshoter@3.8.37': + resolution: {integrity: sha512-il7clR9bd3E2QzjWfR/JafmUyrykvQN8EzqaFG4rfNO5IUYYP/K2rYGAbWykk220weI3r9S09QrSDWVHwNJgHw==} engines: {node: '>=12.13.0'} '@applitools/snippets@2.4.27': resolution: {integrity: sha512-n6ckwbXWyJ+/DoV1T6bRiGXITgTgjayV0j4AzHiBx+HF3JdzygxIkWtn7yl1dJfzeqEGyrtBK6Sq1tTG2GoQcA==} engines: {node: '>=12.13.0'} + '@applitools/snippets@2.5.0': + resolution: {integrity: sha512-7PoDf2Xub68q7bfEcSxzRIOsK+QPUEzCKO5X3YKEq7/y55G1bFalZiY+V0TZEgIu4SSbq8BmCos9798w1J31uA==} + engines: {node: '>=12.13.0'} + '@applitools/socket@1.1.18': resolution: {integrity: sha512-EMI/MMfVH38ucuZhFWOTUR8cPvuoP9b+xi5yBJF8uLlJjxQEmGnvm+Pm3s9o3mfxQzDRddYGtpIo3TTZhMVZdQ==} engines: {node: '>=12.13.0'} - '@applitools/spec-driver-webdriver@1.1.11': - resolution: {integrity: sha512-xeVeqiK+Oyi2xGRME54J3yTXUGR9d2NgcOCkXTdZ+QOj8iPzypelyeHkX4nKJNsLw4Ddh9uvaiFJmKppqGZ1Mg==} + '@applitools/spec-driver-webdriver@1.1.12': + resolution: {integrity: sha512-r6PobChadcc3couBtnf3pTunL7Vi00cNcg2l1rTr0ApSEfJ1m1DdTcX8bgXU1jDzJ2QhCn7OoqsziTajQdWmoA==} engines: {node: '>=12.13.0'} peerDependencies: webdriver: '>=6.0.0' - '@applitools/tunnel-client@1.5.7': - resolution: {integrity: sha512-h2/U2ZTDQp67Q/sU72eNx7dQms54yzfmM/Cordp2ZSQN9FAxt/NN22cUr8Qf+r71Uuu/VYlvzZUdMGl42MuKmA==} + '@applitools/spec-driver-webdriver@1.1.13': + resolution: {integrity: sha512-LcX4mbXdptPjcgRifUvV17pANVhjMiSEYkfZkP0G/ZuPi1czQvgzsSkjeYTKuKJJYLaP19h4CFNjNttD3mSsDQ==} + engines: {node: '>=12.13.0'} + peerDependencies: + webdriver: '>=6.0.0' + + '@applitools/tunnel-client@1.5.8': + resolution: {integrity: sha512-SJByl2/I0NftENw5NvW+nHN+Vq64b0aeTsdCTYKhDhJBWqPEkGYwRR5ziYpk8MWYsL2hWcPUfg/S/hS+M3zmDg==} engines: {node: '>=12.13.0'} hasBin: true @@ -803,20 +795,20 @@ packages: resolution: {integrity: sha512-qgJqx2yjlJBf79YyFehf1nSp4AXOdzJn3POQyg8CMWV0YH6HsjAfJjYaNrbXFcGYCSpPEJGhGehxC7GVKHX3YA==} engines: {node: '>=12.13.0'} - '@argos-ci/api-client@0.2.0': - resolution: {integrity: sha512-stqugeAtbHjD2MwezvgJ4hU0HvlEGwGDVsJvUUD4YoRS0putS8yFjXuempkc90XGeHDEfYZgvG372rcK7/FClA==} + '@argos-ci/api-client@0.5.0': + resolution: {integrity: sha512-syJJmvLtJKQYXDmGYRb+ZKpzpSk/dReqhZZm2tnWn7ThxHaJRJ7Wu3J5nqDpCP3LxoYCVfvV/dmfoJO0v8+PbQ==} engines: {node: '>=18.0.0'} - '@argos-ci/browser@2.1.3': - resolution: {integrity: sha512-C9/k32HrmkHkUT9KrhHuOvlli1ibPGE1nkToC6+t4cAmbJCIU8HFrVa6VG2UT3xJjLht+gpqvPwTbJAsCRXv3A==} + '@argos-ci/browser@2.1.4': + resolution: {integrity: sha512-GursnbWL01wN92hRgEsa0c55ih9Sp6qGeYIXFWP4o42FDzm98LbxIy2e1WS+ezP+gBwsSBEMBTGcGCSSmVzacg==} engines: {node: '>=18.0.0'} - '@argos-ci/core@2.5.0': - resolution: {integrity: sha512-xNHKWzuSLHXm/5fhdEQv8zUwExeEkYzw6CV/Ha9rUBBTPomZL5CNxpXQ/ww1AA4mRC5dq3CfgreRq8qj7HQMVQ==} + '@argos-ci/core@2.8.1': + resolution: {integrity: sha512-5ygruMnfQ3OY6LvywnwTycZFg6oTG5UYvPCVdwQiOh+8FgUZUyJge7QBVfeWW+qC0UXFMo+f3eTQ5YFvTwc0ZA==} engines: {node: '>=18.0.0'} - '@argos-ci/cypress@2.1.2': - resolution: {integrity: sha512-J+G7EoyQTz6ev9yZBKpl1lRuizUwrX4ZMfqfyB9fDtPhyNcW3V5nTZh2iMBsNW/4hDnL5SQ5Tge5eJfuGkffgA==} + '@argos-ci/cypress@2.2.2': + resolution: {integrity: sha512-lwXu6y5DcP4ufYQEom4JtHSHjIYul6+GB4pniC8S97mfXLYq6KITJD4JHbrnfIiQGuV1xNPIaBc4MWX+atFDuw==} engines: {node: '>=18.0.0'} peerDependencies: cypress: ^12.0.0 || ^13.0.0 @@ -825,56 +817,42 @@ packages: resolution: {integrity: sha512-UyACLQe9rvCPbo9muhrLte1AD75kQlcGBuecjmaotaF9MBMj+9Yz+TYs1jJrlLMgqowfIgbXjBYmkXRUn36tCg==} engines: {node: '>=18.0.0'} - '@babel/code-frame@7.24.7': - resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + '@babel/code-frame@7.25.7': + resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.25.2': - resolution: {integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==} + '@babel/compat-data@7.25.7': + resolution: {integrity: sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.25.4': - resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} + '@babel/core@7.25.7': + resolution: {integrity: sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==} engines: {node: '>=6.9.0'} - '@babel/core@7.25.2': - resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} + '@babel/generator@7.25.7': + resolution: {integrity: sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.25.0': - resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} + '@babel/helper-annotate-as-pure@7.25.7': + resolution: {integrity: sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.25.5': - resolution: {integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==} + '@babel/helper-builder-binary-assignment-operator-visitor@7.25.7': + resolution: {integrity: sha512-12xfNeKNH7jubQNm7PAkzlLwEmCs1tfuX3UjIw6vP6QXi+leKh6+LyC/+Ed4EIQermwd58wsyh070yjDHFlNGg==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.24.7': - resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} + '@babel/helper-compilation-targets@7.25.7': + resolution: {integrity: sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==} engines: {node: '>=6.9.0'} - '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': - resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.25.2': - resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-create-class-features-plugin@7.25.0': - resolution: {integrity: sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==} + '@babel/helper-create-class-features-plugin@7.25.7': + resolution: {integrity: sha512-bD4WQhbkx80mAyj/WCm4ZHcF4rDxkoLFO6ph8/5/mQ3z4vAzltQXAmbc7GvVJx5H+lk5Mi5EmbTeox5nMGCsbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-create-class-features-plugin@7.25.4': - resolution: {integrity: sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-create-regexp-features-plugin@7.25.2': - resolution: {integrity: sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==} + '@babel/helper-create-regexp-features-plugin@7.25.7': + resolution: {integrity: sha512-byHhumTj/X47wJ6C6eLpK7wW/WBEcnUeb7D0FNc/jFQnQVw7DOso3Zz5u9x/zLrFVkHa89ZGDbkAa1D54NdrCQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -884,108 +862,103 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - '@babel/helper-member-expression-to-functions@7.24.8': - resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} + '@babel/helper-member-expression-to-functions@7.25.7': + resolution: {integrity: sha512-O31Ssjd5K6lPbTX9AAYpSKrZmLeagt9uwschJd+Ixo6QiRyfpvgtVQp8qrDR9UNFjZ8+DO34ZkdrN+BnPXemeA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.24.7': - resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + '@babel/helper-module-imports@7.25.7': + resolution: {integrity: sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.25.2': - resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} + '@babel/helper-module-transforms@7.25.7': + resolution: {integrity: sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.24.7': - resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} + '@babel/helper-optimise-call-expression@7.25.7': + resolution: {integrity: sha512-VAwcwuYhv/AT+Vfr28c9y6SHzTan1ryqrydSTFGjU0uDJHw3uZ+PduI8plCLkRsDnqK2DMEDmwrOQRsK/Ykjng==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.24.8': - resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} + '@babel/helper-plugin-utils@7.25.7': + resolution: {integrity: sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==} engines: {node: '>=6.9.0'} - '@babel/helper-remap-async-to-generator@7.25.0': - resolution: {integrity: sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==} + '@babel/helper-remap-async-to-generator@7.25.7': + resolution: {integrity: sha512-kRGE89hLnPfcz6fTrlNU+uhgcwv0mBE4Gv3P9Ke9kLVJYpi4AMVVEElXvB5CabrPZW4nCM8P8UyyjrzCM0O2sw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.25.0': - resolution: {integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==} + '@babel/helper-replace-supers@7.25.7': + resolution: {integrity: sha512-iy8JhqlUW9PtZkd4pHM96v6BdJ66Ba9yWSE4z0W4TvSZwLBPkyDsiIU3ENe4SmrzRBs76F7rQXTy1lYC49n6Lw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-simple-access@7.24.7': - resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + '@babel/helper-simple-access@7.25.7': + resolution: {integrity: sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==} engines: {node: '>=6.9.0'} - '@babel/helper-skip-transparent-expression-wrappers@7.24.7': - resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} + '@babel/helper-skip-transparent-expression-wrappers@7.25.7': + resolution: {integrity: sha512-pPbNbchZBkPMD50K0p3JGcFMNLVUCuU/ABybm/PGNj4JiHrpmNyqqCphBk4i19xXtNV0JhldQJJtbSW5aUvbyA==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.24.8': - resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + '@babel/helper-string-parser@7.25.7': + resolution: {integrity: sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.24.7': - resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + '@babel/helper-validator-identifier@7.25.7': + resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.24.8': - resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + '@babel/helper-validator-option@7.25.7': + resolution: {integrity: sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.25.0': - resolution: {integrity: sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==} + '@babel/helper-wrap-function@7.25.7': + resolution: {integrity: sha512-MA0roW3JF2bD1ptAaJnvcabsVlNQShUaThyJbCDD4bCp8NEgiFvpoqRI2YS22hHlc2thjO/fTg2ShLMC3jygAg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.25.0': - resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} + '@babel/helpers@7.25.7': + resolution: {integrity: sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.24.7': - resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + '@babel/highlight@7.25.7': + resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.25.3': - resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} + '@babel/parser@7.25.7': + resolution: {integrity: sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.25.4': - resolution: {integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3': - resolution: {integrity: sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==} + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.7': + resolution: {integrity: sha512-UV9Lg53zyebzD1DwQoT9mzkEKa922LNUp5YkTJ6Uta0RbyXaQNUgcvSt7qIu1PpPzVb6rd10OVNTzkyBGeVmxQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0': - resolution: {integrity: sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==} + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.7': + resolution: {integrity: sha512-GDDWeVLNxRIkQTnJn2pDOM1pkCgYdSqPeT1a9vh9yIqu2uzzgw1zcqEb+IJOhy+dTBMlNdThrDIksr2o09qrrQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0': - resolution: {integrity: sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==} + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.7': + resolution: {integrity: sha512-wxyWg2RYaSUYgmd9MR0FyRGyeOMQE/Uzr1wzd/g5cf5bwi9A4v6HFdDm7y1MgDtod/fLOSTZY6jDgV0xU9d5bA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7': - resolution: {integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==} + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.7': + resolution: {integrity: sha512-Xwg6tZpLxc4iQjorYsyGMyfJE7nP5MV8t/Ka58BgiA7Jw0fRqQNcANlLfdJ/yvBt9z9LD2We+BEkT7vLqZRWng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0': - resolution: {integrity: sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.7': + resolution: {integrity: sha512-UVATLMidXrnH+GMUIuxq55nejlj02HP7F5ETyBONzP6G87fPBogG4CH6kxrSrdIuAjdwNO9VzyaYsrZPscWUrw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1027,14 +1000,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-assertions@7.24.7': - resolution: {integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==} + '@babel/plugin-syntax-import-assertions@7.25.7': + resolution: {integrity: sha512-ZvZQRmME0zfJnDQnVBKYzHxXT7lYBB3Revz1GuS7oLXWMgqUPX4G+DDbT30ICClht9WKV34QVrZhSw6WdklwZQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-attributes@7.24.7': - resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} + '@babel/plugin-syntax-import-attributes@7.25.7': + resolution: {integrity: sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1049,8 +1022,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.24.7': - resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} + '@babel/plugin-syntax-jsx@7.25.7': + resolution: {integrity: sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1097,8 +1070,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.24.7': - resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==} + '@babel/plugin-syntax-typescript@7.25.7': + resolution: {integrity: sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1109,308 +1082,308 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-arrow-functions@7.24.7': - resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} + '@babel/plugin-transform-arrow-functions@7.25.7': + resolution: {integrity: sha512-EJN2mKxDwfOUCPxMO6MUI58RN3ganiRAG/MS/S3HfB6QFNjroAMelQo/gybyYq97WerCBAZoyrAoW8Tzdq2jWg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.25.4': - resolution: {integrity: sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==} + '@babel/plugin-transform-async-generator-functions@7.25.7': + resolution: {integrity: sha512-4B6OhTrwYKHYYgcwErvZjbmH9X5TxQBsaBHdzEIB4l71gR5jh/tuHGlb9in47udL2+wVUcOz5XXhhfhVJwEpEg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.24.7': - resolution: {integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==} + '@babel/plugin-transform-async-to-generator@7.25.7': + resolution: {integrity: sha512-ZUCjAavsh5CESCmi/xCpX1qcCaAglzs/7tmuvoFnJgA1dM7gQplsguljoTg+Ru8WENpX89cQyAtWoaE0I3X3Pg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.24.7': - resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} + '@babel/plugin-transform-block-scoped-functions@7.25.7': + resolution: {integrity: sha512-xHttvIM9fvqW+0a3tZlYcZYSBpSWzGBFIt/sYG3tcdSzBB8ZeVgz2gBP7Df+sM0N1850jrviYSSeUuc+135dmQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.25.0': - resolution: {integrity: sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==} + '@babel/plugin-transform-block-scoping@7.25.7': + resolution: {integrity: sha512-ZEPJSkVZaeTFG/m2PARwLZQ+OG0vFIhPlKHK/JdIMy8DbRJ/htz6LRrTFtdzxi9EHmcwbNPAKDnadpNSIW+Aow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.25.4': - resolution: {integrity: sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==} + '@babel/plugin-transform-class-properties@7.25.7': + resolution: {integrity: sha512-mhyfEW4gufjIqYFo9krXHJ3ElbFLIze5IDp+wQTxoPd+mwFb1NxatNAwmv8Q8Iuxv7Zc+q8EkiMQwc9IhyGf4g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.24.7': - resolution: {integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==} + '@babel/plugin-transform-class-static-block@7.25.7': + resolution: {integrity: sha512-rvUUtoVlkDWtDWxGAiiQj0aNktTPn3eFynBcMC2IhsXweehwgdI9ODe+XjWw515kEmv22sSOTp/rxIRuTiB7zg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.25.4': - resolution: {integrity: sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==} + '@babel/plugin-transform-classes@7.25.7': + resolution: {integrity: sha512-9j9rnl+YCQY0IGoeipXvnk3niWicIB6kCsWRGLwX241qSXpbA4MKxtp/EdvFxsc4zI5vqfLxzOd0twIJ7I99zg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.24.7': - resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} + '@babel/plugin-transform-computed-properties@7.25.7': + resolution: {integrity: sha512-QIv+imtM+EtNxg/XBKL3hiWjgdLjMOmZ+XzQwSgmBfKbfxUjBzGgVPklUuE55eq5/uVoh8gg3dqlrwR/jw3ZeA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.24.8': - resolution: {integrity: sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==} + '@babel/plugin-transform-destructuring@7.25.7': + resolution: {integrity: sha512-xKcfLTlJYUczdaM1+epcdh1UGewJqr9zATgrNHcLBcV2QmfvPPEixo/sK/syql9cEmbr7ulu5HMFG5vbbt/sEA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dotall-regex@7.24.7': - resolution: {integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==} + '@babel/plugin-transform-dotall-regex@7.25.7': + resolution: {integrity: sha512-kXzXMMRzAtJdDEgQBLF4oaiT6ZCU3oWHgpARnTKDAqPkDJ+bs3NrZb310YYevR5QlRo3Kn7dzzIdHbZm1VzJdQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-keys@7.24.7': - resolution: {integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==} + '@babel/plugin-transform-duplicate-keys@7.25.7': + resolution: {integrity: sha512-by+v2CjoL3aMnWDOyCIg+yxU9KXSRa9tN6MbqggH5xvymmr9p4AMjYkNlQy4brMceBnUyHZ9G8RnpvT8wP7Cfg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0': - resolution: {integrity: sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==} + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.7': + resolution: {integrity: sha512-HvS6JF66xSS5rNKXLqkk7L9c/jZ/cdIVIcoPVrnl8IsVpLggTjXs8OWekbLHs/VtYDDh5WXnQyeE3PPUGm22MA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-dynamic-import@7.24.7': - resolution: {integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==} + '@babel/plugin-transform-dynamic-import@7.25.7': + resolution: {integrity: sha512-UvcLuual4h7/GfylKm2IAA3aph9rwvAM2XBA0uPKU3lca+Maai4jBjjEVUS568ld6kJcgbouuumCBhMd/Yz17w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-exponentiation-operator@7.24.7': - resolution: {integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==} + '@babel/plugin-transform-exponentiation-operator@7.25.7': + resolution: {integrity: sha512-yjqtpstPfZ0h/y40fAXRv2snciYr0OAoMXY/0ClC7tm4C/nG5NJKmIItlaYlLbIVAWNfrYuy9dq1bE0SbX0PEg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-export-namespace-from@7.24.7': - resolution: {integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==} + '@babel/plugin-transform-export-namespace-from@7.25.7': + resolution: {integrity: sha512-h3MDAP5l34NQkkNulsTNyjdaR+OiB0Im67VU//sFupouP8Q6m9Spy7l66DcaAQxtmCqGdanPByLsnwFttxKISQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-for-of@7.24.7': - resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} + '@babel/plugin-transform-for-of@7.25.7': + resolution: {integrity: sha512-n/TaiBGJxYFWvpJDfsxSj9lEEE44BFM1EPGz4KEiTipTgkoFVVcCmzAL3qA7fdQU96dpo4gGf5HBx/KnDvqiHw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-function-name@7.25.1': - resolution: {integrity: sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==} + '@babel/plugin-transform-function-name@7.25.7': + resolution: {integrity: sha512-5MCTNcjCMxQ63Tdu9rxyN6cAWurqfrDZ76qvVPrGYdBxIj+EawuuxTu/+dgJlhK5eRz3v1gLwp6XwS8XaX2NiQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-json-strings@7.24.7': - resolution: {integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==} + '@babel/plugin-transform-json-strings@7.25.7': + resolution: {integrity: sha512-Ot43PrL9TEAiCe8C/2erAjXMeVSnE/BLEx6eyrKLNFCCw5jvhTHKyHxdI1pA0kz5njZRYAnMO2KObGqOCRDYSA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-literals@7.25.2': - resolution: {integrity: sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==} + '@babel/plugin-transform-literals@7.25.7': + resolution: {integrity: sha512-fwzkLrSu2fESR/cm4t6vqd7ebNIopz2QHGtjoU+dswQo/P6lwAG04Q98lliE3jkz/XqnbGFLnUcE0q0CVUf92w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-logical-assignment-operators@7.24.7': - resolution: {integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==} + '@babel/plugin-transform-logical-assignment-operators@7.25.7': + resolution: {integrity: sha512-iImzbA55BjiovLyG2bggWS+V+OLkaBorNvc/yJoeeDQGztknRnDdYfp2d/UPmunZYEnZi6Lg8QcTmNMHOB0lGA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-member-expression-literals@7.24.7': - resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} + '@babel/plugin-transform-member-expression-literals@7.25.7': + resolution: {integrity: sha512-Std3kXwpXfRV0QtQy5JJcRpkqP8/wG4XL7hSKZmGlxPlDqmpXtEPRmhF7ztnlTCtUN3eXRUJp+sBEZjaIBVYaw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-amd@7.24.7': - resolution: {integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==} + '@babel/plugin-transform-modules-amd@7.25.7': + resolution: {integrity: sha512-CgselSGCGzjQvKzghCvDTxKHP3iooenLpJDO842ehn5D2G5fJB222ptnDwQho0WjEvg7zyoxb9P+wiYxiJX5yA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.24.8': - resolution: {integrity: sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==} + '@babel/plugin-transform-modules-commonjs@7.25.7': + resolution: {integrity: sha512-L9Gcahi0kKFYXvweO6n0wc3ZG1ChpSFdgG+eV1WYZ3/dGbJK7vvk91FgGgak8YwRgrCuihF8tE/Xg07EkL5COg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.25.0': - resolution: {integrity: sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==} + '@babel/plugin-transform-modules-systemjs@7.25.7': + resolution: {integrity: sha512-t9jZIvBmOXJsiuyOwhrIGs8dVcD6jDyg2icw1VL4A/g+FnWyJKwUfSSU2nwJuMV2Zqui856El9u+ElB+j9fV1g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-umd@7.24.7': - resolution: {integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==} + '@babel/plugin-transform-modules-umd@7.25.7': + resolution: {integrity: sha512-p88Jg6QqsaPh+EB7I9GJrIqi1Zt4ZBHUQtjw3z1bzEXcLh6GfPqzZJ6G+G1HBGKUNukT58MnKG7EN7zXQBCODw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-named-capturing-groups-regex@7.24.7': - resolution: {integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==} + '@babel/plugin-transform-named-capturing-groups-regex@7.25.7': + resolution: {integrity: sha512-BtAT9LzCISKG3Dsdw5uso4oV1+v2NlVXIIomKJgQybotJY3OwCwJmkongjHgwGKoZXd0qG5UZ12JUlDQ07W6Ow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-new-target@7.24.7': - resolution: {integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==} + '@babel/plugin-transform-new-target@7.25.7': + resolution: {integrity: sha512-CfCS2jDsbcZaVYxRFo2qtavW8SpdzmBXC2LOI4oO0rP+JSRDxxF3inF4GcPsLgfb5FjkhXG5/yR/lxuRs2pySA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-nullish-coalescing-operator@7.24.7': - resolution: {integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==} + '@babel/plugin-transform-nullish-coalescing-operator@7.25.7': + resolution: {integrity: sha512-FbuJ63/4LEL32mIxrxwYaqjJxpbzxPVQj5a+Ebrc8JICV6YX8nE53jY+K0RZT3um56GoNWgkS2BQ/uLGTjtwfw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-numeric-separator@7.24.7': - resolution: {integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==} + '@babel/plugin-transform-numeric-separator@7.25.7': + resolution: {integrity: sha512-8CbutzSSh4hmD+jJHIA8vdTNk15kAzOnFLVVgBSMGr28rt85ouT01/rezMecks9pkU939wDInImwCKv4ahU4IA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.24.7': - resolution: {integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==} + '@babel/plugin-transform-object-rest-spread@7.25.7': + resolution: {integrity: sha512-1JdVKPhD7Y5PvgfFy0Mv2brdrolzpzSoUq2pr6xsR+m+3viGGeHEokFKsCgOkbeFOQxfB1Vt2F0cPJLRpFI4Zg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-super@7.24.7': - resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} + '@babel/plugin-transform-object-super@7.25.7': + resolution: {integrity: sha512-pWT6UXCEW3u1t2tcAGtE15ornCBvopHj9Bps9D2DsH15APgNVOTwwczGckX+WkAvBmuoYKRCFa4DK+jM8vh5AA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-catch-binding@7.24.7': - resolution: {integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==} + '@babel/plugin-transform-optional-catch-binding@7.25.7': + resolution: {integrity: sha512-m9obYBA39mDPN7lJzD5WkGGb0GO54PPLXsbcnj1Hyeu8mSRz7Gb4b1A6zxNX32ZuUySDK4G6it8SDFWD1nCnqg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-chaining@7.24.8': - resolution: {integrity: sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==} + '@babel/plugin-transform-optional-chaining@7.25.7': + resolution: {integrity: sha512-h39agClImgPWg4H8mYVAbD1qP9vClFbEjqoJmt87Zen8pjqK8FTPUwrOXAvqu5soytwxrLMd2fx2KSCp2CHcNg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-parameters@7.24.7': - resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} + '@babel/plugin-transform-parameters@7.25.7': + resolution: {integrity: sha512-FYiTvku63me9+1Nz7TOx4YMtW3tWXzfANZtrzHhUZrz4d47EEtMQhzFoZWESfXuAMMT5mwzD4+y1N8ONAX6lMQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-methods@7.25.4': - resolution: {integrity: sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==} + '@babel/plugin-transform-private-methods@7.25.7': + resolution: {integrity: sha512-KY0hh2FluNxMLwOCHbxVOKfdB5sjWG4M183885FmaqWWiGMhRZq4DQRKH6mHdEucbJnyDyYiZNwNG424RymJjA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-property-in-object@7.24.7': - resolution: {integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==} + '@babel/plugin-transform-private-property-in-object@7.25.7': + resolution: {integrity: sha512-LzA5ESzBy7tqj00Yjey9yWfs3FKy4EmJyKOSWld144OxkTji81WWnUT8nkLUn+imN/zHL8ZQlOu/MTUAhHaX3g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-property-literals@7.24.7': - resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} + '@babel/plugin-transform-property-literals@7.25.7': + resolution: {integrity: sha512-lQEeetGKfFi0wHbt8ClQrUSUMfEeI3MMm74Z73T9/kuz990yYVtfofjf3NuA42Jy3auFOpbjDyCSiIkTs1VIYw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.24.7': - resolution: {integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==} + '@babel/plugin-transform-regenerator@7.25.7': + resolution: {integrity: sha512-mgDoQCRjrY3XK95UuV60tZlFCQGXEtMg8H+IsW72ldw1ih1jZhzYXbJvghmAEpg5UVhhnCeia1CkGttUvCkiMQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-reserved-words@7.24.7': - resolution: {integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==} + '@babel/plugin-transform-reserved-words@7.25.7': + resolution: {integrity: sha512-3OfyfRRqiGeOvIWSagcwUTVk2hXBsr/ww7bLn6TRTuXnexA+Udov2icFOxFX9abaj4l96ooYkcNN1qi2Zvqwng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-shorthand-properties@7.24.7': - resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} + '@babel/plugin-transform-shorthand-properties@7.25.7': + resolution: {integrity: sha512-uBbxNwimHi5Bv3hUccmOFlUy3ATO6WagTApenHz9KzoIdn0XeACdB12ZJ4cjhuB2WSi80Ez2FWzJnarccriJeA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.24.7': - resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} + '@babel/plugin-transform-spread@7.25.7': + resolution: {integrity: sha512-Mm6aeymI0PBh44xNIv/qvo8nmbkpZze1KvR8MkEqbIREDxoiWTi18Zr2jryfRMwDfVZF9foKh060fWgni44luw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-sticky-regex@7.24.7': - resolution: {integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==} + '@babel/plugin-transform-sticky-regex@7.25.7': + resolution: {integrity: sha512-ZFAeNkpGuLnAQ/NCsXJ6xik7Id+tHuS+NT+ue/2+rn/31zcdnupCdmunOizEaP0JsUmTFSTOPoQY7PkK2pttXw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-template-literals@7.24.7': - resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} + '@babel/plugin-transform-template-literals@7.25.7': + resolution: {integrity: sha512-SI274k0nUsFFmyQupiO7+wKATAmMFf8iFgq2O+vVFXZ0SV9lNfT1NGzBEhjquFmD8I9sqHLguH+gZVN3vww2AA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typeof-symbol@7.24.8': - resolution: {integrity: sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==} + '@babel/plugin-transform-typeof-symbol@7.25.7': + resolution: {integrity: sha512-OmWmQtTHnO8RSUbL0NTdtpbZHeNTnm68Gj5pA4Y2blFNh+V4iZR68V1qL9cI37J21ZN7AaCnkfdHtLExQPf2uA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.25.2': - resolution: {integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==} + '@babel/plugin-transform-typescript@7.25.7': + resolution: {integrity: sha512-VKlgy2vBzj8AmEzunocMun2fF06bsSWV+FvVXohtL6FGve/+L217qhHxRTVGHEDO/YR8IANcjzgJsd04J8ge5Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-escapes@7.24.7': - resolution: {integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==} + '@babel/plugin-transform-unicode-escapes@7.25.7': + resolution: {integrity: sha512-BN87D7KpbdiABA+t3HbVqHzKWUDN3dymLaTnPFAMyc8lV+KN3+YzNhVRNdinaCPA4AUqx7ubXbQ9shRjYBl3SQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-property-regex@7.24.7': - resolution: {integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==} + '@babel/plugin-transform-unicode-property-regex@7.25.7': + resolution: {integrity: sha512-IWfR89zcEPQGB/iB408uGtSPlQd3Jpq11Im86vUgcmSTcoWAiQMCTOa2K2yNNqFJEBVICKhayctee65Ka8OB0w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-regex@7.24.7': - resolution: {integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==} + '@babel/plugin-transform-unicode-regex@7.25.7': + resolution: {integrity: sha512-8JKfg/hiuA3qXnlLx8qtv5HWRbgyFx2hMMtpDDuU2rTckpKkGu4ycK5yYHwuEa16/quXfoxHBIApEsNyMWnt0g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-sets-regex@7.25.4': - resolution: {integrity: sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==} + '@babel/plugin-transform-unicode-sets-regex@7.25.7': + resolution: {integrity: sha512-YRW8o9vzImwmh4Q3Rffd09bH5/hvY0pxg+1H1i0f7APoUeg12G7+HhLj9ZFNIrYkgBXhIijPJ+IXypN0hLTIbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.25.4': - resolution: {integrity: sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==} + '@babel/preset-env@7.25.7': + resolution: {integrity: sha512-Gibz4OUdyNqqLj+7OAvBZxOD7CklCtMA5/j0JgUEwOnaRULsPDXmic2iKxL2DX2vQduPR5wH2hjZas/Vr/Oc0g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1420,41 +1393,26 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - '@babel/preset-typescript@7.24.7': - resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} + '@babel/preset-typescript@7.25.7': + resolution: {integrity: sha512-rkkpaXJZOFN45Fb+Gki0c+KMIglk4+zZXOoMJuyEK8y8Kkc8Jd3BDmP7qPsz0zQMJj+UD7EprF+AqAXcILnexw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/regjsgen@0.8.0': - resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} - - '@babel/runtime@7.25.0': - resolution: {integrity: sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==} + '@babel/runtime@7.25.7': + resolution: {integrity: sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.25.4': - resolution: {integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==} + '@babel/template@7.25.7': + resolution: {integrity: sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==} engines: {node: '>=6.9.0'} - '@babel/template@7.25.0': - resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} + '@babel/traverse@7.25.7': + resolution: {integrity: sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.25.3': - resolution: {integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.25.4': - resolution: {integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.25.2': - resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.25.4': - resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==} + '@babel/types@7.25.7': + resolution: {integrity: sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==} engines: {node: '>=6.9.0'} '@bcherny/json-schema-ref-parser@10.0.5-fork': @@ -1467,11 +1425,11 @@ packages: '@braintree/sanitize-url@7.1.0': resolution: {integrity: sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg==} - '@changesets/apply-release-plan@7.0.4': - resolution: {integrity: sha512-HLFwhKWayKinWAul0Vj+76jVx1Pc2v55MGPVjZ924Y/ROeSsBMFutv9heHmCUj48lJyRfOTJG5+ar+29FUky/A==} + '@changesets/apply-release-plan@7.0.5': + resolution: {integrity: sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==} - '@changesets/assemble-release-plan@6.0.3': - resolution: {integrity: sha512-bLNh9/Lgl1VwkjWZTq8JmRqH+hj7/Yzfz0jsQ/zJJ+FTmVqmqPj3szeKOri8O/hEM8JmHW019vh2gTO9iq5Cuw==} + '@changesets/assemble-release-plan@6.0.4': + resolution: {integrity: sha512-nqICnvmrwWj4w2x0fOhVj2QEGdlUuwVAwESrUo5HLzWMI1rE5SWfsr9ln+rDqWB6RQ2ZyaMZHUcU7/IRaUJS+Q==} '@changesets/changelog-git@0.2.0': resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} @@ -1479,45 +1437,45 @@ packages: '@changesets/changelog-github@0.5.0': resolution: {integrity: sha512-zoeq2LJJVcPJcIotHRJEEA2qCqX0AQIeFE+L21L8sRLPVqDhSXY8ZWAt2sohtBpFZkBwu+LUwMSKRr2lMy3LJA==} - '@changesets/cli@2.27.7': - resolution: {integrity: sha512-6lr8JltiiXPIjDeYg4iM2MeePP6VN/JkmqBsVA5XRiy01hGS3y629LtSDvKcycj/w/5Eur1rEwby/MjcYS+e2A==} + '@changesets/cli@2.27.9': + resolution: {integrity: sha512-q42a/ZbDnxPpCb5Wkm6tMVIxgeI9C/bexntzTeCFBrQEdpisQqk8kCHllYZMDjYtEc1ZzumbMJAG8H0Z4rdvjg==} hasBin: true - '@changesets/config@3.0.2': - resolution: {integrity: sha512-cdEhS4t8woKCX2M8AotcV2BOWnBp09sqICxKapgLHf9m5KdENpWjyrFNMjkLqGJtUys9U+w93OxWT0czorVDfw==} + '@changesets/config@3.0.3': + resolution: {integrity: sha512-vqgQZMyIcuIpw9nqFIpTSNyc/wgm/Lu1zKN5vECy74u95Qx/Wa9g27HdgO4NkVAaq+BGA8wUc/qvbvVNs93n6A==} '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} - '@changesets/get-dependents-graph@2.1.1': - resolution: {integrity: sha512-LRFjjvigBSzfnPU2n/AhFsuWR5DK++1x47aq6qZ8dzYsPtS/I5mNhIGAS68IAxh1xjO9BTtz55FwefhANZ+FCA==} + '@changesets/get-dependents-graph@2.1.2': + resolution: {integrity: sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==} '@changesets/get-github-info@0.6.0': resolution: {integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==} - '@changesets/get-release-plan@4.0.3': - resolution: {integrity: sha512-6PLgvOIwTSdJPTtpdcr3sLtGatT+Jr22+cQwEBJBy6wP0rjB4yJ9lv583J9fVpn1bfQlBkDa8JxbS2g/n9lIyA==} + '@changesets/get-release-plan@4.0.4': + resolution: {integrity: sha512-SicG/S67JmPTrdcc9Vpu0wSQt7IiuN0dc8iR5VScnnTVPfIaLvKmEGRvIaF0kcn8u5ZqLbormZNTO77bCEvyWw==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} - '@changesets/git@3.0.0': - resolution: {integrity: sha512-vvhnZDHe2eiBNRFHEgMiGd2CT+164dfYyrJDhwwxTVD/OW0FUD6G7+4DIx1dNwkwjHyzisxGAU96q0sVNBns0w==} + '@changesets/git@3.0.1': + resolution: {integrity: sha512-pdgHcYBLCPcLd82aRcuO0kxCDbw/yISlOtkmwmE8Odo1L6hSiZrBOsRl84eYG7DRCab/iHnOkWqExqc4wxk2LQ==} - '@changesets/logger@0.1.0': - resolution: {integrity: sha512-pBrJm4CQm9VqFVwWnSqKEfsS2ESnwqwH+xR7jETxIErZcfd1u2zBSqrHbRHR7xjhSgep9x2PSKFKY//FAshA3g==} + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} '@changesets/parse@0.4.0': resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} - '@changesets/pre@2.0.0': - resolution: {integrity: sha512-HLTNYX/A4jZxc+Sq8D1AMBsv+1qD6rmmJtjsCJa/9MSRybdxh0mjbTvE6JYZQ/ZiQ0mMlDOlGPXTm9KLTU3jyw==} + '@changesets/pre@2.0.1': + resolution: {integrity: sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==} - '@changesets/read@0.6.0': - resolution: {integrity: sha512-ZypqX8+/im1Fm98K4YcZtmLKgjs1kDQ5zHpc2U1qdtNBmZZfo/IBiG162RoP0CUF05tvp2y4IspH11PLnPxuuw==} + '@changesets/read@0.6.1': + resolution: {integrity: sha512-jYMbyXQk3nwP25nRzQQGa1nKLY0KfoOV7VLgwucI0bUO8t8ZLCr6LZmgjXsiKuRDc+5A6doKPr9w2d+FEJ55zQ==} - '@changesets/should-skip-package@0.1.0': - resolution: {integrity: sha512-FxG6Mhjw7yFStlSM7Z0Gmg3RiyQ98d/9VpQAZ3Fzr59dCOM9G6ZdYbjiSAt0XtFr9JR5U2tBaJWPjrkGGc618g==} + '@changesets/should-skip-package@0.1.1': + resolution: {integrity: sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==} '@changesets/types@4.1.0': resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} @@ -1525,8 +1483,8 @@ packages: '@changesets/types@6.0.0': resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} - '@changesets/write@0.3.1': - resolution: {integrity: sha512-SyGtMXzH3qFqlHKcvFY2eX+6b0NGiFcNav8AFsYwy5l8hejOeoeTDemu5Yjmke2V5jpzY+pBvM0vCCQ3gdZpfw==} + '@changesets/write@0.3.2': + resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} '@chevrotain/cst-dts-gen@11.0.3': resolution: {integrity: sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==} @@ -1547,73 +1505,44 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} - '@cspell/cspell-bundled-dicts@8.13.3': - resolution: {integrity: sha512-OfCxUBMyayxKyeDaUZG3LQpiyH8MFUbg9nbIZCGh2x8U6N0fHaP9uR6R+gPzdi/bJp32Kr+RC/Yebojd+AQCGA==} + '@cspell/cspell-bundled-dicts@8.14.4': + resolution: {integrity: sha512-JHZOpCJzN6fPBapBOvoeMxZbr0ZA11ZAkwcqM4w0lKoacbi6TwK8GIYf66hHvwLmMeav75TNXWE6aPTvBLMMqA==} engines: {node: '>=18'} - '@cspell/cspell-bundled-dicts@8.14.2': - resolution: {integrity: sha512-Kv2Utj/RTSxfufGXkkoTZ/3ErCsYWpCijtDFr/FwSsM7mC0PzLpdlcD9xjtgrJO5Kwp7T47iTG21U4Mwddyi8Q==} + '@cspell/cspell-json-reporter@8.14.4': + resolution: {integrity: sha512-gJ6tQbGCNLyHS2iIimMg77as5MMAFv3sxU7W6tjLlZp8htiNZS7fS976g24WbT/hscsTT9Dd0sNHkpo8K3nvVw==} engines: {node: '>=18'} - '@cspell/cspell-json-reporter@8.14.2': - resolution: {integrity: sha512-TZavcnNIZKX1xC/GNj80RgFVKHCT4pHT0qm9jCsQFH2QJfyCrUlkEvotKGSQ04lAyCwWg6Enq95qhouF8YbKUQ==} + '@cspell/cspell-pipe@8.14.4': + resolution: {integrity: sha512-CLLdouqfrQ4rqdQdPu0Oo+HHCU/oLYoEsK1nNPb28cZTFxnn0cuSPKB6AMPBJmMwdfJ6fMD0BCKNbEe1UNLHcw==} engines: {node: '>=18'} - '@cspell/cspell-pipe@8.13.3': - resolution: {integrity: sha512-6a9Zd+fDltgXoJ0fosWqEMx0UdXBXZ7iakhslMNPRmv7GhVAoHBoIXzMVilOE4kYT2Mh/9NM/QW/NbNEpneZIQ==} + '@cspell/cspell-resolver@8.14.4': + resolution: {integrity: sha512-s3uZyymJ04yn8+zlTp7Pt1WRSlAel6XVo+iZRxls3LSvIP819KK64DoyjCD2Uon0Vg9P/K7aAPt8GcxDcnJtgA==} engines: {node: '>=18'} - '@cspell/cspell-pipe@8.14.2': - resolution: {integrity: sha512-aWMoXZAXEre0/M9AYWOW33YyOJZ06i4vvsEpWBDWpHpWQEmsR/7cMMgld8Pp3wlEjIUclUAKTYmrZ61PFWU/og==} + '@cspell/cspell-service-bus@8.14.4': + resolution: {integrity: sha512-i3UG+ep63akNsDXZrtGgICNF3MLBHtvKe/VOIH6+L+NYaAaVHqqQvOY9MdUwt1HXh8ElzfwfoRp36wc5aAvt6g==} engines: {node: '>=18'} - '@cspell/cspell-resolver@8.13.3': - resolution: {integrity: sha512-vlwtMTEWsPPtWfktzT75eGQ0n+0M+9kN+89eSvUUYdCfvY9XAS6z+bTmhS2ULJgntgWtX6gUjABQK0PYYVedOg==} - engines: {node: '>=18'} - - '@cspell/cspell-resolver@8.14.2': - resolution: {integrity: sha512-pSyBsAvslaN0dx0pHdvECJEuFDDBJGAD6G8U4BVbIyj2OPk0Ox0HrZIj6csYxxoJERAgNO/q7yCPwa4j9NNFXg==} - engines: {node: '>=18'} - - '@cspell/cspell-service-bus@8.13.3': - resolution: {integrity: sha512-mFkeWXwGQSDxRiN6Kez77GaMNGNgG7T6o9UE42jyXEgf/bLJTpefbUy4fY5pU3p2mA0eoMzmnJX8l+TC5YJpbA==} - engines: {node: '>=18'} - - '@cspell/cspell-service-bus@8.14.2': - resolution: {integrity: sha512-WUF7xf3YgXYIqjmBwLcVugYIrYL4WfXchgSo9rmbbnOcAArzsK+HKfzb4AniZAJ1unxcIQ0JnVlRmnCAKPjjLg==} - engines: {node: '>=18'} - - '@cspell/cspell-types@8.13.3': - resolution: {integrity: sha512-lA5GbhLOL6FlKCWNMbooRFgNGfTsM6NJnHz60+EEN7XD9OgpFc7w+MBcK4aHsVCxcrIvnejIc8xQDqPnrdmN3w==} - engines: {node: '>=18'} - - '@cspell/cspell-types@8.14.2': - resolution: {integrity: sha512-MRY8MjBNOKGMDSkxAKueYAgVL43miO+lDcLCBBP+7cNXqHiUFMIZteONcGp3kJT0dWS04dN6lKAXvaNF0aWcng==} + '@cspell/cspell-types@8.14.4': + resolution: {integrity: sha512-VXwikqdHgjOVperVVCn2DOe8W3rPIswwZtMHfRYnagpzZo/TOntIjkXPJSfTtl/cFyx5DnCBsDH8ytKGlMeHkw==} engines: {node: '>=18'} '@cspell/dict-ada@4.0.2': resolution: {integrity: sha512-0kENOWQeHjUlfyId/aCM/mKXtkEgV0Zu2RhUXCBr4hHo9F9vph+Uu8Ww2b0i5a4ZixoIkudGA+eJvyxrG1jUpA==} - '@cspell/dict-aws@4.0.3': - resolution: {integrity: sha512-0C0RQ4EM29fH0tIYv+EgDQEum0QI6OrmjENC9u98pB8UcnYxGG/SqinuPxo+TgcEuInj0Q73MsBpJ1l5xUnrsw==} - '@cspell/dict-aws@4.0.4': resolution: {integrity: sha512-6AWI/Kkf+RcX/J81VX8+GKLeTgHWEr/OMhGk3dHQzWK66RaqDJCGDqi7494ghZKcBB7dGa3U5jcKw2FZHL/u3w==} - '@cspell/dict-bash@4.1.3': - resolution: {integrity: sha512-tOdI3QVJDbQSwPjUkOiQFhYcu2eedmX/PtEpVWg0aFps/r6AyjUQINtTgpqMYnYuq8O1QUIQqnpx21aovcgZCw==} - - '@cspell/dict-bash@4.1.4': - resolution: {integrity: sha512-W/AHoQcJYn3Vn/tUiXX2+6D/bhfzdDshwcbQWv9TdiNlXP9P6UJjDKWbxyA5ogJCsR2D0X9Kx11oV8E58siGKQ==} + '@cspell/dict-bash@4.1.5': + resolution: {integrity: sha512-YGim/h7E2U5HCCb2ckNufT6/yyWygt9nSZ5C7qw6oOD3bygbObqD1+rlPor1JW+YyO+3GwTIHE70uKEEU6VZYw==} '@cspell/dict-companies@3.1.4': resolution: {integrity: sha512-y9e0amzEK36EiiKx3VAA+SHQJPpf2Qv5cCt5eTUSggpTkiFkCh6gRKQ97rVlrKh5GJrqinDwYIJtTsxuh2vy2Q==} - '@cspell/dict-cpp@5.1.15': - resolution: {integrity: sha512-5X8SouN/qIUrBTcDEevnKU6G3cRSm3Vm7dQEcjHaptIWp+/2YMknIfYbnhKeR1G9V/sbQaY4CVsVAKEaehY+7Q==} - - '@cspell/dict-cpp@5.1.16': - resolution: {integrity: sha512-32fU5RkuOM55IRcxjByiSoKbjr+C4danDfYjHaQNRWdvjzJzci3fLDGA2wTXiclkgDODxGiV8LCTUwCz+3TNWA==} + '@cspell/dict-cpp@5.1.19': + resolution: {integrity: sha512-i/odUPNFLdqWisOktu6c4qjUR4k+P9Al2RCri3Wso9EFblp53xt/5jIUdGMdDDVQGqX7s/KLtdqNxNKqP3/d+w==} '@cspell/dict-cryptocurrencies@5.0.0': resolution: {integrity: sha512-Z4ARIw5+bvmShL+4ZrhDzGhnc9znaAGHOEMaB/GURdS/jdoreEDY34wdN0NtdLHDO5KO7GduZnZyqGdRoiSmYA==} @@ -1624,11 +1553,11 @@ packages: '@cspell/dict-css@4.0.13': resolution: {integrity: sha512-WfOQkqlAJTo8eIQeztaH0N0P+iF5hsJVKFuhy4jmARPISy8Efcv8QXk2/IVbmjJH0/ZV7dKRdnY5JFVXuVz37g==} - '@cspell/dict-dart@2.0.3': - resolution: {integrity: sha512-cLkwo1KT5CJY5N5RJVHks2genFkNCl/WLfj+0fFjqNR+tk3tBI1LY7ldr9piCtSFSm4x9pO1x6IV3kRUY1lLiw==} + '@cspell/dict-dart@2.2.1': + resolution: {integrity: sha512-yriKm7QkoPx3JPSSOcw6iX9gOb2N50bOo/wqWviqPYbhpMRh9Xiv6dkUy3+ot+21GuShZazO8X6U5+Vw67XEwg==} - '@cspell/dict-data-science@2.0.1': - resolution: {integrity: sha512-xeutkzK0eBe+LFXOFU2kJeAYO6IuFUc1g7iRLr7HeCmlC4rsdGclwGHh61KmttL3+YHQytYStxaRBdGAXWC8Lw==} + '@cspell/dict-data-science@2.0.2': + resolution: {integrity: sha512-VwAck6OZQVqrscKyOrvllixIugIPF+Q6YoFNvXZCPhHGtNyOAVraD3S7kOgPYBdUjgno4QbdMWm92BUPqL1QjQ==} '@cspell/dict-django@4.1.0': resolution: {integrity: sha512-bKJ4gPyrf+1c78Z0Oc4trEB9MuhcB+Yg+uTTWsvhY6O2ncFYbB/LbEZfqhfmmuK/XJJixXfI1laF2zicyf+l0w==} @@ -1636,9 +1565,6 @@ packages: '@cspell/dict-docker@1.1.7': resolution: {integrity: sha512-XlXHAr822euV36GGsl2J1CkBIVg3fZ6879ZOg5dxTIssuhUOCiV2BuzKZmt6aIFmcdPmR14+9i9Xq+3zuxeX0A==} - '@cspell/dict-dotnet@5.0.4': - resolution: {integrity: sha512-FCjeagwME0f5pg7AjhqidsenKnskFN2S6JMaMu5TZn2w+wPVpLnsqmcl0dtW6K/mDrutTYwC/gQFlLbDzoRw4g==} - '@cspell/dict-dotnet@5.0.5': resolution: {integrity: sha512-gjg0L97ee146wX47dnA698cHm85e7EOpf9mVrJD8DmEaqoo/k1oPy2g7c7LgKxK9XnqwoXxhLNnngPrwXOoEtQ==} @@ -1657,6 +1583,9 @@ packages: '@cspell/dict-filetypes@3.0.4': resolution: {integrity: sha512-IBi8eIVdykoGgIv5wQhOURi5lmCNJq0we6DvqKoPQJHthXbgsuO1qrHSiUVydMiQl/XvcnUWTMeAlVUlUClnVg==} + '@cspell/dict-flutter@1.0.0': + resolution: {integrity: sha512-W7k1VIc4KeV8BjEBxpA3cqpzbDWjfb7oXkEb0LecBCBp5Z7kcfnjT1YVotTx/U9PGyAOBhDaEdgZACVGNQhayw==} + '@cspell/dict-fonts@4.0.0': resolution: {integrity: sha512-t9V4GeN/m517UZn63kZPUYP3OQg5f0OBLSd3Md5CU3eH1IFogSvTzHHnz4Wqqbv8NNRiBZ3HfdY/pqREZ6br3Q==} @@ -1672,11 +1601,8 @@ packages: '@cspell/dict-git@3.0.0': resolution: {integrity: sha512-simGS/lIiXbEaqJu9E2VPoYW1OTC2xrwPPXNXFMa2uo/50av56qOuaxDrZ5eH1LidFXwoc8HROCHYeKoNrDLSw==} - '@cspell/dict-golang@6.0.11': - resolution: {integrity: sha512-BMFIDGh1HaFUe1cYBT1dotqyIQG2j3VkNntGQTBa/7i0aBnC5PBJDiAXnUeBHi0AVrz0hyAc7xtcK5KyKCEzwg==} - - '@cspell/dict-golang@6.0.12': - resolution: {integrity: sha512-LEPeoqd+4O+vceHF73S7D7+LYfrAjOvp4Dqzh4MT30ruzlQ77yHRSuYOJtrFN1GK5ntAt/ILSVOKg9sgsz1Llg==} + '@cspell/dict-golang@6.0.13': + resolution: {integrity: sha512-uBUWi+AjFpluB6qF0rsC1gGyooqXeKPUdWHSmSXW/DCnS5PBSjRW6VWWp8efc1Fanob0QJxiZiYlc4U7oxuG6Q==} '@cspell/dict-google@1.0.1': resolution: {integrity: sha512-dQr4M3n95uOhtloNSgB9tYYGXGGEGEykkFyRtfcp5pFuEecYUa0BSgtlGKx9RXVtJtKgR+yFT/a5uQSlt8WjqQ==} @@ -1687,8 +1613,8 @@ packages: '@cspell/dict-html-symbol-entities@4.0.0': resolution: {integrity: sha512-HGRu+48ErJjoweR5IbcixxETRewrBb0uxQBd6xFGcxbEYCX8CnQFTAmKI5xNaIt2PKaZiJH3ijodGSqbKdsxhw==} - '@cspell/dict-html@4.0.5': - resolution: {integrity: sha512-p0brEnRybzSSWi8sGbuVEf7jSTDmXPx7XhQUb5bgG6b54uj+Z0Qf0V2n8b/LWwIPJNd1GygaO9l8k3HTCy1h4w==} + '@cspell/dict-html@4.0.6': + resolution: {integrity: sha512-cLWHfuOhE4wqwC12up6Doxo2u1xxVhX1A8zriR4CUD+osFQzUIcBK1ykNXppga+rt1WyypaJdTU2eV6OpzYrgQ==} '@cspell/dict-java@5.0.7': resolution: {integrity: sha512-ejQ9iJXYIq7R09BScU2y5OUGrSqwcD+J5mHFOKbduuQ5s/Eh/duz45KOzykeMLI6KHPVxhBKpUPBWIsfewECpQ==} @@ -1717,50 +1643,35 @@ packages: '@cspell/dict-node@5.0.1': resolution: {integrity: sha512-lax/jGz9h3Dv83v8LHa5G0bf6wm8YVRMzbjJPG/9rp7cAGPtdrga+XANFq+B7bY5+jiSA3zvj10LUFCFjnnCCg==} - '@cspell/dict-npm@5.0.18': - resolution: {integrity: sha512-weMTyxWpzz19q4wv9n183BtFvdD5fCjtze+bFKpl+4rO/YlPhHL2cXLAeexJz/VDSBecwX4ybTZYoknd1h2J4w==} - - '@cspell/dict-npm@5.1.0': - resolution: {integrity: sha512-731gE9lO8hWb4gUytUk4kycEkAmSf0p8YejB4ZWoyQRvdNcu8p4U5S/yMS+uBPohHtxhSDq0K/vi/QaPm5HYFA==} + '@cspell/dict-npm@5.1.5': + resolution: {integrity: sha512-oAOGWuJYU3DlO+cAsStKMWN8YEkBue25cRC9EwdiL5Z84nchU20UIoYrLfIQejMlZca+1GyrNeyxRAgn4KiivA==} '@cspell/dict-php@4.0.10': resolution: {integrity: sha512-NfTZdp6kcZDF1PvgQ6cY0zE4FUO5rSwNmBH/iwCBuaLfJAFQ97rgjxo+D2bic4CFwNjyHutnHPtjJBRANO5XQw==} - '@cspell/dict-php@4.0.9': - resolution: {integrity: sha512-Rg6+hc8zexiMyT5sXzYdkgr5irYCxl8Rn/OKgUOy7rMN7eD010VefGm62RG6jIBpUIUYFM00Qpc5RA+H4L0KyQ==} - - '@cspell/dict-powershell@5.0.5': - resolution: {integrity: sha512-3JVyvMoDJesAATYGOxcUWPbQPUvpZmkinV3m8HL1w1RrjeMVXXuK7U1jhopSneBtLhkU+9HKFwgh9l9xL9mY2Q==} - - '@cspell/dict-powershell@5.0.6': - resolution: {integrity: sha512-BSi9tmnT7jgNsH5SaHSg70aw+4YwTjkkZBfhHtin0r6AMV2RaiLzsBPvzZGXOcm0yTvl975HYoKMqflXIlk2RA==} + '@cspell/dict-powershell@5.0.10': + resolution: {integrity: sha512-U4H0zm94sNK+YP7jSFb7xb160XLf2dKIPVt5sOYctKlEyR9M16sP8FHbyWV2Yp1YtxXugoNdeCm2vwGEDAd8sg==} '@cspell/dict-public-licenses@2.0.8': resolution: {integrity: sha512-Sup+tFS7cDV0fgpoKtUqEZ6+fA/H+XUgBiqQ/Fbs6vUE3WCjJHOIVsP+udHuyMH7iBfJ4UFYOYeORcY4EaKdMg==} - '@cspell/dict-python@4.2.4': - resolution: {integrity: sha512-sCtLBqMreb+8zRW2bXvFsfSnRUVU6IFm4mT6Dc4xbz0YajprbaPPh/kOUTw5IJRP8Uh+FFb7Xp2iH03CNWRq/A==} - - '@cspell/dict-python@4.2.6': - resolution: {integrity: sha512-Hkz399qDGEbfXi9GYa2hDl7GahglI86JmS2F1KP8sfjLXofUgtnknyC5NWc86nzHcP38pZiPqPbTigyDYw5y8A==} + '@cspell/dict-python@4.2.8': + resolution: {integrity: sha512-4y5dynLiajvowhB3PqlcwJ2C4okK1y2Hombec1+TGcV9sUBfo8FYNw6VRFUUrpsxO+Ut/3ncIifdZS5/zAWi5w==} '@cspell/dict-r@2.0.1': resolution: {integrity: sha512-KCmKaeYMLm2Ip79mlYPc8p+B2uzwBp4KMkzeLd5E6jUlCL93Y5Nvq68wV5fRLDRTf7N1LvofkVFWfDcednFOgA==} - '@cspell/dict-ruby@5.0.3': - resolution: {integrity: sha512-V1xzv9hN6u8r6SM4CkYdsxs4ov8gjXXo0Twfx5kWhLXbEVxTXDMt7ohLTqpy2XlF5mutixZdbHMeFiAww8v+Ug==} + '@cspell/dict-ruby@5.0.4': + resolution: {integrity: sha512-URw0jScj5pv8sKCVLNnde11qVCQR442rUpSd12u46Swl+5qBaSdnOUoCWQk419kd9/dpC6bB/3l4kOSY2fdYHw==} - '@cspell/dict-rust@4.0.5': - resolution: {integrity: sha512-DIvlPRDemjKQy8rCqftAgGNZxY5Bg+Ps7qAIJjxkSjmMETyDgl0KTVuaJPt7EK4jJt6uCZ4ILy96npsHDPwoXA==} + '@cspell/dict-rust@4.0.6': + resolution: {integrity: sha512-Buzy9PfLbdRPibSth8CV1D8ZsYqybo26yNIlAN+8ehU0pSBss0Jv4aleL4vKQ3FjouXeAC27rtEsLd7yaMZTog==} '@cspell/dict-scala@5.0.3': resolution: {integrity: sha512-4yGb4AInT99rqprxVNT9TYb1YSpq58Owzq7zi3ZS5T0u899Y4VsxsBiOgHnQ/4W+ygi+sp+oqef8w8nABR2lkg==} - '@cspell/dict-software-terms@4.0.11': - resolution: {integrity: sha512-L4qtowZEnPGFz1BXIDwcdgF/Dgr4oMKO0HT98NqXafxZ8KGSHe/QBfisnHd/flceNHaw7Sd7iRW0ICJtXiWfLA==} - - '@cspell/dict-software-terms@4.1.1': - resolution: {integrity: sha512-JkXkULoOWYwtdsQ+/6dPtGi2pcrjDQ0NYsTkKt1uFCiITDb+QZkQhAG0kOP69jK6vhSQwUAH3z7jiYWqoK5TKw==} + '@cspell/dict-software-terms@4.1.7': + resolution: {integrity: sha512-+fFTALseXszDN8/khonF1DpTcYzwyNqYxhATLakr7CUPtUCO1fCH4lidMtBN4UtPVpE6tbjc5D8tj51PJxEOcw==} '@cspell/dict-sql@2.1.5': resolution: {integrity: sha512-FmxanytHXss7GAWAXmgaxl3icTCW7YxlimyOSPNfm+njqeUDjw3kEv4mFNDDObBJv8Ec5AWCbUDkWIpkE3IpKg==} @@ -1771,11 +1682,8 @@ packages: '@cspell/dict-swift@2.0.1': resolution: {integrity: sha512-gxrCMUOndOk7xZFmXNtkCEeroZRnS2VbeaIPiymGRHj5H+qfTAzAKxtv7jJbVA3YYvEzWcVE2oKDP4wcbhIERw==} - '@cspell/dict-terraform@1.0.0': - resolution: {integrity: sha512-Ak+vy4HP/bOgzf06BAMC30+ZvL9mzv21xLM2XtfnBLTDJGdxlk/nK0U6QT8VfFLqJ0ZZSpyOxGsUebWDCTr/zQ==} - - '@cspell/dict-terraform@1.0.1': - resolution: {integrity: sha512-29lmUUnZgPh+ieZ5hunick8hzNIpNRtiJh9vAusNskPCrig3RTW6u7F+GG1a8uyslbzSw+Irjf40PTOan1OJJA==} + '@cspell/dict-terraform@1.0.2': + resolution: {integrity: sha512-UZdJwWIpib2Rx02w6vtXTU3z+M/VMZU0F1dhSL3Ab9otQsFntT8U1CX7wBSqQCLg8bJiCfnUyVvMK3UBm3SR8A==} '@cspell/dict-typescript@3.1.6': resolution: {integrity: sha512-1beC6O4P/j23VuxX+i0+F7XqPVc3hhiAzGJHEKqnWf5cWAXQtg0xz3xQJ5MvYx2a7iLaSa+lu7+05vG9UHyu9Q==} @@ -1783,42 +1691,30 @@ packages: '@cspell/dict-vue@3.0.0': resolution: {integrity: sha512-niiEMPWPV9IeRBRzZ0TBZmNnkK3olkOPYxC1Ny2AX4TGlYRajcW0WUtoSHmvvjZNfWLSg2L6ruiBeuPSbjnG6A==} - '@cspell/dynamic-import@8.13.3': - resolution: {integrity: sha512-YN83CFWnMkt9B0q0RBadfEoptUaDRqBikh8b91MOQ0haEnUo6t57j4jAaLnbIEP4ynzMhgruWFKpIC/QaEtCuA==} + '@cspell/dynamic-import@8.14.4': + resolution: {integrity: sha512-GjKsBJvPXp4dYRqsMn7n1zpnKbnpfJnlKLOVeoFBh8fi4n06G50xYr+G25CWX1WT3WFaALAavvVICEUPrVsuqg==} engines: {node: '>=18.0'} - '@cspell/dynamic-import@8.14.2': - resolution: {integrity: sha512-5MbqtIligU7yPwHWU/5yFCgMvur4i1bRAF1Cy8y2dDtHsa204S/w/SaXs+51EFLp2eNbCiBisCBrwJFT7R1RxA==} - engines: {node: '>=18.0'} - - '@cspell/eslint-plugin@8.13.3': - resolution: {integrity: sha512-wb4+WoirtqP4ijcLhCXWbgfE94ggU9D+ENMjTldBNABjcoDse1UyPIR1gSM/oNAAOLaSLtXbeOx7tnWuurjVaQ==} + '@cspell/eslint-plugin@8.14.4': + resolution: {integrity: sha512-Wv6Jkttp/rsEm1nadLFQrUrYg9nTWQFwJu47KO2cfWP39TeH0zXQpmyas1xNlcDx5QJ9JJw9urTT/iw2tsHeRA==} engines: {node: '>=18'} peerDependencies: eslint: ^7 || ^8 || ^9 - '@cspell/filetypes@8.14.2': - resolution: {integrity: sha512-ZevArA0mWeVTTqHicxCPZIAeCibpY3NwWK/x6d1Lgu7RPk/daoGAM546Q2SLChFu+r10tIH7pRG212A6Q9ihPA==} + '@cspell/filetypes@8.14.4': + resolution: {integrity: sha512-qd68dD7xTA4Mnf/wjIKYz2SkiTBshIM+yszOUtLa06YJm0aocoNQ25FHXyYEQYm9NQXCYnRWWA02sFMGs8Sv/w==} engines: {node: '>=18'} - '@cspell/strong-weak-map@8.13.3': - resolution: {integrity: sha512-/QYUEthesPuDarOHa6kcWKJmVq0HIotjPrmAWQ5QpH+dDik1Qin4G/9QdnWX75ueR4DC4WFjBNBU14C4TVSwHQ==} + '@cspell/strong-weak-map@8.14.4': + resolution: {integrity: sha512-Uyfck64TfVU24wAP3BLGQ5EsAfzIZiLfN90NhttpEM7GlOBmbGrEJd4hNOwfpYsE/TT80eGWQVPRTLr5SDbXFA==} engines: {node: '>=18'} - '@cspell/strong-weak-map@8.14.2': - resolution: {integrity: sha512-7sRzJc392CQYNNrtdPEfOHJdRqsqf6nASCtbS5A9hL2UrdWQ4uN7r/D+Y1HpuizwY9eOkZvarcFfsYt5wE0Pug==} - engines: {node: '>=18'} - - '@cspell/url@8.13.3': - resolution: {integrity: sha512-hsxoTnZHwtdR2x9QEE6yfDBB1LUwAj67o1GyKTvI8A2OE/AfzAttirZs+9sxgOGWoBdTOxM9sMLtqB3SxtDB3A==} + '@cspell/url@8.14.4': + resolution: {integrity: sha512-htHhNF8WrM/NfaLSWuTYw0NqVgFRVHYSyHlRT3i/Yv5xvErld8Gw7C6ldm+0TLjoGlUe6X1VV72JSir7+yLp/Q==} engines: {node: '>=18.0'} - '@cspell/url@8.14.2': - resolution: {integrity: sha512-YmWW+B/2XQcCynLpiAQF77Bitm5Cynw3/BICZkbdveKjJkUzEmXB+U2qWuwXOyU8xUYuwkP63YM8McnI567rUA==} - engines: {node: '>=18.0'} - - '@cypress/code-coverage@3.12.45': - resolution: {integrity: sha512-QRvdc9Zmner/CxQ1F5jcNVZR8P8VrRTyE8THcisxnB6D3AMIKKSmjYUGH6OnWBDF/vi3CqimuMSbrUfzmPzmhw==} + '@cypress/code-coverage@3.13.4': + resolution: {integrity: sha512-4Bne95y/Vkye9tfctyiKjYHirA/0LZq7Z5MiCrrT2mlyWfaOSnPeUHG84BdxuycgVOLzMFxqvc+uNQO5lupvTg==} peerDependencies: '@babel/core': ^7.0.1 '@babel/preset-env': ^7.0.0 @@ -1826,8 +1722,8 @@ packages: cypress: '*' webpack: ^4 || ^5 - '@cypress/request@3.0.1': - resolution: {integrity: sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==} + '@cypress/request@3.0.5': + resolution: {integrity: sha512-v+XHd9XmWbufxF1/bTaVm2yhbxY+TB4YtWRqF2zaXBlDNMkls34KiATz0AVDLavL3iB6bQk9/7n3oY1EoLSWGA==} engines: {node: '>= 6'} '@cypress/webpack-preprocessor@6.0.2': @@ -1841,18 +1737,22 @@ packages: '@cypress/xvfb@1.2.4': resolution: {integrity: sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==} + '@dependents/detective-less@5.0.0': + resolution: {integrity: sha512-D/9dozteKcutI5OdxJd8rU+fL6XgaaRg60sPPJWkT33OCiRfkCu5wO5B/yXTaaL2e6EB0lcCBGe5E0XscZCvvQ==} + engines: {node: '>=18'} + '@discoveryjs/json-ext@0.5.7': resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} - '@docsearch/css@3.6.1': - resolution: {integrity: sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg==} + '@docsearch/css@3.6.2': + resolution: {integrity: sha512-vKNZepO2j7MrYBTZIGXvlUOIR+v9KRf70FApRgovWrj3GTs1EITz/Xb0AOlm1xsQBp16clVZj1SY/qaOJbQtZw==} - '@docsearch/js@3.6.1': - resolution: {integrity: sha512-erI3RRZurDr1xES5hvYJ3Imp7jtrXj6f1xYIzDzxiS7nNBufYWPbJwrmMqWC5g9y165PmxEmN9pklGCdLi0Iqg==} + '@docsearch/js@3.6.2': + resolution: {integrity: sha512-pS4YZF+VzUogYrkblCucQ0Oy2m8Wggk8Kk7lECmZM60hTbaydSIhJTTiCrmoxtBqV8wxORnOqcqqOfbmkkQEcA==} - '@docsearch/react@3.6.1': - resolution: {integrity: sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==} + '@docsearch/react@3.6.2': + resolution: {integrity: sha512-rtZce46OOkVflCQH71IdbXSFK+S8iJZlUF56XBW5rIgx/eG5qoomC7Ag3anZson1bBac/JFQn7XOBfved/IMRA==} peerDependencies: '@types/react': '>= 16.8.0 < 19.0.0' react: '>= 16.8.0 < 19.0.0' @@ -1868,11 +1768,11 @@ packages: search-insights: optional: true - '@emnapi/runtime@1.2.0': - resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} + '@emnapi/runtime@1.3.0': + resolution: {integrity: sha512-XMBySMuNZs3DM96xcJmLW4EfGnf+uGmFNjzpehMjuX5PLB5j87ar2Zc4e3PVeZ3I5g3tYtAqskB28manlF69Zw==} - '@es-joy/jsdoccomment@0.46.0': - resolution: {integrity: sha512-C3Axuq1xd/9VqFZpW4YAzOx5O9q/LP46uIQy/iNDpHG3fmPa6TBtvfglMCs3RBiBxAIi0Go97r8+jvTt55XMyQ==} + '@es-joy/jsdoccomment@0.48.0': + resolution: {integrity: sha512-G6QUWIcC+KvSwXNsJyDTHvqUdNoAVJPPgkc3+Uk4WBKqZvoXhlvazOgm9aL0HwihJLQf0l+tOE2UFzXBqCqgDw==} engines: {node: '>=16'} '@esbuild/aix-ppc64@0.21.5': @@ -2163,43 +2063,61 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.11.0': - resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} + '@eslint-community/regexpp@4.11.1': + resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.17.1': - resolution: {integrity: sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==} + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.6.0': + resolution: {integrity: sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.1.0': resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.8.0': - resolution: {integrity: sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==} + '@eslint/js@9.12.0': + resolution: {integrity: sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.4': resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@fastify/ajv-compiler@1.1.0': - resolution: {integrity: sha512-gvCOUNpXsWrIQ3A4aXCLIdblL0tDq42BG/2Xw7oxbil9h11uow10ztS2GuFazNBfjbrsZ5nl+nPl5jDSjj5TSg==} + '@eslint/plugin-kit@0.2.0': + resolution: {integrity: sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@fastify/error@2.0.0': - resolution: {integrity: sha512-wI3fpfDT0t7p8E6dA2eTECzzOd+bZsZCJ2Hcv+Onn2b7ZwK3RwD27uW2QDaMtQhAfWQQP+WNK7nKf0twLsBf9w==} + '@fastify/ajv-compiler@3.6.0': + resolution: {integrity: sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==} - '@floating-ui/core@1.6.7': - resolution: {integrity: sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==} + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} - '@floating-ui/dom@1.6.10': - resolution: {integrity: sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==} + '@fastify/error@3.4.1': + resolution: {integrity: sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==} - '@floating-ui/utils@0.2.7': - resolution: {integrity: sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==} + '@fastify/fast-json-stringify-compiler@4.3.0': + resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} - '@floating-ui/vue@1.1.4': - resolution: {integrity: sha512-ammH7T3vyCx7pmm9OF19Wc42zrGnUw0QvLoidgypWsCLJMtGXEwY7paYIHO+K+oLC3mbWpzIHzeTVienYenlNg==} + '@fastify/merge-json-schemas@0.1.1': + resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==} + + '@floating-ui/core@1.6.8': + resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==} + + '@floating-ui/dom@1.6.11': + resolution: {integrity: sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==} + + '@floating-ui/utils@0.2.8': + resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==} + + '@floating-ui/vue@1.1.5': + resolution: {integrity: sha512-ynL1p5Z+woPVSwgMGqeDrx6HrJfGIDzFyESFkyqJKilGW1+h/8yVY29Khn0LaU6wHBRwZ13ntG6reiHWK6jyzw==} '@hapi/hoek@9.3.0': resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} @@ -2207,8 +2125,8 @@ packages: '@hapi/topo@5.1.0': resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} - '@headlessui-float/vue@0.14.3': - resolution: {integrity: sha512-eIX+zawgy/8ijZM7t7GfNDeEZpL068wTJ3U+gxSepO5NprgOUijHzG3TBFhERbsP4dDq3i0Bs7EaKbk+W57FOg==} + '@headlessui-float/vue@0.14.4': + resolution: {integrity: sha512-MSyWCxUTueeex+veRCf++q4KM/fa4HOe9HDttzGrtgVDBULkGduFK6ItJh7EHJp2U/dY7qpyDUqp2KCHpCEplw==} peerDependencies: '@headlessui/vue': ^1.0.0 vue: ^3.0.0 @@ -2219,31 +2137,36 @@ packages: peerDependencies: tailwindcss: ^3.0 - '@headlessui/vue@1.7.22': - resolution: {integrity: sha512-Hoffjoolq1rY+LOfJ+B/OvkhuBXXBFgd8oBlN+l1TApma2dB0En0ucFZrwQtb33SmcCqd32EQd0y07oziXWNYg==} + '@headlessui/vue@1.7.23': + resolution: {integrity: sha512-JzdCNqurrtuu0YW6QaDtR2PIYCKPUWq28csDyMvN4zmGccmE7lz40Is6hc3LA4HFeCI7sekZ/PQMTNmn9I/4Wg==} engines: {node: '>=10'} peerDependencies: vue: ^3.2.0 + '@humanfs/core@0.19.0': + resolution: {integrity: sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.5': + resolution: {integrity: sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==} + engines: {node: '>=18.18.0'} + '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/retry@0.3.0': - resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} engines: {node: '>=18.18'} - '@iconify-json/carbon@1.1.37': - resolution: {integrity: sha512-Hj9oZtRmN63yt29YovqgqOJQhaoVMNMTkFLT3HKAJm4HjvI405Juez5UfdysYmLjF708U7gJNx4U6K1k5+fTBw==} + '@iconify-json/carbon@1.2.1': + resolution: {integrity: sha512-dIMY6OOY9LnwR3kOqAtfz4phGFG+KNfESEwSL6muCprBelSlSPpRXtdqvEEO/qWhkf5AJ9hWrOV3Egi5Z2IuKA==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - '@iconify/utils@2.1.30': - resolution: {integrity: sha512-bY0IO5xLOlbzJBnjWLxknp6Sss3yla03sVY9VeUz9nT6dbc+EGKlLfCt+6uytJnWm5CUvTF/BNotsLWF7kI61A==} - - '@iconify/utils@2.1.32': - resolution: {integrity: sha512-LeifFZPPKu28O3AEDpYJNdEbvS4/ojAPyIW+pF/vUpJTYnbTiXUHkCh0bwgFRzKvdpb8H4Fbfd/742++MF4fPQ==} + '@iconify/utils@2.1.33': + resolution: {integrity: sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==} '@img/sharp-darwin-arm64@0.33.5': resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} @@ -2490,8 +2413,8 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@polka/url@1.0.0-next.25': - resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} + '@polka/url@1.0.0-next.28': + resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} '@rollup/plugin-babel@5.3.1': resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} @@ -2504,8 +2427,8 @@ packages: '@types/babel__core': optional: true - '@rollup/plugin-node-resolve@15.2.3': - resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + '@rollup/plugin-node-resolve@15.3.0': + resolution: {integrity: sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^2.78.0||^3.0.0||^4.0.0 @@ -2546,8 +2469,8 @@ packages: peerDependencies: rollup: ^1.20.0||^2.0.0 - '@rollup/pluginutils@5.1.0': - resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + '@rollup/pluginutils@5.1.2': + resolution: {integrity: sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -2555,91 +2478,103 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.21.1': - resolution: {integrity: sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==} + '@rollup/rollup-android-arm-eabi@4.24.0': + resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.21.1': - resolution: {integrity: sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==} + '@rollup/rollup-android-arm64@4.24.0': + resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.21.1': - resolution: {integrity: sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==} + '@rollup/rollup-darwin-arm64@4.24.0': + resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.21.1': - resolution: {integrity: sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==} + '@rollup/rollup-darwin-x64@4.24.0': + resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.21.1': - resolution: {integrity: sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.24.0': + resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.21.1': - resolution: {integrity: sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==} + '@rollup/rollup-linux-arm-musleabihf@4.24.0': + resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.21.1': - resolution: {integrity: sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==} + '@rollup/rollup-linux-arm64-gnu@4.24.0': + resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.21.1': - resolution: {integrity: sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==} + '@rollup/rollup-linux-arm64-musl@4.24.0': + resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.21.1': - resolution: {integrity: sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==} + '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': + resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.21.1': - resolution: {integrity: sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==} + '@rollup/rollup-linux-riscv64-gnu@4.24.0': + resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.21.1': - resolution: {integrity: sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==} + '@rollup/rollup-linux-s390x-gnu@4.24.0': + resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.21.1': - resolution: {integrity: sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==} + '@rollup/rollup-linux-x64-gnu@4.24.0': + resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.21.1': - resolution: {integrity: sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==} + '@rollup/rollup-linux-x64-musl@4.24.0': + resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.21.1': - resolution: {integrity: sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==} + '@rollup/rollup-win32-arm64-msvc@4.24.0': + resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.21.1': - resolution: {integrity: sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==} + '@rollup/rollup-win32-ia32-msvc@4.24.0': + resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.21.1': - resolution: {integrity: sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==} + '@rollup/rollup-win32-x64-msvc@4.24.0': + resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==} cpu: [x64] os: [win32] - '@shikijs/core@1.14.1': - resolution: {integrity: sha512-KyHIIpKNaT20FtFPFjCQB5WVSTpLR/n+jQXhWHWVUMm9MaOaG9BGOG0MSyt7yA4+Lm+4c9rTc03tt3nYzeYSfw==} + '@shikijs/core@1.22.0': + resolution: {integrity: sha512-S8sMe4q71TJAW+qG93s5VaiihujRK6rqDFqBnxqvga/3LvqHEnxqBIOPkt//IdXVtHkQWKu4nOQNk0uBGicU7Q==} - '@shikijs/transformers@1.14.1': - resolution: {integrity: sha512-JJqL8QBVCJh3L61jqqEXgFq1cTycwjcGj7aSmqOEsbxnETM9hRlaB74QuXvY/fVJNjbNt8nvWo0VwAXKvMSLRg==} + '@shikijs/engine-javascript@1.22.0': + resolution: {integrity: sha512-AeEtF4Gcck2dwBqCFUKYfsCq0s+eEbCEbkUuFou53NZ0sTGnJnJ/05KHQFZxpii5HMXbocV9URYVowOP2wH5kw==} + + '@shikijs/engine-oniguruma@1.22.0': + resolution: {integrity: sha512-5iBVjhu/DYs1HB0BKsRRFipRrD7rqjxlWTj4F2Pf+nQSPqc3kcyqFFeZXnBMzDf0HdqaFVvhDRAGiYNvyLP+Mw==} + + '@shikijs/transformers@1.22.0': + resolution: {integrity: sha512-k7iMOYuGQA62KwAuJOQBgH2IQb5vP8uiB3lMvAMGUgAMMurePOx3Z7oNqJdcpxqZP6I9cc7nc4DNqSKduCxmdg==} + + '@shikijs/types@1.22.0': + resolution: {integrity: sha512-Fw/Nr7FGFhlQqHfxzZY8Cwtwk5E9nKDUgeLjZgt3UuhcM3yJR9xj3ZGNravZZok8XmEZMiYkSMTPlPkULB8nww==} + + '@shikijs/vscode-textmate@9.3.0': + resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==} '@sideway/address@4.1.5': resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} @@ -2674,11 +2609,11 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} - '@tanstack/virtual-core@3.10.4': - resolution: {integrity: sha512-yHyli4RHVsI+eJ0RjmOsjA9RpHp3/Zah9t+iRjmFa72dq00TeG/NwuLYuCV6CB4RkWD4i5RD421j1eb6BdKgvQ==} + '@tanstack/virtual-core@3.10.8': + resolution: {integrity: sha512-PBu00mtt95jbKFi6Llk9aik8bnR3tR/oQP1o3TSi+iG//+Q2RTIzCEgKkHG8BB86kxMNW6O8wku+Lmi+QFR6jA==} - '@tanstack/vue-virtual@3.10.4': - resolution: {integrity: sha512-oikrjnC7BnUCmqh5ptemclUK6EtJj48AdLcJx1t2fTLQyu+60Alo6gPGC3cANgmbEP/1C9DptbeMcm5AAjyBVg==} + '@tanstack/vue-virtual@3.10.8': + resolution: {integrity: sha512-DB5QA8c/LfqOqIUCpSs3RdOTVroRRdqeHMqBkYrcashSZtOzIv8xbiqHgg7RYxDfkH5F3Y+e0MkuuyGNDVB0BQ==} peerDependencies: vue: ^2.7.0 || ^3.0.0 @@ -2725,8 +2660,8 @@ packages: '@types/cytoscape-fcose@2.2.4': resolution: {integrity: sha512-QwWtnT8HI9h+DHhG5krGc1ZY0Ex+cn85MvX96ZNAjSxuXiZDnjIZW/ypVkvvubTjIY4rSdkJY1D/Nsn8NDpmAw==} - '@types/cytoscape@3.21.5': - resolution: {integrity: sha512-fzYT3vqY5J4gxVXDOsCgDpm0ZdU8bQq+wCv0ucS0MSTtvQdjs3lcb2VetJiUSAd4WBgouqizI+JT1f8Yc6eY7Q==} + '@types/cytoscape@3.21.8': + resolution: {integrity: sha512-6Bo9ZDrv0vfwe8Sg/ERc5VL0yU0gYvP4dgZi0fAXYkKHfyHaNqWRMcwYm3mu4sLsXbB8ZuXE75sR7qnaOL5JgQ==} '@types/d3-array@3.2.1': resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} @@ -2803,8 +2738,8 @@ packages: '@types/d3-scale@4.0.8': resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==} - '@types/d3-selection@3.0.10': - resolution: {integrity: sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==} + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} '@types/d3-shape@1.3.12': resolution: {integrity: sha512-8oMzcd4+poSLGgV0R1Q1rOlx/xdmozS4Xab7np0eamFFUYq71AU9pOCJEFnkXW2aI/oXdVYJzw6pssbSut7Z9Q==} @@ -2821,8 +2756,8 @@ packages: '@types/d3-timer@3.0.2': resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} - '@types/d3-transition@3.0.8': - resolution: {integrity: sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==} + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} '@types/d3-zoom@3.0.8': resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} @@ -2836,20 +2771,17 @@ packages: '@types/dompurify@3.0.5': resolution: {integrity: sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==} - '@types/eslint-scope@3.7.7': - resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} - - '@types/eslint@9.6.0': - resolution: {integrity: sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==} - '@types/estree@0.0.39': resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - '@types/express-serve-static-core@4.19.5': - resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} + '@types/express-serve-static-core@4.19.6': + resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} + + '@types/express-serve-static-core@5.0.0': + resolution: {integrity: sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==} '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} @@ -2878,8 +2810,8 @@ packages: '@types/http-errors@2.0.4': resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} - '@types/http-proxy@1.17.14': - resolution: {integrity: sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==} + '@types/http-proxy@1.17.15': + resolution: {integrity: sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==} '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -2911,8 +2843,8 @@ packages: '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} - '@types/lodash@4.17.7': - resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} + '@types/lodash@4.17.10': + resolution: {integrity: sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==} '@types/markdown-it@12.2.3': resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} @@ -2947,17 +2879,11 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@18.19.47': - resolution: {integrity: sha512-1f7dB3BL/bpd9tnDJrrHb66Y+cVrhxSOTGorRNdHwYTUlTay3HuTDPKo9a/4vX9pMQkhYBcAbL4jQdNlhCFP9A==} + '@types/node@18.19.55': + resolution: {integrity: sha512-zzw5Vw52205Zr/nmErSEkN5FLqXPuKX/k5d1D7RKHATGqU7y6YfX9QxZraUzUrFGqH6XzOzG196BC35ltJC4Cw==} - '@types/node@20.14.14': - resolution: {integrity: sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==} - - '@types/node@20.16.2': - resolution: {integrity: sha512-91s/n4qUPV/wg8eE9KHYW1kouTfDk2FPGjXbBMfRWP/2vg1rCXNQL1OCabwGs0XSdukuK+MwCDXE30QpSeMUhQ==} - - '@types/node@22.5.1': - resolution: {integrity: sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==} + '@types/node@20.16.11': + resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -2969,8 +2895,8 @@ packages: resolution: {integrity: sha512-mFMBfMOz8QxhYVbuINtswBp9VL2b4Y0QqYHwqLz3YbgtfAcat2Dl6Y1o4e22S/OVE6Ebl9m7wWiMT2lSbAs1wA==} deprecated: This is a stub types definition. prettier provides its own type definitions, so you do not need this installed. - '@types/qs@6.9.15': - resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + '@types/qs@6.9.16': + resolution: {integrity: sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==} '@types/ramda@0.28.25': resolution: {integrity: sha512-HrQNqQAGcITpn9HAJFamDxm7iZeeXiP/95pN5OMbNniDjzCCeOHbBKNGmUy8NRi0fhYS+/cXeo91MFC+06gbow==} @@ -2990,9 +2916,6 @@ packages: '@types/rollup-plugin-visualizer@4.2.4': resolution: {integrity: sha512-BW4Q6D1Qy5gno5qHWrnMDC2dOe/TAKXvqCpckOggCCu+XpS+ZZJJ1lq1+K3bvYccoO3Y7f5kglbFAgYGqCgULg==} - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - '@types/send@0.17.4': resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} @@ -3023,11 +2946,8 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - '@types/unist@2.0.10': - resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} - - '@types/unist@3.0.2': - resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -3047,14 +2967,14 @@ packages: '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - '@types/yargs@17.0.32': - resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.0.1': - resolution: {integrity: sha512-5g3Y7GDFsJAnY4Yhvk8sZtFfV6YNF2caLzjrRPUBzewjPCaj0yokePB4LJSobyCzGMzjZZYFbwuzbfDHlimXbQ==} + '@typescript-eslint/eslint-plugin@8.8.1': + resolution: {integrity: sha512-xfvdgA8AP/vxHgtgU310+WBnLB4uJQ9XdyP17RebG26rLtDrQJV3ZYrcopX91GrHmMoH8bdSwMRh2a//TiJ1jQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -3064,8 +2984,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@8.0.1': - resolution: {integrity: sha512-5IgYJ9EO/12pOUwiBKFkpU7rS3IU21mtXzB81TNwq2xEybcmAZrE9qwDtsb5uQd9aVO9o0fdabFyAmKveXyujg==} + '@typescript-eslint/parser@8.8.1': + resolution: {integrity: sha512-hQUVn2Lij2NAxVFEdvIGxT9gP1tq2yM83m+by3whWFsWC+1y8pxxxHUFE1UqDu2VsGi2i6RLcv4QvouM84U+ow==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3074,16 +2994,12 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@8.0.0': - resolution: {integrity: sha512-V0aa9Csx/ZWWv2IPgTfY7T4agYwJyILESu/PVqFtTFz9RIS823mAze+NbnBI8xiwdX3iqeQbcTYlvB04G9wyQw==} + '@typescript-eslint/scope-manager@8.8.1': + resolution: {integrity: sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.0.1': - resolution: {integrity: sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/type-utils@8.0.1': - resolution: {integrity: sha512-+/UT25MWvXeDX9YaHv1IS6KI1fiuTto43WprE7pgSMswHbn1Jm9GEM4Txp+X74ifOWV8emu2AWcbLhpJAvD5Ng==} + '@typescript-eslint/type-utils@8.8.1': + resolution: {integrity: sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -3091,16 +3007,25 @@ packages: typescript: optional: true - '@typescript-eslint/types@8.0.0': - resolution: {integrity: sha512-wgdSGs9BTMWQ7ooeHtu5quddKKs5Z5dS+fHLbrQI+ID0XWJLODGMHRfhwImiHoeO2S5Wir2yXuadJN6/l4JRxw==} + '@typescript-eslint/types@7.18.0': + resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/types@8.8.1': + resolution: {integrity: sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.0.1': - resolution: {integrity: sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@7.18.0': + resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true - '@typescript-eslint/typescript-estree@8.0.0': - resolution: {integrity: sha512-5b97WpKMX+Y43YKi4zVcCVLtK5F98dFls3Oxui8LbnmRsseKenbbDinmvxrWegKDMmlkIq/XHuyy0UGLtpCDKg==} + '@typescript-eslint/typescript-estree@8.8.1': + resolution: {integrity: sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -3108,34 +3033,22 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@8.0.1': - resolution: {integrity: sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@typescript-eslint/utils@8.0.0': - resolution: {integrity: sha512-k/oS/A/3QeGLRvOWCg6/9rATJL5rec7/5s1YmdS0ZU6LHveJyGFwBvLhSRBv6i9xaj7etmosp+l+ViN1I9Aj/Q==} + '@typescript-eslint/utils@8.8.1': + resolution: {integrity: sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/utils@8.0.1': - resolution: {integrity: sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + '@typescript-eslint/visitor-keys@7.18.0': + resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} + engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/visitor-keys@8.0.0': - resolution: {integrity: sha512-oN0K4nkHuOyF3PVMyETbpP5zp6wfyOvm7tWhTMfoqxSSsPmJIh6JNASuZDlODE8eE+0EB9uar+6+vxr9DBTYOA==} + '@typescript-eslint/visitor-keys@8.8.1': + resolution: {integrity: sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.0.1': - resolution: {integrity: sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} '@unocss/astro@0.59.4': resolution: {integrity: sha512-DU3OR5MMR1Uvvec4/wB9EetDASHRg19Moy6z/MiIhn8JWJ0QzWYgSeJcfUX8exomMYv6WUEQJL+CyLI34Wmn8w==} @@ -3232,8 +3145,8 @@ packages: '@vite-pwa/assets-generator': optional: true - '@vitejs/plugin-vue@5.1.2': - resolution: {integrity: sha512-nY9IwH12qeiJqumTCLJLE7IiNx7HZ39cbHaysEUd+Myvbz9KAqd2yq+U01Kab1R/H1BmiyM2ShTYlNH32Fzo3A==} + '@vitejs/plugin-vue@5.1.4': + resolution: {integrity: sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 @@ -3264,58 +3177,55 @@ packages: '@vitest/utils@1.6.0': resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} - '@vue/compat@3.4.38': - resolution: {integrity: sha512-CdX4/3I8hkodU6rG6r8uTi112gsKYVrZcTTEpmG7wP3G1n/lpHKbvl3wBzTc6ClTIqRyHABrYnFyTofiSommQA==} + '@vue/compat@3.5.11': + resolution: {integrity: sha512-ESH2z/vUZQi6yRDBCDjBgip6a0Rk48KiT4Dk1LkxSYnqM++3mlqyMo0MgXFxfLhQ1uMaL6pquSCMgKfivrRqRg==} peerDependencies: - vue: 3.4.38 + vue: 3.5.11 - '@vue/compiler-core@3.4.38': - resolution: {integrity: sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==} + '@vue/compiler-core@3.5.11': + resolution: {integrity: sha512-PwAdxs7/9Hc3ieBO12tXzmTD+Ln4qhT/56S+8DvrrZ4kLDn4Z/AMUr8tXJD0axiJBS0RKIoNaR0yMuQB9v9Udg==} - '@vue/compiler-dom@3.4.38': - resolution: {integrity: sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==} + '@vue/compiler-dom@3.5.11': + resolution: {integrity: sha512-pyGf8zdbDDRkBrEzf8p7BQlMKNNF5Fk/Cf/fQ6PiUz9at4OaUfyXW0dGJTo2Vl1f5U9jSLCNf0EZJEogLXoeew==} - '@vue/compiler-sfc@3.4.38': - resolution: {integrity: sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==} + '@vue/compiler-sfc@3.5.11': + resolution: {integrity: sha512-gsbBtT4N9ANXXepprle+X9YLg2htQk1sqH/qGJ/EApl+dgpUBdTv3yP7YlR535uHZY3n6XaR0/bKo0BgwwDniw==} - '@vue/compiler-ssr@3.4.38': - resolution: {integrity: sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==} + '@vue/compiler-ssr@3.5.11': + resolution: {integrity: sha512-P4+GPjOuC2aFTk1Z4WANvEhyOykcvEd5bIj2KVNGKGfM745LaXGr++5njpdBTzVz5pZifdlR1kpYSJJpIlSePA==} - '@vue/devtools-api@6.6.3': - resolution: {integrity: sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==} + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - '@vue/devtools-api@7.3.9': - resolution: {integrity: sha512-D+GTYtFg68bqSu66EugQUydsOqaDlPLNmYw5oYk8k81uBu9/bVTUrqlAJrAA9Am7MXhKz2gWdDkopY6sOBf/Bg==} + '@vue/devtools-api@7.4.6': + resolution: {integrity: sha512-XipBV5k0/IfTr0sNBDTg7OBUCp51cYMMXyPxLXJZ4K/wmUeMqt8cVdr2ZZGOFq+si/jTyCYnNxeKoyev5DOUUA==} - '@vue/devtools-kit@7.3.9': - resolution: {integrity: sha512-Gr17nA+DaQzqyhNx1DUJr1CJRzTRfbIuuC80ZgU8MD/qNO302tv9la+ROi+Uaw+ULVwU9T71GnwLy4n8m9Lspg==} + '@vue/devtools-kit@7.4.6': + resolution: {integrity: sha512-NbYBwPWgEic1AOd9bWExz9weBzFdjiIfov0yRn4DrRfR+EQJCI9dn4I0XS7IxYGdkmUJi8mFW42LLk18WsGqew==} - '@vue/devtools-shared@7.3.9': - resolution: {integrity: sha512-CdfMRZKXyI8vw+hqOcQIiLihB6Hbbi7WNZGp7LsuH1Qe4aYAFmTaKjSciRZ301oTnwmU/knC/s5OGuV6UNiNoA==} + '@vue/devtools-shared@7.4.6': + resolution: {integrity: sha512-rPeSBzElnHYMB05Cc056BQiJpgocQjY8XVulgni+O9a9Gr9tNXgPteSzFFD+fT/iWMxNuUgGKs9CuW5DZewfIg==} - '@vue/reactivity@3.4.38': - resolution: {integrity: sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==} + '@vue/reactivity@3.5.11': + resolution: {integrity: sha512-Nqo5VZEn8MJWlCce8XoyVqHZbd5P2NH+yuAaFzuNSR96I+y1cnuUiq7xfSG+kyvLSiWmaHTKP1r3OZY4mMD50w==} - '@vue/runtime-core@3.4.38': - resolution: {integrity: sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==} + '@vue/runtime-core@3.5.11': + resolution: {integrity: sha512-7PsxFGqwfDhfhh0OcDWBG1DaIQIVOLgkwA5q6MtkPiDFjp5gohVnJEahSktwSFLq7R5PtxDKy6WKURVN1UDbzA==} - '@vue/runtime-dom@3.4.38': - resolution: {integrity: sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==} + '@vue/runtime-dom@3.5.11': + resolution: {integrity: sha512-GNghjecT6IrGf0UhuYmpgaOlN7kxzQBhxWEn08c/SQDxv1yy4IXI1bn81JgEpQ4IXjRxWtPyI8x0/7TF5rPfYQ==} - '@vue/server-renderer@3.4.38': - resolution: {integrity: sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==} + '@vue/server-renderer@3.5.11': + resolution: {integrity: sha512-cVOwYBxR7Wb1B1FoxYvtjJD8X/9E5nlH4VSkJy2uMA1MzYNdzAAB//l8nrmN9py/4aP+3NjWukf9PZ3TeWULaA==} peerDependencies: - vue: 3.4.38 + vue: 3.5.11 - '@vue/shared@3.4.38': - resolution: {integrity: sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==} + '@vue/shared@3.5.11': + resolution: {integrity: sha512-W8GgysJVnFo81FthhzurdRAWP/byq3q2qIw70e0JWblzVhjgOMiC2GyovXrZTFQJnFVryYaKGP3Tc9vYzYm6PQ==} '@vueuse/core@10.11.1': resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} - '@vueuse/core@11.0.3': - resolution: {integrity: sha512-RENlh64+SYA9XMExmmH1a3TPqeIuJBNNB/63GT35MZI+zpru3oMRUA6cEFr9HmGqEgUisurwGwnIieF6qu3aXw==} - '@vueuse/integrations@10.11.1': resolution: {integrity: sha512-Y5hCGBguN+vuVYTZmdd/IMXLOdfS60zAmDmFYc4BKBcMUPZH1n4tdyDECCPjXm0bNT3ZRUy1xzTLGaUje8Xyaw==} peerDependencies: @@ -3357,59 +3267,12 @@ packages: universal-cookie: optional: true - '@vueuse/integrations@11.0.3': - resolution: {integrity: sha512-w6CDisaxs19S5Fd+NPPLFaA3GoX5gxuxrbTTBu0EYap7oH13w75L6C/+7e9mcoF9akhcR6GyYajwVMQEjdapJg==} - peerDependencies: - async-validator: ^4 - axios: ^1 - change-case: ^5 - drauu: ^0.4 - focus-trap: ^7 - fuse.js: ^7 - idb-keyval: ^6 - jwt-decode: ^4 - nprogress: ^0.2 - qrcode: ^1.5 - sortablejs: ^1 - universal-cookie: ^7 - peerDependenciesMeta: - async-validator: - optional: true - axios: - optional: true - change-case: - optional: true - drauu: - optional: true - focus-trap: - optional: true - fuse.js: - optional: true - idb-keyval: - optional: true - jwt-decode: - optional: true - nprogress: - optional: true - qrcode: - optional: true - sortablejs: - optional: true - universal-cookie: - optional: true - '@vueuse/metadata@10.11.1': resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==} - '@vueuse/metadata@11.0.3': - resolution: {integrity: sha512-+FtbO4SD5WpsOcQTcC0hAhNlOid6QNLzqedtquTtQ+CRNBoAt9GuV07c6KNHK1wCmlq8DFPwgiLF2rXwgSHX5Q==} - '@vueuse/shared@10.11.1': resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} - '@vueuse/shared@11.0.3': - resolution: {integrity: sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==} - '@wdio/config@7.31.1': resolution: {integrity: sha512-WAfswbCatwiaDVqy6kfF/5T8/WS/US/SRhBGUFrfBuGMIe+RRoHgy7jURFWSvUIE7CNHj8yvs46fLUcxhXjzcQ==} engines: {node: '>=12.0.0'} @@ -3510,8 +3373,8 @@ packages: '@xtuc/long@4.2.2': resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - '@zenuml/core@3.24.3': - resolution: {integrity: sha512-ERWZgvVrgKyjzdJWlpiqzPzFNaNn6K439hX6bE9LZySKGbMq6uacKCmro7tLUGN+w9X/xhbQ+8goGzZtdIdOMQ==} + '@zenuml/core@3.24.12': + resolution: {integrity: sha512-SM9TYgyWl1Bm7oWc4lZLq0q9ejT6RdqxBYav8a4BhVvWkFgND088YCL9xlvo9vPJenwIuVNK+xukgqL1nwfztw==} engines: {node: '>=12.0.0'} JSONSelect@0.4.0: @@ -3542,8 +3405,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.3: - resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} engines: {node: '>=0.4.0'} acorn@8.12.1: @@ -3575,6 +3438,14 @@ packages: ajv: optional: true + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv-keywords@3.5.2: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: @@ -3629,8 +3500,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} ansi-sequence-parser@1.1.1: @@ -3667,6 +3538,9 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + app-module-path@2.2.0: + resolution: {integrity: sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==} + app-path@3.3.0: resolution: {integrity: sha512-EAgEXkdcxH1cgEePOSsmUtw9ItPl0KTxnh/pj9ZbhvbKbij9x0oX6PWpGnorDr0DS5AosLgoa5n3T/hZmKQpYA==} engines: {node: '>=8'} @@ -3729,6 +3603,10 @@ packages: assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + ast-module-types@6.0.0: + resolution: {integrity: sha512-LFRg7178Fw5R4FAEwZxVqiRI8IxSM+Ay2UBrHoCerXNme+kMMMfz7T3xDGV/c2fer87hcrtgJGsnSOfUrPK6ng==} + engines: {node: '>=18'} + astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -3751,20 +3629,17 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - avvio@7.2.5: - resolution: {integrity: sha512-AOhBxyLVdpOad3TujtC9kL/9r3HnTkxwQ5ggOsYrvvZP1cCFvzHWJd5XxZDFuTn+IN8vkKSG5SEJrd27vCSbeA==} + avvio@8.4.0: + resolution: {integrity: sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==} aws-sign2@0.7.0: resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - aws4@1.13.1: - resolution: {integrity: sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA==} + aws4@1.13.2: + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} - axios@1.7.3: - resolution: {integrity: sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==} - - axios@1.7.5: - resolution: {integrity: sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==} + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} @@ -3772,8 +3647,8 @@ packages: peerDependencies: '@babel/core': ^7.8.0 - babel-loader@9.1.3: - resolution: {integrity: sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==} + babel-loader@9.2.1: + resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} engines: {node: '>= 14.15.0'} peerDependencies: '@babel/core': ^7.12.0 @@ -3802,8 +3677,8 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-preset-current-node-syntax@1.0.1: - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + babel-preset-current-node-syntax@1.1.0: + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} peerDependencies: '@babel/core': ^7.0.0 @@ -3857,8 +3732,8 @@ packages: bmpimagejs@1.0.4: resolution: {integrity: sha512-21oKU7kbRt2OgOOj7rdiNr/yznDNUQ585plxR00rsmECcZr+6O1oCwB8OIoSHk/bDhbG8mFXIdeQuCPHgZ6QBw==} - body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} bonjour-service@1.2.1: @@ -3878,8 +3753,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.23.3: - resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + browserslist@4.24.0: + resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -3957,8 +3832,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001649: - resolution: {integrity: sha512-fJegqZZ0ZX8HOWr6rcafGr72+xcgJKI9oWfDW5DrD7ExUtgZC7a7R7ZYmZqplh7XDocFdGeIFn7roAxhOeYrPQ==} + caniuse-lite@1.0.30001667: + resolution: {integrity: sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} @@ -4001,9 +3876,15 @@ packages: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + character-entities-legacy@1.1.4: resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + character-entities@1.2.4: resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} @@ -4047,8 +3928,8 @@ packages: resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} engines: {node: '>=8'} - cjs-module-lexer@1.3.1: - resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} + cjs-module-lexer@1.4.1: + resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==} cjson@0.3.0: resolution: {integrity: sha512-bBRQcCIHzI1IVH59fR0bwGrFmi3Btb/JNwM/n401i1DnYgWndpsUBiQRAddLflkZage20A2d25OAWZZk0vBRlA==} @@ -4116,6 +3997,10 @@ packages: clone-response@1.0.3: resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + co@4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} @@ -4154,6 +4039,9 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@11.0.0: resolution: {integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==} engines: {node: '>=16'} @@ -4219,8 +4107,8 @@ packages: engines: {node: ^14.13.0 || >=16.0.0} hasBin: true - confbox@0.1.7: - resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} connect-history-api-fallback@2.0.0: resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} @@ -4230,6 +4118,10 @@ packages: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} + console.table@0.10.0: + resolution: {integrity: sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==} + engines: {node: '> 0.10'} + content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -4251,21 +4143,18 @@ packages: cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} - cookie@0.6.0: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + copy-anything@3.0.5: resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} engines: {node: '>=12.13'} - core-js-compat@3.38.0: - resolution: {integrity: sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A==} - core-js-compat@3.38.1: resolution: {integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==} @@ -4323,71 +4212,42 @@ packages: resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} engines: {node: '>=8'} - cspell-config-lib@8.13.3: - resolution: {integrity: sha512-dzVdar8Kenwxho0PnUxOxwjUvyFYn6Q9mQAMHcQNXQrvo32bdpoF+oNtWC/5FfrQgUgyl19CVQ607bRigYWoOQ==} + cspell-config-lib@8.14.4: + resolution: {integrity: sha512-cnUeJfniTiebqCaQmIUnbSrPrTH7xzKRQjJDHAEV0WYnOG2MhRXI13OzytdFdhkVBdStmgTzTCJKE7x+kmU2NA==} engines: {node: '>=18'} - cspell-config-lib@8.14.2: - resolution: {integrity: sha512-yHP1BdcH5dbjb8qiZr6+bxEnJ+rxTULQ00wBz3eBPWCghJywEAYYvMWoYuxVtPpndlkKYC1wJAHsyNkweQyepA==} + cspell-dictionary@8.14.4: + resolution: {integrity: sha512-pZvQHxpAW5fZAnt3ZKKy3s7M+3CX2t8tCS3uJrpEHIynlCawpG0fPF78rVE5o+g0dON36Lguc/BUuSN4IWKLmQ==} engines: {node: '>=18'} - cspell-dictionary@8.13.3: - resolution: {integrity: sha512-DQ3Tee7LIoy+9Mu52ht32O/MNBZ6i4iUeSTY2sMDDwogno3361BLRyfEjyiYNo3Fqf0Pcnt5MqY2DqIhrF/H/Q==} - engines: {node: '>=18'} - - cspell-dictionary@8.14.2: - resolution: {integrity: sha512-gWuAvf6queGGUvGbfAxxUq55cZ0OevWPbjnCrSB0PpJ4tqdFd8dLcvVrIKzoE2sBXKPw2NDkmoEngs6iGavC0w==} - engines: {node: '>=18'} - - cspell-gitignore@8.14.2: - resolution: {integrity: sha512-lrO/49NaKBpkR7vFxv4OOY+oHmsG5+gNQejrBBWD9Nv9vvjJtz/G36X/rcN6M6tFcQQMWwa01kf04nxz8Ejuhg==} + cspell-gitignore@8.14.4: + resolution: {integrity: sha512-RwfQEW5hD7CpYwS7m3b0ONG0nTLKP6bL2tvMdl7qtaYkL7ztGdsBTtLD1pmwqUsCbiN5RuaOxhYOYeRcpFRIkQ==} engines: {node: '>=18'} hasBin: true - cspell-glob@8.13.3: - resolution: {integrity: sha512-+jGIMYyKDLmoOJIxNPXRdI7utcvw+9FMSmj1ApIdEff5dCkehi0gtzK4H7orXGYEvRdKQvfaXiyduVi79rXsZQ==} + cspell-glob@8.14.4: + resolution: {integrity: sha512-C/xTS5nujMRMuguibq92qMVP767mtxrur7DcVolCvpzcivm1RB5NtIN0OctQxTyMbnmKeQv1t4epRKQ9A8vWRg==} engines: {node: '>=18'} - cspell-glob@8.14.2: - resolution: {integrity: sha512-9Q1Kgoo1ev3fKTpp9y5n8M4RLxd8B0f5o4y5FQe4dBU0j/bt+/YDrLZNWDm77JViV606XQ6fimG1FTTq6pT9/g==} - engines: {node: '>=18'} - - cspell-grammar@8.13.3: - resolution: {integrity: sha512-xPSgKk9HY5EsI8lkMPC9hiZCeAUs+RY/IVliUBW1xEicAJhP4RZIGRdIwtDNNJGwKfNXazjqYhcS4LS0q7xPAQ==} + cspell-grammar@8.14.4: + resolution: {integrity: sha512-yaSKAAJDiamsw3FChbw4HXb2RvTQrDsLelh1+T4MavarOIcAxXrqAJ8ysqm++g+S/ooJz2YO8YWIyzJKxcMf8g==} engines: {node: '>=18'} hasBin: true - cspell-grammar@8.14.2: - resolution: {integrity: sha512-eYwceVP80FGYVJenE42ALnvEKOXaXjq4yVbb1Ni1umO/9qamLWNCQ1RP6rRACy5e/cXviAbhrQ5Mtw6n+pyPEQ==} - engines: {node: '>=18'} - hasBin: true - - cspell-io@8.13.3: - resolution: {integrity: sha512-AeMIkz7+4VuJaPKO/v1pUpyUSOOTyLOAfzeTRRAXEt+KRKOUe36MyUmBMza6gzNcX2yD04VgJukRL408TY9ntw==} + cspell-io@8.14.4: + resolution: {integrity: sha512-o6OTWRyx/Az+PFhr1B0wMAwqG070hFC9g73Fkxd8+rHX0rfRS69QZH7LgSmZytqbZIMxCTDGdsLl33MFGWCbZQ==} engines: {node: '>=18'} - cspell-io@8.14.2: - resolution: {integrity: sha512-uaKpHiY3DAgfdzgKMQml6U8F8o9udMuYxGqYa5FVfN7D5Ap7B2edQzSLTUYwxrFEn4skSfp6XY73+nzJvxzH4Q==} + cspell-lib@8.14.4: + resolution: {integrity: sha512-qdkUkKtm+nmgpA4jQbmQTuepDfjHBDWvs3zDuEwVIVFq/h8gnXrRr75gJ3RYdTy+vOOqHPoLLqgxyqkUUrUGXA==} engines: {node: '>=18'} - cspell-lib@8.13.3: - resolution: {integrity: sha512-aEqxIILeqDtNoCa47/oSl5c926b50ue3PobYs4usn0Ymf0434RopCP+DCGsF7BPtog4j4XWnEmvkcJs57DYWDg==} + cspell-trie-lib@8.14.4: + resolution: {integrity: sha512-zu8EJ33CH+FA5lwTRGqS//Q6phO0qtgEmODMR1KPlD7WlrfTFMb3bWFsLo/tiv5hjpsn7CM6dYDAAgBOSkoyhQ==} engines: {node: '>=18'} - cspell-lib@8.14.2: - resolution: {integrity: sha512-d2oiIXHXnADmnhIuFLOdNE63L7OUfzgpLbYaqAWbkImCUDkevfGrOgnX8TJ03fUgZID4nvQ+3kgu/n2j4eLZjQ==} - engines: {node: '>=18'} - - cspell-trie-lib@8.13.3: - resolution: {integrity: sha512-Z0iLGi9HI+Vf+WhVVeru6dYgQdtaYCKWRlc1SayLfAZhw9BcjrXL8KTXDfAfv/lUgnRu6xwP1isLlDNZECsKVQ==} - engines: {node: '>=18'} - - cspell-trie-lib@8.14.2: - resolution: {integrity: sha512-rZMbaEBGoyy4/zxKECaMyVyGLbuUxYmZ5jlEgiA3xPtEdWwJ4iWRTo5G6dWbQsXoxPYdAXXZ0/q0GQ2y6Jt0kw==} - engines: {node: '>=18'} - - cspell@8.14.2: - resolution: {integrity: sha512-ii/W7fwO4chNQVYl1C/8k7RW8EXzLb69rvg08p8mSJx8B2UasVJ9tuJpTH2Spo1jX6N3H0dKPWUbd1fAmdAhPg==} + cspell@8.14.4: + resolution: {integrity: sha512-R5Awb3i/RKaVVcZzFt8dkN3M6VnifIEDYBcbzbmYjZ/Eq+ASF+QTmI0E9WPhMEcFM1nd7YOyXnETo560yRdoKw==} engines: {node: '>=18'} hasBin: true @@ -4400,8 +4260,8 @@ packages: engines: {node: '>=4'} hasBin: true - cssstyle@4.0.1: - resolution: {integrity: sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==} + cssstyle@4.1.0: + resolution: {integrity: sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==} engines: {node: '>=18'} csstree-validator@3.0.0: @@ -4421,11 +4281,15 @@ packages: peerDependencies: cypress: ^4.5.0 + cypress-split@1.24.0: + resolution: {integrity: sha512-ZEFh1m6z+HwPWpB1h9YAF1L6K/wkPBR3vD+v8Rrg8BRm50sZ7oSx6Dw+sv6zfr5Pfqv247CnobLewdFBLlPIBQ==} + hasBin: true + cypress-wait-until@3.0.2: resolution: {integrity: sha512-iemies796dD5CgjG5kV0MnpEmKSH+s7O83ZoJLVzuVbZmm4lheMsZqAVT73hlMx4QlkwhxbyUzhOBUOZwoOe0w==} - cypress@13.14.1: - resolution: {integrity: sha512-Wo+byPmjps66hACEH5udhXINEiN3qS3jWNGRzJOjrRJF3D0+YrcP2LVB1T7oYaVQM/S+eanqEvBWYc8cf7Vcbg==} + cypress@13.15.0: + resolution: {integrity: sha512-53aO7PwOfi604qzOkCSzNlWquCynLlKE/rmmpSPcziRH6LNfaDUAklQT6WJIsD8ywxlIy+uVZsnTMCCQVd2kTw==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} hasBin: true @@ -4439,8 +4303,8 @@ packages: peerDependencies: cytoscape: ^3.2.0 - cytoscape@3.30.1: - resolution: {integrity: sha512-TRJc3HbBPkHd50u9YfJh2FxD1lDLZ+JXnJoyBn5LkncoeuT7fapO/Hq/Ed8TdFclaKshzInge2i30bg7VKeoPQ==} + cytoscape@3.30.2: + resolution: {integrity: sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==} engines: {node: '>=0.10'} d3-array@2.12.1: @@ -4586,8 +4450,8 @@ packages: resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} engines: {node: '>=0.12'} - dagre-d3-es@7.0.10: - resolution: {integrity: sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==} + dagre-d3-es@7.0.11: + resolution: {integrity: sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==} dashdash@1.14.1: resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} @@ -4620,9 +4484,6 @@ packages: resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} engines: {node: '>=0.11'} - dayjs@1.11.12: - resolution: {integrity: sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==} - dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} @@ -4660,8 +4521,8 @@ packages: supports-color: optional: true - debug@4.3.6: - resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -4695,6 +4556,10 @@ packages: resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} engines: {node: '>=6'} + deep-equal@2.2.3: + resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} + engines: {node: '>= 0.4'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -4710,6 +4575,9 @@ packages: resolution: {integrity: sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==} engines: {node: '>=8'} + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + defer-to-connect@2.0.1: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} @@ -4744,6 +4612,11 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + dependency-tree@11.0.1: + resolution: {integrity: sha512-eCt7HSKIC9NxgIykG2DRq3Aewn9UhVS14MB3rEn6l/AsEI1FBg6ZGSlCU0SZ6Tjm2kkhj6/8c2pViinuyKELhg==} + engines: {node: '>=18'} + hasBin: true + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -4770,6 +4643,49 @@ packages: detect-node@2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + detective-amd@6.0.0: + resolution: {integrity: sha512-NTqfYfwNsW7AQltKSEaWR66hGkTeD52Kz3eRQ+nfkA9ZFZt3iifRCWh+yZ/m6t3H42JFwVFTrml/D64R2PAIOA==} + engines: {node: '>=18'} + hasBin: true + + detective-cjs@6.0.0: + resolution: {integrity: sha512-R55jTS6Kkmy6ukdrbzY4x+I7KkXiuDPpFzUViFV/tm2PBGtTCjkh9ZmTuJc1SaziMHJOe636dtiZLEuzBL9drg==} + engines: {node: '>=18'} + + detective-es6@5.0.0: + resolution: {integrity: sha512-NGTnzjvgeMW1khUSEXCzPDoraLenWbUjCFjwxReH+Ir+P6LGjYtaBbAvITWn2H0VSC+eM7/9LFOTAkrta6hNYg==} + engines: {node: '>=18'} + + detective-postcss@7.0.0: + resolution: {integrity: sha512-pSXA6dyqmBPBuERpoOKKTUUjQCZwZPLRbd1VdsTbt6W+m/+6ROl4BbE87yQBUtLoK7yX8pvXHdKyM/xNIW9F7A==} + engines: {node: ^14.0.0 || >=16.0.0} + peerDependencies: + postcss: ^8.4.38 + + detective-sass@6.0.0: + resolution: {integrity: sha512-h5GCfFMkPm4ZUUfGHVPKNHKT8jV7cSmgK+s4dgQH4/dIUNh9/huR1fjEQrblOQNDalSU7k7g+tiW9LJ+nVEUhg==} + engines: {node: '>=18'} + + detective-scss@5.0.0: + resolution: {integrity: sha512-Y64HyMqntdsCh1qAH7ci95dk0nnpA29g319w/5d/oYcHolcGUVJbIhOirOFjfN1KnMAXAFm5FIkZ4l2EKFGgxg==} + engines: {node: '>=18'} + + detective-stylus@5.0.0: + resolution: {integrity: sha512-KMHOsPY6aq3196WteVhkY5FF+6Nnc/r7q741E+Gq+Ax9mhE2iwj8Hlw8pl+749hPDRDBHZ2WlgOjP+twIG61vQ==} + engines: {node: '>=18'} + + detective-typescript@13.0.0: + resolution: {integrity: sha512-tcMYfiFWoUejSbvSblw90NDt76/4mNftYCX0SMnVRYzSXv8Fvo06hi4JOPdNvVNxRtCAKg3MJ3cBJh+ygEMH+A==} + engines: {node: ^14.14.0 || >=16.0.0} + peerDependencies: + typescript: ^5.4.4 + + detective-vue2@2.0.3: + resolution: {integrity: sha512-AgWdSfVnft8uPGnUkdvE1EDadEENDCzoSRMt2xZfpxsjqVO617zGWXbB8TGIxHaqHz/nHa6lOSgAB8/dt0yEug==} + engines: {node: '>=18'} + peerDependencies: + typescript: ^5.4.4 + devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -4824,6 +4740,9 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + easy-table@1.1.0: + resolution: {integrity: sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==} + ebnf-parser@0.1.10: resolution: {integrity: sha512-urvSxVQ6XJcoTpc+/x2pWhhuOX4aljCNQpwzw+ifZvV1andZkAmiJc3Rq1oGEAQmcjiLceyMXOy1l8ms8qs2fQ==} @@ -4838,8 +4757,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.4: - resolution: {integrity: sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==} + electron-to-chromium@1.5.33: + resolution: {integrity: sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==} elkjs@0.9.3: resolution: {integrity: sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==} @@ -4848,8 +4767,8 @@ packages: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} engines: {node: '>=12'} - emoji-regex@10.3.0: - resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4861,6 +4780,10 @@ packages: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + encoding@0.1.13: resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} @@ -4887,8 +4810,8 @@ packages: resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - envinfo@7.13.0: - resolution: {integrity: sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==} + envinfo@7.14.0: + resolution: {integrity: sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==} engines: {node: '>=4'} hasBin: true @@ -4911,6 +4834,9 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + es-module-lexer@1.5.4: resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} @@ -4957,8 +4883,8 @@ packages: engines: {node: '>=18'} hasBin: true - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} escape-html@1.0.3: @@ -4985,23 +4911,28 @@ packages: engines: {node: '>=0.10.0'} hasBin: true + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + eslint-config-prettier@9.1.0: resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' - eslint-plugin-cypress@3.4.0: - resolution: {integrity: sha512-Rrrr3Ri6wHqzrRr+TyUV7bDS4UnMMrFY1R1PP2F7XdGfe9txDC6lQEshyoNOWqGoPkbbeDm1x1XPc/adxemsnA==} + eslint-plugin-cypress@3.5.0: + resolution: {integrity: sha512-JZQ6XnBTNI8h1B9M7wJSFzc48SYbh7VMMKaNTQOFa3BQlnmXPrVc4PKen8R+fpv6VleiPeej6VxloGb42zdRvw==} peerDependencies: eslint: '>=7' - eslint-plugin-html@8.1.1: - resolution: {integrity: sha512-6qmlJsc40D2m3Dn9oEH+0PAOkJhxVu0f5sVItqpCE0YWgYnyP4xCjBc3UWTHaJcY9ARkWOLIIuXLq0ndRnQOHw==} + eslint-plugin-html@8.1.2: + resolution: {integrity: sha512-pbRchDV2SmqbCi/Ev/q3aAikzG9BcFe0IjjqjtMn8eTLq71ZUggyJB6CDmuwGAXmYZHrXI12XTfCqvgcnPRqGw==} engines: {node: '>=16.0.0'} - eslint-plugin-jest@28.7.0: - resolution: {integrity: sha512-fzPGN7awL2ftVRQh/bsCi+16ArUZWujZnD1b8EGJqy8nr4//7tZ3BIdc/9edcJBtB3hpci3GtdMNFVDwHU0Eag==} + eslint-plugin-jest@28.8.3: + resolution: {integrity: sha512-HIQ3t9hASLKm2IhIOqnu+ifw7uLZkIlR7RYNv7fMcEi/p0CIiJmfriStQS2LDkgtY4nyLbIZAD+JL347Yc2ETQ==} engines: {node: ^16.10.0 || ^18.12.0 || >=20.0.0} peerDependencies: '@typescript-eslint/eslint-plugin': ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -5013,8 +4944,8 @@ packages: jest: optional: true - eslint-plugin-jsdoc@48.11.0: - resolution: {integrity: sha512-d12JHJDPNo7IFwTOAItCeJY1hcqoIxE0lHA8infQByLilQ9xkqrRa6laWCnsuCrf+8rUnvxXY1XuTbibRBNylA==} + eslint-plugin-jsdoc@50.3.1: + resolution: {integrity: sha512-SY9oUuTMr6aWoJggUS40LtMjsRzJPB5ZT7F432xZIHK3EfHF+8i48GbUBpwanrtlL9l1gILNTHK9o8gEhYLcKA==} engines: {node: '>=18'} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 @@ -5035,15 +4966,15 @@ packages: peerDependencies: eslint: '>=8' - eslint-plugin-no-only-tests@3.1.0: - resolution: {integrity: sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==} + eslint-plugin-no-only-tests@3.3.0: + resolution: {integrity: sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==} engines: {node: '>=5.0.0'} eslint-plugin-tsdoc@0.3.0: resolution: {integrity: sha512-0MuFdBrrJVBjT/gyhkP2BqpD0np1NxNLfQ38xXDlSs/KVVpKI2A6vN7jx2Rve/CyUsvOsMGwp9KKrinv7q9g3A==} - eslint-plugin-unicorn@55.0.0: - resolution: {integrity: sha512-n3AKiVpY2/uDcGrS3+QsYDkjPfaOrNrsfQxU9nt5nitd9KuvVXrfAvgCO9DYPSfap+Gqjw9EOrXIsBp5tlHZjA==} + eslint-plugin-unicorn@56.0.0: + resolution: {integrity: sha512-aXpddVz/PQMmd69uxO98PA4iidiVNvA0xOtbpUoz1WhBd4RxOQQYqN618v68drY0hmy5uU2jy1bheKEVWBjlPw==} engines: {node: '>=18.18'} peerDependencies: eslint: '>=8.56.0' @@ -5052,29 +4983,34 @@ packages: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} - eslint-scope@8.0.2: - resolution: {integrity: sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==} + eslint-scope@8.1.0: + resolution: {integrity: sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-visitor-keys@4.0.0: - resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + eslint-visitor-keys@4.1.0: + resolution: {integrity: sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.8.0: - resolution: {integrity: sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==} + eslint@9.12.0: + resolution: {integrity: sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true esniff@2.0.1: resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} engines: {node: '>=0.10'} - espree@10.1.0: - resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} + espree@10.2.0: + resolution: {integrity: sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} esprima@1.1.1: @@ -5179,8 +5115,8 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - express@4.19.2: - resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} + express@4.21.0: + resolution: {integrity: sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==} engines: {node: '>= 0.10.0'} ext@1.7.0: @@ -5225,22 +5161,27 @@ packages: fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - fast-json-stringify@2.7.13: - resolution: {integrity: sha512-ar+hQ4+OIurUGjSJD1anvYSDcUflywhKjfxnsW4TBTD7+u0tJufv6DKRWoQk3vI6YBOWMoz0TQtfbe7dxbQmvA==} - engines: {node: '>= 10.0.0'} + fast-json-stringify@5.16.1: + resolution: {integrity: sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==} fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-querystring@1.1.2: + resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} + fast-redact@3.5.0: resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} engines: {node: '>=6'} - fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + fast-shuffle@6.1.0: + resolution: {integrity: sha512-3aj8oO6bvZFKYDGvXNmmEuxyOjre8trCpIbtFSM/DSKd+o3iSbQQPb5BZQeJ7SPYVivn9EeW3gKh0QdnD027MQ==} - fast-uri@3.0.1: - resolution: {integrity: sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==} + fast-uri@2.4.0: + resolution: {integrity: sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==} + + fast-uri@3.0.2: + resolution: {integrity: sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==} fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} @@ -5252,8 +5193,8 @@ packages: fastify-plugin@3.0.1: resolution: {integrity: sha512-qKcDXmuZadJqdTm6vlCqioEbyewF60b/0LOFCcYN1B6BIZGlYJumWWOYs70SFYLDAH4YqdE1cxH/RKMG7rFxgA==} - fastify@3.29.5: - resolution: {integrity: sha512-FBDgb1gkenZxxh4sTD6AdI6mFnZnsgckpjIXzIvfLSYCa4isfQeD8QWGPib63dxq6btnY0l1j8I0xYhMvUb+sw==} + fastify@4.28.1: + resolution: {integrity: sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ==} fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} @@ -5271,6 +5212,14 @@ packages: fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fdir@6.4.0: + resolution: {integrity: sha512-3oB133prH1o4j/L5lLW7uOCF1PlD+/It2L0eL/iAqWMB91RBbqTewABqxhj0ibBd90EEmWZq7ntIWzVaWcXTGQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + ferrum@1.9.4: resolution: {integrity: sha512-ooNerLoIht/dK4CQJux93z/hnt9JysrXniJCI3r6YRgmHeXC57EJ8XaTCT1Gm8LfhIAeWxyJA0O7d/W3pqDYRg==} @@ -5299,12 +5248,17 @@ packages: filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + filing-cabinet@5.0.2: + resolution: {integrity: sha512-RZlFj8lzyu6jqtFBeXNqUjjNG6xm+gwXue3T70pRxw1W40kJwlgq0PSWAmh0nAnn5DHuBIecLXk9+1VKS9ICXA==} + engines: {node: '>=18'} + hasBin: true + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} find-cache-dir@3.3.2: @@ -5315,14 +5269,23 @@ packages: resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} engines: {node: '>=14.16'} - find-my-way@4.5.1: - resolution: {integrity: sha512-kE0u7sGoUFbMXcOG/xpkmz4sRLCklERnBcg7Ftuu1iAxsfEt2S46RLJ3Sq7vshsEy2wJT2hZxE58XZK27qa8kg==} - engines: {node: '>=10'} + find-cypress-specs@1.43.4: + resolution: {integrity: sha512-GAdz6lfBndbOq9OOJ3psThQ56hqgL8tZUCOLnl60d/l56bvHkC0TNwyqlLfBObiscirSZWSgyGL86jJkrpFMrA==} + engines: {node: '>=18'} + hasBin: true + + find-my-way@8.2.2: + resolution: {integrity: sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==} + engines: {node: '>=14'} find-process@1.4.7: resolution: {integrity: sha512-/U4CYp1214Xrp3u3Fqr9yNynUrr5Le4y0SsJh2lMDDSbpwYSz3M2SMWQC+wqcx79cN8PQtHQIL8KnuY9M66fdg==} hasBin: true + find-test-names@1.28.18: + resolution: {integrity: sha512-hhnGdkWK+qEA5Z02Tu0OqGQIUjFZNyOCE4WaJpbhW4hAF1+NZ7OCr0Bss9RCaj7BBtjoIjkU93utobQ8pg2iVg==} + hasBin: true + find-up-simple@1.0.0: resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==} engines: {node: '>=18'} @@ -5343,9 +5306,6 @@ packages: resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - find-yarn-workspace-root2@1.2.16: - resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} - flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} @@ -5358,20 +5318,17 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - flatstr@1.0.12: - resolution: {integrity: sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==} - flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} flexsearch@0.7.43: resolution: {integrity: sha512-c5o/+Um8aqCSOXGcZoqZOm+NqtVwNsvVpWv6lfmSclU954O3wvQKxxK8zj74fPaSJbXpSLTs4PRhh+wnoCXnKg==} - focus-trap@7.5.4: - resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==} + focus-trap@7.6.0: + resolution: {integrity: sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ==} - follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -5390,17 +5347,13 @@ packages: resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} engines: {node: '>=8.0.0'} - foreground-child@3.2.1: - resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} forever-agent@0.6.1: resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - form-data@2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} - form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -5476,6 +5429,10 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-amd-module-type@6.0.0: + resolution: {integrity: sha512-hFM7oivtlgJ3d6XWD6G47l8Wyh/C6vFw5G24Kk1Tbq85yh5gcM8Fne5/lFhiuxB+RT6+SI7I1ThB9lG4FBh3jw==} + engines: {node: '>=18'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -5530,8 +5487,8 @@ packages: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} - get-tsconfig@4.7.6: - resolution: {integrity: sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==} + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} getos@3.2.1: resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} @@ -5592,8 +5549,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.9.0: - resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==} + globals@15.10.0: + resolution: {integrity: sha512-tqFIbz83w4Y5TCbtgjZjApohbuh7K9BxGYFm7ifwDR240tvdb7P9x+/9VvUKlmkPoiknoJtanI8UOrqxS3a7lQ==} engines: {node: '>=18'} globalthis@1.0.4: @@ -5615,6 +5572,11 @@ packages: glur@1.1.2: resolution: {integrity: sha512-l+8esYHTKOx2G/Aao4lEQ0bnHWg4fWtJbVoZZT9Knxi01pB8C80BR85nONLFwkkQoFRCmXY+BUcGZN3yZ2QsRA==} + gonzales-pe@4.3.0: + resolution: {integrity: sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==} + engines: {node: '>=0.6.0'} + hasBin: true + gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} @@ -5685,6 +5647,12 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hast-util-to-html@9.0.3: + resolution: {integrity: sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} @@ -5710,6 +5678,9 @@ packages: html-to-image@1.11.11: resolution: {integrity: sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==} + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + htmlparser2@9.1.0: resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} @@ -5738,8 +5709,8 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} - http-proxy-middleware@2.0.6: - resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==} + http-proxy-middleware@2.0.7: + resolution: {integrity: sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==} engines: {node: '>=12.0.0'} peerDependencies: '@types/express': ^4.17.13 @@ -5751,8 +5722,8 @@ packages: resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} engines: {node: '>=8.0.0'} - http-signature@1.3.6: - resolution: {integrity: sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==} + http-signature@1.4.0: + resolution: {integrity: sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==} engines: {node: '>=0.10'} http2-wrapper@1.0.3: @@ -5786,8 +5757,11 @@ packages: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - husky@9.1.5: - resolution: {integrity: sha512-rowAVRUBfI0b4+niA4SJMhfQwc107VLkBUgEYYAOQAbqDCnra1nYh83hF/MDmhYs9t9n1E3DuKOrs2LYNC+0Ag==} + humanize-duration@3.32.1: + resolution: {integrity: sha512-inh5wue5XdfObhu/IGEMiA1nUXigSGcaKNemcbLRKa7jXYGDZXr3LoT9pTIzq2hPEbld7w/qv9h+ikWGz8fL1g==} + + husky@9.1.6: + resolution: {integrity: sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==} engines: {node: '>=18'} hasBin: true @@ -5805,10 +5779,6 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} - engines: {node: '>= 4'} - ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -5870,6 +5840,10 @@ packages: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} + interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + interpret@2.2.0: resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==} engines: {node: '>= 0.10'} @@ -5888,6 +5862,10 @@ packages: is-alphanumerical@1.0.4: resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + is-array-buffer@3.0.4: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} @@ -5921,8 +5899,8 @@ packages: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} hasBin: true - is-core-module@2.15.0: - resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} is-data-view@1.0.1: @@ -5976,6 +5954,10 @@ packages: resolution: {integrity: sha512-vlgs2cSgMOfnKU8c1ewgKPyum9rVrjjLLW2HBdL5i0iAJjOs8NY55ZBd/hqUTaYR0EO9CKZd3hVSC2HlIbygTQ==} engines: {node: '>=12'} + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} @@ -6025,6 +6007,10 @@ packages: resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} engines: {node: '>=0.10.0'} + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + is-shared-array-buffer@1.0.3: resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} engines: {node: '>= 0.4'} @@ -6064,9 +6050,24 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + is-url-superb@4.0.0: + resolution: {integrity: sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==} + engines: {node: '>=10'} + + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} + is-what@4.1.16: resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} engines: {node: '>=12.13'} @@ -6329,8 +6330,8 @@ packages: jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - jsdoc-type-pratt-parser@4.0.0: - resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==} + jsdoc-type-pratt-parser@4.1.0: + resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} engines: {node: '>=12.0.0'} jsdom@24.1.3: @@ -6346,11 +6347,6 @@ packages: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - jsesc@3.0.2: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} engines: {node: '>=6'} @@ -6362,6 +6358,9 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-ref-resolver@1.0.1: + resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} + json-schema-to-typescript@13.1.2: resolution: {integrity: sha512-17G+mjx4nunvOpkPvcz7fdwUwYCEwyH8vR3Ym3rFiQ8uzAL3go+c1306Kk7iGRk8HuXBXqy+JJJmpYl0cvOllw==} engines: {node: '>=12.0.0'} @@ -6453,8 +6452,8 @@ packages: resolution: {integrity: sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==} engines: {node: '>=16.0.0'} - launch-editor@2.8.0: - resolution: {integrity: sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==} + launch-editor@2.9.1: + resolution: {integrity: sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==} layout-base@1.0.2: resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} @@ -6466,6 +6465,10 @@ packages: resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} engines: {node: '> 0.8'} + lazy-ass@2.0.3: + resolution: {integrity: sha512-/O3/DoQmI1XAhklDvF1dAjFf/epE8u3lzOZegQfLZ8G7Ud5bTRSZiFOpukHCu6jODrCA4gtIdwUCC7htxcDACA==} + engines: {node: '> 0.8'} + leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -6477,8 +6480,8 @@ packages: lex-parser@0.1.4: resolution: {integrity: sha512-DuAEISsr1H4LOpmFLkyMc8YStiRWZCO8hMsoXAXSbgyfvs2WQhSt0+/FBv3ZU/JBFZMGcE+FWzEBSzwUU7U27w==} - light-my-request@4.12.0: - resolution: {integrity: sha512-0y+9VIfJEsPVzK5ArSIJ8Dkxp8QMP7/aCuxCUtG/tr9a2NoOf/snATE/OUc05XUplJCEnRh6gTkH7xh9POt1DQ==} + light-my-request@5.14.0: + resolution: {integrity: sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==} lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} @@ -6494,8 +6497,8 @@ packages: linkify-it@4.0.1: resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} - lint-staged@15.2.9: - resolution: {integrity: sha512-BZAt8Lk3sEnxw7tfxM7jeZlPRuT4M68O0/CwZhhaw6eeWu0Lz5eERE3m386InivXB64fp/mDID452h48tvKlRQ==} + lint-staged@15.2.10: + resolution: {integrity: sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==} engines: {node: '>=18.12.0'} hasBin: true @@ -6508,14 +6511,10 @@ packages: enquirer: optional: true - listr2@8.2.4: - resolution: {integrity: sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==} + listr2@8.2.5: + resolution: {integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==} engines: {node: '>=18.0.0'} - load-yaml-file@0.2.0: - resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} - engines: {node: '>=6'} - loader-runner@4.3.0: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} @@ -6589,10 +6588,13 @@ packages: loglevel-plugin-prefix@0.8.4: resolution: {integrity: sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==} - loglevel@1.9.1: - resolution: {integrity: sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==} + loglevel@1.9.2: + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} engines: {node: '>= 0.6.0'} + long@5.2.3: + resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} + longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -6624,8 +6626,8 @@ packages: magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} - magicast@0.3.4: - resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==} + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} @@ -6676,8 +6678,8 @@ packages: mdast-util-frontmatter@2.0.1: resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} - mdast-util-gfm-autolink-literal@2.0.0: - resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} mdast-util-gfm-footnote@2.0.0: resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} @@ -6697,6 +6699,9 @@ packages: mdast-util-phrasing@4.1.0: resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + mdast-util-to-markdown@2.1.0: resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} @@ -6731,8 +6736,8 @@ packages: resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} engines: {node: '>=16.10'} - merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -6904,9 +6909,6 @@ packages: minisearch@6.3.0: resolution: {integrity: sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==} - minisearch@7.1.0: - resolution: {integrity: sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==} - mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -6919,8 +6921,18 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.7.1: - resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + mlly@1.7.2: + resolution: {integrity: sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==} + + module-definition@6.0.0: + resolution: {integrity: sha512-sEGP5nKEXU7fGSZUML/coJbrO+yQtxcppDAYWRE9ovWsTbFoUHB2qDUx564WUzDaBHXsD46JBbIK5WVTwCyu3w==} + engines: {node: '>=18'} + hasBin: true + + module-lookup-amd@9.0.2: + resolution: {integrity: sha512-p7PzSVEWiW9fHRX9oM+V4aV5B2nCVddVNv4DZ/JB6t9GsXY4E+ZVhPpnwUX7bbJyGeeVZqhS8q/JZ/H77IqPFA==} + engines: {node: '>=18'} + hasBin: true mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -6989,6 +7001,15 @@ packages: encoding: optional: true + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-fetch@3.3.1: resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -7007,6 +7028,10 @@ packages: node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + node-source-walk@7.0.0: + resolution: {integrity: sha512-1uiY543L+N7Og4yswvlm5NCKgPKDEXd9AUR9Jh3gen6oOeBsesr6LqhXom1er3eRzSUcVRWXzhv8tSNrIfGHKw==} + engines: {node: '>=18'} + nomnom@1.5.2: resolution: {integrity: sha512-fiVbT7BqxiQqjlR9U3FDGOSERFCKoXVCdxV2FwZuNN7/cmJ42iQx35nUFOAFDcyvemu9Adp+IlsCGlKQYLmBKw==} deprecated: Package no longer supported. Contact support@npmjs.com for more info. @@ -7034,8 +7059,8 @@ packages: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - nwsapi@2.2.12: - resolution: {integrity: sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==} + nwsapi@2.2.13: + resolution: {integrity: sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==} nyc@15.1.0: resolution: {integrity: sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==} @@ -7054,6 +7079,10 @@ packages: resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} engines: {node: '>= 0.4'} + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} @@ -7065,8 +7094,8 @@ packages: obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - ofetch@1.3.4: - resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==} + ofetch@1.4.0: + resolution: {integrity: sha512-MuHgsEhU6zGeX+EMh+8mSMrYTnsqJQQrpM00Q6QHMKNqQ0bKy0B43tk8tL1wg+CnsSTy1kg4Ir2T5Ig6rD+dfQ==} omggif@1.0.10: resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} @@ -7098,15 +7127,18 @@ packages: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} + oniguruma-to-js@0.4.3: + resolution: {integrity: sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==} + open@8.4.2: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} - openapi-fetch@0.11.1: - resolution: {integrity: sha512-WtDQsrvxjXuCmo6u6WMQPfUaya8cLfL+ZCaXorPo9MMumqlU/Km/SrCXsEcJH234D4iykOkvJ6Q/iWBzK7+3rA==} + openapi-fetch@0.11.3: + resolution: {integrity: sha512-r18fERgpxFrI4pv79ABD1dqFetWz7pTfwRd7jQmRm/lFdCDpWF43kvHUiOqOZu+tWsMydDJMpJN1hlZ9inRvfA==} - openapi-typescript-helpers@0.0.12: - resolution: {integrity: sha512-FO+5kTWO6KDutigamr2MRwciYkAUYhqdctlyVRrQOe2uxif2/O2+GcS07jNnP36AUK6ubSsGu3GeBiYIc6eQzA==} + openapi-typescript-helpers@0.0.13: + resolution: {integrity: sha512-z44WK2e7ygW3aUtAtiurfEACohf/Qt9g6BsejmIYgEoY4REHeRzgFJmO3ium0libsuzPc145I+8lE9aiiZrQvQ==} optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} @@ -7214,11 +7246,11 @@ packages: resolution: {integrity: sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==} engines: {node: '>=8'} - package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@0.2.0: - resolution: {integrity: sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==} + package-manager-detector@0.2.1: + resolution: {integrity: sha512-/hVW2fZvAdEas+wyKh0SnlZ2mx0NIa1+j11YaQkogEJkcMErbwchHCuo8z7lEtajZJQZ6rgZNVTWMVVd71Bjng==} pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -7234,8 +7266,8 @@ packages: parse-entities@2.0.0: resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} - parse-imports@2.1.1: - resolution: {integrity: sha512-TDT4HqzUiTMO1wJRwg/t/hYk8Wdp3iF/ToMIlAoVQfL1Xs/sTxq1dKWSMjMbQmIarfWKymOyly40+zmPHXMqCA==} + parse-imports@2.2.1: + resolution: {integrity: sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==} engines: {node: '>= 18'} parse-json@5.2.0: @@ -7290,8 +7322,8 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + path-to-regexp@0.1.10: + resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -7310,6 +7342,9 @@ packages: pause-stream@0.0.11: resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + pcg@1.0.0: + resolution: {integrity: sha512-6wjoSJZ4TEJhI0rLDOKd5mOu6TwS4svn9oBaRsD1PCrhlDNLWAaTimWJgBABmIGJxzkI+RbaHJYRLGVf9QFE5Q==} + pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} @@ -7319,13 +7354,17 @@ packages: performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} @@ -7342,20 +7381,20 @@ packages: pino-abstract-transport@1.2.0: resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} - pino-std-serializers@3.2.0: - resolution: {integrity: sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==} - pino-std-serializers@6.2.2: resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} - pino@6.14.0: - resolution: {integrity: sha512-iuhEDel3Z3hF9Jfe44DPXR8l07bhjuFY3GMHIXbjnY9XcafbyDDwl2sN2vw2GjMPf5Nkoe+OFao7ffn9SXaKDg==} - hasBin: true + pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} pino@8.21.0: resolution: {integrity: sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==} hasBin: true + pino@9.4.0: + resolution: {integrity: sha512-nbkQb5+9YPhQRz/BeQmrWpEknAaqjpAqRK8NwJpmrX/JHu7JuZC5G1CeAwJDJfGes4h+YihC6in3Q2nGb+Y09w==} + hasBin: true + pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -7376,8 +7415,8 @@ packages: resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} engines: {node: '>=14.16'} - pkg-types@1.1.3: - resolution: {integrity: sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==} + pkg-types@1.2.0: + resolution: {integrity: sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==} plist@3.1.0: resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==} @@ -7445,16 +7484,23 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.4.41: - resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} + postcss-values-parser@6.0.2: + resolution: {integrity: sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==} + engines: {node: '>=10'} + peerDependencies: + postcss: ^8.2.9 + + postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} engines: {node: ^10 || ^12 || >=14} - preact@10.23.2: - resolution: {integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==} + preact@10.24.2: + resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} - preferred-pm@3.1.4: - resolution: {integrity: sha512-lEHd+yEm22jXdCphDrkvIJQU66EuLojPPtvZkpKIkiD+l0DMThF/niqZKJSoU8Vl7iuvtmzyMhir9LdVy5WMnA==} - engines: {node: '>=10'} + precinct@12.1.2: + resolution: {integrity: sha512-x2qVN3oSOp3D05ihCd8XdkIPuEQsyte7PSxzLqiRgktu79S5Dr1I75/S+zAup8/0cwjoiJTQztE9h0/sWp9bJQ==} + engines: {node: '>=18'} + hasBin: true prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -7495,12 +7541,12 @@ packages: resolution: {integrity: sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==} engines: {node: '>=8'} - process-warning@1.0.0: - resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} - process-warning@3.0.0: resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} + process-warning@4.0.0: + resolution: {integrity: sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==} + process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} @@ -7509,6 +7555,9 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -7530,8 +7579,8 @@ packages: psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - pump@3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + pump@3.0.2: + resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} @@ -7540,12 +7589,8 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - qs@6.10.4: - resolution: {integrity: sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==} - engines: {node: '>=0.6'} - - qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} querystringify@2.2.0: @@ -7561,12 +7606,18 @@ packages: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} + quote-unquote@1.0.0: + resolution: {integrity: sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==} + railroad-diagrams@1.0.0: resolution: {integrity: sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==} ramda@0.28.0: resolution: {integrity: sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==} + ramda@0.29.0: + resolution: {integrity: sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==} + randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} @@ -7615,12 +7666,16 @@ packages: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} + rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + rechoir@0.7.1: resolution: {integrity: sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==} engines: {node: '>= 0.10'} - regenerate-unicode-properties@10.1.1: - resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + regenerate-unicode-properties@10.2.0: + resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} engines: {node: '>=4'} regenerate@1.4.2: @@ -7632,24 +7687,30 @@ packages: regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + regex@4.3.3: + resolution: {integrity: sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg==} + regexp-tree@0.1.27: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true - regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} - regexpu-core@5.3.2: - resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + regexpu-core@6.1.1: + resolution: {integrity: sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==} engines: {node: '>=4'} + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + regjsparser@0.10.0: resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} hasBin: true - regjsparser@0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + regjsparser@0.11.1: + resolution: {integrity: sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ==} hasBin: true release-zalgo@1.0.0: @@ -7678,6 +7739,10 @@ packages: request-progress@3.0.0: resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==} + require-and-forget@1.0.1: + resolution: {integrity: sha512-Sea861D/seGo3cptxc857a34Df0oEijXit8Q3IDodiwZMzVmyXrRI9EgQQa3hjkhoEjNzCBvv0t/0fMgebmWLg==} + engines: {node: '>=6'} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -7689,6 +7754,15 @@ packages: require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + requirejs-config-file@4.0.0: + resolution: {integrity: sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw==} + engines: {node: '>=10.13.0'} + + requirejs@2.3.7: + resolution: {integrity: sha512-DouTG8T1WanGok6Qjg2SXuCMzszOo0eHeH9hDZ5Y4x8Je+9JB38HdTLT4/VA8OaUhBa0JPVHJ0pyBkM1z+pDsw==} + engines: {node: '>=0.4.0'} + hasBin: true + requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -7699,6 +7773,10 @@ packages: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} + resolve-dependency-path@4.0.0: + resolution: {integrity: sha512-hlY1SybBGm5aYN3PC4rp15MzsJLM1w+MEA/4KU3UBPfz4S0lL3FL6mgv7JgaA8a+ZTeEQAiF1a1BuN2nkqiIlg==} + engines: {node: '>=18'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -7729,9 +7807,9 @@ packages: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} - ret@0.2.2: - resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} - engines: {node: '>=4'} + ret@0.4.3: + resolution: {integrity: sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==} + engines: {node: '>=10'} retry@0.13.1: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} @@ -7771,22 +7849,19 @@ packages: rollup: optional: true - rollup@2.79.1: - resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} + rollup@2.79.2: + resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} engines: {node: '>=10.0.0'} hasBin: true - rollup@4.21.1: - resolution: {integrity: sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==} + rollup@4.24.0: + resolution: {integrity: sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true roughjs@4.6.6: resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} - rrweb-cssom@0.6.0: - resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} - rrweb-cssom@0.7.1: resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} @@ -7813,8 +7888,8 @@ packages: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'} - safe-regex2@2.0.0: - resolution: {integrity: sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==} + safe-regex2@3.1.0: + resolution: {integrity: sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==} safe-stable-stringify@2.5.0: resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} @@ -7823,6 +7898,11 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sass-lookup@6.0.1: + resolution: {integrity: sha512-nl9Wxbj9RjEJA5SSV0hSDoU2zYGtE+ANaDS4OFUR7nYrquvBFvPKZZtQHe3lvnxCcylEDV00KUijjdMTUElcVQ==} + engines: {node: '>=18'} + hasBin: true + saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} @@ -7835,8 +7915,8 @@ packages: resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} engines: {node: '>= 12.13.0'} - search-insights@2.15.0: - resolution: {integrity: sha512-ch2sPCUDD4sbPQdknVl9ALSi9H7VyoeVbsxznYz6QV55jJ8CI3EtwpO1i84keN4+hF5IeHWIeGvc08530JkVXQ==} + search-insights@2.17.2: + resolution: {integrity: sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==} secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} @@ -7848,9 +7928,6 @@ packages: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} - semver-store@0.3.0: - resolution: {integrity: sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg==} - semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -7869,8 +7946,8 @@ packages: engines: {node: '>=10'} hasBin: true - send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} serialize-javascript@6.0.2: @@ -7880,8 +7957,8 @@ packages: resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} engines: {node: '>= 0.8.0'} - serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} set-blocking@2.0.0: @@ -7931,11 +8008,16 @@ packages: shell-quote@1.8.1: resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + shelljs@0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + shiki@0.14.7: resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} - shiki@1.14.1: - resolution: {integrity: sha512-FujAN40NEejeXdzPt+3sZ3F2dx1U24BY2XTY01+MG8mbxCiA2XukXdcbyMyLAHJ/1AUUnQd1tZlvIjefWWEJeA==} + shiki@1.22.0: + resolution: {integrity: sha512-/t5LlhNs+UOKQCYBtl5ZsH/Vclz73GIqT2yQsCBygr8L/ppTdmpL4w3kPLoZJbMKVWtoG77Ue1feOjZfDxvMkw==} side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} @@ -7951,6 +8033,10 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-bin-help@1.8.0: + resolution: {integrity: sha512-0LxHn+P1lF5r2WwVB/za3hLRIsYoLaNq1CXqjbrs3ZvLuvlWnRKrUjEWzV7umZL7hpQ7xULiQMV+0iXdRa5iFg==} + engines: {node: '>=14.16'} + simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -7998,18 +8084,18 @@ packages: sockjs@0.3.24: resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} - sonic-boom@1.4.1: - resolution: {integrity: sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==} - sonic-boom@3.8.1: resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} + sonic-boom@4.1.0: + resolution: {integrity: sha512-NGipjjRicyJJ03rPiZCJYjwlsuP2d1/5QUviozRXC7S3WdVWNK5e3Ojieb9CCyfhq2UC+3+SRd9nG3I2lPRvUw==} + source-map-js@1.0.1: resolution: {integrity: sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==} engines: {node: '>=0.10.0'} - source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} source-map-support@0.5.13: @@ -8038,6 +8124,9 @@ packages: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} deprecated: Please use @jridgewell/sourcemap-codec instead + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + spawn-command@0.0.2: resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} @@ -8060,8 +8149,8 @@ packages: spdx-expression-parse@4.0.0: resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} - spdx-license-ids@3.0.18: - resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} + spdx-license-ids@3.0.20: + resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} spdy-transport@3.0.0: resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} @@ -8074,6 +8163,10 @@ packages: resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} engines: {node: '>=0.10.0'} + spec-change@1.11.11: + resolution: {integrity: sha512-wSxi1XKeNr8JxBlYj13Lw8TTMpojYU2zRlkmyXl0kHp+xGkwYUpXaVXcofiEmEqrq1HoGg7pwKEzvMjYcQubtw==} + hasBin: true + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -8099,8 +8192,8 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - start-server-and-test@2.0.5: - resolution: {integrity: sha512-2CV4pz69NJVJKQmJeSr+O+SPtOreu0yxvhPmSXclzmAKkPREuMabyMh+Txpzemjx0RDzXOcG2XkhiUuxjztSQw==} + start-server-and-test@2.0.8: + resolution: {integrity: sha512-v2fV6NV2F7tL1ocwfI4Wpait+IKjRbT5l3ZZ+ZikXdMLmxYsS8ynGAsCQAUVXkVyGyS+UibsRnvgHkMvJIvCsw==} engines: {node: '>=16'} hasBin: true @@ -8115,6 +8208,10 @@ packages: std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + stop-iteration-iterator@1.0.0: + resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} + engines: {node: '>= 0.4'} + stream-combiner@0.0.4: resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} @@ -8126,10 +8223,6 @@ packages: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} - string-similarity@4.0.4: - resolution: {integrity: sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -8163,6 +8256,9 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + stringify-object@3.3.0: resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} engines: {node: '>=4'} @@ -8217,6 +8313,11 @@ packages: stylis@4.3.4: resolution: {integrity: sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==} + stylus-lookup@6.0.0: + resolution: {integrity: sha512-RaWKxAvPnIXrdby+UWCr1WRfa+lrPMSJPySte4Q6a+rWyjeJyFOLJxr5GrAVfcMCsfVlCuzTAJ/ysYT8p8do7Q==} + engines: {node: '>=18'} + hasBin: true + sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -8249,15 +8350,15 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - synckit@0.9.1: - resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==} + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} engines: {node: ^14.18.0 || >=16.0.0} tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} - tailwindcss@3.4.10: - resolution: {integrity: sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==} + tailwindcss@3.4.13: + resolution: {integrity: sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==} engines: {node: '>=14.0.0'} hasBin: true @@ -8301,13 +8402,8 @@ packages: uglify-js: optional: true - terser@5.31.3: - resolution: {integrity: sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==} - engines: {node: '>=10'} - hasBin: true - - terser@5.31.6: - resolution: {integrity: sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==} + terser@5.34.1: + resolution: {integrity: sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA==} engines: {node: '>=10'} hasBin: true @@ -8328,6 +8424,9 @@ packages: thread-stream@2.7.0: resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==} + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + throat@6.0.2: resolution: {integrity: sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==} @@ -8344,16 +8443,16 @@ packages: resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==} engines: {node: '>=0.12'} - tiny-lru@8.0.2: - resolution: {integrity: sha512-ApGvZ6vVvTNdsmt676grvCkUCGwzG9IqXma5Z07xJgiC5L7akUMof5U8G2JTI9Rz/ovtVhJBlY6mNhEvtjzOIg==} - engines: {node: '>=6'} - tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} tinyexec@0.3.0: resolution: {integrity: sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==} + tinyglobby@0.2.9: + resolution: {integrity: sha512-8or1+BGEdk1Zkkw2ii16qSS7uVrQJPre5A9o/XkWPATkk23FZh/15BKFxPnlTy6vkljZxLqYCzzBMj30ZrSvjw==} + engines: {node: '>=12.0.0'} + tinypool@0.8.4: resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} engines: {node: '>=14.0.0'} @@ -8381,6 +8480,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toad-cache@3.7.0: + resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} + engines: {node: '>=12'} + toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -8410,6 +8513,9 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} @@ -8429,20 +8535,25 @@ packages: ts-toolbelt@6.15.5: resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==} - tslib@2.6.3: - resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} - tsx@4.19.0: - resolution: {integrity: sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==} + tsx@4.19.1: + resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==} engines: {node: '>=18.0.0'} hasBin: true tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + tweetnacl@0.14.5: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} @@ -8478,8 +8589,8 @@ packages: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} - type-fest@4.25.0: - resolution: {integrity: sha512-bRkIGlXsnGBRBQRAY56UXBm//9qH4bmJfFvq83gSz41N282df+fjy8ofcEgc1sM8geNt5cl6mC2g9Fht1cs8Aw==} + type-fest@4.26.1: + resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==} engines: {node: '>=16'} type-is@1.6.18: @@ -8520,8 +8631,8 @@ packages: peerDependencies: typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x - typescript-eslint@8.0.1: - resolution: {integrity: sha512-V3Y+MdfhawxEjE16dWpb7/IOgeXnLwAEEkS7v8oDqNcR1oYlqWhGH/iHqHdKVdpWme1VPZ0SoywXAkCqawj2eQ==} + typescript-eslint@8.8.1: + resolution: {integrity: sha512-R0dsXFt6t4SAFjUSKFjMh4pXDtq04SsFKCVGDP3ZOzNP7itF0jBcZYU4fMsZr4y7O7V7Nc751dDeESbe4PbQMQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -8534,14 +8645,19 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@5.6.2: + resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==} + engines: {node: '>=14.17'} + hasBin: true + uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} - uglify-js@3.19.1: - resolution: {integrity: sha512-y/2wiW+ceTYR2TSSptAhfnEtpLaQ4Ups5zrjB2d3kuVxHj16j/QJwPl5PvuGy9uARb39J0+iKxcRPvtpsx4A4A==} + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} hasBin: true @@ -8560,16 +8676,20 @@ packages: undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - unicode-canonical-property-names-ecmascript@2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} engines: {node: '>=4'} unicode-match-property-ecmascript@2.0.0: resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} engines: {node: '>=4'} - unicode-match-property-value-ecmascript@2.1.0: - resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + unicode-match-property-value-ecmascript@2.2.0: + resolution: {integrity: sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==} engines: {node: '>=4'} unicode-property-aliases-ecmascript@2.1.0: @@ -8599,6 +8719,9 @@ packages: unist-util-is@6.0.0: resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + unist-util-stringify-position@2.0.3: resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} @@ -8652,9 +8775,14 @@ packages: '@nuxt/kit': optional: true - unplugin@1.12.0: - resolution: {integrity: sha512-KeczzHl2sATPQUx1gzo+EnUkmN4VmGBYRRVOZSGvGITE9rGHRDGqft6ONceP3vgXcyJ2XjX5axG5jMWUwNCYLw==} + unplugin@1.14.1: + resolution: {integrity: sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w==} engines: {node: '>=14.0.0'} + peerDependencies: + webpack-sources: ^3 + peerDependenciesMeta: + webpack-sources: + optional: true untildify@4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} @@ -8664,8 +8792,8 @@ packages: resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} engines: {node: '>=4'} - update-browserslist-db@1.1.0: - resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -8709,8 +8837,8 @@ packages: vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} - vfile@6.0.2: - resolution: {integrity: sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg==} + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} vite-node@1.6.0: resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} @@ -8734,8 +8862,8 @@ packages: '@vite-pwa/assets-generator': optional: true - vite@5.4.2: - resolution: {integrity: sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==} + vite@5.4.8: + resolution: {integrity: sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -8785,18 +8913,6 @@ packages: postcss: optional: true - vitepress@1.3.4: - resolution: {integrity: sha512-I1/F6OW1xl3kW4PaIMC6snxjWgf3qfziq2aqsDoFc/Gt41WbcRv++z8zjw8qGRIJ+I4bUW7ZcKFDHHN/jkH9DQ==} - hasBin: true - peerDependencies: - markdown-it-mathjax3: ^4 - postcss: ^8 - peerDependenciesMeta: - markdown-it-mathjax3: - optional: true - postcss: - optional: true - vitest@1.6.0: resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -8865,8 +8981,8 @@ packages: '@vue/composition-api': optional: true - vue@3.4.38: - resolution: {integrity: sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==} + vue@3.5.11: + resolution: {integrity: sha512-/8Wurrd9J3lb72FTQS7gRMNQD4nztTtKPmuDuPuhqXmmpD6+skVjAeahNpVzsuky6Sy9gy7wn8UadqPtt9SQIg==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -8882,21 +8998,24 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - wait-on@7.2.0: - resolution: {integrity: sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==} + wait-on@8.0.1: + resolution: {integrity: sha512-1wWQOyR2LVVtaqrcIL2+OM+x7bkpmzVROa0Nf6FryXkS+er5Sa1kzFGjzZRqLnHa3n1rACFLeTwUqE1ETL9Mig==} engines: {node: '>=12.0.0'} hasBin: true walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - watchpack@2.4.1: - resolution: {integrity: sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==} + watchpack@2.4.2: + resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} engines: {node: '>=10.13.0'} wbuf@1.7.3: resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} @@ -8965,8 +9084,8 @@ packages: webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - webpack@5.93.0: - resolution: {integrity: sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==} + webpack@5.95.0: + resolution: {integrity: sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -9004,13 +9123,13 @@ packages: which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + which-module@2.0.1: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} - which-pm@2.2.0: - resolution: {integrity: sha512-MOiaDbA5ZZgUjkeMWM5EkJp4loW5ZRoa5bc3/aeMox/PJelMhE6t7S/mLuiY43DBupyxH+S0U1bTui9kWUlmsw==} - engines: {node: '>=8.15'} - which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} @@ -9173,8 +9292,8 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.5.0: - resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==} + yaml@2.5.1: + resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==} engines: {node: '>= 14'} hasBin: true @@ -9214,6 +9333,22 @@ packages: snapshots: + '@actions/core@1.11.1': + dependencies: + '@actions/exec': 1.1.1 + '@actions/http-client': 2.2.3 + + '@actions/exec@1.1.1': + dependencies: + '@actions/io': 1.1.3 + + '@actions/http-client@2.2.3': + dependencies: + tunnel: 0.0.6 + undici: 5.28.4 + + '@actions/io@1.1.3': {} + '@adobe/jsonschema2md@8.0.2': dependencies: '@types/json-schema': 7.0.15 @@ -9236,19 +9371,19 @@ snapshots: transitivePeerDependencies: - supports-color - '@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.15.0)': + '@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.2)': dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.15.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.2) '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.15.0)': + '@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.2)': dependencies: '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) - search-insights: 2.15.0 + search-insights: 2.17.2 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch @@ -9347,14 +9482,9 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@antfu/install-pkg@0.1.1': - dependencies: - execa: 5.1.1 - find-up: 5.0.0 - '@antfu/install-pkg@0.4.1': dependencies: - package-manager-detector: 0.2.0 + package-manager-detector: 0.2.1 tinyexec: 0.3.0 '@antfu/utils@0.7.10': {} @@ -9366,7 +9496,7 @@ snapshots: jsonpointer: 5.0.1 leven: 3.1.0 - '@applitools/core-base@1.16.0': + '@applitools/core-base@1.16.1': dependencies: '@applitools/image': 1.1.13 '@applitools/logger': 2.0.18 @@ -9377,20 +9507,51 @@ snapshots: transitivePeerDependencies: - supports-color - '@applitools/core@4.18.1(encoding@0.1.13)(typescript@5.4.5)': + '@applitools/core@4.18.2(encoding@0.1.13)(typescript@5.4.5)': dependencies: - '@applitools/core-base': 1.16.0 - '@applitools/dom-capture': 11.3.1 + '@applitools/core-base': 1.16.1 + '@applitools/dom-capture': 11.4.0 '@applitools/dom-snapshot': 4.11.3 - '@applitools/driver': 1.18.0 - '@applitools/ec-client': 1.9.3(typescript@5.4.5) + '@applitools/driver': 1.19.0 + '@applitools/ec-client': 1.9.4(typescript@5.4.5) '@applitools/logger': 2.0.18 - '@applitools/nml-client': 1.8.9 + '@applitools/nml-client': 1.8.10 '@applitools/req': 1.7.2 - '@applitools/screenshoter': 3.8.35 + '@applitools/screenshoter': 3.8.36 '@applitools/snippets': 2.4.27 '@applitools/socket': 1.1.18 - '@applitools/spec-driver-webdriver': 1.1.11(webdriver@7.31.1(typescript@5.4.5)) + '@applitools/spec-driver-webdriver': 1.1.12(webdriver@7.31.1(typescript@5.4.5)) + '@applitools/ufg-client': 1.12.3 + '@applitools/utils': 1.7.4 + '@types/ws': 8.5.5 + abort-controller: 3.0.0 + chalk: 4.1.2 + node-fetch: 2.6.7(encoding@0.1.13) + semver: 7.6.2 + webdriver: 7.31.1(typescript@5.4.5) + ws: 8.17.1 + yargs: 17.7.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - typescript + - utf-8-validate + + '@applitools/core@4.19.0(encoding@0.1.13)(typescript@5.4.5)': + dependencies: + '@applitools/core-base': 1.16.1 + '@applitools/dom-capture': 11.5.0 + '@applitools/dom-snapshot': 4.11.3 + '@applitools/driver': 1.19.1 + '@applitools/ec-client': 1.9.5(typescript@5.4.5) + '@applitools/logger': 2.0.18 + '@applitools/nml-client': 1.8.11 + '@applitools/req': 1.7.2 + '@applitools/screenshoter': 3.8.37 + '@applitools/snippets': 2.5.0 + '@applitools/socket': 1.1.18 + '@applitools/spec-driver-webdriver': 1.1.13(webdriver@7.31.1(typescript@5.4.5)) '@applitools/ufg-client': 1.12.3 '@applitools/utils': 1.7.4 '@types/ws': 8.5.5 @@ -9413,7 +9574,12 @@ snapshots: mdn-data: 2.1.0 source-map-js: 1.0.1 - '@applitools/dom-capture@11.3.1': + '@applitools/dom-capture@11.4.0': + dependencies: + '@applitools/dom-shared': 1.0.15 + '@applitools/functional-commons': 1.6.0 + + '@applitools/dom-capture@11.5.0': dependencies: '@applitools/dom-shared': 1.0.15 '@applitools/functional-commons': 1.6.0 @@ -9427,7 +9593,7 @@ snapshots: '@applitools/functional-commons': 1.6.0 pako: 1.0.11 - '@applitools/driver@1.18.0': + '@applitools/driver@1.19.0': dependencies: '@applitools/logger': 2.0.18 '@applitools/snippets': 2.4.27 @@ -9436,15 +9602,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@applitools/ec-client@1.9.3(typescript@5.4.5)': + '@applitools/driver@1.19.1': dependencies: - '@applitools/core-base': 1.16.0 - '@applitools/driver': 1.18.0 + '@applitools/logger': 2.0.18 + '@applitools/snippets': 2.5.0 + '@applitools/utils': 1.7.4 + semver: 7.6.2 + transitivePeerDependencies: + - supports-color + + '@applitools/ec-client@1.9.4(typescript@5.4.5)': + dependencies: + '@applitools/core-base': 1.16.1 + '@applitools/driver': 1.19.0 '@applitools/logger': 2.0.18 '@applitools/req': 1.7.2 '@applitools/socket': 1.1.18 - '@applitools/spec-driver-webdriver': 1.1.11(webdriver@7.31.1(typescript@5.4.5)) - '@applitools/tunnel-client': 1.5.7 + '@applitools/spec-driver-webdriver': 1.1.12(webdriver@7.31.1(typescript@5.4.5)) + '@applitools/tunnel-client': 1.5.8 + '@applitools/utils': 1.7.4 + abort-controller: 3.0.0 + webdriver: 7.31.1(typescript@5.4.5) + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + - typescript + + '@applitools/ec-client@1.9.5(typescript@5.4.5)': + dependencies: + '@applitools/core-base': 1.16.1 + '@applitools/driver': 1.19.1 + '@applitools/logger': 2.0.18 + '@applitools/req': 1.7.2 + '@applitools/socket': 1.1.18 + '@applitools/spec-driver-webdriver': 1.1.13(webdriver@7.31.1(typescript@5.4.5)) + '@applitools/tunnel-client': 1.5.8 '@applitools/utils': 1.7.4 abort-controller: 3.0.0 webdriver: 7.31.1(typescript@5.4.5) @@ -9460,14 +9652,14 @@ snapshots: binary: 0.3.0 is-localhost-ip: 2.0.0 - '@applitools/execution-grid-tunnel@3.0.5': + '@applitools/execution-grid-tunnel@3.0.8': dependencies: '@applitools/eg-frpc': 1.0.5 '@applitools/eg-socks5-proxy-server': 0.5.6 '@applitools/logger': 1.1.53 dotenv: 16.4.5 encoding: 0.1.13 - fastify: 3.29.5 + fastify: 4.28.1 fastify-plugin: 3.0.1 find-process: 1.4.7 ini: 3.0.1 @@ -9479,10 +9671,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@applitools/eyes-cypress@3.44.7(encoding@0.1.13)(typescript@5.4.5)': + '@applitools/eyes-cypress@3.44.9(encoding@0.1.13)(typescript@5.4.5)': dependencies: - '@applitools/core': 4.18.1(encoding@0.1.13)(typescript@5.4.5) - '@applitools/eyes': 1.22.1(encoding@0.1.13)(typescript@5.4.5) + '@applitools/core': 4.19.0(encoding@0.1.13)(typescript@5.4.5) + '@applitools/eyes': 1.22.2(encoding@0.1.13)(typescript@5.4.5) '@applitools/functional-commons': 1.6.0 '@applitools/logger': 2.0.18 '@applitools/utils': 1.7.4 @@ -9498,9 +9690,9 @@ snapshots: - typescript - utf-8-validate - '@applitools/eyes@1.22.1(encoding@0.1.13)(typescript@5.4.5)': + '@applitools/eyes@1.22.2(encoding@0.1.13)(typescript@5.4.5)': dependencies: - '@applitools/core': 4.18.1(encoding@0.1.13)(typescript@5.4.5) + '@applitools/core': 4.18.2(encoding@0.1.13)(typescript@5.4.5) '@applitools/logger': 2.0.18 '@applitools/utils': 1.7.4 transitivePeerDependencies: @@ -9536,7 +9728,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@applitools/nml-client@1.8.9': + '@applitools/nml-client@1.8.10': + dependencies: + '@applitools/logger': 2.0.18 + '@applitools/req': 1.7.2 + '@applitools/utils': 1.7.4 + transitivePeerDependencies: + - supports-color + + '@applitools/nml-client@1.8.11': dependencies: '@applitools/logger': 2.0.18 '@applitools/req': 1.7.2 @@ -9554,7 +9754,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@applitools/screenshoter@3.8.35': + '@applitools/screenshoter@3.8.36': dependencies: '@applitools/image': 1.1.13 '@applitools/logger': 2.0.18 @@ -9563,8 +9763,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@applitools/screenshoter@3.8.37': + dependencies: + '@applitools/image': 1.1.13 + '@applitools/logger': 2.0.18 + '@applitools/snippets': 2.5.0 + '@applitools/utils': 1.7.4 + transitivePeerDependencies: + - supports-color + '@applitools/snippets@2.4.27': {} + '@applitools/snippets@2.5.0': {} + '@applitools/socket@1.1.18': dependencies: '@applitools/logger': 2.0.18 @@ -9572,9 +9783,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@applitools/spec-driver-webdriver@1.1.11(webdriver@7.31.1(typescript@5.4.5))': + '@applitools/spec-driver-webdriver@1.1.12(webdriver@7.31.1(typescript@5.4.5))': dependencies: - '@applitools/driver': 1.18.0 + '@applitools/driver': 1.19.0 '@applitools/utils': 1.7.4 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 @@ -9582,9 +9793,19 @@ snapshots: transitivePeerDependencies: - supports-color - '@applitools/tunnel-client@1.5.7': + '@applitools/spec-driver-webdriver@1.1.13(webdriver@7.31.1(typescript@5.4.5))': dependencies: - '@applitools/execution-grid-tunnel': 3.0.5 + '@applitools/driver': 1.19.1 + '@applitools/utils': 1.7.4 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + webdriver: 7.31.1(typescript@5.4.5) + transitivePeerDependencies: + - supports-color + + '@applitools/tunnel-client@1.5.8': + dependencies: + '@applitools/execution-grid-tunnel': 3.0.8 '@applitools/logger': 2.0.18 '@applitools/req': 1.7.2 '@applitools/socket': 1.1.18 @@ -9611,881 +9832,831 @@ snapshots: '@applitools/utils@1.7.4': {} - '@argos-ci/api-client@0.2.0': + '@argos-ci/api-client@0.5.0': dependencies: - openapi-fetch: 0.11.1 + openapi-fetch: 0.11.3 - '@argos-ci/browser@2.1.3': {} + '@argos-ci/browser@2.1.4': {} - '@argos-ci/core@2.5.0': + '@argos-ci/core@2.8.1': dependencies: - '@argos-ci/api-client': 0.2.0 + '@argos-ci/api-client': 0.5.0 '@argos-ci/util': 2.1.1 - axios: 1.7.5(debug@4.3.6) + axios: 1.7.7(debug@4.3.7) convict: 6.2.4 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) fast-glob: 3.3.2 sharp: 0.33.5 tmp: 0.2.3 transitivePeerDependencies: - supports-color - '@argos-ci/cypress@2.1.2(cypress@13.14.1)': + '@argos-ci/cypress@2.2.2(cypress@13.15.0)': dependencies: - '@argos-ci/browser': 2.1.3 - '@argos-ci/core': 2.5.0 + '@argos-ci/browser': 2.1.4 + '@argos-ci/core': 2.8.1 '@argos-ci/util': 2.1.1 - cypress: 13.14.1 + cypress: 13.15.0 cypress-wait-until: 3.0.2 transitivePeerDependencies: - supports-color '@argos-ci/util@2.1.1': {} - '@babel/code-frame@7.24.7': + '@babel/code-frame@7.25.7': dependencies: - '@babel/highlight': 7.24.7 - picocolors: 1.0.1 + '@babel/highlight': 7.25.7 + picocolors: 1.1.0 - '@babel/compat-data@7.25.2': {} + '@babel/compat-data@7.25.7': {} - '@babel/compat-data@7.25.4': {} - - '@babel/core@7.25.2': + '@babel/core@7.25.7': dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.0 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helpers': 7.25.0 - '@babel/parser': 7.25.4 - '@babel/template': 7.25.0 - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.2 + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.7) + '@babel/helpers': 7.25.7 + '@babel/parser': 7.25.7 + '@babel/template': 7.25.7 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.7 convert-source-map: 2.0.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.25.0': + '@babel/generator@7.25.7': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.7 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - jsesc: 2.5.2 + jsesc: 3.0.2 - '@babel/generator@7.25.5': + '@babel/helper-annotate-as-pure@7.25.7': dependencies: - '@babel/types': 7.25.4 - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 2.5.2 + '@babel/types': 7.25.7 - '@babel/helper-annotate-as-pure@7.24.7': + '@babel/helper-builder-binary-assignment-operator-visitor@7.25.7': dependencies: - '@babel/types': 7.25.4 - - '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': - dependencies: - '@babel/traverse': 7.25.4 - '@babel/types': 7.25.4 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/helper-compilation-targets@7.25.2': + '@babel/helper-compilation-targets@7.25.7': dependencies: - '@babel/compat-data': 7.25.2 - '@babel/helper-validator-option': 7.24.8 - browserslist: 4.23.3 + '@babel/compat-data': 7.25.7 + '@babel/helper-validator-option': 7.25.7 + browserslist: 4.24.0 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.25.0(@babel/core@7.25.2)': + '@babel/helper-create-class-features-plugin@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-member-expression-to-functions': 7.24.8 - '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/traverse': 7.25.3 + '@babel/core': 7.25.7 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-member-expression-to-functions': 7.25.7 + '@babel/helper-optimise-call-expression': 7.25.7 + '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.7) + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/traverse': 7.25.7 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-class-features-plugin@7.25.4(@babel/core@7.25.2)': + '@babel/helper-create-regexp-features-plugin@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-member-expression-to-functions': 7.24.8 - '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/traverse': 7.25.4 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-create-regexp-features-plugin@7.25.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - regexpu-core: 5.3.2 + '@babel/core': 7.25.7 + '@babel/helper-annotate-as-pure': 7.25.7 + regexpu-core: 6.1.1 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.25.2)': + '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - debug: 4.3.6(supports-color@8.1.1) + '@babel/core': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + debug: 4.3.7(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: - supports-color - '@babel/helper-member-expression-to-functions@7.24.8': + '@babel/helper-member-expression-to-functions@7.25.7': dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.4 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@7.24.7': + '@babel/helper-module-imports@7.25.7': dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.2 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': + '@babel/helper-module-transforms@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-simple-access': 7.24.7 - '@babel/helper-validator-identifier': 7.24.7 - '@babel/traverse': 7.25.3 + '@babel/core': 7.25.7 + '@babel/helper-module-imports': 7.25.7 + '@babel/helper-simple-access': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + '@babel/traverse': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/helper-optimise-call-expression@7.24.7': + '@babel/helper-optimise-call-expression@7.25.7': dependencies: - '@babel/types': 7.25.4 + '@babel/types': 7.25.7 - '@babel/helper-plugin-utils@7.24.8': {} + '@babel/helper-plugin-utils@7.25.7': {} - '@babel/helper-remap-async-to-generator@7.25.0(@babel/core@7.25.2)': + '@babel/helper-remap-async-to-generator@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-wrap-function': 7.25.0 - '@babel/traverse': 7.25.4 + '@babel/core': 7.25.7 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-wrap-function': 7.25.7 + '@babel/traverse': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.25.0(@babel/core@7.25.2)': + '@babel/helper-replace-supers@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-member-expression-to-functions': 7.24.8 - '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/traverse': 7.25.3 + '@babel/core': 7.25.7 + '@babel/helper-member-expression-to-functions': 7.25.7 + '@babel/helper-optimise-call-expression': 7.25.7 + '@babel/traverse': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/helper-simple-access@7.24.7': + '@babel/helper-simple-access@7.25.7': dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.4 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + '@babel/helper-skip-transparent-expression-wrappers@7.25.7': dependencies: - '@babel/traverse': 7.25.3 - '@babel/types': 7.25.4 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/helper-string-parser@7.24.8': {} + '@babel/helper-string-parser@7.25.7': {} - '@babel/helper-validator-identifier@7.24.7': {} + '@babel/helper-validator-identifier@7.25.7': {} - '@babel/helper-validator-option@7.24.8': {} + '@babel/helper-validator-option@7.25.7': {} - '@babel/helper-wrap-function@7.25.0': + '@babel/helper-wrap-function@7.25.7': dependencies: - '@babel/template': 7.25.0 - '@babel/traverse': 7.25.4 - '@babel/types': 7.25.4 + '@babel/template': 7.25.7 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/helpers@7.25.0': + '@babel/helpers@7.25.7': dependencies: - '@babel/template': 7.25.0 - '@babel/types': 7.25.2 + '@babel/template': 7.25.7 + '@babel/types': 7.25.7 - '@babel/highlight@7.24.7': + '@babel/highlight@7.25.7': dependencies: - '@babel/helper-validator-identifier': 7.24.7 + '@babel/helper-validator-identifier': 7.25.7 chalk: 2.4.2 js-tokens: 4.0.0 - picocolors: 1.0.1 + picocolors: 1.1.0 - '@babel/parser@7.25.3': + '@babel/parser@7.25.7': dependencies: - '@babel/types': 7.25.2 + '@babel/types': 7.25.7 - '@babel/parser@7.25.4': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/types': 7.25.4 - - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/traverse': 7.25.4 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/traverse': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0(@babel/core@7.25.2)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0(@babel/core@7.25.2)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/plugin-transform-optional-chaining': 7.25.7(@babel/core@7.25.7) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0(@babel/core@7.25.2)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/traverse': 7.25.4 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/traverse': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.7 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-syntax-import-assertions@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-syntax-import-attributes@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-syntax-jsx@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-syntax-typescript@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.25.2)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-arrow-functions@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-async-generator-functions@7.25.4(@babel/core@7.25.2)': + '@babel/plugin-transform-async-generator-functions@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-remap-async-to-generator': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) - '@babel/traverse': 7.25.4 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-remap-async-to-generator': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.7) + '@babel/traverse': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-async-to-generator@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-remap-async-to-generator': 7.25.0(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-module-imports': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-remap-async-to-generator': 7.25.7(@babel/core@7.25.7) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-block-scoped-functions@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-block-scoping@7.25.0(@babel/core@7.25.2)': + '@babel/plugin-transform-block-scoping@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-class-properties@7.25.4(@babel/core@7.25.2)': + '@babel/plugin-transform-class-properties@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-class-static-block@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.7) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.25.4(@babel/core@7.25.2)': + '@babel/plugin-transform-classes@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) - '@babel/traverse': 7.25.4 + '@babel/core': 7.25.7 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.7) + '@babel/traverse': 7.25.7 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-computed-properties@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/template': 7.25.0 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/template': 7.25.7 - '@babel/plugin-transform-destructuring@7.24.8(@babel/core@7.25.2)': + '@babel/plugin-transform-destructuring@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-dotall-regex@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-duplicate-keys@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0(@babel/core@7.25.2)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-dynamic-import@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.7) - '@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-exponentiation-operator@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.24.7 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-export-namespace-from@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.7) - '@babel/plugin-transform-for-of@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-for-of@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.25.1(@babel/core@7.25.2)': + '@babel/plugin-transform-function-name@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/traverse': 7.25.4 + '@babel/core': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/traverse': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-json-strings@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.7) - '@babel/plugin-transform-literals@7.25.2(@babel/core@7.25.2)': + '@babel/plugin-transform-literals@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-logical-assignment-operators@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.7) - '@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-member-expression-literals@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-modules-amd@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.24.8(@babel/core@7.25.2)': + '@babel/plugin-transform-modules-commonjs@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-simple-access': 7.24.7 + '@babel/core': 7.25.7 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-simple-access': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.25.0(@babel/core@7.25.2)': + '@babel/plugin-transform-modules-systemjs@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-validator-identifier': 7.24.7 - '@babel/traverse': 7.25.4 + '@babel/core': 7.25.7 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + '@babel/traverse': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-modules-umd@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-named-capturing-groups-regex@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-new-target@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-new-target@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-nullish-coalescing-operator@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.7) - '@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-numeric-separator@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.7) - '@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-object-rest-spread@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-transform-parameters': 7.25.7(@babel/core@7.25.7) - '@babel/plugin-transform-object-super@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-object-super@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.7) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-optional-catch-binding@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.7) - '@babel/plugin-transform-optional-chaining@7.24.8(@babel/core@7.25.2)': + '@babel/plugin-transform-optional-chaining@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.7) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-parameters@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-private-methods@7.25.4(@babel/core@7.25.2)': + '@babel/plugin-transform-private-methods@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-private-property-in-object@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.7) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-property-literals@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-regenerator@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 regenerator-transform: 0.15.2 - '@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-reserved-words@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-shorthand-properties@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-spread@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-spread@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-sticky-regex@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-template-literals@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-typeof-symbol@7.24.8(@babel/core@7.25.2)': + '@babel/plugin-transform-typeof-symbol@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-typescript@7.25.2(@babel/core@7.25.2)': + '@babel/plugin-transform-typescript@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/plugin-syntax-typescript': 7.25.7(@babel/core@7.25.7) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-unicode-escapes@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-unicode-property-regex@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.25.2)': + '@babel/plugin-transform-unicode-regex@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-unicode-sets-regex@7.25.4(@babel/core@7.25.2)': + '@babel/plugin-transform-unicode-sets-regex@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + '@babel/core': 7.25.7 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.7) + '@babel/helper-plugin-utils': 7.25.7 - '@babel/preset-env@7.25.4(@babel/core@7.25.2)': + '@babel/preset-env@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/compat-data': 7.25.4 - '@babel/core': 7.25.2 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-validator-option': 7.24.8 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.3(@babel/core@7.25.2) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.25.2) - '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-async-generator-functions': 7.25.4(@babel/core@7.25.2) - '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-block-scoping': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-transform-class-properties': 7.25.4(@babel/core@7.25.2) - '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-classes': 7.25.4(@babel/core@7.25.2) - '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-destructuring': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-function-name': 7.25.1(@babel/core@7.25.2) - '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-literals': 7.25.2(@babel/core@7.25.2) - '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-modules-systemjs': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-private-methods': 7.25.4(@babel/core@7.25.2) - '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-typeof-symbol': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-unicode-sets-regex': 7.25.4(@babel/core@7.25.2) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.25.2) - babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.2) - babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.2) - babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.2) + '@babel/compat-data': 7.25.7 + '@babel/core': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-validator-option': 7.25.7 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.7) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.7) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.7) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.7) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-import-assertions': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-syntax-import-attributes': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.7) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.7) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.7) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.7) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.7) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.25.7) + '@babel/plugin-transform-arrow-functions': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-async-generator-functions': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-async-to-generator': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-block-scoped-functions': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-block-scoping': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-class-properties': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-class-static-block': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-classes': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-computed-properties': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-destructuring': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-dotall-regex': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-duplicate-keys': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-dynamic-import': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-exponentiation-operator': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-export-namespace-from': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-for-of': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-function-name': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-json-strings': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-literals': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-logical-assignment-operators': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-member-expression-literals': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-modules-amd': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-modules-commonjs': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-modules-systemjs': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-modules-umd': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-named-capturing-groups-regex': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-new-target': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-nullish-coalescing-operator': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-numeric-separator': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-object-rest-spread': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-object-super': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-optional-catch-binding': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-optional-chaining': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-parameters': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-private-methods': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-private-property-in-object': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-property-literals': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-regenerator': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-reserved-words': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-shorthand-properties': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-spread': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-sticky-regex': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-template-literals': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-typeof-symbol': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-unicode-escapes': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-unicode-property-regex': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-unicode-regex': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-unicode-sets-regex': 7.25.7(@babel/core@7.25.7) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.25.7) + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.7) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.7) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.7) core-js-compat: 3.38.1 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.25.2)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/types': 7.25.4 + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/types': 7.25.7 esutils: 2.0.3 - '@babel/preset-typescript@7.24.7(@babel/core@7.25.2)': + '@babel/preset-typescript@7.25.7(@babel/core@7.25.7)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-validator-option': 7.24.8 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-validator-option': 7.25.7 + '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-modules-commonjs': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-transform-typescript': 7.25.7(@babel/core@7.25.7) transitivePeerDependencies: - supports-color - '@babel/regjsgen@0.8.0': {} - - '@babel/runtime@7.25.0': + '@babel/runtime@7.25.7': dependencies: regenerator-runtime: 0.14.1 - '@babel/runtime@7.25.4': + '@babel/template@7.25.7': dependencies: - regenerator-runtime: 0.14.1 + '@babel/code-frame': 7.25.7 + '@babel/parser': 7.25.7 + '@babel/types': 7.25.7 - '@babel/template@7.25.0': + '@babel/traverse@7.25.7': dependencies: - '@babel/code-frame': 7.24.7 - '@babel/parser': 7.25.4 - '@babel/types': 7.25.2 - - '@babel/traverse@7.25.3': - dependencies: - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.0 - '@babel/parser': 7.25.4 - '@babel/template': 7.25.0 - '@babel/types': 7.25.2 - debug: 4.3.6(supports-color@8.1.1) + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/parser': 7.25.7 + '@babel/template': 7.25.7 + '@babel/types': 7.25.7 + debug: 4.3.7(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/traverse@7.25.4': + '@babel/types@7.25.7': dependencies: - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.5 - '@babel/parser': 7.25.4 - '@babel/template': 7.25.0 - '@babel/types': 7.25.4 - debug: 4.3.6(supports-color@8.1.1) - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - - '@babel/types@7.25.2': - dependencies: - '@babel/helper-string-parser': 7.24.8 - '@babel/helper-validator-identifier': 7.24.7 - to-fast-properties: 2.0.0 - - '@babel/types@7.25.4': - dependencies: - '@babel/helper-string-parser': 7.24.8 - '@babel/helper-validator-identifier': 7.24.7 + '@babel/helper-string-parser': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 to-fast-properties: 2.0.0 '@bcherny/json-schema-ref-parser@10.0.5-fork': @@ -10499,13 +10670,12 @@ snapshots: '@braintree/sanitize-url@7.1.0': {} - '@changesets/apply-release-plan@7.0.4': + '@changesets/apply-release-plan@7.0.5': dependencies: - '@babel/runtime': 7.25.0 - '@changesets/config': 3.0.2 + '@changesets/config': 3.0.3 '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.0 - '@changesets/should-skip-package': 0.1.0 + '@changesets/git': 3.0.1 + '@changesets/should-skip-package': 0.1.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 detect-indent: 6.1.0 @@ -10516,12 +10686,11 @@ snapshots: resolve-from: 5.0.0 semver: 7.6.3 - '@changesets/assemble-release-plan@6.0.3': + '@changesets/assemble-release-plan@6.0.4': dependencies: - '@babel/runtime': 7.25.0 '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.1 - '@changesets/should-skip-package': 0.1.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/should-skip-package': 0.1.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 semver: 7.6.3 @@ -10538,46 +10707,42 @@ snapshots: transitivePeerDependencies: - encoding - '@changesets/cli@2.27.7': + '@changesets/cli@2.27.9': dependencies: - '@babel/runtime': 7.25.0 - '@changesets/apply-release-plan': 7.0.4 - '@changesets/assemble-release-plan': 6.0.3 + '@changesets/apply-release-plan': 7.0.5 + '@changesets/assemble-release-plan': 6.0.4 '@changesets/changelog-git': 0.2.0 - '@changesets/config': 3.0.2 + '@changesets/config': 3.0.3 '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.1 - '@changesets/get-release-plan': 4.0.3 - '@changesets/git': 3.0.0 - '@changesets/logger': 0.1.0 - '@changesets/pre': 2.0.0 - '@changesets/read': 0.6.0 - '@changesets/should-skip-package': 0.1.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/get-release-plan': 4.0.4 + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/should-skip-package': 0.1.1 '@changesets/types': 6.0.0 - '@changesets/write': 0.3.1 + '@changesets/write': 0.3.2 '@manypkg/get-packages': 1.1.3 - '@types/semver': 7.5.8 ansi-colors: 4.1.3 - chalk: 2.4.2 ci-info: 3.9.0 enquirer: 2.4.1 external-editor: 3.1.0 fs-extra: 7.0.1 - human-id: 1.0.2 mri: 1.2.0 - outdent: 0.5.0 p-limit: 2.3.0 - preferred-pm: 3.1.4 + package-manager-detector: 0.2.1 + picocolors: 1.1.0 resolve-from: 5.0.0 semver: 7.6.3 spawndamnit: 2.0.0 term-size: 2.2.1 - '@changesets/config@3.0.2': + '@changesets/config@3.0.3': dependencies: '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.1 - '@changesets/logger': 0.1.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/logger': 0.1.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 @@ -10587,74 +10752,67 @@ snapshots: dependencies: extendable-error: 0.1.7 - '@changesets/get-dependents-graph@2.1.1': + '@changesets/get-dependents-graph@2.1.2': dependencies: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 - chalk: 2.4.2 - fs-extra: 7.0.1 + picocolors: 1.1.0 semver: 7.6.3 '@changesets/get-github-info@0.6.0(encoding@0.1.13)': dependencies: dataloader: 1.4.0 - node-fetch: 2.6.7(encoding@0.1.13) + node-fetch: 2.7.0(encoding@0.1.13) transitivePeerDependencies: - encoding - '@changesets/get-release-plan@4.0.3': + '@changesets/get-release-plan@4.0.4': dependencies: - '@babel/runtime': 7.25.0 - '@changesets/assemble-release-plan': 6.0.3 - '@changesets/config': 3.0.2 - '@changesets/pre': 2.0.0 - '@changesets/read': 0.6.0 + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/config': 3.0.3 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 '@changesets/get-version-range-type@0.4.0': {} - '@changesets/git@3.0.0': + '@changesets/git@3.0.1': dependencies: - '@babel/runtime': 7.25.0 '@changesets/errors': 0.2.0 - '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 micromatch: 4.0.8 spawndamnit: 2.0.0 - '@changesets/logger@0.1.0': + '@changesets/logger@0.1.1': dependencies: - chalk: 2.4.2 + picocolors: 1.1.0 '@changesets/parse@0.4.0': dependencies: '@changesets/types': 6.0.0 js-yaml: 3.14.1 - '@changesets/pre@2.0.0': + '@changesets/pre@2.0.1': dependencies: - '@babel/runtime': 7.25.0 '@changesets/errors': 0.2.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - '@changesets/read@0.6.0': + '@changesets/read@0.6.1': dependencies: - '@babel/runtime': 7.25.0 - '@changesets/git': 3.0.0 - '@changesets/logger': 0.1.0 + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 '@changesets/parse': 0.4.0 '@changesets/types': 6.0.0 - chalk: 2.4.2 fs-extra: 7.0.1 p-filter: 2.1.0 + picocolors: 1.1.0 - '@changesets/should-skip-package@0.1.0': + '@changesets/should-skip-package@0.1.1': dependencies: - '@babel/runtime': 7.25.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 @@ -10662,9 +10820,8 @@ snapshots: '@changesets/types@6.0.0': {} - '@changesets/write@0.3.1': + '@changesets/write@0.3.2': dependencies: - '@babel/runtime': 7.25.0 '@changesets/types': 6.0.0 fs-extra: 7.0.1 human-id: 1.0.2 @@ -10690,72 +10847,17 @@ snapshots: '@colors/colors@1.5.0': optional: true - '@cspell/cspell-bundled-dicts@8.13.3': - dependencies: - '@cspell/dict-ada': 4.0.2 - '@cspell/dict-aws': 4.0.3 - '@cspell/dict-bash': 4.1.3 - '@cspell/dict-companies': 3.1.4 - '@cspell/dict-cpp': 5.1.15 - '@cspell/dict-cryptocurrencies': 5.0.0 - '@cspell/dict-csharp': 4.0.2 - '@cspell/dict-css': 4.0.13 - '@cspell/dict-dart': 2.0.3 - '@cspell/dict-django': 4.1.0 - '@cspell/dict-docker': 1.1.7 - '@cspell/dict-dotnet': 5.0.4 - '@cspell/dict-elixir': 4.0.3 - '@cspell/dict-en-common-misspellings': 2.0.4 - '@cspell/dict-en-gb': 1.1.33 - '@cspell/dict-en_us': 4.3.23 - '@cspell/dict-filetypes': 3.0.4 - '@cspell/dict-fonts': 4.0.0 - '@cspell/dict-fsharp': 1.0.1 - '@cspell/dict-fullstack': 3.2.0 - '@cspell/dict-gaming-terms': 1.0.5 - '@cspell/dict-git': 3.0.0 - '@cspell/dict-golang': 6.0.11 - '@cspell/dict-google': 1.0.1 - '@cspell/dict-haskell': 4.0.1 - '@cspell/dict-html': 4.0.5 - '@cspell/dict-html-symbol-entities': 4.0.0 - '@cspell/dict-java': 5.0.7 - '@cspell/dict-julia': 1.0.1 - '@cspell/dict-k8s': 1.0.6 - '@cspell/dict-latex': 4.0.0 - '@cspell/dict-lorem-ipsum': 4.0.0 - '@cspell/dict-lua': 4.0.3 - '@cspell/dict-makefile': 1.0.0 - '@cspell/dict-monkeyc': 1.0.6 - '@cspell/dict-node': 5.0.1 - '@cspell/dict-npm': 5.0.18 - '@cspell/dict-php': 4.0.9 - '@cspell/dict-powershell': 5.0.5 - '@cspell/dict-public-licenses': 2.0.8 - '@cspell/dict-python': 4.2.4 - '@cspell/dict-r': 2.0.1 - '@cspell/dict-ruby': 5.0.3 - '@cspell/dict-rust': 4.0.5 - '@cspell/dict-scala': 5.0.3 - '@cspell/dict-software-terms': 4.0.11 - '@cspell/dict-sql': 2.1.5 - '@cspell/dict-svelte': 1.0.2 - '@cspell/dict-swift': 2.0.1 - '@cspell/dict-terraform': 1.0.0 - '@cspell/dict-typescript': 3.1.6 - '@cspell/dict-vue': 3.0.0 - - '@cspell/cspell-bundled-dicts@8.14.2': + '@cspell/cspell-bundled-dicts@8.14.4': dependencies: '@cspell/dict-ada': 4.0.2 '@cspell/dict-aws': 4.0.4 - '@cspell/dict-bash': 4.1.4 + '@cspell/dict-bash': 4.1.5 '@cspell/dict-companies': 3.1.4 - '@cspell/dict-cpp': 5.1.16 + '@cspell/dict-cpp': 5.1.19 '@cspell/dict-cryptocurrencies': 5.0.0 '@cspell/dict-csharp': 4.0.2 '@cspell/dict-css': 4.0.13 - '@cspell/dict-dart': 2.0.3 + '@cspell/dict-dart': 2.2.1 '@cspell/dict-django': 4.1.0 '@cspell/dict-docker': 1.1.7 '@cspell/dict-dotnet': 5.0.5 @@ -10764,15 +10866,16 @@ snapshots: '@cspell/dict-en-gb': 1.1.33 '@cspell/dict-en_us': 4.3.23 '@cspell/dict-filetypes': 3.0.4 + '@cspell/dict-flutter': 1.0.0 '@cspell/dict-fonts': 4.0.0 '@cspell/dict-fsharp': 1.0.1 '@cspell/dict-fullstack': 3.2.0 '@cspell/dict-gaming-terms': 1.0.5 '@cspell/dict-git': 3.0.0 - '@cspell/dict-golang': 6.0.12 + '@cspell/dict-golang': 6.0.13 '@cspell/dict-google': 1.0.1 '@cspell/dict-haskell': 4.0.1 - '@cspell/dict-html': 4.0.5 + '@cspell/dict-html': 4.0.6 '@cspell/dict-html-symbol-entities': 4.0.0 '@cspell/dict-java': 5.0.7 '@cspell/dict-julia': 1.0.1 @@ -10783,62 +10886,46 @@ snapshots: '@cspell/dict-makefile': 1.0.0 '@cspell/dict-monkeyc': 1.0.6 '@cspell/dict-node': 5.0.1 - '@cspell/dict-npm': 5.1.0 + '@cspell/dict-npm': 5.1.5 '@cspell/dict-php': 4.0.10 - '@cspell/dict-powershell': 5.0.6 + '@cspell/dict-powershell': 5.0.10 '@cspell/dict-public-licenses': 2.0.8 - '@cspell/dict-python': 4.2.6 + '@cspell/dict-python': 4.2.8 '@cspell/dict-r': 2.0.1 - '@cspell/dict-ruby': 5.0.3 - '@cspell/dict-rust': 4.0.5 + '@cspell/dict-ruby': 5.0.4 + '@cspell/dict-rust': 4.0.6 '@cspell/dict-scala': 5.0.3 - '@cspell/dict-software-terms': 4.1.1 + '@cspell/dict-software-terms': 4.1.7 '@cspell/dict-sql': 2.1.5 '@cspell/dict-svelte': 1.0.2 '@cspell/dict-swift': 2.0.1 - '@cspell/dict-terraform': 1.0.1 + '@cspell/dict-terraform': 1.0.2 '@cspell/dict-typescript': 3.1.6 '@cspell/dict-vue': 3.0.0 - '@cspell/cspell-json-reporter@8.14.2': + '@cspell/cspell-json-reporter@8.14.4': dependencies: - '@cspell/cspell-types': 8.14.2 + '@cspell/cspell-types': 8.14.4 - '@cspell/cspell-pipe@8.13.3': {} + '@cspell/cspell-pipe@8.14.4': {} - '@cspell/cspell-pipe@8.14.2': {} - - '@cspell/cspell-resolver@8.13.3': + '@cspell/cspell-resolver@8.14.4': dependencies: global-directory: 4.0.1 - '@cspell/cspell-resolver@8.14.2': - dependencies: - global-directory: 4.0.1 + '@cspell/cspell-service-bus@8.14.4': {} - '@cspell/cspell-service-bus@8.13.3': {} - - '@cspell/cspell-service-bus@8.14.2': {} - - '@cspell/cspell-types@8.13.3': {} - - '@cspell/cspell-types@8.14.2': {} + '@cspell/cspell-types@8.14.4': {} '@cspell/dict-ada@4.0.2': {} - '@cspell/dict-aws@4.0.3': {} - '@cspell/dict-aws@4.0.4': {} - '@cspell/dict-bash@4.1.3': {} - - '@cspell/dict-bash@4.1.4': {} + '@cspell/dict-bash@4.1.5': {} '@cspell/dict-companies@3.1.4': {} - '@cspell/dict-cpp@5.1.15': {} - - '@cspell/dict-cpp@5.1.16': {} + '@cspell/dict-cpp@5.1.19': {} '@cspell/dict-cryptocurrencies@5.0.0': {} @@ -10846,16 +10933,14 @@ snapshots: '@cspell/dict-css@4.0.13': {} - '@cspell/dict-dart@2.0.3': {} + '@cspell/dict-dart@2.2.1': {} - '@cspell/dict-data-science@2.0.1': {} + '@cspell/dict-data-science@2.0.2': {} '@cspell/dict-django@4.1.0': {} '@cspell/dict-docker@1.1.7': {} - '@cspell/dict-dotnet@5.0.4': {} - '@cspell/dict-dotnet@5.0.5': {} '@cspell/dict-elixir@4.0.3': {} @@ -10868,6 +10953,8 @@ snapshots: '@cspell/dict-filetypes@3.0.4': {} + '@cspell/dict-flutter@1.0.0': {} + '@cspell/dict-fonts@4.0.0': {} '@cspell/dict-fsharp@1.0.1': {} @@ -10878,9 +10965,7 @@ snapshots: '@cspell/dict-git@3.0.0': {} - '@cspell/dict-golang@6.0.11': {} - - '@cspell/dict-golang@6.0.12': {} + '@cspell/dict-golang@6.0.13': {} '@cspell/dict-google@1.0.1': {} @@ -10888,7 +10973,7 @@ snapshots: '@cspell/dict-html-symbol-entities@4.0.0': {} - '@cspell/dict-html@4.0.5': {} + '@cspell/dict-html@4.0.6': {} '@cspell/dict-java@5.0.7': {} @@ -10908,39 +10993,27 @@ snapshots: '@cspell/dict-node@5.0.1': {} - '@cspell/dict-npm@5.0.18': {} - - '@cspell/dict-npm@5.1.0': {} + '@cspell/dict-npm@5.1.5': {} '@cspell/dict-php@4.0.10': {} - '@cspell/dict-php@4.0.9': {} - - '@cspell/dict-powershell@5.0.5': {} - - '@cspell/dict-powershell@5.0.6': {} + '@cspell/dict-powershell@5.0.10': {} '@cspell/dict-public-licenses@2.0.8': {} - '@cspell/dict-python@4.2.4': + '@cspell/dict-python@4.2.8': dependencies: - '@cspell/dict-data-science': 2.0.1 - - '@cspell/dict-python@4.2.6': - dependencies: - '@cspell/dict-data-science': 2.0.1 + '@cspell/dict-data-science': 2.0.2 '@cspell/dict-r@2.0.1': {} - '@cspell/dict-ruby@5.0.3': {} + '@cspell/dict-ruby@5.0.4': {} - '@cspell/dict-rust@4.0.5': {} + '@cspell/dict-rust@4.0.6': {} '@cspell/dict-scala@5.0.3': {} - '@cspell/dict-software-terms@4.0.11': {} - - '@cspell/dict-software-terms@4.1.1': {} + '@cspell/dict-software-terms@4.1.7': {} '@cspell/dict-sql@2.1.5': {} @@ -10948,89 +11021,79 @@ snapshots: '@cspell/dict-swift@2.0.1': {} - '@cspell/dict-terraform@1.0.0': {} - - '@cspell/dict-terraform@1.0.1': {} + '@cspell/dict-terraform@1.0.2': {} '@cspell/dict-typescript@3.1.6': {} '@cspell/dict-vue@3.0.0': {} - '@cspell/dynamic-import@8.13.3': + '@cspell/dynamic-import@8.14.4': dependencies: import-meta-resolve: 4.1.0 - '@cspell/dynamic-import@8.14.2': + '@cspell/eslint-plugin@8.14.4(eslint@9.12.0(jiti@1.21.6))': dependencies: - import-meta-resolve: 4.1.0 + '@cspell/cspell-types': 8.14.4 + '@cspell/url': 8.14.4 + cspell-lib: 8.14.4 + eslint: 9.12.0(jiti@1.21.6) + synckit: 0.9.2 - '@cspell/eslint-plugin@8.13.3(eslint@9.8.0)': + '@cspell/filetypes@8.14.4': {} + + '@cspell/strong-weak-map@8.14.4': {} + + '@cspell/url@8.14.4': {} + + '@cypress/code-coverage@3.13.4(@babel/core@7.25.7)(@babel/preset-env@7.25.7(@babel/core@7.25.7))(babel-loader@9.2.1(@babel/core@7.25.7)(webpack@5.95.0(esbuild@0.21.5)))(cypress@13.15.0)(webpack@5.95.0(esbuild@0.21.5))': dependencies: - '@cspell/cspell-types': 8.13.3 - '@cspell/url': 8.13.3 - cspell-lib: 8.13.3 - eslint: 9.8.0 - synckit: 0.9.1 - - '@cspell/filetypes@8.14.2': {} - - '@cspell/strong-weak-map@8.13.3': {} - - '@cspell/strong-weak-map@8.14.2': {} - - '@cspell/url@8.13.3': {} - - '@cspell/url@8.14.2': {} - - '@cypress/code-coverage@3.12.45(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(babel-loader@9.1.3(@babel/core@7.25.2)(webpack@5.93.0(esbuild@0.21.5)))(cypress@13.14.1)(webpack@5.93.0(esbuild@0.21.5))': - dependencies: - '@babel/core': 7.25.2 - '@babel/preset-env': 7.25.4(@babel/core@7.25.2) - '@cypress/webpack-preprocessor': 6.0.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(babel-loader@9.1.3(@babel/core@7.25.2)(webpack@5.93.0(esbuild@0.21.5)))(webpack@5.93.0(esbuild@0.21.5)) - babel-loader: 9.1.3(@babel/core@7.25.2)(webpack@5.93.0(esbuild@0.21.5)) + '@babel/core': 7.25.7 + '@babel/preset-env': 7.25.7(@babel/core@7.25.7) + '@cypress/webpack-preprocessor': 6.0.2(@babel/core@7.25.7)(@babel/preset-env@7.25.7(@babel/core@7.25.7))(babel-loader@9.2.1(@babel/core@7.25.7)(webpack@5.95.0(esbuild@0.21.5)))(webpack@5.95.0(esbuild@0.21.5)) + babel-loader: 9.2.1(@babel/core@7.25.7)(webpack@5.95.0(esbuild@0.21.5)) chalk: 4.1.2 - cypress: 13.14.1 - dayjs: 1.11.12 - debug: 4.3.6(supports-color@8.1.1) + cypress: 13.15.0 + dayjs: 1.11.13 + debug: 4.3.7(supports-color@8.1.1) execa: 4.1.0 globby: 11.1.0 istanbul-lib-coverage: 3.2.2 js-yaml: 4.1.0 nyc: 15.1.0 - webpack: 5.93.0(esbuild@0.21.5) + webpack: 5.95.0(esbuild@0.21.5) transitivePeerDependencies: - supports-color - '@cypress/request@3.0.1': + '@cypress/request@3.0.5': dependencies: aws-sign2: 0.7.0 - aws4: 1.13.1 + aws4: 1.13.2 caseless: 0.12.0 combined-stream: 1.0.8 extend: 3.0.2 forever-agent: 0.6.1 - form-data: 2.3.3 - http-signature: 1.3.6 + form-data: 4.0.0 + http-signature: 1.4.0 is-typedarray: 1.0.0 isstream: 0.1.2 json-stringify-safe: 5.0.1 mime-types: 2.1.35 performance-now: 2.1.0 - qs: 6.10.4 + qs: 6.13.0 safe-buffer: 5.2.1 tough-cookie: 4.1.4 tunnel-agent: 0.6.0 uuid: 8.3.2 - '@cypress/webpack-preprocessor@6.0.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(babel-loader@9.1.3(@babel/core@7.25.2)(webpack@5.93.0(esbuild@0.21.5)))(webpack@5.93.0(esbuild@0.21.5))': + '@cypress/webpack-preprocessor@6.0.2(@babel/core@7.25.7)(@babel/preset-env@7.25.7(@babel/core@7.25.7))(babel-loader@9.2.1(@babel/core@7.25.7)(webpack@5.95.0(esbuild@0.21.5)))(webpack@5.95.0(esbuild@0.21.5))': dependencies: - '@babel/core': 7.25.2 - '@babel/preset-env': 7.25.4(@babel/core@7.25.2) - babel-loader: 9.1.3(@babel/core@7.25.2)(webpack@5.93.0(esbuild@0.21.5)) + '@babel/core': 7.25.7 + '@babel/preset-env': 7.25.7(@babel/core@7.25.7) + babel-loader: 9.2.1(@babel/core@7.25.7)(webpack@5.95.0(esbuild@0.21.5)) bluebird: 3.7.1 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) lodash: 4.17.21 - webpack: 5.93.0(esbuild@0.21.5) + webpack: 5.95.0(esbuild@0.21.5) transitivePeerDependencies: - supports-color @@ -11041,14 +11104,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@dependents/detective-less@5.0.0': + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 7.0.0 + '@discoveryjs/json-ext@0.5.7': {} - '@docsearch/css@3.6.1': {} + '@docsearch/css@3.6.2': {} - '@docsearch/js@3.6.1(@algolia/client-search@4.24.0)(search-insights@2.15.0)': + '@docsearch/js@3.6.2(@algolia/client-search@4.24.0)(search-insights@2.17.2)': dependencies: - '@docsearch/react': 3.6.1(@algolia/client-search@4.24.0)(search-insights@2.15.0) - preact: 10.23.2 + '@docsearch/react': 3.6.2(@algolia/client-search@4.24.0)(search-insights@2.17.2) + preact: 10.24.2 transitivePeerDependencies: - '@algolia/client-search' - '@types/react' @@ -11056,27 +11124,27 @@ snapshots: - react-dom - search-insights - '@docsearch/react@3.6.1(@algolia/client-search@4.24.0)(search-insights@2.15.0)': + '@docsearch/react@3.6.2(@algolia/client-search@4.24.0)(search-insights@2.17.2)': dependencies: - '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.15.0) + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.2) '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) - '@docsearch/css': 3.6.1 + '@docsearch/css': 3.6.2 algoliasearch: 4.24.0 optionalDependencies: - search-insights: 2.15.0 + search-insights: 2.17.2 transitivePeerDependencies: - '@algolia/client-search' - '@emnapi/runtime@1.2.0': + '@emnapi/runtime@1.3.0': dependencies: tslib: 2.7.0 optional: true - '@es-joy/jsdoccomment@0.46.0': + '@es-joy/jsdoccomment@0.48.0': dependencies: comment-parser: 1.4.1 esquery: 1.6.0 - jsdoc-type-pratt-parser: 4.0.0 + jsdoc-type-pratt-parser: 4.1.0 '@esbuild/aix-ppc64@0.21.5': optional: true @@ -11219,28 +11287,30 @@ snapshots: '@esbuild/win32-x64@0.23.1': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.8.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@9.12.0(jiti@1.21.6))': dependencies: - eslint: 9.8.0 + eslint: 9.12.0(jiti@1.21.6) eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.11.0': {} + '@eslint-community/regexpp@4.11.1': {} - '@eslint/config-array@0.17.1': + '@eslint/config-array@0.18.0': dependencies: '@eslint/object-schema': 2.1.4 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color + '@eslint/core@0.6.0': {} + '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 - debug: 4.3.6(supports-color@8.1.1) - espree: 10.1.0 + debug: 4.3.7(supports-color@8.1.1) + espree: 10.2.0 globals: 14.0.0 - ignore: 5.3.1 + ignore: 5.3.2 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -11248,32 +11318,48 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.8.0': {} + '@eslint/js@9.12.0': {} '@eslint/object-schema@2.1.4': {} - '@fastify/ajv-compiler@1.1.0': + '@eslint/plugin-kit@0.2.0': dependencies: - ajv: 6.12.6 + levn: 0.4.1 - '@fastify/error@2.0.0': {} - - '@floating-ui/core@1.6.7': + '@fastify/ajv-compiler@3.6.0': dependencies: - '@floating-ui/utils': 0.2.7 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + fast-uri: 2.4.0 - '@floating-ui/dom@1.6.10': + '@fastify/busboy@2.1.1': {} + + '@fastify/error@3.4.1': {} + + '@fastify/fast-json-stringify-compiler@4.3.0': dependencies: - '@floating-ui/core': 1.6.7 - '@floating-ui/utils': 0.2.7 + fast-json-stringify: 5.16.1 - '@floating-ui/utils@0.2.7': {} - - '@floating-ui/vue@1.1.4(vue@3.4.38(typescript@5.4.5))': + '@fastify/merge-json-schemas@0.1.1': dependencies: - '@floating-ui/dom': 1.6.10 - '@floating-ui/utils': 0.2.7 - vue-demi: 0.14.10(vue@3.4.38(typescript@5.4.5)) + fast-deep-equal: 3.1.3 + + '@floating-ui/core@1.6.8': + dependencies: + '@floating-ui/utils': 0.2.8 + + '@floating-ui/dom@1.6.11': + dependencies: + '@floating-ui/core': 1.6.8 + '@floating-ui/utils': 0.2.8 + + '@floating-ui/utils@0.2.8': {} + + '@floating-ui/vue@1.1.5(vue@3.5.11(typescript@5.6.2))': + dependencies: + '@floating-ui/dom': 1.6.11 + '@floating-ui/utils': 0.2.8 + vue-demi: 0.14.10(vue@3.5.11(typescript@5.6.2)) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -11284,56 +11370,51 @@ snapshots: dependencies: '@hapi/hoek': 9.3.0 - '@headlessui-float/vue@0.14.3(@headlessui/vue@1.7.22(vue@3.4.38(typescript@5.4.5)))(vue@3.4.38(typescript@5.4.5))': + '@headlessui-float/vue@0.14.4(@headlessui/vue@1.7.23(vue@3.5.11(typescript@5.6.2)))(vue@3.5.11(typescript@5.6.2))': dependencies: - '@floating-ui/core': 1.6.7 - '@floating-ui/dom': 1.6.10 - '@floating-ui/vue': 1.1.4(vue@3.4.38(typescript@5.4.5)) - '@headlessui/vue': 1.7.22(vue@3.4.38(typescript@5.4.5)) - vue: 3.4.38(typescript@5.4.5) + '@floating-ui/core': 1.6.8 + '@floating-ui/dom': 1.6.11 + '@floating-ui/vue': 1.1.5(vue@3.5.11(typescript@5.6.2)) + '@headlessui/vue': 1.7.23(vue@3.5.11(typescript@5.6.2)) + vue: 3.5.11(typescript@5.6.2) transitivePeerDependencies: - '@vue/composition-api' - '@headlessui/tailwindcss@0.2.1(tailwindcss@3.4.10)': + '@headlessui/tailwindcss@0.2.1(tailwindcss@3.4.13)': dependencies: - tailwindcss: 3.4.10 + tailwindcss: 3.4.13 - '@headlessui/vue@1.7.22(vue@3.4.38(typescript@5.4.5))': + '@headlessui/vue@1.7.23(vue@3.5.11(typescript@5.6.2))': dependencies: - '@tanstack/vue-virtual': 3.10.4(vue@3.4.38(typescript@5.4.5)) - vue: 3.4.38(typescript@5.4.5) + '@tanstack/vue-virtual': 3.10.8(vue@3.5.11(typescript@5.6.2)) + vue: 3.5.11(typescript@5.6.2) + + '@humanfs/core@0.19.0': {} + + '@humanfs/node@0.16.5': + dependencies: + '@humanfs/core': 0.19.0 + '@humanwhocodes/retry': 0.3.1 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.3.0': {} + '@humanwhocodes/retry@0.3.1': {} - '@iconify-json/carbon@1.1.37': + '@iconify-json/carbon@1.2.1': dependencies: '@iconify/types': 2.0.0 '@iconify/types@2.0.0': {} - '@iconify/utils@2.1.30': - dependencies: - '@antfu/install-pkg': 0.1.1 - '@antfu/utils': 0.7.10 - '@iconify/types': 2.0.0 - debug: 4.3.6(supports-color@8.1.1) - kolorist: 1.8.0 - local-pkg: 0.5.0 - mlly: 1.7.1 - transitivePeerDependencies: - - supports-color - - '@iconify/utils@2.1.32': + '@iconify/utils@2.1.33': dependencies: '@antfu/install-pkg': 0.4.1 '@antfu/utils': 0.7.10 '@iconify/types': 2.0.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) kolorist: 1.8.0 local-pkg: 0.5.0 - mlly: 1.7.1 + mlly: 1.7.2 transitivePeerDependencies: - supports-color @@ -11403,7 +11484,7 @@ snapshots: '@img/sharp-wasm32@0.33.5': dependencies: - '@emnapi/runtime': 1.2.0 + '@emnapi/runtime': 1.3.0 optional: true '@img/sharp-win32-ia32@0.33.5': @@ -11434,7 +11515,7 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 20.16.2 + '@types/node': 20.16.11 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -11447,14 +11528,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.2 + '@types/node': 20.16.11 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.16.2) + jest-config: 29.7.0(@types/node@20.16.11) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -11479,7 +11560,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.2 + '@types/node': 20.16.11 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -11497,7 +11578,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.16.2 + '@types/node': 20.16.11 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -11519,7 +11600,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.16.2 + '@types/node': 20.16.11 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -11566,7 +11647,7 @@ snapshots: '@jest/transform@29.7.0': dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.7 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1 @@ -11589,8 +11670,8 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.16.2 - '@types/yargs': 17.0.32 + '@types/node': 20.16.11 + '@types/yargs': 17.0.33 chalk: 4.1.2 '@jridgewell/gen-mapping@0.3.5': @@ -11621,14 +11702,14 @@ snapshots: '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.25.0 + '@babel/runtime': 7.25.7 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.25.0 + '@babel/runtime': 7.25.7 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -11663,131 +11744,153 @@ snapshots: '@pkgr/core@0.1.1': {} - '@polka/url@1.0.0-next.25': {} + '@polka/url@1.0.0-next.28': {} - '@rollup/plugin-babel@5.3.1(@babel/core@7.25.2)(@types/babel__core@7.20.5)(rollup@2.79.1)': + '@rollup/plugin-babel@5.3.1(@babel/core@7.25.7)(@types/babel__core@7.20.5)(rollup@2.79.2)': dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-imports': 7.24.7 - '@rollup/pluginutils': 3.1.0(rollup@2.79.1) - rollup: 2.79.1 + '@babel/core': 7.25.7 + '@babel/helper-module-imports': 7.25.7 + '@rollup/pluginutils': 3.1.0(rollup@2.79.2) + rollup: 2.79.2 optionalDependencies: '@types/babel__core': 7.20.5 transitivePeerDependencies: - supports-color - '@rollup/plugin-node-resolve@15.2.3(rollup@2.79.1)': + '@rollup/plugin-node-resolve@15.3.0(rollup@2.79.2)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + '@rollup/pluginutils': 5.1.2(rollup@2.79.2) '@types/resolve': 1.20.2 deepmerge: 4.3.1 - is-builtin-module: 3.2.1 is-module: 1.0.0 resolve: 1.22.8 optionalDependencies: - rollup: 2.79.1 + rollup: 2.79.2 - '@rollup/plugin-replace@2.4.2(rollup@2.79.1)': + '@rollup/plugin-replace@2.4.2(rollup@2.79.2)': dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.1) + '@rollup/pluginutils': 3.1.0(rollup@2.79.2) magic-string: 0.25.9 - rollup: 2.79.1 + rollup: 2.79.2 - '@rollup/plugin-terser@0.4.4(rollup@2.79.1)': + '@rollup/plugin-terser@0.4.4(rollup@2.79.2)': dependencies: serialize-javascript: 6.0.2 smob: 1.5.0 - terser: 5.31.6 + terser: 5.34.1 optionalDependencies: - rollup: 2.79.1 + rollup: 2.79.2 - '@rollup/plugin-typescript@11.1.6(rollup@4.21.1)(tslib@2.7.0)(typescript@5.4.5)': + '@rollup/plugin-typescript@11.1.6(rollup@4.24.0)(tslib@2.7.0)(typescript@5.4.5)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.21.1) + '@rollup/pluginutils': 5.1.2(rollup@4.24.0) resolve: 1.22.8 typescript: 5.4.5 optionalDependencies: - rollup: 4.21.1 + rollup: 4.24.0 tslib: 2.7.0 - '@rollup/pluginutils@3.1.0(rollup@2.79.1)': + '@rollup/pluginutils@3.1.0(rollup@2.79.2)': dependencies: '@types/estree': 0.0.39 estree-walker: 1.0.1 picomatch: 2.3.1 - rollup: 2.79.1 + rollup: 2.79.2 - '@rollup/pluginutils@5.1.0(rollup@2.79.1)': + '@rollup/pluginutils@5.1.2(rollup@2.79.2)': dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 2.79.1 + rollup: 2.79.2 - '@rollup/pluginutils@5.1.0(rollup@4.21.1)': + '@rollup/pluginutils@5.1.2(rollup@4.24.0)': dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 4.21.1 + rollup: 4.24.0 - '@rollup/rollup-android-arm-eabi@4.21.1': + '@rollup/rollup-android-arm-eabi@4.24.0': optional: true - '@rollup/rollup-android-arm64@4.21.1': + '@rollup/rollup-android-arm64@4.24.0': optional: true - '@rollup/rollup-darwin-arm64@4.21.1': + '@rollup/rollup-darwin-arm64@4.24.0': optional: true - '@rollup/rollup-darwin-x64@4.21.1': + '@rollup/rollup-darwin-x64@4.24.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.21.1': + '@rollup/rollup-linux-arm-gnueabihf@4.24.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.21.1': + '@rollup/rollup-linux-arm-musleabihf@4.24.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.21.1': + '@rollup/rollup-linux-arm64-gnu@4.24.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.21.1': + '@rollup/rollup-linux-arm64-musl@4.24.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.21.1': + '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.21.1': + '@rollup/rollup-linux-riscv64-gnu@4.24.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.21.1': + '@rollup/rollup-linux-s390x-gnu@4.24.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.21.1': + '@rollup/rollup-linux-x64-gnu@4.24.0': optional: true - '@rollup/rollup-linux-x64-musl@4.21.1': + '@rollup/rollup-linux-x64-musl@4.24.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.21.1': + '@rollup/rollup-win32-arm64-msvc@4.24.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.21.1': + '@rollup/rollup-win32-ia32-msvc@4.24.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.21.1': + '@rollup/rollup-win32-x64-msvc@4.24.0': optional: true - '@shikijs/core@1.14.1': + '@shikijs/core@1.22.0': dependencies: + '@shikijs/engine-javascript': 1.22.0 + '@shikijs/engine-oniguruma': 1.22.0 + '@shikijs/types': 1.22.0 + '@shikijs/vscode-textmate': 9.3.0 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.3 + + '@shikijs/engine-javascript@1.22.0': + dependencies: + '@shikijs/types': 1.22.0 + '@shikijs/vscode-textmate': 9.3.0 + oniguruma-to-js: 0.4.3 + + '@shikijs/engine-oniguruma@1.22.0': + dependencies: + '@shikijs/types': 1.22.0 + '@shikijs/vscode-textmate': 9.3.0 + + '@shikijs/transformers@1.22.0': + dependencies: + shiki: 1.22.0 + + '@shikijs/types@1.22.0': + dependencies: + '@shikijs/vscode-textmate': 9.3.0 '@types/hast': 3.0.4 - '@shikijs/transformers@1.14.1': - dependencies: - shiki: 1.14.1 + '@shikijs/vscode-textmate@9.3.0': {} '@sideway/address@4.1.5': dependencies: @@ -11822,12 +11925,12 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tanstack/virtual-core@3.10.4': {} + '@tanstack/virtual-core@3.10.8': {} - '@tanstack/vue-virtual@3.10.4(vue@3.4.38(typescript@5.4.5))': + '@tanstack/vue-virtual@3.10.8(vue@3.5.11(typescript@5.6.2))': dependencies: - '@tanstack/virtual-core': 3.10.4 - vue: 3.4.38(typescript@5.4.5) + '@tanstack/virtual-core': 3.10.8 + vue: 3.5.11(typescript@5.6.2) '@tootallnate/once@2.0.0': {} @@ -11835,33 +11938,33 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.25.4 - '@babel/types': 7.25.4 + '@babel/parser': 7.25.7 + '@babel/types': 7.25.7 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.6 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.25.4 + '@babel/types': 7.25.7 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.25.4 - '@babel/types': 7.25.4 + '@babel/parser': 7.25.7 + '@babel/types': 7.25.7 '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.25.4 + '@babel/types': 7.25.7 '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 20.16.2 + '@types/node': 20.16.11 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.5.1 + '@types/node': 20.16.11 '@types/braces@3.0.4': {} @@ -11869,37 +11972,37 @@ snapshots: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 20.16.2 + '@types/node': 20.16.11 '@types/responselike': 1.0.3 '@types/connect-history-api-fallback@1.5.4': dependencies: - '@types/express-serve-static-core': 4.19.5 - '@types/node': 22.5.1 + '@types/express-serve-static-core': 5.0.0 + '@types/node': 20.16.11 '@types/connect@3.4.38': dependencies: - '@types/node': 20.16.2 + '@types/node': 20.16.11 '@types/cors@2.8.17': dependencies: - '@types/node': 20.16.2 + '@types/node': 20.16.11 '@types/cytoscape-fcose@2.2.4': dependencies: - '@types/cytoscape': 3.21.5 + '@types/cytoscape': 3.21.8 - '@types/cytoscape@3.21.5': {} + '@types/cytoscape@3.21.8': {} '@types/d3-array@3.2.1': {} '@types/d3-axis@3.0.6': dependencies: - '@types/d3-selection': 3.0.10 + '@types/d3-selection': 3.0.11 '@types/d3-brush@3.0.6': dependencies: - '@types/d3-selection': 3.0.10 + '@types/d3-selection': 3.0.11 '@types/d3-chord@3.0.6': {} @@ -11916,7 +12019,7 @@ snapshots: '@types/d3-drag@3.0.7': dependencies: - '@types/d3-selection': 3.0.10 + '@types/d3-selection': 3.0.11 '@types/d3-dsv@3.0.7': {} @@ -11960,7 +12063,7 @@ snapshots: dependencies: '@types/d3-time': 3.0.3 - '@types/d3-selection@3.0.10': {} + '@types/d3-selection@3.0.11': {} '@types/d3-shape@1.3.12': dependencies: @@ -11976,14 +12079,14 @@ snapshots: '@types/d3-timer@3.0.2': {} - '@types/d3-transition@3.0.8': + '@types/d3-transition@3.0.9': dependencies: - '@types/d3-selection': 3.0.10 + '@types/d3-selection': 3.0.11 '@types/d3-zoom@3.0.8': dependencies: '@types/d3-interpolate': 3.0.4 - '@types/d3-selection': 3.0.10 + '@types/d3-selection': 3.0.11 '@types/d3@7.4.3': dependencies: @@ -12010,12 +12113,12 @@ snapshots: '@types/d3-random': 3.0.3 '@types/d3-scale': 4.0.8 '@types/d3-scale-chromatic': 3.0.3 - '@types/d3-selection': 3.0.10 + '@types/d3-selection': 3.0.11 '@types/d3-shape': 3.1.6 '@types/d3-time': 3.0.3 '@types/d3-time-format': 4.0.3 '@types/d3-timer': 3.0.2 - '@types/d3-transition': 3.0.8 + '@types/d3-transition': 3.0.9 '@types/d3-zoom': 3.0.8 '@types/debug@4.1.12': @@ -12026,32 +12129,29 @@ snapshots: dependencies: '@types/trusted-types': 2.0.7 - '@types/eslint-scope@3.7.7': - dependencies: - '@types/eslint': 9.6.0 - '@types/estree': 1.0.5 - - '@types/eslint@9.6.0': - dependencies: - '@types/estree': 1.0.5 - '@types/json-schema': 7.0.15 - '@types/estree@0.0.39': {} - '@types/estree@1.0.5': {} + '@types/estree@1.0.6': {} - '@types/express-serve-static-core@4.19.5': + '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 20.16.2 - '@types/qs': 6.9.15 + '@types/node': 20.16.11 + '@types/qs': 6.9.16 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + + '@types/express-serve-static-core@5.0.0': + dependencies: + '@types/node': 20.16.11 + '@types/qs': 6.9.16 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 '@types/express@4.17.21': dependencies: '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.19.5 - '@types/qs': 6.9.15 + '@types/express-serve-static-core': 4.19.6 + '@types/qs': 6.9.16 '@types/serve-static': 1.15.7 '@types/flexsearch@0.7.6': {} @@ -12061,16 +12161,16 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 5.1.2 - '@types/node': 22.5.1 + '@types/node': 20.16.11 '@types/glob@8.1.0': dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.16.2 + '@types/node': 20.16.11 '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 20.16.2 + '@types/node': 20.16.11 '@types/hast@3.0.4': dependencies: @@ -12080,9 +12180,9 @@ snapshots: '@types/http-errors@2.0.4': {} - '@types/http-proxy@1.17.14': + '@types/http-proxy@1.17.15': dependencies: - '@types/node': 22.5.1 + '@types/node': 20.16.11 '@types/istanbul-lib-coverage@2.0.6': {} @@ -12098,7 +12198,7 @@ snapshots: '@types/jsdom@21.1.7': dependencies: - '@types/node': 20.14.14 + '@types/node': 20.16.11 '@types/tough-cookie': 4.0.5 parse5: 7.1.2 @@ -12108,15 +12208,15 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 20.16.2 + '@types/node': 20.16.11 '@types/linkify-it@5.0.0': {} '@types/lodash-es@4.17.12': dependencies: - '@types/lodash': 4.17.7 + '@types/lodash': 4.17.10 - '@types/lodash@4.17.7': {} + '@types/lodash@4.17.10': {} '@types/markdown-it@12.2.3': dependencies: @@ -12130,11 +12230,11 @@ snapshots: '@types/mdast@3.0.15': dependencies: - '@types/unist': 2.0.10 + '@types/unist': 2.0.11 '@types/mdast@4.0.4': dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 '@types/mdurl@2.0.0': {} @@ -12150,23 +12250,15 @@ snapshots: '@types/node-forge@1.3.11': dependencies: - '@types/node': 22.5.1 + '@types/node': 20.16.11 '@types/node@12.20.55': {} - '@types/node@18.19.47': + '@types/node@18.19.55': dependencies: undici-types: 5.26.5 - '@types/node@20.14.14': - dependencies: - undici-types: 5.26.5 - - '@types/node@20.16.2': - dependencies: - undici-types: 6.19.8 - - '@types/node@22.5.1': + '@types/node@20.16.11': dependencies: undici-types: 6.19.8 @@ -12178,7 +12270,7 @@ snapshots: dependencies: prettier: 3.3.3 - '@types/qs@6.9.15': {} + '@types/qs@6.9.16': {} '@types/ramda@0.28.25': dependencies: @@ -12190,20 +12282,18 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 20.16.2 + '@types/node': 20.16.11 '@types/retry@0.12.0': {} '@types/rollup-plugin-visualizer@4.2.4': dependencies: - rollup: 2.79.1 - - '@types/semver@7.5.8': {} + rollup: 2.79.2 '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.5.1 + '@types/node': 20.16.11 '@types/serve-index@1.9.4': dependencies: @@ -12212,7 +12302,7 @@ snapshots: '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 22.5.1 + '@types/node': 20.16.11 '@types/send': 0.17.4 '@types/sinonjs__fake-timers@8.1.1': {} @@ -12221,7 +12311,7 @@ snapshots: '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.5.1 + '@types/node': 20.16.11 '@types/stack-utils@2.0.3': {} @@ -12231,9 +12321,7 @@ snapshots: '@types/trusted-types@2.0.7': {} - '@types/unist@2.0.10': {} - - '@types/unist@3.0.2': {} + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} @@ -12243,32 +12331,32 @@ snapshots: '@types/ws@8.5.12': dependencies: - '@types/node': 22.5.1 + '@types/node': 20.16.11 '@types/ws@8.5.5': dependencies: - '@types/node': 20.16.2 + '@types/node': 20.16.11 '@types/yargs-parser@21.0.3': {} - '@types/yargs@17.0.32': + '@types/yargs@17.0.33': dependencies: '@types/yargs-parser': 21.0.3 '@types/yauzl@2.10.3': dependencies: - '@types/node': 20.16.2 + '@types/node': 20.16.11 optional: true - '@typescript-eslint/eslint-plugin@8.0.1(@typescript-eslint/parser@8.0.1(eslint@9.8.0)(typescript@5.4.5))(eslint@9.8.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@8.8.1(@typescript-eslint/parser@8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5))(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5)': dependencies: - '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 8.0.1(eslint@9.8.0)(typescript@5.4.5) - '@typescript-eslint/scope-manager': 8.0.1 - '@typescript-eslint/type-utils': 8.0.1(eslint@9.8.0)(typescript@5.4.5) - '@typescript-eslint/utils': 8.0.1(eslint@9.8.0)(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 8.0.1 - eslint: 9.8.0 + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5) + '@typescript-eslint/scope-manager': 8.8.1 + '@typescript-eslint/type-utils': 8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5) + '@typescript-eslint/utils': 8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 8.8.1 + eslint: 9.12.0(jiti@1.21.6) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -12278,34 +12366,29 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.0.1(eslint@9.8.0)(typescript@5.4.5)': + '@typescript-eslint/parser@8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5)': dependencies: - '@typescript-eslint/scope-manager': 8.0.1 - '@typescript-eslint/types': 8.0.1 - '@typescript-eslint/typescript-estree': 8.0.1(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 8.0.1 - debug: 4.3.6(supports-color@8.1.1) - eslint: 9.8.0 + '@typescript-eslint/scope-manager': 8.8.1 + '@typescript-eslint/types': 8.8.1 + '@typescript-eslint/typescript-estree': 8.8.1(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 8.8.1 + debug: 4.3.7(supports-color@8.1.1) + eslint: 9.12.0(jiti@1.21.6) optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.0.0': + '@typescript-eslint/scope-manager@8.8.1': dependencies: - '@typescript-eslint/types': 8.0.0 - '@typescript-eslint/visitor-keys': 8.0.0 + '@typescript-eslint/types': 8.8.1 + '@typescript-eslint/visitor-keys': 8.8.1 - '@typescript-eslint/scope-manager@8.0.1': + '@typescript-eslint/type-utils@8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5)': dependencies: - '@typescript-eslint/types': 8.0.1 - '@typescript-eslint/visitor-keys': 8.0.1 - - '@typescript-eslint/type-utils@8.0.1(eslint@9.8.0)(typescript@5.4.5)': - dependencies: - '@typescript-eslint/typescript-estree': 8.0.1(typescript@5.4.5) - '@typescript-eslint/utils': 8.0.1(eslint@9.8.0)(typescript@5.4.5) - debug: 4.3.6(supports-color@8.1.1) + '@typescript-eslint/typescript-estree': 8.8.1(typescript@5.4.5) + '@typescript-eslint/utils': 8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5) + debug: 4.3.7(supports-color@8.1.1) ts-api-utils: 1.3.0(typescript@5.4.5) optionalDependencies: typescript: 5.4.5 @@ -12313,114 +12396,77 @@ snapshots: - eslint - supports-color - '@typescript-eslint/types@8.0.0': {} + '@typescript-eslint/types@7.18.0': {} - '@typescript-eslint/types@8.0.1': {} + '@typescript-eslint/types@8.8.1': {} - '@typescript-eslint/typescript-estree@8.0.0(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.6.2)': dependencies: - '@typescript-eslint/types': 8.0.0 - '@typescript-eslint/visitor-keys': 8.0.0 - debug: 4.3.6(supports-color@8.1.1) + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.7(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.6.2) optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.0.1(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@8.8.1(typescript@5.4.5)': dependencies: - '@typescript-eslint/types': 8.0.1 - '@typescript-eslint/visitor-keys': 8.0.1 - debug: 4.3.6(supports-color@8.1.1) - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.4.5) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.0.0(eslint@9.8.0)(typescript@5.4.5)': - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) - '@typescript-eslint/scope-manager': 8.0.0 - '@typescript-eslint/types': 8.0.0 - '@typescript-eslint/typescript-estree': 8.0.0(typescript@5.4.5) - eslint: 9.8.0 - transitivePeerDependencies: - - supports-color - - typescript - - '@typescript-eslint/utils@8.0.1(eslint@9.8.0)(typescript@5.4.5)': - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) - '@typescript-eslint/scope-manager': 8.0.1 - '@typescript-eslint/types': 8.0.1 - '@typescript-eslint/typescript-estree': 8.0.1(typescript@5.4.5) - eslint: 9.8.0 - transitivePeerDependencies: - - supports-color - - typescript - - '@typescript-eslint/visitor-keys@8.0.0': - dependencies: - '@typescript-eslint/types': 8.0.0 - eslint-visitor-keys: 3.4.3 - - '@typescript-eslint/visitor-keys@8.0.1': - dependencies: - '@typescript-eslint/types': 8.0.1 - eslint-visitor-keys: 3.4.3 - - '@unocss/astro@0.59.4(rollup@2.79.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))': - dependencies: - '@unocss/core': 0.59.4 - '@unocss/reset': 0.59.4 - '@unocss/vite': 0.59.4(rollup@2.79.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6)) - optionalDependencies: - vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) - transitivePeerDependencies: - - rollup - - '@unocss/astro@0.59.4(rollup@4.21.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))': - dependencies: - '@unocss/core': 0.59.4 - '@unocss/reset': 0.59.4 - '@unocss/vite': 0.59.4(rollup@4.21.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6)) - optionalDependencies: - vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) - transitivePeerDependencies: - - rollup - - '@unocss/cli@0.59.4(rollup@2.79.1)': - dependencies: - '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.0(rollup@2.79.1) - '@unocss/config': 0.59.4 - '@unocss/core': 0.59.4 - '@unocss/preset-uno': 0.59.4 - cac: 6.7.14 - chokidar: 3.6.0 - colorette: 2.0.20 - consola: 3.2.3 + '@typescript-eslint/types': 8.8.1 + '@typescript-eslint/visitor-keys': 8.8.1 + debug: 4.3.7(supports-color@8.1.1) fast-glob: 3.3.2 - magic-string: 0.30.11 - pathe: 1.1.2 - perfect-debounce: 1.0.0 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.12.0(jiti@1.21.6)) + '@typescript-eslint/scope-manager': 8.8.1 + '@typescript-eslint/types': 8.8.1 + '@typescript-eslint/typescript-estree': 8.8.1(typescript@5.4.5) + eslint: 9.12.0(jiti@1.21.6) + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + eslint-visitor-keys: 3.4.3 + + '@typescript-eslint/visitor-keys@8.8.1': + dependencies: + '@typescript-eslint/types': 8.8.1 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.2.0': {} + + '@unocss/astro@0.59.4(rollup@2.79.2)(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/reset': 0.59.4 + '@unocss/vite': 0.59.4(rollup@2.79.2)(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1)) + optionalDependencies: + vite: 5.4.8(@types/node@20.16.11)(terser@5.34.1) transitivePeerDependencies: - rollup - '@unocss/cli@0.59.4(rollup@4.21.1)': + '@unocss/cli@0.59.4(rollup@2.79.2)': dependencies: '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.0(rollup@4.21.1) + '@rollup/pluginutils': 5.1.2(rollup@2.79.2) '@unocss/config': 0.59.4 '@unocss/core': 0.59.4 '@unocss/preset-uno': 0.59.4 @@ -12453,7 +12499,7 @@ snapshots: gzip-size: 6.0.0 sirv: 2.0.4 - '@unocss/postcss@0.59.4(postcss@8.4.41)': + '@unocss/postcss@0.59.4(postcss@8.4.47)': dependencies: '@unocss/config': 0.59.4 '@unocss/core': 0.59.4 @@ -12461,7 +12507,7 @@ snapshots: css-tree: 2.3.1 fast-glob: 3.3.2 magic-string: 0.30.11 - postcss: 8.4.41 + postcss: 8.4.47 '@unocss/preset-attributify@0.59.4': dependencies: @@ -12469,9 +12515,9 @@ snapshots: '@unocss/preset-icons@0.59.4': dependencies: - '@iconify/utils': 2.1.30 + '@iconify/utils': 2.1.33 '@unocss/core': 0.59.4 - ofetch: 1.3.4 + ofetch: 1.4.0 transitivePeerDependencies: - supports-color @@ -12500,7 +12546,7 @@ snapshots: '@unocss/preset-web-fonts@0.59.4': dependencies: '@unocss/core': 0.59.4 - ofetch: 1.3.4 + ofetch: 1.4.0 '@unocss/preset-wind@0.59.4': dependencies: @@ -12519,9 +12565,9 @@ snapshots: '@unocss/transformer-attributify-jsx-babel@0.59.4': dependencies: - '@babel/core': 7.25.2 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) - '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.7) + '@babel/preset-typescript': 7.25.7(@babel/core@7.25.7) '@unocss/core': 0.59.4 transitivePeerDependencies: - supports-color @@ -12544,10 +12590,10 @@ snapshots: dependencies: '@unocss/core': 0.59.4 - '@unocss/vite@0.59.4(rollup@2.79.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))': + '@unocss/vite@0.59.4(rollup@2.79.2)(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))': dependencies: '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + '@rollup/pluginutils': 5.1.2(rollup@2.79.2) '@unocss/config': 0.59.4 '@unocss/core': 0.59.4 '@unocss/inspector': 0.59.4 @@ -12556,51 +12602,40 @@ snapshots: chokidar: 3.6.0 fast-glob: 3.3.2 magic-string: 0.30.11 - vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) + vite: 5.4.8(@types/node@20.16.11)(terser@5.34.1) transitivePeerDependencies: - rollup - '@unocss/vite@0.59.4(rollup@4.21.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))': + '@vite-pwa/vitepress@0.4.0(vite-plugin-pwa@0.19.8(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0))': dependencies: - '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.0(rollup@4.21.1) - '@unocss/config': 0.59.4 - '@unocss/core': 0.59.4 - '@unocss/inspector': 0.59.4 - '@unocss/scope': 0.59.4 - '@unocss/transformer-directives': 0.59.4 - chokidar: 3.6.0 - fast-glob: 3.3.2 - magic-string: 0.30.11 - vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) - transitivePeerDependencies: - - rollup + vite-plugin-pwa: 0.19.8(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0) - '@vite-pwa/vitepress@0.4.0(vite-plugin-pwa@0.19.8(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0))': + '@vitejs/plugin-vue@5.1.4(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))(vue@3.5.11(typescript@5.4.5))': dependencies: - vite-plugin-pwa: 0.19.8(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0) + vite: 5.4.8(@types/node@20.16.11)(terser@5.34.1) + vue: 3.5.11(typescript@5.4.5) - '@vitejs/plugin-vue@5.1.2(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(vue@3.4.38(typescript@5.4.5))': + '@vitejs/plugin-vue@5.1.4(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))(vue@3.5.11(typescript@5.6.2))': dependencies: - vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) - vue: 3.4.38(typescript@5.4.5) + vite: 5.4.8(@types/node@20.16.11)(terser@5.34.1) + vue: 3.5.11(typescript@5.6.2) - '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.16.2)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.31.6))': + '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.16.11)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.34.1))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 magic-string: 0.30.11 - magicast: 0.3.4 - picocolors: 1.0.1 + magicast: 0.3.5 + picocolors: 1.1.0 std-env: 3.7.0 strip-literal: 2.1.0 test-exclude: 6.0.0 - vitest: 1.6.0(@types/node@20.16.2)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.31.6) + vitest: 1.6.0(@types/node@20.16.11)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.34.1) transitivePeerDependencies: - supports-color @@ -12633,9 +12668,9 @@ snapshots: fflate: 0.8.2 flatted: 3.3.1 pathe: 1.1.2 - picocolors: 1.0.1 + picocolors: 1.1.0 sirv: 2.0.4 - vitest: 1.6.0(@types/node@20.16.2)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.31.6) + vitest: 1.6.0(@types/node@20.16.11)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.34.1) '@vitest/utils@1.6.0': dependencies: @@ -12644,52 +12679,52 @@ snapshots: loupe: 2.3.7 pretty-format: 29.7.0 - '@vue/compat@3.4.38(vue@3.4.38(typescript@5.4.5))': + '@vue/compat@3.5.11(vue@3.5.11(typescript@5.6.2))': dependencies: - '@babel/parser': 7.25.4 + '@babel/parser': 7.25.7 estree-walker: 2.0.2 - source-map-js: 1.2.0 - vue: 3.4.38(typescript@5.4.5) + source-map-js: 1.2.1 + vue: 3.5.11(typescript@5.6.2) - '@vue/compiler-core@3.4.38': + '@vue/compiler-core@3.5.11': dependencies: - '@babel/parser': 7.25.4 - '@vue/shared': 3.4.38 + '@babel/parser': 7.25.7 + '@vue/shared': 3.5.11 entities: 4.5.0 estree-walker: 2.0.2 - source-map-js: 1.2.0 + source-map-js: 1.2.1 - '@vue/compiler-dom@3.4.38': + '@vue/compiler-dom@3.5.11': dependencies: - '@vue/compiler-core': 3.4.38 - '@vue/shared': 3.4.38 + '@vue/compiler-core': 3.5.11 + '@vue/shared': 3.5.11 - '@vue/compiler-sfc@3.4.38': + '@vue/compiler-sfc@3.5.11': dependencies: - '@babel/parser': 7.25.4 - '@vue/compiler-core': 3.4.38 - '@vue/compiler-dom': 3.4.38 - '@vue/compiler-ssr': 3.4.38 - '@vue/shared': 3.4.38 + '@babel/parser': 7.25.7 + '@vue/compiler-core': 3.5.11 + '@vue/compiler-dom': 3.5.11 + '@vue/compiler-ssr': 3.5.11 + '@vue/shared': 3.5.11 estree-walker: 2.0.2 magic-string: 0.30.11 - postcss: 8.4.41 - source-map-js: 1.2.0 + postcss: 8.4.47 + source-map-js: 1.2.1 - '@vue/compiler-ssr@3.4.38': + '@vue/compiler-ssr@3.5.11': dependencies: - '@vue/compiler-dom': 3.4.38 - '@vue/shared': 3.4.38 + '@vue/compiler-dom': 3.5.11 + '@vue/shared': 3.5.11 - '@vue/devtools-api@6.6.3': {} + '@vue/devtools-api@6.6.4': {} - '@vue/devtools-api@7.3.9': + '@vue/devtools-api@7.4.6': dependencies: - '@vue/devtools-kit': 7.3.9 + '@vue/devtools-kit': 7.4.6 - '@vue/devtools-kit@7.3.9': + '@vue/devtools-kit@7.4.6': dependencies: - '@vue/devtools-shared': 7.3.9 + '@vue/devtools-shared': 7.4.6 birpc: 0.2.17 hookable: 5.5.3 mitt: 3.0.1 @@ -12697,92 +12732,96 @@ snapshots: speakingurl: 14.0.1 superjson: 2.2.1 - '@vue/devtools-shared@7.3.9': + '@vue/devtools-shared@7.4.6': dependencies: rfdc: 1.4.1 - '@vue/reactivity@3.4.38': + '@vue/reactivity@3.5.11': dependencies: - '@vue/shared': 3.4.38 + '@vue/shared': 3.5.11 - '@vue/runtime-core@3.4.38': + '@vue/runtime-core@3.5.11': dependencies: - '@vue/reactivity': 3.4.38 - '@vue/shared': 3.4.38 + '@vue/reactivity': 3.5.11 + '@vue/shared': 3.5.11 - '@vue/runtime-dom@3.4.38': + '@vue/runtime-dom@3.5.11': dependencies: - '@vue/reactivity': 3.4.38 - '@vue/runtime-core': 3.4.38 - '@vue/shared': 3.4.38 + '@vue/reactivity': 3.5.11 + '@vue/runtime-core': 3.5.11 + '@vue/shared': 3.5.11 csstype: 3.1.3 - '@vue/server-renderer@3.4.38(vue@3.4.38(typescript@5.4.5))': + '@vue/server-renderer@3.5.11(vue@3.5.11(typescript@5.4.5))': dependencies: - '@vue/compiler-ssr': 3.4.38 - '@vue/shared': 3.4.38 - vue: 3.4.38(typescript@5.4.5) + '@vue/compiler-ssr': 3.5.11 + '@vue/shared': 3.5.11 + vue: 3.5.11(typescript@5.4.5) - '@vue/shared@3.4.38': {} + '@vue/server-renderer@3.5.11(vue@3.5.11(typescript@5.6.2))': + dependencies: + '@vue/compiler-ssr': 3.5.11 + '@vue/shared': 3.5.11 + vue: 3.5.11(typescript@5.6.2) - '@vueuse/core@10.11.1(vue@3.4.38(typescript@5.4.5))': + '@vue/shared@3.5.11': {} + + '@vueuse/core@10.11.1(vue@3.5.11(typescript@5.4.5))': dependencies: '@types/web-bluetooth': 0.0.20 '@vueuse/metadata': 10.11.1 - '@vueuse/shared': 10.11.1(vue@3.4.38(typescript@5.4.5)) - vue-demi: 0.14.10(vue@3.4.38(typescript@5.4.5)) + '@vueuse/shared': 10.11.1(vue@3.5.11(typescript@5.4.5)) + vue-demi: 0.14.10(vue@3.5.11(typescript@5.4.5)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/core@11.0.3(vue@3.4.38(typescript@5.4.5))': + '@vueuse/core@10.11.1(vue@3.5.11(typescript@5.6.2))': dependencies: '@types/web-bluetooth': 0.0.20 - '@vueuse/metadata': 11.0.3 - '@vueuse/shared': 11.0.3(vue@3.4.38(typescript@5.4.5)) - vue-demi: 0.14.10(vue@3.4.38(typescript@5.4.5)) + '@vueuse/metadata': 10.11.1 + '@vueuse/shared': 10.11.1(vue@3.5.11(typescript@5.6.2)) + vue-demi: 0.14.10(vue@3.5.11(typescript@5.6.2)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/integrations@10.11.1(axios@1.7.5)(focus-trap@7.5.4)(vue@3.4.38(typescript@5.4.5))': + '@vueuse/integrations@10.11.1(axios@1.7.7)(focus-trap@7.6.0)(vue@3.5.11(typescript@5.4.5))': dependencies: - '@vueuse/core': 10.11.1(vue@3.4.38(typescript@5.4.5)) - '@vueuse/shared': 10.11.1(vue@3.4.38(typescript@5.4.5)) - vue-demi: 0.14.10(vue@3.4.38(typescript@5.4.5)) + '@vueuse/core': 10.11.1(vue@3.5.11(typescript@5.4.5)) + '@vueuse/shared': 10.11.1(vue@3.5.11(typescript@5.4.5)) + vue-demi: 0.14.10(vue@3.5.11(typescript@5.4.5)) optionalDependencies: - axios: 1.7.5(debug@4.3.6) - focus-trap: 7.5.4 + axios: 1.7.7(debug@4.3.7) + focus-trap: 7.6.0 transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/integrations@11.0.3(axios@1.7.5)(focus-trap@7.5.4)(vue@3.4.38(typescript@5.4.5))': + '@vueuse/integrations@10.11.1(axios@1.7.7)(focus-trap@7.6.0)(vue@3.5.11(typescript@5.6.2))': dependencies: - '@vueuse/core': 11.0.3(vue@3.4.38(typescript@5.4.5)) - '@vueuse/shared': 11.0.3(vue@3.4.38(typescript@5.4.5)) - vue-demi: 0.14.10(vue@3.4.38(typescript@5.4.5)) + '@vueuse/core': 10.11.1(vue@3.5.11(typescript@5.6.2)) + '@vueuse/shared': 10.11.1(vue@3.5.11(typescript@5.6.2)) + vue-demi: 0.14.10(vue@3.5.11(typescript@5.6.2)) optionalDependencies: - axios: 1.7.5(debug@4.3.6) - focus-trap: 7.5.4 + axios: 1.7.7(debug@4.3.7) + focus-trap: 7.6.0 transitivePeerDependencies: - '@vue/composition-api' - vue '@vueuse/metadata@10.11.1': {} - '@vueuse/metadata@11.0.3': {} - - '@vueuse/shared@10.11.1(vue@3.4.38(typescript@5.4.5))': + '@vueuse/shared@10.11.1(vue@3.5.11(typescript@5.4.5))': dependencies: - vue-demi: 0.14.10(vue@3.4.38(typescript@5.4.5)) + vue-demi: 0.14.10(vue@3.5.11(typescript@5.4.5)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/shared@11.0.3(vue@3.4.38(typescript@5.4.5))': + '@vueuse/shared@10.11.1(vue@3.5.11(typescript@5.6.2))': dependencies: - vue-demi: 0.14.10(vue@3.4.38(typescript@5.4.5)) + vue-demi: 0.14.10(vue@3.5.11(typescript@5.6.2)) transitivePeerDependencies: - '@vue/composition-api' - vue @@ -12801,7 +12840,7 @@ snapshots: '@wdio/logger@7.26.0': dependencies: chalk: 4.1.2 - loglevel: 1.9.1 + loglevel: 1.9.2 loglevel-plugin-prefix: 0.8.4 strip-ansi: 6.0.1 @@ -12809,7 +12848,7 @@ snapshots: '@wdio/types@7.30.2(typescript@5.4.5)': dependencies: - '@types/node': 18.19.47 + '@types/node': 18.19.55 got: 11.8.6 optionalDependencies: typescript: 5.4.5 @@ -12898,21 +12937,21 @@ snapshots: '@webassemblyjs/ast': 1.12.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@1.2.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0))(webpack@5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0))': + '@webpack-cli/configtest@1.2.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0))(webpack@5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0))': dependencies: - webpack: 5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0) - webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0) + webpack: 5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0) + webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0) - '@webpack-cli/info@1.5.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0))': + '@webpack-cli/info@1.5.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0))': dependencies: - envinfo: 7.13.0 - webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0) + envinfo: 7.14.0 + webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0) - '@webpack-cli/serve@1.7.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0))(webpack-dev-server@4.15.2(webpack-cli@4.10.0)(webpack@5.93.0))': + '@webpack-cli/serve@1.7.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0))(webpack-dev-server@4.15.2(webpack-cli@4.10.0)(webpack@5.95.0))': dependencies: - webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0) + webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0) optionalDependencies: - webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.93.0) + webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.95.0) '@xmldom/xmldom@0.8.10': {} @@ -12920,14 +12959,14 @@ snapshots: '@xtuc/long@4.2.2': {} - '@zenuml/core@3.24.3(typescript@5.4.5)': + '@zenuml/core@3.24.12(typescript@5.6.2)': dependencies: - '@headlessui-float/vue': 0.14.3(@headlessui/vue@1.7.22(vue@3.4.38(typescript@5.4.5)))(vue@3.4.38(typescript@5.4.5)) - '@headlessui/tailwindcss': 0.2.1(tailwindcss@3.4.10) - '@headlessui/vue': 1.7.22(vue@3.4.38(typescript@5.4.5)) + '@headlessui-float/vue': 0.14.4(@headlessui/vue@1.7.23(vue@3.5.11(typescript@5.6.2)))(vue@3.5.11(typescript@5.6.2)) + '@headlessui/tailwindcss': 0.2.1(tailwindcss@3.4.13) + '@headlessui/vue': 1.7.23(vue@3.5.11(typescript@5.6.2)) '@types/assert': 1.5.10 '@types/ramda': 0.28.25 - '@vue/compat': 3.4.38(vue@3.4.38(typescript@5.4.5)) + '@vue/compat': 3.5.11(vue@3.5.11(typescript@5.6.2)) antlr4: 4.11.0 color-string: 1.9.1 dom-to-image-more: 2.16.0 @@ -12938,11 +12977,11 @@ snapshots: lodash: 4.17.21 marked: 4.3.0 pino: 8.21.0 - postcss: 8.4.41 + postcss: 8.4.47 ramda: 0.28.0 - tailwindcss: 3.4.10 - vue: 3.4.38(typescript@5.4.5) - vuex: 4.1.0(vue@3.4.38(typescript@5.4.5)) + tailwindcss: 3.4.13 + vue: 3.5.11(typescript@5.6.2) + vuex: 4.1.0(vue@3.5.11(typescript@5.6.2)) transitivePeerDependencies: - '@vue/composition-api' - ts-node @@ -12971,7 +13010,7 @@ snapshots: dependencies: acorn: 8.12.1 - acorn-walk@8.3.3: + acorn-walk@8.3.4: dependencies: acorn: 8.12.1 @@ -12979,13 +13018,13 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color agent-base@7.1.1: dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -13003,6 +13042,10 @@ snapshots: optionalDependencies: ajv: 8.17.1 + ajv-formats@3.0.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + ajv-keywords@3.5.2(ajv@6.12.6): dependencies: ajv: 6.12.6 @@ -13029,7 +13072,7 @@ snapshots: ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.0.1 + fast-uri: 3.0.2 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -13074,7 +13117,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.0.1: {} + ansi-regex@6.1.0: {} ansi-sequence-parser@1.1.1: {} @@ -13101,6 +13144,8 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + app-module-path@2.2.0: {} + app-path@3.3.0: dependencies: execa: 1.0.0 @@ -13157,6 +13202,8 @@ snapshots: assertion-error@1.1.0: {} + ast-module-types@6.0.0: {} + astral-regex@2.0.0: {} async@3.2.6: {} @@ -13171,58 +13218,46 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - avvio@7.2.5: + avvio@8.4.0: dependencies: - archy: 1.0.0 - debug: 4.3.6(supports-color@8.1.1) + '@fastify/error': 3.4.1 fastq: 1.17.1 - queue-microtask: 1.2.3 - transitivePeerDependencies: - - supports-color aws-sign2@0.7.0: {} - aws4@1.13.1: {} + aws4@1.13.2: {} - axios@1.7.3(debug@4.3.6): + axios@1.7.7(debug@4.3.7): dependencies: - follow-redirects: 1.15.6(debug@4.3.6) + follow-redirects: 1.15.9(debug@4.3.7) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - axios@1.7.5(debug@4.3.6): + babel-jest@29.7.0(@babel/core@7.25.7): dependencies: - follow-redirects: 1.15.6(debug@4.3.6) - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - babel-jest@29.7.0(@babel/core@7.25.2): - dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.7 '@jest/transform': 29.7.0 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.25.2) + babel-preset-jest: 29.6.3(@babel/core@7.25.7) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 transitivePeerDependencies: - supports-color - babel-loader@9.1.3(@babel/core@7.25.2)(webpack@5.93.0(esbuild@0.21.5)): + babel-loader@9.2.1(@babel/core@7.25.7)(webpack@5.95.0(esbuild@0.21.5)): dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.7 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.93.0(esbuild@0.21.5) + webpack: 5.95.0(esbuild@0.21.5) babel-plugin-istanbul@6.1.1: dependencies: - '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-plugin-utils': 7.25.7 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 @@ -13232,56 +13267,59 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: - '@babel/template': 7.25.0 - '@babel/types': 7.25.4 + '@babel/template': 7.25.7 + '@babel/types': 7.25.7 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.6 - babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.25.2): + babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.25.7): dependencies: - '@babel/compat-data': 7.25.4 - '@babel/core': 7.25.2 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + '@babel/compat-data': 7.25.7 + '@babel/core': 7.25.7 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.7) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.25.2): + babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.25.7): dependencies: - '@babel/core': 7.25.2 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.7) core-js-compat: 3.38.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.25.2): + babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.25.7): dependencies: - '@babel/core': 7.25.2 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.7) transitivePeerDependencies: - supports-color - babel-preset-current-node-syntax@1.0.1(@babel/core@7.25.2): + babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.7): dependencies: - '@babel/core': 7.25.2 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) + '@babel/core': 7.25.7 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.7) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.7) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.7) + '@babel/plugin-syntax-import-attributes': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.7) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.7) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.7) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.7) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.7) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.7) - babel-preset-jest@29.6.3(@babel/core@7.25.2): + babel-preset-jest@29.6.3(@babel/core@7.25.7): dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.7 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.25.2) + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.7) bail@2.0.2: {} @@ -13318,7 +13356,7 @@ snapshots: bmpimagejs@1.0.4: {} - body-parser@1.20.2: + body-parser@1.20.3: dependencies: bytes: 3.1.2 content-type: 1.0.5 @@ -13328,7 +13366,7 @@ snapshots: http-errors: 2.0.0 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.11.0 + qs: 6.13.0 raw-body: 2.5.2 type-is: 1.6.18 unpipe: 1.0.0 @@ -13364,12 +13402,12 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.23.3: + browserslist@4.24.0: dependencies: - caniuse-lite: 1.0.30001649 - electron-to-chromium: 1.5.4 + caniuse-lite: 1.0.30001667 + electron-to-chromium: 1.5.33 node-releases: 2.0.18 - update-browserslist-db: 1.1.0(browserslist@4.23.3) + update-browserslist-db: 1.1.1(browserslist@4.24.0) bser@2.1.1: dependencies: @@ -13438,7 +13476,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001649: {} + caniuse-lite@1.0.30001667: {} caseless@0.12.0: {} @@ -13490,8 +13528,12 @@ snapshots: char-regex@1.0.2: {} + character-entities-html4@2.1.0: {} + character-entities-legacy@1.1.4: {} + character-entities-legacy@3.0.0: {} + character-entities@1.2.4: {} character-entities@2.0.2: {} @@ -13538,7 +13580,7 @@ snapshots: ci-info@4.0.0: {} - cjs-module-lexer@1.3.1: {} + cjs-module-lexer@1.4.1: {} cjson@0.3.0: dependencies: @@ -13619,6 +13661,9 @@ snapshots: dependencies: mimic-response: 1.0.1 + clone@1.0.4: + optional: true + co@4.6.0: {} collect-v8-coverage@1.0.2: {} @@ -13653,6 +13698,8 @@ snapshots: dependencies: delayed-stream: 1.0.0 + comma-separated-tokens@2.0.3: {} + commander@11.0.0: {} commander@12.1.0: {} @@ -13715,12 +13762,16 @@ snapshots: tree-kill: 1.2.2 yargs: 17.7.2 - confbox@0.1.7: {} + confbox@0.1.8: {} connect-history-api-fallback@2.0.0: {} consola@3.2.3: {} + console.table@0.10.0: + dependencies: + easy-table: 1.1.0 + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 @@ -13738,21 +13789,17 @@ snapshots: cookie-signature@1.0.6: {} - cookie@0.5.0: {} - cookie@0.6.0: {} + cookie@0.7.2: {} + copy-anything@3.0.5: dependencies: is-what: 4.1.16 - core-js-compat@3.38.0: - dependencies: - browserslist: 4.23.3 - core-js-compat@3.38.1: dependencies: - browserslist: 4.23.3 + browserslist: 4.24.0 core-util-is@1.0.2: {} @@ -13793,13 +13840,13 @@ snapshots: p-filter: 3.0.0 p-map: 6.0.0 - create-jest@29.7.0(@types/node@20.16.2): + create-jest@29.7.0(@types/node@20.16.11): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.16.2) + jest-config: 29.7.0(@types/node@20.16.11) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -13834,86 +13881,59 @@ snapshots: crypto-random-string@2.0.0: {} - cspell-config-lib@8.13.3: + cspell-config-lib@8.14.4: dependencies: - '@cspell/cspell-types': 8.13.3 + '@cspell/cspell-types': 8.14.4 comment-json: 4.2.5 - yaml: 2.5.0 + yaml: 2.5.1 - cspell-config-lib@8.14.2: + cspell-dictionary@8.14.4: dependencies: - '@cspell/cspell-types': 8.14.2 - comment-json: 4.2.5 - yaml: 2.5.0 - - cspell-dictionary@8.13.3: - dependencies: - '@cspell/cspell-pipe': 8.13.3 - '@cspell/cspell-types': 8.13.3 - cspell-trie-lib: 8.13.3 + '@cspell/cspell-pipe': 8.14.4 + '@cspell/cspell-types': 8.14.4 + cspell-trie-lib: 8.14.4 fast-equals: 5.0.1 - cspell-dictionary@8.14.2: + cspell-gitignore@8.14.4: dependencies: - '@cspell/cspell-pipe': 8.14.2 - '@cspell/cspell-types': 8.14.2 - cspell-trie-lib: 8.14.2 - fast-equals: 5.0.1 - - cspell-gitignore@8.14.2: - dependencies: - '@cspell/url': 8.14.2 - cspell-glob: 8.14.2 - cspell-io: 8.14.2 + '@cspell/url': 8.14.4 + cspell-glob: 8.14.4 + cspell-io: 8.14.4 find-up-simple: 1.0.0 - cspell-glob@8.13.3: + cspell-glob@8.14.4: dependencies: - '@cspell/url': 8.13.3 + '@cspell/url': 8.14.4 micromatch: 4.0.8 - cspell-glob@8.14.2: + cspell-grammar@8.14.4: dependencies: - '@cspell/url': 8.14.2 - micromatch: 4.0.8 + '@cspell/cspell-pipe': 8.14.4 + '@cspell/cspell-types': 8.14.4 - cspell-grammar@8.13.3: + cspell-io@8.14.4: dependencies: - '@cspell/cspell-pipe': 8.13.3 - '@cspell/cspell-types': 8.13.3 + '@cspell/cspell-service-bus': 8.14.4 + '@cspell/url': 8.14.4 - cspell-grammar@8.14.2: + cspell-lib@8.14.4: dependencies: - '@cspell/cspell-pipe': 8.14.2 - '@cspell/cspell-types': 8.14.2 - - cspell-io@8.13.3: - dependencies: - '@cspell/cspell-service-bus': 8.13.3 - '@cspell/url': 8.13.3 - - cspell-io@8.14.2: - dependencies: - '@cspell/cspell-service-bus': 8.14.2 - '@cspell/url': 8.14.2 - - cspell-lib@8.13.3: - dependencies: - '@cspell/cspell-bundled-dicts': 8.13.3 - '@cspell/cspell-pipe': 8.13.3 - '@cspell/cspell-resolver': 8.13.3 - '@cspell/cspell-types': 8.13.3 - '@cspell/dynamic-import': 8.13.3 - '@cspell/strong-weak-map': 8.13.3 - '@cspell/url': 8.13.3 + '@cspell/cspell-bundled-dicts': 8.14.4 + '@cspell/cspell-pipe': 8.14.4 + '@cspell/cspell-resolver': 8.14.4 + '@cspell/cspell-types': 8.14.4 + '@cspell/dynamic-import': 8.14.4 + '@cspell/filetypes': 8.14.4 + '@cspell/strong-weak-map': 8.14.4 + '@cspell/url': 8.14.4 clear-module: 4.1.2 comment-json: 4.2.5 - cspell-config-lib: 8.13.3 - cspell-dictionary: 8.13.3 - cspell-glob: 8.13.3 - cspell-grammar: 8.13.3 - cspell-io: 8.13.3 - cspell-trie-lib: 8.13.3 + cspell-config-lib: 8.14.4 + cspell-dictionary: 8.14.4 + cspell-glob: 8.14.4 + cspell-grammar: 8.14.4 + cspell-io: 8.14.4 + cspell-trie-lib: 8.14.4 env-paths: 3.0.0 fast-equals: 5.0.1 gensequence: 7.0.0 @@ -13923,60 +13943,27 @@ snapshots: vscode-uri: 3.0.8 xdg-basedir: 5.1.0 - cspell-lib@8.14.2: + cspell-trie-lib@8.14.4: dependencies: - '@cspell/cspell-bundled-dicts': 8.14.2 - '@cspell/cspell-pipe': 8.14.2 - '@cspell/cspell-resolver': 8.14.2 - '@cspell/cspell-types': 8.14.2 - '@cspell/dynamic-import': 8.14.2 - '@cspell/filetypes': 8.14.2 - '@cspell/strong-weak-map': 8.14.2 - '@cspell/url': 8.14.2 - clear-module: 4.1.2 - comment-json: 4.2.5 - cspell-config-lib: 8.14.2 - cspell-dictionary: 8.14.2 - cspell-glob: 8.14.2 - cspell-grammar: 8.14.2 - cspell-io: 8.14.2 - cspell-trie-lib: 8.14.2 - env-paths: 3.0.0 - fast-equals: 5.0.1 - gensequence: 7.0.0 - import-fresh: 3.3.0 - resolve-from: 5.0.0 - vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.0.8 - xdg-basedir: 5.1.0 - - cspell-trie-lib@8.13.3: - dependencies: - '@cspell/cspell-pipe': 8.13.3 - '@cspell/cspell-types': 8.13.3 + '@cspell/cspell-pipe': 8.14.4 + '@cspell/cspell-types': 8.14.4 gensequence: 7.0.0 - cspell-trie-lib@8.14.2: + cspell@8.14.4: dependencies: - '@cspell/cspell-pipe': 8.14.2 - '@cspell/cspell-types': 8.14.2 - gensequence: 7.0.0 - - cspell@8.14.2: - dependencies: - '@cspell/cspell-json-reporter': 8.14.2 - '@cspell/cspell-pipe': 8.14.2 - '@cspell/cspell-types': 8.14.2 - '@cspell/dynamic-import': 8.14.2 - '@cspell/url': 8.14.2 + '@cspell/cspell-json-reporter': 8.14.4 + '@cspell/cspell-pipe': 8.14.4 + '@cspell/cspell-types': 8.14.4 + '@cspell/dynamic-import': 8.14.4 + '@cspell/url': 8.14.4 chalk: 5.3.0 chalk-template: 1.1.0 commander: 12.1.0 - cspell-dictionary: 8.14.2 - cspell-gitignore: 8.14.2 - cspell-glob: 8.14.2 - cspell-io: 8.14.2 - cspell-lib: 8.14.2 + cspell-dictionary: 8.14.4 + cspell-gitignore: 8.14.4 + cspell-glob: 8.14.4 + cspell-io: 8.14.4 + cspell-lib: 8.14.4 fast-glob: 3.3.2 fast-json-stable-stringify: 2.1.0 file-entry-cache: 9.1.0 @@ -13987,13 +13974,13 @@ snapshots: css-tree@2.3.1: dependencies: mdn-data: 2.0.30 - source-map-js: 1.2.0 + source-map-js: 1.2.1 cssesc@3.0.0: {} - cssstyle@4.0.1: + cssstyle@4.1.0: dependencies: - rrweb-cssom: 0.6.0 + rrweb-cssom: 0.7.1 csstree-validator@3.0.0: dependencies: @@ -14005,23 +13992,37 @@ snapshots: cuint@0.2.2: {} - cypress-image-snapshot@4.0.1(cypress@13.14.1)(jest@29.7.0(@types/node@20.16.2)): + cypress-image-snapshot@4.0.1(cypress@13.15.0)(jest@29.7.0(@types/node@20.16.11)): dependencies: chalk: 2.4.2 - cypress: 13.14.1 + cypress: 13.15.0 fs-extra: 7.0.1 glob: 7.2.3 - jest-image-snapshot: 4.2.0(jest@29.7.0(@types/node@20.16.2)) + jest-image-snapshot: 4.2.0(jest@29.7.0(@types/node@20.16.11)) pkg-dir: 3.0.0 term-img: 4.1.0 transitivePeerDependencies: - jest + cypress-split@1.24.0(@babel/core@7.25.7): + dependencies: + '@actions/core': 1.11.1 + arg: 5.0.2 + console.table: 0.10.0 + debug: 4.3.7(supports-color@8.1.1) + fast-shuffle: 6.1.0 + find-cypress-specs: 1.43.4(@babel/core@7.25.7) + globby: 11.1.0 + humanize-duration: 3.32.1 + transitivePeerDependencies: + - '@babel/core' + - supports-color + cypress-wait-until@3.0.2: {} - cypress@13.14.1: + cypress@13.15.0: dependencies: - '@cypress/request': 3.0.1 + '@cypress/request': 3.0.5 '@cypress/xvfb': 1.2.4(supports-color@8.1.1) '@types/sinonjs__fake-timers': 8.1.1 '@types/sizzle': 2.3.8 @@ -14037,7 +14038,7 @@ snapshots: commander: 6.2.1 common-tags: 1.8.2 dayjs: 1.11.13 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) enquirer: 2.4.1 eventemitter2: 6.4.7 execa: 4.1.0 @@ -14064,17 +14065,17 @@ snapshots: untildify: 4.0.0 yauzl: 2.10.0 - cytoscape-cose-bilkent@4.1.0(cytoscape@3.30.1): + cytoscape-cose-bilkent@4.1.0(cytoscape@3.30.2): dependencies: cose-base: 1.0.3 - cytoscape: 3.30.1 + cytoscape: 3.30.2 - cytoscape-fcose@2.2.0(cytoscape@3.30.1): + cytoscape-fcose@2.2.0(cytoscape@3.30.2): dependencies: cose-base: 2.2.0 - cytoscape: 3.30.1 + cytoscape: 3.30.2 - cytoscape@3.30.1: {} + cytoscape@3.30.2: {} d3-array@2.12.1: dependencies: @@ -14248,7 +14249,7 @@ snapshots: es5-ext: 0.10.64 type: 2.7.3 - dagre-d3-es@7.0.10: + dagre-d3-es@7.0.11: dependencies: d3: 7.9.0 lodash-es: 4.17.21 @@ -14286,9 +14287,7 @@ snapshots: date-fns@2.30.0: dependencies: - '@babel/runtime': 7.25.0 - - dayjs@1.11.12: {} + '@babel/runtime': 7.25.7 dayjs@1.11.13: {} @@ -14310,9 +14309,9 @@ snapshots: dependencies: ms: 2.1.2 - debug@4.3.6(supports-color@8.1.1): + debug@4.3.7(supports-color@8.1.1): dependencies: - ms: 2.1.2 + ms: 2.1.3 optionalDependencies: supports-color: 8.1.1 @@ -14334,6 +14333,27 @@ snapshots: dependencies: type-detect: 4.1.0 + deep-equal@2.2.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + es-get-iterator: 1.1.3 + get-intrinsic: 1.2.4 + is-arguments: 1.1.1 + is-array-buffer: 3.0.4 + is-date-object: 1.0.5 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + isarray: 2.0.5 + object-is: 1.1.6 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.3 + side-channel: 1.0.6 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + deep-is@0.1.4: {} deepmerge@4.3.1: {} @@ -14346,6 +14366,11 @@ snapshots: dependencies: strip-bom: 4.0.0 + defaults@1.0.4: + dependencies: + clone: 1.0.4 + optional: true + defer-to-connect@2.0.1: {} define-data-property@1.1.4: @@ -14374,6 +14399,15 @@ snapshots: depd@2.0.0: {} + dependency-tree@11.0.1: + dependencies: + commander: 12.1.0 + filing-cabinet: 5.0.2 + precinct: 12.1.2 + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dequal@2.0.3: {} destr@2.0.3: {} @@ -14388,6 +14422,61 @@ snapshots: detect-node@2.1.0: {} + detective-amd@6.0.0: + dependencies: + ast-module-types: 6.0.0 + escodegen: 2.1.0 + get-amd-module-type: 6.0.0 + node-source-walk: 7.0.0 + + detective-cjs@6.0.0: + dependencies: + ast-module-types: 6.0.0 + node-source-walk: 7.0.0 + + detective-es6@5.0.0: + dependencies: + node-source-walk: 7.0.0 + + detective-postcss@7.0.0(postcss@8.4.47): + dependencies: + is-url: 1.2.4 + postcss: 8.4.47 + postcss-values-parser: 6.0.2(postcss@8.4.47) + + detective-sass@6.0.0: + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 7.0.0 + + detective-scss@5.0.0: + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 7.0.0 + + detective-stylus@5.0.0: {} + + detective-typescript@13.0.0(typescript@5.6.2): + dependencies: + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2) + ast-module-types: 6.0.0 + node-source-walk: 7.0.0 + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + + detective-vue2@2.0.3(typescript@5.6.2): + dependencies: + '@vue/compiler-sfc': 3.5.11 + detective-es6: 5.0.0 + detective-sass: 6.0.0 + detective-scss: 5.0.0 + detective-stylus: 5.0.0 + detective-typescript: 13.0.0(typescript@5.6.2) + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -14436,6 +14525,10 @@ snapshots: eastasianwidth@0.2.0: {} + easy-table@1.1.0: + optionalDependencies: + wcwidth: 1.0.1 + ebnf-parser@0.1.10: {} ecc-jsbn@0.1.2: @@ -14449,13 +14542,13 @@ snapshots: dependencies: jake: 10.9.2 - electron-to-chromium@1.5.4: {} + electron-to-chromium@1.5.33: {} elkjs@0.9.3: {} emittery@0.13.1: {} - emoji-regex@10.3.0: {} + emoji-regex@10.4.0: {} emoji-regex@8.0.0: {} @@ -14463,6 +14556,8 @@ snapshots: encodeurl@1.0.2: {} + encodeurl@2.0.0: {} + encoding@0.1.13: dependencies: iconv-lite: 0.6.3 @@ -14487,7 +14582,7 @@ snapshots: env-paths@3.0.0: {} - envinfo@7.13.0: {} + envinfo@7.14.0: {} environment@1.1.0: {} @@ -14531,7 +14626,7 @@ snapshots: object-inspect: 1.13.2 object-keys: 1.1.1 object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 + regexp.prototype.flags: 1.5.3 safe-array-concat: 1.1.2 safe-regex-test: 1.0.3 string.prototype.trim: 1.2.9 @@ -14550,6 +14645,18 @@ snapshots: es-errors@1.3.0: {} + es-get-iterator@1.1.3: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + is-arguments: 1.1.1 + is-map: 2.0.3 + is-set: 2.0.3 + is-string: 1.0.7 + isarray: 2.0.5 + stop-iteration-iterator: 1.0.0 + es-module-lexer@1.5.4: {} es-object-atoms@1.0.0: @@ -14650,7 +14757,7 @@ snapshots: '@esbuild/win32-ia32': 0.23.1 '@esbuild/win32-x64': 0.23.1 - escalade@3.1.2: {} + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -14670,44 +14777,52 @@ snapshots: optionalDependencies: source-map: 0.1.43 - eslint-config-prettier@9.1.0(eslint@9.8.0): + escodegen@2.1.0: dependencies: - eslint: 9.8.0 + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 - eslint-plugin-cypress@3.4.0(eslint@9.8.0): + eslint-config-prettier@9.1.0(eslint@9.12.0(jiti@1.21.6)): dependencies: - eslint: 9.8.0 + eslint: 9.12.0(jiti@1.21.6) + + eslint-plugin-cypress@3.5.0(eslint@9.12.0(jiti@1.21.6)): + dependencies: + eslint: 9.12.0(jiti@1.21.6) globals: 13.24.0 - eslint-plugin-html@8.1.1: + eslint-plugin-html@8.1.2: dependencies: htmlparser2: 9.1.0 - eslint-plugin-jest@28.7.0(@typescript-eslint/eslint-plugin@8.0.1(@typescript-eslint/parser@8.0.1(eslint@9.8.0)(typescript@5.4.5))(eslint@9.8.0)(typescript@5.4.5))(eslint@9.8.0)(jest@29.7.0(@types/node@20.16.2))(typescript@5.4.5): + eslint-plugin-jest@28.8.3(@typescript-eslint/eslint-plugin@8.8.1(@typescript-eslint/parser@8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5))(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5))(eslint@9.12.0(jiti@1.21.6))(jest@29.7.0(@types/node@20.16.11))(typescript@5.4.5): dependencies: - '@typescript-eslint/utils': 8.0.0(eslint@9.8.0)(typescript@5.4.5) - eslint: 9.8.0 + '@typescript-eslint/utils': 8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5) + eslint: 9.12.0(jiti@1.21.6) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.0.1(@typescript-eslint/parser@8.0.1(eslint@9.8.0)(typescript@5.4.5))(eslint@9.8.0)(typescript@5.4.5) - jest: 29.7.0(@types/node@20.16.2) + '@typescript-eslint/eslint-plugin': 8.8.1(@typescript-eslint/parser@8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5))(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5) + jest: 29.7.0(@types/node@20.16.11) transitivePeerDependencies: - supports-color - typescript - eslint-plugin-jsdoc@48.11.0(eslint@9.8.0): + eslint-plugin-jsdoc@50.3.1(eslint@9.12.0(jiti@1.21.6)): dependencies: - '@es-joy/jsdoccomment': 0.46.0 + '@es-joy/jsdoccomment': 0.48.0 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) escape-string-regexp: 4.0.0 - eslint: 9.8.0 - espree: 10.1.0 + eslint: 9.12.0(jiti@1.21.6) + espree: 10.2.0 esquery: 1.6.0 - parse-imports: 2.1.1 + parse-imports: 2.2.1 semver: 7.6.3 spdx-expression-parse: 4.0.0 - synckit: 0.9.1 + synckit: 0.9.2 transitivePeerDependencies: - supports-color @@ -14716,35 +14831,35 @@ snapshots: lodash: 4.17.21 vscode-json-languageservice: 4.2.1 - eslint-plugin-lodash@8.0.0(eslint@9.8.0): + eslint-plugin-lodash@8.0.0(eslint@9.12.0(jiti@1.21.6)): dependencies: - eslint: 9.8.0 + eslint: 9.12.0(jiti@1.21.6) lodash: 4.17.21 - eslint-plugin-markdown@5.1.0(eslint@9.8.0): + eslint-plugin-markdown@5.1.0(eslint@9.12.0(jiti@1.21.6)): dependencies: - eslint: 9.8.0 + eslint: 9.12.0(jiti@1.21.6) mdast-util-from-markdown: 0.8.5 transitivePeerDependencies: - supports-color - eslint-plugin-no-only-tests@3.1.0: {} + eslint-plugin-no-only-tests@3.3.0: {} eslint-plugin-tsdoc@0.3.0: dependencies: '@microsoft/tsdoc': 0.15.0 '@microsoft/tsdoc-config': 0.17.0 - eslint-plugin-unicorn@55.0.0(eslint@9.8.0): + eslint-plugin-unicorn@56.0.0(eslint@9.12.0(jiti@1.21.6)): dependencies: - '@babel/helper-validator-identifier': 7.24.7 - '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + '@babel/helper-validator-identifier': 7.25.7 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.12.0(jiti@1.21.6)) ci-info: 4.0.0 clean-regexp: 1.0.0 - core-js-compat: 3.38.0 - eslint: 9.8.0 + core-js-compat: 3.38.1 + eslint: 9.12.0(jiti@1.21.6) esquery: 1.6.0 - globals: 15.9.0 + globals: 15.10.0 indent-string: 4.0.0 is-builtin-module: 3.2.1 jsesc: 3.0.2 @@ -14760,51 +14875,54 @@ snapshots: esrecurse: 4.3.0 estraverse: 4.3.0 - eslint-scope@8.0.2: + eslint-scope@8.1.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} - eslint-visitor-keys@4.0.0: {} + eslint-visitor-keys@4.1.0: {} - eslint@9.8.0: + eslint@9.12.0(jiti@1.21.6): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) - '@eslint-community/regexpp': 4.11.0 - '@eslint/config-array': 0.17.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.12.0(jiti@1.21.6)) + '@eslint-community/regexpp': 4.11.1 + '@eslint/config-array': 0.18.0 + '@eslint/core': 0.6.0 '@eslint/eslintrc': 3.1.0 - '@eslint/js': 9.8.0 + '@eslint/js': 9.12.0 + '@eslint/plugin-kit': 0.2.0 + '@humanfs/node': 0.16.5 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.3.0 - '@nodelib/fs.walk': 1.2.8 + '@humanwhocodes/retry': 0.3.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) escape-string-regexp: 4.0.0 - eslint-scope: 8.0.2 - eslint-visitor-keys: 4.0.0 - espree: 10.1.0 + eslint-scope: 8.1.0 + eslint-visitor-keys: 4.1.0 + espree: 10.2.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - ignore: 5.3.1 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 - is-path-inside: 3.0.3 json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 - strip-ansi: 6.0.1 text-table: 0.2.0 + optionalDependencies: + jiti: 1.21.6 transitivePeerDependencies: - supports-color @@ -14815,11 +14933,11 @@ snapshots: event-emitter: 0.3.5 type: 2.7.3 - espree@10.1.0: + espree@10.2.0: dependencies: acorn: 8.12.1 acorn-jsx: 5.3.2(acorn@8.12.1) - eslint-visitor-keys: 4.0.0 + eslint-visitor-keys: 4.1.0 esprima@1.1.1: {} @@ -14845,7 +14963,7 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 esutils@1.0.0: {} @@ -14938,34 +15056,34 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - express@4.19.2: + express@4.21.0: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.2 + body-parser: 1.20.3 content-disposition: 0.5.4 content-type: 1.0.5 cookie: 0.6.0 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 1.2.0 + finalhandler: 1.3.1 fresh: 0.5.2 http-errors: 2.0.0 - merge-descriptors: 1.0.1 + merge-descriptors: 1.0.3 methods: 1.1.2 on-finished: 2.4.1 parseurl: 1.3.3 - path-to-regexp: 0.1.7 + path-to-regexp: 0.1.10 proxy-addr: 2.0.7 - qs: 6.11.0 + qs: 6.13.0 range-parser: 1.2.1 safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 + send: 0.19.0 + serve-static: 1.16.2 setprototypeof: 1.2.0 statuses: 2.0.1 type-is: 1.6.18 @@ -14990,7 +15108,7 @@ snapshots: extract-zip@2.0.1(supports-color@8.1.1): dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -15018,20 +15136,31 @@ snapshots: fast-json-stable-stringify@2.1.0: {} - fast-json-stringify@2.7.13: + fast-json-stringify@5.16.1: dependencies: - ajv: 6.12.6 - deepmerge: 4.3.1 + '@fastify/merge-json-schemas': 0.1.1 + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + fast-deep-equal: 3.1.3 + fast-uri: 2.4.0 + json-schema-ref-resolver: 1.0.1 rfdc: 1.4.1 - string-similarity: 4.0.4 fast-levenshtein@2.0.6: {} + fast-querystring@1.1.2: + dependencies: + fast-decode-uri-component: 1.0.1 + fast-redact@3.5.0: {} - fast-safe-stringify@2.1.1: {} + fast-shuffle@6.1.0: + dependencies: + pcg: 1.0.0 - fast-uri@3.0.1: {} + fast-uri@2.4.0: {} + + fast-uri@3.0.2: {} fastest-levenshtein@1.0.16: {} @@ -15039,26 +15168,24 @@ snapshots: fastify-plugin@3.0.1: {} - fastify@3.29.5: + fastify@4.28.1: dependencies: - '@fastify/ajv-compiler': 1.1.0 - '@fastify/error': 2.0.0 + '@fastify/ajv-compiler': 3.6.0 + '@fastify/error': 3.4.1 + '@fastify/fast-json-stringify-compiler': 4.3.0 abstract-logging: 2.0.1 - avvio: 7.2.5 + avvio: 8.4.0 fast-content-type-parse: 1.1.0 - fast-json-stringify: 2.7.13 - find-my-way: 4.5.1 - flatstr: 1.0.12 - light-my-request: 4.12.0 - pino: 6.14.0 - process-warning: 1.0.0 + fast-json-stringify: 5.16.1 + find-my-way: 8.2.2 + light-my-request: 5.14.0 + pino: 9.4.0 + process-warning: 3.0.0 proxy-addr: 2.0.7 rfdc: 1.4.1 secure-json-parse: 2.7.0 semver: 7.6.3 - tiny-lru: 8.0.2 - transitivePeerDependencies: - - supports-color + toad-cache: 3.7.0 fastq@1.17.1: dependencies: @@ -15080,6 +15207,10 @@ snapshots: dependencies: pend: 1.2.0 + fdir@6.4.0(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + ferrum@1.9.4: dependencies: fastestsmallesttextencoderdecoder: 1.0.22 @@ -15111,14 +15242,28 @@ snapshots: dependencies: minimatch: 5.1.6 + filing-cabinet@5.0.2: + dependencies: + app-module-path: 2.2.0 + commander: 12.1.0 + enhanced-resolve: 5.17.1 + module-definition: 6.0.0 + module-lookup-amd: 9.0.2 + resolve: 1.22.8 + resolve-dependency-path: 4.0.0 + sass-lookup: 6.0.1 + stylus-lookup: 6.0.0 + tsconfig-paths: 4.2.0 + typescript: 5.4.5 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - finalhandler@1.2.0: + finalhandler@1.3.1: dependencies: debug: 2.6.9 - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 parseurl: 1.3.3 @@ -15138,21 +15283,50 @@ snapshots: common-path-prefix: 3.0.0 pkg-dir: 7.0.0 - find-my-way@4.5.1: + find-cypress-specs@1.43.4(@babel/core@7.25.7): + dependencies: + '@actions/core': 1.11.1 + arg: 5.0.2 + console.table: 0.10.0 + debug: 4.3.7(supports-color@8.1.1) + find-test-names: 1.28.18(@babel/core@7.25.7) + globby: 11.1.0 + minimatch: 3.1.2 + pluralize: 8.0.0 + require-and-forget: 1.0.1 + shelljs: 0.8.5 + spec-change: 1.11.11 + tsx: 4.19.1 + transitivePeerDependencies: + - '@babel/core' + - supports-color + + find-my-way@8.2.2: dependencies: - fast-decode-uri-component: 1.0.1 fast-deep-equal: 3.1.3 - safe-regex2: 2.0.0 - semver-store: 0.3.0 + fast-querystring: 1.1.2 + safe-regex2: 3.1.0 find-process@1.4.7: dependencies: chalk: 4.1.2 commander: 5.1.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color + find-test-names@1.28.18(@babel/core@7.25.7): + dependencies: + '@babel/parser': 7.25.7 + '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.7) + acorn-walk: 8.3.4 + debug: 4.3.7(supports-color@8.1.1) + globby: 11.1.0 + simple-bin-help: 1.8.0 + transitivePeerDependencies: + - '@babel/core' + - supports-color + find-up-simple@1.0.0: {} find-up@3.0.0: @@ -15174,11 +15348,6 @@ snapshots: locate-path: 7.2.0 path-exists: 5.0.0 - find-yarn-workspace-root2@1.2.16: - dependencies: - micromatch: 4.0.8 - pkg-dir: 4.2.0 - flat-cache@4.0.1: dependencies: flatted: 3.3.1 @@ -15191,19 +15360,17 @@ snapshots: flat@5.0.2: {} - flatstr@1.0.12: {} - flatted@3.3.1: {} flexsearch@0.7.43: {} - focus-trap@7.5.4: + focus-trap@7.6.0: dependencies: tabbable: 6.2.0 - follow-redirects@1.15.6(debug@4.3.6): + follow-redirects@1.15.9(debug@4.3.7): optionalDependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) font-awesome@4.7.0: {} @@ -15216,19 +15383,13 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 3.0.7 - foreground-child@3.2.1: + foreground-child@3.3.0: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 forever-agent@0.6.1: {} - form-data@2.3.3: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - form-data@4.0.0: dependencies: asynckit: 0.4.0 @@ -15302,6 +15463,11 @@ snapshots: gensync@1.0.0-beta.2: {} + get-amd-module-type@6.0.0: + dependencies: + ast-module-types: 6.0.0 + node-source-walk: 7.0.0 + get-caller-file@2.0.5: {} get-east-asian-width@1.2.0: {} @@ -15328,11 +15494,11 @@ snapshots: get-stream@4.1.0: dependencies: - pump: 3.0.0 + pump: 3.0.2 get-stream@5.2.0: dependencies: - pump: 3.0.0 + pump: 3.0.2 get-stream@6.0.1: {} @@ -15344,7 +15510,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.2.4 - get-tsconfig@4.7.6: + get-tsconfig@4.8.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -15375,11 +15541,11 @@ snapshots: glob@10.4.5: dependencies: - foreground-child: 3.2.1 + foreground-child: 3.3.0 jackspeak: 3.4.3 minimatch: 9.0.5 minipass: 7.1.2 - package-json-from-dist: 1.0.0 + package-json-from-dist: 1.0.1 path-scurry: 1.11.1 glob@7.2.3: @@ -15415,7 +15581,7 @@ snapshots: globals@14.0.0: {} - globals@15.9.0: {} + globals@15.10.0: {} globalthis@1.0.4: dependencies: @@ -15443,13 +15609,17 @@ snapshots: dependencies: '@sindresorhus/merge-streams': 2.3.0 fast-glob: 3.3.2 - ignore: 5.3.1 + ignore: 5.3.2 path-type: 5.0.0 slash: 5.1.0 unicorn-magic: 0.1.0 glur@1.1.2: {} + gonzales-pe@4.3.0: + dependencies: + minimist: 1.2.8 + gopd@1.0.1: dependencies: get-intrinsic: 1.2.4 @@ -15487,7 +15657,7 @@ snapshots: source-map: 0.6.1 wordwrap: 1.0.0 optionalDependencies: - uglify-js: 3.19.1 + uglify-js: 3.19.3 has-ansi@2.0.0: dependencies: @@ -15522,6 +15692,24 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-to-html@9.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + highlight.js@10.7.3: {} hookable@5.5.3: {} @@ -15545,6 +15733,8 @@ snapshots: html-to-image@1.11.11: {} + html-void-elements@3.0.0: {} + htmlparser2@9.1.0: dependencies: domelementtype: 2.3.0 @@ -15577,20 +15767,20 @@ snapshots: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color - http-proxy-middleware@2.0.6(@types/express@4.17.21): + http-proxy-middleware@2.0.7(@types/express@4.17.21): dependencies: - '@types/http-proxy': 1.17.14 + '@types/http-proxy': 1.17.15 http-proxy: 1.18.1 is-glob: 4.0.3 is-plain-obj: 3.0.0 @@ -15603,12 +15793,12 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.6(debug@4.3.6) + follow-redirects: 1.15.9(debug@4.3.7) requires-port: 1.0.0 transitivePeerDependencies: - debug - http-signature@1.3.6: + http-signature@1.4.0: dependencies: assert-plus: 1.0.0 jsprim: 2.0.2 @@ -15624,23 +15814,23 @@ snapshots: appdata-path: 1.0.0 compression: 1.7.4 cors: 2.8.5 - express: 4.19.2 + express: 4.21.0 spdy: 4.0.2 - uglify-js: 3.19.1 + uglify-js: 3.19.3 transitivePeerDependencies: - supports-color https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color https-proxy-agent@7.0.5: dependencies: agent-base: 7.1.1 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -15652,7 +15842,9 @@ snapshots: human-signals@5.0.0: {} - husky@9.1.5: {} + humanize-duration@3.32.1: {} + + husky@9.1.6: {} iconv-lite@0.4.24: dependencies: @@ -15666,8 +15858,6 @@ snapshots: ieee754@1.2.1: {} - ignore@5.3.1: {} - ignore@5.3.2: {} import-fresh@3.3.0: @@ -15713,6 +15903,8 @@ snapshots: internmap@2.0.3: {} + interpret@1.4.0: {} + interpret@2.2.0: {} ipaddr.js@1.9.1: {} @@ -15726,6 +15918,11 @@ snapshots: is-alphabetical: 1.0.4 is-decimal: 1.0.4 + is-arguments@1.1.1: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + is-array-buffer@3.0.4: dependencies: call-bind: 1.0.7 @@ -15758,7 +15955,7 @@ snapshots: dependencies: ci-info: 3.9.0 - is-core-module@2.15.0: + is-core-module@2.15.1: dependencies: hasown: 2.0.2 @@ -15799,6 +15996,8 @@ snapshots: is-localhost-ip@2.0.0: {} + is-map@2.0.3: {} + is-module@1.0.0: {} is-negative-zero@2.0.3: {} @@ -15832,6 +16031,8 @@ snapshots: is-regexp@1.0.0: {} + is-set@2.0.3: {} + is-shared-array-buffer@1.0.3: dependencies: call-bind: 1.0.7 @@ -15862,10 +16063,21 @@ snapshots: is-unicode-supported@0.1.0: {} + is-url-superb@4.0.0: {} + + is-url@1.2.4: {} + + is-weakmap@2.0.2: {} + is-weakref@1.0.2: dependencies: call-bind: 1.0.7 + is-weakset@2.0.3: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + is-what@4.1.16: {} is-windows@1.0.2: {} @@ -15892,7 +16104,7 @@ snapshots: istanbul-lib-instrument@4.0.3: dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.7 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -15901,8 +16113,8 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.25.2 - '@babel/parser': 7.25.4 + '@babel/core': 7.25.7 + '@babel/parser': 7.25.7 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -15911,8 +16123,8 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.25.2 - '@babel/parser': 7.25.3 + '@babel/core': 7.25.7 + '@babel/parser': 7.25.7 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.3 @@ -15936,7 +16148,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -15945,7 +16157,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -15985,7 +16197,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.2 + '@types/node': 20.16.11 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -16005,16 +16217,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.16.2): + jest-cli@29.7.0(@types/node@20.16.11): dependencies: '@jest/core': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.16.2) + create-jest: 29.7.0(@types/node@20.16.11) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.16.2) + jest-config: 29.7.0(@types/node@20.16.11) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -16024,12 +16236,12 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@20.16.2): + jest-config@29.7.0(@types/node@20.16.11): dependencies: - '@babel/core': 7.25.2 + '@babel/core': 7.25.7 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.25.2) + babel-jest: 29.7.0(@babel/core@7.25.7) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -16049,7 +16261,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 20.16.2 + '@types/node': 20.16.11 transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -16078,7 +16290,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.2 + '@types/node': 20.16.11 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -16088,7 +16300,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.16.2 + '@types/node': 20.16.11 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -16100,12 +16312,12 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - jest-image-snapshot@4.2.0(jest@29.7.0(@types/node@20.16.2)): + jest-image-snapshot@4.2.0(jest@29.7.0(@types/node@20.16.11)): dependencies: chalk: 1.1.3 get-stdin: 5.0.1 glur: 1.1.2 - jest: 29.7.0(@types/node@20.16.2) + jest: 29.7.0(@types/node@20.16.11) lodash: 4.17.21 mkdirp: 0.5.6 pixelmatch: 5.3.0 @@ -16127,7 +16339,7 @@ snapshots: jest-message-util@29.7.0: dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.25.7 '@jest/types': 29.6.3 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -16140,7 +16352,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.16.2 + '@types/node': 20.16.11 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -16175,7 +16387,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.2 + '@types/node': 20.16.11 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -16203,9 +16415,9 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.2 + '@types/node': 20.16.11 chalk: 4.1.2 - cjs-module-lexer: 1.3.1 + cjs-module-lexer: 1.4.1 collect-v8-coverage: 1.0.2 glob: 7.2.3 graceful-fs: 4.2.11 @@ -16223,15 +16435,15 @@ snapshots: jest-snapshot@29.7.0: dependencies: - '@babel/core': 7.25.2 - '@babel/generator': 7.25.0 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2) - '@babel/types': 7.25.2 + '@babel/core': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.7) + '@babel/plugin-syntax-typescript': 7.25.7(@babel/core@7.25.7) + '@babel/types': 7.25.7 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.25.2) + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.7) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -16249,7 +16461,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.16.2 + '@types/node': 20.16.11 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -16268,7 +16480,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.16.2 + '@types/node': 20.16.11 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -16277,23 +16489,23 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.5.1 + '@types/node': 20.16.11 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 20.16.2 + '@types/node': 20.16.11 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.16.2): + jest@29.7.0(@types/node@20.16.11): dependencies: '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.16.2) + jest-cli: 29.7.0(@types/node@20.16.11) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -16347,11 +16559,11 @@ snapshots: jsbn@0.1.1: {} - jsdoc-type-pratt-parser@4.0.0: {} + jsdoc-type-pratt-parser@4.1.0: {} jsdom@24.1.3: dependencies: - cssstyle: 4.0.1 + cssstyle: 4.1.0 data-urls: 5.0.0 decimal.js: 10.4.3 form-data: 4.0.0 @@ -16359,7 +16571,7 @@ snapshots: http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.5 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.12 + nwsapi: 2.2.13 parse5: 7.1.2 rrweb-cssom: 0.7.1 saxes: 6.0.0 @@ -16379,19 +16591,21 @@ snapshots: jsesc@0.5.0: {} - jsesc@2.5.2: {} - jsesc@3.0.2: {} json-buffer@3.0.1: {} json-parse-even-better-errors@2.3.1: {} + json-schema-ref-resolver@1.0.1: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-to-typescript@13.1.2: dependencies: '@bcherny/json-schema-ref-parser': 10.0.5-fork '@types/json-schema': 7.0.15 - '@types/lodash': 4.17.7 + '@types/lodash': 4.17.10 '@types/prettier': 2.7.3 cli-color: 2.0.4 get-stdin: 8.0.0 @@ -16487,9 +16701,9 @@ snapshots: vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.0.8 - launch-editor@2.8.0: + launch-editor@2.9.1: dependencies: - picocolors: 1.0.1 + picocolors: 1.1.0 shell-quote: 1.8.1 layout-base@1.0.2: {} @@ -16498,6 +16712,8 @@ snapshots: lazy-ass@1.6.0: {} + lazy-ass@2.0.3: {} + leven@3.1.0: {} levn@0.4.1: @@ -16507,11 +16723,10 @@ snapshots: lex-parser@0.1.4: {} - light-my-request@4.12.0: + light-my-request@5.14.0: dependencies: - ajv: 8.17.1 - cookie: 0.5.0 - process-warning: 1.0.0 + cookie: 0.7.2 + process-warning: 3.0.0 set-cookie-parser: 2.7.0 lilconfig@2.1.0: {} @@ -16524,18 +16739,18 @@ snapshots: dependencies: uc.micro: 1.0.6 - lint-staged@15.2.9: + lint-staged@15.2.10: dependencies: chalk: 5.3.0 commander: 12.1.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) execa: 8.0.1 lilconfig: 3.1.2 - listr2: 8.2.4 + listr2: 8.2.5 micromatch: 4.0.8 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.5.0 + yaml: 2.5.1 transitivePeerDependencies: - supports-color @@ -16552,7 +16767,7 @@ snapshots: optionalDependencies: enquirer: 2.4.1 - listr2@8.2.4: + listr2@8.2.5: dependencies: cli-truncate: 4.0.0 colorette: 2.0.20 @@ -16561,21 +16776,14 @@ snapshots: rfdc: 1.4.1 wrap-ansi: 9.0.0 - load-yaml-file@0.2.0: - dependencies: - graceful-fs: 4.2.11 - js-yaml: 3.14.1 - pify: 4.0.1 - strip-bom: 3.0.0 - loader-runner@4.3.0: {} local-pkg@0.4.3: {} local-pkg@0.5.0: dependencies: - mlly: 1.7.1 - pkg-types: 1.1.3 + mlly: 1.7.2 + pkg-types: 1.2.0 locate-path@3.0.0: dependencies: @@ -16636,7 +16844,9 @@ snapshots: loglevel-plugin-prefix@0.8.4: {} - loglevel@1.9.1: {} + loglevel@1.9.2: {} + + long@5.2.3: {} longest-streak@3.1.0: {} @@ -16671,11 +16881,11 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 - magicast@0.3.4: + magicast@0.3.5: dependencies: - '@babel/parser': 7.25.3 - '@babel/types': 7.25.2 - source-map-js: 1.2.0 + '@babel/parser': 7.25.7 + '@babel/types': 7.25.7 + source-map-js: 1.2.1 make-dir@3.1.0: dependencies: @@ -16709,7 +16919,7 @@ snapshots: mdast-builder@1.1.1: dependencies: - '@types/unist': 2.0.10 + '@types/unist': 2.0.11 mdast-util-find-and-replace@3.0.1: dependencies: @@ -16756,7 +16966,7 @@ snapshots: transitivePeerDependencies: - supports-color - mdast-util-gfm-autolink-literal@2.0.0: + mdast-util-gfm-autolink-literal@2.0.1: dependencies: '@types/mdast': 4.0.4 ccount: 2.0.1 @@ -16804,7 +17014,7 @@ snapshots: mdast-util-gfm@3.0.0: dependencies: mdast-util-from-markdown: 2.0.1 - mdast-util-gfm-autolink-literal: 2.0.0 + mdast-util-gfm-autolink-literal: 2.0.1 mdast-util-gfm-footnote: 2.0.0 mdast-util-gfm-strikethrough: 2.0.0 mdast-util-gfm-table: 2.0.0 @@ -16818,6 +17028,18 @@ snapshots: '@types/mdast': 4.0.4 unist-util-is: 6.0.0 + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.0 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + mdast-util-to-markdown@2.1.0: dependencies: '@types/mdast': 4.0.4 @@ -16860,7 +17082,7 @@ snapshots: meow@12.1.1: {} - merge-descriptors@1.0.1: {} + merge-descriptors@1.0.3: {} merge-stream@2.0.0: {} @@ -17046,7 +17268,7 @@ snapshots: micromark@2.11.4: dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) parse-entities: 2.0.0 transitivePeerDependencies: - supports-color @@ -17054,7 +17276,7 @@ snapshots: micromark@4.0.0: dependencies: '@types/debug': 4.1.12 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) decode-named-character-reference: 1.0.2 devlop: 1.1.0 micromark-core-commonmark: 2.0.1 @@ -17120,8 +17342,6 @@ snapshots: minisearch@6.3.0: {} - minisearch@7.1.0: {} - mitt@3.0.1: {} mkdirp@0.5.6: @@ -17130,13 +17350,25 @@ snapshots: mkdirp@1.0.4: {} - mlly@1.7.1: + mlly@1.7.2: dependencies: acorn: 8.12.1 pathe: 1.1.2 - pkg-types: 1.1.3 + pkg-types: 1.2.0 ufo: 1.5.4 + module-definition@6.0.0: + dependencies: + ast-module-types: 6.0.0 + node-source-walk: 7.0.0 + + module-lookup-amd@9.0.2: + dependencies: + commander: 12.1.0 + glob: 7.2.3 + requirejs: 2.3.7 + requirejs-config-file: 4.0.0 + mri@1.2.0: {} mrmime@2.0.0: {} @@ -17184,6 +17416,12 @@ snapshots: optionalDependencies: encoding: 0.1.13 + node-fetch@2.7.0(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + node-fetch@3.3.1: dependencies: data-uri-to-buffer: 4.0.1 @@ -17200,6 +17438,10 @@ snapshots: node-releases@2.0.18: {} + node-source-walk@7.0.0: + dependencies: + '@babel/parser': 7.25.7 + nomnom@1.5.2: dependencies: colors: 0.5.1 @@ -17228,7 +17470,7 @@ snapshots: dependencies: path-key: 4.0.0 - nwsapi@2.2.12: {} + nwsapi@2.2.13: {} nyc@15.1.0: dependencies: @@ -17268,6 +17510,11 @@ snapshots: object-inspect@1.13.2: {} + object-is@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + object-keys@1.1.1: {} object.assign@4.1.5: @@ -17279,7 +17526,7 @@ snapshots: obuf@1.1.2: {} - ofetch@1.3.4: + ofetch@1.4.0: dependencies: destr: 2.0.3 node-fetch-native: 1.6.4 @@ -17311,17 +17558,21 @@ snapshots: dependencies: mimic-function: 5.0.1 + oniguruma-to-js@0.4.3: + dependencies: + regex: 4.3.3 + open@8.4.2: dependencies: define-lazy-prop: 2.0.0 is-docker: 2.2.1 is-wsl: 2.2.0 - openapi-fetch@0.11.1: + openapi-fetch@0.11.3: dependencies: - openapi-typescript-helpers: 0.0.12 + openapi-typescript-helpers: 0.0.13 - openapi-typescript-helpers@0.0.12: {} + openapi-typescript-helpers@0.0.13: {} optionator@0.9.4: dependencies: @@ -17420,9 +17671,9 @@ snapshots: lodash.flattendeep: 4.4.0 release-zalgo: 1.0.0 - package-json-from-dist@1.0.0: {} + package-json-from-dist@1.0.1: {} - package-manager-detector@0.2.0: {} + package-manager-detector@0.2.1: {} pako@1.0.11: {} @@ -17443,14 +17694,14 @@ snapshots: is-decimal: 1.0.4 is-hexadecimal: 1.0.4 - parse-imports@2.1.1: + parse-imports@2.2.1: dependencies: es-module-lexer: 1.5.4 slashes: 3.0.12 parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.24.7 + '@babel/code-frame': 7.25.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -17486,7 +17737,7 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-to-regexp@0.1.7: {} + path-to-regexp@0.1.10: {} path-type@4.0.0: {} @@ -17500,16 +17751,23 @@ snapshots: dependencies: through: 2.3.8 + pcg@1.0.0: + dependencies: + long: 5.2.3 + ramda: 0.29.0 + pend@1.2.0: {} perfect-debounce@1.0.0: {} performance-now@2.1.0: {} - picocolors@1.0.1: {} + picocolors@1.1.0: {} picomatch@2.3.1: {} + picomatch@4.0.2: {} + pidtree@0.6.0: {} pify@2.3.0: {} @@ -17521,19 +17779,9 @@ snapshots: readable-stream: 4.5.2 split2: 4.2.0 - pino-std-serializers@3.2.0: {} - pino-std-serializers@6.2.2: {} - pino@6.14.0: - dependencies: - fast-redact: 3.5.0 - fast-safe-stringify: 2.1.1 - flatstr: 1.0.12 - pino-std-serializers: 3.2.0 - process-warning: 1.0.0 - quick-format-unescaped: 4.0.4 - sonic-boom: 1.4.1 + pino-std-serializers@7.0.0: {} pino@8.21.0: dependencies: @@ -17549,6 +17797,20 @@ snapshots: sonic-boom: 3.8.1 thread-stream: 2.7.0 + pino@9.4.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.2.0 + pino-std-serializers: 7.0.0 + process-warning: 4.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.1.0 + thread-stream: 3.1.0 + pirates@4.0.6: {} pixelmatch@5.3.0: @@ -17567,10 +17829,10 @@ snapshots: dependencies: find-up: 6.3.0 - pkg-types@1.1.3: + pkg-types@1.2.0: dependencies: - confbox: 0.1.7 - mlly: 1.7.1 + confbox: 0.1.8 + mlly: 1.7.2 pathe: 1.1.2 plist@3.1.0: @@ -17596,28 +17858,28 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-import@15.1.0(postcss@8.4.41): + postcss-import@15.1.0(postcss@8.4.47): dependencies: - postcss: 8.4.41 + postcss: 8.4.47 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 - postcss-js@4.0.1(postcss@8.4.41): + postcss-js@4.0.1(postcss@8.4.47): dependencies: camelcase-css: 2.0.1 - postcss: 8.4.41 + postcss: 8.4.47 - postcss-load-config@4.0.2(postcss@8.4.41): + postcss-load-config@4.0.2(postcss@8.4.47): dependencies: lilconfig: 3.1.2 - yaml: 2.5.0 + yaml: 2.5.1 optionalDependencies: - postcss: 8.4.41 + postcss: 8.4.47 - postcss-nested@6.2.0(postcss@8.4.41): + postcss-nested@6.2.0(postcss@8.4.47): dependencies: - postcss: 8.4.41 + postcss: 8.4.47 postcss-selector-parser: 6.1.2 postcss-selector-parser@6.1.2: @@ -17627,20 +17889,40 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.4.41: + postcss-values-parser@6.0.2(postcss@8.4.47): + dependencies: + color-name: 1.1.4 + is-url-superb: 4.0.0 + postcss: 8.4.47 + quote-unquote: 1.0.0 + + postcss@8.4.47: dependencies: nanoid: 3.3.7 - picocolors: 1.0.1 - source-map-js: 1.2.0 + picocolors: 1.1.0 + source-map-js: 1.2.1 - preact@10.23.2: {} + preact@10.24.2: {} - preferred-pm@3.1.4: + precinct@12.1.2: dependencies: - find-up: 5.0.0 - find-yarn-workspace-root2: 1.2.16 - path-exists: 4.0.0 - which-pm: 2.2.0 + '@dependents/detective-less': 5.0.0 + commander: 12.1.0 + detective-amd: 6.0.0 + detective-cjs: 6.0.0 + detective-es6: 5.0.0 + detective-postcss: 7.0.0(postcss@8.4.47) + detective-sass: 6.0.0 + detective-scss: 5.0.0 + detective-stylus: 5.0.0 + detective-typescript: 13.0.0(typescript@5.6.2) + detective-vue2: 2.0.3(typescript@5.6.2) + module-definition: 6.0.0 + node-source-walk: 7.0.0 + postcss: 8.4.47 + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color prelude-ls@1.2.1: {} @@ -17673,10 +17955,10 @@ snapshots: dependencies: fromentries: 1.3.2 - process-warning@1.0.0: {} - process-warning@3.0.0: {} + process-warning@4.0.0: {} + process@0.11.10: {} prompts@2.4.2: @@ -17684,6 +17966,8 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 + property-information@6.5.0: {} + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -17701,7 +17985,7 @@ snapshots: psl@1.9.0: {} - pump@3.0.0: + pump@3.0.2: dependencies: end-of-stream: 1.4.4 once: 1.4.0 @@ -17710,11 +17994,7 @@ snapshots: pure-rand@6.1.0: {} - qs@6.10.4: - dependencies: - side-channel: 1.0.6 - - qs@6.11.0: + qs@6.13.0: dependencies: side-channel: 1.0.6 @@ -17726,10 +18006,14 @@ snapshots: quick-lru@5.1.1: {} + quote-unquote@1.0.0: {} + railroad-diagrams@1.0.0: {} ramda@0.28.0: {} + ramda@0.29.0: {} + randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 @@ -17799,11 +18083,15 @@ snapshots: real-require@0.2.0: {} + rechoir@0.6.2: + dependencies: + resolve: 1.22.8 + rechoir@0.7.1: dependencies: resolve: 1.22.8 - regenerate-unicode-properties@10.1.1: + regenerate-unicode-properties@10.2.0: dependencies: regenerate: 1.4.2 @@ -17813,33 +18101,37 @@ snapshots: regenerator-transform@0.15.2: dependencies: - '@babel/runtime': 7.25.4 + '@babel/runtime': 7.25.7 + + regex@4.3.3: {} regexp-tree@0.1.27: {} - regexp.prototype.flags@1.5.2: + regexp.prototype.flags@1.5.3: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-errors: 1.3.0 set-function-name: 2.0.2 - regexpu-core@5.3.2: + regexpu-core@6.1.1: dependencies: - '@babel/regjsgen': 0.8.0 regenerate: 1.4.2 - regenerate-unicode-properties: 10.1.1 - regjsparser: 0.9.1 + regenerate-unicode-properties: 10.2.0 + regjsgen: 0.8.0 + regjsparser: 0.11.1 unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.1.0 + unicode-match-property-value-ecmascript: 2.2.0 + + regjsgen@0.8.0: {} regjsparser@0.10.0: dependencies: jsesc: 0.5.0 - regjsparser@0.9.1: + regjsparser@0.11.1: dependencies: - jsesc: 0.5.0 + jsesc: 3.0.2 release-zalgo@1.0.0: dependencies: @@ -17895,12 +18187,25 @@ snapshots: dependencies: throttleit: 1.0.1 + require-and-forget@1.0.1: + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + require-directory@2.1.1: {} require-from-string@2.0.2: {} require-main-filename@2.0.0: {} + requirejs-config-file@4.0.0: + dependencies: + esprima: 4.0.1 + stringify-object: 3.3.0 + + requirejs@2.3.7: {} + requires-port@1.0.0: {} resolve-alpn@1.2.1: {} @@ -17909,6 +18214,8 @@ snapshots: dependencies: resolve-from: 5.0.0 + resolve-dependency-path@4.0.0: {} + resolve-from@4.0.0: {} resolve-from@5.0.0: {} @@ -17919,7 +18226,7 @@ snapshots: resolve@1.22.8: dependencies: - is-core-module: 2.15.0 + is-core-module: 2.15.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -17937,7 +18244,7 @@ snapshots: onetime: 7.0.0 signal-exit: 4.1.0 - ret@0.2.2: {} + ret@0.4.3: {} retry@0.13.1: {} @@ -17959,50 +18266,48 @@ snapshots: robust-predicates@3.0.2: {} - rollup-plugin-visualizer@5.12.0(rollup@4.21.1): + rollup-plugin-visualizer@5.12.0(rollup@4.24.0): dependencies: open: 8.4.2 picomatch: 2.3.1 source-map: 0.7.4 yargs: 17.7.2 optionalDependencies: - rollup: 4.21.1 + rollup: 4.24.0 - rollup@2.79.1: + rollup@2.79.2: optionalDependencies: fsevents: 2.3.3 - rollup@4.21.1: + rollup@4.24.0: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.21.1 - '@rollup/rollup-android-arm64': 4.21.1 - '@rollup/rollup-darwin-arm64': 4.21.1 - '@rollup/rollup-darwin-x64': 4.21.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.21.1 - '@rollup/rollup-linux-arm-musleabihf': 4.21.1 - '@rollup/rollup-linux-arm64-gnu': 4.21.1 - '@rollup/rollup-linux-arm64-musl': 4.21.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.21.1 - '@rollup/rollup-linux-riscv64-gnu': 4.21.1 - '@rollup/rollup-linux-s390x-gnu': 4.21.1 - '@rollup/rollup-linux-x64-gnu': 4.21.1 - '@rollup/rollup-linux-x64-musl': 4.21.1 - '@rollup/rollup-win32-arm64-msvc': 4.21.1 - '@rollup/rollup-win32-ia32-msvc': 4.21.1 - '@rollup/rollup-win32-x64-msvc': 4.21.1 + '@rollup/rollup-android-arm-eabi': 4.24.0 + '@rollup/rollup-android-arm64': 4.24.0 + '@rollup/rollup-darwin-arm64': 4.24.0 + '@rollup/rollup-darwin-x64': 4.24.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.24.0 + '@rollup/rollup-linux-arm-musleabihf': 4.24.0 + '@rollup/rollup-linux-arm64-gnu': 4.24.0 + '@rollup/rollup-linux-arm64-musl': 4.24.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.24.0 + '@rollup/rollup-linux-riscv64-gnu': 4.24.0 + '@rollup/rollup-linux-s390x-gnu': 4.24.0 + '@rollup/rollup-linux-x64-gnu': 4.24.0 + '@rollup/rollup-linux-x64-musl': 4.24.0 + '@rollup/rollup-win32-arm64-msvc': 4.24.0 + '@rollup/rollup-win32-ia32-msvc': 4.24.0 + '@rollup/rollup-win32-x64-msvc': 4.24.0 fsevents: 2.3.3 - roughjs@4.6.6: + roughjs@4.6.6(patch_hash=vxb6t6fqvzyhwhtjiliqr25jyq): dependencies: hachure-fill: 0.5.2 path-data-parser: 0.1.0 points-on-curve: 0.2.0 points-on-path: 0.2.1 - rrweb-cssom@0.6.0: {} - rrweb-cssom@0.7.1: {} run-parallel@1.2.0: @@ -18013,7 +18318,7 @@ snapshots: rxjs@7.8.1: dependencies: - tslib: 2.6.3 + tslib: 2.7.0 safe-array-concat@1.1.2: dependencies: @@ -18032,14 +18337,18 @@ snapshots: es-errors: 1.3.0 is-regex: 1.1.4 - safe-regex2@2.0.0: + safe-regex2@3.1.0: dependencies: - ret: 0.2.2 + ret: 0.4.3 safe-stable-stringify@2.5.0: {} safer-buffer@2.1.2: {} + sass-lookup@6.0.1: + dependencies: + commander: 12.1.0 + saxes@6.0.0: dependencies: xmlchars: 2.2.0 @@ -18057,7 +18366,7 @@ snapshots: ajv-formats: 2.1.1(ajv@8.17.1) ajv-keywords: 5.1.0(ajv@8.17.1) - search-insights@2.15.0: {} + search-insights@2.17.2: {} secure-json-parse@2.7.0: {} @@ -18068,8 +18377,6 @@ snapshots: '@types/node-forge': 1.3.11 node-forge: 1.3.1 - semver-store@0.3.0: {} - semver@5.7.2: {} semver@6.3.1: {} @@ -18078,7 +18385,7 @@ snapshots: semver@7.6.3: {} - send@0.18.0: + send@0.19.0: dependencies: debug: 2.6.9 depd: 2.0.0 @@ -18112,12 +18419,12 @@ snapshots: transitivePeerDependencies: - supports-color - serve-static@1.15.0: + serve-static@1.16.2: dependencies: - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 0.18.0 + send: 0.19.0 transitivePeerDependencies: - supports-color @@ -18189,6 +18496,12 @@ snapshots: shell-quote@1.8.1: {} + shelljs@0.8.5: + dependencies: + glob: 7.2.3 + interpret: 1.4.0 + rechoir: 0.6.2 + shiki@0.14.7: dependencies: ansi-sequence-parser: 1.1.1 @@ -18196,9 +18509,13 @@ snapshots: vscode-oniguruma: 1.7.0 vscode-textmate: 8.0.0 - shiki@1.14.1: + shiki@1.22.0: dependencies: - '@shikijs/core': 1.14.1 + '@shikijs/core': 1.22.0 + '@shikijs/engine-javascript': 1.22.0 + '@shikijs/engine-oniguruma': 1.22.0 + '@shikijs/types': 1.22.0 + '@shikijs/vscode-textmate': 9.3.0 '@types/hast': 3.0.4 side-channel@1.0.6: @@ -18214,13 +18531,15 @@ snapshots: signal-exit@4.1.0: {} + simple-bin-help@1.8.0: {} + simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 sirv@2.0.4: dependencies: - '@polka/url': 1.0.0-next.25 + '@polka/url': 1.0.0-next.28 mrmime: 2.0.0 totalist: 3.0.1 @@ -18264,18 +18583,17 @@ snapshots: uuid: 8.3.2 websocket-driver: 0.7.4 - sonic-boom@1.4.1: + sonic-boom@3.8.1: dependencies: atomic-sleep: 1.0.0 - flatstr: 1.0.12 - sonic-boom@3.8.1: + sonic-boom@4.1.0: dependencies: atomic-sleep: 1.0.0 source-map-js@1.0.1: {} - source-map-js@1.2.0: {} + source-map-js@1.2.1: {} source-map-support@0.5.13: dependencies: @@ -18302,6 +18620,8 @@ snapshots: sourcemap-codec@1.4.8: {} + space-separated-tokens@2.0.2: {} + spawn-command@0.0.2: {} spawn-wrap@2.0.0: @@ -18321,25 +18641,25 @@ snapshots: spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.18 + spdx-license-ids: 3.0.20 spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.18 + spdx-license-ids: 3.0.20 spdx-expression-parse@4.0.0: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.18 + spdx-license-ids: 3.0.20 - spdx-license-ids@3.0.18: {} + spdx-license-ids@3.0.20: {} spdy-transport@3.0.0: dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -18350,7 +18670,7 @@ snapshots: spdy@4.0.2: dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -18360,6 +18680,17 @@ snapshots: speakingurl@14.0.1: {} + spec-change@1.11.11: + dependencies: + arg: 5.0.2 + debug: 4.3.7(supports-color@8.1.1) + deep-equal: 2.2.3 + dependency-tree: 11.0.1 + lazy-ass: 2.0.3 + tinyglobby: 0.2.9 + transitivePeerDependencies: + - supports-color + split2@4.2.0: {} split@0.3.3: @@ -18388,16 +18719,16 @@ snapshots: stackback@0.0.2: {} - start-server-and-test@2.0.5: + start-server-and-test@2.0.8: dependencies: arg: 5.0.2 bluebird: 3.7.2 check-more-types: 2.24.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) execa: 5.1.1 lazy-ass: 1.6.0 ps-tree: 1.2.0 - wait-on: 7.2.0(debug@4.3.6) + wait-on: 8.0.1(debug@4.3.7) transitivePeerDependencies: - supports-color @@ -18407,6 +18738,10 @@ snapshots: std-env@3.7.0: {} + stop-iteration-iterator@1.0.0: + dependencies: + internal-slot: 1.0.7 + stream-combiner@0.0.4: dependencies: duplexer: 0.1.2 @@ -18418,8 +18753,6 @@ snapshots: char-regex: 1.0.2 strip-ansi: 6.0.1 - string-similarity@4.0.4: {} - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -18434,7 +18767,7 @@ snapshots: string-width@7.2.0: dependencies: - emoji-regex: 10.3.0 + emoji-regex: 10.4.0 get-east-asian-width: 1.2.0 strip-ansi: 7.1.0 @@ -18449,7 +18782,7 @@ snapshots: gopd: 1.0.1 has-symbols: 1.0.3 internal-slot: 1.0.7 - regexp.prototype.flags: 1.5.2 + regexp.prototype.flags: 1.5.3 set-function-name: 2.0.2 side-channel: 1.0.6 @@ -18480,6 +18813,11 @@ snapshots: dependencies: safe-buffer: 5.2.1 + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + stringify-object@3.3.0: dependencies: get-own-enumerable-property-symbols: 3.0.2 @@ -18496,7 +18834,7 @@ snapshots: strip-ansi@7.1.0: dependencies: - ansi-regex: 6.0.1 + ansi-regex: 6.1.0 strip-bom@3.0.0: {} @@ -18522,6 +18860,10 @@ snapshots: stylis@4.3.4: {} + stylus-lookup@6.0.0: + dependencies: + commander: 12.1.0 + sucrase@3.35.0: dependencies: '@jridgewell/gen-mapping': 0.3.5 @@ -18554,14 +18896,14 @@ snapshots: symbol-tree@3.2.4: {} - synckit@0.9.1: + synckit@0.9.2: dependencies: '@pkgr/core': 0.1.1 tslib: 2.7.0 tabbable@6.2.0: {} - tailwindcss@3.4.10: + tailwindcss@3.4.13: dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -18576,12 +18918,12 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 object-hash: 3.0.0 - picocolors: 1.0.1 - postcss: 8.4.41 - postcss-import: 15.1.0(postcss@8.4.41) - postcss-js: 4.0.1(postcss@8.4.41) - postcss-load-config: 4.0.2(postcss@8.4.41) - postcss-nested: 6.2.0(postcss@8.4.41) + picocolors: 1.1.0 + postcss: 8.4.47 + postcss-import: 15.1.0(postcss@8.4.47) + postcss-js: 4.0.1(postcss@8.4.47) + postcss-load-config: 4.0.2(postcss@8.4.47) + postcss-nested: 6.2.0(postcss@8.4.47) postcss-selector-parser: 6.1.2 resolve: 1.22.8 sucrase: 3.35.0 @@ -18592,7 +18934,7 @@ snapshots: teen_process@1.16.0: dependencies: - '@babel/runtime': 7.25.4 + '@babel/runtime': 7.25.7 bluebird: 3.7.2 lodash: 4.17.21 shell-quote: 1.8.1 @@ -18615,36 +18957,29 @@ snapshots: term-size@2.2.1: {} - terser-webpack-plugin@5.3.10(esbuild@0.21.5)(webpack@5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0)): + terser-webpack-plugin@5.3.10(esbuild@0.21.5)(webpack@5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 - terser: 5.31.3 - webpack: 5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0) + terser: 5.34.1 + webpack: 5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0) optionalDependencies: esbuild: 0.21.5 - terser-webpack-plugin@5.3.10(esbuild@0.21.5)(webpack@5.93.0(esbuild@0.21.5)): + terser-webpack-plugin@5.3.10(esbuild@0.21.5)(webpack@5.95.0(esbuild@0.21.5)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 - terser: 5.31.3 - webpack: 5.93.0(esbuild@0.21.5) + terser: 5.34.1 + webpack: 5.95.0(esbuild@0.21.5) optionalDependencies: esbuild: 0.21.5 - terser@5.31.3: - dependencies: - '@jridgewell/source-map': 0.3.6 - acorn: 8.12.1 - commander: 2.20.3 - source-map-support: 0.5.21 - - terser@5.31.6: + terser@5.34.1: dependencies: '@jridgewell/source-map': 0.3.6 acorn: 8.12.1 @@ -18671,6 +19006,10 @@ snapshots: dependencies: real-require: 0.2.0 + thread-stream@3.1.0: + dependencies: + real-require: 0.2.0 + throat@6.0.2: {} throttleit@1.0.1: {} @@ -18684,12 +19023,15 @@ snapshots: es5-ext: 0.10.64 next-tick: 1.1.0 - tiny-lru@8.0.2: {} - tinybench@2.9.0: {} tinyexec@0.3.0: {} + tinyglobby@0.2.9: + dependencies: + fdir: 6.4.0(picomatch@4.0.2) + picomatch: 4.0.2 + tinypool@0.8.4: {} tinyspy@2.2.1: {} @@ -18708,6 +19050,8 @@ snapshots: dependencies: is-number: 7.0.0 + toad-cache@3.7.0: {} + toidentifier@1.0.1: {} totalist@3.0.1: {} @@ -18733,26 +19077,36 @@ snapshots: tree-kill@1.2.2: {} + trim-lines@3.0.1: {} + trough@2.2.0: {} ts-api-utils@1.3.0(typescript@5.4.5): dependencies: typescript: 5.4.5 + ts-api-utils@1.3.0(typescript@5.6.2): + dependencies: + typescript: 5.6.2 + ts-dedent@2.2.0: {} ts-interface-checker@0.1.13: {} ts-toolbelt@6.15.5: {} - tslib@2.6.3: {} + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 tslib@2.7.0: {} - tsx@4.19.0: + tsx@4.19.1: dependencies: esbuild: 0.23.1 - get-tsconfig: 4.7.6 + get-tsconfig: 4.8.1 optionalDependencies: fsevents: 2.3.3 @@ -18760,6 +19114,8 @@ snapshots: dependencies: safe-buffer: 5.2.1 + tunnel@0.0.6: {} + tweetnacl@0.14.5: {} type-check@0.4.0: @@ -18780,7 +19136,7 @@ snapshots: type-fest@0.8.1: {} - type-fest@4.25.0: {} + type-fest@4.26.1: {} type-is@1.6.18: dependencies: @@ -18838,11 +19194,11 @@ snapshots: shiki: 0.14.7 typescript: 5.4.5 - typescript-eslint@8.0.1(eslint@9.8.0)(typescript@5.4.5): + typescript-eslint@8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5): dependencies: - '@typescript-eslint/eslint-plugin': 8.0.1(@typescript-eslint/parser@8.0.1(eslint@9.8.0)(typescript@5.4.5))(eslint@9.8.0)(typescript@5.4.5) - '@typescript-eslint/parser': 8.0.1(eslint@9.8.0)(typescript@5.4.5) - '@typescript-eslint/utils': 8.0.1(eslint@9.8.0)(typescript@5.4.5) + '@typescript-eslint/eslint-plugin': 8.8.1(@typescript-eslint/parser@8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5))(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5) + '@typescript-eslint/parser': 8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5) + '@typescript-eslint/utils': 8.8.1(eslint@9.12.0(jiti@1.21.6))(typescript@5.4.5) optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: @@ -18851,11 +19207,13 @@ snapshots: typescript@5.4.5: {} + typescript@5.6.2: {} + uc.micro@1.0.6: {} ufo@1.5.4: {} - uglify-js@3.19.1: {} + uglify-js@3.19.3: {} unbox-primitive@1.0.2: dependencies: @@ -18876,14 +19234,18 @@ snapshots: undici-types@6.19.8: {} - unicode-canonical-property-names-ecmascript@2.0.0: {} + undici@5.28.4: + dependencies: + '@fastify/busboy': 2.1.1 + + unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-match-property-ecmascript@2.0.0: dependencies: - unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-canonical-property-names-ecmascript: 2.0.1 unicode-property-aliases-ecmascript: 2.1.0 - unicode-match-property-value-ecmascript@2.1.0: {} + unicode-match-property-value-ecmascript@2.2.0: {} unicode-property-aliases-ecmascript@2.1.0: {} @@ -18891,23 +19253,23 @@ snapshots: unified@11.0.4: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 bail: 2.0.2 devlop: 1.1.0 extend: 3.0.2 is-plain-obj: 4.1.0 trough: 2.2.0 - vfile: 6.0.2 + vfile: 6.0.3 unified@11.0.5: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 bail: 2.0.2 devlop: 1.1.0 extend: 3.0.2 is-plain-obj: 4.1.0 trough: 2.2.0 - vfile: 6.0.2 + vfile: 6.0.3 unique-string@2.0.0: dependencies: @@ -18917,15 +19279,19 @@ snapshots: unist-util-inspect@8.0.0: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-is@6.0.0: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 unist-util-stringify-position@2.0.3: dependencies: - '@types/unist': 2.0.10 + '@types/unist': 2.0.11 unist-util-stringify-position@4.0.0: dependencies: @@ -18933,12 +19299,12 @@ snapshots: unist-util-visit-parents@6.0.1: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-is: 6.0.0 unist-util-visit@5.0.0: dependencies: - '@types/unist': 3.0.2 + '@types/unist': 3.0.3 unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 @@ -18948,13 +19314,13 @@ snapshots: universalify@2.0.1: {} - unocss@0.59.4(postcss@8.4.41)(rollup@2.79.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6)): + unocss@0.59.4(postcss@8.4.47)(rollup@2.79.2)(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1)): dependencies: - '@unocss/astro': 0.59.4(rollup@2.79.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6)) - '@unocss/cli': 0.59.4(rollup@2.79.1) + '@unocss/astro': 0.59.4(rollup@2.79.2)(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1)) + '@unocss/cli': 0.59.4(rollup@2.79.2) '@unocss/core': 0.59.4 '@unocss/extractor-arbitrary-variants': 0.59.4 - '@unocss/postcss': 0.59.4(postcss@8.4.41) + '@unocss/postcss': 0.59.4(postcss@8.4.47) '@unocss/preset-attributify': 0.59.4 '@unocss/preset-icons': 0.59.4 '@unocss/preset-mini': 0.59.4 @@ -18969,38 +19335,9 @@ snapshots: '@unocss/transformer-compile-class': 0.59.4 '@unocss/transformer-directives': 0.59.4 '@unocss/transformer-variant-group': 0.59.4 - '@unocss/vite': 0.59.4(rollup@2.79.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6)) + '@unocss/vite': 0.59.4(rollup@2.79.2)(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1)) optionalDependencies: - vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) - transitivePeerDependencies: - - postcss - - rollup - - supports-color - - unocss@0.59.4(postcss@8.4.41)(rollup@4.21.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6)): - dependencies: - '@unocss/astro': 0.59.4(rollup@4.21.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6)) - '@unocss/cli': 0.59.4(rollup@4.21.1) - '@unocss/core': 0.59.4 - '@unocss/extractor-arbitrary-variants': 0.59.4 - '@unocss/postcss': 0.59.4(postcss@8.4.41) - '@unocss/preset-attributify': 0.59.4 - '@unocss/preset-icons': 0.59.4 - '@unocss/preset-mini': 0.59.4 - '@unocss/preset-tagify': 0.59.4 - '@unocss/preset-typography': 0.59.4 - '@unocss/preset-uno': 0.59.4 - '@unocss/preset-web-fonts': 0.59.4 - '@unocss/preset-wind': 0.59.4 - '@unocss/reset': 0.59.4 - '@unocss/transformer-attributify-jsx': 0.59.4 - '@unocss/transformer-attributify-jsx-babel': 0.59.4 - '@unocss/transformer-compile-class': 0.59.4 - '@unocss/transformer-directives': 0.59.4 - '@unocss/transformer-variant-group': 0.59.4 - '@unocss/vite': 0.59.4(rollup@4.21.1)(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6)) - optionalDependencies: - vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) + vite: 5.4.8(@types/node@20.16.11)(terser@5.34.1) transitivePeerDependencies: - postcss - rollup @@ -19008,60 +19345,42 @@ snapshots: unpipe@1.0.0: {} - unplugin-vue-components@0.26.0(@babel/parser@7.25.4)(rollup@2.79.1)(vue@3.4.38(typescript@5.4.5)): + unplugin-vue-components@0.26.0(@babel/parser@7.25.7)(rollup@2.79.2)(vue@3.5.11(typescript@5.6.2))(webpack-sources@3.2.3): dependencies: '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + '@rollup/pluginutils': 5.1.2(rollup@2.79.2) chokidar: 3.6.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) fast-glob: 3.3.2 local-pkg: 0.4.3 magic-string: 0.30.11 minimatch: 9.0.5 resolve: 1.22.8 - unplugin: 1.12.0 - vue: 3.4.38(typescript@5.4.5) + unplugin: 1.14.1(webpack-sources@3.2.3) + vue: 3.5.11(typescript@5.6.2) optionalDependencies: - '@babel/parser': 7.25.4 + '@babel/parser': 7.25.7 transitivePeerDependencies: - rollup - supports-color + - webpack-sources - unplugin-vue-components@0.26.0(@babel/parser@7.25.4)(rollup@4.21.1)(vue@3.4.38(typescript@5.4.5)): - dependencies: - '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.1.0(rollup@4.21.1) - chokidar: 3.6.0 - debug: 4.3.6(supports-color@8.1.1) - fast-glob: 3.3.2 - local-pkg: 0.4.3 - magic-string: 0.30.11 - minimatch: 9.0.5 - resolve: 1.22.8 - unplugin: 1.12.0 - vue: 3.4.38(typescript@5.4.5) - optionalDependencies: - '@babel/parser': 7.25.4 - transitivePeerDependencies: - - rollup - - supports-color - - unplugin@1.12.0: + unplugin@1.14.1(webpack-sources@3.2.3): dependencies: acorn: 8.12.1 - chokidar: 3.6.0 - webpack-sources: 3.2.3 webpack-virtual-modules: 0.6.2 + optionalDependencies: + webpack-sources: 3.2.3 untildify@4.0.0: {} upath@1.2.0: {} - update-browserslist-db@1.1.0(browserslist@4.23.3): + update-browserslist-db@1.1.1(browserslist@4.24.0): dependencies: - browserslist: 4.23.3 - escalade: 3.1.2 - picocolors: 1.0.1 + browserslist: 4.24.0 + escalade: 3.2.0 + picocolors: 1.1.0 uri-js@4.4.1: dependencies: @@ -19104,19 +19423,18 @@ snapshots: '@types/unist': 3.0.3 unist-util-stringify-position: 4.0.0 - vfile@6.0.2: + vfile@6.0.3: dependencies: '@types/unist': 3.0.3 - unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 - vite-node@1.6.0(@types/node@20.16.2)(terser@5.31.6): + vite-node@1.6.0(@types/node@20.16.11)(terser@5.34.1): dependencies: cac: 6.7.14 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) pathe: 1.1.2 - picocolors: 1.0.1 - vite: 5.4.2(@types/node@20.16.2)(terser@5.31.6) + picocolors: 1.1.0 + vite: 5.4.8(@types/node@20.16.11)(terser@5.34.1) transitivePeerDependencies: - '@types/node' - less @@ -19128,78 +19446,68 @@ snapshots: - supports-color - terser - vite-plugin-istanbul@6.0.2(vite@5.4.2(@types/node@20.16.2)(terser@5.31.6)): + vite-plugin-istanbul@6.0.2(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1)): dependencies: '@istanbuljs/load-nyc-config': 1.1.0 - espree: 10.1.0 + espree: 10.2.0 istanbul-lib-instrument: 6.0.3 - picocolors: 1.0.1 + picocolors: 1.1.0 source-map: 0.7.4 test-exclude: 6.0.0 - vite: 5.4.2(@types/node@20.16.2)(terser@5.31.6) + vite: 5.4.8(@types/node@20.16.11)(terser@5.34.1) transitivePeerDependencies: - supports-color - vite-plugin-pwa@0.19.8(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0): + vite-plugin-pwa@0.19.8(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))(workbox-build@7.1.1(@types/babel__core@7.20.5))(workbox-window@7.1.0): dependencies: - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) fast-glob: 3.3.2 pretty-bytes: 6.1.1 - vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) + vite: 5.4.8(@types/node@20.16.11)(terser@5.34.1) workbox-build: 7.1.1(@types/babel__core@7.20.5) workbox-window: 7.1.0 transitivePeerDependencies: - supports-color - vite@5.4.2(@types/node@20.16.2)(terser@5.31.6): + vite@5.4.8(@types/node@20.16.11)(terser@5.34.1): dependencies: esbuild: 0.21.5 - postcss: 8.4.41 - rollup: 4.21.1 + postcss: 8.4.47 + rollup: 4.24.0 optionalDependencies: - '@types/node': 20.16.2 + '@types/node': 20.16.11 fsevents: 2.3.3 - terser: 5.31.6 + terser: 5.34.1 - vite@5.4.2(@types/node@22.5.1)(terser@5.31.6): - dependencies: - esbuild: 0.21.5 - postcss: 8.4.41 - rollup: 4.21.1 - optionalDependencies: - '@types/node': 22.5.1 - fsevents: 2.3.3 - terser: 5.31.6 - - vitepress-plugin-search@1.0.4-alpha.22(flexsearch@0.7.43)(vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.1)(axios@1.7.5)(postcss@8.4.41)(search-insights@2.15.0)(terser@5.31.6)(typescript@5.4.5))(vue@3.4.38(typescript@5.4.5)): + vitepress-plugin-search@1.0.4-alpha.22(flexsearch@0.7.43)(vitepress@1.1.4(@algolia/client-search@4.24.0)(@types/node@20.16.11)(axios@1.7.7)(postcss@8.4.47)(search-insights@2.17.2)(terser@5.34.1)(typescript@5.4.5))(vue@3.5.11(typescript@5.4.5)): dependencies: '@types/flexsearch': 0.7.6 '@types/markdown-it': 12.2.3 flexsearch: 0.7.43 glob-to-regexp: 0.4.1 markdown-it: 13.0.2 - vitepress: 1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.1)(axios@1.7.5)(postcss@8.4.41)(search-insights@2.15.0)(terser@5.31.6)(typescript@5.4.5) - vue: 3.4.38(typescript@5.4.5) + vitepress: 1.1.4(@algolia/client-search@4.24.0)(@types/node@20.16.11)(axios@1.7.7)(postcss@8.4.47)(search-insights@2.17.2)(terser@5.34.1)(typescript@5.4.5) + vue: 3.5.11(typescript@5.4.5) - vitepress@1.1.4(@algolia/client-search@4.24.0)(@types/node@22.5.1)(axios@1.7.5)(postcss@8.4.41)(search-insights@2.15.0)(terser@5.31.6)(typescript@5.4.5): + vitepress@1.1.4(@algolia/client-search@4.24.0)(@types/node@20.16.11)(axios@1.7.7)(postcss@8.4.47)(search-insights@2.17.2)(terser@5.34.1)(typescript@5.4.5): dependencies: - '@docsearch/css': 3.6.1 - '@docsearch/js': 3.6.1(@algolia/client-search@4.24.0)(search-insights@2.15.0) - '@shikijs/core': 1.14.1 - '@shikijs/transformers': 1.14.1 + '@docsearch/css': 3.6.2 + '@docsearch/js': 3.6.2(@algolia/client-search@4.24.0)(search-insights@2.17.2) + '@shikijs/core': 1.22.0 + '@shikijs/transformers': 1.22.0 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 5.1.2(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(vue@3.4.38(typescript@5.4.5)) - '@vue/devtools-api': 7.3.9 - '@vueuse/core': 10.11.1(vue@3.4.38(typescript@5.4.5)) - '@vueuse/integrations': 10.11.1(axios@1.7.5)(focus-trap@7.5.4)(vue@3.4.38(typescript@5.4.5)) - focus-trap: 7.5.4 + '@vitejs/plugin-vue': 5.1.4(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))(vue@3.5.11(typescript@5.4.5)) + '@vue/devtools-api': 7.4.6 + '@vueuse/core': 10.11.1(vue@3.5.11(typescript@5.4.5)) + '@vueuse/integrations': 10.11.1(axios@1.7.7)(focus-trap@7.6.0)(vue@3.5.11(typescript@5.4.5)) + focus-trap: 7.6.0 mark.js: 8.11.1 minisearch: 6.3.0 - shiki: 1.14.1 - vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) - vue: 3.4.38(typescript@5.4.5) + shiki: 1.22.0 + vite: 5.4.8(@types/node@20.16.11)(terser@5.34.1) + vue: 3.5.11(typescript@5.4.5) optionalDependencies: - postcss: 8.4.41 + postcss: 8.4.47 transitivePeerDependencies: - '@algolia/client-search' - '@types/node' @@ -19228,26 +19536,25 @@ snapshots: - typescript - universal-cookie - vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.1)(axios@1.7.5)(postcss@8.4.41)(search-insights@2.15.0)(terser@5.31.6)(typescript@5.4.5): + vitepress@1.1.4(@algolia/client-search@4.24.0)(@types/node@20.16.11)(axios@1.7.7)(postcss@8.4.47)(search-insights@2.17.2)(terser@5.34.1)(typescript@5.6.2): dependencies: - '@docsearch/css': 3.6.1 - '@docsearch/js': 3.6.1(@algolia/client-search@4.24.0)(search-insights@2.15.0) - '@shikijs/core': 1.14.1 - '@shikijs/transformers': 1.14.1 + '@docsearch/css': 3.6.2 + '@docsearch/js': 3.6.2(@algolia/client-search@4.24.0)(search-insights@2.17.2) + '@shikijs/core': 1.22.0 + '@shikijs/transformers': 1.22.0 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 5.1.2(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(vue@3.4.38(typescript@5.4.5)) - '@vue/devtools-api': 7.3.9 - '@vue/shared': 3.4.38 - '@vueuse/core': 11.0.3(vue@3.4.38(typescript@5.4.5)) - '@vueuse/integrations': 11.0.3(axios@1.7.5)(focus-trap@7.5.4)(vue@3.4.38(typescript@5.4.5)) - focus-trap: 7.5.4 + '@vitejs/plugin-vue': 5.1.4(vite@5.4.8(@types/node@20.16.11)(terser@5.34.1))(vue@3.5.11(typescript@5.6.2)) + '@vue/devtools-api': 7.4.6 + '@vueuse/core': 10.11.1(vue@3.5.11(typescript@5.6.2)) + '@vueuse/integrations': 10.11.1(axios@1.7.7)(focus-trap@7.6.0)(vue@3.5.11(typescript@5.6.2)) + focus-trap: 7.6.0 mark.js: 8.11.1 - minisearch: 7.1.0 - shiki: 1.14.1 - vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) - vue: 3.4.38(typescript@5.4.5) + minisearch: 6.3.0 + shiki: 1.22.0 + vite: 5.4.8(@types/node@20.16.11)(terser@5.34.1) + vue: 3.5.11(typescript@5.6.2) optionalDependencies: - postcss: 8.4.41 + postcss: 8.4.47 transitivePeerDependencies: - '@algolia/client-search' - '@types/node' @@ -19276,30 +19583,30 @@ snapshots: - typescript - universal-cookie - vitest@1.6.0(@types/node@20.16.2)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.31.6): + vitest@1.6.0(@types/node@20.16.11)(@vitest/ui@1.6.0)(jsdom@24.1.3)(terser@5.34.1): dependencies: '@vitest/expect': 1.6.0 '@vitest/runner': 1.6.0 '@vitest/snapshot': 1.6.0 '@vitest/spy': 1.6.0 '@vitest/utils': 1.6.0 - acorn-walk: 8.3.3 + acorn-walk: 8.3.4 chai: 4.5.0 - debug: 4.3.6(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) execa: 8.0.1 local-pkg: 0.5.0 magic-string: 0.30.11 pathe: 1.1.2 - picocolors: 1.0.1 + picocolors: 1.1.0 std-env: 3.7.0 strip-literal: 2.1.0 tinybench: 2.9.0 tinypool: 0.8.4 - vite: 5.4.2(@types/node@20.16.2)(terser@5.31.6) - vite-node: 1.6.0(@types/node@20.16.2)(terser@5.31.6) + vite: 5.4.8(@types/node@20.16.11)(terser@5.34.1) + vite-node: 1.6.0(@types/node@20.16.11)(terser@5.34.1) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 20.16.2 + '@types/node': 20.16.11 '@vitest/ui': 1.6.0(vitest@1.6.0) jsdom: 24.1.3 transitivePeerDependencies: @@ -19343,32 +19650,46 @@ snapshots: vscode-uri@3.0.8: {} - vue-demi@0.14.10(vue@3.4.38(typescript@5.4.5)): + vue-demi@0.14.10(vue@3.5.11(typescript@5.4.5)): dependencies: - vue: 3.4.38(typescript@5.4.5) + vue: 3.5.11(typescript@5.4.5) - vue@3.4.38(typescript@5.4.5): + vue-demi@0.14.10(vue@3.5.11(typescript@5.6.2)): dependencies: - '@vue/compiler-dom': 3.4.38 - '@vue/compiler-sfc': 3.4.38 - '@vue/runtime-dom': 3.4.38 - '@vue/server-renderer': 3.4.38(vue@3.4.38(typescript@5.4.5)) - '@vue/shared': 3.4.38 + vue: 3.5.11(typescript@5.6.2) + + vue@3.5.11(typescript@5.4.5): + dependencies: + '@vue/compiler-dom': 3.5.11 + '@vue/compiler-sfc': 3.5.11 + '@vue/runtime-dom': 3.5.11 + '@vue/server-renderer': 3.5.11(vue@3.5.11(typescript@5.4.5)) + '@vue/shared': 3.5.11 optionalDependencies: typescript: 5.4.5 - vuex@4.1.0(vue@3.4.38(typescript@5.4.5)): + vue@3.5.11(typescript@5.6.2): dependencies: - '@vue/devtools-api': 6.6.3 - vue: 3.4.38(typescript@5.4.5) + '@vue/compiler-dom': 3.5.11 + '@vue/compiler-sfc': 3.5.11 + '@vue/runtime-dom': 3.5.11 + '@vue/server-renderer': 3.5.11(vue@3.5.11(typescript@5.6.2)) + '@vue/shared': 3.5.11 + optionalDependencies: + typescript: 5.6.2 + + vuex@4.1.0(vue@3.5.11(typescript@5.6.2)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.11(typescript@5.6.2) w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 - wait-on@7.2.0(debug@4.3.6): + wait-on@8.0.1(debug@4.3.7): dependencies: - axios: 1.7.3(debug@4.3.6) + axios: 1.7.7(debug@4.3.7) joi: 17.13.3 lodash: 4.17.21 minimist: 1.2.8 @@ -19380,7 +19701,7 @@ snapshots: dependencies: makeerror: 1.0.12 - watchpack@2.4.1: + watchpack@2.4.2: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -19389,11 +19710,16 @@ snapshots: dependencies: minimalistic-assert: 1.0.1 + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + optional: true + web-streams-polyfill@3.3.3: {} webdriver@7.31.1(typescript@5.4.5): dependencies: - '@types/node': 18.19.47 + '@types/node': 18.19.55 '@wdio/config': 7.31.1(typescript@5.4.5) '@wdio/logger': 7.26.0 '@wdio/protocols': 7.27.0 @@ -19411,12 +19737,12 @@ snapshots: webidl-conversions@7.0.0: {} - webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0): + webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0): dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 1.2.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0))(webpack@5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0)) - '@webpack-cli/info': 1.5.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0)) - '@webpack-cli/serve': 1.7.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0))(webpack-dev-server@4.15.2(webpack-cli@4.10.0)(webpack@5.93.0)) + '@webpack-cli/configtest': 1.2.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0))(webpack@5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0)) + '@webpack-cli/info': 1.5.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0)) + '@webpack-cli/serve': 1.7.0(webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0))(webpack-dev-server@4.15.2(webpack-cli@4.10.0)(webpack@5.95.0)) colorette: 2.0.20 commander: 7.2.0 cross-spawn: 7.0.3 @@ -19424,21 +19750,21 @@ snapshots: import-local: 3.2.0 interpret: 2.2.0 rechoir: 0.7.1 - webpack: 5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0) + webpack: 5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0) webpack-merge: 5.10.0 optionalDependencies: - webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.93.0) + webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.95.0) - webpack-dev-middleware@5.3.4(webpack@5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0)): + webpack-dev-middleware@5.3.4(webpack@5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0)): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0) + webpack: 5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0) - webpack-dev-server@4.15.2(webpack-cli@4.10.0)(webpack@5.93.0): + webpack-dev-server@4.15.2(webpack-cli@4.10.0)(webpack@5.95.0): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -19454,12 +19780,12 @@ snapshots: compression: 1.7.4 connect-history-api-fallback: 2.0.0 default-gateway: 6.0.3 - express: 4.19.2 + express: 4.21.0 graceful-fs: 4.2.11 html-entities: 2.5.2 - http-proxy-middleware: 2.0.6(@types/express@4.17.21) + http-proxy-middleware: 2.0.7(@types/express@4.17.21) ipaddr.js: 2.2.0 - launch-editor: 2.8.0 + launch-editor: 2.9.1 open: 8.4.2 p-retry: 4.6.2 rimraf: 3.0.2 @@ -19468,11 +19794,11 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0)) + webpack-dev-middleware: 5.3.4(webpack@5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0)) ws: 8.18.0 optionalDependencies: - webpack: 5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0) - webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0) + webpack: 5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0) + webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0) transitivePeerDependencies: - bufferutil - debug @@ -19489,16 +19815,15 @@ snapshots: webpack-virtual-modules@0.6.2: {} - webpack@5.93.0(esbuild@0.21.5): + webpack@5.95.0(esbuild@0.21.5): dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 '@webassemblyjs/ast': 1.12.1 '@webassemblyjs/wasm-edit': 1.12.1 '@webassemblyjs/wasm-parser': 1.12.1 acorn: 8.12.1 acorn-import-attributes: 1.9.5(acorn@8.12.1) - browserslist: 4.23.3 + browserslist: 4.24.0 chrome-trace-event: 1.0.4 enhanced-resolve: 5.17.1 es-module-lexer: 1.5.4 @@ -19512,24 +19837,23 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(esbuild@0.21.5)(webpack@5.93.0(esbuild@0.21.5)) - watchpack: 2.4.1 + terser-webpack-plugin: 5.3.10(esbuild@0.21.5)(webpack@5.95.0(esbuild@0.21.5)) + watchpack: 2.4.2 webpack-sources: 3.2.3 transitivePeerDependencies: - '@swc/core' - esbuild - uglify-js - webpack@5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0): + webpack@5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0): dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 '@webassemblyjs/ast': 1.12.1 '@webassemblyjs/wasm-edit': 1.12.1 '@webassemblyjs/wasm-parser': 1.12.1 acorn: 8.12.1 acorn-import-attributes: 1.9.5(acorn@8.12.1) - browserslist: 4.23.3 + browserslist: 4.24.0 chrome-trace-event: 1.0.4 enhanced-resolve: 5.17.1 es-module-lexer: 1.5.4 @@ -19543,11 +19867,11 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(esbuild@0.21.5)(webpack@5.93.0(esbuild@0.21.5)(webpack-cli@4.10.0)) - watchpack: 2.4.1 + terser-webpack-plugin: 5.3.10(esbuild@0.21.5)(webpack@5.95.0(esbuild@0.21.5)(webpack-cli@4.10.0)) + watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: - webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.93.0) + webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.95.0) transitivePeerDependencies: - '@swc/core' - esbuild @@ -19591,12 +19915,14 @@ snapshots: is-string: 1.0.7 is-symbol: 1.0.4 - which-module@2.0.1: {} - - which-pm@2.2.0: + which-collection@1.0.2: dependencies: - load-yaml-file: 0.2.0 - path-exists: 4.0.0 + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 + + which-module@2.0.1: {} which-typed-array@1.1.15: dependencies: @@ -19641,13 +19967,13 @@ snapshots: workbox-build@7.1.1(@types/babel__core@7.20.5): dependencies: '@apideck/better-ajv-errors': 0.3.6(ajv@8.17.1) - '@babel/core': 7.25.2 - '@babel/preset-env': 7.25.4(@babel/core@7.25.2) - '@babel/runtime': 7.25.4 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.25.2)(@types/babel__core@7.20.5)(rollup@2.79.1) - '@rollup/plugin-node-resolve': 15.2.3(rollup@2.79.1) - '@rollup/plugin-replace': 2.4.2(rollup@2.79.1) - '@rollup/plugin-terser': 0.4.4(rollup@2.79.1) + '@babel/core': 7.25.7 + '@babel/preset-env': 7.25.7(@babel/core@7.25.7) + '@babel/runtime': 7.25.7 + '@rollup/plugin-babel': 5.3.1(@babel/core@7.25.7)(@types/babel__core@7.20.5)(rollup@2.79.2) + '@rollup/plugin-node-resolve': 15.3.0(rollup@2.79.2) + '@rollup/plugin-replace': 2.4.2(rollup@2.79.2) + '@rollup/plugin-terser': 0.4.4(rollup@2.79.2) '@surma/rollup-plugin-off-main-thread': 2.2.3 ajv: 8.17.1 common-tags: 1.8.2 @@ -19656,7 +19982,7 @@ snapshots: glob: 7.2.3 lodash: 4.17.21 pretty-bytes: 5.6.0 - rollup: 2.79.1 + rollup: 2.79.2 source-map: 0.8.0-beta.0 stringify-object: 3.3.0 strip-comments: 2.0.1 @@ -19804,7 +20130,7 @@ snapshots: yallist@3.1.1: {} - yaml@2.5.0: {} + yaml@2.5.1: {} yargs-parser@18.1.3: dependencies: @@ -19832,7 +20158,7 @@ snapshots: yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.1.2 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 diff --git a/renovate.json b/renovate.json index 859cd982c..5e074f885 100644 --- a/renovate.json +++ b/renovate.json @@ -35,6 +35,10 @@ { "groupName": "eslint", "matchPackagePatterns": ["eslint"] + }, + { + "groupName": "dompurify", + "matchPackagePatterns": ["dompurify"] } ], "dependencyDashboard": false, diff --git a/scripts/tsc-check.ts b/scripts/tsc-check.ts new file mode 100644 index 000000000..7a5ff50a9 --- /dev/null +++ b/scripts/tsc-check.ts @@ -0,0 +1,175 @@ +/** + * Verify the as-built tarballs can be imported into a fresh, out-of-tree TypeScript project. + */ + +/* eslint-disable no-console */ +import { mkdtemp, mkdir, writeFile, readFile, readdir, copyFile, rm } from 'node:fs/promises'; +import { execFileSync } from 'child_process'; +import * as path from 'path'; +import { fileURLToPath } from 'url'; +import { tmpdir } from 'node:os'; + +const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file +const __dirname = path.dirname(__filename); // get the name of the directory + +/** + * Packages to build and import + */ +const PACKAGES = { + mermaid: 'mermaid', + '@mermaid-js/layout-elk': 'mermaid-layout-elk', + // TODO: these don't import cleanly yet due to exotic tsconfig.json requirements + // '@mermaid-js/mermaid-zenuml': 'mermaid-zenuml', + // '@mermaid-js/parser': 'parser', +}; + +/** + * Files to create in the temporary package. + */ +const SRC = { + // a minimal description of a buildable package + 'package.json': (tarballs: Record) => + JSON.stringify( + { + dependencies: tarballs, + scripts: { build: 'tsc -b --verbose' }, + devDependencies: { + // these are somewhat-unexpectedly required, and a downstream would need + // to match the real `package.json` values + 'type-fest': '*', + '@types/d3': '^7.4.3', + '@types/dompurify': '^3.0.5', + typescript: '*', + }, + }, + null, + 2 + ), + // a fairly strict TypeScript configuration + 'tsconfig.json': () => + JSON.stringify( + { + compilerOptions: { + allowSyntheticDefaultImports: true, + composite: true, + declaration: true, + esModuleInterop: true, + incremental: true, + lib: ['dom', 'es2020'], + module: 'esnext', + moduleResolution: 'node', + noEmitOnError: true, + noImplicitAny: true, + noUnusedLocals: true, + sourceMap: true, + target: 'es2020', + rootDir: './src', + outDir: './lib', + strict: true, + tsBuildInfoFile: 'lib/.tsbuildinfo', + }, + }, + null, + 2 + ), + // the simplest possible script: will everything even import? + 'src/index.ts': (tarballs) => { + const imports: string[] = []; + const outputs: string[] = []; + let i = 0; + for (const pkg of Object.keys(tarballs)) { + imports.push(`import * as pkg_${i} from '${pkg}';`); + outputs.push(`console.log(pkg_${i});`); + i++; + } + return [...imports, ...outputs].join('\n'); + }, +}; + +/** + * Commands to run after source files are created. + * + * `npm` is used to detect any unwanted `pnpm`-specific runtime "features". + */ +const COMMANDS = [ + ['npm', 'install'], + ['npm', 'run', 'build'], +]; + +/** + * Built files to expect after commands are executed. + */ +const LIB = ['lib/index.js', 'lib/index.js.map', 'lib/index.d.ts', 'lib/.tsbuildinfo']; + +/** + * Run a small out-of-tree build. + */ +async function main() { + console.warn('Checking out-of-tree TypeScript build using', Object.keys(PACKAGES).join('\n')); + const cwd = await mkdtemp(path.join(tmpdir(), 'mermaid-tsc-check-')); + console.warn('... creating temporary folder', cwd); + const tarballs = await buildTarballs(cwd); + + for (const [filename, generate] of Object.entries(SRC)) { + const dest = path.join(cwd, filename); + await mkdir(path.dirname(dest), { recursive: true }); + console.warn('... creating', dest); + const text = generate(tarballs); + await writeFile(dest, text); + console.info(text); + } + + for (const argv of COMMANDS) { + console.warn('... in', cwd); + console.warn('>>>', ...argv); + execFileSync(argv[0], argv.slice(1), { cwd }); + } + + for (const lib of LIB) { + const checkLib = path.join(cwd, lib); + console.warn('... checking built file', checkLib); + await readFile(checkLib, 'utf-8'); + } + + console.warn('... deleting', cwd); + await rm(cwd, { recursive: true, force: true }); + console.warn('... tsc-check OK for\n', Object.keys(PACKAGES).join('\n')); +} + +/** Build all the tarballs. */ +async function buildTarballs(tmp: string): Promise> { + const dist = path.join(tmp, 'dist'); + await mkdir(dist); + const promises: Promise[] = []; + const tarballs: Record = {}; + for (const [pkg, srcPath] of Object.entries(PACKAGES)) { + promises.push(buildOneTarball(pkg, srcPath, dist, tarballs)); + } + await Promise.all(promises); + return tarballs; +} + +/** Build a single tarball. */ +async function buildOneTarball( + pkg: string, + srcPath: string, + dist: string, + tarballs: Record +): Promise { + const cwd = await mkdtemp(path.join(dist, 'pack-')); + const pkgDir = path.join(__dirname, '../packages', srcPath); + const argv = ['pnpm', 'pack', '--pack-destination', cwd]; + console.warn('>>>', ...argv); + execFileSync(argv[0], argv.slice(1), { cwd: pkgDir }); + const built = await readdir(cwd); + const dest = path.join(dist, built[0]); + await copyFile(path.join(cwd, built[0]), dest); + await rm(cwd, { recursive: true, force: true }); + tarballs[pkg] = dest; +} + +void main().catch((err) => { + console.error(err); + console.error('!!! tsc-check FAIL: temp folder left in place. see logs above for failure notes'); + process.exit(1); +}); diff --git a/tsconfig.json b/tsconfig.json index 08e23be8e..abc88759b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -75,7 +75,7 @@ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, - "preserveSymlinks": true /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */, + // "preserveSymlinks": true /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */, "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, /* Type Checking */ diff --git a/vite.config.ts b/vite.config.ts index ed0ba10f7..fb31841d6 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,15 +2,10 @@ import jison from './.vite/jisonPlugin.js'; import jsonSchemaPlugin from './.vite/jsonSchemaPlugin.js'; import typescript from '@rollup/plugin-typescript'; import { defaultExclude, defineConfig } from 'vitest/config'; -import path from 'path'; export default defineConfig({ resolve: { extensions: ['.js'], - alias: { - // Define your alias here - $root: path.resolve(__dirname, 'packages/mermaid/src'), - }, }, plugins: [ jison(),